v1.8.6
Feature release: renamable save state slots, recording sync across Time Machine rewinds, TV Mode screen selection, Wii controller toggle hotkey, RetroAchievements session/ping API, and TCC folder-scope management that stops the repeat Downloads permission prompt at launch.
Highlights
- Renamable save state slots: Hover a slot to reveal a pencil button and rename it inline, or use the Rename item in the slot/thumbnail context menu. Names persist in a sidecar
.meta.jsonnext to each.statefile and revert to "Slot N" once emptied. The auto slot (-1) is intentionally non-renamable. - Recording stays in sync across rewinds (#30): Video frame appends and audio capture are suspended during rewind/scrub mode, and the rewind window's wall-clock duration is subtracted from the PTS anchors so the recording skips the rewind on both tracks (no frozen frame, no silence gap). An opt-in "Cut rewinds from recording" setting and a "Allow rewind during recording" toggle expose both behaviors; the writer is stopped synchronously on window close before
runner.stop()to avoid an audio-capture crash on an unmapped XPC shared-memory pointer. - TV Mode screen selection: A new
TVModeMainSettingsViewcentralizes TV Mode settings (behavior, theme, display options, visible collections, gamepad button remapping), andTVModeScreenPickerViewlets you choose which connected display to use when entering TV Mode via a newScreenCatalog. - Wii controller toggle hotkey: Attach/detach the Wii controller at runtime through a new hotkey binding. Wii IR settings now use stringified integers for core options, with adjusted defaults in
dolphin_libretro_default.json, and synthetic pointer tracking is supported during input capture. - RetroAchievements session/ping API: Adds
rcheevos_api_init_ping/rcheevos_api_init_start_sessionfor rich-presence updates and session start, plusrcheevos_api_init_login_with_tokenfor token refresh. The settings view surfaces a refresh action for user stats and re-login notifications. Error handling is now a structuredRAErrortype with localized messages. - TCC folder-scope management: ROMLibrary now manages TCC permission grants for folder scopes. Combined with the folder bookmark fix in
LogManager/LoggerService(resolve with.withSecurityScope, pairstartAccessingSecurityScopedResource/stopAccessingSecurityScopedResourcearound the open log file handle), the app no longer re-prompts for Downloads access on every launch. - Hotkey settings revamp: Reset individual hotkey actions or multiple at once to their default bindings. A new
HotkeyTabenum organizes App, In-Game, and Special hotkeys, with new sections for Wii controller and Speed & Rewind actions. Gamepad Navigation settings are now reused under Hotkeys rather than living on a separate page. - BoxArtService integration:
GameCardViewandGameDetailViewuse the shared BoxArtService, with a newforceReplaceparameter ondownloadAndCache. - Per-launch auto-load override:
launchGamegains adisableAutoLoadOnStartparameter to skip auto-load for a single launch without changing the global preference.
Detailed Changes
- feat: add display name for save state slots (#31) — user-renamable slots persisted via sidecar
.meta.json, cleared when the slot is fully emptied;SlotInfogainscustomNameand itsEquatablecompares it so SwiftUI re-renders on reload - fix: keep recording A/V in sync across Time Machine rewinds (#30) —
isRewindPausedflag +rewindPtsOffsetaccumulator, strict monotonic PTS watermarks, audio read position reset on rewind release, synchronous writer stop onwindowWillClose - feat: opt-in setting to cut Time Machine rewinds from recordings —
recording_seamlessRewindCutandtimeMachine_rewindDuringRecording(default ON to preserve behavior) with localized OSD hint when rewind is blocked - refactor: revert seamless chunk-rotation code (#30) — chunk inflation and trim computation issues forced a revert to the cut-PTS-skip single-writer approach; the MetalCoordinator snapshot fix is preserved so rewind scrub frames stay out of the recording
- feat: surface TimeMachineBuffer evicted entries + add
bufferBasedRecordingtoggle scaffold —TimeMachineBuffer.pushreturns evicted entries; the buffer-based pipeline is not yet wired up, recording service still uses cut-PTS-skip - chore: leave recording service at working cut-PTS-skip behavior — verified pre-rewind content preserved across rewind boundaries; file length is play-time only
- feat(tvmode): implement screen selection and settings management —
TVModeMainSettingsView,ScreenCatalog,ScreenDescriptor,TVModeScreenPickerViewwith new localization keys (en/es/pt) - feat: add
disableAutoLoadOnStartparameter tolaunchGamefunction - feat(BoxArtService): add
forceReplaceparameter todownloadAndCachemethod - feat: integrate BoxArtService into
GameCardViewandGameDetailViewfor improved box art handling - Implement ping and start session API layers for RetroAchievements integration —
rcheevos_api_init_ping,rcheevos_api_init_start_session,rcheevos_api_init_login_with_token;RetroAchievementsServicemanages token refresh and session handling with user notifications and refresh UI - feat: enhance RetroAchievements error handling with structured
RAErrortype and localized messages - feat: implement TCC permissions management and folder scope handling in ROMLibrary
- fix: stop re-prompting for Downloads access on every launch — resolve the custom log folder bookmark with
.withSecurityScopeand pairstartAccessingSecurityScopedResource/stopAccessingSecurityScopedResourcearound the open log file handle - feat: Enhance Hotkey Configuration and Settings — per-action and bulk reset of hotkey defaults, new
HotkeyTabenum (App/In-Game/Special), Wii controller and Speed & Rewind sections, Gamepad Navigation reused under Hotkeys - Refactor logging levels and enhance Wii controller functionality — INFO changed to DEBUG in CoreOverrideBridge/LibretroBridgeImpl/LibretroCallbacks/LibretroGlobals; Wii controller attach/detach toggle hotkey; stringified-int Wii IR core options with adjusted defaults; synthetic pointer tracking during input capture
- Bump marketing version to 1.8.6 and build number to 29 across
project.yml, both Info.plists, anddocs/_config.yml