Miyoo Flip: Up-to-date with main#761
Open
apommel wants to merge 20 commits into
Open
Conversation
* Fix badge download cap at 256 preventing large achievement sets from fully downloading
* Add offline achievements development plan
* Update dev working file
* WIP: Initial working-ish commit
* WIP: Sync generally working, but still some issues with a potentially stale ledger
* Fix order-dependent SYNC_ACK matching and production hardening for offline RA
ledgerGetPendingUnlocks and ledgerCompact used naive matching that
cancelled ALL UNLOCKs with a matching SYNC_ACK achievement ID regardless
of order, causing re-unlocks after a sync to be silently dropped.
Both now use order-aware matching: a SYNC_ACK only cancels the earliest
preceding unmatched UNLOCK, preserving later re-unlocks as pending.
Also includes Phase 6 production hardening:
- Ledger compaction after successful sync (removes acked pairs)
- Resilient chain validation (no longer truncates at first break)
- Diagnostic logging removed, verbose logs downgraded to DEBUG
- API token sanitized in HTTP error logs
* Add connectivity state machine for offline-first RA startup (Phase 7)
Replace blocking WiFi wait with async background probe. When a cached
login exists, start in offline mode immediately and probe the RA server
every 30s in the background. On success, seamlessly transition to online
mode with deferred notification, sync, and hardcore re-enable on the
main thread. Fall back to current blocking behavior only when no cache
exists. Wire up DISCONNECTED/RECONNECTED events to flip offline state,
manage the probe lifecycle, and always track pending unlocks regardless
of online/offline mode.
* Fix offline-to-online transition reliability and reduce notification noise
Process deferred connectivity flags (online/offline notifications, sync,
hardcore re-enable, login retry) during gameplay via periodic 500ms
check
in RA_doFrame(), instead of only when the menu is opened in RA_idle().
Prevent false RECONNECTED events by returning retryable errors for
non-cacheable requests (awardachievement, ping) in offline mode instead
of synthetic success responses. Suppress transient offline/connected
notification spam at startup when WiFi connects quickly. Add sync retry
on failure via connectivity probe re-trigger.
* Clean up RA integration: reduce log noise, remove dead variables, add safety comment
Downgrade per-response queue log from INFO to DEBUG and rcheevos
internal
logging from INFO to WARN. Remove unused variables (ra_probe_thread,
ra_sync_needs_retry). Strip redundant "Warning:" prefix from WARN-level
messages. Add comment explaining why the direct callback in the offline
non-cacheable path is thread-safe.
* Fix notification thread safety and system indicator width on Brick
Add progress_mutex to protect progress_state, which is written by
background threads (sync engine, badge downloads) and read by the main
thread during rendering. Writers lock around all updates; the render
path
snapshots progress_state under lock then renders from the local copy to
keep critical sections sub-microsecond.
Fix system indicator pill width using hardcoded 10 (internal pill
padding)
instead of the PADDING macro, matching the formula in
GFX_blitHardwareIndicator.
On Brick where PADDING=5, the old formula allocated a surface too
narrow,
clipping the pill on the right edge.
* Remove planning doc
* Fix RA offline thread safety: add ledger mutex, reorder shutdown, validate sync responses
* Remove RA offline/connected status notifications
Suppress the 4 notifications that alert users to RetroAchievement
connectivity state changes (offline mode, reconnected, connected).
These transitions are handled transparently with automatic syncing,
so surfacing them adds noise without actionable information.
* Fix offline achievement sync not updating count or list until second restart
Remove ra_offline_mode guard from startsession patching to avoid race
with connectivity probe. Re-apply pending offline unlocks after hardcore
re-enable (both deferred and reconnect paths) since softcore-only bits
get cleared. Add deferred sync-apply so the sync thread's confirmed
unlocks update rcheevos state without requiring a restart. Augment
game-load notification count with pending offline unlocks.
* Refactor ra_offline.c: extract SHA-256, fix hardcore filter, deduplicate ledger logic
- Extract SHA-256 to common/sha256.c + sha256.h for reuse
- Fix hardcore filter asymmetry: reject hardcore unlocks at write time
and filter during compaction to prevent immortal unsynced records
- Extract ledger_record_init() helper to deduplicate ledgerWrite*
boilerplate
- Fix thread-safety: replace static buffer in get_request_type with
caller-provided buffer
- Replace prev_hash[0] scratch flag with dedicated bool* cancelled array
- Remove redundant double ledger read in patchStartsessionResponse
- Consolidate 9 identical passthrough blocks into goto passthrough
- Extract shared ledger_read_pending_records() to unify SYNC_ACK
cancellation logic between ledgerCompact and ledgerGetPendingUnlocks
* Fix race: defer offline sync until game is loaded
The probe thread's online transition triggered sync before rcheevos
finished loading the game. The sync thread would compact the ledger
before startsession patching or ra_reapply_pending_unlocks could use
it, causing the just-synced achievement to appear locked until the
next restart. Defer both sync start and sync_apply processing until
ra_game_loaded is true.
* Fix online unlocks showing as offline-pending after mid-game sync
When an achievement was unlocked while online, the event handler
added it to the pending cache (write-ahead for crash safety) but
the HTTP callback only wrote a SYNC_ACK to the ledger — it never
removed the entry from the in-memory pending cache. The UI kept
showing the [O] offline indicator for server-confirmed unlocks.
Remove the pending cache entry when awardachievement succeeds.
* Add RA offline sync engine and Settings sync button
- Add common/md5.c+h: standalone MD5 with nui_ prefix to avoid LTO
symbol collision with rcheevos' internal rhash/md5.c
- Add common/ra_sync.c+h: shared offline sync engine used by both
settings and minarch; supports game_id filtering, configurable
delays, MD5-signed award requests, SYNC_ACK ledger writes, and
startsession cache invalidation after successful sync
- Add "Sync Offline Unlocks" button to settings with B-button cancel,
progress overlay, and RA_SYNC_CONFIG_INTERACTIVE timing
- Refactor minarch ra_integration.c to use shared sync engine instead
of inline rc_api award calls; per-game sync on game load
- Fix overlay text ghosting in settings showOverlay force-draw path
- Fix stale startsession cache causing synced achievements to show as
locked on first offline-first game launch after a settings sync
* Fix stale startsession cache after online achievement unlock sync
* Show pending offline unlock count in Settings sync button description
* fix: patch startsession cache in-place instead of deleting it on online award
When an achievement is confirmed online (either during gameplay or via
settings sync), the cached startsession file is now surgically updated
to include the new unlock rather than being deleted entirely. This
prevents the next offline-first load from seeing 0/X unlocks and
re-triggering all past achievements as new offline unlocks.
* perf(ra): fix main-thread stalls on achievement unlock
- Move ledger fsync off main thread via async write queue
- Pre-decode badge surfaces on HTTP worker thread at download time
- Replace O(N) response queue shift loop with O(1) ring buffer
- Fix use-after-free in progress indicator icon
* Replace [O] text tag with wifi-off icon for offline achievement indicators
* feat(ra): replace text indicators with sprite icons in achievement UI
Replace [M] mute and [O] offline text tags with ASSET_VOLUME_MUTE and
ASSET_WIFI_OFF sprite icons in achievement list rows and the detail
page. Mute icon is src_rect-cropped to 12px to match text height.
List X button hint now toggles MUTE/UNMUTE based on selected item.
* Fix sync notification showing total pending count instead of game-filtered count
When launching a game with offline achievements pending across multiple
games, the initial "Syncing N offline achievements..." notification
incorrectly showed the total count from all games rather than only the
count for the loaded game. The completion notification was correct since
RA_Sync_syncAll filters by game_id internally.
* WIP: fix offline achievement timestamp bugs and add diagnostic logging
Three interrelated bugs in the offline→online achievement sync path:
1. waiting_for_reset never cleared: rc_client_set_hardcore_enabled()
sets waiting_for_reset=1, but rc_client_reset() was never called to
acknowledge it, permanently blocking do_frame achievement processing
after offline→online transitions with hardcore re-enable.
2. On-device unlock timestamps overwritten: the deferred sync-apply code
replaced the original ledger timestamp with time(NULL), causing the
on-device display to show the sync time instead of the actual unlock
time after sync completed.
3. Startsession patching only injected into softcore "Unlocks" array,
not "HardcoreUnlocks". When hardcore was re-enabled, rcheevos saw
pending achievements as not-yet-unlocked-in-hardcore, reset them to
ACTIVE, and could re-award them via its own server call without &o=,
causing the RA server to record the sync time as the unlock time.
Also adds diagnostic logging: per-achievement startsession injection
details, rc_client_reset confirmation, redacted POST body (to verify
&o= is present), and raw server response (to distinguish "Success"
from "User already has").
* Show notification when game is not recognized by RetroAchievements
When a ROM hash is unknown to RetroAchievements, users previously had
no indication of the issue until they opened the achievements menu.
Now a toast notification is shown immediately ("No achievements found
for this game"), and the achievements menu provides guidance about
checking retroachievements.org for compatibility patches or supported
ROM versions.
Also removes erroneous ra_start_offline_sync(0) calls from the game
load failure paths, which were triggering sync-all behavior for
unrelated games instead of being scoped to the current game.
* fix(ra): prevent timestamp loss in offline→online achievement sync
Reported: offline achievement unlock times being replaced by sync time
on the RA server. Root cause: race between our sync engine
(which sends &o=<seconds_since>) and rcheevos' own retry path
(which doesn't include &o=, causing server to use current time).
Fix 1: In ra_server_call(), intercept awardachievement requests
and return synthetic success if the achievement is in our pending
ledger. This lets our sync engine handle the submission with the
correct timestamp.
Fix 2: In ra_http_callback(), query ledger for original timestamp
BEFORE removing from cache, use it when patching startsession cache.
Previously time(NULL) was always used, corrupting on-device display.
Also adds build version to startup log for easier testing.
* fix(ra): block rcheevos retry path to prevent duplicate awardachievement submissions
When achievements are unlocked offline, rcheevos' internal retry
mechanism
races with our sync engine, sending awardachievement with incorrect
CLOCK_MONOTONIC-based timestamps that can overwrite correct wall-clock
timestamps on the RA server.
- Gate awardachievement in ra_server_call() to return synthetic success
when unlock is pending or sync is in progress
- Fix startsession cache patch to skip update when ledger entry is
already compacted, preventing time(NULL) fallback corruption
- Add tagged diagnostic logging ([AWARD_GATE], [AWARD_HTTP], etc.)
- Bump build version to 3
* fix(ra): retry game load on connectivity restore when offline cache misses
When starting offline with a game never previously played online, game
data requests (gameid, achievementsets, patch) have no cached response.
Previously these got a synthetic {"Success":true} which rcheevos
couldn't
parse, permanently failing the game load with no retry mechanism.
- Only synthesize responses for simple types (login2, startsession)
- Return retryable error for game data types on cache miss
- Add game_load_retry deferred flag to retry load on connectivity
restore
- Preserve pending load info until game load succeeds (not on attempt)
- Clear retry state on game unload to prevent stale retries
* Fix offline achievement unlock times for renamed RA accounts
The RA server validates the sync hash using its internal `username`
field,
which may differ from `display_name` after an account rename. Our sync
engine was using the locally-configured display name, causing a hash
mismatch that made the server silently drop the `&o=`
(seconds_since_unlock)
offset parameter — recording unlock times as the sync time instead of
the
actual unlock time.
Extract the internal username from the `AvatarUrl` field in the login
response (which is built from the server's `username`, not
`display_name`),
persist it in config as `raServerUsername`, and use it for sync hash
computation with fallback to the local username for first-boot
compatibility.
* fix: resolve offline achievement timestamp bug caused by RA username mismatch
The RA server silently ignores the backdate offset (&o=) when the MD5
hash is computed with the wrong username. The login API returns
display_name (which users can change) rather than the internal username
used for hash validation. Extract the server's internal username from
the AvatarUrl field (/UserPic/USERNAME.png) at every login path and
persist it in config for the sync engine.
Also fixes an off-by-one in config.c that corrupted raServerUsername
on every load/save cycle (strncmp length 16 vs correct 17), and adds
a missing rc_client_reset() call in the RECONNECTED handler.
* Small text tweak
* refactor: harden and restructure offline RetroAchievements subsystem
Five-wave refactoring of the offline RA code (~1500 net lines across 12
files):
Wave 1 — Bug fixes:
- Join probe/sync threads on shutdown instead of detaching (BF-1)
- Fix JSON success-field parsing for awardachievement responses (BF-2)
- URL-encode username/token in sync HTTP requests (BF-3)
- Fix fwrite short-write checks in cache persistence (BF-4)
- Block with timeout when offline queue is full instead of dropping
(BF-5)
Wave 2/3 — Deduplication:
- Extract shared helpers to new header-only ra_util.h (JSON parsing,
URL param extraction, recursive mkdir, login POST, interruptible
sleep)
- Add filtered query variants to ra_offline API to eliminate
caller-side
loops over the full pending-unlock set
- Consolidate duplicate cache-corruption handling
Wave 4 — Concurrency hardening:
- Dedicated ra_probe_mutex for probe thread lifecycle (CH-1)
- New ra_cache_mutex serializing read-modify-write on startsession
cache updates (CH-2)
- Mark cross-thread flag volatile (CH-4, CH-3 skipped: gnu99 has no
_Atomic)
- Lock notification progress-indicator reads (CH-5)
Wave 5 — State machine refactoring:
- SM-1: State enums (RAConnState, RALoginState, RAGameState,
RASyncState)
with derivation functions replacing scattered compound flag checks
- SM-2: Mutex-protected event queue (ra_fsm.c/h) so background threads
post events instead of writing shared flags
- SM-3: FSM becomes authoritative — RADeferredState struct and its
mutex
removed; ra_process_deferred_flags() rewritten as event-driven
dispatch
- SM-4: ra_logged_in/ra_game_loaded booleans replaced with
authoritative
ra_login_state/ra_game_state enums; every transition is an explicit
assignment; fixes stale-state bug on online game-load failure (T7)
* fix(ra): detect WiFi drops mid-game and sync offline achievements on reconnect
Two complementary mechanisms to reliably detect connectivity changes:
1. Lightweight WiFi polling (Phase 3 in ra_process_deferred_flags):
Checks wpa_cli association state every 5 seconds — no network
traffic. Detects WiFi loss (walk out of range, router reboot,
interface toggle) within seconds and switches to offline mode,
starting the connectivity probe for automatic sync on return.
2. AWARD_GATE fallback: When an awardachievement HTTP request fails
and rcheevos retries into a pending-cache hit, the gate now
recognizes this as evidence of connectivity loss and transitions
to offline mode. Catches edge cases where WiFi appears associated
but the route to the internet is broken.
Previously, mid-game WiFi loss was only detected after rcheevos
exhausted its internal retry backoff and fired
RC_CLIENT_EVENT_DISCONNECTED,
which could take over a minute — or never fire at all if the
AWARD_GATE's
synthetic success satisfied rcheevos first. Offline achievements would
be
recorded in the ledger but never synced.
* refactor(ra): replace volatile bools with SDL_AtomicInt, rename ra_fsm, harden offline subsystem
- Fix use-after-free in startsession cache patching (read pre_patch_len
before the call that may realloc the buffer)
- Add missing init guard to RA_Offline_refreshPendingCache
- Replace all cross-thread volatile bool flags with SDL_atomic_t in
ra_offline.c (3 flags, ~27 sites), ra_integration.c (3 flags, ~22
sites), ra_sync.c (cancel parameter), and settings.cpp (cancel flag)
- Update ra_interruptible_sleep and RA_Sync_syncAll signatures to accept
SDL_atomic_t* instead of volatile bool*
- Rename ra_fsm to ra_event_queue (files, RA_FSM_* symbols to RA_EVQ_*,
internal statics fsm_* to evq_*, log tags, includes, both makefiles)
- Namespace sha256 public symbols with nui_ prefix (SHA256_CTX →
NUI_SHA256_CTX, sha256_init → nui_sha256_init, etc.) and add
extern "C" guard to sha256.h
- Fix include guard style (__RA_OFFLINE_H__ → RA_OFFLINE_H, same for
ra_sync.h)
- Downgrade per-item sync logging from INFO to DEBUG, remove timezone
delta diagnostic logging from api.c and both platform.c files
- Seed srand() only once in RA_Sync_syncAll via static guard
- Document lock ordering, ledger hash chain, and two-tier connectivity
probe architecture
* fix(ra): clear pending cache after sync-apply, fix notification TOCTOU race
* fix(ra): clear stale raServerUsername when AvatarUrl is unavailable
On login success, the internal/server username is extracted from the
AvatarUrl field so offline unlock signatures use a name the server
still recognizes. If AvatarUrl is missing or unparseable, the prior
code silently left any previously-cached value in place — so a stale
name from an earlier login would keep being used even after a rename.
Make CFG_setRAServerUsernameFromAvatarUrl return bool, and at every
login/probe success site clear raServerUsername when extraction fails.
This lets the existing ra_sync.c fallback select the user-entered
username (CFG_getRAUsername) — unlock timestamps may be wrong for
renamed accounts, but that's better than signing with a stale name.
* refactor(ra): pin raServerUsername to settings-auth, drop background writes
raServerUsername signs offline achievement unlocks. It was being re-
extracted from AvatarUrl on every successful rc_client background
login, every connectivity-probe success, and lazily on first sync via
sync_resolve_server_username(). If the RA server ever tightened its
rules around renamed accounts, these paths would keep overwriting the
stored value with a stale internal name and unlock signing would keep
failing with no user-visible recovery.
Restrict writes to RA_authenticateSync in ra_auth.c, which is the
only place the user consciously enters credentials (settings
"Authenticate" menu). Remove the extraction calls from the
ra_integration.c login callback and probe, delete
sync_resolve_server_username in ra_sync.c, and simplify the sync-site
lookup to CFG_getRAServerUsername() with a direct fallback to
CFG_getRAUsername() when empty.
raServerUsername now reflects the last time the user explicitly
authenticated. If unlock signing breaks after a rename, re-running
"Authenticate" in settings is the single, obvious recovery path.
* fix(ra): match JSON-escaped "\/UserPic\/" in AvatarUrl parser
RA API responses escape forward slashes in JSON string values, so the
AvatarUrl field arrives as "http:\/\/...\/UserPic\/name.png". The
parser was only looking for the unescaped "/UserPic/" marker, which
worked when the string came pre-decoded from rcheevos (user->avatar_url)
but silently failed on raw API response bodies — including the settings
"Authenticate" path, which is now the sole writer of raServerUsername.
The result was an empty raServerUsername after every settings auth.
Try the unescaped marker first, then fall back to the escaped form.
* core: clean up comment in parse_login_response
* chore: clean up MINARCH_BUILD_VERSION debugging
* refactor(ra): extract shared logging macros and replace custom crypto
Add ra_log.h with a parameterized RA_LOG_PREFIX macro and migrate all
four RA source files to it, eliminating duplicate per-file LOG_* wrapper
definitions that could silently diverge.
Replace hand-rolled md5.c/sha256.c with OpenSSL's EVP API; remove both
files and add -lcrypto to LDFLAGS for all RA-enabled platforms.
* Add AGENTS.md and CLAUDE.md to gitignore
* fix(build): bundle libcrypto for all RA-enabled handheld platforms
* fix: ensure libchdr/libcrypto are readable before CI system copy
CI fails with 'Permission denied' when copying libcrypto.so.1.1
from the build output. Some sub-builds produce files with
restrictive permissions; add chmod a+r before the copy to
normalize permissions for all platforms.
* Revert "fix: ensure libchdr/libcrypto are readable before CI system copy"
This reverts commit 26c8c8a.
* fix(build): chmod libcrypto readable inside docker build
The toolchain's libcrypto.so.1.1 has restrictive perms; cp -L
preserves them, leaving the file root-owned and unreadable to
the host CI user during the subsequent `system` bundling step.
Run chmod a+r inside the docker build (where we are root and the
mode change actually sticks) rather than on the host, which was
the failure mode of the previously-reverted 26c8c8a.
* feat: implement hook system for pre and post command execution * feat: implement shared hook runner and integrate into launch and suspend scripts * feat: add documentation for NextUI hooks and usage guidelines * feat: add hooks path and directory creation in launch scripts --------- Co-authored-by: frysee <frysee@googlemail.com>
* fix: stack corruption on cheat loading * fix: missing semicolon in Cheat_getPaths * Apply suggestion from @frysee --------- Co-authored-by: frysee <frysee@googlemail.com>
* build: support podman as container runtime fallback Auto-detect docker or podman at build time, preferring docker when both are present. Override with CONTAINER_RUNTIME=podman (or any other compatible runtime) on the make command line. Signed-off-by: Christophe Vanlancker <carroarmato0@gmail.com> * build: clean workspace when switching between docker and podman Docker runs as real root inside the container, so build artifacts and cloned repos (other/) end up root-owned on the host. Rootless podman can't write into those directories, causing permission errors mid-build. Keep track of the last-used runtime in workspace/.container_runtime. When a different runtime is requested, re-run the cleanup inside the previous container using 'find -depth -user root -delete', which strips out everything the old runtime created while leaving host-owned source files untouched. If the previous runtime is gone, print a manual cleanup command and bail out cleanly. Also fixes a missing clean target in btmanager/Makefile, which was caught when the cleanup path exercised it for the first time. Signed-off-by: Christophe Vanlancker <carroarmato0@gmail.com> --------- Signed-off-by: Christophe Vanlancker <carroarmato0@gmail.com> Co-authored-by: frysee <frysee@googlemail.com>
…oveRetro#695) * Replace userspace CPU governor with kernel scaling governors Remove all manual CPU frequency control via the userspace governor and scaling_setspeed. Instead, three shell scripts (auto_governor.sh, powersave_governor.sh, performance_governor.sh) configure the kernel governor and frequency range dynamically at runtime. - auto: ondemand, min to one step below max frequency - powersave: conservative, min to midpoint frequency - performance: schedutil, min to max frequency The minarch CPU Speed menu is reduced from four options (Powersave, Normal, Performance, Auto) to three (Auto, Performance, Powersave). Selecting a profile executes the corresponding script via an absolute path constructed from SYSTEM_PATH. The auto governor is always restored on minarch exit, including early-exit paths. The userspace PLAT_cpu_monitor frequency-scaling loop is removed from both tg5040 and tg5050 platform.c; the thread is retained for CPU usage measurement only. PLAT_setCPUSpeed and PLAT_setCustomCPUSpeed are now no-ops so existing callers (ledcontrol, bootlogo, etc.) are unaffected. * fix: address kernel-cpu-governor review feedback * Simplify the CPU Speed description in MinArch * Switch the governor scripts to the shared policy0 path * Remove the unrelated diff about rom_path Also stop running the CPU monitor when it is not needed by gating it behind the Debug HUD setting and removing the NextUI-side thread launch. Previously, nextui.c was launching this thread in teh back- ground and detaching from it. Now, it's launched conditionally in minarch.c only when the Debug HUD switch is turned on. The platform monitor loop now checks the shared enabled state so the sampling work shuts down when the HUD is off. Hope this squeezes a little more performance out of the cpu. * fix: update governor scripts to include frequency ranges in comments * fix: remaining references to CPU_PATH * fix: adapt scripts to tg5050, which has two clusters * chore: combined governor scripts * fix: bring back PLAT_setCPUSpeed so paks can communicate their cpu needs * chore: removed obsolete macro --------- Co-authored-by: frysee <frysee@googlemail.com>
…shes (LoveRetro#728) Co-authored-by: frysee <frysee@googlemail.com>
* fix: cpu stuck in performance mode on fresh install This fixes a bug where on fresh install i.e. when the CPU speed for minarch has not otherwise been changed, the CPU Speed stays stuck in Performance mode even though the UI shows Auto. This is because minarch calls setOverclock(1) to upgrade to performance mode, but this overwrites the "overclock" variable. If a subsequent "Config_readoptions()" call does not reset it back to something else, the cpu will silently stay in performance mode while the UI shows the default option of Auto. The fix is to set Auto cpu mode explicitly when minarch starts. At present this selects schedutil from min to one less than the max frequency. On TG5040 this is 10% slower clock, so startup time of every game will be 10% slower. But this is of the order of 100-200 ms, while the power and thermal savings are massive. Closes LoveRetro#732 * fix: revert cpu speed to performance during load Avoid clobbering the cpu speed by using PWR_setCPUSpeed() directly. Also move the reset of cpu speed to the last possible place before the gfx loop starts. This fixes the bug without any performance regression, but infact a minor performance gain during load (about 5% faster loading).
…oveRetro#739) When selecting an entry (e.g. Recents) from the Quick Menu, the SCREEN_QUICKMENU input block handles the A press and calls Entry_open, but never calls readyResume for the newly-selected first entry of the opened directory. As a result, can_resume retains its stale value and the footer shows "Power: Sleep" instead of "X: Resume" until the user scrolls to trigger a readyResume call. Normal navigation (pressing A on "Recently Played" in the game list) already calls readyResume immediately after Entry_open. Mirror that same call in the Quick Menu A-press handler. Fixes LoveRetro#737
* feat: support custom fonts in system settings Users can drop .ttf/.otf files into .system/res/fonts/ and they appear as options in the Settings font picker alongside the built-in "Next" and "OG" fonts. Font selection is stored by filename in minuisettings.txt with backward compatibility for existing font=0/1 integer values. Falls back to the default font if a custom font file is removed. * fix: maintain backward compat for font setting in minuisettings.txt Write integer values (font=0, font=1) for built-in fonts so existing paks that parse the setting as an integer keep working. Custom fonts write the filename string. Affects CFG_sync, CFG_get, and CFG_print. * fix: address PR feedback on custom fonts - nextval font always returns integer (0 or 1), never filename - CFG_print outputs font as integer to fix gabagool JSON parsing - Move custom fonts to .system/res/ alongside built-ins (no subfolder) - Remove FONTS_PATH define, all fonts use RES_PATH - Filter BPreplay system fonts from settings font picker - Move licenses dir to .system/res/licenses/ * chore: remove licenses directory for custom fonts Users supply their own fonts; licensing is their responsibility.
…#750) * fix: properly detect usb-c cards plugged in before booting * fix: apply the same patch to tg5050
…aker and headphones
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Make the my355-latest branch up-to-date with the main branch.
As such, the new kernel CPU governor and hook feature were added, similarly to what was done for the other platforms.
In addition, the following improvements were made:
I have made other small changes (to allow to reach lower volume and brightness), but we can cover those in another PR as they are more dabatable.