add long button press to launcher for power on options

note: currently this feels more like a hack
This commit is contained in:
Thomas Jentzsch 2019-08-13 14:06:27 +02:00
parent c143a3dcfc
commit 063308ac09
17 changed files with 110 additions and 43 deletions

View File

@ -24,30 +24,31 @@ During emulation:
Button 9 RESET Reset Button 9 RESET Reset
Inside Launcher: Inside Launcher:
Joystick Button Action Joystick Button Action
-------------------------------------------- -------------------------------------------------
Up SAVE Previous game Up SAVE Previous game
Down RESET Next game Down RESET Next game
Left LOAD Page up Left LOAD Page up
Right MODE Page down Right MODE Page down
Button 1 SKILL P1 Start selected game Button 1 SKILL P1 Start selected game
Button 2 SKILL P2 Open power-on options Button 2 or SKILL P2 Open power-on options
Button 4 COLOR,B/W Open settings hold Button 1
Button 4 COLOR,B/W Open settings
Inside a dialog: Inside a dialog:
Joystick Button Action Joystick Button Action
------------------------------------------------------ -------------------------------------------------------
Up SAVE Increase current setting Up SAVE Increase current setting
Down RESET Decrease current setting Down RESET Decrease current setting
Left LOAD Previous dialog element Left LOAD Previous dialog element
Right MODE Next dialog element Right MODE Next dialog element
Button 1 SKILL P1 Select element Button 1 SKILL P1 Select element
Button 2 SKILL P2 OK Button 2 SKILL P2 OK
Button 3 or 4:3,16:9 Previous tab Button 3 or 4:3,16:9 Previous tab
Button 1 + Left Button 1 + Left
Button 4 or FRY Next tab Button 4 or FRY Next tab
Button 1 + Right Button 1 + Right
Button 6 - Cancel Button 6 - Cancel
Note: If you have a keyboard attached via OTG all keys work as described in Note: If you have a keyboard attached via OTG all keys work as described in
the Stella User's Guide. the Stella User's Guide.

View File

@ -286,7 +286,7 @@ void ContextMenu::handleKeyDown(StellaKey key, StellaMod mod)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ContextMenu::handleJoyDown(int stick, int button) void ContextMenu::handleJoyDown(int stick, int button, bool longPress)
{ {
handleEvent(instance().eventHandler().eventForJoyButton(kMenuMode, stick, button)); handleEvent(instance().eventHandler().eventForJoyButton(kMenuMode, stick, button));
} }

View File

@ -87,7 +87,7 @@ class ContextMenu : public Dialog, public CommandSender
bool handleMouseClicks(int x, int y, MouseButton b) override; bool handleMouseClicks(int x, int y, MouseButton b) override;
void handleMouseWheel(int x, int y, int direction) override; void handleMouseWheel(int x, int y, int direction) override;
void handleKeyDown(StellaKey key, StellaMod mod) override; void handleKeyDown(StellaKey key, StellaMod mod) override;
void handleJoyDown(int stick, int button) override; void handleJoyDown(int stick, int button, bool longPress) override;
void handleJoyAxis(int stick, int axis, int value, int button) override; void handleJoyAxis(int stick, int axis, int value, int button) override;
bool handleJoyHat(int stick, int hat, JoyHat value, int button) override; bool handleJoyHat(int stick, int hat, JoyHat value, int button) override;
void handleEvent(Event::Type e); void handleEvent(Event::Type e);

View File

