Skip to content

Fix issue - shoulder buttons do not perform page up/down actions#666

Open
Oberworld wants to merge 1102 commits into
Aloshi:masterfrom
RetroPie:master
Open

Fix issue - shoulder buttons do not perform page up/down actions#666
Oberworld wants to merge 1102 commits into
Aloshi:masterfrom
RetroPie:master

Conversation

@Oberworld

Copy link
Copy Markdown

Hi, I'm nismo from retropie forums (my nick was taken here).

There is a bug on Emulationstation that make L and R buttons to fast navigate in gamelist doesn't work.

Fieldofcows did a fix months ago and I tested without any issues.

Can you update the code to add it?

Here is the commit: fieldofcows@97f56a1

Regards.

@robertybob

Copy link
Copy Markdown

@Oberworld I think this can be closed as it's not been created properly :)

@hex007

hex007 commented Aug 25, 2017

Copy link
Copy Markdown

@Oberworld This is not the repo for EmulationStation for Retropie

Go here -> https://github.com/Retropie/EmulationStation

And close this PR. It has too many commits and this repo is not maintained

@hex007

hex007 commented Sep 24, 2017

Copy link
Copy Markdown

@Oberworld Please close this PR ASAP

EnsignRutherford and others added 24 commits May 18, 2021 12:58
…d code to fire an event when ES is configured to bring up a startup system.
…o games available. This allows the bash scripts to pick up this event and perform an action as opposed to not triggering the event.
tellg can report -1 if there was an error while reading the file, because it was casted to a size_t type which is unsigned, this will become 18446744073709551615. It will then attempt to allocate that many bytes and of course crash. This will just return an empty resource if there was an error.
input: change how input events during start are discarded
CLI option --no-confirm-quit for skipping the confirm dialog on quit …
…o games available. This allows the bash scripts to pick up this event and perform an action as opposed to not triggering the event.
…the screensaver is started as that will fire off an event depending on the setting.
…evice for seed

- Use C++11 built-in ranlux48 and random_device for seeding
- Shuffles systems (aso.) like a card deck and picks top system until empty, then shuffles again
- Fixes the flaws of the current random implementation: Real 1/N chance for an element in a set of N
- Minor refactorings
Better Random: Perfect shuffle of systems, games and screensaver items
This ensures that configurations created before HIDAPI drivers were enabled by default (2.0.12)
will work when EmulationStation uses a newer SDL2 version.

Using the HIDAPI drivers may produce a different name for joysticks and pottentially changes the mapping.
Example using a PS4 (Dualshock 4) controller:
 - without HIDAPI, the controller is named "Wireless Controller", with HIDAPI enabled is named "PS4 Controller"
 - without HIDAPI, the D-Pad is detected as a HAT, but with the drivers enabled it's detected as a series of buttons
 - the device GUID is different between the 2 configurations
The different name would probably break also the input configuration script for RetroArch, which doesn't use SDL2 as default input driver and would receive a wrong name and wrong mappings.

Note that the HIDAPI drivers are available just for a few controller models (PS4/PS4/Amazon Luna/Stadia/Xbox360(w)/Xbox One/Steam),
but these controllers are widely used and breaking their configuration would cause much confusion.
* renamed image to media and added setting rename function

* replaced references to 'image' with 'media' and removed hardcoded video extensions

* fixed a bug when checking a null path
Center the gamelist in the available textlist height
The change extends the DateTime formatting options and simplifies a bit the code.
Added:
 * Nintendo Switch (TGDB, ScreenScraper)
 * TIC 80 (ScreenScraper)
 * PICO-8 (ScreenScraper)
 * Sam Coupe (TGDB, ScreenScraper)
 * PC-FX (TGDB, ScreenScraper)
 * ZMachine (ScreenScraper)

Updated:
 * ZX81 Sinclair - added for TGDB
pjft and others added 30 commits May 31, 2025 13:46
nanosvg: update from upstream
Add support for scroll sounds to SystemView and ImageGridComponent
Fix Font (texture) handling
Do an update for MAME related resources, based on the XML/Dat information taken on 12.01.2026 from:

 * MAME 0.284
 * FinalBurn Neo
 * MAME 2003-Plus

Summary: 38351 games, 91 bioses, 1165 devices
This reverts commit 2313548, reversing
changes made to a72ca01.
Quote the filenames, since some of them contain spaces.
Re-generated the arcade/MAME resources files, from:
 - MAME 0.284
 - FinalBurn Neo (as of 31.01.2026)
 - MAME 2003-Plus (as of 31.01.2026)

