Rewrites SEL's `banks.c` to use an array of `u_long` and make use of
declarations to populate it.
This PR comes after giving up at believing the original developers would
had the decency of using structs instead of crude array of data. They
are really developers from another era.
This is one of the few remaining sound functions.
It calls `ApplyQuadChannelSetting` and `func_80135624` in extremely
similar ways, so I've adjusted the arguments to those functions so they
match. `func_80135624` should probably get its own name which is similar
to `ApplyQuadChannelSetting`, but I don't know enough about these
functions to actually tell what it's doing.
One of the few remaining DRA functions.
Some of the code here seems fake, but it matches so I'm going with it. I
tried to change all the pointers to use the loop indexing but it didn't
work. Might have been written by a coder who was more comfortable
working with pointers than with loops.
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.
Creates the file `config_us.c` with all the configuration needed for the
game to know where to locate files in the disc (previously
`lba_stage.c`), equipments, accessories, menu strings (previously
`lang_us.c`, , spells, relics and enemy structures. There is also an exp
table for levelling up but I did not import it yet.
This is a major change in the codebase on how we handle assets.
Previously they were exported as JSON in `assets/dra`. The main problem
is that strings were not properly compiled, still relying on hardcoded
offsets expected to be found in the `.rodata` section.
I deducted all those information belong to a single C file because the
same strings in rodata were referenced from equipment to enemies. If
those strings are found in the same C file, the compiler will optimise
duplicated strings by de-duplicating them. This is how I reached the
conclusion of having all those definitions in a single file.
Obviously the major pain point of this is that a JSON was much more
declarative and easy to be consumed. Especially if tools were going to
use those files. Counting the commas with the struct definition on the
side is not the best thing for modding.
I had to comment out the HD `lba_stage` as it would require a major work
to support the Japanese text.
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.
Last test app specific PR for a few days. This adds a dummy stage that
gets loaded by `InitStageDummy`. It does very similarly what the game
does by copying the exported stage functions into `g_api.o`. The new
entrypoint is now `InitRoomEntities`.
The dummy stage loads some assets from WRP. The stage layout and tileset
are loaded in-memory. I created a very barebone `RenderTilemap` to draw
the foreground without any scrolling implemented. I am not sure why the
HUD is only showing when entering in the menu and it's black.
There is a hack job in the dummy stage to skip the SEL overlay and ask
the game to load WRP. Choosing WRP is purely arbitrary as any stage but
SEL would result to the same behaviour.
This is a bit of a memory hog. I introduced a memory pool instead of
using `malloc` for the assets loaded dynamically. The dummy stage will
not stay here for long, so I do not find useful to optimise it.
<img width="263" alt="image"
src="https://github.com/Xeeynamo/sotn-decomp/assets/6128729/4c0c0ed9-ddca-4f5b-a35d-a3fe0f8ababa">
Technically unimpressive, but I had to go through quite a good amount of
changes. Here is the full changelog to make everything work:
* Ensure `ResetPlatform` is always called to avoid memory leaks
* Add `g_RawVram` to emulate the PS1 VRAM
* ~~The engine will load the optional file `disks/vram.bin`, a RAM dump
from an emulator~~
* SDL2 will create 256x256 textures on-the-fly whenever a specific tpage
is requested via `GetVramTexture`
* The function `GetVramTexture` caches the last called tpage to avoid
tanking the performance
* `GetVramTexture` for only renders 4bpp and 8bpp textures with their
specified palette
* Remove `SDL2_image` as the font is now loaded straight from the VRAM
* Calling `VSync` will call the set callback, which the game uses for
DMA operations
* `MyLoadImage` is not yet implemented, but it is a placeholder to then
interact with `g_RawVram`
* The menu font now uses the texture found in the VRAM
* Plugged a custom version of `LoadFileSim`
* The file `sim_pc.c` is similar to the original game's code but it is
used here to load files from custom paths
* Using F5, F6 or F7 can dump the VRAM content on-screen, respectively
in 16bpp, 8bpp and 4bpp
There are new graphical glitches on the font. In some occasions it
appears black. It seems to be related to a flag in `P_TAG.code`. I plan
to dig into it when I can render entities on screen to avoid potential
mistakes. The same problem is present for the first half of Alucard's
portrait. It seems to be related when a texture is transparent? 🤷
I am not sure why the font is completely corrupted when entering in the
Equip menu. It is hard to understand if I introduced any regression.
Maybe the glitch was always there but it was hidden since I was always
forcing the font texture to be rendered.
EDIT: Implemented `LoadImage`, `SaveImage` and `ClearImage`
Previously attempted by @sonicdcer https://decomp.me/scratch/CMSl2.
I'm not sure the signature for func_801CDD80 is correct, which led me
down this rabbit hole. It matches, but there's a lot of ugliness going
on, I'm not sure if `arg1` has the correct type, or that `GH_Props` is
the right struct to access..
This one is pretty weird, there are a whole bunch of temp variables that
I couldn't figure out how to solve.
There are 8 blocks which set a variable, capped between 0 and an upper
limit (0xF0 or 0xFF). For the upper limit, I have created a `MIN()`
macro. I tried to make a `CLIP()` which would handle both limits in one
macro, but couldn't create one that would match.
Scratch here if anyone can improve things:
https://decomp.me/scratch/fY8js
This is a historical W.I.P. that held me back due to some dirty bytes in
the US version. It is now done.
I renamed the file to `lba_stage.c` as I plan to add another file called
`lba_bin.c` right after this PR.
To quickly build the HD LBA, which is very different, I wrote a quick
script to duplicate and patch the US one:
```python
def s16(f):
return int.from_bytes(f.read(2), byteorder='little', signed=False)
def s32(f):
return int.from_bytes(f.read(4), byteorder='little', signed=False)
with open("disks/pspeu/PSP_GAME/USRDIR/res/ps/hdbin/dra.bin", "rb") as f:
f.seek(0x3C50)
for i in range(0, 0x50):
print(f"0x{s32(f):04X}, 0x{s32(f):04X}, 0x{s32(f):05X}, 0x{s32(f):04X}, 0x{s32(f):04X}, 0x{s32(f):05X}, 0x{s32(f):04X},")
s32(f)
s32(f)
s32(f)
s32(f)
```
---------
Co-authored-by: sozud <122322823+sozud@users.noreply.github.com>
Sorry for the unimaginative function name, not really sure what it's for
yet. Pulled into the existing header as these two functions always
appear together. Slightly refactored the function.
Some entity, don't know what. There seem to be a lot of entities that
just use 7C and 7E from the `ext`, might be something we think about
unifying in the future.
I am not sure if we want to use this pattern. Here I am proposing to
wrap functions to open files and read the entirety of a file.
The objective is to avoid performing sanity checks for `fopen`, `fread`
and `malloc`, other than ensuring allocated resources are correctly
de-allocated on both happy and unhappy paths.
How it works is the first parameter is always the callback, while
starting from the second are all the parameters necessary to instantiate
and allocate the resources to be passed to the callback.
Found this function in RIC, it's very similar to the one in DRA, which
is nice.
Patterns of zeros in the rodata indicated that this should be the start
of a new file, which also makes sense since CreateEntFactoryFromEntity
comes with it.
RIC has its own array of blueprints, I'll probably add that to the splat
later on but that seems like material for a separate PR. For now we
focus on the entity function.