replace magic controller strings with enums

automatic detected controller update in GameInfoDialog & StellaSettingsDialog
This commit is contained in:
Thomas Jentzsch 2019-08-16 11:05:55 +02:00
parent d531d8e686
commit 48836e849e
15 changed files with 364 additions and 311 deletions

View File

@ -321,29 +321,33 @@ 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)
{
case Controller::Type::Keyboard:
if(port == Controller::Jack::Left)
myLeftMode = EventMode::kKeypadMode;
else
myRightMode = EventMode::kKeypadMode;
}
else if (BSPF::startsWithIgnoreCase(controllerName, "PADDLES"))
{
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;
}
else if (controllerName == "CM")
{
break;
case Controller::Type::CompuMate:
myLeftMode = myRightMode = EventMode::kCompuMateMode;
}
else
{
break;
default:
// let's use joystick then
if(port == Controller::Jack::Left)
myLeftMode = EventMode::kJoystickMode;
else

View File

@ -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();

View File

@ -139,29 +139,33 @@ 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)
{
case Controller::Type::Keyboard:
if(port == Controller::Jack::Left)
myLeftMode = EventMode::kKeypadMode;
else
myRightMode = EventMode::kKeypadMode;
}
else if (BSPF::startsWithIgnoreCase(controllerName, "PADDLES"))
{
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;
}
else if (controllerName == "CM")
{
break;
case Controller::Type::CompuMate:
myLeftMode = myRightMode = EventMode::kCompuMateMode;
}
else
{
break;
default:
// let's use joystick then
if(port == Controller::Jack::Left)
myLeftMode = EventMode::kJoystickMode;
else

View File

@ -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();

View File

@ -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<Controller> leftC = getControllerPort(left, Controller::Jack::Left, romMd5),
rightC = getControllerPort(right, Controller::Jack::Right, romMd5);
unique_ptr<Controller> leftC = getControllerPort(leftType, Controller::Jack::Left, romMd5),
rightC = getControllerPort(rightType, Controller::Jack::Right, romMd5);
// Swap the ports if necessary
if(!swappedPorts)
@ -848,56 +848,56 @@ void Console::setControllers(const string& romMd5)
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
unique_ptr<Controller> Console::getControllerPort(const string& controllerName,
Controller::Jack port, const string& romMd5)
unique_ptr<Controller> Console::getControllerPort(const Controller::Type type,
const Controller::Jack port, const string& romMd5)
{
unique_ptr<Controller> controller;
myOSystem.eventHandler().defineKeyControllerMappings(controllerName, port);
myOSystem.eventHandler().defineJoyControllerMappings(controllerName, port);
myOSystem.eventHandler().defineKeyControllerMappings(type, port);
myOSystem.eventHandler().defineJoyControllerMappings(type, port);
if(controllerName == "JOYSTICK")
{
// always create because it may have been changed by user dialog
controller = make_unique<Joystick>(port, myEvent, *mySystem);
}
else if(controllerName == "BOOSTERGRIP")
switch(type)
{
case Controller::Type::BoosterGrip:
controller = make_unique<BoosterGrip>(port, myEvent, *mySystem);
}
else if(controllerName == "DRIVING")
{
break;
case Controller::Type::Driving:
controller = make_unique<Driving>(port, myEvent, *mySystem);
}
else if((controllerName == "KEYBOARD") || (controllerName == "KEYPAD"))
{
break;
case Controller::Type::Keyboard:
controller = make_unique<Keyboard>(port, myEvent, *mySystem);
}
else if(BSPF::startsWithIgnoreCase(controllerName, "PADDLES"))
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(controllerName == "PADDLES_IAXIS")
if(type == Controller::Type::PaddlesIAxis)
swapAxis = true;
else if(controllerName == "PADDLES_IAXDR")
else if(type == Controller::Type::PaddlesIAxDr)
swapAxis = swapDir = true;
controller = make_unique<Paddles>(port, myEvent, *mySystem,
swapPaddles, swapAxis, swapDir);
break;
}
else if(controllerName == "AMIGAMOUSE")
{
case Controller::Type::AmigaMouse:
controller = make_unique<AmigaMouse>(port, myEvent, *mySystem);
}
else if(controllerName == "ATARIMOUSE")
{
break;
case Controller::Type::AtariMouse:
controller = make_unique<AtariMouse>(port, myEvent, *mySystem);
}
else if(controllerName == "TRAKBALL")
{
break;
case Controller::Type::TrakBall:
controller = make_unique<TrakBall>(port, myEvent, *mySystem);
}
else if(controllerName == "ATARIVOX")
break;
case Controller::Type::AtariVox:
{
const string& nvramfile = myOSystem.nvramDir() + "atarivox_eeprom.dat";
Controller::onMessageCallback callback = [&os = myOSystem](const string& msg) {
@ -907,8 +907,9 @@ unique_ptr<Controller> Console::getControllerPort(const string& controllerName,
};
controller = make_unique<AtariVox>(port, myEvent, *mySystem,
myOSystem.settings().getString("avoxport"), nvramfile, callback);
break;
}
else if(controllerName == "SAVEKEY")
case Controller::Type::SaveKey:
{
const string& nvramfile = myOSystem.nvramDir() + "savekey_eeprom.dat";
Controller::onMessageCallback callback = [&os = myOSystem](const string& msg) {
@ -917,21 +918,25 @@ unique_ptr<Controller> Console::getControllerPort(const string& controllerName,
os.frameBuffer().showMessage(msg);
};
controller = make_unique<SaveKey>(port, myEvent, *mySystem, nvramfile, callback);
break;
}
else if(controllerName == "GENESIS")
{
case Controller::Type::Genesis:
controller = make_unique<Genesis>(port, myEvent, *mySystem);
}
else if(controllerName == "KIDVID")
{
break;
case Controller::Type::KidVid:
controller = make_unique<KidVid>(port, myEvent, *mySystem, romMd5);
}
else if(controllerName == "MINDLINK")
{
break;
case Controller::Type::MindLink:
controller = make_unique<MindLink>(port, myEvent, *mySystem);
}
else // What else can we do?
break;
default:
// What else can we do?
// always create because it may have been changed by user dialog
controller = make_unique<Joystick>(port, myEvent, *mySystem);
}
return controller;
}

View File

@ -339,8 +339,8 @@ class Console : public Serializable, public ConsoleIO
/**
Selects the left or right controller depending on ROM properties
*/
unique_ptr<Controller> getControllerPort(const string& controllerName,
Controller::Jack port, const string& romMd5);
unique_ptr<Controller> getControllerPort(const Controller::Type type,
const Controller::Jack port, const string& romMd5);
/**
Loads a user-defined palette file (from OSystem::paletteFile), filling the

View File

@ -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<int>(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;
}

View File

@ -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;

View File

@ -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,
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::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;
}

View File

@ -15,7 +15,6 @@
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#ifndef CONTROLLER_DETECTOR_HXX
#define CONTROLLER_DETECTOR_HXX
@ -40,8 +39,8 @@ 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,
static Controller::Type detectType(const uInt8* image, uInt32 size,
const Controller::Type controller, const Controller::Jack port,
const Settings& settings);
/**
@ -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,7 +70,7 @@ class ControllerDetector
@return The detected controller type
*/
static string autodetectPort(const uInt8* image, uInt32 size, Controller::Jack port,
static Controller::Type autodetectPort(const uInt8* image, uInt32 size, Controller::Jack port,
const Settings& settings);
/**

View File

@ -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);
}
/**

View File

@ -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

View File

@ -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());
}

View File

@ -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);
}

View File

@ -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