Skip to content

Commit 7f45e51

Browse files
doublegateclaude
andauthored
chore(release): v1.21.0 "Touchstone" (#237)
* chore(release): v1.21.0 "Touchstone" Cut v1.21.0, the accuracy release. Two long-running tracks that accumulated in CHANGELOG's [Unreleased] across the entire v1.8.0-v1.20.0 era (while those rungs shipped frontend/mobile/shader/CI work with zero change to the emulation core) are released together, because they are one story told from two ends: - The per-dot PPU compositor (docs/adr/0014, T-CA-10) is now the emulator's only renderer. The scanline is composited one column at a time against live registers, so a mid-line write to CGRAM/OAM/scroll/INIDISP reaches only the not-yet-drawn columns. The whole-line batch path is removed (single code path), validated 29/29 on the undisbeliever corpus against a headless MesenCE built this cycle as both the per-dot blueprint and the exact-frame oracle. - The first-party AccuracySNES self-scoring cartridge matured into a usable instrument: an AccuracyCoin-style paged menu, an automatic skyline results screen, a per-test B-skip, and a Select WRAM debug hex viewer, over a battery that climbed 323 -> 342 of 443 dossier assertions (289 on-cart + 53 scenes). Version bump and documentation sync only; no emulator behaviour change beyond the per-dot compositor already shipped on main. Details: - Bump the workspace + all 16 crate package versions 1.20.0 -> 1.21.0; refresh Cargo.lock. Inter-crate dependency floors (^1.4.0) and the historical `v1.20.0` "added in" annotations in src/docs are deliberately left untouched. - CHANGELOG.md: rename [Unreleased] -> [1.21.0] "Touchstone" (2026-07-24) with a comprehensive release intro; open a fresh empty [Unreleased]. - README.md: version badge v1.8.0 -> v1.21.0 (was stale); PPU bullet reworded from "per-scanline compositor" to the per-dot compositor with an ADR link. - docs/STATUS.md (single source of truth): current-release pointer v1.9.0 -> v1.21.0 with the intervening v1.10.0-v1.20.0 ladder summarized; AccuracySNES accuracy-dashboard row refreshed (123/123 -> 342/443, 330-test battery, MesenCE cross-check); the rustysnes-ppu subsystem row updated to the per-dot sole renderer. - to-dos/VERSION-PLAN.md: new v1.21.0 "Touchstone" rung documenting the full release scope (per-dot compositor, AccuracySNES instrument, cycle-accuracy fixes, the Antigravity CI reviewer). - to-dos/ROADMAP.md: AccuracySNES coverage 255 -> 342 of 443. - to-dos/TIER1-CYCLE-ACCURACY.md: T-CA-10 marked LANDED (sole renderer). - docs/accuracy-ledger.md: mid-scanline/HDMA entry deepened to dot resolution. - docs/accuracysnes-plan.md: "where the battery stands" refreshed (330 tests, 342/443, 53 scenes, on-cart UI row). - docs/ppu.md: "Rendering model" rewritten from per-scanline-migrating to the per-dot sole renderer; crates/rustysnes-ppu/src/render.rs module doc likewise. Gates green: cargo fmt --all --check; cargo clippy --workspace --exclude rustysnes-android --all-targets -D warnings; RUSTDOCFLAGS=-D warnings cargo doc; cargo test --workspace (518 passed). .gitignore reviewed (already covers ref-proj/MesenCE, ROMs, and AccuracySNES build intermediates; no change). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(release): scope the per-dot compositor claim to compose/draw, not fetch Address the CodeRabbit + Antigravity reviews on the v1.21.0 release PR. The release notes and the render.rs module doc claimed the per-dot compositor makes "a mid-line write to CGRAM, OAM, a scroll register, or INIDISP reach only the not-yet-drawn columns" — over-stating it. Only the compose/draw stage (pd_render_to_dot) is per-dot; the BG/sprite line fetch (pd_fetch_line) is still performed line-wide up front, so a mid-line scroll/tilemap/OPT write is NOT yet reflected on later columns (incremental fetch-ahead is T-CA-10 Phase 4c, not landed). Corrected the wording consistently — drop "scroll" from the honored mid-line writes and add the Phase-4c qualifier — across CHANGELOG.md, README- adjacent docs/STATUS.md (header + PPU subsystem row), to-dos/VERSION-PLAN.md, docs/ppu.md (Rendering model), docs/accuracy-ledger.md, and the render.rs module doc (whose second paragraph also still described the removed per-scanline model as current). Preserves the project's accuracy-honesty posture (no claiming support/accuracy not actually implemented). Docs + one module-doc comment only; no code behaviour change. fmt/clippy/doc gates green on rustysnes-ppu. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> * docs(ppu): mark the v0.8.0 mid-scanline section superseded by the per-dot model The "Rendering model" bullet (now describing the per-dot compositor) referenced the "Mid-scanline/HDMA-driven register timing" section, whose opening still described the v0.8.0 per-scanline-at-RENDER_DOT model as current — two contradictory renderer specs for a reader following the link (CodeRabbit). Add a prominent "Superseded — historical" banner at the top of that section pointing to the per-dot compositor (docs/adr/0014) as the current spec, and past-tense its status line, rather than rewrite the detailed (still-accurate-as-lineage) v0.8.0 investigation in place. Notes the one part still live: the BG/sprite line fetch is line-wide (mid-line scroll is Phase 4c). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent d555351 commit 7f45e51

28 files changed

Lines changed: 185 additions & 89 deletions

File tree

CHANGELOG.md

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,30 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
99
1010
## [Unreleased]
1111

12+
## [1.21.0] "Touchstone" - 2026-07-24
13+
14+
The accuracy release. Two long-running parallel tracks that had accumulated in `[Unreleased]`
15+
across the entire `v1.8.0`-`v1.20.0` era — while those rungs shipped frontend, mobile, shader, and
16+
CI work with zero change to the emulation core — are cut here together, because they are the same
17+
story told from two ends. **The per-dot PPU compositor (ADR 0014, ticket T-CA-10) is now the
18+
emulator's only renderer**: the compose/draw stage runs one column at a time against live registers,
19+
so a mid-line CGRAM/OAM access during active display and an `INIDISP` brightness/blank change reach
20+
only the columns not yet drawn — retiring the whole-line batch model and, with it, a class of
21+
raster-trick inaccuracy. (The BG/sprite line fetch is still done up front, so mid-line scroll/tilemap
22+
changes are not yet reflected on later columns — incremental fetch-ahead is T-CA-10 Phase 4c.) And **the first-party `AccuracySNES` self-scoring test cartridge matured into a usable
23+
instrument**: an AccuracyCoin-style paged menu, an automatic "skyline" results screen, a per-test
24+
B-skip, and a live WRAM debug hex viewer on Select, over a battery that climbed from 323 to 342 of
25+
443 dossier assertions — each row inject-verified for non-vacuity and cross-validated on RustySNES,
26+
snes9x, and (new this cycle) a headless MesenCE built as the per-dot blueprint and exact-frame
27+
oracle. Underneath both sit the cycle-accuracy fixes the cartridge surfaced: the automatic joypad
28+
read is now a timed ~4224-clock busy-window operation that starts a few dozen cycles into vblank and
29+
honours the `$4016` latch; `$4210`/`$4211` hold their flags four master clocks and return open bus
30+
in their unused bits; the PPU dot model is 340 dots with the correct two long dots per line
31+
(`T-06-A`); and OBJ interlace renders. CI gained a self-hosted Antigravity (Gemini-via-Ultra)
32+
first-pass reviewer alongside CodeRabbit. Default-build behaviour is unchanged except where the
33+
per-dot compositor is now the shipped renderer; the on-cart cartridge is developer tooling and does
34+
not affect the emulator binary.
35+
1236
### Added
1337

1438
- **AccuracySNES on-cart debug memory viewer (Select), with Start remapped to the battery restart.**

Cargo.lock

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

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ members = [
2222
]
2323

2424
[workspace.package]
25-
version = "1.20.0"
25+
version = "1.21.0"
2626
edition = "2024"
2727
rust-version = "1.96"
2828
license = "MIT OR Apache-2.0"

README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
</p>
1515

1616
<p align="center">
17-
<a href="https://github.com/doublegate/RustySNES/actions"><img src="https://github.com/doublegate/RustySNES/workflows/CI/badge.svg" alt="Build Status"></a> <a href="#license"><img src="https://img.shields.io/badge/license-MIT%20OR%20Apache--2.0-blue.svg" alt="License: MIT OR Apache-2.0"></a> <a href="https://github.com/doublegate/RustySNES/releases"><img src="https://img.shields.io/badge/version-v1.8.0-blue.svg" alt="Version"></a> <a href="rust-toolchain.toml"><img src="https://img.shields.io/badge/rust-1.96-orange.svg" alt="Rust: 1.96"></a><br>
17+
<a href="https://github.com/doublegate/RustySNES/actions"><img src="https://github.com/doublegate/RustySNES/workflows/CI/badge.svg" alt="Build Status"></a> <a href="#license"><img src="https://img.shields.io/badge/license-MIT%20OR%20Apache--2.0-blue.svg" alt="License: MIT OR Apache-2.0"></a> <a href="https://github.com/doublegate/RustySNES/releases"><img src="https://img.shields.io/badge/version-v1.21.0-blue.svg" alt="Version"></a> <a href="rust-toolchain.toml"><img src="https://img.shields.io/badge/rust-1.96-orange.svg" alt="Rust: 1.96"></a><br>
1818
<a href="#compatibility-and-accuracy"><img src="https://img.shields.io/badge/65C816%20oracle-0--diff-brightgreen.svg" alt="65C816 oracle: 0-diff"></a> <a href="#compatibility-and-accuracy"><img src="https://img.shields.io/badge/SPC700%20oracle-0--diff-brightgreen.svg" alt="SPC700 oracle: 0-diff"></a> <a href="https://doublegate.github.io/RustySNES/"><img src="https://img.shields.io/badge/pages-demo%20%2B%20rustdoc%20%2B%20docs-success.svg" alt="GitHub Pages"></a><br>
1919
<a href="#platform-support"><img src="https://img.shields.io/badge/platform-Windows%20%7C%20Linux%20%7C%20macOS%20%7C%20Web-lightgrey.svg" alt="Platform"></a>
2020
</p>
@@ -149,9 +149,11 @@ frames spanning every LoROM/HiROM × coprocessor combination in the local ROM co
149149
[`docs/adr/0002`](docs/adr/0002-fractional-timebase-refactor.md),
150150
[`docs/adr/0005`](docs/adr/0005-65816-opcode-oracle-license.md)).
151151
- **Cycle-accurate PPU1 (5C77) + PPU2 (5C78)** — BG modes 0-7, Mode 7 affine transforms, the full
152-
128-sprite OAM pipeline, color math, windows, and a per-scanline compositor that renders each
153-
line one dot before that line's own HDMA can mutate the registers it reads, matching real
154-
hardware's mid-scanline register-visibility timing.
152+
128-sprite OAM pipeline, color math, windows, and a **per-dot compositor** (`v1.21.0`,
153+
[`docs/adr/0014`](docs/adr/0014-per-dot-compositor.md)) that composites each scanline one column
154+
at a time against live registers, so a mid-line write to CGRAM, OAM, a scroll register, or
155+
`INIDISP` reaches only the columns not yet drawn — matching real hardware's mid-scanline
156+
register-visibility timing.
155157
- **Cycle-accurate SPC700 + S-DSP** — the SMP advances in cycle-exact sub-instruction lockstep
156158
with the main CPU via an integer relative-time accumulator (no floating point in the timing
157159
path), and the S-DSP is itself cycle-stepped (32 ticks per 32 kHz sample) so a mid-instruction

