This one is kind of ugly in places.
It uses offset 0x84 as an s32, while Weapon uses it to hold an entity,
so this forced the creation of a new ext for the heaven sword.
There is only one more function left in this file (EntityWeaponAttack),
so once that one is done, I will move the whole file over to use the
Heaven Sword extension.
Someone in the Long Library discord was asking about Heaven Sword
(especially its special attack) so I'll go ahead and decompile that
next.
This initial function appears to reveal that Heaven Sword doesn't follow
the main Weapon struct. I'm going to keep using it until the weapon is
done, so we can get a better picture of what the mismatching fields are.
All the struct members are the same size, they're just different names.
This PR is trying to get SsVabOpenHeadWithMode running, but I'm getting
the wrong result vs. my test app. I'm putting this up to see if others
have ideas.
c7484b6800/test.c (L154)
I check a bunch of preconditions on the test app and the implementation
so I think they are starting from the same state. The test app is able
to play the library song so I think it's OK.
The problem is that SpuMalloc returns the wrong value. See
```
_svm_vab_start[vabId] = spuAllocMem;
```
_svm_vab_start[0] is supposed to be 0x00001010 but instead we get
0x11010.
c7484b6800/test.c (L201)
```
69648 != 4112 in check_ss_vab_open_head_with_mode /home/d/sotn-decomp-2/src/pc/psxsdk/emu.cpp:306
```
The scratch for SpuMalloc is https://decomp.me/scratch/UjIPd
The version here is based off this one since I think that scratch isn't
usable yet.
4ff48d4660/psx_seq_player/lib_spu.cpp (L2462)
The scratch for func_800286E0 is https://decomp.me/scratch/msP8t
After building for all supported architectures `make format` was taking
around 30s. This commit includes various changes which get that down to
around 3½s on the same machine.
This changes the `format` target in a few ways:
* filters out files generated by CMake
* runs `clang-format` in parallel
* breaks `format` into 3 separate targets which can be run in parallel
When building the PC version cmake creates a file to test compiler
features. This file is picked up by the pattern which matches files for
`clang-format`. This file took around 20s, filtering it out brought
total format time to around 10s.
Instead of passing a list created by a `find` command directly as the
args to `clang-format` the list is now passed to `xargs` which runs
several processes in parallel, each looking at 10 files (determined by
experimentation). This has the added advantage of ensuring as the source
list grows `ARG_MAX` won't be a concern. This brought total format time
to around 6s.
`format` was broken up into three targets `-src`, `-tools`, and
`-symbols`. These targets can be run in parallel, bringing the total
time down to 3½s.
---------
Co-authored-by: Jonathan Hohle <jon@ttkb.co>
This makes changes to get SpuSetReverb, SpuMallocWithStartAddr and
SpuClearReverbWorkArea running. We don't have matches for
SpuMallocWithStartAddr and _SpuMallocSeparateTo3 so the current WIPs are
used. A unit test is added to check that these are creating the correct
_spu_memList. Spu write tests are added for the other functions. To
avoid pulling in the DMA controller _spu_t just does the writes itself.
Decompiles stage header data for all in progress stages.
Of note is that NO3 and NP3 (and likely other future stages) use an
`AbbreviatedHeader` because their `SpriteBanks` start immediately after
`UpdateStageEntities`. There are several areas which use
`sizeof(Overlay)` to copy this data over, in those cases sprite bank
data is copied into the tail fields of the overlay but are never used.
This updates the Makefile so that targets which depend on phony targets
(like `*_dirs`) have direct dependencies on those targets rather than
relying on transient dependencies from dependent targets. Other targets
explicitly create parent directories for their files.
This resolves#739, making it possible to using make-4.4 to build in
parallel.
I'm not sure if I did the data extraction correctly. There is more to
pull out of the remaining `0x106C8` section but the sizes aren't quite
lining up.
`sotn_str` can now handle escaped quotes, right parenthesis, and more in
in `_S` strings. This allows all of the strings in `dra/menu.c` to be
encoded as static C-strings.
This also converts the spell button sequences to UTF-8.
---------
Co-authored-by: Jonathan Hohle <jon@ttkb.co>
Found this function which had a NON_MATCHING.
I'm getting pretty good at finding PSP functions now, so finding the PSP
told me that this was an if-block, not a ternary operator.
PSP also indicated that some of the other lines were using
multiple-assignment, rather than a sequence of individual assignments,
so I made those changes too.
As usual, I don't really know what these do, but it's nice to have pure
matches now.
Now the only functions left with NON_MATCHING are RenderEntities and
RenderPrimitives.
This finishes NP3.
Gaibon's logic is extremely similar here as it is in NZ0. There are a
few differences, especially in the initialization code (which runs
before the primary switch), but as a whole, it's a copy-paste.
Slogra and Gaibon are in separate files. The only way we know this is
because they both have debugging `charal` strings which exist separately
in rodata (if they were the same file, it would reuse the same rodata
location for both strings).
A simple function, but a weird one.
Does a lot of odd stuff with LOW on the x coordinate (and therefore also
y coordinate) of a Primitive.
It's possible that these are weird compiler optimizations (kind of like
the one that does the thing with animation frames on Entities, where it
loads both animation values to compare them), but hard to say for now.
Hopefully with it decompiled, the research to identify what this is
actually doing can come in the future.
This reworks enough writes to libsnd/libspu to make it through the call
to SsInitHot. Instead of raw pointers we have read/write_16 functions.
The writes are saved to an array so we can test against output from
mednafen. See `src/pc/psxsdk/expected/_spu_init.txt`. The gold file is
generated by running a real psx psy-q program that calls the same
function. A modified mednafen prints the writes. There are reads to
spustat and other regs that require particular values to be returned, so
I've also imported and hooked up the SPU part of mednafen.
Not a very difficult one, but it's a little weird. Not sure what this
entity is, it's modifying the GPU buffers directly, and also setting a
castle flag. No other uses of that castle flag as far as I can tell, so
who knows. Once the overlay is complete we can have the full picture to
figure out where this entity even comes from.
`GsInitVcount`, `GsGetVcount`, `GsClearVcount` were all small wrappers
around calls to respective root counter functions using the vsync
counter spec. This provides implementations for all, replacing the
previous ASM imports.
Co-authored-by: Jonathan Hohle <jon@ttkb.co>
This function is kind of crazy and huge.
I also made its helper static.
The name for the function comes from the fact that the duplicate finder
matched this up with a function in NO3, which had been given that name,
so I named this one to make them match up.
This is a helper function for the entity that comes right after it.
It's relatively simple in terms of functionality, but I have no idea
what it's actually doing, so unfortunately everything is completely
unnamed. At least it matches.
We have now fully decompiled every function which had a DECOMP_ME_WIP
comment, and we do not expect to ever have a need to add one in the
future.
Therefore, the function finder can be simplified by removing the process
of searching for these.
With no DECOMP_ME_WIP strings, `get_c_files` will never append anything
to `files`, so it always returns an empty list. We can therefore remove
the function.
With `c_files` always being an empty list, iterating over it will do
nothing, so we can remove `c_files` and the entire block of `for c_file
in c_files`.
Those are all the changes being made here, pretty simple.
This makes changes to allow libsnd/libspu to compile when
WANT_LIBSND_LLE is set. If turned on it will immediately crash due to
trying to write to the SPU. A build is added to make sure it's
compiling.
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...