OK! I made some headway. The problem is linked to JoystickImpl.cpp, line 192
cache.connected = joyGetPosEx(JOYSTICKID1 + index, &joyInfo) == JOYERR_NOERROR;
Which is in the JoystickImpl::isConnected function below. When commenting it out, the program no longer crashes.
bool JoystickImpl::isConnected(unsigned int index)
{
// We check the connection state of joysticks only every N milliseconds,
// because of a strange (buggy?) behavior of joyGetPosEx when joysticks
// are just plugged/unplugged -- it takes really long and kills the app performances
ConnectionCache& cache = connectionCache[index];
if (cache.timer.getElapsedTime() > connectionRefreshDelay)
{
cache.timer.restart();
JOYINFOEX joyInfo;
joyInfo.dwSize = sizeof(joyInfo);
joyInfo.dwFlags = 0;
cache.connected = joyGetPosEx(JOYSTICKID1 + index, &joyInfo) == JOYERR_NOERROR;
return cache.connected;
}
else
{
return cache.connected;
}
}
Interestingly, negating its effect by adding the line:
cache.connected = 0;
Immediately after, while leaving it in, still causes the crash. Seems it seems to be a problem in the Microsoft library itself?
Replacing:
cache.connected = joyGetPosEx(JOYSTICKID1 + index, &joyInfo) == JOYERR_NOERROR;
With:
sf::err() << index;
sf::err().flush();
sf::err() << ":" << joyGetPosEx(JOYSTICKID1 + index, &joyInfo) << " ";
sf::err().flush();
Yielded final 2 lines:
0:167 1:167 2:167 3:167 4:165 5:165 6:165 7:165
0:167 1:167 2:167 3:167 4
So it seems to be crashing with the first controller that never existed after 4 have been disconnected? For my purposes I changed the Joystick::Count enum from 8 to 4, which fixes my crash, but obviously is not a real solution to the problem.