mirror of
https://github.com/snesrev/zelda3.git
synced 2025-12-19 18:05:55 -05:00
Add support for german translation
First extract the german dialogue: python restool.py --extract-dialogue -r german.sfc Then extract resources / build the assert file: python restool.py --extract-from-rom --languages=de
This commit is contained in:
671
assets.h
671
assets.h
@@ -1,339 +1,332 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
kNumberOfAssets = 165
|
kNumberOfAssets = 165
|
||||||
};
|
};
|
||||||
extern const uint8 *g_asset_ptrs[kNumberOfAssets];
|
extern const uint8 *g_asset_ptrs[kNumberOfAssets];
|
||||||
extern uint32 g_asset_sizes[kNumberOfAssets];
|
extern uint32 g_asset_sizes[kNumberOfAssets];
|
||||||
#define kSoundBank_intro ((uint8*)g_asset_ptrs[0])
|
extern MemBlk FindInAssetArray(int asset, int idx);
|
||||||
#define kSoundBank_intro_SIZE (g_asset_sizes[0])
|
|
||||||
#define kSoundBank_indoor ((uint8*)g_asset_ptrs[1])
|
#define kSoundBank_intro ((uint8*)g_asset_ptrs[0])
|
||||||
#define kSoundBank_indoor_SIZE (g_asset_sizes[1])
|
#define kSoundBank_intro_SIZE (g_asset_sizes[0])
|
||||||
#define kSoundBank_ending ((uint8*)g_asset_ptrs[2])
|
#define kSoundBank_indoor ((uint8*)g_asset_ptrs[1])
|
||||||
#define kSoundBank_ending_SIZE (g_asset_sizes[2])
|
#define kSoundBank_indoor_SIZE (g_asset_sizes[1])
|
||||||
#define kDungeonRoom ((uint8*)g_asset_ptrs[3])
|
#define kSoundBank_ending ((uint8*)g_asset_ptrs[2])
|
||||||
#define kDungeonRoom_SIZE (g_asset_sizes[3])
|
#define kSoundBank_ending_SIZE (g_asset_sizes[2])
|
||||||
#define kDungeonRoomOffs ((uint16*)g_asset_ptrs[4])
|
#define kDungeonRoom ((uint8*)g_asset_ptrs[3])
|
||||||
#define kDungeonRoomOffs_SIZE (g_asset_sizes[4])
|
#define kDungeonRoom_SIZE (g_asset_sizes[3])
|
||||||
#define kDungeonRoomDoorOffs ((uint16*)g_asset_ptrs[5])
|
#define kDungeonRoomOffs ((uint16*)g_asset_ptrs[4])
|
||||||
#define kDungeonRoomDoorOffs_SIZE (g_asset_sizes[5])
|
#define kDungeonRoomOffs_SIZE (g_asset_sizes[4])
|
||||||
#define kDungeonRoomHeaders ((uint8*)g_asset_ptrs[6])
|
#define kDungeonRoomDoorOffs ((uint16*)g_asset_ptrs[5])
|
||||||
#define kDungeonRoomHeaders_SIZE (g_asset_sizes[6])
|
#define kDungeonRoomDoorOffs_SIZE (g_asset_sizes[5])
|
||||||
#define kDungeonRoomHeadersOffs ((uint16*)g_asset_ptrs[7])
|
#define kDungeonRoomHeaders ((uint8*)g_asset_ptrs[6])
|
||||||
#define kDungeonRoomHeadersOffs_SIZE (g_asset_sizes[7])
|
#define kDungeonRoomHeaders_SIZE (g_asset_sizes[6])
|
||||||
#define kDungeonRoomChests ((uint8*)g_asset_ptrs[8])
|
#define kDungeonRoomHeadersOffs ((uint16*)g_asset_ptrs[7])
|
||||||
#define kDungeonRoomChests_SIZE (g_asset_sizes[8])
|
#define kDungeonRoomHeadersOffs_SIZE (g_asset_sizes[7])
|
||||||
#define kDungeonRoomTeleMsg ((uint16*)g_asset_ptrs[9])
|
#define kDungeonRoomChests ((uint8*)g_asset_ptrs[8])
|
||||||
#define kDungeonRoomTeleMsg_SIZE (g_asset_sizes[9])
|
#define kDungeonRoomChests_SIZE (g_asset_sizes[8])
|
||||||
#define kDungeonPitsHurtPlayer ((uint16*)g_asset_ptrs[10])
|
#define kDungeonRoomTeleMsg ((uint16*)g_asset_ptrs[9])
|
||||||
#define kDungeonPitsHurtPlayer_SIZE (g_asset_sizes[10])
|
#define kDungeonRoomTeleMsg_SIZE (g_asset_sizes[9])
|
||||||
#define kEntranceData_rooms ((uint16*)g_asset_ptrs[11])
|
#define kDungeonPitsHurtPlayer ((uint16*)g_asset_ptrs[10])
|
||||||
#define kEntranceData_rooms_SIZE (g_asset_sizes[11])
|
#define kDungeonPitsHurtPlayer_SIZE (g_asset_sizes[10])
|
||||||
#define kEntranceData_relativeCoords ((uint8*)g_asset_ptrs[12])
|
#define kEntranceData_rooms ((uint16*)g_asset_ptrs[11])
|
||||||
#define kEntranceData_relativeCoords_SIZE (g_asset_sizes[12])
|
#define kEntranceData_rooms_SIZE (g_asset_sizes[11])
|
||||||
#define kEntranceData_scrollX ((uint16*)g_asset_ptrs[13])
|
#define kEntranceData_relativeCoords ((uint8*)g_asset_ptrs[12])
|
||||||
#define kEntranceData_scrollX_SIZE (g_asset_sizes[13])
|
#define kEntranceData_relativeCoords_SIZE (g_asset_sizes[12])
|
||||||
#define kEntranceData_scrollY ((uint16*)g_asset_ptrs[14])
|
#define kEntranceData_scrollX ((uint16*)g_asset_ptrs[13])
|
||||||
#define kEntranceData_scrollY_SIZE (g_asset_sizes[14])
|
#define kEntranceData_scrollX_SIZE (g_asset_sizes[13])
|
||||||
#define kEntranceData_playerX ((uint16*)g_asset_ptrs[15])
|
#define kEntranceData_scrollY ((uint16*)g_asset_ptrs[14])
|
||||||
#define kEntranceData_playerX_SIZE (g_asset_sizes[15])
|
#define kEntranceData_scrollY_SIZE (g_asset_sizes[14])
|
||||||
#define kEntranceData_playerY ((uint16*)g_asset_ptrs[16])
|
#define kEntranceData_playerX ((uint16*)g_asset_ptrs[15])
|
||||||
#define kEntranceData_playerY_SIZE (g_asset_sizes[16])
|
#define kEntranceData_playerX_SIZE (g_asset_sizes[15])
|
||||||
#define kEntranceData_cameraX ((uint16*)g_asset_ptrs[17])
|
#define kEntranceData_playerY ((uint16*)g_asset_ptrs[16])
|
||||||
#define kEntranceData_cameraX_SIZE (g_asset_sizes[17])
|
#define kEntranceData_playerY_SIZE (g_asset_sizes[16])
|
||||||
#define kEntranceData_cameraY ((uint16*)g_asset_ptrs[18])
|
#define kEntranceData_cameraX ((uint16*)g_asset_ptrs[17])
|
||||||
#define kEntranceData_cameraY_SIZE (g_asset_sizes[18])
|
#define kEntranceData_cameraX_SIZE (g_asset_sizes[17])
|
||||||
#define kEntranceData_blockset ((uint8*)g_asset_ptrs[19])
|
#define kEntranceData_cameraY ((uint16*)g_asset_ptrs[18])
|
||||||
#define kEntranceData_blockset_SIZE (g_asset_sizes[19])
|
#define kEntranceData_cameraY_SIZE (g_asset_sizes[18])
|
||||||
#define kEntranceData_floor ((int8*)g_asset_ptrs[20])
|
#define kEntranceData_blockset ((uint8*)g_asset_ptrs[19])
|
||||||
#define kEntranceData_floor_SIZE (g_asset_sizes[20])
|
#define kEntranceData_blockset_SIZE (g_asset_sizes[19])
|
||||||
#define kEntranceData_palace ((int8*)g_asset_ptrs[21])
|
#define kEntranceData_floor ((int8*)g_asset_ptrs[20])
|
||||||
#define kEntranceData_palace_SIZE (g_asset_sizes[21])
|
#define kEntranceData_floor_SIZE (g_asset_sizes[20])
|
||||||
#define kEntranceData_doorwayOrientation ((uint8*)g_asset_ptrs[22])
|
#define kEntranceData_palace ((int8*)g_asset_ptrs[21])
|
||||||
#define kEntranceData_doorwayOrientation_SIZE (g_asset_sizes[22])
|
#define kEntranceData_palace_SIZE (g_asset_sizes[21])
|
||||||
#define kEntranceData_startingBg ((uint8*)g_asset_ptrs[23])
|
#define kEntranceData_doorwayOrientation ((uint8*)g_asset_ptrs[22])
|
||||||
#define kEntranceData_startingBg_SIZE (g_asset_sizes[23])
|
#define kEntranceData_doorwayOrientation_SIZE (g_asset_sizes[22])
|
||||||
#define kEntranceData_quadrant1 ((uint8*)g_asset_ptrs[24])
|
#define kEntranceData_startingBg ((uint8*)g_asset_ptrs[23])
|
||||||
#define kEntranceData_quadrant1_SIZE (g_asset_sizes[24])
|
#define kEntranceData_startingBg_SIZE (g_asset_sizes[23])
|
||||||
#define kEntranceData_quadrant2 ((uint8*)g_asset_ptrs[25])
|
#define kEntranceData_quadrant1 ((uint8*)g_asset_ptrs[24])
|
||||||
#define kEntranceData_quadrant2_SIZE (g_asset_sizes[25])
|
#define kEntranceData_quadrant1_SIZE (g_asset_sizes[24])
|
||||||
#define kEntranceData_doorSettings ((uint16*)g_asset_ptrs[26])
|
#define kEntranceData_quadrant2 ((uint8*)g_asset_ptrs[25])
|
||||||
#define kEntranceData_doorSettings_SIZE (g_asset_sizes[26])
|
#define kEntranceData_quadrant2_SIZE (g_asset_sizes[25])
|
||||||
#define kEntranceData_musicTrack ((uint8*)g_asset_ptrs[27])
|
#define kEntranceData_doorSettings ((uint16*)g_asset_ptrs[26])
|
||||||
#define kEntranceData_musicTrack_SIZE (g_asset_sizes[27])
|
#define kEntranceData_doorSettings_SIZE (g_asset_sizes[26])
|
||||||
#define kStartingPoint_rooms ((uint16*)g_asset_ptrs[28])
|
#define kEntranceData_musicTrack ((uint8*)g_asset_ptrs[27])
|
||||||
#define kStartingPoint_rooms_SIZE (g_asset_sizes[28])
|
#define kEntranceData_musicTrack_SIZE (g_asset_sizes[27])
|
||||||
#define kStartingPoint_relativeCoords ((uint8*)g_asset_ptrs[29])
|
#define kStartingPoint_rooms ((uint16*)g_asset_ptrs[28])
|
||||||
#define kStartingPoint_relativeCoords_SIZE (g_asset_sizes[29])
|
#define kStartingPoint_rooms_SIZE (g_asset_sizes[28])
|
||||||
#define kStartingPoint_scrollX ((uint16*)g_asset_ptrs[30])
|
#define kStartingPoint_relativeCoords ((uint8*)g_asset_ptrs[29])
|
||||||
#define kStartingPoint_scrollX_SIZE (g_asset_sizes[30])
|
#define kStartingPoint_relativeCoords_SIZE (g_asset_sizes[29])
|
||||||
#define kStartingPoint_scrollY ((uint16*)g_asset_ptrs[31])
|
#define kStartingPoint_scrollX ((uint16*)g_asset_ptrs[30])
|
||||||
#define kStartingPoint_scrollY_SIZE (g_asset_sizes[31])
|
#define kStartingPoint_scrollX_SIZE (g_asset_sizes[30])
|
||||||
#define kStartingPoint_playerX ((uint16*)g_asset_ptrs[32])
|
#define kStartingPoint_scrollY ((uint16*)g_asset_ptrs[31])
|
||||||
#define kStartingPoint_playerX_SIZE (g_asset_sizes[32])
|
#define kStartingPoint_scrollY_SIZE (g_asset_sizes[31])
|
||||||
#define kStartingPoint_playerY ((uint16*)g_asset_ptrs[33])
|
#define kStartingPoint_playerX ((uint16*)g_asset_ptrs[32])
|
||||||
#define kStartingPoint_playerY_SIZE (g_asset_sizes[33])
|
#define kStartingPoint_playerX_SIZE (g_asset_sizes[32])
|
||||||
#define kStartingPoint_cameraX ((uint16*)g_asset_ptrs[34])
|
#define kStartingPoint_playerY ((uint16*)g_asset_ptrs[33])
|
||||||
#define kStartingPoint_cameraX_SIZE (g_asset_sizes[34])
|
#define kStartingPoint_playerY_SIZE (g_asset_sizes[33])
|
||||||
#define kStartingPoint_cameraY ((uint16*)g_asset_ptrs[35])
|
#define kStartingPoint_cameraX ((uint16*)g_asset_ptrs[34])
|
||||||
#define kStartingPoint_cameraY_SIZE (g_asset_sizes[35])
|
#define kStartingPoint_cameraX_SIZE (g_asset_sizes[34])
|
||||||
#define kStartingPoint_blockset ((uint8*)g_asset_ptrs[36])
|
#define kStartingPoint_cameraY ((uint16*)g_asset_ptrs[35])
|
||||||
#define kStartingPoint_blockset_SIZE (g_asset_sizes[36])
|
#define kStartingPoint_cameraY_SIZE (g_asset_sizes[35])
|
||||||
#define kStartingPoint_floor ((int8*)g_asset_ptrs[37])
|
#define kStartingPoint_blockset ((uint8*)g_asset_ptrs[36])
|
||||||
#define kStartingPoint_floor_SIZE (g_asset_sizes[37])
|
#define kStartingPoint_blockset_SIZE (g_asset_sizes[36])
|
||||||
#define kStartingPoint_palace ((int8*)g_asset_ptrs[38])
|
#define kStartingPoint_floor ((int8*)g_asset_ptrs[37])
|
||||||
#define kStartingPoint_palace_SIZE (g_asset_sizes[38])
|
#define kStartingPoint_floor_SIZE (g_asset_sizes[37])
|
||||||
#define kStartingPoint_doorwayOrientation ((uint8*)g_asset_ptrs[39])
|
#define kStartingPoint_palace ((int8*)g_asset_ptrs[38])
|
||||||
#define kStartingPoint_doorwayOrientation_SIZE (g_asset_sizes[39])
|
#define kStartingPoint_palace_SIZE (g_asset_sizes[38])
|
||||||
#define kStartingPoint_startingBg ((uint8*)g_asset_ptrs[40])
|
#define kStartingPoint_doorwayOrientation ((uint8*)g_asset_ptrs[39])
|
||||||
#define kStartingPoint_startingBg_SIZE (g_asset_sizes[40])
|
#define kStartingPoint_doorwayOrientation_SIZE (g_asset_sizes[39])
|
||||||
#define kStartingPoint_quadrant1 ((uint8*)g_asset_ptrs[41])
|
#define kStartingPoint_startingBg ((uint8*)g_asset_ptrs[40])
|
||||||
#define kStartingPoint_quadrant1_SIZE (g_asset_sizes[41])
|
#define kStartingPoint_startingBg_SIZE (g_asset_sizes[40])
|
||||||
#define kStartingPoint_quadrant2 ((uint8*)g_asset_ptrs[42])
|
#define kStartingPoint_quadrant1 ((uint8*)g_asset_ptrs[41])
|
||||||
#define kStartingPoint_quadrant2_SIZE (g_asset_sizes[42])
|
#define kStartingPoint_quadrant1_SIZE (g_asset_sizes[41])
|
||||||
#define kStartingPoint_doorSettings ((uint16*)g_asset_ptrs[43])
|
#define kStartingPoint_quadrant2 ((uint8*)g_asset_ptrs[42])
|
||||||
#define kStartingPoint_doorSettings_SIZE (g_asset_sizes[43])
|
#define kStartingPoint_quadrant2_SIZE (g_asset_sizes[42])
|
||||||
#define kStartingPoint_entrance ((uint8*)g_asset_ptrs[44])
|
#define kStartingPoint_doorSettings ((uint16*)g_asset_ptrs[43])
|
||||||
#define kStartingPoint_entrance_SIZE (g_asset_sizes[44])
|
#define kStartingPoint_doorSettings_SIZE (g_asset_sizes[43])
|
||||||
#define kStartingPoint_musicTrack ((uint8*)g_asset_ptrs[45])
|
#define kStartingPoint_entrance ((uint8*)g_asset_ptrs[44])
|
||||||
#define kStartingPoint_musicTrack_SIZE (g_asset_sizes[45])
|
#define kStartingPoint_entrance_SIZE (g_asset_sizes[44])
|
||||||
#define kDungeonRoomDefault ((uint8*)g_asset_ptrs[46])
|
#define kStartingPoint_musicTrack ((uint8*)g_asset_ptrs[45])
|
||||||
#define kDungeonRoomDefault_SIZE (g_asset_sizes[46])
|
#define kStartingPoint_musicTrack_SIZE (g_asset_sizes[45])
|
||||||
#define kDungeonRoomDefaultOffs ((uint16*)g_asset_ptrs[47])
|
#define kDungeonRoomDefault ((uint8*)g_asset_ptrs[46])
|
||||||
#define kDungeonRoomDefaultOffs_SIZE (g_asset_sizes[47])
|
#define kDungeonRoomDefault_SIZE (g_asset_sizes[46])
|
||||||
#define kDungeonRoomOverlay ((uint8*)g_asset_ptrs[48])
|
#define kDungeonRoomDefaultOffs ((uint16*)g_asset_ptrs[47])
|
||||||
#define kDungeonRoomOverlay_SIZE (g_asset_sizes[48])
|
#define kDungeonRoomDefaultOffs_SIZE (g_asset_sizes[47])
|
||||||
#define kDungeonRoomOverlayOffs ((uint16*)g_asset_ptrs[49])
|
#define kDungeonRoomOverlay ((uint8*)g_asset_ptrs[48])
|
||||||
#define kDungeonRoomOverlayOffs_SIZE (g_asset_sizes[49])
|
#define kDungeonRoomOverlay_SIZE (g_asset_sizes[48])
|
||||||
#define kDungeonSecrets ((uint8*)g_asset_ptrs[50])
|
#define kDungeonRoomOverlayOffs ((uint16*)g_asset_ptrs[49])
|
||||||
#define kDungeonSecrets_SIZE (g_asset_sizes[50])
|
#define kDungeonRoomOverlayOffs_SIZE (g_asset_sizes[49])
|
||||||
#define kDungAttrsForTile_Offs ((uint16*)g_asset_ptrs[51])
|
#define kDungeonSecrets ((uint8*)g_asset_ptrs[50])
|
||||||
#define kDungAttrsForTile_Offs_SIZE (g_asset_sizes[51])
|
#define kDungeonSecrets_SIZE (g_asset_sizes[50])
|
||||||
#define kDungAttrsForTile ((uint8*)g_asset_ptrs[52])
|
#define kDungAttrsForTile_Offs ((uint16*)g_asset_ptrs[51])
|
||||||
#define kDungAttrsForTile_SIZE (g_asset_sizes[52])
|
#define kDungAttrsForTile_Offs_SIZE (g_asset_sizes[51])
|
||||||
#define kMovableBlockDataInit ((uint16*)g_asset_ptrs[53])
|
#define kDungAttrsForTile ((uint8*)g_asset_ptrs[52])
|
||||||
#define kMovableBlockDataInit_SIZE (g_asset_sizes[53])
|
#define kDungAttrsForTile_SIZE (g_asset_sizes[52])
|
||||||
#define kTorchDataInit ((uint16*)g_asset_ptrs[54])
|
#define kMovableBlockDataInit ((uint16*)g_asset_ptrs[53])
|
||||||
#define kTorchDataInit_SIZE (g_asset_sizes[54])
|
#define kMovableBlockDataInit_SIZE (g_asset_sizes[53])
|
||||||
#define kTorchDataJunk ((uint16*)g_asset_ptrs[55])
|
#define kTorchDataInit ((uint16*)g_asset_ptrs[54])
|
||||||
#define kTorchDataJunk_SIZE (g_asset_sizes[55])
|
#define kTorchDataInit_SIZE (g_asset_sizes[54])
|
||||||
#define kEnemyDamageData ((uint8*)g_asset_ptrs[56])
|
#define kTorchDataJunk ((uint16*)g_asset_ptrs[55])
|
||||||
#define kEnemyDamageData_SIZE (g_asset_sizes[56])
|
#define kTorchDataJunk_SIZE (g_asset_sizes[55])
|
||||||
#define kLinkGraphics ((uint8*)g_asset_ptrs[57])
|
#define kEnemyDamageData ((uint8*)g_asset_ptrs[56])
|
||||||
#define kLinkGraphics_SIZE (g_asset_sizes[57])
|
#define kEnemyDamageData_SIZE (g_asset_sizes[56])
|
||||||
#define kDungeonSprites ((uint8*)g_asset_ptrs[58])
|
#define kLinkGraphics ((uint8*)g_asset_ptrs[57])
|
||||||
#define kDungeonSprites_SIZE (g_asset_sizes[58])
|
#define kLinkGraphics_SIZE (g_asset_sizes[57])
|
||||||
#define kDungeonSpriteOffs ((uint16*)g_asset_ptrs[59])
|
#define kDungeonSprites ((uint8*)g_asset_ptrs[58])
|
||||||
#define kDungeonSpriteOffs_SIZE (g_asset_sizes[59])
|
#define kDungeonSprites_SIZE (g_asset_sizes[58])
|
||||||
#define kMap32ToMap16_0 ((uint8*)g_asset_ptrs[60])
|
#define kDungeonSpriteOffs ((uint16*)g_asset_ptrs[59])
|
||||||
#define kMap32ToMap16_0_SIZE (g_asset_sizes[60])
|
#define kDungeonSpriteOffs_SIZE (g_asset_sizes[59])
|
||||||
#define kMap32ToMap16_1 ((uint8*)g_asset_ptrs[61])
|
#define kMap32ToMap16_0 ((uint8*)g_asset_ptrs[60])
|
||||||
#define kMap32ToMap16_1_SIZE (g_asset_sizes[61])
|
#define kMap32ToMap16_0_SIZE (g_asset_sizes[60])
|
||||||
#define kMap32ToMap16_2 ((uint8*)g_asset_ptrs[62])
|
#define kMap32ToMap16_1 ((uint8*)g_asset_ptrs[61])
|
||||||
#define kMap32ToMap16_2_SIZE (g_asset_sizes[62])
|
#define kMap32ToMap16_1_SIZE (g_asset_sizes[61])
|
||||||
#define kMap32ToMap16_3 ((uint8*)g_asset_ptrs[63])
|
#define kMap32ToMap16_2 ((uint8*)g_asset_ptrs[62])
|
||||||
#define kMap32ToMap16_3_SIZE (g_asset_sizes[63])
|
#define kMap32ToMap16_2_SIZE (g_asset_sizes[62])
|
||||||
#define kDialogueOffs ((uint16*)g_asset_ptrs[64])
|
#define kMap32ToMap16_3 ((uint8*)g_asset_ptrs[63])
|
||||||
#define kDialogueOffs_SIZE (g_asset_sizes[64])
|
#define kMap32ToMap16_3_SIZE (g_asset_sizes[63])
|
||||||
#define kDialogueText ((uint8*)g_asset_ptrs[65])
|
#define kSprGfx(idx) FindInAssetArray(64, idx)
|
||||||
#define kDialogueText_SIZE (g_asset_sizes[65])
|
#define kBgGfx(idx) FindInAssetArray(65, idx)
|
||||||
#define kSprGfx ((uint8*)g_asset_ptrs[66])
|
#define kOverworldMapGfx ((uint8*)g_asset_ptrs[66])
|
||||||
#define kSprGfx_SIZE (g_asset_sizes[66])
|
#define kOverworldMapGfx_SIZE (g_asset_sizes[66])
|
||||||
#define kBgGfx ((uint8*)g_asset_ptrs[67])
|
#define kLightOverworldTilemap ((uint8*)g_asset_ptrs[67])
|
||||||
#define kBgGfx_SIZE (g_asset_sizes[67])
|
#define kLightOverworldTilemap_SIZE (g_asset_sizes[67])
|
||||||
#define kOverworldMapGfx ((uint8*)g_asset_ptrs[68])
|
#define kDarkOverworldTilemap ((uint8*)g_asset_ptrs[68])
|
||||||
#define kOverworldMapGfx_SIZE (g_asset_sizes[68])
|
#define kDarkOverworldTilemap_SIZE (g_asset_sizes[68])
|
||||||
#define kLightOverworldTilemap ((uint8*)g_asset_ptrs[69])
|
#define kPredefinedTileData ((uint16*)g_asset_ptrs[69])
|
||||||
#define kLightOverworldTilemap_SIZE (g_asset_sizes[69])
|
#define kPredefinedTileData_SIZE (g_asset_sizes[69])
|
||||||
#define kDarkOverworldTilemap ((uint8*)g_asset_ptrs[70])
|
#define kMap16ToMap8 ((uint16*)g_asset_ptrs[70])
|
||||||
#define kDarkOverworldTilemap_SIZE (g_asset_sizes[70])
|
#define kMap16ToMap8_SIZE (g_asset_sizes[70])
|
||||||
#define kPredefinedTileData ((uint16*)g_asset_ptrs[71])
|
#define kGeneratedWishPondItem ((uint8*)g_asset_ptrs[71])
|
||||||
#define kPredefinedTileData_SIZE (g_asset_sizes[71])
|
#define kGeneratedWishPondItem_SIZE (g_asset_sizes[71])
|
||||||
#define kFontData ((uint16*)g_asset_ptrs[72])
|
#define kGeneratedBombosArr ((uint8*)g_asset_ptrs[72])
|
||||||
#define kFontData_SIZE (g_asset_sizes[72])
|
#define kGeneratedBombosArr_SIZE (g_asset_sizes[72])
|
||||||
#define kMap16ToMap8 ((uint16*)g_asset_ptrs[73])
|
#define kGeneratedEndSequence15 ((uint8*)g_asset_ptrs[73])
|
||||||
#define kMap16ToMap8_SIZE (g_asset_sizes[73])
|
#define kGeneratedEndSequence15_SIZE (g_asset_sizes[73])
|
||||||
#define kGeneratedWishPondItem ((uint8*)g_asset_ptrs[74])
|
#define kEnding_Credits_Text ((uint8*)g_asset_ptrs[74])
|
||||||
#define kGeneratedWishPondItem_SIZE (g_asset_sizes[74])
|
#define kEnding_Credits_Text_SIZE (g_asset_sizes[74])
|
||||||
#define kGeneratedBombosArr ((uint8*)g_asset_ptrs[75])
|
#define kEnding_Credits_Offs ((uint16*)g_asset_ptrs[75])
|
||||||
#define kGeneratedBombosArr_SIZE (g_asset_sizes[75])
|
#define kEnding_Credits_Offs_SIZE (g_asset_sizes[75])
|
||||||
#define kGeneratedEndSequence15 ((uint8*)g_asset_ptrs[76])
|
#define kEnding_MapData ((uint16*)g_asset_ptrs[76])
|
||||||
#define kGeneratedEndSequence15_SIZE (g_asset_sizes[76])
|
#define kEnding_MapData_SIZE (g_asset_sizes[76])
|
||||||
#define kEnding_Credits_Text ((uint8*)g_asset_ptrs[77])
|
#define kEnding0_Offs ((uint16*)g_asset_ptrs[77])
|
||||||
#define kEnding_Credits_Text_SIZE (g_asset_sizes[77])
|
#define kEnding0_Offs_SIZE (g_asset_sizes[77])
|
||||||
#define kEnding_Credits_Offs ((uint16*)g_asset_ptrs[78])
|
#define kEnding0_Data ((uint8*)g_asset_ptrs[78])
|
||||||
#define kEnding_Credits_Offs_SIZE (g_asset_sizes[78])
|
#define kEnding0_Data_SIZE (g_asset_sizes[78])
|
||||||
#define kEnding_MapData ((uint16*)g_asset_ptrs[79])
|
#define kPalette_DungBgMain ((uint16*)g_asset_ptrs[79])
|
||||||
#define kEnding_MapData_SIZE (g_asset_sizes[79])
|
#define kPalette_DungBgMain_SIZE (g_asset_sizes[79])
|
||||||
#define kEnding0_Offs ((uint16*)g_asset_ptrs[80])
|
#define kPalette_MainSpr ((uint16*)g_asset_ptrs[80])
|
||||||
#define kEnding0_Offs_SIZE (g_asset_sizes[80])
|
#define kPalette_MainSpr_SIZE (g_asset_sizes[80])
|
||||||
#define kEnding0_Data ((uint8*)g_asset_ptrs[81])
|
#define kPalette_ArmorAndGloves ((uint16*)g_asset_ptrs[81])
|
||||||
#define kEnding0_Data_SIZE (g_asset_sizes[81])
|
#define kPalette_ArmorAndGloves_SIZE (g_asset_sizes[81])
|
||||||
#define kPalette_DungBgMain ((uint16*)g_asset_ptrs[82])
|
#define kPalette_Sword ((uint16*)g_asset_ptrs[82])
|
||||||
#define kPalette_DungBgMain_SIZE (g_asset_sizes[82])
|
#define kPalette_Sword_SIZE (g_asset_sizes[82])
|
||||||
#define kPalette_MainSpr ((uint16*)g_asset_ptrs[83])
|
#define kPalette_Shield ((uint16*)g_asset_ptrs[83])
|
||||||
#define kPalette_MainSpr_SIZE (g_asset_sizes[83])
|
#define kPalette_Shield_SIZE (g_asset_sizes[83])
|
||||||
#define kPalette_ArmorAndGloves ((uint16*)g_asset_ptrs[84])
|
#define kPalette_SpriteAux3 ((uint16*)g_asset_ptrs[84])
|
||||||
#define kPalette_ArmorAndGloves_SIZE (g_asset_sizes[84])
|
#define kPalette_SpriteAux3_SIZE (g_asset_sizes[84])
|
||||||
#define kPalette_Sword ((uint16*)g_asset_ptrs[85])
|
#define kPalette_MiscSprite_Indoors ((uint16*)g_asset_ptrs[85])
|
||||||
#define kPalette_Sword_SIZE (g_asset_sizes[85])
|
#define kPalette_MiscSprite_Indoors_SIZE (g_asset_sizes[85])
|
||||||
#define kPalette_Shield ((uint16*)g_asset_ptrs[86])
|
#define kPalette_SpriteAux1 ((uint16*)g_asset_ptrs[86])
|
||||||
#define kPalette_Shield_SIZE (g_asset_sizes[86])
|
#define kPalette_SpriteAux1_SIZE (g_asset_sizes[86])
|
||||||
#define kPalette_SpriteAux3 ((uint16*)g_asset_ptrs[87])
|
#define kPalette_OverworldBgMain ((uint16*)g_asset_ptrs[87])
|
||||||
#define kPalette_SpriteAux3_SIZE (g_asset_sizes[87])
|
#define kPalette_OverworldBgMain_SIZE (g_asset_sizes[87])
|
||||||
#define kPalette_MiscSprite_Indoors ((uint16*)g_asset_ptrs[88])
|
#define kPalette_OverworldBgAux12 ((uint16*)g_asset_ptrs[88])
|
||||||
#define kPalette_MiscSprite_Indoors_SIZE (g_asset_sizes[88])
|
#define kPalette_OverworldBgAux12_SIZE (g_asset_sizes[88])
|
||||||
#define kPalette_SpriteAux1 ((uint16*)g_asset_ptrs[89])
|
#define kPalette_OverworldBgAux3 ((uint16*)g_asset_ptrs[89])
|
||||||
#define kPalette_SpriteAux1_SIZE (g_asset_sizes[89])
|
#define kPalette_OverworldBgAux3_SIZE (g_asset_sizes[89])
|
||||||
#define kPalette_OverworldBgMain ((uint16*)g_asset_ptrs[90])
|
#define kPalette_PalaceMapBg ((uint16*)g_asset_ptrs[90])
|
||||||
#define kPalette_OverworldBgMain_SIZE (g_asset_sizes[90])
|
#define kPalette_PalaceMapBg_SIZE (g_asset_sizes[90])
|
||||||
#define kPalette_OverworldBgAux12 ((uint16*)g_asset_ptrs[91])
|
#define kPalette_PalaceMapSpr ((uint16*)g_asset_ptrs[91])
|
||||||
#define kPalette_OverworldBgAux12_SIZE (g_asset_sizes[91])
|
#define kPalette_PalaceMapSpr_SIZE (g_asset_sizes[91])
|
||||||
#define kPalette_OverworldBgAux3 ((uint16*)g_asset_ptrs[92])
|
#define kHudPalData ((uint16*)g_asset_ptrs[92])
|
||||||
#define kPalette_OverworldBgAux3_SIZE (g_asset_sizes[92])
|
#define kHudPalData_SIZE (g_asset_sizes[92])
|
||||||
#define kPalette_PalaceMapBg ((uint16*)g_asset_ptrs[93])
|
#define kOverworldMapPaletteData ((uint16*)g_asset_ptrs[93])
|
||||||
#define kPalette_PalaceMapBg_SIZE (g_asset_sizes[93])
|
#define kOverworldMapPaletteData_SIZE (g_asset_sizes[93])
|
||||||
#define kPalette_PalaceMapSpr ((uint16*)g_asset_ptrs[94])
|
#define kDialogue(idx) FindInAssetArray(94, idx)
|
||||||
#define kPalette_PalaceMapSpr_SIZE (g_asset_sizes[94])
|
#define kDialogueFont(idx) FindInAssetArray(95, idx)
|
||||||
#define kHudPalData ((uint16*)g_asset_ptrs[95])
|
#define kDialogueMap(idx) FindInAssetArray(96, idx)
|
||||||
#define kHudPalData_SIZE (g_asset_sizes[95])
|
#define kDungMap_FloorLayout(idx) FindInAssetArray(97, idx)
|
||||||
#define kOverworldMapPaletteData ((uint16*)g_asset_ptrs[96])
|
#define kDungMap_Tiles(idx) FindInAssetArray(98, idx)
|
||||||
#define kOverworldMapPaletteData_SIZE (g_asset_sizes[96])
|
#define kBgTilemap_0 ((uint8*)g_asset_ptrs[99])
|
||||||
#define kDungMap_FloorLayout ((uint8*)g_asset_ptrs[97])
|
#define kBgTilemap_0_SIZE (g_asset_sizes[99])
|
||||||
#define kDungMap_FloorLayout_SIZE (g_asset_sizes[97])
|
#define kBgTilemap_1 ((uint8*)g_asset_ptrs[100])
|
||||||
#define kDungMap_Tiles ((uint8*)g_asset_ptrs[98])
|
#define kBgTilemap_1_SIZE (g_asset_sizes[100])
|
||||||
#define kDungMap_Tiles_SIZE (g_asset_sizes[98])
|
#define kBgTilemap_2 ((uint8*)g_asset_ptrs[101])
|
||||||
#define kBgTilemap_0 ((uint8*)g_asset_ptrs[99])
|
#define kBgTilemap_2_SIZE (g_asset_sizes[101])
|
||||||
#define kBgTilemap_0_SIZE (g_asset_sizes[99])
|
#define kBgTilemap_3 ((uint8*)g_asset_ptrs[102])
|
||||||
#define kBgTilemap_1 ((uint8*)g_asset_ptrs[100])
|
#define kBgTilemap_3_SIZE (g_asset_sizes[102])
|
||||||
#define kBgTilemap_1_SIZE (g_asset_sizes[100])
|
#define kBgTilemap_4 ((uint8*)g_asset_ptrs[103])
|
||||||
#define kBgTilemap_2 ((uint8*)g_asset_ptrs[101])
|
#define kBgTilemap_4_SIZE (g_asset_sizes[103])
|
||||||
#define kBgTilemap_2_SIZE (g_asset_sizes[101])
|
#define kBgTilemap_5 ((uint8*)g_asset_ptrs[104])
|
||||||
#define kBgTilemap_3 ((uint8*)g_asset_ptrs[102])
|
#define kBgTilemap_5_SIZE (g_asset_sizes[104])
|
||||||
#define kBgTilemap_3_SIZE (g_asset_sizes[102])
|
#define kOverworld_Hibytes_Comp(idx) FindInAssetArray(105, idx)
|
||||||
#define kBgTilemap_4 ((uint8*)g_asset_ptrs[103])
|
#define kOverworld_Lobytes_Comp(idx) FindInAssetArray(106, idx)
|
||||||
#define kBgTilemap_4_SIZE (g_asset_sizes[103])
|
#define kOverworldMapIsSmall ((uint8*)g_asset_ptrs[107])
|
||||||
#define kBgTilemap_5 ((uint8*)g_asset_ptrs[104])
|
#define kOverworldMapIsSmall_SIZE (g_asset_sizes[107])
|
||||||
#define kBgTilemap_5_SIZE (g_asset_sizes[104])
|
#define kOverworldAuxTileThemeIndexes ((uint8*)g_asset_ptrs[108])
|
||||||
#define kOverworld_Hibytes_Comp ((uint8*)g_asset_ptrs[105])
|
#define kOverworldAuxTileThemeIndexes_SIZE (g_asset_sizes[108])
|
||||||
#define kOverworld_Hibytes_Comp_SIZE (g_asset_sizes[105])
|
#define kOverworldBgPalettes ((uint8*)g_asset_ptrs[109])
|
||||||
#define kOverworld_Lobytes_Comp ((uint8*)g_asset_ptrs[106])
|
#define kOverworldBgPalettes_SIZE (g_asset_sizes[109])
|
||||||
#define kOverworld_Lobytes_Comp_SIZE (g_asset_sizes[106])
|
#define kOverworld_SignText ((uint16*)g_asset_ptrs[110])
|
||||||
#define kOverworldMapIsSmall ((uint8*)g_asset_ptrs[107])
|
#define kOverworld_SignText_SIZE (g_asset_sizes[110])
|
||||||
#define kOverworldMapIsSmall_SIZE (g_asset_sizes[107])
|
#define kOwMusicSets ((uint8*)g_asset_ptrs[111])
|
||||||
#define kOverworldAuxTileThemeIndexes ((uint8*)g_asset_ptrs[108])
|
#define kOwMusicSets_SIZE (g_asset_sizes[111])
|
||||||
#define kOverworldAuxTileThemeIndexes_SIZE (g_asset_sizes[108])
|
#define kOwMusicSets2 ((uint8*)g_asset_ptrs[112])
|
||||||
#define kOverworldBgPalettes ((uint8*)g_asset_ptrs[109])
|
#define kOwMusicSets2_SIZE (g_asset_sizes[112])
|
||||||
#define kOverworldBgPalettes_SIZE (g_asset_sizes[109])
|
#define kBirdTravel_ScreenIndex ((uint16*)g_asset_ptrs[113])
|
||||||
#define kOverworld_SignText ((uint16*)g_asset_ptrs[110])
|
#define kBirdTravel_ScreenIndex_SIZE (g_asset_sizes[113])
|
||||||
#define kOverworld_SignText_SIZE (g_asset_sizes[110])
|
#define kBirdTravel_Map16LoadSrcOff ((uint16*)g_asset_ptrs[114])
|
||||||
#define kOwMusicSets ((uint8*)g_asset_ptrs[111])
|
#define kBirdTravel_Map16LoadSrcOff_SIZE (g_asset_sizes[114])
|
||||||
#define kOwMusicSets_SIZE (g_asset_sizes[111])
|
#define kBirdTravel_ScrollX ((uint16*)g_asset_ptrs[115])
|
||||||
#define kOwMusicSets2 ((uint8*)g_asset_ptrs[112])
|
#define kBirdTravel_ScrollX_SIZE (g_asset_sizes[115])
|
||||||
#define kOwMusicSets2_SIZE (g_asset_sizes[112])
|
#define kBirdTravel_ScrollY ((uint16*)g_asset_ptrs[116])
|
||||||
#define kBirdTravel_ScreenIndex ((uint16*)g_asset_ptrs[113])
|
#define kBirdTravel_ScrollY_SIZE (g_asset_sizes[116])
|
||||||
#define kBirdTravel_ScreenIndex_SIZE (g_asset_sizes[113])
|
#define kBirdTravel_LinkXCoord ((uint16*)g_asset_ptrs[117])
|
||||||
#define kBirdTravel_Map16LoadSrcOff ((uint16*)g_asset_ptrs[114])
|
#define kBirdTravel_LinkXCoord_SIZE (g_asset_sizes[117])
|
||||||
#define kBirdTravel_Map16LoadSrcOff_SIZE (g_asset_sizes[114])
|
#define kBirdTravel_LinkYCoord ((uint16*)g_asset_ptrs[118])
|
||||||
#define kBirdTravel_ScrollX ((uint16*)g_asset_ptrs[115])
|
#define kBirdTravel_LinkYCoord_SIZE (g_asset_sizes[118])
|
||||||
#define kBirdTravel_ScrollX_SIZE (g_asset_sizes[115])
|
#define kBirdTravel_CameraXScroll ((uint16*)g_asset_ptrs[119])
|
||||||
#define kBirdTravel_ScrollY ((uint16*)g_asset_ptrs[116])
|
#define kBirdTravel_CameraXScroll_SIZE (g_asset_sizes[119])
|
||||||
#define kBirdTravel_ScrollY_SIZE (g_asset_sizes[116])
|
#define kBirdTravel_CameraYScroll ((uint16*)g_asset_ptrs[120])
|
||||||
#define kBirdTravel_LinkXCoord ((uint16*)g_asset_ptrs[117])
|
#define kBirdTravel_CameraYScroll_SIZE (g_asset_sizes[120])
|
||||||
#define kBirdTravel_LinkXCoord_SIZE (g_asset_sizes[117])
|
#define kBirdTravel_Unk1 ((int8*)g_asset_ptrs[121])
|
||||||
#define kBirdTravel_LinkYCoord ((uint16*)g_asset_ptrs[118])
|
#define kBirdTravel_Unk1_SIZE (g_asset_sizes[121])
|
||||||
#define kBirdTravel_LinkYCoord_SIZE (g_asset_sizes[118])
|
#define kBirdTravel_Unk3 ((int8*)g_asset_ptrs[122])
|
||||||
#define kBirdTravel_CameraXScroll ((uint16*)g_asset_ptrs[119])
|
#define kBirdTravel_Unk3_SIZE (g_asset_sizes[122])
|
||||||
#define kBirdTravel_CameraXScroll_SIZE (g_asset_sizes[119])
|
#define kWhirlpoolAreas ((uint16*)g_asset_ptrs[123])
|
||||||
#define kBirdTravel_CameraYScroll ((uint16*)g_asset_ptrs[120])
|
#define kWhirlpoolAreas_SIZE (g_asset_sizes[123])
|
||||||
#define kBirdTravel_CameraYScroll_SIZE (g_asset_sizes[120])
|
#define kOverworld_Entrance_Area ((uint16*)g_asset_ptrs[124])
|
||||||
#define kBirdTravel_Unk1 ((int8*)g_asset_ptrs[121])
|
#define kOverworld_Entrance_Area_SIZE (g_asset_sizes[124])
|
||||||
#define kBirdTravel_Unk1_SIZE (g_asset_sizes[121])
|
#define kOverworld_Entrance_Pos ((uint16*)g_asset_ptrs[125])
|
||||||
#define kBirdTravel_Unk3 ((int8*)g_asset_ptrs[122])
|
#define kOverworld_Entrance_Pos_SIZE (g_asset_sizes[125])
|
||||||
#define kBirdTravel_Unk3_SIZE (g_asset_sizes[122])
|
#define kOverworld_Entrance_Id ((uint8*)g_asset_ptrs[126])
|
||||||
#define kWhirlpoolAreas ((uint16*)g_asset_ptrs[123])
|
#define kOverworld_Entrance_Id_SIZE (g_asset_sizes[126])
|
||||||
#define kWhirlpoolAreas_SIZE (g_asset_sizes[123])
|
#define kFallHole_Area ((uint16*)g_asset_ptrs[127])
|
||||||
#define kOverworld_Entrance_Area ((uint16*)g_asset_ptrs[124])
|
#define kFallHole_Area_SIZE (g_asset_sizes[127])
|
||||||
#define kOverworld_Entrance_Area_SIZE (g_asset_sizes[124])
|
#define kFallHole_Pos ((uint16*)g_asset_ptrs[128])
|
||||||
#define kOverworld_Entrance_Pos ((uint16*)g_asset_ptrs[125])
|
#define kFallHole_Pos_SIZE (g_asset_sizes[128])
|
||||||
#define kOverworld_Entrance_Pos_SIZE (g_asset_sizes[125])
|
#define kFallHole_Entrances ((uint8*)g_asset_ptrs[129])
|
||||||
#define kOverworld_Entrance_Id ((uint8*)g_asset_ptrs[126])
|
#define kFallHole_Entrances_SIZE (g_asset_sizes[129])
|
||||||
#define kOverworld_Entrance_Id_SIZE (g_asset_sizes[126])
|
#define kExitData_ScreenIndex ((uint8*)g_asset_ptrs[130])
|
||||||
#define kFallHole_Area ((uint16*)g_asset_ptrs[127])
|
#define kExitData_ScreenIndex_SIZE (g_asset_sizes[130])
|
||||||
#define kFallHole_Area_SIZE (g_asset_sizes[127])
|
#define kExitDataRooms ((uint16*)g_asset_ptrs[131])
|
||||||
#define kFallHole_Pos ((uint16*)g_asset_ptrs[128])
|
#define kExitDataRooms_SIZE (g_asset_sizes[131])
|
||||||
#define kFallHole_Pos_SIZE (g_asset_sizes[128])
|
#define kExitData_Map16LoadSrcOff ((uint16*)g_asset_ptrs[132])
|
||||||
#define kFallHole_Entrances ((uint8*)g_asset_ptrs[129])
|
#define kExitData_Map16LoadSrcOff_SIZE (g_asset_sizes[132])
|
||||||
#define kFallHole_Entrances_SIZE (g_asset_sizes[129])
|
#define kExitData_ScrollX ((uint16*)g_asset_ptrs[133])
|
||||||
#define kExitData_ScreenIndex ((uint8*)g_asset_ptrs[130])
|
#define kExitData_ScrollX_SIZE (g_asset_sizes[133])
|
||||||
#define kExitData_ScreenIndex_SIZE (g_asset_sizes[130])
|
#define kExitData_ScrollY ((uint16*)g_asset_ptrs[134])
|
||||||
#define kExitDataRooms ((uint16*)g_asset_ptrs[131])
|
#define kExitData_ScrollY_SIZE (g_asset_sizes[134])
|
||||||
#define kExitDataRooms_SIZE (g_asset_sizes[131])
|
#define kExitData_XCoord ((uint16*)g_asset_ptrs[135])
|
||||||
#define kExitData_Map16LoadSrcOff ((uint16*)g_asset_ptrs[132])
|
#define kExitData_XCoord_SIZE (g_asset_sizes[135])
|
||||||
#define kExitData_Map16LoadSrcOff_SIZE (g_asset_sizes[132])
|
#define kExitData_YCoord ((uint16*)g_asset_ptrs[136])
|
||||||
#define kExitData_ScrollX ((uint16*)g_asset_ptrs[133])
|
#define kExitData_YCoord_SIZE (g_asset_sizes[136])
|
||||||
#define kExitData_ScrollX_SIZE (g_asset_sizes[133])
|
#define kExitData_CameraXScroll ((uint16*)g_asset_ptrs[137])
|
||||||
#define kExitData_ScrollY ((uint16*)g_asset_ptrs[134])
|
#define kExitData_CameraXScroll_SIZE (g_asset_sizes[137])
|
||||||
#define kExitData_ScrollY_SIZE (g_asset_sizes[134])
|
#define kExitData_CameraYScroll ((uint16*)g_asset_ptrs[138])
|
||||||
#define kExitData_XCoord ((uint16*)g_asset_ptrs[135])
|
#define kExitData_CameraYScroll_SIZE (g_asset_sizes[138])
|
||||||
#define kExitData_XCoord_SIZE (g_asset_sizes[135])
|
#define kExitData_NormalDoor ((uint16*)g_asset_ptrs[139])
|
||||||
#define kExitData_YCoord ((uint16*)g_asset_ptrs[136])
|
#define kExitData_NormalDoor_SIZE (g_asset_sizes[139])
|
||||||
#define kExitData_YCoord_SIZE (g_asset_sizes[136])
|
#define kExitData_FancyDoor ((uint16*)g_asset_ptrs[140])
|
||||||
#define kExitData_CameraXScroll ((uint16*)g_asset_ptrs[137])
|
#define kExitData_FancyDoor_SIZE (g_asset_sizes[140])
|
||||||
#define kExitData_CameraXScroll_SIZE (g_asset_sizes[137])
|
#define kExitData_Unk1 ((int8*)g_asset_ptrs[141])
|
||||||
#define kExitData_CameraYScroll ((uint16*)g_asset_ptrs[138])
|
#define kExitData_Unk1_SIZE (g_asset_sizes[141])
|
||||||
#define kExitData_CameraYScroll_SIZE (g_asset_sizes[138])
|
#define kExitData_Unk3 ((int8*)g_asset_ptrs[142])
|
||||||
#define kExitData_NormalDoor ((uint16*)g_asset_ptrs[139])
|
#define kExitData_Unk3_SIZE (g_asset_sizes[142])
|
||||||
#define kExitData_NormalDoor_SIZE (g_asset_sizes[139])
|
#define kSpExit_Top ((uint16*)g_asset_ptrs[143])
|
||||||
#define kExitData_FancyDoor ((uint16*)g_asset_ptrs[140])
|
#define kSpExit_Top_SIZE (g_asset_sizes[143])
|
||||||
#define kExitData_FancyDoor_SIZE (g_asset_sizes[140])
|
#define kSpExit_Bottom ((uint16*)g_asset_ptrs[144])
|
||||||
#define kExitData_Unk1 ((int8*)g_asset_ptrs[141])
|
#define kSpExit_Bottom_SIZE (g_asset_sizes[144])
|
||||||
#define kExitData_Unk1_SIZE (g_asset_sizes[141])
|
#define kSpExit_Left ((uint16*)g_asset_ptrs[145])
|
||||||
#define kExitData_Unk3 ((int8*)g_asset_ptrs[142])
|
#define kSpExit_Left_SIZE (g_asset_sizes[145])
|
||||||
#define kExitData_Unk3_SIZE (g_asset_sizes[142])
|
#define kSpExit_Right ((uint16*)g_asset_ptrs[146])
|
||||||
#define kSpExit_Top ((uint16*)g_asset_ptrs[143])
|
#define kSpExit_Right_SIZE (g_asset_sizes[146])
|
||||||
#define kSpExit_Top_SIZE (g_asset_sizes[143])
|
#define kSpExit_Tab4 ((int16*)g_asset_ptrs[147])
|
||||||
#define kSpExit_Bottom ((uint16*)g_asset_ptrs[144])
|
#define kSpExit_Tab4_SIZE (g_asset_sizes[147])
|
||||||
#define kSpExit_Bottom_SIZE (g_asset_sizes[144])
|
#define kSpExit_Tab5 ((int16*)g_asset_ptrs[148])
|
||||||
#define kSpExit_Left ((uint16*)g_asset_ptrs[145])
|
#define kSpExit_Tab5_SIZE (g_asset_sizes[148])
|
||||||
#define kSpExit_Left_SIZE (g_asset_sizes[145])
|
#define kSpExit_Tab6 ((int16*)g_asset_ptrs[149])
|
||||||
#define kSpExit_Right ((uint16*)g_asset_ptrs[146])
|
#define kSpExit_Tab6_SIZE (g_asset_sizes[149])
|
||||||
#define kSpExit_Right_SIZE (g_asset_sizes[146])
|
#define kSpExit_Tab7 ((int16*)g_asset_ptrs[150])
|
||||||
#define kSpExit_Tab4 ((int16*)g_asset_ptrs[147])
|
#define kSpExit_Tab7_SIZE (g_asset_sizes[150])
|
||||||
#define kSpExit_Tab4_SIZE (g_asset_sizes[147])
|
#define kSpExit_LeftEdgeOfMap ((uint16*)g_asset_ptrs[151])
|
||||||
#define kSpExit_Tab5 ((int16*)g_asset_ptrs[148])
|
#define kSpExit_LeftEdgeOfMap_SIZE (g_asset_sizes[151])
|
||||||
#define kSpExit_Tab5_SIZE (g_asset_sizes[148])
|
#define kSpExit_Dir ((uint8*)g_asset_ptrs[152])
|
||||||
#define kSpExit_Tab6 ((int16*)g_asset_ptrs[149])
|
#define kSpExit_Dir_SIZE (g_asset_sizes[152])
|
||||||
#define kSpExit_Tab6_SIZE (g_asset_sizes[149])
|
#define kSpExit_SprGfx ((uint8*)g_asset_ptrs[153])
|
||||||
#define kSpExit_Tab7 ((int16*)g_asset_ptrs[150])
|
#define kSpExit_SprGfx_SIZE (g_asset_sizes[153])
|
||||||
#define kSpExit_Tab7_SIZE (g_asset_sizes[150])
|
#define kSpExit_AuxGfx ((uint8*)g_asset_ptrs[154])
|
||||||
#define kSpExit_LeftEdgeOfMap ((uint16*)g_asset_ptrs[151])
|
#define kSpExit_AuxGfx_SIZE (g_asset_sizes[154])
|
||||||
#define kSpExit_LeftEdgeOfMap_SIZE (g_asset_sizes[151])
|
#define kSpExit_PalBg ((uint8*)g_asset_ptrs[155])
|
||||||
#define kSpExit_Dir ((uint8*)g_asset_ptrs[152])
|
#define kSpExit_PalBg_SIZE (g_asset_sizes[155])
|
||||||
#define kSpExit_Dir_SIZE (g_asset_sizes[152])
|
#define kSpExit_PalSpr ((uint8*)g_asset_ptrs[156])
|
||||||
#define kSpExit_SprGfx ((uint8*)g_asset_ptrs[153])
|
#define kSpExit_PalSpr_SIZE (g_asset_sizes[156])
|
||||||
#define kSpExit_SprGfx_SIZE (g_asset_sizes[153])
|
#define kOverworldSecrets_Offs ((uint16*)g_asset_ptrs[157])
|
||||||
#define kSpExit_AuxGfx ((uint8*)g_asset_ptrs[154])
|
#define kOverworldSecrets_Offs_SIZE (g_asset_sizes[157])
|
||||||
#define kSpExit_AuxGfx_SIZE (g_asset_sizes[154])
|
#define kOverworldSecrets ((uint8*)g_asset_ptrs[158])
|
||||||
#define kSpExit_PalBg ((uint8*)g_asset_ptrs[155])
|
#define kOverworldSecrets_SIZE (g_asset_sizes[158])
|
||||||
#define kSpExit_PalBg_SIZE (g_asset_sizes[155])
|
#define kOverworldSpriteOffs ((uint16*)g_asset_ptrs[159])
|
||||||
#define kSpExit_PalSpr ((uint8*)g_asset_ptrs[156])
|
#define kOverworldSpriteOffs_SIZE (g_asset_sizes[159])
|
||||||
#define kSpExit_PalSpr_SIZE (g_asset_sizes[156])
|
#define kOverworldSprites ((uint8*)g_asset_ptrs[160])
|
||||||
#define kOverworldSecrets_Offs ((uint16*)g_asset_ptrs[157])
|
#define kOverworldSprites_SIZE (g_asset_sizes[160])
|
||||||
#define kOverworldSecrets_Offs_SIZE (g_asset_sizes[157])
|
#define kOverworldSpriteGfx ((uint8*)g_asset_ptrs[161])
|
||||||
#define kOverworldSecrets ((uint8*)g_asset_ptrs[158])
|
#define kOverworldSpriteGfx_SIZE (g_asset_sizes[161])
|
||||||
#define kOverworldSecrets_SIZE (g_asset_sizes[158])
|
#define kOverworldSpritePalettes ((uint8*)g_asset_ptrs[162])
|
||||||
#define kOverworldSpriteOffs ((uint16*)g_asset_ptrs[159])
|
#define kOverworldSpritePalettes_SIZE (g_asset_sizes[162])
|
||||||
#define kOverworldSpriteOffs_SIZE (g_asset_sizes[159])
|
#define kMap8DataToTileAttr ((uint8*)g_asset_ptrs[163])
|
||||||
#define kOverworldSprites ((uint8*)g_asset_ptrs[160])
|
#define kMap8DataToTileAttr_SIZE (g_asset_sizes[163])
|
||||||
#define kOverworldSprites_SIZE (g_asset_sizes[160])
|
#define kSomeTileAttr ((uint8*)g_asset_ptrs[164])
|
||||||
#define kOverworldSpriteGfx ((uint8*)g_asset_ptrs[161])
|
#define kSomeTileAttr_SIZE (g_asset_sizes[164])
|
||||||
#define kOverworldSpriteGfx_SIZE (g_asset_sizes[161])
|
#define kAssets_Sig 90, 101, 108, 100, 97, 51, 95, 118, 48, 32, 32, 32, 32, 32, 10, 0, 27, 174, 233, 45, 74, 174, 252, 50, 49, 27, 153, 197, 27, 43, 216, 197, 132, 101, 173, 169, 36, 108, 15, 155, 176, 169, 57, 131, 174, 101, 51, 207
|
||||||
#define kOverworldSpritePalettes ((uint8*)g_asset_ptrs[162])
|
|
||||||
#define kOverworldSpritePalettes_SIZE (g_asset_sizes[162])
|
|
||||||
#define kMap8DataToTileAttr ((uint8*)g_asset_ptrs[163])
|
|
||||||
#define kMap8DataToTileAttr_SIZE (g_asset_sizes[163])
|
|
||||||
#define kSomeTileAttr ((uint8*)g_asset_ptrs[164])
|
|
||||||
#define kSomeTileAttr_SIZE (g_asset_sizes[164])
|
|
||||||
#define kAssets_Sig 90, 101, 108, 100, 97, 51, 95, 118, 48, 32, 32, 32, 32, 32, 10, 0, 140, 60, 238, 107, 183, 109, 113, 156, 115, 98, 147, 236, 79, 160, 95, 71, 26, 185, 82, 158, 43, 82, 22, 60, 62, 92, 250, 152, 23, 230, 97, 235
|
|
||||||
|
|||||||
3
config.c
3
config.c
@@ -442,6 +442,9 @@ static bool HandleIniConfig(int section, const char *key, char *value) {
|
|||||||
return ParseBool(value, &g_config.display_perf_title);
|
return ParseBool(value, &g_config.display_perf_title);
|
||||||
} else if (StringEqualsNoCase(key, "DisableFrameDelay")) {
|
} else if (StringEqualsNoCase(key, "DisableFrameDelay")) {
|
||||||
return ParseBool(value, &g_config.disable_frame_delay);
|
return ParseBool(value, &g_config.disable_frame_delay);
|
||||||
|
} else if (StringEqualsNoCase(key, "Language")) {
|
||||||
|
g_config.language = value;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
} else if (section == 4) {
|
} else if (section == 4) {
|
||||||
if (StringEqualsNoCase(key, "ItemSwitchLR")) {
|
if (StringEqualsNoCase(key, "ItemSwitchLR")) {
|
||||||
|
|||||||
1
config.h
1
config.h
@@ -73,6 +73,7 @@ typedef struct Config {
|
|||||||
char *memory_buffer;
|
char *memory_buffer;
|
||||||
const char *shader;
|
const char *shader;
|
||||||
const char *msu_path;
|
const char *msu_path;
|
||||||
|
const char *language;
|
||||||
} Config;
|
} Config;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|||||||
14
load_gfx.c
14
load_gfx.c
@@ -325,7 +325,7 @@ static const int8 kGraphicsLoadSp6[20] = {
|
|||||||
static const uint8 kMirrorWarp_LoadNext_NmiLoad[15] = {0, 14, 15, 16, 17, 0, 0, 0, 0, 0, 0, 18, 19, 20, 0};
|
static const uint8 kMirrorWarp_LoadNext_NmiLoad[15] = {0, 14, 15, 16, 17, 0, 0, 0, 0, 0, 0, 18, 19, 20, 0};
|
||||||
|
|
||||||
static const uint8 *GetCompSpritePtr(int i) {
|
static const uint8 *GetCompSpritePtr(int i) {
|
||||||
return kSprGfx + *(uint32 *)(kSprGfx + i * 4);
|
return kSprGfx(i).ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplyPaletteFilter_bounce() {
|
void ApplyPaletteFilter_bounce() {
|
||||||
@@ -932,7 +932,7 @@ void Graphics_LoadChrHalfSlot() { // 80e3fa
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TransferFontToVRAM() { // 80e556
|
void TransferFontToVRAM() { // 80e556
|
||||||
memcpy(&g_zenv.vram[0x7000], kFontData, 0x800 * sizeof(uint16));
|
memcpy(&g_zenv.vram[0x7000], FindIndexInMemblk(kDialogueFont(0), 0).ptr, 0x800 * sizeof(uint16));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Do3To4High(uint16 *vram_ptr, const uint8 *decomp_addr) { // 80e5af
|
void Do3To4High(uint16 *vram_ptr, const uint8 *decomp_addr) { // 80e5af
|
||||||
@@ -991,17 +991,17 @@ void LoadCommonSprites() { // 80e6b7
|
|||||||
int Decomp_spr(uint8 *dst, int gfx) { // 80e772
|
int Decomp_spr(uint8 *dst, int gfx) { // 80e772
|
||||||
if (gfx < 12)
|
if (gfx < 12)
|
||||||
gfx = 12; // ensure it wont decode bad sheets.
|
gfx = 12; // ensure it wont decode bad sheets.
|
||||||
|
MemBlk blk = kSprGfx(gfx);
|
||||||
const uint8 *sprite_data = GetCompSpritePtr(gfx);
|
const uint8 *sprite_data = GetCompSpritePtr(gfx);
|
||||||
// If the size is not 0x600 then it's compressed
|
// If the size is not 0x600 then it's compressed
|
||||||
if (gfx >= 103 || (((uint32 *)kSprGfx)[gfx + 1] - ((uint32 *)kSprGfx)[gfx]) != 0x600)
|
if (gfx >= 103 || blk.size != 0x600)
|
||||||
return Decompress(dst, sprite_data);
|
return Decompress(dst, blk.ptr);
|
||||||
memcpy(dst, sprite_data, 0x600);
|
memcpy(dst, blk.ptr, 0x600);
|
||||||
return 0x600;
|
return 0x600;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Decomp_bg(uint8 *dst, int gfx) { // 80e78f
|
int Decomp_bg(uint8 *dst, int gfx) { // 80e78f
|
||||||
const uint8 *p = kBgGfx + *(uint32 *)(kBgGfx + gfx * 4);
|
return Decompress(dst, kBgGfx(gfx).ptr);
|
||||||
return Decompress(dst, p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int Decompress(uint8 *dst, const uint8 *src) { // 80e79e
|
int Decompress(uint8 *dst, const uint8 *src) { // 80e79e
|
||||||
|
|||||||
5
main.c
5
main.c
@@ -304,6 +304,7 @@ int main(int argc, char** argv) {
|
|||||||
g_config.extend_y * kPpuRenderFlags_Height240 |
|
g_config.extend_y * kPpuRenderFlags_Height240 |
|
||||||
g_config.no_sprite_limits * kPpuRenderFlags_NoSpriteLimits;
|
g_config.no_sprite_limits * kPpuRenderFlags_NoSpriteLimits;
|
||||||
ZeldaEnableMsu(g_config.enable_msu);
|
ZeldaEnableMsu(g_config.enable_msu);
|
||||||
|
ZeldaSetLanguage(g_config.language);
|
||||||
|
|
||||||
if (g_config.fullscreen == 1)
|
if (g_config.fullscreen == 1)
|
||||||
g_win_flags ^= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
g_win_flags ^= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||||
@@ -865,3 +866,7 @@ static void SwitchDirectory() {
|
|||||||
pos--;
|
pos--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MemBlk FindInAssetArray(int asset, int idx) {
|
||||||
|
return FindIndexInMemblk((MemBlk) { g_asset_ptrs[asset], g_asset_sizes[asset] }, idx);
|
||||||
|
}
|
||||||
|
|||||||
564
messaging.c
564
messaging.c
@@ -101,108 +101,6 @@ static PlayerHandlerFunc *const kDungMapSubmodules[] = {
|
|||||||
};
|
};
|
||||||
static const uint16 kText_Positions[2] = {0x6125, 0x6244};
|
static const uint16 kText_Positions[2] = {0x6125, 0x6244};
|
||||||
static const uint16 kSrmOffsets[4] = {0, 0x500, 0xa00, 0xf00};
|
static const uint16 kSrmOffsets[4] = {0, 0x500, 0xa00, 0xf00};
|
||||||
static const uint8 kTextDictionary[] = {
|
|
||||||
0x59, 0x59, 0x59, 0x59,
|
|
||||||
0x59, 0x59, 0x59,
|
|
||||||
0x59, 0x59,
|
|
||||||
0x51, 0x2c, 0x59,
|
|
||||||
0x1a, 0x27, 0x1d, 0x59,
|
|
||||||
0x1a, 0x2b, 0x1e, 0x59,
|
|
||||||
0x1a, 0x25, 0x25, 0x59,
|
|
||||||
0x1a, 0x22, 0x27,
|
|
||||||
0x1a, 0x27, 0x1d,
|
|
||||||
0x1a, 0x2d, 0x59,
|
|
||||||
0x1a, 0x2c, 0x2d,
|
|
||||||
0x1a, 0x27,
|
|
||||||
0x1a, 0x2d,
|
|
||||||
0x1b, 0x25, 0x1e,
|
|
||||||
0x1b, 0x1a,
|
|
||||||
0x1b, 0x1e,
|
|
||||||
0x1b, 0x28,
|
|
||||||
0x1c, 0x1a, 0x27, 0x59,
|
|
||||||
0x1c, 0x21, 0x1e,
|
|
||||||
0x1c, 0x28, 0x26,
|
|
||||||
0x1c, 0x24,
|
|
||||||
0x1d, 0x1e, 0x2c,
|
|
||||||
0x1d, 0x22,
|
|
||||||
0x1d, 0x28,
|
|
||||||
0x1e, 0x27, 0x59,
|
|
||||||
0x1e, 0x2b, 0x59,
|
|
||||||
0x1e, 0x1a, 0x2b,
|
|
||||||
0x1e, 0x27, 0x2d,
|
|
||||||
0x1e, 0x1d, 0x59,
|
|
||||||
0x1e, 0x27,
|
|
||||||
0x1e, 0x2b,
|
|
||||||
0x1e, 0x2f,
|
|
||||||
0x1f, 0x28, 0x2b,
|
|
||||||
0x1f, 0x2b, 0x28,
|
|
||||||
0x20, 0x22, 0x2f, 0x1e, 0x59,
|
|
||||||
0x20, 0x1e, 0x2d,
|
|
||||||
0x20, 0x28,
|
|
||||||
0x21, 0x1a, 0x2f, 0x1e,
|
|
||||||
0x21, 0x1a, 0x2c,
|
|
||||||
0x21, 0x1e, 0x2b,
|
|
||||||
0x21, 0x22,
|
|
||||||
0x21, 0x1a,
|
|
||||||
0x22, 0x20, 0x21, 0x2d, 0x59,
|
|
||||||
0x22, 0x27, 0x20, 0x59,
|
|
||||||
0x22, 0x27,
|
|
||||||
0x22, 0x2c,
|
|
||||||
0x22, 0x2d,
|
|
||||||
0x23, 0x2e, 0x2c, 0x2d,
|
|
||||||
0x24, 0x27, 0x28, 0x30,
|
|
||||||
0x25, 0x32, 0x59,
|
|
||||||
0x25, 0x1a,
|
|
||||||
0x25, 0x28,
|
|
||||||
0x26, 0x1a, 0x27,
|
|
||||||
0x26, 0x1a,
|
|
||||||
0x26, 0x1e,
|
|
||||||
0x26, 0x2e,
|
|
||||||
0x27, 0x51, 0x2d, 0x59,
|
|
||||||
0x27, 0x28, 0x27,
|
|
||||||
0x27, 0x28, 0x2d,
|
|
||||||
0x28, 0x29, 0x1e, 0x27,
|
|
||||||
0x28, 0x2e, 0x27, 0x1d,
|
|
||||||
0x28, 0x2e, 0x2d, 0x59,
|
|
||||||
0x28, 0x1f,
|
|
||||||
0x28, 0x27,
|
|
||||||
0x28, 0x2b,
|
|
||||||
0x29, 0x1e, 0x2b,
|
|
||||||
0x29, 0x25, 0x1e,
|
|
||||||
0x29, 0x28, 0x30,
|
|
||||||
0x29, 0x2b, 0x28,
|
|
||||||
0x2b, 0x1e, 0x59,
|
|
||||||
0x2b, 0x1e,
|
|
||||||
0x2c, 0x28, 0x26, 0x1e,
|
|
||||||
0x2c, 0x1e,
|
|
||||||
0x2c, 0x21,
|
|
||||||
0x2c, 0x28,
|
|
||||||
0x2c, 0x2d,
|
|
||||||
0x2d, 0x1e, 0x2b, 0x59,
|
|
||||||
0x2d, 0x21, 0x22, 0x27,
|
|
||||||
0x2d, 0x1e, 0x2b,
|
|
||||||
0x2d, 0x21, 0x1a,
|
|
||||||
0x2d, 0x21, 0x1e,
|
|
||||||
0x2d, 0x21, 0x22,
|
|
||||||
0x2d, 0x28,
|
|
||||||
0x2d, 0x2b,
|
|
||||||
0x2e, 0x29,
|
|
||||||
0x2f, 0x1e, 0x2b,
|
|
||||||
0x30, 0x22, 0x2d, 0x21,
|
|
||||||
0x30, 0x1a,
|
|
||||||
0x30, 0x1e,
|
|
||||||
0x30, 0x21,
|
|
||||||
0x30, 0x22,
|
|
||||||
0x32, 0x28, 0x2e,
|
|
||||||
0x7, 0x1e, 0x2b,
|
|
||||||
0x13, 0x21, 0x1a,
|
|
||||||
0x13, 0x21, 0x1e,
|
|
||||||
0x13, 0x21, 0x22,
|
|
||||||
0x18, 0x28, 0x2e,
|
|
||||||
};
|
|
||||||
static const uint16 kTextDictionary_Idx[] = {
|
|
||||||
0, 4, 7, 9, 12, 16, 20, 24, 27, 30, 33, 36, 38, 40, 43, 45, 47, 49, 53, 56, 59, 61, 64, 66, 68, 71, 74, 77, 80, 83, 85, 87, 89, 92, 95, 100, 103, 105, 109, 112, 115, 117, 119, 124, 128, 130, 132, 134, 138, 142, 145, 147, 149, 152, 154, 156, 158, 162, 165, 168, 172, 176, 180, 182, 184, 186, 189, 192, 195, 198, 201, 203, 207, 209, 211, 213, 215, 219, 223, 226, 229, 232, 235, 237, 239, 241, 244, 248, 250, 252, 254, 256, 259, 262, 265, 268, 271, 274
|
|
||||||
};
|
|
||||||
static const int8 kText_InitializationData[32] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0x39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1c, 4, 0, 0, 0, 0, 0};
|
static const int8 kText_InitializationData[32] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0x39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x1c, 4, 0, 0, 0, 0, 0};
|
||||||
static const uint16 kText_BorderTiles[9] = {0x28f3, 0x28f4, 0x68f3, 0x28c8, 0x387f, 0x68c8, 0xa8f3, 0xa8f4, 0xe8f3};
|
static const uint16 kText_BorderTiles[9] = {0x28f3, 0x28f4, 0x68f3, 0x28c8, 0x387f, 0x68c8, 0xa8f3, 0xa8f4, 0xe8f3};
|
||||||
static const uint8 kText_CommandLengths[25] = {
|
static const uint8 kText_CommandLengths[25] = {
|
||||||
@@ -212,16 +110,7 @@ static const uint8 kText_CommandLengths[25] = {
|
|||||||
static const uint8 kVWF_RenderCharacter_setMasks[8] = {0x80, 0x40, 0x20, 0x10, 8, 4, 2, 1};
|
static const uint8 kVWF_RenderCharacter_setMasks[8] = {0x80, 0x40, 0x20, 0x10, 8, 4, 2, 1};
|
||||||
static const uint16 kVWF_RenderCharacter_renderPos[3] = {0, 0x2a0, 0x540};
|
static const uint16 kVWF_RenderCharacter_renderPos[3] = {0, 0x2a0, 0x540};
|
||||||
static const uint16 kVWF_RenderCharacter_linePositions[3] = {0, 0x40, 0x80};
|
static const uint16 kVWF_RenderCharacter_linePositions[3] = {0, 0x40, 0x80};
|
||||||
static const uint8 kVWF_RenderCharacter_widths[99] = {
|
|
||||||
6, 6, 6, 6, 6, 6, 6, 6, 3, 6, 6, 6, 7, 6, 6, 6, 6, 6, 6, 7, 6, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6,
|
|
||||||
6, 6, 3, 5, 6, 3, 7, 6, 6, 6, 6, 5, 6, 6, 6, 7, 7, 7, 7, 6, 6, 4, 6, 6, 6, 6, 6, 6, 6, 6, 3, 7,
|
|
||||||
6, 4, 4, 6, 8, 6, 6, 6, 6, 6, 8, 8, 8, 7, 7, 7, 7, 4, 8, 8, 8, 8, 8, 8, 8, 4, 8, 8, 8, 8, 8, 8,
|
|
||||||
8, 8, 4,
|
|
||||||
};
|
|
||||||
static const uint16 kVWF_RowPositions[3] = {0, 2, 4};
|
static const uint16 kVWF_RowPositions[3] = {0, 2, 4};
|
||||||
static const uint16 kVWF_LinePositions[3] = {0, 40, 80};
|
|
||||||
static const uint16 kVWF_Command7B[4] = {0x24b8, 0x24ba, 0x24bc, 0x24be};
|
|
||||||
static const uint16 kVWF_Command7C[8] = {0x24b8, 0x24ba, 0x24bc, 0x24be, 0x24b8, 0x24ba, 0x24bc, 0x24be};
|
|
||||||
static const uint16 kText_WaitDurations[16] = {31, 63, 94, 125, 156, 188, 219, 250, 281, 313, 344, 375, 406, 438, 469, 500};
|
static const uint16 kText_WaitDurations[16] = {31, 63, 94, 125, 156, 188, 219, 250, 281, 313, 344, 375, 406, 438, 469, 500};
|
||||||
static PlayerHandlerFunc *const kText_Render[] = {
|
static PlayerHandlerFunc *const kText_Render[] = {
|
||||||
&RenderText_Draw_Border,
|
&RenderText_Draw_Border,
|
||||||
@@ -336,11 +225,11 @@ static PlayerHandlerFunc *const kModule_Death[16] = {
|
|||||||
static const uint8 kLocationMenuStartPos[3] = {0, 1, 6};
|
static const uint8 kLocationMenuStartPos[3] = {0, 1, 6};
|
||||||
static void RunInterface();
|
static void RunInterface();
|
||||||
const uint8 *GetDungmapFloorLayout() {
|
const uint8 *GetDungmapFloorLayout() {
|
||||||
return kDungMap_FloorLayout + *(uint32 *)(kDungMap_FloorLayout + (cur_palace_index_x2 >> 1) * 4);
|
return kDungMap_FloorLayout(cur_palace_index_x2 >> 1).ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8 GetOtherDungmapInfo(int count) {
|
uint8 GetOtherDungmapInfo(int count) {
|
||||||
const uint8 *p = kDungMap_Tiles + *(uint32 *)(kDungMap_Tiles + (cur_palace_index_x2 >> 1) * 4);
|
const uint8 *p = kDungMap_Tiles(cur_palace_index_x2 >> 1).ptr;
|
||||||
return p[count];
|
return p[count];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,10 +240,6 @@ void DungMap_4() {
|
|||||||
overworld_map_state--;
|
overworld_map_state--;
|
||||||
}
|
}
|
||||||
|
|
||||||
const uint8 *GetCurrentTextPtr() {
|
|
||||||
return kDialogueText + kDialogueOffs[dialogue_message_index];
|
|
||||||
}
|
|
||||||
|
|
||||||
void Module_Messaging_6() {
|
void Module_Messaging_6() {
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
@@ -2259,8 +2144,7 @@ void Text_Initialize_initModuleStateLoop() { // 8ec493
|
|||||||
RenderText_SetDefaultWindowPosition();
|
RenderText_SetDefaultWindowPosition();
|
||||||
text_tilemap_cur = 0x3980;
|
text_tilemap_cur = 0x3980;
|
||||||
Text_LoadCharacterBuffer();
|
Text_LoadCharacterBuffer();
|
||||||
RenderText_Draw_EmptyBuffer();
|
memset(messaging_buf, 0, 0x7e0);
|
||||||
dialogue_msg_dst_offs = 0;
|
|
||||||
nmi_subroutine_index = 2;
|
nmi_subroutine_index = 2;
|
||||||
nmi_disable_core_updates = 2;
|
nmi_disable_core_updates = 2;
|
||||||
}
|
}
|
||||||
@@ -2272,58 +2156,159 @@ void Text_InitVwfState() { // 8ec4c9
|
|||||||
vwf_line_ptr = 0;
|
vwf_line_ptr = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Text_LoadCharacterBuffer() { // 8ec4e2
|
enum {
|
||||||
const uint8 *src = GetCurrentTextPtr(), *src_org = src;
|
kTextCommandStart_US = 0x67,
|
||||||
uint8 *dst = messaging_text_buffer;
|
kTextDictBase = 0x88,
|
||||||
dst[0] = dst[1] = 0x7f;
|
|
||||||
dialogue_msg_dst_offs = 0;
|
kTextCmd_NextPic = 0,
|
||||||
dialogue_msg_src_offs = 0;
|
kTextCmd_Choose = 1,
|
||||||
for (;;) {
|
kTextCmd_Item = 2,
|
||||||
uint8 c = *src++;
|
kTextCmd_Name = 3,
|
||||||
if (!(c & 0x80)) {
|
kTextCmd_Window = 4, // Only used with 2
|
||||||
switch (c) {
|
kTextCmd_Number = 5,
|
||||||
case 0x67 + 3: dst = Text_WritePlayerName(dst); break;
|
kTextCmd_Position = 6,
|
||||||
case 0x67 + 4: // RenderText_ExtendedCommand_SetWindowType
|
kTextCmd_ScrollSpd = 7,
|
||||||
text_render_state = *src++;
|
kTextCmd_Selchg = 8,
|
||||||
break;
|
kTextCmd_Choose3 = 10,
|
||||||
case 0x67 + 5: { // Text_WritePreloadedNumber
|
kTextCmd_Choose2 = 11,
|
||||||
uint8 t = *src++;
|
kTextCmd_Scroll = 12,
|
||||||
uint8 v = byte_7E1CF2[t >> 1];
|
kTextCmd_1 = 13,
|
||||||
*dst++ = 0x34 + ((t & 1) ? v >> 4 : v & 0xf);
|
kTextCmd_2 = 14,
|
||||||
break;
|
kTextCmd_3 = 15,
|
||||||
}
|
kTextCmd_Color = 16,
|
||||||
case 0x67 + 6:
|
kTextCmd_Wait = 17,
|
||||||
text_msgbox_topleft = kText_Positions[*src++];
|
kTextCmd_Sound = 18,
|
||||||
break;
|
kTextCmd_Speed = 19,
|
||||||
case 0x67 + 16:
|
kTextCmd_Mark = 20, // Unused
|
||||||
text_tilemap_cur = ((0x387F & 0xe300) | 0x180) | (*src++ << 10) & 0x3c00;
|
kTextCmd_Mark2 = 21, // Unused
|
||||||
break;
|
kTextCmd_Clear = 22, // Unused
|
||||||
case 0x67 + 7:
|
kTextCmd_Waitkey = 23,
|
||||||
case 0x67 + 17:
|
kTextCmd_EndMessage = 24,
|
||||||
case 0x67 + 18:
|
|
||||||
case 0x67 + 19:
|
kTextCmd_IsLetter = 25, // Pseudo cmd
|
||||||
*dst++ = c;
|
};
|
||||||
*dst++ = *src++;
|
|
||||||
break;
|
enum {
|
||||||
case 0x7f:
|
kTextCmd_EU_Scroll = 0x80, // frequency 875
|
||||||
dialogue_msg_dst_offs = dst - messaging_text_buffer;
|
kTextCmd_EU_Waitkey = 0x81, // frequency 362
|
||||||
dialogue_msg_src_offs = src - src_org - 1;
|
kTextCmd_EU_1 = 0x82, // frequency 25
|
||||||
*dst = 0x7f;
|
kTextCmd_EU_2 = 0x83, // frequency 496
|
||||||
return; // done
|
kTextCmd_EU_3 = 0x84, // frequency 347
|
||||||
default:
|
kTextCmd_EU_Name = 0x85, // frequency 64
|
||||||
*dst++ = c;
|
kTextCmd_EU_Rest = 0x87,
|
||||||
break;
|
};
|
||||||
}
|
|
||||||
} else {
|
#define TEXTCMD_MULTIBYTE(a) ((a) & 1)
|
||||||
// dictionary
|
#define TEXTCMD_CMD(a) (((a) >> 1) & 0x1f)
|
||||||
c -= 0x88;
|
#define TEXTCMD_PARAM(a) ((a) >> 6)
|
||||||
int idx = kTextDictionary_Idx[c], num = kTextDictionary_Idx[c + 1] - idx;
|
#define TEXTCMD_MK(c, x, m) ((c) << 6 | (x) << 1 | (m))
|
||||||
memcpy(dst, &kTextDictionary[idx], num);
|
|
||||||
dst += num;
|
uint32 Text_DecodeCmd(uint8 a, const uint8 *src) {
|
||||||
|
if ((g_zenv.dialogue_flags & 1) == 0) {
|
||||||
|
// US encoding
|
||||||
|
if (a < kTextCommandStart_US)
|
||||||
|
return TEXTCMD_MK(a, kTextCmd_IsLetter, 0);
|
||||||
|
if (a >= 0x80)
|
||||||
|
return TEXTCMD_MK(26, kTextCmd_IsLetter, 0); // could happen when loading snapshots
|
||||||
|
assert(a < 0x80);
|
||||||
|
static const uint8 kText_CommandLengths_US[] = { 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
|
||||||
|
if (kText_CommandLengths_US[a - kTextCommandStart_US])
|
||||||
|
return TEXTCMD_MK(*src, a - kTextCommandStart_US, 1);
|
||||||
|
else
|
||||||
|
return TEXTCMD_MK(0, a - kTextCommandStart_US, 0);
|
||||||
|
} else {
|
||||||
|
// EU encoding
|
||||||
|
if (a < 0x7f)
|
||||||
|
return TEXTCMD_MK(a, kTextCmd_IsLetter, 0);
|
||||||
|
static const uint8 kSoundLut[1] = {45};
|
||||||
|
static const uint8 kReturns_Simple[] = {
|
||||||
|
TEXTCMD_MK(0, kTextCmd_EndMessage, 0),
|
||||||
|
TEXTCMD_MK(0, kTextCmd_Scroll, 0),
|
||||||
|
TEXTCMD_MK(0, kTextCmd_Waitkey, 0),
|
||||||
|
TEXTCMD_MK(0, kTextCmd_1, 0),
|
||||||
|
TEXTCMD_MK(0, kTextCmd_2, 0),
|
||||||
|
TEXTCMD_MK(0, kTextCmd_3, 0),
|
||||||
|
TEXTCMD_MK(0, kTextCmd_Name, 0),
|
||||||
|
TEXTCMD_MK(0, kTextCmd_Name, 0), // Unused
|
||||||
|
};
|
||||||
|
if (a < kTextCmd_EU_Rest)
|
||||||
|
return kReturns_Simple[a - 0x7f];
|
||||||
|
a = *src;
|
||||||
|
switch (a >> 4) {
|
||||||
|
case 0: return TEXTCMD_MK(a & 0xF, kTextCmd_Wait, 1);
|
||||||
|
case 1: return TEXTCMD_MK(a & 0xF, kTextCmd_Color, 1);
|
||||||
|
case 2: return TEXTCMD_MK(a & 0xF, kTextCmd_Number, 1);
|
||||||
|
case 3: return TEXTCMD_MK(a & 0xF, kTextCmd_Speed, 1);
|
||||||
|
case 4: return TEXTCMD_MK(kSoundLut[a & 0xF], kTextCmd_Sound, 1);
|
||||||
|
case 8: {
|
||||||
|
static const uint8 kReturns_Ext[] = {
|
||||||
|
TEXTCMD_MK(0, kTextCmd_Choose, 1),
|
||||||
|
TEXTCMD_MK(0, kTextCmd_Choose2, 1),
|
||||||
|
TEXTCMD_MK(0, kTextCmd_Choose3, 1),
|
||||||
|
TEXTCMD_MK(0, kTextCmd_Selchg, 1),
|
||||||
|
TEXTCMD_MK(0, kTextCmd_Item, 1),
|
||||||
|
TEXTCMD_MK(0, kTextCmd_NextPic, 1),
|
||||||
|
TEXTCMD_MK(2, kTextCmd_Window, 1),
|
||||||
|
TEXTCMD_MK(0, kTextCmd_Position, 1),
|
||||||
|
TEXTCMD_MK(1, kTextCmd_Position, 1),
|
||||||
|
};
|
||||||
|
return kReturns_Ext[a - 0x80];
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
return TEXTCMD_MK(26, kTextCmd_IsLetter, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Perform initial parsing of the string, expanding words, processing some commands, etc.
|
||||||
|
void Text_LoadCharacterBuffer() { // 8ec4e2
|
||||||
|
MemBlk dictionary = FindIndexInMemblk(g_zenv.dialogue_blk, 0);
|
||||||
|
MemBlk dialogue = FindIndexInMemblk(g_zenv.dialogue_blk, 1);
|
||||||
|
MemBlk text_str = FindIndexInMemblk(dialogue, dialogue_message_index);
|
||||||
|
const uint8 *src = text_str.ptr, *src_end = src + text_str.size, *src_org = src;
|
||||||
|
uint8 *dst = messaging_text_buffer;
|
||||||
|
while (src < src_end) {
|
||||||
|
uint8 c = *src++;
|
||||||
|
if (c >= kTextDictBase) {
|
||||||
|
MemBlk blk = FindIndexInMemblk(dictionary, c - kTextDictBase);
|
||||||
|
memcpy(dst, blk.ptr, blk.size);
|
||||||
|
dst += blk.size;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
// Decode the next byte or multibyte character (in case we support that in the future)
|
||||||
|
// This is dependent on the current language cause US / PAL encode commands differently
|
||||||
|
uint32 cmd = Text_DecodeCmd(c, src);
|
||||||
|
switch (TEXTCMD_CMD(cmd)) {
|
||||||
|
case kTextCmd_Name: dst = Text_WritePlayerName(dst); break;
|
||||||
|
case kTextCmd_Window: // RenderText_ExtendedCommand_SetWindowType
|
||||||
|
text_render_state = TEXTCMD_PARAM(cmd);
|
||||||
|
break;
|
||||||
|
case kTextCmd_Number: { // Text_WritePreloadedNumber
|
||||||
|
uint8 t = TEXTCMD_PARAM(cmd);
|
||||||
|
uint8 v = dialogue_number[t >> 1];
|
||||||
|
*dst++ = 0x34 + ((t & 1) ? v >> 4 : v & 0xf);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case kTextCmd_Position:
|
||||||
|
text_msgbox_topleft = kText_Positions[TEXTCMD_PARAM(cmd)];
|
||||||
|
break;
|
||||||
|
case kTextCmd_Color:
|
||||||
|
text_tilemap_cur = ((0x387F & 0xe300) | 0x180) | (TEXTCMD_PARAM(cmd) << 10) & 0x3c00;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// This combination is handled when rendering instead of here
|
||||||
|
*dst++ = c;
|
||||||
|
if (TEXTCMD_MULTIBYTE(cmd))
|
||||||
|
*dst++ = *src;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
src += TEXTCMD_MULTIBYTE(cmd);
|
||||||
|
}
|
||||||
|
*dst = 0x7f;
|
||||||
|
dialogue_msg_read_pos = 0;
|
||||||
|
}
|
||||||
|
|
||||||
uint8 *Text_WritePlayerName(uint8 *p) { // 8ec5b3
|
uint8 *Text_WritePlayerName(uint8 *p) { // 8ec5b3
|
||||||
uint8 slot = srm_var1;
|
uint8 slot = srm_var1;
|
||||||
int offs = ((slot>>1) - 1) * 0x500;
|
int offs = ((slot>>1) - 1) * 0x500;
|
||||||
@@ -2396,133 +2381,103 @@ void RenderText_Draw_CharacterTilemap() { // 8ec97d
|
|||||||
}
|
}
|
||||||
|
|
||||||
void RenderText_Draw_MessageCharacters() { // 8ec984
|
void RenderText_Draw_MessageCharacters() { // 8ec984
|
||||||
restart:
|
RESTART:;
|
||||||
if (dialogue_msg_src_offs >= 99) {
|
uint32 cmd = Text_DecodeCmd(messaging_text_buffer[dialogue_msg_read_pos],
|
||||||
dialogue_msg_src_offs = 0;
|
&messaging_text_buffer[dialogue_msg_read_pos + 1]);
|
||||||
text_next_position = 0;
|
|
||||||
} else if (dialogue_msg_src_offs >= 59 && dialogue_msg_src_offs < 80) {
|
switch (TEXTCMD_CMD(cmd)) {
|
||||||
dialogue_msg_src_offs = 0x50;
|
case kTextCmd_IsLetter:
|
||||||
text_next_position = 0;
|
if (vwf_line_speed_cur >= 2) {
|
||||||
} else if (dialogue_msg_src_offs >= 19 && dialogue_msg_src_offs < 40) {
|
vwf_line_speed_cur--;
|
||||||
dialogue_msg_src_offs = 0x28;
|
|
||||||
text_next_position = 0;
|
|
||||||
}
|
|
||||||
if ((dialogue_msg_src_offs == 18 || dialogue_msg_src_offs == 58 || dialogue_msg_src_offs == 98) && (text_next_position & 7) >= 6) {
|
|
||||||
dialogue_msg_src_offs++;
|
|
||||||
goto restart;
|
|
||||||
}
|
|
||||||
int t = (messaging_text_buffer[dialogue_msg_dst_offs] & 0x7f) - 0x66;
|
|
||||||
if (t < 0)
|
|
||||||
t = 0;
|
|
||||||
switch (t) {
|
|
||||||
case 0: // RenderText_Draw_RenderCharacter
|
|
||||||
switch (vwf_line_mode < 2 ? vwf_line_mode : 2) {
|
|
||||||
case 0: // RenderText_Draw_RenderCharacter_All
|
|
||||||
RenderText_Draw_RenderCharacter_All();
|
|
||||||
break;
|
|
||||||
case 1: // VWF_RenderSingle
|
|
||||||
VWF_RenderSingle();
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
vwf_line_mode--;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
VWF_RenderSingle(TEXTCMD_PARAM(cmd));
|
||||||
|
dialogue_msg_read_pos += 1 + TEXTCMD_MULTIBYTE(cmd);
|
||||||
|
if (vwf_line_speed_cur == 0)
|
||||||
|
goto RESTART;
|
||||||
break;
|
break;
|
||||||
case 1: // RenderText_Draw_NextImage
|
case kTextCmd_NextPic: // RenderText_Draw_NextImage
|
||||||
if (main_module_index == 20) {
|
if (main_module_index == 20) {
|
||||||
PaletteFilterHistory();
|
PaletteFilterHistory();
|
||||||
if (!BYTE(palette_filter_countdown))
|
if (!BYTE(palette_filter_countdown))
|
||||||
dialogue_msg_dst_offs++;
|
goto COMMAND_DONE;
|
||||||
} else {
|
} else {
|
||||||
dialogue_msg_dst_offs++;
|
goto COMMAND_DONE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2: // RenderText_Draw_Choose2LowOr3
|
case kTextCmd_Choose: // RenderText_Draw_Choose2LowOr3
|
||||||
RenderText_Draw_Choose2LowOr3();
|
RenderText_Draw_Choose2LowOr3();
|
||||||
break;
|
break;
|
||||||
case 3: // RenderText_Draw_ChooseItem
|
case kTextCmd_Item: // RenderText_Draw_ChooseItem
|
||||||
RenderText_Draw_ChooseItem();
|
RenderText_Draw_ChooseItem();
|
||||||
break;
|
break;
|
||||||
case 4: //
|
case kTextCmd_Name:
|
||||||
case 5: //
|
case kTextCmd_Window:
|
||||||
case 6: //
|
case kTextCmd_Number:
|
||||||
case 7: //
|
case kTextCmd_Position:
|
||||||
case 8: // RenderText_Draw_Ignore
|
case kTextCmd_Color:
|
||||||
byte_7E1CEA = messaging_text_buffer[dialogue_msg_dst_offs + 1];
|
// These get handled in Text_LoadCharacterBuffer
|
||||||
dialogue_msg_dst_offs += 2;
|
|
||||||
break;
|
|
||||||
case 9: // RenderText_Draw_Choose2HiOr3
|
|
||||||
RenderText_Draw_Choose2HiOr3();
|
|
||||||
break;
|
|
||||||
case 10: //
|
|
||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
case 11: // RenderText_Draw_Choose3
|
// These are unused
|
||||||
|
case kTextCmd_Mark:
|
||||||
|
case kTextCmd_Mark2:
|
||||||
|
case kTextCmd_Clear:
|
||||||
|
assert(0);
|
||||||
|
break;
|
||||||
|
case kTextCmd_ScrollSpd:
|
||||||
|
dialogue_scroll_speed = TEXTCMD_PARAM(cmd);
|
||||||
|
goto COMMAND_DONE;
|
||||||
|
case kTextCmd_Selchg: // RenderText_Draw_Choose2HiOr3
|
||||||
|
RenderText_Draw_Choose2HiOr3();
|
||||||
|
break;
|
||||||
|
case kTextCmd_Choose3: // RenderText_Draw_Choose3
|
||||||
RenderText_Draw_Choose3();
|
RenderText_Draw_Choose3();
|
||||||
break;
|
break;
|
||||||
case 12: // RenderText_Draw_Choose1Or2
|
case kTextCmd_Choose2: // RenderText_Draw_Choose1Or2
|
||||||
RenderText_Draw_Choose1Or2();
|
RenderText_Draw_Choose1Or2();
|
||||||
break;
|
break;
|
||||||
case 13: // RenderText_Draw_Scroll
|
case kTextCmd_Scroll: // RenderText_Draw_Scroll
|
||||||
RenderText_Draw_Scroll();
|
if (RenderText_Draw_Scroll())
|
||||||
|
goto COMMAND_DONE;
|
||||||
break;
|
break;
|
||||||
case 14: //
|
case kTextCmd_1: //
|
||||||
case 15: //
|
case kTextCmd_2: //
|
||||||
case 16: // VWF_SetLine
|
case kTextCmd_3: // VWF_SetLine
|
||||||
dialogue_msg_src_offs = kVWF_LinePositions[(t + 2) & 3];
|
vwf_curline = kVWF_RowPositions[TEXTCMD_CMD(cmd) - kTextCmd_1];
|
||||||
vwf_curline = kVWF_RowPositions[(t + 2) & 3];
|
|
||||||
vwf_flag_next_line = 1;
|
vwf_flag_next_line = 1;
|
||||||
dialogue_msg_dst_offs++;
|
goto COMMAND_DONE;
|
||||||
text_next_position = 0;
|
case kTextCmd_Wait: // RenderText_Draw_Wait
|
||||||
break;
|
switch (joypad1L_last & 0x80 ? 1 : text_wait_countdown) {
|
||||||
case 17: // RenderText_Draw_SetColor
|
|
||||||
byte_7E1CDC &= ~0x1c;
|
|
||||||
byte_7E1CDC |= (messaging_text_buffer[dialogue_msg_dst_offs + 1] & 7) << 2;
|
|
||||||
dialogue_msg_dst_offs += 2;
|
|
||||||
break;
|
|
||||||
case 18: // RenderText_Draw_Wait
|
|
||||||
switch (joypad1L_last & 0x80 ? 1 : text_wait_countdown >= 2 ? 2 : text_wait_countdown) {
|
|
||||||
case 0:
|
case 0:
|
||||||
text_wait_countdown = kText_WaitDurations[messaging_text_buffer[dialogue_msg_dst_offs + 1] & 0xf] - 1;
|
text_wait_countdown = kText_WaitDurations[TEXTCMD_PARAM(cmd)] - 1;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
dialogue_msg_dst_offs += 2;
|
|
||||||
BYTE(text_wait_countdown) = 0;
|
BYTE(text_wait_countdown) = 0;
|
||||||
break;
|
goto COMMAND_DONE;
|
||||||
case 2:
|
default:
|
||||||
text_wait_countdown--;
|
text_wait_countdown--;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 19: // RenderText_Draw_PlaySfx
|
case kTextCmd_Sound: // RenderText_Draw_PlaySfx
|
||||||
sound_effect_2 = messaging_text_buffer[dialogue_msg_dst_offs + 1];
|
sound_effect_2 = TEXTCMD_PARAM(cmd);
|
||||||
dialogue_msg_dst_offs += 2;
|
goto COMMAND_DONE;
|
||||||
break;
|
case kTextCmd_Speed: // RenderText_Draw_SetSpeed
|
||||||
case 20: // RenderText_Draw_SetSpeed
|
vwf_line_speed = vwf_line_speed_cur = TEXTCMD_PARAM(cmd);
|
||||||
vwf_line_speed = vwf_line_mode = messaging_text_buffer[dialogue_msg_dst_offs + 1];
|
goto COMMAND_DONE;
|
||||||
dialogue_msg_dst_offs += 2;
|
case kTextCmd_Waitkey: // RenderText_Draw_PauseForInput
|
||||||
break;
|
|
||||||
case 21: // RenderText_Draw_Command7B
|
|
||||||
RenderText_Draw_Command7B();
|
|
||||||
break;
|
|
||||||
case 22: // RenderText_Draw_ABunchOfSpaces
|
|
||||||
RenderText_Draw_ABunchOfSpaces();
|
|
||||||
break;
|
|
||||||
case 23: // RenderText_Draw_EmptyBuffer
|
|
||||||
RenderText_Draw_EmptyBuffer();
|
|
||||||
break;
|
|
||||||
case 24: // RenderText_Draw_PauseForInput
|
|
||||||
if (text_wait_countdown2 != 0) {
|
if (text_wait_countdown2 != 0) {
|
||||||
if (--text_wait_countdown2 == 1)
|
if (--text_wait_countdown2 == 1)
|
||||||
sound_effect_2 = 36;
|
sound_effect_2 = 36;
|
||||||
} else {
|
} else {
|
||||||
if ((filtered_joypad_H | filtered_joypad_L) & 0xc0) {
|
if ((filtered_joypad_H | filtered_joypad_L) & 0xc0) {
|
||||||
dialogue_msg_dst_offs++;
|
|
||||||
text_wait_countdown2 = 28;
|
text_wait_countdown2 = 28;
|
||||||
|
goto COMMAND_DONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 25: // RenderText_Draw_Terminate
|
case kTextCmd_EndMessage: // RenderText_Draw_Terminate
|
||||||
if (text_wait_countdown2 != 0) {
|
if (text_wait_countdown2 != 0) {
|
||||||
if (--text_wait_countdown2 == 1)
|
if (--text_wait_countdown2 == 1)
|
||||||
sound_effect_2 = 36;
|
sound_effect_2 = 36;
|
||||||
@@ -2534,6 +2489,9 @@ restart:
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (0) COMMAND_DONE: {
|
||||||
|
dialogue_msg_read_pos += 1 + TEXTCMD_MULTIBYTE(cmd);
|
||||||
|
}
|
||||||
nmi_subroutine_index = 2;
|
nmi_subroutine_index = 2;
|
||||||
nmi_disable_core_updates = 2;
|
nmi_disable_core_updates = 2;
|
||||||
}
|
}
|
||||||
@@ -2551,35 +2509,26 @@ void RenderText_Draw_Finish() { // 8eca35
|
|||||||
main_module_index = saved_module_for_menu;
|
main_module_index = saved_module_for_menu;
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderText_Draw_RenderCharacter_All() { // 8eca99
|
void VWF_RenderSingle(int c) { // 8ecab8
|
||||||
VWF_RenderSingle();
|
if (c != 0x59)
|
||||||
if (dialogue_msg_src_offs != 19 && dialogue_msg_src_offs != 59 && dialogue_msg_src_offs != 99)
|
|
||||||
RenderText_Draw_MessageCharacters();
|
|
||||||
}
|
|
||||||
|
|
||||||
void VWF_RenderSingle() { // 8ecab8
|
|
||||||
uint8 t = messaging_text_buffer[dialogue_msg_dst_offs];
|
|
||||||
if (t != 0x59)
|
|
||||||
sound_effect_2 = 12;
|
sound_effect_2 = 12;
|
||||||
VWF_RenderCharacter();
|
vwf_line_speed_cur = vwf_line_speed;
|
||||||
vwf_line_mode = vwf_line_speed;
|
|
||||||
}
|
|
||||||
|
|
||||||
void VWF_RenderCharacter() { // 8ecb5e
|
|
||||||
if (vwf_flag_next_line) {
|
if (vwf_flag_next_line) {
|
||||||
vwf_line_ptr = kVWF_RenderCharacter_renderPos[vwf_curline>>1];
|
vwf_line_ptr = kVWF_RenderCharacter_renderPos[vwf_curline>>1];
|
||||||
vwf_var1 = kVWF_RenderCharacter_linePositions[vwf_curline>>1];
|
vwf_var1 = kVWF_RenderCharacter_linePositions[vwf_curline>>1];
|
||||||
vwf_flag_next_line = 0;
|
vwf_flag_next_line = 0;
|
||||||
}
|
}
|
||||||
uint8 c = messaging_text_buffer[dialogue_msg_dst_offs];
|
|
||||||
uint8 width = kVWF_RenderCharacter_widths[c];
|
const uint8 *kFontData = FindIndexInMemblk(g_zenv.dialogue_font_blk, 0).ptr;
|
||||||
|
uint8 width = FindIndexInMemblk(g_zenv.dialogue_font_blk, 1).ptr[c];
|
||||||
|
|
||||||
int i = vwf_var1++;
|
int i = vwf_var1++;
|
||||||
uint8 arrval = vwf_arr[i];
|
uint8 arrval = vwf_arr[i];
|
||||||
vwf_arr[i + 1] = arrval + width;
|
vwf_arr[i + 1] = arrval + width;
|
||||||
uint16 r10 = (c & 0x70) * 2 + (c & 0xf);
|
uint16 r10 = (c & 0x70) * 2 + (c & 0xf);
|
||||||
uint16 r0 = arrval * 2;
|
uint16 r0 = arrval * 2;
|
||||||
const uint16 *const kTextBits = kFontData;
|
const uint16 *src2 = (uint16*)(kFontData + r10 * 16);
|
||||||
const uint16 *src2 = kTextBits + r10 * 8;
|
|
||||||
uint8 *mbuf = (uint8 *)messaging_buf;
|
uint8 *mbuf = (uint8 *)messaging_buf;
|
||||||
for (int i = 0; i != 16; i += 2) {
|
for (int i = 0; i != 16; i += 2) {
|
||||||
uint16 r4 = *src2++;
|
uint16 r4 = *src2++;
|
||||||
@@ -2604,7 +2553,7 @@ void VWF_RenderCharacter() { // 8ecb5e
|
|||||||
WORD(mbuf[x + 0]) = r4;
|
WORD(mbuf[x + 0]) = r4;
|
||||||
}
|
}
|
||||||
uint16 r8 = vwf_line_ptr + 0x150;
|
uint16 r8 = vwf_line_ptr + 0x150;
|
||||||
const uint16 *src3 = kTextBits + (r10 + 16) * 8;
|
const uint16 *src3 = (uint16*)(kFontData + (r10 + 16) * 16);
|
||||||
for (int i = 0; i != 16; i += 2) {
|
for (int i = 0; i != 16; i += 2) {
|
||||||
uint16 r4 = *src3++;
|
uint16 r4 = *src3++;
|
||||||
int y = r8 + r0;
|
int y = r8 + r0;
|
||||||
@@ -2627,7 +2576,6 @@ void VWF_RenderCharacter() { // 8ecb5e
|
|||||||
if (r4 != 0)
|
if (r4 != 0)
|
||||||
WORD(mbuf[x + 0]) = r4;
|
WORD(mbuf[x + 0]) = r4;
|
||||||
}
|
}
|
||||||
dialogue_msg_dst_offs++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderText_Draw_Choose2LowOr3() { // 8ecd1a
|
void RenderText_Draw_Choose2LowOr3() { // 8ecd1a
|
||||||
@@ -2645,8 +2593,6 @@ void RenderText_Draw_Choose2LowOr3() { // 8ecd1a
|
|||||||
sound_effect_2 = 32;
|
sound_effect_2 = 32;
|
||||||
dialogue_message_index = t + 1;
|
dialogue_message_index = t + 1;
|
||||||
Text_LoadCharacterBuffer();
|
Text_LoadCharacterBuffer();
|
||||||
text_next_position = 0;
|
|
||||||
dialogue_msg_dst_offs = 0;
|
|
||||||
Text_InitVwfState();
|
Text_InitVwfState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2719,8 +2665,6 @@ void RenderText_Draw_Choose2HiOr3() { // 8ece83
|
|||||||
sound_effect_2 = 32;
|
sound_effect_2 = 32;
|
||||||
dialogue_message_index = t + 11;
|
dialogue_message_index = t + 11;
|
||||||
Text_LoadCharacterBuffer();
|
Text_LoadCharacterBuffer();
|
||||||
text_next_position = 0;
|
|
||||||
dialogue_msg_dst_offs = 0;
|
|
||||||
Text_InitVwfState();
|
Text_InitVwfState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2743,8 +2687,6 @@ void RenderText_Draw_Choose3() { // 8ecef7
|
|||||||
sound_effect_2 = 32;
|
sound_effect_2 = 32;
|
||||||
dialogue_message_index = choice + 6;
|
dialogue_message_index = choice + 6;
|
||||||
Text_LoadCharacterBuffer();
|
Text_LoadCharacterBuffer();
|
||||||
text_next_position = 0;
|
|
||||||
dialogue_msg_dst_offs = 0;
|
|
||||||
Text_InitVwfState();
|
Text_InitVwfState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2765,14 +2707,12 @@ void RenderText_Draw_Choose1Or2() { // 8ecf72
|
|||||||
sound_effect_2 = 32;
|
sound_effect_2 = 32;
|
||||||
dialogue_message_index = t + 9;
|
dialogue_message_index = t + 9;
|
||||||
Text_LoadCharacterBuffer();
|
Text_LoadCharacterBuffer();
|
||||||
text_next_position = 0;
|
|
||||||
dialogue_msg_dst_offs = 0;
|
|
||||||
Text_InitVwfState();
|
Text_InitVwfState();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderText_Draw_Scroll() { // 8ecfe2
|
bool RenderText_Draw_Scroll() { // 8ecfe2
|
||||||
uint8 r2 = byte_7E1CEA;
|
uint8 r2 = dialogue_scroll_speed;
|
||||||
do {
|
do {
|
||||||
for (int i = 0; i < 0x7e0; i += 16) {
|
for (int i = 0; i < 0x7e0; i += 16) {
|
||||||
uint16 *p = (uint16 *)((uint8 *)messaging_buf + i);
|
uint16 *p = (uint16 *)((uint8 *)messaging_buf + i);
|
||||||
@@ -2790,43 +2730,12 @@ void RenderText_Draw_Scroll() { // 8ecfe2
|
|||||||
p[i] = 0;
|
p[i] = 0;
|
||||||
|
|
||||||
if ((++byte_7E1CDF & 0xf) == 0) {
|
if ((++byte_7E1CDF & 0xf) == 0) {
|
||||||
dialogue_msg_dst_offs++;
|
|
||||||
dialogue_msg_src_offs = 80;
|
|
||||||
vwf_curline = 4;
|
vwf_curline = 4;
|
||||||
vwf_flag_next_line = 1;
|
vwf_flag_next_line = 1;
|
||||||
text_next_position = 0;
|
return true;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
} while (r2--);
|
} while (r2--);
|
||||||
}
|
return false;
|
||||||
|
|
||||||
void RenderText_Draw_Command7B() { // 8ed18d
|
|
||||||
int i = (messaging_text_buffer[dialogue_msg_dst_offs + 1] & 0x7f);
|
|
||||||
int j = dialogue_msg_src_offs;
|
|
||||||
WORD(g_ram[0x2D8 + j]) = kVWF_Command7B[i * 2 + 0];
|
|
||||||
WORD(g_ram[0x300 + j]) = kVWF_Command7B[i * 2 + 1];
|
|
||||||
dialogue_msg_src_offs = j + 2;
|
|
||||||
dialogue_msg_dst_offs += 2;
|
|
||||||
RenderText_Draw_MessageCharacters();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderText_Draw_ABunchOfSpaces() { // 8ed1bd
|
|
||||||
int i = (messaging_text_buffer[dialogue_msg_dst_offs + 1] & 0x7f);
|
|
||||||
int j = dialogue_msg_src_offs;
|
|
||||||
WORD(g_ram[0x2D8 + j]) = kVWF_Command7C[i * 4 + 0];
|
|
||||||
WORD(g_ram[0x300 + j]) = kVWF_Command7C[i * 4 + 1];
|
|
||||||
WORD(g_ram[0x2DA + j]) = kVWF_Command7C[i * 4 + 2];
|
|
||||||
WORD(g_ram[0x302 + j]) = kVWF_Command7C[i * 4 + 3];
|
|
||||||
dialogue_msg_src_offs = j + 4;
|
|
||||||
dialogue_msg_dst_offs += 2;
|
|
||||||
RenderText_Draw_MessageCharacters();
|
|
||||||
}
|
|
||||||
|
|
||||||
void RenderText_Draw_EmptyBuffer() { // 8ed1f9
|
|
||||||
memset(messaging_buf, 0, 0x7e0);
|
|
||||||
dialogue_msg_src_offs = 0;
|
|
||||||
dialogue_msg_dst_offs++;
|
|
||||||
text_next_position = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RenderText_SetDefaultWindowPosition() { // 8ed280
|
void RenderText_SetDefaultWindowPosition() { // 8ed280
|
||||||
@@ -2875,28 +2784,19 @@ void RenderText_Refresh() { // 8ed307
|
|||||||
nmi_load_bg_from_vram = 1;
|
nmi_load_bg_from_vram = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void Text_GenerateMessagePointers() { // 8ed3eb
|
void Text_GenerateMessagePointers() { // 8ed3eb
|
||||||
const uint8 *src = kDialogueText;
|
// This is not actually used. Only for ram compat.
|
||||||
|
MemBlk dialogue = FindIndexInMemblk(g_zenv.dialogue_blk, 1);
|
||||||
uint32 p = 0x1c8000;
|
uint32 p = 0x1c8000;
|
||||||
uint8 *dst = kTextDialoguePointers;
|
uint8 *dst = kTextDialoguePointers;
|
||||||
for (int i = 0;; i++) {
|
for (int i = 0; i < 398; i++) {
|
||||||
if (i == 359)
|
if (i == 359)
|
||||||
p = 0xedf40;
|
p = 0xedf40;
|
||||||
WORD(dst[0]) = p;
|
WORD(dst[0]) = p;
|
||||||
dst[2] = p >> 16;
|
dst[2] = p >> 16;
|
||||||
dst += 3;
|
dst += 3;
|
||||||
|
p += (uint32)FindIndexInMemblk(dialogue, i).size + 1;
|
||||||
if (i == 397)
|
|
||||||
break;
|
|
||||||
|
|
||||||
for (;;) {
|
|
||||||
int j = *src;
|
|
||||||
int len = (j >= 0x67 && j < 0x80) ? kText_CommandLengths[j - 0x67] : 1;
|
|
||||||
src += len;
|
|
||||||
p += len;
|
|
||||||
if (j == 0x7f)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
const uint8 *GetDungmapFloorLayout();
|
const uint8 *GetDungmapFloorLayout();
|
||||||
uint8 GetOtherDungmapInfo(int count);
|
uint8 GetOtherDungmapInfo(int count);
|
||||||
void DungMap_4();
|
void DungMap_4();
|
||||||
const uint8 *GetCurrentTextPtr();
|
|
||||||
void Module_Messaging_6();
|
void Module_Messaging_6();
|
||||||
void OverworldMap_SetupHdma();
|
void OverworldMap_SetupHdma();
|
||||||
const uint8 *GetLightOverworldTilemap();
|
const uint8 *GetLightOverworldTilemap();
|
||||||
@@ -108,9 +107,7 @@ void RenderText_Draw_BorderIncremental();
|
|||||||
void RenderText_Draw_CharacterTilemap();
|
void RenderText_Draw_CharacterTilemap();
|
||||||
void RenderText_Draw_MessageCharacters();
|
void RenderText_Draw_MessageCharacters();
|
||||||
void RenderText_Draw_Finish();
|
void RenderText_Draw_Finish();
|
||||||
void RenderText_Draw_RenderCharacter_All();
|
|
||||||
void VWF_RenderSingle();
|
void VWF_RenderSingle();
|
||||||
void VWF_RenderCharacter();
|
|
||||||
void RenderText_Draw_Choose2LowOr3();
|
void RenderText_Draw_Choose2LowOr3();
|
||||||
void RenderText_Draw_ChooseItem();
|
void RenderText_Draw_ChooseItem();
|
||||||
void RenderText_FindYItem_Previous();
|
void RenderText_FindYItem_Previous();
|
||||||
@@ -119,10 +116,7 @@ void RenderText_DrawSelectedYItem();
|
|||||||
void RenderText_Draw_Choose2HiOr3();
|
void RenderText_Draw_Choose2HiOr3();
|
||||||
void RenderText_Draw_Choose3();
|
void RenderText_Draw_Choose3();
|
||||||
void RenderText_Draw_Choose1Or2();
|
void RenderText_Draw_Choose1Or2();
|
||||||
void RenderText_Draw_Scroll();
|
bool RenderText_Draw_Scroll();
|
||||||
void RenderText_Draw_Command7B();
|
|
||||||
void RenderText_Draw_ABunchOfSpaces();
|
|
||||||
void RenderText_Draw_EmptyBuffer();
|
|
||||||
void RenderText_SetDefaultWindowPosition();
|
void RenderText_SetDefaultWindowPosition();
|
||||||
void RenderText_DrawBorderInitialize();
|
void RenderText_DrawBorderInitialize();
|
||||||
uint16 *RenderText_DrawBorderRow(uint16 *d, int y);
|
uint16 *RenderText_DrawBorderRow(uint16 *d, int y);
|
||||||
|
|||||||
117
other/make_text_dict.py
Normal file
117
other/make_text_dict.py
Normal file
@@ -0,0 +1,117 @@
|
|||||||
|
import array
|
||||||
|
|
||||||
|
memos = {}
|
||||||
|
memoslist = []
|
||||||
|
def memo(s):
|
||||||
|
m = memos.get(s)
|
||||||
|
if m == None:
|
||||||
|
m = len(memoslist)
|
||||||
|
memos[s] = m
|
||||||
|
memoslist.append(s)
|
||||||
|
return m
|
||||||
|
|
||||||
|
def tos(s): return "".join(memoslist[c] for c in s)
|
||||||
|
|
||||||
|
lines = []
|
||||||
|
for line in open('dialogue.txt', 'r').read().splitlines():
|
||||||
|
line = line.split(': ')[1]
|
||||||
|
|
||||||
|
r = array.array('H')
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
while i < len(line):
|
||||||
|
if line[i] == '[':
|
||||||
|
j = line.index(']', i + 1)
|
||||||
|
r.append(memo(line[i:j+1]))
|
||||||
|
i = j + 1
|
||||||
|
else:
|
||||||
|
r.append(memo(line[i]))
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
#print(repr(line))
|
||||||
|
#print(r)
|
||||||
|
lines.append(list(r))
|
||||||
|
import collections
|
||||||
|
|
||||||
|
|
||||||
|
def find_all_ngrams(lines, N, cost):
|
||||||
|
ctr = collections.Counter()
|
||||||
|
for line in lines:
|
||||||
|
for i in range(len(line) - N + 1):
|
||||||
|
if line[i] != line[i+1]:
|
||||||
|
ctr[tuple(line[i:i+N])] += 1
|
||||||
|
r = list((b, a) for a, b in ctr.items() if b >= 2)
|
||||||
|
if len(r) == 0:
|
||||||
|
return None, 0
|
||||||
|
b, a = max(r)
|
||||||
|
return a, (N - cost) * b - N - 2 # 2 is the overhead of the dict
|
||||||
|
|
||||||
|
def find_best_ngram(cost):
|
||||||
|
best_score=0
|
||||||
|
|
||||||
|
for i in range(2, 32):
|
||||||
|
text, score = find_all_ngrams(lines, i, cost)
|
||||||
|
if score > best_score:
|
||||||
|
best_score = score
|
||||||
|
best_text = text
|
||||||
|
return best_score, best_text
|
||||||
|
|
||||||
|
def update_ngrams(lines, replace_from, replace_to):
|
||||||
|
for line in lines:
|
||||||
|
for i in range(len(line) - len(replace_from) + 1):
|
||||||
|
if tuple(line[i:i+len(replace_from)]) == replace_from:
|
||||||
|
line[i:i+len(replace_from)] = replace_to
|
||||||
|
|
||||||
|
total_gain = 0
|
||||||
|
|
||||||
|
original_tokens = sum(len(line) for line in lines)
|
||||||
|
|
||||||
|
|
||||||
|
kTextDictionary_US = [
|
||||||
|
' ', ' ', ' ', "'s ", 'and ',
|
||||||
|
'are ', 'all ', 'ain', 'and', 'at ',
|
||||||
|
'ast', 'an', 'at', 'ble', 'ba',
|
||||||
|
'be', 'bo', 'can ', 'che', 'com',
|
||||||
|
'ck', 'des', 'di', 'do', 'en ',
|
||||||
|
'er ', 'ear', 'ent', 'ed ', 'en',
|
||||||
|
'er', 'ev', 'for', 'fro', 'give ',
|
||||||
|
'get', 'go', 'have', 'has', 'her',
|
||||||
|
'hi', 'ha', 'ight ', 'ing ', 'in',
|
||||||
|
'is', 'it', 'just', 'know', 'ly ',
|
||||||
|
'la', 'lo', 'man', 'ma', 'me',
|
||||||
|
'mu', "n't ", 'non', 'not', 'open',
|
||||||
|
'ound', 'out ', 'of', 'on', 'or',
|
||||||
|
'per', 'ple', 'pow', 'pro', 're ',
|
||||||
|
're', 'some', 'se', 'sh', 'so',
|
||||||
|
'st', 'ter ', 'thin', 'ter', 'tha',
|
||||||
|
'the', 'thi', 'to', 'tr', 'up',
|
||||||
|
'ver', 'with', 'wa', 'we', 'wh',
|
||||||
|
'wi', 'you', 'Her', 'Tha', 'The',
|
||||||
|
'Thi', 'You',
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
dictionary = []
|
||||||
|
|
||||||
|
for i in range(111+256):
|
||||||
|
best_score, best_text = find_best_ngram(1 if i < 111 else 2)
|
||||||
|
if best_score == 0:
|
||||||
|
break
|
||||||
|
|
||||||
|
total_gain += best_score
|
||||||
|
|
||||||
|
print(f'Removed best bigram "{tos(best_text)}" with gain {best_score}, total gain {total_gain} / {original_tokens}')
|
||||||
|
|
||||||
|
dictionary.append(best_text)
|
||||||
|
|
||||||
|
update_ngrams(lines, best_text, [memo('{%s}' % tos(best_text))])
|
||||||
|
|
||||||
|
#print('kTextDictionary_NEW = [')
|
||||||
|
#for i, d in enumerate(dictionary):
|
||||||
|
# repl = tos(d).replace('{', '').replace('}', '')
|
||||||
|
# print(f'{repr(repl)},')
|
||||||
|
#print(']')
|
||||||
|
|
||||||
|
|
||||||
|
for i, a in enumerate(lines):
|
||||||
|
print(i, tos(a))
|
||||||
@@ -2449,11 +2449,11 @@ void Overworld_DecompressAndDrawAllQuadrants() { // 82f54a
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const uint8 *GetOverworldHibytes(int i) {
|
static const uint8 *GetOverworldHibytes(int i) {
|
||||||
return kOverworld_Hibytes_Comp + *(uint32 *)(kOverworld_Hibytes_Comp + i * 4);
|
return kOverworld_Hibytes_Comp(i).ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint8 *GetOverworldLobytes(int i) {
|
static const uint8 *GetOverworldLobytes(int i) {
|
||||||
return kOverworld_Lobytes_Comp + *(uint32 *)(kOverworld_Lobytes_Comp + i * 4);
|
return kOverworld_Lobytes_Comp(i).ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1058,8 +1058,8 @@ void FortuneTeller_LightOrDarkWorld(int k, bool dark_world) {
|
|||||||
if (!dark_world)
|
if (!dark_world)
|
||||||
sprite_graphics[k] = 0;
|
sprite_graphics[k] = 0;
|
||||||
j = kFortuneTeller_Prices[sprite_A[k]>>1];
|
j = kFortuneTeller_Prices[sprite_A[k]>>1];
|
||||||
byte_7E1CF2[0] = (j / 10) | (j % 10)<< 4 ;
|
dialogue_number[0] = (j / 10) | (j % 10)<< 4 ;
|
||||||
byte_7E1CF2[1] = 0;
|
dialogue_number[1] = 0;
|
||||||
Sprite_ShowMessageUnconditional(0xf4);
|
Sprite_ShowMessageUnconditional(0xf4);
|
||||||
sprite_ai_state[k]++;
|
sprite_ai_state[k]++;
|
||||||
break;
|
break;
|
||||||
@@ -11396,7 +11396,7 @@ void Sprite_HappinessPond(int k) { // 86c44c
|
|||||||
if (choice_in_multiselect_box == 0) {
|
if (choice_in_multiselect_box == 0) {
|
||||||
int i = (link_bomb_upgrades | link_arrow_upgrades) != 0;
|
int i = (link_bomb_upgrades | link_arrow_upgrades) != 0;
|
||||||
sprite_graphics[k] = i * 2;
|
sprite_graphics[k] = i * 2;
|
||||||
WORD(byte_7E1CF2[0]) = WORD(kHappinessPondCostHex[i * 2]);
|
WORD(dialogue_number[0]) = WORD(kHappinessPondCostHex[i * 2]);
|
||||||
Sprite_ShowMessageUnconditional(0x14e);
|
Sprite_ShowMessageUnconditional(0x14e);
|
||||||
sprite_ai_state[k] = 2;
|
sprite_ai_state[k] = 2;
|
||||||
flag_is_link_immobilized = 1;
|
flag_is_link_immobilized = 1;
|
||||||
@@ -11409,7 +11409,7 @@ show_later_msg:
|
|||||||
break;
|
break;
|
||||||
case 2: {
|
case 2: {
|
||||||
int i = sprite_graphics[k] + choice_in_multiselect_box;
|
int i = sprite_graphics[k] + choice_in_multiselect_box;
|
||||||
byte_7E1CF2[1] = kHappinessPondCostHex[i];
|
dialogue_number[1] = kHappinessPondCostHex[i];
|
||||||
if (link_rupees_goal < kHappinessPondCost[i]) {
|
if (link_rupees_goal < kHappinessPondCost[i]) {
|
||||||
goto show_later_msg;
|
goto show_later_msg;
|
||||||
} else {
|
} else {
|
||||||
@@ -11430,7 +11430,7 @@ show_later_msg:
|
|||||||
sprite_ai_state[k] = 5;
|
sprite_ai_state[k] = 5;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
byte_7E1CF2[0] = (link_rupees_in_pond / 10) * 16 + (link_rupees_in_pond % 10);
|
dialogue_number[0] = (link_rupees_in_pond / 10) * 16 + (link_rupees_in_pond % 10);
|
||||||
sprite_ai_state[k] = 4;
|
sprite_ai_state[k] = 4;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -11481,7 +11481,7 @@ show_later_msg:
|
|||||||
int i = link_bomb_upgrades + 1;
|
int i = link_bomb_upgrades + 1;
|
||||||
if (i != 8) {
|
if (i != 8) {
|
||||||
link_bomb_upgrades = i;
|
link_bomb_upgrades = i;
|
||||||
byte_7E1CF2[0] = link_bomb_filler = kMaxBombsForLevelHex[i];
|
dialogue_number[0] = link_bomb_filler = kMaxBombsForLevelHex[i];
|
||||||
Sprite_ShowMessageUnconditional(0x96);
|
Sprite_ShowMessageUnconditional(0x96);
|
||||||
} else {
|
} else {
|
||||||
link_rupees_goal += 100;
|
link_rupees_goal += 100;
|
||||||
@@ -11518,7 +11518,7 @@ show_later_msg:
|
|||||||
int i = link_arrow_upgrades + 1;
|
int i = link_arrow_upgrades + 1;
|
||||||
if (i != 8) {
|
if (i != 8) {
|
||||||
link_arrow_upgrades = i;
|
link_arrow_upgrades = i;
|
||||||
byte_7E1CF2[0] = link_arrow_filler = kMaxArrowsForLevelHex[i];
|
dialogue_number[0] = link_arrow_filler = kMaxArrowsForLevelHex[i];
|
||||||
Sprite_ShowMessageUnconditional(0x97);
|
Sprite_ShowMessageUnconditional(0x97);
|
||||||
} else {
|
} else {
|
||||||
link_rupees_goal += 100;
|
link_rupees_goal += 100;
|
||||||
@@ -12947,8 +12947,8 @@ void Sprite_MazeGameGuy(int k) { // 8dcbf2
|
|||||||
t %= 60;
|
t %= 60;
|
||||||
int c = t / 10;
|
int c = t / 10;
|
||||||
t %= 10;
|
t %= 10;
|
||||||
byte_7E1CF2[0] = t | c << 4;
|
dialogue_number[0] = t | c << 4;
|
||||||
byte_7E1CF2[1] = b | a << 4;
|
dialogue_number[1] = b | a << 4;
|
||||||
t = Sprite_ShowMessageOnContact(k, 0xcb);
|
t = Sprite_ShowMessageOnContact(k, 0xcb);
|
||||||
if (t & 0x100) {
|
if (t & 0x100) {
|
||||||
sprite_D[k] = sprite_head_dir[k] = (uint8)t;
|
sprite_D[k] = sprite_head_dir[k] = (uint8)t;
|
||||||
|
|||||||
7
tables/.gitignore
vendored
7
tables/.gitignore
vendored
@@ -1,5 +1,5 @@
|
|||||||
zelda3.sfc
|
zelda3.sfc
|
||||||
dialogue.txt
|
dialogue*.txt
|
||||||
generated_*.h
|
generated_*.h
|
||||||
linksprite.png
|
linksprite.png
|
||||||
map32_to_map16.txt
|
map32_to_map16.txt
|
||||||
@@ -8,4 +8,7 @@ sfx.txt
|
|||||||
/sound
|
/sound
|
||||||
sound_ending.txt
|
sound_ending.txt
|
||||||
sound_indoor.txt
|
sound_indoor.txt
|
||||||
sound_intro.txt
|
sound_intro.txt
|
||||||
|
/hud_icons.png
|
||||||
|
/font*.png
|
||||||
|
|
||||||
|
|||||||
@@ -9,13 +9,7 @@ import array, hashlib, struct
|
|||||||
from util import cache
|
from util import cache
|
||||||
import sprite_sheets
|
import sprite_sheets
|
||||||
import argparse
|
import argparse
|
||||||
|
import os
|
||||||
parser = argparse.ArgumentParser(description='Compile resources.')
|
|
||||||
parser.add_argument('rom', nargs='?', help='the rom file')
|
|
||||||
parser.add_argument('--sprites-from-png', action='store_true', help='Use the sprite images from the .PNG files')
|
|
||||||
args = parser.parse_args()
|
|
||||||
|
|
||||||
ROM = util.LoadedRom(args.rom)
|
|
||||||
|
|
||||||
def flatten(xss):
|
def flatten(xss):
|
||||||
return [x for xs in xss for x in xs]
|
return [x for xs in xss for x in xs]
|
||||||
@@ -41,6 +35,10 @@ def add_asset_int16(name, data):
|
|||||||
assert name not in assets
|
assert name not in assets
|
||||||
assets[name] = ('int16', bytes(array.array('h', data)))
|
assets[name] = ('int16', bytes(array.array('h', data)))
|
||||||
|
|
||||||
|
def add_asset_packed(name, data):
|
||||||
|
assert name not in assets
|
||||||
|
assets[name] = ('packed', pack_arrays(data))
|
||||||
|
|
||||||
def print_map32_to_map16():
|
def print_map32_to_map16():
|
||||||
tab = {}
|
tab = {}
|
||||||
for line in open('map32_to_map16.txt'):
|
for line in open('map32_to_map16.txt'):
|
||||||
@@ -68,20 +66,12 @@ def print_map32_to_map16():
|
|||||||
add_asset_uint8('kMap32ToMap16_2', res[2])
|
add_asset_uint8('kMap32ToMap16_2', res[2])
|
||||||
add_asset_uint8('kMap32ToMap16_3', res[3])
|
add_asset_uint8('kMap32ToMap16_3', res[3])
|
||||||
|
|
||||||
|
def compress_dialogue(fname, lang):
|
||||||
def print_dialogue():
|
lines = []
|
||||||
new_r = []
|
for line in open(fname, encoding='utf8').read().splitlines():
|
||||||
offs = []
|
|
||||||
for line in open('dialogue.txt'):
|
|
||||||
line = line.strip('\n')
|
|
||||||
a, b = line.split(': ', 1)
|
a, b = line.split(': ', 1)
|
||||||
index = int(a)
|
lines.append(b)
|
||||||
offs.append(len(new_r))
|
return text_compression.compress_strings(lines, lang)
|
||||||
r = text_compression.compress_string(b)
|
|
||||||
new_r.extend(r)
|
|
||||||
|
|
||||||
add_asset_uint16('kDialogueOffs', offs)
|
|
||||||
add_asset_uint8('kDialogueText', new_r)
|
|
||||||
|
|
||||||
def compress_store(r):
|
def compress_store(r):
|
||||||
rr = []
|
rr = []
|
||||||
@@ -95,14 +85,20 @@ def compress_store(r):
|
|||||||
rr.append(0xff)
|
rr.append(0xff)
|
||||||
return rr
|
return rr
|
||||||
|
|
||||||
def pack_u32_arrays(arr):
|
# Pack arrays and determine automatically the index size
|
||||||
all_offs, offs = [], len(arr) * 4
|
def pack_arrays(arr):
|
||||||
for i in range(len(arr)):
|
if len(arr) == 0:
|
||||||
all_offs.append(offs)
|
return b''
|
||||||
|
all_offs, offs = [], 0
|
||||||
|
for i in range(len(arr) - 1):
|
||||||
offs += len(arr[i])
|
offs += len(arr[i])
|
||||||
return b''.join([struct.pack('I', i) for i in all_offs] + arr)
|
all_offs.append(offs)
|
||||||
|
if offs < 65536 and len(arr) <= 8192:
|
||||||
|
return b''.join([struct.pack('H', i) for i in all_offs] + arr + [struct.pack('H', len(arr) - 1)])
|
||||||
|
else:
|
||||||
|
return b''.join([struct.pack('I', i) for i in all_offs] + arr + [struct.pack('H', 8192 + len(arr) - 1)])
|
||||||
|
|
||||||
def print_images():
|
def print_images(args):
|
||||||
sprsheet = sprite_sheets.load_sprite_sheets() if args.sprites_from_png else None
|
sprsheet = sprite_sheets.load_sprite_sheets() if args.sprites_from_png else None
|
||||||
|
|
||||||
all = []
|
all = []
|
||||||
@@ -114,25 +110,45 @@ def print_images():
|
|||||||
else:
|
else:
|
||||||
decomp, comp_len = util.decomp(tables.kCompSpritePtrs[i], ROM.get_byte, False, True)
|
decomp, comp_len = util.decomp(tables.kCompSpritePtrs[i], ROM.get_byte, False, True)
|
||||||
all.append(bytes(ROM.get_bytes(tables.kCompSpritePtrs[i], comp_len)))
|
all.append(bytes(ROM.get_bytes(tables.kCompSpritePtrs[i], comp_len)))
|
||||||
add_asset_uint8('kSprGfx', pack_u32_arrays(all))
|
add_asset_packed('kSprGfx', all)
|
||||||
|
|
||||||
all = []
|
all = []
|
||||||
for i in range(len(tables.kCompBgPtrs)):
|
for i in range(len(tables.kCompBgPtrs)):
|
||||||
decomp, comp_len = util.decomp(tables.kCompBgPtrs[i], ROM.get_byte, False, True)
|
decomp, comp_len = util.decomp(tables.kCompBgPtrs[i], ROM.get_byte, False, True)
|
||||||
all.append(bytes(ROM.get_bytes(tables.kCompBgPtrs[i], comp_len)))
|
all.append(bytes(ROM.get_bytes(tables.kCompBgPtrs[i], comp_len)))
|
||||||
add_asset_uint8('kBgGfx', pack_u32_arrays(all))
|
add_asset_packed('kBgGfx', all)
|
||||||
|
|
||||||
|
def print_dialogue(args):
|
||||||
|
from text_compression import kDialogueFilenames
|
||||||
|
|
||||||
|
languages = ['us']
|
||||||
|
if args.languages:
|
||||||
|
for a in args.languages.split(','):
|
||||||
|
if a in languages or a not in kDialogueFilenames:
|
||||||
|
raise Exception(f'Language {a} is not valid')
|
||||||
|
if not os.path.exists(kDialogueFilenames[a]):
|
||||||
|
raise Exception(f'{kDialogueFilenames[a]} not found. You need to extract it with --extract-dialogue using the ROM of that language.')
|
||||||
|
languages.append(a)
|
||||||
|
|
||||||
def print_misc():
|
all_langs, all_fonts, mappings = [], [], []
|
||||||
|
for i, lang in enumerate(languages):
|
||||||
|
dict_packed = pack_arrays(text_compression.encode_dictionary(lang))
|
||||||
|
dialogue_packed = pack_arrays(compress_dialogue(kDialogueFilenames[lang], lang))
|
||||||
|
all_langs.append(pack_arrays([dict_packed, dialogue_packed]))
|
||||||
|
font_data, font_width = sprite_sheets.encode_font_from_png(lang)
|
||||||
|
all_fonts.append(pack_arrays([font_data, font_width]))
|
||||||
|
mappings.append(pack_arrays([lang.encode('utf8'), bytearray([i, i, i != 0])]))
|
||||||
|
add_asset_packed('kDialogue', all_langs)
|
||||||
|
add_asset_packed('kDialogueFont', all_fonts)
|
||||||
|
add_asset_packed('kDialogueMap', mappings)
|
||||||
|
|
||||||
|
def print_misc(args):
|
||||||
add_asset_uint8('kOverworldMapGfx', ROM.get_bytes(0x18c000, 0x4000))
|
add_asset_uint8('kOverworldMapGfx', ROM.get_bytes(0x18c000, 0x4000))
|
||||||
add_asset_uint8('kLightOverworldTilemap', ROM.get_bytes(0xac727, 4096))
|
add_asset_uint8('kLightOverworldTilemap', ROM.get_bytes(0xac727, 4096))
|
||||||
add_asset_uint8('kDarkOverworldTilemap', ROM.get_bytes(0xaD727, 1024))
|
add_asset_uint8('kDarkOverworldTilemap', ROM.get_bytes(0xaD727, 1024))
|
||||||
|
|
||||||
add_asset_uint16('kPredefinedTileData', ROM.get_words(0x9B52, 6438))
|
add_asset_uint16('kPredefinedTileData', ROM.get_words(0x9B52, 6438))
|
||||||
|
|
||||||
add_asset_uint16('kFontData', ROM.get_words(0xe8000, 2048))
|
|
||||||
|
|
||||||
add_asset_uint16('kMap16ToMap8', ROM.get_words(0x8f8000, 3752 * 4))
|
add_asset_uint16('kMap16ToMap8', ROM.get_words(0x8f8000, 3752 * 4))
|
||||||
|
|
||||||
add_asset_uint8('kGeneratedWishPondItem', ROM.get_bytes(0x888450, 256))
|
add_asset_uint8('kGeneratedWishPondItem', ROM.get_bytes(0x888450, 256))
|
||||||
@@ -175,14 +191,14 @@ def print_overworld():
|
|||||||
addr = ROM.get_24(0x82F94D + i * 3)
|
addr = ROM.get_24(0x82F94D + i * 3)
|
||||||
decomp, comp_len = util.decomp(addr, ROM.get_byte, True, True)
|
decomp, comp_len = util.decomp(addr, ROM.get_byte, True, True)
|
||||||
r.append(bytes(ROM.get_bytes(addr, comp_len)))
|
r.append(bytes(ROM.get_bytes(addr, comp_len)))
|
||||||
add_asset_uint8('kOverworld_Hibytes_Comp', pack_u32_arrays(r))
|
add_asset_packed('kOverworld_Hibytes_Comp', r)
|
||||||
|
|
||||||
r = []
|
r = []
|
||||||
for i in range(160):
|
for i in range(160):
|
||||||
addr = ROM.get_24(0x82FB2D + i * 3)
|
addr = ROM.get_24(0x82FB2D + i * 3)
|
||||||
decomp, comp_len = util.decomp(addr, ROM.get_byte, True, True)
|
decomp, comp_len = util.decomp(addr, ROM.get_byte, True, True)
|
||||||
r.append(bytes(ROM.get_bytes(addr, comp_len)))
|
r.append(bytes(ROM.get_bytes(addr, comp_len)))
|
||||||
add_asset_uint8('kOverworld_Lobytes_Comp', pack_u32_arrays(r))
|
add_asset_packed('kOverworld_Lobytes_Comp', r)
|
||||||
|
|
||||||
def is_area_head(i):
|
def is_area_head(i):
|
||||||
return i >= 128 or ROM.get_byte(0x82A5EC + (i & 63)) == (i & 63)
|
return i >= 128 or ROM.get_byte(0x82A5EC + (i & 63)) == (i & 63)
|
||||||
@@ -430,8 +446,8 @@ def print_dungeon_map():
|
|||||||
b = ROM.get_bytes(addr, nonzero_bytes)
|
b = ROM.get_bytes(addr, nonzero_bytes)
|
||||||
r2.append(bytes(b))
|
r2.append(bytes(b))
|
||||||
|
|
||||||
add_asset_uint8('kDungMap_FloorLayout', pack_u32_arrays(r))
|
add_asset_packed('kDungMap_FloorLayout', r)
|
||||||
add_asset_uint8('kDungMap_Tiles', pack_u32_arrays(r2))
|
add_asset_packed('kDungMap_Tiles', r2)
|
||||||
|
|
||||||
|
|
||||||
@cache
|
@cache
|
||||||
@@ -691,8 +707,6 @@ def print_dungeon_rooms():
|
|||||||
add_asset_uint16('kMovableBlockDataInit', ROM.get_words(0x84f1de, 198))
|
add_asset_uint16('kMovableBlockDataInit', ROM.get_words(0x84f1de, 198))
|
||||||
add_asset_uint16('kTorchDataInit', ROM.get_words(0x84F36A, 144))
|
add_asset_uint16('kTorchDataInit', ROM.get_words(0x84F36A, 144))
|
||||||
add_asset_uint16('kTorchDataJunk', ROM.get_words(0x84F48a, 48))
|
add_asset_uint16('kTorchDataJunk', ROM.get_words(0x84F48a, 48))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def print_enemy_damage_data():
|
def print_enemy_damage_data():
|
||||||
decomp, comp_len = util.decomp(0x83e800, ROM.get_byte, True, True)
|
decomp, comp_len = util.decomp(0x83e800, ROM.get_byte, True, True)
|
||||||
@@ -736,24 +750,21 @@ def print_sound_banks():
|
|||||||
name, data = compile_music.print_song(song)
|
name, data = compile_music.print_song(song)
|
||||||
add_asset_uint8(name, data)
|
add_asset_uint8(name, data)
|
||||||
|
|
||||||
def print_all():
|
def print_all(args):
|
||||||
print_sound_banks()
|
print_sound_banks()
|
||||||
print_dungeon_rooms()
|
print_dungeon_rooms()
|
||||||
print_enemy_damage_data()
|
print_enemy_damage_data()
|
||||||
print_link_graphics()
|
print_link_graphics()
|
||||||
print_dungeon_sprites()
|
print_dungeon_sprites()
|
||||||
print_map32_to_map16()
|
print_map32_to_map16()
|
||||||
print_dialogue()
|
print_images(args)
|
||||||
print_images()
|
print_misc(args)
|
||||||
print_misc()
|
print_dialogue(args)
|
||||||
print_dungeon_map()
|
print_dungeon_map()
|
||||||
print_tilemaps()
|
print_tilemaps()
|
||||||
print_overworld()
|
print_overworld()
|
||||||
print_overworld_tables()
|
print_overworld_tables()
|
||||||
|
|
||||||
print_all()
|
|
||||||
|
|
||||||
|
|
||||||
def write_assets_to_file(print_header = False):
|
def write_assets_to_file(print_header = False):
|
||||||
key_sig = b''
|
key_sig = b''
|
||||||
all_data = []
|
all_data = []
|
||||||
@@ -765,12 +776,17 @@ enum {
|
|||||||
kNumberOfAssets = %d
|
kNumberOfAssets = %d
|
||||||
};
|
};
|
||||||
extern const uint8 *g_asset_ptrs[kNumberOfAssets];
|
extern const uint8 *g_asset_ptrs[kNumberOfAssets];
|
||||||
extern uint32 g_asset_sizes[kNumberOfAssets];''' % len(assets))
|
extern uint32 g_asset_sizes[kNumberOfAssets];
|
||||||
|
extern MemBlk FindInAssetArray(int asset, int idx);
|
||||||
|
''' % len(assets))
|
||||||
|
|
||||||
for i, (k, (tp, data)) in enumerate(assets.items()):
|
for i, (k, (tp, data)) in enumerate(assets.items()):
|
||||||
if print_header:
|
if print_header:
|
||||||
print('#define %s ((%s*)g_asset_ptrs[%d])' % (k, tp, i))
|
if tp == 'packed':
|
||||||
print('#define %s_SIZE (g_asset_sizes[%d])' % (k, i))
|
print('#define %s(idx) FindInAssetArray(%d, idx)' % (k, i))
|
||||||
|
else:
|
||||||
|
print('#define %s ((%s*)g_asset_ptrs[%d])' % (k, tp, i))
|
||||||
|
print('#define %s_SIZE (g_asset_sizes[%d])' % (k, i))
|
||||||
key_sig += k.encode('utf8') + b'\0'
|
key_sig += k.encode('utf8') + b'\0'
|
||||||
all_data.append(data)
|
all_data.append(data)
|
||||||
|
|
||||||
@@ -792,6 +808,17 @@ extern uint32 g_asset_sizes[kNumberOfAssets];''' % len(assets))
|
|||||||
|
|
||||||
open('zelda3_assets.dat', 'wb').write(file_data)
|
open('zelda3_assets.dat', 'wb').write(file_data)
|
||||||
|
|
||||||
write_assets_to_file(False)
|
def main(args):
|
||||||
|
print_all(args)
|
||||||
|
write_assets_to_file(args.print_assets_header)
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
ROM = util.load_rom(sys.argv[1] if len(sys.argv) >= 2 else None)
|
||||||
|
class DefaultArgs:
|
||||||
|
sprites_from_png = False
|
||||||
|
languages = None
|
||||||
|
print_assets_header = False
|
||||||
|
main(DefaultArgs())
|
||||||
|
else:
|
||||||
|
ROM = util.ROM
|
||||||
|
|
||||||
|
|||||||
@@ -240,7 +240,7 @@ def print_all_overworld_areas():
|
|||||||
print_overworld_area(i)
|
print_overworld_area(i)
|
||||||
|
|
||||||
def print_dialogue():
|
def print_dialogue():
|
||||||
text_compression.print_strings(open('dialogue.txt', 'w'), get_byte)
|
text_compression.print_strings(util.ROM, file = open(text_compression.kDialogueFilenames[util.ROM.language], 'w', encoding='utf8'))
|
||||||
|
|
||||||
def decode_room_objects(p):
|
def decode_room_objects(p):
|
||||||
objs = []
|
objs = []
|
||||||
@@ -529,11 +529,13 @@ def print_all_text_stuff():
|
|||||||
def main():
|
def main():
|
||||||
make_directories()
|
make_directories()
|
||||||
print_all_text_stuff()
|
print_all_text_stuff()
|
||||||
extract_music.extract_sound_data(ROM)
|
extract_music.extract_sound_data(util.ROM)
|
||||||
sprite_sheets.decode_link_sprites()
|
sprite_sheets.decode_link_sprites()
|
||||||
sprite_sheets.decode_sprite_sheets()
|
sprite_sheets.decode_sprite_sheets()
|
||||||
|
sprite_sheets.decode_hud_icons()
|
||||||
ROM = util.load_rom(sys.argv[1] if len(sys.argv) >= 2 else None)
|
sprite_sheets.decode_font()
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
util.load_rom(sys.argv[1] if len(sys.argv) >= 2 else None)
|
||||||
|
main()
|
||||||
|
|
||||||
main()
|
|
||||||
#sprite_sheets.decode_sprite_sheets()
|
|
||||||
|
|||||||
BIN
tables/palette_usage.bin
Normal file
BIN
tables/palette_usage.bin
Normal file
Binary file not shown.
48
tables/restool.py
Normal file
48
tables/restool.py
Normal file
@@ -0,0 +1,48 @@
|
|||||||
|
import argparse
|
||||||
|
import util
|
||||||
|
import sys
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description='Resource tool used to build zelda3_assets.dat', allow_abbrev=False)
|
||||||
|
parser.add_argument('-r', '--rom', nargs='?', metavar='ROM')
|
||||||
|
parser.add_argument('--extract-from-rom', '-e', action='store_true', help='Extract/overwrite things from the ROM')
|
||||||
|
|
||||||
|
optional = parser.add_argument_group('Language settings')
|
||||||
|
optional.add_argument('--extract-dialogue', action='store_true', help = 'Extract dialogue from the german ROM')
|
||||||
|
optional.add_argument('--languages', action='store', metavar='L1,L2', help = 'Comma separated list of additional languages to build (de).')
|
||||||
|
|
||||||
|
optional = parser.add_argument_group('Debug things')
|
||||||
|
optional.add_argument('--no-build', action='store_true', help="Don't actually build zelda3_assets.dat")
|
||||||
|
optional.add_argument('--print-strings', action='store_true', help="Print all dialogue strings")
|
||||||
|
optional.add_argument('--print-assets-header', action='store_true')
|
||||||
|
|
||||||
|
optional = parser.add_argument_group('Image handling')
|
||||||
|
optional.add_argument('--sprites-from-png', action='store_true', help="When compiling, load sprites from png instead of from ROM")
|
||||||
|
|
||||||
|
args = parser.parse_args()
|
||||||
|
|
||||||
|
if args.extract_dialogue:
|
||||||
|
ROM = util.load_rom(args.rom, True)
|
||||||
|
import extract_resources, sprite_sheets
|
||||||
|
extract_resources.print_dialogue()
|
||||||
|
sprite_sheets.decode_font()
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
ROM = util.load_rom(args.rom)
|
||||||
|
|
||||||
|
want_compile = True
|
||||||
|
|
||||||
|
if args.extract_from_rom:
|
||||||
|
import extract_resources
|
||||||
|
extract_resources.main()
|
||||||
|
|
||||||
|
if args.print_strings:
|
||||||
|
import text_compression
|
||||||
|
text_compression.print_strings(ROM)
|
||||||
|
want_compile = False
|
||||||
|
|
||||||
|
if want_compile and not args.no_build:
|
||||||
|
import compile_resources
|
||||||
|
compile_resources.main(args)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -4,6 +4,8 @@ import util
|
|||||||
from util import get_bytes, get_words, get_byte, cache
|
from util import get_bytes, get_words, get_byte, cache
|
||||||
import array
|
import array
|
||||||
import tables
|
import tables
|
||||||
|
import sys
|
||||||
|
|
||||||
override_armor_palette = None
|
override_armor_palette = None
|
||||||
#override_armor_palette = [0x7fff, 0x237e, 0x11b7, 0x369e, 0x14a5, 0x1ff, 0x1078, 0x599d, 0x3647, 0x3b68, 0xa4a, 0x12ef, 0x2a5c, 0x1571, 0x7a18,
|
#override_armor_palette = [0x7fff, 0x237e, 0x11b7, 0x369e, 0x14a5, 0x1ff, 0x1078, 0x599d, 0x3647, 0x3b68, 0xa4a, 0x12ef, 0x2a5c, 0x1571, 0x7a18,
|
||||||
# 0x7fff, 0x237e, 0x11b7, 0x369e, 0x14a5, 0x1ff, 0x1078, 0x599d, 0x6980, 0x7691, 0x26b8, 0x437f, 0x2a5c, 0x1199, 0x7a18,
|
# 0x7fff, 0x237e, 0x11b7, 0x369e, 0x14a5, 0x1ff, 0x1078, 0x599d, 0x6980, 0x7691, 0x26b8, 0x437f, 0x2a5c, 0x1199, 0x7a18,
|
||||||
@@ -25,21 +27,20 @@ def save_as_24bpp_png(dimensions, data, fname):
|
|||||||
img.save(fname)
|
img.save(fname)
|
||||||
|
|
||||||
@cache
|
@cache
|
||||||
def decode_2bit_tileset(tileset):
|
def decode_2bit_tileset(tileset, height = 32, base = 0):
|
||||||
data = util.decomp(tables.kCompSpritePtrs[tileset], get_byte, False)
|
data = util.decomp(tables.kCompSpritePtrs[tileset], get_byte, False)
|
||||||
assert len(data) == 0x400
|
assert len(data) == 0x400 * height // 32
|
||||||
height = 32
|
|
||||||
dst = bytearray(128*height)
|
dst = bytearray(128*height)
|
||||||
def decode_2bit(offs, toffs):
|
def decode_2bit(offs, toffs, base):
|
||||||
for y in range(8):
|
for y in range(8):
|
||||||
d0, d1 = data[offs + y * 2], data[offs + y * 2 + 1]
|
d0, d1 = data[offs + y * 2], data[offs + y * 2 + 1]
|
||||||
for x in range(8):
|
for x in range(8):
|
||||||
t = ((d0 >> x) & 1) * 1 + ((d1 >> x) & 1) * 2
|
t = ((d0 >> x) & 1) * 1 + ((d1 >> x) & 1) * 2
|
||||||
dst[toffs + y * 128 + (7 - x)] = t * 255 // 3
|
dst[toffs + y * 128 + (7 - x)] = t + base
|
||||||
for i in range(16*height//8):
|
for i in range(16*height//8):
|
||||||
x = i % 16
|
x = i % 16
|
||||||
y = i // 16
|
y = i // 16
|
||||||
decode_2bit(i * 16, x * 8 + y * 8 * 128)
|
decode_2bit(i * 16, x * 8 + y * 8 * 128, base[i] if isinstance(base, tuple) else base)
|
||||||
return dst
|
return dst
|
||||||
|
|
||||||
def is_high_3bit_tileset(tileset):
|
def is_high_3bit_tileset(tileset):
|
||||||
@@ -109,6 +110,94 @@ def decode_link_sprites():
|
|||||||
kLinkPalette = [0, 0x7fff, 0x237e, 0x11b7, 0x369e, 0x14a5, 0x1ff, 0x1078, 0x599d, 0x3647, 0x3b68, 0xa4a, 0x12ef, 0x2a5c, 0x1571, 0x7a18]
|
kLinkPalette = [0, 0x7fff, 0x237e, 0x11b7, 0x369e, 0x14a5, 0x1ff, 0x1078, 0x599d, 0x3647, 0x3b68, 0xa4a, 0x12ef, 0x2a5c, 0x1571, 0x7a18]
|
||||||
save_as_png((128, 448), decode_4bit_tileset_link(), 'linksprite.png', convert_snes_palette(kLinkPalette))
|
save_as_png((128, 448), decode_4bit_tileset_link(), 'linksprite.png', convert_snes_palette(kLinkPalette))
|
||||||
|
|
||||||
|
def get_hud_snes_palette():
|
||||||
|
hud_palette = get_words(0x9BD660, 64)
|
||||||
|
palette = [(31 << 10 | 31) for i in range(256)]
|
||||||
|
for i in range(16):
|
||||||
|
for j in range(1, 4):
|
||||||
|
palette[i * 16 + j] = hud_palette[i * 4 + j]
|
||||||
|
return palette
|
||||||
|
|
||||||
|
def decode_hud_icons():
|
||||||
|
class PaletteUsage:
|
||||||
|
def __init__(self):
|
||||||
|
self.data = open('palette_usage.bin', 'rb').read()
|
||||||
|
def get(self, icon):
|
||||||
|
usage = self.data[icon]
|
||||||
|
for j in range(8):
|
||||||
|
if usage & (1 << j):
|
||||||
|
return j
|
||||||
|
return 0
|
||||||
|
pu = PaletteUsage()
|
||||||
|
dst = bytearray()
|
||||||
|
for slot, image_set in enumerate([106, 107, 105]):
|
||||||
|
tbase = tuple([pu.get(slot * 128 + i) * 16 for i in range(128)])
|
||||||
|
dst += decode_2bit_tileset(image_set, height = 64, base = tbase)
|
||||||
|
|
||||||
|
save_as_png((128, 64 * 3), dst, 'hud_icons.png', convert_snes_palette(get_hud_snes_palette()[:128]))
|
||||||
|
|
||||||
|
kFontTypes = {
|
||||||
|
'us' : (0xe8000, 256, 'font.png', (0x8ECADF, 99)),
|
||||||
|
'de' : (0xCC6E8, 256, 'font_de.png', (0x8CDECF, 112)),
|
||||||
|
}
|
||||||
|
def decode_font():
|
||||||
|
lang = util.ROM.language
|
||||||
|
def decomp_one_spr_2bit(data, offs, target, toffs, pitch, palette_base):
|
||||||
|
for y in range(8):
|
||||||
|
d0, d1 = data[offs + y * 2], data[offs + y * 2 + 1]
|
||||||
|
for x in range(8):
|
||||||
|
t = ((d0 >> x) & 1) * 1 + ((d1 >> x) & 1) * 2
|
||||||
|
target[toffs + y * pitch + (7 - x)] = t + palette_base
|
||||||
|
ft = kFontTypes[lang]
|
||||||
|
W = get_bytes(*ft[3])
|
||||||
|
w = 128 + 15
|
||||||
|
hi = ft[1] // 32
|
||||||
|
h = hi * 17
|
||||||
|
data = get_bytes(ft[0], ft[1] * 16)
|
||||||
|
dst = bytearray(w * h)
|
||||||
|
for i in range(ft[1]):
|
||||||
|
x, y = i % 16, i // 16
|
||||||
|
pal_base = 6 * 16
|
||||||
|
base_offs = x * 9 + (y * 8 + (y >> 1)) * w
|
||||||
|
decomp_one_spr_2bit(data, i * 16, dst, base_offs + w, w, pal_base)
|
||||||
|
if (y & 1) == 0:
|
||||||
|
j = (y >> 1) * 16 + x
|
||||||
|
if j < len(W):
|
||||||
|
dst[base_offs + W[j] - 1] = 255
|
||||||
|
pal = convert_snes_palette(get_hud_snes_palette()[:128])
|
||||||
|
pal.extend([0] * 384)
|
||||||
|
pal[0], pal[1], pal[2] = 192, 192, 192
|
||||||
|
pal[255*3+0], pal[255*3+1], pal[255*3+2] = 128, 128, 128
|
||||||
|
save_as_png((w, h), dst, ft[2], pal)
|
||||||
|
assert (data, W) == encode_font_from_png(lang)
|
||||||
|
|
||||||
|
def encode_font_from_png(lang):
|
||||||
|
font_data = Image.open(kFontTypes[lang][2]).tobytes()
|
||||||
|
def encode_one_spr_2bit(data, offs, target, toffs, pitch):
|
||||||
|
for y in range(8):
|
||||||
|
d0, d1 = 0, 0
|
||||||
|
for x in range(8):
|
||||||
|
pixel = data[offs + y * pitch + 7 - x]
|
||||||
|
d0 |= (pixel & 1) << x
|
||||||
|
d1 |= ((pixel >> 1) & 1) << x
|
||||||
|
target[toffs + y * 2 + 0], target[toffs + y * 2 + 1] = d0, d1
|
||||||
|
w = 128 + 15
|
||||||
|
dst = bytearray(256 * 16)
|
||||||
|
def get_width(base_offs):
|
||||||
|
for i in range(8):
|
||||||
|
if font_data[base_offs + i] == 255:
|
||||||
|
break
|
||||||
|
return i + 1
|
||||||
|
W = bytearray()
|
||||||
|
for i in range(256):
|
||||||
|
x, y = i % 16, i // 16
|
||||||
|
base_offs = x * 9 + (y * 8 + (y >> 1)) * w
|
||||||
|
if (y & 1) == 0:
|
||||||
|
W.append(get_width(base_offs))
|
||||||
|
encode_one_spr_2bit(font_data, base_offs + w, dst, i * 16, w)
|
||||||
|
chars_per_lang = kFontTypes[lang][3][1]
|
||||||
|
return dst, W[:chars_per_lang]
|
||||||
|
|
||||||
# Returns the dungeon palette for the specified palette index
|
# Returns the dungeon palette for the specified palette index
|
||||||
# 0 = lightworld, 1 = darkworld, 2 = dungeon
|
# 0 = lightworld, 1 = darkworld, 2 = dungeon
|
||||||
@cache
|
@cache
|
||||||
@@ -425,7 +514,6 @@ class MasterTilesheets:
|
|||||||
encode_into((y * 16 + x) * 24, y * 8 * 128 + x * 8)
|
encode_into((y * 16 + x) * 24, y * 8 * 128 + x * 8)
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
||||||
def decode_sprite_sheets():
|
def decode_sprite_sheets():
|
||||||
master_tilesheets = MasterTilesheets()
|
master_tilesheets = MasterTilesheets()
|
||||||
|
|
||||||
@@ -516,3 +604,10 @@ def load_sprite_sheets():
|
|||||||
if not is_empty(src_pos):
|
if not is_empty(src_pos):
|
||||||
master_tilesheets.add_verify_8x8(tileset, pal_lut, img_data, pitch, dst_pos, src_pos)
|
master_tilesheets.add_verify_8x8(tileset, pal_lut, img_data, pitch, dst_pos, src_pos)
|
||||||
return master_tilesheets
|
return master_tilesheets
|
||||||
|
|
||||||
|
#if __name__ == "__main__":
|
||||||
|
# ROM = util.load_rom(sys.argv[1] if len(sys.argv) >= 2 else None, True)
|
||||||
|
# decode_font()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -1,255 +1,315 @@
|
|||||||
|
import util, sys
|
||||||
|
|
||||||
kTextAlphabet = [
|
kTextAlphabet_US = [
|
||||||
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
|
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", # 0 - 15
|
||||||
"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z",
|
"Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", # 16 - 31
|
||||||
|
"g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", # 32 - 47
|
||||||
|
"w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "!", "?", # 48 - 63
|
||||||
|
"-", ".", ",",
|
||||||
|
|
||||||
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m",
|
# 64 - 79
|
||||||
"n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
|
|
||||||
|
|
||||||
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
|
|
||||||
|
|
||||||
# codes 0x3E and up
|
|
||||||
"!", "?", "-", ".", ",",
|
|
||||||
|
|
||||||
# codes 0x43 and up
|
|
||||||
"[...]", ">", "(", ")",
|
"[...]", ">", "(", ")",
|
||||||
|
|
||||||
# codes 0x47 and up
|
|
||||||
"[Ankh]", "[Waves]", "[Snake]", "[LinkL]", "[LinkR]",
|
"[Ankh]", "[Waves]", "[Snake]", "[LinkL]", "[LinkR]",
|
||||||
"\"", "[Up]", "[Down]", "[Left]", "[Right]", "'",
|
"\"", "[Up]", "[Down]", "[Left]",
|
||||||
|
|
||||||
# codes 0x52 and up
|
# 80 - 95
|
||||||
"[1HeartL]", "[1HeartR]", "[2HeartL]", "[3HeartL]",
|
"[Right]", "'", "[1HeartL]", "[1HeartR]", "[2HeartL]", "[3HeartL]", "[3HeartR]",
|
||||||
"[3HeartR]", "[4HeartL]", "[4HeartR]",
|
"[4HeartL]", "[4HeartR]", " ", "<", "[A]", "[B]", "[X]", "[Y]",
|
||||||
|
|
||||||
" ", "<", "[A]", "[B]", "[X]", "[Y]",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
kText_CommandLengths = [1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, ]
|
kTextAlphabet_EU = [
|
||||||
kText_CommandNames = [
|
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", # 0 - 15
|
||||||
"NextPic",
|
"Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d", "e", "f", # 16 - 31
|
||||||
"Choose",
|
"g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", # 32 - 47
|
||||||
"Item",
|
"w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "!", "?", # 48 - 63
|
||||||
"Name",
|
|
||||||
"Window",
|
|
||||||
"Number",
|
# 64 - 79
|
||||||
"Position",
|
"-", ".", ",", "[...]", ">", "(", ")",
|
||||||
"ScrollSpd",
|
"[Ankh]", "[Waves]", "[Snake]", "[LinkL]", "[LinkR]",
|
||||||
"Selchg",
|
"\"", "[UpL]", "[UpR]", "[LeftL]",
|
||||||
"Crash",
|
|
||||||
"Choose3",
|
|
||||||
"Choose2",
|
# 80 - 95
|
||||||
"Scroll",
|
"[LeftR]", "'", "[1HeartL]", "[1HeartR]", "[2HeartL]", "[3HeartL]", "[3HeartR]",
|
||||||
"1",
|
"[4HeartL]", "[4HeartR]", " ", "ö", "[A]", "[B]", "[X]", "[Y]", "ü",
|
||||||
"2",
|
|
||||||
"3",
|
# 96-111
|
||||||
"Color",
|
"ß", ":", "[DownL]", "[DownR]", "[RightL]", "[RightR]", "è", "é", "ê", "à", "ù", "ç", "Ä", "Ö", "Ü", "ä"
|
||||||
"Wait",
|
|
||||||
"Sound",
|
# 112-
|
||||||
"Speed",
|
|
||||||
"Mark",
|
|
||||||
"Mark2",
|
|
||||||
"Clear",
|
|
||||||
"Waitkey",
|
|
||||||
"EndMessage"
|
|
||||||
]
|
]
|
||||||
|
|
||||||
kTextDictionary = [ 0x59, 0x59, 0x59, 0x59,
|
kText_CommandLengths_US = [1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, ]
|
||||||
0x59, 0x59, 0x59,
|
kText_CommandNames_US = [
|
||||||
0x59, 0x59,
|
"NextPic", "Choose", "Item", "Name", "Window", "Number",
|
||||||
0x51, 0x2c, 0x59,
|
"Position","ScrollSpd", "Selchg", "Unused_Crash", "Choose3",
|
||||||
0x1a, 0x27, 0x1d, 0x59,
|
"Choose2", "Scroll", "1", "2", "3", "Color",
|
||||||
0x1a, 0x2b, 0x1e, 0x59,
|
"Wait", "Sound", "Speed", "Unused_Mark", "Unused_Mark2", "Unused_Clear",
|
||||||
0x1a, 0x25, 0x25, 0x59,
|
"Waitkey"
|
||||||
0x1a, 0x22, 0x27,
|
|
||||||
0x1a, 0x27, 0x1d,
|
|
||||||
0x1a, 0x2d, 0x59,
|
|
||||||
0x1a, 0x2c, 0x2d,
|
|
||||||
0x1a, 0x27,
|
|
||||||
0x1a, 0x2d,
|
|
||||||
0x1b, 0x25, 0x1e,
|
|
||||||
0x1b, 0x1a,
|
|
||||||
0x1b, 0x1e,
|
|
||||||
0x1b, 0x28,
|
|
||||||
0x1c, 0x1a, 0x27, 0x59,
|
|
||||||
0x1c, 0x21, 0x1e,
|
|
||||||
0x1c, 0x28, 0x26,
|
|
||||||
0x1c, 0x24,
|
|
||||||
0x1d, 0x1e, 0x2c,
|
|
||||||
0x1d, 0x22,
|
|
||||||
0x1d, 0x28,
|
|
||||||
0x1e, 0x27, 0x59,
|
|
||||||
0x1e, 0x2b, 0x59,
|
|
||||||
0x1e, 0x1a, 0x2b,
|
|
||||||
0x1e, 0x27, 0x2d,
|
|
||||||
0x1e, 0x1d, 0x59,
|
|
||||||
0x1e, 0x27,
|
|
||||||
0x1e, 0x2b,
|
|
||||||
0x1e, 0x2f,
|
|
||||||
0x1f, 0x28, 0x2b,
|
|
||||||
0x1f, 0x2b, 0x28,
|
|
||||||
0x20, 0x22, 0x2f, 0x1e, 0x59,
|
|
||||||
0x20, 0x1e, 0x2d,
|
|
||||||
0x20, 0x28,
|
|
||||||
0x21, 0x1a, 0x2f, 0x1e,
|
|
||||||
0x21, 0x1a, 0x2c,
|
|
||||||
0x21, 0x1e, 0x2b,
|
|
||||||
0x21, 0x22,
|
|
||||||
0x21, 0x1a,
|
|
||||||
0x22, 0x20, 0x21, 0x2d, 0x59,
|
|
||||||
0x22, 0x27, 0x20, 0x59,
|
|
||||||
0x22, 0x27,
|
|
||||||
0x22, 0x2c,
|
|
||||||
0x22, 0x2d,
|
|
||||||
0x23, 0x2e, 0x2c, 0x2d,
|
|
||||||
0x24, 0x27, 0x28, 0x30,
|
|
||||||
0x25, 0x32, 0x59,
|
|
||||||
0x25, 0x1a,
|
|
||||||
0x25, 0x28,
|
|
||||||
0x26, 0x1a, 0x27,
|
|
||||||
0x26, 0x1a,
|
|
||||||
0x26, 0x1e,
|
|
||||||
0x26, 0x2e,
|
|
||||||
0x27, 0x51, 0x2d, 0x59,
|
|
||||||
0x27, 0x28, 0x27,
|
|
||||||
0x27, 0x28, 0x2d,
|
|
||||||
0x28, 0x29, 0x1e, 0x27,
|
|
||||||
0x28, 0x2e, 0x27, 0x1d,
|
|
||||||
0x28, 0x2e, 0x2d, 0x59,
|
|
||||||
0x28, 0x1f,
|
|
||||||
0x28, 0x27,
|
|
||||||
0x28, 0x2b,
|
|
||||||
0x29, 0x1e, 0x2b,
|
|
||||||
0x29, 0x25, 0x1e,
|
|
||||||
0x29, 0x28, 0x30,
|
|
||||||
0x29, 0x2b, 0x28,
|
|
||||||
0x2b, 0x1e, 0x59,
|
|
||||||
0x2b, 0x1e,
|
|
||||||
0x2c, 0x28, 0x26, 0x1e,
|
|
||||||
0x2c, 0x1e,
|
|
||||||
0x2c, 0x21,
|
|
||||||
0x2c, 0x28,
|
|
||||||
0x2c, 0x2d,
|
|
||||||
0x2d, 0x1e, 0x2b, 0x59,
|
|
||||||
0x2d, 0x21, 0x22, 0x27,
|
|
||||||
0x2d, 0x1e, 0x2b,
|
|
||||||
0x2d, 0x21, 0x1a,
|
|
||||||
0x2d, 0x21, 0x1e,
|
|
||||||
0x2d, 0x21, 0x22,
|
|
||||||
0x2d, 0x28,
|
|
||||||
0x2d, 0x2b,
|
|
||||||
0x2e, 0x29,
|
|
||||||
0x2f, 0x1e, 0x2b,
|
|
||||||
0x30, 0x22, 0x2d, 0x21,
|
|
||||||
0x30, 0x1a,
|
|
||||||
0x30, 0x1e,
|
|
||||||
0x30, 0x21,
|
|
||||||
0x30, 0x22,
|
|
||||||
0x32, 0x28, 0x2e,
|
|
||||||
0x7, 0x1e, 0x2b,
|
|
||||||
0x13, 0x21, 0x1a,
|
|
||||||
0x13, 0x21, 0x1e,
|
|
||||||
0x13, 0x21, 0x22,
|
|
||||||
0x18, 0x28, 0x2e,
|
|
||||||
]
|
]
|
||||||
|
|
||||||
kTextDictionary_Idx = [
|
kTextDictionary_US = [
|
||||||
0, 4, 7, 9, 12, 16, 20, 24, 27, 30, 33, 36, 38, 40, 43, 45, 47, 49, 53, 56, 59, 61, 64, 66, 68, 71, 74, 77, 80, 83, 85, 87, 89, 92, 95, 100, 103, 105, 109, 112, 115, 117, 119, 124, 128, 130, 132, 134, 138, 142, 145, 147, 149, 152, 154, 156, 158, 162, 165, 168, 172, 176, 180, 182, 184, 186, 189, 192, 195, 198, 201, 203, 207, 209, 211, 213, 215, 219, 223, 226, 229, 232, 235, 237, 239, 241, 244, 248, 250, 252, 254, 256, 259, 262, 265, 268, 271, 274
|
' ', ' ', ' ', "'s ", 'and ',
|
||||||
|
'are ', 'all ', 'ain', 'and', 'at ',
|
||||||
|
'ast', 'an', 'at', 'ble', 'ba',
|
||||||
|
'be', 'bo', 'can ', 'che', 'com',
|
||||||
|
'ck', 'des', 'di', 'do', 'en ',
|
||||||
|
'er ', 'ear', 'ent', 'ed ', 'en',
|
||||||
|
'er', 'ev', 'for', 'fro', 'give ',
|
||||||
|
'get', 'go', 'have', 'has', 'her',
|
||||||
|
'hi', 'ha', 'ight ', 'ing ', 'in',
|
||||||
|
'is', 'it', 'just', 'know', 'ly ',
|
||||||
|
'la', 'lo', 'man', 'ma', 'me',
|
||||||
|
'mu', "n't ", 'non', 'not', 'open',
|
||||||
|
'ound', 'out ', 'of', 'on', 'or',
|
||||||
|
'per', 'ple', 'pow', 'pro', 're ',
|
||||||
|
're', 'some', 'se', 'sh', 'so',
|
||||||
|
'st', 'ter ', 'thin', 'ter', 'tha',
|
||||||
|
'the', 'thi', 'to', 'tr', 'up',
|
||||||
|
'ver', 'with', 'wa', 'we', 'wh',
|
||||||
|
'wi', 'you', 'Her', 'Tha', 'The',
|
||||||
|
'Thi', 'You',
|
||||||
]
|
]
|
||||||
|
|
||||||
def make_dict():
|
|
||||||
r, rinv = {}, {}
|
|
||||||
for i in range(len(kTextDictionary_Idx) - 1):
|
|
||||||
ln = kTextDictionary_Idx[i + 1] - kTextDictionary_Idx[i]
|
|
||||||
idx = kTextDictionary_Idx[i]
|
|
||||||
s = "".join(kTextAlphabet[kTextDictionary[idx+i]] for i in range(ln))
|
|
||||||
r[i] = s
|
|
||||||
rinv[s] = i
|
|
||||||
return r, rinv
|
|
||||||
|
|
||||||
kTextDictionary_Ascii, kTextDictionary_AsciiBack = make_dict()
|
kText_CommandLengths_EU = [1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2]
|
||||||
|
kText_CommandNames_EU = [
|
||||||
|
"Selchg", "Choose3", "Choose2", "Scroll", "1", "2", "3",
|
||||||
|
"Color", "Wait", "Sound", "Speed", "Mark", "Mark2",
|
||||||
|
"Clear", "Waitkey", "EndMessage", "NextPic", "Choose",
|
||||||
|
"Item", "Name", "Window", "Number", "Position", "ScrollSpd",
|
||||||
|
]
|
||||||
|
|
||||||
def decode_strings(get_byte):
|
kTextDictionary_DE = [
|
||||||
p = 0x9c8000
|
' ', ' ', ' ', '-Knopf', ' ich ',
|
||||||
|
' Sch', ' Ver', ' zu ', ' es ', 'aber',
|
||||||
|
'alle', 'auch', 'ang', 'aus', 'auf',
|
||||||
|
'an', 'bist', 'bin', 'bei', 'der ',
|
||||||
|
'die ', 'das ', 'den ', 'dem ', 'daß',
|
||||||
|
'der', 'die', 'das', 'den', 'da',
|
||||||
|
'etwas', 'ein ', 'ein', 'en ', 'er ',
|
||||||
|
'es ', 'en', 'er', 'es', 'ei',
|
||||||
|
'für', 'fe', 'habe', 'hier', 'hast',
|
||||||
|
'her', 'ich ', 'icht', 'ich', 'ist',
|
||||||
|
'ie ', 'im', 'ie', 'kannst ', 'kannst',
|
||||||
|
'kommen', 'kann ', 'll', 'mich', 'mein',
|
||||||
|
'mit', 'mal', 'mir', 'nicht ', 'nicht',
|
||||||
|
'nen', 'nn', 'och ', 'och', 'or',
|
||||||
|
'schon', 'sich', 'sein', 'sch', 'sie',
|
||||||
|
'st', 'tte', 'te ', 'te', 'und ',
|
||||||
|
'und', 'ung', 'um', 'von', 'ver',
|
||||||
|
'vor', 'wird', 'zu ', 'Amulett', 'Aber',
|
||||||
|
'Deine', 'Dich ', 'Dir ', 'Dir', 'Der',
|
||||||
|
'Die', 'Das', 'Du ', 'Du', 'Da',
|
||||||
|
'Ein', 'Hyrule', 'Hier', 'Ich ', 'Master-Schwert',
|
||||||
|
'Mach', 'Rubine', 'Sch', 'Sie', 'Ver',
|
||||||
|
'Weisen', 'Zelda',
|
||||||
|
]
|
||||||
|
|
||||||
|
class LangUS:
|
||||||
|
alphabet = kTextAlphabet_US
|
||||||
|
dictionary = kTextDictionary_US
|
||||||
|
command_lengths = kText_CommandLengths_US
|
||||||
|
command_names = kText_CommandNames_US
|
||||||
|
rom_addrs = [0x9c8000, 0x8edf40]
|
||||||
|
COMMAND_START = 0x67
|
||||||
|
SWITCH_BANK = 0x80
|
||||||
|
FINISH = 0xff
|
||||||
|
DICT_BASE_ENC, DICT_BASE_DEC = 0x88, 0x88
|
||||||
|
def encode_command(self, cmd_index, param):
|
||||||
|
name = self.command_names[cmd_index]
|
||||||
|
if param == None:
|
||||||
|
return [cmd_index + self.COMMAND_START]
|
||||||
|
return [cmd_index + self.COMMAND_START, int(param)]
|
||||||
|
|
||||||
|
class LangDE:
|
||||||
|
alphabet = kTextAlphabet_EU
|
||||||
|
dictionary = kTextDictionary_DE
|
||||||
|
command_lengths = kText_CommandLengths_EU
|
||||||
|
command_names = kText_CommandNames_EU
|
||||||
|
rom_addrs = [0x9c8000, 0x8CEB00]
|
||||||
|
COMMAND_START = 0x70
|
||||||
|
SWITCH_BANK = 0x88
|
||||||
|
FINISH = 0x8f
|
||||||
|
DICT_BASE_ENC, DICT_BASE_DEC = 0x88, 0x90
|
||||||
|
US = False
|
||||||
|
|
||||||
|
kCmdInfo = {
|
||||||
|
"Scroll" : (0x80, ),
|
||||||
|
"Waitkey" : (0x81, ),
|
||||||
|
"1" : (0x82, ),
|
||||||
|
"2" : (0x83, ),
|
||||||
|
"3" : (0x84, ),
|
||||||
|
"Name" : (0x85, ),
|
||||||
|
"Wait" : (0x87, {i:i+0x00 for i in range(16)}),
|
||||||
|
"Color" : (0x87, {i:i+0x10 for i in range(16)}),
|
||||||
|
"Number" : (0x87, {i:i+0x20 for i in range(16)}),
|
||||||
|
"Speed" : (0x87, {i:i+0x30 for i in range(16)}),
|
||||||
|
"Sound" : (0x87, {45 : 0x40}),
|
||||||
|
"Choose" : (0x87, 0x80),
|
||||||
|
"Choose2" : (0x87, 0x81),
|
||||||
|
"Choose3" : (0x87, 0x82),
|
||||||
|
"Selchg" : (0x87, 0x83),
|
||||||
|
"Item" : (0x87, 0x84),
|
||||||
|
"NextPic" : (0x87, 0x85),
|
||||||
|
"Window" : (0x87, {0 : None, 2 : 0x86}),
|
||||||
|
"Position" : (0x87, {0: 0x87, 1: 0x88}),
|
||||||
|
"ScrollSpd" : (0, {0 : None}),
|
||||||
|
}
|
||||||
|
|
||||||
|
def encode_command(self, cmd_index, param):
|
||||||
|
info = self.kCmdInfo[self.command_names[cmd_index]]
|
||||||
|
if len(info) <= 1 or isinstance(info[1], int):
|
||||||
|
assert param == None
|
||||||
|
return info
|
||||||
|
else:
|
||||||
|
assert param != None
|
||||||
|
r = info[1][param]
|
||||||
|
return (info[0], r) if r != None else ()
|
||||||
|
|
||||||
|
kLanguages = {
|
||||||
|
'us' : LangUS(),
|
||||||
|
'de' : LangDE(),
|
||||||
|
}
|
||||||
|
|
||||||
|
kDialogueFilenames = {
|
||||||
|
'us' : 'dialogue.txt',
|
||||||
|
'de' : 'dialogue_de.txt',
|
||||||
|
}
|
||||||
|
|
||||||
|
dict_expansion = []
|
||||||
|
|
||||||
|
def decode_strings_generic(get_byte, lang):
|
||||||
|
info = kLanguages[lang]
|
||||||
|
p, rom_idx = info.rom_addrs[0], 1
|
||||||
result = []
|
result = []
|
||||||
while True:
|
while True:
|
||||||
org_p = p
|
s, srcdata = '', []
|
||||||
#print('0x%x' % p)
|
|
||||||
s = ''
|
|
||||||
srcdata = []
|
|
||||||
while True:
|
while True:
|
||||||
c = get_byte(p)
|
c = get_byte(p)
|
||||||
srcdata.append(c)
|
srcdata.append(c)
|
||||||
l = kText_CommandLengths[c - 0x67] if c >= 0x67 and c < 0x80 else 1
|
l = info.command_lengths[c - info.COMMAND_START] if c >= info.COMMAND_START and c < info.SWITCH_BANK else 1
|
||||||
|
|
||||||
p += l
|
p += l
|
||||||
if c == 0x7f:
|
if c == 0x7f: # EndMessage
|
||||||
break
|
break
|
||||||
if c < 0x67:
|
if c < info.COMMAND_START:
|
||||||
s += kTextAlphabet[c]
|
s += info.alphabet[c]
|
||||||
elif c < 0x80:
|
elif c < info.SWITCH_BANK:
|
||||||
if l == 2:
|
if l == 2:
|
||||||
srcdata.append(get_byte(p-1))
|
srcdata.append(get_byte(p - 1))
|
||||||
s += '[%s %.2d]' % (kText_CommandNames[c - 0x67], get_byte(p-1))
|
s += '[%s %.2d]' % (info.command_names[c - info.COMMAND_START], get_byte(p - 1))
|
||||||
else:
|
else:
|
||||||
s += '[%s]' % kText_CommandNames[c - 0x67]
|
s += '[%s]' % info.command_names[c - info.COMMAND_START]
|
||||||
elif c == 0x80:
|
elif c == info.FINISH:
|
||||||
p = 0x8edf40
|
return result # done
|
||||||
s = None
|
elif c == info.SWITCH_BANK:
|
||||||
break
|
p = info.rom_addrs[rom_idx]; rom_idx += 1
|
||||||
elif c > 0x80 and c < 0x88:
|
s, srcdata = '', []
|
||||||
|
elif c < info.SWITCH_BANK + 8:
|
||||||
assert 0
|
assert 0
|
||||||
elif c == 0xff:
|
|
||||||
return result
|
|
||||||
else:
|
else:
|
||||||
s += kTextDictionary_Ascii[c - 0x88]
|
s += info.dictionary[c - info.DICT_BASE_DEC]
|
||||||
if s != None:
|
dict_expansion.append(len(info.dictionary[c - info.DICT_BASE_DEC]))
|
||||||
result.append((s, srcdata))
|
|
||||||
|
|
||||||
def print_strings(f, get_byte):
|
|
||||||
for i, s in enumerate(decode_strings(get_byte)):
|
|
||||||
print('%s: %s' % (i + 1, s[0]), file = f)
|
|
||||||
|
|
||||||
def find_string_char_at(s, i):
|
result.append((s, srcdata))
|
||||||
|
|
||||||
|
|
||||||
|
def print_strings(rom, file = None):
|
||||||
|
texts = decode_strings_generic(rom.get_byte, rom.language)
|
||||||
|
if len(texts) == 396:
|
||||||
|
extra_str = "[Speed 00]0- [Number 00]. 1- [Number 01][2]2- [Number 02]. 3- [Number 03]"
|
||||||
|
texts = texts[:4] + [(extra_str, None)] + texts[4:]
|
||||||
|
|
||||||
|
for i, s in enumerate(texts):
|
||||||
|
print('%s: %s' % (i + 1, s[0]), file = file)
|
||||||
|
|
||||||
|
|
||||||
|
def encode_greedy_from_dict(s, i, rev, a2i, info):
|
||||||
a = s[i:]
|
a = s[i:]
|
||||||
|
if r := rev.get(a[0]):
|
||||||
|
for k, v in r.items():
|
||||||
|
if a.startswith(k):
|
||||||
|
return [v + info.DICT_BASE_ENC], len(k)
|
||||||
|
|
||||||
for k, v in kTextDictionary_AsciiBack.items():
|
if a[0] == '[':
|
||||||
if a.startswith(k):
|
cmd, param = a[1:a.index(']')], None
|
||||||
return [v + 0x88], len(k)
|
cmdlen = len(cmd)
|
||||||
|
if r := a2i.get(a[:cmdlen+2]):
|
||||||
|
return [r], cmdlen+2
|
||||||
|
if ' ' in cmd:
|
||||||
|
cmd, param = cmd.split(' ', 1)
|
||||||
|
param = int(param)
|
||||||
|
if cmd not in info.command_names:
|
||||||
|
raise Exception(f'Invalid cmd {cmd}')
|
||||||
|
i = info.command_names.index(cmd)
|
||||||
|
if info.command_lengths[i] != (1 if param == None else 2):
|
||||||
|
raise Exception(f'Invalid cmd params {cmd} {param}')
|
||||||
|
return info.encode_command(i, param), cmdlen + 2
|
||||||
|
else:
|
||||||
|
return [a2i[a[0]]], 1
|
||||||
|
|
||||||
for i, s in enumerate(kTextAlphabet):
|
|
||||||
if a.startswith(s):
|
|
||||||
return [i], len(s)
|
|
||||||
|
|
||||||
if a.startswith('['):
|
|
||||||
cmd = a[1:a.index(']')]
|
|
||||||
if cmd in kText_CommandNames:
|
|
||||||
i = kText_CommandNames.index(cmd)
|
|
||||||
return [i + 0x67], len(cmd) + 2
|
|
||||||
|
|
||||||
for i, s in enumerate(kText_CommandNames):
|
|
||||||
if kText_CommandLengths[i] == 2 and cmd.startswith(s):
|
|
||||||
e = cmd[len(s):].strip()
|
|
||||||
return [i + 0x67, int(e)], len(cmd) + 2
|
|
||||||
|
|
||||||
print('substr %s not found' % a)
|
print('substr %s not found' % a)
|
||||||
assert 0
|
assert 0
|
||||||
|
|
||||||
def compress_string(s):
|
def compress_strings(xs, lang = 'us'):
|
||||||
# find the greedy best match
|
info = kLanguages[lang]
|
||||||
i = 0
|
rev = {}
|
||||||
r = []
|
for a,b in enumerate(info.dictionary):
|
||||||
while i < len(s):
|
rev.setdefault(b[0], {})[b] = a
|
||||||
what, num = find_string_char_at(s, i)
|
#rev = {b:a for a,b in enumerate(info.dictionary)}
|
||||||
r.extend(what)
|
a2i = {e:i for i,e in enumerate(info.alphabet)}
|
||||||
i += num
|
def compress_string(s):
|
||||||
r.append(0x7f)
|
i = 0
|
||||||
return r
|
r = bytearray()
|
||||||
|
while i < len(s):
|
||||||
|
what, num = encode_greedy_from_dict(s, i, rev, a2i, info)
|
||||||
|
r.extend(what)
|
||||||
|
i += num
|
||||||
|
return r
|
||||||
|
return [compress_string(x) for x in xs]
|
||||||
|
|
||||||
def verify(get_byte):
|
def verify(get_byte):
|
||||||
for i, (decoded, original) in enumerate(decode_strings(get_byte)):
|
for i, (decoded, original) in enumerate(decode_strings_generic(get_byte, 'us')):
|
||||||
c = compress_string(decoded)
|
c = compress_strings([decoded])[0]
|
||||||
if c != original:
|
if c != original:
|
||||||
print('String %s not match: %s, %s' % (decoded, c, original))
|
print('String %s not match: %s, %s' % (decoded, c, original))
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def encode_dictionary(lang = 'us'):
|
||||||
|
info = kLanguages[lang]
|
||||||
|
rev = {b:a for a,b in enumerate(info.alphabet)}
|
||||||
|
return [bytearray(rev[c] for c in line) for line in info.dictionary]
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
ROM = util.load_rom(sys.argv[1] if len(sys.argv) >= 2 else None, True)
|
||||||
|
|
||||||
|
decoded = decode_strings_generic(ROM.get_byte, 'de')
|
||||||
|
print('Total bytes: %d' % sum(len(a[1]) for a in decoded))
|
||||||
|
|
||||||
|
print('Dict tokens: %d' % len(dict_expansion))
|
||||||
|
print('Dict save: %d' % (sum(dict_expansion) - len(dict_expansion)))
|
||||||
|
|
||||||
|
print('US size ', len(kTextDictionary_US))
|
||||||
|
print('DE size ', len(kTextDictionary_DE))
|
||||||
|
|
||||||
|
texts = [a[0] for a in decoded]
|
||||||
|
|
||||||
|
|
||||||
|
# Pal seems to have one string too little
|
||||||
|
if len(texts) == 396:
|
||||||
|
extra_str = "[Speed 00]0- [Number 00]. 1- [Number 01][2]2- [Number 02]. 3- [Number 03]"
|
||||||
|
texts = texts[:4] + [extra_str] + texts[4:]
|
||||||
|
|
||||||
|
#for i, s in enumerate(texts):
|
||||||
|
# print('%s: %s' % (i + 1, s), file = None)
|
||||||
|
|
||||||
|
|
||||||
|
#encode_dictionary()
|
||||||
|
compr = compress_strings(texts, 'de')
|
||||||
|
print(f'Compressed size (excl eof): {sum(len(a) for a in compr)}')
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,11 +11,16 @@ def cache(user_function):
|
|||||||
# Both are common SNES rom extensions. For Zelda3 (NA), they are equivalent files.
|
# Both are common SNES rom extensions. For Zelda3 (NA), they are equivalent files.
|
||||||
COMMON_ROM_NAMES = ['zelda3.sfc', 'zelda3.smc']
|
COMMON_ROM_NAMES = ['zelda3.sfc', 'zelda3.smc']
|
||||||
DEFAULT_ROM_DIRECTORY = os.path.dirname(__file__)
|
DEFAULT_ROM_DIRECTORY = os.path.dirname(__file__)
|
||||||
ZELDA3_SHA256 = '66871d66be19ad2c34c927d6b14cd8eb6fc3181965b6e517cb361f7316009cfb'
|
|
||||||
|
|
||||||
def load_rom(filename):
|
ZELDA3_SHA256_US = '66871d66be19ad2c34c927d6b14cd8eb6fc3181965b6e517cb361f7316009cfb'
|
||||||
|
ZELDA3_SHA256 = {
|
||||||
|
'030ff80d0087bca440094cd914c03da0aa199dc6edb9adfb43f1267e99fde45f' : 'de',
|
||||||
|
ZELDA3_SHA256_US : 'us',
|
||||||
|
}
|
||||||
|
|
||||||
|
def load_rom(filename, support_multilanguage = False):
|
||||||
global ROM
|
global ROM
|
||||||
ROM = LoadedRom(filename)
|
ROM = LoadedRom(filename, support_multilanguage)
|
||||||
return ROM
|
return ROM
|
||||||
|
|
||||||
def get_byte(addr):
|
def get_byte(addr):
|
||||||
@@ -44,12 +49,18 @@ def get_word(addr):
|
|||||||
|
|
||||||
|
|
||||||
class LoadedRom:
|
class LoadedRom:
|
||||||
def __init__(self, path = None):
|
def __init__(self, path = None, support_multilanguage = False):
|
||||||
rom_path = self.__get_rom_path(path)
|
rom_path = self.__get_rom_path(path)
|
||||||
self.ROM = open(rom_path, 'rb').read()
|
self.ROM = open(rom_path, 'rb').read()
|
||||||
hash = hashlib.sha256(self.ROM).hexdigest()
|
hash = hashlib.sha256(self.ROM).hexdigest()
|
||||||
if hash != ZELDA3_SHA256:
|
self.language = ZELDA3_SHA256.get(hash)
|
||||||
raise Exception(f"ROM with hash {hash} not supported. Expected {ZELDA3_SHA256}. Please verify your ROM is the NA 1.0 version.");
|
|
||||||
|
if support_multilanguage:
|
||||||
|
if self.language == None:
|
||||||
|
raise Exception(f"ROM with hash {hash} not supported.");
|
||||||
|
else:
|
||||||
|
if self.language != 'us':
|
||||||
|
raise Exception(f"ROM with hash {hash} not supported. Expected {ZELDA3_SHA256_US}. Please verify your ROM is the NA 1.0 version.");
|
||||||
|
|
||||||
def get_byte(self, ea):
|
def get_byte(self, ea):
|
||||||
assert (ea & 0x8000)
|
assert (ea & 0x8000)
|
||||||
|
|||||||
3
third_party/.gitignore
vendored
3
third_party/.gitignore
vendored
@@ -1,4 +1,3 @@
|
|||||||
/tcc/
|
/tcc/
|
||||||
/SDL2-2.24.0/
|
/SDL2-2.*/
|
||||||
/SDL2-2.24.1/
|
|
||||||
/gl_core/*.o
|
/gl_core/*.o
|
||||||
6
types.h
6
types.h
@@ -92,6 +92,12 @@ typedef struct OamEnt {
|
|||||||
uint8 x, y, charnum, flags;
|
uint8 x, y, charnum, flags;
|
||||||
} OamEnt;
|
} OamEnt;
|
||||||
|
|
||||||
|
typedef struct MemBlk {
|
||||||
|
const uint8 *ptr;
|
||||||
|
size_t size;
|
||||||
|
} MemBlk;
|
||||||
|
MemBlk FindIndexInMemblk(MemBlk data, size_t i);
|
||||||
|
|
||||||
void NORETURN Die(const char *error);
|
void NORETURN Die(const char *error);
|
||||||
|
|
||||||
#endif // ZELDA3_TYPES_H_
|
#endif // ZELDA3_TYPES_H_
|
||||||
|
|||||||
23
util.c
23
util.c
@@ -170,3 +170,26 @@ void ByteArray_AppendByte(ByteArray *arr, uint8 v) {
|
|||||||
ByteArray_Resize(arr, arr->size + 1);
|
ByteArray_Resize(arr, arr->size + 1);
|
||||||
arr->data[arr->size - 1] = v;
|
arr->data[arr->size - 1] = v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Automatically selects between 16 or 32 bit indexes. Can hold up to 8192 elements in 16-bit mode.
|
||||||
|
MemBlk FindIndexInMemblk(MemBlk data, size_t i) {
|
||||||
|
if (data.size < 2)
|
||||||
|
return (MemBlk) { 0, 0 };
|
||||||
|
size_t end = data.size - 2, left_off, right_off;
|
||||||
|
size_t mx = *(uint16 *)(data.ptr + end);
|
||||||
|
if (mx < 8192) {
|
||||||
|
if (i > mx || mx * 2 > end)
|
||||||
|
return (MemBlk) { 0, 0 };
|
||||||
|
left_off = ((i == 0) ? mx * 2 : mx * 2 + *(uint16 *)(data.ptr + i * 2 - 2));
|
||||||
|
right_off = (i == mx) ? end : mx * 2 + *(uint16 *)(data.ptr + i * 2);
|
||||||
|
} else {
|
||||||
|
mx -= 8192;
|
||||||
|
if (i > mx || mx * 4 > end)
|
||||||
|
return (MemBlk) { 0, 0 };
|
||||||
|
left_off = ((i == 0) ? mx * 4 : mx * 4 + *(uint32 *)(data.ptr + i * 4 - 4));
|
||||||
|
right_off = (i == mx) ? end : mx * 4 + *(uint32 *)(data.ptr + i * 4);
|
||||||
|
}
|
||||||
|
if (left_off > right_off || right_off > end)
|
||||||
|
return (MemBlk) { 0, 0 };
|
||||||
|
return (MemBlk) { data.ptr + left_off, right_off - left_off };
|
||||||
|
}
|
||||||
|
|||||||
12
variables.h
12
variables.h
@@ -814,12 +814,12 @@
|
|||||||
#define text_msgbox_topleft_copy (*(uint16*)(g_ram+0x1CD0))
|
#define text_msgbox_topleft_copy (*(uint16*)(g_ram+0x1CD0))
|
||||||
#define text_msgbox_topleft (*(uint16*)(g_ram+0x1CD2))
|
#define text_msgbox_topleft (*(uint16*)(g_ram+0x1CD2))
|
||||||
#define text_render_state (*(uint8*)(g_ram+0x1CD4))
|
#define text_render_state (*(uint8*)(g_ram+0x1CD4))
|
||||||
#define vwf_line_mode (*(uint8*)(g_ram+0x1CD5))
|
#define vwf_line_speed_cur (*(uint8*)(g_ram+0x1CD5))
|
||||||
#define vwf_line_speed (*(uint8*)(g_ram+0x1CD6))
|
#define vwf_line_speed (*(uint8*)(g_ram+0x1CD6))
|
||||||
#define text_incremental_state (*(uint8*)(g_ram+0x1CD7))
|
#define text_incremental_state (*(uint8*)(g_ram+0x1CD7))
|
||||||
#define messaging_module (*(uint8*)(g_ram+0x1CD8))
|
#define messaging_module (*(uint8*)(g_ram+0x1CD8))
|
||||||
#define dialogue_msg_dst_offs (*(uint16*)(g_ram+0x1CD9))
|
#define dialogue_msg_read_pos (*(uint16*)(g_ram+0x1CD9))
|
||||||
#define byte_7E1CDC (*(uint8*)(g_ram+0x1CDC))
|
#define dialogue_text_color (*(uint8*)(g_ram+0x1CDC))
|
||||||
#define dialogue_msg_src_offs (*(uint16*)(g_ram+0x1CDD))
|
#define dialogue_msg_src_offs (*(uint16*)(g_ram+0x1CDD))
|
||||||
#define byte_7E1CDF (*(uint8*)(g_ram+0x1CDF))
|
#define byte_7E1CDF (*(uint8*)(g_ram+0x1CDF))
|
||||||
#define text_wait_countdown (*(uint16*)(g_ram+0x1CE0))
|
#define text_wait_countdown (*(uint16*)(g_ram+0x1CE0))
|
||||||
@@ -827,9 +827,11 @@
|
|||||||
#define text_next_position (*(uint8*)(g_ram+0x1CE6))
|
#define text_next_position (*(uint8*)(g_ram+0x1CE6))
|
||||||
#define choice_in_multiselect_box (*(uint8*)(g_ram+0x1CE8))
|
#define choice_in_multiselect_box (*(uint8*)(g_ram+0x1CE8))
|
||||||
#define text_wait_countdown2 (*(uint8*)(g_ram+0x1CE9))
|
#define text_wait_countdown2 (*(uint8*)(g_ram+0x1CE9))
|
||||||
#define byte_7E1CEA (*(uint8*)(g_ram+0x1CEA))
|
|
||||||
|
// This seems never nonzero
|
||||||
|
#define dialogue_scroll_speed (*(uint8*)(g_ram+0x1CEA))
|
||||||
#define dialogue_message_index (*(uint16*)(g_ram+0x1CF0))
|
#define dialogue_message_index (*(uint16*)(g_ram+0x1CF0))
|
||||||
#define byte_7E1CF2 ((uint8*)(g_ram+0x1CF2))
|
#define dialogue_number ((uint8*)(g_ram+0x1CF2))
|
||||||
#define choice_in_multiselect_box_bak (*(uint8*)(g_ram+0x1CF4))
|
#define choice_in_multiselect_box_bak (*(uint8*)(g_ram+0x1CF4))
|
||||||
#define alt_sprite_state ((uint8*)(g_ram+0x1D00))
|
#define alt_sprite_state ((uint8*)(g_ram+0x1D00))
|
||||||
#define alt_sprite_type ((uint8*)(g_ram+0x1D10))
|
#define alt_sprite_type ((uint8*)(g_ram+0x1D10))
|
||||||
|
|||||||
@@ -15,6 +15,12 @@ ExtendedAspectRatio = 4:3
|
|||||||
# display is set to exactly 60hz)
|
# display is set to exactly 60hz)
|
||||||
DisableFrameDelay = 0
|
DisableFrameDelay = 0
|
||||||
|
|
||||||
|
# Set which language to use. Note. In order to use other languages you need to create
|
||||||
|
# the assets file appropriately.
|
||||||
|
# python restool.py --extract-dialogue -r german.sfc
|
||||||
|
# python restool.py --languages=de
|
||||||
|
# Language = de
|
||||||
|
|
||||||
[Graphics]
|
[Graphics]
|
||||||
# Window size ( Auto or WidthxHeight )
|
# Window size ( Auto or WidthxHeight )
|
||||||
WindowSize = Auto
|
WindowSize = Auto
|
||||||
|
|||||||
@@ -113,6 +113,8 @@ static void VerifySnapshotsEq(Snapshot *b, Snapshot *a, Snapshot *prev) {
|
|||||||
memcpy(a->ram + 0x1db20, b->ram + 0x1db20, 64 * 2); // msu
|
memcpy(a->ram + 0x1db20, b->ram + 0x1db20, 64 * 2); // msu
|
||||||
a->ram[0x654] = b->ram[0x654]; // msu_volume
|
a->ram[0x654] = b->ram[0x654]; // msu_volume
|
||||||
|
|
||||||
|
memcpy(a->ram + 0x1CDD, b->ram + 0x1CDD, 2); // dialogue_msg_src_offs
|
||||||
|
|
||||||
if (memcmp(b->ram, a->ram, 0x20000)) {
|
if (memcmp(b->ram, a->ram, 0x20000)) {
|
||||||
fprintf(stderr, "@%d: Memory compare failed (mine != theirs, prev):\n", frame_counter);
|
fprintf(stderr, "@%d: Memory compare failed (mine != theirs, prev):\n", frame_counter);
|
||||||
int j = 0;
|
int j = 0;
|
||||||
|
|||||||
27
zelda_rtl.c
27
zelda_rtl.c
@@ -10,7 +10,7 @@
|
|||||||
#include "spc_player.h"
|
#include "spc_player.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "audio.h"
|
#include "audio.h"
|
||||||
|
#include "assets.h"
|
||||||
ZeldaEnv g_zenv;
|
ZeldaEnv g_zenv;
|
||||||
uint8 g_ram[131072];
|
uint8 g_ram[131072];
|
||||||
|
|
||||||
@@ -739,7 +739,7 @@ bool ZeldaRunFrame(int inputs) {
|
|||||||
EmuSyncMemoryRegion(&g_ram[kRam_CrystalRotateCounter], 1);
|
EmuSyncMemoryRegion(&g_ram[kRam_CrystalRotateCounter], 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_emu_runframe == NULL || enhanced_features0 != 0) {
|
if (g_emu_runframe == NULL || enhanced_features0 != 0 || g_zenv.dialogue_flags) {
|
||||||
// can't compare against real impl when running with extra features.
|
// can't compare against real impl when running with extra features.
|
||||||
ZeldaRunFrameInternal(inputs, run_what);
|
ZeldaRunFrameInternal(inputs, run_what);
|
||||||
} else {
|
} else {
|
||||||
@@ -751,7 +751,28 @@ bool ZeldaRunFrame(int inputs) {
|
|||||||
return is_replay;
|
return is_replay;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ZeldaSetLanguage(const char *language) {
|
||||||
|
static const uint8 kDefaultConf[3] = { 0, 0, 0 };
|
||||||
|
MemBlk found = { kDefaultConf, 3 };
|
||||||
|
if (language) {
|
||||||
|
size_t n = strlen(language);
|
||||||
|
for (int i = 0; ; i++) {
|
||||||
|
MemBlk mb = kDialogueMap(i);
|
||||||
|
if (mb.ptr == 0) {
|
||||||
|
fprintf(stderr, "Unable to find language '%s'\n", language);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
MemBlk name = FindIndexInMemblk(mb, 0);
|
||||||
|
if (name.size == n && !memcmp(name.ptr, language, n)) {
|
||||||
|
found = FindIndexInMemblk(mb, 1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g_zenv.dialogue_blk = kDialogue(found.ptr[0]);
|
||||||
|
g_zenv.dialogue_font_blk = kDialogueFont(found.ptr[1]);
|
||||||
|
g_zenv.dialogue_flags = found.ptr[2];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char *const kReferenceSaves[] = {
|
static const char *const kReferenceSaves[] = {
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ typedef struct ZeldaEnv {
|
|||||||
struct Ppu *ppu;
|
struct Ppu *ppu;
|
||||||
struct SpcPlayer *player;
|
struct SpcPlayer *player;
|
||||||
struct Dma *dma;
|
struct Dma *dma;
|
||||||
|
|
||||||
|
MemBlk dialogue_blk;
|
||||||
|
MemBlk dialogue_font_blk;
|
||||||
|
uint8 dialogue_flags;
|
||||||
} ZeldaEnv;
|
} ZeldaEnv;
|
||||||
extern ZeldaEnv g_zenv;
|
extern ZeldaEnv g_zenv;
|
||||||
extern int frame_ctr_dbg;
|
extern int frame_ctr_dbg;
|
||||||
@@ -50,7 +54,7 @@ void ZeldaApuLock();
|
|||||||
void ZeldaApuUnlock();
|
void ZeldaApuUnlock();
|
||||||
bool ZeldaIsPlayingMusicTrack(uint8 track);
|
bool ZeldaIsPlayingMusicTrack(uint8 track);
|
||||||
uint8 ZeldaGetEntranceMusicTrack(int track);
|
uint8 ZeldaGetEntranceMusicTrack(int track);
|
||||||
|
void ZeldaSetLanguage(const char *language);
|
||||||
void PatchCommand(char cmd);
|
void PatchCommand(char cmd);
|
||||||
|
|
||||||
// Things for state management
|
// Things for state management
|
||||||
|
|||||||
Reference in New Issue
Block a user