diff --git a/src/common/PJoystickHandler.cxx b/src/common/PJoystickHandler.cxx index f7c02fe2f..f888b4efa 100644 --- a/src/common/PJoystickHandler.cxx +++ b/src/common/PJoystickHandler.cxx @@ -321,33 +321,37 @@ void PhysicalJoystickHandler::setDefaultMapping(Event::Type event, EventMode mod } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PhysicalJoystickHandler::defineControllerMappings(const string& controllerName, Controller::Jack port) +void PhysicalJoystickHandler::defineControllerMappings(const Controller::Type type, Controller::Jack port) { // determine controller events to use - if ((controllerName == "KEYBOARD") || (controllerName == "KEYPAD")) + switch(type) { - if (port == Controller::Jack::Left) - myLeftMode = EventMode::kKeypadMode; - else - myRightMode = EventMode::kKeypadMode; - } - else if (BSPF::startsWithIgnoreCase(controllerName, "PADDLES")) - { - if (port == Controller::Jack::Left) - myLeftMode = EventMode::kPaddlesMode; - else - myRightMode = EventMode::kPaddlesMode; - } - else if (controllerName == "CM") - { - myLeftMode = myRightMode = EventMode::kCompuMateMode; - } - else - { - if (port == Controller::Jack::Left) - myLeftMode = EventMode::kJoystickMode; - else - myRightMode = EventMode::kJoystickMode; + case Controller::Type::Keyboard: + if(port == Controller::Jack::Left) + myLeftMode = EventMode::kKeypadMode; + else + myRightMode = EventMode::kKeypadMode; + break; + + case Controller::Type::Paddles: + case Controller::Type::PaddlesIAxDr: + case Controller::Type::PaddlesIAxis: + if(port == Controller::Jack::Left) + myLeftMode = EventMode::kPaddlesMode; + else + myRightMode = EventMode::kPaddlesMode; + break; + + case Controller::Type::CompuMate: + myLeftMode = myRightMode = EventMode::kCompuMateMode; + break; + + default: + // let's use joystick then + if(port == Controller::Jack::Left) + myLeftMode = EventMode::kJoystickMode; + else + myRightMode = EventMode::kJoystickMode; } } diff --git a/src/common/PJoystickHandler.hxx b/src/common/PJoystickHandler.hxx index c40a85b06..a9f54a124 100644 --- a/src/common/PJoystickHandler.hxx +++ b/src/common/PJoystickHandler.hxx @@ -71,7 +71,7 @@ class PhysicalJoystickHandler void setDefaultMapping(Event::Type type, EventMode mode); /** define mappings for current controllers */ - void defineControllerMappings(const string& controllerName, Controller::Jack port); + void defineControllerMappings(const Controller::Type type, Controller::Jack port); /** enable mappings for emulation mode */ void enableEmulationMappings(); diff --git a/src/common/PKeyboardHandler.cxx b/src/common/PKeyboardHandler.cxx index cd837d7ac..f669b0916 100644 --- a/src/common/PKeyboardHandler.cxx +++ b/src/common/PKeyboardHandler.cxx @@ -139,33 +139,37 @@ void PhysicalKeyboardHandler::setDefaultMapping(Event::Type event, EventMode mod } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -void PhysicalKeyboardHandler::defineControllerMappings(const string& controllerName, Controller::Jack port) +void PhysicalKeyboardHandler::defineControllerMappings(const Controller::Type type, Controller::Jack port) { // determine controller events to use - if ((controllerName == "KEYBOARD") || (controllerName == "KEYPAD")) + switch(type) { - if (port == Controller::Jack::Left) - myLeftMode = EventMode::kKeypadMode; - else - myRightMode = EventMode::kKeypadMode; - } - else if (BSPF::startsWithIgnoreCase(controllerName, "PADDLES")) - { - if (port == Controller::Jack::Left) - myLeftMode = EventMode::kPaddlesMode; - else - myRightMode = EventMode::kPaddlesMode; - } - else if (controllerName == "CM") - { - myLeftMode = myRightMode = EventMode::kCompuMateMode; - } - else - { - if (port == Controller::Jack::Left) - myLeftMode = EventMode::kJoystickMode; - else - myRightMode = EventMode::kJoystickMode; + case Controller::Type::Keyboard: + if(port == Controller::Jack::Left) + myLeftMode = EventMode::kKeypadMode; + else + myRightMode = EventMode::kKeypadMode; + break; + + case Controller::Type::Paddles: + case Controller::Type::PaddlesIAxDr: + case Controller::Type::PaddlesIAxis: + if(port == Controller::Jack::Left) + myLeftMode = EventMode::kPaddlesMode; + else + myRightMode = EventMode::kPaddlesMode; + break; + + case Controller::Type::CompuMate: + myLeftMode = myRightMode = EventMode::kCompuMateMode; + break; + + default: + // let's use joystick then + if(port == Controller::Jack::Left) + myLeftMode = EventMode::kJoystickMode; + else + myRightMode = EventMode::kJoystickMode; } } diff --git a/src/common/PKeyboardHandler.hxx b/src/common/PKeyboardHandler.hxx index d24d3ca17..8c9aab5f1 100644 --- a/src/common/PKeyboardHandler.hxx +++ b/src/common/PKeyboardHandler.hxx @@ -48,7 +48,7 @@ class PhysicalKeyboardHandler void setDefaultMapping(Event::Type type, EventMode mode, bool updateDefaults = false); /** define mappings for current controllers */ - void defineControllerMappings(const string& controllerName, Controller::Jack port); + void defineControllerMappings(const Controller::Type type, Controller::Jack port); /** enable mappings for emulation mode */ void enableEmulationMappings(); diff --git a/src/emucore/Console.cxx b/src/emucore/Console.cxx index ed0d56484..3d65f698c 100644 --- a/src/emucore/Console.cxx +++ b/src/emucore/Console.cxx @@ -801,14 +801,14 @@ void Console::setControllers(const string& romMd5) myLeftControl = std::move(myCMHandler->leftController()); myRightControl = std::move(myCMHandler->rightController()); - myOSystem.eventHandler().defineKeyControllerMappings("CM", Controller::Jack::Left); - myOSystem.eventHandler().defineJoyControllerMappings("CM", Controller::Jack::Left); + myOSystem.eventHandler().defineKeyControllerMappings(Controller::Type::CompuMate, Controller::Jack::Left); + myOSystem.eventHandler().defineJoyControllerMappings(Controller::Type::CompuMate, Controller::Jack::Left); } else { // Setup the controllers based on properties - string left = myProperties.get(PropType::Controller_Left); - string right = myProperties.get(PropType::Controller_Right); + Controller::Type leftType = Controller::getType(myProperties.get(PropType::Controller_Left)); + Controller::Type rightType = Controller::getType(myProperties.get(PropType::Controller_Right)); uInt32 size = 0; const uInt8* image = myCart->getImage(size); const bool swappedPorts = myProperties.get(PropType::Console_SwapPorts) == "YES"; @@ -816,14 +816,14 @@ void Console::setControllers(const string& romMd5) // Try to detect controllers if(image != nullptr || size != 0) { - left = ControllerDetector::detectType(image, size, left, + leftType = ControllerDetector::detectType(image, size, leftType, !swappedPorts ? Controller::Jack::Left : Controller::Jack::Right, myOSystem.settings()); - right = ControllerDetector::detectType(image, size, right, + rightType = ControllerDetector::detectType(image, size, rightType, !swappedPorts ? Controller::Jack::Right : Controller::Jack::Left, myOSystem.settings()); } - unique_ptr leftC = getControllerPort(left, Controller::Jack::Left, romMd5), - rightC = getControllerPort(right, Controller::Jack::Right, romMd5); + unique_ptr leftC = getControllerPort(leftType, Controller::Jack::Left, romMd5), + rightC = getControllerPort(rightType, Controller::Jack::Right, romMd5); // Swap the ports if necessary if(!swappedPorts) @@ -848,90 +848,95 @@ void Console::setControllers(const string& romMd5) } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -unique_ptr Console::getControllerPort(const string& controllerName, - Controller::Jack port, const string& romMd5) +unique_ptr Console::getControllerPort(const Controller::Type type, + const Controller::Jack port, const string& romMd5) { unique_ptr controller; - myOSystem.eventHandler().defineKeyControllerMappings(controllerName, port); - myOSystem.eventHandler().defineJoyControllerMappings(controllerName, port); + myOSystem.eventHandler().defineKeyControllerMappings(type, port); + myOSystem.eventHandler().defineJoyControllerMappings(type, port); - if(controllerName == "JOYSTICK") + switch(type) { - // always create because it may have been changed by user dialog - controller = make_unique(port, myEvent, *mySystem); + case Controller::Type::BoosterGrip: + controller = make_unique(port, myEvent, *mySystem); + break; + + case Controller::Type::Driving: + controller = make_unique(port, myEvent, *mySystem); + break; + + case Controller::Type::Keyboard: + controller = make_unique(port, myEvent, *mySystem); + break; + + case Controller::Type::Paddles: + case Controller::Type::PaddlesIAxis: + case Controller::Type::PaddlesIAxDr: + { + // Also check if we should swap the paddles plugged into a jack + bool swapPaddles = myProperties.get(PropType::Controller_SwapPaddles) == "YES"; + bool swapAxis = false, swapDir = false; + if(type == Controller::Type::PaddlesIAxis) + swapAxis = true; + else if(type == Controller::Type::PaddlesIAxDr) + swapAxis = swapDir = true; + controller = make_unique(port, myEvent, *mySystem, + swapPaddles, swapAxis, swapDir); + break; + } + case Controller::Type::AmigaMouse: + controller = make_unique(port, myEvent, *mySystem); + break; + + case Controller::Type::AtariMouse: + controller = make_unique(port, myEvent, *mySystem); + break; + + case Controller::Type::TrakBall: + controller = make_unique(port, myEvent, *mySystem); + break; + + case Controller::Type::AtariVox: + { + const string& nvramfile = myOSystem.nvramDir() + "atarivox_eeprom.dat"; + Controller::onMessageCallback callback = [&os = myOSystem](const string& msg) { + bool devSettings = os.settings().getBool("dev.settings"); + if(os.settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess")) + os.frameBuffer().showMessage(msg); + }; + controller = make_unique(port, myEvent, *mySystem, + myOSystem.settings().getString("avoxport"), nvramfile, callback); + break; + } + case Controller::Type::SaveKey: + { + const string& nvramfile = myOSystem.nvramDir() + "savekey_eeprom.dat"; + Controller::onMessageCallback callback = [&os = myOSystem](const string& msg) { + bool devSettings = os.settings().getBool("dev.settings"); + if(os.settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess")) + os.frameBuffer().showMessage(msg); + }; + controller = make_unique(port, myEvent, *mySystem, nvramfile, callback); + break; + } + case Controller::Type::Genesis: + controller = make_unique(port, myEvent, *mySystem); + break; + + case Controller::Type::KidVid: + controller = make_unique(port, myEvent, *mySystem, romMd5); + break; + + case Controller::Type::MindLink: + controller = make_unique(port, myEvent, *mySystem); + break; + + default: + // What else can we do? + // always create because it may have been changed by user dialog + controller = make_unique(port, myEvent, *mySystem); } - else if(controllerName == "BOOSTERGRIP") - { - controller = make_unique(port, myEvent, *mySystem); - } - else if(controllerName == "DRIVING") - { - controller = make_unique(port, myEvent, *mySystem); - } - else if((controllerName == "KEYBOARD") || (controllerName == "KEYPAD")) - { - controller = make_unique(port, myEvent, *mySystem); - } - else if(BSPF::startsWithIgnoreCase(controllerName, "PADDLES")) - { - // Also check if we should swap the paddles plugged into a jack - bool swapPaddles = myProperties.get(PropType::Controller_SwapPaddles) == "YES"; - bool swapAxis = false, swapDir = false; - if(controllerName == "PADDLES_IAXIS") - swapAxis = true; - else if(controllerName == "PADDLES_IAXDR") - swapAxis = swapDir = true; - controller = make_unique(port, myEvent, *mySystem, - swapPaddles, swapAxis, swapDir); - } - else if(controllerName == "AMIGAMOUSE") - { - controller = make_unique(port, myEvent, *mySystem); - } - else if(controllerName == "ATARIMOUSE") - { - controller = make_unique(port, myEvent, *mySystem); - } - else if(controllerName == "TRAKBALL") - { - controller = make_unique(port, myEvent, *mySystem); - } - else if(controllerName == "ATARIVOX") - { - const string& nvramfile = myOSystem.nvramDir() + "atarivox_eeprom.dat"; - Controller::onMessageCallback callback = [&os = myOSystem](const string& msg) { - bool devSettings = os.settings().getBool("dev.settings"); - if(os.settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess")) - os.frameBuffer().showMessage(msg); - }; - controller = make_unique(port, myEvent, *mySystem, - myOSystem.settings().getString("avoxport"), nvramfile, callback); - } - else if(controllerName == "SAVEKEY") - { - const string& nvramfile = myOSystem.nvramDir() + "savekey_eeprom.dat"; - Controller::onMessageCallback callback = [&os = myOSystem](const string& msg) { - bool devSettings = os.settings().getBool("dev.settings"); - if(os.settings().getBool(devSettings ? "dev.eepromaccess" : "plr.eepromaccess")) - os.frameBuffer().showMessage(msg); - }; - controller = make_unique(port, myEvent, *mySystem, nvramfile, callback); - } - else if(controllerName == "GENESIS") - { - controller = make_unique(port, myEvent, *mySystem); - } - else if(controllerName == "KIDVID") - { - controller = make_unique(port, myEvent, *mySystem, romMd5); - } - else if(controllerName == "MINDLINK") - { - controller = make_unique(port, myEvent, *mySystem); - } - else // What else can we do? - controller = make_unique(port, myEvent, *mySystem); return controller; } diff --git a/src/emucore/Console.hxx b/src/emucore/Console.hxx index ac84a8fd0..9d59b4b81 100644 --- a/src/emucore/Console.hxx +++ b/src/emucore/Console.hxx @@ -339,8 +339,8 @@ class Console : public Serializable, public ConsoleIO /** Selects the left or right controller depending on ROM properties */ - unique_ptr getControllerPort(const string& controllerName, - Controller::Jack port, const string& romMd5); + unique_ptr getControllerPort(const Controller::Type type, + const Controller::Jack port, const string& romMd5); /** Loads a user-defined palette file (from OSystem::paletteFile), filling the diff --git a/src/emucore/Control.cxx b/src/emucore/Control.cxx index 99d73695e..424b7bb78 100644 --- a/src/emucore/Control.cxx +++ b/src/emucore/Control.cxx @@ -103,3 +103,48 @@ bool Controller::load(Serializer& in) } return true; } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string Controller::getName(const Type type) +{ + string NAMES[int(Controller::Type::LastType)] = + { + "Unknown", + "AmigaMouse", "AtariMouse", "AtariVox", "BoosterGrip", "CompuMate", + "Driving", "Sega Genesis", "Joystick", "Keyboard", "KidVid", "MindLink", + "Paddles", "Paddles_IAxis", "Paddles_IAxDr", "SaveKey", "TrakBall" + }; + + return NAMES[int(type)]; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +string Controller::getPropName(const Type type) +{ + string PROP_NAMES[int(Controller::Type::LastType)] = + { + "AUTO", + "AMIGAMOUSE", "ATARIMOUSE", "ATARIVOX", "BOOSTERGRIP", "COMPUMATE", + "DRIVING", "GENESIS", "JOYSTICK", "KEYBOARD", "KIDVID", "MINDLINK", + "PADDLES", "PADDLES_IAXIS", "PADDLES_IAXDR", "SAVEKEY", "TRAKBALL" + }; + + return PROP_NAMES[int(type)]; +} + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +Controller::Type Controller::getType(const string& propName) +{ + for(int i = 0; i < static_cast(Type::LastType); ++i) + { + if(BSPF::equalsIgnoreCase(propName, getPropName(Type(i)))) + { + return Type(i); + } + } + // special case + if(BSPF::equalsIgnoreCase(propName, "KEYPAD")) + return Type::Keyboard; + + return Type::Unknown; +} diff --git a/src/emucore/Control.hxx b/src/emucore/Control.hxx index 9693cac31..0a61a2fff 100644 --- a/src/emucore/Control.hxx +++ b/src/emucore/Control.hxx @@ -90,9 +90,11 @@ class Controller : public Serializable */ enum class Type { + Unknown, AmigaMouse, AtariMouse, AtariVox, BoosterGrip, CompuMate, Driving, Genesis, Joystick, Keyboard, KidVid, MindLink, - Paddles, SaveKey, TrakBall + Paddles, PaddlesIAxis, PaddlesIAxDr, SaveKey, TrakBall, + LastType }; /** @@ -254,6 +256,21 @@ class Controller : public Serializable myOnAnalogPinUpdateCallback = callback; } + /** + Returns the display name of the given controller type + */ + static string getName(const Type type); + + /** + Returns the property name of the given controller type + */ + static string getPropName(const Type type); + + /** + Returns the controller type of the given property name + */ + static Type getType(const string& propName); + public: /// Constant which represents maximum resistance for analog pins static constexpr Int32 MAX_RESISTANCE = 0x7FFFFFFF; diff --git a/src/emucore/ControllerDetector.cxx b/src/emucore/ControllerDetector.cxx index ee1a02dd3..9f51f64be 100644 --- a/src/emucore/ControllerDetector.cxx +++ b/src/emucore/ControllerDetector.cxx @@ -17,26 +17,27 @@ //============================================================================ #include "Settings.hxx" +#include "Logger.hxx" #include "ControllerDetector.hxx" // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string ControllerDetector::detectType(const uInt8* image, uInt32 size, - const string& controller, const Controller::Jack port, - const Settings& settings) +Controller::Type ControllerDetector::detectType(const uInt8* image, uInt32 size, + const Controller::Type type, const Controller::Jack port, + const Settings& settings) { - string type(controller); - - if(type == "AUTO" || settings.getBool("rominfo")) + if(type == Controller::Type::Unknown || settings.getBool("rominfo")) { - string detectedType = autodetectPort(image, size, port, settings); + Controller::Type detectedType = autodetectPort(image, size, port, settings); - if(type != "AUTO" && type != detectedType) + if(type != Controller::Type::Unknown && type != detectedType) { cerr << "Controller auto-detection not consistent: " - << type << ", " << detectedType << endl; + << Controller::getName(type) << ", " << Controller::getName(detectedType) << endl; } - type = detectedType; + Logger::debug(Controller::getName(detectedType) + " detected for " + + (port == Controller::Jack::Left ? "left" : "right") + " port"); + return detectedType; } return type; @@ -44,38 +45,39 @@ string ControllerDetector::detectType(const uInt8* image, uInt32 size, // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - string ControllerDetector::detectName(const uInt8* image, uInt32 size, - const string& controller, const Controller::Jack port, + const Controller::Type controller, const Controller::Jack port, const Settings& settings) { - return getControllerName(detectType(image, size, controller, port, settings)); + return Controller::getName(detectType(image, size, controller, port, settings)); } // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -string ControllerDetector::autodetectPort(const uInt8* image, uInt32 size, - Controller::Jack port, const Settings& settings) +Controller::Type ControllerDetector::autodetectPort(const uInt8* image, uInt32 size, + Controller::Jack port, const Settings& settings) { // default type joystick - string type = "JOYSTICK"; // TODO: remove magic strings + Controller::Type type = Controller::Type::Joystick; if(isProbablySaveKey(image, size, port)) - type = "SAVEKEY"; + type = Controller::Type::SaveKey; else if(usesJoystickButton(image, size, port)) { if(isProbablyTrakBall(image, size)) - type = "TRAKBALL"; + type = Controller::Type::TrakBall; else if(isProbablyAtariMouse(image, size)) - type = "ATARIMOUSE"; + type = Controller::Type::AmigaMouse; else if(isProbablyAmigaMouse(image, size)) - type = "AMIGAMOUSE"; + type = Controller::Type::AmigaMouse; else if(usesKeyboard(image, size, port)) - type = "KEYBOARD"; + type = Controller::Type::Keyboard; else if(usesGenesisButton(image, size, port)) - type = "GENESIS"; + + type = Controller::Type::Genesis; } else { if(usesPaddle(image, size, port, settings)) - type = "PADDLES"; + type = Controller::Type::Paddles; } // TODO: BOOSTERGRIP, DRIVING, MINDLINK, ATARIVOX, KIDVID // not detectable: PADDLES_IAXIS, PADDLES_IAXDR @@ -638,44 +640,3 @@ bool ControllerDetector::isProbablySaveKey(const uInt8* image, uInt32 size, Cont return false; } - -// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -const string ControllerDetector::getControllerName(const string& controller) -{ - // auto detected: - if(BSPF::equalsIgnoreCase(controller, "JOYSTICK")) - return "Joystick"; - if(BSPF::equalsIgnoreCase(controller, "SAVEKEY")) - return "SaveKey"; - if(BSPF::equalsIgnoreCase(controller, "TRAKBALL")) - return "TrakBall"; - if(BSPF::equalsIgnoreCase(controller, "ATARIMOUSE")) - return "AtariMouse"; - if(BSPF::equalsIgnoreCase(controller, "AMIGAMOUSE")) - return "AmigaMouse"; - if(BSPF::equalsIgnoreCase(controller, "KEYBOARD")) - return "Keyboard"; - if(BSPF::equalsIgnoreCase(controller, "GENESIS")) - return "Sega Genesis"; - if(BSPF::equalsIgnoreCase(controller, "PADDLES")) - return "Paddles"; - // not auto detected: - if(BSPF::equalsIgnoreCase(controller, "BOOSTERGRIP")) - return "BoosterGrip"; - if(BSPF::equalsIgnoreCase(controller, "DRIVING")) - return "Driving"; - if(BSPF::equalsIgnoreCase(controller, "MINDLINK")) - return "MindLink"; - if(BSPF::equalsIgnoreCase(controller, "ATARIVOX")) - return "AtariVox"; - if(BSPF::equalsIgnoreCase(controller, "PADDLES_IAXIS")) - return "Paddles IAxis"; - if(BSPF::equalsIgnoreCase(controller, "PADDLES_IAXDR")) - return "Paddles IAxDr"; - if(BSPF::equalsIgnoreCase(controller, "COMPUMATE")) - return "CompuMate"; - if(BSPF::equalsIgnoreCase(controller, "KIDVID")) - return "KidVid"; - - return controller; -} diff --git a/src/emucore/ControllerDetector.hxx b/src/emucore/ControllerDetector.hxx index 529ff4de3..0eaea7903 100644 --- a/src/emucore/ControllerDetector.hxx +++ b/src/emucore/ControllerDetector.hxx @@ -15,7 +15,6 @@ // this file, and for a DISCLAIMER OF ALL WARRANTIES. //============================================================================ - #ifndef CONTROLLER_DETECTOR_HXX #define CONTROLLER_DETECTOR_HXX @@ -40,9 +39,9 @@ class ControllerDetector @param settings A reference to the various settings (read-only) @return The detected controller type */ - static string detectType(const uInt8* image, uInt32 size, - const string& controller, const Controller::Jack port, - const Settings& settings); + static Controller::Type detectType(const uInt8* image, uInt32 size, + const Controller::Type controller, const Controller::Jack port, + const Settings& settings); /** Detects the controller type at the given port if no controller is provided @@ -50,25 +49,16 @@ class ControllerDetector @param image A pointer to the ROM image @param size The size of the ROM image - @param controller The provided controller type of the ROM image + @param type The provided controller type of the ROM image @param port The port to be checked @param settings A reference to the various settings (read-only) @return The (detected) controller name */ static string detectName(const uInt8* image, uInt32 size, - const string& controller, const Controller::Jack port, + const Controller::Type type, const Controller::Jack port, const Settings& settings); - /** - Returns a nicer formatted name for the given controller. - - @param controller The provided controller type of the ROM image - - @return The controller name - */ - static const string getControllerName(const string& controller); - private: /** Detects the controller type at the given port. @@ -80,8 +70,8 @@ class ControllerDetector @return The detected controller type */ - static string autodetectPort(const uInt8* image, uInt32 size, Controller::Jack port, - const Settings& settings); + static Controller::Type autodetectPort(const uInt8* image, uInt32 size, Controller::Jack port, + const Settings& settings); /** Search the image for the specified byte signature. diff --git a/src/emucore/EventHandler.hxx b/src/emucore/EventHandler.hxx index b2112dbc4..33fa0b03c 100644 --- a/src/emucore/EventHandler.hxx +++ b/src/emucore/EventHandler.hxx @@ -194,8 +194,8 @@ class EventHandler /** Enable controller specific keyboard event mappings. */ - void defineKeyControllerMappings(const string& controllerName, Controller::Jack port) { - myPKeyHandler->defineControllerMappings(controllerName, port); + void defineKeyControllerMappings(const Controller::Type type, Controller::Jack port) { + myPKeyHandler->defineControllerMappings(type, port); } /** @@ -245,8 +245,8 @@ class EventHandler /** Enable controller specific keyboard event mappings. */ - void defineJoyControllerMappings(const string& controllerName, Controller::Jack port) { - myPJoyHandler->defineControllerMappings(controllerName, port); + void defineJoyControllerMappings(const Controller::Type type, Controller::Jack port) { + myPJoyHandler->defineControllerMappings(type, port); } /** diff --git a/src/gui/GameInfoDialog.cxx b/src/gui/GameInfoDialog.cxx index 9317e6c87..ee545c427 100644 --- a/src/gui/GameInfoDialog.cxx +++ b/src/gui/GameInfoDialog.cxx @@ -462,50 +462,10 @@ void GameInfoDialog::loadConsoleProperties(const Properties& props) // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void GameInfoDialog::loadControllerProperties(const Properties& props) { - bool swapPorts = props.get(PropType::Console_SwapPorts) == "YES"; - bool autoDetect = false; - ByteBuffer image; - string md5 = props.get(PropType::Cart_MD5); - uInt32 size = 0; - - // try to load the image for auto detection - if(!instance().hasConsole()) - { - const FilesystemNode& node = FilesystemNode(instance().launcher().selectedRom()); - - autoDetect = node.exists() && !node.isDirectory() && (image = instance().openROM(node, md5, size)) != nullptr; - } - string label = ""; string controller = props.get(PropType::Controller_Left); - myLeftPort->setSelected(controller, "AUTO"); - if(myLeftPort->getSelectedTag().toString() == "AUTO") - { - if(instance().hasConsole()) - label = (!swapPorts ? instance().console().leftController().name() - : instance().console().rightController().name()) + " detected"; - else if(autoDetect) - label = ControllerDetector::detectName(image.get(), size, controller, - !swapPorts ? Controller::Jack::Left : Controller::Jack::Right, - instance().settings()) + " detected"; - } - myLeftPortDetected->setLabel(label); - - label = ""; controller = props.get(PropType::Controller_Right); - myRightPort->setSelected(controller, "AUTO"); - if(myRightPort->getSelectedTag().toString() == "AUTO") - { - if(instance().hasConsole()) - label = (!swapPorts ? instance().console().rightController().name() - : instance().console().leftController().name()) + " detected"; - else if(autoDetect) - label = ControllerDetector::detectName(image.get(), size, controller, - !swapPorts ? Controller::Jack::Right : Controller::Jack::Left, - instance().settings()) + " detected"; - } - myRightPortDetected->setLabel(label); mySwapPorts->setState(props.get(PropType::Console_SwapPorts) == "YES"); mySwapPaddles->setState(props.get(PropType::Controller_SwapPaddles) == "YES"); @@ -650,6 +610,49 @@ void GameInfoDialog::setDefaults() // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - void GameInfoDialog::updateControllerStates() { + bool swapPorts = mySwapPorts->getState(); + bool autoDetect = false; + ByteBuffer image; + string md5 = myGameProperties.get(PropType::Cart_MD5); + uInt32 size = 0; + + // try to load the image for auto detection + if(!instance().hasConsole()) + { + const FilesystemNode& node = FilesystemNode(instance().launcher().selectedRom()); + + autoDetect = node.exists() && !node.isDirectory() && (image = instance().openROM(node, md5, size)) != nullptr; + } + string label = ""; + Controller::Type type = Controller::getType(myLeftPort->getSelectedTag().toString()); + + if(type == Controller::Type::Unknown) + { + if(instance().hasConsole()) + label = (!swapPorts ? instance().console().leftController().name() + : instance().console().rightController().name()) + " detected"; + else if(autoDetect) + label = ControllerDetector::detectName(image.get(), size, type, + !swapPorts ? Controller::Jack::Left : Controller::Jack::Right, + instance().settings()) + " detected"; + } + myLeftPortDetected->setLabel(label); + + label = ""; + type = Controller::getType(myRightPort->getSelectedTag().toString()); + + if(type == Controller::Type::Unknown) + { + if(instance().hasConsole()) + label = (!swapPorts ? instance().console().rightController().name() + : instance().console().leftController().name()) + " detected"; + else if(autoDetect) + label = ControllerDetector::detectName(image.get(), size, type, + !swapPorts ? Controller::Jack::Right : Controller::Jack::Left, + instance().settings()) + " detected"; + } + myRightPortDetected->setLabel(label); + const string& contrLeft = myLeftPort->getSelectedTag().toString(); const string& contrRight = myRightPort->getSelectedTag().toString(); bool enableEEEraseButton = false; @@ -667,9 +670,6 @@ void GameInfoDialog::updateControllerStates() const Controller& lport = instance().console().leftController(); const Controller& rport = instance().console().rightController(); - enableSwapPaddles |= BSPF::equalsIgnoreCase(instance().console().leftController().name(), "Paddles"); - enableSwapPaddles |= BSPF::equalsIgnoreCase(instance().console().rightController().name(), "Paddles"); - // we only enable the button if we have a valid previous and new controller. bool enableBtnForLeft = (contrLeft == "AUTO" || contrLeft == "SAVEKEY" || contrLeft == "ATARIVOX") && @@ -728,7 +728,7 @@ void GameInfoDialog::handleCommand(CommandSender* sender, int cmd, break; case TabWidget::kTabChangedCmd: - if(data == 2) // 'Controller' tab selected + if(data == 2) // 'Controllers' tab selected updateControllerStates(); // The underlying dialog still needs access to this command diff --git a/src/gui/RomInfoWidget.cxx b/src/gui/RomInfoWidget.cxx index 90698f234..4028f8b0d 100644 --- a/src/gui/RomInfoWidget.cxx +++ b/src/gui/RomInfoWidget.cxx @@ -136,6 +136,8 @@ void RomInfoWidget::parseProperties(const FilesystemNode& node) // Load the image for controller auto detection string left = myProperties.get(PropType::Controller_Left); string right = myProperties.get(PropType::Controller_Right); + Controller::Type leftType = Controller::getType(left); + Controller::Type rightType = Controller::getType(right); try { ByteBuffer image; @@ -145,10 +147,10 @@ void RomInfoWidget::parseProperties(const FilesystemNode& node) if(node.exists() && !node.isDirectory() && (image = instance().openROM(node, md5, size)) != nullptr) { - left = ControllerDetector::detectName(image.get(), size, left, + left = ControllerDetector::detectName(image.get(), size, leftType, !swappedPorts ? Controller::Jack::Left : Controller::Jack::Right, instance().settings()); - right = ControllerDetector::detectName(image.get(), size, right, + right = ControllerDetector::detectName(image.get(), size, rightType, !swappedPorts ? Controller::Jack::Right : Controller::Jack::Left, instance().settings()); } diff --git a/src/gui/StellaSettingsDialog.cxx b/src/gui/StellaSettingsDialog.cxx index 60e96da9f..497767b47 100644 --- a/src/gui/StellaSettingsDialog.cxx +++ b/src/gui/StellaSettingsDialog.cxx @@ -187,7 +187,7 @@ void StellaSettingsDialog::addGameOptions(WidgetArray& wid, int& xpos, int& ypos int pwidth = font.getStringWidth("Sega Genesis"); myLeftPortLabel = new StaticTextWidget(this, font, xpos, ypos + 1, "Left port "); myLeftPort = new PopUpWidget(this, font, myLeftPortLabel->getRight(), - myLeftPortLabel->getTop() - 1, pwidth, lineHeight, ctrls, ""); + myLeftPortLabel->getTop() - 1, pwidth, lineHeight, ctrls, "", 0, kLeftCChanged); wid.push_back(myLeftPort); ypos += lineHeight + VGAP; @@ -197,7 +197,7 @@ void StellaSettingsDialog::addGameOptions(WidgetArray& wid, int& xpos, int& ypos myRightPortLabel = new StaticTextWidget(this, font, xpos, ypos + 1, "Right port "); myRightPort = new PopUpWidget(this, font, myRightPortLabel->getRight(), - myRightPortLabel->getTop() - 1, pwidth, lineHeight, ctrls, ""); + myRightPortLabel->getTop() - 1, pwidth, lineHeight, ctrls, "", 0, kRightCChanged); wid.push_back(myRightPort); ypos += lineHeight + VGAP; myRightPortDetected = new StaticTextWidget(this, ifont, myRightPort->getLeft(), ypos, @@ -371,6 +371,11 @@ void StellaSettingsDialog::handleCommand(CommandSender* sender, int cmd, handleOverscanChange(); break; + case kLeftCChanged: + case kRightCChanged: + updateControllerStates(); + break; + default: Dialog::handleCommand(sender, cmd, data, 0); break; @@ -441,49 +446,12 @@ void StellaSettingsDialog::loadControllerProperties(const Properties& props) if (enable) { - bool autoDetect = false; - ByteBuffer image; - string md5 = props.get(PropType::Cart_MD5); - uInt32 size = 0; - const FilesystemNode& node = FilesystemNode(instance().launcher().selectedRom()); - - // try to load the image for auto detection - if (!instance().hasConsole() && - node.exists() && !node.isDirectory() && (image = instance().openROM(node, md5, size)) != nullptr) - autoDetect = true; - - string label = ""; string controller = props.get(PropType::Controller_Left); - bool swapPorts = props.get(PropType::Console_SwapPorts) == "YES"; - myLeftPort->setSelected(controller, "AUTO"); - if (myLeftPort->getSelectedTag().toString() == "AUTO") - { - if (instance().hasConsole()) - label = (!swapPorts ? instance().console().leftController().name() - : instance().console().rightController().name()) + " detected"; - else if (autoDetect) - label = ControllerDetector::detectName(image.get(), size, controller, - !swapPorts ? Controller::Jack::Left : Controller::Jack::Right, - instance().settings()) + " detected"; - } - myLeftPortDetected->setLabel(label); - - label = ""; controller = props.get(PropType::Controller_Right); - myRightPort->setSelected(controller, "AUTO"); - if (myRightPort->getSelectedTag().toString() == "AUTO") - { - if (instance().hasConsole()) - label = (!swapPorts ? instance().console().rightController().name() - : instance().console().leftController().name()) + " detected"; - else if (autoDetect) - label = ControllerDetector::detectName(image.get(), size, controller, - !swapPorts ? Controller::Jack::Right : Controller::Jack::Left, - instance().settings()) + " detected"; - } - myRightPortDetected->setLabel(label); + + updateControllerStates(); } else { @@ -529,3 +497,56 @@ void StellaSettingsDialog::openHelp() #endif myHelpDialog->open(); } + +// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +void StellaSettingsDialog::updateControllerStates() +{ + bool autoDetect = false; + ByteBuffer image; + string md5 = myGameProperties.get(PropType::Cart_MD5); + uInt32 size = 0; + + // try to load the image for auto detection + if(!instance().hasConsole()) + { + const FilesystemNode& node = FilesystemNode(instance().launcher().selectedRom()); + + autoDetect = node.exists() && !node.isDirectory() && (image = instance().openROM(node, md5, size)) != nullptr; + } + string label = ""; + Controller::Type type = Controller::getType(myLeftPort->getSelectedTag().toString()); + + if(type == Controller::Type::Unknown) + { + if(instance().hasConsole()) + label = (instance().console().leftController().name()) + " detected"; + else if(autoDetect) + label = ControllerDetector::detectName(image.get(), size, type, + Controller::Jack::Left, + instance().settings()) + " detected"; + } + myLeftPortDetected->setLabel(label); + + label = ""; + type = Controller::getType(myRightPort->getSelectedTag().toString()); + + if(type == Controller::Type::Unknown) + { + if(instance().hasConsole()) + label = (instance().console().rightController().name()) + " detected"; + else if(autoDetect) + label = ControllerDetector::detectName(image.get(), size, type, + Controller::Jack::Right, + instance().settings()) + " detected"; + } + myRightPortDetected->setLabel(label); + + // Compumate bankswitching scheme doesn't allow to select controllers + bool enableSelectControl = myGameProperties.get(PropType::Cart_Type) != "CM"; + + myLeftPortLabel->setEnabled(enableSelectControl); + myRightPortLabel->setEnabled(enableSelectControl); + myLeftPort->setEnabled(enableSelectControl); + myRightPort->setEnabled(enableSelectControl); +} + diff --git a/src/gui/StellaSettingsDialog.hxx b/src/gui/StellaSettingsDialog.hxx index 1c93b3170..e5b70b607 100644 --- a/src/gui/StellaSettingsDialog.hxx +++ b/src/gui/StellaSettingsDialog.hxx @@ -66,6 +66,8 @@ class StellaSettingsDialog : public Dialog void openHelp(); + void updateControllerStates(); + private: // UI theme PopUpWidget* myThemePopup; @@ -109,7 +111,9 @@ class StellaSettingsDialog : public Dialog kHelp = 'SShl', kScanlinesChanged = 'SSsc', kPhosphorChanged = 'SSph', - kOverscanChanged = 'SSov' + kOverscanChanged = 'SSov', + kLeftCChanged = 'LCch', + kRightCChanged = 'RCch', }; // Game properties for currently loaded ROM