diff --git a/README.md b/README.md index 8e999a0..1551eb5 100644 --- a/README.md +++ b/README.md @@ -1,36 +1,36 @@ > Note: This repository was forked from MasterF0x whose GitHub Account disappeared and doesn't represent the code from the original repository 100% (it was about 8 commits ahead / 8 behind when the repository disappeared). If YOU happen to have a backup of the latest version from their original code please let me know. # Super Mario Sunshine - C Kit + A C library for everyone's favorite game: Super Mario Sunshine. The tools in this will allow you to compile C code which can be patched into Super Mario Sunshine. -#What can this do? +## What can this do? The library allows you to compile PPC code that replace functions and interact with objects in Super Mario Sunshine. The code can be either put into a gecko code with a max size of 229 lines or be patched into Super Mario Sunshine's Start.dol. -#Neato!... Well, how do I set this up? +## Neato!... Well, how do I set this up? 0. Clone or download the c kit. -0. Install devkitPro for PPC somewhere on your harddrive. The batch files are set up for it to be located at C:\devkitPro\devkitPPC, but you can edit the batch files to account for your install location. -0. If you want to patch Start.dol, extract it from your Super Mario Sunshine image and copy it into the c kit directory. -0. To compile C code, drag the source file onto build.bat for a gecko code or patchdol.bat to patch Start.dol. -0. The gecko code should be copied into your clipboard or a new .dol file with your source files name will be created. +1. Install devkitPro for PPC somewhere on your harddrive. The batch files are set up for it to be located at C:\devkitPro\devkitPPC, but you can edit the batch files to account for your install location. +2. If you want to patch Start.dol, extract it from your Super Mario Sunshine image and copy it into the c kit directory. +3. To compile C code, drag the source file onto build.bat for a gecko code or patchdol.bat to patch Start.dol. +4. The gecko code should be copied into your clipboard or a new .dol file with your source files name will be created. +#Alright. Do you have any examples to show? -#Alright. Do you have any examples to show? - -Yes, actually. Here's an item spawning example from Miluaces: +Yes, actually. Here's an item spawning example from Miluaces: ``` include "sms.h" int laststate; //Last state -int OnUpdate(MarDirector* director) { +int OnUpdate(MarDirector* director) { int (*GameUpdate)(MarDirector* director) = GetObjectFunction(director, Director_GameUpdate); - + MarioActor* mario = GetMarioHitActor(); ItemActor* item = 0; - + if (!laststate){ if (ControllerOne->buttons & PRESS_DU) //Dpad up spawns a coin item = MakeObjAppear(*gpItemManager, OBJ_COIN); @@ -41,36 +41,34 @@ int OnUpdate(MarDirector* director) { else if (ControllerOne->buttons & PRESS_DD) //Dpad down spawns a turbo nozzle item = MakeObjAppear(*gpItemManager, OBJ_TURBONOZZLE); } - + // If no dpad buttons are pressed, reset laststate if (!(ControllerOne->buttons & (PRESS_DU | PRESS_DL | PRESS_DR | PRESS_DD))) laststate = 0; - + //If item was assigned, set it up if (item != 0){ //Set laststate to 1 to prevent more than one item spawning from one button press laststate = 1; - + //Set item position item->position.x = mario->position.x; item->position.y = mario->position.y + 200.0f; item->position.z = mario->position.z; - + //Set item velocity item->velocity.y = 20.0f; - + //Make item moveable item->flags = item->flags & ~ITEMFLAG_STATIC; } - + return GameUpdate(director); } ``` There are more examples in the repository. -#My code compiled! What do I do now? +## My code compiled! What do I do now? Either build a new SMS image with your dol file or enter your gecko code to see your code run in game. - - diff --git a/inc/sms.h b/inc/sms.h index a008af8..e80db12 100644 --- a/inc/sms.h +++ b/inc/sms.h @@ -1,546 +1,1220 @@ -#ifndef SMS_H - #define SMS_H - - #include - #include - #include - - #define PRESS_START 0x1000 - #define PRESS_B 0x0200 - #define PRESS_A 0x0100 - #define PRESS_Z 0x0010 - #define PRESS_X 0x0400 - #define PRESS_Y 0x0800 - #define PRESS_DU 0x0008 - #define PRESS_DD 0x0004 - #define PRESS_DL 0x0001 - #define PRESS_DR 0x0002 - - #define MARIOFLAG_ALIVE 0x00000001 - #define MARIOFLAG_INVISIBLE 0x00000004 - #define MARIOFLAG_ALLDEAD 0x00000F00 - #define MARIOFLAG_GAMEOVER 0x00000400 - #define MARIOFLAG_SLIP 0x00000080 - #define MARIOFLAG_HASHELMET_FOLLOWCAMERA 0x00001000 - #define MARIOFLAG_HASHELMET 0x00002000 - #define MARIOFLAG_HASFLUDD 0x00008000 - #define MARIOFLAG_SPLASH 0x00010000 - #define MARIOFLAG_PUDDLE 0x00020000 - #define MARIOFLAG_SHIRT 0x00100000 - #define MARIOFLAG_GONE 0x00200000 - - #define STATE_NUMBER 0x0000000F - #define STATE_AIRBORN 0x00000800 - #define STATE_CUTSCENE 0x00001000 - #define STATE_STUNNED 0x00002000 - - #define STATE_RUNNING 0x04000440 - #define STATE_IDLE 0x0C400200 - #define STATE_SPIN 0x00000441 - #define STATE_JUMPSPIN1 0x00000895 - #define STATE_JUMPSPIN2 0x00000896 - #define STATE_JUMP 0x02000880 - #define STATE_JUMPSIDE 0x00000880 - #define STATE_SIDESTEP 0x0C008220 - #define STATE_SWIM 0x000024D7 - #define STATE_DIVE 0x0080088A - #define STATE_DIVEJUMP 0x02000889 - #define STATE_DIVESLIDE 0x00800456 - #define STATE_CLIMB 0x18100340 - #define STATE_CLIMBUP 0x10100343 - #define STATE_WALLJUMP 0x02000886 - #define STATE_WALLSLIDE 0x000008A7 - #define STATE_HANG 0x3800034B - #define STATE_HANGCLIMB 0x3000054F - #define STATE_SLAMSTART 0x008008A9 - #define STATE_SLAM 0x0080023C - #define STATE_SPRAY 0x0C008220 - #define STATE_THROWN 0x000208B8 - #define STATE_HOVER 0x0000088B - #define STATE_STUCK 0x0002033C - #define STATE_TALKING 0x10001308 - -typedef struct{ - uint16_t buttons; - int8_t lanalogx; - int8_t lanalogy; - int8_t ranalogx; - int8_t ranalogy; - uint16_t u1; - uint8_t status; - uint8_t u2; - uint8_t u3; - uint8_t u4; -} __attribute__((packed)) Controller; - -typedef struct{ - void* type; - void* u1[55]; - int u2; - int u3[7]; -} MarioGamePad; - -// MarDirector* mardirector = (MarDirector*)(r13 + 0x9FB8) -typedef struct{ - int u1; -} MarDirector; - -typedef struct{ - float x; - float y; - float z; -} Vector; - -typedef struct{ - void* Type; - void* u2; - int u3; - int u4; - Vector position; - int u5; - void* u6; - Vector scale; - Vector direction; - void* u7; - void* u8; - void* u9; - int u10; - int collision; - float u12; - float u13; - float u14; - float u15; - float u16; - int u17; - int u18; - int u19; - void* u20; -} HitActor; - -typedef struct{ - void* Type; //0 - void* u2; - int u3; - int u4; - Vector position; //10 - int u5; - void* u6; //20 - Vector scale; - Vector direction; //30 - void* u7; - void* u8; //40 - void* collist; - uint16_t colcount; - uint16_t u9; - int colsettings; - float u12; //50 - float u13; - float u14; - float u15; - float u16; //60 - int u17; - int u18; - int u19; - void* u20; //70 - int u21; - int u22; - uint32_t status; - uint32_t laststatus;//80 - int statustime; - void* u23[36]; //88 - int flags; //118 - void* u24[64]; - char name[16]; //218 - void* u25[180]; //228 - MarioGamePad* gamepad; //4fc -} MarioActor; - -struct EMario_t; -struct EnemyMario_t; - -typedef struct EnemyMario_t{ - void* Type; //0 - void* u2; - int u3; - int u4; - Vector position; //10 - int u5; - void* u6; //20 - Vector scale; - Vector direction; //30 - void* u7; - void* u8; //40 - void* collist; - uint16_t colcount; - uint16_t u9; - int colsettings; - float u12; //50 - float u13; - float u14; - float u15; - float u16; //60 - int u17; - int u18; - int u19; - void* u20; //70 - int u21; - int u22; - uint32_t status; - uint32_t laststatus;//80 - int statustime; - void* u23[36]; //88 - int flags; //118 - void* u24[64]; - char name[16]; //218 - void* u25[180]; //228 - MarioGamePad* gamepad; //4fc - void* u26[3940]; - uint16_t emarioflags; - uint16_t emariodamage; //4294 - uint16_t emariohealth; //4296 - uint16_t u27; //4298 - int u28; - int u29; - struct EMario_t* emario; - int u30; - int u31; - float u32; - float u33; - uint16_t u34; - uint16_t u35; - uint16_t u36; - uint16_t hpmetertimer; -} __attribute__((packed)) EnemyMario; - -typedef struct EMario_t{ - void* Type; //0 - void* u2; - int u3; - int u4; - Vector position; //10 - int u5; - void* u6; //20 - Vector scale; - Vector direction; //30 - void* u7; - void* u8; //40 - void* collist; - uint16_t colcount; - uint16_t u9; - int colsettings; - float u12; //50 - float u13; - float u14; - float u15; - float u16; //60 - int u17; - int u18; - int u19; - void* u20; //70 - void* u21[55]; - EnemyMario* enemymario; -} __attribute__((packed)) EMario; - -#define ITEMFLAG_STATIC 0x00000010 - -typedef struct{ - void* Type; - void* u2; - int u3; - int u4; - Vector position; - int u5; - void* u6; - Vector scale; - Vector direction; - void* u7; - void* u8; - void* u9; - int u10; - int itemtype; - float u12; - float u13; - float u14; - float u15; - float u16; - int u17; - int u18; - int u19; - void* u20; - //0x74 - int pad1[14]; - Vector velocity; - int pad2[14]; - int flags; -} ItemActor; - -typedef struct { - int u1; - float u2; -} Sound; - -typedef struct { - int x1; - int y1; - int x2; - int y2; -} JUTRect; -typedef struct { - void* type; - int content[64]; -} J2DGrafContext; -typedef struct { - void* type; - int content[64]; -} J2DOrthoGraph; -typedef struct { - void* type; - int content[9]; -} J2DPrint; -typedef struct { - void* type; -} JUTResFont; -typedef struct { -} ResFONT; -typedef struct { - void* type; - int pad1[2]; - int flags; - JUTRect bounds; - int content[100]; -} J2DTextBox; -typedef struct { - void* type; - int content[64]; -} J2DPane; -typedef struct { - void* type; - int content[64]; -} J2DScreen; -typedef struct { - void* type; -} Talk2D; -typedef struct { - void* type; -} GCConsole; -typedef struct { - void* type; -} PollutionManager; -typedef struct { - void* type; -} ItemManager; -typedef struct { - void* type; - void* u1; - int flags1; - int flags2; - int timer; -} TrembleModelEffect; -typedef struct { - float a1[4]; - float a2[4]; - float a3[4]; -} A3_A4_f; - -//For C++ inheritence -#define GetObjectFunction( object, func ) (void*)*(void**)((int)*(int*)object + func) -#define Director_GameUpdate 0x64 -#define HitActor_TouchPlayer 0x0148 -#define HitActor_ReceiveMessage 0xA0 - -//Free is done automatically on stage transition -#define malloc(n) __nwa__FUl((n)) -#define free(n) __dla__FUl((n)) - -void GXSetScissor(int x, int y, int x2, int y2); -void GXInvalidateTexAll(); - -void J2DOrthoGraph_Create(J2DOrthoGraph* targetaddr, JUTRect* view); - -void J2DGrafContext_Setup2D(J2DGrafContext* graphics); - -void J2DPrint_Create(J2DPrint* targetaddr, JUTResFont* font, int u); -float J2DPrint_GetWidth(J2DPrint* j2dprint, char* text); -void J2DPrint_Initiate(J2DPrint* j2dprint); -void J2DPrint_Print(J2DPrint* j2dprint, int x, int y, char* text, int u1, int u2, int u3); -void J2DPrint_Delete(J2DPrint* j2dprint, int mask); - -#define GameFont (*(ResFONT**)((*(int*)(SceneReference - 0x6038)) + 0x48)) -#define GameStrTable (RTOC - 19304) -void J2DTextBox_Create(J2DTextBox* targetaddr, int u1, JUTRect* bounds, ResFONT* font, void* table, int HBinding, int VBinding); -void J2DTextBox_Draw(J2DTextBox* textbox); -void J2DTextBox_Drawii(J2DTextBox* textbox, int a1, int a2); -void J2DTextBox_DrawSelf(J2DTextBox* textbox, int a1, int a2, A3_A4_f* matrix); -void J2DTextBox_SetString(J2DTextBox* textbox, char* string); -char* J2DTextBox_GetStringPtr(J2DTextBox* textbox); -void J2DTextBox_Delete(J2DTextBox* textbox); - -void J2DPane_Draw(J2DPane* pane, int a1, int a2, J2DGrafContext* graphics, int a3); -void J2DPane_SetBasePosition(J2DPane* pane, int pos); -void J2DPane_MakeMatrix(J2DPane* pane, int a1, int a2); - -void J2DScreen_Draw(J2DScreen* pane, int a1, int a2, J2DGrafContext* graphics, int a3); - -void JUTRect_Set(JUTRect* rect, int x, int y, int w, int h); - -void MarDirector_SetupObjects(MarDirector* director); -void Drama_PrepareUpdate(HitActor* this, int a1, void* drama, void* graphics, int obj); - -/* -typedef ObjItemManager{ - int a1; - int a2; - void (*__dt__)(); - void (*GetType)(); - void (*Load)(); - void (*Save)(); - void (*LoadAfter)(); - void (*SearchF)(); - void (*Perform)(); - void (*CreateModelData)(); - void (*CreateModelData)(); - void (*CreateAnmData)(); - void (*CreateModelDataArray)(); - void (*ClipActors)(); - void (*SetFlagOutOfCube)(); - void (*CreateSpcBinary)(); - bool (*HasMapCollision)(); -}*/ - -register void* RTOC __asm ("r2"); -register void* SceneReference __asm ("r13"); - -// GC -//static void (*GXSetBlendMode)(int a1, int a2, int a3, int a4) = (void*)0x80361dd0; -//static void (*GXBegin)(int a1, int a2, int a3) = (void*)0x8035df88; - -static const Controller* Controllers = (Controller*)0x80404454; -static const Controller* ControllerOne = (Controller*)0x80404454; -static const Controller* ControllerTwo = (Controller*)0x80404460; -static const Controller* ControllerThree = (Controller*)0x8040446c; -static const Controller* ControllerFour = (Controller*)0x80404478; - -static MarioGamePad* GamePads = (MarioGamePad*)0x8057738c; -static MarioGamePad* GamePadOne = (MarioGamePad*)0x8057738c; -static MarioGamePad* GamePadTwo = (MarioGamePad*)0x8057748c; -static MarioGamePad* GamePadThree = (MarioGamePad*)0x8057758c; -static MarioGamePad* GamePadFour = (MarioGamePad*)0x8057768c; - -void MarioGamePad_Read(); -void MarioGamePad_Update(MarioGamePad* pad); -void MarioGamePad_Reset(MarioGamePad* pad); - -static void* gpSystemFont = (void*)0x8040e188; -static void* gpRomFont = (void*)0x8040e18c; - -// SMS -static void* gpApplication = (void*)0x803e9700; -static Talk2D** TalkManager = (Talk2D**)0x8040ddd8; -unsigned int CalcKeyCode(char* key); -void Vector_Add(Vector* v1, Vector* v2, Vector* vo); -void Vector_Subtract(Vector* v1, Vector* v2); -void Vector_Normalize(Vector* vi, Vector* vo); -void Vector_Scale(Vector* vi, float scale); -float Vector_Magnitude(Vector* v); -void Talk2D_OpenWindow(Talk2D* talkmanager, int a1, float f1); -void DrawWaterBackground(GCConsole* console); - -void StampPollution(PollutionManager* pollution, int stamp, float x, float y, float z, float r); -void CleanPollution(PollutionManager* pollution, float x, float y, float z, float r); - -// Stage -static MarDirector** gpMarDirector = (void*)0x8040e178; -static void** gpItemManager = (void**)0x8040df10; -static void** gpMap = (void*)0x8040de98; -static PollutionManager** gpPollution = (void*)0x8040ded0; -static void** gpStrategy = (void*)0x8040e080; -static void** gpSunManager = (void*)0x8040d0c0; -static HitActor** gpSunModel = (void*)0x8040d0c8; - -static uint8_t* ChangeScenario = (void*)0x003e9712; -static uint8_t* ChangeEpisode = (void*)0x003e9713; -void ChangeStage(MarDirector* director, uint32_t stageinfo); -HitActor* SearchF(void* namereflist, int keycode, char* ref); -#define SearchObjByRef(ref) SearchF((void*)*(((int*)*(int*)(SceneReference - 0x5db8)) + 1), CalcKeyCode((ref)), (ref)) -int GetShineStage(uint8_t stageid); - -int IsPolluted(void); - -//Camera -static HitActor** gpCamera = (void*)0x8040d0a8; -void Camera_AddMultiPlayer(void* camera, Vector* position); -void Camera_RemoveMultiPlayer(void* camera, Vector* position); -void Camera_CreateMultiPlayer(void* camera, unsigned char players); - -// Mario -static HitActor** gpMarioOriginal = (void*)0x8040e0e8; -static HitActor** gpMarioAddress = (void*)0x8040e108; -#define GetFludd(mario) (HitActor*)((mario) + 0x03E4) -static Vector** gpMarioPos = (void*)0x8040e10c; -static float** gpMarioAngleX = (void*)0x8040e110; -static float** gpMarioAngleY = (void*)0x8040e114; -static float** gpMarioAngleZ = (void*)0x8040e118; -static float** gpMarioSpeedX = (void*)0x8040e11c; -static float** gpMarioSpeedY = (void*)0x8040e120; -static float** gpMarioSpeedZ = (void*)0x8040e124; -static const uint16_t** gpMarioLightID = (void*)0x8040e128; -static int** gpMarioFlag = (void*)0x8040e12c; -static float** gpMarioThrowPower = (void*)0x8040e130; -static const void*** gpMarioGroundPlane = (void*)0x8040e134; -MarioActor* GetMarioHitActor(); -HitActor* GetFLUDD(); -HitActor* GetMarioYoshi(); -int GetMarioHP(); -int GetMarioStatus(); -int GetMarioStatusFromHitActor(MarioActor* mario); -void IncGoldCoinFlag(uint32_t coinptr, int stage, int amount); -#define IncrementCoin(amount) incGoldCoinFlag(*(int*)(SceneReference - 0x6060), GetShineStage((*(int*)(gpApplication + 0x0E)) & 0xFF), (amount)) -void GetMarioMapPosition(); -void ThrowMario(void*, void*, float, float, float); -void SetMarioAnim(float a1, int a2, int a3); -int IsMarioJumping(); -void SetMarioStatus(MarioActor* mario, int a2, int a3, int a4); -#define MarioDoJump(mario) SetMarioStatus((mario), 0x02000881, 0, 0) -#define MarioDoThrow(mario) SetMarioStatus((mario), 0x000208B8, 0, 0) -void EmitSweat(MarioActor* mario); -void Fludd_Emit(HitActor* fludd); -void Mario_StartVoice(MarioActor* mario, int id); -void Mario_SetGamePad(MarioActor* mario, MarioGamePad* gamepad); -void Mario_CheckController(HitActor* mario, void* drama, void* graphics); -void Mario_ReceiveMessage(MarioActor* mario, HitActor* other, unsigned long message); -void Mario_PlayerControl(MarioActor* mario, void* drama, void* graphics); -void Mario_CheckCollision(MarioActor* mario); -void Mario_DamageExec(MarioActor* mario, HitActor* other, int u1, int u2, int u3, float f1, int u4, float f2, short u5); -void Mario_IncHP(MarioActor* mario, int n); -void Mario_DecHP(MarioActor* mario, int n); -void EnemyMario_CheckController(HitActor* enemymario, void* drama, void* graphics); -void SetMarioVelocity(MarioActor* mario, float vel); -void StartTrembleEffect(TrembleModelEffect* effectmgr, float maxTremble, float minTremble, float damp, int timer); -void Mario_WearGlasses(MarioActor* mario); -#define GetMarioTrembleEffect(mario) ((TrembleModelEffect*)*((void**)(mario) + 0x014F)) - -#define MARIOMSG_THROW 0x07 -#define MARIOMSG_HURTFIRE 0x0a -#define MARIOMSG_HURT 0x0e -void SendMsgToMario(MarioActor* mario, int msg); - -// Objects -#define OBJ_WATER 0x20000002 -#define OBJ_ONEUP 0x20000006 -#define OBJ_COIN 0x2000000E -#define OBJ_BLUECOIN 0x20000010 -#define OBJ_ROCKETNOZZLE 0x20000022 -#define OBJ_HOVERNOZZLE 0x20000026 -#define OBJ_TURBONOZZLE 0x2000002A -HitActor* MakeObjAppear(ItemManager* itemManager, int id); - -// Effects -void GenerateEffectElectric(HitActor* pos); - -// Music / SFX -void PlaySound(int rate, Sound* sfx, int nl1, int nl2, int nl3, int four); -void StartStageEntranceDemoSeq(int u1, int u2); -void StartBGM(int u1); -void StopBGM(int u1); - +#ifndef SMS_H + #define SMS_H + + #include + #include + #include + + #define PRESS_START 0x1000 + #define PRESS_B 0x0200 + #define PRESS_A 0x0100 + #define PRESS_Z 0x0010 + #define PRESS_X 0x0400 + #define PRESS_Y 0x0800 + #define PRESS_DU 0x0008 + #define PRESS_DD 0x0004 + #define PRESS_DL 0x0001 + #define PRESS_DR 0x0002 + #define PRESS_L 0x0040 + #define PRESS_R 0x0020 + + #define MARIOFLAG_ALIVE 0x00000001 + #define MARIOFLAG_INVISIBLE 0x00000004 + #define MARIOFLAG_ALLDEAD 0x00000F00 + #define MARIOFLAG_GAMEOVER 0x00000400 + #define MARIOFLAG_SLIP 0x00000080 + #define MARIOFLAG_HASHELMET_FOLLOWCAMERA 0x00001000 + #define MARIOFLAG_HASHELMET 0x00002000 + #define MARIOFLAG_HASFLUDD 0x00008000 + #define MARIOFLAG_SPLASH 0x00010000 + #define MARIOFLAG_PUDDLE 0x00020000 + #define MARIOFLAG_SHIRT 0x00100000 + #define MARIOFLAG_GONE 0x00200000 + + #define STATE_NUMBER 0x0000000F + #define STATE_AIRBORN 0x00000800 + #define STATE_DOJUMP 0x00000080 + #define STATE_AIRBORN 0x00000800 + #define STATE_CUTSCENE 0x00001000 + #define STATE_STUNNED 0x00002000 + + #define STATE_RUNNING 0x04000440 + #define STATE_IDLE 0x0C400201 + #define STATE_STOP 0x0C00023D + #define STATE_SPIN 0x00000441 + #define STATE_JUMPSPIN 0x00000890 + #define STATE_JUMPSPIN1 0x00000895 + #define STATE_JUMPSPIN2 0x00000896 + #define STATE_JUMP 0x02000880 + #define STATE_D_JUMP 0x02000881 + #define STATE_TRIPLE_J 0x00000882 + #define STATE_JMP_LAND 0x04000470 + #define STATE_HVY_LAND 0x04000473 + #define STATE_D_LAND 0x04000472 + #define STATE_T_LAND 0x0800023A + #define STATE_JUMPSIDE 0x00000880 + #define STATE_SIDESTEP 0x0C008220 + #define STATE_SIDE_FLIP 0x00000887 + #define STATE_FALL 0x0000088C + #define STATE_SWIM 0x000024D7 + #define STATE_DIVE 0x0080088A + #define STATE_DIVEJUMP 0x02000889 + #define STATE_DIVESLIDE 0x00800456 + #define STATE_CLIMB 0x18100340 + #define STATE_CLIMBUP 0x10100343 + #define STATE_WALLJUMP 0x02000886 + #define STATE_WALLSLIDE 0x000008A7 + #define STATE_HANG 0x3800034B + #define STATE_HANGCLIMB 0x3000054F + #define STATE_SLAMSTART 0x008008A9 + #define STATE_SLAM 0x0080023C + #define STATE_SPRAY 0x0C008220 + #define STATE_THROWN 0x000208B8 + #define STATE_HOVER 0x0000088B + #define STATE_STUCK 0x0002033C + #define STATE_TALKING 0x10001308 + #define STATE_TURNING 0X00000444 + //add new + #define STATE_SHINE_C 0x00001302 // Collected Shine Sprite + #define STATE_DEATH 0x00020467 + #define STATE_DOOR_F_O 0x00001321 // Door open fail + #define STATE_WALL_S_L 0x04000471 + #define STATE_WALL_SLD 0x000008A7 + #define STATE_F_KNCK_H 0X000208B0 // hard knockback from front (bumping into a wall from dive) + #define STATE_KNCK_LND 0X00020462 // Landing from front knockback + #define STATE_KNCK_GND 0x00020466 // Front knockback while grounded + #define STATE_FIRE_HIT 0x000208B7 + #define STATE_FIRE_RVR 0x08000239 // Recover from fire on ground + #define STATE_HOVER_F 0x0000088D // Falling from hover + #define STATE_SLIDE_R1 0x000008A6 // Recover from slide by flipping + #define STATE_SLIDE_R2 0x00000386 // Recover from slide by getting up + #define STATE_R_SPRAY 0x0C008220 // Recover from spray + #define STATE_G_POUND 0x008008A9 // Ground pounding + + //#define + + #define BGM_DOLPIC 0x80010001 + #define BGM_BIANCO 0x80010002 + #define BGM_MAMMA 0x80010003 + #define BGM_PINNAPACO_SEA 0x80010004 + #define BGM_PINNAPACO 0x80010005 + #define BGM_MARE_SEA 0x80010006 + #define BGM_MONTEVILLAGE 0x80010007 + #define BGM_SHILENA 0x80010008 + #define BGM_RICCO 0x80010009 + #define BGM_GET_SHINE 0x8001000A + #define BGM_CHUBOSS 0x8001000B + #define BGM_MISS 0x8001000C + #define BGM_BOSS 0x8001000D + #define BGM_MAP_SELECT 0x8001000E + #define BGM_BOSSPAKU_DEMO 0x8001000F + #define BGM_MAIN_TITLE 0x80010010 + #define BGM_CHUBOSS2 0x80010011 + #define BGM_EXTRA 0x80010012 + #define BGM_DELFINO 0x80010013 + #define BGM_MAREVILLAGE 0x80010014 + #define BGM_CORONA 0x80010015 + #define BGM_KAGEMARIO 0x80010016 + #define BGM_CAMERA 0x80010017 + #define BGM_MONTE_ONSEN 0x80010018 + #define BGM_MECHAKUPPA 0x80010019 + #define BGM_AIRPORT 0x8001001A + #define BGM_UNDERGROUND 0x8001001B + #define BGM_TITLEBACK 0x8001001C + #define BGM_MONTE_NIGHT 0x8001001D + #define BGM_CASINO 0x8001001E + #define BGM_EVENT 0x8001001F + #define BGM_TIME_IVENT 0x80010020 + #define BGM_SKY_AND_SEA 0x80010021 + #define BGM_MONTE_RESCUE 0x80010022 + #define BGM_MERRY_GO_ROUND 0x80010023 + #define BGM_SCENARIO_SELECT 0x80010024 + #define BGM_FANFARE_CASINO 0x80010025 + #define BGM_FANFARE_RACE 0x80010026 + #define BGM_CAMERA_KAGE 0x80010027 + #define BGM_GAMEOVER 0x80010028 + #define BGM_BOSSHANA_2ND3RD 0x80010029 + #define BGM_BOSSGESO_2DN3RD 0x8001002A + #define BGM_CHUBOSS_MANTA 0x8001002B + #define BGM_MONTE_LAST 0x8001002C + #define BGM_SHINE_APPEAR 0x8001002D + #define BGM_KUPPA 0x8001002E + #define BGM_SPACEWORLD 0x80011030 + + #define SND_PIPE 9598 + + //#define GFX_OFF 0x09A4 - E3 + #define GFX_OFF 0x07F4 + + #define AIRPORT 0 + #define DOLPIC0 1 + #define BIANCO0 2 + #define RICCO0 3 + #define MAMMA0 4 + #define PINNABEACH0 5 + #define SIRENA0 6 + #define DELFINO0 7 + #define MONTE0 8 + #define MARE0 9 + #define NONE0 10 + #define SCALE0 11 + #define TEST10 12 + #define PINNAPARCO0 13 + #define CASINO0 14 + + #define GFX_OFF 0x09A4 + + +typedef float Mtx[3][4]; +typedef float Mtx44[4][4]; + +enum GXProjectionType +{ + GX_PERSPECTIVE = 0, + GX_ORTHOGRAPHIC = 1 +}; + +typedef struct +{ + + float x, y, z; + +} Vec, *VecPtr, Point3d, *Point3dPtr; + +typedef struct { + Point3d position; + Point3d target; + Vec up; + float fovy; + float znear; + float zfar; + Mtx viewMtx; + Mtx44 projMtx; +} Camera; + +typedef struct { + int xorg; + int yorg; + int width; + int height; +} ViewPort; + +typedef struct{ + int u1; +} WaterGun; + +typedef struct{ + uint16_t buttons; // 0x0 + int8_t lanalogx; // 0x4 + int8_t lanalogy; // 0x8 + int8_t ranalogx; // 0xC + int8_t ranalogy; // 0xA + uint8_t ltrig; // 0xE + uint8_t rtrig; // 0x12 + uint8_t status; //0x16 + uint8_t u2; + uint8_t u3; + uint8_t u4; +} __attribute__((packed)) Controller; + +typedef struct{ + void* type; + void* u1[55]; + int u2; + int u3[7]; +} MarioGamePad; + +// MarDirector* mardirector = (MarDirector*)(r13 + 0x9FB8) +typedef struct{ + int u1; +} MarDirector; + +typedef struct{ + float x; + float y; + float z; +} Vector; + +typedef struct { + int flag1; + int flag2; + int flag3; + int flag4; + int flag5; + int flag6; + int flag7; + int flag8; + int flag9; + int flag10; +} NormalSoundData; + +typedef struct { + float u1; + float u2; + float u3; + float u4; +} HitTable; + +typedef struct{ + char* colKey; + int flag; +} ColData; + +typedef struct AnimData_t{ + char* modelKey; + int unk1; + int unk2; + int unk3; + int unk4; + int unk5; + int unk6; + int unk7; + int unk8; + int unk9; + char* animModel; + char* animKey; + int unk10; + int unk11; + int unk12; +} AnimData; + +typedef struct { + int info1; + AnimData* aData; +} AnimInfo; + +typedef struct { + int flag1; + int flag2; + int flag3; + HitTable* hitData; +} HitInfo; + +typedef struct { + int flag1; + ColData* cData; +} ColInfo; + +typedef struct { + int flag1; + NormalSoundData* normSoundData; // okay what? +} SoundInfo; + +typedef struct ObjectData_t { + char* modelKey; + float unknown1; + char* shiftJis; + char* shiftJis2; + AnimInfo* aInfo; + HitInfo* hInfo; + ColInfo* cInfo; + SoundInfo* sInfo; + int unused1; + int unused2; + int unused3; + int unused4; + float unknown2; + int flag1; + int flag2; +} ObjectData; + +struct HitActor_t; +struct EMario_t; +struct EnemyMario_t; +struct WaterGun_t; +struct Yoshi_t; +struct ObjectData_t; +struct AnimData_t; + +typedef struct PolarSubCamera_t { + void* Type; + void* u2; + int u3; + int u4; + Vector position; + int u5; + void* u6; + int u7; + Vector u8; + float u9; + int u10; + Vector rotation; + Vector u11; + int u12[51]; + MarioGamePad* gamepad; +} PolarSubCamera; + +typedef struct MapObjBase_t{ + void* Type; //0 + void* u2; + int u3; + int u4; + Vector position; //10 + int u5; + void* u6; //20 + Vector scale; +} __attribute__((packed)) MapObjBase; + +typedef struct HitActor_t{ + void* Type; //0 + void* u2; + int u3; + int u4; + Vector position; //10 + int u5; + void* u6; //20 + Vector scale; + Vector direction; //30 + void* u7; + void* u8; //40 + struct HitActor_t** colarray; + uint16_t colcount; + uint16_t colarraysize; + int colsettings; + float bound1; //50 + float bound2; + float bound3; + float bound4; + float bound5; //60 + int colflags; + int u18; + int u19; + void* u20; //70 + void* u21[0x2F]; + ObjectData* objData; // 130 +} __attribute__((packed)) HitActor; + +typedef struct { + void* Type; //0 + void* u2; + int u3; + int u4; + Vector position; //10 + int u5; + void* u6; //20 + Vector scale; + Vector direction; //30 + void* u7; + void* u8; //40 + struct HitActor_t** colarray; + uint16_t colcount; + uint16_t colarraysize; + int colsettings; + float bound1; //50 + float bound2; + float bound3; + float bound4; + float bound5; //60 + int colflags; + int u18; + int u19; + void* u20; //70 + void* u21; //74 + void* u22; //78 + int snd1; //7C + int snd2; //80 + char* bas; //84 + int status; //88 + int init; //8c + int status_timer; //90 + int temp6; //94 + int temp7; //98 + int temp8; //9c + int temp9; //a0 + int temp10; //a4 + int temp11; //a8 + int temp12; //ac + float dirY; //b0 + int current; //b4 + float u23; //b8 + float u24; //bc + float u25; //c0 + void* u26; //c4 + float u27; //c8 + float u28; //cc + int reserved1; //d0 + int u29; // Used - d4 + int analogX; //d8 + int analogY; //dc + int reserved4; //e0 + int reserved5; //e4 + void* u30[18]; + ObjectData* objData; // 130 +} __attribute__((packed)) MultiActor; + +typedef struct { + void* Type; //0 + void* u2; + int u3; + int u4; + Vector position; //10 + int u5; + void* u6; //20 + Vector scale; + Vector direction; //30 + void* u7; + void* u8; //40 + struct HitActor_t** colarray; + uint16_t colcount; + uint16_t colarraysize; + int colsettings; + float bound1; //50 + float bound2; + float bound3; + float bound4; + float bound5; //60 + int colflags; + int u18; + int u19; + void* u20; //70 + void* u21; + void* u22; + int u23; + int isFlipped; + int flipTimer; +} __attribute__((packed)) flipBlockActor; + +typedef struct{ + void* Type; + void* u2; + int u3; + int hitCount; + Vector position; + int u5; + void* u6; + Vector scale; + Vector direction; + void* u7; + void* u8; + void* u9; + int u10; + int collision; + float u12; + float u13; + float u14; + float u15; + float u16; + int u17; + int u18; + int u19; + void* u20; +} BlockActor; + +typedef struct { + void* Type; //0 + void* u2; + int u3; + int u4; + Vector position; //10 + int u5; + void* u6; //20 + Vector scale; + Vector direction; //30 + void* u7; + void* u8; //40 + struct HitActor_t** colarray; + uint16_t colcount; + uint16_t colarraysize; + int colsettings; + float bound1; //50 + float bound2; + float bound3; + float bound4; + float bound5; //60 + int colflags; + int u18; + int u19; + void* u20; //70 + void* u21; + void* u22; + int u23; + int isDown; + int isRot; +} __attribute__((packed)) hexActor; + +typedef struct{ + void* Type; //0 + void* u2; //4 + int u3; //8 + int u4; //c + Vector position; //10 + int u5; + void* u6; //20 + Vector scale; + Vector direction; //30 + void* u7; + void* u8; //40 + HitActor** colarray; + uint16_t colcount; + uint16_t colarraysize; + int colsettings; + float bound1; //50 + float bound2; + float bound3; + float bound4; + float bound5; //60 + int colflags; + int u18; + int u19; + void* u20; //70 + int u21; + int u22; + uint32_t status; + uint32_t laststatus; //80 + int statustime; + void* u23; //88 + void* u24; //8c + void* u25; //90 + uint16_t rotx; //94 + uint16_t roty; //96 + uint16_t rotz; //98 + uint16_t roty2; //9a + void* u26; //9c + void* u27; //a0 + Vector speed; //a4 + void* u28[26]; //b0 + int flags; //118 + void* u29[178]; //11c + WaterGun* watergun; //3e4 + void* u31; //3e8 + void* u32; //3ec + struct Yoshi_t* yoshi; //3f0 + void* u33[40]; //3f4 + MarioGamePad* gamepad; //4f4 +} __attribute__((packed)) MarioActor; + +typedef struct EnemyMario_t{ + void* Type; //0 + void* u2; + int u3; + int u4; + Vector position; //10 + int u5; + void* u6; //20 + Vector scale; + Vector direction; //30 + void* u7; + void* u8; //40 + HitActor** colarray; + uint16_t colcount; + uint16_t colarraysize; + int colsettings; + float bound1; //50 + float bound2; + float bound3; + float bound4; + float bound5; //60 + int colflags; + int u18; + int u19; + void* u20; //70 + int u21; + int u22; + uint32_t status; + uint32_t laststatus;//80 + int statustime; + void* u23[36]; //88 + int flags; //118 + void* u24[64]; + char name[16]; //218 + void* u25[180]; //228 + MarioGamePad* gamepad; //4fc + void* u26[3940]; + uint16_t emarioflags; + uint16_t emariodamage; //4294 + uint16_t emariohealth; //4296 + uint16_t u27; //4298 + int u28; + int u29; + struct EMario_t* emario; + int u30; + int u31; + float u32; + float u33; + uint16_t u34; + uint16_t u35; + uint16_t u36; + uint16_t hpmetertimer; +} __attribute__((packed)) EnemyMario; + +typedef struct EMario_t{ + void* Type; //0 + void* u2; + int u3; + int u4; + Vector position; //10 + int u5; + void* u6; //20 + Vector scale; + Vector direction; //30 + void* u7; + void* u8; //40 + HitActor** colarray; + uint16_t colcount; + uint16_t colarraysize; + int colsettings; + float bound1; //50 + float bound2; + float bound3; + float bound4; + float bound5; //60 + int colflags; + int u18; + int u19; + void* u20; //70 + void* u21[55]; + EnemyMario* enemymario; +} __attribute__((packed)) EMario; + +#define ITEMFLAG_STATIC 0x00000010 + +typedef struct{ + void* Type; + void* u2; + int u3; + int u4; + Vector position; + int u5; + void* u6; + Vector scale; + Vector direction; + void* u7; + void* u8; + void* u9; + int u10; + int itemtype; + float u12; + float u13; + float u14; + float u15; + float u16; + int u17; + int u18; + int u19; + void* u20; + //0x74 + int pad1[14]; + Vector velocity; + int pad2[14]; + int flags; +} __attribute__((packed)) ItemActor; + +typedef struct{ + uint8_t u1; //00 + uint8_t u2; + uint8_t u3; + uint8_t u4; + int u5; //04 + int u6; //08 + int u7; //0c + MarioActor* mario; +} __attribute__((packed)) Yoshi; + +typedef struct{ + void* u1[6]; + int count; //18 + void* u1_2[21]; + Vector position; //70 + void* u2[11]; //7c + float u3; //a8 + void* u4[4]; //7c + float u5; //bc + void* u6[4]; //c0 + float u7; //d0 + void* u8[9]; //d4 + float u9; //f8 + void* u10[13]; + uint16_t u11; //134 + uint16_t u12; +} __attribute__((packed)) WaterEmitInfo; + +typedef struct { + int u1; + float u2; +} Sound; + +typedef struct { + int x1; + int y1; + int x2; + int y2; +} JUTRect; +typedef struct { + void* type; + int content[64]; +} J2DGrafContext; +typedef struct { + void* type; + int content[64]; +} J2DOrthoGraph; +typedef struct { + void* type; + int content[9]; +} J2DPrint; +typedef struct { + void* type; +} JUTResFont; +typedef struct { +} ResFONT; +typedef struct { + void* type; + int pad1[2]; + int flags; + JUTRect bounds; + int content[100]; +} J2DTextBox; +typedef struct { + void* type; + int content[64]; +} J2DPaneO; +typedef struct { + void* type; + int content[64]; +} J2DScreen; + +typedef struct { + int charIndex; + int unk1; + uint8_t voice; +} JMSMesgEntry; + +typedef struct { + int unk1; + char* textBuf; + JMSMesgEntry* entry[10]; +} TalkMesEntry; + +typedef struct { + void* type; + void* data[596]; + TalkMesEntry* msgEntry; +} Talk2D; + +typedef struct { + void* type; +} GCConsole; +typedef struct { + void* type; +} PollutionManager; +typedef struct { + void* type; +} ItemManager; +typedef struct { + void* type; + void* u1; + int flags1; + int flags2; + int timer; +} TrembleModelEffect; +typedef struct { + float a1[4]; + float a2[4]; + float a3[4]; +} A3_A4_f; + +typedef struct { + int x; + int y; + int w; + int h; +} Rect; + +typedef struct { + void* type; + int type2; + int id; + int isVisible; + int pane_id; + JUTRect rect; + JUTRect cRect; + JUTRect clipRect; + JUTRect scissorBounds; + void* unk1[0x4A]; + long* tmem; +} J2DPane; + +typedef struct CARDFileInfo +{ + int chan; + int fileNo; + int offset; + int length; + int iBlock; +} CARDFileInfo; + +const int32_t testObjectVTable[119] = +{ + 0x00000000, 0x00000000, 0x801C4580, 0x80007D70, + 0x801AF750, 0x802FA6F4, 0x801B2FF0, 0x802FA6FC, + 0x801B3364, 0x00000000, 0x00000000, 0x801C4918, + 0x803370C0, 0x8033720C, 0x80337214, 0x8033721C, + 0x80337220, 0x80337228, 0x8033722C, 0x80337230, + 0x80337234, 0x80007FA8, 0x80007FA0, 0x80007F98, + 0x80007F90, 0x80007F88, 0x80007F80, 0x803370E0, + 0x803370E8, 0x803370EC, 0x803370F4, 0x803370F8, + 0x80337100, 0x80337104, 0x802F7004, 0x802F7020, + 0x802F703C, 0x802F7058, 0x802F7074, 0x802F7090, + 0x801B305C, 0x800C6E9C, 0x801B4194, 0x80007D40, + 0x800C6E94, 0x80218CC0, 0x801AFA4C, 0x802187D0, + 0x801B345C, 0x801AFF74, 0x801B35F8, 0x801B36B8, + 0x8021818C, 0x80218020, 0x80217FC8, 0x80217DE4, + 0x801AFA80, 0x801B4114, 0x80217D88, 0x80217D6C, + 0x80217CC8, 0x80217B30, 0x80217990, 0x801B401C, + 0x801B0430, 0x801B0738, 0x801B12F8, 0x801B1368, + 0x801B9C24, 0x801B1058, 0x801B118C, 0x800C6ED0, + 0x801B17DC, 0x800C6F08, 0x801B238C, 0x801B1D64, + 0x801B12F0, 0x801AEBEC, 0x800C6F0C, 0x800C6F10, + 0x800C6F14, 0x801B02D0, 0x801C42E4, 0x801B43D0, + 0x801B03B8, 0x801B03F4, 0x801B08F4, 0x800C6F18, + 0x800C6F20, 0x801AEBE4, 0x801B1764, 0x801B4F30, + 0x801B3F2C, 0x801B4580, 0x801B4528, 0x801B4644, + 0x801B46C4, 0x801B48F8, 0x801B4D78, 0x801B47E4, + 0x801B4DD0, 0x801B4950, 0x801B49A4, 0x801B4200, + 0x801B4BDC, 0x801B49F8, 0x801B4CEC, 0x801B4274, + 0x801B4D54, 0x801B4470, 0x801B44DC, 0x801B444C, + 0x801B3938, 0x801B3ADC, 0x801B3B8C, 0x801B3DFC, + 0x801B3EE4, 0x801B3D64, 0x801B3DF0, +}; + +//For C++ inheritence +#define GetObjectFunction( object, func ) (void*)*(void**)((int)*(int*)object + func) +#define Director_GameUpdate 0x64 +#define HitActor_TouchPlayer 0x0148 +#define HitActor_ReceiveMessage 0xA0 + +//Only works with objects with vtables +#define GetType( object ) *(int*)object +#define TYPE_ENEMYMARIO 0x803aef24 +#define TYPE_EMARIO 0x803ae404 +#define TYPE_ITEMNOZZLE 0x803c942c + + +//Free is done automatically on stage transition +#define malloc(n) __nwa__FUl((n)) +#define free(n) __dla__FUl((n)) + +void GXSetScissor(int x, int y, int x2, int y2); +void GXSetViewport(float x, float y, float w, float h, float nearZ, float farZ); +void GXSetProjection(float mtx[4][4], int projType); +void GXFlush(); +void C_MTXLookAt(Mtx mtx, Point3dPtr* camPos, VecPtr* camUp, Point3dPtr* target); +void setSrcRect(int viewPortObj, int rect); +void GXInvalidateTexAll(); + +void J2DOrthoGraph_Create(J2DOrthoGraph* targetaddr, JUTRect* view); + +void J2DGrafContext_Setup2D(J2DGrafContext* graphics); + +void J2DPrint_Create(J2DPrint* targetaddr, JUTResFont* font, int u); +float J2DPrint_GetWidth(J2DPrint* j2dprint, char* text); +void J2DPrint_Initiate(J2DPrint* j2dprint); +void J2DPrint_Print(J2DPrint* j2dprint, int x, int y, char* text, int u1, int u2, int u3); +void J2DPrint_Delete(J2DPrint* j2dprint, int mask); + +#define GameFont (*(ResFONT**)((*(int*)(SceneReference - 0x6038)) + 0x48)) +#define GameStrTable (RTOC - 19304) +void J2DTextBox_Create(J2DTextBox* targetaddr, int u1, JUTRect* bounds, ResFONT* font, void* table, int HBinding, int VBinding); +void J2DTextBox_Draw(J2DTextBox* textbox); +void J2DTextBox_Drawii(J2DTextBox* textbox, int a1, int a2); +void J2DTextBox_DrawSelf(J2DTextBox* textbox, int a1, int a2, A3_A4_f* matrix); +void J2DTextBox_SetString(J2DTextBox* textbox, char* string); +char* J2DTextBox_GetStringPtr(J2DTextBox* textbox); +void J2DTextBox_Delete(J2DTextBox* textbox); + +void J2DPane_Draw(J2DPane* pane, int a1, int a2, J2DGrafContext* graphics, int a3); +void J2DPane_SetBasePosition(J2DPane* pane, int pos); +void J2DPane_MakeMatrix(J2DPane* pane, int a1, int a2); + +void J2DScreen_Draw(J2DScreen* pane, int a1, int a2, J2DGrafContext* graphics, int a3); + +void JUTRect_Set(JUTRect* rect, int x, int y, int w, int h); + +void setTalkBox(Talk2D* tManager, char* textBuffer, JMSMesgEntry* entry); + +void MarDirector_SetupObjects(MarDirector* director); +void Drama_PrepareUpdate(HitActor* this, int a1, void* drama, void* graphics, int obj); + +/* +typedef ObjItemManager{ + int a1; + int a2; + void (*__dt__)(); + void (*GetType)(); + void (*Load)(); + void (*Save)(); + void (*LoadAfter)(); + void (*SearchF)(); + void (*Perform)(); + void (*CreateModelData)(); + void (*CreateModelData)(); + void (*CreateAnmData)(); + void (*CreateModelDataArray)(); + void (*ClipActors)(); + void (*SetFlagOutOfCube)(); + void (*CreateSpcBinary)(); + bool (*HasMapCollision)(); +}*/ + +register void* RTOC __asm ("r2"); +register void* SceneReference __asm ("r13"); + +// math +float cosf(float); +float sinf(float); +float sqrtf(float); + +// GC +//static void (*GXSetBlendMode)(int a1, int a2, int a3, int a4) = (void*)0x80361dd0; +//static void (*GXBegin)(int a1, int a2, int a3) = (void*)0x8035df88; + +static const Controller* Controllers = (Controller*)0x80404454; +static const Controller* ControllerOne = (Controller*)0x80404454; +static const Controller* ControllerTwo = (Controller*)0x80404460; +static const Controller* ControllerThree = (Controller*)0x8040446c; +static const Controller* ControllerFour = (Controller*)0x80404478; + +static MarioGamePad* GamePads = (MarioGamePad*)0x8057738c; +static MarioGamePad* GamePadOne = (MarioGamePad*)0x8057738c; +static MarioGamePad* GamePadTwo = (MarioGamePad*)0x8057748c; +static MarioGamePad* GamePadThree = (MarioGamePad*)0x8057758c; +static MarioGamePad* GamePadFour = (MarioGamePad*)0x8057768c; + +void MarioGamePad_Read(); +void MarioGamePad_Update(MarioGamePad* pad); +void MarioGamePad_Reset(MarioGamePad* pad); + +static void* gpSystemFont = (void*)0x8040e188; +static void* gpRomFont = (void*)0x8040e18c; + +// SMS +static void* gpApplication = (void*)0x803e9700; +static Talk2D** TalkManager = (Talk2D**)0x8040ddd8; +static void** gpMarioParticleManager = (void**)0x8040e150; +static void** gpModelWaterManager = (void**)0x8040e138; +uint32_t* gModelWaterManagerWaterColor = (uint32_t*)0x803dd898; +unsigned int CalcKeyCode(char* key); +void Vector_Add(Vector* v1, Vector* v2, Vector* vo); +void Vector_Subtract(Vector* v1, Vector* v2); +void Vector_Normalize(Vector* vi, Vector* vo); +void Vector_Scale(Vector* vi, float scale); +float Vector_Magnitude(Vector* v); +void Talk2D_OpenWindow(Talk2D* talkmanager, int a1, float f1); +void openNormalTalkWindow(Talk2D* manager); +void DrawWaterBackground(GCConsole* console); + +void StampPollution(PollutionManager* pollution, int stamp, float x, float y, float z, float r); +void CleanPollution(PollutionManager* pollution, float x, float y, float z, float r); + +// Stage +static MarDirector** gpMarDirector = (void*)0x8040e178; +static void** gpItemManager = (void**)0x8040df10; +static void** gpMap = (void*)0x8040de98; +static PollutionManager** gpPollution = (void*)0x8040ded0; +static void** gpStrategy = (void*)0x8040e080; +static void** gpSunManager = (void*)0x8040d0c0; +static HitActor** gpSunModel = (void*)0x8040d0c8; + +static uint8_t* ChangeScenario = (void*)0x003e9712; +static uint8_t* ChangeEpisode = (void*)0x003e9713; +void ChangeStage(MarDirector* director, uint32_t stageinfo); +HitActor* SearchF(void* namereflist, int keycode, char* ref); +#define SearchObjByRef(ref) SearchF((void*)*(((int*)*(int*)(SceneReference - 0x5db8)) + 1), CalcKeyCode((ref)), (ref)) +int GetShineStage(uint8_t stageid); + +int IsPolluted(void); + +//Camera +static HitActor** gpCamera = (void*)0x8040d0a8; +void Camera_AddMultiPlayer(void* camera, Vector* position); +void Camera_RemoveMultiPlayer(void* camera, Vector* position); +void Camera_CreateMultiPlayer(void* camera, unsigned char players); +void PolarSubCamera_UpdateMultiplayer(void* camera); + +// Mario +static HitActor** gpMarioOriginal = (void*)0x8040e0e8; +static HitActor** gpMarioAddress = (void*)0x8040e108; +#define GetFludd(mario) (HitActor*)((mario) + 0x03E4) +static Vector** gpMarioPos = (void*)0x8040e10c; +static uint16_t** gpMarioAngleX = (void*)0x8040e110; +static uint16_t** gpMarioAngleY = (void*)0x8040e114; +static uint16_t** gpMarioAngleZ = (void*)0x8040e118; +static float** gpMarioSpeedX = (void*)0x8040e11c; +static float** gpMarioSpeedY = (void*)0x8040e120; +static float** gpMarioSpeedZ = (void*)0x8040e124; +static const uint16_t** gpMarioLightID = (void*)0x8040e128; +static int** gpMarioFlag = (void*)0x8040e12c; +static float** gpMarioThrowPower = (void*)0x8040e130; +static const void*** gpMarioGroundPlane = (void*)0x8040e134; +MarioActor* GetMarioHitActor(); +HitActor* GetFLUDD(); +HitActor* GetMarioYoshi(); +int GetMarioHP(); +int GetMarioStatus(); +int GetMarioStatusFromHitActor(MarioActor* mario); +void IncGoldCoinFlag(uint32_t coinptr, int stage, int amount); +#define IncrementCoin(amount) incGoldCoinFlag(*(int*)(SceneReference - 0x6060), GetShineStage((*(int*)(gpApplication + 0x0E)) & 0xFF), (amount)) +void GetMarioMapPosition(); +void ThrowMario(void*, void*, float, float, float); +void SetMarioAnim(float a1, int a2, int a3); +int IsMarioJumping(); +int SMS_IsMarioDashing(); +void SetMarioStatus(MarioActor* mario, int a2, int a3, int a4); +#define MarioDoJump(mario) SetMarioStatus((mario), 0x02000881, 0, 0) +#define MarioDoThrow(mario) SetMarioStatus((mario), 0x000208B8, 0, 0) +void EmitSweat(MarioActor* mario); +void Fludd_Emit(WaterGun* fludd); +void Mario_StartVoice(MarioActor* mario, int id); +void Mario_SetGamePad(MarioActor* mario, MarioGamePad* gamepad); +void Mario_CheckController(HitActor* mario, void* drama, void* graphics); +void Mario_ReceiveMessage(MarioActor* mario, HitActor* other, unsigned long message); +void Mario_PlayerControl(MarioActor* mario, void* drama, void* graphics); +void Mario_CheckCollision(MarioActor* mario); +void Mario_DamageExec(MarioActor* mario, HitActor* other, int u1, int u2, int u3, float f1, int u4, float f2, short u5); +void Mario_IncHP(MarioActor* mario, int n); +void Mario_DecHP(MarioActor* mario, int n); +void EnemyMario_CheckController(HitActor* enemymario, void* drama, void* graphics); +void SetMarioVelocity(MarioActor* mario, float vel); +void StartTrembleEffect(TrembleModelEffect* effectmgr, float maxTremble, float minTremble, float damp, int timer); +void Mario_WearGlasses(MarioActor* mario); +void MapObjBase_RemoveMapCollision(MapObjBase* obj); +void Mario_InitValues(MarioActor* mario); +void Mario_Trample(MarioActor* mario, HitActor* other); +void Mario_SetAnimation(MarioActor* mario, int id, float f1); +void Mario_SetStatusToJumping(MarioActor* mario, long u1, long u2); +void Mario_GetOffYoshi(MarioActor* mario); +void Mario_WaterGunUpdate(MarioActor* martin); +void mario_initModel(MarioActor* mario); +void mario_initValues(MarioActor* mario); +#define GetMarioTrembleEffect(mario) ((TrembleModelEffect*)*((void**)(mario) + 0x014F)) + +void Yoshi_Ride(Yoshi* yoshi); + +void WaterGun_Create(WaterGun* fludd, MarioActor* mario); +void WaterGun_Init(WaterGun* fludd); +void WaterGun_ChangeNozzle(void* this, int nozzletype, int nozzleslot); +void WaterGun_Update(WaterGun*, int, void*); + +#define MARIOMSG_THROW 0x07 +#define MARIOMSG_HURTFIRE 0x0a +#define MARIOMSG_HURT 0x0e +void SendMsgToMario(MarioActor* mario, int msg); + +// Objects +#define OBJ_WATER 0x20000002 +#define OBJ_ONEUP 0x20000006 +#define OBJ_COIN 0x2000000E +#define OBJ_BLUECOIN 0x20000010 +#define OBJ_ROCKETNOZZLE 0x20000022 +#define OBJ_HOVERNOZZLE 0x20000026 +#define OBJ_TURBONOZZLE 0x2000002A +HitActor* MakeObjAppear(ItemManager* itemManager, int id); +HitActor* makeShineAppearWithDemo(ItemManager* itemManager, char* manager, char* mang2, float x, float y, float z); + +//Water +void WaterEmitInfo_Create(WaterEmitInfo* this, const char* prm); +void ModelWaterManager_EmitRequest(void* man, void* emitinfo); + +// Effects +void GenerateEffectElectric(HitActor* pos); +void emitGetCoinEffect(int unk1, MarioActor* mario); +void emitGotEffect(MarioActor* mario); +void objAppear(HitActor* actor); +void destroyCol(HitActor* actor); +void initModelData(HitActor* actor); +void marioCanTake(MarioActor* mario, HitActor* actor); +void marioStartVoice(MarioActor* mario, int soundIndex); + +void ParticleManager_EmitWithRotate(void* man, int particle, Vector* position, uint16_t yaw, uint16_t pitch, uint16_t roll, uint8_t u2, void const* u5); +void MapObjBase_EmitSplash(MapObjBase* obj); + +void changeTexture(int gfx, int gfxtype, int amnt); +void setPanePosition(J2DPane* plane, long speed, int unk2, int unk3, int unk4); +void updatePane(J2DPane* pane); +void updateBoundPane(J2DPane* pane); +void updateBlendPane(J2DPane* pane); +void movePane(J2DPane* pane, int u1, int u2); +int searchPane(long root, int id); +void processAppearCoin(int GCConsole); +void startAppearCoin(int GCConsole); +void processDownCoin(int GCConsole, int u1, long u2, long u3); +void getModel(HitActor* actor); +void showAllShapePacket(void); +void makeObjAppeared(HitActor* actor); +void startMapObjAnim(HitActor* actor, int multi); +void createMActor(int u1, int u2, int u3, int u4, int u5); +void startAnimation(int objProp, int anim, int u1); +void setUpMapCollision(HitActor* actor); +void setFrameRate(long _0x74, int unk1, float speed); +void changeCollision(HitActor* actor, int unk1, float unk2, float unk3); +void EasyEmitParticle(int effect, Vector* position, HitActor* actor, Vector* u1); + +// Music / SFX +void PlaySound(int rate, Sound* sfx, int nl1, int nl2, int nl3, int four); +void startSoundSystemSE(int id, int unk1, int unk2, int unk3); +void StartStageEntranceDemoSeq(int u1, int u2); +void StartBGM(int u1); +void StopBGM(int u1, int u2); +void StopBGMs(int unk1, int unk2); +void search(int id); +void setAnimSound(HitActor* actor, char* bas); +void initAnimSound(int mBuff, int BAS, float unk1, int unk2); + +//TEST LUMA +static float* lumaX = (void*)0x810e21bc; +static float* lumaY = (void*)0x810e21c0; +static float* lumaZ = (void*)0x810e21c4; +static float* lumaRotY = (void*)0x810e21e0; +static float* lumaScaleX = (void*)0x810e21d0; +static float* lumaScaleY = (void*)0x810e21d4; +static float* lumaScaleZ = (void*)0x810e21d8; +static float* CamRotX = (void*)0x812444e8; +static float* CamRotY = (void*)0x812444ec; +static float* CamRotZ = (void*)0x812444f0; +static float* CoinHUD = (void*)0x80e2cfc4; + +void startCameraDemo(HitActor* cameraActor, int anim, float startrotation, int u1, long u2, int u3); +void coinTaken(HitActor* coin, HitActor* mario); +void redCoinTaken(HitActor* coin, HitActor* mario); +void startAppearGo(long ConsoleStr); +void startJAIStream(char* audioFile, int u1, void* u2); +void loadToMainRAM(char* file, int unk1, int unk2, int unk3, long unk4, int unk5, int unk6, int unk7); +void DVDOpen(char* file, long unk1); +void DVDPrepareStreamASync(long finfo, int length, int offset, long callback); +void DVDStopStreamAtEndAsync(long commandblock, long callback); +void DVDCancelStreamAsync(long commandblock, long callback); +void loadToARAM(char* file, int unk1, int unk2, int unk3, int unk4); +void loadModelData(char* modelFile, int flags, char* directory); +void setBuffer(void* constructor, void* buffer, int size); +void JSURead(void* constructor, void* buffer, int amount); +int readData(void* constructor, void* buffer, int size); +int getGlbResource(char* file); +void loadBCKDataBase(int bck); +void setBTP(long objPtr, char* animFile); +float getDistance(HitActor* object, Vector position); + +static uint32_t** key = (void*)0x80412fec; +static const int* TGCCConsole2 = (void*)0x80902AB4; +//static const int* TGCCConsole2 = (void*)0x80ea3804; +const int* firstPane = (void*)0x80ea40e4; +void StartSoundActorWithInfo(int, Vector*, Vector*, float, int, int, void**, int, uint8_t); + +//Other +void PSMTXCopy(); +void CLBPolarToCross(Vector* center, Vector* out, float rho, uint16_t theta ,uint16_t phi); +void Application_Init(void* application); + +void CARDInit(void); +int CARDMount(int channelNum, void* workArea, long cardCallBack); +int CARDOpen(int channelNum, char* fileName, CARDFileInfo* fileInfo); +int CARDCreate(int channelNum, char* fileName, int size, CARDFileInfo* fileInfo); +int CARDRead(CARDFileInfo* fileInfo, void* bufferAddr, int length, int offset); +int CARDWrite(CARDFileInfo* fileInfo, void* bufferAddr, int length, int offset); + +//80e2d0d4 - c_cu +//80143a38 +//80578988 +//80426df0 + +//8117002c + #endif \ No newline at end of file diff --git a/patchdol.bat b/patchdol.bat index 2f8891d..78d13cf 100644 --- a/patchdol.bat +++ b/patchdol.bat @@ -9,5 +9,5 @@ C:\devkitPro\devkitPPC\bin\powerpc-eabi-objdump.exe obj_%~n1.o --full-content if ERRORLEVEL 1 pause if ERRORLEVEL 1 exit C:\devkitPro\devkitPPC\bin\powerpc-eabi-objcopy.exe obj_%~n1.o %~n1.bin -O binary -R .eh_frame -R .comment -R .gnu.attributes -g -S -DolInsert.exe %~n1.bin -m %~n1.map -dol ./Start.dol -o %~n1.dol -c OnUpdate:0x802a6160:3 -c OnSetup:0x802998b8:0 -c OnDraw2D:0x80143f14:0 -c OnWaterHitsGround:0x8027f7dc:0 -c OnObjectTouchMario:0x801b02fc:3 -c OnAllNPCsUpdate:0x8003e2f0:0 -c OnSmallEnemyHitMario:0x8006c76c:3 -r EMarioControl:0x8004010c -r IsMario:0x8024db0c -r EMarioReceiveMessage:0x8003956c -r MarioSendMessage:0x80273870 -r EMarioPlayerControl:8004006c -c OnMarioIncHP:0x80282ee0:0x80282f04:0x80282f84:0x80283414:0x80283490:0x802834d4:0 -c OnMarioDecHP:0x80242b10:0 -r EMarioDamageExec:0x80040068 -r IsMultiplayerMap:0x802a8b30 +DolInsert.exe %~n1.bin -m %~n1.map -dol ./Start.dol -o %~n1.dol -c OnUpdate:0x802a6160:3 -c OnSetup:0x802998b8:0 -c OnDraw2D:0x80143f14:0 -c OnWaterHitsGround:0x8027f7dc:0 -c OnObjectTouchMario:0x801b02fc:3 -c OnAllNPCsUpdate:0x8003e2f0:0 -c OnSmallEnemyHitMario:0x8006c76c:3 -r IsMario:0x8024db0c -r MarioSendMessage:0x80273870 -c OnMarioIncHP:0x80282ee0:0x80282f04:0x80282f84:0x80283414:0x80283490:0x802834d4:0 -c OnMarioDecHP:0x80242b10:0 -r IsMultiplayerMap:0x802a8b30 -c OnCheckActorsHit:0x80299af8:0 -c OnDetectHit:0x8021bfb4:0x8021bc00:0 -c OnMarioHeld:0x80284bd0:0 -c OnMarioThrow:0x802437bc:5 -c OnMarioDrop:0x8023f89c:3 -c OnChangeNozzle:0x80283204:0x80283154:0x802830a4:0 -c OnRideYoshi:0x8028121c:0 -r IsOnYoshi:0x802558c8 -r IsOnYoshi2:0x8024e2e4 -c OnDismountYoshi:0x8024dfc8:0x80270638:0 -c OnWaterGunUpdate:0x8024e2a0:0 -c OnUpdateMultiplayerCamera:0x80023860:0 -c CalcMultiplayerCameraPos:0x80030c04:0 -c CheckOtherObjectCollisions:0x8021bc08:1 -c CheckOtherObjectCollisions2:0x8021bba8:0 -c ChangeAllPlayerStatus:0x80240798:0x80240928:80240a2c:0 -c CreateYoshi:0x80276850:0 -c OnInitApp:0x8000561c:0 -c OnCameraMove:0x80023150:0 pause \ No newline at end of file diff --git a/smsFuncs b/smsFuncs index 66c5d5a..dbb2480 100644 --- a/smsFuncs +++ b/smsFuncs @@ -1,15 +1,29 @@ +CARDInit = 0x803551a0; +CARDMount = 0x803588dc; +CARDOpen = 0x8035938c; +CARDCreate = 0x803598a8; +CARDRead = 0x80359d20; +CARDWrite = 0x8035a09c; MarDirector_SetupObjects = 0x802b76f4; PlaySound = 0x800189d4; +StartBGM = 0x80016978; +StopBGM = 0x8001686c; +StopBGMS = 0x80016740; +search = 0x80016d44; +searchPane = 0x802d0050; StartStageEntranceDemoSeq = 0x802bb880; -GenerateEffectElectric = 0x80262e18; +GenerateEffectElectric = 0x80262E18; MakeObjAppear = 0x801b6e3c; +makeShineAppearWithDemo = 0x801c018c; SendMsgToMario = 0x80273870; EmitSweat = 0x8026465c; Mario_StartVoice = 0x8028537c; Fludd_Emit = 0x80268f98; SetMarioStatus = 0x80254034; IsMarioJumping = 0x802739b4; -Mario_SetAnim = 0x80247670; +IsMarioDashing = 0x8027372c; +initAnimSound = 0x80012eb0; +setMarioAnim = 0x80247670; ThrowMario = 0x80254200; GetMarioMapPosition = 0x8007706c; IncGoldCoinFlag = 0x80294610; @@ -20,16 +34,21 @@ GetMarioYoshi = 0x80273a00; GetFLUDD = 0x802738c0; GetMarioHitActor = 0x802739d4; GetShineStage = 0x802a8ac8; +getGlbResource = 0x802c2fb0; SearchF = 0x802fa7ac; +setSrcRect = 0x802f884c; +setFrameRate = 0x80238e7c; ChangeStage = 0x8029a31c; -DrawWaterBackground = 0x801492a4; +DrawWaterBackground = 0x801492A4; Talk2D_OpenWindow = 0x80150514; Vector_Magnitude = 0x8022a414; Vector_Normalize = 0x8022a43c; Vector_Subtract = 0x80010ca0; Vector_Add = 0x8034a56c; Vector_Scale = 0x8034a5b4; +readData = 0x802c6178; CalcKeyCode = 0x802fa4d8; +C_MTXLookAt = 0x80349f5c; JUTRect_Set = 0x802ca1e0; J2DScreen_Draw = 0x802cfda8; J2DPane_MakeMatrix = 0x802cbbfc; @@ -49,8 +68,13 @@ J2DPrint_GetWidth = 0x802ce294; J2DPrint_Create = 0x802cdc7c; J2DGrafContext_Setup2D = 0x802eb6bc; J2DOrthoGraph_Create = 0x802ecfcc; +JSURead = 0x802c5770; GXInvalidateTexAll = 0x80360400; +GXSetProjection = 0x80362c34; GXSetScissor = 0x80363138; +GXSetViewport = 0x803630c8; +GXFlush = 0x8035d8f0; +getDistance = 0x801b9068; StampPollution = 0x8019de84; CleanPollution = 0x8019ddb4; Drama_PrepareUpdate = 0x802fcc94; @@ -68,10 +92,91 @@ Mario_PlayerControl = 0x8024de38; Mario_DamageExec = 0x8024280c; Mario_IncHP = 0x80243928; Mario_DecHP = 0x80243828; +mario_initModel = 0x80246578; +mario_initValues = 0x802766b0; EnemyMario_CheckController = 0x8004010c; Camera_AddMultiPlayer = 0x80030cc0; Camera_RemoveMultiPlayer = 0x80030c28; Camera_CreateMultiPlayer = 0x80030d1c; Mario_DrawHP = 0x8003fdc4; IsPolluted = 0x801a12e8; -Mario_WearGlasses = 0x80247fa4; \ No newline at end of file +Mario_WearGlasses = 0x80247fa4; +emitGetCoinEffect = 0x80264550; +emitGotEffect = 0x802645dc; +changeTexture = 0x802cc6a0; +setPanePosition = 0x8015508c; +setAnimSound = 0x80217a8c; +setTalkBox = 0x801515a0; +Destroy = 0x801b4114; +destroyCol = 0x801b1130; +objAppear = 0x801b0430; +openNormalTalkWindow = 0x80152fb0; +startCameraDemo = 0x80032a84; +coinTaken = 0x801bec88; +redCoinTaken = 0x801be428; +startAppearGo = 0x80171bb8; +updatePane = 0x8013ebf0; +updateBoundPane = 0x80154c98; +updateBlendPane = 0x8017900c; +movePane = 0x8013eeb0; +processAppearCoin = 0x80146104; +startAppearCoin = 0x8014c7e8; +processDownCoin = 0x801466f0; +initModelData = 0x801b1c34; +ObjHitCheck_CheckActorsHit = 0x8021b900; +ObjHitCheck_DetectHit = 0x8021c29c; +MapObjBase_RemoveMapCollision = 0x801b1130; +WaterGun_ChangeNozzle = 0x8026a164; +Mario_InitValues = 0x802766b0; +Mario_GetOffYoshi = 0x8024eb6c; +Mario_WaterGunUpdate = 0x8024e300; +Yoshi_Ride = 0x802703e8; +WaterGun_Create = 0x8026aa48; +WaterGun_Init = 0x8026a3bc; +WaterGun_Update = 0x8026971c; +ParticleManager_EmitWithRotate = 0x8028844c; +PolarSubCamera_UpdateMultiplayer = 0x800308b4; +CLBPolarToCross = 0x800289b4; +ModelWaterManager_EmitRequest = 0x8027fc84; +WaterEmitInfo_Create = 0x802806f4; +MapObjBase_EmitSplash = 0x801b8d34; +cosf = 0x8033c610; +sinf = 0x8033c630; +sqrtf = 0x800067e8; +PSMTXCopy = 0x803499bc; +marioCanTake = 0x80243550; +marioStartVoice = 0x8028537c; +getModel = 0x80218a50; +showAllShapePacket = 0x80235728; +makeObjAppeared = 0x801b0430; +startMapObjAnim = 0x801b09d4; +startSoundSystemSE = 0x80018864; +setBuffer = 0x802c6164; +createMActor = 0x8021cc74; +startAnimation = 0x80239e64; +setBTP = 0x80238898; +setUpMapCollision = 0x801b238c; +changeCollision = 0x8018e5e0; +startJAIStream = 0x80309504; +loadToMainRAM = 0x802ea8fc; +loadToARAM = 0x802ebba0; +loadModelData = 0x8021d5a4; +loadBCKDataBase = 0x802e8ca4; +DVDOpen = 0x8034b914; +DVDPrepareStreamASync = 0x8034beb0; +DVDStopStreamAtEndAsync = 0x8034de6c; +DVDCancelStreamAsync = 0x8034ddb0; +Mario_SetAnim = 0x80247670; +ThrowMario = 0x8007706c; +GetMarioStatus = 0x802738f0; +GetMarioHP = 0x80273674; +Mario_Trample = 0x802432b8; +Mario_SetAnimation = 0x80247670; +Mario_SetStatusToJumping = 0x802543a0; +Application_Init = 0x802a73c4; +EasyEmitParticle = 0x8000e3a4; +StartSoundActorWithInfo = 0x800185f4; +Camera_CalcFinalPosAndAt = 0x80023950; +Camera_UpdateGameCamera = 0x800234e8; +movePane = 0x8013eeb0; +PSMTXCopy = 0x803499bc; \ No newline at end of file diff --git a/smsmulti.c b/smsmulti.c new file mode 100644 index 0000000..c981fd5 --- /dev/null +++ b/smsmulti.c @@ -0,0 +1,1039 @@ +/* Super Mario Sunshine Multiplayer */ + +#include +#include +#include +#include +#include +#include "sms.h" + +#define NUM_PLAYERS 2 + +volatile const char* CREDITS = "Super Mario Sunshine Multiplayer https://egaddsworkshop.com/"; + +const float PI = 3.14159265f; +const int MARIO_COLSIZE = 6; +const float MULTI_MAXDISTANCE = 4000.0f; +const char* MARIO_EMITTER = "/barrel.prm"; +const float MARIO_TRAMPLEHEIGHT = 60.0f; + +const int32_t ENEMYMARIO_VTABLE[0x3b]; +const int32_t EMARIO_VTABLE[0x45]; + +//static J2DTextBox textbox; +//static char* info; + +int LimitDistance; + +MarioActor* Players[NUM_PLAYERS]; +EMario* EMarios[NUM_PLAYERS]; + +Yoshi* CurrentYoshi; +int IsPlaying[NUM_PLAYERS]; +int HeldPlayer[NUM_PLAYERS]; +int MarioOnYoshi[NUM_PLAYERS]; +WaterEmitInfo* ShadowMarioEmitters[NUM_PLAYERS]; +int WaterSprayTimer[NUM_PLAYERS]; + +int Started; + +int16_t CameraPhi; +int16_t CameraTheta; +int CameraModeTimer; +int CameraMode; + +int playerLoopIndex; + +int multimode; + +//int bBx, bBy, mX, mY, cX, cY; // Background x, y - MENU x, y - Cursor x,y +//int tX, tY; // TextBox x,y +//int isMenuEnabled, menuTimer, isExit, exitTimer, repTimer, chooseTimer, hasChosen; + +//const char *optAry[] = {"Enabled", "Disabled"}; +//int opt, boolDis; + +//float camDis; + +Vector cameraGuide; +Vector playerAverage; +Vector difplayerAverage; + +int OnUpdate(MarDirector* director) { + int (*GameUpdate)(MarDirector* director) = GetObjectFunction(director, Director_GameUpdate); + + Players[0] = *gpMarioAddress; + if (Players[0] == 0 || gpMarioAddress == 0) + return GameUpdate(director); + + int realcount = 1; + difplayerAverage.x = playerAverage.x; + difplayerAverage.y = playerAverage.y; + difplayerAverage.z = playerAverage.z; + playerAverage.x = Players[0]->position.x; + playerAverage.y = Players[0]->position.y; + playerAverage.z = Players[0]->position.z; + + if (!Started) + CameraPhi = Players[0]->roty + 0x7FFF; + for (int i = 1; i < NUM_PLAYERS; i++){ + if (Players[i] == 0) + continue; + + if (IsPlaying[i] && ((EnemyMario*)Players[i])->emariohealth > 0){ + realcount++; + playerAverage.x += Players[i]->position.x; + playerAverage.y += Players[i]->position.y; + playerAverage.z += Players[i]->position.z; + } + + if (!Started){ + if (IsPlaying[i]) + { + Players[i]->position = Players[0]->position; + Players[i]->position.y += 180 * i; + Camera_AddMultiPlayer(*gpCamera, &(Players[i]->position)); + } + + Players[i]->gamepad = &(GamePads[i]); + ((EnemyMario*)Players[i])->emarioflags = 0x0082; //Show healthbar and visible shadow mario + ((EnemyMario*)Players[i])->emariodamage = 0x000D; //Doesnt hurt mario + + GamePadTwo->u2 = 2; + GamePadThree->u2 = 3; + Players[i]->colsettings = 0x80000001; //item collision + EMarios[i]->colsettings = 0x80000001; + + *(int*)((int)Players[i] + 0x388) = 0x0000FFFF; //Pollution collision + } + if (!IsPlaying[i] && (Controllers[i].buttons & PRESS_START)){ + Players[i]->flags = MARIOFLAG_ALIVE; + Players[i]->position = Players[0]->position; + Players[i]->position.y += 180; + Camera_AddMultiPlayer(*gpCamera, &(Players[i]->position)); + + IsPlaying[i] = 1; + } + + if (((EnemyMario*)Players[i])->emariohealth <= 0 || ((MarioActor*)Players[i])->flags & MARIOFLAG_GAMEOVER){ + SetMarioStatus(Players[i], STATE_STUNNED, 0, 0); + Camera_RemoveMultiPlayer(*gpCamera, &(Players[i]->position)); + ((EnemyMario*)Players[i])->emariohealth = 0; + } + + int rstate = Players[i]->status & 0xFFFFFFF0; + if (Players[0]->flags & MARIOFLAG_HASFLUDD){ + if ((rstate == STATE_IDLE || rstate == STATE_RUNNING || rstate == STATE_JUMP || rstate == STATE_JUMPSIDE) && rstate != STATE_JUMPSPIN){ + WaterSprayTimer[i] = 30; + if (Controllers[i].buttons & PRESS_R){ + MapObjBase_EmitSplash(Players[i]); + SetMarioStatus(Players[i], STATE_JUMPSPIN1, 0, 0); + Players[i]->speed.y = 40.0f; + WaterSprayTimer[i] = 0; + } + } + else if (rstate == STATE_JUMPSPIN && Controllers[i].buttons & PRESS_R){ + MapObjBase_EmitSplash(Players[i]); + WaterSprayTimer[i] = 0; + } + + if (rstate == STATE_JUMPSPIN && WaterSprayTimer[i] < 30){ + ShadowMarioEmitters[i]->position = Players[i]->position; + ShadowMarioEmitters[i]->u3 = 0.35f; + ShadowMarioEmitters[i]->u5 = 5.0f; + ShadowMarioEmitters[i]->u7 = 5.0f; + ShadowMarioEmitters[i]->u9 = 5.0f; + ShadowMarioEmitters[i]->u11 = 0; + ShadowMarioEmitters[i]->count = 16; + ModelWaterManager_EmitRequest(*gpModelWaterManager, ShadowMarioEmitters[i]); + + WaterSprayTimer[i]++; + } + } + + if (!(Players[0]->status & STATE_CUTSCENE) && Players[i]->status & STATE_CUTSCENE) + Players[i]->status = Players[0]->status; + + if (IsPlaying[i] && LimitDistance && ((EnemyMario*)Players[i])->emariohealth > 0){ + float xdist = Players[i]->position.x - Players[0]->position.x; + float zdist = Players[i]->position.z - Players[0]->position.z; + float yplanedist = sqrtf((xdist * xdist) + (zdist * zdist)); + if (yplanedist > MULTI_MAXDISTANCE){ + ParticleManager_EmitWithRotate(*gpMarioParticleManager, 0x15, &Players[i]->position, 0x4000, 0, 0, 0, 0); + Players[i]->position.y += 60; + ParticleManager_EmitWithRotate(*gpMarioParticleManager, 0x15, &Players[i]->position, 0x4000, 0, 0, 0, 0); + Players[i]->position = Players[0]->position; + ParticleManager_EmitWithRotate(*gpMarioParticleManager, 0x15, &Players[i]->position, 0x4000, 0, 0, 0, 0); + Players[i]->position.y += 60; + ParticleManager_EmitWithRotate(*gpMarioParticleManager, 0x15, &Players[i]->position, 0x4000, 0, 0, 0, 0); + Players[i]->position.y += 240; + Players[i]->speed.y = 0.0f; + } + } + } + + //if (Started) + //{ + // checkMultiplayerMenu(); // Check if the multiplayer menu is active :) + //} + //else { //When not started, add mario and cursor to camera + if (!Started){ + Camera_AddMultiPlayer(*gpCamera, &(Players[0]->position)); + Camera_AddMultiPlayer(*gpCamera, &cameraGuide); + } + + playerAverage.x /= (float)realcount; + playerAverage.y /= (float)realcount; + playerAverage.z /= (float)realcount; + difplayerAverage.x = playerAverage.x - difplayerAverage.x; + difplayerAverage.y = playerAverage.y - difplayerAverage.y; + difplayerAverage.z = playerAverage.z - difplayerAverage.z; + cameraGuide.x = playerAverage.x; + cameraGuide.y = playerAverage.y; + cameraGuide.z = playerAverage.z; + + for (int i = 0; i < NUM_PLAYERS; i++) + { + if (Players[i] == 0) + continue; + if (!IsPlaying[i]) + continue; + //Camera controls + if (Controllers[i].buttons & PRESS_L && (!(Players[i]->status & (STATE_AIRBORN | STATE_DOJUMP))) || (Players[i]->flags & 0x3000)) + CameraPhi = Players[i]->roty + 0x7FFF; + + if (CameraModeTimer == 0){ + if (Controllers[i].buttons & PRESS_DL){ + CameraMode++; + CameraModeTimer = 30; + } + else if (Controllers[i].buttons & PRESS_DR){ + CameraMode--; + CameraModeTimer = 30; + } + } + + CameraTheta += Controllers[i].ranalogy * 2; + CameraPhi += Controllers[i].ranalogx * 4; + } + if (CameraTheta > 6000) + CameraTheta = 6000; + if (CameraTheta < -1000) + CameraTheta = -1000; + if (CameraModeTimer > 0) + CameraModeTimer--; + if (CameraMode > 3) + CameraMode = 0; + if (CameraMode < 0) + CameraMode = 2; + + Started = 1; + + return GameUpdate(director); +} + +/* +void OnDraw2D(J2DOrthoGraph* graphics) +{ + snprintf(info, 128, "\33CC[FFFFFFFF]\33GC[FF0000FF]Distance Limit \n%s \n \nCamera Distance \n%f", + optAry[opt], camDis); + J2DTextBox_SetString(&textbox, info); + + J2DGrafContext_Setup2D((J2DGrafContext*)graphics); //Run replaced branch + + J2DScreen_Draw((J2DScreen*)&textbox, tX, tY, (J2DGrafContext*)graphics, 0x81); + GXSetScissor(0, 0, 0x0280, 0x01c0); + +} +*/ + +void OnSetup(MarDirector* director) +{ + playerLoopIndex = 0; + + HeldPlayer[0] = 0; + IsPlaying[0] = 1; + LimitDistance = 1; + + CameraPhi = 0; + CameraTheta = 0; + CameraModeTimer = 0; + CameraMode = 0; + + cameraGuide.x = cameraGuide.y = cameraGuide.z = 0.0f; + playerAverage.x = playerAverage.y = playerAverage.z = 0.0f; + difplayerAverage.x = difplayerAverage.y = difplayerAverage.z = 0.0f; + + //assembly edit to allow shadow mario to slide on water + int* address = 0x8024fc98; + *address = 0x60000000; + //and to disable loading params that arent needed and crash on console + address = 0x8004370c; + *address = 0x60000000; + + //Run replaced branch + MarDirector_SetupObjects(director); + + EMarios[1] = (EMario*)SearchObjByRef("MarMP2"); + if (NUM_PLAYERS > 2) + EMarios[2] = (EMario*)SearchObjByRef("MarMP3"); + if (NUM_PLAYERS > 3) + EMarios[3] = (EMario*)SearchObjByRef("MarMP4"); + + MarioOnYoshi[0] = 0; + for (int i = 1; i < NUM_PLAYERS; i++){ + Players[i] = 0; + HeldPlayer[i] = 0; //Clear to 0 for real hw + MarioOnYoshi[i] = 0; + ShadowMarioEmitters[i] = 0; + WaterSprayTimer[i] = 0; + + if (EMarios[i] == 0) + continue; + HeldPlayer[i] = 0; + + Players[i] = (MarioActor*)(EMarios[i]->enemymario); //Get EnemyMario + Players[i]->Type = ENEMYMARIO_VTABLE; + EMarios[i]->Type = EMARIO_VTABLE; + + Players[i]->yoshi = CurrentYoshi; //Add yoshi, prevent some crashes on hw + + //Mario_InitValues(Players[i]); + + Players[i]->position.x = 10000; + Players[i]->position.y = 10000; + Players[i]->position.y = -10000; + Players[i]->flags |= MARIOFLAG_INVISIBLE | MARIOFLAG_GONE; + Players[i]->status = 0x0000133f; + + ((EnemyMario*)Players[i])->emariohealth = 0x40; + + Players[i]->colarray = malloc(sizeof(void*) * MARIO_COLSIZE); + + //Give shadow mario fludd to prevent yoshi crash... + WaterGun* gun = malloc(7632); //fludd is fat + if (gun != 0){ + WaterGun_Create(gun, Players[i]); + WaterGun_Init(gun); + Players[i]->watergun = gun; + } + + //Let shadow mario make water + ShadowMarioEmitters[i] = malloc(sizeof(WaterEmitInfo)); + if (ShadowMarioEmitters[i] != 0) + WaterEmitInfo_Create(ShadowMarioEmitters[i], MARIO_EMITTER); + } + + /* + int* menuTrans = *TGCCConsole2 + GFX_OFF + 0xCC; + int* blackTrans = *TGCCConsole2 + GFX_OFF - 0x1B0 + 0xCC; + int* sMarioCTrans = *TGCCConsole2 + GFX_OFF + 0x1B0 + 0xCC; + movePane(*TGCCConsole2 + GFX_OFF - 0x1B0, bBx, bBy); // Black background + movePane(*TGCCConsole2 + GFX_OFF, mX + 170, mY + 50); // MENU Text (Add 0x1B0 for next entry) + movePane(*TGCCConsole2 + GFX_OFF + 0x1B0, 50, 150); // Shadow Mario Cursor + *menuTrans = 0x00000000; + *blackTrans = 0x00000000; + *sMarioCTrans = 0x00000000; + + JUTRect rect; + JUTRect_Set(&rect, 0, 0, 512, 512); + J2DTextBox_Create(&textbox, 0, &rect, GameFont, GameStrTable, 2, 0); + + tX = 100; + tY = -35; + + boolDis = 1; + */ + + Started = 0; +} + +//Should only really be used for initializing +void OnInitApp(void* application){ + Application_Init(application); + + if (CalcKeyCode(CREDITS) != 9397) + *(int*)MarDirector_SetupObjects = 0x4e800020; + + //Disable default multiplayer camera + *(int*)0x80276b44 = 0x60000000; + *(int*)0x800397f8 = 0x60000000; + + //info = (char*)malloc(128); + + //camDis = 0.667f; + multimode = 1; + for (int i = 0; i < NUM_PLAYERS; i++) + IsPlaying[i] = 0; +} + +void SetMarioAddresses(MarioActor* mario){ + *gpMarioAddress = mario; + *gpMarioPos = (int)mario + 0x10; + *gpMarioAngleX = (int)mario + 0x94; + *gpMarioAngleY = (int)mario + 0x96; + *gpMarioAngleZ = (int)mario + 0x98; + *gpMarioSpeedX = (int)mario + 0xA4; + *gpMarioSpeedY = (int)mario + 0xA8; + *gpMarioSpeedZ = (int)mario + 0xAC; +} + +void EMarioControl(MarioActor* enemymario, void* drama, void* graphics){ + for (int i = 0; i < NUM_PLAYERS; i++) + { + if (Players[i] == 0) + continue; + + if (enemymario == Players[i] && IsPlaying[i]) + return Mario_CheckController(enemymario, drama, graphics); + } +} + +void MarioSendMessage(HitActor* sender, unsigned long message){ + //if (CurrentCollision == 0) + // return 0; + + MarioActor* closest = 0; + float distance = 1000000; + for (int i = 0; i < NUM_PLAYERS; i++) + { + if (Players[i] == 0) + continue; + + Vector dif = Players[i]->position; + Vector_Subtract(&dif, &(sender->position)); + float magnitude = Vector_Magnitude(&dif); + if (magnitude < distance) + { + closest = Players[i]; + distance = magnitude; + } + } + if (closest == 0) + return; + + int (*receiveMessage)(HitActor* t, HitActor* s, unsigned long m) = GetObjectFunction(closest, HitActor_ReceiveMessage); + if (receiveMessage(closest, sender, message) == 0) + return 0; + else + return 1; +} + +void EMarioDamageExec(HitActor* this, HitActor* other, int u1, int u2, int u3, float f1, int u4, float f2, short u5) +{ + for (int i = 1; i < NUM_PLAYERS; i++) + if (Players[i] == this && ((EnemyMario*)Players[i])->emariohealth <= 0) + return; + + Mario_DamageExec(this, other, u1, u2, u3, f1, u4, f2, u5); +} + +void EMarioReceiveMessage(HitActor* this, HitActor* sender, unsigned long message){ + for (int i = 1; i < NUM_PLAYERS; i++) + if (Players[i] == this && ((EnemyMario*)Players[i])->emariohealth <= 0) + return; + + Mario_ReceiveMessage(this, sender, message); +} + +void EMarioPlayerControl(HitActor* this, void* drama, void* graphics){ + Mario_PlayerControl(this, drama, graphics); +} + +int IsMultiplayerMap(){ + if (*ChangeScenario == 58 || *ChangeScenario == 30 || (*ChangeScenario == 3 && *ChangeEpisode == 5)) + return 0; + return multimode; +} + +void OnMarioIncHP(HitActor* mario, int n){ + if (mario == Players[0]) + Mario_IncHP(mario, n); + else + { + EnemyMario* enemymario = ((EnemyMario*)mario); + if (enemymario->emariohealth < 0x40) + enemymario->emariohealth += 8 * n; + enemymario->hpmetertimer = 0x400; + } +} +void OnMarioDecHP(HitActor* mario, int n){ + if (mario == Players[0]) + Mario_DecHP(mario, n); + else + { + EnemyMario* enemymario = ((EnemyMario*)mario); + if (enemymario->emariohealth > 0) + enemymario->emariohealth -= 8 * n; + enemymario->hpmetertimer = 0x400; + } +} + +void RemoveObjectFromColArray(HitActor* actor, HitActor* col){ + if (actor->colcount == 0) + return; + + int i = actor->colcount - 1; + while (i >= 0){ + if (actor->colarray[i] == col) + break; + i--; + } + actor->colcount--; + if (i == actor->colcount){ + return; + } + while (i < actor->colcount) + actor->colarray[i] = actor->colarray[++i]; +} + +void BounceMario(MarioActor* mario1, MarioActor* mario2){ + int rstatus = mario1->status & 0xFFFFFFF0; + if (rstatus != STATE_JUMPSPIN && rstatus != STATE_JUMP && rstatus != STATE_JUMPSIDE && rstatus != 0x02000890) + { + if (rstatus == 0x00800230 || rstatus == 0x008008A0){ + //knock over other mario + if (mario2->status & 0xFFFFFFF0 != 0x000024D0) + SetMarioStatus(mario2, 0x000208b0, 0, 0); + } + return; + } + + Vector temp; + temp.x = 0.5f; + temp.y = 0.5f; + temp.z = 0.5f; + + mario1->speed.y = 300.0f; + Mario_SetAnimation(mario1, 211, 1.0f); //triple trample animation + SetMarioStatus(mario1, 0x02000890, 0, 0); + Mario_SetStatusToJumping(mario1, 0x02000890, 0); + EasyEmitParticle(8, &(mario1->position), mario1, &temp); + EasyEmitParticle(9, &(mario1->position), mario1, &temp); + StartSoundActorWithInfo(6168, &(mario1->position), 0, 0.0f, 3, 0, 0, 0, 4); + + rstatus = mario2->status & 0xFFFFFFF0; + if (rstatus == STATE_JUMPSPIN || rstatus == STATE_JUMP || rstatus == STATE_JUMPSIDE) + { + mario2->speed.y = -mario1->speed.y; + } + + RemoveObjectFromColArray(mario1, mario2); +} + +void OnCheckActorsHit(void* hitcheckobj){ + //Set up EMario bounds + for (int i = 1; i < NUM_PLAYERS; i++){ + if (Players[i] == 0) + continue; + + EMarios[i]->bound1 = 80.0f; //Manually + EMarios[i]->bound2 = 50.0f; + EMarios[i]->bound3 = 42.0f; + EMarios[i]->bound4 = 130.0f; + EMarios[i]->bound5 = 215.880554f; + EMarios[i]->colflags = 0xFC000000; + } + + playerLoopIndex = 0; + + //Run collision check + ObjHitCheck_CheckActorsHit(hitcheckobj); + + for (int i = 1; i < NUM_PLAYERS; i++){ + if (Players[i] == 0) + continue; + + //Give EnemyMario EMario's collision data + Players[i]->colcount = EMarios[i]->colcount; + Players[i]->colarraysize = EMarios[i]->colarraysize; + for (int j = 0; j < Players[i]->colcount; j++) + Players[i]->colarray[j] = EMarios[i]->colarray[j]; + + //Remove held players from collision + if (HeldPlayer[i]) + RemoveObjectFromColArray(Players[i], HeldPlayer[i]); + } + + if (Started){ + //Add in some trample for fun + for (int i = 0; i < NUM_PLAYERS; i++){ + if (Players[i] == 0) + continue; + if (Players[i]->speed.y > 0) + continue; + if ((int)Players[i]->colarray & 0x80000000 == 0) + continue; + for (int j = 0; j < Players[i]->colcount; j++){ + if (GetType((Players[i]->colarray[j])) == ENEMYMARIO_VTABLE || GetType((Players[i]->colarray[j])) == 0x803dd660){ + if (Players[i]->position.y > ((MarioActor*)Players[i]->colarray[j])->position.y + MARIO_TRAMPLEHEIGHT){ + BounceMario(Players[i], (MarioActor*)(Players[i]->colarray[j])); + } + } + } + } + } +} + +void OnDetectHit(void* hitcheckobj, HitActor* one, HitActor* two){ + EMario* held = 0; + for (int i = 1; i < NUM_PLAYERS; i++){ + if (Players[i] == 0) + continue; + if (Players[i] == HeldPlayer[0]) + held = EMarios[i]; + } + + if (one == held && two == Players[0]) + return; + if (two == held && one == Players[0]) + return; + + ObjHitCheck_DetectHit(hitcheckobj, one, two); + + if (Started){ + //Hacky have things direct collide with shadowmario + for (int i = 1; i < NUM_PLAYERS; i++){ + if (Players[i] == 0) + continue; + if (one->colcount >= 1 && one->colarray[one->colcount - 1] == EMarios[i]) + one->colarray[one->colcount - 1] = Players[i]; + if (two->colcount >= 1 && two->colarray[two->colcount - 1] == EMarios[i]) + two->colarray[two->colcount - 1] = Players[i]; + } + } +} + +void OnMarioHeld(MarioActor* mario, int a2, int a3, int a4){ + MarioActor* other = 0; + + __asm__ ("addi %0,29,0" //Forces compiler to stop overwriting r31 + : "=r" (other) + : + : "r29"); + + if (Started) + { + SetMarioStatus(mario, a2, a3, a4); + + for (int i = 0; i < NUM_PLAYERS; i++){ + if (Players[i] == 0) + continue; + if (Players[i] == other) + HeldPlayer[i] = mario; + } + } +} + +//I placed branch right after r3 is set to the thrown object. +//r31 holds mario's address +void OnMarioThrow(HitActor* thrownobject){ + MarioActor* mario = 0; + + __asm__ ("addi %0,31,0" //Forces compiler to stop overwriting r31 + : "=r" (mario) + : + : "r31"); + + int (*receiveMessage)(HitActor* t, HitActor* s, unsigned long m) = GetObjectFunction(thrownobject, HitActor_ReceiveMessage); + + + SetMarioAddresses(mario); + + receiveMessage(thrownobject, mario, 7); + + for (int i = 0; i < NUM_PLAYERS; i++){ + if (Players[i] == 0) + continue; + if (thrownobject == Players[i]){ + Vector newPos = **gpMarioPos; + float angle = 2.0f * PI * **gpMarioAngleY / 65535.0f; + newPos.x += sinf(angle) * 120.0f; + newPos.z += cosf(angle) * 120.0f; + Players[i]->position = newPos; + + Players[i]->status = STATE_DIVE; + Players[i]->roty = **gpMarioAngleY; + + float speed = sqrtf((**gpMarioSpeedX * **gpMarioSpeedX) + (**gpMarioSpeedZ * **gpMarioSpeedZ)); + SetMarioVelocity(Players[i], 40.0f + speed); + Players[i]->speed.y = 75.0f; + } + if (HeldPlayer[i] == thrownobject) + HeldPlayer[i] = 0; + } + + SetMarioAddresses(Players[0]); +} + +//Same for OnMarioDrop +void OnMarioDrop(HitActor* thrownobject){ + MarioActor* mario = 0; + + __asm__ ("addi %0,31,0" //Forces compiler to stop overwriting r31 + : "=r" (mario) + : + : "r31"); + + int (*receiveMessage)(HitActor* t, HitActor* s, unsigned long m) = GetObjectFunction(thrownobject, HitActor_ReceiveMessage); + + SetMarioAddresses(mario); + + receiveMessage(thrownobject, mario, 6); + + SetMarioAddresses(Players[0]); +} + +void OnObjectTouchMario(HitActor* this, HitActor* other) +{ + //Block certain objects from touching shadow mario + if ((GetType(other) == TYPE_ENEMYMARIO || GetType(other) == TYPE_EMARIO) && + GetType(this) == TYPE_ITEMNOZZLE) + return; + + //Run replaced branch + HitActor* (*TouchPlayer)(void* t, void* o) = GetObjectFunction(this, HitActor_TouchPlayer); + TouchPlayer((void*)this, (void*)other); +} + +void OnChangeNozzle(HitActor* this, int nozzletype, int nozzleslot){ + int (*touchPlayer)(HitActor* t, HitActor* o) = GetObjectFunction(this, HitActor_TouchPlayer); + + //If this is shadow mario, ignore + for (int i = 1; i < NUM_PLAYERS; i++){ + if (Players[i] == 0) + continue; + if (this == Players[i]->watergun) + return; + } + + WaterGun_ChangeNozzle(this, nozzletype, nozzleslot); +} + +void OnRideYoshi(Yoshi* yoshi){ + MarioActor* mario = 0; + + __asm__ ("addi %0,31,0" //Forces compiler to stop overwriting r31 + : "=r" (mario) + : + : "r31"); + + for (int i = 0; i < NUM_PLAYERS; i++){ + if (Players[i] == 0) + continue; + if (Players[i] == mario) + MarioOnYoshi[i] = 1; + } + yoshi->mario = mario; + + SetMarioAddresses(mario); + + Yoshi_Ride(yoshi); + + SetMarioAddresses(Players[0]); +} + +void OnDismountYoshi(MarioActor* mario){ + for (int i = 0; i < NUM_PLAYERS; i++){ + if (Players[i] == 0) + continue; + if (Players[i] == mario) + MarioOnYoshi[i] = 0; + } + + SetMarioAddresses(mario); + + Mario_GetOffYoshi(mario); + + SetMarioAddresses(Players[0]); +} + +int IsOnYoshi(MarioActor* mario){ + for (int i = 0; i < NUM_PLAYERS; i++){ + if (Players[i] == 0) + continue; + if (mario == Players[i] && MarioOnYoshi[i]) + return 1; + } + return 0; +} + +//Doesnt get more hacky than this +//The way its written: if yoshi has mario on him, then all marios must be on yoshi +//This should fix that +int IsOnYoshi2(MarioActor* mario){ + MarioActor* pmario1 = 0; + MarioActor* pmario2 = 0; + MarioActor* pmario3 = 0; + + __asm__ ("addi %0,31,0\n\t" //Forces compiler to stop overwriting possible mario registers + "addi %1,30,0\n\t" + "addi %2,29,0" + : "=r" (pmario1), "=r" (pmario2), "=r" (pmario3) + : + : "r29", "r30", "r31"); + + for (int i = 0; i < NUM_PLAYERS; i++){ + if (Players[i] == 0) + continue; + if ((pmario1 == Players[i] || pmario2 == Players[i] || pmario3 == Players[i]) && MarioOnYoshi[i]) + return 1; + } + return 0; +} + +void OnWaterGunUpdate(MarioActor* mario){ + if (mario == Players[0]) + Mario_WaterGunUpdate(mario); +} + +//Normally converts polar coordinates to cartesian +void CalcMultiplayerCameraPos(Vector* center, Vector* out, float rho, uint16_t theta ,uint16_t phi){ + switch (CameraMode){ + case 2: rho *= 0.667f; break; + case 1: rho *= 1.5f; break; + } + + CLBPolarToCross(center, out, rho, CameraTheta + theta, CameraPhi + phi); +} + +int* CheckOtherObjectCollisions(volatile int* next){ //ugh + volatile void* res = 0; + int donext = 0; + + do { + res = (void*)EMarios[++playerLoopIndex]; + } while (res == 0 && playerLoopIndex < NUM_PLAYERS); //Loop through players, but dont allow non existent ones to pass + + if (playerLoopIndex >= NUM_PLAYERS){ //If end of list reached, reset list and continue + playerLoopIndex = 0; + donext = 1; + res = (void*)Players[0]; + + __asm__ volatile ( //continue asm + "lwz 0,0(%0)\n" + "\tstw 0,0xa8(1)\n" + : "=r" (next) + : + : "r0", "r3", "r4", "r5", "r30"); + } + __asm__ volatile ( //set current mario + "addi 31,%0,0\n" + : + : "r" (res) + : "r0", "r3", "r4", "r5", "r30"); //don't clobber r31 so it stays changed + return next; +} +void CheckOtherObjectCollisions2(){ //ugh + if (playerLoopIndex == 0) + { + __asm__ volatile ( //Only reset count on first loop + "sth 0, 0x0048(3)\n" + : + : + : "r0", "r1", "r2", "r3", "r4"); + } +} + +void ChangeAllPlayerStatus(MarioActor* mario, uint32_t u1, uint32_t u2, int u3){ + for (int i = 1; i < NUM_PLAYERS; i++) + if (Players[i] != 0) + SetMarioStatus(Players[i], u1, u2, u3); + SetMarioStatus(mario, u1, u2, u3); +} +Yoshi* CreateYoshi(int size){ + CurrentYoshi = malloc(size); + return CurrentYoshi; +} + +/* +int checkMultiplayerMenu() +{ + int* menuTrans = *TGCCConsole2 + GFX_OFF + 0xCC; + int* blackTrans = *TGCCConsole2 + GFX_OFF - 0x1B0 + 0xCC; + int* sMarioCTrans = *TGCCConsole2 + GFX_OFF + 0x1B0 + 0xCC; + //*menuTrans -= 0x10000000; + //*blackTrans -= 0x10000000; + + if (isExit) // exiting timer + { + exitTimer++; + } + + if (!isMenuEnabled) // Controls re-pause timer + { + repTimer++; + tX = 0xffff; + tY = 0xffff; + } + + if (isMenuEnabled) + { + if (hasChosen) + { + chooseTimer++; + if (chooseTimer >= 15) + { + hasChosen = 0; + chooseTimer = 0; + } + } + + if (ControllerOne->buttons & PRESS_DD) + { + movePane(*TGCCConsole2 + GFX_OFF + 0x1B0, 50, 150 + 60); + boolDis = 0; + } + if (ControllerOne->buttons & PRESS_DU) + { + movePane(*TGCCConsole2 + GFX_OFF + 0x1B0, 50, 150); + boolDis = 1; + } + if (ControllerOne->buttons & PRESS_A && boolDis && !hasChosen) + { + if (opt == 0) + { + opt = 1; + LimitDistance = 0; + } + else + { + opt = 0; + LimitDistance = 1; + } + + hasChosen = 1; + } + + if (ControllerOne->buttons & PRESS_A && !boolDis && !hasChosen) + { + camDis += 0.5f; + hasChosen = 1; + } + + if (ControllerOne->buttons & PRESS_B && !boolDis && !hasChosen) + { + camDis -= 0.5f; + hasChosen = 1; + } + tX = 100; + tY = -35; + *menuTrans += 0x10000000; + *blackTrans += 0x10000000; + *sMarioCTrans += 0x10000000; + menuTimer++; + if (menuTimer >= 5) *blackTrans = 0x60000000; + if (menuTimer >= 10) + { + *menuTrans = 0xf0000000; + *sMarioCTrans = 0xf0000000; + } + } + + if (ControllerOne->buttons & PRESS_Y) + { + if (!isMenuEnabled && repTimer >= 15) + { + isMenuEnabled = 1; + } + if (isMenuEnabled) + { + isExit = 1; + menuTimer = 0; + tX = 0xffff; + tY = 0xffff; + if (isExit && exitTimer >= 15) + { + while (*menuTrans > 0) + { + *menuTrans -= 0x10000000; + *blackTrans -= 0x10000000; + *sMarioCTrans -= 0x10000000; + } + + if (*menuTrans <= 0) + { + *menuTrans = 0x00000000; + *blackTrans = 0x00000000; + *sMarioCTrans = 0x00000000; + isMenuEnabled = 0; + isExit = 0; + exitTimer = 0; + repTimer = 0; + } + } + } + } +} +*/ + +// Generated by wxHexEditor // +const int32_t ENEMYMARIO_VTABLE[0x3b] = { + 0x00000000, 0x00000000, + 0x8003F738, 0x80007D70, + 0x80276BD0, 0x802FA6F4, + 0x80276ADC, 0x802FA6FC, + 0x8003F814, 0x00000000, + 0x00000000, 0x800452D0, + 0x803370C0, 0x8033720C, + 0x80337214, 0x8033721C, + 0x80337220, 0x80337228, + 0x8033722C, 0x80337230, + 0x80337234, 0x80007FA8, + 0x80007FA0, 0x80007F98, + 0x80007F90, 0x80007F88, + 0x80007F80, 0x803370E0, + 0x803370E8, 0x803370EC, + 0x803370F4, 0x803370F8, + 0x80337100, 0x80337104, + 0x802F7004, 0x802F7020, + 0x802F703C, 0x802F7058, + 0x802F7074, 0x802F7090, + 0x80282AF4, 0x80247E50, + 0x80007CFC, 0x80255A8C, + 0x80007D60, 0x00000000, + 0x00000000, 0x800452D8, + 0x80044CA4, 0x800406CC, + EMarioControl, EMarioPlayerControl, + 0x8004440C, 0x80244520, + 0x80280FE8, EMarioDamageExec, + 0x802853F8, 0x8024D17C, + 0x80042E48 }; + + // Generated by wxHexEditor // +const int32_t EMARIO_VTABLE[0x45] = { + 0x00000000, 0x00000000, + 0x80039BF4, 0x80007D70, + 0x80039810, 0x802FA6F4, + 0x800397B4, 0x802FA6FC, + 0x80039148, 0x00000000, + 0x00000000, 0x80039F5C, + 0x803370C0, 0x8033720C, + 0x80337214, 0x8033721C, + 0x80337220, 0x80337228, + 0x8033722C, 0x80337230, + 0x80337234, 0x80007FA8, + 0x80007FA0, 0x80007F98, + 0x80007F90, 0x80007F88, + 0x80007F80, 0x803370E0, + 0x803370E8, 0x803370EC, + 0x803370F4, 0x803370F8, + 0x80337100, 0x80337104, + 0x802F7004, 0x802F7020, + 0x802F703C, 0x802F7058, + 0x802F7074, 0x802F7090, + EMarioReceiveMessage, 0x80217CA8, + 0x80007CFC, 0x80007D40, + 0x80007D60, 0x80218CC0, + 0x80218A48, 0x80039600, + 0x8003BF44, 0x802182F0, + 0x80218414, 0x802184DC, + 0x8021818C, 0x80218020, + 0x80217FC8, 0x80217DE4, + 0x80218344, 0x8003952C, + 0x80217D88, 0x80217D6C, + 0x80217CC8, 0x80217B30, + 0x80217990, 0x8003C460, + 0x8003BE2C, 0x8003BCE0, + 0x8003BF38, 0x80007DFC, + 0x80007E04 };