summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--NewerProject.yaml1
-rwxr-xr-xinclude/game.h218
-rw-r--r--kamek_ntsc.x25
-rw-r--r--kamek_ntsc2.x25
-rw-r--r--kamek_pal.x25
-rw-r--r--kamek_pal2.x25
-rw-r--r--src/tilesetfixer.cpp94
-rw-r--r--tilesetfixer.yaml9
8 files changed, 416 insertions, 6 deletions
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 cb567f3..b26842b 100755
--- a/include/game.h
+++ b/include/game.h
@@ -5,6 +5,7 @@
#include <rvl/mtx.h>
#include <rvl/GXEnum.h>
#include <rvl/vifuncs.h>
+#include <rvl/arc.h>
extern "C" {
@@ -34,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];
@@ -288,11 +290,13 @@ namespace ut {
// I don't need the methods anyway.
class LinkListNode {
+ public:
LinkListNode *next;
LinkListNode *prev;
};
class LinkList {
+ public:
int count;
LinkListNode initialNode;
};
@@ -300,6 +304,7 @@ namespace ut {
class Color : public GXColor { };
class Rect {
+ public:
f32 left;
f32 top;
f32 right;
@@ -457,6 +462,45 @@ namespace lyt {
u8 paneIsOwnedBySomeoneElse;
u8 _D7;
};
+
+ class TextBox : public Pane {
+ public:
+ TextBox(void *, void *); // todo: TextBox((res::TextBox const *,ResBlockSet const &))
+ ~TextBox();
+
+ void *GetRuntimeTypeInfo() const;
+
+ void DrawSelf(const DrawInfo &info);
+
+ ut::Color GetVtxColor(ulong id) const;
+ void SetVtxColor(ulong id, ut::Color color);
+ uchar GetVtxColorElement(ulong id) const;
+ void SetVtxColorElement(ulong id, uchar value);
+
+ virtual void LoadMtx(const DrawInfo &info);
+
+ virtual void AllocStringBuffer(u16 size);
+ virtual void FreeStringBuffer();
+
+ virtual u16 SetString(const wchar_t *str, u16 destOffset = 0);
+ virtual u16 SetString(const wchar_t *str, u16 destOffset, u16 length);
+
+ wchar_t *stringBuf;
+
+ ut::Color colour1, colour2;
+ void *font; // actually a ut::ResFont or whatever
+
+ float fontSizeX, fontSizeY;
+ float lineSpace, charSpace;
+
+ void *tagProc; // actually a TagProcessor
+
+ u16 bufferLength;
+ u16 stringLength;
+
+ u8 alignment;
+ u8 flags;
+ };
}
@@ -663,17 +707,21 @@ extern "C" void GXDrawDone(); // 801C4FE0
namespace m2d {
class Base_c /*: public nw4r::ut::Link what's this? */ {
+ public:
u32 _00;
u32 _04;
Base_c();
virtual ~Base_c();
- virtual void _vf0C();
+ virtual void draw(); // don't call this directly
+
+ void scheduleForDrawing();
- u8 _0C;
+ u8 drawOrder;
};
class Simple_c : public Base_c {
+ public:
nw4r::lyt::Layout layout;
nw4r::lyt::DrawInfo drawInfo;
@@ -686,7 +734,7 @@ namespace m2d {
Simple_c();
~Simple_c();
- void _vf0C();
+ void draw();
virtual void _vf10();
virtual void _vf14();
};
@@ -696,6 +744,7 @@ namespace m2d {
namespace EGG {
class Frustum {
+ public:
GXProjectionType projType;
int isCentered;
float width;
@@ -792,10 +841,13 @@ struct Tree {
typedef bool (*ChainedFunc)(void*);
-struct FunctionChain {
+class FunctionChain {
+public:
ChainedFunc *functions;
u16 count;
u16 current;
+
+ void setup(ChainedFunc *functions, u16 count); // 8015F740
};
@@ -850,6 +902,8 @@ public:
fBase_c *GetParent();
fBase_c *GetChild();
fBase_c *GetNext();
+
+ bool hasUninitialisedProcesses(); // 80162B60
};
class dBase_c : public fBase_c {
@@ -876,7 +930,7 @@ public:
class dScene_c : public dBase_c {
public:
- FunctionChain *funcChain;
+ FunctionChain *ptrToInitChain;
dScene_c();
@@ -890,6 +944,11 @@ public:
int afterDraw();
~dScene_c();
+
+
+ void setInitChain(FunctionChain &initChain) {
+ ptrToInitChain = &initChain;
+ }
};
class dActor_c : public dBase_c {
@@ -1081,7 +1140,7 @@ public:
dDvdLoader_c(); // 8008F140
virtual ~dDvdLoader_c(); // 8008F170
- void *load(const char *filename, u8 unk = 0); // 8008F1B0
+ void *load(const char *filename, u8 unk = 0, void *heap = 0); // 8008F1B0
bool close(); // 8008F2B0 -- Frees command, DON'T USE THIS unless you free the buffer yourself
bool unload(); // 8008F310 -- Frees command and buffer, USE THIS
@@ -1098,5 +1157,152 @@ private:
+// More layout crap
+// This file REALLY needs to be reorganised.
+
+namespace nw4r {
+namespace lyt {
+
+ class ResourceAccessor {
+ public:
+ ResourceAccessor();
+ virtual ~ResourceAccessor();
+
+ virtual void *GetResource(u32 dirKey, const char *filename, u32 *sizePtr) = 0;
+ virtual void *GetFont(const char *name);
+ };
+
+ class ArcResourceAccessor : public ResourceAccessor {
+ public:
+ ArcResourceAccessor();
+ ~ArcResourceAccessor();
+
+ bool Attach(void *data, const char *rootDirName);
+ void *GetResource(u32 dirKey, const char *filename, u32 *sizePtr);
+ void *GetFont(const char *name);
+
+ ARCHandle arc;
+ u32 unk_20;
+ ut::LinkList list; // 0x24
+ char rootDirName[0x80]; // 0x30
+ // class ends at 0xB0
+ };
+
+}
+}
+
+namespace m2d {
+ class ResAcc_c {
+ public:
+ ResAcc_c();
+ virtual ~ResAcc_c();
+ virtual void initialSetup();
+
+ nw4r::lyt::ResourceAccessor *resAccPtr; // 0x04
+ u32 unk_08; // 0x08
+ nw4r::lyt::ArcResourceAccessor resAcc; // 0x0C
+ // class ends at 0xBC
+ };
+
+ class ResAccLoader_c : public ResAcc_c {
+ public:
+ ResAccLoader_c();
+ ~ResAccLoader_c();
+
+ void *buffer;
+ dDvdLoader_c loader; // 0xC0
+ // ends at 0xD4
+
+ bool loadArc(const char *path);
+ bool loadArc(const char *path, u8 unk);
+ void free();
+ };
+
+ class EmbedLayoutBase_c : public Base_c {
+ public:
+ EmbedLayoutBase_c();
+ ~EmbedLayoutBase_c();
+
+ void draw(); // don't call this directly
+
+ virtual void update();
+ virtual bool build(const char *brlytPath, ResAcc_c *resAcc = 0);
+
+ nw4r::lyt::Pane *getRootPane();
+ nw4r::lyt::Pane *findPaneByName(const char *name) const;
+ nw4r::lyt::TextBox *findTextBoxByName(const char *name) const;
+ nw4r::lyt::Pane *findPictureByName(const char *name) const; // TODO: change to others
+ nw4r::lyt::Pane *findWindowByName(const char *name) const;
+
+ void animate();
+ void calculateMtx();
+
+ nw4r::lyt::Layout layout; // 0x10 -- actually m2d::Layout_c but I'll add that later
+ nw4r::lyt::DrawInfo drawInfo; // 0x30
+ void *unk_84; // 0x84 -- a ResAcc? referenced in Build()
+ float posX; // 0x88
+ float posY; // 0x8C
+ float clipX; // 0x90
+ float clipY; // 0x94
+ float clipWidth; // 0x98
+ float clipHeight; // 0x9C
+ bool clippingEnabled; // 0xA0
+ u32 hasAnimations; // 0xA4
+ u32 unk_A8; // 0xA8
+ };
+
+ class EmbedLayout_c : public EmbedLayoutBase_c {
+ public:
+ EmbedLayout_c();
+ ~EmbedLayout_c();
+
+ bool build(const char *brlytPath, ResAcc_c *resAcc = 0);
+
+ bool loadArc(const char *name, bool isLangSpecific);
+ bool loadArc(const char *name, u8 unk, bool isLangSpecific);
+
+ bool loadArcForRegion(const char *name); // uses EU/Layout/$name
+
+ // there's also a NedEU one, but should it really be listed here...?
+
+ bool free();
+
+ // does NSMBW even use consts? I have no idea. maybe not
+
+ void getPanes(const char **names, nw4r::lyt::Pane *output, int count) const;
+ void getWindows(const char **names, nw4r::lyt::Pane *output, int count) const; // TODO: change to others
+ void getPictures(const char **names, nw4r::lyt::Pane *output, int count) const;
+ void getTextBoxes(const char **names, nw4r::lyt::TextBox *output, int count) const;
+
+ void setLangStrings(const char **names, const int *msgIDs, int category, int count);
+
+ void loadAnimations(const char **names, int count);
+ void loadGroups(const char **names, int *animLinkIDs, int count);
+
+ void enableNonLoopAnim(int num, bool goToLastFrame = false);
+ void enableLoopAnim(int num);
+ void resetAnim(int num, bool goToLastFrame = false);
+ void disableAnim(int num);
+ void disableAllAnimations();
+
+ bool isAnimOn(int num = -1);
+ bool isAnyAnimOn();
+
+ void execAnimations();
+
+ ResAccLoader_c loader; // 0xAC
+ void *brlanHandlers; // 0x180
+ void *grpHandlers; // 0x184
+ bool *animsEnabled; // 0x188
+ int brlanCount; // 0x18C
+ int grpCount; // 0x190
+ int lastAnimTouched; // 0x194
+
+ private:
+ void fixTextBoxesRecursively(nw4r::lyt::Pane *pane);
+ };
+}
+
+
#endif
diff --git a/kamek_ntsc.x b/kamek_ntsc.x
index 45f1063..e93be35 100644
--- a/kamek_ntsc.x
+++ b/kamek_ntsc.x
@@ -86,12 +86,18 @@ SECTIONS {
__nw__FUl = 0x802B9210;
__dl__FPv = 0x802B9280;
+ __construct_new_array = 0x802DC7E0;
+ __destroy_new_array = 0x802DCB10;
+
+
+ setup__13FunctionChainFPPFPv_bUs = 0x8015F600;
willBeDeleted__7fBase_cFv = 0x801622D0;
moreHeapShit__7fBase_cFUiPv = 0x801625F0;
createHeap__7fBase_cFUiPv = 0x801627F0;
heapCreated__7fBase_cFv = 0x801628B0;
Delete__7fBase_cFv = 0x80162510;
+ hasUninitialisedProcesses__7fBase_cFv = 0x80162A20;
GetExplanationString__7dBase_cFv = 0x8006C660;
@@ -167,6 +173,13 @@ SECTIONS {
DrawAllLayoutsAfterX__Fi = 0x80163390;
DrawAllLayoutsAfterXandBeforeY__Fii = 0x80163420;
+ __ct__Q23m2d13EmbedLayout_cFv = 0x800C8950;
+ __dt__Q23m2d13EmbedLayout_cFv = 0x800C89A0;
+ loadArc__Q23m2d13EmbedLayout_cFPCcb = 0x800C8CB0;
+ free__Q23m2d13EmbedLayout_cFv = 0x800C9930;
+ execAnimations__Q23m2d13EmbedLayout_cFv = 0x800C9560;
+ scheduleForDrawing__Q23m2d6Base_cFv = 0x80163850;
+
RenderEffects__Fii = 0x80093F10;
RemoveAllFromScnRoot__Fv = 0x80164E70;
@@ -220,6 +233,9 @@ SECTIONS {
GameHeaps = 0x80377C48;
+ BGDatClass = 0x80429DF0;
+ GetTilesetName__FPvii = 0x800813F0;
+
IsWideScreen__Fv = 0x800B54B0;
Player_Active = 0x80354E50;
@@ -236,6 +252,8 @@ SECTIONS {
GetObjectParent = 0x80162590;
OSReport = 0x8015F730;
+ StagePtr = 0x8042A1C8;
+
_Z20CreateParentedObjectsPvic = 0x80162B00;
_Z47CheckIfMenuShouldBeCancelledForSpecifiedWiimotei = 0x800B53A0;
_Z21StartTitleScreenStagebi = 0x801017D0;
@@ -252,6 +270,7 @@ SECTIONS {
QueueArcLoad = 0x800DF840;
RetrieveFileFromArc = 0x800DF180;
RetrieveFileFromArcAlt = 0x800DF3C0;
+
SpawnSprite = 0x80064610;
StoreObjectState = 0x800B1100;
TriggerEventFlag = 0x800E4A30;
@@ -274,6 +293,12 @@ 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;
+ load__12dDvdLoader_cFPCcUcPv = 0x8008F1B0;
+ unload__12dDvdLoader_cFv = 0x8008F310;
_Z22BgTexMng__LoadAnimTilePvisPcS0_c = 0x80087B60; /* same for ntsc */
BgTexMng__LoadAnimTile__FPvisPcPcc = 0x80087B60; /* same for ntsc */
diff --git a/kamek_ntsc2.x b/kamek_ntsc2.x
index 50d951e..2d48f72 100644
--- a/kamek_ntsc2.x
+++ b/kamek_ntsc2.x
@@ -86,12 +86,18 @@ SECTIONS {
__nw__FUl = 0x802B9210;
__dl__FPv = 0x802B9280;
+ __construct_new_array = 0x802DC7E0;
+ __destroy_new_array = 0x802DCB10;
+
+
+ setup__13FunctionChainFPPFPv_bUs = 0x8015F600;
willBeDeleted__7fBase_cFv = 0x801622D0;
moreHeapShit__7fBase_cFUiPv = 0x801625F0;
createHeap__7fBase_cFUiPv = 0x801627F0;
heapCreated__7fBase_cFv = 0x801628B0;
Delete__7fBase_cFv = 0x80162510;
+ hasUninitialisedProcesses__7fBase_cFv = 0x80162A20;
GetExplanationString__7dBase_cFv = 0x8006C660;
@@ -167,6 +173,13 @@ SECTIONS {
DrawAllLayoutsAfterX__Fi = 0x80163390;
DrawAllLayoutsAfterXandBeforeY__Fii = 0x80163420;
+ __ct__Q23m2d13EmbedLayout_cFv = 0x800C8950;
+ __dt__Q23m2d13EmbedLayout_cFv = 0x800C89A0;
+ loadArc__Q23m2d13EmbedLayout_cFPCcb = 0x800C8CB0;
+ free__Q23m2d13EmbedLayout_cFv = 0x800C9930;
+ execAnimations__Q23m2d13EmbedLayout_cFv = 0x800C9560;
+ scheduleForDrawing__Q23m2d6Base_cFv = 0x80163850;
+
RenderEffects__Fii = 0x80093F10;
RemoveAllFromScnRoot__Fv = 0x80164E70;
@@ -220,6 +233,9 @@ SECTIONS {
GameHeaps = 0x80377C48;
+ BGDatClass = 0x80429DF0;
+ GetTilesetName__FPvii = 0x800813F0;
+
IsWideScreen__Fv = 0x800B54B0;
Player_Active = 0x80354E50;
@@ -236,6 +252,8 @@ SECTIONS {
GetObjectParent = 0x80162590;
OSReport = 0x8015F730;
+ StagePtr = 0x8042A1C8;
+
_Z20CreateParentedObjectsPvic = 0x80162B00;
_Z47CheckIfMenuShouldBeCancelledForSpecifiedWiimotei = 0x800B53A0;
_Z21StartTitleScreenStagebi = 0x801017D0;
@@ -252,6 +270,7 @@ SECTIONS {
QueueArcLoad = 0x800DF840;
RetrieveFileFromArc = 0x800DF180;
RetrieveFileFromArcAlt = 0x800DF3C0;
+
SpawnSprite = 0x80064610;
StoreObjectState = 0x800B1100;
TriggerEventFlag = 0x800E4A30;
@@ -274,6 +293,12 @@ 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;
+ load__12dDvdLoader_cFPCcUcPv = 0x8008F1B0;
+ unload__12dDvdLoader_cFv = 0x8008F310;
_Z22BgTexMng__LoadAnimTilePvisPcS0_c = 0x80087B60; /* same for ntsc */
BgTexMng__LoadAnimTile__FPvisPcPcc = 0x80087B60; /* same for ntsc */
diff --git a/kamek_pal.x b/kamek_pal.x
index cbfa970..34bbba8 100644
--- a/kamek_pal.x
+++ b/kamek_pal.x
@@ -86,12 +86,18 @@ SECTIONS {
__nw__FUl = 0x802B9350;
__dl__FPv = 0x802B93C0;
+ __construct_new_array = 0x802DCAD0;
+ __destroy_new_array = 0x802DCE00;
+
+
+ setup__13FunctionChainFPPFPv_bUs = 0x8015F740;
willBeDeleted__7fBase_cFv = 0x80162410;
moreHeapShit__7fBase_cFUiPv = 0x80162730;
createHeap__7fBase_cFUiPv = 0x80162930;
heapCreated__7fBase_cFv = 0x801629F0;
Delete__7fBase_cFv = 0x80162650;
+ hasUninitialisedProcesses__7fBase_cFv = 0x80162B60;
GetExplanationString__7dBase_cFv = 0x8006C660;
@@ -167,6 +173,13 @@ SECTIONS {
DrawAllLayoutsAfterX__Fi = 0x801634D0;
DrawAllLayoutsAfterXandBeforeY__Fii = 0x80163560;
+ __ct__Q23m2d13EmbedLayout_cFv = 0x800C89A0;
+ __dt__Q23m2d13EmbedLayout_cFv = 0x800C89F0;
+ loadArc__Q23m2d13EmbedLayout_cFPCcb = 0x800C8D00;
+ free__Q23m2d13EmbedLayout_cFv = 0x800C9A20;
+ execAnimations__Q23m2d13EmbedLayout_cFv = 0x800C9650;
+ scheduleForDrawing__Q23m2d6Base_cFv = 0x80163990;
+
RenderEffects__Fii = 0x80093F10;
RemoveAllFromScnRoot__Fv = 0x80164FB0;
@@ -220,6 +233,9 @@ SECTIONS {
GameHeaps = 0x80377F48;
+ BGDatClass = 0x8042A0D0;
+ GetTilesetName__FPvii = 0x800813F0;
+
IsWideScreen__Fv = 0x800B5500;
Player_Active = 0x80355150;
@@ -236,6 +252,8 @@ SECTIONS {
GetObjectParent = 0x801626D0;
OSReport = 0x8015F870;
+ StagePtr = 0x8042A4A8;
+
_Z20CreateParentedObjectsPvic = 0x80162C40;
_Z47CheckIfMenuShouldBeCancelledForSpecifiedWiimotei = 0x800B53F0;
_Z21StartTitleScreenStagebi = 0x801018E0;
@@ -252,6 +270,7 @@ SECTIONS {
QueueArcLoad = 0x800DF930;
RetrieveFileFromArc = 0x800DF270;
RetrieveFileFromArcAlt = 0x800DF4B0;
+
SpawnSprite = 0x80064610;
StoreObjectState = 0x800B1100;
TriggerEventFlag = 0x800E4B20;
@@ -274,6 +293,12 @@ 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;
+ load__12dDvdLoader_cFPCcUcPv = 0x8008F1B0;
+ unload__12dDvdLoader_cFv = 0x8008F310;
_Z22BgTexMng__LoadAnimTilePvisPcS0_c = 0x80087B60; /* same for ntsc */
BgTexMng__LoadAnimTile__FPvisPcPcc = 0x80087B60; /* same for ntsc */
diff --git a/kamek_pal2.x b/kamek_pal2.x
index 684d968..c18de20 100644
--- a/kamek_pal2.x
+++ b/kamek_pal2.x
@@ -86,12 +86,18 @@ SECTIONS {
__nw__FUl = 0xDEADBEEF;
__dl__FPv = 0xDEADBEEF;
+ __construct_new_array = 0xDEADBEEF;
+ __destroy_new_array = 0xDEADBEEF;
+
+
+ setup__13FunctionChainFPPFPv_bUs = 0xDEADBEEF;
willBeDeleted__7fBase_cFv = 0xDEADBEEF;
moreHeapShit__7fBase_cFUiPv = 0xDEADBEEF;
createHeap__7fBase_cFUiPv = 0xDEADBEEF;
heapCreated__7fBase_cFv = 0xDEADBEEF;
Delete__7fBase_cFv = 0xDEADBEEF;
+ hasUninitialisedProcesses__7fBase_cFv = 0xDEADBEEF;
GetExplanationString__7dBase_cFv = 0xDEADBEEF;
@@ -167,6 +173,13 @@ SECTIONS {
DrawAllLayoutsAfterX__Fi = 0xDEADBEEF;
DrawAllLayoutsAfterXandBeforeY__Fii = 0xDEADBEEF;
+ __ct__Q23m2d13EmbedLayout_cFv = 0xDEADBEEF;
+ __dt__Q23m2d13EmbedLayout_cFv = 0xDEADBEEF;
+ loadArc__Q23m2d13EmbedLayout_cFPCcb = 0xDEADBEEF;
+ free__Q23m2d13EmbedLayout_cFv = 0xDEADBEEF;
+ execAnimations__Q23m2d13EmbedLayout_cFv = 0xDEADBEEF;
+ scheduleForDrawing__Q23m2d6Base_cFv = 0xDEADBEEF;
+
RenderEffects__Fii = 0xDEADBEEF;
RemoveAllFromScnRoot__Fv = 0xDEADBEEF;
@@ -220,6 +233,9 @@ SECTIONS {
GameHeaps = 0xDEADBEEF;
+ BGDatClass = 0xDEADBEEF;
+ GetTilesetName__FPvii = 0xDEADBEEF;
+
IsWideScreen__Fv = 0xDEADBEEF;
Player_Active = 0xDEADBEEF;
@@ -236,6 +252,8 @@ SECTIONS {
GetObjectParent = 0xDEADBEEF;
OSReport = 0xDEADBEEF;
+ StagePtr = 0xDEADBEEF;
+
_Z20CreateParentedObjectsPvic = 0xDEADBEEF;
_Z47CheckIfMenuShouldBeCancelledForSpecifiedWiimotei = 0xDEADBEEF;
_Z21StartTitleScreenStagebi = 0xDEADBEEF;
@@ -252,6 +270,7 @@ SECTIONS {
QueueArcLoad = 0xDEADBEEF;
RetrieveFileFromArc = 0xDEADBEEF;
RetrieveFileFromArcAlt = 0xDEADBEEF;
+
SpawnSprite = 0xDEADBEEF;
StoreObjectState = 0xDEADBEEF;
TriggerEventFlag = 0xDEADBEEF;
@@ -274,6 +293,12 @@ 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;
+ load__12dDvdLoader_cFPCcUcPv = 0xDEADBEEF;
+ unload__12dDvdLoader_cFv = 0xDEADBEEF;
_Z22BgTexMng__LoadAnimTilePvisPcS0_c = 0xDEADBEEF; /* same for ntsc */
BgTexMng__LoadAnimTile__FPvisPcPcc = 0xDEADBEEF; /* same for ntsc */
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);
+}
+
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)'
+