summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTreeki <treeki@gmail.com>2011-03-28 00:04:21 +0200
committerTreeki <treeki@gmail.com>2011-03-28 00:04:21 +0200
commit0aae0eed9a74a463852f6548e282c10b6c632cf2 (patch)
tree997eac377cae26e8440fb703eff60278dc60ae62 /src
parentb348b5f9124d28fe6ccc620253ba414fb08f3933 (diff)
downloadkamek-0aae0eed9a74a463852f6548e282c10b6c632cf2.tar.gz
kamek-0aae0eed9a74a463852f6548e282c10b6c632cf2.zip
Pa1/2/3 tilesets can now be swapped into any slot, except for animations
Diffstat (limited to '')
-rw-r--r--src/tilesetfixer.cpp94
1 files changed, 94 insertions, 0 deletions
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 <common.h>
+#include <game.h>
+
+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);
+}
+