mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-25 15:45:38 +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;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
Input comp;
|
||||
|
|
|
@ -142,6 +142,7 @@ public:
|
|||
// Returns true if there is an Input mapped to this name, false otherwise.
|
||||
// Writes Input mapped to this name to result if true.
|
||||
bool getInputByName(const std::string& name, Input* result);
|
||||
int getInputIDByName(const std::string& name);
|
||||
|
||||
void loadFromXML(pugi::xml_node& root);
|
||||
void writeToXML(pugi::xml_node& parent);
|
||||
|
|
|
@ -142,7 +142,7 @@ void InputManager::removeJoystickByJoystickID(SDL_JoystickID joyId)
|
|||
mJoysticks.erase(joyIt);
|
||||
}
|
||||
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())
|
||||
return;
|
||||
|
||||
for (auto iter = mJoysticks.cbegin(); iter != mJoysticks.cend(); iter++)
|
||||
SDL_JoystickClose(iter->second);
|
||||
for (auto it = mJoysticks.cbegin(); it != mJoysticks.cend(); it++)
|
||||
SDL_JoystickClose(it->second);
|
||||
mJoysticks.clear();
|
||||
|
||||
for (auto iter = mInputConfigs.cbegin(); iter != mInputConfigs.cend(); iter++)
|
||||
delete iter->second;
|
||||
for (auto it = mInputConfigs.cbegin(); it != mInputConfigs.cend(); it++)
|
||||
delete it->second;
|
||||
mInputConfigs.clear();
|
||||
|
||||
for (auto iter = mPrevAxisValues.cbegin(); iter != mPrevAxisValues.cend(); iter++)
|
||||
delete[] iter->second;
|
||||
for (auto it = mPrevAxisValues.cbegin(); it != mPrevAxisValues.cend(); it++)
|
||||
delete[] it->second;
|
||||
mPrevAxisValues.clear();
|
||||
|
||||
if (mKeyboardInputConfig != nullptr) {
|
||||
|
@ -191,11 +191,11 @@ int InputManager::getButtonCountByDevice(SDL_JoystickID id)
|
|||
if (id == DEVICE_KEYBOARD)
|
||||
return 120; // It's a lot, okay.
|
||||
else if (id == DEVICE_CEC)
|
||||
#ifdef HAVE_CECLIB
|
||||
#ifdef HAVE_CECLIB
|
||||
return CEC::CEC_USER_CONTROL_CODE_MAX;
|
||||
#else // HAVE_LIBCEF
|
||||
#else // HAVE_LIBCEF
|
||||
return 0;
|
||||
#endif // HAVE_CECLIB
|
||||
#endif // HAVE_CECLIB
|
||||
else
|
||||
return SDL_JoystickNumButtons(mJoysticks[id]);
|
||||
}
|
||||
|
@ -213,26 +213,40 @@ InputConfig* InputManager::getInputConfigByDevice(int device)
|
|||
bool InputManager::parseEvent(const SDL_Event& ev, Window* window)
|
||||
{
|
||||
bool causedEvent = false;
|
||||
int32_t axisValue;
|
||||
|
||||
switch (ev.type) {
|
||||
case SDL_JOYAXISMOTION:
|
||||
// If it switched boundaries.
|
||||
if ((abs(ev.jaxis.value) > DEADZONE) !=
|
||||
axisValue = ev.jaxis.value;
|
||||
// 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)) {
|
||||
int normValue;
|
||||
if (abs(ev.jaxis.value) <= DEADZONE)
|
||||
if (abs(axisValue) <= DEADZONE) {
|
||||
normValue = 0;
|
||||
else
|
||||
if (ev.jaxis.value > 0)
|
||||
}
|
||||
else {
|
||||
if (axisValue > 0)
|
||||
normValue = 1;
|
||||
else
|
||||
normValue = -1;
|
||||
}
|
||||
|
||||
window->input(getInputConfigByDevice(ev.jaxis.which), Input(ev.jaxis.which,
|
||||
TYPE_AXIS, ev.jaxis.axis, normValue, false));
|
||||
causedEvent = true;
|
||||
}
|
||||
|
||||
mPrevAxisValues[ev.jaxis.which][ev.jaxis.axis] = ev.jaxis.value;
|
||||
mPrevAxisValues[ev.jaxis.which][ev.jaxis.axis] = axisValue;
|
||||
return causedEvent;
|
||||
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
|
|
|
@ -380,26 +380,35 @@ bool GuiInputConfig::filterTrigger(Input input, InputConfig* config, int inputId
|
|||
#if defined(__linux__)
|
||||
// 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.
|
||||
|
||||
if ((
|
||||
// Match PlayStation joystick with 6 axes only.
|
||||
strstr(config->getDeviceName().c_str(), "PLAYSTATION") != nullptr ||
|
||||
strstr(config->getDeviceName().c_str(), "PS3 Ga") != nullptr ||
|
||||
strstr(config->getDeviceName().c_str(), "PS(R) Ga") != nullptr ||
|
||||
// BigBen kid's PS3 gamepad 146b:0902, matched on SDL GUID because its name "Bigben
|
||||
// Interactive Bigben Game Pad" may be too generic.
|
||||
strcmp(config->getDeviceGUIDString().c_str(), "030000006b1400000209000011010000") == 0)
|
||||
&& InputManager::getInstance()->getAxisCountByDevice(config->getDeviceId()) == 6) {
|
||||
// Digital triggers are unwanted.
|
||||
if (input.type == TYPE_BUTTON && (input.id == 6 || input.id == 7)) {
|
||||
mHoldingInput = false;
|
||||
return true;
|
||||
// This is relevant mostly for Sony Dual Shock controllers.
|
||||
if (InputManager::getInstance()->getAxisCountByDevice(config->getDeviceId()) == 6) {
|
||||
if (config->getDeviceName().find("PLAYSTATION") != std::string::npos ||
|
||||
config->getDeviceName().find("PS3 Ga") != std::string::npos ||
|
||||
config->getDeviceName().find("PS(R) Ga") != std::string::npos ||
|
||||
config->getDeviceName().find("PS4 Controller") != std::string::npos ||
|
||||
config->getDeviceName().find("Sony Interactive") != std::string::npos ||
|
||||
// BigBen kid's PS3 gamepad 146b:0902, matched on SDL GUID because its name
|
||||
// "Bigben Interactive Bigben Game Pad" may be too generic.
|
||||
config->getDeviceGUIDString().find("030000006b1400000209000011010000")
|
||||
!= std::string::npos ) {
|
||||
// Remove digital trigger events.
|
||||
if (input.type == TYPE_BUTTON && (input.id == 6 || input.id == 7)) {
|
||||
mHoldingInput = false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Ignore negative pole for axes 2/5 only when triggers are being configured.
|
||||
if (input.type == TYPE_AXIS && (input.id == 2 || input.id == 5)) {
|
||||
if (strstr(GUI_INPUT_CONFIG_LIST[inputId].name, "Trigger") != nullptr) {
|
||||
// Ignore negative poles when triggers are being configured.
|
||||
// This is not a good solution as it's hardcoded to input 2 and 5 (Xbox controllers) and
|
||||
// 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)
|
||||
mSkipAxis = true;
|
||||
else if (input.value == -1)
|
||||
|
@ -410,11 +419,10 @@ bool GuiInputConfig::filterTrigger(Input input, InputConfig* config, int inputId
|
|||
return true;
|
||||
}
|
||||
}
|
||||
#else
|
||||
(void)input;
|
||||
(void)config;
|
||||
(void)inputId;
|
||||
#endif
|
||||
|
||||
// (void)input;
|
||||
// (void)config;
|
||||
// (void)inputId;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue