Skip to content

feat: comprehensive libretro core improvements — bug fixes, new options, modern API, CUE/CCD detection#1825

Merged
midwan merged 7 commits intomasterfrom
libretro-improvements
Mar 9, 2026
Merged

feat: comprehensive libretro core improvements — bug fixes, new options, modern API, CUE/CCD detection#1825
midwan merged 7 commits intomasterfrom
libretro-improvements

Conversation

@midwan
Copy link
Collaborator

@midwan midwan commented Mar 8, 2026

Summary

Comprehensive libretro core overhaul identified through two audit rounds comparing Amiberry's implementation against the libretro spec and PUAE (the reference UAE-based core). 4 commits, 22 changes across bug fixes, defensive hardening, new features, and API modernization.

Bug Fixes (7)

  • Fix double zfile_fclose in retro_unserialize()restore_state_file() already closes the zfile via savestate_restore_finish(). The extra close was a use-after-free.
  • Fix retro_serialize_size() underestimation — was only counting fastmem[0]/z3fastmem[0], missing boards 1–3 (MAX_RAM_BOARDS=4), z3chipmem, and mbresmem_low/high. Increased fixed overhead from 2MB to 8MB.
  • Fix aspect ratioupdate_geometry() was using raw pixel ratio instead of fixed 4:3. Amiga output is always 4:3 regardless of pixel resolution.
  • Fix mouse polling limited to 1 port — loop was hardcoded i < 1. Expanded to both ports with per-port state arrays.
  • Skip input polling for RETRO_DEVICE_NONE ports — avoids unnecessary joypad/analog/trigger polling.
  • Skip mouse polling for non-mouse ports — only polls mouse on ports configured as RETRO_DEVICE_MOUSE or RETRO_DEVICE_JOYPAD.
  • Fix device subclass masking — CD32 Pad / Joystick subclass IDs were compared directly against RETRO_DEVICE_JOYPAD in joyport auto-ordering, causing subclass selections to be misrouted. Now applies RETRO_DEVICE_MASK before comparison (matching how poll_input() already handles this).

Defensive Hardening (6)

  • Guard environ_cb against NULL in retro_set_environment() — prevents crash if frontend passes NULL callback.
  • OOM-safe argv construction in core_entry() — all ~15 strdup() calls replaced with safe_strdup() that tracks allocation failures. If any fail, amiberry_main() is skipped and an error is logged.
  • Declare serialization quirksRETRO_SERIALIZATION_QUIRK_CORE_VARIABLE_SIZE | MUST_INITIALIZE so frontends know save-state size varies and serialization fails before first retro_run().
  • Warn on unreadable disk paths in replace_image_index() — logs a warning but still accepts the path (file may appear later, e.g. network mount).
  • Truncate WHDLoad filenames — caps sanitized filenames to 200 chars to prevent filesystem path-length overflow on extraction.
  • Disk control mutex — all 12 disk control callbacks now hold std::mutex to prevent race conditions from concurrent frontend/emulator access to disk_images, disk_index, and disk_ejected.

New Features (5)

  • RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME — enables Workbench boot without selecting content.
  • CD32 Pad + Joystick controller subtypesRETRO_DEVICE_SUBCLASS(JOYPAD, 1/2) exposed in RetroArch controller selection UI.
  • CUE sheet parserdetect_cd_content_from_cue() parses FILE/TRACK directives, resolves the binary path, and reads sector 16 with correct offset for MODE1/2048 and MODE1/2352 sector sizes. Replaces filename heuristic for CUE files.
  • CCD file parserdetect_cd_content_from_ccd() finds the companion .img file (raw 2352-byte sectors) and reads sector 16. Replaces filename heuristic for CCD files.
  • 4 new core options:
    • amiberry_sound_filter — off / emulated (A500 hardware filter) / always on
    • amiberry_stereo_separation — 0 (mono) through 10 (full stereo), default 7 (Amiga hard-panned)
    • amiberry_floppy_speed — turbo / 1x / 2x / 4x / 8x
    • amiberry_video_standard — auto / PAL (50Hz) / NTSC (60Hz), core restart required

API Modernization (4)

  • SET_MESSAGE_EXT — replaces deprecated SET_MESSAGE with severity, duration in ms, priority, and notification type. Falls back to legacy SET_MESSAGE on older frontends.
  • GET_PERF_INTERFACE — acquires performance counter interface for future profiling.
  • SET_AUDIO_BUFFER_STATUS_CALLBACK + SET_MINIMUM_AUDIO_LATENCY — registers 64ms minimum audio latency to reduce crackling on 50Hz PAL content running on 60Hz displays. Logs underrun-likely conditions.
  • MAX_GFX geometry — increased from 1280×1024 to 1920×1280 (matching draw buffer dimensions) so superhires modes (1508px wide) aren't clamped by initial geometry.

