feat: Add RetroAchievements integration and in-game notifications#633
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! |
…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. |
frysee
left a comment
There was a problem hiding this comment.
LGTM - lets revert the http.h location change (my bad, sorry) and then we're good to go I think.
Move http.c and http.h back to workspace/all/common/ to avoid minarch-relative include paths in common files (ra_auth.c, ra_badges.c).
|
Changes are in. Ping for re-review. |
|
I think this is good to go. I'm going to let 6.8.0 marinate for a bit in case we need bugfixes for rewind, but I guess we could put this out on the nightly repo already. |
Prevents the "Loading badges" notification from showing indefinitely when downloads stall due to poor network conditions.
| @if [ ! -f "src/include/rc_client.h" ]; then \ | ||
| echo "Cloning rcheevos..."; \ | ||
| rm -rf src; \ | ||
| git clone https://github.com/RetroAchievements/rcheevos.git src; \ |
There was a problem hiding this comment.
super minor but is there a reason why we clone the whole repo and then checkout the version rather than do a shallow clone directly to the version?


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: