Fix packed raw menu sound effects
This commit is contained in:
@@ -117,7 +117,7 @@ highest-risk area of the port. This doc is the steering state; it feeds the A2b
|
||||
catalog id in the graphics surface, so that surface remains stable after a nested helper returns or a
|
||||
sibling script becomes active. Voice and movie calls likewise resolve against the executing frame;
|
||||
SFX is the separate universal packed-id family documented below.
|
||||
4. **Audio.** **BGM/voice wired; VFS bytes complete (2026-07-11); packed-raw SFX correction pending.** `IHost.PlayBgm/PlayVoice` +
|
||||
4. **Audio.** **BGM/voice/SFX wired; VFS bytes complete (2026-07-11); packed-raw SFX corrected 2026-07-20.** `IHost.PlayBgm/PlayVoice` +
|
||||
VM dispatch (`play-bgm` 0xbf / `play-voice` 0xc4, both argc 1); `ResourceMap.ReadAudio` opens the
|
||||
resolved catalog entry through `IAssetStore`; `GodotAdvHost` passes the bytes to `Main`'s players
|
||||
(`AudioStreamOggVorbis.LoadFromBuffer`; BGM loops, voice interrupt-on-new). Non-Godot hosts no-op it
|
||||
@@ -219,13 +219,13 @@ store.
|
||||
on-disk `BinExtractALF.exe` are validation references; the Kelebek repository exposes no clear license,
|
||||
so its code should not be copied without clarification. The focused `LzssDecoder` is shared with
|
||||
`Sys4AssetCatalog`; raw and compressed information/pixel/ACIF sections use the same bounded primitive.
|
||||
4. **Runtime consumers (scripts/textures complete; SFX resolver correction pending).** `ResourceMap.ResolveTexture` preserves
|
||||
4. **Runtime consumers (complete for scripts, textures, and current audio families).** `ResourceMap.ResolveTexture` preserves
|
||||
scene-local resolution and falls back to universal raw ids for SYSTEM4 assets; `GodotAdvHost` caches
|
||||
decoded RGBA surfaces by catalog identity and supplies synchronous dimensions to opcode `0x208`.
|
||||
Godot no longer reads `build/textures/*.BMP`. BGM direct-name and scene-local voice entries are opened
|
||||
through the same `IAssetStore`; the SFX WAV/player path is also present, but `GodotAdvHost` still applies
|
||||
scene-local resolution where op `0xb4` requires `ResolvePacked`. SC0000 worked because its raw ids happen
|
||||
to coincide with the first section. Extraction and conversion tools remain diagnostics.
|
||||
Godot no longer reads `build/textures/*.BMP`. BGM direct-name, scene-local voice, and packed-raw SFX
|
||||
entries are opened through the same `IAssetStore`. `ResourceMap.ResolveSoundEffect` owns op `0xb4`'s
|
||||
`ResolvePacked` lookup and audio filtering; the existing Godot WAV/channel path consumes its result.
|
||||
Extraction and conversion tools remain diagnostics.
|
||||
|
||||
### Acceptance gates
|
||||
|
||||
|
||||
@@ -1795,14 +1795,16 @@ raw catalog id `0x28` to `E0808.WAV`, loads channel 0, and `0xb5@0xc2e` starts i
|
||||
scratch global `G[0x6242d]` is maintained outside script-visible writes; the SC0000 port profile exposes it
|
||||
as an external value of 4 rather than pretending the script assigned it.
|
||||
|
||||
**TITLE SFX silence root cause (2026-07-20).** TITLE preloads raw id `0x2aea` (`SE020.WAV`) into channel 2
|
||||
**TITLE SFX packed-raw correction (2026-07-20).** TITLE preloads raw id `0x2aea` (`SE020.WAV`) into channel 2
|
||||
and executes `0xb5(2)` whenever mouse/joy selection changes. Each activation path loads raw id `0x3321`
|
||||
(`SE015.WAV`) into channel 1 and immediately starts it; GAMESTART additionally uses raw `0x2aeb`
|
||||
(`SE013.WAV`). A synchronized Godot trace captured repeated hover starts and the Game Start activation, but
|
||||
each preceding load recorded `file:null`. `GodotAdvHost.LoadSoundEffect` currently applies the active
|
||||
script's scene-local manifest, and TITLE has only 14 local entries, so all three large raw ids fail before
|
||||
the existing WAV/player path. BGM remains audible because it uses its separate direct-name resolver. The
|
||||
bounded fix is a scene-independent packed-raw SFX resolver, not changes to callbacks, mixing, or channels.
|
||||
each preceding load recorded `file:null`: `GodotAdvHost.LoadSoundEffect` applied the active script's
|
||||
scene-local manifest, and TITLE has only 14 local entries. `ResourceMap.ResolveSoundEffect` now uses the
|
||||
native packed lookup and filters the selected record to OGG/WAV before the existing byte/player path.
|
||||
The corrected synchronized trace resolves and starts `SE020`, `SE015`, and `SE013` through
|
||||
TITLE→GAMESTART→TITLE, and the user confirmed hover, activation, and cancel sounds are audible. BGM remains
|
||||
independent through its direct-name resolver; no callback, mixer, or channel workaround was needed.
|
||||
|
||||
That later service start is opcode `0x2bf`, now identified as the facade's `SetDelay` operation.
|
||||
`op_0x2bf_schedule_sfx_start@0x425240` passes `(channel,start_mode,delay_ms)` to
|
||||
|
||||
@@ -130,7 +130,7 @@
|
||||
### 0xb4 `sfx-load` (play-sound-effect, argc 2)
|
||||
- **summary:** (packed_raw_resource_id)(channel) — synchronously open the universal SYS4INI/AAI catalog entry and replace the channel's decoded sound buffer without starting playback. A zero high byte is a raw SYS4INI index; a nonzero high byte selects an append catalog and uses the low 24-bit index. Native manager supports channels 0..12; SC0000 uses 0..9.
|
||||
- **grounding:** source=investigation, confidence=high
|
||||
- **evidence:** Ghidra /v2: op_0xb4_sfx_load@0x4201d0 -> sfx_channel_load@0x482500 -> asset_open_indexed_entry@0x44f390 + sound_decode_channel@0x483360. The opener indexes the base catalog directly for a zero high byte and selects mounted_aai[high_byte] otherwise. SC0000 0xc29 uses raw 0x28 = E0808.WAV. TITLE independently proves the addressing rule: raw 0x2aea = SE020.WAV is preloaded on channel 2 and started on every hover-selection change; raw 0x3321 = SE015.WAV is loaded/started on activation. A synchronized port trace executes those loads and starts but reports file=null because Godot incorrectly applies TITLE's 14-entry scene manifest.
|
||||
- **evidence:** Ghidra /v2: op_0xb4_sfx_load@0x4201d0 -> sfx_channel_load@0x482500 -> asset_open_indexed_entry@0x44f390 + sound_decode_channel@0x483360. The opener indexes the base catalog directly for a zero high byte and selects mounted_aai[high_byte] otherwise. SC0000 0xc29 uses raw 0x28 = E0808.WAV. TITLE independently proves the addressing rule: raw 0x2aea = SE020.WAV is preloaded on channel 2 and started on every hover-selection change; raw 0x3321 = SE015.WAV is loaded/started on activation. The pre-fix port trace reported file=null under scene-manifest resolution; after switching Godot to ResolveSoundEffect/ResolvePacked, a synchronized TITLE->GAMESTART->TITLE trace resolves and starts SE020/SE015/SE013, confirmed audible by the user.
|
||||
|
||||
### 0xb5 `sfx-start` (u0041D050, argc 1)
|
||||
- **summary:** (channel) — start the already-loaded channel once (logical loop=false). DirectSound publishes synchronously through Play(0,0,DSBPLAY_LOOPING); the low-level flag loops only the streaming ring, while decoder EOF stops logical playback.
|
||||
|
||||
@@ -99,11 +99,12 @@ SYSTEM4's computed resource id `G[0x699]=0x22`; `G[0]=1` and the script-produced
|
||||
single-scene diagnostic harness. This lands the boot/title/New Game entry half of B1–B3; proving a completed
|
||||
scene return plus boundary cleanup still belongs to B1 completion.
|
||||
|
||||
**TITLE SFX investigation (2026-07-20).** Hover and activation callbacks are already executing their
|
||||
scripted `0xb5` starts. The load fails earlier because op `0xb4` uses universal packed SYS4INI/AAI ids,
|
||||
while Godot currently treats them as active-script manifest ids. TITLE's `0x2aea`/`SE020.WAV` hover and
|
||||
`0x3321`/`SE015.WAV` activation loads therefore resolve null; BGM is unaffected. The next bounded correction
|
||||
is a packed-raw SFX resolver plus TITLE/GAMESTART regression coverage, with no mixer redesign indicated.
|
||||
**TITLE SFX packed-raw correction (2026-07-20).** Hover and activation callbacks were already executing their
|
||||
scripted `0xb5` starts. The load failed earlier because op `0xb4` uses universal packed SYS4INI/AAI ids,
|
||||
while Godot treated them as active-script manifest ids. The new packed-raw resolver maps TITLE's
|
||||
`0x2aea`/`SE020.WAV` hover, `0x3321`/`SE015.WAV` activation, and GAMESTART's `0x2aeb`/`SE013.WAV` cancel
|
||||
through the existing channel players. A synchronized TITLE→GAMESTART→TITLE trace records every load/start
|
||||
with its filename, and manual validation confirms they are audible; BGM remains unaffected.
|
||||
|
||||
## Stage B1 — Persistent session and scene coordinator
|
||||
|
||||
|
||||
Reference in New Issue
Block a user