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.
One of the last two functions!
Since this is duplicated in every overlay (but never used in any of
them), it will make sense to de-duplicate this. I will use my automatic
de-duplication script to put it into the appropriate .h file. That can
either be in this PR (after getting the seal of approval), or can be a
separate PR (after merging this initial WRP version). I'm good with any
option.
Very cool though, glad I figured this one out finally! Hopefully the
last one will come along soon...
This function is part of a small network of functions that pass around
Entities and Point32s, so it ends up being a little weird. I guess the
first two elements of an Entity are equivalent to a Point32, but still
weird.
Within this function though, there is nothing to indicate that the args
are Entity, and a PSP function seems to allocate the right stack size to
call this with Point32, so I think we should do that, and have the
callers cast their entities to Point32 if needed.
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.
Decompiles several `EntityWeasponAttack` functions that were grouped by
the deduper. Many of the variations are subtle - change to how the
subtype is calculated, draw mode, setting sprite bank or not, setting
vars or not.
Co-authored-by: Jonathan Hohle <jon@ttkb.co>
Instead of sending one single draw call, this batches as much calls as
possible. I am supporting the vertex buffer with an index buffer to
minimse how much data is sent to the driver.
The `StoreImage` got some minor boost too.
A tiny helper function for the cutscenes in the game.
This is a duplicate function. It exists right before every cutscene
function that I've been decompiling, and this one is no different. I
directly copied and pasted it (wow, I'm just like the original SOTN
programmers :D).
Nothing special at all here, I literally just pasted it, never even
looked at assembly, but it matches.
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>
This is an old function which is decompiled, but is messy. It had an
Unkstruct, which I determined to be a variant of the Primitive.
Therefore, we add a new Primitive version to Primitive.h, and delete the
Unkstruct, rewriting this function.
Hopefully decompiling the caller will help to determine what this
function does, as well as what the unknown primitive members are.
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.
One duplicate and one near-duplicate.
`func_801B101C` ([decomp](https://decomp.me/scratch/K87Ql)) is listed as
a 96% match of `func_801B76F0` but it seems to be using a slightly
different Dialogue struct.
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>