mirror of https://github.com/stella-emu/stella.git
replace magic controller strings with enums
automatic detected controller update in GameInfoDialog & StellaSettingsDialog
This commit is contained in:
parent
d531d8e686
commit
48836e849e
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
||||
|
|
|
@ -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,90 +848,95 @@ 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")
|
||||
switch(type)
|
||||
{
|
||||
// always create because it may have been changed by user dialog
|
||||
controller = make_unique<Joystick>(port, myEvent, *mySystem);
|
||||
case Controller::Type::BoosterGrip:
|
||||
controller = make_unique<BoosterGrip>(port, myEvent, *mySystem);
|
||||
break;
|
||||
|
||||
case Controller::Type::Driving:
|
||||
controller = make_unique<Driving>(port, myEvent, *mySystem);
|
||||
break;
|
||||
|
||||
case Controller::Type::Keyboard:
|
||||
controller = make_unique<Keyboard>(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<Paddles>(port, myEvent, *mySystem,
|
||||
swapPaddles, swapAxis, swapDir);
|
||||
break;
|
||||
}
|
||||
case Controller::Type::AmigaMouse:
|
||||
controller = make_unique<AmigaMouse>(port, myEvent, *mySystem);
|
||||
break;
|
||||
|
||||
case Controller::Type::AtariMouse:
|
||||
controller = make_unique<AtariMouse>(port, myEvent, *mySystem);
|
||||
break;
|
||||
|
||||
case Controller::Type::TrakBall:
|
||||
controller = make_unique<TrakBall>(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<AtariVox>(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<SaveKey>(port, myEvent, *mySystem, nvramfile, callback);
|
||||
break;
|
||||
}
|
||||
case Controller::Type::Genesis:
|
||||
controller = make_unique<Genesis>(port, myEvent, *mySystem);
|
||||
break;
|
||||
|
||||
case Controller::Type::KidVid:
|
||||
controller = make_unique<KidVid>(port, myEvent, *mySystem, romMd5);
|
||||
break;
|
||||
|
||||
case Controller::Type::MindLink:
|
||||
controller = make_unique<MindLink>(port, myEvent, *mySystem);
|
||||
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);
|
||||
}
|
||||
else if(controllerName == "BOOSTERGRIP")
|
||||
{
|
||||
controller = make_unique<BoosterGrip>(port, myEvent, *mySystem);
|
||||
}
|
||||
else if(controllerName == "DRIVING")
|
||||
{
|
||||
controller = make_unique<Driving>(port, myEvent, *mySystem);
|
||||
}
|
||||
else if((controllerName == "KEYBOARD") || (controllerName == "KEYPAD"))
|
||||
{
|
||||
controller = make_unique<Keyboard>(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<Paddles>(port, myEvent, *mySystem,
|
||||
swapPaddles, swapAxis, swapDir);
|
||||
}
|
||||
else if(controllerName == "AMIGAMOUSE")
|
||||
{
|
||||
controller = make_unique<AmigaMouse>(port, myEvent, *mySystem);
|
||||
}
|
||||
else if(controllerName == "ATARIMOUSE")
|
||||
{
|
||||
controller = make_unique<AtariMouse>(port, myEvent, *mySystem);
|
||||
}
|
||||
else if(controllerName == "TRAKBALL")
|
||||
{
|
||||
controller = make_unique<TrakBall>(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<AtariVox>(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<SaveKey>(port, myEvent, *mySystem, nvramfile, callback);
|
||||
}
|
||||
else if(controllerName == "GENESIS")
|
||||
{
|
||||
controller = make_unique<Genesis>(port, myEvent, *mySystem);
|
||||
}
|
||||
else if(controllerName == "KIDVID")
|
||||
{
|
||||
controller = make_unique<KidVid>(port, myEvent, *mySystem, romMd5);
|
||||
}
|
||||
else if(controllerName == "MINDLINK")
|
||||
{
|
||||
controller = make_unique<MindLink>(port, myEvent, *mySystem);
|
||||
}
|
||||
else // What else can we do?
|
||||
controller = make_unique<Joystick>(port, myEvent, *mySystem);
|
||||
|
||||
return controller;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue