diff options
-rw-r--r-- | NewerProject.yaml | 1 | ||||
-rwxr-xr-x | include/game.h | 218 | ||||
-rw-r--r-- | kamek_ntsc.x | 25 | ||||
-rw-r--r-- | kamek_ntsc2.x | 25 | ||||
-rw-r--r-- | kamek_pal.x | 25 | ||||
-rw-r--r-- | kamek_pal2.x | 25 | ||||
-rw-r--r-- | src/tilesetfixer.cpp | 94 | ||||
-rw-r--r-- | tilesetfixer.yaml | 9 |
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)' + |