From 738a9d1d2f7a9fd0a0122c8cb9b9da3cfc547113 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 6 Apr 2018 20:56:04 +0200 Subject: [PATCH 01/18] replaces controller names with mapping names TODO: handle new values --- src/gui/GameInfoDialog.cxx | 42 ++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 18 deletions(-) diff --git a/src/gui/GameInfoDialog.cxx b/src/gui/GameInfoDialog.cxx index 3c736f571..a3241432f 100644 --- a/src/gui/GameInfoDialog.cxx +++ b/src/gui/GameInfoDialog.cxx @@ -176,32 +176,38 @@ GameInfoDialog::GameInfoDialog( tabID = myTab->addTab("Controller"); ypos = vBorder; - pwidth = font.getStringWidth("Paddles_IAxis"); + pwidth = font.getStringWidth("BoosterGrip A"); myP0Label = new StaticTextWidget(myTab, font, hSpace, ypos+1, "P0 controller "); ctrls.clear(); - VarList::push_back(ctrls, "Joystick", "JOYSTICK" ); - VarList::push_back(ctrls, "Paddles", "PADDLES" ); - VarList::push_back(ctrls, "Paddles_IAxis", "PADDLES_IAXIS"); - VarList::push_back(ctrls, "Paddles_IDir", "PADDLES_IDIR" ); - VarList::push_back(ctrls, "Paddles_IAxDr", "PADDLES_IAXDR"); - VarList::push_back(ctrls, "BoosterGrip", "BOOSTERGRIP" ); - VarList::push_back(ctrls, "Driving", "DRIVING" ); - VarList::push_back(ctrls, "Keyboard", "KEYBOARD" ); - VarList::push_back(ctrls, "AmigaMouse", "AMIGAMOUSE" ); - VarList::push_back(ctrls, "AtariMouse", "ATARIMOUSE" ); - VarList::push_back(ctrls, "Trakball", "TRAKBALL" ); - VarList::push_back(ctrls, "AtariVox", "ATARIVOX" ); - VarList::push_back(ctrls, "SaveKey", "SAVEKEY" ); - VarList::push_back(ctrls, "Sega Genesis", "GENESIS" ); -// VarList::push_back(ctrls, "KidVid", "KIDVID" ); - VarList::push_back(ctrls, "MindLink", "MINDLINK" ); + VarList::push_back(ctrls, "Joystick A", "JOYSTICK_A"); + VarList::push_back(ctrls, "Joystick B", "JOYSTICK_B"); + VarList::push_back(ctrls, "Paddles A", "PADDLES_A"); + VarList::push_back(ctrls, "Paddles B", "PADDLES_B"); + //VarList::push_back(ctrls, "Paddles_IAxis", "PADDLES_IAXIS"); + //VarList::push_back(ctrls, "Paddles_IDir", "PADDLES_IDIR"); + //VarList::push_back(ctrls, "Paddles_IAxDr", "PADDLES_IAXDR"); + VarList::push_back(ctrls, "BoosterGrip A", "BOOSTERGRIP_A"); + VarList::push_back(ctrls, "BoosterGrip B", "BOOSTERGRIP_B"); + VarList::push_back(ctrls, "Driving A", "DRIVING_A"); + VarList::push_back(ctrls, "Driving B", "DRIVING_B"); + VarList::push_back(ctrls, "Keyboard A", "KEYBOARD_A"); + VarList::push_back(ctrls, "Keyboard B", "KEYBOARD_B"); + VarList::push_back(ctrls, "AmigaMouse", "AMIGAMOUSE"); + VarList::push_back(ctrls, "AtariMouse", "ATARIMOUSE"); + VarList::push_back(ctrls, "TrakBall", "TRAKBALL"); + VarList::push_back(ctrls, "AtariVox", "ATARIVOX"); + VarList::push_back(ctrls, "SaveKey", "SAVEKEY"); + VarList::push_back(ctrls, "Sega Genesis A", "GENESIS_A"); + VarList::push_back(ctrls, "Sega Genesis B", "GENESIS_B"); + // VarList::push_back(ctrls, "KidVid", "KIDVID" ); + VarList::push_back(ctrls, "MindLink", "MINDLINK"); myP0Controller = new PopUpWidget(myTab, font, myP0Label->getRight(), myP0Label->getTop()-1, pwidth, lineHeight, ctrls, "", 0, kLeftCChanged); wid.push_back(myP0Controller); ypos += lineHeight + VGAP; - pwidth = font.getStringWidth("Paddles_IAxis"); + pwidth = font.getStringWidth("BoosterGrip A"); myP1Label = new StaticTextWidget(myTab, font, hSpace, ypos+1, "P1 controller "); myP1Controller = new PopUpWidget(myTab, font, myP1Label->getRight(), myP1Label->getTop()-1, pwidth, lineHeight, ctrls, "", 0, kRightCChanged); From 62464498358873fe496a7ca746bb9933dcfbf170 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 7 Apr 2018 08:51:59 +0200 Subject: [PATCH 02/18] reordered and renamed some controller mappings --- src/gui/GameInfoDialog.cxx | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/gui/GameInfoDialog.cxx b/src/gui/GameInfoDialog.cxx index a3241432f..c4bc2cfce 100644 --- a/src/gui/GameInfoDialog.cxx +++ b/src/gui/GameInfoDialog.cxx @@ -176,7 +176,7 @@ GameInfoDialog::GameInfoDialog( tabID = myTab->addTab("Controller"); ypos = vBorder; - pwidth = font.getStringWidth("BoosterGrip A"); + pwidth = font.getStringWidth("Booster-Grip A"); myP0Label = new StaticTextWidget(myTab, font, hSpace, ypos+1, "P0 controller "); ctrls.clear(); VarList::push_back(ctrls, "Joystick A", "JOYSTICK_A"); @@ -186,28 +186,28 @@ GameInfoDialog::GameInfoDialog( //VarList::push_back(ctrls, "Paddles_IAxis", "PADDLES_IAXIS"); //VarList::push_back(ctrls, "Paddles_IDir", "PADDLES_IDIR"); //VarList::push_back(ctrls, "Paddles_IAxDr", "PADDLES_IAXDR"); - VarList::push_back(ctrls, "BoosterGrip A", "BOOSTERGRIP_A"); - VarList::push_back(ctrls, "BoosterGrip B", "BOOSTERGRIP_B"); VarList::push_back(ctrls, "Driving A", "DRIVING_A"); VarList::push_back(ctrls, "Driving B", "DRIVING_B"); VarList::push_back(ctrls, "Keyboard A", "KEYBOARD_A"); VarList::push_back(ctrls, "Keyboard B", "KEYBOARD_B"); - VarList::push_back(ctrls, "AmigaMouse", "AMIGAMOUSE"); - VarList::push_back(ctrls, "AtariMouse", "ATARIMOUSE"); - VarList::push_back(ctrls, "TrakBall", "TRAKBALL"); - VarList::push_back(ctrls, "AtariVox", "ATARIVOX"); - VarList::push_back(ctrls, "SaveKey", "SAVEKEY"); - VarList::push_back(ctrls, "Sega Genesis A", "GENESIS_A"); - VarList::push_back(ctrls, "Sega Genesis B", "GENESIS_B"); // VarList::push_back(ctrls, "KidVid", "KIDVID" ); VarList::push_back(ctrls, "MindLink", "MINDLINK"); + VarList::push_back(ctrls, "Booster-Grip A", "BOOSTERGRIP_A"); + VarList::push_back(ctrls, "Booster-Grip B", "BOOSTERGRIP_B"); + VarList::push_back(ctrls, "Sega Genesis A", "GENESIS_A"); + VarList::push_back(ctrls, "Sega Genesis B", "GENESIS_B"); + VarList::push_back(ctrls, "Trak-Ball", "TRAKBALL"); + VarList::push_back(ctrls, "Atari Mouse", "ATARIMOUSE"); + VarList::push_back(ctrls, "Amiga Mouse", "AMIGAMOUSE"); + VarList::push_back(ctrls, "AtariVox", "ATARIVOX"); + VarList::push_back(ctrls, "SaveKey", "SAVEKEY"); myP0Controller = new PopUpWidget(myTab, font, myP0Label->getRight(), myP0Label->getTop()-1, pwidth, lineHeight, ctrls, "", 0, kLeftCChanged); wid.push_back(myP0Controller); ypos += lineHeight + VGAP; - pwidth = font.getStringWidth("BoosterGrip A"); + pwidth = font.getStringWidth("Booster-Grip A"); myP1Label = new StaticTextWidget(myTab, font, hSpace, ypos+1, "P1 controller "); myP1Controller = new PopUpWidget(myTab, font, myP1Label->getRight(), myP1Label->getTop()-1, pwidth, lineHeight, ctrls, "", 0, kRightCChanged); From 980fd5c025dbace0013f0c71942b6ca09c7bbf1f Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 7 Apr 2018 23:06:12 +0200 Subject: [PATCH 03/18] very preliminary InputDialog changes --- src/gui/EventMappingWidget.cxx | 12 +++- src/gui/EventMappingWidget.hxx | 2 + src/gui/InputDialog.cxx | 119 ++++++++++++++++++++++++++++++--- src/gui/InputDialog.hxx | 5 ++ 4 files changed, 125 insertions(+), 13 deletions(-) diff --git a/src/gui/EventMappingWidget.cxx b/src/gui/EventMappingWidget.cxx index 67cfefec1..0631d3da1 100644 --- a/src/gui/EventMappingWidget.cxx +++ b/src/gui/EventMappingWidget.cxx @@ -52,7 +52,8 @@ EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font, buttonHeight = font.getLineHeight() + 4; const int HBORDER = 8; const int VBORDER = 8; - int xpos = HBORDER, ypos = VBORDER; + //int xpos = HBORDER, ypos = VBORDER; + int xpos = x, ypos = y; myActionsList = new StringListWidget(boss, font, xpos, ypos, _w - buttonWidth - HBORDER * 2 - 8, _h - 3*lineHeight - VBORDER); @@ -107,7 +108,8 @@ EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font, myComboButton = nullptr; // Show message for currently selected event - xpos = HBORDER; ypos = VBORDER + myActionsList->getHeight() + 8; + //xpos = HBORDER; ypos = VBORDER + myActionsList->getHeight() + 8; + xpos = x; ypos = y + myActionsList->getHeight() + 8; StaticTextWidget* t; t = new StaticTextWidget(boss, font, xpos, ypos+2, font.getStringWidth("Action"), fontHeight, "Action", TextAlign::Left); @@ -118,6 +120,12 @@ EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font, myKeyMapping->clearFlags(WIDGET_RETAIN_FOCUS); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EventMappingWidget::setActionList(const StringList& actions) +{ + myActionsList->setList(actions); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EventMappingWidget::loadConfig() { diff --git a/src/gui/EventMappingWidget.hxx b/src/gui/EventMappingWidget.hxx index 7ab299bf2..999def081 100644 --- a/src/gui/EventMappingWidget.hxx +++ b/src/gui/EventMappingWidget.hxx @@ -48,6 +48,8 @@ class EventMappingWidget : public Widget, public CommandSender void setDefaults(); + void setActionList(const StringList& actions); + private: enum { kStartMapCmd = 'map ', diff --git a/src/gui/InputDialog.cxx b/src/gui/InputDialog.cxx index f6cd9599b..ed0afcfaa 100644 --- a/src/gui/InputDialog.cxx +++ b/src/gui/InputDialog.cxx @@ -46,7 +46,8 @@ InputDialog::InputDialog(OSystem& osystem, DialogContainer& parent, const int lineHeight = font.getLineHeight(), fontWidth = font.getMaxCharWidth(), buttonHeight = font.getLineHeight() + 4; - const int vBorder = 4; + const int HBORDER = 10; + const int VBORDER = 8; int xpos, ypos, tabID; StringList actions; @@ -55,24 +56,17 @@ InputDialog::InputDialog(OSystem& osystem, DialogContainer& parent, _h = std::min(16 * (lineHeight + 4) + 16 + _th, max_h); // The tab widget - xpos = 2; ypos = vBorder + _th; + xpos = 2; ypos = VBORDER + _th; myTab = new TabWidget(this, font, xpos, ypos, _w - 2*xpos, _h -_th - buttonHeight - 20); addTabWidget(myTab); // 1) Event mapper for emulation actions - tabID = myTab->addTab("Emul. Events"); - actions = instance().eventHandler().getActionList(kEmulationMode); - myEmulEventMapper = new EventMappingWidget(myTab, font, 2, 2, - myTab->getWidth(), - myTab->getHeight() - 4, - actions, kEmulationMode); - myTab->setParentWidget(tabID, myEmulEventMapper); - addToFocusList(myEmulEventMapper->getFocusList(), myTab, tabID); + addEmulMappingTab(font); // 2) Event mapper for UI actions tabID = myTab->addTab("UI Events"); actions = instance().eventHandler().getActionList(kMenuMode); - myMenuEventMapper = new EventMappingWidget(myTab, font, 2, 2, + myMenuEventMapper = new EventMappingWidget(myTab, font, HBORDER, VBORDER, myTab->getWidth(), myTab->getHeight() - 4, actions, kMenuMode); @@ -97,6 +91,60 @@ InputDialog::~InputDialog() { } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void InputDialog::addEmulMappingTab(const GUI::Font& font) +{ + const int lineHeight = font.getLineHeight(), + fontWidth = font.getMaxCharWidth(), + fontHeight = font.getFontHeight(); + int xpos, ypos, lwidth, pwidth, tabID; + WidgetArray wid; + VariantList items; + StringList actions; + const int VGAP = 4; + const int VBORDER = 10; + const int HBORDER = 8; + + tabID = myTab->addTab("Emul. Events"); + + xpos = HBORDER; + ypos = VBORDER; + + //StaticTextWidget* t = new StaticTextWidget(myTab, font, xpos, ypos + 1, 24, lineHeight, ""); + + pwidth = font.getStringWidth("Booster-Grip A"); + items.clear(); + VarList::push_back(items, "Joystick A", "JOYSTICK_A"); + VarList::push_back(items, "Joystick B", "JOYSTICK_B"); + VarList::push_back(items, "Paddles A", "PADDLES_A"); + VarList::push_back(items, "Paddles B", "PADDLES_B"); + VarList::push_back(items, "Driving A", "DRIVING_A"); + VarList::push_back(items, "Driving B", "DRIVING_B"); + VarList::push_back(items, "Keyboard A", "KEYBOARD_A"); + VarList::push_back(items, "Keyboard B", "KEYBOARD_B"); + VarList::push_back(items, "Booster-Grip A", "BOOSTERGRIP_A"); + VarList::push_back(items, "Booster-Grip B", "BOOSTERGRIP_B"); + VarList::push_back(items, "Sega Genesis A", "GENESIS_A"); + VarList::push_back(items, "Sega Genesis B", "GENESIS_B"); + + myMapping = new PopUpWidget(myTab, font, xpos, ypos, pwidth, lineHeight, items, + "Mapping ", 0, kMappingChanged); + wid.push_back(myMapping); + ypos += lineHeight + VGAP; + + actions = instance().eventHandler().getActionList(kEmulationMode); + myEmulEventMapper = new EventMappingWidget(myTab, font, xpos, ypos, + myTab->getWidth(), + myTab->getHeight() - 2 - ypos, + actions, kEmulationMode); + + wid.push_back(myEmulEventMapper); + + // Add items for virtual device ports + addToFocusList(wid, myTab, tabID); +} + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void InputDialog::addDevicePortTab(const GUI::Font& font) { @@ -295,6 +343,9 @@ void InputDialog::loadConfig() // Enable/disable control key-combos myCtrlCombo->setState(instance().settings().getBool("ctrlcombo")); + myMapping->setSelectedIndex(0); + mappingChanged(); + myTab->loadConfig(); } @@ -492,6 +543,10 @@ void InputDialog::handleCommand(CommandSender* sender, int cmd, setDefaults(); break; + case kMappingChanged: + mappingChanged(); + break; + case kDeadzoneChanged: myDeadzoneLabel->setValue(3200 + 1000*myDeadzone->getValue()); break; @@ -545,3 +600,45 @@ void InputDialog::handleCommand(CommandSender* sender, int cmd, Dialog::handleCommand(sender, cmd, data, 0); } } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void InputDialog::mappingChanged() +{ + const string& mapping = myMapping->getSelectedTag().toString(); + + if(mapping == "JOYSTICK_A" || mapping == "JOYSTICK_B") + { + StringList actions = { "Left", "Right", "Up", "Down", "Fire" }; + myEmulEventMapper->setActionList(actions); + } + + if(mapping == "BOOSTERGRIP_A" || mapping == "BOOSTERGRIP_B") + { + StringList actions = { "Left", "Right", "Up", "Down", "Fire", "Top Trigger", "Handle Grip" }; + myEmulEventMapper->setActionList(actions); + } + + if(mapping == "GENESIS_A" || mapping == "GENESIS_B") + { + StringList actions = { "Left", "Right", "Up", "Down", "Fire", "Fire 2" }; + myEmulEventMapper->setActionList(actions); + } + + if(mapping == "PADDLES_A" || mapping == "PADDLES_B") + { + StringList actions = { "Clockwise", "Counter-Clockwise", "Fire" }; + myEmulEventMapper->setActionList(actions); + } + + if(mapping == "DRIVING_A" || mapping == "DRIVING_B") + { + StringList actions = { "Clockwise", "Counter-Clockwise", "Fire" }; + myEmulEventMapper->setActionList(actions); + } + + if(mapping == "KEYBOARD_A" || mapping == "KEYBOARD_B") + { + StringList actions = { "1", "2", "3", "4", "5", "6", "7", "8", "9" , "*" , "0" , "#" }; + myEmulEventMapper->setActionList(actions); + } +} \ No newline at end of file diff --git a/src/gui/InputDialog.hxx b/src/gui/InputDialog.hxx index 44ea8c6c9..8b993ef0c 100644 --- a/src/gui/InputDialog.hxx +++ b/src/gui/InputDialog.hxx @@ -53,12 +53,16 @@ class InputDialog : public Dialog void saveConfig() override; void setDefaults() override; + void addEmulMappingTab(const GUI::Font& font); void addDevicePortTab(const GUI::Font& font); + void mappingChanged(); + void eraseEEPROM(); private: enum { + kMappingChanged = 'MPch', kDeadzoneChanged = 'DZch', kDPSpeedChanged = 'PDch', kMPSpeedChanged = 'PMch', @@ -70,6 +74,7 @@ class InputDialog : public Dialog TabWidget* myTab; + PopUpWidget* myMapping; EventMappingWidget* myEmulEventMapper; EventMappingWidget* myMenuEventMapper; From d798a007d04821f0dffc6cc49dd6d5c691881ab0 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Tue, 10 Apr 2018 16:45:06 +0200 Subject: [PATCH 04/18] A few more details/ideas --- src/gui/InputDialog.cxx | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/src/gui/InputDialog.cxx b/src/gui/InputDialog.cxx index ed0afcfaa..ec77f5d66 100644 --- a/src/gui/InputDialog.cxx +++ b/src/gui/InputDialog.cxx @@ -114,6 +114,10 @@ void InputDialog::addEmulMappingTab(const GUI::Font& font) pwidth = font.getStringWidth("Booster-Grip A"); items.clear(); + VarList::push_back(items, "Emulator", "EMULATOR_A"); // this might be better place in UI Events tab + //VarList::push_back(items, "Emulator B", "EMULATOR_B"); // not sure why this might be useful :) + VarList::push_back(items, "Console A", "CONSOLE_A"); + VarList::push_back(items, "Console B", "CONSOLE_B"); // a separate mapping might make sense e.g. for games which use the switches a lot VarList::push_back(items, "Joystick A", "JOYSTICK_A"); VarList::push_back(items, "Joystick B", "JOYSTICK_B"); VarList::push_back(items, "Paddles A", "PADDLES_A"); @@ -606,37 +610,58 @@ void InputDialog::mappingChanged() { const string& mapping = myMapping->getSelectedTag().toString(); - if(mapping == "JOYSTICK_A" || mapping == "JOYSTICK_B") + if(mapping.rfind("EMULATOR_", 0) == 0) + { + // Note: It seems a good idea to list the current keys in the list too. + StringList actions = { + "Save State F9", + "Change State F10", + "Load State F11", + "Snapshot F12", + "Fry Cartridge Backspace", + "etc." }; + myEmulEventMapper->setActionList(actions); + } + + if(mapping.rfind("CONSOLE_", 0) == 0) + { + StringList actions = { "Select", "Reset", "Color TV", "Black & White TV", "Swap Color / B&W TV", "7800 Pause Key", + "P0 Diffculty A", "P0 Diffculty B", "P0 Swap Diffculty", "P1 Diffculty A", "P1 Diffculty B", "P1 Swap Diffculty"}; + myEmulEventMapper->setActionList(actions); + } + + if(mapping.rfind("JOYSTICK_", 0) == 0) { StringList actions = { "Left", "Right", "Up", "Down", "Fire" }; myEmulEventMapper->setActionList(actions); } - if(mapping == "BOOSTERGRIP_A" || mapping == "BOOSTERGRIP_B") + if(mapping.rfind("BOOSTERGRIP_", 0) == 0) { StringList actions = { "Left", "Right", "Up", "Down", "Fire", "Top Trigger", "Handle Grip" }; + // TODO: align extra button names with doc myEmulEventMapper->setActionList(actions); } - if(mapping == "GENESIS_A" || mapping == "GENESIS_B") + if(mapping.rfind("GENESIS_", 0 ) == 0) { - StringList actions = { "Left", "Right", "Up", "Down", "Fire", "Fire 2" }; + StringList actions = { "Left", "Right", "Up", "Down", "Button B", "Button C" }; myEmulEventMapper->setActionList(actions); } - if(mapping == "PADDLES_A" || mapping == "PADDLES_B") + if(mapping.rfind("PADDLES_", 0) == 0) { StringList actions = { "Clockwise", "Counter-Clockwise", "Fire" }; myEmulEventMapper->setActionList(actions); } - if(mapping == "DRIVING_A" || mapping == "DRIVING_B") + if(mapping.rfind("DRIVING_", 0) == 0) { StringList actions = { "Clockwise", "Counter-Clockwise", "Fire" }; myEmulEventMapper->setActionList(actions); } - if(mapping == "KEYBOARD_A" || mapping == "KEYBOARD_B") + if(mapping.rfind("KEYBOARD_", 0) == 0) { StringList actions = { "1", "2", "3", "4", "5", "6", "7", "8", "9" , "*" , "0" , "#" }; myEmulEventMapper->setActionList(actions); From eb591cb096f101f4dfd530f98d710381c6974275 Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Wed, 11 Apr 2018 13:04:29 -0230 Subject: [PATCH 05/18] Remove 'combo' events and associated remapping. --- src/emucore/Event.hxx | 3 - src/emucore/EventHandler.cxx | 185 +---------------------------- src/emucore/EventHandler.hxx | 18 +-- src/emucore/Settings.cxx | 1 - src/gui/ComboDialog.cxx | 143 ---------------------- src/gui/ComboDialog.hxx | 59 --------- src/gui/EventMappingWidget.cxx | 31 ----- src/gui/EventMappingWidget.hxx | 7 +- src/gui/module.mk | 1 - src/windows/Stella.vcxproj | 4 +- src/windows/Stella.vcxproj.filters | 8 +- 11 files changed, 5 insertions(+), 455 deletions(-) delete mode 100644 src/gui/ComboDialog.cxx delete mode 100644 src/gui/ComboDialog.hxx diff --git a/src/emucore/Event.hxx b/src/emucore/Event.hxx index f286acf18..a44de1e44 100644 --- a/src/emucore/Event.hxx +++ b/src/emucore/Event.hxx @@ -61,9 +61,6 @@ class Event KeyboardOne7, KeyboardOne8, KeyboardOne9, KeyboardOneStar, KeyboardOne0, KeyboardOnePound, - Combo1, Combo2, Combo3, Combo4, Combo5, Combo6, Combo7, Combo8, - Combo9, Combo10, Combo11, Combo12, Combo13, Combo14, Combo15, Combo16, - SALeftAxis0Value, SALeftAxis1Value, SARightAxis0Value, SARightAxis1Value, diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index 4b8c5388a..fc6435a9a 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -71,11 +71,6 @@ EventHandler::EventHandler(OSystem& osystem) // Create joystick handler (to handle all physical joystick functionality) myPJoyHandler = make_unique(osystem, *this, myEvent); - - // Erase the 'combo' array - for(int i = 0; i < kComboSize; ++i) - for(int j = 0; j < kEventsPerCombo; ++j) - myComboTable[i][j] = Event::NoType; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -88,7 +83,6 @@ void EventHandler::initialize() { // Make sure the event/action mappings are correctly set, // and fill the ActionList structure with valid values - setComboMap(); setActionMappings(kEmulationMode); setActionMappings(kMenuMode); @@ -403,31 +397,6 @@ void EventHandler::handleEvent(Event::Type event, Int32 state) } return; - //////////////////////////////////////////////////////////////////////// - // A combo event is simply multiple calls to handleEvent, once for - // each event it contains - case Event::Combo1: - case Event::Combo2: - case Event::Combo3: - case Event::Combo4: - case Event::Combo5: - case Event::Combo6: - case Event::Combo7: - case Event::Combo8: - case Event::Combo9: - case Event::Combo10: - case Event::Combo11: - case Event::Combo12: - case Event::Combo13: - case Event::Combo14: - case Event::Combo15: - case Event::Combo16: - for(int i = 0, combo = event - Event::Combo1; i < kEventsPerCombo; ++i) - if(myComboTable[combo][i] != Event::NoType) - handleEvent(myComboTable[combo][i], state); - return; - //////////////////////////////////////////////////////////////////////// - //////////////////////////////////////////////////////////////////////// // Events which relate to switches() case Event::ConsoleColor: @@ -712,56 +681,6 @@ void EventHandler::setActionMappings(EventMode mode) } } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EventHandler::setComboMap() -{ - // Since istringstream swallows whitespace, we have to make the - // delimiters be spaces - string list = myOSystem.settings().getString("combomap"); - replace(list.begin(), list.end(), ':', ' '); - istringstream buf(list); - - // Erase the 'combo' array - auto ERASE_ALL = [&]() { - for(int i = 0; i < kComboSize; ++i) - for(int j = 0; j < kEventsPerCombo; ++j) - myComboTable[i][j] = Event::NoType; - }; - - // Get combo count, which should be the first int in the list - // If it isn't, then we treat the entire list as invalid - if(!buf.good()) - ERASE_ALL(); - else - { - string key; - buf >> key; - if(atoi(key.c_str()) == kComboSize) - { - // Fill the combomap table with events for as long as they exist - int combocount = 0; - while(buf >> key && combocount < kComboSize) - { - // Each event in a comboevent is separated by a comma - replace(key.begin(), key.end(), ',', ' '); - istringstream buf2(key); - - int eventcount = 0; - while(buf2 >> key && eventcount < kEventsPerCombo) - { - myComboTable[combocount][eventcount] = Event::Type(atoi(key.c_str())); - ++eventcount; - } - ++combocount; - } - } - else - ERASE_ALL(); - } - - saveComboMapping(); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EventHandler::removePhysicalJoystickFromDatabase(const string& name) { @@ -879,23 +798,6 @@ void EventHandler::saveJoyMapping() #endif } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EventHandler::saveComboMapping() -{ - // Iterate through the combomap table and create a colon-separated list - // For each combo event, create a comma-separated list of its events - // Prepend the event count, so we can check it on next load - ostringstream buf; - buf << kComboSize; - for(int i = 0; i < kComboSize; ++i) - { - buf << ":" << myComboTable[i][0]; - for(int j = 1; j < kEventsPerCombo; ++j) - buf << "," << myComboTable[i][j]; - } - myOSystem.settings().setValue("combomap", buf.str()); -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - StringList EventHandler::getActionList(EventMode mode) const { @@ -916,74 +818,6 @@ StringList EventHandler::getActionList(EventMode mode) const return l; } -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -VariantList EventHandler::getComboList(EventMode /**/) const -{ - // For now, this only works in emulation mode - VariantList l; - ostringstream buf; - - VarList::push_back(l, "None", "-1"); - for(uInt32 i = 0; i < kEmulActionListSize; ++i) - { - if(EventHandler::ourEmulActionList[i].allow_combo) - { - buf << i; - VarList::push_back(l, EventHandler::ourEmulActionList[i].action, buf.str()); - buf.str(""); - } - } - return l; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -StringList EventHandler::getComboListForEvent(Event::Type event) const -{ - StringList l; - ostringstream buf; - if(event >= Event::Combo1 && event <= Event::Combo16) - { - int combo = event - Event::Combo1; - for(uInt32 i = 0; i < kEventsPerCombo; ++i) - { - Event::Type e = myComboTable[combo][i]; - for(uInt32 j = 0; j < kEmulActionListSize; ++j) - { - if(EventHandler::ourEmulActionList[j].event == e && - EventHandler::ourEmulActionList[j].allow_combo) - { - buf << j; - l.push_back(buf.str()); - buf.str(""); - } - } - // Make sure entries are 1-to-1, using '-1' to indicate Event::NoType - if(i == l.size()) - l.push_back("-1"); - } - } - return l; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void EventHandler::setComboListForEvent(Event::Type event, const StringList& events) -{ - if(event >= Event::Combo1 && event <= Event::Combo16) - { - assert(events.size() == 8); - int combo = event - Event::Combo1; - for(int i = 0; i < 8; ++i) - { - int idx = atoi(events[i].c_str()); - if(idx >=0 && idx < kEmulActionListSize) - myComboTable[combo][i] = EventHandler::ourEmulActionList[idx].event; - else - myComboTable[combo][i] = Event::NoType; - } - saveComboMapping(); - } -} - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Event::Type EventHandler::eventAtIndex(int idx, EventMode mode) const { @@ -1308,24 +1142,7 @@ EventHandler::ActionList EventHandler::ourEmulActionList[kEmulActionListSize] = { Event::KeyboardOne9, "P1 Keyboard 9", "", true }, { Event::KeyboardOneStar, "P1 Keyboard *", "", true }, { Event::KeyboardOne0, "P1 Keyboard 0", "", true }, - { Event::KeyboardOnePound, "P1 Keyboard #", "", true }, - - { Event::Combo1, "Combo 1", "", false }, - { Event::Combo2, "Combo 2", "", false }, - { Event::Combo3, "Combo 3", "", false }, - { Event::Combo4, "Combo 4", "", false }, - { Event::Combo5, "Combo 5", "", false }, - { Event::Combo6, "Combo 6", "", false }, - { Event::Combo7, "Combo 7", "", false }, - { Event::Combo8, "Combo 8", "", false }, - { Event::Combo9, "Combo 9", "", false }, - { Event::Combo10, "Combo 10", "", false }, - { Event::Combo11, "Combo 11", "", false }, - { Event::Combo12, "Combo 12", "", false }, - { Event::Combo13, "Combo 13", "", false }, - { Event::Combo14, "Combo 14", "", false }, - { Event::Combo15, "Combo 15", "", false }, - { Event::Combo16, "Combo 16", "", false } + { Event::KeyboardOnePound, "P1 Keyboard #", "", true } }; // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/emucore/EventHandler.hxx b/src/emucore/EventHandler.hxx index a6d32ce98..2be2924d9 100644 --- a/src/emucore/EventHandler.hxx +++ b/src/emucore/EventHandler.hxx @@ -151,11 +151,6 @@ class EventHandler bool frying() const { return myFryingFlag; } StringList getActionList(EventMode mode) const; - VariantList getComboList(EventMode mode) const; - - /** Used to access the list of events assigned to a specific combo event. */ - StringList getComboListForEvent(Event::Type event) const; - void setComboListForEvent(Event::Type event, const StringList& events); /** Convert keys and physical joystick events into Stella events. */ Event::Type eventForKey(StellaKey key, EventMode mode) const { @@ -249,11 +244,6 @@ class EventHandler */ void setDefaultMapping(Event::Type event, EventMode mode); - /** - Sets the combo event mappings to those in the 'combomap' setting - */ - void setComboMap(); - /** Joystick emulates 'impossible' directions (ie, left & right at the same time). @@ -361,9 +351,7 @@ class EventHandler private: enum { - kComboSize = 16, - kEventsPerCombo = 8, - kEmulActionListSize = 80 + kComboSize, + kEmulActionListSize = 80, kMenuActionListSize = 14 }; @@ -375,7 +363,6 @@ class EventHandler void setDefaultJoymap(Event::Type, EventMode mode); void saveKeyMapping(); void saveJoyMapping(); - void saveComboMapping(); private: // Structure used for action menu items @@ -402,9 +389,6 @@ class EventHandler // all possible controller modes unique_ptr myMouseControl; - // The event(s) assigned to each combination event - Event::Type myComboTable[kComboSize][kEventsPerCombo]; - // Indicates the current state of the system (ie, which mode is current) EventHandlerState myState; diff --git a/src/emucore/Settings.cxx b/src/emucore/Settings.cxx index b54c366ed..04541bd9f 100644 --- a/src/emucore/Settings.cxx +++ b/src/emucore/Settings.cxx @@ -77,7 +77,6 @@ Settings::Settings(OSystem& osystem) // Input event options setInternal("keymap", ""); setInternal("joymap", ""); - setInternal("combomap", ""); setInternal("joydeadzone", "13"); setInternal("joyallow4", "false"); setInternal("usemouse", "analog"); diff --git a/src/gui/ComboDialog.cxx b/src/gui/ComboDialog.cxx deleted file mode 100644 index 35b76ddb6..000000000 --- a/src/gui/ComboDialog.cxx +++ /dev/null @@ -1,143 +0,0 @@ -//============================================================================ -// -// SSSS tt lll lll -// SS SS tt ll ll -// SS tttttt eeee ll ll aaaa -// SSSS tt ee ee ll ll aa -// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" -// SS SS tt ee ll ll aa aa -// SSSS ttt eeeee llll llll aaaaa -// -// Copyright (c) 1995-2018 by Bradford W. Mott, Stephen Anthony -// and the Stella Team -// -// See the file "License.txt" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -//============================================================================ - -#include "bspf.hxx" -#include "Control.hxx" -#include "Dialog.hxx" -#include "EventHandler.hxx" -#include "OSystem.hxx" -#include "EditTextWidget.hxx" -#include "PopUpWidget.hxx" -#include "Widget.hxx" -#include "Font.hxx" -#include "ComboDialog.hxx" - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -ComboDialog::ComboDialog(GuiObject* boss, const GUI::Font& font, - const VariantList& combolist) - : Dialog(boss->instance(), boss->parent(), font, ""), - myComboEvent(Event::NoType) -{ - const int lineHeight = font.getLineHeight(), - fontWidth = font.getMaxCharWidth(); - int xpos, ypos; - WidgetArray wid; - - // Set real dimensions - _w = 35 * fontWidth + 10; - _h = 10 * (lineHeight + 4) + 10 + _th; - xpos = 10; - ypos = 10 + _th; - - // Get maximum width of popupwidget - int pwidth = 0; - for(const auto& s: combolist) - pwidth = std::max(font.getStringWidth(s.first), pwidth); - - // Add event popup for 8 events - auto ADD_EVENT_POPUP = [&](int idx, const string& label) - { - myEvents[idx] = new PopUpWidget(this, font, xpos, ypos, - pwidth, lineHeight, combolist, label); - wid.push_back(myEvents[idx]); - ypos += lineHeight + 4; - }; - - xpos = 10; - myEvents[0] = nullptr; ADD_EVENT_POPUP(0, "Event 1 "); - myEvents[1] = nullptr; ADD_EVENT_POPUP(1, "Event 2 "); - myEvents[2] = nullptr; ADD_EVENT_POPUP(2, "Event 3 "); - myEvents[3] = nullptr; ADD_EVENT_POPUP(3, "Event 4 "); - myEvents[4] = nullptr; ADD_EVENT_POPUP(4, "Event 5 "); - myEvents[5] = nullptr; ADD_EVENT_POPUP(5, "Event 6 "); - myEvents[6] = nullptr; ADD_EVENT_POPUP(6, "Event 7 "); - myEvents[7] = nullptr; ADD_EVENT_POPUP(7, "Event 8 "); - - // Add Defaults, OK and Cancel buttons - addDefaultsOKCancelBGroup(wid, font); - - addToFocusList(wid); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ComboDialog::show(Event::Type event, const string& name) -{ - // Make sure the event is allowed - if(event >= Event::Combo1 && event <= Event::Combo16) - { - myComboEvent = event; - setTitle("Add events for " + name); - open(); - } - else - myComboEvent = Event::NoType; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ComboDialog::loadConfig() -{ - StringList events = instance().eventHandler().getComboListForEvent(myComboEvent); - - uInt32 size = std::min(uInt32(events.size()), 8u); - for(uInt32 i = 0; i < size; ++i) - myEvents[i]->setSelected("", events[i]); - - // Fill any remaining items to 'None' - if(size < 8) - for(uInt32 i = size; i < 8; ++i) - myEvents[i]->setSelected("None", "-1"); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ComboDialog::saveConfig() -{ - StringList events; - for(int i = 0; i < 8; ++i) - events.push_back(myEvents[i]->getSelectedTag().toString()); - - instance().eventHandler().setComboListForEvent(myComboEvent, events); -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ComboDialog::setDefaults() -{ - for(int i = 0; i < 8; ++i) - myEvents[i]->setSelected("None", "-1"); - - _dirty = true; -} - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ComboDialog::handleCommand(CommandSender* sender, int cmd, - int data, int id) -{ - switch(cmd) - { - case GuiObject::kOKCmd: - saveConfig(); - close(); - break; - - case GuiObject::kDefaultsCmd: - setDefaults(); - break; - - default: - Dialog::handleCommand(sender, cmd, data, 0); - break; - } -} diff --git a/src/gui/ComboDialog.hxx b/src/gui/ComboDialog.hxx deleted file mode 100644 index f6ad4db57..000000000 --- a/src/gui/ComboDialog.hxx +++ /dev/null @@ -1,59 +0,0 @@ -//============================================================================ -// -// SSSS tt lll lll -// SS SS tt ll ll -// SS tttttt eeee ll ll aaaa -// SSSS tt ee ee ll ll aa -// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" -// SS SS tt ee ll ll aa aa -// SSSS ttt eeeee llll llll aaaaa -// -// Copyright (c) 1995-2018 by Bradford W. Mott, Stephen Anthony -// and the Stella Team -// -// See the file "License.txt" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -//============================================================================ - -#ifndef COMBO_DIALOG_HXX -#define COMBO_DIALOG_HXX - -class PopUpWidget; -class EditTextWidget; -class StaticTextWidget; -class OSystem; - -#include "Dialog.hxx" -#include "bspf.hxx" - -class ComboDialog : public Dialog -{ - public: - ComboDialog(GuiObject* boss, const GUI::Font& font, const VariantList& combolist); - virtual ~ComboDialog() = default; - - /** Place the dialog onscreen and center it */ - void show(Event::Type event, const string& name); - - private: - void loadConfig() override; - void saveConfig() override; - void setDefaults() override; - - void handleCommand(CommandSender* sender, int cmd, int data, int id) override; - - private: - Event::Type myComboEvent; - - PopUpWidget* myEvents[8]; - - private: - // Following constructors and assignment operators not supported - ComboDialog() = delete; - ComboDialog(const ComboDialog&) = delete; - ComboDialog(ComboDialog&&) = delete; - ComboDialog& operator=(const ComboDialog&) = delete; - ComboDialog& operator=(ComboDialog&&) = delete; -}; - -#endif diff --git a/src/gui/EventMappingWidget.cxx b/src/gui/EventMappingWidget.cxx index 0631d3da1..f13dddfce 100644 --- a/src/gui/EventMappingWidget.cxx +++ b/src/gui/EventMappingWidget.cxx @@ -26,7 +26,6 @@ #include "StringListWidget.hxx" #include "Widget.hxx" #include "Font.hxx" -#include "ComboDialog.hxx" #include "Variant.hxx" #include "EventMappingWidget.hxx" @@ -36,7 +35,6 @@ EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font, const StringList& actions, EventMode mode) : Widget(boss, font, x, y, w, h), CommandSender(boss), - myComboDialog(nullptr), myEventMode(mode), myActionSelected(-1), myRemapStatus(false), @@ -92,21 +90,6 @@ EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font, myResetButton->setTarget(this); addFocusWidget(myResetButton); - if(mode == kEmulationMode) - { - ypos += lineHeight + 20; - myComboButton = new ButtonWidget(boss, font, xpos, ypos, - buttonWidth, buttonHeight, - "Combo" + ELLIPSIS, kComboCmd); - myComboButton->setTarget(this); - addFocusWidget(myComboButton); - - VariantList combolist = instance().eventHandler().getComboList(mode); - myComboDialog = new ComboDialog(boss, font, combolist); - } - else - myComboButton = nullptr; - // Show message for currently selected event //xpos = HBORDER; ypos = VBORDER + myActionsList->getHeight() + 8; xpos = x; ypos = y + myActionsList->getHeight() + 8; @@ -244,13 +227,6 @@ void EventMappingWidget::enableButtons(bool state) myCancelMapButton->setEnabled(!state); myEraseButton->setEnabled(state); myResetButton->setEnabled(state); - if(myComboButton) - { - Event::Type e = - instance().eventHandler().eventAtIndex(myActionSelected, myEventMode); - - myComboButton->setEnabled(state && e >= Event::Combo1 && e <= Event::Combo16); - } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -389,12 +365,5 @@ void EventMappingWidget::handleCommand(CommandSender* sender, int cmd, case kResetCmd: resetRemapping(); break; - - case kComboCmd: - if(myComboDialog) - myComboDialog->show( - instance().eventHandler().eventAtIndex(myActionSelected, myEventMode), - instance().eventHandler().actionAtIndex(myActionSelected, myEventMode)); - break; } } diff --git a/src/gui/EventMappingWidget.hxx b/src/gui/EventMappingWidget.hxx index 999def081..dc9b58704 100644 --- a/src/gui/EventMappingWidget.hxx +++ b/src/gui/EventMappingWidget.hxx @@ -26,7 +26,6 @@ class StaticTextWidget; class StringListWidget; class PopUpWidget; class GuiObject; -class ComboDialog; class InputDialog; #include "Widget.hxx" @@ -55,8 +54,7 @@ class EventMappingWidget : public Widget, public CommandSender kStartMapCmd = 'map ', kStopMapCmd = 'smap', kEraseCmd = 'eras', - kResetCmd = 'rest', - kComboCmd = 'cmbo' + kResetCmd = 'rest' }; bool handleKeyDown(StellaKey key, StellaMod mod) override; @@ -82,12 +80,9 @@ class EventMappingWidget : public Widget, public CommandSender ButtonWidget* myCancelMapButton; ButtonWidget* myEraseButton; ButtonWidget* myResetButton; - ButtonWidget* myComboButton; StringListWidget* myActionsList; EditTextWidget* myKeyMapping; - ComboDialog* myComboDialog; - // 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; diff --git a/src/gui/module.mk b/src/gui/module.mk index b598334c7..9083cb64f 100644 --- a/src/gui/module.mk +++ b/src/gui/module.mk @@ -6,7 +6,6 @@ MODULE_OBJS := \ src/gui/BrowserDialog.o \ src/gui/CheckListWidget.o \ src/gui/ColorWidget.o \ - src/gui/ComboDialog.o \ src/gui/CommandDialog.o \ src/gui/CommandMenu.o \ src/gui/ConfigPathDialog.o \ diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj index 9f49220f1..ea9094e77 100644 --- a/src/windows/Stella.vcxproj +++ b/src/windows/Stella.vcxproj @@ -445,7 +445,6 @@ - @@ -772,7 +771,6 @@ - @@ -836,4 +834,4 @@ - \ No newline at end of file + diff --git a/src/windows/Stella.vcxproj.filters b/src/windows/Stella.vcxproj.filters index 511d26624..edaebbdc4 100644 --- a/src/windows/Stella.vcxproj.filters +++ b/src/windows/Stella.vcxproj.filters @@ -342,9 +342,6 @@ Source Files\gui - - Source Files\gui - Source Files\gui @@ -1229,9 +1226,6 @@ Header Files\gui - - Header Files\gui - Header Files\gui @@ -1856,4 +1850,4 @@ Resource Files - \ No newline at end of file + From 6e426955e5052a4648639ef7141b2ba5d20319ed Mon Sep 17 00:00:00 2001 From: Stephen Anthony Date: Wed, 11 Apr 2018 18:05:34 -0230 Subject: [PATCH 06/18] Removed ComboDialog from OSX project file. --- src/macosx/stella.xcodeproj/project.pbxproj | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/macosx/stella.xcodeproj/project.pbxproj b/src/macosx/stella.xcodeproj/project.pbxproj index 4de23d9c1..bfdb84e2a 100644 --- a/src/macosx/stella.xcodeproj/project.pbxproj +++ b/src/macosx/stella.xcodeproj/project.pbxproj @@ -617,8 +617,6 @@ DCFB9FAC1ECA2609004FD69B /* DelayQueueIteratorImpl.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCFB9FAB1ECA2609004FD69B /* DelayQueueIteratorImpl.hxx */; }; DCFF14CD18B0260300A20364 /* EventHandlerSDL2.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCFF14CB18B0260300A20364 /* EventHandlerSDL2.cxx */; }; DCFF14CE18B0260300A20364 /* EventHandlerSDL2.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCFF14CC18B0260300A20364 /* EventHandlerSDL2.hxx */; }; - DCFFE59D12100E1400DFA000 /* ComboDialog.cxx in Sources */ = {isa = PBXBuildFile; fileRef = DCFFE59B12100E1400DFA000 /* ComboDialog.cxx */; }; - DCFFE59E12100E1400DFA000 /* ComboDialog.hxx in Headers */ = {isa = PBXBuildFile; fileRef = DCFFE59C12100E1400DFA000 /* ComboDialog.hxx */; }; E0306E0C1F93E916003DDD52 /* YStartDetector.cxx in Sources */ = {isa = PBXBuildFile; fileRef = E0306E061F93E915003DDD52 /* YStartDetector.cxx */; }; E0306E0D1F93E916003DDD52 /* FrameLayoutDetector.hxx in Headers */ = {isa = PBXBuildFile; fileRef = E0306E071F93E915003DDD52 /* FrameLayoutDetector.hxx */; }; E0306E0E1F93E916003DDD52 /* YStartDetector.hxx in Headers */ = {isa = PBXBuildFile; fileRef = E0306E081F93E915003DDD52 /* YStartDetector.hxx */; }; @@ -1293,8 +1291,6 @@ DCFB9FAB1ECA2609004FD69B /* DelayQueueIteratorImpl.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = DelayQueueIteratorImpl.hxx; sourceTree = ""; }; DCFF14CB18B0260300A20364 /* EventHandlerSDL2.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = EventHandlerSDL2.cxx; sourceTree = ""; }; DCFF14CC18B0260300A20364 /* EventHandlerSDL2.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = EventHandlerSDL2.hxx; sourceTree = ""; }; - DCFFE59B12100E1400DFA000 /* ComboDialog.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ComboDialog.cxx; sourceTree = ""; }; - DCFFE59C12100E1400DFA000 /* ComboDialog.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = ComboDialog.hxx; sourceTree = ""; }; E0306E061F93E915003DDD52 /* YStartDetector.cxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = YStartDetector.cxx; sourceTree = ""; }; E0306E071F93E915003DDD52 /* FrameLayoutDetector.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = FrameLayoutDetector.hxx; sourceTree = ""; }; E0306E081F93E915003DDD52 /* YStartDetector.hxx */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = YStartDetector.hxx; sourceTree = ""; }; @@ -1838,8 +1834,6 @@ 2DEF21F908BC033500B246B4 /* CheckListWidget.hxx */, DC44019C1F1A5D01008C08F6 /* ColorWidget.cxx */, DC44019D1F1A5D01008C08F6 /* ColorWidget.hxx */, - DCFFE59B12100E1400DFA000 /* ComboDialog.cxx */, - DCFFE59C12100E1400DFA000 /* ComboDialog.hxx */, 2DDBEAAA084578BF00812C11 /* Command.hxx */, 2D73959308C3EB4E0060BB99 /* CommandDialog.cxx */, 2D73959408C3EB4E0060BB99 /* CommandDialog.hxx */, @@ -2341,7 +2335,6 @@ CFE3F60C1E84A9A200A8204E /* CartBUSWidget.hxx in Headers */, DCD6FC9411C28C6F005DA767 /* PNGLibrary.hxx in Headers */, DC98F35711F5B56200AA520F /* MessageBox.hxx in Headers */, - DCFFE59E12100E1400DFA000 /* ComboDialog.hxx in Headers */, DCD2839912E39F1200A808DC /* Thumbulator.hxx in Headers */, DC69670B1361FD0A0036499D /* pngdebug.h in Headers */, DC69670C1361FD0A0036499D /* pnginfo.h in Headers */, @@ -2746,7 +2739,6 @@ DCD6FC9311C28C6F005DA767 /* PNGLibrary.cxx in Sources */, DC98F35611F5B56200AA520F /* MessageBox.cxx in Sources */, DC9616301F817830008A2206 /* FlashWidget.cxx in Sources */, - DCFFE59D12100E1400DFA000 /* ComboDialog.cxx in Sources */, DCD2839812E39F1200A808DC /* Thumbulator.cxx in Sources */, DC1BC6662066B4390076F74A /* PKeyboardHandler.cxx in Sources */, DC6C726213CDEA0A008A5975 /* LoggerDialog.cxx in Sources */, From e36003a40380d3f924953e3e7407981d2f44bead Mon Sep 17 00:00:00 2001 From: thrust26 Date: Thu, 20 Jun 2019 14:13:59 +0200 Subject: [PATCH 07/18] initial changes --- src/common/ControllerMap.cxx | 223 ++++++++++++++++++++++++++ src/common/ControllerMap.hxx | 129 +++++++++++++++ src/common/KeyMap.cxx | 4 +- src/common/KeyMap.hxx | 3 +- src/common/PJoystickHandler.cxx | 11 +- src/common/PJoystickHandler.hxx | 10 ++ src/common/PKeyboardHandler.cxx | 2 +- src/common/module.mk | 1 + src/emucore/EventHandlerConstants.hxx | 2 + src/windows/Stella.vcxproj | 4 +- src/windows/Stella.vcxproj.filters | 8 +- 11 files changed, 390 insertions(+), 7 deletions(-) create mode 100644 src/common/ControllerMap.cxx create mode 100644 src/common/ControllerMap.hxx diff --git a/src/common/ControllerMap.cxx b/src/common/ControllerMap.cxx new file mode 100644 index 000000000..fca8511d4 --- /dev/null +++ b/src/common/ControllerMap.cxx @@ -0,0 +1,223 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#include "ControllerMap.hxx" + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +ControllerMap::ControllerMap(void) +{ +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void ControllerMap::add(const Event::Type event, const ControllerMapping& mapping) +{ + myMap[mapping] = event; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void ControllerMap::add(const Event::Type event, const EventMode mode, const int stick, const int button, + const JoyAxis axis, const JoyDir adir, const int hat, const JoyHat hdir) +{ + add(event, ControllerMapping(mode, stick, button, axis, adir, hat, hdir)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void ControllerMap::erase(const ControllerMapping& mapping) +{ + myMap.erase(mapping); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void ControllerMap::erase(const EventMode mode, const int stick, const int button, + const JoyAxis axis, const JoyDir adir, const int hat, const JoyHat hdir) +{ + erase(ControllerMapping(mode, stick, button, axis, adir, hat, hdir)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Event::Type ControllerMap::get(const ControllerMapping& mapping) const +{ + auto find = myMap.find(mapping); + if (find != myMap.end()) + return find->second; + + return Event::Type::NoType; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Event::Type ControllerMap::get(const EventMode mode, const int stick, const int button, + const JoyAxis axis, const JoyDir adir, const int hat, const JoyHat hdir) const +{ + return get(ControllerMapping(mode, stick, button, axis, adir, hat, hdir)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool ControllerMap::check(const ControllerMapping & mapping) const +{ + auto find = myMap.find(mapping); + + return (find != myMap.end()); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool ControllerMap::check(const EventMode mode, const int stick, const int button, + const JoyAxis axis, const JoyDir adir, const int hat, const JoyHat hdir) const +{ + return check(ControllerMapping(mode, stick, button, axis, adir, hat, hdir)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string ControllerMap::getDesc(const Event::Type event, const ControllerMapping& mapping) const +{ + ostringstream buf; + + buf << "J" << mapping.stick; + + // button description + if (mapping.button != CTRL_NONE) + buf << "/B" << mapping.button; + + // axis description + if (int(mapping.axis) != CTRL_NONE) + { + buf << "/A" << mapping.hat; + switch (mapping.axis) + { + case JoyAxis::X: buf << "X"; break; + case JoyAxis::Y: buf << "Y"; break; + default: break; + } + + if (Event::isAnalog(event)) + buf << "+|-"; + else if (mapping.adir == JoyDir::NEG) + buf << "-"; + else + buf << "+"; + } + + // hat description + if (mapping.hat != CTRL_NONE) + { + buf << "/H" << mapping.hat; + switch (mapping.hdir) + { + case JoyHat::UP: buf << "/up"; break; + case JoyHat::DOWN: buf << "/down"; break; + case JoyHat::LEFT: buf << "/left"; break; + case JoyHat::RIGHT: buf << "/right"; break; + default: break; + } + } + + + return buf.str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string ControllerMap::getDesc(const Event::Type event, const EventMode mode, const int stick, const int button, + const JoyAxis axis, const JoyDir adir, const int hat, const JoyHat hdir) const +{ + return getDesc(event, ControllerMapping(mode, stick, button, axis, adir, hat, hdir)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string ControllerMap::getEventMappingDesc(const Event::Type event, const EventMode mode) const +{ + ostringstream buf; + + for (auto item : myMap) + { + if (item.second == event && item.first.mode == mode) + { + if (buf.str() != "") + buf << ", "; + buf << getDesc(event, item.first); + } + } + return buf.str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +ControllerMap::ControllerMappingArray ControllerMap::getEventMapping(const Event::Type event, const EventMode mode) const +{ + ControllerMappingArray map; + + for (auto item : myMap) + if (item.second == event && item.first.mode == mode) + map.push_back(item.first); + + return map; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string ControllerMap::saveMapping(const EventMode mode) const +{ + ostringstream buf; + + for (auto item : myMap) + { + if (item.first.mode == mode) + { + if (buf.str() != "") + buf << "|"; + buf << item.second << ":" << item.first.stick << "," << item.first.button << "," + << int(item.first.axis) << "," << int(item.first.adir) << "," << item.first.hat << "," << int(item.first.hdir); + } + } + return buf.str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +int ControllerMap::loadMapping(string& list, const EventMode mode) +{ + // Since istringstream swallows whitespace, we have to make the + // delimiters be spaces + std::replace(list.begin(), list.end(), '|', ' '); + std::replace(list.begin(), list.end(), ':', ' '); + std::replace(list.begin(), list.end(), ',', ' '); + istringstream buf(list); + int event, stick, button, axis, adir, hat, hdir, i = 0; + + while (buf >> event && buf >> stick && buf >> button + && buf >> axis && buf >> adir && buf >> hat && buf >> hdir && ++i) + add(Event::Type(event), EventMode(mode), stick, button, JoyAxis(axis), JoyDir(adir), hat, JoyHat(hdir)); + + return i; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void ControllerMap::eraseMode(const EventMode mode) +{ + for (auto item = myMap.begin(); item != myMap.end();) + if (item->first.mode == mode) { + auto _item = item++; + erase(_item->first); + } + else item++; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void ControllerMap::eraseEvent(const Event::Type event, const EventMode mode) +{ + for (auto item = myMap.begin(); item != myMap.end();) + if (item->second == event && item->first.mode == mode) { + auto _item = item++; + erase(_item->first); + } + else item++; +} diff --git a/src/common/ControllerMap.hxx b/src/common/ControllerMap.hxx new file mode 100644 index 000000000..1afe6011a --- /dev/null +++ b/src/common/ControllerMap.hxx @@ -0,0 +1,129 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#ifndef CONTROLLERMAP_HXX +#define CONTROLLERMAP_HXX + +#include +#include "Event.hxx" +#include "EventHandlerConstants.hxx" + +/** + This class handles controller mappings in Stella. + + @author Thomas Jentzsch +*/ +class ControllerMap +{ + public: + + struct ControllerMapping + { + EventMode mode; + int stick; // stick number + int button; // button number + JoyAxis axis; // horizontal/vertical + JoyDir adir; // axis direction (neg/pos) + int hat; // hat number + JoyHat hdir; // hat direction (left/right/up/down) + + ControllerMapping() + : mode(EventMode(0)), stick(0), button(0), + axis(JoyAxis(0)), adir(JoyDir(0)), hat(0), hdir(JoyHat(0)) { } + ControllerMapping(const ControllerMapping& m) + : mode(m.mode), stick(m.stick), button(m.button), + axis(m.axis), adir(m.adir), hat(m.hat), hdir(m.hdir) { } + explicit ControllerMapping(EventMode c_mode, int c_stick, int c_button, + JoyAxis c_axis, JoyDir c_adir, int c_hat, JoyHat c_hdir) + : mode(c_mode), stick(c_stick), button(c_button), + axis(c_axis), adir(c_adir), hat(c_hat), hdir(c_hdir) { } + + bool operator==(const ControllerMapping& other) const + { + return (mode == other.mode + && stick == other.stick + && button == other.button + && axis == other.axis + && adir == other.adir + && hat == other.hat + && hdir == other.hdir + ); + } + }; + using ControllerMappingArray = std::vector; + + ControllerMap(); + virtual ~ControllerMap() = default; + + /** Add new mapping for given event */ + void add(const Event::Type event, const ControllerMapping& mapping); + void add(const Event::Type event, const EventMode mode, const int stick, const int button, + const JoyAxis axis, const JoyDir adir, const int hat, const JoyHat hdir); + + /** Erase mapping */ + void erase(const ControllerMapping& mapping); + void erase(const EventMode mode, const int stick, const int button, + const JoyAxis axis, const JoyDir adir, const int hat, const JoyHat hdir); + + /** Get event for mapping */ + Event::Type get(const ControllerMapping& mapping) const; + Event::Type get(const EventMode mode, const int stick, const int button, + const JoyAxis axis, const JoyDir adir, const int hat, const JoyHat hdir) const; + + /** Check if a mapping exists */ + bool check(const ControllerMapping& mapping) const; + bool check(const EventMode mode, const int stick, const int button, + const JoyAxis axis, const JoyDir adir, const int hat, const JoyHat hdir) const; + + /** Get mapping description */ + string getDesc(const Event::Type event, const ControllerMapping& mapping) const; + string getDesc(const Event::Type event, const EventMode mode, const int stick, const int button, + const JoyAxis axis, const JoyDir adir, const int hat, const JoyHat hdir) const; + + /** Get the mapping description(s) for given event and mode */ + string getEventMappingDesc(const Event::Type event, const EventMode mode) const; + + ControllerMappingArray getEventMapping(const Event::Type event, const EventMode mode) const; + + string saveMapping(const EventMode mode) const; + int loadMapping(string& list, const EventMode mode); + + /** Erase all mappings for given mode */ + void eraseMode(const EventMode mode); + /** Erase given event's mapping for given mode */ + void eraseEvent(const Event::Type event, const EventMode mode); + /** clear all mappings for a modes */ + // void clear() { myMap.clear(); } + size_t size() { return myMap.size(); } + + private: + struct ControllerHash { + size_t operator()(const ControllerMapping& m)const { + return std::hash()((uInt64(m.mode)) // 3 bit + ^ ((uInt64(m.stick)) << 3) // 2 bits + ^ ((uInt64(m.button)) << 5) // 2 bits + ^ ((uInt64(m.axis)) << 7) // 1 bit + ^ ((uInt64(m.adir)) << 8) // 1 bit + ^ ((uInt64(m.hat)) << 9) // 1 bit + ^ ((uInt64(m.hdir)) << 10)); // 2 bits + } + }; + + std::unordered_map myMap; +}; + +#endif diff --git a/src/common/KeyMap.cxx b/src/common/KeyMap.cxx index 4f5515828..551b1a86e 100644 --- a/src/common/KeyMap.cxx +++ b/src/common/KeyMap.cxx @@ -161,9 +161,9 @@ string KeyMap::getEventMappingDesc(const Event::Type event, const int mode) cons } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -std::vector KeyMap::getEventMapping(const Event::Type event, const int mode) const +KeyMap::MappingArray KeyMap::getEventMapping(const Event::Type event, const int mode) const { - std::vector map; + MappingArray map; for (auto item : myMap) if (item.second == event && item.first.mode == mode) diff --git a/src/common/KeyMap.hxx b/src/common/KeyMap.hxx index 5b0d82ef5..f69d92b1e 100644 --- a/src/common/KeyMap.hxx +++ b/src/common/KeyMap.hxx @@ -55,6 +55,7 @@ class KeyMap ); } }; + using MappingArray = std::vector; KeyMap(); virtual ~KeyMap() = default; @@ -82,7 +83,7 @@ class KeyMap /** Get the mapping description(s) for given event and mode */ string getEventMappingDesc(const Event::Type event, const int mode) const; - std::vector getEventMapping(const Event::Type event, const int mode) const; + MappingArray getEventMapping(const Event::Type event, const int mode) const; string saveMapping(const int mode) const; int loadMapping(string& list, const int mode); diff --git a/src/common/PJoystickHandler.cxx b/src/common/PJoystickHandler.cxx index 7af501c8f..fb8f1e18c 100644 --- a/src/common/PJoystickHandler.cxx +++ b/src/common/PJoystickHandler.cxx @@ -426,7 +426,7 @@ string PhysicalJoystickHandler::getMappingDesc(Event::Type event, EventMode mode dir = NUM_JOY_DIRS; // Immediately exit the inner loop after this iteration buf << "/+|-"; } - else if(dir == 0) + else if(dir == int(JoyDir::NEG)) buf << "/-"; else buf << "/+"; @@ -521,6 +521,15 @@ bool PhysicalJoystickHandler::addHatMapping(Event::Type event, EventMode mode, return false; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void PhysicalJoystickHandler::addMapping(Event::Type event, EventMode mode, int stick, + int button, JoyAxis axis, JoyDir adir, int hat, JoyHat hdir) +{ + myControllerMap.add(event, mode, stick, button, axis, adir, hat, hdir); + +} + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void PhysicalJoystickHandler::handleAxisEvent(int stick, int axis, int value) { diff --git a/src/common/PJoystickHandler.hxx b/src/common/PJoystickHandler.hxx index a300fdddf..b8bc447a6 100644 --- a/src/common/PJoystickHandler.hxx +++ b/src/common/PJoystickHandler.hxx @@ -28,6 +28,7 @@ class Event; #include "EventHandlerConstants.hxx" #include "PhysicalJoystick.hxx" #include "Variant.hxx" +#include "ControllerMap.hxx" using PhysicalJoystickPtr = shared_ptr; @@ -78,6 +79,12 @@ class PhysicalJoystickHandler bool addBtnMapping(Event::Type event, EventMode mode, int stick, int button); bool addHatMapping(Event::Type event, EventMode mode, int stick, int hat, JoyHat value); + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + void addMapping(Event::Type event, EventMode mode, int stick, + int button, JoyAxis axis, JoyDir adir, int hat, JoyHat hdir); + + + /** Handle a physical joystick event. */ void handleAxisEvent(int stick, int axis, int value); void handleBtnEvent(int stick, int button, bool pressed); @@ -133,6 +140,9 @@ class PhysicalJoystickHandler static const Event::Type SA_Axis[NUM_PORTS][NUM_JOY_AXIS]; static const Event::Type SA_Button[NUM_PORTS][NUM_JOY_BTN]; static const Event::Type SA_Key[NUM_PORTS][NUM_KEY_BTN]; + + // Hashmap of controller events + ControllerMap myControllerMap; }; #endif diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index d795f5589..8afcfdb0d 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -236,7 +236,7 @@ void PhysicalKeyboardHandler::enableMappings(const EventSet events, EventMode mo void PhysicalKeyboardHandler::enableMapping(const Event::Type event, EventMode mode) { // copy from controller mode into emulation mode - std::vector mappings = myKeyMap.getEventMapping(event, mode); + KeyMap::MappingArray mappings = myKeyMap.getEventMapping(event, mode); for (const auto& mapping : mappings) myKeyMap.add(event, kEmulationMode, mapping.key, mapping.mod); diff --git a/src/common/module.mk b/src/common/module.mk index dc24e6886..9c9f5c08a 100644 --- a/src/common/module.mk +++ b/src/common/module.mk @@ -6,6 +6,7 @@ MODULE_OBJS := \ src/common/FBSurfaceSDL2.o \ src/common/FrameBufferSDL2.o \ src/common/FSNodeZIP.o \ + src/common/ControllerMap.o \ src/common/KeyMap.o \ src/common/Logger.o \ src/common/main.o \ diff --git a/src/emucore/EventHandlerConstants.hxx b/src/emucore/EventHandlerConstants.hxx index 08ea4a96b..d0f7edaeb 100644 --- a/src/emucore/EventHandlerConstants.hxx +++ b/src/emucore/EventHandlerConstants.hxx @@ -38,6 +38,8 @@ enum class MouseButton { NONE }; +static constexpr int CTRL_NONE = -1; + enum class JoyAxis { X = 0, Y = 1, diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj index 9ef2b4b25..a57bcf2c5 100644 --- a/src/windows/Stella.vcxproj +++ b/src/windows/Stella.vcxproj @@ -374,8 +374,9 @@ - + + @@ -1073,6 +1074,7 @@ + diff --git a/src/windows/Stella.vcxproj.filters b/src/windows/Stella.vcxproj.filters index 966e31a7f..bde453361 100644 --- a/src/windows/Stella.vcxproj.filters +++ b/src/windows/Stella.vcxproj.filters @@ -978,6 +978,9 @@ Source Files\gui + + Source Files + @@ -2000,6 +2003,9 @@ Header Files + + Header Files + @@ -2012,4 +2018,4 @@ Resource Files - + \ No newline at end of file From 9b210cd8619f394cea79ca45f7952e52ee061593 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 21 Jun 2019 10:35:45 +0200 Subject: [PATCH 08/18] refactor into two separate maps for stick and hats --- src/common/ControllerMap.hxx | 129 ------------ src/common/JoyHatMap.cxx | 200 +++++++++++++++++++ src/common/JoyHatMap.hxx | 109 ++++++++++ src/common/{ControllerMap.cxx => JoyMap.cxx} | 93 ++++----- src/common/JoyMap.hxx | 121 +++++++++++ src/common/PJoystickHandler.cxx | 17 +- src/common/PJoystickHandler.hxx | 12 +- src/common/PhysicalJoystick.hxx | 6 + src/common/module.mk | 3 +- src/windows/Stella.vcxproj | 6 +- src/windows/Stella.vcxproj.filters | 10 +- 11 files changed, 509 insertions(+), 197 deletions(-) delete mode 100644 src/common/ControllerMap.hxx create mode 100644 src/common/JoyHatMap.cxx create mode 100644 src/common/JoyHatMap.hxx rename src/common/{ControllerMap.cxx => JoyMap.cxx} (57%) create mode 100644 src/common/JoyMap.hxx diff --git a/src/common/ControllerMap.hxx b/src/common/ControllerMap.hxx deleted file mode 100644 index 1afe6011a..000000000 --- a/src/common/ControllerMap.hxx +++ /dev/null @@ -1,129 +0,0 @@ -//============================================================================ -// -// SSSS tt lll lll -// SS SS tt ll ll -// SS tttttt eeee ll ll aaaa -// SSSS tt ee ee ll ll aa -// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" -// SS SS tt ee ll ll aa aa -// SSSS ttt eeeee llll llll aaaaa -// -// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony -// and the Stella Team -// -// See the file "License.txt" for information on usage and redistribution of -// this file, and for a DISCLAIMER OF ALL WARRANTIES. -//============================================================================ - -#ifndef CONTROLLERMAP_HXX -#define CONTROLLERMAP_HXX - -#include -#include "Event.hxx" -#include "EventHandlerConstants.hxx" - -/** - This class handles controller mappings in Stella. - - @author Thomas Jentzsch -*/ -class ControllerMap -{ - public: - - struct ControllerMapping - { - EventMode mode; - int stick; // stick number - int button; // button number - JoyAxis axis; // horizontal/vertical - JoyDir adir; // axis direction (neg/pos) - int hat; // hat number - JoyHat hdir; // hat direction (left/right/up/down) - - ControllerMapping() - : mode(EventMode(0)), stick(0), button(0), - axis(JoyAxis(0)), adir(JoyDir(0)), hat(0), hdir(JoyHat(0)) { } - ControllerMapping(const ControllerMapping& m) - : mode(m.mode), stick(m.stick), button(m.button), - axis(m.axis), adir(m.adir), hat(m.hat), hdir(m.hdir) { } - explicit ControllerMapping(EventMode c_mode, int c_stick, int c_button, - JoyAxis c_axis, JoyDir c_adir, int c_hat, JoyHat c_hdir) - : mode(c_mode), stick(c_stick), button(c_button), - axis(c_axis), adir(c_adir), hat(c_hat), hdir(c_hdir) { } - - bool operator==(const ControllerMapping& other) const - { - return (mode == other.mode - && stick == other.stick - && button == other.button - && axis == other.axis - && adir == other.adir - && hat == other.hat - && hdir == other.hdir - ); - } - }; - using ControllerMappingArray = std::vector; - - ControllerMap(); - virtual ~ControllerMap() = default; - - /** Add new mapping for given event */ - void add(const Event::Type event, const ControllerMapping& mapping); - void add(const Event::Type event, const EventMode mode, const int stick, const int button, - const JoyAxis axis, const JoyDir adir, const int hat, const JoyHat hdir); - - /** Erase mapping */ - void erase(const ControllerMapping& mapping); - void erase(const EventMode mode, const int stick, const int button, - const JoyAxis axis, const JoyDir adir, const int hat, const JoyHat hdir); - - /** Get event for mapping */ - Event::Type get(const ControllerMapping& mapping) const; - Event::Type get(const EventMode mode, const int stick, const int button, - const JoyAxis axis, const JoyDir adir, const int hat, const JoyHat hdir) const; - - /** Check if a mapping exists */ - bool check(const ControllerMapping& mapping) const; - bool check(const EventMode mode, const int stick, const int button, - const JoyAxis axis, const JoyDir adir, const int hat, const JoyHat hdir) const; - - /** Get mapping description */ - string getDesc(const Event::Type event, const ControllerMapping& mapping) const; - string getDesc(const Event::Type event, const EventMode mode, const int stick, const int button, - const JoyAxis axis, const JoyDir adir, const int hat, const JoyHat hdir) const; - - /** Get the mapping description(s) for given event and mode */ - string getEventMappingDesc(const Event::Type event, const EventMode mode) const; - - ControllerMappingArray getEventMapping(const Event::Type event, const EventMode mode) const; - - string saveMapping(const EventMode mode) const; - int loadMapping(string& list, const EventMode mode); - - /** Erase all mappings for given mode */ - void eraseMode(const EventMode mode); - /** Erase given event's mapping for given mode */ - void eraseEvent(const Event::Type event, const EventMode mode); - /** clear all mappings for a modes */ - // void clear() { myMap.clear(); } - size_t size() { return myMap.size(); } - - private: - struct ControllerHash { - size_t operator()(const ControllerMapping& m)const { - return std::hash()((uInt64(m.mode)) // 3 bit - ^ ((uInt64(m.stick)) << 3) // 2 bits - ^ ((uInt64(m.button)) << 5) // 2 bits - ^ ((uInt64(m.axis)) << 7) // 1 bit - ^ ((uInt64(m.adir)) << 8) // 1 bit - ^ ((uInt64(m.hat)) << 9) // 1 bit - ^ ((uInt64(m.hdir)) << 10)); // 2 bits - } - }; - - std::unordered_map myMap; -}; - -#endif diff --git a/src/common/JoyHatMap.cxx b/src/common/JoyHatMap.cxx new file mode 100644 index 000000000..ea6480dc9 --- /dev/null +++ b/src/common/JoyHatMap.cxx @@ -0,0 +1,200 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#include "JoyHatMap.hxx" + +// TODOs +// - two maps per controller (joydirs, hatdirs) +// - both maps combined with buttons +// - directions can work alone and with a button combination +// - buttons can work without a direction (mapped in joydir) + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +JoyHatMap::JoyHatMap(void) +{ +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void JoyHatMap::add(const Event::Type event, const JoyHatMapping& mapping) +{ + myMap[mapping] = event; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void JoyHatMap::add(const Event::Type event, const EventMode mode, const int hat, const JoyHat hdir) +{ + add(event, JoyHatMapping(mode, hat, hdir)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void JoyHatMap::erase(const JoyHatMapping& mapping) +{ + myMap.erase(mapping); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void JoyHatMap::erase(const EventMode mode, const int hat, const JoyHat hdir) +{ + erase(JoyHatMapping(mode, hat, hdir)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Event::Type JoyHatMap::get(const JoyHatMapping& mapping) const +{ + auto find = myMap.find(mapping); + if (find != myMap.end()) + return find->second; + + return Event::Type::NoType; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Event::Type JoyHatMap::get(const EventMode mode, const int hat, const JoyHat hdir) const +{ + return get(JoyHatMapping(mode, hat, hdir)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool JoyHatMap::check(const JoyHatMapping & mapping) const +{ + auto find = myMap.find(mapping); + + return (find != myMap.end()); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool JoyHatMap::check(const EventMode mode, const int hat, const JoyHat hdir) const +{ + return check(JoyHatMapping(mode, hat, hdir)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string JoyHatMap::getDesc(const Event::Type event, const JoyHatMapping & mapping) const +{ + ostringstream buf; + + //buf << "J" << mapping.stick; + + // hat description + if (mapping.hat != CTRL_NONE) + { + buf << "/H" << mapping.hat; + switch (mapping.hdir) + { + case JoyHat::UP: buf << "/up"; break; + case JoyHat::DOWN: buf << "/down"; break; + case JoyHat::LEFT: buf << "/left"; break; + case JoyHat::RIGHT: buf << "/right"; break; + default: break; + } + } + + + return buf.str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string JoyHatMap::getDesc(const Event::Type event, const EventMode mode, const int hat, const JoyHat hdir) const +{ + return getDesc(event, JoyHatMapping(mode, hat, hdir)); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string JoyHatMap::getEventMappingDesc(const Event::Type event, const EventMode mode) const +{ + ostringstream buf; + + for (auto item : myMap) + { + if (item.second == event && item.first.mode == mode) + { + if (buf.str() != "") + buf << ", "; + buf << getDesc(event, item.first); + } + } + return buf.str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +JoyHatMap::JoyHatMappingArray JoyHatMap::getEventMapping(const Event::Type event, const EventMode mode) const +{ + JoyHatMappingArray map; + + for (auto item : myMap) + if (item.second == event && item.first.mode == mode) + map.push_back(item.first); + + return map; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string JoyHatMap::saveMapping(const EventMode mode) const +{ + ostringstream buf; + + for (auto item : myMap) + { + if (item.first.mode == mode) + { + if (buf.str() != "") + buf << "|"; + buf << item.second << ":" /*<< item.first.stick*/ << "," << + item.first.hat << "," << int(item.first.hdir); + } + } + return buf.str(); +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +int JoyHatMap::loadMapping(string & list, const EventMode mode) +{ + // Since istringstream swallows whitespace, we have to make the + // delimiters be spaces + std::replace(list.begin(), list.end(), '|', ' '); + std::replace(list.begin(), list.end(), ':', ' '); + std::replace(list.begin(), list.end(), ',', ' '); + istringstream buf(list); + int event, stick, hat, hdir, i = 0; + + while (buf >> event && buf >> stick && buf >> hat && buf >> hdir && ++i) + add(Event::Type(event), EventMode(mode), hat, JoyHat(hdir)); + + return i; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void JoyHatMap::eraseMode(const EventMode mode) +{ + for (auto item = myMap.begin(); item != myMap.end();) + if (item->first.mode == mode) { + auto _item = item++; + erase(_item->first); + } + else item++; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void JoyHatMap::eraseEvent(const Event::Type event, const EventMode mode) +{ + for (auto item = myMap.begin(); item != myMap.end();) + if (item->second == event && item->first.mode == mode) { + auto _item = item++; + erase(_item->first); + } + else item++; +} diff --git a/src/common/JoyHatMap.hxx b/src/common/JoyHatMap.hxx new file mode 100644 index 000000000..bbee81baa --- /dev/null +++ b/src/common/JoyHatMap.hxx @@ -0,0 +1,109 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#ifndef JOYHATMAP_HXX +#define JOYHATMAP_HXX + +#include +#include "Event.hxx" +#include "EventHandlerConstants.hxx" + +/** + This class handles controller mappings in Stella. + + @author Thomas Jentzsch +*/ +class JoyHatMap +{ +public: + + struct JoyHatMapping + { + EventMode mode; + int hat; // hat number + JoyHat hdir; // hat direction (left/right/up/down) + + JoyHatMapping() + : mode(EventMode(0)), hat(0), hdir(JoyHat(0)) { } + JoyHatMapping(const JoyHatMapping& m) + : mode(m.mode), hat(m.hat), hdir(m.hdir) { } + explicit JoyHatMapping(EventMode c_mode, int c_hat, JoyHat c_hdir) + : mode(c_mode), hat(c_hat), hdir(c_hdir) { } + + bool operator==(const JoyHatMapping& other) const + { + return (mode == other.mode + && hat == other.hat + && hdir == other.hdir + ); + } + }; + using JoyHatMappingArray = std::vector; + + JoyHatMap(); + virtual ~JoyHatMap() = default; + + /** Add new mapping for given event */ + void add(const Event::Type event, const JoyHatMapping& mapping); + void add(const Event::Type event, const EventMode mode, const int hat, const JoyHat hdir); + + /** Erase mapping */ + void erase(const JoyHatMapping& mapping); + void erase(const EventMode mode, const int hat, const JoyHat hdir); + + /** Get event for mapping */ + Event::Type get(const JoyHatMapping& mapping) const; + Event::Type get(const EventMode mode, const int hat, const JoyHat hdir) const; + + /** Check if a mapping exists */ + bool check(const JoyHatMapping& mapping) const; + bool check(const EventMode mode, const int hat, const JoyHat hdir) const; + + /** Get mapping description */ + string getDesc(const Event::Type event, const JoyHatMapping& mapping) const; + string getDesc(const Event::Type event, const EventMode mode, const int hat, const JoyHat hdir) const; + + /** Get the mapping description(s) for given event and mode */ + string getEventMappingDesc(const Event::Type event, const EventMode mode) const; + + JoyHatMappingArray getEventMapping(const Event::Type event, const EventMode mode) const; + + string saveMapping(const EventMode mode) const; + int loadMapping(string& list, const EventMode mode); + + /** Erase all mappings for given mode */ + void eraseMode(const EventMode mode); + /** Erase given event's mapping for given mode */ + void eraseEvent(const Event::Type event, const EventMode mode); + /** clear all mappings for a modes */ + // void clear() { myMap.clear(); } + size_t size() { return myMap.size(); } + +private: + struct JoyHatHash { + size_t operator()(const JoyHatMapping& m)const { + return std::hash()((uInt64(m.mode)) // 3 bit + ^ ((uInt64(m.hat)) << 3) // 1 bit + ^ ((uInt64(m.hdir)) << 4) // 2 bits + ); + } + }; + + std::unordered_map myMap; +}; + +#endif diff --git a/src/common/ControllerMap.cxx b/src/common/JoyMap.cxx similarity index 57% rename from src/common/ControllerMap.cxx rename to src/common/JoyMap.cxx index fca8511d4..48754aa98 100644 --- a/src/common/ControllerMap.cxx +++ b/src/common/JoyMap.cxx @@ -15,41 +15,47 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ -#include "ControllerMap.hxx" +#include "JoyMap.hxx" + +// TODOs +// - two maps per controller (joydirs, hatdirs) +// - both maps combined with buttons +// - directions can work alone and with a button combination +// - buttons can work without a direction (mapped in joydir) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -ControllerMap::ControllerMap(void) +JoyMap::JoyMap(void) { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ControllerMap::add(const Event::Type event, const ControllerMapping& mapping) +void JoyMap::add(const Event::Type event, const JoyMapping& mapping) { myMap[mapping] = event; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ControllerMap::add(const Event::Type event, const EventMode mode, const int stick, const int button, - const JoyAxis axis, const JoyDir adir, const int hat, const JoyHat hdir) +void JoyMap::add(const Event::Type event, const EventMode mode, const int button, + const JoyAxis axis, const JoyDir adir) { - add(event, ControllerMapping(mode, stick, button, axis, adir, hat, hdir)); + add(event, JoyMapping(mode, button, axis, adir)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ControllerMap::erase(const ControllerMapping& mapping) +void JoyMap::erase(const JoyMapping& mapping) { myMap.erase(mapping); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ControllerMap::erase(const EventMode mode, const int stick, const int button, - const JoyAxis axis, const JoyDir adir, const int hat, const JoyHat hdir) +void JoyMap::erase(const EventMode mode, const int button, + const JoyAxis axis, const JoyDir adir) { - erase(ControllerMapping(mode, stick, button, axis, adir, hat, hdir)); + erase(JoyMapping(mode, button, axis, adir)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Event::Type ControllerMap::get(const ControllerMapping& mapping) const +Event::Type JoyMap::get(const JoyMapping& mapping) const { auto find = myMap.find(mapping); if (find != myMap.end()) @@ -59,14 +65,14 @@ Event::Type ControllerMap::get(const ControllerMapping& mapping) const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Event::Type ControllerMap::get(const EventMode mode, const int stick, const int button, - const JoyAxis axis, const JoyDir adir, const int hat, const JoyHat hdir) const +Event::Type JoyMap::get(const EventMode mode, const int button, + const JoyAxis axis, const JoyDir adir) const { - return get(ControllerMapping(mode, stick, button, axis, adir, hat, hdir)); + return get(JoyMapping(mode, button, axis, adir)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool ControllerMap::check(const ControllerMapping & mapping) const +bool JoyMap::check(const JoyMapping & mapping) const { auto find = myMap.find(mapping); @@ -74,18 +80,18 @@ bool ControllerMap::check(const ControllerMapping & mapping) const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool ControllerMap::check(const EventMode mode, const int stick, const int button, - const JoyAxis axis, const JoyDir adir, const int hat, const JoyHat hdir) const +bool JoyMap::check(const EventMode mode, const int button, + const JoyAxis axis, const JoyDir adir) const { - return check(ControllerMapping(mode, stick, button, axis, adir, hat, hdir)); + return check(JoyMapping(mode, button, axis, adir)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string ControllerMap::getDesc(const Event::Type event, const ControllerMapping& mapping) const +string JoyMap::getDesc(const Event::Type event, const JoyMapping& mapping) const { ostringstream buf; - buf << "J" << mapping.stick; + //buf << "J" << mapping.stick; // button description if (mapping.button != CTRL_NONE) @@ -94,7 +100,7 @@ string ControllerMap::getDesc(const Event::Type event, const ControllerMapping& // axis description if (int(mapping.axis) != CTRL_NONE) { - buf << "/A" << mapping.hat; + buf << "/A"; switch (mapping.axis) { case JoyAxis::X: buf << "X"; break; @@ -110,33 +116,18 @@ string ControllerMap::getDesc(const Event::Type event, const ControllerMapping& buf << "+"; } - // hat description - if (mapping.hat != CTRL_NONE) - { - buf << "/H" << mapping.hat; - switch (mapping.hdir) - { - case JoyHat::UP: buf << "/up"; break; - case JoyHat::DOWN: buf << "/down"; break; - case JoyHat::LEFT: buf << "/left"; break; - case JoyHat::RIGHT: buf << "/right"; break; - default: break; - } - } - - return buf.str(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string ControllerMap::getDesc(const Event::Type event, const EventMode mode, const int stick, const int button, - const JoyAxis axis, const JoyDir adir, const int hat, const JoyHat hdir) const +string JoyMap::getDesc(const Event::Type event, const EventMode mode, const int button, + const JoyAxis axis, const JoyDir adir) const { - return getDesc(event, ControllerMapping(mode, stick, button, axis, adir, hat, hdir)); + return getDesc(event, JoyMapping(mode, button, axis, adir)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string ControllerMap::getEventMappingDesc(const Event::Type event, const EventMode mode) const +string JoyMap::getEventMappingDesc(const Event::Type event, const EventMode mode) const { ostringstream buf; @@ -153,9 +144,9 @@ string ControllerMap::getEventMappingDesc(const Event::Type event, const EventMo } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -ControllerMap::ControllerMappingArray ControllerMap::getEventMapping(const Event::Type event, const EventMode mode) const +JoyMap::JoyMappingArray JoyMap::getEventMapping(const Event::Type event, const EventMode mode) const { - ControllerMappingArray map; + JoyMappingArray map; for (auto item : myMap) if (item.second == event && item.first.mode == mode) @@ -165,7 +156,7 @@ ControllerMap::ControllerMappingArray ControllerMap::getEventMapping(const Event } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string ControllerMap::saveMapping(const EventMode mode) const +string JoyMap::saveMapping(const EventMode mode) const { ostringstream buf; @@ -175,15 +166,15 @@ string ControllerMap::saveMapping(const EventMode mode) const { if (buf.str() != "") buf << "|"; - buf << item.second << ":" << item.first.stick << "," << item.first.button << "," - << int(item.first.axis) << "," << int(item.first.adir) << "," << item.first.hat << "," << int(item.first.hdir); + buf << item.second << ":" /*<< item.first.stick*/ << "," << item.first.button << "," + << int(item.first.axis) << "," << int(item.first.adir); } } return buf.str(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -int ControllerMap::loadMapping(string& list, const EventMode mode) +int JoyMap::loadMapping(string& list, const EventMode mode) { // Since istringstream swallows whitespace, we have to make the // delimiters be spaces @@ -191,17 +182,17 @@ int ControllerMap::loadMapping(string& list, const EventMode mode) std::replace(list.begin(), list.end(), ':', ' '); std::replace(list.begin(), list.end(), ',', ' '); istringstream buf(list); - int event, stick, button, axis, adir, hat, hdir, i = 0; + int event, stick, button, axis, adir, i = 0; while (buf >> event && buf >> stick && buf >> button - && buf >> axis && buf >> adir && buf >> hat && buf >> hdir && ++i) - add(Event::Type(event), EventMode(mode), stick, button, JoyAxis(axis), JoyDir(adir), hat, JoyHat(hdir)); + && buf >> axis && buf >> adir && ++i) + add(Event::Type(event), EventMode(mode), button, JoyAxis(axis), JoyDir(adir)); return i; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ControllerMap::eraseMode(const EventMode mode) +void JoyMap::eraseMode(const EventMode mode) { for (auto item = myMap.begin(); item != myMap.end();) if (item->first.mode == mode) { @@ -212,7 +203,7 @@ void ControllerMap::eraseMode(const EventMode mode) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void ControllerMap::eraseEvent(const Event::Type event, const EventMode mode) +void JoyMap::eraseEvent(const Event::Type event, const EventMode mode) { for (auto item = myMap.begin(); item != myMap.end();) if (item->second == event && item->first.mode == mode) { diff --git a/src/common/JoyMap.hxx b/src/common/JoyMap.hxx new file mode 100644 index 000000000..ebd145d6d --- /dev/null +++ b/src/common/JoyMap.hxx @@ -0,0 +1,121 @@ +//============================================================================ +// +// SSSS tt lll lll +// SS SS tt ll ll +// SS tttttt eeee ll ll aaaa +// SSSS tt ee ee ll ll aa +// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator" +// SS SS tt ee ll ll aa aa +// SSSS ttt eeeee llll llll aaaaa +// +// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony +// and the Stella Team +// +// See the file "License.txt" for information on usage and redistribution of +// this file, and for a DISCLAIMER OF ALL WARRANTIES. +//============================================================================ + +#ifndef CONTROLLERMAP_HXX +#define CONTROLLERMAP_HXX + +#include +#include "Event.hxx" +#include "EventHandlerConstants.hxx" + +/** + This class handles controller mappings in Stella. + + @author Thomas Jentzsch +*/ +class JoyMap +{ + public: + + struct JoyMapping + { + EventMode mode; + int button; // button number + JoyAxis axis; // horizontal/vertical + JoyDir adir; // axis direction (neg/pos) + + JoyMapping() + : mode(EventMode(0)), button(0), + axis(JoyAxis(0)), adir(JoyDir(0)) { } + JoyMapping(const JoyMapping& m) + : mode(m.mode), button(m.button), + axis(m.axis), adir(m.adir) { } + explicit JoyMapping(EventMode c_mode, int c_button, + JoyAxis c_axis, JoyDir c_adir) + : mode(c_mode), button(c_button), + axis(c_axis), adir(c_adir) { } + + bool operator==(const JoyMapping& other) const + { + return (mode == other.mode + && button == other.button + && axis == other.axis + && adir == other.adir + ); + } + }; + using JoyMappingArray = std::vector; + + JoyMap(); + virtual ~JoyMap() = default; + + /** Add new mapping for given event */ + void add(const Event::Type event, const JoyMapping& mapping); + void add(const Event::Type event, const EventMode mode, const int button, + const JoyAxis axis, const JoyDir adir); + + /** Erase mapping */ + void erase(const JoyMapping& mapping); + void erase(const EventMode mode, const int button, + const JoyAxis axis, const JoyDir adir); + + /** Get event for mapping */ + Event::Type get(const JoyMapping& mapping) const; + Event::Type get(const EventMode mode, const int button, + const JoyAxis axis, const JoyDir adir) const; + + /** Check if a mapping exists */ + bool check(const JoyMapping& mapping) const; + bool check(const EventMode mode, const int button, + const JoyAxis axis, const JoyDir adir) const; + + /** Get mapping description */ + string getDesc(const Event::Type event, const JoyMapping& mapping) const; + string getDesc(const Event::Type event, const EventMode mode, const int button, + const JoyAxis axis, const JoyDir adir) const; + + /** Get the mapping description(s) for given event and mode */ + string getEventMappingDesc(const Event::Type event, const EventMode mode) const; + + JoyMappingArray getEventMapping(const Event::Type event, const EventMode mode) const; + + string saveMapping(const EventMode mode) const; + int loadMapping(string& list, const EventMode mode); + + /** Erase all mappings for given mode */ + void eraseMode(const EventMode mode); + /** Erase given event's mapping for given mode */ + void eraseEvent(const Event::Type event, const EventMode mode); + /** clear all mappings for a modes */ + // void clear() { myMap.clear(); } + size_t size() { return myMap.size(); } + + private: + struct JoyHash { + size_t operator()(const JoyMapping& m)const { + return std::hash()((uInt64(m.mode)) // 3 bit + ^ ((uInt64(m.button)) << 2) // 2 bits + ^ ((uInt64(m.axis)) << 4) // 1 bit + ^ ((uInt64(m.adir)) << 5) // 1 bit + ); + } + }; + + std::unordered_map myMap; +}; + +#endif diff --git a/src/common/PJoystickHandler.cxx b/src/common/PJoystickHandler.cxx index fb8f1e18c..d38746203 100644 --- a/src/common/PJoystickHandler.cxx +++ b/src/common/PJoystickHandler.cxx @@ -480,7 +480,7 @@ bool PhysicalJoystickHandler::addAxisMapping(Event::Type event, EventMode mode, if(Event::isAnalog(j->axisTable[axis][int(JoyDir::POS)][mode])) j->axisTable[axis][int(JoyDir::POS)][mode] = Event::NoType; - j->axisTable[axis][(value > int(JoyDir::NEG))][mode] = event; + j->axisTable[axis][int(value > 0 ? JoyDir::POS : JoyDir::NEG)][mode] = event; } return true; } @@ -522,13 +522,22 @@ bool PhysicalJoystickHandler::addHatMapping(Event::Type event, EventMode mode, } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PhysicalJoystickHandler::addMapping(Event::Type event, EventMode mode, int stick, - int button, JoyAxis axis, JoyDir adir, int hat, JoyHat hdir) +void PhysicalJoystickHandler::addJoyMapping(Event::Type event, EventMode mode, int stick, + int button, JoyAxis axis, JoyDir adir) { - myControllerMap.add(event, mode, stick, button, axis, adir, hat, hdir); + const PhysicalJoystickPtr j = joy(stick); + j->joyMap.add(event, mode, button, axis, adir); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void PhysicalJoystickHandler::addJoyHatMapping(Event::Type event, EventMode mode, int stick, + int hat, JoyHat hdir) +{ + const PhysicalJoystickPtr j = joy(stick); + + j->joyHatMap.add(event, mode, hat, hdir); +} // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void PhysicalJoystickHandler::handleAxisEvent(int stick, int axis, int value) diff --git a/src/common/PJoystickHandler.hxx b/src/common/PJoystickHandler.hxx index b8bc447a6..f24c85dc3 100644 --- a/src/common/PJoystickHandler.hxx +++ b/src/common/PJoystickHandler.hxx @@ -28,7 +28,6 @@ class Event; #include "EventHandlerConstants.hxx" #include "PhysicalJoystick.hxx" #include "Variant.hxx" -#include "ControllerMap.hxx" using PhysicalJoystickPtr = shared_ptr; @@ -80,10 +79,10 @@ class PhysicalJoystickHandler bool addHatMapping(Event::Type event, EventMode mode, int stick, int hat, JoyHat value); // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void addMapping(Event::Type event, EventMode mode, int stick, - int button, JoyAxis axis, JoyDir adir, int hat, JoyHat hdir); - - + void addJoyMapping(Event::Type event, EventMode mode, int stick, + int button, JoyAxis axis, JoyDir adir); + void addJoyHatMapping(Event::Type event, EventMode mode, int stick, + int hat, JoyHat hdir); /** Handle a physical joystick event. */ void handleAxisEvent(int stick, int axis, int value); @@ -140,9 +139,6 @@ class PhysicalJoystickHandler static const Event::Type SA_Axis[NUM_PORTS][NUM_JOY_AXIS]; static const Event::Type SA_Button[NUM_PORTS][NUM_JOY_BTN]; static const Event::Type SA_Key[NUM_PORTS][NUM_KEY_BTN]; - - // Hashmap of controller events - ControllerMap myControllerMap; }; #endif diff --git a/src/common/PhysicalJoystick.hxx b/src/common/PhysicalJoystick.hxx index dd7872d30..94a7b1e76 100644 --- a/src/common/PhysicalJoystick.hxx +++ b/src/common/PhysicalJoystick.hxx @@ -20,6 +20,8 @@ #include "Event.hxx" #include "EventHandlerConstants.hxx" +#include "JoyMap.hxx" +#include "JoyHatMap.hxx" /** An abstraction of a physical (real) joystick in Stella. @@ -70,6 +72,10 @@ class PhysicalJoystick Event::Type (*hatTable)[NUM_JOY_HAT_DIRS][kNumModes]; int* axisLastValue; + // Hashmaps of controller events + JoyMap joyMap; + JoyHatMap joyHatMap; + private: void getValues(const string& list, IntArray& map) const; diff --git a/src/common/module.mk b/src/common/module.mk index 9c9f5c08a..e61dc12fc 100644 --- a/src/common/module.mk +++ b/src/common/module.mk @@ -6,7 +6,8 @@ MODULE_OBJS := \ src/common/FBSurfaceSDL2.o \ src/common/FrameBufferSDL2.o \ src/common/FSNodeZIP.o \ - src/common/ControllerMap.o \ + src/common/JoyMap.o \ + src/common/JoyHatMap.o \ src/common/KeyMap.o \ src/common/Logger.o \ src/common/main.o \ diff --git a/src/windows/Stella.vcxproj b/src/windows/Stella.vcxproj index a57bcf2c5..378b7b4f2 100644 --- a/src/windows/Stella.vcxproj +++ b/src/windows/Stella.vcxproj @@ -376,7 +376,8 @@ - + + @@ -1074,7 +1075,8 @@ - + + diff --git a/src/windows/Stella.vcxproj.filters b/src/windows/Stella.vcxproj.filters index bde453361..f713f1dd2 100644 --- a/src/windows/Stella.vcxproj.filters +++ b/src/windows/Stella.vcxproj.filters @@ -978,7 +978,10 @@ Source Files\gui - + + Source Files + + Source Files @@ -2003,7 +2006,10 @@ Header Files - + + Header Files + + Header Files From d4ae525baf7268e547ef8b34189eee37b5047d33 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Fri, 21 Jun 2019 21:11:52 +0200 Subject: [PATCH 09/18] implement rudimentary mapping --- src/common/JoyHatMap.cxx | 37 +++-- src/common/JoyHatMap.hxx | 34 +++-- src/common/JoyMap.cxx | 23 +-- src/common/JoyMap.hxx | 14 +- src/common/PJoystickHandler.cxx | 204 ++++++++++++++++---------- src/common/PJoystickHandler.hxx | 23 +-- src/common/PhysicalJoystick.cxx | 62 +++++--- src/common/PhysicalJoystick.hxx | 6 +- src/emucore/EventHandler.cxx | 35 ++++- src/emucore/EventHandler.hxx | 14 +- src/emucore/EventHandlerConstants.hxx | 5 +- src/gui/EventMappingWidget.cxx | 72 ++++++--- src/gui/EventMappingWidget.hxx | 5 +- src/gui/InputDialog.cxx | 12 ++ src/gui/InputDialog.hxx | 1 + 15 files changed, 369 insertions(+), 178 deletions(-) diff --git a/src/common/JoyHatMap.cxx b/src/common/JoyHatMap.cxx index ea6480dc9..a000eb9c2 100644 --- a/src/common/JoyHatMap.cxx +++ b/src/common/JoyHatMap.cxx @@ -35,9 +35,10 @@ void JoyHatMap::add(const Event::Type event, const JoyHatMapping& mapping) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void JoyHatMap::add(const Event::Type event, const EventMode mode, const int hat, const JoyHat hdir) +void JoyHatMap::add(const Event::Type event, const EventMode mode, + const int button, const int hat, const JoyHat hdir) { - add(event, JoyHatMapping(mode, hat, hdir)); + add(event, JoyHatMapping(mode, button, hat, hdir)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -47,9 +48,10 @@ void JoyHatMap::erase(const JoyHatMapping& mapping) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void JoyHatMap::erase(const EventMode mode, const int hat, const JoyHat hdir) +void JoyHatMap::erase(const EventMode mode, + const int button, const int hat, const JoyHat hdir) { - erase(JoyHatMapping(mode, hat, hdir)); + erase(JoyHatMapping(mode, button, hat, hdir)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -63,9 +65,10 @@ Event::Type JoyHatMap::get(const JoyHatMapping& mapping) const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -Event::Type JoyHatMap::get(const EventMode mode, const int hat, const JoyHat hdir) const +Event::Type JoyHatMap::get(const EventMode mode, + const int button, const int hat, const JoyHat hdir) const { - return get(JoyHatMapping(mode, hat, hdir)); + return get(JoyHatMapping(mode, button, hat, hdir)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -77,9 +80,10 @@ bool JoyHatMap::check(const JoyHatMapping & mapping) const } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool JoyHatMap::check(const EventMode mode, const int hat, const JoyHat hdir) const +bool JoyHatMap::check(const EventMode mode, + const int button, const int hat, const JoyHat hdir) const { - return check(JoyHatMapping(mode, hat, hdir)); + return check(JoyHatMapping(mode, button, hat, hdir)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -90,7 +94,7 @@ string JoyHatMap::getDesc(const Event::Type event, const JoyHatMapping & mapping //buf << "J" << mapping.stick; // hat description - if (mapping.hat != CTRL_NONE) + if (mapping.hat != JOY_CTRL_NONE) { buf << "/H" << mapping.hat; switch (mapping.hdir) @@ -108,13 +112,14 @@ string JoyHatMap::getDesc(const Event::Type event, const JoyHatMapping & mapping } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string JoyHatMap::getDesc(const Event::Type event, const EventMode mode, const int hat, const JoyHat hdir) const +string JoyHatMap::getDesc(const Event::Type event, const EventMode mode, + const int button, const int hat, const JoyHat hdir) const { - return getDesc(event, JoyHatMapping(mode, hat, hdir)); + return getDesc(event, JoyHatMapping(mode, button, hat, hdir)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string JoyHatMap::getEventMappingDesc(const Event::Type event, const EventMode mode) const +string JoyHatMap::getEventMappingDesc(const int stick, const Event::Type event, const EventMode mode) const { ostringstream buf; @@ -124,7 +129,7 @@ string JoyHatMap::getEventMappingDesc(const Event::Type event, const EventMode m { if (buf.str() != "") buf << ", "; - buf << getDesc(event, item.first); + buf << "J" << stick << getDesc(event, item.first); } } return buf.str(); @@ -169,10 +174,10 @@ int JoyHatMap::loadMapping(string & list, const EventMode mode) std::replace(list.begin(), list.end(), ':', ' '); std::replace(list.begin(), list.end(), ',', ' '); istringstream buf(list); - int event, stick, hat, hdir, i = 0; + int event, stick, button, hat, hdir, i = 0; - while (buf >> event && buf >> stick && buf >> hat && buf >> hdir && ++i) - add(Event::Type(event), EventMode(mode), hat, JoyHat(hdir)); + while (buf >> event && buf >> stick && buf >> button && buf >> hat && buf >> hdir && ++i) + add(Event::Type(event), EventMode(mode), button, hat, JoyHat(hdir)); return i; } diff --git a/src/common/JoyHatMap.hxx b/src/common/JoyHatMap.hxx index bbee81baa..71f14eb8e 100644 --- a/src/common/JoyHatMap.hxx +++ b/src/common/JoyHatMap.hxx @@ -34,19 +34,21 @@ public: struct JoyHatMapping { EventMode mode; + int button; // button number int hat; // hat number JoyHat hdir; // hat direction (left/right/up/down) JoyHatMapping() - : mode(EventMode(0)), hat(0), hdir(JoyHat(0)) { } + : mode(EventMode(0)), button(0), hat(0), hdir(JoyHat(0)) { } JoyHatMapping(const JoyHatMapping& m) - : mode(m.mode), hat(m.hat), hdir(m.hdir) { } - explicit JoyHatMapping(EventMode c_mode, int c_hat, JoyHat c_hdir) - : mode(c_mode), hat(c_hat), hdir(c_hdir) { } + : mode(m.mode), button(m.button), hat(m.hat), hdir(m.hdir) { } + explicit JoyHatMapping(EventMode c_mode, int c_button, int c_hat, JoyHat c_hdir) + : mode(c_mode), button(c_button), hat(c_hat), hdir(c_hdir) { } bool operator==(const JoyHatMapping& other) const { return (mode == other.mode + && button == other.button && hat == other.hat && hdir == other.hdir ); @@ -59,26 +61,31 @@ public: /** Add new mapping for given event */ void add(const Event::Type event, const JoyHatMapping& mapping); - void add(const Event::Type event, const EventMode mode, const int hat, const JoyHat hdir); + void add(const Event::Type event, const EventMode mode, + const int button, const int hat, const JoyHat hdir); /** Erase mapping */ void erase(const JoyHatMapping& mapping); - void erase(const EventMode mode, const int hat, const JoyHat hdir); + void erase(const EventMode mode, + const int button, const int hat, const JoyHat hdir); /** Get event for mapping */ Event::Type get(const JoyHatMapping& mapping) const; - Event::Type get(const EventMode mode, const int hat, const JoyHat hdir) const; + Event::Type get(const EventMode mode, + const int button, const int hat, const JoyHat hdir) const; /** Check if a mapping exists */ bool check(const JoyHatMapping& mapping) const; - bool check(const EventMode mode, const int hat, const JoyHat hdir) const; + bool check(const EventMode mode, + const int button, const int hat, const JoyHat hdir) const; /** Get mapping description */ string getDesc(const Event::Type event, const JoyHatMapping& mapping) const; - string getDesc(const Event::Type event, const EventMode mode, const int hat, const JoyHat hdir) const; + string getDesc(const Event::Type event, const EventMode mode, + const int button, const int hat, const JoyHat hdir) const; - /** Get the mapping description(s) for given event and mode */ - string getEventMappingDesc(const Event::Type event, const EventMode mode) const; + /** Get the mapping description(s) for given stick, event and mode */ + string getEventMappingDesc(const int stick, const Event::Type event, const EventMode mode) const; JoyHatMappingArray getEventMapping(const Event::Type event, const EventMode mode) const; @@ -97,8 +104,9 @@ private: struct JoyHatHash { size_t operator()(const JoyHatMapping& m)const { return std::hash()((uInt64(m.mode)) // 3 bit - ^ ((uInt64(m.hat)) << 3) // 1 bit - ^ ((uInt64(m.hdir)) << 4) // 2 bits + ^ ((uInt64(m.button)) << 3) // 2 bits + ^ ((uInt64(m.hat)) << 5) // 1 bit + ^ ((uInt64(m.hdir)) << 6) // 2 bits ); } }; diff --git a/src/common/JoyMap.cxx b/src/common/JoyMap.cxx index 48754aa98..311b552da 100644 --- a/src/common/JoyMap.cxx +++ b/src/common/JoyMap.cxx @@ -36,7 +36,7 @@ void JoyMap::add(const Event::Type event, const JoyMapping& mapping) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void JoyMap::add(const Event::Type event, const EventMode mode, const int button, - const JoyAxis axis, const JoyDir adir) + const JoyAxis axis, const JoyDir adir) { add(event, JoyMapping(mode, button, axis, adir)); } @@ -49,7 +49,7 @@ void JoyMap::erase(const JoyMapping& mapping) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void JoyMap::erase(const EventMode mode, const int button, - const JoyAxis axis, const JoyDir adir) + const JoyAxis axis, const JoyDir adir) { erase(JoyMapping(mode, button, axis, adir)); } @@ -66,7 +66,7 @@ Event::Type JoyMap::get(const JoyMapping& mapping) const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Event::Type JoyMap::get(const EventMode mode, const int button, - const JoyAxis axis, const JoyDir adir) const + const JoyAxis axis, const JoyDir adir) const { return get(JoyMapping(mode, button, axis, adir)); } @@ -81,7 +81,7 @@ bool JoyMap::check(const JoyMapping & mapping) const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool JoyMap::check(const EventMode mode, const int button, - const JoyAxis axis, const JoyDir adir) const + const JoyAxis axis, const JoyDir adir) const { return check(JoyMapping(mode, button, axis, adir)); } @@ -94,18 +94,19 @@ string JoyMap::getDesc(const Event::Type event, const JoyMapping& mapping) const //buf << "J" << mapping.stick; // button description - if (mapping.button != CTRL_NONE) + if (mapping.button != JOY_CTRL_NONE) buf << "/B" << mapping.button; // axis description - if (int(mapping.axis) != CTRL_NONE) + if (mapping.axis != JoyAxis::NONE) { buf << "/A"; switch (mapping.axis) { case JoyAxis::X: buf << "X"; break; case JoyAxis::Y: buf << "Y"; break; - default: break; + case JoyAxis::Z: buf << "Z"; break; + default: buf << int(mapping.axis); break; } if (Event::isAnalog(event)) @@ -121,13 +122,13 @@ string JoyMap::getDesc(const Event::Type event, const JoyMapping& mapping) const // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string JoyMap::getDesc(const Event::Type event, const EventMode mode, const int button, - const JoyAxis axis, const JoyDir adir) const + const JoyAxis axis, const JoyDir adir) const { return getDesc(event, JoyMapping(mode, button, axis, adir)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string JoyMap::getEventMappingDesc(const Event::Type event, const EventMode mode) const +string JoyMap::getEventMappingDesc(int stick, const Event::Type event, const EventMode mode) const { ostringstream buf; @@ -137,7 +138,7 @@ string JoyMap::getEventMappingDesc(const Event::Type event, const EventMode mode { if (buf.str() != "") buf << ", "; - buf << getDesc(event, item.first); + buf << "J" << stick << getDesc(event, item.first); } } return buf.str(); @@ -166,7 +167,7 @@ string JoyMap::saveMapping(const EventMode mode) const { if (buf.str() != "") buf << "|"; - buf << item.second << ":" /*<< item.first.stick*/ << "," << item.first.button << "," + buf << item.second << ":" << item.first.button << "," << int(item.first.axis) << "," << int(item.first.adir); } } diff --git a/src/common/JoyMap.hxx b/src/common/JoyMap.hxx index ebd145d6d..095a5c04f 100644 --- a/src/common/JoyMap.hxx +++ b/src/common/JoyMap.hxx @@ -66,30 +66,30 @@ class JoyMap /** Add new mapping for given event */ void add(const Event::Type event, const JoyMapping& mapping); void add(const Event::Type event, const EventMode mode, const int button, - const JoyAxis axis, const JoyDir adir); + const JoyAxis axis, const JoyDir adir); /** Erase mapping */ void erase(const JoyMapping& mapping); void erase(const EventMode mode, const int button, - const JoyAxis axis, const JoyDir adir); + const JoyAxis axis, const JoyDir adir); /** Get event for mapping */ Event::Type get(const JoyMapping& mapping) const; Event::Type get(const EventMode mode, const int button, - const JoyAxis axis, const JoyDir adir) const; + const JoyAxis axis = JoyAxis::NONE, const JoyDir adir = JoyDir::NONE) const; /** Check if a mapping exists */ bool check(const JoyMapping& mapping) const; bool check(const EventMode mode, const int button, - const JoyAxis axis, const JoyDir adir) const; + const JoyAxis axis, const JoyDir adir) const; /** Get mapping description */ string getDesc(const Event::Type event, const JoyMapping& mapping) const; string getDesc(const Event::Type event, const EventMode mode, const int button, - const JoyAxis axis, const JoyDir adir) const; + const JoyAxis axis, const JoyDir adir) const; - /** Get the mapping description(s) for given event and mode */ - string getEventMappingDesc(const Event::Type event, const EventMode mode) const; + /** Get the mapping description(s) for given stick, event and mode */ + string getEventMappingDesc(int stick, const Event::Type event, const EventMode mode) const; JoyMappingArray getEventMapping(const Event::Type event, const EventMode mode) const; diff --git a/src/common/PJoystickHandler.cxx b/src/common/PJoystickHandler.cxx index d38746203..47d598c95 100644 --- a/src/common/PJoystickHandler.cxx +++ b/src/common/PJoystickHandler.cxx @@ -41,7 +41,7 @@ PhysicalJoystickHandler::PhysicalJoystickHandler( // First compare if event list version has changed, and disregard the entire mapping if true getline(buf, joymap, '^'); // event list size, ignore - if(version == Event::VERSION) + if(version != Event::VERSION) { // Otherwise, put each joystick mapping entry into the database while(getline(buf, joymap, '^')) @@ -251,20 +251,29 @@ void PhysicalJoystickHandler::setStickDefaultMapping(int stick, { bool eraseAll = (event == Event::NoType); - auto setDefaultAxis = [&](int a_stick, JoyAxis a_axis, JoyDir a_value, Event::Type a_event) + auto setDefaultAxis = [&](Event::Type a_event, int stick, JoyAxis axis, JoyDir value, int button = JOY_CTRL_NONE) { - if(eraseAll || a_event == event) - myHandler.addJoyAxisMapping(a_event, mode, a_stick, int(a_axis), int(a_value), false); + if (eraseAll || a_event == event) + { + //myHandler.addJoyAxisMapping(a_event, mode, stick, int(axis), int(value), false); + myHandler.addJoyMapping(a_event, mode, stick, button, axis, int(value), false); + } }; - auto setDefaultBtn = [&](int b_stick, int b_button, Event::Type b_event) + auto setDefaultBtn = [&](Event::Type b_event, int stick, int button) { - if(eraseAll || b_event == event) - myHandler.addJoyButtonMapping(b_event, mode, b_stick, b_button, false); + if (eraseAll || b_event == event) + { + //myHandler.addJoyButtonMapping(b_event, mode, stick, button, false); + myHandler.addJoyMapping(b_event, mode, stick, button, JoyAxis::NONE, int(JoyDir::NONE), false); + } }; - auto setDefaultHat = [&](int h_stick, int h_hat, JoyHat h_dir, Event::Type h_event) + auto setDefaultHat = [&](Event::Type h_event, int stick, int hat, JoyHat dir, int button = JOY_CTRL_NONE) { - if(eraseAll || h_event == event) - myHandler.addJoyHatMapping(h_event, mode, h_stick, h_hat, h_dir, false); + if (eraseAll || h_event == event) + { + //myHandler.addJoyHatMapping(h_event, mode, stick, hat, dir, false); + myHandler.addJoyHatMapping(h_event, mode, stick, button, hat, dir, false); + } }; switch(mode) @@ -275,54 +284,54 @@ void PhysicalJoystickHandler::setStickDefaultMapping(int stick, case 0: case 2: // Left joystick left/right directions (assume joystick zero or two) - setDefaultAxis(stick, JoyAxis::X, JoyDir::NEG, Event::JoystickZeroLeft); - setDefaultAxis(stick, JoyAxis::X, JoyDir::POS, Event::JoystickZeroRight); + setDefaultAxis(Event::JoystickZeroLeft, stick, JoyAxis::X, JoyDir::NEG); + setDefaultAxis(Event::JoystickZeroRight, stick, JoyAxis::X, JoyDir::POS); // Left joystick up/down directions (assume joystick zero or two) - setDefaultAxis(stick, JoyAxis::Y, JoyDir::NEG, Event::JoystickZeroUp); - setDefaultAxis(stick, JoyAxis::Y, JoyDir::POS, Event::JoystickZeroDown); + setDefaultAxis(Event::JoystickZeroUp, stick, JoyAxis::Y, JoyDir::NEG); + setDefaultAxis(Event::JoystickZeroDown, stick, JoyAxis::Y, JoyDir::POS); // Left joystick (assume joystick zero or two, buttons zero..two) - setDefaultBtn(stick, 0, Event::JoystickZeroFire); - setDefaultBtn(stick, 1, Event::JoystickZeroFire5); - setDefaultBtn(stick, 2, Event::JoystickZeroFire9); + setDefaultBtn(Event::JoystickZeroFire, stick, 0); + setDefaultBtn(Event::JoystickZeroFire5, stick, 1); + setDefaultBtn(Event::JoystickZeroFire9, stick, 2); // Left joystick left/right directions (assume joystick zero or two and hat 0) - setDefaultHat(stick, 0, JoyHat::LEFT, Event::JoystickZeroLeft); - setDefaultHat(stick, 0, JoyHat::RIGHT, Event::JoystickZeroRight); + setDefaultHat(Event::JoystickZeroLeft, stick, 0, JoyHat::LEFT); + setDefaultHat(Event::JoystickZeroRight, stick, 0, JoyHat::RIGHT); // Left joystick up/down directions (assume joystick zero or two and hat 0) - setDefaultHat(stick, 0, JoyHat::UP, Event::JoystickZeroUp); - setDefaultHat(stick, 0, JoyHat::DOWN, Event::JoystickZeroDown); + setDefaultHat(Event::JoystickZeroUp, stick, 0, JoyHat::UP); + setDefaultHat(Event::JoystickZeroDown, stick, 0, JoyHat::DOWN); #if defined(RETRON77) // Left joystick (assume joystick zero or two, buttons two..four) - setDefaultBtn(stick, 2, Event::CmdMenuMode); - setDefaultBtn(stick, 3, Event::OptionsMenuMode); - setDefaultBtn(stick, 4, Event::ExitMode); + setDefaultBtn(Event::CmdMenuMode, stick, 2); + setDefaultBtn(Event::OptionsMenuMode, stick, 3); + setDefaultBtn(Event::ExitMode, stick, 4); #endif break; case 1: case 3: // Right joystick left/right directions (assume joystick one or three) - setDefaultAxis(stick, JoyAxis::X, JoyDir::NEG, Event::JoystickOneLeft); - setDefaultAxis(stick, JoyAxis::X, JoyDir::POS, Event::JoystickOneRight); + setDefaultAxis(Event::JoystickOneLeft, stick, JoyAxis::X, JoyDir::NEG); + setDefaultAxis(Event::JoystickOneRight, stick, JoyAxis::X, JoyDir::POS); // Right joystick left/right directions (assume joystick one or three) - setDefaultAxis(stick, JoyAxis::Y, JoyDir::NEG, Event::JoystickOneUp); - setDefaultAxis(stick, JoyAxis::Y, JoyDir::POS, Event::JoystickOneDown); + setDefaultAxis(Event::JoystickOneUp, stick, JoyAxis::Y, JoyDir::NEG); + setDefaultAxis(Event::JoystickOneDown, stick, JoyAxis::Y, JoyDir::POS); // Right joystick (assume joystick one or three, buttons zero..two) - setDefaultBtn(stick, 0, Event::JoystickOneFire); - setDefaultBtn(stick, 1, Event::JoystickOneFire5); - setDefaultBtn(stick, 2, Event::JoystickOneFire9); + setDefaultBtn(Event::JoystickOneFire, stick, 0); + setDefaultBtn(Event::JoystickOneFire5, stick, 1); + setDefaultBtn(Event::JoystickOneFire9, stick, 2); // Right joystick left/right directions (assume joystick one or three and hat 0) - setDefaultHat(stick, 0, JoyHat::LEFT, Event::JoystickOneLeft); - setDefaultHat(stick, 0, JoyHat::RIGHT, Event::JoystickOneRight); + setDefaultHat(Event::JoystickOneLeft, stick, 0, JoyHat::LEFT); + setDefaultHat(Event::JoystickOneRight, stick, 0, JoyHat::RIGHT); // Right joystick up/down directions (assume joystick one or three and hat 0) - setDefaultHat(stick, 0, JoyHat::UP, Event::JoystickOneUp); - setDefaultHat(stick, 0, JoyHat::DOWN, Event::JoystickOneDown); + setDefaultHat(Event::JoystickOneUp, stick, 0, JoyHat::UP); + setDefaultHat(Event::JoystickOneDown, stick, 0, JoyHat::DOWN); #if defined(RETRON77) // Right joystick (assume joystick one or three, buttons two..four) - setDefaultBtn(stick, 2, Event::CmdMenuMode); - setDefaultBtn(stick, 3, Event::OptionsMenuMode); - setDefaultBtn(stick, 4, Event::ExitMode); - setDefaultBtn(stick, 5, Event::RewindPause); - setDefaultBtn(stick, 7, Event::ConsoleSelect); - setDefaultBtn(stick, 8, Event::ConsoleReset); + setDefaultBtn(Event::CmdMenuMode, stick, 2); + setDefaultBtn(Event::OptionsMenuMode, stick, 3); + setDefaultBtn(Event::ExitMode, stick, 4); + setDefaultBtn(Event::RewindPause, stick, 5); + setDefaultBtn(Event::ConsoleSelect, stick, 7); + setDefaultBtn(Event::ConsoleReset, stick, 8); #endif break; default: @@ -331,28 +340,27 @@ void PhysicalJoystickHandler::setStickDefaultMapping(int stick, break; case kMenuMode: // Default menu/UI events - setDefaultAxis( stick, JoyAxis::X, JoyDir::NEG, Event::UINavPrev ); - setDefaultAxis( stick, JoyAxis::X, JoyDir::POS, Event::UINavNext ); - setDefaultAxis( stick, JoyAxis::Y, JoyDir::NEG, Event::UIUp ); - setDefaultAxis( stick, JoyAxis::Y, JoyDir::POS, Event::UIDown ); + setDefaultAxis(Event::UINavPrev, stick, JoyAxis::X, JoyDir::NEG); + setDefaultAxis(Event::UINavNext, stick, JoyAxis::X, JoyDir::POS); + setDefaultAxis(Event::UIUp, stick, JoyAxis::Y, JoyDir::NEG); + setDefaultAxis(Event::UIDown, stick, JoyAxis::Y, JoyDir::POS); // joystick (assume buttons zero..three) - setDefaultBtn( stick, 0, Event::UISelect ); - setDefaultBtn( stick, 1, Event::UIOK ); - setDefaultBtn( stick, 2, Event::UITabNext); - setDefaultBtn( stick, 3, Event::UITabPrev ); - setDefaultBtn( stick, 5, Event::UICancel); + setDefaultBtn(Event::UISelect, stick, 0); + setDefaultBtn(Event::UIOK, stick, 1); + setDefaultBtn(Event::UITabNext, stick, 2); + setDefaultBtn(Event::UITabPrev, stick, 3); + setDefaultBtn(Event::UICancel, stick, 5); - setDefaultHat( stick, 0, JoyHat::LEFT, Event::UINavPrev ); - setDefaultHat( stick, 0, JoyHat::RIGHT, Event::UINavNext ); - setDefaultHat( stick, 0, JoyHat::UP, Event::UIUp ); - setDefaultHat( stick, 0, JoyHat::DOWN, Event::UIDown ); + setDefaultHat(Event::UINavPrev, stick, 0, JoyHat::LEFT); + setDefaultHat(Event::UINavNext, stick, 0, JoyHat::RIGHT); + setDefaultHat(Event::UIUp, stick, 0, JoyHat::UP); + setDefaultHat(Event::UIDown, stick, 0, JoyHat::DOWN); break; default: break; } - } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -378,13 +386,14 @@ void PhysicalJoystickHandler::saveMapping() // Save the joystick mapping hash table, making sure to update it with // any changes that have been made during the program run ostringstream joybuf; - joybuf << Event::LastType; + //joybuf << Event::LastType; for(const auto& i: myDatabase) { const string& map = i.second.joy ? i.second.joy->getMap() : i.second.mapping; if(map != "") - joybuf << "^" << map; + //joybuf << "^" << map; + joybuf << map; } myOSystem.settings().setValue("joymap", joybuf.str()); } @@ -400,7 +409,7 @@ string PhysicalJoystickHandler::getMappingDesc(Event::Type event, EventMode mode const PhysicalJoystickPtr j = s.second; if(!j) continue; - // Joystick button mapping/labeling + /*// Joystick button mapping/labeling for(int button = 0; button < j->numButtons; ++button) { if(j->btnTable[button][mode] == event) @@ -454,13 +463,21 @@ string PhysicalJoystickHandler::getMappingDesc(Event::Type event, EventMode mode } } } - } + }*/ + + // new: + //Joystick button + axis mapping / labeling + if (j->joyMap.getEventMapping(event, mode).size()) + buf << j->joyMap.getEventMappingDesc(stick, event, mode); + // Joystick hat mapping/labeling + if (j->joyHatMap.getEventMapping(event, mode).size()) + buf << j->joyHatMap.getEventMappingDesc(stick, event, mode); } return buf.str(); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool PhysicalJoystickHandler::addAxisMapping(Event::Type event, EventMode mode, +/*bool PhysicalJoystickHandler::addAxisMapping(Event::Type event, EventMode mode, int stick, int axis, int value) { const PhysicalJoystickPtr j = joy(stick); @@ -519,24 +536,55 @@ bool PhysicalJoystickHandler::addHatMapping(Event::Type event, EventMode mode, } } return false; -} +}*/ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PhysicalJoystickHandler::addJoyMapping(Event::Type event, EventMode mode, int stick, - int button, JoyAxis axis, JoyDir adir) +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool PhysicalJoystickHandler::addJoyMapping(Event::Type event, EventMode mode, int stick, + int button, JoyAxis axis, int value) { const PhysicalJoystickPtr j = joy(stick); - j->joyMap.add(event, mode, button, axis, adir); + if (j && event < Event::LastType && + button >= JOY_CTRL_NONE && button < j->numButtons && + axis >= JoyAxis::NONE && int(axis) < j->numAxes) + { + // This confusing code is because each axis has two associated values, + // but analog events only affect one of the axis. + if (Event::isAnalog(event)) + { + j->joyMap.add(event, mode, button, axis, JoyDir::NEG); + j->joyMap.add(event, mode, button, axis, JoyDir::POS); + } + else + { + // Otherwise, turn off the analog event(s) for this axis + if (Event::isAnalog(j->joyMap.get(mode, button, axis, JoyDir::NEG))) + j->joyMap.erase(mode, button, axis, JoyDir::NEG); + if (Event::isAnalog(j->joyMap.get(mode, button, axis, JoyDir::POS))) + j->joyMap.erase(mode, button, axis, JoyDir::POS); + + j->joyMap.add(event, mode, button, axis, value == int(JoyDir::NONE) ? JoyDir::NONE : value > 0 ? JoyDir::POS : JoyDir::NEG); + } + return true; + } + return false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PhysicalJoystickHandler::addJoyHatMapping(Event::Type event, EventMode mode, int stick, - int hat, JoyHat hdir) +bool PhysicalJoystickHandler::addJoyHatMapping(Event::Type event, EventMode mode, int stick, + int button, int hat, JoyHat dir) { const PhysicalJoystickPtr j = joy(stick); - j->joyHatMap.add(event, mode, hat, hdir); + if (j && event < Event::LastType && + button >= JOY_CTRL_NONE && button < j->numButtons && + hat >= 0 && hat < j->numHats && dir != JoyHat::CENTER) + { + j->joyHatMap.add(event, mode, button, hat, dir); + return true; + } + return false; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -552,8 +600,10 @@ void PhysicalJoystickHandler::handleAxisEvent(int stick, int axis, int value) if(myHandler.state() == EventHandlerState::EMULATION) { // Every axis event has two associated values, negative and positive - Event::Type eventAxisNeg = j->axisTable[axis][int(JoyDir::NEG)][kEmulationMode]; - Event::Type eventAxisPos = j->axisTable[axis][int(JoyDir::POS)][kEmulationMode]; + //Event::Type eventAxisNeg = j->axisTable[axis][int(JoyDir::NEG)][kEmulationMode]; + //Event::Type eventAxisPos = j->axisTable[axis][int(JoyDir::POS)][kEmulationMode]; + Event::Type eventAxisNeg = j->joyMap.get(kEmulationMode, j->buttonLast[stick], JoyAxis(axis), JoyDir::NEG); + Event::Type eventAxisPos = j->joyMap.get(kEmulationMode, j->buttonLast[stick], JoyAxis(axis), JoyDir::POS); // Check for analog events, which are handled differently // We'll pass them off as Stelladaptor events, and let the controllers @@ -646,19 +696,22 @@ void PhysicalJoystickHandler::handleAxisEvent(int stick, int axis, int value) void PhysicalJoystickHandler::handleBtnEvent(int stick, int button, bool pressed) { const PhysicalJoystickPtr j = joy(stick); - if(!j) return; + if(!j) return; + j->buttonLast[stick] = pressed ? button : JOY_CTRL_NONE; // Stelladaptors handle buttons differently than regular joysticks switch(j->type) { case PhysicalJoystick::JT_REGULAR: // Handle buttons which switch eventhandler state - if(pressed && myHandler.changeStateByEvent(j->btnTable[button][kEmulationMode])) + //if(pressed && myHandler.changeStateByEvent(j->btnTable[button][kEmulationMode])) + if (pressed && myHandler.changeStateByEvent(j->joyMap.get(kEmulationMode, button))) return; // Determine which mode we're in, then send the event to the appropriate place if(myHandler.state() == EventHandlerState::EMULATION) - myHandler.handleEvent(j->btnTable[button][kEmulationMode], pressed); + //myHandler.handleEvent(j->btnTable[button][kEmulationMode], pressed); + myHandler.handleEvent(j->joyMap.get(kEmulationMode, button), pressed); #ifdef GUI_SUPPORT else if(myHandler.hasOverlay()) myHandler.overlay().handleJoyBtnEvent(stick, button, pressed); @@ -718,14 +771,17 @@ void PhysicalJoystickHandler::handleHatEvent(int stick, int hat, int value) const PhysicalJoystickPtr j = joy(stick); if(!j) return; - myHandler.handleEvent(j->hatTable[hat][int(JoyHat::UP)][kEmulationMode], + /*myHandler.handleEvent(j->hatTable[hat][int(JoyHat::UP)][kEmulationMode], value & EVENT_HATUP_M); myHandler.handleEvent(j->hatTable[hat][int(JoyHat::RIGHT)][kEmulationMode], value & EVENT_HATRIGHT_M); myHandler.handleEvent(j->hatTable[hat][int(JoyHat::DOWN)][kEmulationMode], value & EVENT_HATDOWN_M); myHandler.handleEvent(j->hatTable[hat][int(JoyHat::LEFT)][kEmulationMode], - value & EVENT_HATLEFT_M); + value & EVENT_HATLEFT_M);*/ + + // TODO: 4 different events + myHandler.handleEvent(j->joyHatMap.get(kEmulationMode, JOY_CTRL_NONE, hat, JoyHat(value))); } #ifdef GUI_SUPPORT else if(myHandler.hasOverlay()) diff --git a/src/common/PJoystickHandler.hxx b/src/common/PJoystickHandler.hxx index f24c85dc3..ebd8e79f8 100644 --- a/src/common/PJoystickHandler.hxx +++ b/src/common/PJoystickHandler.hxx @@ -74,15 +74,15 @@ class PhysicalJoystickHandler string getMappingDesc(Event::Type, EventMode mode) const; /** Bind a physical joystick event to a virtual event/action. */ - bool addAxisMapping(Event::Type event, EventMode mode, int stick, int axis, int value); + /*bool addAxisMapping(Event::Type event, EventMode mode, int stick, int axis, int value); bool addBtnMapping(Event::Type event, EventMode mode, int stick, int button); - bool addHatMapping(Event::Type event, EventMode mode, int stick, int hat, JoyHat value); + bool addHatMapping(Event::Type event, EventMode mode, int stick, int hat, JoyHat value);*/ // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void addJoyMapping(Event::Type event, EventMode mode, int stick, - int button, JoyAxis axis, JoyDir adir); - void addJoyHatMapping(Event::Type event, EventMode mode, int stick, - int hat, JoyHat hdir); + bool addJoyMapping(Event::Type event, EventMode mode, int stick, + int button, JoyAxis axis, int value); + bool addJoyHatMapping(Event::Type event, EventMode mode, int stick, + int button, int hat, JoyHat hdir); /** Handle a physical joystick event. */ void handleAxisEvent(int stick, int axis, int value); @@ -91,16 +91,19 @@ class PhysicalJoystickHandler Event::Type eventForAxis(int stick, int axis, int joyDir, EventMode mode) const { const PhysicalJoystickPtr j = joy(stick); - return (j && joyDir != int(JoyDir::NEG)) - ? j->axisTable[axis][(joyDir > int(JoyDir::NEG))][mode] : Event::NoType; + //return (j && joyDir != int(JoyDir::NEG)) + // ? j->axisTable[axis][(joyDir > int(JoyDir::NEG))][mode] : Event::NoType; + return j->joyMap.get(mode, JOY_CTRL_NONE, JoyAxis(axis), JoyDir(joyDir)); } Event::Type eventForButton(int stick, int button, EventMode mode) const { const PhysicalJoystickPtr j = joy(stick); - return j ? j->btnTable[button][mode] : Event::NoType; + // return j ? j->btnTable[button][mode] : Event::NoType; + return j->joyMap.get(mode, button); } Event::Type eventForHat(int stick, int hat, JoyHat hatDir, EventMode mode) const { const PhysicalJoystickPtr j = joy(stick); - return j ? j->hatTable[hat][int(hatDir)][mode] : Event::NoType; + //return j ? j->hatTable[hat][int(hatDir)][mode] : Event::NoType; + return j->joyHatMap.get(mode, JOY_CTRL_NONE, hat, hatDir); } /** Returns a list of pairs consisting of joystick name and associated ID. */ diff --git a/src/common/PhysicalJoystick.cxx b/src/common/PhysicalJoystick.cxx index f4e84a002..753fa0b41 100644 --- a/src/common/PhysicalJoystick.cxx +++ b/src/common/PhysicalJoystick.cxx @@ -31,20 +31,22 @@ PhysicalJoystick::PhysicalJoystick() numAxes(0), numButtons(0), numHats(0), - axisTable(nullptr), + /*axisTable(nullptr), btnTable(nullptr), - hatTable(nullptr), - axisLastValue(nullptr) + hatTable(nullptr),*/ + axisLastValue(nullptr), + buttonLast(nullptr) { } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PhysicalJoystick::~PhysicalJoystick() { - delete[] axisTable; + /*delete[] axisTable; delete[] btnTable; - delete[] hatTable; + delete[] hatTable;*/ delete[] axisLastValue; + delete[] buttonLast; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -59,24 +61,28 @@ void PhysicalJoystick::initialize(int index, const string& desc, numAxes = axes; numButtons = buttons; numHats = hats; - if(numAxes) + /*if(numAxes) axisTable = new Event::Type[numAxes][NUM_JOY_DIRS][kNumModes]; if(numButtons) btnTable = new Event::Type[numButtons][kNumModes]; if(numHats) - hatTable = new Event::Type[numHats][NUM_JOY_HAT_DIRS][kNumModes]; + hatTable = new Event::Type[numHats][NUM_JOY_HAT_DIRS][kNumModes];*/ axisLastValue = new int[numAxes]; + buttonLast = new int[numButtons]; + + for (int b = 0; b < numButtons; ++b) + buttonLast[b] = JOY_CTRL_NONE; // Erase the joystick axis mapping array and last axis value for(int a = 0; a < numAxes; ++a) { axisLastValue[a] = 0; - for(int m = 0; m < kNumModes; ++m) + /*for(int m = 0; m < kNumModes; ++m) for (int d = 0; d < NUM_JOY_DIRS; ++d) - axisTable[a][d][m] = Event::NoType; + axisTable[a][d][m] = Event::NoType;*/ } - // Erase the joystick button mapping array + /*// Erase the joystick button mapping array for(int b = 0; b < numButtons; ++b) for(int m = 0; m < kNumModes; ++m) btnTable[b][m] = Event::NoType; @@ -85,7 +91,10 @@ void PhysicalJoystick::initialize(int index, const string& desc, for(int h = 0; h < numHats; ++h) for(int m = 0; m < kNumModes; ++m) for (int d = 0; d < NUM_JOY_HAT_DIRS; ++d) - hatTable[h][d][m] = Event::NoType; + hatTable[h][d][m] = Event::NoType;*/ + + for (int m = 0; m < kNumModes; ++m) + eraseMap(EventMode(m)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -97,7 +106,7 @@ string PhysicalJoystick::getMap() const if(type == JT_REGULAR) { ostringstream joybuf; - joybuf << name << "|" << numAxes; + /*joybuf << name << "|" << numAxes; for(int m = 0; m < kNumModes; ++m) for(int a = 0; a < numAxes; ++a) for (int d = 0; d < NUM_JOY_DIRS; ++d) @@ -110,7 +119,12 @@ string PhysicalJoystick::getMap() const for(int m = 0; m < kNumModes; ++m) for(int h = 0; h < numHats; ++h) for (int d = 0; d < NUM_JOY_HAT_DIRS; ++d) - joybuf << " " << hatTable[h][d][m]; + joybuf << " " << hatTable[h][d][m];*/ + + // new: + joybuf << name; + for (int m = 0; m < kNumModes; ++m) + joybuf << "|" << m << "|" << joyMap.saveMapping(EventMode(m)); return joybuf.str(); } @@ -133,7 +147,7 @@ bool PhysicalJoystick::setMap(const string& mapString) IntArray map; // Parse axis/button/hat values - getValues(items[1], map); + /*getValues(items[1], map); if(int(map.size()) == numAxes * NUM_JOY_DIRS * kNumModes) { // Fill the axes table with events @@ -161,7 +175,7 @@ bool PhysicalJoystick::setMap(const string& mapString) for(int h = 0; h < numHats; ++h) for (int d = 0; d < NUM_JOY_HAT_DIRS; ++d) hatTable[h][d][m] = Event::Type(*event++); - } + }*/ return true; } @@ -169,7 +183,7 @@ bool PhysicalJoystick::setMap(const string& mapString) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void PhysicalJoystick::eraseMap(EventMode mode) { - // Erase axis mappings + /*// Erase axis mappings for(int a = 0; a < numAxes; ++a) for (int d = 0; d < NUM_JOY_DIRS; ++d) axisTable[a][d][mode] = Event::NoType; @@ -181,13 +195,18 @@ void PhysicalJoystick::eraseMap(EventMode mode) // Erase hat mappings for(int h = 0; h < numHats; ++h) for (int d = 0; d < NUM_JOY_HAT_DIRS; ++d) - hatTable[h][d][mode] = Event::NoType; + hatTable[h][d][mode] = Event::NoType;*/ + + // Erase button and axis mappings + joyMap.eraseMode(mode); + // Erase button and axis mappings + joyHatMap.eraseMode(mode); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void PhysicalJoystick::eraseEvent(Event::Type event, EventMode mode) { - // Erase axis mappings + /*// Erase axis mappings for(int a = 0; a < numAxes; ++a) for (int d = 0; d < NUM_JOY_DIRS; ++d) if(axisTable[a][d][mode] == event) @@ -202,7 +221,12 @@ void PhysicalJoystick::eraseEvent(Event::Type event, EventMode mode) for(int h = 0; h < numHats; ++h) for (int d = 0; d < NUM_JOY_HAT_DIRS; ++d) if(hatTable[h][d][mode] == event) - hatTable[h][d][mode] = Event::NoType; + hatTable[h][d][mode] = Event::NoType;*/ + + // Erase button and axis mappings + joyMap.eraseEvent(event, mode); + // Erase hat mappings + joyHatMap.eraseEvent(event, mode); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/common/PhysicalJoystick.hxx b/src/common/PhysicalJoystick.hxx index 94a7b1e76..a325cb3f3 100644 --- a/src/common/PhysicalJoystick.hxx +++ b/src/common/PhysicalJoystick.hxx @@ -67,10 +67,12 @@ class PhysicalJoystick int ID; string name; int numAxes, numButtons, numHats; - Event::Type (*axisTable)[NUM_JOY_DIRS][kNumModes]; + /*Event::Type (*axisTable)[NUM_JOY_DIRS][kNumModes]; Event::Type (*btnTable)[kNumModes]; - Event::Type (*hatTable)[NUM_JOY_HAT_DIRS][kNumModes]; + Event::Type (*hatTable)[NUM_JOY_HAT_DIRS][kNumModes];*/ int* axisLastValue; + int* buttonLast; + // Hashmaps of controller events JoyMap joyMap; diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index 7275e88e3..a61274947 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -1124,7 +1124,7 @@ bool EventHandler::addKeyMapping(Event::Type event, EventMode mode, StellaKey ke } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -bool EventHandler::addJoyAxisMapping(Event::Type event, EventMode mode, +/*bool EventHandler::addJoyAxisMapping(Event::Type event, EventMode mode, int stick, int axis, int value, bool updateMenus) { @@ -1169,8 +1169,41 @@ bool EventHandler::addJoyHatMapping(Event::Type event, EventMode mode, #else return false; #endif +}*/ + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool EventHandler::addJoyMapping(Event::Type event, EventMode mode, + int stick, int button, JoyAxis axis, int value, + bool updateMenus) +{ +#ifdef JOYSTICK_SUPPORT + bool mapped = myPJoyHandler->addJoyMapping(event, mode, stick, button, axis, value); + if (mapped && updateMenus) + setActionMappings(mode); + + return mapped; +#else + return false; +#endif } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +bool EventHandler::addJoyHatMapping(Event::Type event, EventMode mode, + int stick, int button, int hat, JoyHat dir, + bool updateMenus) +{ +#ifdef JOYSTICK_SUPPORT + bool mapped = myPJoyHandler->addJoyHatMapping(event, mode, stick, button, hat, dir); + if (mapped && updateMenus) + setActionMappings(mode); + + return mapped; +#else + return false; +#endif +} + + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EventHandler::eraseMapping(Event::Type event, EventMode mode) { diff --git a/src/emucore/EventHandler.hxx b/src/emucore/EventHandler.hxx index 6a1a5a346..6543562d9 100644 --- a/src/emucore/EventHandler.hxx +++ b/src/emucore/EventHandler.hxx @@ -219,7 +219,7 @@ class EventHandler we want to do this, unless there are a batch of 'adds', in which case it's delayed until the end */ - bool addJoyAxisMapping(Event::Type event, EventMode mode, + /*bool addJoyAxisMapping(Event::Type event, EventMode mode, int stick, int axis, int value, bool updateMenus = true); @@ -235,7 +235,7 @@ class EventHandler we want to do this, unless there are a batch of 'adds', in which case it's delayed until the end */ - bool addJoyButtonMapping(Event::Type event, EventMode mode, int stick, int button, + /*bool addJoyButtonMapping(Event::Type event, EventMode mode, int stick, int button, bool updateMenus = true); /** @@ -251,10 +251,18 @@ class EventHandler we want to do this, unless there are a batch of 'adds', in which case it's delayed until the end */ - bool addJoyHatMapping(Event::Type event, EventMode mode, + /*bool addJoyHatMapping(Event::Type event, EventMode mode, int stick, int hat, JoyHat value, + bool updateMenus = true);*/ + + bool addJoyMapping(Event::Type event, EventMode mode, + int stick, int button, JoyAxis axis = JoyAxis::NONE, int value = 0, + bool updateMenus = true); + bool addJoyHatMapping(Event::Type event, EventMode mode, + int stick, int button, int hat, JoyHat dir, bool updateMenus = true); + /** Erase the specified mapping. diff --git a/src/emucore/EventHandlerConstants.hxx b/src/emucore/EventHandlerConstants.hxx index d0f7edaeb..3c7526685 100644 --- a/src/emucore/EventHandlerConstants.hxx +++ b/src/emucore/EventHandlerConstants.hxx @@ -38,16 +38,19 @@ enum class MouseButton { NONE }; -static constexpr int CTRL_NONE = -1; +static constexpr int JOY_CTRL_NONE = -1; enum class JoyAxis { X = 0, Y = 1, + Z = 2, + NONE = JOY_CTRL_NONE }; enum class JoyDir { NEG = 0, POS = 1, + NONE = JOY_CTRL_NONE }; diff --git a/src/gui/EventMappingWidget.cxx b/src/gui/EventMappingWidget.cxx index a3832ea68..6640c6d25 100644 --- a/src/gui/EventMappingWidget.cxx +++ b/src/gui/EventMappingWidget.cxx @@ -47,6 +47,7 @@ EventMappingWidget::EventMappingWidget(GuiObject* boss, const GUI::Font& font, myLastAxis(0), myLastHat(0), myLastValue(0), + myLastButton(JOY_CTRL_NONE), myFirstTime(true) { const int fontHeight = font.getFontHeight(), @@ -159,9 +160,10 @@ void EventMappingWidget::startRemapping() // Reset all previous events for determining correct axis/hat values myLastStick = myLastAxis = myLastHat = myLastValue = -1; + myLastButton = JOY_CTRL_NONE; // Reset the previously aggregated key mappings - myMod = myKey = 0; + myMod = myLastKey = 0; // Disable all other widgets while in remap mode, except enable 'Cancel' enableButtons(false); @@ -213,6 +215,7 @@ void EventMappingWidget::stopRemapping() // Reset all previous events for determining correct axis/hat values myLastStick = myLastAxis = myLastHat = myLastValue = -1; + myLastButton = JOY_CTRL_NONE; // And re-enable all the widgets enableButtons(true); @@ -257,7 +260,7 @@ bool EventMappingWidget::handleKeyDown(StellaKey key, StellaMod mod) // Remap keys in remap mode if (myRemapStatus && myActionSelected >= 0) { - myKey = key; + myLastKey = key; myMod |= mod; } return true; @@ -272,7 +275,7 @@ bool EventMappingWidget::handleKeyUp(StellaKey key, StellaMod mod) { Event::Type event = instance().eventHandler().eventAtIndex(myActionSelected, myEventMode); - if (instance().eventHandler().addKeyMapping(event, myEventMode, StellaKey(myKey), StellaMod(myMod))) + if (instance().eventHandler().addKeyMapping(event, myEventMode, StellaKey(myLastKey), StellaMod(myMod))) stopRemapping(); } return true; @@ -281,19 +284,42 @@ bool EventMappingWidget::handleKeyUp(StellaKey key, StellaMod mod) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EventMappingWidget::handleJoyDown(int stick, int button) { + cerr << "handleJoyDown" << endl; // Remap joystick buttons in remap mode if(myRemapStatus && myActionSelected >= 0) { - Event::Type event = - instance().eventHandler().eventAtIndex(myActionSelected, myEventMode); - if(instance().eventHandler().addJoyButtonMapping(event, myEventMode, stick, button)) - stopRemapping(); + myLastStick = stick; + myLastButton = button; + } +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EventMappingWidget::handleJoyUp(int stick, int button) +{ + cerr << "handleJoyUp" << endl; + // Remap joystick buttons in remap mode + if (myRemapStatus && myActionSelected >= 0) + { + if (myLastStick == stick && myLastButton == button) + { + EventHandler& eh = instance().eventHandler(); + Event::Type event = eh.eventAtIndex(myActionSelected, myEventMode); + + cerr << "remap" << endl; + // This maps solo button presses only + if (eh.addJoyMapping(event, myEventMode, stick, button)) // new + stopRemapping(); + + //if (eh.addJoyButtonMapping(event, myEventMode, stick, button)) + // stopRemapping(); + } } } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void EventMappingWidget::handleJoyAxis(int stick, int axis, int value) { + cerr << "handleJoyAxis:" << axis << ", " << value << ", (" << stick << ", " << myLastStick << "), (" << axis << ", " << myLastAxis << ")" << endl; // Remap joystick axes in remap mode // There are two phases to detection: // First, detect an axis 'on' event @@ -301,8 +327,9 @@ void EventMappingWidget::handleJoyAxis(int stick, int axis, int value) if(myRemapStatus && myActionSelected >= 0) { // Detect the first axis event that represents 'on' - if(myLastStick == -1 && myLastAxis == -1 && value != 0) + if((myLastStick == -1 || myLastStick == stick) && myLastAxis == -1 && value != 0) { + cerr << "remap start" << endl; myLastStick = stick; myLastAxis = axis; myLastValue = value; @@ -311,13 +338,15 @@ void EventMappingWidget::handleJoyAxis(int stick, int axis, int value) // stick and axis, but turns the axis 'off' else if(myLastStick == stick && axis == myLastAxis && value == 0) { - value = myLastValue; + EventHandler& eh = instance().eventHandler(); + Event::Type event = eh.eventAtIndex(myActionSelected, myEventMode); - Event::Type event = - instance().eventHandler().eventAtIndex(myActionSelected, myEventMode); - if(instance().eventHandler().addJoyAxisMapping(event, myEventMode, - stick, axis, value)) - stopRemapping(); + cerr << "remap stop" << endl; + if (eh.addJoyMapping(event, myEventMode, stick, myLastButton, JoyAxis(axis), myLastValue)) + stopRemapping(); // new + + //if(eh.addJoyAxisMapping(event, myEventMode, stick, axis, myLastValue)) + // stopRemapping(); } } } @@ -332,7 +361,7 @@ bool EventMappingWidget::handleJoyHat(int stick, int hat, JoyHat value) if(myRemapStatus && myActionSelected >= 0) { // Detect the first hat event that represents a valid direction - if(myLastStick == -1 && myLastHat == -1 && value != JoyHat::CENTER) + if((myLastStick == -1 || myLastStick == stick) && myLastHat == -1 && value != JoyHat::CENTER) { myLastStick = stick; myLastHat = hat; @@ -344,16 +373,19 @@ bool EventMappingWidget::handleJoyHat(int stick, int hat, JoyHat value) // stick and hat, but centers the hat else if(myLastStick == stick && hat == myLastHat && value == JoyHat::CENTER) { - value = JoyHat(myLastValue); + EventHandler& eh = instance().eventHandler(); + Event::Type event = eh.eventAtIndex(myActionSelected, myEventMode); - Event::Type event = - instance().eventHandler().eventAtIndex(myActionSelected, myEventMode); - if(instance().eventHandler().addJoyHatMapping(event, myEventMode, - stick, hat, value)) + if (eh.addJoyHatMapping(event, myEventMode, stick, myLastButton, hat, JoyHat(myLastValue))) { stopRemapping(); return true; } + /*if(eh.addJoyHatMapping(event, myEventMode, stick, hat, myLastValue)) + { + stopRemapping(); + return true; + }*/ } } diff --git a/src/gui/EventMappingWidget.hxx b/src/gui/EventMappingWidget.hxx index 7fb82dad4..664e64ffb 100644 --- a/src/gui/EventMappingWidget.hxx +++ b/src/gui/EventMappingWidget.hxx @@ -60,6 +60,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 handleJoyUp(int stick, int button) override; void handleJoyAxis(int stick, int axis, int value) override; bool handleJoyHat(int stick, int hat, JoyHat value) override; @@ -108,7 +109,9 @@ class EventMappingWidget : public Widget, public CommandSender // Aggregates the modifier flags of the mapping int myMod; // Saves the last *pressed* key - int myKey; + int myLastKey; + // Saves the last *pressed* button + int myLastButton; bool myFirstTime; diff --git a/src/gui/InputDialog.cxx b/src/gui/InputDialog.cxx index 94d90d18a..794a5fd7a 100644 --- a/src/gui/InputDialog.cxx +++ b/src/gui/InputDialog.cxx @@ -480,6 +480,18 @@ void InputDialog::handleJoyDown(int stick, int button) Dialog::handleJoyDown(stick, button); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void InputDialog::handleJoyUp(int stick, int button) +{ + // Remap joystick buttons in remap mode, otherwise pass to parent dialog + if (myEmulEventMapper->remapMode()) + myEmulEventMapper->handleJoyUp(stick, button); + else if (myMenuEventMapper->remapMode()) + myMenuEventMapper->handleJoyUp(stick, button); + else + Dialog::handleJoyUp(stick, button); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void InputDialog::handleJoyAxis(int stick, int axis, int value) { diff --git a/src/gui/InputDialog.hxx b/src/gui/InputDialog.hxx index 9281ba3e4..40ec13534 100644 --- a/src/gui/InputDialog.hxx +++ b/src/gui/InputDialog.hxx @@ -46,6 +46,7 @@ class InputDialog : public Dialog void handleKeyDown(StellaKey key, StellaMod mod) override; void handleKeyUp(StellaKey key, StellaMod mod) override; void handleJoyDown(int stick, int button) override; + void handleJoyUp(int stick, int button) override; void handleJoyAxis(int stick, int axis, int value) override; bool handleJoyHat(int stick, int hat, JoyHat value) override; void handleCommand(CommandSender* sender, int cmd, int data, int id) override; From 6b4645485b457233d7064e52316196473191bb5e Mon Sep 17 00:00:00 2001 From: thrust26 Date: Sat, 22 Jun 2019 10:37:42 +0200 Subject: [PATCH 10/18] allow button as modifier for direction and hat load/save controller mappings --- src/common/JoyHatMap.cxx | 14 +- src/common/JoyMap.cxx | 10 +- src/common/PJoystickHandler.cxx | 377 ++++++++++++++++---------------- src/common/PJoystickHandler.hxx | 22 +- src/common/PKeyboardHandler.hxx | 2 +- src/common/PhysicalJoystick.cxx | 143 +++--------- src/common/PhysicalJoystick.hxx | 10 +- src/emucore/EventHandler.hxx | 14 +- src/gui/ContextMenu.cxx | 10 +- src/gui/ContextMenu.hxx | 4 +- src/gui/Dialog.cxx | 18 +- src/gui/Dialog.hxx | 6 +- src/gui/DialogContainer.cxx | 8 +- src/gui/DialogContainer.hxx | 4 +- src/gui/EventMappingWidget.cxx | 9 +- src/gui/EventMappingWidget.hxx | 4 +- src/gui/InputDialog.cxx | 16 +- src/gui/InputDialog.hxx | 4 +- src/gui/LauncherDialog.cxx | 6 +- src/gui/LauncherDialog.hxx | 2 +- src/gui/Widget.hxx | 4 +- 21 files changed, 293 insertions(+), 394 deletions(-) diff --git a/src/common/JoyHatMap.cxx b/src/common/JoyHatMap.cxx index a000eb9c2..6f480ddc4 100644 --- a/src/common/JoyHatMap.cxx +++ b/src/common/JoyHatMap.cxx @@ -17,12 +17,6 @@ #include "JoyHatMap.hxx" -// TODOs -// - two maps per controller (joydirs, hatdirs) -// - both maps combined with buttons -// - directions can work alone and with a button combination -// - buttons can work without a direction (mapped in joydir) - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - JoyHatMap::JoyHatMap(void) { @@ -91,8 +85,6 @@ string JoyHatMap::getDesc(const Event::Type event, const JoyHatMapping & mapping { ostringstream buf; - //buf << "J" << mapping.stick; - // hat description if (mapping.hat != JOY_CTRL_NONE) { @@ -158,7 +150,7 @@ string JoyHatMap::saveMapping(const EventMode mode) const { if (buf.str() != "") buf << "|"; - buf << item.second << ":" /*<< item.first.stick*/ << "," << + buf << item.second << ":" << item.first.button << "," << item.first.hat << "," << int(item.first.hdir); } } @@ -174,9 +166,9 @@ int JoyHatMap::loadMapping(string & list, const EventMode mode) std::replace(list.begin(), list.end(), ':', ' '); std::replace(list.begin(), list.end(), ',', ' '); istringstream buf(list); - int event, stick, button, hat, hdir, i = 0; + int event, button, hat, hdir, i = 0; - while (buf >> event && buf >> stick && buf >> button && buf >> hat && buf >> hdir && ++i) + while (buf >> event && buf >> button && buf >> hat && buf >> hdir && ++i) add(Event::Type(event), EventMode(mode), button, hat, JoyHat(hdir)); return i; diff --git a/src/common/JoyMap.cxx b/src/common/JoyMap.cxx index 311b552da..945091688 100644 --- a/src/common/JoyMap.cxx +++ b/src/common/JoyMap.cxx @@ -17,12 +17,6 @@ #include "JoyMap.hxx" -// TODOs -// - two maps per controller (joydirs, hatdirs) -// - both maps combined with buttons -// - directions can work alone and with a button combination -// - buttons can work without a direction (mapped in joydir) - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - JoyMap::JoyMap(void) { @@ -183,9 +177,9 @@ int JoyMap::loadMapping(string& list, const EventMode mode) std::replace(list.begin(), list.end(), ':', ' '); std::replace(list.begin(), list.end(), ',', ' '); istringstream buf(list); - int event, stick, button, axis, adir, i = 0; + int event, button, axis, adir, i = 0; - while (buf >> event && buf >> stick && buf >> button + while (buf >> event && buf >> button && buf >> axis && buf >> adir && ++i) add(Event::Type(event), EventMode(mode), button, JoyAxis(axis), JoyDir(adir)); diff --git a/src/common/PJoystickHandler.cxx b/src/common/PJoystickHandler.cxx index 47d598c95..8d3158611 100644 --- a/src/common/PJoystickHandler.cxx +++ b/src/common/PJoystickHandler.cxx @@ -27,6 +27,8 @@ #include "DialogContainer.hxx" #endif +static constexpr char CTRL_DELIM = '^'; + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PhysicalJoystickHandler::PhysicalJoystickHandler( OSystem& system, EventHandler& handler, Event& event) @@ -40,14 +42,14 @@ PhysicalJoystickHandler::PhysicalJoystickHandler( string joymap, joyname; // First compare if event list version has changed, and disregard the entire mapping if true - getline(buf, joymap, '^'); // event list size, ignore + getline(buf, joymap, CTRL_DELIM); // event list size, ignore if(version != Event::VERSION) { // Otherwise, put each joystick mapping entry into the database - while(getline(buf, joymap, '^')) + while(getline(buf, joymap, CTRL_DELIM)) { istringstream namebuf(joymap); - getline(namebuf, joyname, '|'); + getline(namebuf, joyname, PhysicalJoystick::MODE_DELIM); if(joyname.length() != 0) myDatabase.emplace(joyname, StickInfo(joymap)); } @@ -205,6 +207,12 @@ void PhysicalJoystickHandler::mapStelladaptors(const string& saport) for(auto& stick: mySticks) { + // remove previously added emulated ports + size_t pos = stick.second->name.find(" (emulates "); + + if (pos != std::string::npos) + stick.second->name.erase(pos); + if(BSPF::startsWithIgnoreCase(stick.second->name, "Stelladaptor")) { if(saOrder[saCount] == 1) @@ -254,26 +262,17 @@ void PhysicalJoystickHandler::setStickDefaultMapping(int stick, auto setDefaultAxis = [&](Event::Type a_event, int stick, JoyAxis axis, JoyDir value, int button = JOY_CTRL_NONE) { if (eraseAll || a_event == event) - { - //myHandler.addJoyAxisMapping(a_event, mode, stick, int(axis), int(value), false); myHandler.addJoyMapping(a_event, mode, stick, button, axis, int(value), false); - } }; auto setDefaultBtn = [&](Event::Type b_event, int stick, int button) { if (eraseAll || b_event == event) - { - //myHandler.addJoyButtonMapping(b_event, mode, stick, button, false); myHandler.addJoyMapping(b_event, mode, stick, button, JoyAxis::NONE, int(JoyDir::NONE), false); - } }; auto setDefaultHat = [&](Event::Type h_event, int stick, int hat, JoyHat dir, int button = JOY_CTRL_NONE) { if (eraseAll || h_event == event) - { - //myHandler.addJoyHatMapping(h_event, mode, stick, hat, dir, false); myHandler.addJoyHatMapping(h_event, mode, stick, button, hat, dir, false); - } }; switch(mode) @@ -386,14 +385,12 @@ void PhysicalJoystickHandler::saveMapping() // Save the joystick mapping hash table, making sure to update it with // any changes that have been made during the program run ostringstream joybuf; - //joybuf << Event::LastType; for(const auto& i: myDatabase) { const string& map = i.second.joy ? i.second.joy->getMap() : i.second.mapping; if(map != "") - //joybuf << "^" << map; - joybuf << map; + joybuf << CTRL_DELIM << map; } myOSystem.settings().setValue("joymap", joybuf.str()); } @@ -467,6 +464,8 @@ string PhysicalJoystickHandler::getMappingDesc(Event::Type event, EventMode mode // new: //Joystick button + axis mapping / labeling + if (buf.str() != "") + buf << ", "; if (j->joyMap.getEventMapping(event, mode).size()) buf << j->joyMap.getEventMappingDesc(stick, event, mode); // Joystick hat mapping/labeling @@ -564,7 +563,8 @@ bool PhysicalJoystickHandler::addJoyMapping(Event::Type event, EventMode mode, i if (Event::isAnalog(j->joyMap.get(mode, button, axis, JoyDir::POS))) j->joyMap.erase(mode, button, axis, JoyDir::POS); - j->joyMap.add(event, mode, button, axis, value == int(JoyDir::NONE) ? JoyDir::NONE : value > 0 ? JoyDir::POS : JoyDir::NEG); + j->joyMap.add(event, mode, button, axis, + value == int(JoyDir::NONE) ? JoyDir::NONE : value > 0 ? JoyDir::POS : JoyDir::NEG); } return true; } @@ -591,104 +591,106 @@ bool PhysicalJoystickHandler::addJoyHatMapping(Event::Type event, EventMode mode void PhysicalJoystickHandler::handleAxisEvent(int stick, int axis, int value) { const PhysicalJoystickPtr j = joy(stick); - if(!j) return; - // Stelladaptors handle axis differently than regular joysticks - switch(j->type) + if (j) { - case PhysicalJoystick::JT_REGULAR: - if(myHandler.state() == EventHandlerState::EMULATION) - { - // Every axis event has two associated values, negative and positive - //Event::Type eventAxisNeg = j->axisTable[axis][int(JoyDir::NEG)][kEmulationMode]; - //Event::Type eventAxisPos = j->axisTable[axis][int(JoyDir::POS)][kEmulationMode]; - Event::Type eventAxisNeg = j->joyMap.get(kEmulationMode, j->buttonLast[stick], JoyAxis(axis), JoyDir::NEG); - Event::Type eventAxisPos = j->joyMap.get(kEmulationMode, j->buttonLast[stick], JoyAxis(axis), JoyDir::POS); + int button = j->buttonLast[stick]; - // Check for analog events, which are handled differently - // We'll pass them off as Stelladaptor events, and let the controllers - // handle it - switch(int(eventAxisNeg)) + // Stelladaptors handle axis differently than regular joysticks + switch (j->type) + { + case PhysicalJoystick::JT_REGULAR: + if (myHandler.state() == EventHandlerState::EMULATION) { - case Event::PaddleZeroAnalog: - myEvent.set(Event::SALeftAxis0Value, value); - break; - case Event::PaddleOneAnalog: - myEvent.set(Event::SALeftAxis1Value, value); - break; - case Event::PaddleTwoAnalog: - myEvent.set(Event::SARightAxis0Value, value); - break; - case Event::PaddleThreeAnalog: - myEvent.set(Event::SARightAxis1Value, value); - break; - default: - { - // Otherwise, we know the event is digital - if(value > Joystick::deadzone()) - myHandler.handleEvent(eventAxisPos); - else if(value < -Joystick::deadzone()) - myHandler.handleEvent(eventAxisNeg); - else - { - // Treat any deadzone value as zero - value = 0; + // Every axis event has two associated values, negative and positive + Event::Type eventAxisNeg = j->joyMap.get(kEmulationMode, button, JoyAxis(axis), JoyDir::NEG); + Event::Type eventAxisPos = j->joyMap.get(kEmulationMode, button, JoyAxis(axis), JoyDir::POS); - // Now filter out consecutive, similar values - // (only pass on the event if the state has changed) - if(j->axisLastValue[axis] != value) + // Check for analog events, which are handled differently + // We'll pass them off as Stelladaptor events, and let the controllers + // handle it + switch (int(eventAxisNeg)) + { + case Event::PaddleZeroAnalog: + myEvent.set(Event::SALeftAxis0Value, value); + break; + case Event::PaddleOneAnalog: + myEvent.set(Event::SALeftAxis1Value, value); + break; + case Event::PaddleTwoAnalog: + myEvent.set(Event::SARightAxis0Value, value); + break; + case Event::PaddleThreeAnalog: + myEvent.set(Event::SARightAxis1Value, value); + break; + default: + { + // Otherwise, we know the event is digital + if (value > Joystick::deadzone()) + myHandler.handleEvent(eventAxisPos); + else if (value < -Joystick::deadzone()) + myHandler.handleEvent(eventAxisNeg); + else { - // Turn off both events, since we don't know exactly which one - // was previously activated. - myHandler.handleEvent(eventAxisNeg, false); - myHandler.handleEvent(eventAxisPos, false); + // Treat any deadzone value as zero + value = 0; + + // Now filter out consecutive, similar values + // (only pass on the event if the state has changed) + if (j->axisLastValue[axis] != value) + { + // Turn off both events, since we don't know exactly which one + // was previously activated. + myHandler.handleEvent(eventAxisNeg, false); + myHandler.handleEvent(eventAxisPos, false); + } } + j->axisLastValue[axis] = value; + break; } - j->axisLastValue[axis] = value; - break; } } - } - else if(myHandler.hasOverlay()) - { - // First, clamp the values to simulate digital input - // (the only thing that the underlying code understands) - if(value > Joystick::deadzone()) - value = 32000; - else if(value < -Joystick::deadzone()) - value = -32000; - else - value = 0; - - // Now filter out consecutive, similar values - // (only pass on the event if the state has changed) - if(value != j->axisLastValue[axis]) + else if (myHandler.hasOverlay()) { - #ifdef GUI_SUPPORT - myHandler.overlay().handleJoyAxisEvent(stick, axis, value); - #endif - j->axisLastValue[axis] = value; - } - } - break; // Regular joystick axis + // First, clamp the values to simulate digital input + // (the only thing that the underlying code understands) + if (value > Joystick::deadzone()) + value = 32000; + else if (value < -Joystick::deadzone()) + value = -32000; + else + value = 0; - // Since the various controller classes deal with Stelladaptor - // devices differently, we send the raw X and Y axis data directly, - // and let the controller handle it - // These events don't have to pass through handleEvent, since - // they can never be remapped - case PhysicalJoystick::JT_STELLADAPTOR_LEFT: - case PhysicalJoystick::JT_2600DAPTOR_LEFT: - if(axis < NUM_JOY_AXIS) - myEvent.set(SA_Axis[int(Controller::Jack::Left)][axis], value); - break; // axis on left controller (0) - case PhysicalJoystick::JT_STELLADAPTOR_RIGHT: - case PhysicalJoystick::JT_2600DAPTOR_RIGHT: - if(axis < NUM_JOY_AXIS) - myEvent.set(SA_Axis[int(Controller::Jack::Right)][axis], value); - break; // axis on right controller (1) - default: - break; + // Now filter out consecutive, similar values + // (only pass on the event if the state has changed) + if (value != j->axisLastValue[axis]) + { + #ifdef GUI_SUPPORT + myHandler.overlay().handleJoyAxisEvent(stick, axis, value, button); + #endif + j->axisLastValue[axis] = value; + } + } + break; // Regular joystick axis + + // Since the various controller classes deal with Stelladaptor + // devices differently, we send the raw X and Y axis data directly, + // and let the controller handle it + // These events don't have to pass through handleEvent, since + // they can never be remapped + case PhysicalJoystick::JT_STELLADAPTOR_LEFT: + case PhysicalJoystick::JT_2600DAPTOR_LEFT: + if (axis < NUM_JOY_AXIS) + myEvent.set(SA_Axis[int(Controller::Jack::Left)][axis], value); + break; // axis on left controller (0) + case PhysicalJoystick::JT_STELLADAPTOR_RIGHT: + case PhysicalJoystick::JT_2600DAPTOR_RIGHT: + if (axis < NUM_JOY_AXIS) + myEvent.set(SA_Axis[int(Controller::Jack::Right)][axis], value); + break; // axis on right controller (1) + default: + break; + } } } @@ -696,67 +698,70 @@ void PhysicalJoystickHandler::handleAxisEvent(int stick, int axis, int value) void PhysicalJoystickHandler::handleBtnEvent(int stick, int button, bool pressed) { const PhysicalJoystickPtr j = joy(stick); - if(!j) return; - j->buttonLast[stick] = pressed ? button : JOY_CTRL_NONE; - // Stelladaptors handle buttons differently than regular joysticks - switch(j->type) + if (j) { - case PhysicalJoystick::JT_REGULAR: - // Handle buttons which switch eventhandler state - //if(pressed && myHandler.changeStateByEvent(j->btnTable[button][kEmulationMode])) - if (pressed && myHandler.changeStateByEvent(j->joyMap.get(kEmulationMode, button))) - return; + j->buttonLast[stick] = pressed ? button : JOY_CTRL_NONE; - // Determine which mode we're in, then send the event to the appropriate place - if(myHandler.state() == EventHandlerState::EMULATION) - //myHandler.handleEvent(j->btnTable[button][kEmulationMode], pressed); - myHandler.handleEvent(j->joyMap.get(kEmulationMode, button), pressed); - #ifdef GUI_SUPPORT - else if(myHandler.hasOverlay()) - myHandler.overlay().handleJoyBtnEvent(stick, button, pressed); - #endif - break; // Regular button + // Stelladaptors handle buttons differently than regular joysticks + switch (j->type) + { + case PhysicalJoystick::JT_REGULAR: + // Handle buttons which switch eventhandler state + if (pressed && myHandler.changeStateByEvent(j->joyMap.get(kEmulationMode, button))) + return; - // These events don't have to pass through handleEvent, since - // they can never be remapped - case PhysicalJoystick::JT_STELLADAPTOR_LEFT: - case PhysicalJoystick::JT_STELLADAPTOR_RIGHT: - // The 'type-2' here refers to the fact that 'PhysicalJoystick::JT_STELLADAPTOR_LEFT' - // and 'PhysicalJoystick::JT_STELLADAPTOR_RIGHT' are at index 2 and 3 in the JoyType - // enum; subtracting two gives us Controller 0 and 1 - if(button < 2) - myEvent.set(SA_Button[j->type-PhysicalJoystick::JT_STELLADAPTOR_LEFT][button], pressed ? 1 : 0); - break; // Stelladaptor button - case PhysicalJoystick::JT_2600DAPTOR_LEFT: - case PhysicalJoystick::JT_2600DAPTOR_RIGHT: - // The 'type-4' here refers to the fact that 'PhysicalJoystick::JT_2600DAPTOR_LEFT' - // and 'PhysicalJoystick::JT_2600DAPTOR_RIGHT' are at index 4 and 5 in the JoyType - // enum; subtracting four gives us Controller 0 and 1 - if(myHandler.state() == EventHandlerState::EMULATION) - { - switch(myOSystem.console().leftController().type()) + // Determine which mode we're in, then send the event to the appropriate place + if (myHandler.state() == EventHandlerState::EMULATION) + myHandler.handleEvent(j->joyMap.get(kEmulationMode, button), pressed); + #ifdef GUI_SUPPORT + else if (myHandler.hasOverlay()) + myHandler.overlay().handleJoyBtnEvent(stick, button, pressed); + #endif + break; // Regular button + + // These events don't have to pass through handleEvent, since + // they can never be remapped + case PhysicalJoystick::JT_STELLADAPTOR_LEFT: + case PhysicalJoystick::JT_STELLADAPTOR_RIGHT: + // The 'type-2' here refers to the fact that 'PhysicalJoystick::JT_STELLADAPTOR_LEFT' + // and 'PhysicalJoystick::JT_STELLADAPTOR_RIGHT' are at index 2 and 3 in the JoyType + // enum; subtracting two gives us Controller 0 and 1 + if (button < 2) + myEvent.set(SA_Button[j->type - PhysicalJoystick::JT_STELLADAPTOR_LEFT][button], pressed ? 1 : 0); + break; // Stelladaptor button + + case PhysicalJoystick::JT_2600DAPTOR_LEFT: + case PhysicalJoystick::JT_2600DAPTOR_RIGHT: + // The 'type-4' here refers to the fact that 'PhysicalJoystick::JT_2600DAPTOR_LEFT' + // and 'PhysicalJoystick::JT_2600DAPTOR_RIGHT' are at index 4 and 5 in the JoyType + // enum; subtracting four gives us Controller 0 and 1 + if (myHandler.state() == EventHandlerState::EMULATION) { - case Controller::Type::Keyboard: - if(button < NUM_KEY_BTN) - myEvent.set(SA_Key[j->type-PhysicalJoystick::JT_2600DAPTOR_LEFT][button], pressed ? 1 : 0); - break; - default: - if(button < NUM_JOY_BTN) myEvent.set(SA_Button[j->type-PhysicalJoystick::JT_2600DAPTOR_LEFT][button], pressed ? 1 : 0); + switch (myOSystem.console().leftController().type()) + { + case Controller::Type::Keyboard: + if (button < NUM_KEY_BTN) + myEvent.set(SA_Key[j->type - PhysicalJoystick::JT_2600DAPTOR_LEFT][button], pressed ? 1 : 0); + break; + default: + if (button < NUM_JOY_BTN) myEvent.set(SA_Button[j->type - PhysicalJoystick::JT_2600DAPTOR_LEFT][button], pressed ? 1 : 0); + } + switch (myOSystem.console().rightController().type()) + { + case Controller::Type::Keyboard: + if (button < NUM_KEY_BTN) + myEvent.set(SA_Key[j->type - PhysicalJoystick::JT_2600DAPTOR_LEFT][button], pressed ? 1 : 0); + break; + default: + if (button < NUM_JOY_BTN) myEvent.set(SA_Button[j->type - PhysicalJoystick::JT_2600DAPTOR_LEFT][button], pressed ? 1 : 0); + } } - switch(myOSystem.console().rightController().type()) - { - case Controller::Type::Keyboard: - if(button < NUM_KEY_BTN) - myEvent.set(SA_Key[j->type-PhysicalJoystick::JT_2600DAPTOR_LEFT][button], pressed ? 1 : 0); - break; - default: - if(button < NUM_JOY_BTN) myEvent.set(SA_Button[j->type-PhysicalJoystick::JT_2600DAPTOR_LEFT][button], pressed ? 1 : 0); - } - } - break; // 2600DAPTOR button - default: - break; + break; // 2600DAPTOR button + + default: + break; + } } } @@ -766,38 +771,40 @@ void PhysicalJoystickHandler::handleHatEvent(int stick, int hat, int value) // Preprocess all hat events, converting to Stella JoyHat type // Generate multiple equivalent hat events representing combined direction // when we get a diagonal hat event - if(myHandler.state() == EventHandlerState::EMULATION) - { - const PhysicalJoystickPtr j = joy(stick); - if(!j) return; - /*myHandler.handleEvent(j->hatTable[hat][int(JoyHat::UP)][kEmulationMode], - value & EVENT_HATUP_M); - myHandler.handleEvent(j->hatTable[hat][int(JoyHat::RIGHT)][kEmulationMode], - value & EVENT_HATRIGHT_M); - myHandler.handleEvent(j->hatTable[hat][int(JoyHat::DOWN)][kEmulationMode], - value & EVENT_HATDOWN_M); - myHandler.handleEvent(j->hatTable[hat][int(JoyHat::LEFT)][kEmulationMode], - value & EVENT_HATLEFT_M);*/ + const PhysicalJoystickPtr j = joy(stick); - // TODO: 4 different events - myHandler.handleEvent(j->joyHatMap.get(kEmulationMode, JOY_CTRL_NONE, hat, JoyHat(value))); - } -#ifdef GUI_SUPPORT - else if(myHandler.hasOverlay()) + if (j) { - if(value == EVENT_HATCENTER_M) - myHandler.overlay().handleJoyHatEvent(stick, hat, JoyHat::CENTER); - else + const int button = j->buttonLast[stick]; + + if (myHandler.state() == EventHandlerState::EMULATION) { - if(value & EVENT_HATUP_M) - myHandler.overlay().handleJoyHatEvent(stick, hat, JoyHat::UP); - if(value & EVENT_HATRIGHT_M) - myHandler.overlay().handleJoyHatEvent(stick, hat, JoyHat::RIGHT); - if(value & EVENT_HATDOWN_M) - myHandler.overlay().handleJoyHatEvent(stick, hat, JoyHat::DOWN); - if(value & EVENT_HATLEFT_M) - myHandler.overlay().handleJoyHatEvent(stick, hat, JoyHat::LEFT); + myHandler.handleEvent(j->joyHatMap.get(kEmulationMode, button, hat, JoyHat::UP), + value & EVENT_HATUP_M); + myHandler.handleEvent(j->joyHatMap.get(kEmulationMode, button, hat, JoyHat::RIGHT), + value & EVENT_HATRIGHT_M); + myHandler.handleEvent(j->joyHatMap.get(kEmulationMode, button, hat, JoyHat::DOWN), + value & EVENT_HATDOWN_M); + myHandler.handleEvent(j->joyHatMap.get(kEmulationMode, button, hat, JoyHat::LEFT), + value & EVENT_HATLEFT_M); + } + #ifdef GUI_SUPPORT + else if (myHandler.hasOverlay()) + { + if (value == EVENT_HATCENTER_M) + myHandler.overlay().handleJoyHatEvent(stick, hat, JoyHat::CENTER, button); + else + { + if (value & EVENT_HATUP_M) + myHandler.overlay().handleJoyHatEvent(stick, hat, JoyHat::UP, button); + if (value & EVENT_HATRIGHT_M) + myHandler.overlay().handleJoyHatEvent(stick, hat, JoyHat::RIGHT, button); + if (value & EVENT_HATDOWN_M) + myHandler.overlay().handleJoyHatEvent(stick, hat, JoyHat::DOWN, button); + if (value & EVENT_HATLEFT_M) + myHandler.overlay().handleJoyHatEvent(stick, hat, JoyHat::LEFT, button); + } } } #endif diff --git a/src/common/PJoystickHandler.hxx b/src/common/PJoystickHandler.hxx index ebd8e79f8..0438162c0 100644 --- a/src/common/PJoystickHandler.hxx +++ b/src/common/PJoystickHandler.hxx @@ -41,7 +41,7 @@ using PhysicalJoystickPtr = shared_ptr; Essentially, this class is an extension of the EventHandler class, but handling only joystick-specific functionality. - @author Stephen Anthony + @author Stephen Anthony, Thomas Jentzsch */ class PhysicalJoystickHandler { @@ -74,11 +74,6 @@ class PhysicalJoystickHandler string getMappingDesc(Event::Type, EventMode mode) const; /** Bind a physical joystick event to a virtual event/action. */ - /*bool addAxisMapping(Event::Type event, EventMode mode, int stick, int axis, int value); - bool addBtnMapping(Event::Type event, EventMode mode, int stick, int button); - bool addHatMapping(Event::Type event, EventMode mode, int stick, int hat, JoyHat value);*/ - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool addJoyMapping(Event::Type event, EventMode mode, int stick, int button, JoyAxis axis, int value); bool addJoyHatMapping(Event::Type event, EventMode mode, int stick, @@ -89,21 +84,18 @@ class PhysicalJoystickHandler void handleBtnEvent(int stick, int button, bool pressed); void handleHatEvent(int stick, int hat, int value); - Event::Type eventForAxis(int stick, int axis, int joyDir, EventMode mode) const { + Event::Type eventForAxis(EventMode mode, int stick, int axis, int value, int button) const { const PhysicalJoystickPtr j = joy(stick); - //return (j && joyDir != int(JoyDir::NEG)) - // ? j->axisTable[axis][(joyDir > int(JoyDir::NEG))][mode] : Event::NoType; - return j->joyMap.get(mode, JOY_CTRL_NONE, JoyAxis(axis), JoyDir(joyDir)); + return j->joyMap.get(mode, button, JoyAxis(axis), + value == int(JoyDir::NONE) ? JoyDir::NONE : value > 0 ? JoyDir::POS : JoyDir::NEG); } - Event::Type eventForButton(int stick, int button, EventMode mode) const { + Event::Type eventForButton(EventMode mode, int stick, int button) const { const PhysicalJoystickPtr j = joy(stick); - // return j ? j->btnTable[button][mode] : Event::NoType; return j->joyMap.get(mode, button); } - Event::Type eventForHat(int stick, int hat, JoyHat hatDir, EventMode mode) const { + Event::Type eventForHat(EventMode mode, int stick, int hat, JoyHat hatDir, int button) const { const PhysicalJoystickPtr j = joy(stick); - //return j ? j->hatTable[hat][int(hatDir)][mode] : Event::NoType; - return j->joyHatMap.get(mode, JOY_CTRL_NONE, hat, hatDir); + return j->joyHatMap.get(mode, button, hat, hatDir); } /** Returns a list of pairs consisting of joystick name and associated ID. */ diff --git a/src/common/PKeyboardHandler.hxx b/src/common/PKeyboardHandler.hxx index ffe869d21..7b3a6a6fb 100644 --- a/src/common/PKeyboardHandler.hxx +++ b/src/common/PKeyboardHandler.hxx @@ -40,7 +40,7 @@ using EventSet = std::set; Essentially, this class is an extension of the EventHandler class, but handling only keyboard-specific functionality. - @author Stephen Anthony + @author Stephen Anthony, Thomas Jentzsch */ class PhysicalKeyboardHandler { diff --git a/src/common/PhysicalJoystick.cxx b/src/common/PhysicalJoystick.cxx index 753fa0b41..62d652b45 100644 --- a/src/common/PhysicalJoystick.cxx +++ b/src/common/PhysicalJoystick.cxx @@ -31,9 +31,6 @@ PhysicalJoystick::PhysicalJoystick() numAxes(0), numButtons(0), numHats(0), - /*axisTable(nullptr), - btnTable(nullptr), - hatTable(nullptr),*/ axisLastValue(nullptr), buttonLast(nullptr) { @@ -42,9 +39,6 @@ PhysicalJoystick::PhysicalJoystick() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - PhysicalJoystick::~PhysicalJoystick() { - /*delete[] axisTable; - delete[] btnTable; - delete[] hatTable;*/ delete[] axisLastValue; delete[] buttonLast; } @@ -61,38 +55,18 @@ void PhysicalJoystick::initialize(int index, const string& desc, numAxes = axes; numButtons = buttons; numHats = hats; - /*if(numAxes) - axisTable = new Event::Type[numAxes][NUM_JOY_DIRS][kNumModes]; - if(numButtons) - btnTable = new Event::Type[numButtons][kNumModes]; - if(numHats) - hatTable = new Event::Type[numHats][NUM_JOY_HAT_DIRS][kNumModes];*/ axisLastValue = new int[numAxes]; buttonLast = new int[numButtons]; + // Erase the last button for (int b = 0; b < numButtons; ++b) buttonLast[b] = JOY_CTRL_NONE; - // Erase the joystick axis mapping array and last axis value + // Erase the last axis value for(int a = 0; a < numAxes; ++a) - { axisLastValue[a] = 0; - /*for(int m = 0; m < kNumModes; ++m) - for (int d = 0; d < NUM_JOY_DIRS; ++d) - axisTable[a][d][m] = Event::NoType;*/ - } - - /*// Erase the joystick button mapping array - for(int b = 0; b < numButtons; ++b) - for(int m = 0; m < kNumModes; ++m) - btnTable[b][m] = Event::NoType; - - // Erase the joystick hat mapping array - for(int h = 0; h < numHats; ++h) - for(int m = 0; m < kNumModes; ++m) - for (int d = 0; d < NUM_JOY_HAT_DIRS; ++d) - hatTable[h][d][m] = Event::NoType;*/ + // Erase the mappings for (int m = 0; m < kNumModes; ++m) eraseMap(EventMode(m)); } @@ -101,102 +75,54 @@ void PhysicalJoystick::initialize(int index, const string& desc, string PhysicalJoystick::getMap() const { // The mapping structure (for remappable devices) is defined as follows: - // NAME | AXIS # + values | BUTTON # + values | HAT # + values, - // where each subsection of values is separated by ':' - if(type == JT_REGULAR) - { + // '$'['|'(':'