From b59672542da9fdda674a9c1cd50eb0fe2f33c07a Mon Sep 17 00:00:00 2001 From: stephena Date: Thu, 8 Jul 2010 16:32:32 +0000 Subject: [PATCH] Further improvements to accessing the UI with joystick axes and hats. The event mapping for such events is now done on the release of the axis/hat, and not on the first press. This should fix the remaining problems with sensitivity, as the user must explicit press and then release the axis/hat, with all other events occurring the meantime being ignored. Fixed bug in continuous events for axes/hats; event that represent 'off' should not be continuously sent. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2063 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba --- src/gui/DialogContainer.cxx | 4 +- src/gui/EventMappingWidget.cxx | 68 +++++++++++++++++++++++++++------- src/gui/EventMappingWidget.hxx | 7 ++++ 3 files changed, 63 insertions(+), 16 deletions(-) diff --git a/src/gui/DialogContainer.cxx b/src/gui/DialogContainer.cxx index 0a9bdd63f..bd8eec36a 100644 --- a/src/gui/DialogContainer.cxx +++ b/src/gui/DialogContainer.cxx @@ -298,7 +298,7 @@ void DialogContainer::handleJoyAxisEvent(int stick, int axis, int value) { myCurrentAxisDown.stick = myCurrentAxisDown.axis = -1; } - else + else if(value != 0) // never repeat the 'off' event { // Now account for repeated axis events (press and hold) myCurrentAxisDown.stick = stick; @@ -320,7 +320,7 @@ void DialogContainer::handleJoyHatEvent(int stick, int hat, JoyHat value) { myCurrentHatDown.stick = myCurrentHatDown.hat = -1; } - else + else if(value != EVENT_HATCENTER) // never repeat the 'center' direction { // Now account for repeated hat events (press and hold) myCurrentHatDown.stick = stick; diff --git a/src/gui/EventMappingWidget.cxx b/src/gui/EventMappingWidget.cxx index 6a06c66e1..601373917 100644 --- a/src/gui/EventMappingWidget.cxx +++ b/src/gui/EventMappingWidget.cxx @@ -124,6 +124,9 @@ void EventMappingWidget::startRemapping() // Set the flags for the next event that arrives myRemapStatus = true; + // Reset all previous events for determining correct axis/hat values + myLastStick = myLastAxis = myLastHat = myLastValue = -1; + // Disable all other widgets while in remap mode, except enable 'Cancel' myActionsList->setEnabled(false); myMapButton->setEnabled(false); @@ -163,6 +166,9 @@ void EventMappingWidget::stopRemapping() // Turn off remap mode myRemapStatus = false; + // Reset all previous events for determining correct axis/hat values + myLastStick = myLastAxis = myLastHat = myLastValue = -1; + // And re-enable all the widgets myActionsList->setEnabled(true); myMapButton->setEnabled(false); @@ -226,35 +232,69 @@ void EventMappingWidget::handleJoyDown(int stick, int button) void EventMappingWidget::handleJoyAxis(int stick, int axis, int value) { // Remap joystick axes in remap mode + // There are two phases to detection: + // First, detect an axis 'on' event + // Then, detect the same axis 'off' event if(myRemapStatus && myActionSelected >= 0) { - Event::Type event = - instance().eventHandler().eventAtIndex(myActionSelected, myEventMode); - if(instance().eventHandler().addJoyAxisMapping(event, myEventMode, - stick, axis, value)) - stopRemapping(); + // Detect the first axis event that represents 'on' + if(myLastStick == -1 && myLastAxis == -1 && value != 0) + { + myLastStick = stick; + myLastAxis = axis; + myLastValue = value; + } + // Detect the first axis event that matches a previously set + // stick and axis, but turns the axis 'off' + else if(myLastStick == stick && axis == myLastAxis && value == 0) + { + value = myLastValue; + + Event::Type event = + instance().eventHandler().eventAtIndex(myActionSelected, myEventMode); + if(instance().eventHandler().addJoyAxisMapping(event, myEventMode, + stick, axis, value)) + stopRemapping(); + } } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool EventMappingWidget::handleJoyHat(int stick, int hat, int value) { - bool result = false; - // Remap joystick hats in remap mode + // There are two phases to detection: + // First, detect a hat direction event + // Then, detect the same hat 'center' event if(myRemapStatus && myActionSelected >= 0) { - Event::Type event = - instance().eventHandler().eventAtIndex(myActionSelected, myEventMode); - if(instance().eventHandler().addJoyHatMapping(event, myEventMode, - stick, hat, value)) + // Detect the first hat event that represents a valid direction + if(myLastStick == -1 && myLastHat == -1 && value != EVENT_HATCENTER) { - stopRemapping(); - result = true; + myLastStick = stick; + myLastHat = hat; + myLastValue = value; + + return true; + } + // Detect the first hat event that matches a previously set + // stick and hat, but centers the hat + else if(myLastStick == stick && hat == myLastHat && value == EVENT_HATCENTER) + { + value = myLastValue; + + Event::Type event = + instance().eventHandler().eventAtIndex(myActionSelected, myEventMode); + if(instance().eventHandler().addJoyHatMapping(event, myEventMode, + stick, hat, value)) + { + stopRemapping(); + return true; + } } } - return result; + return false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/gui/EventMappingWidget.hxx b/src/gui/EventMappingWidget.hxx index b814313bf..643d42b11 100644 --- a/src/gui/EventMappingWidget.hxx +++ b/src/gui/EventMappingWidget.hxx @@ -91,6 +91,13 @@ class EventMappingWidget : public Widget, public CommandSender // In this mode, the next event received is remapped to some action bool myRemapStatus; + // Joystick axes and hats can be more problematic that ordinary buttons + // or keys, in that there can be 'drift' in the values + // Therefore, we map these events when they've been 'released', rather + // than on their first occurrence (aka, when they're 'pressed') + // As a result, we need to keep track of their old values + int myLastStick, myLastAxis, myLastHat, myLastValue; + bool myFirstTime; };