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 --- src/tilesetfixer.cpp | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 src/tilesetfixer.cpp (limited to 'src') 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); +} + -- cgit v1.2.3