-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathissues.jsonl
More file actions
49 lines (49 loc) · 79.3 KB
/
issues.jsonl
File metadata and controls
49 lines (49 loc) · 79.3 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
{"_type":"issue","id":"fuse-8k3","title":"SDL2 fullscreen startup recreates/resizes window visibly","description":"Address native SDL2 UI startup behaviour where ./fuse --full-screen first maps a windowed SDL window and/or recreates the SDL window several times before settling into fullscreen. Analysis points to ui/sdl2/sdl2_display.c: sdl2display_create_window() creates SDL_WINDOW_SHOWN then calls SDL_SetWindowFullscreen(), and startup scaler selection can call scaler_select_scaler() -\u003e uidisplay_hotswap_gfx_mode() -\u003e sdl2display_recreate() before the final display state. SDL1 via sdl12-compat appears to pass fullscreen flags directly to SDL_CreateWindow() for initial fullscreen and tries to reuse the SDL2 window on later SetVideoMode calls, which likely explains why it does not visibly reinitialise. Acceptance: startup with --full-screen should avoid visible windowed-to-fullscreen transition and avoid unnecessary SDL window destroy/create cycles; toggling fullscreen from options should keep existing behaviour; verify at least SDL2 build starts cleanly.","notes":"Reverted last attempted SDL2 auto_fullscreen_scaler tweak per testing feedback. Current uncommitted state is back to the simpler windowed_scaler preservation plus the separate current-fits fullscreen scaler chooser change. Note user preference: options dialog should always show actual scaler in use, not a separate desired scaler. Verified with make -j10 fuse unittests/sdl2displaytest \u0026\u0026 ./unittests/sdl2displaytest.","status":"in_progress","priority":1,"issue_type":"bug","assignee":"Fredrick Meunier","owner":"fredm@spamcop.net","created_at":"2026-05-11T11:42:16Z","created_by":"Fredrick Meunier","updated_at":"2026-05-12T08:41:13Z","started_at":"2026-05-11T12:00:39Z","dependency_count":0,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"fuse-73b","title":"SDL2 fullscreen has scaling artefacts on Ubuntu","description":"Address native SDL2 UI scaling artefacts seen after ./fuse --full-screen on Ubuntu. Analysis suggests the SDL2 renderer path renders a Fuse software-scaled RGB565 texture at image_width * current_scaler, sets SDL_RenderSetLogicalSize() to that size, and lets SDL desktop fullscreen scale it again to the actual renderer output. On common 16:9 desktops this can produce non-integer final scaling. sdl12-compat also uses FULLSCREEN_DESKTOP and logical size, but explicitly sets SDL_HINT_RENDER_SCALE_QUALITY around texture creation, while native SDL2 does not, so backend/default filter differences may explain why SDL1 via sdl12-compat hides or avoids the artefacts. Acceptance: fullscreen output on Ubuntu should avoid obvious uneven/interpolation artefacts while preserving SDL1-style fixed Fuse scaler semantics where possible; test macOS regression if available; document any chosen scale-quality/integer-scaling policy in code comments if non-obvious.","notes":"Do not implement yet. Useful tests: run SDL1/sdl12-compat with SDL12COMPAT_SCALE_METHOD=nearest to see whether artefacts appear; try native SDL2 with SDL_HINT_RENDER_SCALE_QUALITY=0/1 and/or explicit destination rect/integer scaling experiments. Remember project memory sdl2-renderer-backend-guidance: avoid silently replacing fixed scaler semantics with free SDL scaling.","status":"closed","priority":1,"issue_type":"bug","assignee":"Fredrick Meunier","owner":"fredm@spamcop.net","created_at":"2026-05-11T11:42:14Z","created_by":"Fredrick Meunier","updated_at":"2026-05-11T11:59:45Z","started_at":"2026-05-11T11:44:00Z","closed_at":"2026-05-11T11:59:45Z","close_reason":"Implemented SDL2 render scale quality hint for fullscreen scaling artefacts; left commit for maintainer review","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-so3.4","title":"Implement SDL2 desktop fullscreen presentation","description":"Change native SDL2 fullscreen startup and toggling so the default fullscreen path uses SDL_WINDOW_FULLSCREEN_DESKTOP. Present the emulator output in an aspect-correct fullscreen rectangle that fills as much of the desktop fullscreen surface as possible, with clear decisions about how this interacts with Fuse's existing scalers and status icons.","acceptance_criteria":"./fuse --full-screen in the SDL2 UI uses SDL_WINDOW_FULLSCREEN_DESKTOP by default; no real display mode is selected during default fullscreen; emulator output is aspect-correct and visibly fills the desktop fullscreen area rather than remaining a small centered rectangle; fullscreen toggle/recreate paths continue to work.","notes":"Audit-driven scope update from fuse-so3.2:\n- Default SDL2 fullscreen must use SDL_WINDOW_FULLSCREEN_DESKTOP. Do not call SDL_SetWindowDisplayMode() in the normal SDL2 fullscreen path.\n- Create the SDL2 window at the normal image*Fuse-scaler size, enter desktop fullscreen, then sync presentation from SDL_GetWindowSurface()/actual window surface size.\n- Preserve fixed Fuse scaler semantics: choose the largest supported Fuse scaler that fits the desktop fullscreen area and avoid arbitrary SDL free scaling unless it is introduced later as an explicit separate mode.\n- Keep centering offsets, rect scaling/update helpers, status icon placement, and fullscreen toggle/recreate semantics.\n- Update sdl2display_find_best_fullscreen_scaler() to use desktop/actual fullscreen surface height rather than a selected fixed-mode height.\n- SDL1 ui/sdl/sdldisplay.c real mode selection is out of scope for this SDL2 implementation task.\nImplementation direction update:\n- Rework the SDL2 fullscreen presentation toward the sdl12-compat-style path: SDL_WINDOW_FULLSCREEN_DESKTOP plus SDL_RenderSetLogicalSize().\n- Keep Fuse's fixed scaler output as the renderer logical target, upload it to a streaming RGB565 texture, clear the renderer to black, RenderCopy the texture, and Present. SDL handles aspect-correct pillarbox/letterbox.\n- This replaces the prior window-surface blit presentation experiment and makes fullscreen fill as much of the desktop as possible while preserving aspect.","status":"closed","priority":1,"issue_type":"task","assignee":"Fredrick Meunier","owner":"fredm@spamcop.net","created_at":"2026-05-09T22:57:19Z","created_by":"Fredrick Meunier","updated_at":"2026-05-10T00:15:31Z","started_at":"2026-05-09T23:08:00Z","closed_at":"2026-05-10T00:15:31Z","close_reason":"SDL2 renderer logical fullscreen implementation verified manually: fullscreen toggle and screen updates look OK.","labels":["fullscreen","sdl2"],"dependencies":[{"issue_id":"fuse-so3.4","depends_on_id":"fuse-so3","type":"parent-child","created_at":"2026-05-10T08:57:19Z","created_by":"Fredrick Meunier","metadata":"{}"},{"issue_id":"fuse-so3.4","depends_on_id":"fuse-so3.2","type":"blocks","created_at":"2026-05-10T08:57:27Z","created_by":"Fredrick Meunier","metadata":"{}"}],"dependency_count":1,"dependent_count":3,"comment_count":0}
{"_type":"issue","id":"fuse-so3.2","title":"Audit current SDL2 fullscreen mode-selection code and docs","description":"Map all native SDL2 fullscreen paths before changing behaviour. Identify code that enumerates/ranks display modes, settings/options that expose real mode selection, tests that assume fixed fullscreen modes, and documentation/help text that describes SDL fullscreen modes.","acceptance_criteria":"A notes update on this task lists the relevant files/functions/options and marks each as keep, remove, deprecate, or update for desktop fullscreen.","notes":"SDL2 fullscreen mode-selection audit (2026-05-10):\n\nKEEP for now:\n- ui/sdl2/sdl2_display.c:sdl2display_sync_presentation_surfaces(): recomputes window surface, scaled_screen, and centering offsets after the actual fullscreen/window size is known; needed for desktop fullscreen too.\n- ui/sdl2/sdl2_display.c:sdl2display_find_best_fullscreen_scaler() and ui/sdl2/sdl2_display_internal.c:sdl2display_choose_fullscreen_scaler(): preserve SDL1-style fixed Fuse scaler semantics and avoid postage-stamp output; update only the display-height source when fixed modes go away.\n- ui/sdl2/sdl2_display_internal.c:sdl2display_compute_offsets(), sdl2display_scale_rect(), sdl2display_icon_rect(), sdl2display_update_rect(): presentation geometry helpers remain valid for desktop fullscreen.\n- ui/sdl2/sdl2_display.c fullscreen_x_off/fullscreen_y_off: still needed to center fixed scaler output in the desktop-sized window.\n- settings_current.full_screen, --full-screen, menu.c:menu_options_fullscreen, and SDL2 mouse-grab startup behaviour: fullscreen toggle semantics stay.\n\nREMOVE from SDL2 desktop-fullscreen path:\n- ui/sdl2/sdl2_display.c:sdl2display_get_fullscreen_modes(): SDL_GetNumDisplayModes/SDL_GetDisplayMode enumeration, duplicate-resolution collapse, fit calculation, qsort ranking.\n- ui/sdl2/sdl2_display.c:sdl2display_init_fullscreen_mode(): automatic selection of modes[0], list/number/WxH parsing for SDL2, and filling fullscreen_width/fullscreen_height/fullscreen_format/fullscreen_refresh_rate from fixed modes.\n- ui/sdl2/sdl2_display.c:sdl2display_create_window(): fixed-mode branch using SDL_SetWindowDisplayMode() plus SDL_SetWindowFullscreen(... SDL_WINDOW_FULLSCREEN). SDL2 should use SDL_WINDOW_FULLSCREEN_DESKTOP instead.\n- ui/sdl2/sdl2_display.c fullscreen_format/fullscreen_refresh_rate globals once fixed modes are removed. fullscreen_width/fullscreen_height should no longer mean requested display mode; if retained, use only actual window/desktop size or remove.\n- ui/sdl2/sdl2_display_internal.h:sdl2_fullscreen_mode_info and internal.c:sdl2display_mode_fit(), sdl2display_compare_refresh(), sdl2display_compare_mode_info(), sdl2display_get_preferred_refresh() if no other code uses them after removing enumeration/ranking.\n\nDEPRECATE / COMPATIBILITY:\n- settings.dat:sdl_fullscreen_mode and generated settings.c/settings.h/options.h keep the setting for SDL1 and config compatibility. Do not hand-edit generated settings outputs unless changing settings.dat and regenerating.\n- --sdl-fullscreen-mode should become SDL1-only or ignored/deprecated under SDL2, with docs/help updated to avoid promising SDL2 fixed display modes. Existing config key sdlfullscreenmode should remain readable.\n- data/shell-completion/bash/fuse can keep --sdl-fullscreen-mode while SDL1 supports it, unless the option is globally removed later.\n\nUPDATE for desktop fullscreen:\n- ui/sdl2/sdl2_display.c:sdl2display_create_window(): choose windowed size from image*scaler; when full_screen, enter SDL_WINDOW_FULLSCREEN_DESKTOP and then sync surfaces/offsets from SDL_GetWindowSurface().\n- ui/sdl2/sdl2_display.c:sdl2display_find_best_fullscreen_scaler(): base display_height on SDL_GetDesktopDisplayMode() or actual fullscreen window surface height, not a selected fixed mode.\n- man/fuse.1 --full-screen / --sdl-fullscreen-mode sections: remove current SDL2 text saying Fuse automatically chooses a fixed fullscreen display mode and the fit/refresh ranking details; describe SDL2 desktop fullscreen instead.\n- tests in unittests/sdl2displaytest.c: keep geometry/scaler tests; remove or replace refresh/mode-fit/mode-compare tests that only verify fixed mode ranking. Update unittests/sdl2displaytest.c.uncrustify if this generated/format artifact is intentionally tracked by the branch.\n\nTests/docs currently assuming fixed SDL2 modes:\n- unittests/sdl2displaytest.c has coverage for sdl2display_choose_fullscreen_scaler and geometry that should stay; tests named refresh_*(), mode_compare_*(), and mode_fit_*() are tied to fixed mode ranking and should be removed/reworked.\n- man/fuse.1 explicitly documents SDL2 automatic fixed-mode choice, list/number/WxH, and fit/refresh ordering.\n\nNon-SDL2 reference path:\n- ui/sdl/sdldisplay.c keeps SDL1 mode enumeration/list/number/WxH handling via SDL_ListModes() and SDL_SetVideoMode(SDL_FULLSCREEN|SDL_SWSURFACE); this is not part of the SDL2 desktop-fullscreen removal.\n\nGenerated/derived files to watch:\n- settings.c, settings.h, options.h are generated from settings.dat; avoid direct edits.\n- man/fuse.1 appears checked-in docs and should be edited directly if that is the project convention for this branch.","status":"closed","priority":1,"issue_type":"task","assignee":"Fredrick Meunier","owner":"fredm@spamcop.net","created_at":"2026-05-09T22:57:16Z","created_by":"Fredrick Meunier","updated_at":"2026-05-09T23:00:48Z","started_at":"2026-05-09T22:59:42Z","closed_at":"2026-05-09T23:00:48Z","close_reason":"Audit notes added with keep/remove/deprecate/update classifications for SDL2 fullscreen mode-selection paths.","labels":["docs","fullscreen","sdl2"],"dependencies":[{"issue_id":"fuse-so3.2","depends_on_id":"fuse-so3","type":"parent-child","created_at":"2026-05-10T08:57:15Z","created_by":"Fredrick Meunier","metadata":"{}"}],"dependency_count":0,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"fuse-so3","title":"Switch to SDL2 desktop fullscreen","description":"Adopt SDL2 desktop fullscreen as the default fullscreen presentation model for the native SDL2 UI. The goal is to match modern OS expectations: avoid disruptive display-mode switches, use the current desktop mode, and scale/present Fuse's emulator output cleanly in fullscreen. This replaces the previous default strategy of enumerating and selecting real monitor modes for fullscreen, while keeping any explicitly useful compatibility paths/options only where they still make sense.","design":"Use SDL_WINDOW_FULLSCREEN_DESKTOP for native SDL2 fullscreen by default. Preserve Fuse scaler semantics deliberately: decide whether desktop fullscreen should scale the already-scaled software surface to an aspect-correct fullscreen rectangle, or introduce an explicit SDL2 desktop fullscreen presentation path. Avoid silently mixing arbitrary SDL scaling with existing scaler choices except where documented. Remove or deprecate real-mode selection code/options once the replacement behaviour is implemented and tested.","acceptance_criteria":"Native SDL2 --full-screen enters fullscreen without real display-mode switching by default; emulator image fills as much of the desktop fullscreen area as possible while preserving aspect; obsolete SDL2 mode-scanning/default-selection code is removed or isolated behind an explicit fallback/legacy option; user documentation and --sdl-fullscreen-mode help/list behaviour no longer imply real mode selection as the default; SDL2 display unit tests cover desktop fullscreen sizing/presentation decisions.","notes":"Context from SDL1/SDL2 fullscreen discussion: the project is intentionally changing direction from native SDL2 real monitor mode switching to desktop fullscreen as the better modern-OS balance. sdl12-compat appears to use SDL_WINDOW_FULLSCREEN_DESKTOP plus SDL_RenderSetLogicalSize for SDL1 software surfaces, which explains why SDL1-on-SDL2 can fill fullscreen without native SDL2's fixed-mode flicker/postage-stamp behaviour. Implementation should be incremental: audit first, then desktop fullscreen presentation, then cleanup obsolete mode scanning/options/docs/tests. Note: there may be local experimental SDL2 fullscreen edits in the worktree from earlier investigation; review/revert/rebase them before starting implementation.","status":"closed","priority":1,"issue_type":"epic","owner":"fredm@spamcop.net","created_at":"2026-05-09T22:56:55Z","created_by":"Fredrick Meunier","updated_at":"2026-05-10T00:53:07Z","closed_at":"2026-05-10T00:53:07Z","close_reason":"All SDL2 desktop fullscreen child tasks are complete: implementation uses SDL_WINDOW_FULLSCREEN_DESKTOP, presentation/scaler tests and manual notes were added, docs/options were updated, obsolete SDL2 real-mode scanning and selection code was removed, and fullscreen cursor behaviour was matched to SDL1. Final broader check completed by user.","labels":["fullscreen","sdl2"],"dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-yqk","title":"Investigate Windows CI link failure for unittests/displaytest.exe missing WinMain@16","description":"Windows CI is failing to link unittests/displaytest.exe with an undefined WinMain@16 entry point. Investigate the build/link configuration for the display test on Windows and implement the fix needed so the unittest target links successfully in CI.","status":"in_progress","priority":1,"issue_type":"bug","owner":"fredm@spamcop.net","created_at":"2026-04-12T05:07:58Z","created_by":"Fredrick Meunier","updated_at":"2026-04-12T05:08:31Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-3tt","title":"Keyboard fidelity cleanup for SDL2 UI","description":"Improve SDL2 keyboard handling so physical-key behavior and core emulator usability take priority over perfect text-entry or layout fidelity. Resolve concrete key mapping and event handling issues needed for dependable emulator control, including press/release behavior, repeat handling, and focus transitions, before taking on joystick or mouse/grab follow-up.","design":"Use physical-key semantics as the guiding rule for SDL2 keyboard behavior in this tranche. Text/layout fidelity improvements can be follow-up work once dependable emulator control is in place.","acceptance_criteria":"SDL2 key press and key release events map correctly for the essential emulator controls exercised in routine use. Repeat handling avoids obvious stuck-key or duplicate-action problems during normal emulator interaction. Losing and regaining window focus does not leave keys logically stuck or otherwise break subsequent keyboard input. Keyboard behavior is judged primarily by physical-key semantics and emulator usability rather than by text-entry or layout-perfect fidelity. Joystick and mouse/grab behavior remain outside the scope of this issue.","status":"closed","priority":1,"issue_type":"task","assignee":"Fredrick Meunier","owner":"fredm@spamcop.net","created_at":"2026-04-11T11:56:35Z","created_by":"Fredrick Meunier","updated_at":"2026-04-11T13:48:37Z","closed_at":"2026-04-11T13:48:37Z","close_reason":"SDL2 keyboard input now uses physical-key semantics for core keys, releases stuck keys on focus loss, and was verified locally by the user.","dependencies":[{"issue_id":"fuse-3tt","depends_on_id":"fuse-n5p","type":"blocks","created_at":"2026-04-11T21:57:08Z","created_by":"Fredrick Meunier","metadata":"{}"}],"dependency_count":1,"dependent_count":3,"comment_count":0}
{"_type":"issue","id":"fuse-k8e","title":"Native SDL2 sound backend with callback and sfifo","description":"Add sound/sdl2sound.c as a conservative SDL2 audio backend that follows the existing callback-driven buffering model and sfifo integration instead of redesigning the audio pipeline. Keep the backend independently selectable from the UI backend. When UI=sdl2 and SDL2 sound is available, default the sound backend to SDL2 sound while still allowing manual override.","design":"Keep the audio architecture conservative: callback plus sfifo, separate sound/sdl2sound.c module, and no broader audio rewrite. Default coupling for UI=sdl2 is a selection rule only, not a requirement that UI and audio backends always match.","acceptance_criteria":"sound/sdl2sound.c builds as a separate SDL2 audio backend and can be selected without changing the chosen UI backend. The backend opens the SDL2 audio device successfully for normal use and closes it cleanly on shutdown or backend teardown. Audio output uses the existing callback plus sfifo buffering model rather than a new pipeline. In normal emulator use there is no obvious persistent underrun, stall, or dead-air behavior attributable to the backend implementation. Backend selection remains independent of UI selection even though, when UI=sdl2 and SDL2 sound is available, the default sound backend becomes SDL2 sound unless manually overridden.","status":"closed","priority":1,"issue_type":"feature","assignee":"Fredrick Meunier","owner":"fredm@spamcop.net","created_at":"2026-04-11T11:56:18Z","created_by":"Fredrick Meunier","updated_at":"2026-04-11T12:51:45Z","closed_at":"2026-04-11T12:51:45Z","close_reason":"SDL2 sound now uses an SDL audio-device callback with sfifo buffering and was verified locally by the user.","dependencies":[{"issue_id":"fuse-k8e","depends_on_id":"fuse-pir","type":"blocks","created_at":"2026-04-11T21:57:06Z","created_by":"Fredrick Meunier","metadata":"{}"}],"dependency_count":1,"dependent_count":2,"comment_count":0}
{"_type":"issue","id":"fuse-wgi","title":"Minimal native SDL2 UI backend","description":"Introduce ui/sdl2/ as a native SDL2 frontend that reaches basic emulator usability using the existing software rendering and scaler flow. Focus this milestone on starting the emulator, running a responsive event loop, presenting frames in a window, and supporting essential keyboard-driven emulator use, not on text/layout-perfect fidelity or later modernization.","design":"This backend should stay native to ui/sdl2/ and reuse the existing software framebuffer and scaler flow for now. Prioritize dependable physical-key emulator usability over text-entry or layout fidelity in this early milestone.","acceptance_criteria":"Building with UI=sdl2 produces a working native SDL2 frontend under ui/sdl2/. Launching the emulator with UI=sdl2 starts successfully, opens an SDL2 window, and redraws visible emulator frames through the existing software/scaler path. The SDL2 event loop remains responsive during normal emulator use, including routine input and window interaction. Essential keyboard-driven emulator use works well enough for routine control and testing. Quit and shutdown paths exit cleanly without leaving the process hung or the SDL2 UI in a broken state.","status":"closed","priority":1,"issue_type":"feature","owner":"fredm@spamcop.net","created_at":"2026-04-11T11:56:12Z","created_by":"Fredrick Meunier","updated_at":"2026-04-11T12:41:30Z","closed_at":"2026-04-11T12:41:30Z","close_reason":"SDL2 backend now presents visible emulator frames correctly; verified by user after fixing the 16-bit presentation path.","dependencies":[{"issue_id":"fuse-wgi","depends_on_id":"fuse-pir","type":"blocks","created_at":"2026-04-11T21:57:05Z","created_by":"Fredrick Meunier","metadata":"{}"}],"dependency_count":1,"dependent_count":2,"comment_count":0}
{"_type":"issue","id":"fuse-pir","title":"Build/configure groundwork for UI=sdl2 and SDL2 sound selection","description":"Add configure and build-system groundwork for a distinct UI=sdl2 backend and a separate SDL2 sound backend without regressing existing SDL1 codepaths. This task is only about selection, dependency plumbing, and default resolution rules, while keeping UI and audio independently selectable. When UI=sdl2 and SDL2 sound is available, default the sound backend to SDL2 sound while still allowing manual override.","design":"Keep this limited to configure/build and backend selection plumbing. Do not introduce a hybrid SDL1/SDL2 runtime path or an internal SDL1 compatibility layer just to simplify option handling.","acceptance_criteria":"Configure/build logic exposes UI=sdl2 as a distinct selectable UI backend rather than folding it into the SDL1 path. Build/dependency handling distinguishes SDL1 and SDL2 requirements so SDL2-enabled targets can be built without rewriting the SDL1 backend path. UI and audio selection remain independent, so UI=sdl2 can be paired with a non-SDL2 audio backend and SDL2 sound can be selected without requiring UI=sdl2. When UI=sdl2 and SDL2 sound is available, default the sound backend to SDL2 sound while still allowing manual override. Existing SDL1 UI and audio builds continue to configure and build unchanged when SDL2 support is disabled or not selected.","status":"closed","priority":1,"issue_type":"task","owner":"fredm@spamcop.net","created_at":"2026-04-11T11:56:06Z","created_by":"Fredrick Meunier","updated_at":"2026-04-11T12:17:46Z","closed_at":"2026-04-11T12:17:46Z","close_reason":"Implemented SDL2 build/configure groundwork with UI=sdl2 selection, SDL2 sound selection/defaulting, temporary scaffolding sources, and SDL2 UI exclusion of SDL1 sound.","dependency_count":0,"dependent_count":3,"comment_count":0}
{"_type":"issue","id":"fuse-7en","title":"Epic: native SDL2 UI and SDL2 sound backends","description":"Track the SDL2 migration as separate native backends in ui/sdl2/ and sound/sdl2sound.c. Sequence the work as build/configure groundwork first, then minimal SDL2 UI and SDL2 sound, then display cleanup, fullscreen/window behavior, and keyboard fidelity, with joystick, mouse/grab, and final parity cleanup staying as later follow-up. Keep UI and audio independently selectable, preserve the existing software rendering and scaler flow for this tranche, and clarify the default sound rule as: When UI=sdl2 and SDL2 sound is available, default the sound backend to SDL2 sound while still allowing manual override. Explicitly exclude any hybrid SDL1/SDL2 backend, internal SDL1 compatibility layer, or renderer/texture modernization in this epic.","design":"Architectural boundaries for this epic: add native SDL2 implementations as separate modules in ui/sdl2/ and sound/sdl2sound.c, keep backend selection independent between UI and audio, and treat renderer/texture modernization as separate future work rather than a prerequisite.","acceptance_criteria":"The epic description and child issue set explicitly cover build/configure groundwork, minimal SDL2 UI, SDL2 sound, display cleanup, fullscreen/window management, keyboard fidelity, deferred joystick, deferred mouse/grab, and final parity cleanup. The documented sequencing matches the current dependency graph, including fuse-pir blocking fuse-wgi and fuse-k8e, fuse-n5p depending on both fuse-wgi and fuse-k8e, and later input/window follow-up work remaining downstream. The epic text explicitly states that UI and audio stay independently selectable, the existing software/scaler flow stays in scope for this tranche, and the default sound rule is: When UI=sdl2 and SDL2 sound is available, default the sound backend to SDL2 sound while still allowing manual override. The epic text explicitly excludes any hybrid SDL1/SDL2 backend, internal SDL1 compatibility layer, or renderer/texture modernization in this tranche.","status":"closed","priority":1,"issue_type":"feature","owner":"fredm@spamcop.net","created_at":"2026-04-11T11:55:31Z","created_by":"Fredrick Meunier","updated_at":"2026-04-12T01:58:45Z","closed_at":"2026-04-12T01:58:45Z","close_reason":"All SDL2 UI and SDL2 sound backend milestone work is now complete, documented, formatted, and locally verified; remaining future improvements can be tracked separately from this epic.","dependencies":[{"issue_id":"fuse-7en","depends_on_id":"fuse-3tt","type":"blocks","created_at":"2026-04-11T21:57:15Z","created_by":"Fredrick Meunier","metadata":"{}"},{"issue_id":"fuse-7en","depends_on_id":"fuse-4vn","type":"blocks","created_at":"2026-04-11T21:57:15Z","created_by":"Fredrick Meunier","metadata":"{}"},{"issue_id":"fuse-7en","depends_on_id":"fuse-e8p","type":"blocks","created_at":"2026-04-11T21:57:16Z","created_by":"Fredrick Meunier","metadata":"{}"},{"issue_id":"fuse-7en","depends_on_id":"fuse-k8e","type":"blocks","created_at":"2026-04-11T21:57:13Z","created_by":"Fredrick Meunier","metadata":"{}"},{"issue_id":"fuse-7en","depends_on_id":"fuse-l6g","type":"blocks","created_at":"2026-04-11T21:57:14Z","created_by":"Fredrick Meunier","metadata":"{}"},{"issue_id":"fuse-7en","depends_on_id":"fuse-n5p","type":"blocks","created_at":"2026-04-11T21:57:14Z","created_by":"Fredrick Meunier","metadata":"{}"},{"issue_id":"fuse-7en","depends_on_id":"fuse-pir","type":"blocks","created_at":"2026-04-11T21:57:12Z","created_by":"Fredrick Meunier","metadata":"{}"},{"issue_id":"fuse-7en","depends_on_id":"fuse-qqg","type":"blocks","created_at":"2026-04-11T21:57:17Z","created_by":"Fredrick Meunier","metadata":"{}"},{"issue_id":"fuse-7en","depends_on_id":"fuse-wgi","type":"blocks","created_at":"2026-04-11T21:57:13Z","created_by":"Fredrick Meunier","metadata":"{}"}],"dependency_count":9,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-0yb","title":"Model SDL2 fullscreen scaler transitions explicitly","description":"Implement a small SDL2 display scaler state model so fullscreen/windowed transitions match SDL1 behavior more closely while keeping the options dialog truthful. Current SDL2 fullscreen code uses ad hoc windowed_scaler preservation and current_scaler inference, which causes edge cases when filters/scalers are changed in fullscreen. Desired behavior: current_scaler remains the actual scaler in use; entering fullscreen keeps the current scaler if it fits; if substitution is needed, prefer a scaler in the same family/class (TV, PAL TV, AdvMAME, HQ, normal, Timex) before generic fallback; exiting fullscreen restores only when the scaler was automatically substituted; explicit user scaler choices while fullscreen should be respected and become the actual scaler shown in options. Consider states like WINDOWED, FULLSCREEN_NATIVE, FULLSCREEN_AUTO and explicit transition events for fullscreen toggle, user scaler change, machine change, and startup/init.","notes":"Reworked the explicit-scaler-change signaling to avoid the earlier ui/scaler/scaler.[ch] hook. Removed scaler_selecting_scaler() entirely. Added a UI-level one-shot hotswap reason in ui/uidisplay.h + ui.c: uidisplay_set_next_hotswap_reason() / uidisplay_take_next_hotswap_reason(). menu.c marks explicit scaler selections before calling scaler_select_scaler(); SDL2 consumes that reason inside uidisplay_hotswap_gfx_mode(). Reverified with make -j4 fuse unittests/sdl2displaytest unittests/sdl2scalerstatetest \u0026\u0026 ./unittests/sdl2displaytest \u0026\u0026 ./unittests/sdl2scalerstatetest \u0026\u0026 make check.","status":"in_progress","priority":2,"issue_type":"task","assignee":"Fredrick Meunier","owner":"fredm@spamcop.net","created_at":"2026-05-12T08:53:52Z","created_by":"Fredrick Meunier","updated_at":"2026-05-12T11:38:33Z","started_at":"2026-05-12T09:04:09Z","dependencies":[{"issue_id":"fuse-0yb","depends_on_id":"fuse-8k3","type":"blocks","created_at":"2026-05-12T18:53:57Z","created_by":"Fredrick Meunier","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-so3.6","title":"Hide SDL2 cursor while fullscreen","description":"SDL2 desktop fullscreen currently leaves the host mouse pointer visible when entering fullscreen if the mouse was not already grabbed. SDL1 hides the cursor while fullscreen and restores it when leaving. Match that behaviour for SDL2 fullscreen transitions.","acceptance_criteria":"Entering SDL2 fullscreen hides the host cursor even when the mouse was not previously grabbed; leaving fullscreen restores the cursor unless another grab state requires it hidden; SDL1 behaviour is documented as the reference.","notes":"SDL1 reference: ui/sdl/sdldisplay.c hides the cursor after fullscreen hotswap when settings_current.full_screen or ui_mouse_grabbed is true, and shows it otherwise. SDL2 fix exposes the existing cursor visibility helper and applies the same fullscreen-or-grabbed visibility rule after SDL2 window recreation.","status":"closed","priority":2,"issue_type":"bug","assignee":"Fredrick Meunier","owner":"fredm@spamcop.net","created_at":"2026-05-10T00:24:49Z","created_by":"Fredrick Meunier","updated_at":"2026-05-10T00:28:05Z","started_at":"2026-05-10T00:24:51Z","closed_at":"2026-05-10T00:28:05Z","close_reason":"Implemented SDL2 desktop fullscreen unit coverage/manual notes in bead and matched SDL1 cursor hiding behaviour; verified focused SDL2 display/mouse tests and fuse build.","labels":["fullscreen","sdl2"],"dependencies":[{"issue_id":"fuse-so3.6","depends_on_id":"fuse-so3","type":"parent-child","created_at":"2026-05-10T10:24:49Z","created_by":"Fredrick Meunier","metadata":"{}"}],"dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-so3.5","title":"Remove obsolete SDL2 fullscreen mode scanning and selection","description":"After desktop fullscreen is working, remove or greatly simplify native SDL2 code that exists only to enumerate, rank, and choose real fullscreen display modes. Keep only code needed for any explicit legacy/fallback mode, if the project decides to retain one.","acceptance_criteria":"Unused SDL2 mode ranking/listing helpers are removed or isolated behind an explicit legacy option; dead fields such as stored fullscreen width/height/refresh/format are removed where no longer needed; code no longer computes a default real fullscreen mode for normal --full-screen.","notes":"Removed SDL2 fixed fullscreen mode enumeration/selection path in working tree: deleted native SDL2 mode list/ranking helpers, fixed-mode globals, SDL_SetWindowDisplayMode fullscreen branch, and related unit tests while keeping desktop fullscreen scaler tests. Verified with make unittests/sdl2displaytest, ./unittests/sdl2displaytest, and make fuse. Not committed per user request.","status":"closed","priority":2,"issue_type":"task","assignee":"Fredrick Meunier","owner":"fredm@spamcop.net","created_at":"2026-05-09T22:57:22Z","created_by":"Fredrick Meunier","updated_at":"2026-05-10T00:50:50Z","started_at":"2026-05-10T00:40:03Z","closed_at":"2026-05-10T00:50:50Z","close_reason":"Removed SDL2 fixed fullscreen mode enumeration/ranking, fixed-mode globals, SDL_SetWindowDisplayMode path, and related tests; SDL2 fullscreen now uses desktop fullscreen only. Verified with make unittests/sdl2displaytest, ./unittests/sdl2displaytest, and make fuse.","labels":["cleanup","fullscreen","sdl2"],"dependencies":[{"issue_id":"fuse-so3.5","depends_on_id":"fuse-so3","type":"parent-child","created_at":"2026-05-10T08:57:21Z","created_by":"Fredrick Meunier","metadata":"{}"},{"issue_id":"fuse-so3.5","depends_on_id":"fuse-so3.4","type":"blocks","created_at":"2026-05-10T08:57:28Z","created_by":"Fredrick Meunier","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-so3.3","title":"Update SDL2 fullscreen options and user documentation","description":"Update help text, manual pages, README/options documentation, and any generated settings/options descriptions so SDL2 fullscreen documentation matches the new desktop-fullscreen behaviour. Decide the fate of --sdl-fullscreen-mode: remove, deprecate, repurpose, or document as legacy-only if retained.","acceptance_criteria":"User-facing docs no longer describe real SDL2 mode selection as the default; --sdl-fullscreen-mode behaviour is documented accurately or removed/deprecated consistently; generated option/help outputs are regenerated from their sources if required.","notes":"Audit-driven documentation/options updates from fuse-so3.2:\n- Document SDL2 fullscreen as desktop fullscreen: uses the current desktop display mode and does not switch/select real monitor modes by default.\n- Remove SDL2 documentation that promises automatic fixed-mode selection, mode list/number/WxH selection, or fit/refresh-rate ranking. man/fuse.1 currently contains this text in the --full-screen and --sdl-fullscreen-mode sections.\n- Decide and document --sdl-fullscreen-mode consistently as SDL1-only, legacy/deprecated for SDL2, or ignored under SDL2. Keep the existing sdlfullscreenmode config key readable for compatibility unless the project explicitly removes it.\n- settings.dat:sdl_fullscreen_mode likely remains because SDL1 still uses it; do not hand-edit generated settings.c, settings.h, or options.h unless changing settings.dat and regenerating.\n- Shell completion can keep --sdl-fullscreen-mode while SDL1 supports it, unless a later decision removes the option globally.\nDecision update:\n- --sdl-fullscreen-mode is SDL1-only after the SDL2 desktop fullscreen change.\n- SDL2 documentation should not describe mode list/number/WxH fixed monitor mode selection. Native SDL2 fullscreen uses SDL_WINDOW_FULLSCREEN_DESKTOP with renderer logical-size scaling.\n- Keep the setting/config key readable for SDL1/backward compatibility; document that it has no SDL2 effect if the option remains globally visible in help/completion/generated options.","status":"closed","priority":2,"issue_type":"task","assignee":"Fredrick Meunier","owner":"fredm@spamcop.net","created_at":"2026-05-09T22:57:17Z","created_by":"Fredrick Meunier","updated_at":"2026-05-10T00:39:12Z","started_at":"2026-05-10T00:31:56Z","closed_at":"2026-05-10T00:39:12Z","close_reason":"Updated SDL2 fullscreen documentation to describe desktop fullscreen and SDL-only fullscreen mode selection.","labels":["docs","fullscreen","sdl2"],"dependencies":[{"issue_id":"fuse-so3.3","depends_on_id":"fuse-so3","type":"parent-child","created_at":"2026-05-10T08:57:17Z","created_by":"Fredrick Meunier","metadata":"{}"},{"issue_id":"fuse-so3.3","depends_on_id":"fuse-so3.4","type":"blocks","created_at":"2026-05-10T08:57:29Z","created_by":"Fredrick Meunier","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-so3.1","title":"Add SDL2 desktop fullscreen tests and manual verification notes","description":"Add focused unit coverage for desktop fullscreen presentation calculations and update manual test notes for platforms where fullscreen behaviour must be verified visually. Include checks for wide/tall desktop aspect ratios, status icon placement, full refresh behaviour, and fullscreen toggle/recreate.","acceptance_criteria":"SDL2 display helper tests cover aspect-correct desktop fullscreen sizing/offsets; tests pass via make unittests/sdl2displaytest \u0026\u0026 ./unittests/sdl2displaytest; manual verification notes identify at least startup --full-screen and runtime fullscreen toggle cases.","notes":"Audit-driven test updates from fuse-so3.2:\n- Keep/expand tests for SDL2 geometry helpers: centering offsets, rect scaling/update, icon/status placement, and fullscreen scaler choice.\n- Remove or rewrite tests that only verify fixed real-mode ranking once the helpers are removed: refresh_*(), mode_compare_*(), and mode_fit_*() in unittests/sdl2displaytest.c.\n- Add desktop-fullscreen cases for wide and tall desktop aspect ratios, choosing the largest supported Fuse scaler that fits the desktop area, and expected centered offsets.\n- Add manual verification notes for startup ./fuse --full-screen, runtime fullscreen toggle, windowed/fullscreen recreate, status icons, and border/background clearing.\n- If unittests/sdl2displaytest.c.uncrustify is intentionally tracked on this branch, update it consistently with unittests/sdl2displaytest.c.\nRenderer/logical-size implementation update:\n- Update tests/manual notes for SDL2 renderer logical-size presentation rather than window-surface fullscreen offsets.\n- The fullscreen presentation path should keep the fixed Fuse-scaled surface as the renderer logical size and rely on SDL_RenderSetLogicalSize() for aspect-correct pillarbox/letterbox.\n- Manual verification should include wide and tall displays, black bars after full and dirty updates, startup --full-screen, runtime toggle/recreate, and status icon placement after renderer scaling.\n- Offset tests that asserted centering into the SDL window surface are less central; fullscreen_x_off/fullscreen_y_off are expected to be zero in the renderer logical-size path.\nManual verification notes for this task (kept in bead rather than source): verify SDL2 desktop fullscreen visually with startup ./fuse --full-screen and runtime fullscreen toggle/recreate. Cover wide and tall/narrow desktops where available. Confirm renderer logical-size scaling keeps aspect ratio with black bars, black bars stay clear after full refreshes and dirty updates, status icons remain at the expected Spectrum screen positions after scaling, and returning to windowed mode restores the previous windowed scaler.","status":"closed","priority":2,"issue_type":"task","assignee":"Fredrick Meunier","owner":"fredm@spamcop.net","created_at":"2026-05-09T22:57:14Z","created_by":"Fredrick Meunier","updated_at":"2026-05-10T00:28:05Z","started_at":"2026-05-10T00:16:34Z","closed_at":"2026-05-10T00:28:05Z","close_reason":"Implemented SDL2 desktop fullscreen unit coverage/manual notes in bead and matched SDL1 cursor hiding behaviour; verified focused SDL2 display/mouse tests and fuse build.","labels":["fullscreen","sdl2","tests"],"dependencies":[{"issue_id":"fuse-so3.1","depends_on_id":"fuse-so3","type":"parent-child","created_at":"2026-05-10T08:57:13Z","created_by":"Fredrick Meunier","metadata":"{}"},{"issue_id":"fuse-so3.1","depends_on_id":"fuse-so3.4","type":"blocks","created_at":"2026-05-10T08:57:29Z","created_by":"Fredrick Meunier","metadata":"{}"}],"dependency_count":1,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-vv2","title":"Investigate SF #516 GTK3 screen artifacts","description":"Track SourceForge bug #516 (\"Artifacts on screen\"): investigate GTK3 rendering artifacts seen on 4K/high-DPI displays, confirm reproduction conditions, and identify the likely cause or workaround in the GTK3 rendering path.","status":"closed","priority":2,"issue_type":"bug","assignee":"Fredrick Meunier","owner":"fredm@spamcop.net","created_at":"2026-05-02T23:42:08Z","created_by":"Fredrick Meunier","updated_at":"2026-05-04T12:04:01Z","started_at":"2026-05-02T23:42:12Z","closed_at":"2026-05-04T12:04:01Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-079","title":"Fix Windows libspectrum cache path mismatch","description":"The Windows libspectrum workflow restores and saves Cygwin packages from C:\\cygwin-packages, but cygwin-install-action defaults to D:\\cygwin-packages when the D: work volume exists. This causes actions/cache/save to warn that the configured path does not exist. Acceptance: restore/save uses the same package-cache path that the install action uses, and successful runs no longer log Cache save failed for the libspectrum Windows job.","status":"closed","priority":2,"issue_type":"bug","owner":"fredm@spamcop.net","created_at":"2026-04-27T02:17:48Z","created_by":"Fredrick Meunier","updated_at":"2026-05-04T12:05:05Z","started_at":"2026-04-27T02:18:45Z","closed_at":"2026-05-04T12:05:05Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-9d1","title":"Update deprecated GitHub Actions versions","description":"Several workflows still use actions/checkout@v4, actions/upload-artifact@v4, and actions/download-artifact@v4, which trigger deprecation warnings because they run on Node.js 20. Acceptance: workflow references are updated to supported majors so successful runs no longer log the deprecated action runtime warnings.","status":"closed","priority":2,"issue_type":"task","owner":"fredm@spamcop.net","created_at":"2026-04-27T00:55:17Z","created_by":"Fredrick Meunier","updated_at":"2026-05-04T12:04:24Z","started_at":"2026-04-27T00:56:13Z","closed_at":"2026-05-04T12:04:24Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-0ct","title":"Stop Windows Actions exit code 128 cleanup warnings","description":"Windows GitHub Actions release/build jobs finish successfully but log warnings from actions/checkout post-job cleanup: D:\\cygwin\\bin\\git.exe exits with code 128 after reporting dubious ownership for the /cygdrive/... workspace path. The build installs Cygwin after checkout, which leaves Cygwin git on PATH for checkout cleanup while checkout only marked the Windows-form workspace path as safe. Acceptance: Windows workflows no longer emit the exit code 128 warnings in successful runs.","notes":"Root cause:\n- actions/checkout post-job cleanup runs after Cygwin installation, so it ends up invoking D:\\cygwin\\bin\\git.exe.\n- checkout marks the Windows workspace path as safe in its temporary HOME, but Cygwin git sees the repository as /cygdrive/d/... and reports dubious ownership.\n- The resulting post-job git cleanup warning does not fail the build, but it logs exit code 128 on successful runs.\n\nImplemented fix:\n- Set persist-credentials: false on both checkout steps in .github/workflows/build_windows_sub.yml.\n- These jobs do not push, so they do not need checkout to persist auth for post-job cleanup.\n- This should avoid the noisy checkout post-job credential cleanup path that was tripping over Cygwin git.","status":"closed","priority":2,"issue_type":"bug","owner":"fredm@spamcop.net","created_at":"2026-04-27T00:06:18Z","created_by":"Fredrick Meunier","updated_at":"2026-05-04T12:04:48Z","started_at":"2026-04-27T00:07:06Z","closed_at":"2026-05-04T12:04:48Z","close_reason":"Closed","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-1tq","title":"Review Windows release artifact names for SDL variants","description":"User feedback suggests the SDL and SDL2 Windows release artifacts should be named with an explicit 'win32' segment, such as fuse-\u003cversion\u003e-win32-sdl.zip and fuse-\u003cversion\u003e-win32-sdl2.zip, to better distinguish them in the SourceForge files directory. Review the desired naming scheme for zip and installer artifacts, assess compatibility with existing expectations, and implement the chosen convention if appropriate.","status":"open","priority":2,"issue_type":"task","owner":"fredm@spamcop.net","created_at":"2026-04-26T22:32:55Z","created_by":"Fredrick Meunier","updated_at":"2026-04-26T22:32:55Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-msy","title":"Investigate Win32 file drag-and-drop loading","description":"On Windows 10, the Win32 build appears to accept drag initiation visually but dropping a TAP file onto the emulator does not load the game. Investigate Win32 drag-and-drop handling for TAP and similar file types, reproduce the issue if possible, and fix the drop path. Acceptance: dropping a TAP file onto the Win32 emulator loads it as expected, or the failure is explained and narrowed with a concrete follow-up.","status":"open","priority":2,"issue_type":"bug","owner":"fredm@spamcop.net","created_at":"2026-04-26T22:28:23Z","created_by":"Fredrick Meunier","updated_at":"2026-04-26T22:28:23Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-vvh","title":"Ensure Windows release text files use CRLF line endings","description":"Windows release artifacts currently appear to ship text files with LF line endings. Investigate whether the release workflow is missing the package that provides the autoconf-detected UNIX2DOS tool or otherwise failing to convert *.txt and related release text files to CRLF. Acceptance: Windows release zip and installer outputs contain CRLF line endings for the intended text files.","status":"closed","priority":2,"issue_type":"bug","owner":"fredm@spamcop.net","created_at":"2026-04-26T22:28:21Z","created_by":"Fredrick Meunier","updated_at":"2026-04-26T22:35:38Z","started_at":"2026-04-26T22:35:15Z","closed_at":"2026-04-26T22:35:38Z","close_reason":"Installed the Cygwin dos2unix package in the Windows build workflow so configure can detect unix2dos and the existing dist-win32 packaging rules convert release text files to CRLF.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-7o2","title":"Verify Windows installer uninstall support","description":"User feedback asked whether the Windows NSIS installers provide an uninstaller. Confirm the current installer behavior, verify that uninstall metadata and the uninstaller executable work as expected on installed builds, and fix or document any gaps. Acceptance: installer uninstall support is verified and any issues are tracked or resolved.","status":"in_progress","priority":2,"issue_type":"task","owner":"fredm@spamcop.net","created_at":"2026-04-26T22:28:19Z","created_by":"Fredrick Meunier","updated_at":"2026-04-26T22:42:46Z","started_at":"2026-04-26T22:42:46Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-4oy","title":"Review Windows installer install directory per UI variant","description":"The win32, SDL, and SDL2 NSIS installers currently appear to target the same installation directory, which prevents multiple variants from being installed side by side. Review whether the installer directory should vary by UI variant, assess compatibility and user-expectation tradeoffs, and implement a change if appropriate. Acceptance: decide the intended behavior and align the installer path logic with that decision.","notes":"Sizing research:\n- This looks like a small-to-medium installer change, mostly confined to data/win32/installer.nsi.in.\n- The current variant collision is caused by shared installer identifiers: installDir \"$PROGRAMFILES\\Fuse\", uninstall registry key \"Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\Fuse\", and Start Menu folder \"$SMPROGRAMS\\Fuse\".\n- The setup filename already varies by @UI@, so packaging output naming is mostly in place already.\n- A minimal side-by-side-install fix should separate at least the install directory, uninstall registry key, and Start Menu folder per UI variant.\n- Changing only installDir would be incomplete because shared uninstall metadata or shortcuts would still let variants interfere with each other.\n- Additional review is needed for the previous-version uninstall logic, which currently assumes one shared uninstall entry and may need to become variant-specific as well.\n- Expected effort: small code diff, but medium behavior/testing risk because Windows install/upgrade/uninstall paths can regress subtly.","status":"open","priority":2,"issue_type":"task","owner":"fredm@spamcop.net","created_at":"2026-04-26T22:27:23Z","created_by":"Fredrick Meunier","updated_at":"2026-04-26T23:04:47Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-veg","title":"Include widget font in SDL2 Windows package","description":"The Windows installer packages expect ui/widget/fuse.font for widget-based UIs. The current distribution.mk only copies that font for the SDL1 variant, so the SDL2 installer emits a missing-file warning and omits the font. Update the Windows packaging rule so SDL2 packages include fuse.font as well.","status":"closed","priority":2,"issue_type":"bug","owner":"fredm@spamcop.net","created_at":"2026-04-26T07:18:12Z","created_by":"Fredrick Meunier","updated_at":"2026-04-26T07:18:37Z","started_at":"2026-04-26T07:18:18Z","closed_at":"2026-04-26T07:18:37Z","close_reason":"Updated the Windows packaging rule so both SDL and SDL2 widget-based builds create ui/widget and copy fuse.font into the package before the installer is built.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-n4z","title":"Fix Windows installer variant naming","description":"The manual Windows release workflow now builds installers successfully for the win32 variant, but SDL and SDL2 jobs fail because the NSIS template hardcodes the output file name to '-win32-setup.exe'. The dist-win32-exe target expects the installer name to follow the active UI variant (win32, sdl, sdl2). Update the installer template so the output file name tracks the configured UI.","status":"closed","priority":2,"issue_type":"bug","owner":"fredm@spamcop.net","created_at":"2026-04-26T07:13:58Z","created_by":"Fredrick Meunier","updated_at":"2026-04-26T07:15:11Z","started_at":"2026-04-26T07:14:49Z","closed_at":"2026-04-26T07:15:11Z","close_reason":"Updated the NSIS installer template so the output filename uses the configured UI variant rather than hardcoding 'win32', matching the expectations of the dist-win32-exe packaging target for win32, sdl, and sdl2 builds.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-t4u","title":"Fix Windows release NSIS path","description":"The manual Windows release workflow installs NSIS successfully with Chocolatey, but the subsequent Cygwin packaging step fails with 'ERROR: cannot locate makensis tool' because CYGWIN_NOWINPATH prevents the Cygwin shell from seeing the Chocolatey shim path. Update the shared Windows build workflow so makensis is visible to the Cygwin packaging step when installer builds are enabled.","status":"closed","priority":2,"issue_type":"bug","owner":"fredm@spamcop.net","created_at":"2026-04-26T06:19:03Z","created_by":"Fredrick Meunier","updated_at":"2026-04-26T06:56:13Z","started_at":"2026-04-26T06:19:51Z","closed_at":"2026-04-26T06:56:13Z","close_reason":"Replaced the fragile makensis symlink with a Cygwin wrapper script that resolves the Chocolatey shim and the common NSIS install locations before invoking the Windows executable.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-4ro","title":"Fix Windows checkout safe.directory warnings","description":"The Windows GitHub Actions jobs finish successfully but actions/checkout emits post-job exit code 128 warnings because checkout cleanup safelists the workspace using a Windows path while later Cygwin git operations see the same repository via /cygdrive/... . Update the shared Windows workflows so both path forms are registered as safe directories early in the job.","status":"closed","priority":2,"issue_type":"bug","owner":"fredm@spamcop.net","created_at":"2026-04-26T02:04:10Z","created_by":"Fredrick Meunier","updated_at":"2026-04-26T02:06:25Z","started_at":"2026-04-26T02:06:03Z","closed_at":"2026-04-26T02:06:25Z","close_reason":"Registered both Windows and /cygdrive workspace paths as safe directories in the shared Windows checkout workflow so actions/checkout post-job cleanup no longer trips Git's dubious ownership check.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-6al","title":"Fix Windows SDL notice packaging","description":"The Windows release packaging currently includes both SDL and SDL2 entries in LICENSES.txt regardless of the selected UI variant, and the SDL2 release artifact can miss the corresponding 3rd-party notice files. Update the shared Windows packaging path so each variant only documents and ships the runtime notices for DLLs actually included in that package.","status":"closed","priority":2,"issue_type":"bug","owner":"fredm@spamcop.net","created_at":"2026-04-25T23:16:42Z","created_by":"Fredrick Meunier","updated_at":"2026-04-25T23:58:54Z","started_at":"2026-04-25T23:17:38Z","closed_at":"2026-04-25T23:58:54Z","close_reason":"Added a repo-managed SDL2 fallback notice for the Windows packaging path so SDL2 builds still ship 3rd-party license detail when the Cygwin SDL2 package exposes no discoverable notice files on the runner.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-4cu","title":"Fill Windows CI package metadata and license gaps","description":"Why: Comparing the CI-produced win32 package against public Windows releases shows that the DLL/toolchain family is broadly consistent with older releases such as 1.5.6, but the CI package is missing important release metadata and license material needed for a distributable archive. What: update the Windows packaging path so CI/manual release builds include README-win32.txt, LICENSES.txt, and the 3rd-party license files, and make LICENSES.txt reflect the actual shipped DLL set (including current CI-specific runtime libraries such as iconv/liblzma/libFLAC/libOGG where applicable). Context: the main gap is packaging/documentation parity rather than the core DLL approach; installer generation is tracked separately.","status":"closed","priority":2,"issue_type":"task","assignee":"Fredrick Meunier","owner":"fredm@spamcop.net","created_at":"2026-04-23T11:28:21Z","created_by":"Fredrick Meunier","updated_at":"2026-04-24T12:47:23Z","started_at":"2026-04-24T02:23:36Z","closed_at":"2026-04-24T12:47:23Z","close_reason":"Implemented and verified the Windows release packaging updates: added README-win32.txt and LICENSES.txt to the package, copied third-party notices into 3rd-party with package-qualified .txt names, installed the missing manual-generation tools in Windows CI, and restored release-style zip naming.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-6r5.5","title":"Package release-style Windows artifacts without 7z","description":"Produce the release-style Windows deliverables for each manual build run, specifically zip archives and setup.exe installers, and ensure the workflow no longer emits 7z artifacts for this path.","status":"closed","priority":2,"issue_type":"task","owner":"fredm@spamcop.net","created_at":"2026-04-22T12:35:03Z","created_by":"Fredrick Meunier","updated_at":"2026-04-26T04:59:54Z","closed_at":"2026-04-26T04:59:54Z","close_reason":"Extended the shared Windows build workflow to optionally install NSIS, build release-style setup.exe installers alongside zip artifacts, and enabled that installer path for the manual Windows release workflow without changing the default PR build behavior.","dependencies":[{"issue_id":"fuse-6r5.5","depends_on_id":"fuse-6r5","type":"parent-child","created_at":"2026-04-22T22:35:02Z","created_by":"Fredrick Meunier","metadata":"{}"},{"issue_id":"fuse-6r5.5","depends_on_id":"fuse-6r5.3","type":"blocks","created_at":"2026-04-22T22:35:16Z","created_by":"Fredrick Meunier","metadata":"{}"}],"dependency_count":1,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"fuse-6r5.4","title":"Define manual Windows release workflow contract","description":"Document the intended workflow shape before implementation: manual GitHub Actions entrypoint, artifact-only scope, required outputs, required inputs, source defaults/overrides, and which existing reusable workflows should be reused instead of duplicating logic.","design":"Workflow contract:\n- Add a new manual GitHub Actions workflow for Windows release builds using workflow_dispatch.\n- Output scope is artifacts only; no GitHub release creation in v1.\n- Default Fuse source is the current repository checkout on master.\n- Default libspectrum source is the canonical SourceForge git repository on master.\n- Optional overrides are tag-only inputs: fuse_tag and libspectrum_tag. Empty inputs mean use the defaults.\n- Build all three 32-bit Windows variants in one run: win32, sdl, and sdl2.\n- Produce release-style artifacts only: zip and setup.exe for each variant. Do not produce 7z artifacts.\n- Fail the workflow when manually selected Fuse and libspectrum tags are incompatible; do not add fallback resolution.\n- Reuse existing reusable workflows where practical, especially build_libspectrum_windows_sub.yml and build_windows_sub.yml, extending shared logic instead of duplicating full jobs.\n- Keep artifact names aligned with historical SourceForge naming: fuse-\u003cversion\u003e-win32.zip, fuse-\u003cversion\u003e-win32-setup.exe, fuse-\u003cversion\u003e-sdl.zip, fuse-\u003cversion\u003e-sdl-setup.exe, fuse-\u003cversion\u003e-sdl2.zip, and fuse-\u003cversion\u003e-sdl2-setup.exe.","notes":"Implementation notes:\n- The legacy windows_release.yml captures some prior intent but is stale relative to the current reusable workflow interfaces.\n- The current reusable Windows build path already builds zip artifacts, but not installers; installer generation should be added by extending shared packaging logic rather than reviving the legacy workflow as-is.\n- build_libspectrum_windows_sub.yml already supports fetching libspectrum from the canonical SourceForge repository by ref and is the preferred base for libspectrum selection.\n- build_windows_sub.yml is the preferred base for the Fuse-side build matrix, source checkout, configure verification, and artifact upload behavior.","status":"closed","priority":2,"issue_type":"task","owner":"fredm@spamcop.net","created_at":"2026-04-22T12:35:00Z","created_by":"Fredrick Meunier","updated_at":"2026-04-22T12:36:45Z","started_at":"2026-04-22T12:36:40Z","closed_at":"2026-04-22T12:36:45Z","close_reason":"Recorded the manual Windows release workflow contract in the issue design and notes for follow-on implementation tasks.","dependencies":[{"issue_id":"fuse-6r5.4","depends_on_id":"fuse-6r5","type":"parent-child","created_at":"2026-04-22T22:35:00Z","created_by":"Fredrick Meunier","metadata":"{}"}],"dependency_count":0,"dependent_count":2,"comment_count":0}
{"_type":"issue","id":"fuse-6r5.3","title":"Add Windows release build matrix for win32 SDL and SDL2","description":"Implement the Windows build steps for the planned manual release workflow so it can build the win32, SDL, and SDL2 variants, reusing the repository's existing reusable workflows or shared job logic where that is practical.","status":"closed","priority":2,"issue_type":"task","owner":"fredm@spamcop.net","created_at":"2026-04-22T12:34:59Z","created_by":"Fredrick Meunier","updated_at":"2026-04-25T22:46:10Z","started_at":"2026-04-25T22:45:04Z","closed_at":"2026-04-25T22:46:10Z","close_reason":"Updated the manual Windows release workflow to reuse the shared Windows build job for win32, SDL, and SDL2 variants in a single run.","dependencies":[{"issue_id":"fuse-6r5.3","depends_on_id":"fuse-6r5","type":"parent-child","created_at":"2026-04-22T22:34:59Z","created_by":"Fredrick Meunier","metadata":"{}"},{"issue_id":"fuse-6r5.3","depends_on_id":"fuse-6r5.4","type":"blocks","created_at":"2026-04-22T22:35:17Z","created_by":"Fredrick Meunier","metadata":"{}"}],"dependency_count":1,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"fuse-6r5.2","title":"Add workflow_dispatch inputs and source selection defaults","description":"Implement the manual workflow inputs for optional fuse_tag and libspectrum_tag overrides while keeping the default Fuse source on the current checkout/master and the default libspectrum source on canonical SourceForge master.","notes":"Implementation approach:\n- Make this a minimal, low-risk change centered on source/ref selection.\n- Keep it isolated to a manual workflow path so existing automated workflows are unaffected.\n- Aim for a testable result that resolves and passes through default sources and optional fuse_tag/libspectrum_tag overrides, without yet tackling full packaging changes.","status":"closed","priority":2,"issue_type":"task","owner":"fredm@spamcop.net","created_at":"2026-04-22T12:34:58Z","created_by":"Fredrick Meunier","updated_at":"2026-04-25T22:42:19Z","started_at":"2026-04-22T12:39:41Z","closed_at":"2026-04-25T22:42:19Z","close_reason":"Implemented the manual windows_release workflow inputs for optional fuse_tag and libspectrum_tag overrides while preserving the default Fuse checkout and canonical SourceForge libspectrum master behavior. Verified by successful workflow runs.","dependencies":[{"issue_id":"fuse-6r5.2","depends_on_id":"fuse-6r5","type":"parent-child","created_at":"2026-04-22T22:34:58Z","created_by":"Fredrick Meunier","metadata":"{}"},{"issue_id":"fuse-6r5.2","depends_on_id":"fuse-6r5.4","type":"blocks","created_at":"2026-04-22T22:35:16Z","created_by":"Fredrick Meunier","metadata":"{}"}],"dependency_count":1,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"fuse-6r5.1","title":"Add compatibility checks and finalize artifact-only workflow orchestration","description":"Wire the manual Windows release workflow together so it publishes artifacts only, fails fast when the selected Fuse and libspectrum versions are incompatible, and cleanly orchestrates the reusable build and packaging pieces end to end.","status":"open","priority":2,"issue_type":"task","owner":"fredm@spamcop.net","created_at":"2026-04-22T12:34:57Z","created_by":"Fredrick Meunier","updated_at":"2026-04-22T12:34:57Z","dependencies":[{"issue_id":"fuse-6r5.1","depends_on_id":"fuse-6r5","type":"parent-child","created_at":"2026-04-22T22:34:57Z","created_by":"Fredrick Meunier","metadata":"{}"},{"issue_id":"fuse-6r5.1","depends_on_id":"fuse-6r5.2","type":"blocks","created_at":"2026-04-22T22:35:18Z","created_by":"Fredrick Meunier","metadata":"{}"},{"issue_id":"fuse-6r5.1","depends_on_id":"fuse-6r5.5","type":"blocks","created_at":"2026-04-22T22:35:19Z","created_by":"Fredrick Meunier","metadata":"{}"}],"dependency_count":2,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-6r5","title":"Add manual Windows release-build GitHub Actions workflow","description":"Track the planned manual GitHub Actions workflow for Windows release builds. Scope: artifact-only workflow_dispatch entrypoint; default Fuse source from the current checkout/master and libspectrum from canonical SourceForge master; optional fuse_tag and libspectrum_tag overrides; build win32, sdl, and sdl2 variants; emit release-style zip and setup.exe artifacts; do not produce 7z artifacts; fail fast on incompatible Fuse/libspectrum versions; reuse existing reusable workflows where practical.","notes":"Incremental sequencing note:\n- Prefer fuse-6r5.2 as the next implementation step.\n- Rationale: it is the smallest additive change, can be isolated to a manual workflow entrypoint, and should not affect existing PR/build workflows because nothing runs unless manually dispatched.\n- Expected outcome: a testable manual workflow contract for selecting default refs and optional tag overrides before wiring the full build matrix and packaging.","status":"open","priority":2,"issue_type":"epic","owner":"fredm@spamcop.net","created_at":"2026-04-22T12:34:36Z","created_by":"Fredrick Meunier","updated_at":"2026-04-22T12:40:58Z","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-arr","title":"Add GitHub Actions CI coverage for SDL2 target","description":"Why: GitHub Actions CI does not currently build the SDL2 target, so regressions there can slip through. What: extend CI coverage to build the SDL2 target as part of the automated workflow.","status":"closed","priority":2,"issue_type":"task","assignee":"Fredrick Meunier","owner":"fredm@spamcop.net","created_at":"2026-04-12T03:30:29Z","created_by":"Fredrick Meunier","updated_at":"2026-04-22T12:05:36Z","closed_at":"2026-04-22T12:05:36Z","close_reason":"SDL2 target is covered by GitHub Actions workflows on Linux, macOS, and Windows.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-uyv","title":"Run SDL2 unit tests under make check","description":"Ensure the SDL2-specific unit test binaries are included in the automake test harness so /Applications/Xcode.app/Contents/Developer/usr/bin/make check-am\n/Applications/Xcode.app/Contents/Developer/usr/bin/make check-local\n./fuse --unittests\n\nThe Free Unix Spectrum Emulator (Fuse) version 1.7.0.\n(c) 1999-2026 Philip Kendall and others; see the file\n'AUTHORS' for more details.\n\nFor help, please mail \u003cfuse-emulator-devel@lists.sf.net\u003e or use\nthe forums at \u003chttp://sourceforge.net/p/fuse-emulator/discussion/\u003e.\n\nThis program is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\nGNU General Public License for more details.\n\nFinal return value: 0 (should be 0)\n./unittests/displaytest executes them along with the existing unit tests.","status":"closed","priority":2,"issue_type":"task","owner":"fredm@spamcop.net","created_at":"2026-04-12T02:03:55Z","created_by":"Fredrick Meunier","updated_at":"2026-04-12T02:06:26Z","closed_at":"2026-04-12T02:06:26Z","close_reason":"Extended the existing check-local test hook so make check now runs the SDL2 display, joystick, and mouse unit tests in addition to the existing Fuse unit test binaries.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-tbw","title":"Document and format SDL2 backend","description":"Add user-facing documentation for the completed SDL2 backend work, especially fullscreen mode selection and mouse/grab behavior, and run the project formatter over the SDL2 source files to normalize style without changing behavior.","status":"closed","priority":2,"issue_type":"task","owner":"fredm@spamcop.net","created_at":"2026-04-12T01:53:22Z","created_by":"Fredrick Meunier","updated_at":"2026-04-12T01:58:44Z","closed_at":"2026-04-12T01:58:44Z","close_reason":"Documented SDL2 fullscreen and mouse behavior in the man page and ran the documented uncrustify formatting pass over the SDL2 backend, SDL2 sound source, and SDL2-related tests.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-6hh","title":"Add SDL2 fixed fullscreen mode selection","description":"Restore the valued SDL1-style fixed fullscreen mode behavior in the SDL2 backend. The SDL2 UI should retain desktop fullscreen support where appropriate, but also support explicit fullscreen display mode selection/fitting behavior comparable to SDL1, using the existing fullscreen-mode setting/plumbing where feasible.","status":"closed","priority":2,"issue_type":"task","owner":"fredm@spamcop.net","created_at":"2026-04-12T00:58:27Z","created_by":"Fredrick Meunier","updated_at":"2026-04-12T01:27:45Z","closed_at":"2026-04-12T01:27:45Z","close_reason":"Restored SDL1-style fixed fullscreen mode behavior for SDL2, including list/index/WxH selection, automatic fullscreen mode choice biased by scaler fit and refresh preference, and unit coverage for the mode-selection logic.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-h6s","title":"Add SDL2 presentation helper test seam","description":"Create a minimal, C89-friendly test seam for SDL2 presentation logic by extracting pure helper functions and simple inline view structs without abstracting hot-path rendering through indirect calls. Use it to add unit coverage for fullscreen offset/layout and scaler-selection decisions that currently live inside the SDL2 display backend.","status":"closed","priority":2,"issue_type":"task","owner":"fredm@spamcop.net","created_at":"2026-04-11T23:09:12Z","created_by":"Fredrick Meunier","updated_at":"2026-04-11T23:23:45Z","closed_at":"2026-04-11T23:23:45Z","close_reason":"Added a C89-friendly SDL2 presentation helper seam with unit coverage for fullscreen offsets, rect transforms, icon placement, and fullscreen scaler selection without introducing hot-path indirection.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-l6g","title":"Fullscreen and window management for SDL2 UI","description":"Implement SDL2-native fullscreen transitions and window management behavior once core presentation is correct. Cover sizing, mode changes, and window lifecycle behavior needed for routine use, without expanding scope into deferred joystick or mouse/grab work.","acceptance_criteria":"The SDL2 UI supports usable fullscreen and windowed operation with correct transitions, sizing, and window lifecycle behavior on top of the cleaned-up display path; remaining joystick and mouse/grab concerns stay deferred.","status":"closed","priority":2,"issue_type":"task","assignee":"Fredrick Meunier","owner":"fredm@spamcop.net","created_at":"2026-04-11T11:56:29Z","created_by":"Fredrick Meunier","updated_at":"2026-04-11T14:12:31Z","closed_at":"2026-04-11T14:12:31Z","close_reason":"SDL2 fullscreen/window handling now supports the General options fullscreen toggle, centers fullscreen presentation, adjusts scaler choice for fullscreen use, restores the windowed scaler on exit, and was verified locally by the user.","dependencies":[{"issue_id":"fuse-l6g","depends_on_id":"fuse-n5p","type":"blocks","created_at":"2026-04-11T21:57:08Z","created_by":"Fredrick Meunier","metadata":"{}"}],"dependency_count":1,"dependent_count":3,"comment_count":0}
{"_type":"issue","id":"fuse-n5p","title":"Display correctness and presentation cleanup for SDL2 UI","description":"Clean up SDL2 display presentation after the minimal SDL2 UI and SDL2 sound milestones are in place, while explicitly keeping the existing software rendering and scaler flow for this tranche. Focus on concrete correctness issues such as pixel format handling, redraw/expose paths, presentation stability, and scaling behavior before fullscreen or broader polish.","design":"This is a display-correctness pass on top of the existing software/scaler path, not a rendering-architecture rewrite. Keep SDL2 presentation behavior compatible with the current frame production flow so later fullscreen and input work build on a stable base.","acceptance_criteria":"SDL2 presentation handles the intended pixel formats correctly without obvious channel swaps, corruption, or format-mismatch artifacts in normal emulator use. Frame presentation is stable over time, without obvious flicker, runaway redraw behavior, or stale-frame display during routine operation. Redraw and expose/update paths refresh the window correctly after events that require repainting. Scaling and final presentation match the expected behavior of the current software rendering and scaler flow rather than introducing a new renderer/texture pipeline. The task leaves the software/scaler flow in place and does not expand scope into renderer/texture modernization.","status":"closed","priority":2,"issue_type":"task","assignee":"Fredrick Meunier","owner":"fredm@spamcop.net","created_at":"2026-04-11T11:56:24Z","created_by":"Fredrick Meunier","updated_at":"2026-04-11T13:23:46Z","closed_at":"2026-04-11T13:23:46Z","close_reason":"SDL2 display presentation now handles redraw/expose correctly, keeps status/media overlays in sync, and was verified locally by the user.","dependencies":[{"issue_id":"fuse-n5p","depends_on_id":"fuse-k8e","type":"blocks","created_at":"2026-04-11T21:57:07Z","created_by":"Fredrick Meunier","metadata":"{}"},{"issue_id":"fuse-n5p","depends_on_id":"fuse-wgi","type":"blocks","created_at":"2026-04-11T21:57:06Z","created_by":"Fredrick Meunier","metadata":"{}"}],"dependency_count":2,"dependent_count":3,"comment_count":0}
{"_type":"issue","id":"fuse-nqf","title":"Use libspectrum_new0 in SDL2 display allocations","description":"Replace the remaining direct calloc usage in the SDL2 display backend with the project-standard typed libspectrum_new0 allocator and matching libspectrum_free cleanup for consistency with the rest of the codebase.","status":"closed","priority":3,"issue_type":"task","owner":"fredm@spamcop.net","created_at":"2026-04-12T03:20:30Z","created_by":"Fredrick Meunier","updated_at":"2026-04-12T03:21:27Z","closed_at":"2026-04-12T03:21:27Z","close_reason":"Replaced the remaining direct calloc usage in the SDL2 display backend with libspectrum_new0 and paired tmp_screen buffer cleanup with libspectrum_free for allocator consistency.","dependency_count":0,"dependent_count":0,"comment_count":0}
{"_type":"issue","id":"fuse-qqg","title":"Final SDL2 parity cleanup","description":"Track remaining SDL2 backend parity gaps and cleanup once build/configure, minimal UI, SDL2 sound, display, fullscreen/window, keyboard, joystick, and mouse/grab work are all complete. Use this to capture residual polish rather than front-loading modernization.","acceptance_criteria":"Remaining SDL2 parity gaps are enumerated and cleaned up after the earlier milestones finish; no major known parity blocker remains for the SDL2 UI and SDL2 sound backends; renderer/texture modernization remains out of scope unless separately justified.","status":"closed","priority":3,"issue_type":"task","assignee":"Fredrick Meunier","owner":"fredm@spamcop.net","created_at":"2026-04-11T11:56:53Z","created_by":"Fredrick Meunier","updated_at":"2026-04-12T00:55:53Z","closed_at":"2026-04-12T00:55:53Z","close_reason":"Cleaned up the remaining practical SDL2 parity gaps by restoring mouse grab across window recreation and allowing held-key repeat through the widget UI. No major known SDL2 parity blocker remains; SDL1-style fixed fullscreen mode selection remains out of scope for this cleanup.","dependencies":[{"issue_id":"fuse-qqg","depends_on_id":"fuse-4vn","type":"blocks","created_at":"2026-04-11T21:57:11Z","created_by":"Fredrick Meunier","metadata":"{}"},{"issue_id":"fuse-qqg","depends_on_id":"fuse-e8p","type":"blocks","created_at":"2026-04-11T21:57:12Z","created_by":"Fredrick Meunier","metadata":"{}"}],"dependency_count":2,"dependent_count":1,"comment_count":0}
{"_type":"issue","id":"fuse-e8p","title":"Mouse and grab behavior for SDL2 UI","description":"Add SDL2 mouse handling and grab/capture behavior only after the core SDL2 milestones are stable. Treat this as deferred follow-up work after build/configure, minimal UI, SDL2 sound, display cleanup, fullscreen/window management, and keyboard fidelity.","acceptance_criteria":"SDL2 mouse input and grab/capture behavior are implemented after the prerequisite SDL2 UI milestones are complete; behavior is usable without requiring a hybrid SDL1/SDL2 path or unrelated renderer modernization.","status":"closed","priority":3,"issue_type":"task","owner":"fredm@spamcop.net","created_at":"2026-04-11T11:56:47Z","created_by":"Fredrick Meunier","updated_at":"2026-04-12T00:44:36Z","closed_at":"2026-04-12T00:44:36Z","close_reason":"Implemented SDL2 mouse grab/release behavior with relative mode and window grab, added unit tests for mouse grab policy, fixed fullscreen status icon null-safety, and verified the runtime behavior locally with acceptable residual macOS cursor-hide quirks.","dependencies":[{"issue_id":"fuse-e8p","depends_on_id":"fuse-3tt","type":"blocks","created_at":"2026-04-11T21:57:10Z","created_by":"Fredrick Meunier","metadata":"{}"},{"issue_id":"fuse-e8p","depends_on_id":"fuse-l6g","type":"blocks","created_at":"2026-04-11T21:57:10Z","created_by":"Fredrick Meunier","metadata":"{}"}],"dependency_count":2,"dependent_count":2,"comment_count":0}
{"_type":"issue","id":"fuse-4vn","title":"Joystick support for SDL2 UI","description":"Add SDL2 joystick/game-controller support only after build/configure, minimal UI, SDL2 sound, display cleanup, fullscreen/window management, and keyboard fidelity are all in place. Keep this as a follow-up integration task rather than broadening earlier milestones.","acceptance_criteria":"SDL2 joystick support is implemented after the prerequisite SDL2 UI and input/display milestones are complete; it integrates cleanly with the native SDL2 backend without reopening earlier architectural decisions.","status":"closed","priority":3,"issue_type":"task","assignee":"Fredrick Meunier","owner":"fredm@spamcop.net","created_at":"2026-04-11T11:56:40Z","created_by":"Fredrick Meunier","updated_at":"2026-04-11T23:41:02Z","closed_at":"2026-04-11T23:41:02Z","close_reason":"Added native SDL2 joystick support with button/axis/hat event handling, fixed configure-time SDL2 joystick enablement, added unit tests for joystick event translation, and verified behavior with a real joystick.","dependencies":[{"issue_id":"fuse-4vn","depends_on_id":"fuse-3tt","type":"blocks","created_at":"2026-04-11T21:57:09Z","created_by":"Fredrick Meunier","metadata":"{}"},{"issue_id":"fuse-4vn","depends_on_id":"fuse-l6g","type":"blocks","created_at":"2026-04-11T21:57:09Z","created_by":"Fredrick Meunier","metadata":"{}"}],"dependency_count":2,"dependent_count":2,"comment_count":0}
{"_type":"memory","key":"sdl2-renderer-backend-guidance","value":"Future SDL2 renderer/texture backend guidance: keep current surface/scaler parity backend as the stable path; if revisiting a renderer path, use it as a separate follow-up rather than replacing the parity backend wholesale. Practical lessons from historical SDL2 attempts and this branch: (1) renderer backbuffers must be explicitly cleared every frame before drawing because SDL render backbuffers are invalid after present; assume no preserved contents across frames. (2) Dirty-rect updates interact badly with non-integer SDL scaling/filtering and can leave interpolation artifacts at update borders; if using renderer scaling with non-integer factors, prefer full texture updates or be extremely conservative about dirty regions. (3) Relative mouse mode is the right SDL2 approach for grab/ungrab; keep emulator input on key events and treat any SDL_TEXTINPUT support as widget-text-entry-only, not Spectrum input. (4) Fixed software scalers and free SDL scaling become conceptually messy when mixed; for parity/default behavior preserve fixed Fuse scaler semantics, and if adding a freely resizeable SDL scaler mode, make it an explicit alternative mode rather than silently changing existing scaler behavior. (5) Avoid relying on WM-specific aspect-hint logic as a core behavior; it proved fragile and WM-dependent historically. (6) If using textures, RGB565 remains a sensible source format, but be careful about assumptions around filtering, clipping, and fullscreen border clearing. (7) If pursuing renderer fullscreen/window logic, test resize, maximized window, fullscreen transitions, and border clearing across multiple platforms/GPUs early, especially Intel/X11-style cases historically prone to stale backbuffer artifacts. (8) The current branch intentionally retained SDL1-style fixed fullscreen mode selection because it is a valued user feature; do not drop that behavior casually in a renderer redesign."}