improve controller remapping

stop input repeats during remapping
This commit is contained in:
Thomas Jentzsch 2019-08-10 13:56:32 +02:00
parent 2c07c2918a
commit ce10108660
7 changed files with 47 additions and 17 deletions

View File

@ -165,6 +165,8 @@ class Dialog : public GuiObject
void setSize(uInt32 w, uInt32 h, uInt32 max_w, uInt32 max_h);
void positionAt(uInt32 pos);
virtual bool repeatEnabled() { return true; }
private:
void buildCurrentFocusList(int tabID = -1);
bool handleNavEvent(Event::Type e);

View File

@ -280,11 +280,11 @@ void DialogContainer::handleJoyBtnEvent(int stick, int button, bool pressed)
// Send the event to the dialog box on the top of the stack
Dialog* activeDialog = myDialogStack.top();
if(pressed)
if(pressed && myButtonRepeatTime < myTime) // prevent pending repeats after enabling repeat again
{
myCurrentButtonDown.stick = stick;
myCurrentButtonDown.button = button;
myButtonRepeatTime = myTime + kRepeatInitialDelay;
myButtonRepeatTime = myTime + (activeDialog->repeatEnabled() ? kRepeatInitialDelay : kRepeatNone);
activeDialog->handleJoyDown(stick, button);
}
@ -292,8 +292,10 @@ void DialogContainer::handleJoyBtnEvent(int stick, int button, bool pressed)
{
// Only stop firing events if it's the current button
if(stick == myCurrentButtonDown.stick)
{
myCurrentButtonDown.stick = myCurrentButtonDown.button = -1;
myButtonRepeatTime = 0;
}
activeDialog->handleJoyUp(stick, button);
}
}
@ -304,22 +306,26 @@ void DialogContainer::handleJoyAxisEvent(int stick, int axis, int value, int but
if(myDialogStack.empty())
return;
// Send the event to the dialog box on the top of the stack
Dialog* activeDialog = myDialogStack.top();
// Only stop firing events if it's the current stick
if(myCurrentAxisDown.stick == stick && value == 0)
{
cerr << "handleJoyAxisEvent 0" << endl;
myCurrentAxisDown.stick = myCurrentAxisDown.axis = -1;
myAxisRepeatTime = 0;
}
else if(value != 0) // never repeat the 'off' event
else if(value != 0 && myAxisRepeatTime < myTime) // never repeat the 'off' event; prevent pending repeats after enabling repeat again
{
cerr << "handleJoyAxisEvent repeat" << endl;
// Now account for repeated axis events (press and hold)
myCurrentAxisDown.stick = stick;
myCurrentAxisDown.axis = axis;
myCurrentAxisDown.value = value;
myAxisRepeatTime = myTime + kRepeatInitialDelay;
myAxisRepeatTime = myTime + (activeDialog->repeatEnabled() ? kRepeatInitialDelay : kRepeatNone);
}
myDialogStack.top()->handleJoyAxis(stick, axis, value, button);
activeDialog->handleJoyAxis(stick, axis, value, button);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -328,20 +334,25 @@ void DialogContainer::handleJoyHatEvent(int stick, int hat, JoyHat value, int bu
if(myDialogStack.empty())
return;
// Send the event to the dialog box on the top of the stack
Dialog* activeDialog = myDialogStack.top();
// Only stop firing events if it's the current stick
if(myCurrentHatDown.stick == stick && value == JoyHat::CENTER)
{
myCurrentHatDown.stick = myCurrentHatDown.hat = -1;
myHatRepeatTime = 0;
}
else if(value != JoyHat::CENTER) // never repeat the 'center' direction
else if(value != JoyHat::CENTER && myHatRepeatTime < myTime) // never repeat the 'center' direction; prevent pending repeats after enabling repeat again
{
// Now account for repeated hat events (press and hold)
myCurrentHatDown.stick = stick;
myCurrentHatDown.hat = hat;
myCurrentHatDown.value = value;
myHatRepeatTime = myTime + kRepeatInitialDelay;
myHatRepeatTime = myTime + (activeDialog->repeatEnabled() ? kRepeatInitialDelay : kRepeatNone);
//myHatRepeatTime = myTime + kRepeatInitialDelay;
}
myDialogStack.top()->handleJoyHat(stick, hat, value, button);
activeDialog->handleJoyHat(stick, hat, value, button);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -176,7 +176,8 @@ class DialogContainer
enum {
kDoubleClickDelay = 500,
kRepeatInitialDelay = 400,
kRepeatSustainDelay = 50
kRepeatSustainDelay = 50,
kRepeatNone = 1 << 24 // loooong
};
// Indicates the most current time (in milliseconds) as set by updateTime()

View File

@ -270,7 +270,6 @@ bool EventMappingWidget::handleKeyDown(StellaKey key, StellaMod mod)
myLastKey = key;
}
myMod |= mod;
cerr << myMod << ", " << myLastKey << " | " << mod << ", " << key << endl;
}
return true;
}
@ -329,9 +328,15 @@ void EventMappingWidget::handleJoyUp(int stick, int button)
Event::Type event = eh.eventAtIndex(myActionSelected, myEventMode);
cerr << "remap button stop" << endl;
// This maps solo button presses only
if (eh.addJoyMapping(event, myEventMode, stick, button))
stopRemapping();
// map either button/hat, solo button or button/axis combinations
if(myLastHat != -1)
{
if(eh.addJoyHatMapping(event, myEventMode, stick, button, myLastHat, JoyHat(myLastValue)))
stopRemapping();
}
else
if (eh.addJoyMapping(event, myEventMode, stick, button, JoyAxis(myLastAxis), myLastValue))
stopRemapping();
}
}
}
@ -349,7 +354,7 @@ void EventMappingWidget::handleJoyAxis(int stick, int axis, int value, int butto
// Detect the first axis event that represents 'on'
if((myLastStick == -1 || myLastStick == stick) && myLastAxis == -1 && value != 0)
{
cerr << "remap start" << endl;
cerr << "remap axis start" << endl;
myLastStick = stick;
myLastAxis = axis;
myLastValue = value;
@ -361,7 +366,7 @@ void EventMappingWidget::handleJoyAxis(int stick, int axis, int value, int butto
EventHandler& eh = instance().eventHandler();
Event::Type event = eh.eventAtIndex(myActionSelected, myEventMode);
cerr << "remap stop" << endl;
cerr << "remap axis stop" << endl;
if (eh.addJoyMapping(event, myEventMode, stick, myLastButton, JoyAxis(axis), myLastValue))
stopRemapping();
}

View File

@ -33,7 +33,6 @@ class InputDialog;
#include "Command.hxx"
#include "bspf.hxx"
class EventMappingWidget : public Widget, public CommandSender
{
friend class InputDialog;
@ -74,6 +73,8 @@ class EventMappingWidget : public Widget, public CommandSender
void resetRemapping();
void stopRemapping();
bool isRemapping() { return myRemapStatus; }
void drawKeyMapping();
void enableButtons(bool state);

View File

@ -444,6 +444,12 @@ void InputDialog::setDefaults()
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool InputDialog::repeatEnabled()
{
return !myEmulEventMapper->isRemapping() && !myMenuEventMapper->isRemapping();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void InputDialog::handleKeyDown(StellaKey key, StellaMod mod)
{

View File

@ -42,6 +42,10 @@ class InputDialog : public Dialog
const GUI::Font& font, int max_w, int max_h);
virtual ~InputDialog();
protected:
// disable repeat during and directly after mapping events
bool repeatEnabled() override;
private:
void handleKeyDown(StellaKey key, StellaMod mod) override;
void handleKeyUp(StellaKey key, StellaMod mod) override;