From 0aae0eed9a74a463852f6548e282c10b6c632cf2 Mon Sep 17 00:00:00 2001 From: Treeki Date: Mon, 28 Mar 2011 00:04:21 +0200 Subject: Pa1/2/3 tilesets can now be swapped into any slot, except for animations --- NewerProject.yaml | 1 + include/game.h | 1 + kamek_ntsc.x | 6 ++++ kamek_ntsc2.x | 6 ++++ kamek_pal.x | 6 ++++ kamek_pal2.x | 6 ++++ src/tilesetfixer.cpp | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++ tilesetfixer.yaml | 9 +++++ 8 files changed, 129 insertions(+) create mode 100644 src/tilesetfixer.cpp create mode 100644 tilesetfixer.yaml diff --git a/NewerProject.yaml b/NewerProject.yaml index ffe9cf8..20a7d9a 100644 --- a/NewerProject.yaml +++ b/NewerProject.yaml @@ -12,6 +12,7 @@ modules: # - processed/heapbar.yaml - processed/tilegod.yaml - processed/linegod.yaml + - processed/tilesetfixer.yaml # - processed/msgbox.yaml # - processed/replay.yaml diff --git a/include/game.h b/include/game.h index ac5318d..b26842b 100755 --- a/include/game.h +++ b/include/game.h @@ -35,6 +35,7 @@ inline void *GetDVDClass2() { } void *DVD_GetFile(void *dvdclass2, const char *arc, const char *file); +void *DVD_GetFile(void *dvdclass2, const char *arc, const char *file, u32 *length); extern int Player_Active[4]; diff --git a/kamek_ntsc.x b/kamek_ntsc.x index 865402e..e93be35 100644 --- a/kamek_ntsc.x +++ b/kamek_ntsc.x @@ -233,6 +233,9 @@ SECTIONS { GameHeaps = 0x80377C48; + BGDatClass = 0x80429DF0; + GetTilesetName__FPvii = 0x800813F0; + IsWideScreen__Fv = 0x800B54B0; Player_Active = 0x80354E50; @@ -249,6 +252,8 @@ SECTIONS { GetObjectParent = 0x80162590; OSReport = 0x8015F730; + StagePtr = 0x8042A1C8; + _Z20CreateParentedObjectsPvic = 0x80162B00; _Z47CheckIfMenuShouldBeCancelledForSpecifiedWiimotei = 0x800B53A0; _Z21StartTitleScreenStagebi = 0x801017D0; @@ -288,6 +293,7 @@ SECTIONS { DVD_StillLoading__FPv = 0x800DF4E0; DVD_End__Fv = 0x8006A760; DVD_GetFile__FPvPCcPCc = 0x800DF180; + DVD_GetFile__FPvPCcPCcPUi = 0x800DF1E0; __ct__12dDvdLoader_cFv = 0x8008F140; __dt__12dDvdLoader_cFv = 0x8008F170; diff --git a/kamek_ntsc2.x b/kamek_ntsc2.x index b0956d0..2d48f72 100644 --- a/kamek_ntsc2.x +++ b/kamek_ntsc2.x @@ -233,6 +233,9 @@ SECTIONS { GameHeaps = 0x80377C48; + BGDatClass = 0x80429DF0; + GetTilesetName__FPvii = 0x800813F0; + IsWideScreen__Fv = 0x800B54B0; Player_Active = 0x80354E50; @@ -249,6 +252,8 @@ SECTIONS { GetObjectParent = 0x80162590; OSReport = 0x8015F730; + StagePtr = 0x8042A1C8; + _Z20CreateParentedObjectsPvic = 0x80162B00; _Z47CheckIfMenuShouldBeCancelledForSpecifiedWiimotei = 0x800B53A0; _Z21StartTitleScreenStagebi = 0x801017D0; @@ -288,6 +293,7 @@ SECTIONS { DVD_StillLoading__FPv = 0x800DF4E0; DVD_End__Fv = 0x8006A760; DVD_GetFile__FPvPCcPCc = 0x800DF180; + DVD_GetFile__FPvPCcPCcPUi = 0x800DF1E0; __ct__12dDvdLoader_cFv = 0x8008F140; __dt__12dDvdLoader_cFv = 0x8008F170; diff --git a/kamek_pal.x b/kamek_pal.x index a078e12..34bbba8 100644 --- a/kamek_pal.x +++ b/kamek_pal.x @@ -233,6 +233,9 @@ SECTIONS { GameHeaps = 0x80377F48; + BGDatClass = 0x8042A0D0; + GetTilesetName__FPvii = 0x800813F0; + IsWideScreen__Fv = 0x800B5500; Player_Active = 0x80355150; @@ -249,6 +252,8 @@ SECTIONS { GetObjectParent = 0x801626D0; OSReport = 0x8015F870; + StagePtr = 0x8042A4A8; + _Z20CreateParentedObjectsPvic = 0x80162C40; _Z47CheckIfMenuShouldBeCancelledForSpecifiedWiimotei = 0x800B53F0; _Z21StartTitleScreenStagebi = 0x801018E0; @@ -288,6 +293,7 @@ SECTIONS { DVD_StillLoading__FPv = 0x800DF5D0; DVD_End__Fv = 0x8006A760; DVD_GetFile__FPvPCcPCc = 0x800DF270; + DVD_GetFile__FPvPCcPCcPUi = 0x800DF2D0; __ct__12dDvdLoader_cFv = 0x8008F140; __dt__12dDvdLoader_cFv = 0x8008F170; diff --git a/kamek_pal2.x b/kamek_pal2.x index 5807478..c18de20 100644 --- a/kamek_pal2.x +++ b/kamek_pal2.x @@ -233,6 +233,9 @@ SECTIONS { GameHeaps = 0xDEADBEEF; + BGDatClass = 0xDEADBEEF; + GetTilesetName__FPvii = 0xDEADBEEF; + IsWideScreen__Fv = 0xDEADBEEF; Player_Active = 0xDEADBEEF; @@ -249,6 +252,8 @@ SECTIONS { GetObjectParent = 0xDEADBEEF; OSReport = 0xDEADBEEF; + StagePtr = 0xDEADBEEF; + _Z20CreateParentedObjectsPvic = 0xDEADBEEF; _Z47CheckIfMenuShouldBeCancelledForSpecifiedWiimotei = 0xDEADBEEF; _Z21StartTitleScreenStagebi = 0xDEADBEEF; @@ -288,6 +293,7 @@ SECTIONS { DVD_StillLoading__FPv = 0xDEADBEEF; DVD_End__Fv = 0xDEADBEEF; DVD_GetFile__FPvPCcPCc = 0xDEADBEEF; + DVD_GetFile__FPvPCcPCcPUi = 0xDEADBEEF; __ct__12dDvdLoader_cFv = 0xDEADBEEF; __dt__12dDvdLoader_cFv = 0xDEADBEEF; diff --git a/src/tilesetfixer.cpp b/src/tilesetfixer.cpp new file mode 100644 index 0000000..a66fc14 --- /dev/null +++ b/src/tilesetfixer.cpp @@ -0,0 +1,94 @@ +#include +#include + +extern void *BGDatClass, *StagePtr; +const char *GetTilesetName(void *cls, int areaNum, int slotNum); + +asm int GetAreaNum() { + nofralloc + lis r9, StagePtr@h + ori r9, r9, StagePtr@l + lwz r9, 0(r9) + lbz r3, 0x120E(r9) + blr +} + + +void DoFixes(int slotNumber); +void SwapObjData(u8 *data, int slotNumber); + +// Main hook +void TilesetFixerHack() { + for (int i = 1; i < 4; i++) { + DoFixes(i); + } +} + + + +// File format definitions +struct ObjLookupEntry { + u16 offset; + u8 width; + u8 height; +}; + + +void DoFixes(int slotNumber) { + // This is where it all starts + const char *tsName = GetTilesetName(BGDatClass, GetAreaNum(), slotNumber); + + if (tsName == 0 || tsName[0] == 0) { + OSReport("Skipping set %d\n", slotNumber); + return; + } + + OSReport("Processing %d = %s\n", slotNumber, tsName); + + char untHDname[64], untname[64]; + snprintf(untHDname, 64, "BG_unt/%s_hd.bin", tsName); + snprintf(untname, 64, "BG_unt/%s.bin", tsName); + + u32 unt_hd_length; + void *bg_unt_hd_data = DVD_GetFile(GetDVDClass2(), tsName, untHDname, &unt_hd_length); + void *bg_unt = DVD_GetFile(GetDVDClass2(), tsName, untname); + + OSReport("Unt: %p - Unt_HD: %p\n", bg_unt, bg_unt_hd_data); + + ObjLookupEntry *lookups = (ObjLookupEntry*)bg_unt_hd_data; + + int objCount = unt_hd_length / sizeof(ObjLookupEntry); + OSReport("%d objects\n", objCount); + + for (int i = 0; i < objCount; i++) { + // process each object + u8 *thisObj = (u8*)((u32)bg_unt + lookups[i].offset); + //OSReport("processing %d[%p][%04x]\n", i, thisObj, lookups[i].offset); + + SwapObjData(thisObj, slotNumber); + } +} + + +void SwapObjData(u8 *data, int slotNumber) { + // rudimentary parser which will hopefully work + + while (*data != 0xFF) { + u8 cmd = *data; + //OSReport("Command: %02x\n", cmd); + + if (cmd == 0xFE || (cmd & 0x80) != 0) { + data++; + continue; + } + + if ((data[2] & 3) != 0) { + data[2] &= 0xFC; + data[2] |= slotNumber; + } + data += 3; + } + + //OSReport("Ended @ %p\n", data); +} + diff --git a/tilesetfixer.yaml b/tilesetfixer.yaml new file mode 100644 index 0000000..409c443 --- /dev/null +++ b/tilesetfixer.yaml @@ -0,0 +1,9 @@ +--- +source_files: [../src/tilesetfixer.cpp] +hooks: + - name: TilesetFixHack + type: branch_insn + branch_type: b + src_addr_pal: 0x80081694 + target_func: 'TilesetFixerHack(void)' + -- cgit v1.2.3