191 lines
5.1 KiB
C++
191 lines
5.1 KiB
C++
#include "streaming/input/sdlinputsubsystems.h"
|
|
|
|
#include "settings/mappingmanager.h"
|
|
|
|
namespace {
|
|
|
|
int s_JoystickRefs = 0;
|
|
int s_GameControllerRefs = 0;
|
|
#if !SDL_VERSION_ATLEAST(2, 0, 9)
|
|
int s_HapticRefs = 0;
|
|
#endif
|
|
|
|
bool retainSubsystem(Uint32 subsystem, int& refs, const char* subsystemName, const char* ownerTag)
|
|
{
|
|
if (refs == 0 && SDL_InitSubSystem(subsystem) != 0) {
|
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
|
"Failed to initialize %s subsystem for %s: %s",
|
|
subsystemName,
|
|
ownerTag,
|
|
SDL_GetError());
|
|
return false;
|
|
}
|
|
|
|
refs++;
|
|
return true;
|
|
}
|
|
|
|
void releaseSubsystem(Uint32 subsystem, int& refs, const char* subsystemName, const char* ownerTag)
|
|
{
|
|
if (refs <= 0) {
|
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
|
"Ignoring unbalanced release of %s subsystem for %s",
|
|
subsystemName,
|
|
ownerTag);
|
|
refs = 0;
|
|
return;
|
|
}
|
|
|
|
refs--;
|
|
if (refs == 0) {
|
|
SDL_QuitSubSystem(subsystem);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
namespace SdlInputSubsystems {
|
|
|
|
bool acquire(const char* ownerTag, const LeaseOptions& options)
|
|
{
|
|
bool acquiredJoystick = false;
|
|
#if !SDL_VERSION_ATLEAST(2, 0, 9)
|
|
bool acquiredGameController = false;
|
|
bool acquiredHaptic = false;
|
|
#endif
|
|
|
|
if (options.joystick) {
|
|
if (!retainSubsystem(SDL_INIT_JOYSTICK, s_JoystickRefs, "joystick", ownerTag)) {
|
|
return false;
|
|
}
|
|
acquiredJoystick = true;
|
|
}
|
|
|
|
if (options.gameController) {
|
|
if (!retainSubsystem(SDL_INIT_GAMECONTROLLER, s_GameControllerRefs, "gamecontroller", ownerTag)) {
|
|
if (acquiredJoystick) {
|
|
releaseSubsystem(SDL_INIT_JOYSTICK, s_JoystickRefs, "joystick", ownerTag);
|
|
}
|
|
return false;
|
|
}
|
|
#if !SDL_VERSION_ATLEAST(2, 0, 9)
|
|
acquiredGameController = true;
|
|
#endif
|
|
}
|
|
|
|
#if !SDL_VERSION_ATLEAST(2, 0, 9)
|
|
if (options.haptic) {
|
|
if (!retainSubsystem(SDL_INIT_HAPTIC, s_HapticRefs, "haptic", ownerTag)) {
|
|
if (acquiredGameController) {
|
|
releaseSubsystem(SDL_INIT_GAMECONTROLLER, s_GameControllerRefs, "gamecontroller", ownerTag);
|
|
}
|
|
if (acquiredJoystick) {
|
|
releaseSubsystem(SDL_INIT_JOYSTICK, s_JoystickRefs, "joystick", ownerTag);
|
|
}
|
|
return false;
|
|
}
|
|
acquiredHaptic = true;
|
|
}
|
|
#endif
|
|
|
|
if (options.applyMappings) {
|
|
MappingManager mappingManager;
|
|
mappingManager.applyMappings();
|
|
}
|
|
|
|
if (options.flushControllerDeviceEvents) {
|
|
SDL_FlushEvent(SDL_CONTROLLERDEVICEADDED);
|
|
SDL_FlushEvent(SDL_CONTROLLERDEVICEREMOVED);
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void release(const char* ownerTag, const LeaseOptions& options)
|
|
{
|
|
#if !SDL_VERSION_ATLEAST(2, 0, 9)
|
|
if (options.haptic) {
|
|
releaseSubsystem(SDL_INIT_HAPTIC, s_HapticRefs, "haptic", ownerTag);
|
|
}
|
|
#endif
|
|
|
|
if (options.gameController) {
|
|
releaseSubsystem(SDL_INIT_GAMECONTROLLER, s_GameControllerRefs, "gamecontroller", ownerTag);
|
|
}
|
|
|
|
if (options.joystick) {
|
|
releaseSubsystem(SDL_INIT_JOYSTICK, s_JoystickRefs, "joystick", ownerTag);
|
|
}
|
|
}
|
|
|
|
bool hasExclusiveGamepadOwnership()
|
|
{
|
|
if (s_JoystickRefs != 1 || s_GameControllerRefs != 1) {
|
|
return false;
|
|
}
|
|
|
|
#if !SDL_VERSION_ATLEAST(2, 0, 9)
|
|
if (s_HapticRefs != 1) {
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
return true;
|
|
}
|
|
|
|
bool reenumerateGamepadSubsystems(const char* ownerTag)
|
|
{
|
|
if (!hasExclusiveGamepadOwnership()) {
|
|
SDL_LogWarn(SDL_LOG_CATEGORY_APPLICATION,
|
|
"Skipping subsystem re-enumeration for %s due to shared ownership (joystick=%d gamecontroller=%d)",
|
|
ownerTag,
|
|
s_JoystickRefs,
|
|
s_GameControllerRefs);
|
|
return false;
|
|
}
|
|
|
|
#if !SDL_VERSION_ATLEAST(2, 0, 9)
|
|
SDL_QuitSubSystem(SDL_INIT_HAPTIC);
|
|
#endif
|
|
SDL_QuitSubSystem(SDL_INIT_GAMECONTROLLER);
|
|
SDL_QuitSubSystem(SDL_INIT_JOYSTICK);
|
|
|
|
if (SDL_InitSubSystem(SDL_INIT_JOYSTICK) != 0) {
|
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
|
"Failed to reinitialize joystick subsystem for %s: %s",
|
|
ownerTag,
|
|
SDL_GetError());
|
|
return false;
|
|
}
|
|
|
|
if (SDL_InitSubSystem(SDL_INIT_GAMECONTROLLER) != 0) {
|
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
|
"Failed to reinitialize gamecontroller subsystem for %s: %s",
|
|
ownerTag,
|
|
SDL_GetError());
|
|
return false;
|
|
}
|
|
|
|
#if !SDL_VERSION_ATLEAST(2, 0, 9)
|
|
if (SDL_InitSubSystem(SDL_INIT_HAPTIC) != 0) {
|
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
|
"Failed to reinitialize haptic subsystem for %s: %s",
|
|
ownerTag,
|
|
SDL_GetError());
|
|
return false;
|
|
}
|
|
#endif
|
|
|
|
MappingManager mappingManager;
|
|
mappingManager.applyMappings();
|
|
|
|
SDL_JoystickUpdate();
|
|
SDL_GameControllerUpdate();
|
|
|
|
SDL_FlushEvents(SDL_JOYDEVICEADDED, SDL_JOYDEVICEREMOVED);
|
|
SDL_FlushEvents(SDL_CONTROLLERDEVICEADDED, SDL_CONTROLLERDEVICEREMAPPED);
|
|
|
|
return true;
|
|
}
|
|
|
|
}
|