This should finish out the set :)
Can't say I understand the differences here (it's modifying
g_CastleFlags during the item drop randomization routine for crying out
loud) but hey, a match is a match.
Got this one done too! ST0 is slightly simpler than the others.
I tried to adapt the existing matching TestCollisions directly, but I
found that it was easier to work on PSP to get the logic right and then
move to PSX instead.
I think I did this right, but this is my first time de-duplicating a
function, so please point out any mistakes :)
ST0 not included because it has different logic internally - will work
on decompiling that one next.
Well here we are, TestCollisions matching!
I'm going to start with this one, and once it's in, I will follow up by
de-duplicating it.
Please review this closely, especially the changes that are happening in
other files than the main C file.
I suspect we will learn a lot from studying this function; I've already
made some changes (including to the Entity struct) but there will surely
be more.
Nice that this was possible with only two `goto` statements.
I expect a fair bit of revision here, especially related to any
enums/defines I might not be aware of. Please be liberal with comments
:)
Same as #1181 but on PSX. The imported data falls right at the top of
each new file based on some old assumptions of mine, suggesting we're
probably on the right track.
A massive PR, I know. It's the smallest change I could do to make this
happen.
After comparing the function order from both ST/WRP PSX and ST/WRP PSP,
I was able to come up with a file split much different from the one
suggested from Splat. It still returns an 🆗 and it follows the same
group functions order from the two game builds.
As soon as we are on board with the C names, next PR will be to do the
same with the PSX overlay. Then in another PR we will be able to start
merging the C files between the two builds. Ideally the same approach
can be used for sharing C files across the different overlays instead of
relying to floating header files in `src/st`
Thanks to @sozud for the hint and @bismurphy for the refactoring idea.
The function `PreventEntityFromRespawning` on PSP hints that the struct
starts 8 bytes earlier. Also there's a missing `nop` at
`PreventEntityFromRespawning`, suggesting the function had to be moved
to the previous function.
I noticed that this struct had some overlap with other values in memory,
so I have pulled all those values into this struct.
The boundaries of this struct are uncertain and are a matter of ongoing
research.
I get
```
mipsel-linux-gnu-ld: build/pspeu/src/st/wrp_psp/BF50.c.o: in function `FallEntity':
(.text+0x0): undefined reference to `g_CurrentEntity'
mipsel-linux-gnu-ld: (.text+0x4): undefined reference to `g_CurrentEntity'
mipsel-linux-gnu-ld: (.text+0x1c): undefined reference to `g_CurrentEntity'
mipsel-linux-gnu-ld: (.text+0x20): undefined reference to `g_CurrentEntity'
```
Not sure what the issue is
Extract ST/WRP out of #1119 . All the function symbols should have been
cross-referenced. There as some PSX functions missing from PSP and some
new functions from PSP that are not present on PSX (e.g.
`st_init_wrp.c`).
The files `st_debug.c` and `e_breakable.c` are shared between WRP PSX
and WRP PSP. Everything else from PSP is isolated into its own folder. I
had to do some tricks on the YAML config to allow shared code.
`ST_WRP_MERGE = st_debug e_breakable` in the `Makefile` is a bit
annoying as MWCC complains about every single minute detail from the C
source that has been already decompiled for the PSX US build.
`EntityWarpSmallRocks` is matching on PSP but I couldn't extract the
rodata without having a bunch of linker errors. This might be a Splat
issue. I need to investigate further.
`func_psp_09244760` is soooo interesting. The values from `0x11` to
`0x17` matches the Entity IDs that are unique to the WRP overlay. This
aligns to what we have in `typedef enum EntityIDs`.
Overall I am very excited to the recent discoveries from the PSP build!
This organizes funcitons believed to be originally found in `entity.c`
into an equivalent `entity.h` based on the research of @Xeeynamo:
* `DestroyEntity`
* `DestroyEntitiesFromIndex`
* `AnimateEntity`
* `PreventEntityFromRespawning`
Includes `entity.h` in place of stage implementations or ASM.
Co-authored-by: Jonathan Hohle <jon@ttkb.co>
Discovered in #1167, where when the player approaches the red door it
forces the input. The line `g_Player.padPressed = g_Player.padSim;`
makes it even more obvious.
This needs to be rebased upon the other PR, otherwise it will break the
build if merged.
Pulls out `CreateEntityFromLayout`, `CreateEntityWhenInVerticalRange`,
`CreateEntityWhenInHorizontalRange`, `FindFirstEntityToTheRight`,
`FindFirstEntityToTheLeft`, `CreateEntitiesToTheRight`,
`CreateEntitiesToTheLeft`, `FindFirstEntityAbove`,
`FindFirstEntityBelow`, `CreateEntitiesAbove`, `CreateEntitiesBelow`,
`InitRoomEntities`, `UpdateRoomPosition`,
`CreateEntityFromCurrentEntity`, `CreateEntityFromEntity`,
`EntityIsNearPlayer`, and `InitializeEntity` into headers to share the
implementation between stages.
`libstage.h` is a new header intended to bring in a sequential block of
functions shared by all stages.
`st_private.h` is a new header intended for declaring symbols used by
all stages that aren't otherwise accessible to code outside of a stage.
The only discrepency is `MAD` which has a unique implementation of
`CreateEntitiesToTheLeft`. Instead of being able to blanket include
`libstage.h` it needs to bring in individual headers before and after
its implementation.
Co-authored-by: Jonathan Hohle <jon@ttkb.co>
Every other stage uses the same implementation of
`CreateEntitiesToTheLeft`, but MAD's version does not loop through all
entities which may be in range, it finds the first, and depending on
flags may create it, the array pointer is updated and no other entities
are considered. This function is used when scrolling left, meaning if
multiple entities fall within the scroll delta, only the first will be
created which might have some interesting properties.
Co-authored-by: Jonathan Hohle <jon@ttkb.co>
This change renames functions and global stage variables uniformly
across the stages so that these functions can be pulled out and shared
across all of the stages. Based on some other tests there are 12 or so
functions that this will allow to be pulled out of each stage. Since
these implementations are shared, an additional 12 asm functions can be
eliminated in a subsequent pass.
**Vars**
* `g_pStObjLayoutHorizontal` - a horizontally sorted array of stage
entities
* `g_pStObjLayoutVertical` - a vertically sorted array of stage entities
* `g_LayoutObjHorizontal` - a pointer to a `LayoutEntity` in
`g_pStObjLayoutHorizontal`
* `g_LayoutObjVertical` - a pointer to a `LayoutEntity` in
`g_pStObjLayoutVertical`
* `g_LayoutObjPosHorizontal` - the direction last traversed in
`g_LayoutObjHorizontal`
* `g_LayoutObjPosVertical` - the direction last traversed in
`g_pStObjLayoutVertical `
**Functions**
* `FindFirstEntityToTheRight` - given an `x` position, update
`g_LayoutObjHorizontal` with the first entity to the right of `x`
* `FindFirstEntityToTheLeft` - given a `x` position, update
`g_LayoutObjHorizontal` with the first entity to the left of `x`
(backwards)
* `CreateEntitiesToTheRight` - given an `x` position, create all
entities to the right (mutates `g_LayoutObjHorizontal`)
* `CreateEntitiesToTheLeft` - given an `x` position, create all entities
to the left (mutates `g_LayoutObjHorizontal`)
* `FindFirstEntityAbove` - given an `y` position, update
`g_LayoutObjVertical ` with the first entity to the above of `y`
* `FindFirstEntityBelow` - given an `y` position, update
`g_LayoutObjVertical ` with the first entity to the below of `y`
* `CreateEntitiesAbove` - given an `y` position, create all entities
above (mutates `g_LayoutObjVertical`)
* `CreateEntitiesBelow` - given an `y` position, create all entities
beneath (mutates `g_LayoutObjVertical`)
* `UpdateRoomPosition` - look at the current game loop scroll delta and
create any entities given the room layout
I believe all of these implementations are shared across all stages
(including `InitRoomEntities`, and two more `CreateEntity` functions)
(in my initial tests I had a small difference in `DER`, but I believe
that had to do with an incorrect symbol table change).
Co-authored-by: Jonathan Hohle <jon@ttkb.co>
Based on their use in the game loop and during stage updates, it appears
the renamed variables store the scroll position delta for the current
loop and store off the current position for future delta calculation.
These vars are then used by stage code to determine if any entities need
to be created or destroyed based on the new position.
Thanks a lot to @SestrenExsis for doing the majority of the function
matching! I only take the credit for cross-referencing it with the PSP
counterpart and massaging the code until I got a match on PSX.
Looks like just another weapon function.
Weird uses of the Weapon struct. Unfortunately Weapons don't seem to
have any consistency among them. Would be nice if we could define the
Entity extension in each weapon's `w_0XX.c` file, but I don't think
that's a possibility in C.
Very neat to solve this with the help of the PSP version! I couldn't
solve this without it, so this is a cool development. Hoping to keep
benefiting from that!
This is also the final helper function in the weapons. All other
functions in all the weapon overlays are part of the main Weapon struct
that holds the set of several pointers to call.
Based on Sozud's scratch (https://decomp.me/scratch/zVBXP), I got the
function to match, and then confirmed that it also matches on PSX.
I also discovered a few improvements, especially in changing
`D_8016FCC0[entityId];` to instead be
`((PfnEntityUpdate*)FAMILIAR_PTR)[entity->entityId - 0xD0];`
While I was at it, I also updated the D_80170000 variable from a void*
to be g_ServantDesc, just like we have in the servant overlay. The
ServantDesc struct only exists in servant.h, so we update that as well.
Finally, we move g_Weapon to not be at 80170000, since it doesn't belong
there.
Highlights:
* `abs` is a real function the compiler can optimise and inline (thanks
@Mc-muffin for the discovery)
* `-Op` is required to avoid using `div` when dividing integer numbers
* A file split in TT_000 is required to match on PSP
* `UpdateAnim` had the wrong signature
* Splatting the PSP build has been an excellent idea
Given the recent discovery (thanks @Mc-muffin) I deleted the `ABS` macro
(together with a few other unused ones) and started using `abs` instead.
This is not a simple Find & Replace. I also checked every single code
change and removed previously necessary temporary variables.
More PSP matches and a lot of fixes on types and symbols from the PSX
counterpart. I am very happy with the results so far.
`func_80173F74` has some weird `#ifdef VERSION_PSP` I cannot remove. Any
help will be very welcomed.
Matches `func_801713C8`.
This is an important milestone as it is the first function using the
`SEH` instruction. I got this new compiler (and many more) from someone
in ObscureGamers that kindly shared at
https://archive.org/download/compilers-no-license .
This still gives us no clue on what `f32` and the various `.i.hi` stuff
was actually meant to be.
Surprisingly, this uses an s16 for hitboxOffX, so it turns out we need
to adjust the Entity struct in Weapon. Hopefully that's the last of the
changes needed to Entity :)
These two functions are extremely similar so I am doing them in one PR.
Not sure what they actually do, the call to LoadImage is a bit
surprising. This is used for the Skull Shield and Shaman Shield; I don't
know what they have in common.
`func_107000_8017ADF8` is already in the repo and decompiled. I found
that there are several duplicates of this function, so this PR
decompiles all of them.
The only difference between the copies is 1. The address of the data
array, obviously and 2. the assignment to the `size` variable. Some
duplicates use 4 and 6, others use 2 and 3. Otherwise they're exactly
the same.
This is the only heavily-duplicated weapon helper function remaining. I
have decompiled all of the helper functions (the ones that are unique to
the weapon they're part of, rather than being in the standard structure
like `func_ptr_801700XX`) and will be doing PRs for each of them in
sequence.
Decompile SEL func_801B9B7C Mostly based on the work of @sonicdcer (who
had the right code, but wrong struct), and @ser-pounce (who had the
right struct, but unfinished code).
Co-authored-by: Jonathan Hohle <jon@ttkb.co>
OK. Here goes. Version 0.0.1 alpha of the MWCC Global Assembly Processor
(mwccgap). It's currently very simple/limited, but it appears to work
for `src/servant/tt_000/10E8.c`.
There is lot more that can be done to improve mwccgap - i.e. supporting
.rodata migration would be a good addition, but let's see how far we can
get with it in it's current state.
Note that the Makefile could do with some improvements - we don't nede
to use mwccgap for any C file that *dont* have INCLUDE_ASM macros (it's
a waste of time) so these could be ignored, i.e. for SSSV I do something
like this to find the files that need fixing up:
```
GLOBAL_ASM_C_FILES := $(shell $(GREP) GLOBAL_ASM $(SRC_DIR) </dev/null 2>/dev/null)
```
.. although this is perhaps too simple given that SOTN has a mix of PSP
and PSX functions (and therefore there may be INCLUDE_ASM for a PSX
function but none for PSP functions...
After decompiling `func_107000_8017B0AC`, I moved on to more weapon
helper functions, and was surprised to find several more copies of
nearly identical functions. The only difference between these is the
fractional constants applied to the outPoint results (for example, some
use 2/3, others use 3/4, and others still use 1/2).
Given the fact that these are all substantially the same, we could
probably do some de-duplicating by pulling in a header file, but for now
I'm decompiling each one in place, so that we can have all the functions
done.
I believe this is all of the ones that match this structure; hopefully I
didn't miss any!