Back to Provenance

RetroAchievements (Cheevos) — LibRetro Core Status

docs/cheevos-libretro-status.md

3.3.114.1 KB
Original Source

RetroAchievements (Cheevos) — LibRetro Core Status

Audit date: 2026-03-22 Audited by: Claude / Agent (issue #3386) Parent epic: #2705

Summary

All libretro cores in Provenance reach RetroArch's cheevos.c runtime. HAVE_CHEEVOS is compiled into every build variant (Lite, Standard, XL, iOS, tvOS). Achievements are fully wired at the RetroArch framework level; no per-core flag exists that could disable them.


Architecture Overview

User signs in via PVCheevos (Swift)
        │
        ▼
RetroArchConfigManager writes credentials to retroarch.cfg
        │
        ▼
RetroArch starts content via libretro API
        │
        ▼
cheevos.c reads settings->bools.cheevos_enable
  (controlled by retroarch.cfg / PVSettings)
        │
        ▼
rcheevos identifies ROM via hash (rhash/hash.c)
        │
        ▼
rcheevos polls RETRO_ENVIRONMENT_GET_MEMORY_DATA every frame
  (called from runloop.c:rcheevos_test())
        │
        ▼
Achievements unlocked, Rich Presence updated, leaderboards posted

Key observation: the cheevos path lives entirely inside RetroArch. Every libretro core loaded by PVRetroArchCore is subject to the same runloop.c tick path — there is no per-core cheevos opt-in or opt-out.


Build Flag Audit

HAVE_CHEEVOS Definition Sites

FileLocationNotes
Build.xcconfigGCC_PREPROCESSOR_DEFINITIONSGlobal; applies to all Xcode targets
CoresRetro/RetroArch/BuildFlags.xcconfigOTHER_CFLAGS and OTHER_DEBUG_CFLAGSPVRetroArchCore compilation
CoresRetro/Package.swift.define("HAVE_CHEEVOS")Applied to both .debug and .release SPM configs

Verdict: HAVE_CHEEVOS is defined globally for Lite, Standard, and XL variants in both debug and release builds.

griffin.c Cheevos Section (lines 190–240)

c
/*============================================================
ACHIEVEMENTS
============================================================ */
#if defined(HAVE_CHEEVOS)
// cheevos.c, cheevos_client.c, cheevos_menu.c
// + rcheevos source files (rc_client, rc_libretro, rhash, etc.)
#endif

All cheevos/rcheevos source files are included unconditionally when HAVE_CHEEVOS is defined (exact count varies as RetroArch updates; use the audit script to verify).


retroarch.cfg Default State

The Provenance-bundled retroarch.cfg ships with:

ini
cheevos_enable = "false"          # Disabled by default — user must opt in
cheevos_hardcore_mode_enable = "false"
cheevos_username = ""
cheevos_password = ""             # Written by RetroArchConfigManager (not cheevos_token)
cheevos_richpresence_enable = "true"
cheevos_verbose_enable = "true"

Important: cheevos_enable = "false" is the default. Achievements only activate after the user authenticates and enables the feature via the Provenance settings UI, which calls RetroArchConfigManager to update retroarch.cfg.


Per-Core RetroAchievements Status

All cores below are loaded by PVRetroArchCore and therefore share the same cheevos runtime. The "RA Coverage" column describes upstream RetroAchievements game database coverage — it does not reflect a compile-time flag.

Tier 1 — Highest RA Database Coverage

CoreSystemsRA CoverageCheevos CompiledNotes
genesis_plus_gxMD, SMS, GG, SG-1000, CDVery HighGold standard for Sega 8/16-bit
genesis_plus_gx_wideMD (widescreen)Very HighSame core, wide aspect
fceummNES / FamicomVery HighMost NES achievements target fceumm
nestopiaNES / FamicomHighAlternative NES core
quicknesNESMediumFaster, fewer features
bsnesSNESVery HighAccuracy-focused
bsnes_hd_betaSNES (HD)Very Highbsnes with HD mode 7
bsnes_mercury_accuracySNESVery Highbsnes fork
bsnes_mercury_balancedSNESVery Highbsnes fork
bsnes_mercury_performanceSNESVery Highbsnes fork
snes9x2002SNES (GBA port)HighLower accuracy
snes9x2005SNESHigh
snes9x2005_plusSNESHigh
snes9x2010SNESHigh
gambatteGB / GBCVery HighPreferred GB core
sameboyGB / GBCVery HighAccuracy-focused
mgbaGBAVery HighmGBA core, RA reference for GBA cheevos
mednafen_gbaGBAVery HighMednafen GBA core (separate from mGBA)
vba_nextGBAHigh
vbamGBA / GBCHigh
gpspGBAMedium
mednafen_psxPS1Very High
mednafen_psx_hwPS1 (GPU)Very HighHardware renderer variant
pcsx_rearmedPS1HighARM-optimised
mednafen_pcePC Engine / TurboGrafxHigh
mednafen_pce_fastPC Engine (fast)High
mednafen_supergrafxSuperGrafxHigh
mednafen_ngpNeo Geo PocketHigh
mednafen_lynxAtari LynxMedium
mednafen_snesSNES (Bsnes)Very High
mednafen_pcfxPC-FXLowVery few RA games
mednafen_saturnSega SaturnGrowingRA Saturn coverage is expanding

Tier 2 — Good RA Coverage

CoreSystemsRA CoverageCheevos CompiledNotes
ppssppPSPMediumPPSSPP has its own cheevos path via rcheevos
flycastDreamcast / NAOMIMediumGrowing RA database
desmumeNintendo DSMedium
fbneoArcade (Neo-Geo, CPS, etc.)HighFBNeo has extensive RA arcade support
fbalpha2012ArcadeHigh
fbalpha2012_cps1CPS-1High
fbalpha2012_cps2CPS-2High
fbalpha2012_cps3CPS-3Medium
fbalpha2012_neogeoNeo GeoHigh
handyAtari LynxMediumAlternative Lynx core
mame2003ArcadeMedium
mame2003_plusArcadeMedium
mame2010ArcadeMedium
mameArcadeLowCurrent MAME — limited RA titles
mame2000ArcadeLow
prosystemAtari 7800Medium
stellaAtari 2600High
stella2014Atari 2600High
stella2023Atari 2600High
a5200Atari 5200LowFew RA titles
atari800Atari 400/800/5200Low
raceNeo Geo PocketMedium
geolithNeo Geo (AES/MVS)Medium
yabauseSega SaturnLow–MediumLess accurate than Mednafen

Tier 3 — Niche / Low RA Coverage

CoreSystemsRA CoverageCheevos CompiledNotes
bluemsxMSX / MSX2Low
fmsxMSXLow
cap32Amstrad CPCLow
fuseZX SpectrumLow
81ZX81NoneNo RA database entries
hatariAtari STLow
vice_x64C64Low
vice_x64scC64SCLow
vice_x128C128Low
vice_xcbm2CBM-IINone
vice_xcbm5x0CBM-5x0None
vice_xpetPETNone
vice_xplus4Plus/4None
vice_xscpu64SuperCPU64None
vice_xvicVIC-20None
px68kSharp X68000None
x1Sharp X1None
galaksijaGalaksijaNone
m2000Philips P2000TNone
holaniHP 9100None
freechafFairchild Channel FNone
freeintvIntellivisionLow
vecxVectrexLow
potatorSupervisionNone
pokeminiPokémon MiniNone
vemulatorSega VMUNone
gearcolecoColecoVisionLow
theodoreThomson MO/TONone
dinothawrPuzzle (homebrew)None
pocketcdgCD+GNone
gmeGame Music (chiptunes)None
gwGame & WatchNone
scummvmLucasArts / SCUMMLow
dosbox_pureMS-DOSLow
tyrquakeQuakeNone
prboomDoomNone
20482048 (puzzle)None
diceDICE (logic sim)None
vircon32Vircon32 (homebrew)None
wasm4WASM-4 (fantasy)None
xrickRick DangerousNone
squirreljmeJ2ME / MIDPNone
qemux86/ARM (QEMU)NoneNo RA support planned
virtualxt8088 XTNone
virtualjaguarAtari JaguarLow
sameduckBandai Duck HuntNone
same_cdiPhilips CD-iNone
smsplusSega SMSMediumGenesis Plus GX preferred
playPS2NoneExperimental, no RA coverage

Special Cases — Sideload Only (not App Store)

CoreSystemsRA CoverageCheevos CompiledNotes
dolphinGameCube / WiiGrowingJIT required; appstore: false
mcsoftserve?UnknownNot App Store approved

tvOS-Only Cores

CoreSystemsRA CoverageCheevos CompiledNotes
puauAmigaLow
puau2021Amiga (2021)Low

Disabled Cores (not built)

CoreStatusNotes
snes9xenabled: falseDisabled globally; snes9x2002/2005/2010 used instead
vitaquake2*enabled: falseDisabled in all variants

Gaps and Findings

Finding 1 — cheevos_enable = "false" Default

Severity: Medium (UX concern, not a build defect)

retroarch.cfg ships with cheevos_enable = "false". Achievements are silently inactive for users who sign in but don't also toggle the switch in RetroArch settings.

RetroArchConfigManager.updateCredentials(username:password:) writes RetroAchievements credentials to retroarch.cfg. The cheevos_enable setting is written separately, based on the isRetroAchievementsEnabled flag — toggled via the PVCheevos Settings UI — which triggers syncToRetroArch().

Recommendation: Verify that the PVCheevos "Enable RetroAchievements" toggle correctly updates isRetroAchievementsEnabled so that RetroArchConfigManager writes cheevos_enable = "true" in retroarch.cfg when achievements are enabled, and consider a combined sign-in + enable flow to reduce UX confusion.

Finding 2 — achievementsActive Always Returns false

Severity: Low (stubs)

PVRetroArchCoreCore+RetroAchievements.swift:achievementsActive is hardcoded to return false:

swift
public var achievementsActive: Bool {
    // TODO: query cheevos_state() once the C-to-Swift bridge is wired.
    return false
}

This means the PVLibrary / SwiftUI layer cannot query whether an active cheevos session is running.

Recommendation: Implement the C-to-Swift bridge that reads rcheevos state (e.g. rcheevos_hardcore_active, the cheevos_state struct, or a cheevos_get_active() helper) and exposes it as a Swift Bool property, or set a flag from the runloop when achievements activate.

Finding 3 — Per-frame Callback Not Wired (TODO in PVRetroArchCoreCore+RetroAchievements.swift)

Severity: Low (RetroArch handles internally)

PVRetroArchCoreCore+RetroAchievements.swift notes:

In PVLibRetroCore.m, when HAVE_CHEEVOS is defined, intercept the cheevos callback notifications (cheevos_set_rcheevos_callbacks) and forward them to a Swift-side handler.

The C callback bridge is described but marked as a TODO. Native iOS haptics on unlock and PVLibrary progress tracking are not wired.

Recommendation: Implement cheevos_set_rcheevos_callbacks bridge for native unlock notifications (tracked separately from this audit).

Finding 4 — RC_DISABLE_LUA Is Set

Severity: Informational

BuildFlags.xcconfig includes -DRC_DISABLE_LUA. This is correct for iOS/tvOS — Lua support is not available in mobile builds and is not required for rcheevos.

Finding 5 — No Per-Scheme Conditional Compilation of Cheevos

Severity: None (positive finding)

Unlike some RetroArch forks, Provenance does not gate HAVE_CHEEVOS per scheme. The Lite scheme gets the same cheevos-enabled binary as the XL scheme. This is correct behaviour.


Test Plan

Since cheevos are a runtime feature (credentials + enabled flag required), compile-time verification is the primary audit mechanism. Full runtime testing requires:

  1. A RetroAchievements account with a known-verified game hash.
  2. Set cheevos_enable = "true" and credentials in retroarch.cfg (or via Settings UI).
  3. Load the game and observe rcheevos_test() calls in the runloop.
  4. Confirm via verbose logging (cheevos_verbose_enable = "true") that the session activates.

Cores with very high RA coverage that are recommended for smoke testing:

CoreTest GameExpected Behaviour
genesis_plus_gxSonic the Hedgehog (MD)Session starts, rich presence active
fceummSuper Mario Bros (NES)Achievements load on game start
bsnesSuper Mario World (SNES)Achievements load
gambattePokemon Red/Blue (GB)Achievements load
mednafen_psxCrash Bandicoot (PS1)Session starts

Conclusion

All libretro cores in Provenance reach cheevos.c.

The HAVE_CHEEVOS flag is set unconditionally in Build.xcconfig, BuildFlags.xcconfig, and CoresRetro/Package.swift. The griffin.c unified build includes all rcheevos source files under #if defined(HAVE_CHEEVOS). Every core loaded through PVRetroArchCore runs inside the same RetroArch runloop that calls rcheevos_test() per frame.

The three open items (default disabled flag, achievementsActive stub, unlock callback bridge) are UX improvements, not correctness bugs — achievements do work for users who enable them.


Part of epic #2705 — RetroAchievements integration