Jump to content
  • Advertisement
Sign in to follow this  
JackOfCandles

SDL2 - Unexpected Behavior When Hot Swapping Gamepads If One Or More Is Asleep

This topic is 444 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

I created a small test application where I handle the SDL_CONTROLLERDEVICEADDED and SDL_CONTROLLERDEVICEREMOVED events, and output information about the controller being added/removed, based on the information in this blog.

I have two controllers connected to my PC, an Xbox 360 controller and a Logitech controller. What I found is that if they are both active and awake it produces the expected output, but if either one or both of them are asleep, it outputs the wrong name under certain conditions. I don't want to be overly verbose and go over every configuration I tested, but one example is if I start the application with both controllers in sleep mode, it fires the SDL_CONTROLLERDEVICEADDED for the Logitech controller but not the Xbox controller at application startup (The event for the Xbox control only happens when it is awakened), and then when I unplug/plug in the Logitech controller's USB receiver, it shows the device name as "X360" every time, until I wake them both up, at which point it outputs the correct name again.

Perhaps I'm worrying too much about this, as most people probably don't mix and match controllers and likely only use one, but I just found it curious. I'm wondering if it might be a bug in SDL2, or if maybe there is some insight someone might have related to xbox controllers and how they behave in sleep mode.

 

Here is the relevant code if anyone's interested:

struct SdlGamepad
{
	SDL_GameController*	controller;
	SDL_Joystick*		joystick;
	SDL_JoystickID		joystickId;
	std::string		deviceName;
	int			deviceId;
};



std::map<SDL_JoystickID, SdlGamepad> joystickIdToGamepadMap;

SDL_Event event;

bool hasQuit = false;

while (hasQuit == false)
{
	while (SDL_PollEvent(&event))
	{
		switch (event.type)
		{
			case SDL_CONTROLLERDEVICEADDED:
			{
				std::cout << "Controller device added." << std::endl;

				if (SDL_IsGameController(event.cdevice.which))
				{
					SdlGamepad gamepad;

					gamepad.controller = SDL_GameControllerOpen(event.cdevice.which);
					gamepad.joystick = SDL_GameControllerGetJoystick(gamepad.controller);
					gamepad.joystickId = SDL_JoystickInstanceID(gamepad.joystick);

					std::string deviceName = SDL_GameControllerName(gamepad.controller);

					gamepad.deviceName = deviceName;
					gamepad.deviceId = event.cdevice.which;

					joystickIdToGamepadMap[gamepad.joystickId] = gamepad;

					std::cout 
						<< "Controller device name = " << gamepad.deviceName << std::endl
						<< "Controller device ID = " << gamepad.deviceId << std::endl
						<< "Joystick device ID = " << gamepad.joystickId << std::endl << std::endl;

				}

				break;
			}
			case SDL_CONTROLLERDEVICEREMOVED:
			{
				std::cout << "Controller device removed." << std::endl;

				SdlGamepad gamepad = joystickIdToGamepadMap[event.cdevice.which];

				std::cout
					<< "Controller device name = " << gamepad.deviceName << std::endl
					<< "Controller device ID = " << gamepad.deviceId << std::endl
					<< "Joystick device ID = " << gamepad.joystickId << std::endl << std::endl;
  
				SDL_GameControllerClose(gamepad.controller);

				joystickIdToGamepadMap.erase(event.cdevice.which);
  
				break;
			}
			case SDL_QUIT:
			{
				hasQuit = true;
				break;
			}
		}
	}
}

 

Share this post


Link to post
Share on other sites
Advertisement

Perhaps I'm misunderstanding. I'm using the joystick ID as the map key, obtained as the above link says, by calling SDL_JoystickInstanceID(SDL_GameControllerGetJoystick(myController)), albeit factored out into multiple lines. Is that not correct?

Share this post


Link to post
Share on other sites

Your code looks right. The code that is relevant for this particular can be condensed to:

SDL_Event event;
while (SDL_PollEvent(&event))
{
  switch (event.type)
  {
    case SDL_CONTROLLERDEVICEADDED:
    {
      std::cout << "Controller device added." << std::endl;
      if (SDL_IsGameController(event.cdevice.which))
      {
        auto controller = SDL_GameControllerOpen(event.cdevice.which);
        std::cout << "Controller device name = " << SDL_GameControllerName(gamepad.controller) << std::endl;
      }
      break;
    }
  }
}

This should still reproduce the same problem. If it does, I suggest that you report this as a bug in SDL.

Edited by Ansou

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!