# 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 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/.dat data/stage/_ext.dat data/stage/_clip.dat BGM base -> data/stage/sound/_BGM.wav data/stage/sound/_SHOT.wav data/stage/sound/_VIB.csv image key -> data/stage/2d/_menu.dds data/stage/2d/_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/_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.