mirror of
https://github.com/izzy2lost/2ship2harkinian-Android.git
synced 2026-06-19 01:20:08 -07:00
Merge branch 'master' into voice
This commit is contained in:
+2
-2
@@ -74,11 +74,11 @@ If you make significant progress on decompiling a function, but can't get it to
|
||||
|
||||
```c
|
||||
#ifdef NON_MATCHING
|
||||
void CollisionCheck_SpawnWaterDroplets(GlobalContext* globalCtx, Vec3f* v) {
|
||||
void CollisionCheck_SpawnWaterDroplets(PlayState* play, Vec3f* v) {
|
||||
// ...
|
||||
}
|
||||
#else
|
||||
void CollisionCheck_SpawnWaterDroplets(GlobalContext* globalCtx, Vec3f* v);
|
||||
void CollisionCheck_SpawnWaterDroplets(PlayState* play, Vec3f* v);
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/code/z_collision_check/CollisionCheck_SpawnWaterDroplets.s")
|
||||
#endif
|
||||
```
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
<File Name="object_kaizoku_obj" Segment="6">
|
||||
<DList Name="object_kaizoku_obj_DL_0001A0" Offset="0x1A0" />
|
||||
<Texture Name="object_kaizoku_obj_Tex_000300" OutName="tex_000300" Format="rgba16" Width="32" Height="64" Offset="0x300" />
|
||||
<DList Name="object_kaizoku_obj_DL_001680" Offset="0x1680" />
|
||||
<Collision Name="object_kaizoku_obj_Colheader_0019B0" Offset="0x19B0" />
|
||||
<DList Name="gPirateLiftPlatformDL" Offset="0x1680" />
|
||||
<Collision Name="gPirateLiftPlatformCol" Offset="0x19B0" />
|
||||
<Texture Name="object_kaizoku_obj_Tex_0019E0" OutName="tex_0019E0" Format="rgba16" Width="64" Height="32" Offset="0x19E0" />
|
||||
<Texture Name="object_kaizoku_obj_Tex_0029E0" OutName="tex_0029E0" Format="rgba16" Width="16" Height="32" Offset="0x29E0" />
|
||||
<Texture Name="object_kaizoku_obj_Tex_002DE0" OutName="tex_002DE0" Format="rgba16" Width="16" Height="16" Offset="0x2DE0" />
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
<Root>
|
||||
<File Name="object_kin2_obj" Segment="6">
|
||||
<DList Name="object_kin2_obj_DL_000120" Offset="0x120" />
|
||||
<DList Name="object_kin2_obj_DL_000128" Offset="0x128" />
|
||||
<DList Name="object_kin2_obj_DL_0002C0" Offset="0x2C0" />
|
||||
<DList Name="object_kin2_obj_DL_000360" Offset="0x360" />
|
||||
<Collision Name="object_kin2_obj_Colheader_000490" Offset="0x490" />
|
||||
<DList Name="gOceanSpiderHouseBombableWallDebrisDL" Offset="0x128" />
|
||||
<DList Name="gOceanSpiderHouseBombableWallCrackDL" Offset="0x2C0" />
|
||||
<DList Name="gOceanSpiderHouseBombableWallDL" Offset="0x360" />
|
||||
<Collision Name="gOceanSpiderHouseBombableWallCol" Offset="0x490" />
|
||||
<DList Name="object_kin2_obj_DL_000650" Offset="0x650" />
|
||||
<DList Name="object_kin2_obj_DL_000658" Offset="0x658" />
|
||||
<Collision Name="object_kin2_obj_Colheader_000798" Offset="0x798" />
|
||||
<DList Name="object_kin2_obj_DL_000820" Offset="0x820" />
|
||||
<DList Name="object_kin2_obj_DL_000828" Offset="0x828" />
|
||||
<DList Name="gOceanSpiderHouseFireplaceGrateDL" Offset="0x828" />
|
||||
<Collision Name="object_kin2_obj_Colheader_000908" Offset="0x908" />
|
||||
<DList Name="object_kin2_obj_DL_000CA0" Offset="0xCA0" />
|
||||
<DList Name="object_kin2_obj_DL_000CA8" Offset="0xCA8" />
|
||||
<Collision Name="object_kin2_obj_Colheader_000F80" Offset="0xF80" />
|
||||
<DList Name="gOceanSpiderHouseBookshelfDL" Offset="0xCA8" />
|
||||
<Collision Name="gOceanSpiderHouseBookshelfCol" Offset="0xF80" />
|
||||
<DList Name="object_kin2_obj_DL_0010F0" Offset="0x10F0" />
|
||||
<DList Name="object_kin2_obj_DL_0010F8" Offset="0x10F8" />
|
||||
<Collision Name="object_kin2_obj_Colheader_001328" Offset="0x1328" />
|
||||
<DList Name="gOceanSpiderHouseChestOfDrawersDL" Offset="0x10F8" />
|
||||
<Collision Name="gOceanSpiderHouseChestOfDrawersCol" Offset="0x1328" />
|
||||
<!-- <Blob Name="object_kin2_obj_Blob_001354" Size="0x2C" Offset="0x1354" /> -->
|
||||
<Texture Name="object_kin2_obj_TLUT_001380" OutName="tlut_001380" Format="rgba16" Width="4" Height="4" Offset="0x1380" />
|
||||
<Texture Name="gOceanSpiderHouseTLUT" OutName="ocean_spider_house_tlut" Format="rgba16" Width="4" Height="4" Offset="0x1380" />
|
||||
<!-- <Blob Name="object_kin2_obj_Blob_0013A0" Size="0x20" Offset="0x13A0" /> -->
|
||||
<Texture Name="object_kin2_obj_Tex_0013C0" OutName="tex_0013C0" Format="ia8" Width="64" Height="64" Offset="0x13C0" />
|
||||
<Texture Name="object_kin2_obj_Tex_0023C0" OutName="tex_0023C0" Format="rgba16" Width="32" Height="32" Offset="0x23C0" />
|
||||
<Texture Name="object_kin2_obj_Tex_002BC0" OutName="tex_002BC0" Format="rgba16" Width="32" Height="32" Offset="0x2BC0" />
|
||||
<Texture Name="object_kin2_obj_Tex_0033C0" OutName="tex_0033C0" Format="ci4" Width="64" Height="64" Offset="0x33C0" />
|
||||
<Texture Name="object_kin2_obj_Tex_003BC0" OutName="tex_003BC0" Format="rgba16" Width="32" Height="64" Offset="0x3BC0" />
|
||||
<Texture Name="object_kin2_obj_Tex_004BC0" OutName="tex_004BC0" Format="rgba16" Width="32" Height="64" Offset="0x4BC0" />
|
||||
<Texture Name="object_kin2_obj_Tex_005BC0" OutName="tex_005BC0" Format="rgba16" Width="32" Height="32" Offset="0x5BC0" />
|
||||
<Texture Name="object_kin2_obj_Tex_0063C0" OutName="tex_0063C0" Format="rgba16" Width="32" Height="64" Offset="0x63C0" />
|
||||
<Texture Name="object_kin2_obj_Tex_0073C0" OutName="tex_0073C0" Format="rgba16" Width="32" Height="32" Offset="0x73C0" />
|
||||
<Texture Name="object_kin2_obj_Tex_007BC0" OutName="tex_007BC0" Format="i4" Width="64" Height="64" Offset="0x7BC0" />
|
||||
<Texture Name="gOceanSpiderHouseBombableWallCrackTex" OutName="ocean_spider_house_bombable_wall_crack" Format="ia8" Width="64" Height="64" Offset="0x13C0" />
|
||||
<Texture Name="gOceanSpiderHouseBookshelfWoodTex" OutName="ocean_spider_house_bookshelf_wood" Format="rgba16" Width="32" Height="32" Offset="0x23C0" />
|
||||
<Texture Name="gOceanSpiderHouseFireplaceGrateTex" OutName="ocean_spider_house_fireplace_grate" Format="rgba16" Width="32" Height="32" Offset="0x2BC0" />
|
||||
<Texture Name="gOceanSpiderHouseSkullkidPaintingTex" OutName="ocean_spider_house_skullkid_painting" Format="ci4" Width="64" Height="64" Offset="0x33C0" />
|
||||
<Texture Name="gOceanSpiderHouseChestOfDrawersFrontTex" OutName="ocean_spider_house_chest_of_drawers_front" Format="rgba16" Width="32" Height="64" Offset="0x3BC0" />
|
||||
<Texture Name="gOceanSpiderHouseChestOfDrawersBackTex" OutName="ocean_spider_house_chest_of_drawers_back" Format="rgba16" Width="32" Height="64" Offset="0x4BC0" />
|
||||
<Texture Name="gOceanSpiderHouseChestOfDrawersTopTex" OutName="ocean_spider_house_chest_of_drawers_top" Format="rgba16" Width="32" Height="32" Offset="0x5BC0" />
|
||||
<Texture Name="gOceanSpiderHouseBookshelfBooksTex" OutName="ocean_spider_house_bookshelf_books" Format="rgba16" Width="32" Height="64" Offset="0x63C0" />
|
||||
<Texture Name="gOceanSpiderHouseBombableWallDebrisTex1" OutName="ocean_spider_house_debris_1" Format="rgba16" Width="32" Height="32" Offset="0x73C0" />
|
||||
<Texture Name="gOceanSpiderHouseBombableWallDebrisTex2" OutName="ocean_spider_house_debris_2" Format="i4" Width="64" Height="64" Offset="0x7BC0" />
|
||||
</File>
|
||||
</Root>
|
||||
|
||||
+5
-5
@@ -139,18 +139,18 @@ All compound flag lists (e.g. `ACTOR_FLAG_4 | ACTOR_FLAG_8`) should be listed in
|
||||
- Use `sizeof` or `ARRAY_COUNT`/`ARRAY_COUNTU` where it makes sense, e.g. in loops that are using an array.
|
||||
- clang-format sometimes does weird things to array formatting. Experiment with and without a comma after the last element and see which looks better.
|
||||
|
||||
## GlobalCtx2
|
||||
## Play2
|
||||
|
||||
In some particular instances, IDO requires the function argument `globalCtx` to be cast to a second variable of the same type to match. In these particular instances, the function argument should be renamed to `globalCtx2` and than this `globalCtx2` just assigned to a stack variable called `globalCtx`. This cast should occur before the actor `THIS` cast is made. For example in `z_en_firefly.c`
|
||||
In some particular instances, IDO requires the function argument `play` to be cast to a second variable of the same type to match. In these particular instances, the function argument should be renamed to `play2` and than this `play2` just assigned to a stack variable called `play`. This cast should occur before the actor `THIS` cast is made. For example in `z_en_firefly.c`
|
||||
```c
|
||||
void EnFirefly_Update(Actor* thisx, GlobalContext* globalCtx2) {
|
||||
GlobalContext* globalCtx = globalCtx2;
|
||||
void EnFirefly_Update(Actor* thisx, PlayState* play2) {
|
||||
PlayState* play = play2;
|
||||
EnFirefly* this = THIS;
|
||||
```
|
||||
|
||||
In other places the cast is actually not explictly needed, but a stack `pad` variable is still needed. For this there should just be a stack variable called `pad` of type `s32` before the actor `THIS` cast. For example in `z_bg_goron_oyu`
|
||||
```c
|
||||
void BgGoronOyu_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
void BgGoronOyu_Init(Actor* thisx, PlayState* play) {
|
||||
s32 pad;
|
||||
BgGoronOyu* this = THIS;
|
||||
CollisionHeader* colHeader = NULL;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,10 +21,10 @@ The actor file starts off looking like:
|
||||
#define THIS ((EnRecepgirl*)thisx)
|
||||
|
||||
// --------------- 3 ---------------
|
||||
void EnRecepgirl_Init(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnRecepgirl_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnRecepgirl_Update(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnRecepgirl_Draw(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnRecepgirl_Init(Actor* thisx, PlayState* play);
|
||||
void EnRecepgirl_Destroy(Actor* thisx, PlayState* play);
|
||||
void EnRecepgirl_Update(Actor* thisx, PlayState* play);
|
||||
void EnRecepgirl_Draw(Actor* thisx, PlayState* play);
|
||||
|
||||
// --------------- 4 ---------------
|
||||
#if 0
|
||||
@@ -115,7 +115,7 @@ The header file looks like this at the moment:
|
||||
|
||||
struct EnRecepgirl;
|
||||
|
||||
typedef void (*EnRecepgirlActionFunc)(struct EnRecepgirl*, GlobalContext*);
|
||||
typedef void (*EnRecepgirlActionFunc)(struct EnRecepgirl*, PlayState*);
|
||||
|
||||
typedef struct EnRecepgirl {
|
||||
/* 0x0000 */ Actor actor;
|
||||
@@ -141,7 +141,7 @@ The general rule for order of decompilation is
|
||||
- Next, decompile any other functions from the actor you have found in `Init`. You generally start with the action functions, because they return nothing and all take the same arguments,
|
||||
|
||||
```C
|
||||
void func_80whatever(EnRecepgirl* this, GlobalContext* globalCtx);
|
||||
void func_80whatever(EnRecepgirl* this, PlayState* play);
|
||||
```
|
||||
|
||||
- Decompile each action function in turn until you run out. Along the way, do any other functions in the actor for which you have discovered the argument types. (You are probably better doing depth-first on action functions than breadth-first: it's normally easier to follow along one branch of the actions than be thinking about several at once.)
|
||||
@@ -207,14 +207,14 @@ static void *D_80C106B0[4] = {(void *)0x600F8F0, (void *)0x600FCF0, (void *)0x60
|
||||
static s32 D_80C106C8 = 0;
|
||||
InitChainEntry D_80C106C0[2]; // unable to generate initializer
|
||||
|
||||
void EnRecepgirl_Init(EnRecepgirl *this, GlobalContext *globalCtx) {
|
||||
void EnRecepgirl_Init(EnRecepgirl* this, PlayState* play) {
|
||||
EnRecepgirl* this = (EnRecepgirl *) thisx;
|
||||
void **temp_s0;
|
||||
void **phi_s0;
|
||||
|
||||
Actor_ProcessInitChain((Actor *) this, D_80C106C0);
|
||||
ActorShape_Init(&this->actor.shape, -60.0f, NULL, 0.0f);
|
||||
SkelAnime_InitFlex(globalCtx, (SkelAnime *) this->unk_144, &D_06011B60, (AnimationHeader *) &D_06009890, this + 0x188, this + 0x218, 0x18);
|
||||
SkelAnime_InitFlex(play, (SkelAnime *) this->unk_144, &D_06011B60, (AnimationHeader *) &D_06009890, this + 0x188, this + 0x218, 0x18);
|
||||
phi_s0 = D_80C106B0;
|
||||
if (D_80C106C8 == 0) {
|
||||
do {
|
||||
@@ -225,7 +225,7 @@ void EnRecepgirl_Init(EnRecepgirl *this, GlobalContext *globalCtx) {
|
||||
D_80C106C8 = 1;
|
||||
}
|
||||
this->unk_2AC = 2;
|
||||
if (Flags_GetSwitch(globalCtx, (s32) this->actor.params) != 0) {
|
||||
if (Flags_GetSwitch(play, (s32) this->actor.params) != 0) {
|
||||
this->actor.textId = 0x2ADC;
|
||||
} else {
|
||||
this->actor.textId = 0x2AD9;
|
||||
@@ -244,14 +244,14 @@ static void *D_80C106B0[4] = {(void *)0x600F8F0, (void *)0x600FCF0, (void *)0x60
|
||||
static s32 D_80C106C8 = 0;
|
||||
InitChainEntry D_80C106C0[2]; // unable to generate initializer
|
||||
|
||||
void EnRecepgirl_Init(Actor *thisx, GlobalContext *globalCtx) {
|
||||
void EnRecepgirl_Init(Actor* thisx, PlayState* play) {
|
||||
EnRecepgirl* this = (EnRecepgirl *) thisx;
|
||||
void **temp_s0;
|
||||
void **phi_s0;
|
||||
|
||||
Actor_ProcessInitChain((Actor *) this, D_80C106C0);
|
||||
ActorShape_Init(&this->actor.shape, -60.0f, NULL, 0.0f);
|
||||
SkelAnime_InitFlex(globalCtx, (SkelAnime *) this->unk_144, &D_06011B60, (AnimationHeader *) &D_06009890, this + 0x188, this + 0x218, 0x18);
|
||||
SkelAnime_InitFlex(play, (SkelAnime *) this->unk_144, &D_06011B60, (AnimationHeader *) &D_06009890, this + 0x188, this + 0x218, 0x18);
|
||||
phi_s0 = D_80C106B0;
|
||||
if (D_80C106C8 == 0) {
|
||||
do {
|
||||
@@ -262,7 +262,7 @@ void EnRecepgirl_Init(Actor *thisx, GlobalContext *globalCtx) {
|
||||
D_80C106C8 = 1;
|
||||
}
|
||||
this->unk_2AC = 2;
|
||||
if (Flags_GetSwitch(globalCtx, (s32) this->actor.params) != 0) {
|
||||
if (Flags_GetSwitch(play, (s32) this->actor.params) != 0) {
|
||||
this->actor.textId = 0x2ADC;
|
||||
} else {
|
||||
this->actor.textId = 0x2AD9;
|
||||
@@ -300,14 +300,14 @@ static void *D_80C106B0[4] = {(void *)0x600F8F0, (void *)0x600FCF0, (void *)0x60
|
||||
static s32 D_80C106C8 = 0;
|
||||
InitChainEntry D_80C106C0[2]; // unable to generate initializer
|
||||
|
||||
void EnRecepgirl_Init(Actor *thisx, GlobalContext *globalCtx) {
|
||||
void EnRecepgirl_Init(Actor* thisx, PlayState* play) {
|
||||
EnRecepgirl* this = THIS;
|
||||
void **temp_s0;
|
||||
void **phi_s0;
|
||||
|
||||
Actor_ProcessInitChain(&this->actor, D_80C106C0);
|
||||
ActorShape_Init(&this->actor.shape, -60.0f, NULL, 0.0f);
|
||||
SkelAnime_InitFlex(globalCtx, (SkelAnime *) this->unk_144, &D_06011B60, (AnimationHeader *) &D_06009890, this + 0x188, this + 0x218, 0x18);
|
||||
SkelAnime_InitFlex(play, (SkelAnime *) this->unk_144, &D_06011B60, (AnimationHeader *) &D_06009890, this + 0x188, this + 0x218, 0x18);
|
||||
phi_s0 = D_80C106B0;
|
||||
if (D_80C106C8 == 0) {
|
||||
do {
|
||||
@@ -318,7 +318,7 @@ void EnRecepgirl_Init(Actor *thisx, GlobalContext *globalCtx) {
|
||||
D_80C106C8 = 1;
|
||||
}
|
||||
this->unk_2AC = 2;
|
||||
if (Flags_GetSwitch(globalCtx, (s32) this->actor.params) != 0) {
|
||||
if (Flags_GetSwitch(play, (s32) this->actor.params) != 0) {
|
||||
this->actor.textId = 0x2ADC;
|
||||
} else {
|
||||
this->actor.textId = 0x2AD9;
|
||||
@@ -388,7 +388,7 @@ This is the combined system that handles actors' skeletons and their animations.
|
||||
```C
|
||||
Actor_ProcessInitChain(&this->actor, D_80C106C0);
|
||||
ActorShape_Init(&this->actor.shape, -60.0f, NULL, 0.0f);
|
||||
SkelAnime_InitFlex(globalCtx, (SkelAnime *) this->unk_144, &D_06011B60, (AnimationHeader *) &D_06009890, this + 0x188, this + 0x218, 0x18);
|
||||
SkelAnime_InitFlex(play, (SkelAnime *) this->unk_144, &D_06011B60, (AnimationHeader *) &D_06009890, this + 0x188, this + 0x218, 0x18);
|
||||
phi_s0 = D_80C106B0;
|
||||
```
|
||||
|
||||
@@ -396,7 +396,7 @@ An actor with SkelAnime has three structs in the Actor struct that handle it: on
|
||||
|
||||
There are two different sorts of SkelAnime, although for decompilation purposes there is not much difference between them. Looking at the prototype of `SkelAnime_InitFlex` from `functions.h` (or even the definition in `z_skelanime.c`),
|
||||
```C
|
||||
void SkelAnime_InitFlex(GlobalContext* globalCtx, SkelAnime* skelAnime, FlexSkeletonHeader* skeletonHeaderSeg,
|
||||
void SkelAnime_InitFlex(PlayState* play, SkelAnime* skelAnime, FlexSkeletonHeader* skeletonHeaderSeg,
|
||||
AnimationHeader* animation, Vec3s* jointTable, Vec3s* morphTable, s32 limbCount);
|
||||
```
|
||||
we can read off the types of the various arguments:
|
||||
@@ -432,7 +432,7 @@ As with the data, these externed symbols should be kept in increasing address or
|
||||
|
||||
They are both passed to the function as pointers, so need `&` to pass the address instead of the actual data. Hence we end up with
|
||||
```C
|
||||
SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06011B60, &D_06009890, this->jointTable, this->morphTable, 24);
|
||||
SkelAnime_InitFlex(play, &this->skelAnime, &D_06011B60, &D_06009890, this->jointTable, this->morphTable, 24);
|
||||
```
|
||||
note that `this->jointTable` and `this->morphTable` are arrays, so are already effectively pointers and don't need a `&`.
|
||||
|
||||
@@ -487,14 +487,14 @@ Removing some of the declarations for data that we have accounted for, the funct
|
||||
```C
|
||||
? func_80C10148(EnRecepgirl *); // extern
|
||||
|
||||
void EnRecepgirl_Init(Actor *thisx, GlobalContext *globalCtx) {
|
||||
void EnRecepgirl_Init(Actor* thisx, PlayState* play) {
|
||||
EnRecepgirl* this = THIS;
|
||||
void **temp_s0;
|
||||
void **phi_s0;
|
||||
|
||||
Actor_ProcessInitChain(&this->actor, D_80C106C0);
|
||||
ActorShape_Init(&this->actor.shape, -60.0f, NULL, 0.0f);
|
||||
SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06011B60, &D_06009890, this->jointTable, this->morphTable, 24);
|
||||
SkelAnime_InitFlex(play, &this->skelAnime, &D_06011B60, &D_06009890, this->jointTable, this->morphTable, 24);
|
||||
|
||||
phi_s0 = D_80C106B0;
|
||||
if (D_80C106C8 == 0) {
|
||||
@@ -507,7 +507,7 @@ void EnRecepgirl_Init(Actor *thisx, GlobalContext *globalCtx) {
|
||||
}
|
||||
|
||||
this->unk_2AC = 2;
|
||||
if (Flags_GetSwitch(globalCtx, (s32) this->actor.params) != 0) {
|
||||
if (Flags_GetSwitch(play, (s32) this->actor.params) != 0) {
|
||||
this->actor.textId = 0x2ADC;
|
||||
} else {
|
||||
this->actor.textId = 0x2AD9;
|
||||
@@ -520,7 +520,7 @@ We have one significant problem and a few minor ones left.
|
||||
|
||||
### Casts and boolean functions
|
||||
|
||||
mips2c likes casting a lot: this is useful for getting types, less so when the type is changed automatically, such as in `Flags_GetSwitch(globalCtx, (s32) this->actor.params)`. Also, if we look at this function's definition, we discover it will only return `true` or `false`, so we can remove the `!= 0`.
|
||||
mips2c likes casting a lot: this is useful for getting types, less so when the type is changed automatically, such as in `Flags_GetSwitch(play, (s32) this->actor.params)`. Also, if we look at this function's definition, we discover it will only return `true` or `false`, so we can remove the `!= 0`.
|
||||
|
||||
### Functions called
|
||||
|
||||
@@ -529,14 +529,14 @@ One minor problem is what `func_80C10148` is: C needs a prototype to compile it
|
||||
2. It's not used to assign a value
|
||||
|
||||
To this experience will add a third reason:
|
||||
3. This is probably a setup function for an actionFunc, which are usually either `void (*)(ActorType*)` or `void (*)(ActorType*, GlobalContext*)`.
|
||||
3. This is probably a setup function for an actionFunc, which are usually either `void (*)(ActorType*)` or `void (*)(ActorType*, PlayState*)`.
|
||||
|
||||
The upshot of all this is to remove mips2c's `? func_80C10148(EnRecepgirl *); // extern`, and add a `void func_80C10148(EnRecepgirl* this);` underneath the declarations for the main four functions:
|
||||
```C
|
||||
void EnRecepgirl_Init(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnRecepgirl_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnRecepgirl_Update(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnRecepgirl_Draw(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnRecepgirl_Init(Actor* thisx, PlayState* play);
|
||||
void EnRecepgirl_Destroy(Actor* thisx, PlayState* play);
|
||||
void EnRecepgirl_Update(Actor* thisx, PlayState* play);
|
||||
void EnRecepgirl_Draw(Actor* thisx, PlayState* play);
|
||||
|
||||
void func_80C10148(EnRecepgirl* this);
|
||||
```
|
||||
@@ -625,12 +625,12 @@ Hence we end up with
|
||||
void func_80C10148(EnRecepgirl* this);
|
||||
[...]
|
||||
|
||||
void EnRecepgirl_Init(Actor *thisx, GlobalContext *globalCtx) {
|
||||
void EnRecepgirl_Init(Actor* thisx, PlayState* play) {
|
||||
EnRecepgirl* this = THIS;
|
||||
|
||||
Actor_ProcessInitChain(&this->actor, D_80C106C0);
|
||||
ActorShape_Init(&this->actor.shape, -60.0f, NULL, 0.0f);
|
||||
SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_06011B60, &D_06009890, this->jointTable, this->morphTable, 24);
|
||||
SkelAnime_InitFlex(play, &this->skelAnime, &D_06011B60, &D_06009890, this->jointTable, this->morphTable, 24);
|
||||
|
||||
if (D_80C106C8 == 0) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
@@ -641,7 +641,7 @@ void EnRecepgirl_Init(Actor *thisx, GlobalContext *globalCtx) {
|
||||
|
||||
this->unk_2AC = 2;
|
||||
|
||||
if (Flags_GetSwitch(globalCtx, this->actor.params)) {
|
||||
if (Flags_GetSwitch(play, this->actor.params)) {
|
||||
this->actor.textId = 0x2ADC;
|
||||
} else {
|
||||
this->actor.textId = 0x2AD9;
|
||||
|
||||
@@ -51,7 +51,7 @@ You can keep the diff open in the terminal, and it will refresh when the C file
|
||||
In this case, we see that various branches are happening in the wrong place. Here I fear experience is necessary: notice that the function has three blocks that look quite similar, and three separate conditionals that depend on the same variable. This is a good indicator of a switch. Changing the function to use a switch,
|
||||
|
||||
```C
|
||||
void EnJj_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
void EnJj_Init(Actor* thisx, PlayState* play) {
|
||||
EnJj* this = THIS;
|
||||
|
||||
s32 sp4C;
|
||||
@@ -64,7 +64,7 @@ void EnJj_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
|
||||
switch (temp_v0) {
|
||||
case -1:
|
||||
SkelAnime_InitFlex(globalCtx, &this->skelAnime, &D_0600B9A8, &D_06001F4C, this->jointTable,
|
||||
SkelAnime_InitFlex(play, &this->skelAnime, &D_0600B9A8, &D_06001F4C, this->jointTable,
|
||||
this->morphTable, 22);
|
||||
Animation_PlayLoop(&this->skelAnime, &D_06001F4C);
|
||||
this->unk_30A = 0;
|
||||
@@ -78,24 +78,24 @@ void EnJj_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
func_80A87800(this, func_80A87C30);
|
||||
}
|
||||
this->childActor = Actor_SpawnAsChild(
|
||||
&globalCtx->actorCtx, &this->dyna.actor, globalCtx, ACTOR_EN_JJ, this->dyna.actor.world.pos.x - 10.0f,
|
||||
&play->actorCtx, &this->dyna.actor, play, ACTOR_EN_JJ, this->dyna.actor.world.pos.x - 10.0f,
|
||||
this->dyna.actor.world.pos.y, this->dyna.actor.world.pos.z, 0, this->dyna.actor.world.rot.y, 0, 0);
|
||||
DynaPolyActor_Init(&this->dyna, 0);
|
||||
CollisionHeader_GetVirtual(&D_06000A1C, &sp4C);
|
||||
this->dyna.bgId =
|
||||
DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, sp4C);
|
||||
Collider_InitCylinder(globalCtx, &this->collider);
|
||||
Collider_SetCylinder(globalCtx, &this->collider, &this->dyna.actor, &D_80A88CB4);
|
||||
DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, sp4C);
|
||||
Collider_InitCylinder(play, &this->collider);
|
||||
Collider_SetCylinder(play, &this->collider, &this->dyna.actor, &D_80A88CB4);
|
||||
this->dyna.actor.colChkInfo.mass = 0xFF;
|
||||
break;
|
||||
case 0:
|
||||
DynaPolyActor_Init(&this->dyna, 0);
|
||||
CollisionHeader_GetVirtual(&D_06001830, &sp4C);
|
||||
// temp_a1_2 = &globalCtx->colCtx.dyna;
|
||||
// temp_a1_2 = &play->colCtx.dyna;
|
||||
// sp44 = temp_a1_2;
|
||||
this->dyna.bgId =
|
||||
DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, sp4C);
|
||||
func_8003ECA8(globalCtx, &globalCtx->colCtx.dyna, this->dyna.bgId);
|
||||
DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, sp4C);
|
||||
func_8003ECA8(play, &play->colCtx.dyna, this->dyna.bgId);
|
||||
this->dyna.actor.update = func_80A87F44;
|
||||
this->dyna.actor.draw = NULL;
|
||||
Actor_SetScale(&this->dyna.actor, 0.087f);
|
||||
@@ -104,7 +104,7 @@ void EnJj_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
DynaPolyActor_Init(&this->dyna, 0);
|
||||
CollisionHeader_GetVirtual(&D_0600BA8C, &sp4C);
|
||||
this->dyna.bgId =
|
||||
DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, sp4C);
|
||||
DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, sp4C);
|
||||
this->dyna.actor.update = func_80A87F44;
|
||||
this->dyna.actor.draw = NULL;
|
||||
Actor_SetScale(&this->dyna.actor, 0.087f);
|
||||
@@ -123,10 +123,10 @@ we see that the diff is nearly correct (note that `-3` lets you compare current
|
||||

|
||||
</details>
|
||||
|
||||
except we still have some stack issues. Now that `temp_v0` is only used once, it looks fake. Eliminating it actually seems to make the stack worse. To fix this, we employ something that we have evidence that the developers did: namely, we make a copy of `globalCtx` (the theory is that they actually used `gameState` as an argument of the main 4 functions, just like we used `Actor* thisx` as the first argument.) The quick way to do this is to change the top of the function to
|
||||
except we still have some stack issues. Now that `temp_v0` is only used once, it looks fake. Eliminating it actually seems to make the stack worse. To fix this, we employ something that we have evidence that the developers did: namely, we make a copy of `play` (the theory is that they actually used `gameState` as an argument of the main 4 functions, just like we used `Actor* thisx` as the first argument.) The quick way to do this is to change the top of the function to
|
||||
```C
|
||||
void EnJj_Init(Actor* thisx, GlobalContext* globalCtx2) {
|
||||
GlobalContext* globalCtx = globalCtx2;
|
||||
void EnJj_Init(Actor* thisx, PlayState* play2) {
|
||||
PlayState* play = play2;
|
||||
EnJj* this = THIS;
|
||||
...
|
||||
```
|
||||
|
||||
@@ -40,15 +40,15 @@ Large code block, click to show
|
||||
|
||||
#define THIS ((EnRecepgirl*)thisx)
|
||||
|
||||
void EnRecepgirl_Init(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnRecepgirl_Destroy(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnRecepgirl_Update(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnRecepgirl_Draw(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnRecepgirl_Init(Actor* thisx, PlayState* play);
|
||||
void EnRecepgirl_Destroy(Actor* thisx, PlayState* play);
|
||||
void EnRecepgirl_Update(Actor* thisx, PlayState* play);
|
||||
void EnRecepgirl_Draw(Actor* thisx, PlayState* play);
|
||||
|
||||
void func_80C10148(EnRecepgirl* this);
|
||||
void func_80C1019C(EnRecepgirl* this, GlobalContext* globalCtx);
|
||||
void func_80C1019C(EnRecepgirl* this, PlayState* play);
|
||||
void func_80C10290(EnRecepgirl* this);
|
||||
void func_80C102D4(EnRecepgirl * this, GlobalContext * globalCtx);
|
||||
void func_80C102D4(EnRecepgirl* this, PlayState* play);
|
||||
|
||||
const ActorInit En_Recepgirl_InitVars = {
|
||||
ACTOR_EN_RECEPGIRL,
|
||||
@@ -73,13 +73,13 @@ static InitChainEntry D_80C106C0[] = {
|
||||
static s32 D_80C106C8 = 0;
|
||||
|
||||
// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Init.s")
|
||||
void EnRecepgirl_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
void EnRecepgirl_Init(Actor* thisx, PlayState* play) {
|
||||
EnRecepgirl* this = THIS;
|
||||
s32 i;
|
||||
|
||||
Actor_ProcessInitChain(&this->actor, D_80C106C0);
|
||||
ActorShape_Init(&this->actor.shape, -60.0f, NULL, 0.0f);
|
||||
SkelAnime_InitFlex(globalCtx, &this->skelAnime, &object_bg_Skel_011B60, &object_bg_Anim_009890, this->jointTable, this->morphTable, 24);
|
||||
SkelAnime_InitFlex(play, &this->skelAnime, &object_bg_Skel_011B60, &object_bg_Anim_009890, this->jointTable, this->morphTable, 24);
|
||||
|
||||
if (D_80C106C8 == 0) {
|
||||
for (i = 0; i < 4; i++) {
|
||||
@@ -90,7 +90,7 @@ void EnRecepgirl_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
|
||||
this->unk_2AC = 2;
|
||||
|
||||
if (Flags_GetSwitch(globalCtx, this->actor.params)) {
|
||||
if (Flags_GetSwitch(play, this->actor.params)) {
|
||||
this->actor.textId = 0x2ADC;
|
||||
} else {
|
||||
this->actor.textId = 0x2AD9;
|
||||
@@ -100,7 +100,7 @@ void EnRecepgirl_Init(Actor* thisx, GlobalContext* globalCtx) {
|
||||
}
|
||||
|
||||
// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Destroy.s")
|
||||
void EnRecepgirl_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
||||
void EnRecepgirl_Destroy(Actor* thisx, PlayState* play) {
|
||||
}
|
||||
|
||||
// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C100DC.s")
|
||||
@@ -127,7 +127,7 @@ void func_80C10148(EnRecepgirl *this) {
|
||||
}
|
||||
|
||||
// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C1019C.s")
|
||||
void func_80C1019C(EnRecepgirl* this, GlobalContext* globalCtx) {
|
||||
void func_80C1019C(EnRecepgirl* this, PlayState* play) {
|
||||
if (SkelAnime_Update(&this->skelAnime) != 0) {
|
||||
if (this->skelAnime.animation == &object_bg_Anim_00A280) {
|
||||
Animation_MorphToPlayOnce(&this->skelAnime, &object_bg_Anim_00AD98, 5.0f);
|
||||
@@ -136,13 +136,13 @@ void func_80C1019C(EnRecepgirl* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
}
|
||||
|
||||
if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state) != 0) {
|
||||
if (Actor_ProcessTalkRequest(&this->actor, &play->state) != 0) {
|
||||
func_80C10290(this);
|
||||
} else if (Actor_IsFacingPlayer(&this->actor, 0x2000)) {
|
||||
func_800B8614(&this->actor, globalCtx, 60.0f);
|
||||
if (Player_GetMask(globalCtx) == 2) {
|
||||
func_800B8614(&this->actor, play, 60.0f);
|
||||
if (Player_GetMask(play) == 2) {
|
||||
this->actor.textId = 0x2367;
|
||||
} else if (Flags_GetSwitch(globalCtx, this->actor.params)) {
|
||||
} else if (Flags_GetSwitch(play, this->actor.params)) {
|
||||
this->actor.textId = 0x2ADC;
|
||||
} else {
|
||||
this->actor.textId = 0x2AD9;
|
||||
@@ -157,7 +157,7 @@ void func_80C10290(EnRecepgirl *this) {
|
||||
}
|
||||
|
||||
// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C102D4.s")
|
||||
void func_80C102D4(EnRecepgirl *this, GlobalContext *globalCtx) {
|
||||
void func_80C102D4(EnRecepgirl* this, PlayState* play) {
|
||||
u8 temp_v0_2;
|
||||
|
||||
if (SkelAnime_Update(&this->skelAnime) != 0) {
|
||||
@@ -176,16 +176,16 @@ void func_80C102D4(EnRecepgirl *this, GlobalContext *globalCtx) {
|
||||
}
|
||||
}
|
||||
|
||||
temp_v0_2 = Message_GetState(&globalCtx->msgCtx);
|
||||
temp_v0_2 = Message_GetState(&play->msgCtx);
|
||||
if (temp_v0_2 == 2) {
|
||||
this->actor.textId = 0x2ADC;
|
||||
func_80C10148(this);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((temp_v0_2 == 5) && (Message_ShouldAdvance(globalCtx) != 0)) {
|
||||
if ((temp_v0_2 == 5) && (Message_ShouldAdvance(play) != 0)) {
|
||||
if (this->actor.textId == 0x2AD9) {
|
||||
Flags_SetSwitch(globalCtx, this->actor.params);
|
||||
Flags_SetSwitch(play, this->actor.params);
|
||||
Animation_MorphToPlayOnce(&this->skelAnime, &object_bg_Anim_00AD98, 10.0f);
|
||||
if ((gSaveContext.save.weekEventReg[63] & 0x80)) {
|
||||
this->actor.textId = 0x2ADF;
|
||||
@@ -205,23 +205,23 @@ void func_80C102D4(EnRecepgirl *this, GlobalContext *globalCtx) {
|
||||
this->actor.textId = 0x2AE0;
|
||||
}
|
||||
}
|
||||
func_80151938(globalCtx, this->actor.textId);
|
||||
func_80151938(play, this->actor.textId);
|
||||
}
|
||||
}
|
||||
|
||||
// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Update.s")
|
||||
void EnRecepgirl_Update(Actor *thisx, GlobalContext *globalCtx) {
|
||||
void EnRecepgirl_Update(Actor* thisx, PlayState* play) {
|
||||
s32 pad;
|
||||
EnRecepgirl* this = THIS;
|
||||
Vec3s sp30;
|
||||
|
||||
this->actionFunc(this, globalCtx);
|
||||
Actor_TrackPlayer(globalCtx, &this->actor, &this->unk_2AE, &sp30, this->actor.focus.pos);
|
||||
this->actionFunc(this, play);
|
||||
Actor_TrackPlayer(play, &this->actor, &this->unk_2AE, &sp30, this->actor.focus.pos);
|
||||
func_80C100DC(this);
|
||||
}
|
||||
|
||||
// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10558.s")
|
||||
s32 func_80C10558(GlobalContext *globalCtx, s32 limbIndex, Gfx **dList, Vec3f *pos, Vec3s *rot, Actor *thisx) {
|
||||
s32 func_80C10558(PlayState* play, s32 limbIndex, Gfx **dList, Vec3f *pos, Vec3s *rot, Actor *thisx) {
|
||||
EnRecepgirl* this = THIS;
|
||||
|
||||
if (limbIndex == 5) {
|
||||
@@ -231,7 +231,7 @@ s32 func_80C10558(GlobalContext *globalCtx, s32 limbIndex, Gfx **dList, Vec3f *p
|
||||
}
|
||||
|
||||
// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10590.s")
|
||||
void func_80C10590(GlobalContext *globalCtx, s32 limbIndex, Actor *thisx) {
|
||||
void func_80C10590(PlayState* play, s32 limbIndex, Actor *thisx) {
|
||||
EnRecepgirl* this = THIS;
|
||||
|
||||
if (limbIndex == 5) {
|
||||
@@ -241,18 +241,18 @@ void func_80C10590(GlobalContext *globalCtx, s32 limbIndex, Actor *thisx) {
|
||||
}
|
||||
|
||||
// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Draw.s")
|
||||
void EnRecepgirl_Draw(Actor *thisx, GlobalContext *globalCtx) {
|
||||
void EnRecepgirl_Draw(Actor* thisx, PlayState* play) {
|
||||
EnRecepgirl* this = THIS;
|
||||
|
||||
OPEN_DISPS(globalCtx->state.gfxCtx);
|
||||
OPEN_DISPS(play->state.gfxCtx);
|
||||
|
||||
func_8012C28C(globalCtx->state.gfxCtx);
|
||||
func_8012C28C(play->state.gfxCtx);
|
||||
|
||||
gSPSegment(POLY_OPA_DISP++, 0x08, D_80C106B0[this->unk_2AC]);
|
||||
|
||||
SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, func_80C10558, NULL, func_80C10590, &this->actor);
|
||||
SkelAnime_DrawTransformFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, func_80C10558, NULL, func_80C10590, &this->actor);
|
||||
|
||||
CLOSE_DISPS(globalCtx->state.gfxCtx);
|
||||
CLOSE_DISPS(play->state.gfxCtx);
|
||||
}
|
||||
|
||||
```
|
||||
@@ -412,7 +412,7 @@ Finally, clearly `4` is linked to the data over which we're iterating: namely it
|
||||
|
||||
We've got one struct variable left. To find out what it does, we can look at a function that uses it, for example
|
||||
```C
|
||||
s32 EnRecepgirl_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot,
|
||||
s32 EnRecepgirl_OverrideLimbDraw(PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot,
|
||||
Actor* thisx) {
|
||||
EnRecepgirl* this = THIS;
|
||||
|
||||
@@ -422,7 +422,7 @@ s32 EnRecepgirl_OverrideLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Gfx**
|
||||
return false;
|
||||
}
|
||||
|
||||
void EnRecepgirl_UnkLimbDraw(GlobalContext* globalCtx, s32 limbIndex, Actor* thisx) {
|
||||
void EnRecepgirl_UnkLimbDraw(PlayState* play, s32 limbIndex, Actor* thisx) {
|
||||
EnRecepgirl* this = THIS;
|
||||
|
||||
if (limbIndex == 5) {
|
||||
@@ -449,7 +449,7 @@ void func_80C10148(EnRecepgirl* this) {
|
||||
this->actionFunc = func_80C1019C;
|
||||
}
|
||||
|
||||
void func_80C1019C(EnRecepgirl* this, GlobalContext* globalCtx) {
|
||||
void func_80C1019C(EnRecepgirl* this, PlayState* play) {
|
||||
if (SkelAnime_Update(&this->skelAnime) != 0) {
|
||||
if (this->skelAnime.animation == &object_bg_Anim_00A280) {
|
||||
Animation_MorphToPlayOnce(&this->skelAnime, &object_bg_Anim_00AD98, 5.0f);
|
||||
@@ -458,13 +458,13 @@ void func_80C1019C(EnRecepgirl* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
}
|
||||
|
||||
if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state) != 0) {
|
||||
if (Actor_ProcessTalkRequest(&this->actor, &play->state) != 0) {
|
||||
func_80C10290(this);
|
||||
} else if (Actor_IsFacingPlayer(&this->actor, 0x2000)) {
|
||||
func_800B8614(&this->actor, globalCtx, 60.0f);
|
||||
if (Player_GetMask(globalCtx) == PLAYER_MASK_KAFEIS_MASK) {
|
||||
func_800B8614(&this->actor, play, 60.0f);
|
||||
if (Player_GetMask(play) == PLAYER_MASK_KAFEIS_MASK) {
|
||||
this->actor.textId = 0x2367; // "... doesn't Kafei want to break off his engagement ... ?"
|
||||
} else if (Flags_GetSwitch(globalCtx, this->actor.params)) {
|
||||
} else if (Flags_GetSwitch(play, this->actor.params)) {
|
||||
this->actor.textId = 0x2ADC; // hear directions again?
|
||||
} else {
|
||||
this->actor.textId = 0x2AD9; // "Welcome..."
|
||||
@@ -477,7 +477,7 @@ void func_80C10290(EnRecepgirl* this) {
|
||||
this->actionFunc = func_80C102D4;
|
||||
}
|
||||
|
||||
void func_80C102D4(EnRecepgirl* this, GlobalContext* globalCtx) {
|
||||
void func_80C102D4(EnRecepgirl* this, PlayState* play) {
|
||||
u8 temp_v0_2;
|
||||
|
||||
if (SkelAnime_Update(&this->skelAnime)) {
|
||||
@@ -496,13 +496,13 @@ void func_80C102D4(EnRecepgirl* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
}
|
||||
|
||||
temp_v0_2 = Message_GetState(&globalCtx->msgCtx);
|
||||
temp_v0_2 = Message_GetState(&play->msgCtx);
|
||||
if (temp_v0_2 == 2) {
|
||||
this->actor.textId = 0x2ADC; // hear directions again?
|
||||
func_80C10148(this);
|
||||
} else if ((temp_v0_2 == 5) && (Message_ShouldAdvance(globalCtx) != 0)) {
|
||||
} else if ((temp_v0_2 == 5) && (Message_ShouldAdvance(play) != 0)) {
|
||||
if (this->actor.textId == 0x2AD9) { // "Welcome..."
|
||||
Flags_SetSwitch(globalCtx, this->actor.params);
|
||||
Flags_SetSwitch(play, this->actor.params);
|
||||
Animation_MorphToPlayOnce(&this->skelAnime, &object_bg_Anim_00AD98, 10.0f);
|
||||
if (gSaveContext.save.weekEventReg[63] & 0x80) { // showed Couple's Mask to meeting
|
||||
this->actor.textId = 0x2ADF; // Mayor's office is on the left (meeting ended)
|
||||
@@ -524,11 +524,11 @@ void func_80C102D4(EnRecepgirl* this, GlobalContext* globalCtx) {
|
||||
this->actor.textId = 0x2AE0; // drawing room on the right, don't go in without an appointment
|
||||
}
|
||||
}
|
||||
func_80151938(globalCtx, this->actor.textId);
|
||||
func_80151938(play, this->actor.textId);
|
||||
}
|
||||
}
|
||||
```
|
||||
All this branching is to make the conversation look more diverse and interesting. Notably, though, `func_80C1019C` is set to start with, and is only changed when `Actor_ProcessTalkRequest(&this->actor, &globalCtx->state) != 0`. This is something to do with talking. The other function handles the rest of the conversation, and hands back to the first if `Message_GetState(&globalCtx->msgCtx) == 2`. This function is *something* to do with the text state, which will require `z_message` to be decomped. However, observation in-game will reveal this is something to do with ending dialogue. So we can conclude that the action functions are `EnRecepgirl_Wait` and `EnRecepgirl_Talk`. The setup functions are thus `EnRecepgirl_SetupWait` and `EnRecepgirl_SetupTalk`.
|
||||
All this branching is to make the conversation look more diverse and interesting. Notably, though, `func_80C1019C` is set to start with, and is only changed when `Actor_ProcessTalkRequest(&this->actor, &play->state) != 0`. This is something to do with talking. The other function handles the rest of the conversation, and hands back to the first if `Message_GetState(&play->msgCtx) == 2`. This function is *something* to do with the text state, which will require `z_message` to be decomped. However, observation in-game will reveal this is something to do with ending dialogue. So we can conclude that the action functions are `EnRecepgirl_Wait` and `EnRecepgirl_Talk`. The setup functions are thus `EnRecepgirl_SetupWait` and `EnRecepgirl_SetupTalk`.
|
||||
|
||||
For more complex actors, we have a tool called `graphovl.py` that can produce function flow graphs for actors: running
|
||||
```
|
||||
@@ -551,7 +551,7 @@ We like to make macros for reading an actor's `params` (indeed, this is required
|
||||
Actor_SetScale(&this->dyna.actor, 0.1f);
|
||||
DynaPolyActor_Init(&this->dyna, 1);
|
||||
CollisionHeader_GetVirtual(&object_tree_Colheader_001B2C, &colHeader);
|
||||
this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader);
|
||||
this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, colHeader);
|
||||
}
|
||||
```
|
||||
|
||||
@@ -571,7 +571,7 @@ Notice that we use `thisx`: this makes the form of every one of these macros the
|
||||
Actor_SetScale(&this->dyna.actor, 0.1f);
|
||||
DynaPolyActor_Init(&this->dyna, 1);
|
||||
CollisionHeader_GetVirtual(&object_tree_Colheader_001B2C, &colHeader);
|
||||
this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this->dyna.actor, colHeader);
|
||||
this->dyna.bgId = DynaPoly_SetBgActor(play, &play->colCtx.dyna, &this->dyna.actor, colHeader);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -12,29 +12,29 @@ This document will be a bit different: we will look at the draw functions in EnR
|
||||
Unless it is completely invisible, an actor usually has a draw function as one of the main four actor functions. Hence its prototype looks like
|
||||
|
||||
```C
|
||||
void EnRecepgirl_Draw(Actor* thisx, GlobalContext* globalCtx);
|
||||
void EnRecepgirl_Draw(Actor* thisx, PlayState* play);
|
||||
```
|
||||
|
||||
From now on, the process is rather different from the decompilation process used for the other functions. Here is the output of mips2c after sorting out the actor struct from Init, and with the arguments set back to `Actor* thisx`:
|
||||
```C
|
||||
s32 func_80C10558(GlobalContext *globalCtx, s32 limbIndex, Gfx **dList, Vec3f *pos, Vec3s *rot, Actor *actor); // extern
|
||||
void func_80C10590(GlobalContext *globalCtx, s32 limbIndex, Actor *actor); // extern
|
||||
s32 func_80C10558(PlayState* play, s32 limbIndex, Gfx **dList, Vec3f *pos, Vec3s *rot, Actor *actor); // extern
|
||||
void func_80C10590(PlayState* play, s32 limbIndex, Actor *actor); // extern
|
||||
void *D_80C106B0[4] = {(void *)0x600F8F0, (void *)0x600FCF0, (void *)0x60100F0, (void *)0x600FCF0};
|
||||
|
||||
void EnRecepgirl_Draw(Actor *thisx, GlobalContext *globalCtx) {
|
||||
void EnRecepgirl_Draw(Actor* thisx, PlayState* play) {
|
||||
EnRecepgirl* this = (EnRecepgirl *) thisx;
|
||||
GraphicsContext *sp30;
|
||||
Gfx *temp_v1;
|
||||
GraphicsContext *temp_a0;
|
||||
|
||||
temp_a0 = globalCtx->state.gfxCtx;
|
||||
temp_a0 = play->state.gfxCtx;
|
||||
sp30 = temp_a0;
|
||||
func_8012C28C(temp_a0);
|
||||
temp_v1 = sp30->polyOpa.p;
|
||||
sp30->polyOpa.p = temp_v1 + 8;
|
||||
temp_v1->words.w0 = 0xDB060020;
|
||||
temp_v1->words.w1 = (u32) D_80C106B0[this->unk_2AC];
|
||||
SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, (s32) this->skelAnime.dListCount, func_80C10558, NULL, func_80C10590, (Actor *) this);
|
||||
SkelAnime_DrawTransformFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, (s32) this->skelAnime.dListCount, func_80C10558, NULL, func_80C10590, (Actor *) this);
|
||||
}
|
||||
```
|
||||
|
||||
@@ -91,25 +91,25 @@ If you have worked on OoT, you will be aware of the functions `Graph_OpenDisps`
|
||||
|
||||
It's sensible to eliminate all the `gfxCtx` temps and reintroduce as needed. Also remember to change the prototype and function definition back!
|
||||
```C
|
||||
s32 func_80C10558(GlobalContext *globalCtx, s32 limbIndex, Gfx **dList, Vec3f *pos, Vec3s *rot, Actor *actor);
|
||||
s32 func_80C10558(PlayState* play, s32 limbIndex, Gfx **dList, Vec3f *pos, Vec3s *rot, Actor *actor);
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10558.s")
|
||||
|
||||
void func_80C10590(GlobalContext *globalCtx, s32 limbIndex, Actor *actor);
|
||||
void func_80C10590(PlayState* play, s32 limbIndex, Actor *actor);
|
||||
#pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/func_80C10590.s")
|
||||
|
||||
// #pragma GLOBAL_ASM("asm/non_matchings/overlays/ovl_En_Recepgirl/EnRecepgirl_Draw.s")
|
||||
void EnRecepgirl_Draw(Actor *thisx, GlobalContext *globalCtx) {
|
||||
void EnRecepgirl_Draw(Actor* thisx, PlayState* play) {
|
||||
EnRecepgirl* this = THIS;
|
||||
|
||||
OPEN_DISPS(globalCtx->state.gfxCtx);
|
||||
OPEN_DISPS(play->state.gfxCtx);
|
||||
|
||||
func_8012C28C(globalCtx->state.gfxCtx);
|
||||
func_8012C28C(play->state.gfxCtx);
|
||||
|
||||
gSPSegment(POLY_OPA_DISP++, 0x08, D_80C106B0[this->unk_2AC]);
|
||||
|
||||
SkelAnime_DrawTransformFlexOpa(globalCtx, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, func_80C10558, NULL, func_80C10590, &this->actor);
|
||||
SkelAnime_DrawTransformFlexOpa(play, this->skelAnime.skeleton, this->skelAnime.jointTable, this->skelAnime.dListCount, func_80C10558, NULL, func_80C10590, &this->actor);
|
||||
|
||||
CLOSE_DISPS(globalCtx->state.gfxCtx);
|
||||
CLOSE_DISPS(play->state.gfxCtx);
|
||||
}
|
||||
```
|
||||
|
||||
@@ -117,20 +117,20 @@ And this matches.
|
||||
|
||||
The last two functions in the actor are used as arguments in `SkelAnime_DrawTransformFlexOpa`. This is a `SkelAnime` function, except unlike the OoT ones, it has three function callback arguments instead of two: in `functions.h` or `z_skelanime.c`, we find
|
||||
```C
|
||||
void SkelAnime_DrawTransformFlexOpa(GlobalContext* globalCtx, void** skeleton, Vec3s* jointTable, s32 dListCount,
|
||||
void SkelAnime_DrawTransformFlexOpa(PlayState* play, void** skeleton, Vec3s* jointTable, s32 dListCount,
|
||||
OverrideLimbDrawOpa overrideLimbDraw, PostLimbDrawOpa postLimbDraw, TransformLimbDrawOpa transformLimbDraw, Actor* actor)
|
||||
```
|
||||
The typedefs of the callbacks it uses are in `z64animation.h`:
|
||||
```C
|
||||
typedef s32 (*OverrideLimbDrawOpa)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot,
|
||||
typedef s32 (*OverrideLimbDrawOpa)(struct PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot,
|
||||
struct Actor* thisx);
|
||||
|
||||
typedef void (*PostLimbDrawOpa)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot,
|
||||
typedef void (*PostLimbDrawOpa)(struct PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
|
||||
struct Actor* thisx);
|
||||
|
||||
[...]
|
||||
|
||||
typedef void (*TransformLimbDrawOpa)(struct GlobalContext* globalCtx, s32 limbIndex, struct Actor* thisx);
|
||||
typedef void (*TransformLimbDrawOpa)(struct PlayState* play, s32 limbIndex, struct Actor* thisx);
|
||||
```
|
||||
which is where mips2c got them from.
|
||||
|
||||
@@ -140,7 +140,7 @@ In this case, only two of them are used, and it is these that are the last funct
|
||||
|
||||
Well, we don't have a PostLimbDraw here, but as we see from the prototype, it's much the same as the OverrideLimbDraw but without the `pos` argument and no return value.
|
||||
```C
|
||||
s32 func_80C10558(GlobalContext *globalCtx, s32 limbIndex, Gfx **dList, Vec3f *pos, Vec3s *rot, Actor *actor) {
|
||||
s32 func_80C10558(PlayState* play, s32 limbIndex, Gfx **dList, Vec3f *pos, Vec3s *rot, Actor *actor) {
|
||||
if (limbIndex == 5) {
|
||||
rot->x += actor->unk2B0;
|
||||
}
|
||||
@@ -149,7 +149,7 @@ s32 func_80C10558(GlobalContext *globalCtx, s32 limbIndex, Gfx **dList, Vec3f *p
|
||||
```
|
||||
Only two things to do here: we need to use `EnRecepgirl` to get to `actor + 0x2B0`, and the return value is used as a boolean, so we replace `0` by `false` (`true` means "don't draw the limb", and is hardly ever used).
|
||||
```C
|
||||
s32 func_80C10558(GlobalContext *globalCtx, s32 limbIndex, Gfx **dList, Vec3f *pos, Vec3s *rot, Actor *thisx) {
|
||||
s32 func_80C10558(PlayState* play, s32 limbIndex, Gfx **dList, Vec3f *pos, Vec3s *rot, Actor *thisx) {
|
||||
EnRecepgirl* this = THIS;
|
||||
|
||||
if (limbIndex == 5) {
|
||||
@@ -161,7 +161,7 @@ s32 func_80C10558(GlobalContext *globalCtx, s32 limbIndex, Gfx **dList, Vec3f *p
|
||||
|
||||
As for the TransformLimbDraw, it has a much simpler prototype. mips2c gives
|
||||
```C
|
||||
void func_80C10590(GlobalContext *globalCtx, s32 limbIndex, Actor *actor) {
|
||||
void func_80C10590(PlayState* play, s32 limbIndex, Actor *actor) {
|
||||
if (limbIndex == 5) {
|
||||
Matrix_RotateYS((s16) (0x400 - actor->unk2AE), 1);
|
||||
Matrix_MultVecX(500.0f, (Vec3f *) &actor->focus);
|
||||
@@ -173,7 +173,7 @@ There is only minor cleanup needed here:
|
||||
- replacing the last argument of `Matrix_RotateYS` by the enum `MTXMODE_APPLY` (which means "use the current matrix instead of starting from a new identity matrix"), and the first argument by `0x400 - this->unk_2AE.x`.
|
||||
- `(Vec3f *) &actor->focus` to `&actor->focus.pos` (this is the same issue as `(Actor*)this`, where mips2c doesn't climb deep enough into the struct).
|
||||
```C
|
||||
void func_80C10590(GlobalContext *globalCtx, s32 limbIndex, Actor *thisx) {
|
||||
void func_80C10590(PlayState* play, s32 limbIndex, Actor *thisx) {
|
||||
EnRecepgirl* this = THIS;
|
||||
|
||||
if (limbIndex == 5) {
|
||||
@@ -187,7 +187,7 @@ void func_80C10590(GlobalContext *globalCtx, s32 limbIndex, Actor *thisx) {
|
||||
|
||||
Since EnRecepgirl was a bit light on graphics macros, we will look at an example that has a few more. A nice simple one is `ObjTree_Draw`: the original mips2c output is
|
||||
```C
|
||||
void ObjTree_Draw(Actor *thisx, GlobalContext *globalCtx) {
|
||||
void ObjTree_Draw(Actor* thisx, PlayState* play) {
|
||||
s16 sp36;
|
||||
s16 sp34;
|
||||
Gfx *sp28;
|
||||
@@ -201,14 +201,14 @@ void ObjTree_Draw(Actor *thisx, GlobalContext *globalCtx) {
|
||||
|
||||
sp36 = (s16) (s32) (f32) thisx->shape.rot.x;
|
||||
sp34 = (s16) (s32) (f32) thisx->shape.rot.z;
|
||||
temp_a0 = globalCtx->state.gfxCtx;
|
||||
temp_a0 = play->state.gfxCtx;
|
||||
temp_s0 = temp_a0;
|
||||
func_8012C28C(temp_a0);
|
||||
temp_v0 = temp_s0->polyOpa.p;
|
||||
temp_s0->polyOpa.p = temp_v0 + 8;
|
||||
temp_v0->words.w0 = 0xDA380003;
|
||||
sp28 = temp_v0;
|
||||
sp28->words.w1 = Matrix_NewMtx(globalCtx->state.gfxCtx);
|
||||
sp28->words.w1 = Matrix_NewMtx(play->state.gfxCtx);
|
||||
temp_v0_2 = temp_s0->polyOpa.p;
|
||||
temp_s0->polyOpa.p = temp_v0_2 + 8;
|
||||
temp_v0_2->words.w1 = (u32) &D_06000680;
|
||||
@@ -218,7 +218,7 @@ void ObjTree_Draw(Actor *thisx, GlobalContext *globalCtx) {
|
||||
temp_s0->polyOpa.p = temp_v0_3 + 8;
|
||||
temp_v0_3->words.w0 = 0xDA380003;
|
||||
sp20 = temp_v0_3;
|
||||
sp20->words.w1 = Matrix_NewMtx(globalCtx->state.gfxCtx);
|
||||
sp20->words.w1 = Matrix_NewMtx(play->state.gfxCtx);
|
||||
temp_v0_4 = temp_s0->polyOpa.p;
|
||||
temp_s0->polyOpa.p = temp_v0_4 + 8;
|
||||
temp_v0_4->words.w1 = (u32) &D_060007C8;
|
||||
@@ -231,7 +231,7 @@ We can see there are four blocks here, although only two different macros:
|
||||
temp_s0->polyOpa.p = temp_v0 + 8;
|
||||
temp_v0->words.w0 = 0xDA380003;
|
||||
sp28 = temp_v0;
|
||||
sp28->words.w1 = Matrix_NewMtx(globalCtx->state.gfxCtx);
|
||||
sp28->words.w1 = Matrix_NewMtx(play->state.gfxCtx);
|
||||
```
|
||||
gfxdis gives
|
||||
```
|
||||
@@ -240,7 +240,7 @@ gSPMatrix(POLY_OPA_DISP++, 0x12345678, G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVI
|
||||
```
|
||||
so it becomes
|
||||
```C
|
||||
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
```
|
||||
|
||||
```C
|
||||
@@ -263,7 +263,7 @@ gSPDisplayList(POLY_OPA_DISP++, D_06000680);
|
||||
temp_s0->polyOpa.p = temp_v0_3 + 8;
|
||||
temp_v0_3->words.w0 = 0xDA380003;
|
||||
sp20 = temp_v0_3;
|
||||
sp20->words.w1 = Matrix_NewMtx(globalCtx->state.gfxCtx);
|
||||
sp20->words.w1 = Matrix_NewMtx(play->state.gfxCtx);
|
||||
```
|
||||
This is the same as the first one. Indeed, it's identical.
|
||||
```C
|
||||
@@ -276,21 +276,21 @@ This is the same as the second one, but with a different second word.
|
||||
|
||||
Tidying up and inserting `OPEN_DISPS` and `CLOSE_DISPS`, we end up with
|
||||
```C
|
||||
void ObjTree_Draw(Actor* thisx, GlobalContext* globalCtx) {
|
||||
void ObjTree_Draw(Actor* thisx, PlayState* play) {
|
||||
s16 sp36 = (f32) thisx->shape.rot.x;
|
||||
s16 sp34 = (f32) thisx->shape.rot.z;
|
||||
|
||||
OPEN_DISPS(globalCtx->state.gfxCtx);
|
||||
OPEN_DISPS(play->state.gfxCtx);
|
||||
|
||||
func_8012C28C(globalCtx->state.gfxCtx);
|
||||
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
func_8012C28C(play->state.gfxCtx);
|
||||
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(POLY_OPA_DISP++, D_06000680);
|
||||
|
||||
Matrix_RotateZYX(sp36, 0, sp34, MTXMODE_APPLY);
|
||||
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(globalCtx->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPMatrix(POLY_OPA_DISP++, Matrix_NewMtx(play->state.gfxCtx), G_MTX_NOPUSH | G_MTX_LOAD | G_MTX_MODELVIEW);
|
||||
gSPDisplayList(POLY_OPA_DISP++, D_060007C8);
|
||||
|
||||
CLOSE_DISPS(globalCtx->state.gfxCtx);
|
||||
CLOSE_DISPS(play->state.gfxCtx);
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@@ -40,13 +40,13 @@ glabel func_809529AC
|
||||
and turn it into compilable C code:
|
||||
|
||||
```C
|
||||
void func_809529AC(EnMs *this, GlobalContext *globalCtx) {
|
||||
if (Actor_HasParent(&this->actor, globalCtx)) {
|
||||
void func_809529AC(EnMs* this, PlayState* play) {
|
||||
if (Actor_HasParent(&this->actor, play)) {
|
||||
this->actor.textId = 0;
|
||||
func_800B8500(&this->actor, globalCtx, this->actor.xzDistToPlayer, this->actor.playerHeightRel, 0);
|
||||
func_800B8500(&this->actor, play, this->actor.xzDistToPlayer, this->actor.playerHeightRel, 0);
|
||||
this->actionFunc = func_80952A1C;
|
||||
} else {
|
||||
Actor_PickUp(&this->actor, globalCtx, 0x35, this->actor.xzDistToPlayer, this->actor.playerHeightRel);
|
||||
Actor_PickUp(&this->actor, play, 0x35, this->actor.xzDistToPlayer, this->actor.playerHeightRel);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@@ -61,7 +61,7 @@ Now, we can redefine the `jointTable` and `morphTable` in terms of the limb enum
|
||||
|
||||
We can also use our new skeleton name and limb enum when initialization the skeleton like so:
|
||||
```c
|
||||
SkelAnime_Init(globalCtx, &this->skelAnime, &gKingsChamberDekuGuardSkel, NULL, this->jointTable, this->morphTable, KINGS_CHAMBER_DEKU_GUARD_LIMB_MAX);
|
||||
SkelAnime_Init(play, &this->skelAnime, &gKingsChamberDekuGuardSkel, NULL, this->jointTable, this->morphTable, KINGS_CHAMBER_DEKU_GUARD_LIMB_MAX);
|
||||
```
|
||||
|
||||
Lastly, we can use our limb enum in `EnDns_PostLimbDraw`. Where the code originally had:
|
||||
|
||||
@@ -26,7 +26,7 @@ void EnRecepgirl_Destroy(s32 arg0, ? arg1) {
|
||||
```
|
||||
so it really does do nothing. It is worth staying on this briefly to understand what is is doing, though. Even with no context, mips2c knows it takes two arguments because it does two saves onto the stack: the calling convention the N64 uses requires the first four arguments be saved from the registers onto the stack, since the registers are expected to be cleared when a function call happens. It's done a bad job of guessing what they are, but that's to be expected: the assembly only tells us they're words. Thankfully we already know in this case, so we can just replace the `GLOBAL_ASM` by
|
||||
```C
|
||||
void EnRecepgirl_Destroy(Actor* thisx, GlobalContext* globalCtx) {
|
||||
void EnRecepgirl_Destroy(Actor* thisx, PlayState* play) {
|
||||
|
||||
}
|
||||
```
|
||||
@@ -54,11 +54,11 @@ void func_80C10148(EnRecepgirl *this) {
|
||||
|
||||
This gives us some information immediately: `D_0600AD98` is an `AnimationHeader`, and `func_80C1019C` is set as the action function. This means that we know its type, even though mips2c does not: looking in the header, we see the typedef is
|
||||
```C
|
||||
typedef void (*EnRecepgirlActionFunc)(struct EnRecepgirl*, GlobalContext*);
|
||||
typedef void (*EnRecepgirlActionFunc)(struct EnRecepgirl*, PlayState*);
|
||||
```
|
||||
and so we prototype `func_80C1019C` as
|
||||
```C
|
||||
void func_80C1019C(EnRecepgirl* this, GlobalContext* globalCtx);
|
||||
void func_80C1019C(EnRecepgirl* this, PlayState* play);
|
||||
```
|
||||
at the top (were it above the function we're currently working on, the prototype could eventually be replaced by the function definition itself, but since it isn't, it goes at the top with the others).
|
||||
|
||||
@@ -73,7 +73,7 @@ If we tackle these, we end up with
|
||||
```C
|
||||
|
||||
void func_80C10148(EnRecepgirl* this);
|
||||
void func_80C1019C(EnRecepgirl* this, GlobalContext* globalCtx);
|
||||
void func_80C1019C(EnRecepgirl* this, PlayState* play);
|
||||
|
||||
[...]
|
||||
|
||||
@@ -103,7 +103,7 @@ Remake the context and run mips2c on this function's assembly file. We get
|
||||
```C
|
||||
? func_80C10290(EnRecepgirl *); // extern
|
||||
|
||||
void func_80C1019C(EnRecepgirl *this, GlobalContext *globalCtx) {
|
||||
void func_80C1019C(EnRecepgirl* this, PlayState* play) {
|
||||
SkelAnime *sp24;
|
||||
SkelAnime *temp_a0;
|
||||
|
||||
@@ -116,17 +116,17 @@ void func_80C1019C(EnRecepgirl *this, GlobalContext *globalCtx) {
|
||||
Animation_ChangeTransitionRepeat(temp_a0, &D_06009890, -4.0f);
|
||||
}
|
||||
}
|
||||
if (Actor_ProcessTalkRequest((Actor *) this, globalCtx) != 0) {
|
||||
if (Actor_ProcessTalkRequest((Actor *) this, play) != 0) {
|
||||
func_80C10290(this);
|
||||
return;
|
||||
}
|
||||
if (Actor_IsFacingPlayer((Actor *) this, 0x2000) != 0) {
|
||||
func_800B8614((Actor *) this, globalCtx, 60.0f);
|
||||
if (Player_GetMask(globalCtx) == 2) {
|
||||
func_800B8614((Actor *) this, play, 60.0f);
|
||||
if (Player_GetMask(play) == 2) {
|
||||
this->actor.textId = 0x2367;
|
||||
return;
|
||||
}
|
||||
if (Flags_GetSwitch(globalCtx, (s32) this->actor.params) != 0) {
|
||||
if (Flags_GetSwitch(play, (s32) this->actor.params) != 0) {
|
||||
this->actor.textId = 0x2ADC;
|
||||
return;
|
||||
}
|
||||
@@ -147,7 +147,7 @@ This is a bit juicier! We can do some preliminary cleanup, then worry about the
|
||||
Changing all these, we end up with
|
||||
```C
|
||||
void func_80C10148(EnRecepgirl* this);
|
||||
void func_80C1019C(EnRecepgirl* this, GlobalContext* globalCtx);
|
||||
void func_80C1019C(EnRecepgirl* this, PlayState* play);
|
||||
void func_80C10290(EnRecepgirl* this);
|
||||
|
||||
[...]
|
||||
@@ -160,7 +160,7 @@ extern FlexSkeletonHeader D_06011B60;
|
||||
|
||||
[...]
|
||||
|
||||
void func_80C1019C(EnRecepgirl *this, GlobalContext *globalCtx) {
|
||||
void func_80C1019C(EnRecepgirl* this, PlayState* play) {
|
||||
if (SkelAnime_Update(&this->skelAnime) != 0) {
|
||||
if (&D_0600A280 == this->skelAnime.animation) {
|
||||
Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 5.0f);
|
||||
@@ -168,17 +168,17 @@ void func_80C1019C(EnRecepgirl *this, GlobalContext *globalCtx) {
|
||||
Animation_ChangeTransitionRepeat(&this->skelAnime, &D_06009890, -4.0f);
|
||||
}
|
||||
}
|
||||
if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state) != 0) {
|
||||
if (Actor_ProcessTalkRequest(&this->actor, &play->state) != 0) {
|
||||
func_80C10290(this);
|
||||
return;
|
||||
}
|
||||
if (Actor_IsFacingPlayer(&this->actor, 0x2000) != 0) {
|
||||
func_800B8614(&this->actor, globalCtx, 60.0f);
|
||||
if (Player_GetMask(globalCtx) == 2) {
|
||||
func_800B8614(&this->actor, play, 60.0f);
|
||||
if (Player_GetMask(play) == 2) {
|
||||
this->actor.textId = 0x2367;
|
||||
return;
|
||||
}
|
||||
if (Flags_GetSwitch(globalCtx, this->actor.params)) {
|
||||
if (Flags_GetSwitch(play, this->actor.params)) {
|
||||
this->actor.textId = 0x2ADC;
|
||||
return;
|
||||
}
|
||||
@@ -194,7 +194,7 @@ If we look with diff.py, we find this matches. But we can replace some of the `r
|
||||
|
||||
Here, it's debatable whether to keep the first, since `func_80C10290` is likely a setup function. The latter two should be changed to elses, though. For now, let's replace all of them. This leaves us with
|
||||
```C
|
||||
void func_80C1019C(EnRecepgirl* this, GlobalContext* globalCtx) {
|
||||
void func_80C1019C(EnRecepgirl* this, PlayState* play) {
|
||||
if (SkelAnime_Update(&this->skelAnime) != 0) {
|
||||
if (this->skelAnime.animation == &D_0600A280) {
|
||||
Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 5.0f);
|
||||
@@ -203,13 +203,13 @@ void func_80C1019C(EnRecepgirl* this, GlobalContext* globalCtx) {
|
||||
}
|
||||
}
|
||||
|
||||
if (Actor_ProcessTalkRequest(&this->actor, &globalCtx->state) != 0) {
|
||||
if (Actor_ProcessTalkRequest(&this->actor, &play->state) != 0) {
|
||||
func_80C10290(this);
|
||||
} else if (Actor_IsFacingPlayer(&this->actor, 0x2000)) {
|
||||
func_800B8614(&this->actor, globalCtx, 60.0f);
|
||||
if (Player_GetMask(globalCtx) == 2) {
|
||||
func_800B8614(&this->actor, play, 60.0f);
|
||||
if (Player_GetMask(play) == 2) {
|
||||
this->actor.textId = 0x2367;
|
||||
} else if (Flags_GetSwitch(globalCtx, this->actor.params)) {
|
||||
} else if (Flags_GetSwitch(play, this->actor.params)) {
|
||||
this->actor.textId = 0x2ADC;
|
||||
} else {
|
||||
this->actor.textId = 0x2AD9;
|
||||
@@ -227,7 +227,7 @@ typedef enum {
|
||||
/* 0x19 */ PLAYER_MASK_MAX
|
||||
} PlayerMask;
|
||||
```
|
||||
and so we can write the last if as `Player_GetMask(globalCtx) == PLAYER_MASK_KAFEIS_MASK`.
|
||||
and so we can write the last if as `Player_GetMask(play) == PLAYER_MASK_KAFEIS_MASK`.
|
||||
|
||||
Again, we have no choice in what to do next.
|
||||
|
||||
@@ -236,7 +236,7 @@ Again, we have no choice in what to do next.
|
||||
|
||||
Remaking the context and running mips2c gives
|
||||
```C
|
||||
void func_80C102D4(EnRecepgirl *, GlobalContext *); // extern
|
||||
void func_80C102D4(EnRecepgirl*, PlayState*); // extern
|
||||
|
||||
void func_80C10290(EnRecepgirl *this) {
|
||||
Animation_MorphToPlayOnce(&this->skelAnime, &D_0600A280, -4.0f);
|
||||
@@ -256,7 +256,7 @@ Large code block, click to show
|
||||
```C
|
||||
extern AnimationHeader D_06000968;
|
||||
|
||||
void func_80C102D4(EnRecepgirl *this, GlobalContext *globalCtx) {
|
||||
void func_80C102D4(EnRecepgirl* this, PlayState* play) {
|
||||
SkelAnime *sp20;
|
||||
AnimationHeader *temp_v0;
|
||||
SkelAnime *temp_a0;
|
||||
@@ -282,16 +282,16 @@ void func_80C102D4(EnRecepgirl *this, GlobalContext *globalCtx) {
|
||||
Animation_MorphToPlayOnce(sp20, &D_0600A280, -4.0f);
|
||||
}
|
||||
}
|
||||
temp_v0_2 = Message_GetState(&globalCtx->msgCtx);
|
||||
temp_v0_2 = Message_GetState(&play->msgCtx);
|
||||
if (temp_v0_2 == 2) {
|
||||
this->actor.textId = 0x2ADC;
|
||||
func_80C10148(this);
|
||||
return;
|
||||
}
|
||||
if (((temp_v0_2 & 0xFF) == 5) && (Message_ShouldAdvance(globalCtx) != 0)) {
|
||||
if (((temp_v0_2 & 0xFF) == 5) && (Message_ShouldAdvance(play) != 0)) {
|
||||
temp_v0_3 = this->actor.textId;
|
||||
if (temp_v0_3 == 0x2AD9) {
|
||||
Flags_SetSwitch(globalCtx, (s32) this->actor.params);
|
||||
Flags_SetSwitch(play, (s32) this->actor.params);
|
||||
Animation_MorphToPlayOnce(sp20, &D_0600AD98, 10.0f);
|
||||
if ((*(&gSaveContext + 0xF37) & 0x80) != 0) {
|
||||
this->actor.textId = 0x2ADF;
|
||||
@@ -312,7 +312,7 @@ void func_80C102D4(EnRecepgirl *this, GlobalContext *globalCtx) {
|
||||
this->actor.textId = 0x2AE0;
|
||||
}
|
||||
}
|
||||
func_80151938(globalCtx, this->actor.textId);
|
||||
func_80151938(play, this->actor.textId);
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -321,7 +321,7 @@ void func_80C102D4(EnRecepgirl *this, GlobalContext *globalCtx) {
|
||||
|
||||
Well, this is a big one! We get one more extern, for `D_06000968`. A lot of the temps used in the conditionals look fake, with the exception of `temp_v0_2`: because the function is only called once but the temp is used twice, the temp must be real. Removing the others and switching the `animation` conditionals,
|
||||
```C
|
||||
void func_80C102D4(EnRecepgirl *this, GlobalContext *globalCtx) {
|
||||
void func_80C102D4(EnRecepgirl* this, PlayState* play) {
|
||||
u8 temp_v0_2;
|
||||
|
||||
if (SkelAnime_Update(&this->skelAnime) != 0) {
|
||||
@@ -340,16 +340,16 @@ void func_80C102D4(EnRecepgirl *this, GlobalContext *globalCtx) {
|
||||
}
|
||||
}
|
||||
|
||||
temp_v0_2 = Message_GetState(&globalCtx->msgCtx);
|
||||
temp_v0_2 = Message_GetState(&play->msgCtx);
|
||||
if (temp_v0_2 == 2) {
|
||||
this->actor.textId = 0x2ADC;
|
||||
func_80C10148(this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (((temp_v0_2 & 0xFF) == 5) && (Message_ShouldAdvance(globalCtx) != 0)) {
|
||||
if (((temp_v0_2 & 0xFF) == 5) && (Message_ShouldAdvance(play) != 0)) {
|
||||
if (this->actor.textId == 0x2AD9) {
|
||||
Flags_SetSwitch(globalCtx, this->actor.params);
|
||||
Flags_SetSwitch(play, this->actor.params);
|
||||
Animation_MorphToPlayOnce(&this->skelAnime, &D_0600AD98, 10.0f);
|
||||
if ((*(&gSaveContext + 0xF37) & 0x80) != 0) {
|
||||
this->actor.textId = 0x2ADF;
|
||||
@@ -369,7 +369,7 @@ void func_80C102D4(EnRecepgirl *this, GlobalContext *globalCtx) {
|
||||
this->actor.textId = 0x2AE0;
|
||||
}
|
||||
}
|
||||
func_80151938(globalCtx, this->actor.textId);
|
||||
func_80151938(play, this->actor.textId);
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -390,14 +390,14 @@ The yellow shows registers that don't match, the different colours on the regist
|
||||
```
|
||||
somehow we skipped over `t0`. Where is this in the code? The `153` in the middle is the line number in the C file (the `3f0`s are the offsets into the assembly file), we have `--source` if you want to see the code explicitly, or you can do it the old-fashioned way, and work it out from nearby function calls. In this case, `func_80C10148` is run straight after, and the only place that is called is
|
||||
```C
|
||||
temp_v0_2 = Message_GetState(&globalCtx->msgCtx);
|
||||
temp_v0_2 = Message_GetState(&play->msgCtx);
|
||||
if (temp_v0_2 == 2) {
|
||||
this->actor.textId = 0x2ADC;
|
||||
func_80C10148(this);
|
||||
return;
|
||||
}
|
||||
|
||||
if (((temp_v0_2 & 0xFF) == 5) && (Message_ShouldAdvance(globalCtx) != 0)) {
|
||||
if (((temp_v0_2 & 0xFF) == 5) && (Message_ShouldAdvance(play) != 0)) {
|
||||
```
|
||||
|
||||
If you look at the conditionals and the declaration of `temp_v0_2`, you may notice something odd: `temp_v0_2` is a `u8`. Therefore the `& 0xFF` does nothing! It's surprisingly common for this to happen, be it leaving out a `& 0xFF` or adding an extraneous one. If we remove it, we get a match:
|
||||
@@ -417,12 +417,12 @@ Remake the context and run mips2c:
|
||||
```C
|
||||
? func_80C100DC(EnRecepgirl *); // extern
|
||||
|
||||
void EnRecepgirl_Update(Actor *thisx, GlobalContext *globalCtx) {
|
||||
void EnRecepgirl_Update(Actor* thisx, PlayState* play) {
|
||||
EnRecepgirl* this = (EnRecepgirl *) thisx;
|
||||
? sp30;
|
||||
|
||||
this->actionFunc(this, globalCtx);
|
||||
Actor_TrackPlayer(globalCtx, (Actor *) this, this + 0x2AE, (Vec3s *) &sp30, (bitwise Vec3f) this->actor.focus.pos.x, this->actor.focus.pos.y, this->actor.focus.pos.z);
|
||||
this->actionFunc(this, play);
|
||||
Actor_TrackPlayer(play, (Actor *) this, this + 0x2AE, (Vec3s *) &sp30, (bitwise Vec3f) this->actor.focus.pos.x, this->actor.focus.pos.y, this->actor.focus.pos.z);
|
||||
func_80C100DC(this);
|
||||
}
|
||||
```
|
||||
@@ -435,18 +435,18 @@ void func_80C100DC(EnRecepgirl *);
|
||||
|
||||
[...]
|
||||
|
||||
void EnRecepgirl_Update(Actor *thisx, GlobalContext *globalCtx) {
|
||||
void EnRecepgirl_Update(Actor* thisx, PlayState* play) {
|
||||
EnRecepgirl* this = THIS;
|
||||
? sp30;
|
||||
|
||||
this->actionFunc(this, globalCtx);
|
||||
Actor_TrackPlayer(globalCtx, &this->actor, this + 0x2AE, (Vec3s *) &sp30, (bitwise Vec3f) this->actor.focus.pos.x, this->actor.focus.pos.y, this->actor.focus.pos.z);
|
||||
this->actionFunc(this, play);
|
||||
Actor_TrackPlayer(play, &this->actor, this + 0x2AE, (Vec3s *) &sp30, (bitwise Vec3f) this->actor.focus.pos.x, this->actor.focus.pos.y, this->actor.focus.pos.z);
|
||||
func_80C100DC(this);
|
||||
}
|
||||
```
|
||||
Now, our problem is `Actor_TrackPlayer`. The arguments all look terrible! Indeed, if we look at the actual function in `src/code/code_800E8EA0.c` (found by searching), we find that it should be
|
||||
```C
|
||||
s32 Actor_TrackPlayer(GlobalContext* globalCtx, Actor* actor, Vec3s* headRot, Vec3s* torsoRot, Vec3f focusPos)
|
||||
s32 Actor_TrackPlayer(PlayState* play, Actor* actor, Vec3s* headRot, Vec3s* torsoRot, Vec3f focusPos)
|
||||
```
|
||||
So mips2c has made a bit of a mess here:
|
||||
- the third argument should be a `Vec3s`. Hence `this + 0x2AE` is a `Vec3s*`, and so `this->unk_2AE` is a `Vec3s`
|
||||
@@ -455,12 +455,12 @@ So mips2c has made a bit of a mess here:
|
||||
|
||||
Fixing all of this, we end up with
|
||||
```C
|
||||
void EnRecepgirl_Update(EnRecepgirl *this, GlobalContext *globalCtx) {
|
||||
void EnRecepgirl_Update(EnRecepgirl* this, PlayState* play) {
|
||||
EnRecepgirl* this = THIS;
|
||||
Vec3s sp30;
|
||||
|
||||
this->actionFunc(this, globalCtx);
|
||||
Actor_TrackPlayer(globalCtx, &this->actor, &this->unk_2AE, &sp30, this->actor.focus.pos);
|
||||
this->actionFunc(this, play);
|
||||
Actor_TrackPlayer(play, &this->actor, &this->unk_2AE, &sp30, this->actor.focus.pos);
|
||||
func_80C100DC(this);
|
||||
}
|
||||
```
|
||||
@@ -482,21 +482,21 @@ It's entirely possible that `unk_2AD` is not real, and is just padding: see [Typ
|
||||
|
||||

|
||||
|
||||
So `sp30` is in the wrong place: it's `4` too high on the stack in ours. This is because the main four functions do not actually take `GlobalContext`: they really take `Gamestate` and recast it with a temp, just like `EnRecepgirl* this = THIS;`. We haven't implemented this in the repo yet, though, so for now, it suffices to put a pad on the stack where it would go instead: experience has shown when it matters, it goes above the actor recast, so we end up with
|
||||
So `sp30` is in the wrong place: it's `4` too high on the stack in ours. This is because the main four functions do not actually take `PlayState`: they really take `Gamestate` and recast it with a temp, just like `EnRecepgirl* this = THIS;`. We haven't implemented this in the repo yet, though, so for now, it suffices to put a pad on the stack where it would go instead: experience has shown when it matters, it goes above the actor recast, so we end up with
|
||||
```C
|
||||
void EnRecepgirl_Update(Actor *thisx, GlobalContext *globalCtx) {
|
||||
void EnRecepgirl_Update(Actor* thisx, PlayState* play) {
|
||||
s32 pad;
|
||||
EnRecepgirl* this = THIS;
|
||||
Vec3s sp30;
|
||||
|
||||
this->actionFunc(this, globalCtx);
|
||||
Actor_TrackPlayer(globalCtx, &this->actor, &this->unk_2AE, &sp30, this->actor.focus.pos);
|
||||
this->actionFunc(this, play);
|
||||
Actor_TrackPlayer(play, &this->actor, &this->unk_2AE, &sp30, this->actor.focus.pos);
|
||||
func_80C100DC(this);
|
||||
}
|
||||
```
|
||||
and this now matches.
|
||||
|
||||
**N.B.** sometimes using an actual `GlobalContext* globalCtx` temp is required for matching: add it to your bag o' matching memes.
|
||||
**N.B.** sometimes using an actual `PlayState* play` temp is required for matching: add it to your bag o' matching memes.
|
||||
|
||||
### *Some remarks about the function stack
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ Useful data for guessing types:
|
||||
|
||||
Another useful thing to put here: the typedef for an action function is
|
||||
```C
|
||||
typedef void (*ActorNameActionFunc)(struct ActorName*, GlobalContext*);
|
||||
typedef void (*ActorNameActionFunc)(struct ActorName*, PlayState*);
|
||||
```
|
||||
where you replace `ActorName` by the actual actor name as used elsewhere in the actor, e.g. `EnRecepgirl`. In MM these typedefs have been automatically generated, so you don't need to constantly copy from here or another actor any more.
|
||||
|
||||
|
||||
+788
-788
File diff suppressed because it is too large
Load Diff
+3
-3
@@ -20,7 +20,7 @@
|
||||
#define VIRTUAL_TO_PHYSICAL(addr) (uintptr_t)((u8*)(addr) - RDRAM_CACHED)
|
||||
#define SEGMENTED_TO_VIRTUAL(addr) (void*)(PHYSICAL_TO_VIRTUAL(gSegments[SEGMENT_NUMBER(addr)]) + SEGMENT_OFFSET(addr))
|
||||
|
||||
#define GET_ACTIVE_CAM(globalCtx) ((globalCtx)->cameraPtrs[(globalCtx)->activeCamera])
|
||||
#define GET_ACTIVE_CAM(play) ((play)->cameraPtrs[(play)->activeCamera])
|
||||
#define CAM_ID_MAIN 0
|
||||
|
||||
#define SET_NEXT_GAMESTATE(curState, newInit, newStruct) \
|
||||
@@ -38,9 +38,9 @@
|
||||
} \
|
||||
(void)0
|
||||
|
||||
#define GET_PLAYER(globalCtx) ((Player*)(globalCtx)->actorCtx.actorLists[ACTORCAT_PLAYER].first)
|
||||
#define GET_PLAYER(play) ((Player*)(play)->actorCtx.actorLists[ACTORCAT_PLAYER].first)
|
||||
|
||||
#define GET_FIRST_ENEMY(globalCtx) ((Actor*)(globalCtx)->actorCtx.actorLists[ACTORCAT_ENEMY].first)
|
||||
#define GET_FIRST_ENEMY(play) ((Actor*)(play)->actorCtx.actorLists[ACTORCAT_ENEMY].first)
|
||||
|
||||
// linkAge still exists in MM, but is always set to 0 (always adult)
|
||||
// There are remnants of these macros from OOT, but they are essentially useless
|
||||
|
||||
+3
-3
@@ -882,7 +882,7 @@ extern s16 actorCutsceneEnding;
|
||||
extern s16 actorCutsceneCurrentCamera;
|
||||
extern Actor* actorCutsceneCurrentCutsceneActor;
|
||||
// extern UNK_TYPE4 actorCutsceneStartMethod;
|
||||
extern GlobalContext* actorCutscenesGlobalCtxt;
|
||||
extern PlayState* actorCutscenesPlayState;
|
||||
extern s16 actorCutsceneReturnCamera;
|
||||
extern s16 D_801BD8C6;
|
||||
extern GameStateOverlay gGameStateOverlayTable[];
|
||||
@@ -3243,8 +3243,8 @@ extern ShrinkWindowContext gShrinkWindowContext;
|
||||
extern ShrinkWindowContext* gShrinkWindowContextPtr;
|
||||
// extern UNK_TYPE4 D_801F6B50;
|
||||
// extern UNK_TYPE1 D_801F6B58;
|
||||
extern void (*sKaleidoScopeUpdateFunc)(GlobalContext* globalCtx);
|
||||
extern void (*sKaleidoScopeDrawFunc)(GlobalContext* globalCtx);
|
||||
extern void (*sKaleidoScopeUpdateFunc)(PlayState* play);
|
||||
extern void (*sKaleidoScopeDrawFunc)(PlayState* play);
|
||||
extern FaultAddrConvClient sKaleidoAreaFaultClient;
|
||||
// extern UNK_TYPE1 D_801F6C10;
|
||||
extern Input D_801F6C18;
|
||||
|
||||
+23
-23
@@ -979,17 +979,17 @@ typedef struct {
|
||||
/* 0x10 */ OSTime resetTime;
|
||||
} PreNmiBuff; // size = 0x18 (actually osAppNmiBuffer is 0x40 bytes large but the rest is unused)
|
||||
|
||||
typedef struct GlobalContext GlobalContext;
|
||||
typedef struct PlayState PlayState;
|
||||
|
||||
typedef s32 (*ColChkResetFunc)(GlobalContext*, Collider*);
|
||||
typedef void (*ColChkBloodFunc)(GlobalContext*, Collider*, Vec3f*);
|
||||
typedef void (*ColChkApplyFunc)(GlobalContext*, CollisionCheckContext*, Collider*);
|
||||
typedef void (*ColChkVsFunc)(GlobalContext*, CollisionCheckContext*, Collider*, Collider*);
|
||||
typedef s32 (*ColChkLineFunc)(GlobalContext*, CollisionCheckContext*, Collider*, Vec3f*, Vec3f*);
|
||||
typedef s32 (*ColChkResetFunc)(PlayState*, Collider*);
|
||||
typedef void (*ColChkBloodFunc)(PlayState*, Collider*, Vec3f*);
|
||||
typedef void (*ColChkApplyFunc)(PlayState*, CollisionCheckContext*, Collider*);
|
||||
typedef void (*ColChkVsFunc)(PlayState*, CollisionCheckContext*, Collider*, Collider*);
|
||||
typedef s32 (*ColChkLineFunc)(PlayState*, CollisionCheckContext*, Collider*, Vec3f*, Vec3f*);
|
||||
|
||||
typedef void(*draw_func)(GlobalContext* globalCtx, s16 index);
|
||||
typedef void(*draw_func)(PlayState* play, s16 index);
|
||||
|
||||
typedef void(*room_draw_func)(GlobalContext* globalCtx, Room* room, u32 flags);
|
||||
typedef void(*room_draw_func)(PlayState* play, Room* room, u32 flags);
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ draw_func unk0;
|
||||
@@ -1010,7 +1010,7 @@ typedef struct Camera {
|
||||
/* 0x068 */ Vec3f up;
|
||||
/* 0x074 */ Vec3f eyeNext;
|
||||
/* 0x080 */ Vec3f skyboxOffset;
|
||||
/* 0x08C */ struct GlobalContext* globalCtx;
|
||||
/* 0x08C */ struct PlayState* play;
|
||||
/* 0x090 */ struct Player* player;
|
||||
/* 0x094 */ PosRot playerPosRot;
|
||||
/* 0x0A8 */ struct Actor* target;
|
||||
@@ -1115,7 +1115,7 @@ typedef s16 (*QuakeCallbackFunc)(QuakeRequest*, ShakeInfo*);
|
||||
#define QUAKE_IS_SHAKE_PERPENDICULAR (1 << 9)
|
||||
|
||||
typedef struct {
|
||||
/* 0x0 */ GlobalContext* globalCtx;
|
||||
/* 0x0 */ PlayState* play;
|
||||
/* 0x4 */ s32 type; // bitfield, highest set bit determines type
|
||||
/* 0x8 */ s16 countdown;
|
||||
/* 0xA */ s16 state;
|
||||
@@ -1256,7 +1256,7 @@ typedef struct {
|
||||
/* 0x00 */ u16 state;
|
||||
} GameOverContext; // size = 0x02
|
||||
|
||||
struct GlobalContext {
|
||||
struct PlayState {
|
||||
/* 0x00000 */ GameState state;
|
||||
/* 0x000A4 */ s16 sceneNum;
|
||||
/* 0x000A6 */ u8 sceneConfig;
|
||||
@@ -1288,19 +1288,19 @@ struct GlobalContext {
|
||||
/* 0x17D88 */ ObjectContext objectCtx;
|
||||
/* 0x186E0 */ RoomContext roomCtx;
|
||||
/* 0x18760 */ DoorContext doorCtx;
|
||||
/* 0x18768 */ void (*playerInit)(Player* player, struct GlobalContext* globalCtx, FlexSkeletonHeader* skelHeader);
|
||||
/* 0x1876C */ void (*playerUpdate)(Player* player, struct GlobalContext* globalCtx, Input* input);
|
||||
/* 0x18770 */ void (*unk_18770)(struct GlobalContext* globalCtx, Player* player);
|
||||
/* 0x18774 */ s32 (*startPlayerFishing)(struct GlobalContext* globalCtx);
|
||||
/* 0x18778 */ s32 (*grabPlayer)(struct GlobalContext* globalCtx, Player* player);
|
||||
/* 0x1877C */ s32 (*startPlayerCutscene)(struct GlobalContext* globalCtx, Player* player, s32 mode);
|
||||
/* 0x18780 */ void (*func_18780)(Player* player, struct GlobalContext* globalCtx);
|
||||
/* 0x18784 */ s32 (*damagePlayer)(struct GlobalContext* globalCtx, s32 damage);
|
||||
/* 0x18788 */ void (*talkWithPlayer)(struct GlobalContext* globalCtx, Actor* actor);
|
||||
/* 0x1878C */ void (*unk_1878C)(struct GlobalContext* globalCtx);
|
||||
/* 0x18790 */ void (*unk_18790)(struct GlobalContext* globalCtx, s16 arg1, Actor* actor);
|
||||
/* 0x18768 */ void (*playerInit)(Player* player, struct PlayState* play, FlexSkeletonHeader* skelHeader);
|
||||
/* 0x1876C */ void (*playerUpdate)(Player* player, struct PlayState* play, Input* input);
|
||||
/* 0x18770 */ void (*unk_18770)(struct PlayState* play, Player* player);
|
||||
/* 0x18774 */ s32 (*startPlayerFishing)(struct PlayState* play);
|
||||
/* 0x18778 */ s32 (*grabPlayer)(struct PlayState* play, Player* player);
|
||||
/* 0x1877C */ s32 (*startPlayerCutscene)(struct PlayState* play, Player* player, s32 mode);
|
||||
/* 0x18780 */ void (*func_18780)(Player* player, struct PlayState* play);
|
||||
/* 0x18784 */ s32 (*damagePlayer)(struct PlayState* play, s32 damage);
|
||||
/* 0x18788 */ void (*talkWithPlayer)(struct PlayState* play, Actor* actor);
|
||||
/* 0x1878C */ void (*unk_1878C)(struct PlayState* play);
|
||||
/* 0x18790 */ void (*unk_18790)(struct PlayState* play, s16 arg1, Actor* actor);
|
||||
/* 0x18794 */ void* unk_18794; //! @TODO: Determine function prototype
|
||||
/* 0x18798 */ s32 (*setPlayerTalkAnim)(struct GlobalContext* globalCtx, void* talkAnim, s32 arg2);
|
||||
/* 0x18798 */ s32 (*setPlayerTalkAnim)(struct PlayState* play, void* talkAnim, s32 arg2);
|
||||
/* 0x1879C */ s16 playerActorCsIds[10];
|
||||
/* 0x187B0 */ MtxF viewProjectionMtxF;
|
||||
/* 0x187F0 */ Vec3f unk_187F0;
|
||||
|
||||
+5
-5
@@ -13,13 +13,13 @@
|
||||
#define MASS_HEAVY 0xFE // Can only be pushed by OC collisions with IMMOVABLE and HEAVY objects.
|
||||
|
||||
struct Actor;
|
||||
struct GlobalContext;
|
||||
struct PlayState;
|
||||
struct Lights;
|
||||
struct CollisionPoly;
|
||||
|
||||
struct EnBox;
|
||||
|
||||
typedef void(*ActorFunc)(struct Actor* this, struct GlobalContext* globalCtx);
|
||||
typedef void(*ActorFunc)(struct Actor* this, struct PlayState* play);
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ Vec3f pos;
|
||||
@@ -110,7 +110,7 @@ typedef struct {
|
||||
/* 0x1E */ s8 numLoaded; // original name: "clients"
|
||||
} ActorOverlay; // size = 0x20
|
||||
|
||||
typedef void(*ActorShadowFunc)(struct Actor* actor, struct Lights* mapper, struct GlobalContext* globalCtx);
|
||||
typedef void(*ActorShadowFunc)(struct Actor* actor, struct Lights* mapper, struct PlayState* play);
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ Vec3s rot; // Current actor shape rotation
|
||||
@@ -254,7 +254,7 @@ typedef enum {
|
||||
|
||||
struct EnItem00;
|
||||
|
||||
typedef void (*EnItem00ActionFunc)(struct EnItem00*, struct GlobalContext*);
|
||||
typedef void (*EnItem00ActionFunc)(struct EnItem00*, struct PlayState*);
|
||||
|
||||
#define ENITEM00_GET_8000(thisx) ((thisx)->params & 0x8000)
|
||||
#define ENITEM00_GET_7F00(thisx) (((thisx)->params & 0x7F00) >> 8)
|
||||
@@ -275,7 +275,7 @@ typedef struct EnItem00 {
|
||||
|
||||
struct EnAObj;
|
||||
|
||||
typedef void (*EnAObjActionFunc)(struct EnAObj*, struct GlobalContext*);
|
||||
typedef void (*EnAObjActionFunc)(struct EnAObj*, struct PlayState*);
|
||||
|
||||
typedef struct EnAObj {
|
||||
/* 0x000 */ Actor actor;
|
||||
|
||||
+14
-14
@@ -6,7 +6,7 @@
|
||||
#include "z64dma.h"
|
||||
#include "z64math.h"
|
||||
|
||||
struct GlobalContext;
|
||||
struct PlayState;
|
||||
struct Actor;
|
||||
struct SkelAnime;
|
||||
|
||||
@@ -189,7 +189,7 @@ typedef struct SkelAnime {
|
||||
/* 0x2C */ f32 morphRate; // Reciprocal of the number of frames in the morph
|
||||
/* 0x30 */ union {
|
||||
s32 (*normal)(struct SkelAnime*);// Can be Loop, Partial loop, Play once, Morph, or Tapered morph
|
||||
s32 (*link)(struct GlobalContext*, struct SkelAnime*); // Loop, Play once, and Morph
|
||||
s32 (*link)(struct PlayState*, struct SkelAnime*); // Loop, Play once, and Morph
|
||||
} update;
|
||||
/* 0x34 */ s8 initFlags; // Flags used when initializing Link's skeleton
|
||||
/* 0x35 */ u8 moveFlags; // Flags used for animations that move the actor in worldspace.
|
||||
@@ -198,29 +198,29 @@ typedef struct SkelAnime {
|
||||
/* 0x3E */ Vec3s baseTransl; // Base modelspace translation.
|
||||
} SkelAnime; // size = 0x44
|
||||
|
||||
typedef s32 (*OverrideLimbDrawOpa)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot,
|
||||
typedef s32 (*OverrideLimbDrawOpa)(struct PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot,
|
||||
struct Actor* thisx);
|
||||
|
||||
typedef void (*PostLimbDrawOpa)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot,
|
||||
typedef void (*PostLimbDrawOpa)(struct PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
|
||||
struct Actor* thisx);
|
||||
|
||||
typedef s32 (*OverrideLimbDraw)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot,
|
||||
typedef s32 (*OverrideLimbDraw)(struct PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot,
|
||||
struct Actor* thisx, Gfx** gfx);
|
||||
|
||||
typedef void (*PostLimbDraw)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s* rot,
|
||||
typedef void (*PostLimbDraw)(struct PlayState* play, s32 limbIndex, Gfx** dList, Vec3s* rot,
|
||||
struct Actor* thisx, Gfx** gfx);
|
||||
|
||||
typedef s32 (*OverrideLimbDrawFlex)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot,
|
||||
typedef s32 (*OverrideLimbDrawFlex)(struct PlayState* play, s32 limbIndex, Gfx** dList, Vec3f* pos, Vec3s* rot,
|
||||
struct Actor* thisx);
|
||||
|
||||
typedef void (*PostLimbDrawFlex)(struct GlobalContext* globalCtx, s32 limbIndex, Gfx** dList1, Gfx** dList2, Vec3s* rot,
|
||||
typedef void (*PostLimbDrawFlex)(struct PlayState* play, s32 limbIndex, Gfx** dList1, Gfx** dList2, Vec3s* rot,
|
||||
struct Actor* thisx);
|
||||
|
||||
typedef void (*TransformLimbDrawOpa)(struct GlobalContext* globalCtx, s32 limbIndex, struct Actor* thisx);
|
||||
typedef void (*TransformLimbDrawOpa)(struct PlayState* play, s32 limbIndex, struct Actor* thisx);
|
||||
|
||||
typedef void (*TransformLimbDraw)(struct GlobalContext* globalCtx, s32 limbIndex, struct Actor* thisx, Gfx** gfx);
|
||||
typedef void (*TransformLimbDraw)(struct PlayState* play, s32 limbIndex, struct Actor* thisx, Gfx** gfx);
|
||||
|
||||
typedef void (*AnimationEntryCallback)(struct GlobalContext*, AnimationEntryData*);
|
||||
typedef void (*AnimationEntryCallback)(struct PlayState*, AnimationEntryData*);
|
||||
|
||||
extern u32 link_animetion_segment;
|
||||
|
||||
@@ -251,7 +251,7 @@ typedef struct AnimationSpeedInfo {
|
||||
|
||||
struct SkeletonInfo;
|
||||
|
||||
typedef s32 (*UnkKeyframeCallback)(struct GlobalContext* globalCtx, struct SkeletonInfo* skeletonInfo, s32* arg2, Gfx** dList,
|
||||
typedef s32 (*UnkKeyframeCallback)(struct PlayState* play, struct SkeletonInfo* skeletonInfo, s32* arg2, Gfx** dList,
|
||||
u8* arg4, void* arg5);
|
||||
|
||||
// Keyframe limb?
|
||||
@@ -312,10 +312,10 @@ typedef struct SkeletonInfo {
|
||||
/* 0x2C */ s16* unk_2C;
|
||||
} SkeletonInfo;
|
||||
|
||||
typedef s32 (*OverrideKeyframeDrawScaled)(struct GlobalContext* globalCtx, SkeletonInfo* skeletonInfo, s32 limbIndex, Gfx** dList,
|
||||
typedef s32 (*OverrideKeyframeDrawScaled)(struct PlayState* play, SkeletonInfo* skeletonInfo, s32 limbIndex, Gfx** dList,
|
||||
u8* flags, struct Actor* actor, Vec3f* scale, Vec3s* rot, Vec3f* pos);
|
||||
|
||||
typedef void (*PostKeyframeDrawScaled)(struct GlobalContext* globalCtx, SkeletonInfo* skeleton, s32 limbIndex, Gfx** dList,
|
||||
typedef void (*PostKeyframeDrawScaled)(struct PlayState* play, SkeletonInfo* skeleton, s32 limbIndex, Gfx** dList,
|
||||
u8* flags, struct Actor* actor, Vec3f* scale, Vec3s* rot, Vec3f* pos);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#ifndef Z64_BGCHECK_H
|
||||
#define Z64_BGCHECK_H
|
||||
|
||||
struct GlobalContext;
|
||||
struct PlayState;
|
||||
struct Actor;
|
||||
struct DynaPolyActor;
|
||||
|
||||
@@ -223,7 +223,7 @@ typedef struct {
|
||||
} CollisionContext; // size = 0x1470
|
||||
|
||||
typedef struct {
|
||||
/* 0x00 */ struct GlobalContext* globalCtx;
|
||||
/* 0x00 */ struct PlayState* play;
|
||||
/* 0x04 */ CollisionContext* colCtx;
|
||||
/* 0x08 */ u16 xpFlags;
|
||||
/* 0x0C */ CollisionPoly** resultPoly;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user