Skip to content

Commit a3ee3ec

Browse files
committed
Merge origin/main (v1.7.1) into feat/v1.8.0-android
Resolve conflicts from the v1.7.1 release: - Cargo.toml: take main's 1.7.1 workspace + dep-pin bumps; keep the new rustynes-mobile/rustynes-android members + the rustynes-mobile dep (1.7.1). - CHANGELOG.md: keep the v1.8.0 "Android" Added block under [Unreleased] and main's new [1.7.1] release section.
2 parents a98f3ec + acedc11 commit a3ee3ec

6 files changed

Lines changed: 101 additions & 36 deletions

File tree

‎CHANGELOG.md‎

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,46 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
5959
binding pipeline are verified end-to-end (host build/tests, Kotlin
6060
generation, NDK cross-compile to arm64 producing both `.so` libraries).
6161

62+
## [1.7.1] - 2026-06-19
63+
6264
### Fixed
6365

66+
- **ROM-close GPU abort fixed (#1).** In a release build `Gfx::render_with_overlay`'s
67+
`debug_assert_eq!` size check is compiled out, so when `close_rom` set
68+
`emu.nes = None` and the render path handed an empty `present_staging` slice to
69+
`queue.write_texture`, wgpu validation aborted the process ("Copy ... would end
70+
up overrunning the bounds of the Source buffer of size 0"). `render_with_overlay`
71+
(the framebuffer + `index` upload branches) and `render_hd_with_overlay` now skip
72+
the `write_texture` upload when the supplied pixel slice length does not match
73+
`width * height * bytes_per_texel`, keeping the previously-uploaded texture; the
74+
`debug_assert` stays for dev builds. `close_rom` now seeds `present_staging` with
75+
a valid zeroed `NES_W * NES_H * 4` frame, so closing a ROM presents a clean blank
76+
(black) window rather than a frozen last frame or a crash. Frontend-only;
77+
byte-identical when never closing a ROM.
78+
- **Clean pause / unpause — no spurious pacing spike, zero audio underruns (#6).**
79+
Two paused-state glitches fixed. (1) Pacing: on resume `set_paused` rebased
80+
`next_frame_time` to "now" so the producer does not burst-catch-up, but the
81+
produced/presented interval rings still held the pre-pause `last` timestamp, so
82+
the next `record_produced` logged the whole pause duration as a single giant
83+
`produced_max_ms` spike (675 ms / 1395 ms in captured logs). `set_paused` now also
84+
calls `perf.break_phase()` on resume so the paused wall-clock gap is dropped
85+
instead of counted as a produced/presented frame interval. (2) Audio: while paused
86+
the producer stops pushing and the cpal callback drained the ring, then logged an
87+
underrun and re-gated on resume. A new sticky pause flag
88+
(`SampleQueue::gate_for_pause()` / `resume_from_pause()`) outputs silence WITHOUT
89+
consuming the buffered tail and takes precedence over the `start_threshold`
90+
auto-reopen (which previously re-opened the gate on the very next callback because
91+
the full ring satisfied `avail >= start_threshold`), so a clean pause/unpause now
92+
yields zero underruns. Frontend-only; byte-identical when never pausing.
93+
- **Help -> Documentation pane overhaul (#4).** Three fixes to `doc_panel.rs`
94+
(emulation core untouched). (1) Word-wrap at any UI scale: the content pane was a
95+
`ScrollArea::both`, which gives the inner UI unbounded horizontal width so
96+
`Label::wrap` had nothing to wrap against and text only reflowed after a manual
97+
resize at x4 scale; it is now a vertical-only `ScrollArea` with the content column
98+
pinned to `available_width`, so bodies wrap to the pane's real width at x1-x4 and
99+
any pane size. (2) A collapsible multi-level sidebar tree (default-collapsed below
100+
the top level) with intra-document hyperlinks. (3) The changelog dropdown now
101+
lists released versions newest-first but orders the `[Unreleased]` section last.
64102
- **HD-pack tile substitution now applies in the debugger / tool branch (#3).**
65103
A loaded HD pack (e.g. *Zelda Remastered*, ~15,849 rules) parsed and reported
66104
success, but nothing changed on screen whenever the debugger overlay or a
@@ -92,6 +130,13 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
92130
(`MenuAction::ToggleDebugger`, the `ShellFrame::debugger_visible` field, and the
93131
`DebuggerOverlay::toggle` method).
94132

133+
### Documentation
134+
135+
- **Exhaustive README rewrite (#7).** README.md rewritten for v1.7.0 "Forge":
136+
the full feature catalogue, a complete WebAssembly / browser section, the
137+
previously-missing workspace crate, and the full peripheral set, with version
138+
tags and links corrected (#151 review nits applied).
139+
95140
## [1.7.0] - 2026-06-19 - "Forge" (Feature Release)
96141

97142
### Added

‎CLAUDE.md‎

Lines changed: 5 additions & 3 deletions
Large diffs are not rendered by default.

‎Cargo.lock‎

Lines changed: 12 additions & 12 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎Cargo.toml‎

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ members = [
1616
]
1717

1818
[workspace.package]
19-
version = "1.7.0"
19+
version = "1.7.1"
2020
edition = "2024"
2121
rust-version = "1.96"
2222
license = "MIT OR Apache-2.0"
@@ -27,17 +27,17 @@ keywords = ["nes", "emulator", "famicom", "6502", "retro"]
2727
categories = ["emulators", "games"]
2828

2929
[workspace.dependencies]
30-
rustynes-core = { path = "crates/rustynes-core", version = "1.4.1" }
31-
rustynes-cpu = { path = "crates/rustynes-cpu", version = "1.4.1" }
32-
rustynes-ppu = { path = "crates/rustynes-ppu", version = "1.4.1" }
33-
rustynes-apu = { path = "crates/rustynes-apu", version = "1.4.1", default-features = false }
34-
rustynes-mappers = { path = "crates/rustynes-mappers", version = "1.4.1" }
35-
rustynes-netplay = { path = "crates/rustynes-netplay", version = "1.4.1" }
36-
rustynes-script = { path = "crates/rustynes-script", version = "1.4.1" }
37-
rustynes-test-harness = { path = "crates/rustynes-test-harness", version = "1.4.1" }
30+
rustynes-core = { path = "crates/rustynes-core", version = "1.7.1" }
31+
rustynes-cpu = { path = "crates/rustynes-cpu", version = "1.7.1" }
32+
rustynes-ppu = { path = "crates/rustynes-ppu", version = "1.7.1" }
33+
rustynes-apu = { path = "crates/rustynes-apu", version = "1.7.1", default-features = false }
34+
rustynes-mappers = { path = "crates/rustynes-mappers", version = "1.7.1" }
35+
rustynes-netplay = { path = "crates/rustynes-netplay", version = "1.7.1" }
36+
rustynes-script = { path = "crates/rustynes-script", version = "1.7.1" }
37+
rustynes-test-harness = { path = "crates/rustynes-test-harness", version = "1.7.1" }
3838
# v1.8.0 "Android" — the shared mobile bridge, consumed by rustynes-android (and
39-
# v1.9.0's rustynes-ios). Path dep; the version req is a floor (`^1.7.0`).
40-
rustynes-mobile = { path = "crates/rustynes-mobile", version = "1.7.0" }
39+
# v1.9.0's rustynes-ios). Path dep; the version req is a floor.
40+
rustynes-mobile = { path = "crates/rustynes-mobile", version = "1.7.1" }
4141

4242
# v1.1.0 beta.3 (Workstream E) — Lua scripting. `vendored` compiles Lua 5.4
4343
# from source (no system Lua needed); native-only (the wasm/no_std builds never

‎README.md‎

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
1111
[![Build Status](https://github.com/doublegate/RustyNES/workflows/CI/badge.svg)](https://github.com/doublegate/RustyNES/actions)
1212
[![License: MIT OR Apache-2.0](https://img.shields.io/badge/license-MIT%20OR%20Apache--2.0-blue.svg)](#license)
13-
[![Version](https://img.shields.io/badge/version-v1.7.0-blue.svg)](https://github.com/doublegate/RustyNES/releases)
13+
[![Version](https://img.shields.io/badge/version-v1.7.1-blue.svg)](https://github.com/doublegate/RustyNES/releases)
1414
[![Rust: 1.96](https://img.shields.io/badge/rust-1.96-orange.svg)](rust-toolchain.toml)
1515
[![Platform](https://img.shields.io/badge/platform-Windows%20%7C%20Linux%20%7C%20macOS%20%7C%20Web-lightgrey.svg)](#platform-support)
1616
[![AccuracyCoin](<https://img.shields.io/badge/AccuracyCoin-100%25%20(139%2F139)-brightgreen.svg>)](#compatibility-and-accuracy)
@@ -645,13 +645,14 @@ workspace API docs (rustdoc) at
645645

646646
## Version History
647647

648-
The current release is **v1.7.0 "Forge"**, the writable + programmable tooling, accuracy,
649-
mapper-breadth, and reach release on the cycle-accurate v1.0.0 production core (it follows
650-
the v1.6.0 "Studio" TAS-authoring line and the v1.5.0 "Lens" insight/scriptability line).
651-
The road so far:
648+
The current release is **v1.7.1**, a bugfix / polish patch on **v1.7.0 "Forge"** (the
649+
writable + programmable tooling, accuracy, mapper-breadth, and reach release on the
650+
cycle-accurate v1.0.0 production core, which follows the v1.6.0 "Studio" TAS-authoring line
651+
and the v1.5.0 "Lens" insight/scriptability line). The road so far:
652652

653653
| Version | Highlights |
654654
| ---------- | ------------------------------------------------------------------------------------------- |
655+
| **v1.7.1** | Patch on "Forge" — seven fixes: a **ROM-close crash** (skip the `write_texture` upload on a pixel-slice length mismatch so the release build no longer aborts wgpu; `close_rom` presents a clean blank frame); **clean pause/unpause** (a pacing-timer `break_phase()` reset on resume + a sticky audio pause gate → no spurious `produced_max_ms` spike, zero underruns); a **Documentation pane overhaul** (word-wrap at any UI scale, a collapsible multi-level sidebar tree with intra-doc links, `[Unreleased]` ordered last); an **exhaustive README rewrite**; **Tools-menu icon** fixes for NSF Player / Pixel Inspector (glyph swap dodging egui's Ubuntu-Light `fi`/`fl` PUA-ligature collision); **removal of the vestigial "Show Debugger" checkbox** + dead plumbing; and **HD-pack tile substitution** now applying in the debugger / tool render branch. Bugfix-only; with optional features off the shipped / native / `no_std` / wasm builds behave as v1.7.0 and AccuracyCoin holds 100% (139/139). |
655656
| **v1.7.0** | "Forge" — the tools become **writable** and **programmable**. **F** accuracy hardening (battery-save round-trip oracle + length-halt/reload + DMC even/odd-defer pins + an off-by-default PPU extra-scanlines overclock); mapper breadth → **168 families** (G1 reusable-ASIC: FK23C / COOLBOY / MINDKIDS / Sachen / Waixing / Kaiser, BestEffort honesty-gated); **A** editing-capable tools (palette / nametable / CHR / OAM writeback, an iNES / NES 2.0 header editor, an inline 6502 assembler); **C** debugger depth (CallstackManager + step modes, MemoryAccessCounter + uninit-read, ca65 / cc65 `.dbg` source maps); **B** scriptable **TAStudio** (`tastudio.*` Lua API + analysis-canvas callbacks) + full Lua parity; **E** host IPC / automation (`comm.*` / `client.*` / `userdata.*`) behind a new off-by-default `script-ipc` feature (host-mediated sandbox, ADR 0016); **D** rewind (HistoryViewer + Export-Last-30s `.rnm` + a Zwinder XOR-delta + LZ4 tiered greenzone); **G** expansion-audio (NSF router reusing VRC6/7 / FDS / MMC5 / N163 / 5B + MMC5 audio), movie import (`.fcm` / `.fmv` / `.vmv`; `.fm2` / `.bk2` export hashing), and an **HD-Pack Builder** (ADR 0017) + the HD-pack loader real-Mesen-`<tile>`-format fix (ADR 0018); a UI overhaul (consolidated Input Display, modernized menu / status bar, a polished Documentation pane); plus the **H1–H9 reach wave** — browser-RA finish + an RA HUD, spectator netplay + Game-Genie-encoder / `.srt` / `.tbl`, coverage-harness `.zip` / `.7z` / `.fds` discovery, per-game `<rom>.json` config overrides + a DIP editor + a lag counter (ADR 0019), audio depth (stereo panning / Schroeder reverb / crossfeed / output-device picker / 20-band EQ, ADR 0020), web/wasm parity (browser Lua / File-System-Access-API / Gamepad-API / PWA-offline / `?settings=` share-links, ADRs 0021+0022), an **i18n** framework (compile-time string catalog + a language picker, English + Spanish, ADR 0023), and a `full` maximal-native-feature build + `cargo full-run` alias. Additive / off-by-default; the shipped / native / `no_std` / wasm builds stay byte-identical and AccuracyCoin holds 100% (139/139). |
656657
| **v1.6.0** | "Studio" — creator-power + accuracy-polish + reach. A **TAStudio-class piano-roll TAS editor** (save-state greenzone + lag log + markers + forkable branches + `.rnmproj` projects, with a drag-paint egui grid + deterministic seek); **`.fm2` (FCEUX) and `.bk2` (BizHawk) movie interop** ↔ `.rnm`; **Lua movie driving** (`emu.run` / `emu.frameadvance`) + data breadth (memory domains, sized reads, `joypad`); **Mesen2-class debugger depth** (expression / conditional breakpoints, R/W/X watchpoints, a watch window, conditional trace, a full hex editor, RAM watch / search); an **off-axis accuracy** verification + documentation pass (DMC/OAM-DMA controller corruption, `$2007` read-during-render, sprite-overflow + open-bus decay — verified, no engine change); mapper breadth → **150 families** (J.Y. ASIC + a discrete-multicart batch) + a **UNIF (`.unf`) loader**; **FDS-proper** (timed disk-head + `$4032` auto-insert + per-game CRC quirk table); **A/V recording** (ffmpeg → mp4 / mkv, default-off `av-record`); **HD-pack HD audio** (`<bgm>` / `<sfx>` OGG via `$4100`, default-off `hd-pack`); and a **shader / filter ecosystem** (LMP88959 NTSC/PAL, hqNx / xBRZ, a constrained `.slangp` / `.cgp` import). Additive / off-by-default; the shipped / native / `no_std` / wasm builds stay byte-identical and AccuracyCoin holds 100% (139/139). |
657658
| **v1.5.0** | "Lens" — insight + scriptability + creator tooling + polish: debugger **visualization** (Input Miniatures overlay, a graphical PPU event-viewer heatmap, a per-scanline trace, an HD-pack pixel inspector), a Lua **dev/TAS API** (memory/cart/save-state/symbol queries), a **TASVideos** compatibility pass + replay/TAS-window polish + an NSF waveform scope, a measure-first **frontend pacing & audio-sync** perf pass with perf-log↔panel parity, **UX polish** (named-palette editor, per-side overscan WYSIWYG, an Enhancements settings group, device-config controls), **accessibility** (UI scaling, high-contrast + Okabe-Ito colorblind themes, keyboard-only nav), a **native-UI overhaul** + in-app **Documentation** pane, mapper coverage 113 → **123 families**, and **casual-mode browser RetroAchievements** scaffolding (ADR 0015, off by default — emcc-built rcheevos side module + auth-proxy contract; live-browser verify is maintainer-manual). All additive / off-by-default so shipped / native / `no_std` / wasm stay byte-identical; AccuracyCoin 100% (139/139) held. |

‎docs/STATUS.md‎

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,22 @@
11
# RustyNES — Project Status Matrix
22

3-
> **Current release: v1.7.0 "Forge"** (released 2026-06-19) — the "writable +
3+
> **Current release: v1.7.1** (2026-06-19) — a bugfix / polish PATCH on **v1.7.0
4+
> "Forge"** (the feature release it patches; framed below). Additive / bugfix-only:
5+
> with the optional features off the shipped / native / `no_std` / wasm builds behave
6+
> as v1.7.0 (only the embedded `CARGO_PKG_VERSION` string + the seven fixes differ)
7+
> and **AccuracyCoin holds 100% (139/139)** (`cargo test --workspace --features
8+
> test-roms`: **1906 passed, 20 ignored**). The seven fixes: #1 ROM-close GPU abort
9+
> (skip the `write_texture` upload on a pixel-slice length mismatch; `close_rom`
10+
> presents a clean blank frame) · #6 clean pause/unpause (pacing-timer
11+
> `break_phase()` reset on resume + a sticky audio pause gate → no `produced_max_ms`
12+
> spike, zero underruns) · #4 Documentation-pane overhaul (word-wrap at any UI scale,
13+
> collapsible multi-level sidebar tree with intra-doc links, `[Unreleased]` ordered
14+
> last) · #7 exhaustive README rewrite · #2 Tools-menu NSF Player / Pixel Inspector
15+
> icon glyph swap (dodges egui's Ubuntu-Light `fi`/`fl` PUA-ligature collision) · #5
16+
> removed the vestigial "Show Debugger" checkbox + dead plumbing · #3 HD-pack tile
17+
> substitution now applies in the debugger / tool render branch.
18+
>
19+
> **v1.7.0 "Forge"** (released 2026-06-19) — the "writable +
420
> programmable tools" release, MAXIMAL scope (full A–H + an H1–H9 reach wave) on the
521
> current dot-lockstep scheduler. **beta.1** (#134, F accuracy hardening + G1 ASIC
622
> mappers 150→**168** + H7 measure-first perf) · **beta.2** (#135, A editing-capable
@@ -18,8 +34,9 @@
1834
> output widening) · 0021 (File System Access fallback) · 0022 (settings share-link) ·
1935
> 0023 (i18n string-catalog).
2036
21-
**Current release: v1.7.0 "Forge" — the writable + programmable tooling, accuracy,
22-
mapper-breadth, and reach release** on the cycle-accurate v1.0.0 production core. A
37+
**Current release: v1.7.1 — a bugfix / polish patch on v1.7.0 "Forge"** (the
38+
writable + programmable tooling, accuracy, mapper-breadth, and reach feature release
39+
it patches, described below) on the cycle-accurate v1.0.0 production core. A
2340
NES/Famicom emulator with the Mesen2 / higan / ares accuracy bar, shipped as a
2441
polished desktop application. **AccuracyCoin 100.00% (139/139)**, the 60-ROM
2542
`external_real_games` + 52-entry `external_extended` oracles byte-identical,
@@ -849,8 +866,8 @@ unless the default flips.
849866
**RustyNES ships at v1.0.0** (the production cut), with the additive,
850867
off-by-default feature releases **v1.1.0 "Scriptable" → v1.2.0 "Curator" →
851868
v1.3.0 "Bedrock" → v1.4.0 "Fidelity" (+ the v1.4.1 patch) → v1.5.0 "Lens" →
852-
v1.6.0 "Studio" → v1.7.0 "Forge"** on top — **v1.7.0 "Forge" is the current
853-
release**. The
869+
v1.6.0 "Studio" → v1.7.0 "Forge" → v1.7.1 (patch)** on top — **v1.7.1 (the
870+
bugfix/polish patch on v1.7.0 "Forge") is the current release**. The
854871
table below is the **engine-lineage** version history
855872
— the internal engine line whose increments produced the v1.0.0 technology. Its
856873
`v0.9.x` / `v1.x` / `v2.x` markers are the engine's own line, retained as

0 commit comments

Comments
 (0)