@ -588,7 +588,7 @@ bool Dialog::handleMouseClicks(int x, int y, MouseButton b)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Dialog::handleJoyDown(int stick, int button) void Dialog::handleJoyDown(int stick, int button, bool longPress)
{ {
Event::Type e = Event::Type e =
instance().eventHandler().eventForJoyButton(kMenuMode, stick, button); instance().eventHandler().eventForJoyButton(kMenuMode, stick, button);
@ -598,7 +598,7 @@ void Dialog::handleJoyDown(int stick, int button)
if(!handleNavEvent(e) && _focusedWidget) if(!handleNavEvent(e) && _focusedWidget)
{ {
if(_focusedWidget->wantsRaw() || e == Event::NoType) if(_focusedWidget->wantsRaw() || e == Event::NoType)
_focusedWidget->handleJoyDown(stick, button); _focusedWidget->handleJoyDown(stick, button, longPress);
else else
_focusedWidget->handleEvent(e); _focusedWidget->handleEvent(e);
} }

View File

@ -137,7 +137,7 @@ class Dialog : public GuiObject
virtual void handleMouseWheel(int x, int y, int direction); virtual void handleMouseWheel(int x, int y, int direction);
virtual void handleMouseMoved(int x, int y); virtual void handleMouseMoved(int x, int y);
virtual bool handleMouseClicks(int x, int y, MouseButton b); virtual bool handleMouseClicks(int x, int y, MouseButton b);
virtual void handleJoyDown(int stick, int button); virtual void handleJoyDown(int stick, int button, bool longPress = false);
virtual void handleJoyUp(int stick, int button); virtual void handleJoyUp(int stick, int button);
virtual void handleJoyAxis(int stick, int axis, int value, int button = JOY_CTRL_NONE); virtual void handleJoyAxis(int stick, int axis, int value, int button = JOY_CTRL_NONE);
virtual bool handleJoyHat(int stick, int hat, JoyHat value, int button = JOY_CTRL_NONE); virtual bool handleJoyHat(int stick, int hat, JoyHat value, int button = JOY_CTRL_NONE);

View File

@ -31,6 +31,7 @@ DialogContainer::DialogContainer(OSystem& osystem)
myTime(0), myTime(0),
myClickRepeatTime(0), myClickRepeatTime(0),
myButtonRepeatTime(0), myButtonRepeatTime(0),
myButtonLongPressTime(0),
myAxisRepeatTime(0), myAxisRepeatTime(0),
myHatRepeatTime(0) myHatRepeatTime(0)
{ {
@ -68,6 +69,13 @@ void DialogContainer::updateTime(uInt64 time)
myButtonRepeatTime = myTime + _REPEAT_SUSTAIN_DELAY; myButtonRepeatTime = myTime + _REPEAT_SUSTAIN_DELAY;
} }
// Joystick has been pressed long
if(myCurrentButtonDown.stick != -1 && myButtonLongPressTime < myTime)
{
activeDialog->handleJoyDown(myCurrentButtonDown.stick, myCurrentButtonDown.button, true);
myButtonLongPressTime = myButtonRepeatTime = myTime + _REPEAT_NONE;
}
// Joystick axis still pressed // Joystick axis still pressed
if(myCurrentAxisDown.stick != -1 && myAxisRepeatTime < myTime) if(myCurrentAxisDown.stick != -1 && myAxisRepeatTime < myTime)
{ {
@ -288,6 +296,7 @@ void DialogContainer::handleJoyBtnEvent(int stick, int button, bool pressed)
myCurrentButtonDown.stick = stick; myCurrentButtonDown.stick = stick;
myCurrentButtonDown.button = button; myCurrentButtonDown.button = button;
myButtonRepeatTime = myTime + (activeDialog->repeatEnabled() ? _REPEAT_INITIAL_DELAY : _REPEAT_NONE); myButtonRepeatTime = myTime + (activeDialog->repeatEnabled() ? _REPEAT_INITIAL_DELAY : _REPEAT_NONE);
myButtonLongPressTime = myTime + _LONG_PRESS_DELAY;
activeDialog->handleJoyDown(stick, button); activeDialog->handleJoyDown(stick, button);
} }
@ -297,7 +306,7 @@ void DialogContainer::handleJoyBtnEvent(int stick, int button, bool pressed)
if(stick == myCurrentButtonDown.stick) if(stick == myCurrentButtonDown.stick)
{ {
myCurrentButtonDown.stick = myCurrentButtonDown.button = -1; myCurrentButtonDown.stick = myCurrentButtonDown.button = -1;
myButtonRepeatTime = 0; myButtonRepeatTime = myButtonLongPressTime = 0;
} }
activeDialog->handleJoyUp(stick, button); activeDialog->handleJoyUp(stick, button);
} }
@ -312,6 +321,9 @@ void DialogContainer::handleJoyAxisEvent(int stick, int axis, int value, int but
// Send the event to the dialog box on the top of the stack // Send the event to the dialog box on the top of the stack
Dialog* activeDialog = myDialogStack.top(); Dialog* activeDialog = myDialogStack.top();
// Prevent long button press in button/axis combinations
myButtonLongPressTime = myTime + _REPEAT_NONE;
// Only stop firing events if it's the current stick // Only stop firing events if it's the current stick
if(myCurrentAxisDown.stick == stick && value == 0) if(myCurrentAxisDown.stick == stick && value == 0)
{ {
@ -340,6 +352,9 @@ void DialogContainer::handleJoyHatEvent(int stick, int hat, JoyHat value, int bu
// Send the event to the dialog box on the top of the stack // Send the event to the dialog box on the top of the stack
Dialog* activeDialog = myDialogStack.top(); Dialog* activeDialog = myDialogStack.top();
// Prevent long button press in button/hat combinations
myButtonLongPressTime = myTime + _REPEAT_NONE;
// Only stop firing events if it's the current stick // Only stop firing events if it's the current stick
if(myCurrentHatDown.stick == stick && value == JoyHat::CENTER) if(myCurrentHatDown.stick == stick && value == JoyHat::CENTER)
{ {

View File

@ -187,6 +187,7 @@ class DialogContainer
static uInt64 _REPEAT_INITIAL_DELAY; static uInt64 _REPEAT_INITIAL_DELAY;
static uInt64 _REPEAT_SUSTAIN_DELAY; static uInt64 _REPEAT_SUSTAIN_DELAY;
static constexpr uInt64 _REPEAT_NONE = 1 << 24; // loooong static constexpr uInt64 _REPEAT_NONE = 1 << 24; // loooong
static constexpr uInt64 _LONG_PRESS_DELAY = 1000; // 1 second
// For continuous 'mouse down' events // For continuous 'mouse down' events
struct { struct {
@ -202,6 +203,7 @@ class DialogContainer
int button; int button;
} myCurrentButtonDown; } myCurrentButtonDown;
uInt64 myButtonRepeatTime; uInt64 myButtonRepeatTime;
uInt64 myButtonLongPressTime;
// For continuous 'joy axis down' events // For continuous 'joy axis down' events
struct { struct {

View File

@ -309,7 +309,7 @@ bool EventMappingWidget::handleKeyUp(StellaKey key, StellaMod mod)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void EventMappingWidget::handleJoyDown(int stick, int button) void EventMappingWidget::handleJoyDown(int stick, int button, bool longPress)
{ {
cerr << "handleJoyDown" << endl; cerr << "handleJoyDown" << endl;
// Remap joystick buttons in remap mode // Remap joystick buttons in remap mode

View File

@ -58,7 +58,7 @@ class EventMappingWidget : public Widget, public CommandSender
bool handleKeyDown(StellaKey key, StellaMod mod) override; bool handleKeyDown(StellaKey key, StellaMod mod) override;
bool handleKeyUp(StellaKey key, StellaMod mod) override; bool handleKeyUp(StellaKey key, StellaMod mod) override;
void handleJoyDown(int stick, int button) override; void handleJoyDown(int stick, int button, bool longPress = false) override;
void handleJoyUp(int stick, int button) override; void handleJoyUp(int stick, int button) override;
void handleJoyAxis(int stick, int axis, int value, int button) override; void handleJoyAxis(int stick, int axis, int value, int button) override;
bool handleJoyHat(int stick, int hat, JoyHat value, int button) override; bool handleJoyHat(int stick, int hat, JoyHat value, int button) override;

View File

@ -121,6 +121,10 @@ void FileListWidget::handleCommand(CommandSender* sender, int cmd, int data, int
cmd = ItemActivated; cmd = ItemActivated;
break; break;
case ListWidget::kLongButtonPressCmd:
// do nothing, let boss handle this one
break;
default: default:
// If we don't know about the command, send it to the parent and exit // If we don't know about the command, send it to the parent and exit
StringListWidget::handleCommand(sender, cmd, data, id); StringListWidget::handleCommand(sender, cmd, data, id);

View File

@ -475,7 +475,7 @@ void InputDialog::handleKeyUp(StellaKey key, StellaMod mod)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void InputDialog::handleJoyDown(int stick, int button) void InputDialog::handleJoyDown(int stick, int button, bool longPress)
{ {
// Remap joystick buttons in remap mode, otherwise pass to parent dialog // Remap joystick buttons in remap mode, otherwise pass to parent dialog
if(myEmulEventMapper->remapMode()) if(myEmulEventMapper->remapMode())

View File

@ -49,7 +49,7 @@ class InputDialog : public Dialog
private: private:
void handleKeyDown(StellaKey key, StellaMod mod) override; void handleKeyDown(StellaKey key, StellaMod mod) override;
void handleKeyUp(StellaKey key, StellaMod mod) override; void handleKeyUp(StellaKey key, StellaMod mod) override;
void handleJoyDown(int stick, int button) override; void handleJoyDown(int stick, int button, bool longPress) override;
void handleJoyUp(int stick, int button) override; void handleJoyUp(int stick, int button) override;
void handleJoyAxis(int stick, int axis, int value, int button) override; void handleJoyAxis(int stick, int axis, int value, int button) override;
bool handleJoyHat(int stick, int hat, JoyHat value, int button) override; bool handleJoyHat(int stick, int hat, JoyHat value, int button) override;

View File

@ -79,9 +79,9 @@
#endif #endif
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
int x, int y, int w, int h) int x, int y, int w, int h)
: Dialog(osystem, parent, x, y, w, h), : Dialog(osystem, parent, x, y, w, h),
myStartButton(nullptr), myStartButton(nullptr),
myPrevDirButton(nullptr), myPrevDirButton(nullptr),
myOptionsButton(nullptr), myOptionsButton(nullptr),
@ -90,7 +90,8 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent,
myPattern(nullptr), myPattern(nullptr),
myAllFiles(nullptr), myAllFiles(nullptr),
myRomInfoWidget(nullptr), myRomInfoWidget(nullptr),
mySelectedItem(0) mySelectedItem(0),
myEventHandled(false)
{ {
myUseMinimalUI = instance().settings().getBool("minimal_ui"); myUseMinimalUI = instance().settings().getBool("minimal_ui");
@ -466,7 +467,7 @@ void LauncherDialog::handleKeyDown(StellaKey key, StellaMod mod)
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void LauncherDialog::handleJoyDown(int stick, int button) void LauncherDialog::handleJoyDown(int stick, int button, bool longPress)
{ {
// open power-up options and settings for 2nd and 4th button if not mapped otherwise // open power-up options and settings for 2nd and 4th button if not mapped otherwise
Event::Type e = instance().eventHandler().eventForJoyButton(kMenuMode, stick, button); Event::Type e = instance().eventHandler().eventForJoyButton(kMenuMode, stick, button);
@ -476,7 +477,19 @@ void LauncherDialog::handleJoyDown(int stick, int button)
if (button == 3 && (e == Event::Event::UITabPrev || e == Event::NoType)) if (button == 3 && (e == Event::Event::UITabPrev || e == Event::NoType))
openSettings(); openSettings();
else else
Dialog::handleJoyDown(stick, button); {
myEventHandled = false;
myList->setFlags(Widget::FLAG_WANTS_RAWDATA); // allow handling long button press
Dialog::handleJoyDown(stick, button, longPress);
}
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void LauncherDialog::handleJoyUp(int stick, int button)
{
if (!myEventHandled)
Dialog::handleJoyUp(stick, button);
myList->clearFlags(Widget::FLAG_WANTS_RAWDATA); // stop allowing to handle long button press
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -547,6 +560,11 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
updateUI(); updateUI();
break; break;
case ListWidget::kLongButtonPressCmd:
myGlobalProps->open();
myEventHandled = true;
break;
case kQuitCmd: case kQuitCmd:
close(); close();
instance().eventHandler().quit(); instance().eventHandler().quit();
@ -557,6 +575,7 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd,
FilesystemNode node(instance().settings().getString("romdir")); FilesystemNode node(instance().settings().getString("romdir"));
if(!(node.exists() && node.isDirectory())) if(!(node.exists() && node.isDirectory()))
node = FilesystemNode("~"); node = FilesystemNode("~");
myList->setDirectory(node); myList->setDirectory(node);
break; break;
} }

View File

@ -91,7 +91,8 @@ class LauncherDialog : public Dialog
void handleKeyDown(StellaKey key, StellaMod mod) override; void handleKeyDown(StellaKey key, StellaMod mod) override;
void handleMouseDown(int x, int y, MouseButton b, int clickCount) override; void handleMouseDown(int x, int y, MouseButton b, int clickCount) override;
void handleCommand(CommandSender* sender, int cmd, int data, int id) override; void handleCommand(CommandSender* sender, int cmd, int data, int id) override;
void handleJoyDown(int stick, int button) override; void handleJoyDown(int stick, int button, bool longPress) override;
void handleJoyUp(int stick, int button) override;
Event::Type getJoyAxisEvent(int stick, int axis, int value, int button) override; Event::Type getJoyAxisEvent(int stick, int axis, int value, int button) override;
void loadConfig() override; void loadConfig() override;
@ -130,6 +131,7 @@ class LauncherDialog : public Dialog
bool myShowOnlyROMs; bool myShowOnlyROMs;
bool myUseMinimalUI; bool myUseMinimalUI;
bool myEventHandled;
enum { enum {
kPrevDirCmd = 'PRVD', kPrevDirCmd = 'PRVD',

View File

@ -25,6 +25,7 @@
#include "FrameBuffer.hxx" #include "FrameBuffer.hxx"
#include "StellaKeys.hxx" #include "StellaKeys.hxx"
#include "TimerManager.hxx" #include "TimerManager.hxx"
#include "EventHandler.hxx"
#include "ListWidget.hxx" #include "ListWidget.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -323,6 +324,29 @@ bool ListWidget::handleKeyDown(StellaKey key, StellaMod mod)
return handled; return handled;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ListWidget::handleJoyDown(int stick, int button, bool longPress)
{
if (longPress)
sendCommand(ListWidget::kLongButtonPressCmd, _selectedItem, _id);
Event::Type e = _boss->instance().eventHandler().eventForJoyButton(kMenuMode, stick, button);
// handle UISelect event on button up
if(e != Event::UISelect)
handleEvent(e);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void ListWidget::handleJoyUp(int stick, int button)
{
Event::Type e = _boss->instance().eventHandler().eventForJoyButton(kMenuMode, stick, button);
// handle UISelect event on button up
if(e == Event::UISelect)
handleEvent(e);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool ListWidget::handleEvent(Event::Type e) bool ListWidget::handleEvent(Event::Type e)
{ {

View File

@ -31,6 +31,7 @@ class ListWidget : public EditableWidget
public: public:
enum { enum {
kDoubleClickedCmd = 'LIdb', // double click on item - 'data' will be item index kDoubleClickedCmd = 'LIdb', // double click on item - 'data' will be item index
kLongButtonPressCmd = 'LIlb', // long button press
kActivatedCmd = 'LIac', // item activated by return/enter - 'data' will be item index kActivatedCmd = 'LIac', // item activated by return/enter - 'data' will be item index
kDataChangedCmd = 'LIch', // item data changed - 'data' will be item index kDataChangedCmd = 'LIch', // item data changed - 'data' will be item index
kRClickedCmd = 'LIrc', // right click on item - 'data' will be item index kRClickedCmd = 'LIrc', // right click on item - 'data' will be item index
@ -71,6 +72,8 @@ class ListWidget : public EditableWidget
void handleMouseWheel(int x, int y, int direction) override; void handleMouseWheel(int x, int y, int direction) override;
bool handleText(char text) override; bool handleText(char text) override;
bool handleKeyDown(StellaKey key, StellaMod mod) override; bool handleKeyDown(StellaKey key, StellaMod mod) override;
void handleJoyDown(int stick, int button, bool longPress) override;
void handleJoyUp(int stick, int button) override;
bool handleEvent(Event::Type e) override; bool handleEvent(Event::Type e) override;
void handleCommand(CommandSender* sender, int cmd, int data, int id) override; void handleCommand(CommandSender* sender, int cmd, int data, int id) override;

View File

@ -77,7 +77,7 @@ class Widget : public GuiObject
virtual void handleMouseMoved(int x, int y) { } virtual void handleMouseMoved(int x, int y) { }
virtual void handleMouseWheel(int x, int y, int direction) { } virtual void handleMouseWheel(int x, int y, int direction) { }
virtual bool handleMouseClicks(int x, int y, MouseButton b) { return false; } virtual bool handleMouseClicks(int x, int y, MouseButton b) { return false; }
virtual void handleJoyDown(int stick, int button) { } virtual void handleJoyDown(int stick, int button, bool longPress = false) { }
virtual void handleJoyUp(int stick, int button) { } virtual void handleJoyUp(int stick, int button) { }
virtual void handleJoyAxis(int stick, int axis, int value, int button = JOY_CTRL_NONE) { } virtual void handleJoyAxis(int stick, int axis, int value, int button = JOY_CTRL_NONE) { }
virtual bool handleJoyHat(int stick, int hat, JoyHat value, int button = JOY_CTRL_NONE) { return false; } virtual bool handleJoyHat(int stick, int hat, JoyHat value, int button = JOY_CTRL_NONE) { return false; }
@ -176,7 +176,6 @@ class Widget : public GuiObject
Widget& operator=(Widget&&) = delete; Widget& operator=(Widget&&) = delete;
}; };
/* StaticTextWidget */ /* StaticTextWidget */
class StaticTextWidget : public Widget class StaticTextWidget : public Widget
{ {
@ -212,7 +211,6 @@ class StaticTextWidget : public Widget
StaticTextWidget& operator=(StaticTextWidget&&) = delete; StaticTextWidget& operator=(StaticTextWidget&&) = delete;
}; };
/* ButtonWidget */ /* ButtonWidget */
class ButtonWidget : public StaticTextWidget, public CommandSender class ButtonWidget : public StaticTextWidget, public CommandSender
{ {
@ -262,7 +260,6 @@ class ButtonWidget : public StaticTextWidget, public CommandSender
ButtonWidget& operator=(ButtonWidget&&) = delete; ButtonWidget& operator=(ButtonWidget&&) = delete;
}; };
/* CheckboxWidget */ /* CheckboxWidget */
class CheckboxWidget : public ButtonWidget class CheckboxWidget : public ButtonWidget
{ {