114 lines
4.2 KiB
Markdown
114 lines
4.2 KiB
Markdown
# GC 4.71 song catalog reverse notes
|
|
|
|
The Windows build loads its master song catalog from
|
|
`data/boot/stage_param.dat`. `LevelList.dat` is a different fixed-record table:
|
|
its 9002 bytes are a big-endian `u16` count of 1000 followed by 1000 records of
|
|
9 bytes, and it is not the song/asset relation table.
|
|
|
|
## Confirmed loader
|
|
|
|
`FUN_005e66a0` opens `data/boot/stage_param.dat`. It reads a big-endian `u16`
|
|
record count, allocates `count * 0xb4` bytes, and deserializes every variable-size
|
|
disk record into one `0xb4`-byte runtime entry. The dumped file contains 924
|
|
records. IDs are explicit and can have gaps; they are not array indices.
|
|
|
|
The loader stops after the declared record count; it does not require EOF.
|
|
GC 4.75 catalogs can append a version-specific metadata block after the song
|
|
array (one observed 917-record catalog has 4116 trailing bytes). The clean-room
|
|
reader therefore validates every declared record but intentionally leaves such
|
|
post-array data uninterpreted.
|
|
|
|
The game's primitives used by this loader are:
|
|
|
|
- `FUN_005d8bc0`: big-endian `u32`;
|
|
- `FUN_005d8cc0`: `u8`;
|
|
- `FUN_005d97d0`: `u8 byteLength` followed by that many string bytes;
|
|
- `FUN_005d96d0`: CP932-to-current-Windows-codepage conversion, used for display
|
|
strings but not asset identifiers.
|
|
|
|
The recovered runtime entry is:
|
|
|
|
```text
|
|
offset type confirmed/current meaning
|
|
0x00 u32 numeric song ID
|
|
0x04 string* display title
|
|
0x08 string* image/asset key
|
|
0x0c string* artist
|
|
0x10 string* source/subtitle
|
|
0x14 string* normalized sort key
|
|
0x18 u8 genre ID (1 anime, 2 Vocaloid, 3 rhythm game, 4 game,
|
|
5 variety, 6 original, 7 Touhou)
|
|
0x1c string* duration, e.g. "2:03"
|
|
0x20 u8[4] EASY/NORMAL/HARD/EXTRA ratings
|
|
0x30 string* BPM text
|
|
0x34 u8[4] per-difficulty BGM volume percentage
|
|
0x44 u8[4] per-difficulty SHOT volume percentage
|
|
0x54 u32[3] timing values (exact roles not yet named)
|
|
0x60 u8[2] not yet named
|
|
0x68 string* BGM base name
|
|
0x6c string*[4] alternate chart group (mostly empty in current songs)
|
|
0x7c string*[4] auxiliary chart suffixes
|
|
0x8c string*[4] EASY/NORMAL/HARD/EXTRA chart IDs
|
|
0x9c string* not yet named
|
|
0xa0 u32 not yet named
|
|
0xa4 u8[2] not yet named
|
|
0xac string* not yet named
|
|
0xb0 u8 not yet named
|
|
```
|
|
|
|
The clean-room implementation is in `src/gc/StageCatalog.cpp`; the old
|
|
nearby-string search used by `--track-info` has been replaced by this exact
|
|
record parser.
|
|
|
|
## Asset relation
|
|
|
|
For `Oshama Scramble!`, the catalog record contains:
|
|
|
|
```text
|
|
title Oshama Scramble!
|
|
image key oshama
|
|
artist t+pazolite
|
|
ratings 1, 7, 13, 0
|
|
BGM base bgm_b-879_oshama
|
|
charts ac_oshama_easy
|
|
ac_oshama_normal
|
|
ac_oshama_hard
|
|
```
|
|
|
|
The executable derives paths rather than storing full paths in the catalog:
|
|
|
|
```text
|
|
chart ID -> data/stage/<chart ID>.dat
|
|
data/stage/<chart ID>_ext.dat
|
|
data/stage/<chart ID>_clip.dat
|
|
|
|
BGM base -> data/stage/sound/<BGM base><BGM difficulty suffix>_BGM.wav
|
|
data/stage/sound/<BGM base><SHOT difficulty suffix>_SHOT.wav
|
|
data/stage/sound/<BGM base>_VIB.csv
|
|
|
|
image key -> data/stage/2d/<image key>_menu.dds
|
|
data/stage/2d/<image key>_start.dds
|
|
```
|
|
|
|
`FUN_0063ea70` confirms the three chart formats. `FUN_005b3980` and
|
|
`FUN_005b3850` build the `_menu.dds` path from runtime offset `+0x08`.
|
|
For English UI they first try `data/stage/2d/eng/<key>_menu.dds` and fall back to
|
|
the non-language directory. `_start.dds` follows the same rule.
|
|
|
|
`FUN_00613710` prefixes stage audio with `data/stage/sound/` and appends the
|
|
suffixes. If the stage-specific BGM cannot be found, it also has a legacy
|
|
fallback under `data/sound/`.
|
|
|
|
The stage `.dat` then supplies the playable geometry, notes, camera, authored
|
|
background color table, particles, visualizer data and object/model scene. The
|
|
`*_menu.dds` image is selection/game UI artwork, not the gameplay background.
|
|
|
|
## Inspecting a record
|
|
|
|
```sh
|
|
./build/openroller GC/data/boot/stage_param.dat --track-info ac_oshama_hard
|
|
```
|
|
|
|
This prints metadata, all difficulty chart IDs, and every derived stage, sound,
|
|
menu and start-image path with a missing-file marker where applicable.
|