Summary: 38353 games, 91 bioses, 3988 devices
resources: update MAME files and generation script
Introduces setImageAsync() on ImageComponent that skips the stat64-backed
fileExists() check, bypassing the NAS latency that was freezing the main
thread on every game selection. The path is handed directly to
TextureResource with block=false so the background TextureLoader thread
handles the actual file I/O.

Adds mAsyncPending flag; update() polls updateTextureSize() each frame
and calls resize() once the background thread finishes loading, producing
a smooth fade-in rather than a hard stall.

Also caps the deltaTime fed into IList's scroll accumulator to one scroll
tier interval, preventing multiple cursor jumps after a long-blocking
frame. Updates DetailedGameListView, GridGameListView, VideoGameListView,
and VideoComponent to call setImageAsync() for all per-game media.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces the synchronous busy-wait loop
(while (libvlc_media_get_parsed_status() == 0) ;)
with a non-blocking libvlc_media_parse_with_options call and a
per-frame poll via a new handleParsing() method called from render().

Adds mMediaParsing flag to VideoVlcComponent to guard against starting
a new video while the previous media is still being parsed, and to
defer startVideo() until parsing completes. Eliminates the main-thread
stall that caused audio/video to lag on first load.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Serializes the pugixml document to a std::string on the main thread
(fast, in-memory), then dispatches the actual file write to a background
thread via std::async. Pending futures are stored in a global vector;
completed ones are pruned on each subsequent write call.

Adds waitForGamelistWrites() which blocks until all in-flight writes
complete. Called from main() before SystemData::deleteSystems() to
guarantee no data is lost on clean shutdown.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduces an "AsyncFileIO" boolean setting (default off) accessible in
the Other Settings menu as "ASYNC FILE IO", mirroring the pattern used
by "PARSE GAMELISTS ONLY".

When off (default): image loads call the synchronous setImage() path and
gamelist writes use doc.save_file() on the main thread — original
blocking behaviour preserved.

When on: ImageComponent::setImageAsync() and VideoComponent::setImageAsync()
queue texture loads on the background TextureLoader thread; gamelist writes
serialize XML on the main thread then dispatch the file write via
std::async to avoid blocking the UI on slow NAS I/O.

The toggle is handled entirely inside setImageAsync() and updateGamelist()
so no call sites in the game list views needed to change.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
stopVideo() was freezing the UI because libvlc_media_parse_stop and
libvlc_media_player_stop block on internal VLC mutexes. The initial fix
of spawning a std::thread per call also blocked due to pthread_create
mutex contention during stack allocation. This replaces per-call thread
creation with a single persistent worker thread and task queue, so
stopVideo() returns immediately after pushing a cleanup lambda. The
VideoContext is now heap-allocated so ownership can be safely transferred
to the background worker without lifetime issues with VLC callbacks.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
VideoComponent::setVideo() and ImageComponent::setImage() were calling
ResourceManager::fileExists() (fstatat64) on the main thread for every
cursor move, freezing the UI while a NAS drive spins up. Remove the
guards and let VLC / TextureData::load() handle missing files gracefully.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The background texture-loader thread would acquire the exists() mutex
then block on stat64() for a slow NAS path. Meanwhile the main thread
(e.g. Scripting::fireEvent on every cursor move) tried to acquire the
same mutex and froze the UI until the NAS responded.

Fix by doing stat64 outside the mutex: check the cache under lock,
release before the syscall, then reacquire to store the result.
Cache is preserved so return visits to the same game avoid re-stat'ing
on NAS paths. The benign race (two threads both missing cache for the
same path) is acceptable — both will stat and store the same result.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…sing textures

Four related bugs in the async texture loading system:

1. Missing-file retry loop: TextureData had no "load failed" state, so after
   load() returned false (file not found), isLoaded() kept returning false.
   TextureDataManager::get() would re-queue the texture every frame it was
   rendered, causing log spam and spinning the background thread.
   Fix: add mLoadFailed flag set on any load() failure; check it in
   TextureDataManager::get() and TextureLoader::load() before re-queuing.

2. VRAM exhaustion: the retry loop moved the never-loadable texture to the
   front of the LRU list every frame and triggered the eviction path to "make
   room", continuously evicting real textures without gaining anything.
   Resolved by fix #1 stopping the re-queue cycle.

