mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-29 09:35:39 +00:00
Improved the trigger button handling and made it work (somehow) on Windows.
There are still some issues on Windows, especially with Dual Shock controllers, but a larger rewrite is required anyway of the input handling so it's not worthwhile trying to fix it at this time.
This commit is contained in:
parent
a90fb33cc7
commit
dc4870f543
|
@ -96,6 +96,15 @@ bool InputConfig::getInputByName(const std::string& name, Input* result)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int InputConfig::getInputIDByName(const std::string& name)
|
||||||
|
{
|
||||||
|
auto it = mNameMap.find(toLower(name));
|
||||||
|
if (it != mNameMap.cend()) {
|
||||||
|
return it->second.id;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
bool InputConfig::isMappedTo(const std::string& name, Input input)
|
bool InputConfig::isMappedTo(const std::string& name, Input input)
|
||||||
{
|
{
|
||||||
Input comp;
|
Input comp;
|
||||||
|
|
|
@ -142,6 +142,7 @@ public:
|
||||||
// Returns true if there is an Input mapped to this name, false otherwise.
|
// Returns true if there is an Input mapped to this name, false otherwise.
|
||||||
// Writes Input mapped to this name to result if true.
|
// Writes Input mapped to this name to result if true.
|
||||||
bool getInputByName(const std::string& name, Input* result);
|
bool getInputByName(const std::string& name, Input* result);
|
||||||
|
int getInputIDByName(const std::string& name);
|
||||||
|
|
||||||
void loadFromXML(pugi::xml_node& root);
|
void loadFromXML(pugi::xml_node& root);
|
||||||
void writeToXML(pugi::xml_node& parent);
|
void writeToXML(pugi::xml_node& parent);
|
||||||
|
|
|
@ -142,7 +142,7 @@ void InputManager::removeJoystickByJoystickID(SDL_JoystickID joyId)
|
||||||
mJoysticks.erase(joyIt);
|
mJoysticks.erase(joyIt);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
LOG(LogError) << "Could not find joystick to close (instance ID: " << joyId << ")";
|
LOG(LogError) << "Error - Could not find joystick to close (instance ID: " << joyId << ")";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -151,16 +151,16 @@ void InputManager::deinit()
|
||||||
if (!initialized())
|
if (!initialized())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (auto iter = mJoysticks.cbegin(); iter != mJoysticks.cend(); iter++)
|
for (auto it = mJoysticks.cbegin(); it != mJoysticks.cend(); it++)
|
||||||
SDL_JoystickClose(iter->second);
|
SDL_JoystickClose(it->second);
|
||||||
mJoysticks.clear();
|
mJoysticks.clear();
|
||||||
|
|
||||||
for (auto iter = mInputConfigs.cbegin(); iter != mInputConfigs.cend(); iter++)
|
for (auto it = mInputConfigs.cbegin(); it != mInputConfigs.cend(); it++)
|
||||||
delete iter->second;
|
delete it->second;
|
||||||
mInputConfigs.clear();
|
mInputConfigs.clear();
|
||||||
|
|
||||||
for (auto iter = mPrevAxisValues.cbegin(); iter != mPrevAxisValues.cend(); iter++)
|
for (auto it = mPrevAxisValues.cbegin(); it != mPrevAxisValues.cend(); it++)
|
||||||
delete[] iter->second;
|
delete[] it->second;
|
||||||
mPrevAxisValues.clear();
|
mPrevAxisValues.clear();
|
||||||
|
|
||||||
if (mKeyboardInputConfig != nullptr) {
|
if (mKeyboardInputConfig != nullptr) {
|
||||||
|
@ -191,11 +191,11 @@ int InputManager::getButtonCountByDevice(SDL_JoystickID id)
|
||||||
if (id == DEVICE_KEYBOARD)
|
if (id == DEVICE_KEYBOARD)
|
||||||
return 120; // It's a lot, okay.
|
return 120; // It's a lot, okay.
|
||||||
else if (id == DEVICE_CEC)
|
else if (id == DEVICE_CEC)
|
||||||
#ifdef HAVE_CECLIB
|
#ifdef HAVE_CECLIB
|
||||||
return CEC::CEC_USER_CONTROL_CODE_MAX;
|
return CEC::CEC_USER_CONTROL_CODE_MAX;
|
||||||
#else // HAVE_LIBCEF
|
#else // HAVE_LIBCEF
|
||||||
return 0;
|
return 0;
|
||||||
#endif // HAVE_CECLIB
|
#endif // HAVE_CECLIB
|
||||||
else
|
else
|
||||||
return SDL_JoystickNumButtons(mJoysticks[id]);
|
return SDL_JoystickNumButtons(mJoysticks[id]);
|
||||||
}
|
}
|
||||||
|
@ -213,26 +213,40 @@ InputConfig* InputManager::getInputConfigByDevice(int device)
|
||||||
bool InputManager::parseEvent(const SDL_Event& ev, Window* window)
|
bool InputManager::parseEvent(const SDL_Event& ev, Window* window)
|
||||||
{
|
{
|
||||||
bool causedEvent = false;
|
bool causedEvent = false;
|
||||||
|
int32_t axisValue;
|
||||||
|
|
||||||
switch (ev.type) {
|
switch (ev.type) {
|
||||||
case SDL_JOYAXISMOTION:
|
case SDL_JOYAXISMOTION:
|
||||||
// If it switched boundaries.
|
axisValue = ev.jaxis.value;
|
||||||
if ((abs(ev.jaxis.value) > DEADZONE) !=
|
// For the analog trigger buttons, convert the negative<->positive axis values to only
|
||||||
|
// positive values in order to avoid registering double inputs. This is only a
|
||||||
|
// temporary solution until ES has been updated to use the SDL GameController API.
|
||||||
|
if (ev.jaxis.axis == mInputConfigs[ev.jaxis.which]->getInputIDByName("lefttrigger") ||
|
||||||
|
ev.jaxis.axis == mInputConfigs[ev.jaxis.which]->getInputIDByName("righttrigger")) {
|
||||||
|
axisValue += 32768;
|
||||||
|
axisValue /= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if the input value switched boundaries.
|
||||||
|
if ((abs(axisValue) > DEADZONE) !=
|
||||||
(abs(mPrevAxisValues[ev.jaxis.which][ev.jaxis.axis]) > DEADZONE)) {
|
(abs(mPrevAxisValues[ev.jaxis.which][ev.jaxis.axis]) > DEADZONE)) {
|
||||||
int normValue;
|
int normValue;
|
||||||
if (abs(ev.jaxis.value) <= DEADZONE)
|
if (abs(axisValue) <= DEADZONE) {
|
||||||
normValue = 0;
|
normValue = 0;
|
||||||
else
|
}
|
||||||
if (ev.jaxis.value > 0)
|
else {
|
||||||
|
if (axisValue > 0)
|
||||||
normValue = 1;
|
normValue = 1;
|
||||||
else
|
else
|
||||||
normValue = -1;
|
normValue = -1;
|
||||||
|
}
|
||||||
|
|
||||||
window->input(getInputConfigByDevice(ev.jaxis.which), Input(ev.jaxis.which,
|
window->input(getInputConfigByDevice(ev.jaxis.which), Input(ev.jaxis.which,
|
||||||
TYPE_AXIS, ev.jaxis.axis, normValue, false));
|
TYPE_AXIS, ev.jaxis.axis, normValue, false));
|
||||||
causedEvent = true;
|
causedEvent = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
mPrevAxisValues[ev.jaxis.which][ev.jaxis.axis] = ev.jaxis.value;
|
mPrevAxisValues[ev.jaxis.which][ev.jaxis.axis] = axisValue;
|
||||||
return causedEvent;
|
return causedEvent;
|
||||||
|
|
||||||
case SDL_JOYBUTTONDOWN:
|
case SDL_JOYBUTTONDOWN:
|
||||||
|
|
|
@ -380,26 +380,35 @@ bool GuiInputConfig::filterTrigger(Input input, InputConfig* config, int inputId
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
// On Linux, some gamepads return both an analog axis and a digital button for the trigger;
|
// On Linux, some gamepads return both an analog axis and a digital button for the trigger;
|
||||||
// we want the analog axis only, so this function removes the button press event.
|
// we want the analog axis only, so this function removes the button press event.
|
||||||
|
// This is relevant mostly for Sony Dual Shock controllers.
|
||||||
if ((
|
if (InputManager::getInstance()->getAxisCountByDevice(config->getDeviceId()) == 6) {
|
||||||
// Match PlayStation joystick with 6 axes only.
|
if (config->getDeviceName().find("PLAYSTATION") != std::string::npos ||
|
||||||
strstr(config->getDeviceName().c_str(), "PLAYSTATION") != nullptr ||
|
config->getDeviceName().find("PS3 Ga") != std::string::npos ||
|
||||||
strstr(config->getDeviceName().c_str(), "PS3 Ga") != nullptr ||
|
config->getDeviceName().find("PS(R) Ga") != std::string::npos ||
|
||||||
strstr(config->getDeviceName().c_str(), "PS(R) Ga") != nullptr ||
|
config->getDeviceName().find("PS4 Controller") != std::string::npos ||
|
||||||
// BigBen kid's PS3 gamepad 146b:0902, matched on SDL GUID because its name "Bigben
|
config->getDeviceName().find("Sony Interactive") != std::string::npos ||
|
||||||
// Interactive Bigben Game Pad" may be too generic.
|
// BigBen kid's PS3 gamepad 146b:0902, matched on SDL GUID because its name
|
||||||
strcmp(config->getDeviceGUIDString().c_str(), "030000006b1400000209000011010000") == 0)
|
// "Bigben Interactive Bigben Game Pad" may be too generic.
|
||||||
&& InputManager::getInstance()->getAxisCountByDevice(config->getDeviceId()) == 6) {
|
config->getDeviceGUIDString().find("030000006b1400000209000011010000")
|
||||||
// Digital triggers are unwanted.
|
!= std::string::npos ) {
|
||||||
|
// Remove digital trigger events.
|
||||||
if (input.type == TYPE_BUTTON && (input.id == 6 || input.id == 7)) {
|
if (input.type == TYPE_BUTTON && (input.id == 6 || input.id == 7)) {
|
||||||
mHoldingInput = false;
|
mHoldingInput = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// Ignore negative pole for axes 2/5 only when triggers are being configured.
|
// Ignore negative poles when triggers are being configured.
|
||||||
if (input.type == TYPE_AXIS && (input.id == 2 || input.id == 5)) {
|
// This is not a good solution as it's hardcoded to input 2 and 5 (Xbox controllers) and
|
||||||
if (strstr(GUI_INPUT_CONFIG_LIST[inputId].name, "Trigger") != nullptr) {
|
// input 4 and 5 (Playstation Dual Shock controllers) instead of using a general detection
|
||||||
|
// for which type of axis input is used. This is also hardcoded to only work when configuring
|
||||||
|
// the trigger buttons, so it will not be possible to map trigger buttons to the shoulder
|
||||||
|
// button functions in ES for instance. It's probably necessary to update ES to use the SDL
|
||||||
|
// GameController API to fix this properly.
|
||||||
|
if (input.type == TYPE_AXIS && (input.id == 2 || input.id == 4 || input.id == 5)) {
|
||||||
|
if (std::string(GUI_INPUT_CONFIG_LIST[inputId].name).find("Trigger") != std::string::npos) {
|
||||||
if (input.value == 1)
|
if (input.value == 1)
|
||||||
mSkipAxis = true;
|
mSkipAxis = true;
|
||||||
else if (input.value == -1)
|
else if (input.value == -1)
|
||||||
|
@ -410,11 +419,10 @@ bool GuiInputConfig::filterTrigger(Input input, InputConfig* config, int inputId
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
(void)input;
|
// (void)input;
|
||||||
(void)config;
|
// (void)config;
|
||||||
(void)inputId;
|
// (void)inputId;
|
||||||
#endif
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue