From 044e1aa151f52630041dba76958635b88bbe5daf Mon Sep 17 00:00:00 2001 From: stephena Date: Tue, 3 Aug 2010 21:04:58 +0000 Subject: [PATCH] Some cleanups to the event mapping UI and associated functionality: 1) Added a 'Reset' button to the UI, which resets (to defaults) the currently selected item. This is more fine-grained than the actual 'Defaults' button, which resets *all* events. 2) Rearranged some buttons and resized UI. There is now a main 'Defaults' button on the bottom of the dialog, which applies to the currently selected tab. This also allows to set defaults for Virtual Devs, which didn't have such functionality previously. 3) Added a 'Combo' button to the Emulation events tab. It doesn't do anything yet, but eventually will allow to assign events to the 'combo' events. ContextMenu/PopupWidget now supports the scroll button on a mouse when in scroll mode. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2084 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba --- src/emucore/EventHandler.cxx | 240 ++++++++++++++++++--------------- src/emucore/EventHandler.hxx | 13 +- src/emucore/OSystem.cxx | 125 ++++++++++------- src/emucore/OSystem.hxx | 15 ++- src/gui/ContextMenu.cxx | 15 ++- src/gui/ContextMenu.hxx | 1 + src/gui/EventMappingWidget.cxx | 106 ++++++++++----- src/gui/EventMappingWidget.hxx | 24 ++-- src/gui/InputDialog.cxx | 62 ++++++++- src/gui/InputDialog.hxx | 3 +- src/gui/OptionsDialog.cxx | 2 +- 11 files changed, 399 insertions(+), 207 deletions(-) diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index 4e97c07e6..613a2546d 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -1247,6 +1247,10 @@ void EventHandler::setActionMappings(EventMode mode) #else prepend = "Cmd Q"; #endif + else if(event == Event::UINavNext) + prepend = "TAB"; + else if(event == Event::UINavPrev) + prepend = "Shift-TAB"; // else if ... if(key == "") @@ -1278,8 +1282,8 @@ void EventHandler::setKeymap() } else { - setDefaultKeymap(kEmulationMode); - setDefaultKeymap(kMenuMode); + setDefaultKeymap(Event::NoType, kEmulationMode); + setDefaultKeymap(Event::NoType, kMenuMode); } } @@ -1301,8 +1305,8 @@ void EventHandler::setJoymap() } else { - setDefaultJoymap(kEmulationMode); - setDefaultJoymap(kMenuMode); + setDefaultJoymap(Event::NoType, kEmulationMode); + setDefaultJoymap(Event::NoType, kMenuMode); } #endif } @@ -1326,8 +1330,8 @@ void EventHandler::setJoyAxisMap() } else { - setDefaultJoyAxisMap(kEmulationMode); - setDefaultJoyAxisMap(kMenuMode); + setDefaultJoyAxisMap(Event::NoType, kEmulationMode); + setDefaultJoyAxisMap(Event::NoType, kMenuMode); } #endif } @@ -1351,8 +1355,8 @@ void EventHandler::setJoyHatMap() } else { - setDefaultJoyHatMap(kEmulationMode); - setDefaultJoyHatMap(kMenuMode); + setDefaultJoyHatMap(Event::NoType, kEmulationMode); + setDefaultJoyHatMap(Event::NoType, kMenuMode); } #endif } @@ -1547,104 +1551,115 @@ void EventHandler::eraseMapping(Event::Type event, EventMode mode) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EventHandler::setDefaultMapping(EventMode mode) +void EventHandler::setDefaultMapping(Event::Type event, EventMode mode) { - setDefaultKeymap(mode); - setDefaultJoymap(mode); - setDefaultJoyAxisMap(mode); - setDefaultJoyHatMap(mode); + setDefaultKeymap(event, mode); + setDefaultJoymap(event, mode); + setDefaultJoyAxisMap(event, mode); + setDefaultJoyHatMap(event, mode); setActionMappings(mode); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EventHandler::setDefaultKeymap(EventMode mode) +void EventHandler::setDefaultKeymap(Event::Type event, EventMode mode) { - // Erase all mappings - for(int i = 0; i < SDLK_LAST; ++i) - myKeyTable[i][mode] = Event::NoType; +#define SET_DEFAULT_KEY(sdk_key, sdk_mode, sdk_event, sdk_cmp_event) \ + if(eraseAll || sdk_cmp_event == sdk_event) \ + myKeyTable[sdk_key][sdk_mode] = sdk_event; + + // If event is 'NoType', erase and reset all mappings + // Otherwise, only reset the given event + bool eraseAll = (event == Event::NoType); + if(eraseAll) + { + // Erase all mappings + for(int i = 0; i < SDLK_LAST; ++i) + myKeyTable[i][mode] = Event::NoType; + } switch(mode) { case kEmulationMode: - myKeyTable[ SDLK_1 ][mode] = Event::KeyboardZero1; - myKeyTable[ SDLK_2 ][mode] = Event::KeyboardZero2; - myKeyTable[ SDLK_3 ][mode] = Event::KeyboardZero3; - myKeyTable[ SDLK_q ][mode] = Event::KeyboardZero4; - myKeyTable[ SDLK_w ][mode] = Event::KeyboardZero5; - myKeyTable[ SDLK_e ][mode] = Event::KeyboardZero6; - myKeyTable[ SDLK_a ][mode] = Event::KeyboardZero7; - myKeyTable[ SDLK_s ][mode] = Event::KeyboardZero8; - myKeyTable[ SDLK_d ][mode] = Event::KeyboardZero9; - myKeyTable[ SDLK_z ][mode] = Event::KeyboardZeroStar; - myKeyTable[ SDLK_x ][mode] = Event::KeyboardZero0; - myKeyTable[ SDLK_c ][mode] = Event::KeyboardZeroPound; + SET_DEFAULT_KEY(SDLK_1, mode, Event::KeyboardZero1, event); + SET_DEFAULT_KEY(SDLK_2, mode, Event::KeyboardZero2, event); + SET_DEFAULT_KEY(SDLK_3, mode, Event::KeyboardZero3, event); + SET_DEFAULT_KEY(SDLK_q, mode, Event::KeyboardZero4, event); + SET_DEFAULT_KEY(SDLK_w, mode, Event::KeyboardZero5, event); + SET_DEFAULT_KEY(SDLK_e, mode, Event::KeyboardZero6, event); + SET_DEFAULT_KEY(SDLK_a, mode, Event::KeyboardZero7, event); + SET_DEFAULT_KEY(SDLK_s, mode, Event::KeyboardZero8, event); + SET_DEFAULT_KEY(SDLK_d, mode, Event::KeyboardZero9, event); + SET_DEFAULT_KEY(SDLK_z, mode, Event::KeyboardZeroStar, event); + SET_DEFAULT_KEY(SDLK_x, mode, Event::KeyboardZero0, event); + SET_DEFAULT_KEY(SDLK_c, mode, Event::KeyboardZeroPound, event); - myKeyTable[ SDLK_8 ][mode] = Event::KeyboardOne1; - myKeyTable[ SDLK_9 ][mode] = Event::KeyboardOne2; - myKeyTable[ SDLK_0 ][mode] = Event::KeyboardOne3; - myKeyTable[ SDLK_i ][mode] = Event::KeyboardOne4; - myKeyTable[ SDLK_o ][mode] = Event::KeyboardOne5; - myKeyTable[ SDLK_p ][mode] = Event::KeyboardOne6; - myKeyTable[ SDLK_k ][mode] = Event::KeyboardOne7; - myKeyTable[ SDLK_l ][mode] = Event::KeyboardOne8; - myKeyTable[ SDLK_SEMICOLON ][mode] = Event::KeyboardOne9; - myKeyTable[ SDLK_COMMA ][mode] = Event::KeyboardOneStar; - myKeyTable[ SDLK_PERIOD ][mode] = Event::KeyboardOne0; - myKeyTable[ SDLK_SLASH ][mode] = Event::KeyboardOnePound; + SET_DEFAULT_KEY(SDLK_8, mode, Event::KeyboardOne1, event); + SET_DEFAULT_KEY(SDLK_9, mode, Event::KeyboardOne2, event); + SET_DEFAULT_KEY(SDLK_0, mode, Event::KeyboardOne3, event); + SET_DEFAULT_KEY(SDLK_i, mode, Event::KeyboardOne4, event); + SET_DEFAULT_KEY(SDLK_o, mode, Event::KeyboardOne5, event); + SET_DEFAULT_KEY(SDLK_p, mode, Event::KeyboardOne6, event); + SET_DEFAULT_KEY(SDLK_k, mode, Event::KeyboardOne7, event); + SET_DEFAULT_KEY(SDLK_l, mode, Event::KeyboardOne8, event); + SET_DEFAULT_KEY(SDLK_SEMICOLON, mode, Event::KeyboardOne9, event); + SET_DEFAULT_KEY(SDLK_COMMA, mode, Event::KeyboardOneStar, event); + SET_DEFAULT_KEY(SDLK_PERIOD, mode, Event::KeyboardOne0, event); + SET_DEFAULT_KEY(SDLK_SLASH, mode, Event::KeyboardOnePound, event); - myKeyTable[ SDLK_UP ][mode] = Event::JoystickZeroUp; - myKeyTable[ SDLK_DOWN ][mode] = Event::JoystickZeroDown; - myKeyTable[ SDLK_LEFT ][mode] = Event::JoystickZeroLeft; - myKeyTable[ SDLK_RIGHT ][mode] = Event::JoystickZeroRight; - myKeyTable[ SDLK_SPACE ][mode] = Event::JoystickZeroFire1; - myKeyTable[ SDLK_LCTRL ][mode] = Event::JoystickZeroFire1; - myKeyTable[ SDLK_4 ][mode] = Event::JoystickZeroFire2; - myKeyTable[ SDLK_5 ][mode] = Event::JoystickZeroFire3; + SET_DEFAULT_KEY(SDLK_UP, mode, Event::JoystickZeroUp, event); + SET_DEFAULT_KEY(SDLK_DOWN, mode, Event::JoystickZeroDown, event); + SET_DEFAULT_KEY(SDLK_LEFT, mode, Event::JoystickZeroLeft, event); + SET_DEFAULT_KEY(SDLK_RIGHT, mode, Event::JoystickZeroRight, event); + SET_DEFAULT_KEY(SDLK_SPACE, mode, Event::JoystickZeroFire1, event); + SET_DEFAULT_KEY(SDLK_LCTRL, mode, Event::JoystickZeroFire1, event); + SET_DEFAULT_KEY(SDLK_4, mode, Event::JoystickZeroFire2, event); + SET_DEFAULT_KEY(SDLK_5, mode, Event::JoystickZeroFire3, event); - myKeyTable[ SDLK_y ][mode] = Event::JoystickOneUp; - myKeyTable[ SDLK_h ][mode] = Event::JoystickOneDown; - myKeyTable[ SDLK_g ][mode] = Event::JoystickOneLeft; - myKeyTable[ SDLK_j ][mode] = Event::JoystickOneRight; - myKeyTable[ SDLK_f ][mode] = Event::JoystickOneFire1; - myKeyTable[ SDLK_6 ][mode] = Event::JoystickOneFire2; - myKeyTable[ SDLK_7 ][mode] = Event::JoystickOneFire3; + SET_DEFAULT_KEY(SDLK_y, mode, Event::JoystickOneUp, event); + SET_DEFAULT_KEY(SDLK_h, mode, Event::JoystickOneDown, event); + SET_DEFAULT_KEY(SDLK_g, mode, Event::JoystickOneLeft, event); + SET_DEFAULT_KEY(SDLK_j, mode, Event::JoystickOneRight, event); + SET_DEFAULT_KEY(SDLK_f, mode, Event::JoystickOneFire1, event); + SET_DEFAULT_KEY(SDLK_6, mode, Event::JoystickOneFire2, event); + SET_DEFAULT_KEY(SDLK_7, mode, Event::JoystickOneFire3, event); - myKeyTable[ SDLK_F1 ][mode] = Event::ConsoleSelect; - myKeyTable[ SDLK_F2 ][mode] = Event::ConsoleReset; - myKeyTable[ SDLK_F3 ][mode] = Event::ConsoleColor; - myKeyTable[ SDLK_F4 ][mode] = Event::ConsoleBlackWhite; - myKeyTable[ SDLK_F5 ][mode] = Event::ConsoleLeftDifficultyA; - myKeyTable[ SDLK_F6 ][mode] = Event::ConsoleLeftDifficultyB; - myKeyTable[ SDLK_F7 ][mode] = Event::ConsoleRightDifficultyA; - myKeyTable[ SDLK_F8 ][mode] = Event::ConsoleRightDifficultyB; - myKeyTable[ SDLK_F9 ][mode] = Event::SaveState; - myKeyTable[ SDLK_F10 ][mode] = Event::ChangeState; - myKeyTable[ SDLK_F11 ][mode] = Event::LoadState; - myKeyTable[ SDLK_F12 ][mode] = Event::TakeSnapshot; - myKeyTable[ SDLK_BACKSPACE ][mode] = Event::Fry; - myKeyTable[ SDLK_PAUSE ][mode] = Event::PauseMode; - myKeyTable[ SDLK_TAB ][mode] = Event::MenuMode; - myKeyTable[ SDLK_BACKSLASH ][mode] = Event::CmdMenuMode; - myKeyTable[ SDLK_BACKQUOTE ][mode] = Event::DebuggerMode; - myKeyTable[ SDLK_ESCAPE ][mode] = Event::LauncherMode; + + SET_DEFAULT_KEY(SDLK_F1, mode, Event::ConsoleSelect, event); + SET_DEFAULT_KEY(SDLK_F2, mode, Event::ConsoleReset, event); + SET_DEFAULT_KEY(SDLK_F3, mode, Event::ConsoleColor, event); + SET_DEFAULT_KEY(SDLK_F4, mode, Event::ConsoleBlackWhite, event); + SET_DEFAULT_KEY(SDLK_F5, mode, Event::ConsoleLeftDifficultyA, event); + SET_DEFAULT_KEY(SDLK_F6, mode, Event::ConsoleLeftDifficultyB, event); + SET_DEFAULT_KEY(SDLK_F7, mode, Event::ConsoleRightDifficultyA, event); + SET_DEFAULT_KEY(SDLK_F8, mode, Event::ConsoleRightDifficultyB, event); + SET_DEFAULT_KEY(SDLK_F9, mode, Event::SaveState, event); + SET_DEFAULT_KEY(SDLK_F10, mode, Event::ChangeState, event); + SET_DEFAULT_KEY(SDLK_F11, mode, Event::LoadState, event); + SET_DEFAULT_KEY(SDLK_F12, mode, Event::TakeSnapshot, event); + SET_DEFAULT_KEY(SDLK_BACKSPACE, mode, Event::Fry, event); + SET_DEFAULT_KEY(SDLK_PAUSE, mode, Event::PauseMode, event); + SET_DEFAULT_KEY(SDLK_TAB, mode, Event::MenuMode, event); + SET_DEFAULT_KEY(SDLK_BACKSLASH, mode, Event::CmdMenuMode, event); + SET_DEFAULT_KEY(SDLK_BACKQUOTE, mode, Event::DebuggerMode, event); + SET_DEFAULT_KEY(SDLK_ESCAPE, mode, Event::LauncherMode, event); break; case kMenuMode: - myKeyTable[ SDLK_UP ][mode] = Event::UIUp; - myKeyTable[ SDLK_DOWN ][mode] = Event::UIDown; - myKeyTable[ SDLK_LEFT ][mode] = Event::UILeft; - myKeyTable[ SDLK_RIGHT ][mode] = Event::UIRight; + SET_DEFAULT_KEY(SDLK_UP, mode, Event::UIUp, event); + SET_DEFAULT_KEY(SDLK_DOWN, mode, Event::UIDown, event); + SET_DEFAULT_KEY(SDLK_LEFT, mode, Event::UILeft, event); + SET_DEFAULT_KEY(SDLK_RIGHT, mode, Event::UIRight, event); - myKeyTable[ SDLK_HOME ][mode] = Event::UIHome; - myKeyTable[ SDLK_END ][mode] = Event::UIEnd; - myKeyTable[ SDLK_PAGEUP ][mode] = Event::UIPgUp; - myKeyTable[ SDLK_PAGEDOWN ][mode] = Event::UIPgDown; + SET_DEFAULT_KEY(SDLK_HOME, mode, Event::UIHome, event); + SET_DEFAULT_KEY(SDLK_END, mode, Event::UIEnd, event); + SET_DEFAULT_KEY(SDLK_PAGEUP, mode, Event::UIPgUp, event); + SET_DEFAULT_KEY(SDLK_PAGEDOWN, mode, Event::UIPgDown, event); - myKeyTable[ SDLK_RETURN ][mode] = Event::UISelect; - myKeyTable[ SDLK_ESCAPE ][mode] = Event::UICancel; + SET_DEFAULT_KEY(SDLK_RETURN, mode, Event::UISelect, event); + SET_DEFAULT_KEY(SDLK_ESCAPE, mode, Event::UICancel, event); - myKeyTable[ SDLK_BACKSPACE ][mode] = Event::UIPrevDir; + SET_DEFAULT_KEY(SDLK_BACKSPACE, mode, Event::UIPrevDir, event); break; default: @@ -1656,40 +1671,55 @@ void EventHandler::setDefaultKeymap(EventMode mode) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EventHandler::setDefaultJoymap(EventMode mode) +void EventHandler::setDefaultJoymap(Event::Type event, EventMode mode) { - // Erase all mappings - for(int i = 0; i < kNumJoysticks; ++i) - for(int j = 0; j < kNumJoyButtons; ++j) - myJoyTable[i][j][mode] = Event::NoType; + // If event is 'NoType', erase and reset all mappings + // Otherwise, only reset the given event + if(event == Event::NoType) + { + // Erase all mappings + for(int i = 0; i < kNumJoysticks; ++i) + for(int j = 0; j < kNumJoyButtons; ++j) + myJoyTable[i][j][mode] = Event::NoType; + } - myOSystem->setDefaultJoymap(); + myOSystem->setDefaultJoymap(event, mode); saveJoyMapping(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EventHandler::setDefaultJoyAxisMap(EventMode mode) +void EventHandler::setDefaultJoyAxisMap(Event::Type event, EventMode mode) { - // Erase all mappings - for(int i = 0; i < kNumJoysticks; ++i) - for(int j = 0; j < kNumJoyAxis; ++j) - for(int k = 0; k < 2; ++k) - myJoyAxisTable[i][j][k][mode] = Event::NoType; + // If event is 'NoType', erase and reset all mappings + // Otherwise, only reset the given event + if(event == Event::NoType) + { + // Erase all mappings + for(int i = 0; i < kNumJoysticks; ++i) + for(int j = 0; j < kNumJoyAxis; ++j) + for(int k = 0; k < 2; ++k) + myJoyAxisTable[i][j][k][mode] = Event::NoType; + } - myOSystem->setDefaultJoyAxisMap(); + myOSystem->setDefaultJoyAxisMap(event, mode); saveJoyAxisMapping(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EventHandler::setDefaultJoyHatMap(EventMode mode) +void EventHandler::setDefaultJoyHatMap(Event::Type event, EventMode mode) { - // Erase all mappings - for(int i = 0; i < kNumJoysticks; ++i) - for(int j = 0; j < kNumJoyHats; ++j) - for(int k = 0; k < 4; ++k) - myJoyHatTable[i][j][k][mode] = Event::NoType; + // If event is 'NoType', erase and reset all mappings + // Otherwise, only reset the given event + if(event == Event::NoType) + { + // Erase all mappings + for(int i = 0; i < kNumJoysticks; ++i) + for(int j = 0; j < kNumJoyHats; ++j) + for(int k = 0; k < 4; ++k) + myJoyHatTable[i][j][k][mode] = Event::NoType; + } - myOSystem->setDefaultJoyHatMap(); + myOSystem->setDefaultJoyHatMap(event, mode); saveJoyHatMapping(); } diff --git a/src/emucore/EventHandler.hxx b/src/emucore/EventHandler.hxx index 97214dbf3..2ecf2e417 100644 --- a/src/emucore/EventHandler.hxx +++ b/src/emucore/EventHandler.hxx @@ -304,7 +304,7 @@ class EventHandler /** Erase the specified mapping - @event The event for which we erase all mappings + @param event The event for which we erase all mappings @param mode The mode where this event is active */ void eraseMapping(Event::Type event, EventMode mode); @@ -312,9 +312,10 @@ class EventHandler /** Resets the event mappings to default values + @param event The event which to (re)set (Event::NoType resets all) @param mode The mode for which the defaults are set */ - void setDefaultMapping(EventMode mode); + void setDefaultMapping(Event::Type event, EventMode mode); /** Sets the combo event mappings to those in the 'combomap' setting @@ -356,10 +357,10 @@ class EventHandler void setJoymap(); void setJoyAxisMap(); void setJoyHatMap(); - void setDefaultKeymap(EventMode mode); - void setDefaultJoymap(EventMode mode); - void setDefaultJoyAxisMap(EventMode mode); - void setDefaultJoyHatMap(EventMode mode); + void setDefaultKeymap(Event::Type, EventMode mode); + void setDefaultJoymap(Event::Type, EventMode mode); + void setDefaultJoyAxisMap(Event::Type, EventMode mode); + void setDefaultJoyHatMap(Event::Type, EventMode mode); void saveKeyMapping(); void saveJoyMapping(); void saveJoyAxisMapping(); diff --git a/src/emucore/OSystem.cxx b/src/emucore/OSystem.cxx index 4f1f18f93..35ca04c42 100644 --- a/src/emucore/OSystem.cxx +++ b/src/emucore/OSystem.cxx @@ -862,67 +862,100 @@ void OSystem::resetLoopTiming() } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void OSystem::setDefaultJoymap() +void OSystem::setDefaultJoymap(Event::Type event, EventMode mode) { - EventMode mode; +#define SET_DEFAULT_BTN(sdb_event, sdb_mode, sdb_stick, sdb_button, sdb_cmp_event) \ + if(eraseAll || sdb_cmp_event == sdb_event) \ + myEventHandler->setDefaultJoyMapping(sdb_event, sdb_mode, sdb_stick, sdb_button); - mode = kEmulationMode; // Default emulation events - // Left joystick (assume joystick zero, button zero) - myEventHandler->setDefaultJoyMapping(Event::JoystickZeroFire1, mode, 0, 0); - // Right joystick (assume joystick one, button zero) - myEventHandler->setDefaultJoyMapping(Event::JoystickOneFire1, mode, 1, 0); + bool eraseAll = (event == Event::NoType); + switch(mode) + { + case kEmulationMode: // Default emulation events + // Left joystick (assume joystick zero, button zero) + SET_DEFAULT_BTN(Event::JoystickZeroFire1, mode, 0, 0, event); + // Right joystick (assume joystick one, button zero) + SET_DEFAULT_BTN(Event::JoystickOneFire1, mode, 1, 0, event); + break; - mode = kMenuMode; // Default menu/UI events - // Left joystick (assume joystick zero, button zero) - myEventHandler->setDefaultJoyMapping(Event::UISelect, mode, 0, 0); - // Right joystick (assume joystick one, button zero) - myEventHandler->setDefaultJoyMapping(Event::UISelect, mode, 1, 0); + case kMenuMode: // Default menu/UI events + // Left joystick (assume joystick zero, button zero) + SET_DEFAULT_BTN(Event::UISelect, mode, 0, 0, event); + // Right joystick (assume joystick one, button zero) + SET_DEFAULT_BTN(Event::UISelect, mode, 1, 0, event); + break; + + default: + break; + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void OSystem::setDefaultJoyAxisMap() +void OSystem::setDefaultJoyAxisMap(Event::Type event, EventMode mode) { - EventMode mode; +#define SET_DEFAULT_AXIS(sda_event, sda_mode, sda_stick, sda_axis, sda_val, sda_cmp_event) \ + if(eraseAll || sda_cmp_event == sda_event) \ + myEventHandler->setDefaultJoyAxisMapping(sda_event, sda_mode, sda_stick, sda_axis, sda_val); - mode = kEmulationMode; // Default emulation events - // Left joystick left/right directions (assume joystick zero) - myEventHandler->setDefaultJoyAxisMapping(Event::JoystickZeroLeft, mode, 0, 0, 0); - myEventHandler->setDefaultJoyAxisMapping(Event::JoystickZeroRight, mode, 0, 0, 1); - // Left joystick up/down directions (assume joystick zero) - myEventHandler->setDefaultJoyAxisMapping(Event::JoystickZeroUp, mode, 0, 1, 0); - myEventHandler->setDefaultJoyAxisMapping(Event::JoystickZeroDown, mode, 0, 1, 1); - // Right joystick left/right directions (assume joystick one) - myEventHandler->setDefaultJoyAxisMapping(Event::JoystickOneLeft, mode, 1, 0, 0); - myEventHandler->setDefaultJoyAxisMapping(Event::JoystickOneRight, mode, 1, 0, 1); - // Right joystick left/right directions (assume joystick one) - myEventHandler->setDefaultJoyAxisMapping(Event::JoystickOneUp, mode, 1, 1, 0); - myEventHandler->setDefaultJoyAxisMapping(Event::JoystickOneDown, mode, 1, 1, 1); + bool eraseAll = (event == Event::NoType); + switch(mode) + { + case kEmulationMode: // Default emulation events + // Left joystick left/right directions (assume joystick zero) + SET_DEFAULT_AXIS(Event::JoystickZeroLeft, mode, 0, 0, 0, event); + SET_DEFAULT_AXIS(Event::JoystickZeroRight, mode, 0, 0, 1, event); + // Left joystick up/down directions (assume joystick zero) + SET_DEFAULT_AXIS(Event::JoystickZeroUp, mode, 0, 1, 0, event); + SET_DEFAULT_AXIS(Event::JoystickZeroDown, mode, 0, 1, 1, event); + // Right joystick left/right directions (assume joystick one) + SET_DEFAULT_AXIS(Event::JoystickOneLeft, mode, 1, 0, 0, event); + SET_DEFAULT_AXIS(Event::JoystickOneRight, mode, 1, 0, 1, event); + // Right joystick left/right directions (assume joystick one) + SET_DEFAULT_AXIS(Event::JoystickOneUp, mode, 1, 1, 0, event); + SET_DEFAULT_AXIS(Event::JoystickOneDown, mode, 1, 1, 1, event); + break; - mode = kMenuMode; // Default menu/UI events - myEventHandler->setDefaultJoyAxisMapping(Event::UILeft, mode, 0, 0, 0); - myEventHandler->setDefaultJoyAxisMapping(Event::UIRight, mode, 0, 0, 1); - myEventHandler->setDefaultJoyAxisMapping(Event::UIUp, mode, 0, 1, 0); - myEventHandler->setDefaultJoyAxisMapping(Event::UIDown, mode, 0, 1, 1); + case kMenuMode: // Default menu/UI events + SET_DEFAULT_AXIS(Event::UILeft, mode, 0, 0, 0, event); + SET_DEFAULT_AXIS(Event::UIRight, mode, 0, 0, 1, event); + SET_DEFAULT_AXIS(Event::UIUp, mode, 0, 1, 0, event); + SET_DEFAULT_AXIS(Event::UIDown, mode, 0, 1, 1, event); + break; + + default: + break; + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void OSystem::setDefaultJoyHatMap() +void OSystem::setDefaultJoyHatMap(Event::Type event, EventMode mode) { - EventMode mode; +#define SET_DEFAULT_HAT(sdh_event, sdh_mode, sdh_stick, sdh_hat, sdh_dir, sdh_cmp_event) \ + if(eraseAll || sdh_cmp_event == sdh_event) \ + myEventHandler->setDefaultJoyHatMapping(sdh_event, sdh_mode, sdh_stick, sdh_hat, sdh_dir); - mode = kEmulationMode; // Default emulation events - // Left joystick left/right directions (assume joystick zero and hat 0) - myEventHandler->setDefaultJoyHatMapping(Event::JoystickZeroLeft, mode, 0, 0, EVENT_HATLEFT); - myEventHandler->setDefaultJoyHatMapping(Event::JoystickZeroRight, mode, 0, 0, EVENT_HATRIGHT); - // Left joystick up/down directions (assume joystick zero and hat 0) - myEventHandler->setDefaultJoyHatMapping(Event::JoystickZeroUp, mode, 0, 0, EVENT_HATUP); - myEventHandler->setDefaultJoyHatMapping(Event::JoystickZeroDown, mode, 0, 0, EVENT_HATDOWN); + bool eraseAll = (event == Event::NoType); + switch(mode) + { + case kEmulationMode: // Default emulation events + // Left joystick left/right directions (assume joystick zero and hat 0) + SET_DEFAULT_HAT(Event::JoystickZeroLeft, mode, 0, 0, EVENT_HATLEFT, event); + SET_DEFAULT_HAT(Event::JoystickZeroRight, mode, 0, 0, EVENT_HATRIGHT, event); + // Left joystick up/down directions (assume joystick zero and hat 0) + SET_DEFAULT_HAT(Event::JoystickZeroUp, mode, 0, 0, EVENT_HATUP, event); + SET_DEFAULT_HAT(Event::JoystickZeroDown, mode, 0, 0, EVENT_HATDOWN, event); + break; - mode = kMenuMode; // Default menu/UI events - myEventHandler->setDefaultJoyHatMapping(Event::UILeft, mode, 0, 0, EVENT_HATLEFT); - myEventHandler->setDefaultJoyHatMapping(Event::UIRight, mode, 0, 0, EVENT_HATRIGHT); - myEventHandler->setDefaultJoyHatMapping(Event::UIUp, mode, 0, 0, EVENT_HATUP); - myEventHandler->setDefaultJoyHatMapping(Event::UIDown, mode, 0, 0, EVENT_HATDOWN); + case kMenuMode: // Default menu/UI events + SET_DEFAULT_HAT(Event::UILeft, mode, 0, 0, EVENT_HATLEFT, event); + SET_DEFAULT_HAT(Event::UIRight, mode, 0, 0, EVENT_HATRIGHT, event); + SET_DEFAULT_HAT(Event::UIUp, mode, 0, 0, EVENT_HATUP, event); + SET_DEFAULT_HAT(Event::UIDown, mode, 0, 0, EVENT_HATDOWN, event); + break; + + default: + break; + } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/OSystem.hxx b/src/emucore/OSystem.hxx index 7ccd2295e..40ca3bb45 100644 --- a/src/emucore/OSystem.hxx +++ b/src/emucore/OSystem.hxx @@ -403,20 +403,29 @@ class OSystem /** This method determines the default mapping of joystick buttons to Stella events for a specific system/platform. + + @param event The event which to (re)set (Event::NoType resets all) + @param mode The mode for which the defaults are set */ - virtual void setDefaultJoymap(); + virtual void setDefaultJoymap(Event::Type event, EventMode mode); /** This method determines the default mapping of joystick axis to Stella events for a specific system/platform. + + @param event The event which to (re)set (Event::NoType resets all) + @param mode The mode for which the defaults are set */ - virtual void setDefaultJoyAxisMap(); + virtual void setDefaultJoyAxisMap(Event::Type event, EventMode mode); /** This method determines the default mapping of joystick hats to Stella events for a specific system/platform. + + @param event The event which to (re)set (Event::NoType resets all) + @param mode The mode for which the defaults are set */ - virtual void setDefaultJoyHatMap(); + virtual void setDefaultJoyHatMap(Event::Type event, EventMode mode); /** This method creates events from platform-specific hardware. diff --git a/src/gui/ContextMenu.cxx b/src/gui/ContextMenu.cxx index 8d21fe8c4..c8c4cab6a 100644 --- a/src/gui/ContextMenu.cxx +++ b/src/gui/ContextMenu.cxx @@ -111,7 +111,7 @@ void ContextMenu::recalc(const GUI::Rect& image) { // Now is the time to adjust the height // If it's higher than the screen, we need to scroll through - int maxentries = BSPF_min(16, (image.height() - 4) / _rowHeight); + int maxentries = BSPF_min(18, (image.height() - 4) / _rowHeight); if((int)_entries.size() > maxentries) { // We show two less than the max, so we have room for two scroll buttons @@ -228,6 +228,19 @@ bool ContextMenu::handleMouseClicks(int x, int y, int button) return true; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void ContextMenu::handleMouseWheel(int x, int y, int direction) +{ + // Wheel events are only relevant in scroll mode + if(_showScroll) + { + if(direction < 0) + return scrollUp(); + else if(direction > 0) + return scrollDown(); + } +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void ContextMenu::handleKeyDown(int ascii, int keycode, int modifiers) { diff --git a/src/gui/ContextMenu.hxx b/src/gui/ContextMenu.hxx index 527fef045..bd053777d 100644 --- a/src/gui/ContextMenu.hxx +++ b/src/gui/ContextMenu.hxx @@ -77,6 +77,7 @@ class ContextMenu : public Dialog, public CommandSender void handleMouseDown(int x, int y, int button, int clickCount); void handleMouseMoved(int x, int y, int button); bool handleMouseClicks(int x, int y, int button); + void handleMouseWheel(int x, int y, int direction); void handleKeyDown(int ascii, int keycode, int modifiers); // Scroll through entries with arrow keys etc void handleJoyDown(int stick, int button); void handleJoyAxis(int stick, int axis, int value); diff --git a/src/gui/EventMappingWidget.cxx b/src/gui/EventMappingWidget.cxx index 601373917..04d36f977 100644 --- a/src/gui/EventMappingWidget.cxx +++ b/src/gui/EventMappingWidget.cxx @@ -27,6 +27,7 @@ #include "EventHandler.hxx" #include "Event.hxx" #include "OSystem.hxx" +#include "EditTextWidget.hxx" #include "StringListWidget.hxx" #include "Widget.hxx" @@ -64,12 +65,7 @@ EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font, "Map", kStartMapCmd); myMapButton->setTarget(this); addFocusWidget(myMapButton); - ypos += lineHeight + 10; - myEraseButton = new ButtonWidget(boss, font, xpos, ypos, - buttonWidth, buttonHeight, - "Erase", kEraseCmd); - myEraseButton->setTarget(this); - addFocusWidget(myEraseButton); + ypos += lineHeight + 10; myCancelMapButton = new ButtonWidget(boss, font, xpos, ypos, buttonWidth, buttonHeight, @@ -77,18 +73,42 @@ EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font, myCancelMapButton->setTarget(this); myCancelMapButton->clearFlags(WIDGET_ENABLED); addFocusWidget(myCancelMapButton); - ypos += lineHeight + 30; - myDefaultsButton = new ButtonWidget(boss, font, xpos, ypos, - buttonWidth, buttonHeight, - "Defaults", kDefaultsCmd); - myDefaultsButton->setTarget(this); - addFocusWidget(myDefaultsButton); + + ypos += lineHeight + 20; + myEraseButton = new ButtonWidget(boss, font, xpos, ypos, + buttonWidth, buttonHeight, + "Erase", kEraseCmd); + myEraseButton->setTarget(this); + addFocusWidget(myEraseButton); + + ypos += lineHeight + 10; + myResetButton = new ButtonWidget(boss, font, xpos, ypos, + buttonWidth, buttonHeight, + "Reset", kResetCmd); + myResetButton->setTarget(this); + addFocusWidget(myResetButton); + + if(mode == kEmulationMode) + { + ypos += lineHeight + 20; + myComboButton = new ButtonWidget(boss, font, xpos, ypos, + buttonWidth, buttonHeight, + "Combo", kComboCmd); + myComboButton->setTarget(this); + addFocusWidget(myComboButton); + } // Show message for currently selected event - xpos = 10; ypos = 5 + myActionsList->getHeight() + 3; - myKeyMapping = new StaticTextWidget(boss, font, xpos, ypos, _w - 20, fontHeight, - "Action: ", kTextAlignLeft); - myKeyMapping->setFlags(WIDGET_CLEARBG); + xpos = 10; ypos = 5 + myActionsList->getHeight() + 5; + StaticTextWidget* t; + t = new StaticTextWidget(boss, font, xpos, ypos, font.getStringWidth("Action:"), + fontHeight, "Action:", kTextAlignLeft); + t->setFlags(WIDGET_CLEARBG); + + myKeyMapping = new EditTextWidget(boss, font, xpos + t->getWidth() + 5, ypos, + _w - xpos - t->getWidth() - 15, lineHeight, ""); + myKeyMapping->setEditable(false); + myKeyMapping->clearFlags(WIDGET_RETAIN_FOCUS); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -107,7 +127,8 @@ void EventMappingWidget::loadConfig() // Make sure remapping is turned off, just in case the user didn't properly // exit last time - stopRemapping(); + if(myRemapStatus) + stopRemapping(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -115,6 +136,13 @@ void EventMappingWidget::saveConfig() { } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EventMappingWidget::setDefaults() +{ + instance().eventHandler().setDefaultMapping(Event::NoType, myEventMode); + drawKeyMapping(); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EventMappingWidget::startRemapping() { @@ -131,16 +159,16 @@ void EventMappingWidget::startRemapping() myActionsList->setEnabled(false); myMapButton->setEnabled(false); myEraseButton->setEnabled(false); - myDefaultsButton->setEnabled(false); myCancelMapButton->setEnabled(true); + myResetButton->setEnabled(false); // And show a message indicating which key is being remapped ostringstream buf; buf << "Select action for '" << instance().eventHandler().actionAtIndex(myActionSelected, myEventMode) - << "' event"; + << "' event"; myKeyMapping->setTextColor(kTextColorEm); - myKeyMapping->setLabel(buf.str()); + myKeyMapping->setEditString(buf.str()); // Make sure that this widget receives all raw data, before any // pre-processing occurs @@ -160,6 +188,19 @@ void EventMappingWidget::eraseRemapping() drawKeyMapping(); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EventMappingWidget::resetRemapping() +{ + if(myActionSelected < 0) + return; + + Event::Type event = + instance().eventHandler().eventAtIndex(myActionSelected, myEventMode); + instance().eventHandler().setDefaultMapping(event, myEventMode); + + drawKeyMapping(); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EventMappingWidget::stopRemapping() { @@ -173,8 +214,8 @@ void EventMappingWidget::stopRemapping() myActionsList->setEnabled(true); myMapButton->setEnabled(false); myEraseButton->setEnabled(false); - myDefaultsButton->setEnabled(true); myCancelMapButton->setEnabled(false); + myResetButton->setEnabled(true); // Make sure the list widget is in a known state if(myActionSelected >= 0) @@ -194,10 +235,9 @@ void EventMappingWidget::drawKeyMapping() if(myActionSelected >= 0) { ostringstream buf; - buf << "Action: " - << instance().eventHandler().keyAtIndex(myActionSelected, myEventMode); + buf << instance().eventHandler().keyAtIndex(myActionSelected, myEventMode); myKeyMapping->setTextColor(kTextColor); - myKeyMapping->setLabel(buf.str()); + myKeyMapping->setEditString(buf.str()); } } @@ -311,6 +351,7 @@ void EventMappingWidget::handleCommand(CommandSender* sender, int cmd, myMapButton->setEnabled(true); myEraseButton->setEnabled(true); myCancelMapButton->setEnabled(false); + myResetButton->setEnabled(true); } break; @@ -328,17 +369,20 @@ void EventMappingWidget::handleCommand(CommandSender* sender, int cmd, startRemapping(); break; - case kEraseCmd: - eraseRemapping(); - break; - case kStopMapCmd: stopRemapping(); break; - case kDefaultsCmd: - instance().eventHandler().setDefaultMapping(myEventMode); - drawKeyMapping(); + case kEraseCmd: + eraseRemapping(); + break; + + case kResetCmd: + resetRemapping(); + break; + + case kComboCmd: +cerr << "combo\n"; break; } } diff --git a/src/gui/EventMappingWidget.hxx b/src/gui/EventMappingWidget.hxx index 643d42b11..1a1783590 100644 --- a/src/gui/EventMappingWidget.hxx +++ b/src/gui/EventMappingWidget.hxx @@ -26,6 +26,7 @@ class DialogContainer; class CommandSender; class ButtonWidget; +class EditTextWidget; class StaticTextWidget; class StringListWidget; class PopUpWidget; @@ -54,25 +55,22 @@ class EventMappingWidget : public Widget, public CommandSender bool remapMode() { return myRemapStatus; } - protected: - ButtonWidget* myMapButton; - ButtonWidget* myCancelMapButton; - ButtonWidget* myEraseButton; - ButtonWidget* myDefaultsButton; - StringListWidget* myActionsList; - StaticTextWidget* myKeyMapping; + void setDefaults(); private: enum { kStartMapCmd = 'map ', + kStopMapCmd = 'smap', kEraseCmd = 'eras', - kStopMapCmd = 'smap' + kResetCmd = 'rest', + kComboCmd = 'cmbo' }; virtual void handleCommand(CommandSender* sender, int cmd, int data, int id); void startRemapping(); void eraseRemapping(); + void resetRemapping(); void stopRemapping(); void loadConfig(); void saveConfig(); @@ -80,6 +78,14 @@ class EventMappingWidget : public Widget, public CommandSender void drawKeyMapping(); private: + ButtonWidget* myMapButton; + ButtonWidget* myCancelMapButton; + ButtonWidget* myEraseButton; + ButtonWidget* myResetButton; + ButtonWidget* myComboButton; + StringListWidget* myActionsList; + EditTextWidget* myKeyMapping; + // Since this widget can be used for different collections of events, // we need to specify exactly which group of events we are remapping EventMode myEventMode; @@ -91,7 +97,7 @@ 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 + // Joystick axes and hats can be more problematic than 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') diff --git a/src/gui/InputDialog.cxx b/src/gui/InputDialog.cxx index e9607560e..97802f217 100644 --- a/src/gui/InputDialog.cxx +++ b/src/gui/InputDialog.cxx @@ -36,19 +36,20 @@ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - InputDialog::InputDialog(OSystem* osystem, DialogContainer* parent, - const GUI::Font& font) + const GUI::Font& font, int max_w, int max_h) : Dialog(osystem, parent, 0, 0, 0, 0) { const int lineHeight = font.getLineHeight(), fontWidth = font.getMaxCharWidth(), + buttonWidth = font.getStringWidth("Defaults") + 20, buttonHeight = font.getLineHeight() + 4; const int vBorder = 4; int xpos, ypos, tabID; WidgetArray wid; // Set real dimensions - _w = 42 * fontWidth + 10; - _h = 12 * (lineHeight + 4) + 10; + _w = BSPF_min(48 * fontWidth + 10, max_w); + _h = BSPF_min(12 * (lineHeight + 4) + 10, max_h); // The tab widget xpos = 2; ypos = vBorder; @@ -84,8 +85,12 @@ InputDialog::InputDialog(OSystem* osystem, DialogContainer* parent, myTab->activateTabs(); myTab->setActiveTab(0); - // Add OK and Cancel buttons + // Add Defaults, OK and Cancel buttons wid.clear(); + ButtonWidget* b; + b = new ButtonWidget(this, font, 10, _h - buttonHeight - 10, + buttonWidth, buttonHeight, "Defaults", kDefaultsCmd); + wid.push_back(b); addOKCancelBGroup(wid, font); addBGroupToFocusList(wid); } @@ -241,6 +246,51 @@ void InputDialog::saveConfig() instance().eventHandler().allowAllDirections(allowall4); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void InputDialog::setDefaults() +{ + switch(myTab->getActiveTab()) + { + case 0: // Emulation events + myEmulEventMapper->setDefaults(); + break; + + case 1: // UI events + myMenuEventMapper->setDefaults(); + break; + + case 2: // Virtual devices + { + // Left & right ports + myLeftPort->setSelected("left", "left"); + myRightPort->setSelected("right", "right"); + + // Joystick deadzone + myDeadzone->setValue(0); + myDeadzoneLabel->setValue(3200); + + // Mouse/paddle enabled + myMouseEnabled->setState(true); + + // Paddle speed + myPaddleSpeed->setValue(6); + myPaddleLabel->setLabel("6"); + + // AtariVox serial port + myAVoxPort->setEditString(""); + + // Allow all 4 joystick directions + myAllowAll4->setState(false); + break; + } + + default: + break; + } + + _dirty = true; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void InputDialog::handleKeyDown(int ascii, int keycode, int modifiers) { @@ -305,6 +355,10 @@ void InputDialog::handleCommand(CommandSender* sender, int cmd, close(); break; + case kDefaultsCmd: + setDefaults(); + break; + case kLeftChanged: myRightPort->setSelected( myLeftPort->getSelected() == 1 ? 0 : 1); diff --git a/src/gui/InputDialog.hxx b/src/gui/InputDialog.hxx index d1a030d3f..3582da982 100644 --- a/src/gui/InputDialog.hxx +++ b/src/gui/InputDialog.hxx @@ -37,7 +37,7 @@ class InputDialog : public Dialog { public: InputDialog(OSystem* osystem, DialogContainer* parent, - const GUI::Font& font); + const GUI::Font& font, int max_w, int max_h); ~InputDialog(); protected: @@ -49,6 +49,7 @@ class InputDialog : public Dialog void loadConfig(); void saveConfig(); + void setDefaults(); private: void addVDeviceTab(const GUI::Font& font); diff --git a/src/gui/OptionsDialog.cxx b/src/gui/OptionsDialog.cxx index d9bb8e8c6..ad84530ec 100644 --- a/src/gui/OptionsDialog.cxx +++ b/src/gui/OptionsDialog.cxx @@ -119,7 +119,7 @@ OptionsDialog::OptionsDialog(OSystem* osystem, DialogContainer* parent, // Now create all the dialogs attached to each menu button myVideoDialog = new VideoDialog(osystem, parent, font, max_w, max_h); myAudioDialog = new AudioDialog(osystem, parent, font); - myInputDialog = new InputDialog(osystem, parent, font); + myInputDialog = new InputDialog(osystem, parent, font, max_w, max_h); myUIDialog = new UIDialog(osystem, parent, font); myFileSnapDialog = new FileSnapDialog(osystem, parent, font, boss, max_w, max_h); myRomAuditDialog = new RomAuditDialog(osystem, parent, font, max_w, max_h);