mostly renamings, one func (#33)

Matched func_8010E27C from previous NON_MATCHING state

Entity struct members:
facing, hitPoints,

It's worth mentioning that those names are not definitive, but rather
intended to make up some context while decompiling functions, more
accurate names will come once we decomp more.

NZ0 function names:
EntityTransitionDoor
EntityBloodSkeleton

I also updated the permuter configuration yaml file but there's still
work left to do with it for the decomp.me import function to work
properly.
This commit is contained in:
Alejandro Asenjo Nitti 2023-01-02 08:57:53 +00:00 committed by GitHub
parent 88f8bd4283
commit 53fecc2e1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 556 additions and 99 deletions

View File

@ -62,13 +62,14 @@ Some non-matching functions are present in the source preprocessed by the macro
There are a few tricks to make the process more streamlined:
1. Use [decomp.me](https://decomp.me/) with PSY-Q 4.0. Be aware that the repo is using GCC 2.6.x, so decomp.me will sometimes give a slightly different output.
1. The “context” section of decomp.me, is provided by the cmd `SOURCE=src/dra/42398.c make context` as mentioned in the how to decompile.
1. The “context” section of decomp.me, is provided by the cmd `SOURCE=src/dra/42398.c make context`.
1. Use [decomp-permuter](https://github.com/simonlindholm/decomp-permuter) to solve some mismatches.
1. Use [this](https://github.com/mkst/sssv/wiki/Jump-Tables) and [this](https://github.com/pmret/papermario/wiki/GCC-2.8.1-Tips-and-Tricks) guide to understand how some compiler patterns work.
1. Use the `#ifndef NON_MATCHING` if your code is logically equivalent but you cannot yet fully match it.
## Resources
* Project Documentation [Style Guide](https://github.com/Xeeynamo/sotn-decomp/docs/STYLE.md)
* List of resource for sotn <https://github.com/TalicZealot/SotN-Utilities> (speedrun oriented, but still very useful).
* PS1s CPU R3000 instruction [manual](https://cgi.cse.unsw.edu.au/~cs3231/doc/R3000.pdf) and [cheat sheet](https://vhouten.home.xs4all.nl/mipsel/r3000-isa.html)
* [SOTN map viewer written in C](https://github.com/KernelEquinox/SotN-Editor)

View File

@ -25,8 +25,6 @@ segments:
subalign: 4
subsegments:
- [0x0, rodata]
- [0x518, rodata]
- [0x1F18, rodata]
- [0x2BC0, rodata]
- [0x7730, rodata]
- [0x8900, rodata]

View File

@ -1,4 +1,5 @@
CreateEntity = 0x801BB0C4;
EntityTransitionDoor = 0x801BBCB4;
DestroyEntity = 0x801BC8EC;
Random = 0x801B94D4;
SpawnExplosionEntity = 0x801BBB4C;
@ -18,5 +19,6 @@ EntityCandleHeartDrop = 0x801BED20;
EntityAbsorbOrb = 0x801C2AA8;
EntityRoomForeground = 0x801C32EC;
EntityBoneScimitar = 0x801C37E4;
EntityBloodSkeleton = 0x801C7958;
EntityAreaTitlePopup = 0x801C8CAC;
c_GoldPrizes = 0x80181D14;

View File

@ -1110,10 +1110,6 @@ D_800ACD88 = 0x800ACD88;
D_800ACD90 = 0x800ACD90;
rect = 0x800ACD98;
c_backbufferClear = 0x800ACDA0;
SaveIconPalette = 0x800A0518;
SaveIconTexture = 0x800A1F18;
Load_Save_Palette = 0x800E9BA4;
Load_Save_Icon = 0x800E9BDC;
aPbav = 0x800B107C;
aPbav_0 = 0x800B407C;
aPbav_2 = 0x800B607C;

159
docs/STYLE.md Normal file
View File

@ -0,0 +1,159 @@
# Castlevania Symphony of the Night decompilation style guide
## Types
Use the types from `types.h`, not the standard C types: i.e. `u8`,`s8`,`s16`,`u16`,`s32`,`u32` rather than `char`, `short`, `int`, `float` and their `signed`/`unsigned` varieties.
We always write our enums and structs as `typedef`s. (Usually one can't use an enum typedef as a function argument since enum typedefs are implicitly `s32`.)
## Naming
| Type | Style | Example |
| -------------------- | ----------------------- | ----------------------- |
| Local variables | camelCase | `entityRotation` |
| Global variables | g_CamelCase | `g_SettingsSoundMode` |
| Static variables[^1] | s_CamelCase | `s_ZeroVec` |
| Struct members | camelCase | `hitboxWidth` |
| Struct types | PascalCase | `RoomHeader` |
| Enum types | PascalCase | `EntitySteps` |
| Enum values | SCREAMING_SNAKE_CASE | `ENTITY_STEP_0` |
| Defines/macros | SCREAMING_SNAKE_CASE | `PAD_UP`,`GET_PLAYER(x)`|
| Functions | PascalCase | `UpdateAccel` |
| Files | snake_case | `include_asm.h` |
[^1]: including in-function static
Ideally names should be both short and clear, although it's better to be clear than short.
## Formatting
A lot of formatting is done by clang-format, such as
- indent is 4 spaces, tabs are not used
- case labels indented
- 80 column limit
- brackets go on the same line (`if (1) {`)
- pointer goes on type (`s32* var;` not `s32 *var;`)
There are various other conventions that it does not catch, though:
- Blank line between declarations and code:
```c
s32 var;
func();
```
- combine declarations and definitions if possible:
```c
s32 var = 0;
func();
```
instead of
```c
s32 var;
var = 0;
func();
```
- blank lines between switch cases.
## Numbers
### dec(imal)
- timers
- colours and alpha
- Usually array accesses and sizes
### hex(adecimal)
- angles (for now; the code itself is very inconsistent with round hex, round dec, and degrees)
- Addresses
- Bitmasks (i.e. `& 0x80` etc.)
- Struct offset comments
### Booleans
If a function returns only `0` or `1`, and is used as a boolean (i.e. in conditionals), use `bool` type and replace the returns by `false` and `true`.
## Conditionals/Loops
- Spacing out conditional or loop blocks from surrounding code often makes them easier to read.
- We *always* use `{}` on conditional/loop blocks, even if they're one line
- When conditions are `&&`d or `||`d together, use brackets around each that includes an arithmetic comparison or bitwise operator (i.e. not `!var` or `func()`, but ones with `==` or `&` etc.)
- Flag checks or functions that return booleans do not need the `== 0`/`!= 0`.
- Prefer `if-else` over `if { return; }`, i.e.
**Exception**: There are instances when at the beginning of a function you want to return immediately if a validation fails so the rest of the body wouldn't be indented in an else if. See `func_8010189C` for an example.
```c
if (cond) {
foo();
} else {
bar();
}
```
over
```c
if (cond) {
foo();
return;
}
bar();
```
Become familiar with the various defines and enums we have available.
- Those in `macros.h`
- `ABS`, `ABS_ALT`,
- `CLAMP` and friends.
- `GET_PLATER` (look at examples around the repo), if it matches
## Arrays
- It's better to not hardcode array sizes (easier to mod)
- 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.
## Documentation and Comments
Documentation includes:
- Naming functions
- Naming struct variables
- Naming data
- Naming local variables
- Describing the general purpose of the file
- Describing any unusual, interesting or strange features of how the file or parts of its content work
- Labelling and explaining bugs
If you are not sure what something does, it is better to leave it unnamed than name it wrongly. It is fine to make a note of something you are not sure about when PRing, it means the reviewers will pay special attention to it.
We use comments for:
- Top of file: a short description of the system. For overlays there is already a brief description of our current understanding, but feel free to add to it.
- For function descriptions, we use multiline comments,
```c
/**
* Describe what the function does
*/
```
These are *optional*: if you think the code is clear enough, you do not need to put a comment.
- If something in a function is strange, or unintuitive, do leave a comment explaining what's going on. We use `//` for this.
- A bug should be commented with an `//! @bug Bug description` above the code that causes the bug.
- A fake should be commented with an `// !FAKE:` above or to the side of the code that you think it's fake.
### Functions
All functions should go in the main C file in the same order as the assembly (the latter is required to match anyway).

View File

@ -93,7 +93,7 @@ typedef struct Entity {
/* 0x0C */ s32 accelerationY;
/* 0x10 */ s16 unk10;
/* 0x12 */ s16 unk12;
/* 0x14 */ u16 unk14; // related to accelerationX ?
/* 0x14 */ u16 facing;
/* 0x16 */ u16 palette;
/* 0x18 */ s8 blendMode;
/* 0x19 */ u8 unk19;
@ -113,7 +113,7 @@ typedef struct Entity {
/* 0x38 */ s16 unk38;
/* 0x3A */ s16 unk3A;
/* 0x3C */ s16 unk3C;
/* 0x3E */ s16 unk3E;
/* 0x3E */ s16 hitPoints;
/* 0x40 */ s16 unk40;
/* 0x42 */ s16 unk42;
/* 0x44 */ u16 unk44;
@ -294,7 +294,8 @@ typedef enum {
ENTITY_STEP_4,
ENTITY_STEP_5,
ENTITY_STEP_6,
ENTITY_STEP_7
ENTITY_STEP_7,
ENTITY_STEP_19 = 0x19
} EntitySteps;
typedef enum { MONO, STEREO } SoundMode;
@ -374,7 +375,7 @@ extern s32 g_menuRelicsCursorIndex[];
extern s32 g_SettingsCloakMode;
extern s32 g_SettingsSoundMode;
extern s32 D_8003CACC;
extern s32 D_8003CB00;
extern s32 D_8003CB00[];
extern s32 D_8003CB04;
extern GpuBuffer D_8003CB08;
extern GpuBuffer D_800542FC;
@ -546,12 +547,13 @@ extern Entity g_EntityArray[TOTAL_ENTITY_COUNT];
extern s16 D_800733DA; // player->posX.Data.high
extern s16 D_800733DE; // player->posY.Data.high
extern s32 D_800733E0; // player->accelerationX
extern s32 D_800733E8; // player->accelerationY
extern u16 D_800733EC; // player->unk14
extern s32 D_800733E4; // player->accelerationY
extern s32 D_800733E8; // player->unk10
extern u16 D_800733EC; // player->facing
extern u16 D_800733EE; // player->palette
extern s8 D_800733F0; // player->blendMode
extern u8 D_800733F1; // player->unk19
extern s16 D_800733F6[]; // player->unk1E
extern s16 D_800733F6; // player->unk1E
extern u16 D_800733FC; // player->zPriority
extern s16 D_800733FE; // player->objectId
extern u16 D_80073404; // player->step
@ -665,8 +667,8 @@ extern s32 D_80098850;
extern void (*D_800A0004)(); // TODO pointer to 0x50 array of functions
extern s32 D_800A04EC;
extern s32 D_800A0510[];
extern u16 SaveIconPalette[0x10][0x10];
extern u32 SaveIconTexture[0x10];
extern u16 D_800A0518[0x10][0x10];
extern u32 D_800A1F18[0x10];
extern s32 D_800A2438;
extern u8 D_800A2EE8[];
extern u8 D_800A2EED;
@ -734,6 +736,7 @@ extern RECT D_800ACDF0;
extern Unkstruct_800ACEC6 D_800ACEC6;
extern u8 D_800ACF4C[];
extern s16 D_800ACF60[];
extern s32* D_800AE294; // might not really be a pointer
extern s16 D_800AFDA6;
extern const char* c_strEquip;
extern const char* c_strSpells;
@ -796,11 +799,12 @@ extern u8 D_8013761C[]; // can't use `extern MenuContext D_8013761C[];` as it's
// 2-byte aligned
// extern u8 D_80137638[2];
// extern u8 D_80137639[];
extern u8 D_80137692;
extern u8 D_801376B0;
extern s32 D_8013783C;
extern s32 D_801377FC[];
extern s32 D_80137840;
extern s32 D_80137844;
extern s32 D_80137844[];
extern s32 D_80137848;
extern s32 D_8013784C;
extern s32 g_someValue;
@ -825,6 +829,7 @@ extern u32 D_8013798C;
extern s32 D_80137994;
extern s32 D_80137998;
extern u32 D_8013799C;
extern s32 D_801379A0;
extern s32 D_80137E40;
extern s32 D_80137E44;
extern s32 D_80137E48;
@ -836,8 +841,10 @@ extern void* D_80137F7C;
extern s32 D_80137F9C;
extern s32 D_80138430;
extern s32 D_80138438;
extern s32 D_80138460;
extern const char* D_80138784[487];
extern s32 D_80138F20;
extern u8 D_80138F24[]; // Confirmed part of an array / struct
extern s32 D_80138F28;
extern s32 D_80138F7C;
extern s32 D_80138FB0;
@ -909,7 +916,13 @@ void SetRoomBackgroundLayer(s32 /* ? */, s32 /* ? */);
s32 CheckCollision(s32, s16, s32*, s32);
void PlaySfx(s16 sfxId);
s32 func_80019444(void);
void func_800209B4(s32*, s32, s32);
void func_80021E38(s32);
void func_80021EEC(void);
void func_80028D3C(s32, s32);
void func_80029FBC(s32);
void func_8002A09C(void*);
void func_8002ABF4(s32);
void func_800E346C(void);
void func_800E34A4(s8 arg0);
void func_800E34DC(s32 arg0);
@ -967,7 +980,7 @@ void func_800F82F4(void);
void func_800F8858(MenuContext* context);
void func_800FABEC(s32 arg0);
void func_800FAC30(void);
s32 func_800FD4C0(s32, s32);
// s32 func_800FD4C0(s32, s32);
s32 func_800FD664(s32 arg0);
u8* func_800FD744(s32 arg0);
u8* func_800FD760(s32 arg0);
@ -1015,6 +1028,7 @@ void func_801321FC(void);
void func_80132134(void);
s32 func_80132264(void);
s32 func_801326D8(void);
void func_80132028(s32, s8*, s32);
void func_8013271C(void);
void func_80132760(void);
void func_801337B4(void);
@ -1023,7 +1037,5 @@ s32 func_80133950(void);
void func_80133FCC(void);
void func_8013415C(void);
void func_801361F8(void);
void Load_Save_Palette(u16* PaletteDestination, s32 SelectedPalette);
void Load_Save_Icon(u8* IconDestination, s32 SelectedIcon);
#endif

View File

@ -4,7 +4,7 @@
// Closes the SEQ data holding the seq_acces_num that is no longer necessary.
extern void SsSeqClose(short seq_access_num);
/*
/**
* Sets the main volume value in voll and volr respectively.
* Each can be set from 0 to 127.
* It is essential to set it before SEQ data is played.
@ -13,10 +13,54 @@ extern void SsSetMVol(short voll, short volr);
// Carries out attribute setting relating to CD audio.
extern void SsSetSerialAttr(char s_num, char attr, char mode);
/*
/**
* Sets the CD volume value in voll and volr.
* The volume value can be set from 0 to 127.
*/
extern void SsSetSerialVol(short s_num, short voll, short volr);
/**
* Clears the area occupied by the reverb work
* area corresponding to the reverb mode.
* Returns 0 if successful.
*/
extern long SpuClearReverbWorkArea(long rev_mode // Reverb mode
);
/**
* Initializes the sound system, without destroying data that has been
* transferred to the sound buffer. Using Exec()-related functions, when a child
* process wants to initialize the sound system with the sound buffer in its
* current state, it should call SsInitHot() instead of calling SsInit().
*/
void SsInitHot(void);
/**
* Declares the number of voices that the libsnd voice allocation management
* system has access to. Other voices can be keyed on in libspu or via
* SsUtKeyOnV(). Voice numbers are reserved from the lower end (from 0).
* For example, if voices = 20, then:
* (*) Voices 0-19 are used for allocation by libsnd.
* (*) Voices 20-23 are available for libspu.
*
* Returns the set voice count if successful. Returns -1 if unsuccessful
*/
char SsSetReservedVoice(char voices // Voice count
);
/**
* Sets the resolution of a tick. Call this function only once before calling
* SsSeqOpen(), SsSepOpen() or SsStart() for the first time. When it is called
* multiple times, correct operation cannot be guaranteed.
*/
void SsSetTickMode(long tick_mode // Tick mode
);
/**
* Starts the sound system.When SsSetTickMode() is used to set
* a mode that calls SsSeqCalledTbyT() automatically, this
* function causes SsSeqCalledTbyT() to be called each tick.
*/
void SsStart(void);
#endif

View File

@ -1,3 +1,9 @@
/*
* File: 42398.c
* Overlay: RIC
* Description: Overlay for the character Richter.
*/
#include "common.h"
#include "dra.h"
#include "objects.h"
@ -245,7 +251,7 @@ void entrypoint_sotn(void) {
g_blinkTimer = 0;
D_8003C99C = 0;
D_800987B4 = 0;
D_8003CB00 = 0;
D_8003CB00[0] = 0;
D_8003CB04 = 0;
D_8006C37C = &D_8003CB08;
func_80131ED8(0xB9B6);
@ -834,17 +840,29 @@ s32 func_800E9B18(s32 arg0, s32 arg1) {
// https://decomp.me/scratch/kHOQh match with struct
void Load_Save_Palette(u16* PaletteDestination, s32 SelectedPalette) {
void func_800E9BA4(u16* arg0, s32 arg1) {
s32 i;
u16* var_v1 = D_800A0518[0];
var_v1 = D_800A0518[arg1];
for (i = 0; i < 16; i++) {
PaletteDestination[i] = SaveIconPalette[SelectedPalette][i];
*arg0 = *var_v1;
var_v1++;
arg0++;
}
}
void Load_Save_Icon(u8* IconDestination, s32 SelectedIcon) {
void func_800E9BDC(u8* arg0, s32 arg1) {
s32 i;
for (i = 0; i < 0x180; i++) {
IconDestination[i] = ((u8*)SaveIconTexture[SelectedIcon])[i];
u8* var_a1;
var_a1 = (u8*)D_800A1F18[arg1];
for (i = 0; i < 384; i++) {
*arg0 = *var_a1;
var_a1++;
arg0++;
}
}
@ -1307,7 +1325,7 @@ extern Unkstruct_aSimCBinDemoKey aSimCBinDemoKey;
void func_800F04A4(void) {
Unkstruct_aSimCBinDemoKey sp10[10];
char pad[12];
char pad[12]; // !FAKE: Intentional padding to fix the stack pointer
s32 temp;
s32 device;
@ -2372,7 +2390,49 @@ void func_800F9690(void) {
}
}
INCLUDE_ASM("asm/dra/nonmatchings/42398", func_800F96F4);
void func_800F96F4(void) { // !Fake:
s32 new_var2;
POLY_GT4* temp_a0;
s32 temp_a2;
unkStruct3* temp_a0_2;
s32* temp;
s32* new_var;
new_var = &D_80137848;
temp_a0 = &D_80086FEC[D_80137840];
temp_a2 = D_80137692 == 0;
temp = &D_80137844;
if ((D_80137844[0] != 0) && (temp_a2 != 0)) {
(&D_80086FEC[D_80137840])->pad3 = 0x80;
if (D_80137844[0] == 1) {
(&D_80086FEC[D_80137840])->clut = 0x188;
} else {
D_80137844[0] -= 1;
(&D_80086FEC[D_80137840])->clut = 0x181;
}
} else {
temp_a0->pad3 = 8;
}
temp_a0_2 = temp_a0->tag;
temp = new_var;
if (((*temp) != 0) && (temp_a2 != 0)) {
temp_a0_2->unk32 = 0x80;
new_var2 = *temp;
if (new_var2 == 1) {
do {
temp_a0_2->unkE = 0x188;
} while (0);
return;
}
*temp -= 1;
temp_a0_2->unkE = 0x181;
return;
}
temp_a0_2->unk32 = 8;
}
void func_800F97DC(void) {
D_8013794C = (s8*)&D_8007EFE4;
@ -2475,7 +2535,7 @@ void func_800FABEC(s32 context) { D_80137638[context].unk0 = 0; }
void func_800FAC0C(s32 context) { D_80137638[context].unk0 = 2; }
void func_800FAC30(void) {
D_80137844 = 0;
D_80137844[0] = 0;
D_80137848 = 0;
}
@ -2556,6 +2616,7 @@ INCLUDE_ASM("asm/dra/nonmatchings/42398", func_800FBC24);
INCLUDE_ASM("asm/dra/nonmatchings/42398", func_800FD39C);
// https://decomp.me/scratch/XEzwM
INCLUDE_ASM("asm/dra/nonmatchings/42398", func_800FD4C0);
s32 func_800FD5BC(Unkstruct_800FD5BC* arg0) {
@ -2985,7 +3046,7 @@ bool func_8010183C(s32 arg0) {
}
void DrawHudRichter(void);
void func_8010189C() {
void func_8010189C(void) {
POLY_GT4* poly;
s32 i;
u16* new_var;
@ -3066,7 +3127,36 @@ void func_80102628(s32 arg0) {
}
}
INCLUDE_ASM("asm/dra/nonmatchings/42398", func_801026BC);
void func_801026BC(s32 arg0) {
POLY_GT4* poly;
u16 pad3;
poly = &D_80086FEC[D_801379A0];
if (arg0 == 0) {
pad3 = 8;
goto block_7;
}
if (!(g_mapProgramId & 0x20)) {
SetPolyRect(poly, 0, 1, 255, 255);
} else {
poly->x2 = 255;
poly->x0 = 255;
poly->y1 = 240;
poly->y0 = 240;
poly->x3 = 0;
poly->x1 = 0;
poly->y3 = -15;
poly->y2 = -15;
}
func_80107250(poly, arg0 * 2);
if (arg0 == 0x40) {
poly->pad3 = 0;
return;
}
pad3 = 0x35;
block_7:
poly->pad3 = pad3;
}
void func_801027A4(void) { func_801026BC(0); }
@ -3366,8 +3456,8 @@ void func_80109328(void) {
(g_EntityArray[PLAYER_CHARACTER].step == 8)) {
g_EntityArray[PLAYER_CHARACTER].unk1E = 0;
g_EntityArray[PLAYER_CHARACTER].animationFrame = 0x9D;
g_EntityArray[PLAYER_CHARACTER].unk14 =
(g_EntityArray[PLAYER_CHARACTER].unk14 + 1) & 1;
g_EntityArray[PLAYER_CHARACTER].facing =
(g_EntityArray[PLAYER_CHARACTER].facing + 1) & 1;
}
if (D_80072F16[0] != 0) {
@ -3414,10 +3504,10 @@ INCLUDE_ASM("asm/dra/nonmatchings/42398", func_8010D010);
INCLUDE_ASM("asm/dra/nonmatchings/42398", func_8010D2C8);
void func_8010D584(s16 context) {
void func_8010D584(s16 step) {
Entity* player = GET_PLAYER(g_EntityArray);
player->step = context;
player->step = step;
player->unk2E = 0;
}
@ -3546,57 +3636,59 @@ void func_8010E234(s32 speed) {
}
}
#ifndef NON_MATCHING
INCLUDE_ASM("asm/dra/nonmatchings/42398", func_8010E27C);
#else
s32 func_8010E27C(void) {
s32 retValue;
u16* tmp;
u16* facing;
if (D_80072F64 & 2)
if (*D_80072F64 & 2) {
return 0;
}
retValue = 1;
tmp = &g_EntityArray->unk14;
if (*tmp == 1) {
facing = &g_EntityArray->facing;
if (*facing == 1) {
if (D_80072EE8 & 0x2000) {
*tmp = 0;
*facing = 0;
D_80072F6C = 1;
return -1;
}
if (D_80072EE8 & 0x8000) {
} else if (D_80072EE8 & 0x8000) {
return 1;
}
} else {
if (!(D_80072EE8 & 0x2000)) {
if (D_80072EE8 & 0x8000) {
*tmp = 1;
*facing = 1;
D_80072F6C = 1;
return -1;
}
return 0;
}
return 1;
}
return retValue;
return 0;
}
#endif
// https://decomp.me/scratch/YvoMU
INCLUDE_ASM("asm/dra/nonmatchings/42398", func_8010E334);
void func_8010E390(s32 arg0) {
if (g_CurrentEntity->unk14 == 1) {
arg0 = -arg0;
/*
* Updates the Entity acceleration in the X Axis
*/
void func_8010E390(s32 accelerationX) {
if (g_CurrentEntity->facing == 1) {
accelerationX = -accelerationX;
}
g_CurrentEntity->accelerationX = arg0;
g_CurrentEntity->accelerationX = accelerationX;
}
void func_8010E3B8(s32 arg0) {
/*
* Updates the Player acceleration in the X Axis
*/
void func_8010E3B8(s32 accelerationX) {
Entity* player = GET_PLAYER(g_EntityArray);
if (player->objectRoomIndex == 1) {
arg0 = -arg0;
accelerationX = -accelerationX;
}
player->accelerationX = arg0;
player->accelerationX = accelerationX;
}
void func_8010E3E0(void) {
@ -3987,7 +4079,25 @@ void func_80113148(void) {
INCLUDE_ASM("asm/dra/nonmatchings/42398", func_801131C4);
INCLUDE_ASM("asm/dra/nonmatchings/42398", func_801139CC);
void func_801139CC(s32 arg0) {
Entity* player = GET_PLAYER(g_EntityArray);
s32 move = player->facing != 0 ? -3 : 3;
player->posY.Data.high -= 22;
player->posX.Data.high = move + player->posX.Data.high;
func_8011AAFC(g_CurrentEntity, 0x10004, 0);
player->posY.Data.high = player->posY.Data.high + 22;
player->posX.Data.high = player->posX.Data.high - move;
if (arg0 & 1) {
func_80102CD8(3);
PlaySfx(NA_SE_SECRET_STAIRS);
}
if (arg0 & 2) {
player->accelerationX = 0;
player->accelerationY = 0;
}
}
INCLUDE_ASM("asm/dra/nonmatchings/42398", func_80113AAC);
@ -4375,7 +4485,46 @@ INCLUDE_ASM("asm/dra/nonmatchings/42398", func_80123788);
INCLUDE_ASM("asm/dra/nonmatchings/42398", func_801238CC);
#ifndef NON_MATCHING
INCLUDE_ASM("asm/dra/nonmatchings/42398", func_80123A60);
#else
void func_80123A60(Entity* entity) {
Entity* player = GET_PLAYER(g_EntityArray);
if (D_80072F2C & 0x01000000) {
#if 1
entity->posX.Data.high = player->posX.Data.high; //(u16) D_800733DA;
entity->posY.Data.high = player->posY.Data.high; //(u16) D_800733DE;
#else // This one generates the first missing move a0, s0 for some reason?
entity->posX.Data.high = (u16)D_800733DA;
entity->posY.Data.high = (u16)D_800733DE;
#endif
if (entity->step == 0) {
func_8011A328(entity, 0xB);
entity->unk34 = 0x04060000;
entity->step++;
}
if (player->animationFrame == 5) {
entity->hitboxWidth = 12;
entity->hitboxHeight = 32;
entity->unk10 = 0x1C;
entity->unk12 = -0xC;
return;
}
if (player->animationFrame == 6) {
entity->hitboxWidth = 10;
entity->hitboxHeight = 10;
entity->unk10 = 0x1C;
entity->unk12 = 0x10;
return;
}
goto block_7;
}
block_7:
func_80106590(entity);
}
#endif
INCLUDE_ASM("asm/dra/nonmatchings/42398", func_80123B40);
@ -4385,7 +4534,50 @@ INCLUDE_ASM("asm/dra/nonmatchings/42398", func_80124164);
INCLUDE_ASM("asm/dra/nonmatchings/42398", func_801243B0);
#ifndef NON_MATCHING
INCLUDE_ASM("asm/dra/nonmatchings/42398", func_80124A8C);
#else
void func_80124A8C(Entity* entity) {
u32* playerStep = &g_EntityArray[PLAYER_CHARACTER].step;
if (*playerStep == 4) {
s32 playerStep_temp = *playerStep; // might be !FAKE:
switch (entity->step) {
case ENTITY_STEP_0:
entity->animationSet = 0x11;
entity->accelerationY = -0x6000;
func_8010E390(0x4000);
entity->unk5A = 0x50;
entity->palette = 0x819F;
entity->unk4C = &D_800AE294;
entity->unk34 = 0x100000;
entity->facing = 0;
entity->posY.Data.high -= 16;
playerStep_temp = entity->step;
playerStep_temp++;
entity->posX.value += entity->accelerationX << 5;
entity->step = playerStep_temp;
break;
case ENTITY_STEP_1:
entity->posX.value += entity->accelerationX;
entity->posY.value += entity->accelerationY;
if (entity->animationFrameDuration < 0) {
goto block_7;
}
break;
default:
break;
}
} else {
block_7:
func_80106590(entity);
}
}
#endif
INCLUDE_ASM("asm/dra/nonmatchings/42398", func_80124B88);
@ -4479,7 +4671,24 @@ INCLUDE_ASM("asm/dra/nonmatchings/42398", func_8012BEF8);
INCLUDE_ASM("asm/dra/nonmatchings/42398", func_8012C600);
INCLUDE_ASM("asm/dra/nonmatchings/42398", func_8012C88C);
bool func_8012C88C(void) {
if ((g_EntityArray[PLAYER_CHARACTER].unk2E != 0) &&
(g_EntityArray[PLAYER_CHARACTER].unk2E != 8)) {
if (((D_8009744C != 0) && (func_800FE3A8(0xE) == 0)) ||
(D_80072EEC & 2) || (func_800FEEA4(2, 1) < 0)) {
func_8010D584(ENTITY_STEP_19);
func_8010DA48(0xCA);
D_800AFDA6 = 1;
g_EntityArray[PLAYER_CHARACTER].palette = 0x810D;
D_80072F86 = 0;
D_80072F88 = 0;
func_8011AAFC(g_CurrentEntity, 0x24002C, 0);
g_EntityArray[PLAYER_CHARACTER].accelerationY >>= 1;
return true;
}
}
return false;
}
INCLUDE_ASM("asm/dra/nonmatchings/42398", func_8012C97C);
@ -4715,7 +4924,34 @@ void func_80132500(u8 soundMode) {
}
}
INCLUDE_ASM("asm/dra/nonmatchings/42398", func_801325D8);
/**
* Called by entrypoint_sotn, seems to be initializing
* various parts of the sound system
*/
void func_801325D8(void) {
D_8013AEEC = 1;
SsInitHot();
SsSetTickMode(1);
func_80132500(1);
SsSetReservedVoice(0x10);
SsStart();
func_800209B4(&D_80138460, 0x10, 1);
func_80021E38(3);
SpuClearReverbWorkArea(3);
func_80021EEC();
func_80132134();
D_8013B668 = 0x78;
SsSetSerialAttr(0, 0, 1);
func_801324B4(0, D_8013B668, D_8013B668);
D_80138F24[0] = -0x38; // !FAKE: D_80138F24 part of an array / struct
func_80132028(0xE, D_80138F24, 0);
func_80132264();
func_80131FA4(0xA);
func_8002ABF4(0);
func_80029FBC(0);
CdReadyCallback(NULL);
func_80028D3C(0x1010, 0x10000);
}
s32 func_801326D8(void) {
if (D_8013901C != 0)

View File

@ -224,7 +224,7 @@ INCLUDE_ASM("asm/ric/nonmatchings/1AC60", func_8015C9CC);
void func_8015CA84(s32 speed) {
s32 speed;
if (g_CurrentEntity->unk14 == 1)
if (g_CurrentEntity->facing == 1)
speed = -speed;
g_CurrentEntity->accelerationX = speed;
}

View File

@ -133,7 +133,7 @@ void func_80193D7C(Entity* entity) {
entity->posX.Data.high = entity[-1].posX.Data.high;
entity->animationFrame = 0;
entity->posY.Data.high = entity[-1].posY.Data.high;
entity->unk14 = entity[-1].unk14;
entity->facing = entity[-1].facing;
if (entity[-1].animationFrame == 0x32) {
entity->animationFrame = 0x3E;
@ -675,7 +675,7 @@ void InitializeEntity(const u16 arg0[]) {
temp_v1 = *arg0++;
g_CurrentEntity->unk3A = temp_v1;
temp_v0 = (Unkstruct5*)(temp_v1 * sizeof(Unkstruct5) + (u32)D_8003C808);
g_CurrentEntity->unk3E = temp_v0->unk4;
g_CurrentEntity->hitPoints = temp_v0->unk4;
g_CurrentEntity->unk40 = temp_v0->unk6;
g_CurrentEntity->unk42 = temp_v0->unk8;
g_CurrentEntity->unk3C = temp_v0->unkC;

View File

@ -830,7 +830,7 @@ void InitializeEntity(const u16 arg0[]) {
temp_v1 = *arg0++;
D_8006C26C->unk3A = temp_v1;
temp_v0 = (Unkstruct5*)(temp_v1 * sizeof(Unkstruct5) + (u32)D_8003C704);
D_8006C26C->unk3E = temp_v0->unk4;
D_8006C26C->hitPoints = temp_v0->unk4;
D_8006C26C->unk40 = temp_v0->unk6;
D_8006C26C->unk42 = temp_v0->unk8;
D_8006C26C->unk3C = temp_v0->unkC;

View File

@ -41,7 +41,7 @@ void func_801B77D4(Entity* arg0) {
InitializeEntity(D_80180B00);
arg0->animationSet = temp_s0->animationSet;
arg0->zPriority = temp_s0->zPriority;
arg0->unk14 = temp_s0->unk4.data1.unk0;
arg0->facing = temp_s0->unk4.data1.unk0;
arg0->unk5A = temp_s0->unk4.data1.unk1;
arg0->palette = temp_s0->palette;
arg0->unk19 = temp_s0->unk8;
@ -583,7 +583,7 @@ void InitializeEntity(const u16 arg0[]) {
temp_v1 = *arg0++;
g_CurrentEntity->unk3A = temp_v1;
temp_v0 = (Unkstruct5*)(temp_v1 * sizeof(Unkstruct5) + (u32)D_8003C808);
g_CurrentEntity->unk3E = temp_v0->unk4;
g_CurrentEntity->hitPoints = temp_v0->unk4;
g_CurrentEntity->unk40 = temp_v0->unk6;
g_CurrentEntity->unk42 = temp_v0->unk8;
g_CurrentEntity->unk3C = temp_v0->unkC;

View File

@ -25,7 +25,7 @@ void func_801B246C(Entity* arg0) {
InitializeEntity(D_80180A90);
arg0->animationSet = temp_s0->animationSet;
arg0->zPriority = temp_s0->zPriority;
arg0->unk14 = temp_s0->unk4.data1.unk0;
arg0->facing = temp_s0->unk4.data1.unk0;
arg0->unk5A = temp_s0->unk4.data1.unk1;
arg0->palette = temp_s0->palette;
arg0->unk19 = temp_s0->unk8;
@ -73,12 +73,19 @@ void EntityBreakable(Entity* entity) {
}
// TODO: Probably aspsx or compiler flags
// nops in between assignments
// https://decomp.me/scratch/sKMmw
#ifndef NON_MATCHING
INCLUDE_ASM("asm/st/np3/nonmatchings/3246C", func_801B2830);
#else
extern u16 D_80180A60;
extern s8 D_8003CB25;
extern s8 D_8003CB26;
extern s8 D_8003CB27;
extern s8 D_80054319;
extern s8 D_8005431A;
extern s8 D_8005431B;
typedef struct {
/* 0x00 */ char pad00[0x2C];
@ -89,21 +96,21 @@ typedef struct {
/* 0x7E */ s8 unk7E;
} UnkStruct11; // size = 0x7F
void func_801B2830(Entity* arg0) {
switch (arg0->step) {
void func_801B2830(Entity* entity) {
switch (entity->step) {
case 0:
InitializeEntity(&D_80180A60);
arg0->unk7C.modeU8.unk0 = 0x10;
arg0->unk7C.modeU8.unk1 = 8;
arg0->unk7E = 0x38;
entity->unk7C.modeU8.unk0 = 0x10;
entity->unk7C.modeU8.unk1 = 8;
entity->unk7E = 0x38;
case 1:
D_8003CB25 = arg0->unk7C.modeU8.unk0;
D_8003CB26 = arg0->unk7C.modeU8.unk1;
D_8003CB27 = arg0->unk7E;
D_80054319 = arg0->unk7C.modeU8.unk0;
D_8005431A = arg0->unk7C.modeU8.unk1;
D_8005431B = arg0->unk7E;
D_8003CB25 = entity->unk7C.modeU8.unk0;
D_8003CB26 = entity->unk7C.modeU8.unk1;
D_8003CB27 = entity->unk7E;
D_80054319 = entity->unk7C.modeU8.unk0;
D_8005431A = entity->unk7C.modeU8.unk1;
D_8005431B = entity->unk7E;
}
}
#endif
@ -422,7 +429,7 @@ void InitializeEntity(const u16 arg0[]) {
temp_v1 = *arg0++;
g_CurrentEntity->unk3A = temp_v1;
temp_v0 = (Unkstruct5*)(temp_v1 * sizeof(Unkstruct5) + (u32)D_8003C808);
g_CurrentEntity->unk3E = temp_v0->unk4;
g_CurrentEntity->hitPoints = temp_v0->unk4;
g_CurrentEntity->unk40 = temp_v0->unk6;
g_CurrentEntity->unk42 = temp_v0->unk8;
g_CurrentEntity->unk3C = temp_v0->unkC;

View File

@ -181,7 +181,7 @@ s32 func_801BBC3C(Unkstruct5* arg0) {
return diff;
}
INCLUDE_ASM("config/../asm/st/nz0/nonmatchings/394D4", func_801BBCB4);
INCLUDE_ASM("config/../asm/st/nz0/nonmatchings/394D4", EntityTransitionDoor);
void DestroyEntity(Entity* item) {
s32 i;
@ -448,7 +448,7 @@ void InitializeEntity(const u16 arg0[]) {
temp_v1 = *arg0++;
g_CurrentEntity->unk3A = temp_v1;
temp_v0 = (Unkstruct5*)(temp_v1 * sizeof(Unkstruct5) + (u32)D_8003C808);
g_CurrentEntity->unk3E = temp_v0->unk4;
g_CurrentEntity->hitPoints = temp_v0->unk4;
g_CurrentEntity->unk40 = temp_v0->unk6;
g_CurrentEntity->unk42 = temp_v0->unk8;
g_CurrentEntity->unk3C = temp_v0->unkC;
@ -978,7 +978,7 @@ void func_801C3708(void) {
if (g_CurrentEntity->unk7C.modeU8.unk0 == 0) {
if (func_801BCBEC() < 0x40) {
if (g_CurrentEntity->unk14 != (func_801BCC5C() & 1)) {
if (g_CurrentEntity->facing != (func_801BCC5C() & 1)) {
func_801BD52C(4);
}
}
@ -1014,7 +1014,7 @@ void func_801C3E94(Entity* entity) {
entity->unk19 = 4;
entity->animationFrame = entity->subId + 16;
if (entity->unk14 != 0) {
if (entity->facing != 0) {
entity->accelerationX = -entity->accelerationX;
}
@ -1065,7 +1065,7 @@ void func_801C4D18(Entity* entity) {
entity->accelerationY = D_801822C8[entity->subId];
var_v0 = D_801822BC[entity->subId];
if (entity->unk14 == 0) {
if (entity->facing == 0) {
entity->accelerationX = -var_v0;
} else {
entity->accelerationX = var_v0;
@ -1082,7 +1082,7 @@ void func_801C4D18(Entity* entity) {
case ENTITY_STEP_1:
func_801C4CC0();
if ((u16)entity->unk7C.modeS16 < 0x20) {
if (entity->unk14 != 0) {
if (entity->facing != 0) {
var_v0 = entity->accelerationX - 0x2000;
} else {
var_v0 = entity->accelerationX + 0x2000;
@ -1147,7 +1147,7 @@ void func_801C6494(Entity* entity) {
entity->unk19 = 4;
entity->animationFrame = entity->subId + 15;
if (entity->unk14 != 0) {
if (entity->facing != 0) {
entity->accelerationX = -entity->accelerationX;
}
}
@ -1176,7 +1176,7 @@ void func_801C6574(Entity* entity) {
value /= 32;
value = CLAMP_MAX(value, 7);
var_a0 = D_80182488[value];
value = entity->unk14;
value = entity->facing;
if (value > 0) {
var_a0 = -var_a0;
@ -1199,7 +1199,7 @@ void func_801C6678(Entity* entity) {
return;
}
entity->unk14 = entity[-1].unk14;
entity->facing = entity[-1].facing;
entity->zPriority = entity[-1].zPriority - 1;
entity->animationFrame = entity[-1].animationFrame;
entity->posX.Data.high = entity[-1].posX.Data.high;
@ -1239,13 +1239,13 @@ void func_801C7538(Entity* entity) {
entity->accelerationY += 0x2000;
if (entity->accelerationX != 0) {
if (entity->unk14 == 0) {
if (entity->facing == 0) {
new_var = (u16)entity->unk1E - 16;
var_v0 = new_var;
} else {
var_v0 = entity->unk1E + 16;
}
} else if (entity->unk14 != 0) {
} else if (entity->facing != 0) {
var_v0 = entity->unk1E - 16;
} else {
var_v0 = entity->unk1E + 16;
@ -1350,7 +1350,7 @@ void func_801C7884(Entity* entity) {
}
}
INCLUDE_ASM("config/../asm/st/nz0/nonmatchings/394D4", func_801C7958); // Unique
INCLUDE_ASM("config/../asm/st/nz0/nonmatchings/394D4", EntityBloodSkeleton);
s32 func_801C7CF0(Unkstruct5* arg0) {
Entity* player = GET_PLAYER(g_EntityArray);

View File

@ -211,7 +211,7 @@ void EntityDraculaBody(Entity* entity) {
case 0:
InitializeEntity(D_801805E0);
entity->unk3C = 1;
entity->unk3E = 0x7FFF;
entity->hitPoints = 0x7FFF;
entity->unk10 = 3;
entity->unk12 = 0x27;
entity->hitboxWidth = 12;
@ -219,7 +219,7 @@ void EntityDraculaBody(Entity* entity) {
entity->hitboxHeight = 34;
break;
case 1:
entity->unk14 = entity[-1].unk14;
entity->facing = entity[-1].facing;
entity->posX.Data.high = entity[-1].posX.Data.high;
entity->posY.Data.high = entity[-1].posY.Data.high;
entity->unk3C = entity[-1].unk3C & 0xFFFD;
@ -254,7 +254,7 @@ void EntityDraculaFireball(Entity* entity) {
case 0:
InitializeEntity(D_801805EC);
if (entity->unk14 == 0) {
if (entity->facing == 0) {
entity->accelerationX = -0x20000;
} else {
entity->accelerationX = 0x20000;
@ -320,7 +320,7 @@ void EntityDraculaMeteorball(Entity* entity) {
speedX = 0xE00;
}
if (entity->unk14) {
if (entity->facing != 0) {
entity->accelerationX += speedX;
} else {
entity->accelerationX -= speedX;

View File

@ -3257,7 +3257,7 @@ void InitializeEntity(const u16 arg0[]) {
temp_v1 = *arg0++;
g_CurrentEntity->unk3A = temp_v1;
temp_v0 = (Unkstruct5*)(temp_v1 * sizeof(Unkstruct5) + (u32)D_8003C808);
g_CurrentEntity->unk3E = temp_v0->unk4;
g_CurrentEntity->hitPoints = temp_v0->unk4;
g_CurrentEntity->unk40 = temp_v0->unk6;
g_CurrentEntity->unk42 = temp_v0->unk8;
g_CurrentEntity->unk3C = temp_v0->unkC;

View File

@ -1 +1,3 @@
compiler_type = "gcc"
compiler_type = "gcc"
[decompme.compilers]
"mipsel-linux-gnu-cpp" = "psyq4.0"