-
-
Notifications
You must be signed in to change notification settings - Fork 0
Mobile and Cross Platform
RustyNES ports to mobile (Android and iOS) the same way it ports to the browser: the pure-Rust, byte-identical core is unchanged, and only a new host is written. Nothing touches the chip stack or the emitted-frame/sample contract, so AccuracyCoin 100% (139/139) holds on host CI.
Android App (Kotlin) iOS App (SwiftUI)
│ │
│ drives the core via UniFFI │ drives the core via UniFFI
▼ ▼
rustynes-android (JNI) rustynes-ios (Metal/CoreAudio)
│ │
└──────────────────┬───────────────────┘
│
rustynes-mobile (shared)
│
rustynes-core (no_std)
-
crates/rustynes-mobile: The platform-agnostic bridge. Owns the typed control surface overrustynes_core::Nesand lets UniFFI generate the Kotlin (Android) and Swift (iOS) bindings from the#[uniffi::export]surface. -
Determinism & data:
- Input converges on the single late-latched
Buttonsmask per port, exactly as the desktop and wasm hosts do. Touch and hardware gamepad are indistinguishable to the core. - Save-states use the platform-independent
.rnsformat, so a state saved on desktop loads on Android and iOS, preserving cross-play. - No commercial ROMs are ever bundled.
- Input converges on the single late-latched
The Android host (rustynes-android) uses a Jetpack Compose shell that drives the core through the generated NesController.
-
Glue: Carries only the narrow JNI/surface/audio glue UniFFI can't express (e.g.,
ANativeWindow→ wgpu, AAudio sink). -
Prerequisites:
rustup target add aarch64-linux-android x86_64-linux-android,cargo-ndk. - Distribution: Currently distributed via GitHub-Releases sideload. Google Play launch is deferred to v2.1.0. Emulators are allowed on Google Play given no bundled ROMs.
The iOS / iPadOS application is a thin native SwiftUI shell over the byte-identical Rust core.
-
Glue:
rustynes-iosadds only the hot glue UniFFI cannot express over a C ABI (Metal surface lifecycle, CoreAudio sink). -
Metal Surface: The shim builds a surface from the
UIViewpointer (the SwiftUIMTKView) via a raw-window-handle 0.6UiKithandle. wgpu-hal readsview.layerand drives Metal without needing anobjc2dependency. -
Audio:
AudioSinkopens a cpal CoreAudio output stream fed by a lock-free SPSC ring.AVAudioSessionis configured Swift-side. - Tools: Includes creator/power tools like Cheats, a read-only debugger inspector, a TAStudio piano-roll, foreign movie import, and a host audio-depth DSP.
The web frontend builds via Trunk (trunk build --release).
The WASM frontend (crates/rustynes-frontend/web) runs the same core inside a browser canvas, providing a playable demo and lightweight embed capabilities.
RustyNES is a cycle-accurate Nintendo Entertainment System emulator written in pure Rust. Licensed under MIT OR Apache-2.0. | GitHub Repository | Web Demo