1
0
Fork 0

Updated library and linker with more functions

Added tools to patch Start.dol
Added more examples
This commit is contained in:
miluaces 2016-09-25 11:50:37 -07:00
parent 4e4af4167b
commit 646811b83c
20 changed files with 587 additions and 177 deletions

BIN
DOLInsert.exe Normal file

Binary file not shown.

View file

@ -1,29 +1,32 @@
# Super Mario Sunshine - C Kit
A WIP C library for everyone's favorite game: Super Mario Sunshine.
TODO: Add more examples.. (Please)
TODO: Actually fix the code listed in the main example.
A WIP 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?
You can make Gecko code modifications in C for Super Mario Sunshine, and Super Mario Sunshine only, for now. (I'll probably make another kit for some other games in the future, though only me working on them; I don't want to involve Miluaces into the pain. ^ ^' )
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.
This is only for Super Mario Sunshine at the moment. (I'll probably make another kit for some other games in the future, though only me working on them; I don't want to involve Miluaces into the pain. ^ ^' )
#Neato!... Well, how do I set this up?
First, you need to install devkitPro in order for your code to compile, and don't forget to set up the environment for devkitPPC. (Ex., C:\devkitPro\devkitPPC\bin) You can install the lib anywhere on your computer, as long as a folder in the file path doesn't contain any spaces. To compile your code, simply drag your C code file into build.bat.
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.
#Alright. Do you have any examples to show?
Yes, actually. Here's an item spawning example from Miluaces:
```
include "sms.h"
static int laststate __attribute__((section(".sdata"))); //Last state
int laststate; //Last state
int OnUpdate(MarDirector* director) {
int (*GameUpdate)(MarDirector* director) = (void*)*(void**)((int)*(int*)director + 0x64);
int (*GameUpdate)(MarDirector* director) = GetObjectFunction(director, Director_GameUpdate);
MarioActor* mario = GetMarioHitActor();
ItemActor* item = 0;
@ -62,11 +65,15 @@ int OnUpdate(MarDirector* director) {
return GameUpdate(director);
}
```
There are more examples in the repository.
#My code compiled! What do I do now?
That's good! The Gecko code should have automatically been copied to your clipboard. (Thanks Miluaces :D ) With that, you should now be able to paste that into your cheat code list in Dolphin and play your modification!
Either build a new SMS image with your dol file or enter your gecko code to see your code run in game.
---
More examples and updates to the lib will surely come at the right moment. Stick around in the IRC channel #sunshinerealm in irc.nolimitzone.com/6667 to meet and converse with the Sunshine Realm crew and see updates on current SMS modifications, big or small.
More examples and updates to the lib will surely come at the right moment. For support with this check out the Blastsoft Studios Discord ( https://discord.gg/mN9nf ).
Also visit SMS Realm ( http://smsrealm.net/board/ ) to discuss SMS hacking with other users.

Binary file not shown.

View file

@ -1,5 +1,5 @@
C:\devkitPro\devkitPPC\bin\powerpc-eabi-gcc.exe %1 -S -o %~n1.s -O1
C:\devkitPro\devkitPPC\bin\powerpc-eabi-gcc.exe %1 -c -o %~n1.o -O1
C:\devkitPro\devkitPPC\bin\powerpc-eabi-gcc.exe %1 -S -o %~n1.s -O1 -std=c99
C:\devkitPro\devkitPPC\bin\powerpc-eabi-gcc.exe %1 -c -o %~n1.o -O1 -std=c99
if ERRORLEVEL 1 pause
if ERRORLEVEL 1 exit
C:\devkitPro\devkitPPC\bin\powerpc-eabi-ld.exe -Os -T linker -T smsFuncs -o obj_%~n1.o %~n1.o -Map %~n1.map
@ -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 .sdata -R .gnu.attributes -g -S
bin2gecko.exe %~n1.bin -m %~n1.map -c OnUpdate:0x802a6160:3 -c OnSetup:0x802998b8:0 -c OnDraw2D:0x80143f14:0 -c OnWaterHitsGround:0x8027f7dc:0 -c OnObjectTouchMario:0x801b02fc:3 -c OnAllNPCsUpdate:0x8003e2f0:0
bin2gecko.exe %~n1.bin -m %~n1.map -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 OnEMarioControl:0x8004010c -r IsMario:0x8024db0c
pause

View file

@ -1,5 +0,0 @@
powerpc-eabi-gcc.exe sms.s -c -o sms.o
C:\devkitPro\devkitPPC\bin\powerpc-eabi-ld.exe -T linker -o smsobj.o sms.o
C:\devkitPro\devkitPPC\bin\powerpc-eabi-objdump.exe smsobj.o --full-content
C:\devkitPro\devkitPPC\bin\powerpc-eabi-objcopy.exe smsobj.o sms.bin -O binary -R .comment -g -S
bin2gekko.exe sms.bin 0x80248b18

View file

@ -1,13 +0,0 @@
C:\devkitPro\devkitPPC\bin\powerpc-eabi-gcc.exe %1 -S -o %~n1.s -Os
C:\devkitPro\devkitPPC\bin\powerpc-eabi-gcc.exe %1 -c -o %~n1.o -Os
if ERRORLEVEL 1 pause
if ERRORLEVEL 1 exit
C:\devkitPro\devkitPPC\bin\powerpc-eabi-ld.exe -T linker -T smsFuncs -o obj_%~n1.o %~n1.o "C:\devkitPro\devkitPPC\lib\gcc\powerpc-eabi\4.8.2\libgcc.a" -Map %~n1.map
if ERRORLEVEL 1 pause
if ERRORLEVEL 1 exit
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 .sdata -R .gnu.attributes -g -S
bin2gecko.exe %~n1.bin -m %~n1.map -c OnUpdate:0x802a6160:3 -c OnSetup:0x802998b8:0 -c OnDraw2D:0x80143f14:0 -c OnWaterHitsGround:0x8027f7dc:0 -c OnObjectTouchMario:0x801b02fc:3 -c OnAllNPCsUpdate:0x8003e2f0:0
pause

1
cmd.bat Normal file
View file

@ -0,0 +1 @@
START cmd.exe

BIN
cmd.exe

Binary file not shown.

122
dollinker Normal file
View file

@ -0,0 +1,122 @@
__destroy_global_chain = 0x80337dc0;
__register_global_object = 0x80337e08;
__destroy_new_array = 0x80337e20;
__destroy_arr = 0x80337e9c;
__construct_array = 0x80337f14;
__dt__26__partial_array_destructorFv = 0x80338014;
__construct_new_array = 0x803380cc;
__ptmf_test = 0x803381d4;
__ptmf_scall = 0x80338204;
__unregister_fragment = 0x8033822c;
__register_fragment = 0x80338260;
__dt__26__partial_array_destructorFv = 0x80338014;
__cvt_fp2unsigned = 0x8033829c;
exit = 0x80338978;
rand = 0x8033b1a4;
srand = 0x8033b19c;
long2str = 0x8033aaa0;
longlong2str = 0x8033a7c0;
round_decimal = 0x8033a68c;
float2str = 0x8033a054;
toupper = 0x80338f3c;
tolower = 0x80338f64;
__num2dec = 0x80338a84;
__flush_buffer = 0x80338e38;
__prep_buffer = 0x80338f04;
__kill_critical_regions = 0x80338f38;
__div2u = 0x803382f8;
__div2i = 0x803383e4;
__mod2u = 0x8033851c;
__mod2i = 0x80338600;
__shl2i = 0x8033870c;
__shr2u = 0x80338730;
__shr2i = 0x80338754;
__cvt_sll_flt = 0x8033877c;
__cvt_dbl_usll = 0x80338830;
GetR2__Fv = 0x803388fc;
__fini_cpp_exceptions = 0x80338904;
__init_cpp_exceptions = 0x80338938;
fwrite = 0x80338f8c;
wcstombs = 0x80339268;
memcmp = 0x803392a4;
memchr = 0x803392e8;
memmove = 0x80339314;
__copy_longs_rev_unaligned = 0x803393f0;
__copy_longs_unaligned = 0x803394a0;
__copy_longs_rev_aligned = 0x80339564;
__copy_longs_aligned = 0x80339610;
__stdio_atexit = 0x803396cc;
sprintf = 0x803396d0;
snprintf = 0x803397a4;
vsnprintf = 0x80339874;
vprintf = 0x803398e4;
__StringWrite = 0x80339960;
__FileWrite = 0x803399cc;
__pformatter = 0x80339a24;
parse_format = 0x8033acc4;
__StringRead = 0x8033b1c8;
strstr = 0x8033b258;
strrchr = 0x8033b30c;
strchr = 0x8033b30c;
strcmp = 0x8033b33c;
strcat = 0x8033b460;
strncpy = 0x8033b48c;
strcpy = 0x8033b4d0;
strlen = 0x8033b584;
strtol = 0x8033b5a4;
strtoul = 0x8033b694;
__strtoul = 0x8033b740;
__close_console = 0x8033ba88;
__write_console = 0x8033ba90;
__read_console = 0x8033bb28;
fwide = 0x8033bc08;
fabs__Fd = 0x8033bc88;
__ieee754_atan2 = 0x8033bc90;
atan = 0x8033bf28;
frexp = 0x8033c168;
atan2 = 0x8033c204;
fabsf__Ff = 0x8033c224;
atanf = 0x8033c22c;
atan__Ff = 0x8033c420;
_inv_sqrtf = 0x8033c440;
acosf = 0x8033c4b0;
atan2f = 0x8033c4f4;
tanf = 0x8033c5cc;
cos__Ff = 0x8033c610;
sin__Ff = 0x8033c630;
cosf = 0x8033c650;
sinf = 0x8033c7e4;
__sinit_trigf_c = 0x8033c988;
powf = 0x8033c9b8;
expf = 0x8033d0f8;
memset = 0x80003100;
__fill_mem = 0x80003130;
memcpy = 0x800031f4;
__nw__FUl = 0x802c3ba4;
__nw__FUli = 0x802c3bec;
__nwa__FUl = 0x802c3ca4;
__nwa__FUli = 0x802c3cec;
__dl__FPv = 0x802c3da4;
__dla__FPv = 0x802c3e08;
SECTIONS
{
. = 0x80417800;
.text :
{
*(.text)
}
.rodata :
{
*(.rodata*)
}
.data :
{
*(.data)
}
. += 0x08;
.sdata :
{
*(.sdata)
}
}

View file

@ -0,0 +1,27 @@
#include "sms.h"
int doublejumped;
int preva;
int OnUpdate(MarDirector* director) {
int (*GameUpdate)(MarDirector* director) = GetObjectFunction(director, Director_GameUpdate);
//Update
MarioActor* mario = (MarioActor*)*gpMarioAddress;
//Check if mario is in the air
if (mario->status & STATE_AIRBORN)
{
//Check if mario has a double jump available and also if the user just pressed the A button this frame
if (!doublejumped && ControllerOne->buttons & PRESS_A && !preva)
{
doublejumped = 1;
**gpMarioSpeedY = 60.0f;
}
}
else //if mario isn't in the air give him another double jump to use.
doublejumped = 0;
//Save the current A press so it can be used to check if its pressed next frame (think of this as a 0.5 A press)
preva = ControllerOne->buttons & PRESS_A;
return GameUpdate(director);
}

View file

@ -0,0 +1,72 @@
/*
* Empty c file demonstrating available functions the Bin2Gecko and DolInsert tools can replace
*/
#include "sms.h"
//Variable
int variable;
//Update every frame
int OnUpdate(MarDirector* director) {
int (*GameUpdate)(MarDirector* director) = GetObjectFunction(director, Director_GameUpdate);
//Update Here
//Run original replaced function
//Removing this will halt the game
return GameUpdate(director);
}
//Setup after every stage load
void OnSetup(MarDirector* director)
{
//Run original replaced function
//Removing this will cause no stage setup to occur and will likely crash the game
MarDirector_SetupObjects(director);
//Setup here
}
//Whenever water touches ground
void OnWaterHitsGround(PollutionManager* pollution, float x, float y, float z, float r)
{
//Run original replaced function
//If you remove this, water will no longer clean pollution
CleanPollution(pollution, x, y, z, r);
//Code here
}
//Whenever object touches mario
void OnObjectTouchMario(HitActor* this, HitActor* other)
{
//Get the function from the object's vtable
HitActor* (*TouchPlayer)(void* t, void* o) = GetObjectFunction(this, HitActor_TouchPlayer);
//Code here
//Run original replaced function
//If you remove this, no object will react to touching mario
TouchPlayer((void*)this, (void*)other);
}
//Runs once per frame for each NPC
void OnAllNPCsUpdate(HitActor* this, int a1, void* drama, void* graphics, int obj)
{
//Code here
//Run original replaced function
//If you remove this, no NPCs will update
Drama_PrepareUpdate(this, a1, drama, graphics, obj);
}
//Runs once per frame, but allows drawing to HUD
void OnDraw2D(J2DOrthoGraph* graphics)
{
//Run original replaced function
//Removing this will no longer draw FLUDD HUD
MarDirector_SetupObjects(director);
//Draw here
}

View file

@ -12,16 +12,15 @@
/* 4 effects can occur at the same time
* Boring effects removed
* Fixed some crashes
* A few optimizations for space because of 229 byte limit
* A few optimizations for space because of 225 line limit
*/
//Static variables don't take up code space
static int timer[4] __attribute__((section(".sdata"))); //Effect timers
static int currentEffect[4] __attribute__((section(".sdata"))); //Current effects
static int val[4] __attribute__((section(".sdata"))); //Effect values
static int oval[4] __attribute__((section(".sdata"))); //Effect reset values
static Vector lastposition __attribute__((section(".sdata"))); //Stage start position
static MarioActor* mario __attribute__((section(".sdata"))); //Mario
int timer[4]; //Effect timers
int currentEffect[4]; //Current effects
int val[4]; //Effect values
int oval[4]; //Effect reset values
Vector lastposition; //Stage start position
MarioActor* mario; //Mario
//Runs every frame
int OnUpdate(MarDirector* director) {

BIN
obj_sms.o

Binary file not shown.

13
patchdol.bat Normal file
View file

@ -0,0 +1,13 @@
C:\devkitPro\devkitPPC\bin\powerpc-eabi-gcc.exe %1 -S -o %~n1.s -O1 -std=c99 -w
C:\devkitPro\devkitPPC\bin\powerpc-eabi-gcc.exe %1 -c -o %~n1.o -O1 -std=c99 -w
if ERRORLEVEL 1 pause
if ERRORLEVEL 1 exit
C:\devkitPro\devkitPPC\bin\powerpc-eabi-ld.exe -Os -T dollinker -T smsFuncs -o obj_%~n1.o %~n1.o -Map %~n1.map
if ERRORLEVEL 1 pause
if ERRORLEVEL 1 exit
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
pause

BIN
sms.bin

Binary file not shown.

88
sms.c
View file

@ -1,111 +1,43 @@
/* <> are external libs, "" are files we include */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <stdbool.h>
#include "sms.h"
/*
Super Mario Sunshine Disassembly example
*/
/* This code is always running, and is constantly updating. */
static J2DTextBox textbox __attribute__((section(".sdata")));
static J2DTextBox textbox;
static char* info;
static int timesjumped = 0;
static int glasstimer=0;
static bool eqip=false;
int timemilli=30;
int time=30;
int timerx;
int timery;
int OnUpdate(MarDirector* director) {
int (*GameUpdate)(MarDirector* director) = (void*)*(void**)((int)*(int*)director + 0x64);
/*
We simply keep track of Mario's jumping amount.
He needs to stop jumping, or else he'll have an effect!
*/
/* is he jumping? */
bool jumping = IsMarioJumping();
/* this fixes a bug with the counting. jumping counts for every frame, which is what we do NOT want */
static bool inAir __attribute__((section(".sdata")));
static bool eqip __attribute__((section(".sdata")));
static int glasstimer __attribute__((section(".sdata")));
/* create our Mario actor. */
timemilli--;
timery++;
if (timemilli <=0) {
time--;
timemilli=30;
}
if (ControllerOne->buttons & PRESS_DU) {
MarioActor* mario = GetMarioHitActor();
SetMarioAnim(1.0, mario, 109);
}
JUTRect rect;
JUTRect_Set(&rect, timerx, timery, 800, 512);
int (*GameUpdate)(MarDirector* director) = GetObjectFunction(director, Director_GameUpdate);
//Update
return GameUpdate(director);
}
void OnDraw2D(J2DOrthoGraph* graphics)
{
/* Here are his states that we read.
If Mario is doing said action, the return should be 1.
*/
snprintf(info, 128, "Time x %d", time);
// now we set our string to a J2DTextBox
Vector mariopos = **gpMarioPos;
int state = GetMarioStatus();
snprintf(info, 128, "Mario X: %f\nMario Y: %f\nMario Z: %f\nMario State: %X\nNext Stage: %d-%d",
mariopos.x, mariopos.y, mariopos.z, state, *ChangeScenario, *ChangeEpisode);
J2DTextBox_SetString(&textbox, info);
//Run replaced branch
J2DGrafContext_Setup2D((J2DGrafContext*)graphics);
J2DGrafContext_Setup2D((J2DGrafContext*)graphics); //Run replaced branch
J2DScreen_Draw((J2DScreen*)&textbox, 0, 0, (J2DGrafContext*)graphics, 0x81);
GXSetScissor(0, 0, 0x0280, 0x01c0);
JUTRect rect;
JUTRect_Set(&rect, timerx, timery, 800, 512);
//GXSetScissor(0, 0, 0x0280, 0x01c0);
}
/* This code gets ran once. */
void OnSetup(MarDirector* director)
{
MarioActor* mario = GetMarioHitActor();
WearGlasses(mario);
time=300;
timerx=440;
timery=-420;
JUTRect rect;
MarDirector_SetupObjects(director); //Run replaced branch
JUTRect_Set(&rect, timerx, timery, 800, 512);
JUTRect_Set(&rect, 0, 0, 512, 512);
//textbox = (J2DTextBox*)malloc(sizeof(J2DTextBox));
J2DTextBox_Create(&textbox, 0, &rect, GameFont, GameStrTable, 2, 0);
void (*TestNull)(void) = 0x80247fa4;
TestNull();
info = (char*)malloc(128);
}
void *TestNull() {
asm(
"blr ;"
"ori %r1, %r1, 0xd138 ;"
);
}

236
sms.h
View file

@ -1,11 +1,10 @@
//For C++ inheritence
#define GetObjectFunction( object, func ) (void*)*(void**)((int)*(int*)object + func)
#define Director_GameUpdate 0x64
#define HitActor_TouchPlayer 0x0148
#ifndef SMS_H
#define SMS_H
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#define PRESS_START 0x1000
#define PRESS_B 0x0200
#define PRESS_A 0x0100
@ -19,7 +18,8 @@
#define MARIOFLAG_ALIVE 0x00000001
#define MARIOFLAG_INVISIBLE 0x00000004
#define MARIOFLAG_DEAD 0x00000040
#define MARIOFLAG_ALLDEAD 0x00000F00
#define MARIOFLAG_GAMEOVER 0x00000400
#define MARIOFLAG_SLIP 0x00000080
#define MARIOFLAG_HASHELMET_FOLLOWCAMERA 0x00001000
#define MARIOFLAG_HASHELMET 0x00002000
@ -62,14 +62,23 @@
typedef struct{
uint16_t buttons;
uint8_t lanalogx;
uint8_t lanalogy;
uint8_t ranalogx;
uint8_t ranalogy;
int8_t lanalogx;
int8_t lanalogy;
int8_t ranalogx;
int8_t ranalogy;
uint16_t u1;
uint8_t status;
uint8_t u2;
} Controller;
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{
@ -96,7 +105,7 @@ typedef struct{
void* u8;
void* u9;
int u10;
int u11;
int collision;
float u12;
float u13;
float u14;
@ -109,45 +118,128 @@ typedef struct{
} HitActor;
typedef struct{
void* Type;
void* Type; //0
void* u2;
int u3;
int u4;
Vector position;
int u4;
Vector position; //10
int u5;
void* u6;
void* u6; //20
Vector scale;
Vector direction;
Vector direction; //30
void* u7;
void* u8;
void* u9;
int u10;
int u11;
float u12;
void* u8; //40
void* collist;
uint16_t colcount;
uint16_t u9;
int colsettings;
float u12; //50
float u13;
float u14;
float u15;
float u16;
float u16; //60
int u17;
int u18;
int u19;
void* u20;
void* u20; //70
int u21;
int u22;
uint32_t status;
uint32_t laststatus;
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;
typedef struct{
float u1;
float u2;
float u3;
float u4;
float x;
float y;
float z;
} Position;
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
@ -234,12 +326,28 @@ typedef struct {
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))
@ -257,8 +365,6 @@ 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);
static JUTResFont* DiscErrorFont = (JUTResFont*)0x812fef60;
#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);
@ -301,8 +407,8 @@ typedef ObjItemManager{
bool (*HasMapCollision)();
}*/
register void* RTOC asm ("r2");
register void* SceneReference asm ("r13");
register void* RTOC __asm ("r2");
register void* SceneReference __asm ("r13");
// GC
//static void (*GXSetBlendMode)(int a1, int a2, int a3, int a4) = (void*)0x80361dd0;
@ -314,9 +420,18 @@ 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;
static void* gpItemManager = (void*)0x8040df10;
// SMS
static void* gpApplication = (void*)0x803e9700;
@ -335,11 +450,12 @@ void CleanPollution(PollutionManager* pollution, float x, float y, float z, floa
// 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;
void IsPolluted(void);
static void** gpSunManager = (void*)0x8040d0c0;
static HitActor** gpSunModel = (void*)0x8040d0c8;
static uint8_t* ChangeScenario = (void*)0x003e9712;
static uint8_t* ChangeEpisode = (void*)0x003e9713;
@ -348,8 +464,16 @@ 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);
// Mario
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;
@ -369,8 +493,7 @@ HitActor* GetMarioYoshi();
int GetMarioHP();
int GetMarioStatus();
int GetMarioStatusFromHitActor(MarioActor* mario);
void ChangeMarioStatus(MarioActor* mario, int u1, int u2, int u3);
void incGoldCoinFlag(uint32_t coinptr, int stage, int amount);
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);
@ -382,7 +505,19 @@ void SetMarioStatus(MarioActor* mario, int a2, int a3, int a4);
void EmitSweat(MarioActor* mario);
void Fludd_Emit(HitActor* fludd);
void Mario_StartVoice(MarioActor* mario, int id);
void WearGlasses(MarioActor* mario);
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
@ -390,7 +525,6 @@ void WearGlasses(MarioActor* mario);
void SendMsgToMario(MarioActor* mario, int msg);
// Objects
static void* ItemManager = (void*)0x8107e3a4;
#define OBJ_WATER 0x20000002
#define OBJ_ONEUP 0x20000006
#define OBJ_COIN 0x2000000E
@ -398,7 +532,7 @@ static void* ItemManager = (void*)0x8107e3a4;
#define OBJ_ROCKETNOZZLE 0x20000022
#define OBJ_HOVERNOZZLE 0x20000026
#define OBJ_TURBONOZZLE 0x2000002A
HitActor* MakeObjAppear(const void* itemManager, int id);
HitActor* MakeObjAppear(ItemManager* itemManager, int id);
// Effects
void GenerateEffectElectric(HitActor* pos);
@ -406,9 +540,7 @@ 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);
void StartBGM(int u1);
void StopBGM(int u1);
void DraweMarioHP(MarioActor* emario);
#endif
#endif

BIN
sms.o

Binary file not shown.

108
sms2.c Normal file
View file

@ -0,0 +1,108 @@
/* <> are external libs, "" are files we include */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <stdarg.h>
#include <string.h>
#include <stdbool.h>
#include "sms.h"
/*
Super Mario Sunshine Disassembly example
*/
/* This code is always running, and is constantly updating. */
J2DTextBox textbox;
char* info;
bool inAir;
int timesjumped;
int glasstimer;
bool eqip;
int timemilli;
int time;
int timerx;
int timery;
int OnUpdate(MarDirector* director) {
int (*GameUpdate)(MarDirector* director) = (void*)*(void**)((int)*(int*)director + 0x64);
/*
We simply keep track of Mario's jumping amount.
He needs to stop jumping, or else he'll have an effect!
*/
/* is he jumping? */
bool jumping = IsMarioJumping();
timemilli--;
timery++;
if (timemilli <=0) {
time--;
timemilli=30;
}
if (ControllerOne->buttons & PRESS_DU) {
MarioActor* mario = GetMarioHitActor();
SetMarioAnim(1.0, mario, 109);
}
JUTRect rect;
JUTRect_Set(&rect, timerx, timery, 800, 512);
//Update
return GameUpdate(director);
}
void OnDraw2D(J2DOrthoGraph* graphics)
{
/* Here are his states that we read.
If Mario is doing said action, the return should be 1.
*/
snprintf(info, 128, "Time x %d", time);
// now we set our string to a J2DTextBox
J2DTextBox_SetString(&textbox, info);
//Run replaced branch
J2DGrafContext_Setup2D((J2DGrafContext*)graphics);
J2DScreen_Draw((J2DScreen*)&textbox, 0, 0, (J2DGrafContext*)graphics, 0x81);
GXSetScissor(0, 0, 0x0280, 0x01c0);
JUTRect rect;
JUTRect_Set(&rect, timerx, timery, 800, 512);
}
/* This code gets ran once. */
void OnSetup(MarDirector* director)
{
MarioActor* mario = GetMarioHitActor();
WearGlasses(mario);
timemilli=30;
time=300;
timerx=440;
timery=-420;
JUTRect rect;
MarDirector_SetupObjects(director); //Run replaced branch
JUTRect_Set(&rect, timerx, timery, 800, 512);
//textbox = (J2DTextBox*)malloc(sizeof(J2DTextBox));
J2DTextBox_Create(&textbox, 0, &rect, GameFont, GameStrTable, 2, 0);
void (*TestNull)(void) = 0x80247fa4;
TestNull();
info = (char*)malloc(128);
}
void *TestNull() {
asm(
"blr ;"
"ori %r1, %r1, 0xd138 ;"
);
}

View file

@ -1,22 +1,18 @@
MarDirector_SetupObjects = 0x802b76f4;
PlaySound = 0x800189d4;
startBGM = 0x80016978;
stopBGM = 0x8001686c;
StartStageEntranceDemoSeq = 0x802bb880;
GenerateEffectElectric = 0x80262E18;
MakeObjAppear = 0x801b6e3c;
SendMsgToMario = 0x80273870;
EmitSweat = 0x8026465c;
WearGlasses = 0x80247fa4;
Mario_StartVoice = 0x8028537c;
Fludd_Emit = 0x80268f98;
SetMarioStatus = 0x80254034;
IsMarioJumping = 0x802739b4;
SetMarioAnim = 0x80247670;
ChangeMarioStatus = 0x80254034;
Mario_SetAnim = 0x80247670;
ThrowMario = 0x8007706c;
GetMarioMapPosition = 0x8007706c;
incGoldCoinFlag = 0x80294610;
IncGoldCoinFlag = 0x80294610;
GetMarioStatusFromHitActor = 0x80273648;
GetMarioStatus = 0x802738f0;
GetMarioHP = 0x80273674;
@ -58,5 +54,24 @@ GXSetScissor = 0x80363138;
StampPollution = 0x8019de84;
CleanPollution = 0x8019ddb4;
Drama_PrepareUpdate = 0x802fcc94;
DraweMarioHP = 0x8003fdc4;
IsPolluted = 0x801a12e8;
StartTrembleEffect = 0x80226fc8;
SetMarioVelocity = 0x80255734;
Mario_SetGamePad = 0x802765ec;
MarioGamePad_Read = 0x802a8054;
MarioGamePad_Update = 0x802a80e0;
MarioGamePad_Reset = 0x802a897c;
EMario_Create = 0x80039bb0;
Mario_CheckController = 0x80251494;
Mario_CheckCollision = 0x80280fe8;
Mario_ReceiveMessage = 0x80282af4;
Mario_PlayerControl = 0x8024de38;
Mario_DamageExec = 0x8024280c;
Mario_IncHP = 0x80243928;
Mario_DecHP = 0x80243828;
EnemyMario_CheckController = 0x8004010c;
Camera_AddMultiPlayer = 0x80030cc0;
Camera_RemoveMultiPlayer = 0x80030c28;
Camera_CreateMultiPlayer = 0x80030d1c;
Mario_DrawHP = 0x8003fdc4;
IsPolluted = 0x801a12e8;
Mario_WearGlasses = 0x80247fa4;