Build System

  • Makefile version sync — extracts version from root CMakeLists.txt project(VERSION ...) instead of hardcoded 8.0.0.

Testing

  • LSP diagnostics clean on all changed files (only pre-existing retro_dirent.h IDE path issue)
  • JetBrains inspections: no errors
  • Manual code review against libretro.h spec
  • CI build validation via GitHub Actions

…oller types, input polling

- Fix double zfile_fclose in retro_unserialize (restore_state_file
  already closes via savestate_restore_finish)
- Fix retro_serialize_size to sum all RAM boards (MAX_RAM_BOARDS)
  with z3chipmem/mbresmem and increase overhead from 2MB to 8MB
- Add RETRO_ENVIRONMENT_SET_SUPPORT_NO_GAME for Workbench boot
- Use fixed 4:3 aspect ratio instead of raw pixel ratio
- Add CD32 Pad and Joystick controller subtypes
- Add RETRO_ENVIRONMENT_GET_PERF_INTERFACE for profiling
- Fix mouse polling to support both Amiga ports (was hardcoded to 1)
- Skip input polling for ports configured as RETRO_DEVICE_NONE
- Extract Makefile version from CMakeLists.txt instead of hardcoding
@midwan midwan self-assigned this Mar 8, 2026
Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 0a3bcbc960

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

midwan added 3 commits March 9, 2026 00:40
RETRO_DEVICE_SUBCLASS values (CD32 Pad, Joystick) encode the subclass
in the upper bits. The joyport auto-ordering logic compared the raw
device ID against RETRO_DEVICE_JOYPAD, causing subclass selections
to be treated as non-joypad devices. Apply RETRO_DEVICE_MASK before
comparison, matching how poll_input() already handles these values.
- Guard environ_cb against NULL before first use in retro_set_environment
- Replace all bare strdup() calls in core_entry() with safe_strdup that
  tracks allocation failures; skip amiberry_main if OOM occurs
- Declare serialization quirks (CORE_VARIABLE_SIZE, MUST_INITIALIZE) so
  frontends handle variable save-state sizes and pre-init correctly
- Upgrade show_message() to SET_MESSAGE_EXT with severity, duration in
  ms, and priority; falls back to legacy SET_MESSAGE automatically
- Warn on unreadable disk paths in replace_image_index (accept anyway
  since the file may appear later, e.g. network mount)
- Truncate WHDLoad sanitized filenames to 200 chars to prevent
  filesystem path-length overflows on extraction
…ng, disk mutex

Phase 3 — Core options expansion:
- amiberry_sound_filter: off/emulated/on (Amiga low-pass filter)
- amiberry_stereo_separation: 0-10 (Amiga hard-panned audio mixing)
- amiberry_floppy_speed: turbo/1x/2x/4x/8x
- amiberry_video_standard: auto/PAL/NTSC (core restart required)

Phase 4 — Audio API:
- Register SET_MINIMUM_AUDIO_LATENCY (64ms) to reduce crackling on
  50Hz PAL content running on 60Hz displays
- Register SET_AUDIO_BUFFER_STATUS_CALLBACK to receive underrun alerts

Phase 5 — Video geometry:
- Increase MAX_GFX_WIDTH from 1280 to 1920 and MAX_GFX_HEIGHT from
  1024 to 1280, matching the draw buffer dimensions so superhires
  modes (1508px wide) are not clamped by initial geometry

Phase 6 — Disk improvements:
- Implement CUE sheet parser (detect_cd_content_from_cue): parses
  FILE/TRACK directives, resolves binary path, reads sector 16
  with correct offset for MODE1/2048 and MODE1/2352 sector sizes
- Implement CCD parser (detect_cd_content_from_ccd): finds companion
  .img file with raw 2352-byte sectors and reads sector 16
- Replace TODO heuristic with actual CUE/CCD detection in
  detect_cd_content()
- Add std::mutex protection to all disk control callbacks to prevent
  race conditions from concurrent frontend/emulator access
@midwan midwan changed the title fix: libretro core improvements — save state bug, aspect ratio, controller types, input polling feat: comprehensive libretro core improvements — bug fixes, new options, modern API, CUE/CCD detection Mar 9, 2026
midwan added 3 commits March 9, 2026 15:01
…sitivity

- Apply RETRO_DEVICE_MASK in apply_port_device() so CD32 Pad and
  Joystick subclass IDs are correctly recognized as joypads
- Remove redundant amiga_aspect_ratio() helper; inline 4:3 constant
- Make CUE parser fully case-insensitive via lowercase copy matching
@midwan midwan merged commit f27872b into master Mar 9, 2026
24 checks passed
@midwan midwan deleted the libretro-improvements branch March 9, 2026 14:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants