mirror of
https://github.com/jkdansereau/goldeneye-pc-port.git
synced 2026-10-23 15:52:42 +02:00
fix: D435 -- replugged controllers never reopened (render-thread event pump swallowed hot-plug events)
SDL_CONTROLLERDEVICEADDED / REMOVED are dequeued by whichever of the two event pumps polls first; fast3d's gfx_sdl_handle_events had no case for them and dropped them, so inputRescanPads never ran after a replug (the stale handle later aborted in malloc). Both pumps now post a request and inputUpdate() consumes it on the pad-reading thread. Findings D435. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
0e8c2ce213
commit
05af6d4e0d
6 files changed
+43
-1
No files matched your search
@@ -10,6 +10,7 @@
|
||||
#include "input.h"
|
||||
|
||||
extern "C" void videoRequestQuit(const char *why); // port/src/video.c (D344)
|
||||
extern "C" void inputRequestRescan(void); // port/src/input.c (D435)
|
||||
|
||||
static SDL_Window* wnd;
|
||||
static SDL_GLContext ctx;
|
||||
@@ -339,6 +340,10 @@ static void gfx_sdl_handle_events(void) {
|
||||
case SDL_MOUSEWHEEL:
|
||||
inputPostWheel(event.wheel.y); // weapon cycle
|
||||
break;
|
||||
case SDL_CONTROLLERDEVICEADDED: // D435: this pump and video.c's drain the same
|
||||
case SDL_CONTROLLERDEVICEREMOVED: // SDL queue; request a rescan, never rescan here
|
||||
inputRequestRescan();
|
||||
break;
|
||||
case SDL_WINDOWEVENT:
|
||||
if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) {
|
||||
SDL_GL_GetDrawableSize(wnd, &window_width, &window_height);
|
||||
|
||||
@@ -87,6 +87,7 @@ int inputMenuPointerLive(void);
|
||||
|
||||
/* Re-enumerate gamepads after a hotplug (SDL_CONTROLLERDEVICEADDED/REMOVED). */
|
||||
void inputRescanPads(void);
|
||||
void inputRequestRescan(void); /* D435: from either SDL event pump; consumed by inputUpdate() */
|
||||
|
||||
/* D401: Rumble Pak -> real gamepad haptics. The osMotor* shims in
|
||||
* libultra.c (game's src/joy.c rumble state machine) route here.
|
||||
|
||||
@@ -926,8 +926,23 @@ void inputDestroy(void)
|
||||
|
||||
/* Poll once per controller-read: refresh SDL device state and integrate the
|
||||
* mouse-aim delta into the accumulator. */
|
||||
/* D435: controller hot-plug. SDL_CONTROLLERDEVICEADDED / REMOVED land on
|
||||
* whichever of the two event pumps dequeues them first: video.c's host loop
|
||||
* or fast3d's gfx_sdl_handle_events (render thread, every frame), and the
|
||||
* latter used to drop them, so a replugged pad was never reopened. Both pumps
|
||||
* now only post a request; the rescan runs here, at the top of inputUpdate(),
|
||||
* on the thread that is about to read pads[], so a pad is never closed under
|
||||
* a reader. */
|
||||
static SDL_atomic_t s_rescanReq;
|
||||
|
||||
void inputRequestRescan(void)
|
||||
{
|
||||
SDL_AtomicSet(&s_rescanReq, 1);
|
||||
}
|
||||
|
||||
void inputUpdate(void)
|
||||
{
|
||||
if (SDL_AtomicSet(&s_rescanReq, 0)) inputRescanPads(); /* D435 */
|
||||
SDL_GameControllerUpdate();
|
||||
|
||||
/* D287: skip until the host thread has actually enabled relative mode
|
||||
|
||||
+1
-1
@@ -865,7 +865,7 @@ void videoPumpEvents(void)
|
||||
break;
|
||||
case SDL_CONTROLLERDEVICEADDED:
|
||||
case SDL_CONTROLLERDEVICEREMOVED:
|
||||
inputRescanPads();
|
||||
inputRequestRescan(); /* D435: the rescan runs on the pad-reading thread */
|
||||
break;
|
||||
case SDL_WINDOWEVENT:
|
||||
if (ev.window.event == SDL_WINDOWEVENT_CLOSE) {
|
||||
|
||||
Reference in new issue
Block a user