feat(desktop): add muted accelerated ROM playback

This commit is contained in:
0xrsydn 2026-10-07 08:51:05 +07:00
commit 423d0ba120
12 changed files with 270 additions and 16 deletions

View file

@ -176,7 +176,7 @@ The repository is a Cargo workspace with three crates:
| `crates/desktop/src/cartridge/rtc_clock.rs` | Host-only UTC seed and monotonic elapsed-time adapter, with injected epoch/duration tests |
| `crates/desktop/src/cartridge/window.rs` | ROM-window session, bounded slices, capture, STOP/input handling, and progress limits |
| `crates/desktop/src/cartridge/window/tests.rs` | Original ROM pixels, keyboard mapping, STOP wake, HALT, frame budgets, and diagnostics |
| `crates/desktop/src/desktop/rom.rs` | Main-thread ROM window, input polling, optional audio draining/muting, bounded pacing, and frame-limited exit |
| `crates/desktop/src/desktop/rom.rs` | Main-thread ROM window, input polling, optional audio draining/muting, speed-scaled host pacing, and frame-limited exit |
| `crates/desktop/examples/write_rom_demo.rs` | Non-overwriting export of the original input-test ROM |
| `crates/desktop/src/cartridge/tests.rs` | ROM options, bounded readers, instruction/DMA/IRQ budgets, HALT/STOP, and diagnostic reports |
| `crates/desktop/tests/rom_cli.rs` | File loading and exit-status checks; opt-in native ROM-window integration test |

View file

@ -264,8 +264,10 @@ Original tests cover exact sample boundaries, timer consumption, pulse phases, b
## Darwin output adapter
Use `--audio` with `--rom ... --window` to enable CPAL 0.16/CoreAudio output on macOS.
Use `--audio` with `--rom ... --window` at 1× speed to enable CPAL 0.16/CoreAudio output on macOS.
Windows remain muted by default. Terminal runs, ROM suites, and demos do not open an audio device.
ROM-window `--speed` values above 1 override `--audio`: no device is opened and sample capture stays disabled.
Sound hardware still executes at the same emulated cycle rates. Accelerated audio conversion is not implemented.
The flag is invalid in terminal mode and cannot be repeated. Other platforms currently report an explicit unsupported-platform error.
The adapter opens the default output device at its default configuration.

View file

@ -108,6 +108,27 @@ HALT continues device clocks and frame publication.
Normal presentation targets approximately 59.73 frames per second, without frame skipping or accumulated catch-up work.
Slow hosts can run slower than real time. Host sleeping never advances emulated clocks.
### Playback speed
Use `--speed 2` with `--window` to target twice normal speed.
The option accepts integer multipliers from 1 through 16; the default is 1.
Missing values, duplicate options, fractions, and values outside this range are rejected before ROM loading.
The option is not available for terminal runs, test suites, or demos.
```sh
direnv exec . cargo run --locked --release -- --rom roms/pokemon-emerald.gba --rtc --save-type flash128 --save-file roms/pokemon-emerald.sav --window --speed 2
```
Speed changes only the host frame period. CPU/device cycle ratios, captured frames, execution budgets, and save operations remain unchanged.
Every emulated frame is still presented. Actual speed depends on CPU, rendering, window-system, and display costs.
Input remains sampled between bounded execution slices. Interactive STOP retains normal-speed host polling instead of busy waiting.
RTC still follows host elapsed time; the speed multiplier does not accelerate the cartridge clock.
Above 1×, audio output and capture are disabled, even when `--audio` is present.
No host audio device is opened. Sound hardware still executes normally, including diagnostics for unsupported behavior.
At 1×, `--audio` retains its existing meaning. The window title and terminal report show the requested speed.
Finish the in-game save before exiting normally; speed does not change clean-exit persistence rules.
In interactive mode, STOP retains the last image and changes the window title.
The host continues polling input and window-close events while GBA clocks remain frozen.
Only keypad conditions configured by the ROM through KEYCNT and IE can wake STOP.
@ -138,7 +159,8 @@ Right takes priority over Z. Other buttons have no visible effect in this small
No game or firmware content is included.
ROM windows can enable Darwin output with `--audio`; they are muted by default.
The option requires a usable default audio device. Device/configuration errors fail explicitly; omit the flag to run muted.
At 1×, the option requires a usable default audio device. Device/configuration errors fail explicitly; omit the flag to run muted.
Above 1×, `--speed` overrides `--audio` and keeps output muted.
Focus loss and STOP clear queued audio. See [audio output and its limits](audio.md#darwin-output-adapter).
Terminal mode has no audio. Both modes support explicit save files but lack per-step tracing.
Commercial-game compatibility remains unverified and unsupported.

View file

@ -95,6 +95,7 @@ Update this file when a feature lands or a limit is removed.
- Two-bank wave playback, active bank changes, and unsupported serial operations remain diagnostic with whole-access and block-store rollback.
- ROM windows with scanline capture, keyboard input, focus-loss release, bounded execution slices, and interactive keypad wake from STOP.
- Opt-in macOS CoreAudio output, with tested original tones and wave-ROM playback; focus loss and STOP mute queued audio.
- ROM-window `--speed 1..16` targets accelerated playback through host pacing only; audio is muted above 1×.
- Optional ROM-window frame limits and an original input-test ROM generator.
- Headless JSON ROM suites with PC or VBlank completion, register/CPSR/memory/pixel assertions, scheduled buttons, bounded budgets, and structured failure reports.
- Hash-pinned preparation of public `jsmolka/gba-tests` ARM, Thumb, memory, and BIOS ROMs, with verified result-register checkpoints.

View file

@ -99,6 +99,18 @@ Original terminal/native programs activate wave playback without external assets
Fixed-rate capture tests verify sample boundaries, timer/PSG ordering, rollback, queue limits, drop counts, and HALT/STOP.
Host conversion tests require no device and cover rates, stereo/mono mapping, prefill, overflow, underflow, DC removal, and callback splitting.
CLI tests keep output muted by default and reject `--audio` outside ROM-window mode.
Speed tests validate integer multipliers 1–16, default 1, invalid/duplicate options, and window-only use.
Pacing tests check scaled host periods and forced muting above 1×, even with `--audio`.
A native test compares identical final CPU/cycle reports after fixed frame counts at 1×, 2×, and 16×.
It records elapsed host time without imposing a load-sensitive timing assertion.
The original native save/restart test also runs its saving window at 2× with `--audio` requested, but muted.
```sh
direnv exec . cargo test --locked --release -p gameboy-rust-desktop --test rom_cli native_rom_window_speed -- --ignored --nocapture --test-threads=1
```
A Darwin arm64 release run took approximately 1.27 seconds at 1× and 0.63 seconds at 2× for the same original program.
Process/window startup is included. This verifies acceleration in that probe, not a speed guarantee for other games.
The following ignored tests require a native audio device and play original test tones: