feat: Add RetroAchievements integration and in-game notifications#633
feat: Add RetroAchievements integration and in-game notifications#633clintonium-119 wants to merge 27 commits intoLoveRetro:mainfrom
Conversation
9d1d680 to
89784c0
Compare
Adds full RetroAchievements support for tg5040/tg5050 platforms with in-game
toast notifications for achievements, save states, screenshots, and more.
RetroAchievements Features:
- Login via Settings menu with on-screen keyboard
- Achievement unlock notifications with badge images
- Progress tracking and leaderboard support
- Hardcore mode toggle (disables save states/cheats)
- Game hash identification with CHD disc image support
- Automatic badge caching and async downloading
- Rich presence support
In-Game Notification System:
- Toast notifications for save/load state operations
- Screenshot confirmation notifications
- Volume/brightness change indicators
- Achievement unlock popups with game badges
- Non-blocking async design
Technical:
- Integrates rcheevos library (cloned at build time)
- Uses libchdr for CD-ROM/CHD image hashing
- Async HTTP client for RA API communication
- Thread-safe badge cache with memory management
- Platform-conditional compilation (tg5040/tg5050 only)
New files:
- common/notification.{c,h} - Toast notification system
- common/http.{c,h} - Async HTTP client wrapper
- common/ra_auth.{c,h} - RA authentication handling
- common/ra_badges.{c,h} - Badge download/caching
- minarch/ra_integration.{c,h} - Core RA integration
- minarch/chd_reader.{c,h} - CHD image support
- rcheevos/makefile - rcheevos library build
89784c0 to
3dc835d
Compare
|
When RA is turned off in settings, the ingame "Achievements" menu shows a "No game loaded for achievements" message. I think I would prefer either a more fitting message based on |
|
On initial launch of a game where nothing has been cached yet, I can see major slowdown while the badges are pulled down (my assumption). Maybe a toast should stick around until that background process completes? |
Co-authored-by: frysee <frysee@googlemail.com>
Good catch. I think I should hide it completely in that case. |
Yeah, that's a good idea. I can implement that. |
When notifications end, trigger 3 frames of glClear() to fully clear the framebuffer including areas outside the game's viewport.
GFX API refinements: - Remove center_x param from GFX_blitWrappedText (calculates internally) - Rename screen to surface for clarity - Add IndicatorType enum (BRIGHTNESS, VOLUME, COLORTEMP) - Use GFX_blitPillLight instead of GFX_blitPillColor - Use SDL_SWSURFACE instead of 0 in GFX_createScreenFormatSurface RetroAchievements cleanup: - Refactor ra_consoles.h to use lookup table instead of if/strcmp chain - Replace RA_LOG with leveled macros (DEBUG, INFO, WARN, ERROR) mapping to NextUI's native LOG_* functions Video/Desktop fixes: - Add framebuffer clearing for 3 frames when notifications end - Simplify desktop msettings.c with hardcoded defaults
Store RetroAchievements data (muted achievements, badge cache) in SHARED_USERDATA_PATH/.ra instead of per-platform USERDATA_PATH/ra.
Dynamically adjust options menu based on CFG_getRAEnable() state. When RA is disabled, the Achievements item is hidden and Save Changes moves up to fill the gap.
- Add download queue with max 8 concurrent requests to prevent network/disk thrashing that caused gameplay stuttering - Lazy load badge images on-demand instead of during prefetch (only save PNG to disk during prefetch, decode when displayed) - Show persistent "Loading achievement badges..." indicator during download that auto-hides when complete - Fix progress indicator to omit colon when progress string is empty - Remove unused RA_Badges_hasPendingDownloads()
|
Ready for re-review! Here's a summary of the changes since last feedback: Badge prefetching optimization - The biggest change. Badge downloads now use a rate-limited queue (max 8 concurrent) with lazy loading. During prefetch, we only save PNGs to disk without decoding; images are loaded on-demand when actually displayed. This seems to completely eliminate the gameplay stuttering that occurred when loading games with 100+ achievements. A persistent "Loading achievement badges..." indicator shows while it's progressing. Framebuffer clearing
Other changes:
|
You're quick! I'll check it out in a bit, thanks! |
|
Looks like a few of the review items are still open above. Let me know if you want me to take over some of them! |
Ah, yes, they were folded behind the 'X conversationsn hidden' button - I didn't even see them. I'll get on these. |
Co-authored-by: frysee <frysee@googlemail.com>
Co-authored-by: frysee <frysee@googlemail.com>
Co-authored-by: frysee <frysee@googlemail.com>
- Group related static variables into structs: - ra_integration.c: RAPendingLoad and RALoginRetry structs - notification.c: ProgressIndicatorState struct (renamed to progress_state) - ra_badges.c: DownloadQueueState struct - Extract PLAT_initNotificationTexture() from PLAT_initShaders() - Add rcheevos integration guide references to header files: - ra_integration.h, ra_auth.h, ra_badges.h - Simplify/clarify comments in http.c and ra_auth.c
Pull layout values (padding, margins, gaps) to #defines at top of file for better readability and maintainability.
…clintonium-119/NextUI into feature/retroachievements-notifications
Extract rendering logic into focused helper functions: - render_system_indicator() for hardware indicator (top-right) - render_progress_indicator() for progress pill (top-left) - render_notification_pill() for individual notification rendering - render_notification_stack() for stacked notifications (bottom-left)
Use ifneq filter pattern to combine identical rcheevos/libchdr linking for all RA-enabled platforms, with nested conditional for desktop rpath.
Per PR feedback, HTTP client is only used by minarch (RA integration). Update include paths in ra_auth.c and ra_badges.c accordingly.
Remove duplicate toolchain file generation for tg5040/tg5050. The build container already provides CMAKE_TOOLCHAIN_FILE.
Keep underlying code intact for future use, but hide menu item until feature is ready. Default remains OFF.
Group 7 related notification state variables into NotificationOverlay struct for improved readability per PR feedback.
- Rename PLAT_findFileInDir to findFileInDir (now in utils) - Remove duplicate static version from minarch.c (uses utils version with improved best-match logic) - Change LOG_info to LOG_debug for match logging (debugging info, not user-facing) - Update api.h, utils.h declarations
- Move gl_notification_surface to top with other static variables - Add comment explaining why draw_rounded_rect is separate from GFX_blitPill* functions (different rendering context: RGBA for GL overlay vs theme assets for screen format)
|
@frysee I'm sure I've missed (or misunderstood) something, but I've addressed what I could. Let me know if there's anything else you'd like to see, And thanks for the thorough review and feedback. It's a good learning experience for me. |
Thanks for taking your time and implementing changes! A lot of the things were stylistic choices, so no big deal in the first place. |

Adds full RetroAchievements support for tg5040/tg5050 platforms with in-game toast notifications for achievements, save states, screenshots, and more.
RetroAchievements Features:
In-Game Notification System:
Technical:
New files: