Simple PR that aims to re-use the same `config_us` file from #948 but
for SEL. The file is de-duplicated since it is identical.
The file `lba_stage` has to be split again since in DRA it comes before
`config_us` but in SEL it comes after. That indicates it could have been
a stand-alone file.
I also imported the exp table responsible for levelling up.
I had to merge `2C048.c`, `2D260.c` and `2EED8.c`. The hint was in a
string that had to be in `2C048.c` but it was also used in the other two
files. I couldn't still merge this with `33164.c` due to the same
problem I described in #946 .
EDIT: I kept importing more data. SEL also contains its own `lba_stage`,
but some offsets and OVL size are out of sync compared to DRA. I have
the suspect the table was manually maintained, unlike our _"top class
engineering"_
I spent some time trying to merge `2EED8` and `33164` as the rodata
seems to suggest it. But there is a weird 4-bytes padding that is added
when the file split does NOT happen. If you want to have a look before
merging this, please do.
Extract the memory card icons out of DRA.BIN and SEL.BIN.
![image](https://user-images.githubusercontent.com/6128729/227794798-4dd071f9-512b-4c72-8f5d-fcbf7a615519.png)
I also took the opportunity to extract `g_MemcardPortMask` into its own
source file `save_mgr_pre.c`. Unfortunately this is required to keep the
original data order. This suggests that most likely the icon palette and
bitmap were baked into the original `save_mgr.c` as byte arrays. I
decided to take a different approach and extracted them as PNGs for
better moddability.
I had to spin-off Splat into a new fork due to some breaking changes on
0.18.0.
Occasional maintenance:
* asm-differ: latest commit
* m2c: latest commit
* maspsx: latest commit
* spimdisasm: 0.18.0 latest
* splat: 0.17.3
The latest version of splat is 0.19.1 but a breaking change in
[0.18.0](https://github.com/ethteck/splat/pull/294) is preventing me to
upgrade further ([discussion
here](https://discord.com/channels/710646040331681844/813939516385525790/1172978921000669274))
Some YAML were malformed and since splat 0.17.0 there are additional
checks to ensure they are compliant. There are also new checks that
prevents a malformed symbol list including duplicates, which I fixed
too.
Occasional maintenance:
* asm-differ: latest commit
* m2c: latest commit
* maspsx: latest commit
* spimdisasm: 0.18.0 latest
* splat: 0.17.3
The latest version of splat is 0.19.1 but a breaking change in
[0.18.0](https://github.com/ethteck/splat/pull/294) is preventing me to
upgrade further ([discussion
here](https://discord.com/channels/710646040331681844/813939516385525790/1172978921000669274))
Some YAML were malformed and since splat 0.17.0 there are additional
checks to ensure they are compliant. There are also new checks that
prevents a malformed symbol list including duplicates, which I fixed
too.
I started importing the data in SEL also as a proof of concept we can
also import the SOTN-specific formatted strings. For that I integrated
the new tool `tools/sotn-str.py` into the build chain. It works like the
following:
* `./tools/sotn-str.py parse disks/us/ST/SEL/SEL.BIN 27598`: read the
binary content in a specific offset and parse it as a readable Unicode
string.
* `cat src/st/sel/2C048.c | ./tools/sotn-str.py process` converts the
Unicode string into a byte sequence that can be understood by the SOTN
engine.
There is a dirty hack I did to make this work:
```c
#ifndef SOTN_STR
#define _S(x) (x) // Strings processed by tools/sotn-str.py
#endif
```
When invoking `mipsel-linux-gnu-cpp` I am passing -DSOTN_STR,
effectively ignoring `_S` in the pre-processor. Then I am passing it
into `sotn-str` before `iconv` to resolve any string surrounded by `_S`.
I am a bit of afraid this might be annoying when using the permuter. I
tried doing `$(SOTN_STR) -f $< | $(CPP)` but apparently `cpp` does not
work well with content passed via stdin.
Previously if either the YAML or the symbol list were changed, we were
forced to either manually delete the `asm` folder of the specific
overlay or to invoke `make clean`, where the latter forced us to
re-extract all the overlays via `make -j extract`.
That changes with this PR. How `make` works is `target: dep1 dep2` where
if one of the dependencies has the last modified date greater than the
target, the rule is triggered again. Previously we were extracting
overlays doing `make extract_stcen`. But since every overlay extraction
generates a linker script I now changed the rules to do `make
build/us/stcen.ld` to extract the same overlay. As I explained above, if
either the YAML or one of the related symbols changes, the linker
modified date will be older and the extraction for that overlay to be
trigger again.
The above allowed me to stop polluting the repo root with the linker
scripts as they are now moved into `build/us` or `build/hd` depending of
what you're trying to build. If you do `make extract` twice in a row you
will be welcomed with a `make: Nothing to be done for 'extract'.`.
There are still some instances where you **might** need `make clean`
beforehand, especially when modifying the `segment` section in the YAML
or renaming the symbols. A `rm -rf asm/$(VERSION)/$*` can help but I
want to see if the current solution will be enough.
### Please try removing `make clean` from your workflow, once this is
merged, to quickly detect possible problems with this new approach.
I am also planning to make more substantial changes on our build-chain
like this PR or #660 in the future. I am aiming to small incremental
changes over time in case I break someone's flow or detect design flaws.
I am also considering the breaking changes introduced in make 4.4, which
will most likely be included in Ubuntu 24.04 LTS. I set March 2024 as a
deadline to finish all the new build-chain work.
---------
Co-authored-by: sozud <122322823+sozud@users.noreply.github.com>
I am proud to announce I decompiled the biggest function from the game
detected so far! This operates the whole logic of the main menu and
links together all the functions I've been decompiling in the past week.
I did my best to import the `.rodata` function. There's a big catch
though. The symbol `D_801A7620` is used in this function, but I cannot
import it because it is also used by `func_801ACFBC`, found much earlier
than `Update`. This most likely means `2C048.c`, `2D260.c` and `2EED8.c`
were a single source file.
Before committing myself into fully documenting the function, I want to
finish to decompile `func_801ADF94` and `func_801AD66C`, which are
necessary to merge the three files and finish importing the `.rodata`.
Then I need to start to decompile `func_801B2108`, `func_801B3164`,
`func_801B38B4`, `func_801B3A94` and `func_801B3F94` as they are
dependencies of `Update`.
What it is done:
* Decompile the last function from the `save_mgr` trio,
`MemcardDetectSave`.
* Merge `save_mgr.c`, `save_mgr2.c` and `save_mgr3.c` into a single file
* Merge the respective headers
* Import all the `.rodata` segment
* Import all the `.data` segment
* DRA and SEL shares all `src/save_mgr.h`
* Remove orphan symbols
Removing the orphan symbols is very interesting. When certain functions
or global variables are no longer referenced by the exported assembly
code, there is no need to define them in the symbol list. This allows to
freely relocate the code in case modders wants to add or remove code. I
performed this step manually, but will make a script to do this
automatically.
Decompiling this function the meaning of various functions, de-fake
struct and symbols and document a previously unknown function.
This was the second last function from the `save_mgr` group. If
possible, with the next PR I plan to merge `save_mgr`, `save_mgr2`,
`save_mgr3` and importing the relevant `.data` and `.rodata` segments.
A few quick wins, which leave three functions yet to decompile in
`stream.c`.
Interestingly, there are no functions between `save_mgr3.c` and
`stream.c`. Yet the `.rodata` segment between these two source files
stores the entire Equipment, Accessory and LBA arrays. We are currently
exporting the first two as JSONs. I have the feeling these information
were stored just as C code and they got linked on both DRA and SEL.
Adapted from `PSX/SAMPLE/CD/MOVIE/TUTO0.C`. I took the opportunity to
rename a few functions according to the sample code too.
All the functions there seems to be self-contained. So I decided to
rename the source file as `stream.c`. Those are the functions
responsible for animating the KONAMI movie logo
This took me a monumental effort. The PR does:
* Decompile `StoreSaveData` for DRA (US and HD)
* Decompile `StoreSaveData` for SEL
* Match `MemcardFormat` in SEL
* Cross-reference symbols between DRA and SEL
* Bring common code between DRA and SEL to parity
* Discover `save_mgr.c`, `save_mgr2.c` and `save_mgr3.c` have the same
layout in both DRA and SEL
* Deduplicate `save_mgr3.c`
* Import `.data` and `.rodata` from both DRA and SEL
* Convert UTF-8 Japanese characters into Shift-JIS while building
* Minor refactor with less hardcoded magic numbers
I made the following compromises:
* In DRA US `MakeMemcardPath` there is some dirty data at the end of the
string. I had to create a byte array called `HACK_SaveName`. This does
not occur on DRA HD or SEL
* I did not de-duplciate `save_mgr` as there are a good amount of
functions and symbols I have no knowledge about
* I did not decompile `save_mgr2` and it will come as a separate PR.
This is very strange.
All of the "normal" overlays have a function called TestCollisions which
is extremely large and complicated. I noticed this one in the
functions.md list, and specifically that this one is fewer instructions
than the others. I thought decompiling this one might help as a
simplified version to solve the other ones.
I was surprised to find that this is a completely different function,
and does nothing related to collisions at all. It only does a bunch of
Primitive handling. It is not relevant for the real TestCollisions, but
I figured I should decompile it anyway. Here it is.
I do not know what this does. The function call graph
https://raw.githubusercontent.com/Xeeynamo/sotn-decomp/gh-duplicates/function_calls/sel.TestCollisions.svg
does not indicate any callers. We should either determine what this does
and give it a useful name, or revert it to `func_801B410C`.
The behavior with the "scaled_b014" variable is unusual; I'm not sure if
it's possible to change some types somewhere to eliminate its usage.
I think those are all the main important points, more than happy to make
changes to this very weird function.
* Fix HD DRA splat as `func_800E2398` was ending up to be data rather
than code
* Cross-reference more HD DRA symbols with US DRA
* `D_80137038` to `g_PadsRepeatTimer`
* `func_800E81FC` to `LoadFileSim`
* `func_800E8D24` to `ResetPadsRepeat`
* `func_800E8D54` to `UpdatePadsRepeat`
* DRA `func_800E9640` and SEL `func_800E9640` to `MemcardReadFile`
* DRA `func_800E96E8` and SEL `func_800E96E8` to `MemcardWriteFile`
* DRA `func_800E97BC` and SEL `func_800E97BC` to `MemcardEraseFile`
* DRA `func_800E9B18` and SEL `func_800E9B18` to `MemcardFormat`
* Document the various `Memcard` parameters
* Standardise the various `Memcard` variables inside the functions
* Document known PSX bug I found in the official docs