Skip to content

feat(v1.9.9): "Workshop" — iOS creator/power tools + final readiness gate - #204

Merged
doublegate merged 2 commits into
mainfrom
feat/v1.9.9-workshop
Jun 26, 2026
Merged

doublegate merged 2 commits into
mainfrom
feat/v1.9.9-workshop

Conversation

@doublegate

Copy link
Copy Markdown
Owner

v1.9.9 "Workshop" — the final iOS TestFlight release before v2.0.0 "Timebase"

Brings the desktop creator/power-tools to touch and runs a full pre-freeze readiness pass. Additive / off-by-default: the bridge gains only forwarding fns over existing rustynes-core APIs, the deterministic core / chip crates are untouched, the shipped / native / no_std / wasm core stays byte-identical, and AccuracyCoin holds 100% (139/139).

Creator / power tools

  • Cheats — Game Genie editor (persistent live codes) + one-shot raw-RAM peek/poke ($0000–$1FFF).
  • Read-only debugger inspector — FOSS/TestFlight build only, gated off the App-Store channel (ADR 0027): CPU regs, disassembly window, hex view, single-frame step, over new observational bridge fns.
  • TAStudio piano-roll — touch frame-input table + scripted playback + record-to-.rnm.
  • Foreign movie import — .fm2/.bk2/.fcm/.fmv/.vmv → native .rnm (bounds-checked: 16 MiB per-ZIP-member cap, graceful errors, never panics).
  • Audio depth (rustynes-ios host DSP) — 5-band EQ, panning, Schroeder reverb, crossfeed; bypassable to a bit-identical passthrough.
  • Symbol maps — host-side .sym/.mlb/.nl.

Readiness gate (verification · security · gap · completeness)

Full host-gate suite green (fmt / clippy every feature combo / rustdoc / no_std / wasm ×2 / test-roms 139/139 / markdownlint). A security audit (no Critical/High), a gap analysis, and a completeness-critic sweep ran; their findings were folded into a final fix round. Full record in docs/ios-v1.9.9-readiness.md.

Fixes from the gate: file imports + foreign-movie transcode moved off the main thread; poke_ram clamps the address bridge-side; missed EN/ES catalog strings + VoiceOver labels added; TAStudio .rnm export no longer captures trailing idle frames.

Note: mobile is iNES / NES 2.0 only

The picker + Info.plist no longer advertise .fds/.nsf (the shared bridge has no FDS/NSF load path). FDS disk + NSF playback on mobile are a post-v2.0.0 carryover, alongside the 20-band EQ and .dbg source maps.

