#ifndef __KAMEK_GAME_H #define __KAMEK_GAME_H //#define offsetof(type, member) ((__std(size_t)) &(((type *) 0)->member)) #include #include #include #include #include #define offsetof(type, member) ((u32) &(((type *) 0)->member)) extern "C" { int strlen(const char *str); float atan(float x); float atan2(float y, float x); float cos(float x); float sin(float x); } bool DVD_Start(); bool DVD_End(); bool DVD_StillLoading(void *dvdclass2); void DVD_LoadFile(void *dvdclass, char *folder, char *file, void *callbackData); void DVD_FreeFile(void *dvdclass2, char *file); extern void *DVDClass; inline void *GetDVDClass() { return DVDClass; } inline void *GetDVDClass2() { return (void*)(((u32)GetDVDClass())+4); } void *DVD_GetFile(void *dvdclass2, const char *arc, const char *file); void *DVD_GetFile(void *dvdclass2, const char *arc, const char *file, u32 *length); int MakeRandomNumber(int count); int MakeRandomNumberForTiles(int count); extern int Player_Active[4]; extern int Player_ID[4]; extern int Player_Powerup[4]; extern int Player_Flags[4]; extern int Player_Lives[4]; extern int Player_Coins[4]; struct StartLevelInfo { int maybeUnused; unsigned char unk1; // 0x04 unsigned char unk2; // 0x05 unsigned char unk3; // 0x06 unsigned char unk4; // 0x07 unsigned int purpose; // 0x08 unsigned char world1; // 0x0C unsigned char level1; // 0x0D unsigned char world2; // 0x0E unsigned char level2; // 0x0F }; extern void *GameMgr; inline void *GetGameMgr() { return GameMgr; } bool QueryPlayerAvailability(int id); void DoStartLevel(void *gameMgr, StartLevelInfo *sl); void SetSomeConditionShit(int world, int level, unsigned int bits); bool IsWideScreen(); #define GAMEMGR_GET_AFC(gmgr) (*((bool*)(((u32)(gmgr))+0xAFC))) #define COND_COIN1 1 #define COND_COIN2 2 #define COND_COIN3 4 #define COND_NORMAL 0x10 #define COND_SECRET 0x20 #define COND_SGNORMAL 0x80 #define COND_SGSECRET 0x100 class SaveFirstBlock { public: char titleID[4]; // 0x00 u8 field_00; // 0x04 u8 field_01; // 0x05 u8 current_file; // 0x06 u8 field_03; // 0x07 u16 freemode_fav[10][0x2A]; // 0x08 u16 coinbtl_fav[10][0x2A]; // 0x350 u16 bitfield; // 0x698 u16 field_69A; // 0x69A u32 checksum; // 0x69C }; class SaveBlock { public: u8 field_00; // 0x00 u8 field_01; // 0x01 u8 bitfield; // 0x02 u8 current_world; // 0x03 u8 field_04; // 0x04 u8 current_path_node; // 0x05 u8 field_06; // 0x06 u8 switch_on; // 0x07 u8 field_08; // 0x08 u8 powerups_available[7]; // 0x09 u8 toad_level_idx[10]; // 0x10 u8 player_continues[4]; // 0x1A u8 player_coins[4]; // 0x1E u8 player_lives[4]; // 0x22 u8 player_flags[4]; // 0x26 u8 player_type[4]; // 0x2A u8 player_powerup[4]; // 0x2E u8 worlds_available[10]; // 0x32 u32 ambush_countdown[10]; // 0x3C u16 field_64; // 0x64 u16 credits_hiscore; // 0x66 u16 score; // 0x68 u32 completions[10][0x2A]; // 0x6C u8 hint_movie_bought[70]; // 0x6FC u8 toad_location[10]; // 0x742 u8 field_74C[10][4]; // 0x74C u8 field_774[10][4]; // 0x774 u8 field_79C[10][4]; // 0x79C u8 death_counts[10][0x2A]; // 0x7C4 u8 death_count_3_4_switch; // 0x968 u8 pad[0x13]; // 0x969 u32 checksum; // 0x97C u32 GetLevelCondition(int world, int level); bool CheckLevelCondition(int world, int level, int cond); bool CheckIfCoinCollected(int world, int level, int num); }; class SaveFile { public: u32 field_00; u32 field_04; u32 field_08; u32 field_0C; u32 field_10; u32 field_14; u32 field_18; u32 field_1C; // Real Savefile starts here SaveFirstBlock header; SaveBlock blocks[3]; SaveBlock quickSave[3]; SaveBlock *GetBlock(int id); SaveBlock *GetQSBlock(int id); bool CheckIfWriting(); // 0x800E0540 }; class SaveHandler { public: u8 unknown[0x70]; u32 CurrentState; u32 CurrentError; u32 field_7C; }; extern SaveFile *SaveFileInstance; extern SaveHandler *SaveHandlerInstance; inline SaveFile *GetSaveFile() { return SaveFileInstance; } inline SaveHandler *GetSaveHandler() { return SaveHandlerInstance; } #define WPAD_DOWN 0x0001 // Actually Left, but rotated #define WPAD_UP 0x0002 // Actually Right, but rotated #define WPAD_RIGHT 0x0004 // Actually Down, but rotated #define WPAD_LEFT 0x0008 // Actually Up, but rotated #define WPAD_PLUS 0x0010 #define WPAD_TWO 0x0100 #define WPAD_ONE 0x0200 #define WPAD_B 0x0400 #define WPAD_A 0x0800 #define WPAD_MINUS 0x1000 #define WPAD_HOME 0x8000 struct RemoconMngClass { void *vtable; void *controllers[4]; }; /* * Ok, here's how the remocon/wiimote shit works: * Remocon is a NSMB-specific class, it handles the different control methods * and D-pad directions and such automatically. * * Wiimote is a generic class (part of EGG) -- well it's not actually called * that, but who cares. It handles different types of controllers. Only * query it if whatever you're accessing is control type dependent. */ extern RemoconMngClass *RemoconMng; extern int ActiveWiimoteID; extern void *ActiveWiimote; inline RemoconMngClass *GetRemoconMng() { return RemoconMng; } inline int GetActiveWiimoteID() { return ActiveWiimoteID; } inline void *GetActiveRemocon() { return GetRemoconMng()->controllers[GetActiveWiimoteID()]; } inline void *GetActiveWiimote() { return ActiveWiimote; } inline unsigned int Remocon_GetButtons(void *self) { return *((unsigned int*)((u32)self+0x18)); } inline unsigned int Remocon_GetPressed(void *self) { return *((unsigned int*)((u32)self+0x1C)); } typedef bool (*__Wiimote_TestButtons_type)(void*, unsigned int); inline bool Wiimote_TestButtons(void *self, unsigned int btns) { VF_BEGIN(__Wiimote_TestButtons_type, self, 8, 0) return VF_CALL(self, btns); VF_END; } int SearchForIndexOfPlayerID(int id); bool CheckIfContinueShouldBeActivated(); bool CheckIfMenuShouldBeCancelledForSpecifiedWiimote(int num); void StartTitleScreenStage(bool realDemo, int sceneParam); bool CheckIfWeCantDoStuff(); u32 QueryGlobal5758(u32 check); void SaveGame(void *classDoesntMatter, bool isQuick); #include void *CreateParentedObject(short classID, void *parent, int settings, char something); void *CreateChildObject(short classID, void *parent, int settings, int unk1, int unk2); #define WIPE_FADE 0 #define WIPE_CIRCLE 1 #define WIPE_BOWSER 2 #define WIPE_WAVY 3 #define WIPE_MARIO 4 #define WIPE_CIRCLE_s 5 void ActivateWipe(int type); typedef void (*ScreenDrawFunc)(); extern ScreenDrawFunc *CurrentDrawFunc; void WorldMapDrawFunc(); void GameSetupDrawFunc(); void GameSetup__LoadScene(void *self); // 0x80919560 void FreeScene(int id); void WpadShit(int unk); // 0x8016F780 void *BgTexMng__LoadAnimTile(void *self, int tileset, short tile, char *name, char *delays, char reverse); // 0x80087B60 extern void *GameHeaps[]; class dFlagMgr_c { public: dFlagMgr_c(); enum ActionFlag { ACTIVATE = 1, TICKS = 2 }; u64 flags; float _8[64], _108[64]; u8 _208[64]; u64 _248[64]; u8 _448[64]; u32 ticksRemainingForAction[64]; u8 actionFlag[64]; u32 _5C8[64]; // somehow sound related?! assigned by last param to set(); only checked for == 0 u8 _6C8; // assigned -1 by FlagMgr, and other values by the Switch object, nothing else though void setup(bool isNewLevel); void applyAndClearAllTimedActions(); // only used when setup(true) is called void execute(); void set(u8 number, int delay, bool activate, bool reverseEffect, bool makeNoise, u32 unknown=0); u8 findLowestFlagInSet(u32 unk, u64 set); void setSpecial(u8 number, float to8, float to108, u8 to208, u32 unk, u64 to248); float get8(u8 number); float get108(u8 number); u8 get208(u8 number); u64 get248(u8 number); u8 get448(u8 number); // convenience inline functions which may or may not actually exist in Nintendo's original code u64 mask(u8 number) { return (u64)1 << number; } bool active(u8 number) { return (flags & mask(number)) != 0; } bool inactive(u8 number) { return (flags & mask(number)) == 0; } static dFlagMgr_c *instance; }; class mMtx { Mtx data; public: mMtx() { } mMtx(float _00, float _01, float _02, float _03, float _10, float _11, float _12, float _13, float _20, float _21, float _22, float _23); float* operator[](int row) { return data[row]; } operator MtxPtr() const { return (MtxPtr)this; } /* Create New Ones */ void identity(); void translation(float x, float y, float z) { MTXTrans(data, x, y, z); } void scale(float x, float y, float z) { MTXScale(data, x, y, z); } void rotationX(s16 *amount); void rotationY(s16 *amount); void rotationZ(s16 *amount); /* Applied Manipulations */ void applyTranslation(float x, float y, float z) { MTXTransApply(data, data, x, y, z); } void applyScale(float x, float y, float z) { MTXScaleApply(data, data, x, y, z); } void applyRotationX(s16 *amount); void applyRotationY(s16 *amount); void applyRotationZ(s16 *amount); void applyRotationYXZ(s16 *x, s16 *y, s16 *z); void applyRotationZYX(s16 *x, s16 *y, s16 *z); /* Get Stuff */ void getTranslation(Vec *target); void getUnknown(S16Vec *target); }; namespace nw4r { namespace ut { // this isn't 100% accurate because it doesn't use templates // or detail::LinkListImpl, but oh well // I don't need the methods anyway. class LinkListNode { public: LinkListNode *next; LinkListNode *prev; }; class LinkList { public: int count; LinkListNode initialNode; }; class Color : public GXColor { }; class Rect { public: f32 left; f32 top; f32 right; f32 bottom; }; template class TagProcessorBase { }; } namespace lyt { class Pane; // forward declaration class DrawInfo; class AnimTransform; // I'll do these later class AnimResource; class AnimationLink; class ResourceAccessor; class GroupContainer; class Layout { public: Layout(); virtual ~Layout(); virtual bool Build(const void *data, ResourceAccessor *resAcc); virtual AnimTransform *CreateAnimTransform(); virtual AnimTransform *CreateAnimTransform(const void *data, ResourceAccessor *resAcc); virtual AnimTransform *CreateAnimTransform(const AnimResource &res, ResourceAccessor *resAcc); virtual void BindAnimation(AnimTransform *anim); virtual void UnbindAnimation(AnimTransform *anim); virtual void UnbindAllAnimation(); virtual bool BindAnimationAuto(const AnimResource &res, ResourceAccessor *resAcc); virtual void SetAnimationEnable(AnimTransform *anim, bool unk); virtual void CalculateMtx(const DrawInfo &info); virtual void/*?*/ Draw(const DrawInfo &info); virtual void/*?*/ Animate(ulong flag); virtual void/*?*/ SetTagProcessor(ut::TagProcessorBase *tagProc); ut::LinkList animations; Pane *rootPane; GroupContainer *groupContainer; float width; float height; }; class DrawInfo { public: DrawInfo(); virtual ~DrawInfo(); Mtx matrix; float left; float top; float right; float bottom; float scaleX; float scaleY; float alpha; u8 _50; // this is actually a bitfield. todo: investigate how CW handles bitfields, and so on }; class Material { public: // ... }; class Pane { public: //Pane(nw4r::lyt::res::Pane const *); // todo: this struct Pane(void *); virtual ~Pane(); virtual void *GetRuntimeTypeInfo() const; virtual void CalculateMtx(const DrawInfo &info); virtual void Draw(const DrawInfo &info); virtual void DrawSelf(const DrawInfo &info); virtual void Animate(ulong flag); virtual void AnimateSelf(ulong flag); virtual ut::Color GetVtxColor(ulong id) const; virtual void SetVtxColor(ulong id, ut::Color color); virtual uchar GetColorElement(ulong id) const; virtual void SetColorElement(ulong id, uchar value); virtual uchar GetVtxColorElement(ulong id) const; virtual void SetVtxColorElement(ulong id, uchar value); virtual Pane *FindPaneByName(const char *name, bool recursive); virtual Material *FindMaterialByName(const char *name, bool recursive); virtual void/*?*/ BindAnimation(AnimTransform *anim, bool unk1, bool unk2); virtual void UnbindAnimation(AnimTransform *anim, bool unk); virtual void UnbindAllAnimation(bool unk); virtual void UnbindAnimationSelf(AnimTransform *anim); virtual ut::LinkListNode *FindAnimationLinkSelf(AnimTransform *anim); virtual ut::LinkListNode *FindAnimationLinkSelf(const AnimResource &anim); virtual void SetAnimationEnable(AnimTransform *anim, bool unk1, bool unk2); virtual void SetAnimationEnable(const AnimResource &anim, bool unk1, bool unk2); virtual ulong GetMaterialNum() const; virtual Material *GetMaterial() const; virtual Material *GetMaterial(ulong id) const; virtual void LoadMtx(const DrawInfo &info); void AppendChild(Pane *child); ut::Rect GetPaneRect(const DrawInfo &info) const; ut::LinkListNode *AddAnimationLink(AnimationLink *link); Vec2 GetVtxPos() const; ut::LinkListNode parentLink; Pane *parent; ut::LinkList children; ut::LinkList animations; Material *material; Vec trans; Vec rotate; Vec2 scale; Vec2 size; Mtx calcMtx; Mtx effectiveMtx; float _B4; u8 alpha; u8 effectiveAlpha; u8 origin; u8 flag; char name[0x11]; char userdata[8]; u8 _D5; 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; }; } namespace g3d { struct CameraData { enum Flag { FLAG_CAMERA_LOOKAT = 0x00000001, FLAG_CAMERA_ROTATE = 0x00000002, FLAG_CAMERA_AIM = 0x00000004, MASK_CAMERA = 0x00000007, FLAG_CMTX_VALID = 0x00000008, FLAG_PROJ_FLUSTUM = 0x00000010, FLAG_PROJ_PERSP = 0x00000020, FLAG_PROJ_ORTHO = 0x00000040, MASK_PROJ = 0x00000070, FLAG_PMTX_VALID = 0x00000080, FLAG_VIEWPORT_JITTER_ABOVE = 0x00000100 }; Mtx cameraMtx; Mtx44 projMtx; u32 flags; VEC3 cameraPos; VEC3 cameraUp; VEC3 cameraTarget; VEC3 cameraRotate; f32 cameraTwist; GXProjectionType projType; f32 projFovy; f32 projAspect; f32 projNear; f32 projFar; f32 projTop; f32 projBottom; f32 projLeft; f32 projRight; f32 lightScaleS; f32 lightScaleT; f32 lightTransS; f32 lightTransT; VEC2 viewportOrigin; VEC2 viewportSize; f32 viewportNear; f32 viewportFar; u32 scissorX; u32 scissorY; u32 scissorWidth; u32 scissorHeight; s32 scissorOffsetX; s32 scissorOffsetY; }; /* Correct camera cameraMtx: 1.0 0.0 0.0 -0.0 0.0 1.0 0.0 -0.0 0.0 0.0 1.0 -6000.0 projMtx: 0.002345 0.000000 0.000000 -1.000000 0.000000 0.004386 0.000000 -1.000000 0.000000 0.000000 -0.000005 -0.500000 0.000000 0.000000 0.000000 1.000000 flags: 000000C9 : FLAG_CAMERA_LOOKAT | FLAG_CMTX_VALID | FLAG_PROJ_ORTHO | FLAG_PMTX_VALID cameraPos: {0, 0, 15} cameraUp: {0, 1, 0} cameraTarget: {0, 0, 0} cameraRotate: {0, 0, 0} cameraTwist: 0 projType: 1 projFovy: 60 projAspect: 1.333333 projNear: -100000 projFar: 100000 projTop: 456 projBottom: 0 projLeft: 0 projRight: 853 lightScaleS: 0.5 lightScaleT: 0.5 lightTransS: 0.5 lightTransT: 0.5 viewportOrigin: {0,0} viewportSize: {640,456} viewportNear: 0 viewportFar: 1 scissorX: 0 scissorY: 0 scissorWidth: 0x280 scissorHeight: 0x1C8 scissorOffsetX: 0 scissorOffsetY: 0 */ class Camera { public: enum PostureType { POSTURE_LOOKAT, POSTURE_ROTATE, POSTURE_AIM }; struct PostureInfo { PostureType tp; VEC3 cameraUp; VEC3 cameraTarget; VEC3 cameraRotate; f32 cameraTwist; }; private: CameraData *data; public: Camera(CameraData *pCamera); void Init(); void Init(u16 efbWidth, u16 efbHeight, u16 xfbWidth, u16 xfbHeight, u16 viWidth, u16 viHeight); //void SetPosition(f32 x, f32 y, f32 z); void SetPosition(const VEC3 &pos); //void GetPosition(f32 *px, f32 *py, f32 *pz) const; void GetPosition(VEC3 *pPos) const; void SetPosture(const PostureInfo &info); //void GetPosture(PostureInfo *info) const; void SetCameraMtxDirectly(const Mtx &mtx); void GetCameraMtx(Mtx *pMtx) const; void SetOrtho(f32 top, f32 bottom, f32 left, f32 right, f32 near, f32 far); //void SetFrustum(f32 top, f32 bottom, f32 left, f32 right, f32 near, f32 far); void SetPerspective(f32 fovy, f32 aspect, f32 near, f32 far); void SetProjectionMtxDirectly(const Mtx44 *pMtx); void GetProjectionMtx(Mtx44 *pMtx) const; //GXProjectionType GetProjectionType() const; void SetScissor(u32 xOrigin, u32 yOrigin, u32 width, u32 height); void SetScissorBoxOffset(s32 xOffset, s32 yOffset); //void GetScissor(u32 *xOrigin, u32 *yOrigin, u32 *width, u32 *height); void SetViewport(f32 xOrigin, f32 yOrigin, f32 width, f32 height); //void SetViewport(f32 xOrigin, f32 yOrigin, f32 width, f32 height, f32 near, f32 far); void SetViewportZRange(f32 near, f32 far); void SetViewportJitter(u32 field); //void SetViewportJitter(f32 xOrigin, f32 yOrigin, f32 width, f32 height, f32 near, f32 far, u32 field); void GetViewport(f32 *xOrigin, f32 *yOrigin, f32 *width, f32 *height, f32 *near, f32 *far) const; void GXSetViewport() const; void GXSetProjection() const; void GXSetScissor() const; void GXSetScissorBoxOffset() const; }; namespace G3DState { GXRenderModeObj *GetRenderModeObj(); } } } nw4r::g3d::CameraData *GetCameraByID(int id); int GetCurrentCameraID(); // 80164C80 void SetCurrentCameraID(int id); // 80164C90 void LinkScene(int id); // 80164D50 void UnlinkScene(int id); // 80164CD0 void SceneCalcWorld(int sceneID); // 80164E10 void SceneCameraStuff(int sceneID); // 80164EA0 void CalcMaterial(); // 80164E90 void DrawOpa(); // 80164F70 void DrawXlu(); // 80164F80 bool ChangeAlphaUpdate(bool enable); // 802D3270 void DoSpecialDrawing1(); // 8006CAE0 void DoSpecialDrawing2(); // 8006CB40 void SetupLYTDrawing(); // 80163360 void ClearLayoutDrawList(); // 801632B0 void DrawAllLayoutsBeforeX(int x); // 80163440 void DrawAllLayoutsAfterX(int x); // 801634D0 void DrawAllLayoutsAfterXandBeforeY(int x, int y); // 80163560 void RenderEffects(int v1, int v2); // 80093F10 void RemoveAllFromScnRoot(); // 80164FB0 void Reset3DState(); // 80165000 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 draw(); // don't call this directly void scheduleForDrawing(); u8 drawOrder; }; class Simple_c : public Base_c { public: nw4r::lyt::Layout layout; nw4r::lyt::DrawInfo drawInfo; u32 _84; float _88; float _8C; float _90; u32 _94; Simple_c(); ~Simple_c(); void draw(); virtual void _vf10(); virtual void _vf14(); }; } namespace EGG { class Frustum { public: GXProjectionType projType; int isCentered; float width; float height; float fovy; float dunno; float near; float far; float center_x_maybe; float center_y_maybe; float x_direction; float unk2; float unk3; short some_flag_bit; // isCentered might actually be isNotCentered, dunno Frustum(GXProjectionType projType, Vec2 size, bool isCentered, float near, float far); // 802C6D20 Frustum(Frustum &f); // 802C6D90 virtual ~Frustum(); // 802C75F0 virtual void loadDirectly(); // 802C7050 virtual void loadIntoCamera(nw4r::g3d::Camera cam); // 802C7070 void setOrtho(float top, float bottom, float left, float right, float near, float far); // 802C6DD0 void setFovy(float newFovy); // 802C6F60 void getCenterPointsBasedOnPos(float x, float y, float *destX, float *destY); // 802C6FD0 // no idea what this does float getSomethingForPerspective(float blah); // 802C7020 protected: // not all of these might be protected, dunno void copyAllFields(Frustum &f); // 802C6EE0 void saveSomething(float f1, float f2, float f3, float f4); // 802C70C0 void loadSomething(float *f1, float *f2, float *f3, float *f4); // 802C70E0 void loadPerspective(); // 802C7110 void loadOrtho(); // 802C7140 void setCameraPerspective(nw4r::g3d::Camera cam); // 802C7170 void setCameraOrtho(nw4r::g3d::Camera cam); // 802C71E0 void getPerspectiveProjMtx(Mtx44 *mtx); // 802C7250 void getPerspectiveProjv(float *ptr); // 802C72E0 void getOrthoProjv(float *ptr); // 802C73A0 void getOrthoVars(float *top, float *bottom, float *left, float *right); // 802C7480 }; } class TileRenderer { public: TileRenderer(); ~TileRenderer(); TileRenderer *list1, *list2; u16 tileNumber; u8 unkFlag, someBool; float x, y, z; float scale; s16 rotation; u8 unkByte; u16 getTileNum(); bool getSomeBool(); void setSomeBool(u8 value); float getX(); float getY(); float getZ(); void setPosition(float x, float y); void setPosition(float x, float y, float z); u8 getUnkFlag(); void setVars(float scale); // sets unkFlag=1, rotation=0, unkByte=0 void setVars(float scale, s16 rotation); // sets unkFlag=2, unkByte=0 float getScale(); float getRotationFloat(); s16 getRotation(); u8 getUnkByte(); class List { public: u32 count; TileRenderer *first, *last; // order? void add(TileRenderer *r); void remove(TileRenderer *r); void removeAll(); List(); ~List(); }; }; class dActor_c; // forward declaration class dStageActor_c; // forward declaration class Physics { public: struct Unknown { Unknown(); ~Unknown(); float x, y; }; struct Info { float x1, y1, x2, y2; // Might be distance to center/edge like APhysics void *otherCallback1, *otherCallback2, *otherCallback3; }; Physics(); ~Physics(); dActor_c *owner; Physics *next, *prev; u32 _C, _10, _14, _18, _1C, _20, _24, _28, _2C, _30, _34, _38, _3C; void *otherCallback1, *otherCallback2, *otherCallback3; void *callback1, *callback2, *callback3; float lastX, lastY; Unknown unkArray[4]; float x, y; float _88, _8C, _90; Vec lastActorPosition; float _A0, _A4, last_A0, last_A4, _B0, _B4; u32 _B8; s16 *ptrToRotationShort; s16 currentRotation; s16 rotDiff; s16 rotDiffAlt; u32 isRound; u32 _CC; u32 flagsMaybe; u32 _D4, _D8; u8 isAddedToList, _DD, layer; u32 id; void addToList(); void removeFromList(); void baseSetup(dActor_c *actor, u32 t_40, u32 t_44, u32 t_48, u8 t_DD, u8 layer); // note: Scale can be a null pointer (in that case, it'll use 1.0) void setup(dActor_c *actor, float x1, float y1, float x2, float y2, void *otherCB1, void *otherCB2, void *otherCB3, u8 t_DD, u8 layer, Vec2 *scale = 0); void setup(dActor_c *actor, Vec2 *p1, Vec2 *p2, void *otherCB1, void *otherCB2, void *otherCB3, u8 t_DD, u8 layer, Vec2 *scale = 0); void setup(dActor_c *actor, Info *pInfo, u8 t_DD, u8 layer, Vec2 *scale = 0); // radius might be diameter? dunno void setupRound(dActor_c *actor, float x, float y, float radius, void *otherCB1, void *otherCB2, void *otherCB3, u8 t_DD, u8 layer); void setRect(float x1, float y1, float x2, float y2, Vec2 *scale = 0); void setRect(Vec2 *p1, Vec2 *p2, Vec2 *scale = 0); void setX(float value); void setY(float value); void setWidth(float value); void setHeight(float value); void setPtrToRotation(s16 *ptr); void update(); // todo: more stuff that might not be relevant atm }; class ActivePhysics { public: struct Info; // forward declaration typedef void (*Callback)(Info *self, Info *other); struct Info { float xDistToCenter; float yDistToCenter; float xDistToEdge; float yDistToEdge; u8 category1; u8 category2; u32 bitfield1; u32 bitfield2; u16 unkShort1C; Callback callback; }; ActivePhysics(); virtual ~ActivePhysics(); dStageActor_c *owner; u32 _8; u32 _C; ActivePhysics *listPrev, *listNext; u32 _18; Info info; u32 _40, _44, _48, _4C; float firstFloatArray[8]; float secondFloatArray[8]; Vec2 positionOfLastCollision; u16 result1; u16 result2; u16 result3; u8 collisionCheckType; u8 chainlinkMode; u8 layer; u8 someFlagByte; u8 isLinkedIntoList; void clear(); void addToList(); void removeFromList(); void initWithStruct(dActor_c *owner, Info *info); void initWithStruct(dActor_c *owner, Info *info, u8 clMode); u16 checkResult1(u16 param); u16 checkResult3(u16 param); float top(); float bottom(); float yCenter(); float right(); float left(); float xCenter(); // Plus more stuff that isn't needed in the public API, I'm pretty sure. }; #include class dActorState_c; class dActorMultiState_c; template class dStateWrapperBase_c { public: dStateWrapperBase_c(TOwner *pOwner) : manager(&pointless, &executor, &dStateBase_c::mNoState), executor(pOwner) { } dStateWrapperBase_c(TOwner *pOwner, dState_c *pInitState) : manager(&pointless, &executor, pInitState), executor(pOwner) { } virtual ~dStateWrapperBase_c() { } dStatePointless_c pointless; dStateExecutor_c executor; dStateMgr_c manager; // All these are passed straight through to the manager virtual void ensureStateHasBegun() { manager.ensureStateHasBegun(); } virtual void execute() { manager.execute(); } virtual void endCurrentState() { manager.endCurrentState(); } virtual void setState(dStateBase_c *pNewState) { manager.setState(pNewState); } virtual void executeNextStateThisTick() { manager.executeNextStateThisTick(); } virtual dStateMethodExecutorBase_c *getCurrentStateMethodExecutor() { return manager.getCurrentStateMethodExecutor(); } virtual dStateBase_c *getNextState() { return manager.getNextState(); } virtual dStateBase_c *getCurrentState() { return manager.getCurrentState(); } virtual dStateBase_c *getPreviousState() { return manager.getPreviousState(); } }; template class dStateWrapper_c : public dStateWrapperBase_c { public: dStateWrapper_c(TOwner *pOwner) : dStateWrapperBase_c(pOwner) { } dStateWrapper_c(TOwner *pOwner, dState_c *pInitState) : dStateWrapperBase_c(pOwner, pInitState) { } ~dStateWrapper_c() { } }; class MultiStateMgrBase { public: virtual ~MultiStateMgrBase(); dStateWrapper_c s1, s2; dStateWrapper_c *ptrToStateMgr; virtual void ensureStateHasBegun(); // calls vfC on ptrToStateMgr virtual void execute(); // calls vf10 on ptrToStateMgr virtual void endCurrentState(); // if (isSecondStateMgr()) { disableSecond(); } else { ptrToStateMgr->_vf14(); } virtual void setState(dStateBase_c *state); // calls vf18 on ptrToStateMgr virtual void executeNextStateThisTick(); // calls vf1C on ptrToStateMgr virtual dStateMethodExecutorBase_c *getCurrentStateMethodExecutor(); // calls vf20 on ptrToStateMgr virtual dStateBase_c *getNextState(); // calls vf24 on ptrToStateMgr virtual dStateBase_c *getCurrentState(); // calls vf28 on ptrToStateMgr virtual dStateBase_c *getPreviousState(); // calls vf2C on ptrToStateMgr virtual void enableSecondWithState(dStateBase_c *state); // sets ptrToStateMgr to s2, calls vf18 on it virtual void disableSecond(); // if (isSecondStateMgr()) { ptrToStateMgr->vf14(); ptrToStateMgr = &s1; } virtual bool isSecondStateMgr(); virtual dStateBase_c *getCurrentStateFromFirst(); // calls vf28 on s1 }; class MultiStateMgr : public MultiStateMgrBase { public: // what the fuck does this do ~MultiStateMgr(); }; #define REF_NINTENDO_STATE(NAME) \ static State StateID_##NAME; #define DECLARE_STATE(NAME) \ static State StateID_##NAME; \ void beginState_##NAME(); \ void executeState_##NAME(); \ void endState_##NAME(); #define CREATE_STATE(CLASS, NAME) \ CLASS::State CLASS::StateID_##NAME \ (#CLASS "::StateID_" #NAME, \ &CLASS::beginState_##NAME, \ &CLASS::executeState_##NAME, \ &CLASS::endState_##NAME); #define CREATE_STATE_E(CLASS, NAME) \ CREATE_STATE(CLASS, NAME) \ void CLASS::beginState_##NAME() { } \ void CLASS::endState_##NAME() { } #define USING_STATES(CLASS) \ typedef dState_c State; struct LinkListEntry { LinkListEntry *prev; LinkListEntry *next; void *owned_obj; }; struct LinkList { LinkListEntry *first; LinkListEntry *last; // PTMF goes here, but I don't know how to represent it }; struct OrderedLinkListEntry : LinkListEntry { u16 order; u16 _; }; struct TreeNode { TreeNode *parent; TreeNode *child; TreeNode *prev; TreeNode *next; void *owned_obj; }; struct Tree { TreeNode *firstNode; // PTMF goes here, but I don't know how to represent it }; typedef bool (*ChainedFunc)(void*); class FunctionChain { public: ChainedFunc *functions; u16 count; u16 current; void setup(ChainedFunc *functions, u16 count); // 8015F740 }; class dStageActor_c; // forward declaration class collisionMgr_c { public: collisionMgr_c(); virtual ~collisionMgr_c(); //FIXME params and returns and add more void Clear1(); void Clear2(); void Init(dStageActor_c*,u8*,u8*,u8*); void Clear3(); int CollidedWithTile(); dStageActor_c* owner; void* struct1_ptr; void* struct2_ptr; void* some_ptr; Vec3* parent_pos_ptr; Vec3* parent_last_pos_ptr; Vec3* parent_speed_ptr; Vec3 someVelocityThing; float xDeltaMaybe; float yDeltaMaybe; u8 _34[24]; //FIXME float someFloat; void* class2DC_ptr; //FIXME void* another_ptr; void* ptr_to_ptr_to_underneath_actor; u8 _5C[44]; //FIXME u32 bitfield_for_checks; u32 bitfield_backup; u32 _90, _94; u8 which_player_of_parent; u8 which_controller; u16 _9A, _9C; u8 _9E[2]; //FIXME u32 another_bitfield; u8 _A4; u8 _A5[3]; //FIXME u32 yet_another_bitfield; u8 _AC; u8 _AD[3]; //FIXME u32 directional_bitfields[2]; // left right u8 flagsB8; u8 flagsB9; u8 _BA[2]; //FIXME u8 _BC, _BD; u16 _BE; u8 _C0, _C1; u16 _C2; u8 _C4[4]; //FIXME u16 _C8; u8 _CA[22]; //FIXME u8 _E0, _E1, _E2; u8 _E3; //FIXME u8 _E4, _E5; u8 _E6[2]; //FIXME u32 current_layer_ptr; u8 current_layer; u8 _ED[3]; //FIXME }; class freezeMgr_c { public: u32 some_count; u32 ice_timer1; u32 ice_timer2; u32 _mstate; //0=not,1=frozen,3=die_coin u32 _10; u32 _nstate; //1=countdown,2=meltedNormal u32 spawns_coin; //1=delete,3=coin u32 _1C_timerLenType; u32 _20_defaultTimerLenType; u32 _24; u32 _28; u32 perm_freeze; u32 _30; u32 actorIds[12]; void* owner; // _64 freezeMgr_c(); ~freezeMgr_c(); //FIXME add params and returns void doSomethingCool1(); void doSomethingCool2(); void setSomething(u32,u32,u32); void Create_ICEACTORs(void*,int); void Delete_ICEACTORs(); void SetIceTimer_pt1(); void SetIceTimer_pt2(); void CheckIceTimer_lte_Value(); void doSomethingCool3(); void doSomethingCool4(); void doSomethingCool5(); void doSomethingCool6(); void DoMeltNormal(); void doSomethingCool7(); void CheckCountdownTimer(); }; class fBase_c { public: u32 id; u32 settings; u16 name; u8 _A; u8 _B; u8 _C; u8 _D; u8 base_type; u8 _F; TreeNode link_connect; OrderedLinkListEntry link_execute; OrderedLinkListEntry link_draw; LinkListEntry link_IDlookup; u32 _50; u32 _54; u32 _58; u32 heap; fBase_c(); virtual int onCreate(); virtual int beforeCreate(); virtual int afterCreate(int); virtual int onDelete(); virtual int beforeDelete(); virtual int afterDelete(int); virtual int onExecute(); virtual int beforeExecute(); virtual int afterExecute(int); virtual int onDraw(); virtual int beforeDraw(); virtual int afterDraw(int); virtual void willBeDeleted(); virtual bool moreHeapShit(u32 size, void *parentHeap); virtual bool createHeap(u32 size, void *parentHeap); virtual void heapCreated(); virtual ~fBase_c(); void Delete(); fBase_c *GetParent(); fBase_c *GetChild(); fBase_c *GetNext(); bool hasUninitialisedProcesses(); // 80162B60 }; class dBase_c : public fBase_c { public: u32 _64; const char *explanation_string; const char *name_string; dBase_c(); int beforeCreate(); int afterCreate(int); int beforeDelete(); int afterDelete(int); int beforeExecute(); int afterExecute(int); int beforeDraw(); int afterDraw(int); ~dBase_c(); virtual const char *GetExplanationString(); }; class dScene_c : public dBase_c { public: FunctionChain *ptrToInitChain; dScene_c(); int beforeCreate(); int afterCreate(int); int beforeDelete(); int afterDelete(int); int beforeExecute(); int afterExecute(int); int beforeDraw(); int afterDraw(int); ~dScene_c(); void setInitChain(FunctionChain &initChain) { ptrToInitChain = &initChain; } }; class dActor_c : public dBase_c { public: LinkListEntry link_actor; mMtx matrix; Vec pos; Vec last_pos; Vec pos_delta; Vec pos_delta2; Vec scale; Vec speed; Vec max_speed; S16Vec rot; S16Vec _106; u32 _10C; u32 _110; float y_speed_inc; u32 _118; float x_speed_inc; u32 _120; bool visible; dActor_c(); virtual void specialDraw1(); virtual void specialDraw2(); virtual int _vf58(); virtual void _vf5C(); ~dActor_c(); }; class dStageActor_c : public dActor_c { public: u8 _125; u32 _128, _12C, _130, _134, _138, _13C; float _140; u32 _144; ActivePhysics aPhysics; collisionMgr_c collMgr; u8 classAt2DC[0x34]; u32 _310, _314; float spriteSomeRectX, spriteSomeRectY; float _320, _324, _328, _32C, _330, _334, _338, _33C, _340, _344; u8 direction; u8 currentZoneID; u8 _34A, _34B; u8 *spriteByteStorage; u16 *spriteShortStorage; u16 spriteEventNum; u64 spriteEventMask; u32 _360; u16 spriteSomeFlag; u8 _366, _367; u32 _368; u8 _36C, _36D; Vec somethingRelatedToScale; u32 _37C, _380, _384, _388; u8 _38C, _38D, enableFlag, currentLayerID; u8 _390, _391, _392, _padding; dStageActor_c(); int beforeCreate(); int afterCreate(int); int beforeDelete(); int afterDelete(int); int beforeExecute(); int afterExecute(int); int beforeDraw(); int afterDraw(int); const char *GetExplanationString(); virtual bool _vf60(); // does stuff with BG_GM virtual void kill(); // nullsub here, defined in StageActor. probably no params virtual int _vf68(); // params unknown. return (1) might be bool virtual u8 *_vf6C(); // returns byte 0x38D virtual Vec2 _vf70(); // returns Vec Actor.pos + Vec Actor.field_D0 virtual int _vf74(); // params unknown. return (1) might be bool virtual void _vf78(); // params unknown. nullsub virtual void _vf7C(); // params unknown. nullsub virtual void eatIn(); // copies Actor.scale into StageActor.somethingRelatedToScale virtual void disableEatIn(); // params unknown. nullsub virtual void _vf88(); // params unknown. nullsub virtual bool _vf8C(void *other); // dAcPy_c/daPlBase_c? return (1) is probably bool. seems related to EatOut. uses vfA4 virtual bool _vf90(dStageActor_c *other); // does something with scores virtual void _vf94(void *other); // dAcPy_c/daPlBase_c? modifies This's position virtual void removeMyActivePhysics(); virtual void addMyActivePhysics(); virtual void returnRegularScale(); // the reverse of vf80, yay virtual void _vfA4(void *other); // AcPy/PlBase? similar to vf94 but not quite the same virtual float _vfA8(void *other); // AcPy/PlBase? what DOES this do...? does a bit of float math virtual void _vfAC(void *other); // copies somethingRelatedToScale into scale, then multiplies scale by vfA8's return virtual void killedByLevelClear(); // plays Wm_en_burst_s at actor position virtual void _vfB4(); // params unknown. nullsub virtual void _vfB8(); // params unknown. nullsub virtual void _vfBC(); // params unknown. nullsub virtual void _vfC0(); // params unknown. nullsub virtual void _vfC4(); // params unknown. nullsub virtual void _vfC8(Vec2 *p); // does stuff including effects and playing PLAYER_SE_OBJ/GROUP_BOOT/SE_OBJ_CMN_SPLASH virtual void _vfCC(Vec2 *p); // mostly same as vfC8, but uses PLAYER_SE_OBJ/GROUP_BOOT/SE_OBJ_CMN_SPLASH_LAVA virtual void _vfD0(Vec2 *p); // mostly same as vfC8, but uses PLAYER_SE_OBJ/GROUP_BOOT/SE_OBJ_CMN_SPLASH_POISON // I'll add methods as I need them void checkZoneBoundaries(u32 flags); // I think this method is for that, anyway ~dStageActor_c(); static void create(Actors type, u32 settings, Vec *pos, S16Vec *rot, u8 layer); static void createChild(Actors type, u32 settings, Vec *pos, S16Vec *rot, u8 layer); }; class dAc_Py_c : public dStageActor_c { public: u8 data[0x1164 - 0x394]; ActivePhysics bPhysics; ActivePhysics cPhysics; ActivePhysics dPhysics; ActivePhysics ePhysics; dAc_Py_c(); int beforeCreate(); int afterCreate(int); int beforeDelete(); int afterDelete(int); int beforeExecute(); int afterExecute(int); int beforeDraw(); int afterDraw(int); ~dAc_Py_c(); }; /* TODO class dActorState_c : public dStageActor_c { public: ~dActorState_c(); virtual void _vfD4(); virtual void _vfD8(); virtual void _vfDC(); }; */ class dActorMultiState_c : public dStageActor_c { public: ~dActorMultiState_c(); MultiStateMgr acState; virtual void doStateChange(dStateBase_c *state); // might return bool? overridden by dEn_c virtual void _vfD8(); // nullsub ?? virtual void _vfDC(); // nullsub ?? virtual void _vfE0(); // nullsub ?? }; class dEn_c : public dActorMultiState_c { public: float _414, _418, _41C, _420; void *nextState; u32 _428, _42C; u8 _430, _431, isDead; u32 _434; u16 _438; u32 _43C; Vec velocity1, velocity2; u8 _458, _459, _45A, _45B, _45C, _45D, _45E; u32 _460; Vec initialScale; float _470; u32 _474, _478; dEn_c *_47C; u32 _480; //FIXME verify that size fits //u8 classAt484[0x4EC - 0x484]; freezeMgr_c frzMgr; u32 _4EC; float _4F0, _4F4, _4F8; u32 flags_4FC; u16 counter_500, counter_502; u16 counter_504[4]; u16 counter_50C; u32 _510, _514, _518; void *_51C; dEn_c *_520; u32 _524; dEn_c(); int afterCreate(int); int beforeExecute(int); int afterExecute(int); int beforeDraw(int); void kill(); void eatIn(); void disableEatIn(); bool _vf8C(void *other); // AcPy/PlBase? void _vfAC(); void _vfCC(Vec2 *p); void _vfD0(Vec2 *p); void doStateChange(dStateBase_c *state); // might return bool, dunno // Now here's where the fun starts. virtual bool preSpriteCollision(ActivePhysics *apThis, ActivePhysics *apOther); virtual bool prePlayerCollision(ActivePhysics *apThis, ActivePhysics *apOther); virtual bool preYoshiCollision(ActivePhysics *apThis, ActivePhysics *apOther); virtual bool stageActorCollision(ActivePhysics *apThis, ActivePhysics *apOther); virtual void spriteCollision(ActivePhysics *apThis, ActivePhysics *apOther); virtual void playerCollision(ActivePhysics *apThis, ActivePhysics *apOther); virtual void yoshiCollision(ActivePhysics *apThis, ActivePhysics *apOther); // WHAT A MESS virtual void collisionCat3_StarPower(ActivePhysics *apThis, ActivePhysics *apOther); virtual void collisionCat5_Mario(ActivePhysics *apThis, ActivePhysics *apOther); virtual void _vf108(ActivePhysics *apThis, ActivePhysics *apOther); virtual void collisionCatD_GroundPound(ActivePhysics *apThis, ActivePhysics *apOther); virtual void _vf110(ActivePhysics *apThis, ActivePhysics *apOther); virtual void collisionCat8_FencePunch(ActivePhysics *apThis, ActivePhysics *apOther); virtual void collisionCat7_WMWaggleWater(ActivePhysics *apThis, ActivePhysics *apOther); virtual void collisionCat7_WMWaggleWaterYoshi(ActivePhysics *apThis, ActivePhysics *apOther); virtual void _vf120(ActivePhysics *apThis, ActivePhysics *apOther); virtual void collisionCatA_PenguinMario(ActivePhysics *apThis, ActivePhysics *apOther); virtual void collisionCat11_PipeCannon(ActivePhysics *apThis, ActivePhysics *apOther); virtual void collisionCat9_RollingObject(ActivePhysics *apThis, ActivePhysics *apOther); virtual void collisionCat1_Fireball_E_Explosion(ActivePhysics *apThis, ActivePhysics *apOther); virtual bool collisionCat2_IceBall_15_YoshiIce(ActivePhysics *apThis, ActivePhysics *apOther); virtual void collisionCat13_Hammer(ActivePhysics *apThis, ActivePhysics *apOther); virtual void collisionCat14_YoshiFire(ActivePhysics *apThis, ActivePhysics *apOther); virtual void _vf140(dStageActor_c *actor); virtual void _vf144(int something); virtual void _vf148(); // deletes actors held by Class484 and other stuff virtual void _vf14C(); // deletes actors held by Class484 and makes an En Coin Jump virtual u32 _vf150(); // reads some bits from a value in Class1EC virtual void eatenByYoshiProbably(); // nullsub, params unknown virtual void playHpdpSound1(); // plays PLAYER_SE_EMY/GROUP_BOOT/SE_EMY_DOWN_HPDP_S or _H virtual void playEnemyDownSound1(); virtual void playEnemyDownComboSound(void *player); // AcPy_c/daPlBase_c? virtual void playHpdpSound2(); // plays PLAYER_SE_EMY/GROUP_BOOT/SE_EMY_DOWN_HPDP_S or _H virtual void _vf168(); // nullsub, params unknown // State Functions virtual void dieFumi_Begin(); // does something involving looping thruogh players virtual void dieFumi_Execute(); // does movement and some other stuff virtual void dieFumi_End(); // nullsub virtual void dieFall_Begin(); // does something involving looping thruogh players virtual void dieFall_Execute(); // does movement and some other stuff virtual void dieFall_End(); // nullsub virtual void dieBigFall_Begin(); // calls vf178 [dieFall_Begin] virtual void dieBigFall_Execute(); // does movement and some other stuff (but less than 170 and 17C) virtual void dieBigFall_End(); // calls vf180 [dieFall_End] virtual void dieSmoke_Begin(); // spawns Wm_en_burst_m effect and then removeMyActivePhysics virtual void dieSmoke_Execute(); // deletes actor with r4=1 virtual void dieSmoke_End(); // nullsub virtual void dieYoshiFumi_Begin(); // spawns Wm_mr_yoshistep effect and then removeMyActivePhysics virtual void dieYoshiFumi_Execute(); // deletes actor with r4=1 virtual void dieYoshiFumi_End(); // nullsub virtual void dieIceVanish_Begin(); // lots of weird stuff virtual void dieIceVanish_Execute(); // deletes actor with r4=1 virtual void dieIceVanish_End(); // nullsub virtual void dieGoal_Begin(); // nullsub virtual void dieGoal_Execute(); // nullsub virtual void dieGoal_End(); // nullsub virtual void dieOther_Begin(); // deletes actor with r4=1 virtual void dieOther_Execute(); // nullsub virtual void dieOther_End(); // nullsub virtual void eatIn_Begin(); // nullsub virtual void eatIn_Execute(); // changes to EatNow on one condition, otherwise calls vfAC virtual void eatIn_End(); // nullsub virtual void eatNow_Begin(); // nullsub virtual void eatNow_Execute(); // nullsub virtual void eatNow_End(); // nullsub virtual void eatOut_Begin(); // nullsub virtual void eatOut_Execute(); // nullsub virtual void eatOut_End(); // nullsub virtual void hitSpin_Begin(); // nullsub virtual void hitSpin_Execute(); // nullsub virtual void hitSpin_End(); // nullsub virtual void ice_Begin(); // does stuff with Class484 and lots of vf's virtual void ice_Execute(); // tons of stuff with Class484 virtual void ice_End(); // sets a field in Class484 to 0 virtual void spawnHitEffectAtPosition(Vec2 pos); virtual void doSomethingWithHardHitAndSoftHitEffects(Vec pos); virtual void playEnemyDownSound2(); virtual void add2ToYSpeed(); virtual bool _vf218(); // stuff with floats and camera virtual void _vf21C(); // does stuff with the speeds virtual void _vf220(void *other); // some type of actor, PlBase? calls vf3F4 on other with r4=this, r5=0 virtual void _vf224(); // stores a couple of values into the struct at 464 virtual void _vf228(); // more fun stuff with 464 and floats virtual bool CreateIceActors(); // does stuff involving ICE_ACTORs and arrays virtual void _vf230(); // "relatedToPlayerOrYoshiCollision" apparently. nullsub, params unknown for now. virtual void _vf234(); // nullsub, params unknown virtual void _vf238(); // calls vf34 on class394, params unknown virtual void _vf23C(); // nullsub, params unknown virtual void _vf240(); // nullsub, params unknown virtual int _vf244(); // returns 0. might be bool. params unknown virtual int _vf248(int something); // does some math involving field510 and [7,7,4,0] and param virtual void _vf24C(void *other); // deals with something in the class involving the bahp flag virtual void _vf250(void *other); virtual void _vf254(void *other); virtual void _vf258(void *other); virtual void _vf25C(void *other); // calls vf250 virtual void _vf260(void *other); // AcPy/PlBase? plays the SE_EMY_FUMU_%d sounds based on some value virtual void _vf264(dStageActor_c *other); // if other is player or yoshi, do Wm_en_hit and a few other things virtual void _vf268(void *other); // AcPy/PlBase? plays the SE_EMY_DOWN_SPIN_%d sounds based on some value virtual void spawnHitEffectAtPositionAgain(Vec2 pos); virtual void playMameStepSound(); // SE_EMY_MAME_STEP at actor position virtual void _vf274(); // nullsub, params unknown virtual void _vf278(void *other); // AcPy/PlBase? plays the SE_EMY_YOSHI_FUMU_%d sounds based on some value virtual void _vf27C(); // nullsub, params unknown ~dEn_c(); static void collisionCallback(ActivePhysics::Info *one, ActivePhysics::Info *two); // States USING_STATES(dEn_c); REF_NINTENDO_STATE(DieFumi); REF_NINTENDO_STATE(DieFall); REF_NINTENDO_STATE(DieBigFall); REF_NINTENDO_STATE(DieSmoke); REF_NINTENDO_STATE(DieIceVanish); REF_NINTENDO_STATE(DieYoshiFumi); REF_NINTENDO_STATE(DieGoal); REF_NINTENDO_STATE(DieOther); }; class daEnBlockMain_c : public dEn_c { public: u32 _528, _52C, _530; Physics physics; float _618, _61C, _620; u32 _624, _628, _62C; float initialY; float _634, _638, _63C, _640; u32 countdown, _648, _64C; u32 _650, _654, _658, _65C; u16 _660; u8 _662, _663, _664, _665, _666, _667; u8 _668, _669, _66A, _66B, _66C, _66D, _66E, _66F; u8 _670, _671, _672, _673; u8 _674; u8 _675, _676, _677, _678, _679, _67A, _67B, _67C; u8 _67D, _67E, _67F, _680; u32 _684; u8 _688, isGroundPound, anotherFlag, _68B, _68C, _68D, _68E, _68F; u32 _690; u8 _694; // Regular methods void blockInit(float initialY); void blockUpdate(); u8 blockResult(); virtual void calledWhenUpMoveBegins(); virtual void calledWhenDownMoveBegins(); virtual void calledWhenUpMoveExecutes(); virtual void calledWhenUpMoveDiffExecutes(); virtual void calledWhenDownMoveExecutes(); virtual void calledWhenDownMoveEndExecutes(); virtual void calledWhenDownMoveDiffExecutes(); virtual void calledWhenDownMoveDiffEndExecutes(); virtual void updateScale(bool movingDown); // State functions virtual void upMove_Begin(); virtual void upMove_Execute(); virtual void upMove_End(); virtual void downMove_Begin(); virtual void downMove_Execute(); virtual void downMove_End(); virtual void downMoveEnd_Begin(); virtual void downMoveEnd_Execute(); virtual void downMoveEnd_End(); virtual void upMove_Diff_Begin(); virtual void upMove_Diff_Execute(); virtual void upMove_Diff_End(); virtual void downMove_Diff_Begin(); virtual void downMove_Diff_Execute(); virtual void downMove_Diff_End(); virtual void downMove_DiffEnd_Begin(); virtual void downMove_DiffEnd_Execute(); virtual void downMove_DiffEnd_End(); static void *PhysicsCallback1; static void *PhysicsCallback2; static void *PhysicsCallback3; static void *OPhysicsCallback1; static void *OPhysicsCallback2; static void *OPhysicsCallback3; USING_STATES(daEnBlockMain_c); REF_NINTENDO_STATE(UpMove); REF_NINTENDO_STATE(DownMove); REF_NINTENDO_STATE(DownMoveEnd); REF_NINTENDO_STATE(UpMove_Diff); REF_NINTENDO_STATE(DownMove_Diff); REF_NINTENDO_STATE(DownMove_DiffEnd); ~daEnBlockMain_c(); }; class dBgGm_c { public: // TODO TODO TODO TODO TODO static dBgGm_c *instance; TileRenderer::List *getTileRendererList(int index); }; class dPlayerModelBase_c { // dunno what's public and what's private here // don't really care public: dPlayerModelBase_c(u8 player_id); // 800D5420 virtual ~dPlayerModelBase_c(); // 800D55D0 char allocator[28]; // actually a mHeapAllocatorSubclass but I don't have that u32 _20; u32 _24; char someAnimation[2][0x38]; // actually PlayerAnim's char yetAnotherAnimation[40]; // actually m3d::banm_c afaics -- is it even 40 bytes? Vec someVector[2]; // maybe not an array Vec headOffs; Vec scale; u8 player_id_1; u8 player_id_2; u8 powerup_id; u8 powerup_tex; int current_anim; int last_anim_maybe; u32 _15C; int someFlags; u32 _164; u32 _168; // related to jump_strings u32 _16C; u32 _170; u32 _174; u8 _178; char padding[3]; // not needed? u32 model_visibility_flags_maybe; u32 mode_maybe; float _184; float _188; u32 _18C; char someArray[6][12]; // some unknown class/struct char _1D8[0x24]; short _1FC; short _1FE; short _200; char padding_[2]; // not needed? u32 _204; u32 _208; virtual int _vf0C(); // 800D6DA0 virtual void prepare(); // 800D5720 virtual void finaliseModel(); // 800D5740 virtual void update(); // 800D5750 virtual void update3DStuff(); // 800D5760 virtual void _vf20(); // 800D6D90 virtual void draw(); // 800D5C70 virtual int getCurrentModel(); // 800D5870 virtual int getCurrentResFile(); // 800D62D0 virtual void setPowerup(u8 powerup_id); // 800D5730 virtual void setPowerupTexture(); // 800D5CC0 virtual void _vf38(); // 800D6D80 virtual void _vf3C(); // 800BD750 virtual void _vf40(); // 800D6D70 virtual void _vf44(); // 800D6D60 virtual void _vf48(); // 800BD740 virtual void _vf4C(); // 800BD730 virtual void getModelMatrix(u32 unk, MtxPtr dest); // 800D5820 virtual int _vf54(); // 80318D0C virtual bool _vf58(int type, char *buf, bool unk); // 800D6930 virtual void startAnimation(int id, float frame, float unk, float updateRate); // 800D5EC0 virtual int _vf60(); // 800D6920 virtual void _vf64(int id, float unk1, float unk2, float unk3); // 800D62F0 virtual void _vf68(int id, float unk); // 800D63E0 virtual void _vf6C(); // 800D62E0 virtual void _vf70(); // 800D6690 virtual void _vf74(); // 800D66A0 virtual void _vf78(); // 800D66B0 virtual void SomethingRelatedToPenguinAnims(); // 800D66C0 virtual void _vf80(); // 800D6A20 virtual void _vf84(float frame); // 800D5D00 virtual void _vf88(float frame); // 800D5D70 virtual void _vf8C(float updateRate); // 800D5D80 virtual void setUpdateRateForAnim1(float updateRate); // 800D5DF0 virtual void _vf94(); // 800D6D40 virtual int _vf98(); // 800D6D30 virtual void _vf9C(); // 800D6D20 virtual int _vfA0(); // 800D6D10 virtual void _vfA4(); // 800D6D00 virtual int _vfA8(); // 800D6CF0 virtual void _vfAC(bool blah); // 800BD720 // I won't even bother with non-virtual functions.... }; class dPlayerModelHandler_c { public: dPlayerModelHandler_c(u8 player_id); // 800D6DB0 virtual ~dPlayerModelHandler_c(); // 800D6EF0 dPlayerModelBase_c *mdlClass; // might be dPlayerModel_c ? int loadModel(u8 player_id, int powerup_id, int unk); // 800D6EE0 void update(); // 800D6F80 void setMatrix(Mtx matrix); // 800D6FA0 void setSRT(Vec position, S16Vec rotation, Vec scale); // 800D7030 void callVF20(); // 800D70F0 void draw(); // 800D7110 private: int hasMatrix; // might be bool ? void allocPlayerClass(u8 player_id); // 800D6E00 }; class mTexture_c { public: mTexture_c(); // 802C0D20 mTexture_c(u16 width, u16 height, GXTexFmt format); // 802C0D70 // vtable is at 80350450 virtual ~mTexture_c(); // 802C0DB0 virtual void setFlagTo1(); // 802C0E20 void setImageBuffer(void *buffer); // 802C0E30 void load(GXTexMapID id); // 802C0E50 void makeTexObj(GXTexObj *obj); // 802C0E90 void flushDC(); // 802C0F10 void makeRadialGradient(); // 802C0F60 parameters unknown yet void makeLinearGradient(int type, char size, u16 startPos, u16 endPos, GXColor begin, GXColor end, bool startAtCenter); // 802C1120 // "type" should be enum once I figure it out // reverse might not be accurate void allocateBuffer(/* EGG::Heap */void *heap = 0); // 802C14D0 void plotPixel(u16 x, u16 y, GXColor pixel); // 802C1570 u16 width; u16 height; u8 flags; u8 format; u8 wrapS; u8 wrapT; u8 minFilter; u8 magFilter; private: void *buffer; void *myBuffer; }; class dDvdLoader_c { public: dDvdLoader_c(); // 8008F140 virtual ~dDvdLoader_c(); // 8008F170 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 int size; void *command; // really mDvd_toMainRam_c void *heap; // really EGG::Heap void *buffer; private: virtual void freeBuffer(); // 8008F380 void freeCommand(); // 8008F3F0 }; namespace nw4r { namespace ut { class CharWriter { public: CharWriter(); ~CharWriter(); void SetupGX(); void SetFontSize(float w, float h); void SetFontSize(float v); float GetFontWidth() const; float GetFontHeight() const; float GetFontAscent() const; float GetFontDescent() const; // returns width float Print(ushort character); void PrintGlyph(float, float, float, /* nw4r::ut::Glyph const & */ void*); void UpdateVertexColor(); private: void SetupGXWithColorMapping(Color c1, Color c2); public: Color colors[8]; // todo: document u32 modeOfSomeKind; float scaleX; float scaleY; float posX; float posY; float posZ; GXTexFilter minFilt; GXTexFilter magFilt; u16 completelyUnknown; u8 alpha; u8 isFixedWidth; float fixedWidthValue; /* ResFont* */ void *font; }; // actually TextWriterBase, but ... class TextWriter : public CharWriter { public: TextWriter(); ~TextWriter(); float GetLineHeight() const; // left out most of these to avoid all the format string vararg bullshit float CalcStringWidth(wchar_t const *string, int length) const; float Print(wchar_t const *string, int length); float CalcLineWidth(wchar_t const *string, int length); float GetLineSpace() const; bool IsDrawFlagSet(ulong, ulong) const; float _4C; float charSpace; float somethingRelatedToLineHeight; u32 _58; u32 drawFlag; void *tagProcessorMaybe; }; } } // 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); }; } extern "C" float fmod(float, float); bool RectanglesOverlap(Vec *bl1, Vec *tr1, Vec *bl2, Vec *tr2); /* Tilemap related stuff */ class TilemapClass { public: virtual ~TilemapClass(); u16 *allocatedBlocks[256]; u32 _404; u8 blockLookup[2048]; u16 blockCount; u32 _C0C; u32 ts1ID, ts2ID, ts3ID, layerID, areaID, frmHeap, is2Castle; // Only the public API is listed u16 *getPointerToTile(int x, int y, u32 *blockNum = 0, bool unkBool = 0); // TODO: more? }; class BGDatClass { public: BGDatClass(); virtual ~BGDatClass(); u8 *bgData[4][3]; TilemapClass *tilemaps[4][3]; u8 *tsObjIndexData[4][4]; u8 *tsObjData[4][4]; char tsNames[4][4][0x20]; // this is fucked up! // the parent heap is frmHeaps[0][0] // each tileset's heap is frmHeaps[AREA][LAYER+1] void *frmHeaps[4][4]; static BGDatClass *instance; // 8042A0D0 // I've only listed the public API because other stuff isn't really needed atm. const char *getTilesetName(int area, int number); // TODO: more? }; struct BGRender { u8 unk[0xC00]; u8 *objectData; u8 _C04, _C05; u16 _C06, _C08; u16 blockNumber; u16 curX, curY; u16 tileToPlace; u16 objDataOffset, objType, objX, objY, objWidth, objHeight; u16 tileNumberWithinBlock, areaID; }; // A HACK extern void *DVDClass; extern "C" u8 *GetRes(void *Something, const char *arcname, const char *filename); // Use THESE instead, until I write something up for dRes or dRes_c or whatever the fuck it's called inline u8 *getResource(const char *arcName, const char *fileName) { return GetRes((void*)(((u8*)DVDClass)+4), arcName, fileName); } inline void scaleDown(Vec* scale, float amt) { scale->x -= amt; scale->y -= amt; scale->z -= amt; } inline void scaleUp(Vec* scale, float amt) { scale->x -= amt; scale->y -= amt; scale->z -= amt; } #endif