mirror of
https://github.com/zeldaret/oot.git
synced 2025-07-03 14:34:32 +00:00
Whitespace (#1112)
* remove trailing whitespaces * minor docs tweaks * some more trailing whitespaces * few more tweaks
This commit is contained in:
parent
f344fe648b
commit
f4a72303cb
150 changed files with 493 additions and 494 deletions
|
@ -4,9 +4,9 @@
|
|||
This project uses [Doxygen](https://www.doxygen.nl/index.html) to generate documentation pages from comments found in the source files. This guide focuses on writing compatible comments and ensuring consistency across the codebase.
|
||||
```diff
|
||||
- Note -
|
||||
As the codebase is constantly changing, only document what is complete, well-understood and not
|
||||
As the codebase is constantly changing, only document what is complete, well-understood and not
|
||||
already covered by good naming. This is especially true for function parameters and return values.
|
||||
Also note that there is no obligation to completing the documentation steps for functions you
|
||||
Also note that there is no obligation to completing the documentation steps for functions you
|
||||
work on if you do not want to at the time.
|
||||
```
|
||||
To generate a doxygen manual for the project, ensure you have doxygen installed and then cd into the project root directory and run `doxygen Doxyfile`.
|
||||
|
@ -97,4 +97,4 @@ For centered rendering on a separate line:
|
|||
/**
|
||||
* \f[ \textrm{Your LaTeX Here} \f]
|
||||
*/
|
||||
```
|
||||
```
|
||||
|
|
|
@ -60,8 +60,8 @@ The above is a rough ordering for the beginner. As you become more experienced,
|
|||
|
||||
Associated to each actor is a `.data` file, containing data that the actor uses. This ranges from spawn positions, to display lists, to even some cutscene data. Since the structure of the data is very inconsistent between actors, automatic importing has been very limited, so the vast majority must be done manually.
|
||||
|
||||
There are two ways of transfering the data into an actor: we can either
|
||||
- import it all naively as words (`s32`s), which will still allow it to compile, and sort out the actual types later, or
|
||||
There are two ways of transfering the data into an actor: we can either
|
||||
- import it all naively as words (`s32`s), which will still allow it to compile, and sort out the actual types later, or
|
||||
- we can extern each piece of data as we come across it, and come back to it later when we have a better idea of what it is.
|
||||
|
||||
We will concentrate on the second here; the other is covered in [the document about data](data.md). Thankfully this means we essentially don't have to do anything to the data yet. Nevertheless, it is often quite helpful to copy over at least some of the data and leave it commented out for later replacement. *Data must go in the same order as in the data file, and data is "all or nothing": you cannot only import some of it*.
|
||||
|
@ -93,7 +93,7 @@ from the main directory of the repository. In this case, the C file is `src/over
|
|||
|
||||

|
||||
|
||||
Now, open the file containing the assembly for `EnJj_Init`.
|
||||
Now, open the file containing the assembly for `EnJj_Init`.
|
||||
|
||||

|
||||
|
||||
|
@ -117,7 +117,7 @@ void EnJj_Init(EnJj *this, GlobalContext *globalCtx) {
|
|||
ActorShape_Init(&this->actor.shape, 0.0f, NULL, 0.0f);
|
||||
temp_v0 = this->actor.params;
|
||||
temp_a1 = this + 0x164;
|
||||
[...]
|
||||
[...]
|
||||
```
|
||||
|
||||
Typically for all buth the simplest functions, there is a lot that needs fixing before we are anywhere near seeing how close we are to the original code. You will notice that mips2c creates a lot of temporary variables. Usually most of these will turn out to not be real, and we need to remove the right ones to get the code to match.
|
||||
|
@ -217,7 +217,7 @@ void EnJj_Init(Actor *thisx, GlobalContext *globalCtx) {
|
|||
In the next sections, we shall sort out the various initialisation functions that occur in Init. There are several types, and one of the reasons we are using EnJj as the example is that it has several of the most common ones. A disadvantage of this actor is that it has an unusually complicated Init: we can see that it does three different things depending on the value of its params.
|
||||
|
||||
### Init chains
|
||||
|
||||
|
||||
Almost always, one of the first items in `Init` is a function that looks like
|
||||
|
||||
```C
|
||||
|
@ -324,7 +324,7 @@ this->dyna.bgId = DynaPoly_SetBgActor(globalCtx, &globalCtx->colCtx.dyna, &this-
|
|||
Next, replace `(DynaPolyActor *) this` by `&this->dyna`. There's not a lot more we can do to the DynaPoly stuff right now, so just remove the casts to void and move on.
|
||||
|
||||
### Colliders
|
||||
|
||||
|
||||
The next common thing that actors have is colliders. Not every actor has these, but most do, even if they don't just use them for collision system purposes.
|
||||
|
||||
The relevant functions in this actor are
|
||||
|
@ -355,7 +355,7 @@ Collider_SetCylinder(globalCtx, &this->collider, &this->dyna.actor, &D_80A88CB4)
|
|||
|
||||
(You may prefer to just comment out temps initially, to keep track of where they were.)
|
||||
|
||||
The last thing we need to deal with is the last variable of `Collider_SetCylinder`, which is again data.
|
||||
The last thing we need to deal with is the last variable of `Collider_SetCylinder`, which is again data.
|
||||
|
||||
<!--Also again we have a script to translate the raw data. This one is called `colliderinit.py`, and lives in `tools/overlayhelpers`. It takes the VRAM address of the data and the type of collider (for more info on use, pass it `-h`). We find
|
||||
```
|
||||
|
@ -575,7 +575,7 @@ Unfortunately the others are not so easy to deal with. In order to find out what
|
|||
|
||||
```MIPS
|
||||
glabel func_80A87800
|
||||
/* 00000 80A87800 03E00008 */ jr $ra
|
||||
/* 00000 80A87800 03E00008 */ jr $ra
|
||||
/* 00004 80A87804 AC8502FC */ sw $a1, 0x02FC($a0) ## 000002FC
|
||||
```
|
||||
|
||||
|
@ -593,7 +593,7 @@ Put this between `struct EnJj;` and the actor struct in the header file. This al
|
|||
We have actually learnt three useful pieces of information from this, the other two being that the function above Init is simply
|
||||
```C
|
||||
void func_80A87800(EnJj* this, EnJjActionFunc actionFunc) {
|
||||
this->actionFunc = actionFunc;
|
||||
this->actionFunc = actionFunc;
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -695,7 +695,7 @@ extern UNK_TYPE D_0600BA8C;
|
|||
|
||||
// #pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Jj/func_80A87800.s")
|
||||
void func_80A87800(EnJj* this, EnJjActionFunc actionFunc) {
|
||||
this->actionFunc = actionFunc;
|
||||
this->actionFunc = actionFunc;
|
||||
}
|
||||
|
||||
// #pragma GLOBAL_ASM("asm/non_matchings/overlays/actors/ovl_En_Jj/EnJj_Init.s")
|
||||
|
@ -904,7 +904,7 @@ except we still have some stack issues. Now that `temp_v0` is only used once, it
|
|||
void EnJj_Init(Actor* thisx, GlobalContext* globalCtx2) {
|
||||
GlobalContext* globalCtx = globalCtx2;
|
||||
EnJj* this = THIS;
|
||||
...
|
||||
...
|
||||
```
|
||||
|
||||
It turns out that this is enough to completely fix the diff:
|
||||
|
|
|
@ -12,29 +12,29 @@
|
|||
## Decompilation
|
||||
|
||||
- [Begining decompilation: order, Init and the actor struct](beginning_decomp.md)
|
||||
- Order of decompilation
|
||||
- Init and common actor features
|
||||
- Initchains
|
||||
- Actors and dynapoly actors
|
||||
- Colliders
|
||||
- Skelanime
|
||||
|
||||
- Matching
|
||||
- Using diff
|
||||
- control flow (branches) -> instruction ordering -> register allocation -> stack
|
||||
- Order of decompilation
|
||||
- Init and common actor features
|
||||
- Initchains
|
||||
- Actors and dynapoly actors
|
||||
- Colliders
|
||||
- Skelanime
|
||||
|
||||
- Matching
|
||||
- Using diff
|
||||
- control flow (branches) -> instruction ordering -> register allocation -> stack
|
||||
|
||||
- [The rest of the functions in the actor](other_functions.md)
|
||||
- Order of decompilation
|
||||
- Action Functions and other functions
|
||||
|
||||
- More on matching: the permuter
|
||||
- More on matching: the permuter
|
||||
|
||||
- [Draw functions](draw_functions.md)
|
||||
|
||||
- [Data, migration and non-migration](data.md)
|
||||
- Importing the data: early and late
|
||||
- Fake symbols
|
||||
- Inlining
|
||||
- Importing the data: early and late
|
||||
- Fake symbols
|
||||
- Inlining
|
||||
|
||||
## [Object Decompilation](object_decomp.md)
|
||||
- Object files
|
||||
|
@ -46,9 +46,9 @@
|
|||
|
||||
- [Preparing to merge](merging.md)
|
||||
- Preliminary documentation
|
||||
- Preparing to PR
|
||||
- Pull Requests
|
||||
- Trello
|
||||
- Preparing to PR
|
||||
- Pull Requests
|
||||
- Trello
|
||||
|
||||
## Appendices
|
||||
- [Types, Structs and Padding](types_structs_padding.md) (a miscellany of useful stuff)
|
||||
|
|
|
@ -10,8 +10,8 @@
|
|||
|
||||
Each actor's data is stored in a separate file. EnJj's data is in `data/overlays/actors/z_en_jj.data.s`, for example. At some point in the decompilation process we need to convert this raw data into recognisable information for the C to use.
|
||||
|
||||
There are two main ways to do this: either
|
||||
1. import the data first and type it later, or
|
||||
There are two main ways to do this: either
|
||||
1. import the data first and type it later, or
|
||||
2. wait until the data appears in functions, extern it, then import it at the end
|
||||
|
||||
Sometimes something between these two is appropriate: wait until the largest or strangest bits of data appear in functions, get some typing information out of that, and then import it, but for now, let's stick to both of these.
|
||||
|
@ -123,7 +123,7 @@ beginseg
|
|||
include "build/data/overlays/actors/z_en_tg.reloc.o"
|
||||
endseg
|
||||
```
|
||||
and comment out the .data line,
|
||||
and comment out the .data line,
|
||||
```
|
||||
beginseg
|
||||
name "ovl_En_Tg"
|
||||
|
@ -211,7 +211,7 @@ void func_80B1871C(GlobalContext* globalCtx, s32 limbIndex, Gfx** dList, Vec3s*
|
|||
EnTg* this = THIS;
|
||||
|
||||
Vec3f sp18 = D_80B18968;
|
||||
|
||||
|
||||
if (limbIndex == 9) {
|
||||
Matrix_MultVec3f(&sp18, &this->actor.world2.pos);
|
||||
}
|
||||
|
|
|
@ -30,8 +30,8 @@ EnJj* this = THIS;
|
|||
in the declarations as before. 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
|
||||
void EnJj_Draw(Actor *thisx, GlobalContext *globalCtx) {
|
||||
EnJj* this = THIS;
|
||||
|
||||
EnJj* this = THIS;
|
||||
|
||||
GraphicsContext *sp4C;
|
||||
Gfx *sp3C;
|
||||
EnJj *sp18;
|
||||
|
@ -166,7 +166,7 @@ Lastly, the penultimate and antepenultimate arguments of `SkelAnime_DrawFlexOpa`
|
|||
|
||||
For more examples of graphics macros and the structure of Draw functions, we look at a function from `EnDntNormal`, which is some Deku Scrubs used in the minigame stuff in Lost Woods. This has a good selection of macros, and two functions that are commonly combined with Draw, namely OverrideLimbDraw and PostLimbDraw.
|
||||
|
||||
The mips2c output for
|
||||
The mips2c output for
|
||||
|
||||
```C
|
||||
void func_809F5A6C(Actor *thisx, GlobalContext *globalCtx) {
|
||||
|
@ -289,7 +289,8 @@ static Color_RGBA8 D_809F5E4C[] = {
|
|||
{ 255, 255, 255, 255 }, { 255, 195, 175, 255 }, { 210, 255, 0, 255 },
|
||||
{ 255, 255, 255, 255 }, { 210, 255, 0, 255 }, { 255, 195, 175, 255 },
|
||||
{ 255, 255, 255, 255 }, { 255, 195, 175, 255 }, { 210, 255, 0, 255 },
|
||||
};```
|
||||
};
|
||||
```
|
||||
|
||||
Now, we have two things to worry about: how to implement the negative pointer access, and how the second word is built. Negative accesses can be done by just subtracting 1, so that
|
||||
```C
|
||||
|
@ -304,7 +305,7 @@ or rather, since it is a `Color_RGB8`,
|
|||
temp_v0_3->words.w1 = (temp_v1.b << 8) | (temp_v1.r << 0x18) | (temp_v1.g << 0x10) | 0xFF;
|
||||
```
|
||||
|
||||
The last thing to worry about is how to put this word into the macro. Let's think aboout what the word actually is in a concrete case; it is easiest to see what is going on in hex, so suppose we are in the case
|
||||
The last thing to worry about is how to put this word into the macro. Let's think about what the word actually is in a concrete case; it is easiest to see what is going on in hex, so suppose we are in the case
|
||||
```C
|
||||
temp_v1 = { 0xFF, 0xC3, 0xAF, 0xFF };
|
||||
```
|
||||
|
@ -465,7 +466,7 @@ s32 func_809F58E4(GlobalContext *globalCtx, s32 limbIndex, Gfx **dList, Vec3f *p
|
|||
OPEN_DISPS(globalCtx->state.gfxCtx, "../z_en_dnt_nomal.c", 1733);
|
||||
gDPPipeSync(POLY_OPA_DISP++);
|
||||
gDPSetEnvColor(POLY_OPA_DISP++, D_809F5E4C[this->type - 1].r, D_809F5E4C[this->type - 1].g, D_809F5E4C[this->type - 1].b, 255);
|
||||
CLOSE_DISPS(globalCtx->state.gfxCtx, (const char*)"../z_en_dnt_nomal.c", 1743);
|
||||
CLOSE_DISPS(globalCtx->state.gfxCtx, "../z_en_dnt_nomal.c", 1743);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ Suggestions are saved in the function directory it imported the function into.
|
|||
|
||||
## first_diff
|
||||
|
||||
Tells you where your built rom first differs from the baserom. It gives you a memory address that you can use to do, e.g. a binary diff, and also tries too find what function or data this address is in. Run with
|
||||
Tells you where your built rom first differs from the baserom. It gives you a memory address that you can use to do, e.g. a binary diff, and also tries too find what function or data this address is in. Run with
|
||||
```C
|
||||
./first_diff.py
|
||||
```
|
||||
|
|
|
@ -6,9 +6,9 @@ In this project, we are decompiling The Legend of Zelda: Ocarina of Time. This m
|
|||
glabel func_80A13098
|
||||
/* 00028 80A13098 8482001C */ lh $v0, 0x001C($a0) ## 0000001C
|
||||
/* 0002C 80A1309C 24010004 */ addiu $at, $zero, 0x0004 ## $at = 00000004
|
||||
/* 00030 80A130A0 14410003 */ bne $v0, $at, .L80A130B0
|
||||
/* 00030 80A130A0 14410003 */ bne $v0, $at, .L80A130B0
|
||||
/* 00034 80A130A4 244EFFFE */ addiu $t6, $v0, 0xFFFE ## $t6 = FFFFFFFE
|
||||
/* 00038 80A130A8 10000002 */ beq $zero, $zero, .L80A130B4
|
||||
/* 00038 80A130A8 10000002 */ beq $zero, $zero, .L80A130B4
|
||||
/* 0003C 80A130AC A480001C */ sh $zero, 0x001C($a0) ## 0000001C
|
||||
.L80A130B0:
|
||||
/* 00040 80A130B0 A48E001C */ sh $t6, 0x001C($a0) ## 0000001C
|
||||
|
@ -19,7 +19,7 @@ glabel func_80A13098
|
|||
/* 00050 80A130C0 A1E20004 */ sb $v0, 0x0004($t7) ## 00000004
|
||||
/* 00054 80A130C4 A08201B8 */ sb $v0, 0x01B8($a0) ## 000001B8
|
||||
/* 00058 80A130C8 A08201B9 */ sb $v0, 0x01B9($a0) ## 000001B9
|
||||
/* 0005C 80A130CC 03E00008 */ jr $ra
|
||||
/* 0005C 80A130CC 03E00008 */ jr $ra
|
||||
/* 00060 80A130D0 A0980117 */ sb $t8, 0x0117($a0) ## 00000117
|
||||
```
|
||||
|
||||
|
@ -62,13 +62,13 @@ A lot of work has already been done on the code to bring it into a format that i
|
|||
|
||||
An *actor* is any thing in the game that moves or performs actions or interactions: Link is an actor, enemies are actors, NPCs are actors, props like grass are actors (Fishing is also an actor, the largest one, but you don't need to know about it). The vast majority of actors are *overlays*, which means they are loaded only when the game needs them.
|
||||
|
||||
In the code, each actor is associated to several files: there is
|
||||
In the code, each actor is associated to several files: there is
|
||||
- the main .c file, e.g. `src/overlays/actors/ovl_En_Firefly/z_en_firefly.c`
|
||||
- the actor's Header file, e.g. `src/overlays/actors/ovl_En_Firefly/z_en_firefly.h`
|
||||
- various .o files that tell the `make` script how to incorporate it into building the ROM,
|
||||
- various .o files that tell the `make` script how to incorporate it into building the ROM,
|
||||
|
||||
and then for undecompiled actors, various assembly (.s) files, generally including:
|
||||
and then for undecompiled actors, various assembly (.s) files, generally including:
|
||||
- one for the actor's *data* (this usually includes things like its collision information about how to draw it, and various other stuff that is used in it), e.g. `data/overlays/actors/z_en_firefly.data.s`
|
||||
- one for each function in the actor, e.g. `asm/non_matchings/overlays/actors/ovl_En_Firefly/func_80A13098.s`
|
||||
|
||||
The basic process of decomp is to take one of the .s files, run it through a decompilation program (mips_to_c) that reads the ASM very literally, and then, through humen ingenuity, reshape it into code that not only compiles in the first place, but completely matches the original code (well-written or otherwise).
|
||||
The basic process of decomp is to take one of the .s files, run it through a decompilation program (mips_to_c) that reads the ASM very literally, and then, through humen ingenuity, reshape it into code that not only compiles in the first place, but completely matches the original code (well-written or otherwise).
|
||||
|
|
|
@ -89,7 +89,7 @@ There is no need to wait for your PR to be approved and committed before working
|
|||
## Trello
|
||||
|
||||
It's helpful to use the labels on Trello.
|
||||
- RESERVED is obvious.
|
||||
- RESERVED is obvious.
|
||||
- Work in Progress is for when you're actively working on something
|
||||
- Matched for when it is totally decompiled and matching
|
||||
- Documented if at least everything is named and odd code is commented. We'll likely wipe these and start over when proper documentation begins.
|
||||
|
|
|
@ -164,7 +164,7 @@ If you'd rather not have it tell you about the checksum, you can run `make COMPA
|
|||
|
||||
---
|
||||
|
||||
To revert to the original texture, you can just run `extract_assets.py -s` on the object again.
|
||||
To revert to the original texture, you can just run `extract_assets.py -s` on the object again.
|
||||
|
||||
N.B. doing this will overwrite every custom texture, as will running `make setup`.
|
||||
|
||||
|
|
|
@ -13,15 +13,15 @@ Following the scheme we gave last time, we have three options:
|
|||
Another option is to look at `Destroy`, which for smaller actors can often be done straight after Init, since it usually just removes colliders and deallocates dynapoly. However, glancing at the three given functions' assembly, there is an obvious standout:
|
||||
```MIPS
|
||||
glabel func_80A87F44
|
||||
/* 00744 80A87F44 AFA40000 */ sw $a0, 0x0000($sp)
|
||||
/* 00748 80A87F48 03E00008 */ jr $ra
|
||||
/* 0074C 80A87F4C AFA50004 */ sw $a1, 0x0004($sp)
|
||||
/* 00744 80A87F44 AFA40000 */ sw $a0, 0x0000($sp)
|
||||
/* 00748 80A87F48 03E00008 */ jr $ra
|
||||
/* 0074C 80A87F4C AFA50004 */ sw $a1, 0x0004($sp)
|
||||
|
||||
```
|
||||
This is a classic "function with two arguments that does nothing". So we can simply comment out the appropriate pragma and put
|
||||
```C
|
||||
void func_80A87F44(Actor* thisx, GlobalContext* globalCtx) {
|
||||
|
||||
|
||||
}
|
||||
```
|
||||
in the C file.
|
||||
|
@ -190,7 +190,7 @@ To use the permuter, clone the decomp-permuter repo from the link given in Disco
|
|||
|
||||
It will put it in a subdirectory of `nonmatchings`. You then run
|
||||
```sh
|
||||
./permuter.py nonmatchings/<function_name>/
|
||||
./permuter.py nonmatchings/<function_name>/
|
||||
```
|
||||
to produce suggestions. There are various arguments that can be used, of which the most important initially is `-j`: `-jN` tells it to use `N` CPU threads.
|
||||
|
||||
|
@ -217,7 +217,7 @@ The first suggestion looks plausible:
|
|||
- func_8003EBF8(globalCtx, &globalCtx->colCtx.dyna, this->childActor->bgId);
|
||||
+ func_8003EBF8(globalCtx, &globalCtx->colCtx.dyna, new_var->bgId);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -285,7 +285,7 @@ void func_80A87C30(EnJj *this, GlobalContext *globalCtx) {
|
|||
}
|
||||
```
|
||||
|
||||
There are three things left to do to this function:
|
||||
There are three things left to do to this function:
|
||||
- prototype the new action function, `func_80A87CEC`. This one is used before its definition, so needs to be prototyped at the top of the file.
|
||||
- extern `D_80A88CF0`, and since the arguments of `Math_Vec3f_DistXZ` are `Vec3f`s, convert it to floats. To do float conversion, either use an online converter, or get an extension for VSCode that can do it. The data becomes
|
||||
```C
|
||||
|
@ -698,7 +698,7 @@ void func_80A87D94(EnJj *this, GlobalContext *globalCtx) {
|
|||
|
||||
At the top we have
|
||||
```C
|
||||
temp_v0 = *globalCtx->unk1D94;
|
||||
temp_v0 = *globalCtx->unk1D94;
|
||||
if (temp_v0 != 1) {
|
||||
if (temp_v0 != 2) {
|
||||
if (temp_v0 != 3) {
|
||||
|
@ -721,18 +721,18 @@ void func_80A87D94(EnJj *this, GlobalContext *globalCtx) {
|
|||
|
||||
switch (globalCtx->csCtx.npcActions[2]->action) {
|
||||
case 1:
|
||||
temp_v1_3 = this->unk_30A;
|
||||
phi_v1 = temp_v1_3;
|
||||
if ((temp_v1_3 & 2) != 0) {
|
||||
this->unk_30E = 0;
|
||||
this->unk_30F = Rand_S16Offset((u16)0x14, (u16)0x14);
|
||||
this->unk_310 = 0;
|
||||
temp_t9 = this->unk_30A ^ 2;
|
||||
this->unk_311 = 0;
|
||||
this->unk_30A = temp_t9;
|
||||
phi_v1 = temp_t9 & 0xFFFF;
|
||||
}
|
||||
break;
|
||||
temp_v1_3 = this->unk_30A;
|
||||
phi_v1 = temp_v1_3;
|
||||
if ((temp_v1_3 & 2) != 0) {
|
||||
this->unk_30E = 0;
|
||||
this->unk_30F = Rand_S16Offset((u16)0x14, (u16)0x14);
|
||||
this->unk_310 = 0;
|
||||
temp_t9 = this->unk_30A ^ 2;
|
||||
this->unk_311 = 0;
|
||||
this->unk_30A = temp_t9;
|
||||
phi_v1 = temp_t9 & 0xFFFF;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
temp_t1 = this->unk_30A | 1;
|
||||
temp_v1_2 = temp_t1 & 0xFFFF;
|
||||
|
@ -744,23 +744,23 @@ void func_80A87D94(EnJj *this, GlobalContext *globalCtx) {
|
|||
this->unk_30A = temp_t4;
|
||||
phi_v1 = temp_t4 & 0xFFFF;
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case 3:
|
||||
temp_v1 = this->unk_30A;
|
||||
temp_t7 = temp_v1 | 2;
|
||||
phi_v1 = temp_v1;
|
||||
if ((temp_v1 & 2) == 0) {
|
||||
this->unk_30E = 0;
|
||||
this->unk_30F = 0;
|
||||
this->unk_310 = 1;
|
||||
this->unk_311 = 0;
|
||||
this->unk_30A = temp_t7;
|
||||
phi_v1 = temp_t7 & 0xFFFF;
|
||||
}
|
||||
break;
|
||||
temp_v1 = this->unk_30A;
|
||||
temp_t7 = temp_v1 | 2;
|
||||
phi_v1 = temp_v1;
|
||||
if ((temp_v1 & 2) == 0) {
|
||||
this->unk_30E = 0;
|
||||
this->unk_30F = 0;
|
||||
this->unk_310 = 1;
|
||||
this->unk_311 = 0;
|
||||
this->unk_30A = temp_t7;
|
||||
phi_v1 = temp_t7 & 0xFFFF;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
phi_v1 = this->unk_30A;
|
||||
break;
|
||||
phi_v1 = this->unk_30A;
|
||||
break;
|
||||
}
|
||||
if ((phi_v1 & 1) != 0) {
|
||||
Audio_PlayActorSound2((Actor *) this, (u16)0x206DU);
|
||||
|
@ -780,7 +780,7 @@ As usual, most of the remaining temps look fake. The only one that does not is p
|
|||
|
||||
<details>
|
||||
<summary>
|
||||
Matching C for `func_80A87D94`
|
||||
Matching C for `func_80A87D94`
|
||||
</summary>
|
||||
|
||||
```C
|
||||
|
|
|
@ -28,4 +28,4 @@ Since actors cover so many different categories of stuff in the game, they come
|
|||
|
||||
The general rule of thumb is to pick something with few, simple interactions with its environment. (For example, my first actor was BgIceTurara: icicles, which can do about 3 different things: break, fall, and grow.) This hopefully means that the functions are mostly small and simple. You are also probably better off if Draw and Init are small functions, although difficulty is sometimes not correlated to size.
|
||||
|
||||
If in doubt, ask someone to have a quick look through the code to see if it's suitable.
|
||||
If in doubt, ask someone to have a quick look through the code to see if it's suitable.
|
||||
|
|
|
@ -14,7 +14,7 @@ The following are the common data types used everywhere:
|
|||
| char | 1 byte | character |
|
||||
| u8 | 1 byte | unsigned byte |
|
||||
| s8 | 1 byte | signed byte |
|
||||
| u16 | 2 bytes | unsigned short |
|
||||
| u16 | 2 bytes | unsigned short |
|
||||
| s16 | 2 bytes | signed short |
|
||||
| u32 | 4 bytes/1 word | unsigned int |
|
||||
| s32 | 4 bytes/1 word | signed int |
|
||||
|
@ -43,8 +43,8 @@ Here are the usual names and the sizes of some of the most common structs used i
|
|||
| ----------------------- | --------------------- | --------------- |
|
||||
| `Actor` | `actor` | 0x14C |
|
||||
| `DynaPolyActor` | `dyna` | 0x164 |
|
||||
| `Vec3f` | | 0xC |
|
||||
| `Vec3s` | | 0x6 |
|
||||
| `Vec3f` | | 0xC |
|
||||
| `Vec3s` | | 0x6 |
|
||||
| `SkelAnime` | `skelAnime` | 0x44 |
|
||||
| `Vec3s[limbCount]` | `jointTable` | 0x6 * limbCount |
|
||||
| `Vec3s[limbCount]` | `morphTable` | 0x6 * limbCount |
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue