Skip to content

Commit 74742a1

Browse files
committed
Fix unplugging controller sometimes crashing game
Could crash if the ID wasn't in the dictionary. The old code also didn't properly close everything (it would close either the jostick or the gamepad, but not both).
1 parent 44725d0 commit 74742a1

File tree

2 files changed

+30
-16
lines changed

2 files changed

+30
-16
lines changed

osu.Framework/Platform/SDL2/SDL2Window_Input.cs

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -275,8 +275,7 @@ private void handleControllerDeviceEvent(SDL_ControllerDeviceEvent evtCdevice)
275275
break;
276276

277277
case SDL_EventType.SDL_CONTROLLERDEVICEREMOVED:
278-
SDL_GameControllerClose(controllers[evtCdevice.which].ControllerHandle);
279-
controllers.Remove(evtCdevice.which);
278+
removeJoystick(evtCdevice.which);
280279
break;
281280

282281
case SDL_EventType.SDL_CONTROLLERDEVICEREMAPPED:
@@ -323,6 +322,20 @@ private void addJoystick(int which)
323322
controllers[instanceID] = new SDL2ControllerBindings(joystick, controller);
324323
}
325324

325+
private void removeJoystick(int which)
326+
{
327+
int instanceID = SDL_JoystickGetDeviceInstanceID(which);
328+
329+
if (controllers.Remove(instanceID, out var controller))
330+
{
331+
if (controller.ControllerHandle != IntPtr.Zero)
332+
SDL_GameControllerClose(controller.ControllerHandle);
333+
334+
if (controller.JoystickHandle != IntPtr.Zero)
335+
SDL_JoystickClose(controller.JoystickHandle);
336+
}
337+
}
338+
326339
/// <summary>
327340
/// Populates <see cref="controllers"/> with joysticks that are already connected.
328341
/// </summary>
@@ -343,12 +356,7 @@ private void handleJoyDeviceEvent(SDL_JoyDeviceEvent evtJdevice)
343356
break;
344357

345358
case SDL_EventType.SDL_JOYDEVICEREMOVED:
346-
// if the joystick is already closed, ignore it
347-
if (!controllers.ContainsKey(evtJdevice.which))
348-
break;
349-
350-
SDL_JoystickClose(controllers[evtJdevice.which].JoystickHandle);
351-
controllers.Remove(evtJdevice.which);
359+
removeJoystick(evtJdevice.which);
352360
break;
353361
}
354362
}

osu.Framework/Platform/SDL3/SDL3Window_Input.cs

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -322,8 +322,7 @@ private void handleControllerDeviceEvent(SDL_GamepadDeviceEvent evtCdevice)
322322
break;
323323

324324
case SDL_EventType.SDL_EVENT_GAMEPAD_REMOVED:
325-
SDL_CloseGamepad(controllers[evtCdevice.which].GamepadHandle);
326-
controllers.Remove(evtCdevice.which);
325+
removeJoystick(evtCdevice.which);
327326
break;
328327

329328
case SDL_EventType.SDL_EVENT_GAMEPAD_REMAPPED:
@@ -368,6 +367,18 @@ private void addJoystick(SDL_JoystickID instanceID)
368367
controllers[instanceID] = new SDL3ControllerBindings(joystick, controller);
369368
}
370369

370+
private void removeJoystick(SDL_JoystickID instanceID)
371+
{
372+
if (controllers.Remove(instanceID, out var controller))
373+
{
374+
if (controller.GamepadHandle != null)
375+
SDL_CloseGamepad(controller.GamepadHandle);
376+
377+
if (controller.JoystickHandle != null)
378+
SDL_CloseJoystick(controller.JoystickHandle);
379+
}
380+
}
381+
371382
/// <summary>
372383
/// Populates <see cref="controllers"/> with joysticks that are already connected.
373384
/// </summary>
@@ -393,12 +404,7 @@ private void handleJoyDeviceEvent(SDL_JoyDeviceEvent evtJdevice)
393404
break;
394405

395406
case SDL_EventType.SDL_EVENT_JOYSTICK_REMOVED:
396-
// if the joystick is already closed, ignore it
397-
if (!controllers.ContainsKey(evtJdevice.which))
398-
break;
399-
400-
SDL_CloseJoystick(controllers[evtJdevice.which].JoystickHandle);
401-
controllers.Remove(evtJdevice.which);
407+
removeJoystick(evtJdevice.which);
402408
break;
403409
}
404410
}

0 commit comments

Comments
 (0)