3. mAsyncPending stuck forever: updateTextureSize() never returned true for
   failed textures since isLoaded() stays false after failure. ImageComponent
   polled updateTextureSize() every frame indefinitely and the render path
   logged a debug skip every ~1 second per missing image.
   Fix: return true from updateTextureSize() when hasLoadFailed() is set so
   callers treat it as terminal (mSize stays 0,0; image renders blank).

4. Thread not dying on exit: TextureLoader::~TextureLoader() cleared the queue
   and set mExit without holding mMutex, racing with the background thread's
   condition_variable wait (which holds the mutex while sleeping). The clear
   and mExit assignment are now done inside a scoped lock before notify_one().

Also adds hasLoadFailed() guards to TextureDataManager::load() and
TextureResource::reload() to close secondary paths that bypassed the check.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When a game list view is rendered in the background (e.g. during the system
carousel transition), update() is never called for its ImageComponents, so
mAsyncPending would stay true indefinitely for failed loads even after
mLoadFailed was set by the background thread.

Add TextureResource::hasLoadFailed() and check it in the render skip-path
to clear mAsyncPending without the overhead of updateTextureSize() or an
unnecessary resize() call.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two bools allowed impossible states and required callers to check both
with two mutex acquisitions. Replace with a single LoadStatus enum
(LOADING / LOADED / FAILED) returned under one lock, and use a switch
in updateTextureSize() to make each state's intent explicit.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Background views receive render() but not update(), so the
updateTextureSize() poll in update() never runs for them.
Check updateTextureSize() in the render skip block instead —
handles both LOADED and FAILED states without needing update().

Remove now-unused hasLoadFailed() from TextureResource.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When the NAS is slow to respond, the snapshot image may not finish
loading before the configured video start delay expires, causing the
image to never display and the video to start immediately after a
blank screen.

Keep pushing mStartTime forward in handleStartDelay() while
mStaticImage.isAsyncPending() so the full delay runs only after the
snapshot is actually visible to the user.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two bugs reported after async image loading:

1. Texture flickering after screensaver + random navigation
   The LRU eviction loop in TextureDataManager::load() was calling
   mLoader->remove() on LOADING textures, which have no data in RAM or
   VRAM (getVRAMUsage()==0).  Evicting them frees zero memory but cancels
   their pending background load.  The next bind() then re-triggers load(),
   which runs the eviction loop again — creating an evict→cancel→re-queue→
   evict cascade that causes non-stop flickering under memory pressure.

   Fix: skip any texture whose loadStatus() != LOADED in the eviction loop.
   Only textures that actually hold pixel data are worth evicting.

2. Process stays alive after quit (two open unix streams in lsof)
   VideoVlcComponent::cleanupWorker() ran an infinite while(true) with no
   exit condition, and the thread was detach()ed so it could never be
   joined.  Its condition variable and mutex were static class members whose
   destructors could be called while the thread was still blocked on them —
   undefined behaviour that can hang the process.  Additionally,
   libvlc_release() was never called, leaving VLC's internal unix-domain
   sockets open.

   Fix:
   - Add sCleanupExit flag; cleanupWorker() breaks when flag is set and
     queue is empty.
   - Keep thread joinable (remove detach()).
   - Add VideoVlcComponent::deinit(): signals exit, joins thread, releases
     libvlc instance.
   - Call VideoVlcComponent::deinit() from main() after window.deinit() so
     all VideoVlcComponents are destroyed before the join.

https://claude.ai/code/session_01PEfY7jzoFWHyPex93Ma7Ti
- Add favorite icon to game list with full theme support
- Make favoriteIconVisible a theme variable instead of a per-view textlist attribute
- Fix resource paths (:/...) not resolving correctly in theme files
- Don't shift text when favoriteIconPath fails to load

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
add heart next to name for a favorite in the list
The eviction loop in TextureDataManager::load() walks the LRU list and frees
LOADED textures until total memory drops below MaxVRAM, with no awareness of
whether a texture is currently being rendered.  With synchronous loading this
was hidden — bind() would re-load the just-evicted texture before the GPU
draw call.  Async loading defers the reload past the current frame, so the
on-screen texture renders blank for one or more frames before reappearing,
and a new eviction triggers each frame the visible set is re-bound.  The
result is the non-stop flickering pjft reported.

Fix: stamp each successful bind with a monotonically increasing generation
counter (advanced once per Window::render()), and have eviction skip any
texture whose generation matches the current or previous frame.  A second
pass falls back to evicting on-screen textures only if the working set itself
exceeds MaxVRAM, so we never deadlock.

https://claude.ai/code/session_01PEfY7jzoFWHyPex93Ma7Ti
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.