diff --git a/docs/R77_readme.txt b/docs/R77_readme.txt index 0de05664f..7569ea439 100644 --- a/docs/R77_readme.txt +++ b/docs/R77_readme.txt @@ -24,30 +24,31 @@ During emulation: Button 9 RESET Reset Inside Launcher: - Joystick Button Action - -------------------------------------------- - Up SAVE Previous game - Down RESET Next game - Left LOAD Page up - Right MODE Page down - Button 1 SKILL P1 Start selected game - Button 2 SKILL P2 Open power-on options - Button 4 COLOR,B/W Open settings + Joystick Button Action + ------------------------------------------------- + Up SAVE Previous game + Down RESET Next game + Left LOAD Page up + Right MODE Page down + Button 1 SKILL P1 Start selected game + Button 2 or SKILL P2 Open power-on options + hold Button 1 + Button 4 COLOR,B/W Open settings Inside a dialog: - Joystick Button Action - ------------------------------------------------------ - Up SAVE Increase current setting - Down RESET Decrease current setting - Left LOAD Previous dialog element - Right MODE Next dialog element - Button 1 SKILL P1 Select element - Button 2 SKILL P2 OK - Button 3 or 4:3,16:9 Previous tab - Button 1 + Left - Button 4 or FRY Next tab - Button 1 + Right - Button 6 - Cancel + Joystick Button Action + ------------------------------------------------------- + Up SAVE Increase current setting + Down RESET Decrease current setting + Left LOAD Previous dialog element + Right MODE Next dialog element + Button 1 SKILL P1 Select element + Button 2 SKILL P2 OK + Button 3 or 4:3,16:9 Previous tab + Button 1 + Left + Button 4 or FRY Next tab + Button 1 + Right + Button 6 - Cancel Note: If you have a keyboard attached via OTG all keys work as described in the Stella User's Guide. diff --git a/src/gui/ContextMenu.cxx b/src/gui/ContextMenu.cxx index 17811f676..21b39b8c8 100644 --- a/src/gui/ContextMenu.cxx +++ b/src/gui/ContextMenu.cxx @@ -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)); } diff --git a/src/gui/ContextMenu.hxx b/src/gui/ContextMenu.hxx index 975c3f336..90bcaa8e4 100644 --- a/src/gui/ContextMenu.hxx +++ b/src/gui/ContextMenu.hxx @@ -87,7 +87,7 @@ class ContextMenu : public Dialog, public CommandSender bool handleMouseClicks(int x, int y, MouseButton b) override; void handleMouseWheel(int x, int y, int direction) 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; bool handleJoyHat(int stick, int hat, JoyHat value, int button) override; void handleEvent(Event::Type e); diff --git a/src/gui/Dialog.cxx b/src/gui/Dialog.cxx index 6816c6922..be0b03533 100644 --- a/src/gui/Dialog.cxx +++ b/src/gui/Dialog.cxx @@ -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 = instance().eventHandler().eventForJoyButton(kMenuMode, stick, button); @@ -598,7 +598,7 @@ void Dialog::handleJoyDown(int stick, int button) if(!handleNavEvent(e) && _focusedWidget) { if(_focusedWidget->wantsRaw() || e == Event::NoType) - _focusedWidget->handleJoyDown(stick, button); + _focusedWidget->handleJoyDown(stick, button, longPress); else _focusedWidget->handleEvent(e); } diff --git a/src/gui/Dialog.hxx b/src/gui/Dialog.hxx index 25380e577..31b067c51 100644 --- a/src/gui/Dialog.hxx +++ b/src/gui/Dialog.hxx @@ -137,7 +137,7 @@ class Dialog : public GuiObject virtual void handleMouseWheel(int x, int y, int direction); virtual void handleMouseMoved(int x, int y); 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 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); diff --git a/src/gui/DialogContainer.cxx b/src/gui/DialogContainer.cxx index 6f1d36fe9..a6056bf32 100644 --- a/src/gui/DialogContainer.cxx +++ b/src/gui/DialogContainer.cxx @@ -31,6 +31,7 @@ DialogContainer::DialogContainer(OSystem& osystem) myTime(0), myClickRepeatTime(0), myButtonRepeatTime(0), + myButtonLongPressTime(0), myAxisRepeatTime(0), myHatRepeatTime(0) { @@ -68,6 +69,13 @@ void DialogContainer::updateTime(uInt64 time) 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 if(myCurrentAxisDown.stick != -1 && myAxisRepeatTime < myTime) { @@ -288,6 +296,7 @@ void DialogContainer::handleJoyBtnEvent(int stick, int button, bool pressed) myCurrentButtonDown.stick = stick; myCurrentButtonDown.button = button; myButtonRepeatTime = myTime + (activeDialog->repeatEnabled() ? _REPEAT_INITIAL_DELAY : _REPEAT_NONE); + myButtonLongPressTime = myTime + _LONG_PRESS_DELAY; activeDialog->handleJoyDown(stick, button); } @@ -297,7 +306,7 @@ void DialogContainer::handleJoyBtnEvent(int stick, int button, bool pressed) if(stick == myCurrentButtonDown.stick) { myCurrentButtonDown.stick = myCurrentButtonDown.button = -1; - myButtonRepeatTime = 0; + myButtonRepeatTime = myButtonLongPressTime = 0; } 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 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 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 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 if(myCurrentHatDown.stick == stick && value == JoyHat::CENTER) { diff --git a/src/gui/DialogContainer.hxx b/src/gui/DialogContainer.hxx index e20884481..30f234ac4 100644 --- a/src/gui/DialogContainer.hxx +++ b/src/gui/DialogContainer.hxx @@ -187,6 +187,7 @@ class DialogContainer static uInt64 _REPEAT_INITIAL_DELAY; static uInt64 _REPEAT_SUSTAIN_DELAY; static constexpr uInt64 _REPEAT_NONE = 1 << 24; // loooong + static constexpr uInt64 _LONG_PRESS_DELAY = 1000; // 1 second // For continuous 'mouse down' events struct { @@ -202,6 +203,7 @@ class DialogContainer int button; } myCurrentButtonDown; uInt64 myButtonRepeatTime; + uInt64 myButtonLongPressTime; // For continuous 'joy axis down' events struct { diff --git a/src/gui/EventMappingWidget.cxx b/src/gui/EventMappingWidget.cxx index 6bef36dec..b1a4085f8 100644 --- a/src/gui/EventMappingWidget.cxx +++ b/src/gui/EventMappingWidget.cxx @@ -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; // Remap joystick buttons in remap mode diff --git a/src/gui/EventMappingWidget.hxx b/src/gui/EventMappingWidget.hxx index 2d17a8800..051ca8a78 100644 --- a/src/gui/EventMappingWidget.hxx +++ b/src/gui/EventMappingWidget.hxx @@ -58,7 +58,7 @@ class EventMappingWidget : public Widget, public CommandSender bool handleKeyDown(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 handleJoyAxis(int stick, int axis, int value, int button) override; bool handleJoyHat(int stick, int hat, JoyHat value, int button) override; diff --git a/src/gui/FileListWidget.cxx b/src/gui/FileListWidget.cxx index 3526ae7d8..920470e89 100644 --- a/src/gui/FileListWidget.cxx +++ b/src/gui/FileListWidget.cxx @@ -121,6 +121,10 @@ void FileListWidget::handleCommand(CommandSender* sender, int cmd, int data, int cmd = ItemActivated; break; + case ListWidget::kLongButtonPressCmd: + // do nothing, let boss handle this one + break; + default: // If we don't know about the command, send it to the parent and exit StringListWidget::handleCommand(sender, cmd, data, id); diff --git a/src/gui/InputDialog.cxx b/src/gui/InputDialog.cxx index f389789f0..875caf2fe 100644 --- a/src/gui/InputDialog.cxx +++ b/src/gui/InputDialog.cxx @@ -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 if(myEmulEventMapper->remapMode()) diff --git a/src/gui/InputDialog.hxx b/src/gui/InputDialog.hxx index c2d210ab9..845a00fb5 100644 --- a/src/gui/InputDialog.hxx +++ b/src/gui/InputDialog.hxx @@ -49,7 +49,7 @@ class InputDialog : public Dialog private: void handleKeyDown(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 handleJoyAxis(int stick, int axis, int value, int button) override; bool handleJoyHat(int stick, int hat, JoyHat value, int button) override; diff --git a/src/gui/LauncherDialog.cxx b/src/gui/LauncherDialog.cxx index 637412be2..77054ba1b 100644 --- a/src/gui/LauncherDialog.cxx +++ b/src/gui/LauncherDialog.cxx @@ -79,9 +79,9 @@ #endif // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, - int x, int y, int w, int h) - : Dialog(osystem, parent, x, y, w, h), + LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, + int x, int y, int w, int h) + : Dialog(osystem, parent, x, y, w, h), myStartButton(nullptr), myPrevDirButton(nullptr), myOptionsButton(nullptr), @@ -90,7 +90,8 @@ LauncherDialog::LauncherDialog(OSystem& osystem, DialogContainer& parent, myPattern(nullptr), myAllFiles(nullptr), myRomInfoWidget(nullptr), - mySelectedItem(0) + mySelectedItem(0), + myEventHandled(false) { 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 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)) openSettings(); 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(); break; + case ListWidget::kLongButtonPressCmd: + myGlobalProps->open(); + myEventHandled = true; + break; + case kQuitCmd: close(); instance().eventHandler().quit(); @@ -557,6 +575,7 @@ void LauncherDialog::handleCommand(CommandSender* sender, int cmd, FilesystemNode node(instance().settings().getString("romdir")); if(!(node.exists() && node.isDirectory())) node = FilesystemNode("~"); + myList->setDirectory(node); break; } diff --git a/src/gui/LauncherDialog.hxx b/src/gui/LauncherDialog.hxx index 502aeb70f..6ea7e567b 100644 --- a/src/gui/LauncherDialog.hxx +++ b/src/gui/LauncherDialog.hxx @@ -91,7 +91,8 @@ class LauncherDialog : public Dialog void handleKeyDown(StellaKey key, StellaMod mod) override; void handleMouseDown(int x, int y, MouseButton b, int clickCount) 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; void loadConfig() override; @@ -130,6 +131,7 @@ class LauncherDialog : public Dialog bool myShowOnlyROMs; bool myUseMinimalUI; + bool myEventHandled; enum { kPrevDirCmd = 'PRVD', diff --git a/src/gui/ListWidget.cxx b/src/gui/ListWidget.cxx index 09a442b2b..82004107c 100644 --- a/src/gui/ListWidget.cxx +++ b/src/gui/ListWidget.cxx @@ -25,6 +25,7 @@ #include "FrameBuffer.hxx" #include "StellaKeys.hxx" #include "TimerManager.hxx" +#include "EventHandler.hxx" #include "ListWidget.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -323,6 +324,29 @@ bool ListWidget::handleKeyDown(StellaKey key, StellaMod mod) 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) { diff --git a/src/gui/ListWidget.hxx b/src/gui/ListWidget.hxx index 96c5c8480..cda1dc4da 100644 --- a/src/gui/ListWidget.hxx +++ b/src/gui/ListWidget.hxx @@ -31,6 +31,7 @@ class ListWidget : public EditableWidget public: enum { 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 kDataChangedCmd = 'LIch', // item data changed - '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; bool handleText(char text) 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; void handleCommand(CommandSender* sender, int cmd, int data, int id) override; diff --git a/src/gui/Widget.hxx b/src/gui/Widget.hxx index 969fcdc1c..8f8ba8e2b 100644 --- a/src/gui/Widget.hxx +++ b/src/gui/Widget.hxx @@ -77,7 +77,7 @@ class Widget : public GuiObject virtual void handleMouseMoved(int x, int y) { } virtual void handleMouseWheel(int x, int y, int direction) { } 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 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; } @@ -176,7 +176,6 @@ class Widget : public GuiObject Widget& operator=(Widget&&) = delete; }; - /* StaticTextWidget */ class StaticTextWidget : public Widget { @@ -212,7 +211,6 @@ class StaticTextWidget : public Widget StaticTextWidget& operator=(StaticTextWidget&&) = delete; }; - /* ButtonWidget */ class ButtonWidget : public StaticTextWidget, public CommandSender { @@ -262,7 +260,6 @@ class ButtonWidget : public StaticTextWidget, public CommandSender ButtonWidget& operator=(ButtonWidget&&) = delete; }; - /* CheckboxWidget */ class CheckboxWidget : public ButtonWidget {