iOS build + on-device validation remain the documented TestFlight carryover (Linux CI can't compile Swift).

🤖 Generated with Claude Code

…gate

The last iOS TestFlight release before v2.0.0 "Timebase". Brings the desktop
creator/power-tools to touch and runs a full pre-freeze readiness pass
(host-gate verification, security audit, gap analysis, completeness-critic).
Additive / off-by-default: the bridge gains only forwarding fns over existing
rustynes-core APIs, the deterministic core / chip crates are untouched, the
shipped / native / no_std / wasm core stays byte-identical, and AccuracyCoin
holds 100% (139/139).

Creator tools:
- Cheats: Game Genie editor (persistent) + raw-RAM peek/poke ($0000-$1FFF).
- Read-only debugger inspector (FOSS/TestFlight build only, gated off the
  App-Store channel per ADR 0027): CPU regs, disassembly window, hex view,
  single-frame step, over new observational bridge fns.
- TAStudio piano-roll: touch frame-input table + scripted playback +
  record-to-.rnm from power-on.
- Foreign movie import .fm2/.bk2/.fcm/.fmv/.vmv -> native .rnm (bounds-checked,
  16 MiB per-ZIP-member cap, graceful errors).
- Audio depth (rustynes-ios host DSP): 5-band EQ, panning, Schroeder reverb,
  crossfeed; bypassable to a bit-identical passthrough.
- Host-side symbol maps (.sym/.mlb/.nl).

Readiness pass / fixes:
- File imports + foreign-movie transcode moved off the main thread.
- poke_ram clamps the address to the work-RAM mirror bridge-side.
- Missed EN/ES catalog strings + VoiceOver labels added across the new views.
- TAStudio .rnm export no longer captures trailing idle frames.
- Mobile ROM loading is iNES/NES 2.0 only: the picker + Info.plist no longer
  advertise .fds/.nsf (the shared bridge has no FDS/NSF load path) -- FDS/NSF
  on mobile are a post-v2.0.0 carryover.
- docs/ios-v1.9.9-readiness.md records the full gate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 26, 2026 13:38

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR ships the iOS v1.9.9 “Workshop” release: bringing creator/power tools (cheats, TAStudio, read-only debugger, foreign movie import, symbol maps, and host-side audio DSP) to the iOS SwiftUI shell while keeping the deterministic Rust core behavior unchanged, plus a “readiness gate” documentation pass and version bumps.

Changes:

  • Adds new iOS creator tooling UI (Cheats, TAStudio, Debugger) and related bridge/host plumbing (foreign movie import, symbol map parsing, audio-depth DSP controls).
  • Extends rustynes-mobile with additive FFI-forwarded APIs for cheats + observational debug reads + foreign movie import, and extends rustynes-ios with an output-only audio DSP stage wired into the CoreAudio sink.
  • Updates iOS import flows to use async/off-main file I/O and removes iOS .fds/.nsf advertising (Info.plist + picker) to match supported load paths.

Reviewed changes

Copilot reviewed 29 out of 30 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
ios/RustyNES/TAStudioView.swift New touch TAStudio piano-roll authoring/playback/export UI.
ios/RustyNES/SymbolMap.swift New host-side parser for .sym/.mlb/.nl symbol files.
ios/RustyNES/SettingsView.swift Adds audio-depth section + localizable slider titles + async palette import.
ios/RustyNES/RustyNESApp.swift Updates open-URL handling to async import/open; clarifies supported ROM types.
ios/RustyNES/ROMLibrary.swift Moves ROM import and ROM reads off-main via async APIs.
ios/RustyNES/PillMenu.swift Adds creator/power tool menu entries; gates debugger to FOSS channel.
ios/RustyNES/PaletteManager.swift Makes palette import async/off-main.
ios/RustyNES/MoviePanelView.swift Adds foreign movie import entry and UTTypes support.
ios/RustyNES/Localizable.xcstrings Adds EN/ES strings for new creator tools + audio-depth labels.
ios/RustyNES/Info.plist Removes .fds/.nsf document types/UTIs; keeps .nes + .zip.
ios/RustyNES/GameView.swift Wires new sheets (Cheats/TAStudio/Debugger) + pause policy updates.
ios/RustyNES/EmulatorCore.swift Adds forwarding APIs (cheats/debug/movie import/audio depth) + TAStudio playback/export logic.
ios/RustyNES/DebuggerView.swift New read-only debugger inspector UI + symbol loading.
ios/RustyNES/ContentView.swift Updates import/open and library open to async; limits ROM picker types to .nes + .zip.
ios/RustyNES/CheatsView.swift New Game Genie + raw RAM peek/poke UI.
ios/RustyNES/AudioDepth.swift New persisted settings model for host audio-depth DSP.
ios/RustyNES/AppModel.swift Adds audio-depth model/apply hook; adds foreign movie import pipeline; async open/import.
docs/STATUS.md Updates project status matrix for v1.9.9.
docs/ios.md Documents v1.9.9 creator/power tools and iOS v1.9.x status/carryovers.
docs/ios-v1.9.9-readiness.md New readiness gate record (verification/security/gap/completeness).
crates/rustynes-mobile/src/lib.rs Adds UniFFI records + exported APIs for cheats/debug/import; adds bounds/safety helpers + tests.
crates/rustynes-ios/src/lib.rs Exposes new audio_dsp module.
crates/rustynes-ios/src/ffi.rs Adds C ABI to publish live audio-depth config to the sink.
crates/rustynes-ios/src/audio.rs Wires audio-depth DSP into real-time callback via lock-free config mailbox.
crates/rustynes-ios/src/audio_dsp.rs New host-safe EQ/pan/reverb/crossfeed DSP implementation + unit tests.
crates/rustynes-ios/include/rustynes_ios.h Adds header declaration for rustynes_ios_audio_set_depth.
CHANGELOG.md Adds v1.9.9 release notes.
Cargo.toml Bumps workspace version to 1.9.9.
Cargo.lock Updates crate versions to 1.9.9.
android/app/build.gradle.kts Bumps Android versionCode/versionName to 1.9.9.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread ios/RustyNES/CheatsView.swift Outdated
Comment thread ios/RustyNES/EmulatorCore.swift
Comment thread ios/RustyNES/AppModel.swift Outdated
Comment thread ios/RustyNES/TAStudioView.swift Outdated

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the v1.9.9 'Workshop' release, which adds several creator and power-user tools to the iOS build, including a Game Genie cheat editor, a read-only debugger inspector, a TAStudio piano-roll for input scripting, foreign movie import support, and host-side audio-depth DSP (EQ, pan, reverb, crossfeed). The changes include new Rust modules for the DSP and FFI, updated Swift models for settings and UI, and several async refactors to improve UI responsiveness during file operations. The review feedback highlights critical issues regarding security-scoped resource access in background tasks, suggests improvements for hex address parsing robustness, proposes UI enhancements for the memory editor, and recommends replacing a polling timer with an asynchronous loop for better battery efficiency.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread ios/RustyNES/ROMLibrary.swift
Comment thread ios/RustyNES/PaletteManager.swift
Comment thread ios/RustyNES/AppModel.swift
Comment thread ios/RustyNES/DebuggerView.swift
Comment thread ios/RustyNES/SymbolMap.swift
Comment thread ios/RustyNES/CheatsView.swift
Comment thread ios/RustyNES/TAStudioView.swift
…tudio

Resolve the gemini + copilot threads on v1.9.9 "Workshop" (all in ios/RustyNES/):

- Security-scoped resource (gemini HIGH x4): hoist startAccessingSecurityScoped-
  Resource() + its defer out of Task.detached onto the main-actor caller so the
  scope brackets the await (acquiring it inside the detached task can fail).
  Fixed in ROMLibrary, PaletteManager, AppModel.importForeignMovie, DebuggerView;
  also fixed the identical pre-existing pattern in HDPackStore.importPack.
- importForeignMovie no longer captures the non-Sendable EmulatorCore in a
  detached closure: the task returns only Data; the transcode runs back on main.
- CheatsView raw-RAM editor validates the address to $0000-$1FFF (parsedAddr is
  nil out-of-range), so Peek/Poke disable and can't alias into the mirror.
- tasStartExport guards against an empty frame table so the recorder is never
  left armed.
- SymbolMap parses hex with UInt(_,radix:16) + <= 0xFFFF range check instead of
  a fragile length test.
- TAStudio frame-count label uses the localized "%lld frames" key; the poll
  timer only runs during an active export (connectable publisher), idle-CPU-free.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@doublegate
doublegate merged commit 70a971b into main Jun 26, 2026
23 checks passed
@doublegate
doublegate deleted the feat/v1.9.9-workshop branch June 26, 2026 14:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants