This is doing a few different things; I'm sort of finding issues and
fixing them one by one. I've found more, but don't want this PR to get
too bloated.
1) Removal of more uses of ET_Generic, and eliminating a few of its
members
2) Renaming EntityUnk15 to EntityGreyPuff
3) Reworking Animset data. It's s16, not u32, so the data in d_2F324.c
has been adjusted to match that.
Spriteparts data is the same between bat and ghost, so I moved them to a
shared header.
If they are different than other familiars, we'll have to rename the
shared header.
A small refactor renaming a global variable for when the cutscene has
control of the engine.
In servant, it short cuts the main update function so that your familiar
isn't doing stuff while a cutscene is running.
Also some flag cleanup.
I've figured out quite a bit with the functions and how they are called.
It looks like most of the functions in ServantDesc are actually update
functions called by using the entityId as an offset. I want to update to
make that more clear, but I want to isolate that into it's own PR and I
already had this refactor in flight.
Lots of cleanup here to make the code easier to read.
1. Adding CLUT index defines to avoid magic numbers
2. Adding InitializeMode enum and hooking that up
3. Updating function names for servant init
4. Cleaning up magic numbers used in tt_000 init function
I wanted to add a enum for the EntityId, but both servants share 0xD1.
Looking at the other EntityIDs definitions, there seems to be some
crossover, but it also looks like they may be partly unique across the
different binaries. Probably need more study to figure out how to unify
them (or if it's even possible to unify).
We also may want to look at splitting enum definitions and defining
flags/fixed values into some sort of enum file structure. Having them
all in game.h is making a large file. But we would obviously not want to
fracture the codebase more. Either way, that's way beyond the scope of
what I wanted to do here.
Adds the CEN overaly to the HD version of the game.
Resolves#1638.
This uses most, but not all, matching functions. Some were excluded
because due to symbols mapping that has not bee completed yet.
Not all data has been imported, and mapping symbols, and data should
make many of the remaining functions easy to import.
Primary goal here was to eliminate `ext.generic.unkB0`. It turns out
that the only entity that reaches up into this unkB0 region is the
Subweapon entity.
I went through and changed these all to `ext.subweapon.subweaponId`, but
also did some analysis on all the uses to make sure this was an accurate
change to make.
Other highlights:
- Naming CheckSubwpnChainLimit and its RIC counterpart
- Moving the RIC version of that function to the next file, split makes
more sense this way.
- Made both versions of that function `static`
- renamed subweapondef's unk6 to be chainLimit
- Changed g_unkGraphicsStruct.unk0 to be called `pauseEnemies`. It's
true when the stopwatch subweapon is used, and in cutscenes. Found this
due to looking at the stopwatch subweapon setting this value. Also made
it a bool since it's only ever used as a bool.
- Added some playersteps enum uses where they were still using hex
values
- Studied RicEntityStopwatchCrashLightning in order to give it that name
I think that's about it. Overall just some modest cleanup, but continues
to make the game code more readable.
Decompilation of func_us_80171864
Adding ET_Ghost for the Entity.ext union.
Thanks to @sozud for setting up a PSP environment for me.
Thanks to @joshlory for figuring out the last bit.
This adds this overlay to the project.
Importantly, we use a new tool (tools/auto_dedupe_new_overlay) to
process the new overlay and automatically split its C files according to
known duplicate files. As of now, this does not do any decompiling (the
whole overlay is kept as INCLUDE_ASM), but it automatically does all the
file splits and code copying needed. Hopefully this reduces some amount
of duplicated work.
To be clear, this new script is not in any build chain, but is meant to
be used after `make-config` to take the overlay from being a single
giant lump of `us.c` to being individual files, for the sake of easier
deduplicating. It will likely need some revision for future overlays,
but at least it should be a good start toward reducing tedious work.
I'll leave this overlay in place like this for about a week in case
there are any newcomers who would like to try de-duplicating some of
these files and decompiling the new functions; after that week I'll get
into doing things myself.
Minor follow-up to #1686 . I couldn't de-fake the g_Dialogue symbols in
ST0 like I did with `src/st/dre/bss.c` due some functions that are not
yet fully decompiled.
Various small cleanups on this function.
In the past it was EntityStrongWarg, but I found that this is actually
the Fire Warg.
It is unused in NO3, but is used in RNO3.
Also removed a Multi that was being used that applied across two
different entities.
Various comments, cleanups, renamings, etc
Thought this was going to be more work as duplicate report had it at 93%
and with a jump table, as it turns out I think they're the same besides
a single global memory address
More research on how cutscenes work.
I normalized all the various C files as `cutscene.c`, marked all the
isolated function as `static` and renamed the main entity as
`{STAGE}_CutsceneExec` (e.g. `CEN_CutsceneExec`). I am using the
`OVL_EXPORT` to automate the names.
TO-DO:
- [x] Rename entity as `{STAGE}_EntityCutscene` for consistency
- [x] CEN
- [x] DRE
- [x] NO3
- [x] NZ0
- [x] ST0
- [x] MAR
~~SEL~~
The offset of the portrait data seems to be hardcoded. I have no idea
how to resolve these offsets at compilation time. The entire cutscene
script thing is very sketchy and horribly designed by the original
developers. What a nightmare to integrate into our project.
This is how a cutscene script gets decompiled:
```
LOAD_PORTRAIT(0x80188D8C, 0),
SET_PORTRAIT(1, 0),
SCRIPT_UNKNOWN_11(),
PLAY_SOUND(0x37B),
WAIT_FOR_SOUND(),
SET_SPEED(4),
'T','h','a','t',' ','v','o','i','c','e','!',' ',
SET_WAIT(16),
SET_SPEED(3),
'A','l','u','c','a','r','d',',',
LINE_BREAK(),
SET_WAIT(16),
SET_FLAG(2),
'i','t','\'','s',' ','y','o','u','!',
SET_WAIT(48),
NEXT_DIALOG(),
```
`CutsceneUnk2` uses 8 prims but only 7 are allocated. It looks like at
some point the game writes to the address `0x00000000` but I did not
confirm it with a PS1 debugger. This is a potential bug. `CutsceneUnk2`
signature was also wrong.
I had to get rid of `GfxBank` in `src/st/cen/header.c` and I probably
need to do the same for the other header files. The code reads chunks of
WORDS at the time and a structure would be too large to include
`GFX_TERMINATE` in it.
CEN is there but not linked because it conflicts with some WRP symbols.
I decided to take a much simpler approach compared to what I did with
WRP (which needs to be refactored later on).
There's a cutscene parser. The asset manager is exporting it to
`src/st/cen/cutscene_data.h` if you want to have a look. I know I am
still using `config/assets.us.weapon.yaml` and it probably needs to be
renamed as `config/assets.us.yaml` later on. I am still deciding.
* `ProcessEvent`
* `CreateEventEntity`
* `CalculateAngleToEntity` (the function formerly known as
func_80173F30)
* `GetTargetPositionWithDistanceBuffer` (the function formerly known as
func_80173F74)
There's 4 more duplicates which I'll start on separately so as to not
make this PR too big.
- Decompiled duplicate function func_us_801714F4
- Decompiled duplicate function func_us_80172904
- Decompiled duplicate function func_us_8017293C (renamed
Tt001UpdateAnim per tt_000 duplicate)
- Decompiled duplicate function func_us_80172B50
- Decompiled duplicate function func_us_80172B88
- Added EntitySearch D_80170EE4[] to servant.h to be used by
func_us_80172B88 similar to duplicate in tt_000
A lot of these are in the same order in tt_000, so I would assume they
could be moved to shared static functions at some point.
this one was trickier and larger than my previous contributions. I'm not
sure what the best way to rename the symbols are, so I expect to receive
some comments on that.
The decompilation script did not like to decompile anything from tt_001
because it ended in us.c. This would cause it to find muliple (5) paths
and would halt.
Change moves the code to F84.c in line with the code split in tt_000
Followed [the
guide](https://github.com/Xeeynamo/sotn-decomp/wiki/Decompilation#add-new-overlay)
which seemed to work relatively painlessly for this overlay.
I hit an issue in `make-config.py` where no duplicates were found and
have added a separate commit which fixed that. Otherwise no issues with
guide.
```
josh@JoshsPC:/mnt/c/dev/sotn-decomp$ tools/make-config.py tt_001
✔ generating psx splat config
✔ splitting config/splat.us.tt_001.yaml
✔ adjusting files at src/servant/tt_001
✔ disassembling matched functions
✖ finding duplicates across overlays
Traceback (most recent call last):
File "/mnt/c/dev/sotn-decomp/tools/make-config.py", line 1132, in <module>
raise e
File "/mnt/c/dev/sotn-decomp/tools/make-config.py", line 1126, in <module>
make_config(args.input, args.version)
File "/mnt/c/dev/sotn-decomp/tools/make-config.py", line 1106, in make_config
if found > 0:
TypeError: '>' not supported between instances of 'NoneType' and 'int'
```
I was also able to remove the weird `goto block` on `RicMain`.
The HD version seems to be an older version. I am not entirely sure of
the US changes, but it seem to fix a series of bugs when Richter gets
grabbed by Gaibon? There's a new debug string which ints
`g_Player.unk7A` being named as `run_disable_f` but I did not yet rename
it.
I went through all of CEN, cross-referencing it with WRP to make as many
files match as possible. This involved pulling in data (which had been
pulled in on WRP but not on CEN yet), renaming shared variables to not
have placeholder names, adjusting file splits, and more.
EntityBreakable seems to be very different here, so I did not do any
deduplication on that one yet. I think we need to get a robust system
for deduplicating across stages so we can share .h files even when the
stages are different. Right now there's no way for an included .h file
to know it's part of CEN (at least, that I know of).
This is similar to other cutscenes but with a few minor differences. Of
note is that the PSX version uses an uninitialized pointer.
Pulls in the remaining duplicates and `func_us_8018C90C` as well
finishing off the remaining functions in `boss/mar`.
This completes the migration for all stages into e_misc.h. They are now
all using it in a unified manner.
It's very satisfying to have everything coming together across the
stages like this!
First working version of this.
Next steps will involve doing #ifdef to unify the function, but wanted
to start by getting something in that matches by itself.
Several quality of life changes for building:
* The Makefile has a `help` target which will show common targets.
Targets with comments starting with `##@` will be included in the help
output.
* The `check` target now has colored output.
* Added `check_disk` target which will check hashes of extracted disk
contents (useful for those who dump their own discs)
* Added `dump_disk` target which will create a bin/cue pair from an
original disc.
Good amount of deduplication here.
The only issue I ran into is that NZ0 has slightly different data for
one array (it's missing two zeros at the end). I tried doing `#undef
STAGE #define STAGE STAGE_NZ0` in `nz0.h` and testing `#if STAGE ==
STAGE_NZ0`, but for some reason that was failing. I went with `#define
STAGE_IS_NZ0` and `#if !defined(STAGE_IS_NZ0)` for now; not sure what I
was doing wrong.
Pulls this function into a .h file.
Since each overlay uses a different offset into g_CastleFlags, we use
`#define HEART_DROP_CASTLE_FLAG` before each `#include` statement in
order to set these up correctly.
Next we will hopefully be able to dedupe e_misc.c, but that will take a
bit longer especially since PSP still needs EntityRelicOrb done, but I'm
working on that one now.
PSX: https://decomp.me/scratch/RL97B
PSP: https://decomp.me/scratch/3WKmX
`func_us_8018B4A0` needed to be decompiled before importing all the
assets due to GCC compiling `PfnEntityUpdates[entity->entityId - 1]`
into a hardcoded offset landing to the `header.c` data as a fake symbol.
The decompiled function seem to be some kind of object spawner for the
cutscenes controller. I have yet to confirm that, so I did not rename
any symbols yet.
EDIT: `func_us_8018B4A0` turned out to be a shared function I renamed as
`CutsceneRun`. DRE and CEN use slightly different variants and they will
not use the new `cutscene.h`. I plan on putting more stuff into
`cutscene.h` in a separate PR and maybe rename all the C files that
handle cutscenes accordingly.
Matches 72% of the entire overlay in one go. Around 80% of the overlay
code is made of duplicate function.
A few observations:
* `func_us_8018AC0C` seems to be an older, buggy version of
`func_801B246C` and it seem to indicate `ObjInit2` was either a `u16`
array or there were macros involved.
* `e_breakable` is the same function, but the data changes in most
overlays; I had to pull the data out. The SFX ID is also different.
Data handled through the asset manager and BSS will come as part of a
separate PR.
This PR prepares MAR to be de-duplicated easily. I just de-duplicate
some easy C files. I am submitting this as it is to allow @sozud to
submit #1610 without any delay.
note: it took me longer than I expected to do this. It is a step it
would really be beneficial to have automated in the future via
`make-config.py`
Renames the file, imports the data, and uses the .h in every overlay.
Given that this one doesn't have any PSP craziness, would this maybe be
a place where it would make sense to copy in the function C code? Right
now st_update.h is just an array definition and a few #include calls for
the .h files for `random.h`, `update.h`, and `update_stage_entities.h`.
I noticed that there was large overlap between these, but it was
incomplete as different stages had different levels of de-duplication
completed.
I went through and completely de-duplicated this file, so it is now
st_common.h everywhere.
There were a few leftover functions in MAD and ST0, so I decompiled
those in my previous PRs, and now in this one, I'm doing ifdef to make
it all match for all stages.
This is pretty cool and represents a large amount of code reduction.
The original C file which was used as the basis for st_common.h was the
WRP one, which has PSP support, so this may be a great step to making
many overlays match on PSP too.
ST0 has a different version of this function, which was not yet
decompiled. Other people had some scratches, but they weren't very
close.
I took the function that exists in other overlays, and removed code
until it matched.
Might try to de-duplicate this with ST0 ifdef stuff, but for now, I
wanted to just get the single decompiled function reviewed.
RotMatrix
RotMatrixYXZ
RotMatrixX
RotMatrixY
RotMatrixZ
ScaleMatrix
I think these are handwritten because they heavily use $t registers,
which is not like the code gcc produces. It makes sense for these to be
hand-optimized since they are speed-critical. Also, these don't use the
`ctc2` etc. instructions so I don't think it's a mix of C and gte
macros.
I dumped all the remaining gte funcs to a gist if others want to inspect
these https://gist.github.com/sozud/62a6a4a7f751010d435714a5191c46f3
Not a big PR. The highlights are `g_Player.timers` and
`entity->hitParams`. The last one is a bit weird as it looks like a mix
between `attackElement` and `hitEffect`.
The `var_s4` on `RicMain` is uninitialised and it leads to an undefined
behaviour. Recompiling the code for PSX by moving things around, that
variable will not be `0` at the beginning but some random value. This
prevented Richter's run, blade dash and high jump to work. I added an
`#ifdef` in case people wants to mod the overlay.
This is probably the last batch of changes for RIC for a while.
List of the most important changes:
* The two fields in `FACTORY` are now reversed; what used to be
`FACTORY(0x2000, 44)` is now `FACTORY(44, 0x20)`
* Introduce `WFACTORY` to imply `((g_HandId + 1) << 0xC)` in it
(`((g_HandId + 1) << 0xE)` is not yet cracked)
* Remove `assets/ric/blueprints.json` in favour of baking the info into
a C file to easily link enums
* Add `B_MAKE` to define a blueprint entry
* Document almost all RIC entities
* Document almost all RIC blueprints
Follow-up to #1569 .
Loads of changes, where the most prominent one is synchronising the
`self->ext.*.subweaponId` field across entities to make it work on
`RicSetSubweaponParams`. I added some static assertions with the new
macro `SYNC_FIELD`, which is easier to read.
The new `enum RicSubweapons` decouples the subweapons of Richter from
those found in DRA. This is important because
`assets/ric/subweapondefs.json` is different from the definition stored
in DRA.
I discovered new entities and renamed them accordingly. I am following
the format `RicEntity` for each entity. Then `RicEntitySubwpn` or
`RicEntityCrash` for the appropriate category.
The BSS section has been assigned to the right places and `ric.h` has
been cleaned as most of the declarations are no longer necessary. More
data and functions have been marked as `static`.
`src/st/st0/2DAC8.c` had a reference to `.ext.agunea`, which was
probably put there by mistake. The fake symbol `D_801758D0` has been
removed and I think I found a way to fix the stopwatch subweapon without
the `#ifdef`.
```c
#ifdef VERSION_PC
#ifdef _MSC_VER
{
s32 temp_x = (rcos(primLine->angle) << 8);
s32 temp_y = (-(rsin(primLine->angle) << 8));
primLine->velocityX = *(f32*)&temp_x;
primLine->velocityY = *(f32*)&temp_y;
}
#else
primLine->velocityX = (f32)(rcos(primLine->angle) << 8);
primLine->velocityY = (f32) - (rsin(primLine->angle) << 8);
#endif
#else
primLine->velocityX = (rcos(primLine->angle) << 8);
primLine->velocityY = -(rsin(primLine->angle) << 8);
#endif
```
this one has been resolved by just using `velocityX.val`.
I documented all the `PLAYER.step` for Richter and got the meaning of
most of the functions with their parameters. There are some additional
renaming and magic numbers documented that are not worth to mention
individually.
I plan to get rid of `EntityTypes` as it is not sustainable to document
256 combination of entities. Instead I am thinking it would be a better
approach to document the `g_Entities` indices as ranges. For example
from `32` to `47` we have particles, from `48` to `64` we have player
entities that can hit the stage entities and so on.
I re-organised and re-imported some of the data close to the function
that use them. This will allow me to later split entities into their own
units as separate C files.
In addition to decompiling the function, two big changes were needed:
- Decompiling this function uncovered a maspsx bug with generating `nop`
padding instructions; that is now fixed and this PR includes a maspsx
update.
- We also discovered (thanks @mkst !) that g_Tilemap.bg was not actually
a member of g_Tilemap. I renamed it to g_BgLayers, and did a
find-and-replace across the repo to change all references. This appears
to have no impact on any existing function, but leads to the correct
register loading on this function.
It's a weird one, and was tricky to get matching (actually, this was a
super old decomp.me browser tab I discovered was still open, which is
why I came back to it), but these tricky ones are great for discovering
where we have mistakes in our structure of the game's data.
Renamed `PLAYER_ext_generic_unk7C` to `PLAYER_ext_player_anim` since we
know the player entity is being referenced.
Added a size comment to `WeaponAnimation` to help me find it next time
I'm looking for an `0x10` sized struct.
NO3 and NP3 had a weird mix of Bone Scimitar functions where each was
partially complete and missing different parts.
Now both are complete and modernized. Could use another pass to make it
PSP-matching, but for now I'll leave this one at this point where the
code seems nice.
Main changes here involve renaming the Ext member from `et38` to
`wargpuff` which seems more descriptive.
Also added entity ID numbers across the overlays, to be used in the
function right before the warg puff function, which spawns the warg
puffs with a call to `CreateEntityFromEntity`.
- Rename func_801733D4 to BatFamiliarBlueTrail
- Add PSP symbols for several various variables used in `func_80172120`
- Attempt to get `func_80172120` closer to matching on PSP. Almost got
it but not quite working; this is at least an improvement. Scratch:
https://decomp.me/scratch/QBytP
- Create `Ext` for BatFamiliarBlueTrail; all it uses is the parent which
is the same as Factory, but still better to have its own until we know
the real situation for entities.
- General commenting to make flow of functions clearer.
Copied the `EnttityMerman` and `EntityMerman2` implementations from NP3
to NO3. These are identical, however, rely on too many things which
require renaming to share at this point.
NO3's `EntityMerman2` was previously `EntityMerman3`, but is identical
to NP3's Merman2, so it was renamed to match.
A small amount of cleanup was done to the implementations to bring them
closer to current standards.
Might try replacing the clut with actual 16 bit colors. Is this the
right macro to use?
```
#define COLOR16(r, g, b, a) (r) + ((g) << 5) + ((b) << 10) + ((a) << 15)
```
This is a proposal on how I would like the naming scheme going forward
for the player. The proposal includes the naming and layout once we
document Alucard and decompile Maria (PSP). Please let's agree on naming
and structure so it can be easy to hack and plug new custom characters
at any time.
* Animations to have `XXX_anim_yyy` where `XXX` is three letters for
`arc`, `ric` or `mar` (`arc` taken from `BIN/ARC_F.BIN`). To mark them
`static` whenever it is possible to do so.
* `PL_S_xxx` to mark a player step. Steps might be similar between the
three different players, but they must be isolated into the respective
headers `dra.h` for Alucard, `ric.h` for Richter, `mar.h` for Maria. I
am aware that Alcuard steps are used in weapons, which is why they are
currently found in `game.h`. This needs to be addressed at some point.
* PL_T_xxx` for the various timers from `g_Player.D_80072F00`. Those
_might_ be need to be shared between all players, we need more research.
* `XxxHandleYyy` for the step handlers. You will see `RicHandleJump` to
handle `PL_S_JUMP`.
* `XxxSetYyy` for the functions responsible of transitioning into a
specific step (see `RicSetJump`)
Prefer imperative verbs than paste tense or anything else. So `dead`
instead of `killed`, `run` instead of `running` and so on.
Functions and animations have `Ric` or `ric_` pre-pended since those
symbols are publicly exported and not marked as static. But `#define`s
and `enum`s that are isolated into the player's header should be
generic.
I cracked the animation system, so I created the macros `A_END`,
`A_LOOP_AT` and so on.
In a next pull request I will change `Entity::unk4C` into
`Entity::anim`. I did not want to include it here to not change too many
files in one go.
Just some symbol renaming; this is a big task and will probably take
lots of research to work out how all the different interwoven systems
work, but this is some starting steps.
This is a simple synchronization between methods already decompiled in
NP3 to their counterparts in NO3. Player water effect has been split to
match, but no data has been mapped in this pass.
Decompiles methods based on the NP3 implementation:
* `EntityBackgroundBushes`
* `func_801B94F0`
* `func_801D0A2C`
* `EntityAlucardWaterEffect`
* `EntityMermanSpawner`
* `EntityMermanExplosion`
Splits `e_bone_scimitar`, and `player_water_effect` into a separates
file to match `NP3`.
Maps `create_entity` and `e_collect` data, text, and bss for all stages.
Adds macros for defining padding for various sections by size.
Tables for section sizes have been added to common includes to make
calculating offsets easier when segments.
This change moves BSS variables into their most appropriate compile
unit, "decompiles" several data files, and splits out some existing data
into its logical unit.
BSS data has all been removed from `bss.c` and moved to a file where the
data is either first used or where it can be made static.
Several data files have been converted to appropriate types and added
to the most appropriate file. This converts the header related
references and some of the other early data.
Finally, some data like has been rearranged and moved into logical
compile units like data from `entity.c` into `holyglassescutscene.c`.
Logical boundaries were chosen based on where data could be made static.
Allow to compile weapon overlays as a single C files. The benefit is to
disallow symbols to be exported by statically compile them all but the
header. We would no longer need to use `OVL_EXPORT` as long as the
symbols are marked as `static`. The frames data is also generated as an
array of data that can be just included into their respective C files,
generated by JSON files on the fly.
I changed `animset` to `frameset` as the data does not represent a set
of animations but rather a set of frames, where every frame has multiple
sprites. The information on how the frames are played (e.g. animation)
is found elsewhere.
Following the full list of changes to achieve this project:
* The `animset` from splat is now dummied out
* The `frameset` JSON is now generated by the asset manager
* The `frameset` JSON is now compiled into `src/weapon/w_0xx_y.h`
* The `header.c` has been moved into `shared.h`
* For simplicity I added a `#define g_Animset w_000_1`. I did not want
to hack the asset manager too much to force the name to be `g_Animset`
and I did not want to change all the symbols yet.
* Simplified `weapon_pc.c` as we now only need the exported header
* Always try to build the most up-to-date asset manager: this should
avoid weird errors whenever people pull new changes
As the asset manager now can accept those `config` files, now the CLI
supports the following commands:
* `stage extract`
* `stage build`
* `config extract` (NEW)
* `config build` (NEW)
The config structure is heavily inspired to Splat to maintain
consistency and continuity.
I did not do it for `weapon`. This is the script I used:
`python3 a.py asm/us/st/dre/data/23264.sbss.s > src/st/dre/bss.c`
```python
import sys
with open(sys.argv[1], "r") as f:
lines = f.readlines()
print('#include "common.h"')
print("")
for line in lines:
if line == "\n":
continue
elif line.startswith(".include"):
continue
elif line.startswith(".section"):
continue
elif line.startswith("glabel"):
label = line[7:].replace("\n", "")
len = 0
elif ".word" in line:
if len > 0 and n != 4:
print(f"WARN: {label}", file=sys.stderr)
n = 4
len += 1
elif ".short" in line:
if len > 0 and n != 2:
print(f"WARN: {label}", file=sys.stderr)
n = 2
len += 1
elif ".byte" in line:
if len > 0 and n != 1:
print(f"WARN: {label}", file=sys.stderr)
n = 1
len += 1
elif line.startswith(".size"):
if len == 1:
if n == 1:
print(f"u8 {label};")
elif n == 2:
print(f"u16 {label};")
elif n == 4:
print(f"u32 {label};")
else:
if n == 1:
print(f"u8 {label}[{len}];")
elif n == 2:
print(f"u16 {label}[{len}];")
elif n == 4:
print(f"u32 {label}[{len}];")
```
the script is a bit dumb. It does not account of the header. Some types
are wrong compared to their prototype. The memory layout matches though,
so we can keep iterating on top of this.
Adds an a PSX implementation of `EntityRWarpRoom`. This is similar to
`EntityWarpRoom`, but needs to raise and lower the player stands on, and
obviously has to warp to other inverted rooms.
This also pulls in the remaining data and static storage, completing the
`rwrp` mapping.
---------
Co-authored-by: Jonathan Hohle <jon@ttkb.co>
The most important thing here is that D_170000_8017CBD0 is an array of
f32 values. But since entry 0 is only accessed with `.i.hi`, the
auto-detected symbol was `CBD2`, offset by 2, so I had to manually make
the symbol for this one variable. I studied the symbols file to figure
out how to declare it, and this ended up working. Now that I know how to
make weapon symbols, I can start making useful names for these in the
future. Not for this one though, this doesn't make any sense.
Brings DRA up to one function remaining.
I think everything is in order, but looking forward to any suggestions.
The last missing function is a pretty irrelevant Kanji function, so it
will be nice to have all the material to really start understanding DRA
now.
Start to perform a series of code refactoring to align the various
overlays on how NZ0, WRP and RWRP are currently organised, aiming to
share as much code as possible. This is a good stop gap that does not
change too much. There are virtually no major changes other than the
removal of the fake symbol `D_8003BEEC`.
I found it is very hard to share every single line of code due to some
minor differences in the castle flags. I couldn't yet spot a reliable
pattern on how castle flags are manager across stages.
My vision is to share as much code as possible, possibly not as header
files but as C files in a similar fashion of #1425 . I am aiming to
model NP3 so we can merge it with NO3 given the fact they share a good
chunk of the code base.
I am waiting to split the rest of the entities into their own individual
files. My idea is to have a file per entity or per entity group with
their own set of data and helper functions, possibly all marked as
`static`. We agreed it is probably a good idea to wait exploring the PSP
build of NZ0, NO3 or NP3 before performing this step.
This will decompile all the functions but the new `EntityRWarpRoom` from
the RWRP overlay.
Note that as `e_misc.c` has a function with a different castle flag, I
had to use a shared header. Everything else was identical.
---------
Co-authored-by: bismurphy <tjmurphy@mit.edu>
Mostly identical to MAD and PSP. There are four very different functions
from US that needs to be decompiled to be 100% complete:
* [x] `e_misc.c` `EntityMessageBox`
* [x] `e_misc.c` `EntityRelicOrb`
* [x] ~`e_stage_name.c` `StageNamePopupHelper`~ it does not exist
* [x] `e_stage_name.c` `EntityStageNamePopup`
These four very different functions are the only ones that use the JP
text instead of the US one. This overlay also lacks of `BlitChar`.
`EntityStageNamePopup` is very similar to the PSP counterpart. I used
@joshlory scratch to match the HD part.
`EntityRelicOrb` had some #ifdef between US and BETA (aka the MAD
overlay). I found some code that crossed between BETA and HD, so I just
put an `#else` after `VERSION_US`. We are starting to reconstruct how
the source code originally evolved across different game builds.
The vast majority of this comes from a 6-month-old scratch by
@ser-pounce , here: https://decomp.me/scratch/7Ram0
I finished it up, and made some changes to make it fit into the current
state of the repo.
That scratch puts the isrgb24 value into a StreamCtl struct. I'm
inclined to agree with that, but want to minimize the impact of this PR
on the larger repo for the moment. I expect StreamCtl to be used more
heavily in the final function for SEL, but we'll see how that goes.
The StreamEnv struct is in exactly the same location as
Unkstruct_801B9B7C (which was actually unused), so I eliminated that
one.
That's just about all I have to say for now.
The next function of SEL, func_801B99E4, makes it clear that D_8003C908
is not a struct member. I do not know why it was placed in this struct.
I have that function now matching, but since we're changing around
variables that are used elsewhere, I decided to split the PR so that we
can handle one type of change at a time.
The D_8003C908 variable has not yet been used in any C code, so this
change does not affect anything.
Further, since both struct members were s32, I decided to make it a
2-member array for the sake of conciseness in the code.
Changelog:
* Import all the PSP WRP data that belong to `e_collect.c`
* Remove the `ext.generic` use in favour of `ET_EquipItemDrop`
* Document some fields from `ET_EquipItemDrop`
* Discover the extra field `mariaSubWeapon` on PSP
* `g_api.AddToInventory` signature changed to allow a better match on
[EntityEquipItemDrop](https://decomp.me/scratch/PULKm)
* Remove the fake array `D_8003BF9C` in favour of `g_CastleFlags`
* The `O_TAG` struct is also valid on PSP
* Decompile `EntityPrizeDrop` on PSP
* Align `func_8018CAB0` to PSP
* Align `EntityPrizeDrop` to PSP with a bunch of `#ifdef`
* Align `EntityEquipItemDrop` to PSP using the WIP scratch
[EntityEquipItemDrop](https://decomp.me/scratch/PULKm)
* `DestroyCurrentEntity` is just an dummy item collector from
`EntityPrizeDrop`
* Duplicate functions in other overlays are not yet aligned as I am
waiting to migrate them to use `e_collect`
I noticed splat is not able to successfully recognise pointers if the
data is too scattered. I had to merge the `data` in the YAML and allow
it to be exported into a single file before starting to import it.
The only missing function from `e_collect.c` is
[EntityEquipItemDrop](https://decomp.me/scratch/PULKm).
Data on PSX are slightly shuffled within the same C file. I believe the
PSP build retains the original data order.
Thanks to @sozud for the majority of the work on `EntityPrizeDrop` and
`EntityEquipItemDrop` on PSP. And thanks to @bismurphy for solving the
last piece of the puzzle to match `EntityPrizeDrop`.
Wow! With this one, Richter is now down to a single non-matching
function (it's a duplicate of a DRA function which is missing - the one
with the funny pointer math which is connected with
EntityPlayerDissolves).
Anyway, we're matching. This is different from DRA's
EntityPlayerBlinkWhite, but in weird ways that made it a huge pain to
get matching. Definitely was not a matter of replacing a few lines like
some duplicated functions are.
Anyway, looking forward to see if there's anything to fix!
This was decompiled by @joshlory , but due to some annoying rodata, I
ended up taking over the PR on their behalf and submitting. The file
split here was a bit tricky to get right, but now we're matching.
I did not do any reviewing of this code, it is presented here as it was
made by josh's scratch.
RIC had 3 functions remaining, one of which was this one. Given its
similarity to the one in DRA, I decided to revisit it, and thankfully it
now matches.
I also did some cleanup on the DRA one, including renaming variables,
using macros, etc.
We now have two functions remaining in RIC. They are both duplicates of
remaining DRA functions, which have the same issues as the DRA ones do.
This means that once DRA is solved, RIC will be too, which is amazing!
This function was previously the last function in its file.
Upon decompiling, the rodata (specifically the `00 00 00 00` pattern)
indicated that the file does not end here, and that in fact the entire
following file should be part of this file, so I had to change the
splits to accomplish this.
It's an ugly function, and was hard to get a match, but here it is. Did
what I could to document variables but it doesn't seem to make much
sense, if you ask me.
This was EntityMPReplenished, but then I looked into how it is used and
found that it is used for many other things besides replenishing MP, so
I named it more generically.
I think I hunted down every situation where it is used and documented
them fairly well. In general, I think this is a relatively good-looking
function and is easy to read.
Looking forward to seeing any feedback!
Now with the maspsx changes, this can also match by using
SPRITESHEET_PTR.
Tried to document all the variables, use flags when possible, etc, so
hopefully this is mostly complete. Should be exciting to have
RenderEntities and RenderPrimitives both working now!
Open to suggestions for how to break this change up to make it easier to
review. The data extraction necessary for naming values in `D_800ACF60`
and `D_800ACF84` could be a separate commit... but I'm not sure it's
worth it.
This links w_000 and allows the texture to be loaded to vram, as well as
the functions executed.
g_Cluts was renamed since the stages also have g_Cluts. A macro and
preprocessor defines are used to allow unique weapon function names.
This doesn't load the animsets since it seems like that stuff is getting
redone with the asset manager.
This is the largest function remaining in the decomp, and now it's dealt
with.
It's a giant beast and I can't claim to be anywhere near understanding a
single thing that it does. Researching this and documenting it will be a
second giant PR. Maybe I'll do that someday, but for now I'll leave it
to anyone else who wants to give it a try. None of the variables have
useful names. We could have "give the variables in this function useful
names relating to how they are used" be a "good first PR" issue, since
we set up several of those a while ago.
Data types on some of the externs it uses have been changed to match how
the function uses them.
This also uses g_PlOvlSpritesheet, which we have found seems to need to
be accessed as a numerical pointer, so I added a #define for that. It
seems to be working, so big thank you to everyone who was involved in
the process of setting that up. I believe this is the first function to
actually make use of that.
Besides that, I'll leave it to others to make their comments. There is
really too much in this function for me to talk about it, but hopefully
this is a reasonable start and we can make whatever tweaks are needed to
get this merged.
This is a big messy function, but it's decompiled!
Did what I could to rename variables in a useful way, but I could only
get so far. Hopefully one day we can work out exactly what all the
different angles, XY variables, etc are. But this is one of the biggest
remaining functions and it's great to have matching.
There was a question in the decomp discord about the bounce when Alucard
dive-kicks and hits an enemy. I tracked this down, and in the process,
found some moderately old functions that could use some improvements to
their code style. I also cross-referenced these with PSP to make the
code make a bit more sense.
The PSP version makes it clear that D_800ACF7C is not a struct and is
just an array of s16, so I made that change. The struct version matched
on PS1, but now that PSP reveals that it was fake, we turn it back to
just an array.
Let me know if I missed anything! Nice to have real names for some of
these functions.
This aims to deprecate all the Splat tools in `tools/splat_ext` in
favour of a more centralised asset manager. This brings the following
advantages:
* Much faster extraction
* Faster build
* Automatically define `static` symbols or unique names whenever
`static` is not possible
* Allow to embed assets into the output binary
* Drastically simplify `Makefile` by removing all the asset build rules
* Avoid situations where it is not possible to extract and build assets
that is not 4-byte aligned
This is achieved by having the splat YAML targeting a normal C file as
data and have an external tool to take care of the following:
1. Extract asset files straight from the overlay binary file into human
readable file in `assets/st/STAGE_NAME`
2. Build assets as header files that go into `src/st/STAGE_NAME` to just
include them from any C file
This requires each stage header to have the following new format: please
see `src/st/nz0/header.c`
Built assets in `src/st` are ignored by Git.
As for now, for simplicity sake, the steps `make extract_assets` and
`make build_assets` are just executed within `make extract` exclusively
for the US version.
I plan to auto-generate files such as `src/st/nz0/tile_data.c`.
For a first iteration I am aiming to handle the following:
* [X] Extract rooms: `assets/st/*/rooms.json`
* [X] Extract room layers: `assets/st/*/entity_layouts.json`
* [X] Extract tilemap data: `assets/st/*/tilemap_*.bin`
* [X] Extract tilemap definitions: `assets/st/*/tiledef_*.json`
* [X] Extract sprites: `assets/st/*/sprites.json`
* [x] Extract entity layouts
* [X] Build rooms: `src/st/*/rooms.h`
* [X] Build room layers: `src/st/*/layers.h`
* [X] Build tilemap data: `src/st/*/tilemap_*.h`
* [X] Build tilemap definitions: `src/st/*/tiledef_*.h`
* [x] Build sprites (aka `g_SpriteBanks`)
* [x] Build entity layouts
* [x] Allow the tool to suggest how to adjust the Splat config for each
overlay
I want the tool to cover the following stages:
* [x] CEN
* [x] DRE
* ~MAD~ I do not think this can be done, it is way too different from
the other overlays
* [x] NO3
* [x] NP3
* [X] NZ0
* [x] ST0
* [X] WRP
* [x] RWRP
* ~WRP (PSP)~ Maybe in a follow-up PR
For a later iteration I plan on extracting and build:
* Entity GFX thingie
* The CLUT thingie in the header
* Uncompressed GFX data
* Cutscene data
* Blueprints
* The `src/config_us.h` thingie
---------
Co-authored-by: Josh Lory <josh.lory@outlook.com>
The Karma Coin, surprisingly, has the largest EntityWeaponAttack of all
the weapons. For that reason, I'm targeting it next.
It has one small other entity function, so this PR decompiles that
first, prior to going ahead and decompiling the EntityWeaponAttack
itself.
Otherwise, nothing too crazy special here. I imagine decompiling the
Karma Coin will make it clear what this helper entity is.
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
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.
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.
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).