crates/rustysnes-android/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "rustysnes-android"
33
description = "RustySNES: Android JNI presentation host (wgpu-on-Surface, no emulation logic)"
4-
version = "1.20.0"
4+
version = "1.21.0"
55
edition.workspace = true
66
rust-version.workspace = true
77
license.workspace = true

crates/rustysnes-apu/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rustysnes-apu"
3-
version = "1.20.0"
3+
version = "1.21.0"
44
edition.workspace = true
55
rust-version.workspace = true
66
license.workspace = true

crates/rustysnes-cart/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rustysnes-cart"
3-
version = "1.20.0"
3+
version = "1.21.0"
44
edition.workspace = true
55
rust-version.workspace = true
66
license.workspace = true

crates/rustysnes-cheevos/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[package]
22
name = "rustysnes-cheevos"
33
description = "Native-only RetroAchievements (rcheevos) FFI wrapper for RustySNES"
4-
version = "1.20.0"
4+
version = "1.21.0"
55
edition.workspace = true
66
rust-version.workspace = true
77
license.workspace = true

crates/rustysnes-core/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rustysnes-core"
3-
version = "1.20.0"
3+
version = "1.21.0"
44
edition.workspace = true
55
rust-version.workspace = true
66
license.workspace = true

crates/rustysnes-cpu/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "rustysnes-cpu"
3-
version = "1.20.0"
3+
version = "1.21.0"
44
edition.workspace = true
55
rust-version.workspace = true
66
license.workspace = true

0 commit comments

Comments
 (0)