From f7e46338b8de72c9b8837fc1b599838a762a07b5 Mon Sep 17 00:00:00 2001 From: thrust26 Date: Wed, 2 Aug 2023 17:03:57 +0200 Subject: [PATCH] added default mapping controller port option (resolves #897) --- Changes.txt | 2 + docs/index.html | 2 +- src/common/PJoystickHandler.cxx | 86 +++++++++++++++++++++------------ src/common/PJoystickHandler.hxx | 17 ++++++- src/common/PKeyboardHandler.cxx | 6 +-- src/common/PhysicalJoystick.cxx | 55 +++++++++++++++++++-- src/common/PhysicalJoystick.hxx | 13 +++++ src/emucore/Event.hxx | 2 +- src/emucore/EventHandler.cxx | 15 ++++++ src/emucore/EventHandler.hxx | 13 +++-- src/gui/Dialog.hxx | 1 + src/gui/DialogContainer.cxx | 12 +++++ src/gui/DialogContainer.hxx | 8 +++ src/gui/JoystickDialog.cxx | 51 +++++++++++++++---- src/gui/JoystickDialog.hxx | 9 +++- src/os/windows/Stella.vcxproj | 2 +- 16 files changed, 237 insertions(+), 57 deletions(-) diff --git a/Changes.txt b/Changes.txt index eb605d984..7d822af5d 100644 --- a/Changes.txt +++ b/Changes.txt @@ -30,6 +30,8 @@ * Enhanced Kid Vid support to play tape audio. + * Added port selection, used for controller default mapping + * Added missing PlusROM support for E7 bankswitching. * Acclerated emulation up to ~15% (ARM). diff --git a/docs/index.html b/docs/index.html index 7516a9120..860e7dd27 100644 --- a/docs/index.html +++ b/docs/index.html @@ -4041,7 +4041,7 @@ Allow all 4 directions ...Allow all 4 joystick directions to be pressed simultaneously-joyallow4 Use modifier key combosEnable using modifier keys in keyboard actions-modcombo Swap Stelladaptor portsSwap the order of the detected Stelladaptors/2600-daptors (see Advanced Configuration - Stelladaptor/2600-daptor Support)-saport - Controller DatabaseShow all controllers that Stella knows about, with the option to remove them  + Controller DatabaseShow all controllers that Stella knows about and allow assigning them to a default mapping port and removing them  Erase EEPROMErase the whole AtariVox/SaveKey flash memory  AtariVox serial portDescribed in further detail in Advanced Configuration - AtariVox/SaveKey Support -avoxport diff --git a/src/common/PJoystickHandler.cxx b/src/common/PJoystickHandler.cxx index c03076fbf..5b38d8d51 100644 --- a/src/common/PJoystickHandler.cxx +++ b/src/common/PJoystickHandler.cxx @@ -228,6 +228,17 @@ bool PhysicalJoystickHandler::remove(string_view name) return false; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void PhysicalJoystickHandler::setPort(string_view name, PhysicalJoystick::Port port) +{ + const auto it = myDatabase.find(name); + if(it != myDatabase.end() && it->second.joy != nullptr) + { + it->second.joy->setPort(port); + // TODO: update mappings + } +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool PhysicalJoystickHandler::mapStelladaptors(string_view saport, int ID) { @@ -359,35 +370,42 @@ void PhysicalJoystickHandler::setStickDefaultMapping( if(j) { - switch (mode) + switch(mode) { case EventMode::kEmulationMode: { - // A regular joystick defaults to left or right based on the - // stick number being even or odd; 'daptor joysticks request a - // specific port - const bool useLeftMappings = - j->type == PhysicalJoystick::Type::REGULAR ? ((stick % 2) == 0) : - (j->type == PhysicalJoystick::Type::LEFT_STELLADAPTOR || - j->type == PhysicalJoystick::Type::LEFT_2600DAPTOR); + // A regular joystick defaults to left or right based on + // the defined port or stick number being even or odd; + // 'daptor' joysticks request a specific port + bool useLeftMappings; + if(j->type == PhysicalJoystick::Type::REGULAR) + { + useLeftMappings = j->port == PhysicalJoystick::Port::LEFT + || (j->port == PhysicalJoystick::Port::AUTO && (stick % 2) == 0); + } + else + useLeftMappings = + j->type == PhysicalJoystick::Type::LEFT_STELLADAPTOR || + j->type == PhysicalJoystick::Type::LEFT_2600DAPTOR; + if(useLeftMappings) { // put all controller events into their own mode's mappings - for (const auto& item : DefaultLeftJoystickMapping) + for(const auto& item : DefaultLeftJoystickMapping) setDefaultAction(stick, item, event, EventMode::kJoystickMode, updateDefaults); - for (const auto& item : DefaultLeftKeyboardMapping) + for(const auto& item : DefaultLeftKeyboardMapping) setDefaultAction(stick, item, event, EventMode::kKeyboardMode, updateDefaults); - for (const auto& item : DefaultLeftDrivingMapping) + for(const auto& item : DefaultLeftDrivingMapping) setDefaultAction(stick, item, event, EventMode::kDrivingMode, updateDefaults); } else { // put all controller events into their own mode's mappings - for (const auto& item : DefaultRightJoystickMapping) + for(const auto& item : DefaultRightJoystickMapping) setDefaultAction(stick, item, event, EventMode::kJoystickMode, updateDefaults); - for (const auto& item : DefaultRightKeyboardMapping) + for(const auto& item : DefaultRightKeyboardMapping) setDefaultAction(stick, item, event, EventMode::kKeyboardMode, updateDefaults); - for (const auto& item : DefaultRightDrivingMapping) + for(const auto& item : DefaultRightDrivingMapping) setDefaultAction(stick, item, event, EventMode::kDrivingMode, updateDefaults); } @@ -404,16 +422,16 @@ void PhysicalJoystickHandler::setStickDefaultMapping( // and 2600-daptors support two players natively. const int paddlesPerJoystick = (j->type == PhysicalJoystick::Type::REGULAR && !retron77) ? 1 : 2; - if( paddlesPerJoystick == 2 ) + if(paddlesPerJoystick == 2) { - if( useLeftMappings ) + if(useLeftMappings) { - for (const auto& item : DefaultLeftPaddlesMapping) + for(const auto& item : DefaultLeftPaddlesMapping) setDefaultAction(stick, item, event, EventMode::kPaddlesMode, updateDefaults); } else { - for (const auto& item : DefaultRightPaddlesMapping) + for(const auto& item : DefaultRightPaddlesMapping) setDefaultAction(stick, item, event, EventMode::kPaddlesMode, updateDefaults); } } @@ -430,29 +448,29 @@ void PhysicalJoystickHandler::setStickDefaultMapping( const bool useLeftPaddleMappings = (stick % 4) < 2; const bool useAPaddleMappings = (stick % 2) == 0; - if( useLeftPaddleMappings ) + if(useLeftPaddleMappings) { - if( useAPaddleMappings ) + if(useAPaddleMappings) { - for (const auto& item : DefaultLeftAPaddlesMapping) + for(const auto& item : DefaultLeftAPaddlesMapping) setDefaultAction(stick, item, event, EventMode::kPaddlesMode, updateDefaults); } else { - for (const auto& item : DefaultLeftBPaddlesMapping) + for(const auto& item : DefaultLeftBPaddlesMapping) setDefaultAction(stick, item, event, EventMode::kPaddlesMode, updateDefaults); } } else { - if( useAPaddleMappings ) + if(useAPaddleMappings) { - for (const auto& item : DefaultRightAPaddlesMapping) + for(const auto& item : DefaultRightAPaddlesMapping) setDefaultAction(stick, item, event, EventMode::kPaddlesMode, updateDefaults); } else { - for (const auto& item : DefaultRightBPaddlesMapping) + for(const auto& item : DefaultRightBPaddlesMapping) setDefaultAction(stick, item, event, EventMode::kPaddlesMode, updateDefaults); } } @@ -466,7 +484,7 @@ void PhysicalJoystickHandler::setStickDefaultMapping( } case EventMode::kMenuMode: - for (const auto& item : DefaultMenuMapping) + for(const auto& item : DefaultMenuMapping) setDefaultAction(stick, item, event, EventMode::kMenuMode, updateDefaults); break; @@ -1071,13 +1089,19 @@ void PhysicalJoystickHandler::handleHatEvent(int stick, int hat, int value) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -VariantList PhysicalJoystickHandler::database() const +PhysicalJoystickHandler::MinStrickInfoList PhysicalJoystickHandler::minStickList() const { - VariantList db; - for(const auto& [_name, _info]: myDatabase) - VarList::push_back(db, _name, _info.joy ? _info.joy->ID : -1); + MinStrickInfoList list; - return db; + for(const auto& [_name, _info] : myDatabase) + { + MinStrickInfo stick(_name, + _info.joy ? _info.joy->ID : -1, + _info.joy ? _info.joy->port : PhysicalJoystick::Port::AUTO); + + list.push_back(stick); + } + return list; } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/common/PJoystickHandler.hxx b/src/common/PJoystickHandler.hxx index bf3d6ee28..d1514ba22 100644 --- a/src/common/PJoystickHandler.hxx +++ b/src/common/PJoystickHandler.hxx @@ -46,6 +46,18 @@ using PhysicalJoystickPtr = shared_ptr; */ class PhysicalJoystickHandler { + public: + struct MinStrickInfo + { + string name; + int ID; + PhysicalJoystick::Port port; + + explicit MinStrickInfo(string _name, int _id, PhysicalJoystick::Port _port) + : name{_name}, ID{_id}, port{_port} {} + }; + using MinStrickInfoList = std::vector; + private: struct StickInfo { @@ -74,6 +86,7 @@ class PhysicalJoystickHandler int add(const PhysicalJoystickPtr& stick); bool remove(int id); bool remove(string_view name); + void setPort(string_view name, PhysicalJoystick::Port port); bool mapStelladaptors(string_view saport, int ID = -1); bool hasStelladaptors() const; void setDefaultMapping(Event::Type event, EventMode mode); @@ -112,8 +125,8 @@ class PhysicalJoystickHandler return j->joyMap.get(mode, button, hat, hatDir); } - /** Returns a list of pairs consisting of joystick name and associated ID. */ - VariantList database() const; + /** Returns a list containing minimal controller info (name, ID, port). */ + MinStrickInfoList minStickList() const; void changeDigitalDeadZone(int direction = +1); void changeAnalogPaddleDeadZone(int direction = +1); diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index 832558175..d88f94aef 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -221,7 +221,7 @@ void PhysicalKeyboardHandler::defineControllerMappings( const Controller::Type type, Controller::Jack port, const Properties& properties) { // Determine controller events to use - if(type == Controller::Type::QuadTari) + if(type == Controller::Type::QuadTari) { if(port == Controller::Jack::Left) { @@ -233,7 +233,7 @@ void PhysicalKeyboardHandler::defineControllerMappings( myRightMode = getMode(properties, PropType::Controller_Right1); myRight2ndMode = getMode(properties, PropType::Controller_Right2); } - } + } else { const EventMode mode = getMode(type); @@ -459,7 +459,7 @@ bool PhysicalKeyboardHandler::isDrivingEvent(const Event::Type event) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool PhysicalKeyboardHandler::isCommonEvent(const Event::Type event) { - return !(isJoystickEvent(event) || isPaddleEvent(event) + return !(isJoystickEvent(event) || isPaddleEvent(event) || isKeyboardEvent(event) || isDrivingEvent(event)); } diff --git a/src/common/PhysicalJoystick.cxx b/src/common/PhysicalJoystick.cxx index 0b4cc68f0..b499da0ee 100644 --- a/src/common/PhysicalJoystick.cxx +++ b/src/common/PhysicalJoystick.cxx @@ -69,6 +69,7 @@ json PhysicalJoystick::getMap() const json mapping = json::object(); mapping["name"] = name; + mapping["port"] = getName(port); for (const auto& mode: { EventMode::kMenuMode, EventMode::kJoystickMode, EventMode::kPaddlesMode, EventMode::kKeyboardMode, EventMode::kDrivingMode, EventMode::kCommonMode @@ -84,14 +85,19 @@ bool PhysicalJoystick::setMap(const json& map) int i = 0; for (const auto& entry: map.items()) { - if (entry.key() == "name") continue; + if (entry.key() == "name") + continue; + if(entry.key() == "port") + { + port = getPort(entry.value()); + continue; + } try { joyMap.loadMapping(entry.value(), eventModeFromJsonName(entry.key())); } catch (const json::exception&) { Logger::error("ignoring invalid json mapping for " + entry.key()); } - i++; } @@ -107,6 +113,34 @@ bool PhysicalJoystick::setMap(const json& map) return true; } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string PhysicalJoystick::getName(const PhysicalJoystick::Port _port) const +{ + static constexpr std::array(PhysicalJoystick::Port::NUM_PORTS)> NAMES = + { + "Auto", "Left", "Right" + }; + + return string{NAMES[static_cast(_port)]}; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +PhysicalJoystick::Port PhysicalJoystick::getPort(string_view portName) const +{ + static constexpr std::array(PhysicalJoystick::Port::NUM_PORTS)> NAMES = + { + "Auto", "Left", "Right" + }; + + for(int i = 0; i < static_cast(PhysicalJoystick::Port::NUM_PORTS); ++i) + if (BSPF::equalsIgnoreCase(portName, NAMES[i])) + return PhysicalJoystick::Port{i}; + + return PhysicalJoystick::Port::AUTO; +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - json PhysicalJoystick::convertLegacyMapping(string_view mapping, string_view name) { @@ -167,7 +201,22 @@ void PhysicalJoystick::getValues(string_view list, IntArray& map) string PhysicalJoystick::about() const { ostringstream buf; - buf << "'" << name << "' with: " << numAxes << " axes, " << numButtons << " buttons, " + + buf << "'" << name << "' in "; + switch(port) + { + case Port::LEFT: + buf << "left"; + break; + case Port::RIGHT: + buf << "right"; + break; + default: + buf << "auto"; + break; + } + buf << " port with: " + << numAxes << " axes, " << numButtons << " buttons, " << numHats << " hats"; return buf.str(); diff --git a/src/common/PhysicalJoystick.hxx b/src/common/PhysicalJoystick.hxx index c079b1348..ee0aaa422 100644 --- a/src/common/PhysicalJoystick.hxx +++ b/src/common/PhysicalJoystick.hxx @@ -43,10 +43,18 @@ class PhysicalJoystick static constexpr char MODE_DELIM = '>'; // must not be '^', '|' or '#' public: + enum class Port { + AUTO, + LEFT, + RIGHT, + NUM_PORTS + }; + PhysicalJoystick() = default; nlohmann::json getMap() const; bool setMap(const nlohmann::json& map); + void setPort(const Port _port) { port = _port; } static nlohmann::json convertLegacyMapping(string_view mapping, string_view name); @@ -69,6 +77,7 @@ class PhysicalJoystick Type type{Type::REGULAR}; int ID{-1}; string name{"None"}; + Port port{Port::AUTO}; int numAxes{0}, numButtons{0}, numHats{0}; IntArray axisLastValue; IntArray buttonLast; @@ -79,6 +88,10 @@ class PhysicalJoystick private: static void getValues(string_view list, IntArray& map); + // Convert from string to Port type and vice versa + string getName(const Port _port) const; + Port getPort(string_view portName) const; + friend ostream& operator<<(ostream& os, const PhysicalJoystick& s) { os << " ID: " << s.ID << ", name: " << s.name << ", numaxis: " << s.numAxes << ", numbtns: " << s.numButtons << ", numhats: " << s.numHats; diff --git a/src/emucore/Event.hxx b/src/emucore/Event.hxx index efa863f4d..5020f6162 100644 --- a/src/emucore/Event.hxx +++ b/src/emucore/Event.hxx @@ -84,7 +84,7 @@ class Event UIUp, UIDown, UILeft, UIRight, UIHome, UIEnd, UIPgUp, UIPgDown, UISelect, UINavPrev, UINavNext, UIOK, UICancel, UIPrevDir, - UITabPrev, UITabNext, + UITabPrev, UITabNext, UIReload, NextMouseControl, ToggleGrabMouse, MouseAxisXMove, MouseAxisYMove, MouseAxisXValue, MouseAxisYValue, diff --git a/src/emucore/EventHandler.cxx b/src/emucore/EventHandler.cxx index 36d53a489..7c0b04e1b 100644 --- a/src/emucore/EventHandler.cxx +++ b/src/emucore/EventHandler.cxx @@ -169,6 +169,9 @@ void EventHandler::addPhysicalJoystick(const PhysicalJoystickPtr& joy) setActionMappings(EventMode::kEmulationMode); setActionMappings(EventMode::kMenuMode); + + if(myOverlay) + myOverlay->handleEvent(Event::UIReload); #endif } @@ -177,6 +180,9 @@ void EventHandler::removePhysicalJoystick(int id) { #ifdef JOYSTICK_SUPPORT myPJoyHandler->remove(id); + + if(myOverlay) + myOverlay->handleEvent(Event::UIReload); #endif } @@ -2078,6 +2084,15 @@ void EventHandler::removePhysicalJoystickFromDatabase(string_view name) #endif } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void EventHandler::setPhysicalJoystickPortInDatabase(string_view name, + PhysicalJoystick::Port port) +{ +#ifdef JOYSTICK_SUPPORT + myPJoyHandler->setPort(name, port); +#endif +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - bool EventHandler::addKeyMapping(Event::Type event, EventMode mode, StellaKey key, StellaMod mod) { diff --git a/src/emucore/EventHandler.hxx b/src/emucore/EventHandler.hxx index d3956ec9d..49b388f2c 100644 --- a/src/emucore/EventHandler.hxx +++ b/src/emucore/EventHandler.hxx @@ -333,11 +333,10 @@ class EventHandler bool hasOverlay() const { return myOverlay != nullptr; } /** - Return a list of all physical joysticks currently in the internal database - (first part of variant) and its internal ID (second part of variant). + Return a simple list of all physical joysticks currently in the internal database */ - VariantList physicalJoystickDatabase() const { - return myPJoyHandler->database(); + PhysicalJoystickHandler::MinStrickInfoList physicalJoystickList() const { + return myPJoyHandler->minStickList(); } /** @@ -346,6 +345,12 @@ class EventHandler */ void removePhysicalJoystickFromDatabase(string_view name); + /** + Change the port of the physical joystick identified by 'name' in + the joystick database, only if it is not currently active. + */ + void setPhysicalJoystickPortInDatabase(string_view name, PhysicalJoystick::Port port); + /** Enable/disable text events (distinct from single-key events). */ diff --git a/src/gui/Dialog.hxx b/src/gui/Dialog.hxx index a1b12486b..1ea2e3257 100644 --- a/src/gui/Dialog.hxx +++ b/src/gui/Dialog.hxx @@ -168,6 +168,7 @@ class Dialog : public GuiObject virtual void handleJoyUp(int stick, int button); virtual void handleJoyAxis(int stick, JoyAxis axis, JoyDir adir, int button = JOY_CTRL_NONE); virtual bool handleJoyHat(int stick, int hat, JoyHatDir hdir, int button = JOY_CTRL_NONE); + virtual void handleEvent(Event::Type event) {}; void handleCommand(CommandSender* sender, int cmd, int data, int id) override; virtual Event::Type getJoyAxisEvent(int stick, JoyAxis axis, JoyDir adir, int button); diff --git a/src/gui/DialogContainer.cxx b/src/gui/DialogContainer.cxx index dd52b299a..293257d8b 100644 --- a/src/gui/DialogContainer.cxx +++ b/src/gui/DialogContainer.cxx @@ -425,6 +425,18 @@ void DialogContainer::handleJoyHatEvent(int stick, int hat, JoyHatDir hdir, int activeDialog->handleJoyHat(stick, hat, hdir, button); } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void DialogContainer::handleEvent(Event::Type event) +{ + if(myDialogStack.empty()) + return; + + // Send the event to the dialog box on the top of the stack + Dialog* activeDialog = myDialogStack.top(); + + activeDialog->handleEvent(event); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void DialogContainer::reset() { diff --git a/src/gui/DialogContainer.hxx b/src/gui/DialogContainer.hxx index caf18ce40..83d6c0e09 100644 --- a/src/gui/DialogContainer.hxx +++ b/src/gui/DialogContainer.hxx @@ -23,6 +23,7 @@ class OSystem; class EventHandler; #include "EventHandlerConstants.hxx" +#include "Event.hxx" #include "StellaKeys.hxx" #include "Stack.hxx" #include "bspf.hxx" @@ -119,6 +120,13 @@ class DialogContainer */ void handleJoyHatEvent(int stick, int hat, JoyHatDir hdir, int button); + /** + Handle an arbitray dialog event. + + @param event The send event + */ + void handleEvent(Event::Type event); + /** Tick the dialog and all its widgets. */ diff --git a/src/gui/JoystickDialog.cxx b/src/gui/JoystickDialog.cxx index 4a986f450..fc8800033 100644 --- a/src/gui/JoystickDialog.cxx +++ b/src/gui/JoystickDialog.cxx @@ -20,6 +20,7 @@ #include "Widget.hxx" #include "Font.hxx" #include "EditTextWidget.hxx" +#include "PopUpWidget.hxx" #include "StringListWidget.hxx" #include "Variant.hxx" #include "JoystickDialog.hxx" @@ -47,12 +48,23 @@ JoystickDialog::JoystickDialog(GuiObject* boss, const GUI::Font& font, // Joystick ID ypos = _h - VBORDER - (buttonHeight + lineHeight) / 2; - auto* t = new StaticTextWidget(this, font, xpos, ypos+2, "Controller ID "); + auto* t = new StaticTextWidget(this, font, xpos, ypos, "Controller ID "); xpos += t->getWidth(); - myJoyText = new EditTextWidget(this, font, xpos, ypos, - font.getStringWidth("Unplugged "), font.getLineHeight(), ""); + myJoyText = new EditTextWidget(this, font, xpos, ypos - 2, + font.getStringWidth("Unplugged "), lineHeight, ""); myJoyText->setEditable(false); + // Port + VariantList ports; + VarList::push_back(ports, "Auto", static_cast(PhysicalJoystick::Port::AUTO)); + VarList::push_back(ports, "Left", static_cast(PhysicalJoystick::Port::LEFT)); + VarList::push_back(ports, "Right", static_cast(PhysicalJoystick::Port::RIGHT)); + + myJoyPort = new PopUpWidget(this, font, myJoyText->getRight() + fontWidth * 2, ypos - 1, + font.getStringWidth("Right"), lineHeight, ports, "Port ", 0, kPortCmd); + myJoyPort->setToolTip("Define default mapping port."); + wid.push_back(myJoyPort); + // Add buttons at bottom xpos = _w - buttonWidth - HBORDER; ypos = _h - VBORDER - buttonHeight; @@ -77,10 +89,11 @@ void JoystickDialog::loadConfig() myJoyIDs.clear(); StringList sticks; - for(const auto& [_name, _id]: instance().eventHandler().physicalJoystickDatabase()) + for(const auto& _entry : instance().eventHandler().physicalJoystickList()) { - sticks.push_back(_name); - myJoyIDs.push_back(_id.toInt()); + sticks.push_back(_entry.name); + myJoyIDs.push_back(_entry.ID); + myJoyPorts.push_back(static_cast(_entry.port)); } myJoyList->setList(sticks); myJoyList->setSelected(0); @@ -91,6 +104,13 @@ void JoystickDialog::loadConfig() } } +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void JoystickDialog::handleEvent(Event::Type event) +{ + if(event == Event::Type::UIReload) + loadConfig(); +} + // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void JoystickDialog::handleCommand(CommandSender* sender, int cmd, int data, int id) { @@ -100,6 +120,13 @@ void JoystickDialog::handleCommand(CommandSender* sender, int cmd, int data, int close(); break; + case kPortCmd: + myJoyPorts[myJoyList->getSelected()] = myJoyPort->getSelected(); + instance().eventHandler().setPhysicalJoystickPortInDatabase( + myJoyList->getSelectedString(), + static_cast(myJoyPort->getSelected())); + break; + case kRemoveCmd: instance().eventHandler().removePhysicalJoystickFromDatabase( myJoyList->getSelectedString()); @@ -107,20 +134,24 @@ void JoystickDialog::handleCommand(CommandSender* sender, int cmd, int data, int break; case ListWidget::kSelectionChangedCmd: - if(myJoyIDs[data] >= 0) + { + const bool isPlugged = myJoyIDs[data] >= 0; + if(isPlugged) { - myRemoveBtn->setEnabled(false); ostringstream buf; buf << "C" << myJoyIDs[data]; myJoyText->setText(buf.str()); + myJoyPort->setSelected(myJoyPorts[data]); } else { - myRemoveBtn->setEnabled(true); myJoyText->setText("Unplugged"); + myJoyPort->setText(""); } + myJoyPort->setEnabled(isPlugged); + myRemoveBtn->setEnabled(!isPlugged); break; - + } default: Dialog::handleCommand(sender, cmd, data, id); break; diff --git a/src/gui/JoystickDialog.hxx b/src/gui/JoystickDialog.hxx index 2079516ad..bf12302b4 100644 --- a/src/gui/JoystickDialog.hxx +++ b/src/gui/JoystickDialog.hxx @@ -22,6 +22,7 @@ class CommandSender; class GuiObject; class ButtonWidget; class EditTextWidgetWidget; +class PopUpWidget; class StringListWidget; #include "Dialog.hxx" @@ -43,17 +44,23 @@ class JoystickDialog : public Dialog private: void loadConfig() override; void handleCommand(CommandSender* sender, int cmd, int data, int id) override; + void handleEvent(Event::Type event) override; private: StringListWidget* myJoyList{nullptr}; EditTextWidget* myJoyText{nullptr}; + PopUpWidget* myJoyPort{nullptr}; ButtonWidget* myRemoveBtn{nullptr}; ButtonWidget* myCloseBtn{nullptr}; IntArray myJoyIDs; + IntArray myJoyPorts; - enum { kRemoveCmd = 'JDrm' }; + enum { + kRemoveCmd = 'JDrm', + kPortCmd = 'JDpt' + }; private: // Following constructors and assignment operators not supported diff --git a/src/os/windows/Stella.vcxproj b/src/os/windows/Stella.vcxproj index 05ab4683f..d659a040d 100755 --- a/src/os/windows/Stella.vcxproj +++ b/src/os/windows/Stella.vcxproj @@ -646,7 +646,7 @@ MachineX64 - PGUpdate + PGOptimization