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.