libretroadmin 214c77052e libretro: include turbo toggle phase in savestate (fixes #75)
The libretro driver's per-frame turbo toggle counters
(turbo_button_toggle[MAX_PLAYERS][TURBO_BUTTONS]) are advanced in the
input poll while the turbo button is held, and the modular phase of
that counter drives when the underlying NES button fires inside the
turbo cycle.  These counters were module-level state with no
savestate involvement: not serialized, not reset on retro_reset, not
reset on retro_unserialize.

In netplay, the host and client tick this counter independently from
their own local input.  When the host snapshots state and ships it to
the client to align them, the chunk parser restores every NES
hardware register, mapper register, and core-level setting - but
both ends' turbo counters keep whatever local phase they had.  As
long as the turbo button stays held, the two ends compute different
turbo-fired-this-frame bits, which produce different NES input
sequences, which produce divergent game state.  Issue #75 has been
open on this since 2017.

Two-line fix:

 1. After FCEUI_LoadGame returns successfully in retro_load_game, the
    core has just finished populating SFMDATA[] with all mapper
    chunks via AddExState.  Append one more chunk
    (AddExState(turbo_button_toggle, sizeof(...), 0, "TBTG")) so
    the toggle counters save and restore alongside everything else.
    The "TBTG" tag is unused by any known mapper.
    ReadStateChunk's skip-unknown logic handles older states that
    predate this chunk - the array stays at the value retro_reset
    zero-initialised it to, which is now the correct post-load
    default.

 2. memset turbo_button_toggle to zero in retro_reset.  Without this,
    a held turbo button would resume mid-cycle on Reset and produce
    a different first-frame NES input bit than a fresh boot - small
    but observably non-deterministic, and the same surface that #75
    targets.

Verified by inspecting the serialized state binary:

  - Pre-fix: no TBTG chunk present.
  - Post-fix, after 5 frames of held turbo with delay=3:
      TBTG @ offset 5624, size 8, payload 02 00 00 00 00 00 00 00
      (counter for player-0 turbo-A = 2, as expected from
       5 increments mod (delay+1) = mod 4)

ReadStateChunk + CheckS handle the restore via the standard tag-match
path (state.c:277), which is bit-for-bit identical to how every
mapper chunk gets reloaded.  No additional load-side wiring needed.
2026-06-14 21:29:56 +02:00
2024-09-23 05:55:21 -07:00
2023-01-02 19:47:36 +01:00
2026-04-02 10:14:04 +01:00
Fix
2017-12-21 20:40:28 +09:00
2014-12-23 09:50:29 +01:00
2015-08-06 13:28:43 +02:00
2025-09-03 16:20:50 +02:00
2019-06-28 23:44:06 +02:00

Build Status Build status

FCE Ultra mappers modified

FCEU "mappers modified" is an unofficial build of FCEU Ultra by CaH4e3, which supports a lot of new mappers including some obscure mappers such as one for unlicensed NES ROM's.

Sequential targets Light Guns support added

Support for Sequential targets Light Guns has been added. "Gun Aux A" serves as light sensor logic input.

Description
Pinned internal source mirror of libretro/libretro-fceumm for Supergame releases
Readme 4.3 MiB
Languages
C 97.7%
Python 2%
C++ 0.2%