input_common: Reimplement SDL
This commit is contained in:
parent
ea4cf3cc6b
commit
4904ef8001
|
@ -46,6 +46,7 @@ SDLDriver::SDLDriver(std::string input_engine_) : InputEngine(std::move(input_en
|
|||
// not a generic one
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_JOY_CONS, "1");
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH, "1");
|
||||
SDL_SetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED, "0");
|
||||
|
||||
// Disable hidapi driver for xbox. Already default on Windows, this causes conflict with native
|
||||
// driver on Linux.
|
||||
|
@ -84,36 +85,37 @@ SDLDriver::~SDLDriver() {
|
|||
CloseJoysticks();
|
||||
SDL_DelEventWatch(&SDLEventWatcher, this);
|
||||
|
||||
if (initialized) {
|
||||
if (vibration_thread.joinable()) {
|
||||
vibration_thread.join();
|
||||
}
|
||||
|
||||
if (initialized) {
|
||||
SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER);
|
||||
}
|
||||
|
||||
initialized = false;
|
||||
}
|
||||
|
||||
void SDLDriver::InitJoystick(int joystick_index) {
|
||||
SDL_Joystick* sdl_joystick = SDL_JoystickOpen(joystick_index);
|
||||
SDL_GameController* sdl_gamecontroller = nullptr;
|
||||
|
||||
if (SDL_IsGameController(joystick_index)) {
|
||||
sdl_gamecontroller = SDL_GameControllerOpen(joystick_index);
|
||||
}
|
||||
|
||||
if (!sdl_joystick) {
|
||||
LOG_ERROR(Input, "Failed to open joystick {}", joystick_index);
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<SDLDriver::JoystickID> SDLDriver::GetSDLJoystickBySDLID(SDL_JoystickID sdl_id) {
|
||||
auto sdl_joystick = SDL_JoystickFromInstanceID(sdl_id);
|
||||
const auto guid = GetGUID(sdl_joystick);
|
||||
}
|
||||
|
||||
void SDLDriver::CloseJoystick(SDL_Joystick* sdl_joystick) {
|
||||
const auto guid = GetGUID(sdl_joystick);
|
||||
}
|
||||
|
||||
void SDLDriver::CloseJoysticks() {
|
||||
std::scoped_lock lock{joystick_map_mutex};
|
||||
const auto map_it = joystick_map.find(guid);
|
||||
|
||||
if (map_it == joystick_map.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const auto vec_it =
|
||||
std::find_if(map_it->second.begin(), map_it->second.end(),
|
||||
[sdl_id](const auto& joystick) { return joystick->sdl_index == sdl_id; });
|
||||
|
||||
if (vec_it == map_it->second.end()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return *vec_it;
|
||||
}
|
||||
|
||||
void SDLDriver::PumpEvents() const {
|
||||
|
@ -124,32 +126,87 @@ void SDLDriver::PumpEvents() const {
|
|||
|
||||
void SDLDriver::HandleGameControllerEvent(const SDL_Event& event) {
|
||||
switch (event.type) {
|
||||
case SDL_JOYBUTTONUP: {
|
||||
case SDL_JOYBUTTONUP:
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
case SDL_JOYHATMOTION:
|
||||
case SDL_JOYAXISMOTION:
|
||||
case SDL_CONTROLLERSENSORUPDATE:
|
||||
UpdateControllerStatus(event.type, event.jdevice.which);
|
||||
break;
|
||||
}
|
||||
case SDL_JOYBUTTONDOWN: {
|
||||
break;
|
||||
}
|
||||
case SDL_JOYHATMOTION: {
|
||||
break;
|
||||
}
|
||||
case SDL_JOYAXISMOTION: {
|
||||
break;
|
||||
}
|
||||
case SDL_CONTROLLERSENSORUPDATE: {
|
||||
break;
|
||||
}
|
||||
case SDL_JOYDEVICEREMOVED:
|
||||
LOG_DEBUG(Input, "Controller removed with Instance_ID {}", event.jdevice.which);
|
||||
CloseJoystick(SDL_JoystickFromInstanceID(event.jdevice.which));
|
||||
CloseJoystick(event.jdevice.which);
|
||||
break;
|
||||
case SDL_JOYDEVICEADDED:
|
||||
LOG_DEBUG(Input, "Controller connected with device index {}", event.jdevice.which);
|
||||
InitJoystick(event.jdevice.which);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SDLDriver::InitJoystick(int joystick_index) {
|
||||
LOG_DEBUG(Input, "Controller connected with device index {}", joystick_index);
|
||||
SDL_Joystick* sdl_joystick = SDL_JoystickOpen(joystick_index);
|
||||
SDL_GameController* sdl_gamecontroller = nullptr;
|
||||
|
||||
if (!sdl_joystick) {
|
||||
LOG_ERROR(Input, "Failed to open joystick {}", joystick_index);
|
||||
return;
|
||||
}
|
||||
|
||||
const auto guid = GetGUID(sdl_joystick);
|
||||
const auto joystick = GetSDLJoystickBySDLID(joystick_index);
|
||||
PreSetController(joystick->identifier);
|
||||
|
||||
if (SDL_IsGameController(joystick_index)) {
|
||||
sdl_gamecontroller = SDL_GameControllerOpen(joystick_index);
|
||||
}
|
||||
|
||||
if (sdl_gamecontroller) {
|
||||
SetBattery(joystick->identifier, GetBatteryLevel(joystick_index));
|
||||
if (SDL_GameControllerHasSensor(sdl_gamecontroller, SDL_SENSOR_ACCEL) == SDL_TRUE) {
|
||||
SDL_GameControllerSetSensorEnabled(sdl_gamecontroller, SDL_SENSOR_ACCEL, SDL_TRUE);
|
||||
}
|
||||
if (SDL_GameControllerHasSensor(sdl_gamecontroller, SDL_SENSOR_GYRO) == SDL_TRUE) {
|
||||
SDL_GameControllerSetSensorEnabled(sdl_gamecontroller, SDL_SENSOR_GYRO, SDL_TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SDLDriver::CloseJoystick(int joystick_index) {
|
||||
LOG_DEBUG(Input, "Controller removed with device index {}", joystick_index);
|
||||
|
||||
std::scoped_lock lock{joystick_map_mutex};
|
||||
}
|
||||
|
||||
void SDLDriver::CloseJoysticks() {
|
||||
std::scoped_lock lock{joystick_map_mutex};
|
||||
joystick_map.clear();
|
||||
}
|
||||
|
||||
void SDLDriver::UpdateControllerStatus(u32 event, int joystick_index, int index, int value) {
|
||||
const auto joystick = GetSDLJoystickBySDLID(joystick_index);
|
||||
switch (event) {
|
||||
case SDL_JOYBATTERYUPDATED:
|
||||
SetBattery(joystick->identifier, GetBatteryLevel(value));
|
||||
case SDL_JOYBUTTONUP:
|
||||
SetButton(joystick->identifier, index, false);
|
||||
break;
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
SetButton(joystick->identifier, index, true);
|
||||
break;
|
||||
case SDL_JOYHATMOTION:
|
||||
SetHatButton(joystick->identifier, index, value);
|
||||
break;
|
||||
case SDL_JOYAXISMOTION:
|
||||
SetAxis(joystick->identifier, index, value / 32767.0f);
|
||||
break;
|
||||
case SDL_CONTROLLERSENSORUPDATE:
|
||||
SetMotion(joystick->identifier, 0, GetMotion(joystick_index));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bool SDLDriver::IsStickInverted(const Common::ParamPackage& params) {
|
||||
if (!params.Has("guid") || !params.Has("port")) {
|
||||
return false;
|
||||
|
@ -166,7 +223,6 @@ Common::Input::VibrationError SDLDriver::SetVibration(
|
|||
return Common::Input::VibrationError::None;
|
||||
}
|
||||
|
||||
|
||||
void SDLDriver::SendVibrations() {
|
||||
std::vector<VibrationRequest> filtered_vibrations{};
|
||||
while (!vibration_queue.Empty()) {
|
||||
|
|
|
@ -57,16 +57,29 @@ private:
|
|||
Common::Input::VibrationStatus vibration;
|
||||
};
|
||||
|
||||
struct JoystickID {
|
||||
int sdl_index;
|
||||
bool has_rumble;
|
||||
PadIdentifier identifier;
|
||||
};
|
||||
|
||||
std::shared_ptr<JoystickID> GetSDLJoystickBySDLID(SDL_JoystickID sdl_id);
|
||||
|
||||
void InitJoystick(int joystick_index);
|
||||
void CloseJoystick(SDL_Joystick* sdl_joystick);
|
||||
void CloseJoystick(int joystick_index);
|
||||
|
||||
/// Needs to be called before SDL_QuitSubSystem.
|
||||
void CloseJoysticks();
|
||||
|
||||
void UpdateControllerStatus(u32 event, int joystick_index, int index, int value);
|
||||
|
||||
Common::Input::BatteryLevel GetBatteryLevel(int value);
|
||||
|
||||
/// Takes all vibrations from the queue and sends the command to the controller
|
||||
void SendVibrations();
|
||||
|
||||
/// Map of GUID of a list of corresponding virtual Joysticks
|
||||
std::unordered_map<Common::UUID, std::vector<std::shared_ptr<JoystickID>>> joystick_map;
|
||||
std::mutex joystick_map_mutex;
|
||||
|
||||
std::atomic<bool> initialized = false;
|
||||
|
|
Loading…
Reference in New Issue