This is a huge one! Lots of file shuffling needed to happen, but now
that things are in place I feel relatively confident that we have our
file splits in the right places, which is great. It's really cool when
we can make file splits that are motivated by game structure, and not by
rodata limitations.
Anyway, here it is, let me know which flags and stuff I forgot about :)
Another big one! This required mangling the files a little bit; once the
other functions are decompiled the files should come back together
nicely. The function itself is in 4B018.c, and the function is currently
alone in that file.
Kind of a complicated process to get this one working, beyond the normal
function decompilation.
Files are split for now, because there are weird things with rodata. I
have already done the two remaining Gurkha functions, so my next PRs
will pull those in and will end up bringing the files back together.
Messy things here, tried to make it looks nice but as always, feedback
is appreciated.
What is a SOTN? A nasty, miserable little pile of pointer manipulations!
Well here we are, the last one! Solving the previous function helped me
figure out the patterns here, but wow, this is really a miracle.
Let me know how you want to handle the de-duplication. We can either do
that here, or merge this and do all the others in a second PR.
Fairly straightforward de-duplication. If anyone has better names for
either the function or the array it uses, feel free to suggest them, but
with this thing being so weird and its purpose being unknown, I had to
keep the names pretty generic.
3 NZ0 functions remaining? I think you mean 2 NZ0 functions remaining :)
I don't really understand this one, it's a bit of a mess. Lots of
tilemap stuff, so maybe this does something with the weird shifting
backgrounds in the Alchemy lab? Who knows.
I was able to start with the red door code and rely on that a fair bit.
I modified the code to recreate the parts that are needed for the blue
door.
Their entity extensions matched up (with the blue door needing a couple
extra members) so I changed ET_RedDoor to just be ET_Door, and both
doors use it. I'll be curious to see if the weird golden door to the
Olrox fight is similar to these ones.
NZ0 is really getting empty now!
This is a weird function, we don't really know what it does. But
matching is always the first step. Just glad it works.
The behavior on the `dataPtr` makes me sad. Pointers are treated in such
evil ways in this game.
This took me a lot of manual work. But I think I confirmed a pattern
that will help me to automate all of this for all the next stage
overlays that will be imported in the repo.
I noticed some stages with only one room having more than two layers or
more than two tile definitions, it might be either debugging or unused
content? I did not have time to explore any of that.
I modified the `tiledef` splat extension to greatly minimise the set-up
and noise.
Relatively simple function.
I'm trying to get better at things like using good variable names,
organizing files, etc, and I think it pays off. This function is more
readable than it would have been in the initial scratch. Excited to
really get the game into a state where all the code is directly
readable.
PSX: https://decomp.me/scratch/74j2Y
PSP: https://decomp.me/scratch/ons5L
Let me know if you'd like to inline `CLAMP_MIN` and `CLAMP_MAX`, or move
them to `macros.h` or `common.h`. I see a reference to `CLAMP` in
STYLE.md but couldn't find it in the repo.
The duplicate finder missed this one, but I found it indirectly by
looking for the preceding functions, which are all duplicates. This
should actually be the last of the cutscenes (at least, until we get new
overlays).
All these cutscenes have little tweaks to their logic, but nothing very
interesting, so not much more to share here. But cool to have them all
done!
I think this is pretty much ready to be merged it. I do not see much of
a point of having the branch floating around.
I am using a `#ifndef HARD_LINK` to avoid compiling duplicate functions
with the same symbol name.
For data with the same symbol name but different content I am doing a
`#define OVL_EXPORT(x) WRP_##x`. So for example
`OVL_EXPORT(g_EntityGfx)` will be expanded as `WRP_g_EntityGfx`. It is
an unfortunate hack. On the other hand all the data migration allowed me
to mark most of the data and functions as `static`. If we use the same
approach on other overlays we could easily statically link them as well.
SEL is enabled by default. It will take you straight to the real WRP,
not the dummy one.
Most of the changes are loading assets from their respective JSON files.
Linking the stage was pretty straight forward.
Still work in progress. I removed splat as a submodule and started using
it as a pip package instead. Everything is matching but the memory card
icons part in both DRA and SEL. I still have no idea what the issue is.
Once this PR is good to be merged, we can get rid of the splat fork too.
As far as the duplicate-finder can tell, this is the last of the
cutscenes, but who knows - we may find more. Luckily, the pattern is
pretty recognizable.
Named it due to what we see at the very end in `case 7`, with the
TimeAttackController getting triggered.
I was asked to help with #556 , but that is an old PR and I'm not sure I
want to be doing a PR into a PR, so here's this one.
I did not touch the code at all, just shifted around the files and such
in order to get rodata to match.
Merging `wrp_psp/warp.c` into `wrp/warp.c`.
I imported all the BSS data into `wrp_psp/bss.c`. I do not feel it is
yet the right time to split the bss section into the individual files as
I feel it might have a ripple effect to every other overlay.
I confirm empty arrays on PSX are in data, but on PSP they are in bss.
This is currently forcing me to do some `#ifdef` here and there. It
should get solved once the bss is split into their respective original
files.
I feel very positive about the file split in WRP. So far it seems to be
accurate. I really hope to spread this new pattern to other overlays
too. It should make importing new stage overlays in the future much
easier.
Continuing to run the cycle on all these cutscenes.
This one is interesting because it switches on self->params to do
different things - this might signify when the Succubus shows up as
"Lisa", versus after the reveal when it shows up as Succubus. Unsure,
that can be a project for the future.
This adds some additional context for func_801B9744 and renames globals
to fit their assumed purpose.
Migrated various stream metadata to C definitions.
The makefile changes add a dependency on `sel.h` to all the objects that
get built from the `st/sel` directory.
Co-authored-by: Jonathan Hohle <jon@ttkb.co>
Wow. This is perhaps one of the hardest functions I've ever done. It
does disgusting things with pointers that I've never seen anything like
before - some of them are the fault of the programmers, some are the
compiler.
Once I was like 98% done, I found func_801B69F8 which is very similar
(and decompiled), but wasn't picked up by the duplicate finder, so that
was a little sad. Once I found that though, the last of my mysteries
were quickly solved.
This is a huge function and it's nice to get it cracked.
More data imported into the C files. I reached this stopgap due to
`st_debug.c`, where I am failing to import the data from PSP. Strangely
enough, PSP suggests `st_debug`, `e_breakable` and even `warp` being in
the same file?!
The INIT section seems to follow the `PfnEntityUpdates` on both PSP and
PSX. But on PSX this is very close to the top while on PSP is right in
the middle.
Overall the PSX C and DATA order seem to align perfectly. PSP is far
more unpredictable, but the DATA order seem to also follow the C files.
The advantage of PSP is that almost everything is out of order compared
to PSX, which easily suggests file splits.
Another key difference between PSP and PSX is that arrays filled with
`0x00` are found in DATA on PSX and in BSS on PSP.
These are the common implementation. They needed to be split for the
jump tables to be positioned correctly.
Co-authored-by: Jonathan Hohle <jon@ttkb.co>
Boy, this one was a beast!
It created yet another evil awful horrible variant of Primitive, where
it's referencing several s32 values in the struct, so we had to add
another to Primitive.h.
The splat was slightly off, it was missing the nop at the end of this
function.
It appears that this function manages 385 primitives to make the life
max up spawning animation, and puts them all through a bunch of GTE
functions, so I'm wondering if that's why the animation is so laggy.
I'm confused on why this function doesn't show up in duplicates.txt,
since I would have thought it would be universal across all overlays
which contain a boss (which is most of them). Although... now that I
think of it, Slogra and Gaibon are the only bosses in the overlays that
are currently in the decomp, so that's probably why. CEN, DRE, ST0, NP3,
etc don't have bosses so they don't need to have this entity. Hopefully
this ends up duplicating in the other overlays once those get pulled in.
An awful function, but at least it matches!
Given the fact that sharing compiled C objects is not exactly possible
(code heavily copy&pasted maybe? this initiative is now abandoned 👉53a566f075)
I decided to keep pressing forward with shared headers. Thanks a lot to
@hohle for making our life much easier by cross-referencing symbols.
The file split on WRP seems to be the closest file split we might have
compared to the original source code (still speculating here). I think
it would be a good idea to start splitting other overlays too with the
same approach.
My idea is to have a file split like the following:
```
st/
cen/
e_particles.c
e_misc.c
st_common.c
nz0/
e_particles.c
e_misc.c
st_common.c
wrp/
e_particles.c
e_misc.c
st_common.c
e_particles.h
e_misc.h
st_common.h
```
each of those C files will just be a one-line `#include
"../the_shared_code.h"` as usual. Right now we create individual headers
for single functions, sometimes for more than one function when we think
grouping makes sense. But I think we can start merging some of those
headers and consolidate the code. This can be done gradually. For
example `src/st/e_particles.h` is still importing function headers under
the hood. That is okay for now, but later on I wish to import those
headers functions into their respective parent headers.
Another important aspect to consider that will validate a correct file
split is to start importing the data inside these new C files. Right now
we have floating data such as `src/st/wrp_psp/wrp_data_EA00.c` or
monstrosities such as `src/st/wrp/6FD0.c`. An example of a (possibly)
correct migrated data is what this PR does with WRP PSP and NZ0 PSX,
with data pointing in `src/st/*/e_particles.c`.
A few changes here.
First, Slogra needs to be split out to his own file, as mentioned in my
previous PR.
I decompiled EntityCloseBossRoom, but I decided it needed a better name,
since, while it does close the door to the boss room, it actually does a
lot more and in general manages the fight (most importantly, it starts
the fight, spawns Slogra and Gaibon, and when they die, spawns the life
max up). Therefore I named it BossFightManager. Since this function, and
the door blocks it spawns, are the only ones in this file, I decided to
call it bossfight. I think we should try to be liberal with naming
files, once we know all the functions contained in them.
Otherwise I think that should do it! Very cool to have the first boss
fight in the game all figured out.
This was great to get working!
There was a Decompme WIP, but I decided to ignore that and do it from
the beginning, and I think that worked out well. PSP was of course very
helpful.
This ended up being pretty readable with all the steps that were already
documented (I think that was Sonic's doing, so thanks!). Pretty happy to
have this working!
Slogra and Gaibon each have a separate `FntPrint("charal %x\n",
self->animCurFrame);` call in their debug step. Importantly, this string
is in rodata in two places. If Slogra and Gaibon are in the same file,
they share the same string address, and the rodata only gets the string
in one place. Splitting the files restores the duplicated string in
rodata, meaning that these files need to be split.
I have already decompiled EntityCloseBossRoom and found the same issue
there, so my next PR will end up pulling out Slogra into his own file as
well.
Lots of code here, review carefully!
This one was fun! Lots of use of the coordinate transformation
functions, and lots of weirdly packed data.
Had to shift the splat a little bit. This is the last function in the
file (location-wise, not the last to be decompiled) and the end of the C
segment was slightly off.
Pulls out `EntityExplosion` into a common file.
`cen` and `rwrp` appear to have not imported a declaration for
`AnimateEntity` and call it as an undeclared function with a int-sized
return value. Since `AnimateEntity` is declared in the same compilation
unit a workaround is done to fix how the return value is interpreted.