public void ProcessControllerEvent(ControllerDeviceEvent ev) { int id = ev.Which; if (id < 0) { Debug.Print("[SDL2] Invalid controller id {0} in {1}", id, ev.Type); return; } switch (ev.Type) { case EventType.CONTROLLERDEVICEADDED: IntPtr handle = SDL.GameControllerOpen(id); if (handle != IntPtr.Zero) { // The id variable here corresponds to a device_id between 0 and Sdl.NumJoysticks(). // It is only used in the ADDED event. All other events use an instance_id which increases // monotonically in each ADDED event. // The idea is that device_id refers to the n-th connected joystick, whereas instance_id // refers to the actual hardware device behind the n-th joystick. // Yes, it's confusing. int device_id = id; int instance_id = last_controllers_instance++; Sdl2GamePad pad = new Sdl2GamePad(handle); IntPtr joystick = SDL.GameControllerGetJoystick(handle); if (joystick != IntPtr.Zero) { pad.Capabilities = new GamePadCapabilities( GamePadType.GamePad, GetBoundAxes(joystick), GetBoundButtons(joystick), true); pad.State.SetConnected(true); // Connect this device and add the relevant device index if (controllers.Count <= id) { controllers.Add(pad); } else { controllers[device_id] = pad; } sdl_instanceid_to_controllers.Add(instance_id, device_id); } else { Debug.Print("[SDL2] Failed to retrieve joystick from game controller. Error: {0}", SDL.GetError()); } } break; case EventType.CONTROLLERDEVICEREMOVED: if (IsControllerInstanceValid(id)) { int instance_id = id; int device_id = sdl_instanceid_to_controllers[instance_id]; controllers[device_id].State.SetConnected(false); sdl_instanceid_to_controllers.Remove(device_id); } else { Debug.Print("[SDL2] Invalid game controller instance {0} in {1}", id, ev.Type); } break; case EventType.CONTROLLERDEVICEREMAPPED: if (IsControllerInstanceValid(id)) { // Todo: what should we do in this case? } else { Debug.Print("[SDL2] Invalid game controller instance {0} in {1}", id, ev.Type); } break; } }