- Fixed PSP pause taking up to ~1.1s to actually go silent: its output
thread ran independently of stream->state, draining its whole software
ring regardless. audiostream_t.state is now volatile and the output
thread checks AUDIO_STREAM_STATE_PLAYING before each hardware chunk,
skipping output (without consuming the ring) while paused - pause now
goes silent within about one chunk (~23ms) and resume has no gap.
- Added audioMixerPause/Resume/SetPan/SetLoop/FadeTo/IsFading to the
mixer - immediate, channel-indexed primitives for cutscenes to drive.
Fade transitions (fadeFrom/To/Duration/Time/Easing) live on
audiomixerchannelstate_t and advance every frame in
audioMixerChannelApplyVolume(), reusing the same easingApply()
interpolation uifullbox_t already uses for screen fades.
- New src/dusk/rpg/cutscene/item/audio/ with 9 cutscene item types:
AUDIO_PLAY (+ AUDIO_PLAY_SIMPLE/AUDIO_PLAY_LOOPED shorthands),
AUDIO_STOP, AUDIO_PAUSE, AUDIO_RESUME, AUDIO_FADE (+ FADE_OUT/FADE_IN
shorthands), AUDIO_FADE_WAIT, AUDIO_SET_PAN, AUDIO_SET_LOOP, and the
combined AUDIO_SET - registered through the same enum/union/callback
table/macro mechanism every other item type uses.
- Wired the same 9 types into the JSON-based (offline JSONC -> binary
.cts) cutscene asset pipeline: tools/asset/cutscene/__main__.py's
encoder and assetcutsceneloader.c's decoder. Verified round-trip by
hand-encoding/decoding a test file covering all 9 types, and confirmed
the two existing real cutscene files re-encode byte-identical.
Built and verified on Linux, PSP (Docker), GameCube (Docker) and Wii
(Docker).
Co-Authored-By: Claude Sonnet 5 <[email protected]>