From fe1570fe3b073800779cdf2514d267df3849c903 Mon Sep 17 00:00:00 2001
From: DoubleGate
Date: Sun, 12 Jul 2026 09:55:37 -0400
Subject: [PATCH] =?UTF-8?q?release:=20cut=20v2.1.10=20"Fathom"=20(creator?=
=?UTF-8?q?=20tools=20and=20web=20parity=20=E2=80=94=20"Loom")?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Cuts the v2.1.10 release — the creator-tools-and-web-parity step of the
v2.1.5 → v2.2.0 "deepen the existing project" run. Bumps the workspace version
2.1.9 → 2.1.10, renames CHANGELOG `[Unreleased]` → `[2.1.10]`, refreshes
Cargo.lock, syncs the README badge / current-release paragraph / BibTeX, and
authors `.github/release-notes/v2.1.10.md`.
v2.1.10 (PRs #287, #288) deepens content-creation and closes the deferred browser
gaps, on the byte-identical deterministic core (AccuracyCoin 141/141,
visual_regression byte-identical, save-state / TAS / netplay replay bit-identical):
- #288 — TAStudio greenzone / force-greenzone caching + Lua API breadth (full
lifecycle callbacks, memory read-write with *Debug variants, HUD drawing,
example library, wasm piccolo parity). Two review-surfaced greenzone
anchor-bookkeeping bugs fixed with new regression tests.
- #287 — browser RetroAchievements (wasm trampoline + deployable auth-proxy,
ADR 0015; live login is a documented deploy-to-verify step) + Vs. DualSystem
presentation in the libretro core. Vs. DualSystem wasm present honestly
deferred. A real rustynes-libretro push_audio realloc bug fixed en route.
No default-build behavior change.
Co-Authored-By: Claude Opus 4.8
---
.github/release-notes/v2.1.10.md | 26 +++++++++++++++++++++++
CHANGELOG.md | 2 ++
Cargo.lock | 36 ++++++++++++++++----------------
Cargo.toml | 2 +-
README.md | 27 +++++++++++++-----------
5 files changed, 62 insertions(+), 31 deletions(-)
create mode 100644 .github/release-notes/v2.1.10.md
diff --git a/.github/release-notes/v2.1.10.md b/.github/release-notes/v2.1.10.md
new file mode 100644
index 00000000..e5bb4b1d
--- /dev/null
+++ b/.github/release-notes/v2.1.10.md
@@ -0,0 +1,26 @@
+# RustyNES v2.1.10 — Fathom (creator tools and web parity — Loom)
+
+The **creator-tools-and-web-parity** step of the v2.1.5 → v2.2.0 "deepen the existing project" run. It deepens the content-creation surface (TAStudio + Lua) and closes the deferred browser gaps (RetroAchievements + Vs. `DualSystem` libretro present). The deterministic core is untouched — greenzone snapshots and Lua reads/writes preserve the TAS/replay contract — so **AccuracyCoin 141/141 (100.00%)**, `visual_regression` byte-identical, and save-state / TAS / netplay replay stay bit-identical. Two PRs (#287, #288).
+
+## Added
+
+### Creator tools — TAStudio depth + Lua API breadth (B8/B9) — #288
+
+- **TAStudio greenzone** — per-frame cached save-states with a **force-greenzone** range so piano-roll seeking / rewinding is instant (bounded, `MAX_FORCED_GREENZONE_FRAMES` ≈ 3 min; forced frames pinned as non-evictable anchors). Named markers and richer branch slots (the `.rnmproj` model already carried these) round out the surface.
+- **Lua API breadth** — the full lifecycle-callback surface (`startFrame` / `endFrame` / `nmi` / `irq` / `reset` / `inputPolled` / `spriteZeroHit` / `codeBreak` / `stateLoaded` / `stateSaved`), CPU / PPU / palette / OAM / CHR read-write (reads are the side-effect-free debug-peek path — no open-bus / mapper side effects; writes stay gated / deferred), `emu.drawLine` HUD drawing (mlua + piccolo + both render sites), a bundled example-script library (`hud_graph.lua`, `palette_viewer.lua`, `lifecycle_events.lua`), and a **wasm `piccolo` parity uplift** (read-parity memory table + `drawLine`, the deferred-but-lands write contract preserved, ADR 0012).
+
+### Web parity — browser RetroAchievements + Vs. `DualSystem` libretro (ADR 0015) — #287
+
+- **Browser RetroAchievements** — completes the wasm trampoline marshalling and adds the **deployable auth-proxy** the browser client needs (`deploy/Dockerfile.raproxy` + an `ra-proxy` compose service behind Caddy; RA credentials via env only, never committed). The full code path is in place with marshalling-contract tests; the live login + unlock is a documented deploy-to-verify step (`docs/cheevos-browser.md`).
+- **Vs. `DualSystem` presentation in the libretro core** — detects the cabinet, steps both consoles, and composes a 512×240 side-by-side XRGB8888 image with the correct port mapping + audio + save-state — delivering the dual-console view for the mainstream RetroArch target.
+
+## Deferred (documented honestly)
+
+- **Vs. `DualSystem` on the wasm desktop-style present** — the core compositor and the libretro path are done, but un-gating the browser GPU present for the four Vs. arcade boards is a niche, CI-unverifiable (no headless-browser GPU) change to the common wasm present hot-path; kept deferred with the rationale in `docs/frontend.md`.
+
+## Notes
+
+- Version: workspace `2.1.9 → 2.1.10` (Cargo.lock refreshed). No dependency or mobile changes (the mobile apps re-release at v2.3.0).
+- **No default-build behavior change.** TAStudio greenzone is pure frontend anchor bookkeeping; Lua writes stay gated/deferred; the web-parity work is browser/libretro/deploy. AccuracyCoin stays **141/141 (100.00%)**, `visual_regression` byte-identical, and save-state / TAS / netplay replay stay bit-identical (verified by the greenzone bit-identity + TAS-replay gates). Two review-surfaced fixes landed alongside: a real `rustynes-libretro::push_audio` hot-path realloc (capacity 4096 vs stereo-interleave 8192) and two TAStudio greenzone anchor-bookkeeping bugs (each with a new regression test).
+- Docs updated in-change: `docs/scripting.md`, `docs/frontend.md`, `docs/cheevos-browser.md`, `deploy/README.md`, `CHANGELOG.md`.
+- Full host gate green: fmt · clippy (native all-targets + `scripting` / `scripting,hd-pack` / `retroachievements` + all wasm32 targets incl. `browser-cheevos` / `script-wasm`) · `cargo build -p rustynes-libretro` · rustdoc (`-D warnings`) · markdownlint (pinned v0.39.0) · AccuracyCoin 141/141 + `visual_regression` byte-identical + the greenzone / TAS bit-identity suites + `rustynes-script` (mlua + piccolo) tests · version consistency.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 29c66722..78654418 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -14,6 +14,8 @@ cycle-accurate core later replaced.
## [Unreleased]
+## [2.1.10] - 2026-07-12 - "Fathom" (creator tools and web parity — TAStudio greenzone + Lua API breadth + browser-RA auth-proxy deploy stack + Vs. DualSystem libretro presentation — "Loom")
+
### Added
- **Vs. `DualSystem` presentation in the libretro core (v2.1.10 "Web Parity").**
diff --git a/Cargo.lock b/Cargo.lock
index 150eda2b..6c06c45c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4248,7 +4248,7 @@ dependencies = [
[[package]]
name = "rustynes-android"
-version = "2.1.9"
+version = "2.1.10"
dependencies = [
"android-activity",
"android_logger",
@@ -4266,7 +4266,7 @@ dependencies = [
[[package]]
name = "rustynes-apu"
-version = "2.1.9"
+version = "2.1.10"
dependencies = [
"bitflags 2.13.0",
"criterion",
@@ -4279,7 +4279,7 @@ dependencies = [
[[package]]
name = "rustynes-cheevos"
-version = "2.1.9"
+version = "2.1.10"
dependencies = [
"cc",
"ureq",
@@ -4287,7 +4287,7 @@ dependencies = [
[[package]]
name = "rustynes-core"
-version = "2.1.9"
+version = "2.1.10"
dependencies = [
"bitflags 2.13.0",
"criterion",
@@ -4304,7 +4304,7 @@ dependencies = [
[[package]]
name = "rustynes-cpu"
-version = "2.1.9"
+version = "2.1.10"
dependencies = [
"bitflags 2.13.0",
"criterion",
@@ -4315,7 +4315,7 @@ dependencies = [
[[package]]
name = "rustynes-frontend"
-version = "2.1.9"
+version = "2.1.10"
dependencies = [
"anstyle",
"arboard",
@@ -4369,11 +4369,11 @@ dependencies = [
[[package]]
name = "rustynes-gfx-shaders"
-version = "2.1.9"
+version = "2.1.10"
[[package]]
name = "rustynes-hdpack"
-version = "2.1.9"
+version = "2.1.10"
dependencies = [
"lewton",
"png",
@@ -4384,7 +4384,7 @@ dependencies = [
[[package]]
name = "rustynes-ios"
-version = "2.1.9"
+version = "2.1.10"
dependencies = [
"bytemuck",
"cpal",
@@ -4398,7 +4398,7 @@ dependencies = [
[[package]]
name = "rustynes-libretro"
-version = "2.1.9"
+version = "2.1.10"
dependencies = [
"libc",
"rust-libretro",
@@ -4407,7 +4407,7 @@ dependencies = [
[[package]]
name = "rustynes-mappers"
-version = "2.1.9"
+version = "2.1.10"
dependencies = [
"bitflags 2.13.0",
"criterion",
@@ -4419,7 +4419,7 @@ dependencies = [
[[package]]
name = "rustynes-mobile"
-version = "2.1.9"
+version = "2.1.10"
dependencies = [
"rustynes-core",
"rustynes-hdpack",
@@ -4434,14 +4434,14 @@ dependencies = [
[[package]]
name = "rustynes-monetization"
-version = "2.1.9"
+version = "2.1.10"
dependencies = [
"uniffi",
]
[[package]]
name = "rustynes-netplay"
-version = "2.1.9"
+version = "2.1.10"
dependencies = [
"futures-util",
"js-sys",
@@ -4457,7 +4457,7 @@ dependencies = [
[[package]]
name = "rustynes-ppu"
-version = "2.1.9"
+version = "2.1.10"
dependencies = [
"bitflags 2.13.0",
"criterion",
@@ -4469,14 +4469,14 @@ dependencies = [
[[package]]
name = "rustynes-ra"
-version = "2.1.9"
+version = "2.1.10"
dependencies = [
"rustynes-cheevos",
]
[[package]]
name = "rustynes-script"
-version = "2.1.9"
+version = "2.1.10"
dependencies = [
"mlua",
"piccolo",
@@ -4487,7 +4487,7 @@ dependencies = [
[[package]]
name = "rustynes-test-harness"
-version = "2.1.9"
+version = "2.1.10"
dependencies = [
"insta",
"png",
diff --git a/Cargo.toml b/Cargo.toml
index 8546cdc3..db4c3a12 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -21,7 +21,7 @@ members = [
]
[workspace.package]
-version = "2.1.9"
+version = "2.1.10"
edition = "2024"
rust-version = "1.96"
license = "MIT OR Apache-2.0"
diff --git a/README.md b/README.md
index a6ab3c34..8559a69a 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,7 @@
-

+


@@ -775,16 +775,19 @@ and the Material-for-MkDocs documentation handbook at
## Current Release
-RustyNES's current release is **v2.1.9 "Fathom" ("Aperture")**, the presentation-and-signal
-step of the v2.1.5 → v2.2.0 "deepen the project" run — it adds a **marquee CRT shader stack**
-(WGSL ports of **CRT-Royale**, **crt-guest-advanced**, and **Sony Megatron** HDR, selectable
-in Settings → Shaders with mask/scanline/curvature controls and per-game presets), a
-**raw NTSC composite signal-decode path** (a new `rustynes-ppu::raw_signal` un-decoded 2C02
-composite model plus a `signal_decode.wgsl` pass that reconstructs and demodulates the real
-signal for artifact-accurate color), **GIF + WAV capture** (extending `av-record`), and a
-**generated-NTSC palette editor** with a live preview. Every shader / signal / capture path
-is **opt-in and default-off**, so the shipped default presentation stays byte-identical:
-**AccuracyCoin stays 141/141 (100.00%)**, nestest 0-diff, `visual_regression` byte-identical.
+RustyNES's current release is **v2.1.10 "Fathom" ("Loom")**, the creator-tools-and-web-parity
+step of the v2.1.5 → v2.2.0 "deepen the project" run — on the **creator** side it deepens
+**TAStudio** (greenzone / force-greenzone caching so piano-roll seeking is instant, named
+markers, richer branch slots) and broadens the **Lua API** (the full lifecycle-callback surface,
+CPU/PPU/palette/OAM/CHR read-write with side-effect-free `*Debug` variants, HUD drawing, an
+example-script library, and wasm-`piccolo` parity uplift); on the **web-parity** side it
+completes the **browser RetroAchievements** path (wasm trampoline marshalling + a deployable
+auth-proxy stack, ADR 0015) and brings **Vs. `DualSystem`** presentation to the **libretro**
+core. The deterministic core is untouched — greenzone snapshots + Lua reads/writes preserve
+the TAS/replay contract — so **AccuracyCoin stays 141/141 (100.00%)**, `visual_regression` is
+byte-identical, and save-state / TAS / netplay replay stay bit-identical. (Vs. `DualSystem` on
+the wasm present path is honestly deferred, and the browser-RA live login is a documented
+deploy-to-verify step — see the CHANGELOG.)
The v2.1.x line opened with **v2.1.0**, the accuracy-remediation release (a display-only
PPU palette-backdrop-override fix, 86 mapper families promoted BestEffort → Curated, and
@@ -910,7 +913,7 @@ If you use RustyNES in academic research, please cite:
author = {RustyNES Contributors},
title = {RustyNES: A Cycle-Accurate NES Emulator in Rust},
year = {2026},
- version = {2.1.9},
+ version = {2.1.10},
url = {https://github.com/doublegate/RustyNES},
note = {Cycle-accurate NES emulator on a master-clock-precise scheduler;
AccuracyCoin 100\% (141/141), nestest 0-diff; 172 mapper families,