diff --git a/HELP.md b/HELP.md index 5da7678..3328540 100644 --- a/HELP.md +++ b/HELP.md @@ -691,8 +691,12 @@ development board IPC bridge. The IRIS-compatible fork lives at: enabled = true ``` + The dev board is an opt-in build feature — without `ultra64` the `[ultra64]` + section is ignored and no board appears in GIO slot 0: + ```bash - cargo run --release --features lightning,rex-jit + cargo run --release --features lightning,rex-jit,ultra64 # CLI + cargo run --release -p iris-gui --features ultra64 # GUI ``` 2. Build and run the N64 emulator (it can be started at any time — it will diff --git a/installer/iris-gui.iss b/installer/iris-gui.iss index dccb38a..51859b5 100644 --- a/installer/iris-gui.iss +++ b/installer/iris-gui.iss @@ -38,14 +38,26 @@ #define ArchIdentifier "x64compatible" #endif -#define MyAppName "IRIS" +; CPU variant of the bundled iris-gui.exe. CI passes /DR5000=1 for the R5000 +; build; without it this is the default R4400 build. The two get distinct AppIds, +; names, and default folders so both can be installed side by side — same binary +; layout, different emulated CPU (a compile-time choice, so they can't be one +; installer with a switch). +#ifdef R5000 + #define MyAppName "IRIS (R5000)" + #define MyAppId "{{2B6E5D74-9C41-4A83-B7F0-5E1C8D2A64B9}" +#else + #define MyAppName "IRIS" + #define MyAppId "{{A7F2C91E-3D8B-4F5A-8E2C-1B9D6A3E8F42}" +#endif #define MyAppPublisher "Dani Sarfati" #define MyAppURL "https://github.com/danifunker/iris" #define MyAppExeName "iris-gui.exe" [Setup] -; Stable AppId — do not change across releases. -AppId={{A7F2C91E-3D8B-4F5A-8E2C-1B9D6A3E8F42} +; Stable AppIds — do not change across releases (an AppId change orphans the +; previous install's uninstall entry instead of upgrading it). +AppId={#MyAppId} AppName={#MyAppName} AppVersion={#MyAppVersion} AppPublisher={#MyAppPublisher} diff --git a/iris-gui/Cargo.toml b/iris-gui/Cargo.toml index 4c99214..0410f65 100644 --- a/iris-gui/Cargo.toml +++ b/iris-gui/Cargo.toml @@ -76,16 +76,24 @@ r5k = ["iris/r5k"] # YouTube / max in-process perf: lightning (no GDB hot-path) + idle-pause on the # embedded iris core. Build with: cargo build -p iris-gui --release --features premiere premiere = ["iris/lightning", "iris/idle-pause"] +# v1 MIPS JIT, then armed at runtime with IRIS_JIT=1. Off by default, so the +# Debug tab's JIT section is inert unless you build with this. +# Build with: cargo build -p iris-gui --features jit +jit = ["iris/jit"] +# N64 development board (Ultra64) — GIO slot 0 + POSIX shm bridge to an external +# gopher64. Gates both the core device and this crate's toggle/help window (the +# `ultra64` field on iris's Config only exists with the core feature on). +# Build with: cargo build -p iris-gui --features ultra64 +ultra64 = ["iris/ultra64"] [dependencies] -# Group A (additive) features are always on for iris-gui so the user can -# enable them at runtime via the config UI: chd (.chd disk paths), camera -# (vino source), jit (IRIS_JIT toggle), rex-jit, ultra64 (N64 dev board IPC -# bridge). They add code paths and native dependencies (ultra64: shared_memory -# + raw_sync, both cross-platform) but no runtime cost when unused — the -# ultra64 GIO device + POSIX shm bridge are only created when the user enables -# the board on the General tab. The toggle itself is hidden in App Store builds. -iris = { path = "..", features = ["chd", "camera", "jit", "rex-jit", "ultra64"] } +# Group A (additive) features are always on for iris-gui so the user can enable +# them at runtime via the config UI: chd (.chd disk paths), camera (vino source), +# rex-jit (REX3 draw-shader compiler). They add code paths and native deps but no +# runtime cost when unused. `jit` and `ultra64` used to be here too; they are now +# opt-in passthrough features (above), since neither is usable without extra +# setup — IRIS_JIT=1 for the one, an external gopher64 for the other. +iris = { path = "..", features = ["chd", "camera", "rex-jit"] } eframe = { version = "0.35", default-features = false, features = ["default_fonts", "glow", "wayland", "x11"] } egui = "0.35" crossbeam-channel = "0.5" diff --git a/iris-gui/src/config_ui.rs b/iris-gui/src/config_ui.rs index 397429f..098713e 100644 --- a/iris-gui/src/config_ui.rs +++ b/iris-gui/src/config_ui.rs @@ -345,11 +345,14 @@ fn show_general(ui: &mut Ui, cfg: &mut MachineConfig) -> ConfigAction { // N64 development board (Ultra64). A single runtime toggle — the GIO device // and POSIX shm bridge (/iris_n64_bridge) are only created when this is on, - // read once at VM start. Hidden in App Store builds: the sandbox can't open - // the named shm or run the external gopher64 process it talks to. + // read once at VM start. The toggle exists only in builds that carry the + // board (source builds with --features ultra64; shipped builds don't), and + // never in App Store builds: the sandbox can't open the named shm or run the + // external gopher64 process it talks to. #[cfg(not(feature = "appstore"))] { ui.separator(); + #[cfg(feature = "ultra64")] ui.checkbox(&mut cfg.ultra64.enabled, "N64 development board (Ultra64)") .on_hover_text( "Emulate the SGI Indy N64 development board. Requires the gopher64 \ @@ -357,10 +360,13 @@ fn show_general(ui: &mut Ui, cfg: &mut MachineConfig) -> ConfigAction { IRIX. Applies on next Start. See docs/ultra64.md.", ); ui.label( - RichText::new( + RichText::new(if cfg!(feature = "ultra64") { "Settings autosave ~600 ms after edits (watch for * next to the machine name). \ - Platform, resolution, and Ultra64 apply on the next Stop → Start.", - ) + Platform, resolution, and Ultra64 apply on the next Stop → Start." + } else { + "Settings autosave ~600 ms after edits (watch for * next to the machine name). \ + Platform and resolution apply on the next Stop → Start." + }) .weak() .small(), ); @@ -1405,7 +1411,13 @@ fn show_debug(ui: &mut Ui, cfg: &mut MachineConfig) -> ConfigAction { .small(), ); ui.separator(); - ui.label("JIT (requires `cargo build --features jit`)"); + // The v1 MIPS JIT is an opt-in build feature, so these knobs do nothing + // unless this binary was built with iris-gui's `jit` passthrough. + ui.label(if build_features::JIT { + "JIT" + } else { + "JIT (inert — this build has no JIT; rebuild with `cargo build -p iris-gui --features jit`)" + }); Grid::new("jit_grid").num_columns(2).striped(true).show(ui, |ui| { ui.label("Enable JIT (IRIS_JIT=1)"); ui.checkbox(&mut cfg.jit.enabled, ""); diff --git a/iris-gui/src/main.rs b/iris-gui/src/main.rs index 1f3bd8b..c27d8f1 100644 --- a/iris-gui/src/main.rs +++ b/iris-gui/src/main.rs @@ -262,6 +262,7 @@ struct App { /// Whether the "Mount the shared folder in IRIX" Help window is open. show_nfs_help: bool, /// Whether the "N64 development board (Ultra64)" Help window is open. + #[cfg(feature = "ultra64")] show_ultra64_help: bool, /// Whether the License / Privacy Help windows are open. show_license: bool, @@ -494,6 +495,7 @@ impl App { serial_input: String::new(), show_help_info: false, show_nfs_help: false, + #[cfg(feature = "ultra64")] show_ultra64_help: false, show_license: false, show_privacy: false, @@ -1409,10 +1411,11 @@ impl App { self.show_nfs_help = true; ui.close(); } - // N64 dev board getting-started guide. Hidden in App Store - // builds, where the board can't run (sandbox blocks the POSIX - // shm bridge and there's no way to run the external gopher64). - #[cfg(not(feature = "appstore"))] + // N64 dev board getting-started guide. Only in builds that carry + // the board (source builds with --features ultra64), and never in + // App Store builds, where it can't run anyway (sandbox blocks the + // POSIX shm bridge and there's no way to run the external gopher64). + #[cfg(all(feature = "ultra64", not(feature = "appstore")))] if ui.button("🎮 N64 development board (Ultra64)…") .on_hover_text("How to set up the N64 devkit and run ROMs with gload") .clicked() @@ -1454,20 +1457,19 @@ impl App { // jit/rex-jit are compile-time features, but the sandbox (App // Store) build forces interpreter-only at runtime via IRIS_NO_JIT // (Cranelift's non-MAP_JIT pages get killed under the sandbox). - // Report the runtime reality so a compiled-in "jit: on" doesn't - // read as "the JIT is running" when it can't be. + // Report the runtime reality so a compiled-in "on" doesn't read + // as "the JIT is running" when it can't be. Not-compiled-in is + // plain "off" — shipped builds carry rex-jit but not the v1 jit, + // so "off (sandbox)" there would name the wrong reason. let jit_off = std::env::var_os("IRIS_NO_JIT").is_some(); - let jit_state = |feat: bool| if jit_off { "off (sandbox)" } else if feat { "on" } else { "off" }; + let jit_state = |feat: bool| if !feat { "off" } else if jit_off { "off (sandbox)" } else { "on" }; ui.label(format!(" jit: {}", jit_state(bf::JIT))); ui.label(format!(" rex-jit: {}", jit_state(bf::REX_JIT))); ui.label(format!(" lightning: {}", if bf::LIGHTNING { "on (no debug)" } else { "off" })); - // ultra64 (N64 dev board) is compiled in, but the App Store - // sandbox can't open its POSIX shm bridge — report the runtime - // reality there, matching the jit/rex-jit treatment above. - let ultra64_state = if cfg!(feature = "appstore") { - "off (sandbox)" - } else if bf::ULTRA64 { "on" } else { "off" }; - ui.label(format!(" ultra64: {}", ultra64_state)); + // ultra64 (N64 dev board) is a source-build opt-in; shipped builds + // don't carry it, and the App Store sandbox couldn't open its + // POSIX shm bridge even if they did. + ui.label(format!(" ultra64: {}", if bf::ULTRA64 { "on" } else { "off" })); }); }); } @@ -2754,6 +2756,7 @@ impl App { /// bridge); the N64 itself is the external gopher64 fork, so the guide is /// mostly about wiring the two processes together. Never reachable in App /// Store builds (the menu item that opens it is compiled out there). + #[cfg(feature = "ultra64")] fn ultra64_help_window(&mut self, ctx: &egui::Context) { if !self.show_ultra64_help { return; @@ -3256,6 +3259,7 @@ impl eframe::App for App { self.nfs_help_window(ctx); // Help → "N64 development board (Ultra64)" — devkit getting-started guide. + #[cfg(feature = "ultra64")] self.ultra64_help_window(ctx); // "Synchronizing disks…" modal during the exit-time CHD fold-back.