Major changes to controller infrastructure.

Basically, separate high-level read/write from low-level set/getPin methods.
This commit is contained in:
Stephen Anthony 2019-03-29 20:47:24 -02:30
parent 39884db86f
commit cfe79ec0b1
56 changed files with 677 additions and 620 deletions

View File

@ -46,7 +46,7 @@ MouseControl::MouseControl(Console& console, const string& mode)
Axis yaxis = Axis(int(m_mode[1]) - '0'); Axis yaxis = Axis(int(m_mode[1]) - '0');
ostringstream msg; ostringstream msg;
msg << "Mouse X-axis is "; msg << "Mouse X-axis is ";
Controller::Type xtype = Controller::Joystick, ytype = Controller::Joystick; Controller::Type xtype = Controller::Type::Joystick, ytype = Controller::Type::Joystick;
int xid = -1, yid = -1; int xid = -1, yid = -1;
switch(xaxis) switch(xaxis)
{ {
@ -54,42 +54,42 @@ MouseControl::MouseControl(Console& console, const string& mode)
msg << "not used"; msg << "not used";
break; break;
case Paddle0: case Paddle0:
xtype = Controller::Paddles; xtype = Controller::Type::Paddles;
xid = 0; xid = 0;
msg << "Paddle 0"; msg << "Paddle 0";
break; break;
case Paddle1: case Paddle1:
xtype = Controller::Paddles; xtype = Controller::Type::Paddles;
xid = 1; xid = 1;
msg << "Paddle 1"; msg << "Paddle 1";
break; break;
case Paddle2: case Paddle2:
xtype = Controller::Paddles; xtype = Controller::Type::Paddles;
xid = 2; xid = 2;
msg << "Paddle 2"; msg << "Paddle 2";
break; break;
case Paddle3: case Paddle3:
xtype = Controller::Paddles; xtype = Controller::Type::Paddles;
xid = 3; xid = 3;
msg << "Paddle 3"; msg << "Paddle 3";
break; break;
case Driving0: case Driving0:
xtype = Controller::Driving; xtype = Controller::Type::Driving;
xid = 0; xid = 0;
msg << "Driving 0"; msg << "Driving 0";
break; break;
case Driving1: case Driving1:
xtype = Controller::Driving; xtype = Controller::Type::Driving;
xid = 1; xid = 1;
msg << "Driving 1"; msg << "Driving 1";
break; break;
case MindLink0: case MindLink0:
xtype = Controller::MindLink; xtype = Controller::Type::MindLink;
xid = 0; xid = 0;
msg << "MindLink 0"; msg << "MindLink 0";
break; break;
case MindLink1: case MindLink1:
xtype = Controller::MindLink; xtype = Controller::Type::MindLink;
xid = 1; xid = 1;
msg << "MindLink 1"; msg << "MindLink 1";
break; break;
@ -101,42 +101,42 @@ MouseControl::MouseControl(Console& console, const string& mode)
msg << "not used"; msg << "not used";
break; break;
case Paddle0: case Paddle0:
ytype = Controller::Paddles; ytype = Controller::Type::Paddles;
yid = 0; yid = 0;
msg << "Paddle 0"; msg << "Paddle 0";
break; break;
case Paddle1: case Paddle1:
ytype = Controller::Paddles; ytype = Controller::Type::Paddles;
yid = 1; yid = 1;
msg << "Paddle 1"; msg << "Paddle 1";
break; break;
case Paddle2: case Paddle2:
ytype = Controller::Paddles; ytype = Controller::Type::Paddles;
yid = 2; yid = 2;
msg << "Paddle 2"; msg << "Paddle 2";
break; break;
case Paddle3: case Paddle3:
ytype = Controller::Paddles; ytype = Controller::Type::Paddles;
yid = 3; yid = 3;
msg << "Paddle 3"; msg << "Paddle 3";
break; break;
case Driving0: case Driving0:
ytype = Controller::Driving; ytype = Controller::Type::Driving;
yid = 0; yid = 0;
msg << "Driving 0"; msg << "Driving 0";
break; break;
case Driving1: case Driving1:
ytype = Controller::Driving; ytype = Controller::Type::Driving;
yid = 1; yid = 1;
msg << "Driving 1"; msg << "Driving 1";
break; break;
case MindLink0: case MindLink0:
ytype = Controller::MindLink; ytype = Controller::Type::MindLink;
yid = 0; yid = 0;
msg << "MindLink 0"; msg << "MindLink 0";
break; break;
case MindLink1: case MindLink1:
ytype = Controller::MindLink; ytype = Controller::Type::MindLink;
yid = 1; yid = 1;
msg << "MindLink 1"; msg << "MindLink 1";
break; break;
@ -192,7 +192,7 @@ void MouseControl::addLeftControllerModes(bool noswap)
{ {
if(controllerSupportsMouse(myLeftController)) if(controllerSupportsMouse(myLeftController))
{ {
if(myLeftController.type() == Controller::Paddles) if(myLeftController.type() == Controller::Type::Paddles)
{ {
if(noswap) addPaddleModes(0, 1, 0, 1); if(noswap) addPaddleModes(0, 1, 0, 1);
else addPaddleModes(2, 3, 0, 1); else addPaddleModes(2, 3, 0, 1);
@ -213,7 +213,7 @@ void MouseControl::addRightControllerModes(bool noswap)
{ {
if(controllerSupportsMouse(myRightController)) if(controllerSupportsMouse(myRightController))
{ {
if(myRightController.type() == Controller::Paddles) if(myRightController.type() == Controller::Type::Paddles)
{ {
if(noswap) addPaddleModes(2, 3, 2, 3); if(noswap) addPaddleModes(2, 3, 2, 3);
else addPaddleModes(0, 1, 2, 3); else addPaddleModes(0, 1, 2, 3);
@ -232,7 +232,7 @@ void MouseControl::addRightControllerModes(bool noswap)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void MouseControl::addPaddleModes(int lport, int rport, int lname, int rname) void MouseControl::addPaddleModes(int lport, int rport, int lname, int rname)
{ {
Controller::Type type = Controller::Paddles; Controller::Type type = Controller::Type::Paddles;
ostringstream msg; ostringstream msg;
msg << "Mouse is Paddle " << lname << " controller"; msg << "Mouse is Paddle " << lname << " controller";
MouseMode mode0(type, lport, type, lport, msg.str()); MouseMode mode0(type, lport, type, lport, msg.str());
@ -260,5 +260,5 @@ bool MouseControl::controllerSupportsMouse(Controller& controller)
// We can pass in dummy values here, since the controllers will be // We can pass in dummy values here, since the controllers will be
// initialized by a call to next() once the system is up and running // initialized by a call to next() once the system is up and running
return controller.setMouseControl( return controller.setMouseControl(
Controller::Joystick, -1, Controller::Joystick, -1); Controller::Type::Joystick, -1, Controller::Type::Joystick, -1);
} }

View File

@ -81,8 +81,8 @@ class MouseControl
string message; string message;
explicit MouseMode(const string& msg = "") explicit MouseMode(const string& msg = "")
: xtype(Controller::Joystick), : xtype(Controller::Type::Joystick),
ytype(Controller::Joystick), ytype(Controller::Type::Joystick),
xid(-1), xid(-1),
yid(-1), yid(-1),
message(msg) { } message(msg) { }
@ -97,8 +97,8 @@ class MouseControl
friend ostream& operator<<(ostream& os, const MouseMode& mm) friend ostream& operator<<(ostream& os, const MouseMode& mm)
{ {
os << "xtype=" << mm.xtype << ", xid=" << mm.xid os << "xtype=" << int(mm.xtype) << ", xid=" << mm.xid
<< ", ytype=" << mm.ytype << ", yid=" << mm.yid << ", ytype=" << int(mm.ytype) << ", yid=" << mm.yid
<< ", msg=" << mm.message; << ", msg=" << mm.message;
return os; return os;
} }

View File

@ -631,7 +631,7 @@ void PhysicalJoystickHandler::handleBtnEvent(int stick, int button, bool pressed
{ {
switch(myOSystem.console().leftController().type()) switch(myOSystem.console().leftController().type())
{ {
case Controller::Keyboard: case Controller::Type::Keyboard:
if(button < 12) myEvent.set(SA_Key[j->type-4][button], pressed ? 1 : 0); if(button < 12) myEvent.set(SA_Key[j->type-4][button], pressed ? 1 : 0);
break; break;
default: default:
@ -639,7 +639,7 @@ void PhysicalJoystickHandler::handleBtnEvent(int stick, int button, bool pressed
} }
switch(myOSystem.console().rightController().type()) switch(myOSystem.console().rightController().type())
{ {
case Controller::Keyboard: case Controller::Type::Keyboard:
if(button < 12) myEvent.set(SA_Key[j->type-4][button], pressed ? 1 : 0); if(button < 12) myEvent.set(SA_Key[j->type-4][button], pressed ? 1 : 0);
break; break;
default: default:

View File

@ -70,9 +70,9 @@ void StateManager::toggleRecordMode()
// normal, and those states files wouldn't be compatible with normal // normal, and those states files wouldn't be compatible with normal
// controllers. // controllers.
myMovieWriter.putString( myMovieWriter.putString(
myOSystem.console().controller(Controller::Left).name()); myOSystem.console().controller(Controller::Jack::Left).name());
myMovieWriter.putString( myMovieWriter.putString(
myOSystem.console().controller(Controller::Right).name()); myOSystem.console().controller(Controller::Jack::Right).name());
// If we get this far, we're really in movie record mode // If we get this far, we're really in movie record mode
myActiveMode = kMovieRecordMode; myActiveMode = kMovieRecordMode;
@ -112,8 +112,8 @@ void StateManager::toggleRecordMode()
const string& left = myMovieReader.getString(); const string& left = myMovieReader.getString();
const string& right = myMovieReader.getString(); const string& right = myMovieReader.getString();
if(left != myOSystem.console().controller(Controller::Left).name() || if(left != myOSystem.console().controller(Controller::Jack::Left).name() ||
right != myOSystem.console().controller(Controller::Right).name()) right != myOSystem.console().controller(Controller::Jack::Right).name())
return false; return false;
// If we get this far, we're really in movie record mode // If we get this far, we're really in movie record mode
@ -184,14 +184,14 @@ void StateManager::update()
#if 0 #if 0
case Mode::MovieRecord: case Mode::MovieRecord:
myOSystem.console().controller(Controller::Left).save(myMovieWriter); myOSystem.console().controller(Controller::Jack::Left).save(myMovieWriter);
myOSystem.console().controller(Controller::Right).save(myMovieWriter); myOSystem.console().controller(Controller::Jack::Right).save(myMovieWriter);
myOSystem.console().switches().save(myMovieWriter); myOSystem.console().switches().save(myMovieWriter);
break; break;
case Mode::MoviePlayback: case Mode::MoviePlayback:
myOSystem.console().controller(Controller::Left).load(myMovieReader); myOSystem.console().controller(Controller::Jack::Left).load(myMovieReader);
myOSystem.console().controller(Controller::Right).load(myMovieReader); myOSystem.console().controller(Controller::Jack::Right).load(myMovieReader);
myOSystem.console().switches().load(myMovieReader); myOSystem.console().switches().load(myMovieReader);
break; break;
#endif #endif

View File

@ -22,6 +22,7 @@
#include "CartDebug.hxx" #include "CartDebug.hxx"
#include "CpuDebug.hxx" #include "CpuDebug.hxx"
#include "RiotDebug.hxx" #include "RiotDebug.hxx"
#include "ControlLowLevel.hxx"
#include "TIADebug.hxx" #include "TIADebug.hxx"
#include "TiaOutputWidget.hxx" #include "TiaOutputWidget.hxx"
#include "DebuggerParser.hxx" #include "DebuggerParser.hxx"
@ -1270,110 +1271,110 @@ void DebuggerParser::executeHelp()
// "joy0up" // "joy0up"
void DebuggerParser::executeJoy0Up() void DebuggerParser::executeJoy0Up()
{ {
Controller& controller = debugger.riotDebug().controller(Controller::Left); ControllerLowLevel lport(debugger.myOSystem.console().leftController());
if(argCount == 0) if(argCount == 0)
controller.set(Controller::One, !controller.read(Controller::One)); lport.togglePin(Controller::DigitalPin::One);
else if(argCount == 1) else if(argCount == 1)
controller.set(Controller::One, args[0] != 0); lport.setPin(Controller::DigitalPin::One, args[0] != 0);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "joy0down" // "joy0down"
void DebuggerParser::executeJoy0Down() void DebuggerParser::executeJoy0Down()
{ {
Controller& controller = debugger.riotDebug().controller(Controller::Left); ControllerLowLevel lport(debugger.myOSystem.console().leftController());
if(argCount == 0) if(argCount == 0)
controller.set(Controller::Two, !controller.read(Controller::Two)); lport.togglePin(Controller::DigitalPin::Two);
else if(argCount == 1) else if(argCount == 1)
controller.set(Controller::Two, args[0] != 0); lport.setPin(Controller::DigitalPin::Two, args[0] != 0);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "joy0left" // "joy0left"
void DebuggerParser::executeJoy0Left() void DebuggerParser::executeJoy0Left()
{ {
Controller& controller = debugger.riotDebug().controller(Controller::Left); ControllerLowLevel lport(debugger.myOSystem.console().leftController());
if(argCount == 0) if(argCount == 0)
controller.set(Controller::Three, !controller.read(Controller::Three)); lport.togglePin(Controller::DigitalPin::Three);
else if(argCount == 1) else if(argCount == 1)
controller.set(Controller::Three, args[0] != 0); lport.setPin(Controller::DigitalPin::Three, args[0] != 0);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "joy0right" // "joy0right"
void DebuggerParser::executeJoy0Right() void DebuggerParser::executeJoy0Right()
{ {
Controller& controller = debugger.riotDebug().controller(Controller::Left); ControllerLowLevel lport(debugger.myOSystem.console().leftController());
if(argCount == 0) if(argCount == 0)
controller.set(Controller::Four, !controller.read(Controller::Four)); lport.togglePin(Controller::DigitalPin::Four);
else if(argCount == 1) else if(argCount == 1)
controller.set(Controller::Four, args[0] != 0); lport.setPin(Controller::DigitalPin::Four, args[0] != 0);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "joy0fire" // "joy0fire"
void DebuggerParser::executeJoy0Fire() void DebuggerParser::executeJoy0Fire()
{ {
Controller& controller = debugger.riotDebug().controller(Controller::Left); ControllerLowLevel lport(debugger.myOSystem.console().leftController());
if(argCount == 0) if(argCount == 0)
controller.set(Controller::Six, !controller.read(Controller::Six)); lport.togglePin(Controller::DigitalPin::Six);
else if(argCount == 1) else if(argCount == 1)
controller.set(Controller::Six, args[0] != 0); lport.setPin(Controller::DigitalPin::Six, args[0] != 0);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "joy1up" // "joy1up"
void DebuggerParser::executeJoy1Up() void DebuggerParser::executeJoy1Up()
{ {
Controller& controller = debugger.riotDebug().controller(Controller::Right); ControllerLowLevel rport(debugger.myOSystem.console().rightController());
if(argCount == 0) if(argCount == 0)
controller.set(Controller::One, !controller.read(Controller::One)); rport.togglePin(Controller::DigitalPin::One);
else if(argCount == 1) else if(argCount == 1)
controller.set(Controller::One, args[0] != 0); rport.setPin(Controller::DigitalPin::One, args[0] != 0);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "joy1down" // "joy1down"
void DebuggerParser::executeJoy1Down() void DebuggerParser::executeJoy1Down()
{ {
Controller& controller = debugger.riotDebug().controller(Controller::Right); ControllerLowLevel rport(debugger.myOSystem.console().rightController());
if(argCount == 0) if(argCount == 0)
controller.set(Controller::Two, !controller.read(Controller::Two)); rport.togglePin(Controller::DigitalPin::Two);
else if(argCount == 1) else if(argCount == 1)
controller.set(Controller::Two, args[0] != 0); rport.setPin(Controller::DigitalPin::Two, args[0] != 0);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "joy1left" // "joy1left"
void DebuggerParser::executeJoy1Left() void DebuggerParser::executeJoy1Left()
{ {
Controller& controller = debugger.riotDebug().controller(Controller::Right); ControllerLowLevel rport(debugger.myOSystem.console().rightController());
if(argCount == 0) if(argCount == 0)
controller.set(Controller::Three, !controller.read(Controller::Three)); rport.togglePin(Controller::DigitalPin::Three);
else if(argCount == 1) else if(argCount == 1)
controller.set(Controller::Three, args[0] != 0); rport.setPin(Controller::DigitalPin::Three, args[0] != 0);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "joy1right" // "joy1right"
void DebuggerParser::executeJoy1Right() void DebuggerParser::executeJoy1Right()
{ {
Controller& controller = debugger.riotDebug().controller(Controller::Right); ControllerLowLevel rport(debugger.myOSystem.console().rightController());
if(argCount == 0) if(argCount == 0)
controller.set(Controller::Four, !controller.read(Controller::Four)); rport.togglePin(Controller::DigitalPin::Four);
else if(argCount == 1) else if(argCount == 1)
controller.set(Controller::Four, args[0] != 0); rport.setPin(Controller::DigitalPin::Four, args[0] != 0);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// "joy1fire" // "joy1fire"
void DebuggerParser::executeJoy1Fire() void DebuggerParser::executeJoy1Fire()
{ {
Controller& controller = debugger.riotDebug().controller(Controller::Right); ControllerLowLevel rport(debugger.myOSystem.console().rightController());
if(argCount == 0) if(argCount == 0)
controller.set(Controller::Six, !controller.read(Controller::Six)); rport.togglePin(Controller::DigitalPin::Six);
else if(argCount == 1) else if(argCount == 1)
controller.set(Controller::Six, args[0] != 0); rport.setPin(Controller::DigitalPin::Six, args[0] != 0);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -1596,16 +1597,12 @@ void DebuggerParser::executeReset()
{ {
debugger.reset(); debugger.reset();
debugger.rom().invalidate(); debugger.rom().invalidate();
debugger.riotDebug().controller(Controller::Left).set(Controller::One, true);
debugger.riotDebug().controller(Controller::Left).set(Controller::Two, true); ControllerLowLevel lport(debugger.myOSystem.console().leftController());
debugger.riotDebug().controller(Controller::Left).set(Controller::Three, true); ControllerLowLevel rport(debugger.myOSystem.console().rightController());
debugger.riotDebug().controller(Controller::Left).set(Controller::Four, true); lport.resetDigitalPins();
debugger.riotDebug().controller(Controller::Left).set(Controller::Six, true); rport.resetDigitalPins();
debugger.riotDebug().controller(Controller::Right).set(Controller::One, true);
debugger.riotDebug().controller(Controller::Right).set(Controller::Two, true);
debugger.riotDebug().controller(Controller::Right).set(Controller::Three, true);
debugger.riotDebug().controller(Controller::Right).set(Controller::Four, true);
debugger.riotDebug().controller(Controller::Right).set(Controller::Six, true);
commandResult << "reset system"; commandResult << "reset system";
} }

View File

@ -231,13 +231,6 @@ Int32 RiotDebug::timDivider() const
return mySystem.m6532().myDivider; return mySystem.m6532().myDivider;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Controller& RiotDebug::controller(Controller::Jack jack) const
{
return jack == Controller::Left ? myConsole.leftController() :
myConsole.rightController();
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool RiotDebug::diffP0(int newVal) bool RiotDebug::diffP0(int newVal)
{ {

View File

@ -84,9 +84,6 @@ class RiotDebug : public DebuggerSystem
Int32 intimClocks() const; Int32 intimClocks() const;
Int32 timDivider() const; Int32 timDivider() const;
/* Controller ports */
Controller& controller(Controller::Jack jack) const;
/* Console switches */ /* Console switches */
bool diffP0(int newVal = -1); bool diffP0(int newVal = -1);
bool diffP1(int newVal = -1); bool diffP1(int newVal = -1);

View File

@ -29,7 +29,7 @@ AtariVoxWidget::AtariVoxWidget(GuiObject* boss, const GUI::Font& font,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void AtariVoxWidget::eraseCurrent() void AtariVoxWidget::eraseCurrent()
{ {
AtariVox& avox = static_cast<AtariVox&>(myController); AtariVox& avox = static_cast<AtariVox&>(myController->base());
avox.eraseCurrent(); avox.eraseCurrent();
} }
@ -37,7 +37,7 @@ void AtariVoxWidget::eraseCurrent()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool AtariVoxWidget::isPageUsed(uInt32 page) bool AtariVoxWidget::isPageUsed(uInt32 page)
{ {
AtariVox& avox = static_cast<AtariVox&>(myController); AtariVox& avox = static_cast<AtariVox&>(myController->base());
return avox.isPageUsed(page); return avox.isPageUsed(page);
} }

View File

@ -78,16 +78,16 @@ BoosterWidget::BoosterWidget(GuiObject* boss, const GUI::Font& font,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void BoosterWidget::loadConfig() void BoosterWidget::loadConfig()
{ {
myPins[kJUp]->setState(!myController.read(ourPinNo[kJUp])); myPins[kJUp]->setState(!myController->getPin(ourPinNo[kJUp]));
myPins[kJDown]->setState(!myController.read(ourPinNo[kJDown])); myPins[kJDown]->setState(!myController->getPin(ourPinNo[kJDown]));
myPins[kJLeft]->setState(!myController.read(ourPinNo[kJLeft])); myPins[kJLeft]->setState(!myController->getPin(ourPinNo[kJLeft]));
myPins[kJRight]->setState(!myController.read(ourPinNo[kJRight])); myPins[kJRight]->setState(!myController->getPin(ourPinNo[kJRight]));
myPins[kJFire]->setState(!myController.read(ourPinNo[kJFire])); myPins[kJFire]->setState(!myController->getPin(ourPinNo[kJFire]));
myPins[kJBooster]->setState( myPins[kJBooster]->setState(
myController.read(Controller::Five) == Controller::MIN_RESISTANCE); myController->getPin(Controller::AnalogPin::Five) == Controller::MIN_RESISTANCE);
myPins[kJTrigger]->setState( myPins[kJTrigger]->setState(
myController.read(Controller::Nine) == Controller::MIN_RESISTANCE); myController->getPin(Controller::AnalogPin::Nine) == Controller::MIN_RESISTANCE);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -103,15 +103,15 @@ void BoosterWidget::handleCommand(
case kJLeft: case kJLeft:
case kJRight: case kJRight:
case kJFire: case kJFire:
myController.set(ourPinNo[id], !myPins[id]->getState()); myController->setPin(ourPinNo[id], !myPins[id]->getState());
break; break;
case kJBooster: case kJBooster:
myController.set(Controller::Five, myController->setPin(Controller::AnalogPin::Five,
myPins[id]->getState() ? Controller::MIN_RESISTANCE : myPins[id]->getState() ? Controller::MIN_RESISTANCE :
Controller::MAX_RESISTANCE); Controller::MAX_RESISTANCE);
break; break;
case kJTrigger: case kJTrigger:
myController.set(Controller::Nine, myController->setPin(Controller::AnalogPin::Nine,
myPins[id]->getState() ? Controller::MIN_RESISTANCE : myPins[id]->getState() ? Controller::MIN_RESISTANCE :
Controller::MAX_RESISTANCE); Controller::MAX_RESISTANCE);
break; break;
@ -121,6 +121,6 @@ void BoosterWidget::handleCommand(
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Controller::DigitalPin BoosterWidget::ourPinNo[5] = { Controller::DigitalPin BoosterWidget::ourPinNo[5] = {
Controller::One, Controller::Two, Controller::Three, Controller::Four, Controller::DigitalPin::One, Controller::DigitalPin::Two, Controller::DigitalPin::Three, Controller::DigitalPin::Four,
Controller::Six Controller::DigitalPin::Six
}; };

View File

@ -25,6 +25,7 @@ class ButtonWidget;
#include "Widget.hxx" #include "Widget.hxx"
#include "Console.hxx" #include "Console.hxx"
#include "Command.hxx" #include "Command.hxx"
#include "ControlLowLevel.hxx"
class ControllerWidget : public Widget, public CommandSender class ControllerWidget : public Widget, public CommandSender
@ -34,7 +35,7 @@ class ControllerWidget : public Widget, public CommandSender
Controller& controller) Controller& controller)
: Widget(boss, font, x, y, 16, 16), : Widget(boss, font, x, y, 16, 16),
CommandSender(boss), CommandSender(boss),
myController(controller) myController(make_unique<ControllerLowLevel>(controller))
{ {
_w = 18 * font.getMaxCharWidth(); _w = 18 * font.getMaxCharWidth();
_h = 8 * font.getLineHeight(); _h = 8 * font.getLineHeight();
@ -45,19 +46,19 @@ class ControllerWidget : public Widget, public CommandSender
virtual void loadConfig() override { } virtual void loadConfig() override { }
protected: protected:
Controller& myController; unique_ptr<ControllerLowLevel> myController;
protected: protected:
bool isLeftPort() bool isLeftPort()
{ {
bool swappedPorts = instance().console().properties().get(Console_SwapPorts) == "YES"; bool swappedPorts = instance().console().properties().get(Console_SwapPorts) == "YES";
return (myController.jack() == Controller::Left) ^ swappedPorts; return (myController->base().jack() == Controller::Jack::Left) ^ swappedPorts;
} }
string getHeader() string getHeader()
{ {
return (isLeftPort() ? "Left (" : "Right (") + myController.name() + ")"; return (isLeftPort() ? "Left (" : "Right (") + myController->base().name() + ")";
} }
private: private:

View File

@ -60,8 +60,8 @@ DrivingWidget::DrivingWidget(GuiObject* boss, const GUI::Font& font,
void DrivingWidget::loadConfig() void DrivingWidget::loadConfig()
{ {
uInt8 gray = 0; uInt8 gray = 0;
if(myController.read(Controller::One)) gray += 1; if(myController->getPin(Controller::DigitalPin::One)) gray += 1;
if(myController.read(Controller::Two)) gray += 2; if(myController->getPin(Controller::DigitalPin::Two)) gray += 2;
for(myGrayIndex = 0; myGrayIndex < 4; ++myGrayIndex) for(myGrayIndex = 0; myGrayIndex < 4; ++myGrayIndex)
{ {
@ -72,7 +72,7 @@ void DrivingWidget::loadConfig()
} }
} }
myFire->setState(!myController.read(Controller::Six)); myFire->setState(!myController->getPin(Controller::DigitalPin::Six));
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -83,18 +83,18 @@ void DrivingWidget::handleCommand(
{ {
case kGrayUpCmd: case kGrayUpCmd:
myGrayIndex = (myGrayIndex + 1) % 4; myGrayIndex = (myGrayIndex + 1) % 4;
myController.set(Controller::One, (ourGrayTable[myGrayIndex] & 0x1) != 0); myController->setPin(Controller::DigitalPin::One, (ourGrayTable[myGrayIndex] & 0x1) != 0);
myController.set(Controller::Two, (ourGrayTable[myGrayIndex] & 0x2) != 0); myController->setPin(Controller::DigitalPin::Two, (ourGrayTable[myGrayIndex] & 0x2) != 0);
setValue(myGrayIndex); setValue(myGrayIndex);
break; break;
case kGrayDownCmd: case kGrayDownCmd:
myGrayIndex = myGrayIndex == 0 ? 3 : myGrayIndex - 1; myGrayIndex = myGrayIndex == 0 ? 3 : myGrayIndex - 1;
myController.set(Controller::One, (ourGrayTable[myGrayIndex] & 0x1) != 0); myController->setPin(Controller::DigitalPin::One, (ourGrayTable[myGrayIndex] & 0x1) != 0);
myController.set(Controller::Two, (ourGrayTable[myGrayIndex] & 0x2) != 0); myController->setPin(Controller::DigitalPin::Two, (ourGrayTable[myGrayIndex] & 0x2) != 0);
setValue(myGrayIndex); setValue(myGrayIndex);
break; break;
case kFireCmd: case kFireCmd:
myController.set(Controller::Six, !myFire->getState()); myController->setPin(Controller::DigitalPin::Six, !myFire->getState());
break; break;
} }
} }

View File

@ -72,14 +72,14 @@ GenesisWidget::GenesisWidget(GuiObject* boss, const GUI::Font& font,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void GenesisWidget::loadConfig() void GenesisWidget::loadConfig()
{ {
myPins[kJUp]->setState(!myController.read(ourPinNo[kJUp])); myPins[kJUp]->setState(!myController->getPin(ourPinNo[kJUp]));
myPins[kJDown]->setState(!myController.read(ourPinNo[kJDown])); myPins[kJDown]->setState(!myController->getPin(ourPinNo[kJDown]));
myPins[kJLeft]->setState(!myController.read(ourPinNo[kJLeft])); myPins[kJLeft]->setState(!myController->getPin(ourPinNo[kJLeft]));
myPins[kJRight]->setState(!myController.read(ourPinNo[kJRight])); myPins[kJRight]->setState(!myController->getPin(ourPinNo[kJRight]));
myPins[kJBbtn]->setState(!myController.read(ourPinNo[kJBbtn])); myPins[kJBbtn]->setState(!myController->getPin(ourPinNo[kJBbtn]));
myPins[kJCbtn]->setState( myPins[kJCbtn]->setState(
myController.read(Controller::Five) == Controller::MAX_RESISTANCE); myController->getPin(Controller::AnalogPin::Five) == Controller::MAX_RESISTANCE);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -95,10 +95,10 @@ void GenesisWidget::handleCommand(
case kJLeft: case kJLeft:
case kJRight: case kJRight:
case kJBbtn: case kJBbtn:
myController.set(ourPinNo[id], !myPins[id]->getState()); myController->setPin(ourPinNo[id], !myPins[id]->getState());
break; break;
case kJCbtn: case kJCbtn:
myController.set(Controller::Five, myController->setPin(Controller::AnalogPin::Five,
myPins[id]->getState() ? Controller::MAX_RESISTANCE : myPins[id]->getState() ? Controller::MAX_RESISTANCE :
Controller::MIN_RESISTANCE); Controller::MIN_RESISTANCE);
break; break;
@ -108,6 +108,6 @@ void GenesisWidget::handleCommand(
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Controller::DigitalPin GenesisWidget::ourPinNo[5] = { Controller::DigitalPin GenesisWidget::ourPinNo[5] = {
Controller::One, Controller::Two, Controller::Three, Controller::Four, Controller::DigitalPin::One, Controller::DigitalPin::Two, Controller::DigitalPin::Three, Controller::DigitalPin::Four,
Controller::Six Controller::DigitalPin::Six
}; };

View File

@ -65,11 +65,11 @@ JoystickWidget::JoystickWidget(GuiObject* boss, const GUI::Font& font,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void JoystickWidget::loadConfig() void JoystickWidget::loadConfig()
{ {
myPins[kJUp]->setState(!myController.read(ourPinNo[kJUp])); myPins[kJUp]->setState(!myController->getPin(ourPinNo[kJUp]));
myPins[kJDown]->setState(!myController.read(ourPinNo[kJDown])); myPins[kJDown]->setState(!myController->getPin(ourPinNo[kJDown]));
myPins[kJLeft]->setState(!myController.read(ourPinNo[kJLeft])); myPins[kJLeft]->setState(!myController->getPin(ourPinNo[kJLeft]));
myPins[kJRight]->setState(!myController.read(ourPinNo[kJRight])); myPins[kJRight]->setState(!myController->getPin(ourPinNo[kJRight]));
myPins[kJFire]->setState(!myController.read(ourPinNo[kJFire])); myPins[kJFire]->setState(!myController->getPin(ourPinNo[kJFire]));
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -77,11 +77,11 @@ void JoystickWidget::handleCommand(
CommandSender* sender, int cmd, int data, int id) CommandSender* sender, int cmd, int data, int id)
{ {
if(cmd == CheckboxWidget::kCheckActionCmd) if(cmd == CheckboxWidget::kCheckActionCmd)
myController.set(ourPinNo[id], !myPins[id]->getState()); myController->setPin(ourPinNo[id], !myPins[id]->getState());
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Controller::DigitalPin JoystickWidget::ourPinNo[5] = { Controller::DigitalPin JoystickWidget::ourPinNo[5] = {
Controller::One, Controller::Two, Controller::Three, Controller::Four, Controller::DigitalPin::One, Controller::DigitalPin::Two, Controller::DigitalPin::Three, Controller::DigitalPin::Four,
Controller::Six Controller::DigitalPin::Six
}; };

View File

@ -68,11 +68,11 @@ PaddleWidget::PaddleWidget(GuiObject* boss, const GUI::Font& font,
void PaddleWidget::loadConfig() void PaddleWidget::loadConfig()
{ {
myP0Resistance->setValue(Int32(Paddles::MAX_RESISTANCE - myP0Resistance->setValue(Int32(Paddles::MAX_RESISTANCE -
myController.read(Controller::Nine))); myController->getPin(Controller::AnalogPin::Nine)));
myP1Resistance->setValue(Int32(Paddles::MAX_RESISTANCE - myP1Resistance->setValue(Int32(Paddles::MAX_RESISTANCE -
myController.read(Controller::Five))); myController->getPin(Controller::AnalogPin::Five)));
myP0Fire->setState(!myController.read(Controller::Four)); myP0Fire->setState(!myController->getPin(Controller::DigitalPin::Four));
myP1Fire->setState(!myController.read(Controller::Three)); myP1Fire->setState(!myController->getPin(Controller::DigitalPin::Three));
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -82,18 +82,18 @@ void PaddleWidget::handleCommand(
switch(cmd) switch(cmd)
{ {
case kP0Changed: case kP0Changed:
myController.set(Controller::Nine, myController->setPin(Controller::AnalogPin::Nine,
Int32(Paddles::MAX_RESISTANCE - myP0Resistance->getValue())); Int32(Paddles::MAX_RESISTANCE - myP0Resistance->getValue()));
break; break;
case kP1Changed: case kP1Changed:
myController.set(Controller::Five, myController->setPin(Controller::AnalogPin::Five,
Int32(Paddles::MAX_RESISTANCE - myP1Resistance->getValue())); Int32(Paddles::MAX_RESISTANCE - myP1Resistance->getValue()));
break; break;
case kP0Fire: case kP0Fire:
myController.set(Controller::Four, !myP0Fire->getState()); myController->setPin(Controller::DigitalPin::Four, !myP0Fire->getState());
break; break;
case kP1Fire: case kP1Fire:
myController.set(Controller::Three, !myP1Fire->getState()); myController->setPin(Controller::DigitalPin::Three, !myP1Fire->getState());
break; break;
} }
} }

View File

@ -75,7 +75,7 @@ void PointingDeviceWidget::loadConfig()
{ {
setGrayCodeH(); setGrayCodeH();
setGrayCodeV(); setGrayCodeV();
myFire->setState(!myController.read(Controller::Six)); myFire->setState(!myController->getPin(Controller::DigitalPin::Six));
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -83,7 +83,7 @@ void PointingDeviceWidget::handleCommand(CommandSender* sender, int cmd, int dat
{ {
// since the PointingDevice uses its own, internal state (not reading the controller), // since the PointingDevice uses its own, internal state (not reading the controller),
// we have to communicate directly with it // we have to communicate directly with it
PointingDevice& pDev = static_cast<PointingDevice&>(myController); PointingDevice& pDev = static_cast<PointingDevice&>(myController->base());
switch(cmd) switch(cmd)
{ {
@ -108,7 +108,7 @@ void PointingDeviceWidget::handleCommand(CommandSender* sender, int cmd, int dat
setGrayCodeV(); setGrayCodeV();
break; break;
case kTBFire: case kTBFire:
myController.set(Controller::Six, !myFire->getState()); myController->setPin(Controller::DigitalPin::Six, !myFire->getState());
break; break;
} }
} }
@ -116,7 +116,7 @@ void PointingDeviceWidget::handleCommand(CommandSender* sender, int cmd, int dat
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PointingDeviceWidget::setGrayCodeH() void PointingDeviceWidget::setGrayCodeH()
{ {
PointingDevice& pDev = static_cast<PointingDevice&>(myController); PointingDevice& pDev = static_cast<PointingDevice&>(myController->base());
pDev.myCountH &= 0b11; pDev.myCountH &= 0b11;
setValue(myGrayValueH, pDev.myCountH, pDev.myTrackBallLeft); setValue(myGrayValueH, pDev.myCountH, pDev.myTrackBallLeft);
@ -125,7 +125,7 @@ void PointingDeviceWidget::setGrayCodeH()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PointingDeviceWidget::setGrayCodeV() void PointingDeviceWidget::setGrayCodeV()
{ {
PointingDevice& pDev = static_cast<PointingDevice&>(myController); PointingDevice& pDev = static_cast<PointingDevice&>(myController->base());
pDev.myCountV &= 0b11; pDev.myCountV &= 0b11;
setValue(myGrayValueV, pDev.myCountV, !pDev.myTrackBallDown); setValue(myGrayValueV, pDev.myCountV, !pDev.myTrackBallDown);

View File

@ -133,13 +133,12 @@ RiotWidget::RiotWidget(GuiObject* boss, const GUI::Font& lfont,
myTimDivider->setEditable(false); myTimDivider->setEditable(false);
// Controller ports // Controller ports
const RiotDebug& riot = instance().debugger().riotDebug();
xpos = col; ypos = 10; xpos = col; ypos = 10;
myLeftControl = addControlWidget(boss, lfont, xpos, ypos, myLeftControl = addControlWidget(boss, lfont, xpos, ypos,
riot.controller(Controller::Left)); instance().console().leftController());
xpos += myLeftControl->getWidth() + 15; xpos += myLeftControl->getWidth() + 15;
myRightControl = addControlWidget(boss, lfont, xpos, ypos, myRightControl = addControlWidget(boss, lfont, xpos, ypos,
riot.controller(Controller::Right)); instance().console().rightController());
// TIA INPTx registers (R), left port // TIA INPTx registers (R), left port
const char* const contLeftReadNames[] = { "INPT0", "INPT1", "INPT4" }; const char* const contLeftReadNames[] = { "INPT0", "INPT1", "INPT4" };
@ -397,16 +396,18 @@ void RiotWidget::handleCommand(CommandSender* sender, int cmd, int data, int id)
break; break;
case kSWCHARBitsID: case kSWCHARBitsID:
{ {
#if 0
// TODO: Check if there is a nicer way to do this // TODO: Check if there is a nicer way to do this
value = Debugger::get_bits(mySWCHAReadBits->getState()); value = Debugger::get_bits(mySWCHAReadBits->getState());
riot.controller(Controller::Left).set(Controller::One, value & 0b00010000); riot.controller(Controller::Jack::Left).set(Controller::DigitalPin::One, value & 0b00010000);
riot.controller(Controller::Left).set(Controller::Two, value & 0b00100000); riot.controller(Controller::Jack::Left).set(Controller::DigitalPin::Two, value & 0b00100000);
riot.controller(Controller::Left).set(Controller::Three, value & 0b01000000); riot.controller(Controller::Jack::Left).set(Controller::DigitalPin::Three, value & 0b01000000);
riot.controller(Controller::Left).set(Controller::Four, value & 0b10000000); riot.controller(Controller::Jack::Left).set(Controller::DigitalPin::Four, value & 0b10000000);
riot.controller(Controller::Right).set(Controller::One, value & 0b00000001); riot.controller(Controller::Jack::Right).set(Controller::DigitalPin::One, value & 0b00000001);
riot.controller(Controller::Right).set(Controller::Two, value & 0b00000010); riot.controller(Controller::Jack::Right).set(Controller::DigitalPin::Two, value & 0b00000010);
riot.controller(Controller::Right).set(Controller::Three, value & 0b00000100); riot.controller(Controller::Jack::Right).set(Controller::DigitalPin::Three, value & 0b00000100);
riot.controller(Controller::Right).set(Controller::Four, value & 0b00001000); riot.controller(Controller::Jack::Right).set(Controller::DigitalPin::Four, value & 0b00001000);
#endif
break; break;
} }
} }
@ -447,29 +448,29 @@ ControllerWidget* RiotWidget::addControlWidget(GuiObject* boss, const GUI::Font&
{ {
switch(controller.type()) switch(controller.type())
{ {
case Controller::AmigaMouse: case Controller::Type::AmigaMouse:
return new AmigaMouseWidget(boss, font, x, y, controller); return new AmigaMouseWidget(boss, font, x, y, controller);
case Controller::AtariMouse: case Controller::Type::AtariMouse:
return new AtariMouseWidget(boss, font, x, y, controller); return new AtariMouseWidget(boss, font, x, y, controller);
case Controller::AtariVox: case Controller::Type::AtariVox:
return new AtariVoxWidget(boss, font, x, y, controller); return new AtariVoxWidget(boss, font, x, y, controller);
case Controller::BoosterGrip: case Controller::Type::BoosterGrip:
return new BoosterWidget(boss, font, x, y, controller); return new BoosterWidget(boss, font, x, y, controller);
case Controller::Driving: case Controller::Type::Driving:
return new DrivingWidget(boss, font, x, y, controller); return new DrivingWidget(boss, font, x, y, controller);
case Controller::Genesis: case Controller::Type::Genesis:
return new GenesisWidget(boss, font, x, y, controller); return new GenesisWidget(boss, font, x, y, controller);
case Controller::Joystick: case Controller::Type::Joystick:
return new JoystickWidget(boss, font, x, y, controller); return new JoystickWidget(boss, font, x, y, controller);
case Controller::Keyboard: case Controller::Type::Keyboard:
return new KeyboardWidget(boss, font, x, y, controller); return new KeyboardWidget(boss, font, x, y, controller);
// case Controller::KidVid: // TODO - implement this // case Controller::Type::KidVid: // TODO - implement this
// case Controller::MindLink: // TODO - implement this // case Controller::Type::MindLink: // TODO - implement this
case Controller::Paddles: case Controller::Type::Paddles:
return new PaddleWidget(boss, font, x, y, controller); return new PaddleWidget(boss, font, x, y, controller);
case Controller::SaveKey: case Controller::Type::SaveKey:
return new SaveKeyWidget(boss, font, x, y, controller); return new SaveKeyWidget(boss, font, x, y, controller);
case Controller::TrakBall: case Controller::Type::TrakBall:
return new TrakBallWidget(boss, font, x, y, controller); return new TrakBallWidget(boss, font, x, y, controller);
default: default:
return new NullControlWidget(boss, font, x, y, controller); return new NullControlWidget(boss, font, x, y, controller);

View File

@ -29,7 +29,7 @@ SaveKeyWidget::SaveKeyWidget(GuiObject* boss, const GUI::Font& font,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void SaveKeyWidget::eraseCurrent() void SaveKeyWidget::eraseCurrent()
{ {
SaveKey& skey = static_cast<SaveKey&>(myController); SaveKey& skey = static_cast<SaveKey&>(myController->base());
skey.eraseCurrent(); skey.eraseCurrent();
} }
@ -37,7 +37,7 @@ void SaveKeyWidget::eraseCurrent()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool SaveKeyWidget::isPageUsed(uInt32 page) bool SaveKeyWidget::isPageUsed(uInt32 page)
{ {
SaveKey& skey = static_cast<SaveKey&>(myController); SaveKey& skey = static_cast<SaveKey&>(myController->base());
return skey.isPageUsed(page); return skey.isPageUsed(page);
} }

View File

@ -31,10 +31,15 @@ class AmigaMouse : public PointingDevice
@param system The system using this controller @param system The system using this controller
*/ */
AmigaMouse(Jack jack, const Event& event, const System& system) AmigaMouse(Jack jack, const Event& event, const System& system)
: PointingDevice(jack, event, system, Controller::AmigaMouse, : PointingDevice(jack, event, system, Controller::Type::AmigaMouse,
trackballSensitivity) { } trackballSensitivity) { }
virtual ~AmigaMouse() = default; virtual ~AmigaMouse() = default;
/**
Returns the name of this controller.
*/
string name() const override { return "AmigaMouse"; }
protected: protected:
uInt8 ioPortA(uInt8 countH, uInt8 countV, uInt8, uInt8) override uInt8 ioPortA(uInt8 countH, uInt8 countV, uInt8, uInt8) override
{ {

View File

@ -31,10 +31,15 @@ class AtariMouse : public PointingDevice
@param system The system using this controller @param system The system using this controller
*/ */
AtariMouse(Jack jack, const Event& event, const System& system) AtariMouse(Jack jack, const Event& event, const System& system)
: PointingDevice(jack, event, system, Controller::AtariMouse, : PointingDevice(jack, event, system, Controller::Type::AtariMouse,
trackballSensitivity) { } trackballSensitivity) { }
virtual ~AtariMouse() = default; virtual ~AtariMouse() = default;
/**
Returns the name of this controller.
*/
string name() const override { return "AtariMouse"; }
protected: protected:
uInt8 ioPortA(uInt8 countH, uInt8 countV, uInt8, uInt8) override uInt8 ioPortA(uInt8 countH, uInt8 countV, uInt8, uInt8) override
{ {

View File

@ -24,7 +24,7 @@
AtariVox::AtariVox(Jack jack, const Event& event, const System& system, AtariVox::AtariVox(Jack jack, const Event& event, const System& system,
const string& portname, const string& eepromfile, const string& portname, const string& eepromfile,
onMessageCallback callback) onMessageCallback callback)
: SaveKey(jack, event, system, eepromfile, callback, Controller::AtariVox), : SaveKey(jack, event, system, eepromfile, callback, Controller::Type::AtariVox),
myShiftCount(0), myShiftCount(0),
myShiftRegister(0), myShiftRegister(0),
myLastDataWriteCycle(0) myLastDataWriteCycle(0)
@ -35,7 +35,8 @@ AtariVox::AtariVox(Jack jack, const Event& event, const System& system,
else else
myAboutString = " (invalid serial port \'" + portname + "\')"; myAboutString = " (invalid serial port \'" + portname + "\')";
myDigitalPinState[Three] = myDigitalPinState[Four] = true; setPin(DigitalPin::Three, true);
setPin(DigitalPin::Four, true);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -47,9 +48,9 @@ bool AtariVox::read(DigitalPin pin)
switch(pin) switch(pin)
{ {
// Pin 2: SpeakJet READY // Pin 2: SpeakJet READY
case Two: case DigitalPin::Two:
// For now, we just assume the device is always ready // For now, we just assume the device is always ready
return myDigitalPinState[Two] = true; return setPin(pin, true);
default: default:
return SaveKey::read(pin); return SaveKey::read(pin);
@ -64,8 +65,8 @@ void AtariVox::write(DigitalPin pin, bool value)
{ {
// Pin 1: SpeakJet DATA // Pin 1: SpeakJet DATA
// output serial data to the speakjet // output serial data to the speakjet
case One: case DigitalPin::One:
myDigitalPinState[One] = value; setPin(pin, value);
clockDataIn(value); clockDataIn(value);
break; break;

View File

@ -20,10 +20,10 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BoosterGrip::BoosterGrip(Jack jack, const Event& event, const System& system) BoosterGrip::BoosterGrip(Jack jack, const Event& event, const System& system)
: Controller(jack, event, system, Controller::BoosterGrip), : Controller(jack, event, system, Controller::Type::BoosterGrip),
myControlID(-1) myControlID(-1)
{ {
if(myJack == Left) if(myJack == Jack::Left)
{ {
myUpEvent = Event::JoystickZeroUp; myUpEvent = Event::JoystickZeroUp;
myDownEvent = Event::JoystickZeroDown; myDownEvent = Event::JoystickZeroDown;
@ -48,28 +48,28 @@ BoosterGrip::BoosterGrip(Jack jack, const Event& event, const System& system)
myYAxisValue = Event::SARightAxis1Value; myYAxisValue = Event::SARightAxis1Value;
} }
updateAnalogPin(Five, MAX_RESISTANCE); setPin(AnalogPin::Five, MAX_RESISTANCE);
updateAnalogPin(Nine, MAX_RESISTANCE); setPin(AnalogPin::Nine, MAX_RESISTANCE);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void BoosterGrip::update() void BoosterGrip::update()
{ {
// Digital events (from keyboard or joystick hats & buttons) // Digital events (from keyboard or joystick hats & buttons)
myDigitalPinState[One] = (myEvent.get(myUpEvent) == 0); setPin(DigitalPin::One, myEvent.get(myUpEvent) == 0);
myDigitalPinState[Two] = (myEvent.get(myDownEvent) == 0); setPin(DigitalPin::Two, myEvent.get(myDownEvent) == 0);
myDigitalPinState[Three] = (myEvent.get(myLeftEvent) == 0); setPin(DigitalPin::Three, myEvent.get(myLeftEvent) == 0);
myDigitalPinState[Four] = (myEvent.get(myRightEvent) == 0); setPin(DigitalPin::Four, myEvent.get(myRightEvent) == 0);
myDigitalPinState[Six] = (myEvent.get(myFireEvent) == 0); setPin(DigitalPin::Six, myEvent.get(myFireEvent) == 0);
// The CBS Booster-grip has two more buttons on it. These buttons are // The CBS Booster-grip has two more buttons on it. These buttons are
// connected to the inputs usually used by paddles. // connected to the inputs usually used by paddles.
updateAnalogPin( setPin(
Five, AnalogPin::Five,
(myEvent.get(myTriggerEvent) != 0) ? MIN_RESISTANCE : MAX_RESISTANCE (myEvent.get(myTriggerEvent) != 0) ? MIN_RESISTANCE : MAX_RESISTANCE
); );
updateAnalogPin( setPin(
Nine, AnalogPin::Nine,
(myEvent.get(myBoosterEvent) != 0) ? MIN_RESISTANCE : MAX_RESISTANCE (myEvent.get(myBoosterEvent) != 0) ? MIN_RESISTANCE : MAX_RESISTANCE
); );
@ -78,22 +78,22 @@ void BoosterGrip::update()
int yaxis = myEvent.get(myYAxisValue); int yaxis = myEvent.get(myYAxisValue);
if(xaxis > 16384-4096) if(xaxis > 16384-4096)
{ {
myDigitalPinState[Four] = false; setPin(DigitalPin::Four, false);
// Stelladaptor sends "half moved right" for L+R pushed together // Stelladaptor sends "half moved right" for L+R pushed together
if(xaxis < 16384+4096) if(xaxis < 16384+4096)
myDigitalPinState[Three] = false; setPin(DigitalPin::Three, false);
} }
else if(xaxis < -16384) else if(xaxis < -16384)
myDigitalPinState[Three] = false; setPin(DigitalPin::Three, false);
if(yaxis > 16384-4096) if(yaxis > 16384-4096)
{ {
myDigitalPinState[Two] = false; setPin(DigitalPin::Two, false);
// Stelladaptor sends "half moved down" for U+D pushed together // Stelladaptor sends "half moved down" for U+D pushed together
if(yaxis < 16384+4096) if(yaxis < 16384+4096)
myDigitalPinState[One] = false; setPin(DigitalPin::One, false);
} }
else if(yaxis < -16384) else if(yaxis < -16384)
myDigitalPinState[One] = false; setPin(DigitalPin::One, false);
// Mouse motion and button events // Mouse motion and button events
if(myControlID > -1) if(myControlID > -1)
@ -107,24 +107,24 @@ void BoosterGrip::update()
if((!(abs(mousey) > abs(mousex) << 1)) && (abs(mousex) >= MJ_Threshold)) if((!(abs(mousey) > abs(mousex) << 1)) && (abs(mousex) >= MJ_Threshold))
{ {
if(mousex < 0) if(mousex < 0)
myDigitalPinState[Three] = false; setPin(DigitalPin::Three, false);
else if (mousex > 0) else if (mousex > 0)
myDigitalPinState[Four] = false; setPin(DigitalPin::Four, false);
} }
if((!(abs(mousex) > abs(mousey) << 1)) && (abs(mousey) >= MJ_Threshold)) if((!(abs(mousex) > abs(mousey) << 1)) && (abs(mousey) >= MJ_Threshold))
{ {
if(mousey < 0) if(mousey < 0)
myDigitalPinState[One] = false; setPin(DigitalPin::One, false);
else if(mousey > 0) else if(mousey > 0)
myDigitalPinState[Two] = false; setPin(DigitalPin::Two, false);
} }
} }
// Get mouse button state // Get mouse button state
if(myEvent.get(Event::MouseButtonLeftValue)) if(myEvent.get(Event::MouseButtonLeftValue))
myDigitalPinState[Six] = false; setPin(DigitalPin::Six, false);
if(myEvent.get(Event::MouseButtonRightValue)) if(myEvent.get(Event::MouseButtonRightValue))
updateAnalogPin(Nine, MIN_RESISTANCE); setPin(AnalogPin::Nine, MIN_RESISTANCE);
} }
} }
@ -135,11 +135,11 @@ bool BoosterGrip::setMouseControl(
// Currently, the booster-grip takes full control of the mouse, using both // Currently, the booster-grip takes full control of the mouse, using both
// axes for its two degrees of movement, and the left/right buttons for // axes for its two degrees of movement, and the left/right buttons for
// fire and booster, respectively // fire and booster, respectively
if(xtype == Controller::BoosterGrip && ytype == Controller::BoosterGrip && if(xtype == Controller::Type::BoosterGrip && ytype == Controller::Type::BoosterGrip &&
xid == yid) xid == yid)
{ {
myControlID = ((myJack == Left && xid == 0) || myControlID = ((myJack == Jack::Left && xid == 0) ||
(myJack == Right && xid == 1) (myJack == Jack::Right && xid == 1)
) ? xid : -1; ) ? xid : -1;
} }
else else

View File

@ -48,6 +48,11 @@ class BoosterGrip : public Controller
*/ */
void update() override; void update() override;
/**
Returns the name of this controller.
*/
string name() const override { return "BoosterGrip"; }
/** /**
Determines how this controller will treat values received from the Determines how this controller will treat values received from the
X/Y axis and left/right buttons of the mouse. Since not all controllers X/Y axis and left/right buttons of the mouse. Since not all controllers

View File

@ -28,13 +28,13 @@ CompuMate::CompuMate(const Console& console, const Event& event,
{ {
// These controller pointers will be retrieved by the Console, which will // These controller pointers will be retrieved by the Console, which will
// also take ownership of them // also take ownership of them
myLeftController = make_unique<CMControl>(*this, Controller::Left, event, system); myLeftController = make_unique<CMControl>(*this, Controller::Jack::Left, event, system);
myRightController = make_unique<CMControl>(*this, Controller::Right, event, system); myRightController = make_unique<CMControl>(*this, Controller::Jack::Right, event, system);
myLeftController->updateAnalogPin(Controller::Nine, Controller::MAX_RESISTANCE); myLeftController->setPin(Controller::AnalogPin::Nine, Controller::MAX_RESISTANCE);
myLeftController->updateAnalogPin(Controller::Five, Controller::MIN_RESISTANCE); myLeftController->setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE);
myRightController->updateAnalogPin(Controller::Nine, Controller::MIN_RESISTANCE); myRightController->setPin(Controller::AnalogPin::Nine, Controller::MIN_RESISTANCE);
myRightController->updateAnalogPin(Controller::Five, Controller::MAX_RESISTANCE); myRightController->setPin(Controller::AnalogPin::Five, Controller::MAX_RESISTANCE);
enableKeyHandling(false); enableKeyHandling(false);
} }
@ -52,149 +52,139 @@ void CompuMate::update()
Controller& lp = myConsole.leftController(); Controller& lp = myConsole.leftController();
Controller& rp = myConsole.rightController(); Controller& rp = myConsole.rightController();
lp.myAnalogPinValue[Controller::Nine] = Controller::MAX_RESISTANCE; lp.setPin(Controller::AnalogPin::Nine, Controller::MAX_RESISTANCE);
lp.myAnalogPinValue[Controller::Five] = Controller::MIN_RESISTANCE; lp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE);
lp.myDigitalPinState[Controller::Six] = true; lp.setPin(Controller::DigitalPin::Six, true);
rp.myAnalogPinValue[Controller::Nine] = Controller::MIN_RESISTANCE; rp.setPin(Controller::AnalogPin::Nine, Controller::MIN_RESISTANCE);
rp.myAnalogPinValue[Controller::Five] = Controller::MAX_RESISTANCE; rp.setPin(Controller::AnalogPin::Five, Controller::MAX_RESISTANCE);
rp.myDigitalPinState[Controller::Six] = true; rp.setPin(Controller::DigitalPin::Six, true);
if (myKeyTable[KBDK_LSHIFT] || myKeyTable[KBDK_RSHIFT]) if (myKeyTable[KBDK_LSHIFT] || myKeyTable[KBDK_RSHIFT])
rp.myAnalogPinValue[Controller::Five] = Controller::MIN_RESISTANCE; rp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE);
if (myKeyTable[KBDK_LCTRL] || myKeyTable[KBDK_RCTRL]) if (myKeyTable[KBDK_LCTRL] || myKeyTable[KBDK_RCTRL])
lp.myAnalogPinValue[Controller::Nine] = Controller::MIN_RESISTANCE; lp.setPin(Controller::AnalogPin::Nine, Controller::MIN_RESISTANCE);
rp.myDigitalPinState[Controller::Three] = true; rp.setPin(Controller::DigitalPin::Three, true);
rp.myDigitalPinState[Controller::Four] = true; rp.setPin(Controller::DigitalPin::Four, true);
switch(myColumn) // This is updated inside CartCM class switch(myColumn) // This is updated inside CartCM class
{ {
case 0: case 0:
if (myKeyTable[KBDK_7]) lp.myDigitalPinState[Controller::Six] = false; if (myKeyTable[KBDK_7]) lp.setPin(Controller::DigitalPin::Six, false);
if (myKeyTable[KBDK_U]) rp.myDigitalPinState[Controller::Three] = false; if (myKeyTable[KBDK_U]) rp.setPin(Controller::DigitalPin::Three, false);
if (myKeyTable[KBDK_J]) rp.myDigitalPinState[Controller::Six] = false; if (myKeyTable[KBDK_J]) rp.setPin(Controller::DigitalPin::Six, false);
if (myKeyTable[KBDK_M]) rp.myDigitalPinState[Controller::Four] = false; if (myKeyTable[KBDK_M]) rp.setPin(Controller::DigitalPin::Four, false);
break; break;
case 1: case 1:
if (myKeyTable[KBDK_6]) lp.myDigitalPinState[Controller::Six] = false; if (myKeyTable[KBDK_6]) lp.setPin(Controller::DigitalPin::Six, false);
// Emulate the '?' character (Shift-6) with the actual question key // Emulate the '?' character (Shift-6) with the actual question key
if (myKeyTable[KBDK_SLASH] && (myKeyTable[KBDK_LSHIFT] || myKeyTable[KBDK_RSHIFT])) if (myKeyTable[KBDK_SLASH] && (myKeyTable[KBDK_LSHIFT] || myKeyTable[KBDK_RSHIFT]))
{ {
rp.myAnalogPinValue[Controller::Five] = Controller::MIN_RESISTANCE; rp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE);
lp.myDigitalPinState[Controller::Six] = false; lp.setPin(Controller::DigitalPin::Six, false);
} }
if (myKeyTable[KBDK_Y]) rp.myDigitalPinState[Controller::Three] = false; if (myKeyTable[KBDK_Y]) rp.setPin(Controller::DigitalPin::Three, false);
if (myKeyTable[KBDK_H]) rp.myDigitalPinState[Controller::Six] = false; if (myKeyTable[KBDK_H]) rp.setPin(Controller::DigitalPin::Six, false);
if (myKeyTable[KBDK_N]) rp.myDigitalPinState[Controller::Four] = false; if (myKeyTable[KBDK_N]) rp.setPin(Controller::DigitalPin::Four, false);
break; break;
case 2: case 2:
if (myKeyTable[KBDK_8]) lp.myDigitalPinState[Controller::Six] = false; if (myKeyTable[KBDK_8]) lp.setPin(Controller::DigitalPin::Six, false);
// Emulate the '[' character (Shift-8) with the actual key // Emulate the '[' character (Shift-8) with the actual key
if (myKeyTable[KBDK_LEFTBRACKET] && !(myKeyTable[KBDK_LSHIFT] || myKeyTable[KBDK_RSHIFT])) if (myKeyTable[KBDK_LEFTBRACKET] && !(myKeyTable[KBDK_LSHIFT] || myKeyTable[KBDK_RSHIFT]))
{ {
rp.myAnalogPinValue[Controller::Five] = Controller::MIN_RESISTANCE; rp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE);
lp.myDigitalPinState[Controller::Six] = false; lp.setPin(Controller::DigitalPin::Six, false);
} }
if (myKeyTable[KBDK_I]) rp.myDigitalPinState[Controller::Three] = false; if (myKeyTable[KBDK_I]) rp.setPin(Controller::DigitalPin::Three, false);
if (myKeyTable[KBDK_K]) rp.myDigitalPinState[Controller::Six] = false; if (myKeyTable[KBDK_K]) rp.setPin(Controller::DigitalPin::Six, false);
if (myKeyTable[KBDK_COMMA]) rp.myDigitalPinState[Controller::Four] = false; if (myKeyTable[KBDK_COMMA]) rp.setPin(Controller::DigitalPin::Four, false);
break; break;
case 3: case 3:
if (myKeyTable[KBDK_2]) lp.myDigitalPinState[Controller::Six] = false; if (myKeyTable[KBDK_2]) lp.setPin(Controller::DigitalPin::Six, false);
// Emulate the '-' character (Shift-2) with the actual minus key // Emulate the '-' character (Shift-2) with the actual minus key
if (myKeyTable[KBDK_MINUS] && !(myKeyTable[KBDK_LSHIFT] || myKeyTable[KBDK_RSHIFT])) if (myKeyTable[KBDK_MINUS] && !(myKeyTable[KBDK_LSHIFT] || myKeyTable[KBDK_RSHIFT]))
{ {
rp.myAnalogPinValue[Controller::Five] = Controller::MIN_RESISTANCE; rp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE);
lp.myDigitalPinState[Controller::Six] = false; lp.setPin(Controller::DigitalPin::Six, false);
} }
if (myKeyTable[KBDK_W]) rp.myDigitalPinState[Controller::Three] = false; if (myKeyTable[KBDK_W]) rp.setPin(Controller::DigitalPin::Three, false);
if (myKeyTable[KBDK_S]) rp.myDigitalPinState[Controller::Six] = false; if (myKeyTable[KBDK_S]) rp.setPin(Controller::DigitalPin::Six, false);
if (myKeyTable[KBDK_X]) rp.myDigitalPinState[Controller::Four] = false; if (myKeyTable[KBDK_X]) rp.setPin(Controller::DigitalPin::Four, false);
break; break;
case 4: case 4:
if (myKeyTable[KBDK_3]) lp.myDigitalPinState[Controller::Six] = false; if (myKeyTable[KBDK_3]) lp.setPin(Controller::DigitalPin::Six, false);
if (myKeyTable[KBDK_E]) rp.myDigitalPinState[Controller::Three] = false; if (myKeyTable[KBDK_E]) rp.setPin(Controller::DigitalPin::Three, false);
if (myKeyTable[KBDK_D]) rp.myDigitalPinState[Controller::Six] = false; if (myKeyTable[KBDK_D]) rp.setPin(Controller::DigitalPin::Six, false);
if (myKeyTable[KBDK_C]) rp.myDigitalPinState[Controller::Four] = false; if (myKeyTable[KBDK_C]) rp.setPin(Controller::DigitalPin::Four, false);
break; break;
case 5: case 5:
if (myKeyTable[KBDK_0]) lp.myDigitalPinState[Controller::Six] = false; if (myKeyTable[KBDK_0]) lp.setPin(Controller::DigitalPin::Six, false);
// Emulate the quote character (Shift-0) with the actual quote key // Emulate the quote character (Shift-0) with the actual quote key
if (myKeyTable[KBDK_APOSTROPHE] && (myKeyTable[KBDK_LSHIFT] || myKeyTable[KBDK_RSHIFT])) if (myKeyTable[KBDK_APOSTROPHE] && (myKeyTable[KBDK_LSHIFT] || myKeyTable[KBDK_RSHIFT]))
{ {
rp.myAnalogPinValue[Controller::Five] = Controller::MIN_RESISTANCE; rp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE);
lp.myDigitalPinState[Controller::Six] = false; lp.setPin(Controller::DigitalPin::Six, false);
} }
if (myKeyTable[KBDK_P]) rp.myDigitalPinState[Controller::Three] = false; if (myKeyTable[KBDK_P]) rp.setPin(Controller::DigitalPin::Three, false);
if (myKeyTable[KBDK_RETURN] || myKeyTable[KBDK_KP_ENTER]) if (myKeyTable[KBDK_RETURN] || myKeyTable[KBDK_KP_ENTER])
rp.myDigitalPinState[Controller::Six] = false; rp.setPin(Controller::DigitalPin::Six, false);
if (myKeyTable[KBDK_SPACE]) rp.myDigitalPinState[Controller::Four] = false; if (myKeyTable[KBDK_SPACE]) rp.setPin(Controller::DigitalPin::Four, false);
// Emulate Ctrl-space (aka backspace) with the actual Backspace key // Emulate Ctrl-space (aka backspace) with the actual Backspace key
if (myKeyTable[KBDK_BACKSPACE]) if (myKeyTable[KBDK_BACKSPACE])
{ {
lp.myAnalogPinValue[Controller::Nine] = Controller::MIN_RESISTANCE; lp.setPin(Controller::AnalogPin::Nine, Controller::MIN_RESISTANCE);
rp.myDigitalPinState[Controller::Four] = false; rp.setPin(Controller::DigitalPin::Four, false);
} }
break; break;
case 6: case 6:
if (myKeyTable[KBDK_9]) lp.myDigitalPinState[Controller::Six] = false; if (myKeyTable[KBDK_9]) lp.setPin(Controller::DigitalPin::Six, false);
// Emulate the ']' character (Shift-9) with the actual key // Emulate the ']' character (Shift-9) with the actual key
if (myKeyTable[KBDK_RIGHTBRACKET] && !(myKeyTable[KBDK_LSHIFT] || myKeyTable[KBDK_RSHIFT])) if (myKeyTable[KBDK_RIGHTBRACKET] && !(myKeyTable[KBDK_LSHIFT] || myKeyTable[KBDK_RSHIFT]))
{ {
rp.myAnalogPinValue[Controller::Five] = Controller::MIN_RESISTANCE; rp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE);
lp.myDigitalPinState[Controller::Six] = false; lp.setPin(Controller::DigitalPin::Six, false);
} }
if (myKeyTable[KBDK_O]) rp.myDigitalPinState[Controller::Three] = false; if (myKeyTable[KBDK_O]) rp.setPin(Controller::DigitalPin::Three, false);
if (myKeyTable[KBDK_L]) rp.myDigitalPinState[Controller::Six] = false; if (myKeyTable[KBDK_L]) rp.setPin(Controller::DigitalPin::Six, false);
if (myKeyTable[KBDK_PERIOD]) rp.myDigitalPinState[Controller::Four] = false; if (myKeyTable[KBDK_PERIOD]) rp.setPin(Controller::DigitalPin::Four, false);
break; break;
case 7: case 7:
if (myKeyTable[KBDK_5]) lp.myDigitalPinState[Controller::Six] = false; if (myKeyTable[KBDK_5]) lp.setPin(Controller::DigitalPin::Six, false);
// Emulate the '=' character (Shift-5) with the actual equals key // Emulate the '=' character (Shift-5) with the actual equals key
if (myKeyTable[KBDK_EQUALS] && !(myKeyTable[KBDK_LSHIFT] || myKeyTable[KBDK_RSHIFT])) if (myKeyTable[KBDK_EQUALS] && !(myKeyTable[KBDK_LSHIFT] || myKeyTable[KBDK_RSHIFT]))
{ {
rp.myAnalogPinValue[Controller::Five] = Controller::MIN_RESISTANCE; rp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE);
lp.myDigitalPinState[Controller::Six] = false; lp.setPin(Controller::DigitalPin::Six, false);
} }
if (myKeyTable[KBDK_T]) rp.myDigitalPinState[Controller::Three] = false; if (myKeyTable[KBDK_T]) rp.setPin(Controller::DigitalPin::Three, false);
if (myKeyTable[KBDK_G]) rp.myDigitalPinState[Controller::Six] = false; if (myKeyTable[KBDK_G]) rp.setPin(Controller::DigitalPin::Six, false);
if (myKeyTable[KBDK_B]) rp.myDigitalPinState[Controller::Four] = false; if (myKeyTable[KBDK_B]) rp.setPin(Controller::DigitalPin::Four, false);
break; break;
case 8: case 8:
if (myKeyTable[KBDK_1]) lp.myDigitalPinState[Controller::Six] = false; if (myKeyTable[KBDK_1]) lp.setPin(Controller::DigitalPin::Six, false);
// Emulate the '+' character (Shift-1) with the actual plus key (Shift-=) // Emulate the '+' character (Shift-1) with the actual plus key (Shift-=)
if (myKeyTable[KBDK_EQUALS] && (myKeyTable[KBDK_LSHIFT] || myKeyTable[KBDK_RSHIFT])) if (myKeyTable[KBDK_EQUALS] && (myKeyTable[KBDK_LSHIFT] || myKeyTable[KBDK_RSHIFT]))
{ {
rp.myAnalogPinValue[Controller::Five] = Controller::MIN_RESISTANCE; rp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE);
lp.myDigitalPinState[Controller::Six] = false; lp.setPin(Controller::DigitalPin::Six, false);
} }
if (myKeyTable[KBDK_Q]) rp.myDigitalPinState[Controller::Three] = false; if (myKeyTable[KBDK_Q]) rp.setPin(Controller::DigitalPin::Three, false);
if (myKeyTable[KBDK_A]) rp.myDigitalPinState[Controller::Six] = false; if (myKeyTable[KBDK_A]) rp.setPin(Controller::DigitalPin::Six, false);
if (myKeyTable[KBDK_Z]) rp.myDigitalPinState[Controller::Four] = false; if (myKeyTable[KBDK_Z]) rp.setPin(Controller::DigitalPin::Four, false);
break; break;
case 9: case 9:
if (myKeyTable[KBDK_4]) lp.myDigitalPinState[Controller::Six] = false; if (myKeyTable[KBDK_4]) lp.setPin(Controller::DigitalPin::Six, false);
// Emulate the '/' character (Shift-4) with the actual slash key // Emulate the '/' character (Shift-4) with the actual slash key
if (myKeyTable[KBDK_SLASH] && !(myKeyTable[KBDK_LSHIFT] || myKeyTable[KBDK_RSHIFT])) if (myKeyTable[KBDK_SLASH] && !(myKeyTable[KBDK_LSHIFT] || myKeyTable[KBDK_RSHIFT]))
{ {
rp.myAnalogPinValue[Controller::Five] = Controller::MIN_RESISTANCE; rp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE);
lp.myDigitalPinState[Controller::Six] = false; lp.setPin(Controller::DigitalPin::Six, false);
} }
if (myKeyTable[KBDK_R]) rp.myDigitalPinState[Controller::Three] = false; if (myKeyTable[KBDK_R]) rp.setPin(Controller::DigitalPin::Three, false);
if (myKeyTable[KBDK_F]) rp.myDigitalPinState[Controller::Six] = false; if (myKeyTable[KBDK_F]) rp.setPin(Controller::DigitalPin::Six, false);
if (myKeyTable[KBDK_V]) rp.myDigitalPinState[Controller::Four] = false; if (myKeyTable[KBDK_V]) rp.setPin(Controller::DigitalPin::Four, false);
break; break;
default: default:
break; break;
} }
if (lp.myOnAnalogPinUpdateCallback) {
lp.myOnAnalogPinUpdateCallback(Controller::Five);
lp.myOnAnalogPinUpdateCallback(Controller::Nine);
}
if (rp.myOnAnalogPinUpdateCallback) {
rp.myOnAnalogPinUpdateCallback(Controller::Five);
rp.myOnAnalogPinUpdateCallback(Controller::Nine);
}
} }

View File

@ -100,7 +100,7 @@ class CompuMate
*/ */
CMControl(class CompuMate& handler, Controller::Jack jack, const Event& event, CMControl(class CompuMate& handler, Controller::Jack jack, const Event& event,
const System& system) const System& system)
: Controller(jack, event, system, Controller::CompuMate), : Controller(jack, event, system, Controller::Type::CompuMate),
myHandler(handler) { } myHandler(handler) { }
virtual ~CMControl() = default; virtual ~CMControl() = default;
@ -111,7 +111,7 @@ class CompuMate
happen at the same cycle and is redundant. happen at the same cycle and is redundant.
*/ */
void controlWrite(uInt8) override { void controlWrite(uInt8) override {
if(myJack == Controller::Left) myHandler.update(); if(myJack == Controller::Jack::Left) myHandler.update();
} }
/** /**
@ -120,6 +120,11 @@ class CompuMate
*/ */
void update() override { } void update() override { }
/**
Returns the name of this controller.
*/
string name() const override { return "CompuMate"; }
private: private:
class CompuMate& myHandler; class CompuMate& myHandler;

View File

@ -116,8 +116,8 @@ Console::Console(OSystem& osystem, unique_ptr<Cartridge>& cart,
// For now, we just add dummy joystick controllers, since autodetection // For now, we just add dummy joystick controllers, since autodetection
// runs the emulation for a while, and this may interfere with 'smart' // runs the emulation for a while, and this may interfere with 'smart'
// controllers such as the AVox and SaveKey // controllers such as the AVox and SaveKey
myLeftControl = make_unique<Joystick>(Controller::Left, myEvent, *mySystem); myLeftControl = make_unique<Joystick>(Controller::Jack::Left, myEvent, *mySystem);
myRightControl = make_unique<Joystick>(Controller::Right, myEvent, *mySystem); myRightControl = make_unique<Joystick>(Controller::Jack::Right, myEvent, *mySystem);
// Let the cart know how to query for the 'Cartridge.StartBank' property // Let the cart know how to query for the 'Cartridge.StartBank' property
myCart->setStartBankFromPropsFunc([this]() { myCart->setStartBankFromPropsFunc([this]() {
@ -819,13 +819,13 @@ void Console::setControllers(const string& rommd5)
if(image != nullptr || size != 0) if(image != nullptr || size != 0)
{ {
left = ControllerDetector::detectType(image, size, left, left = ControllerDetector::detectType(image, size, left,
!swappedPorts ? Controller::Left : Controller::Right, myOSystem.settings()); !swappedPorts ? Controller::Jack::Left : Controller::Jack::Right, myOSystem.settings());
right = ControllerDetector::detectType(image, size, right, right = ControllerDetector::detectType(image, size, right,
!swappedPorts ? Controller::Right : Controller::Left, myOSystem.settings()); !swappedPorts ? Controller::Jack::Right : Controller::Jack::Left, myOSystem.settings());
} }
unique_ptr<Controller> leftC = getControllerPort(rommd5, left, Controller::Left), unique_ptr<Controller> leftC = getControllerPort(rommd5, left, Controller::Jack::Left),
rightC = getControllerPort(rommd5, right, Controller::Right); rightC = getControllerPort(rommd5, right, Controller::Jack::Right);
// Swap the ports if necessary // Swap the ports if necessary
if(!swappedPorts) if(!swappedPorts)

View File

@ -21,22 +21,17 @@
#ifndef CONSOLE_IO_HXX #ifndef CONSOLE_IO_HXX
#define CONSOLE_IO_HXX #define CONSOLE_IO_HXX
class ConsoleIO { class ConsoleIO
{
public: public:
/** /**
Get the controller plugged into the specified jack Get the controller plugged into the specified jack
@return The specified controller @return The specified controller
*/ */
virtual Controller& leftController() const = 0; virtual Controller& leftController() const = 0;
virtual Controller& rightController() const = 0; virtual Controller& rightController() const = 0;
Controller& controller(Controller::Jack jack) const {
return jack == Controller::Left ? leftController() : rightController();
}
/** /**
Get the console switches Get the console switches

View File

@ -29,105 +29,31 @@ Controller::Controller(Jack jack, const Event& event, const System& system,
myType(type), myType(type),
myOnAnalogPinUpdateCallback(nullptr) myOnAnalogPinUpdateCallback(nullptr)
{ {
myDigitalPinState[One] = resetDigitalPins();
myDigitalPinState[Two] = resetAnalogPins();
myDigitalPinState[Three] =
myDigitalPinState[Four] =
myDigitalPinState[Six] = true;
myAnalogPinValue[Five] =
myAnalogPinValue[Nine] = MAX_RESISTANCE;
switch(myType)
{
case Joystick:
myName = "Joystick";
break;
case Paddles:
myName = "Paddles";
break;
case BoosterGrip:
myName = "BoosterGrip";
break;
case Driving:
myName = "Driving";
break;
case Keyboard:
myName = "Keyboard";
break;
case AmigaMouse:
myName = "AmigaMouse";
break;
case AtariMouse:
myName = "AtariMouse";
break;
case TrakBall:
myName = "TrakBall";
break;
case AtariVox:
myName = "AtariVox";
break;
case SaveKey:
myName = "SaveKey";
break;
case KidVid:
myName = "KidVid";
break;
case Genesis:
myName = "Genesis";
break;
case MindLink:
myName = "MindLink";
break;
case CompuMate:
myName = "CompuMate";
break;
}
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
uInt8 Controller::read() uInt8 Controller::read()
{ {
uInt8 ioport = 0x00; uInt8 ioport = 0b0000;
if(read(One)) ioport |= 0x01; if(read(DigitalPin::One)) ioport |= 0b0001;
if(read(Two)) ioport |= 0x02; if(read(DigitalPin::Two)) ioport |= 0b0010;
if(read(Three)) ioport |= 0x04; if(read(DigitalPin::Three)) ioport |= 0b0100;
if(read(Four)) ioport |= 0x08; if(read(DigitalPin::Four)) ioport |= 0b1000;
return ioport; return ioport;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool Controller::read(DigitalPin pin) bool Controller::read(DigitalPin pin)
{ {
return myDigitalPinState[pin]; return getPin(pin);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Int32 Controller::read(AnalogPin pin) Int32 Controller::read(AnalogPin pin)
{ {
return myAnalogPinValue[pin]; return getPin(pin);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Controller::set(DigitalPin pin, bool value)
{
myDigitalPinState[pin] = value;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Controller::set(AnalogPin pin, Int32 value)
{
updateAnalogPin(pin, value);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Controller::updateAnalogPin(AnalogPin pin, Int32 value)
{
myAnalogPinValue[pin] = value;
if (myOnAnalogPinUpdateCallback) {
myOnAnalogPinUpdateCallback(pin);
}
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -136,15 +62,15 @@ bool Controller::save(Serializer& out) const
try try
{ {
// Output the digital pins // Output the digital pins
out.putBool(myDigitalPinState[One]); out.putBool(getPin(DigitalPin::One));
out.putBool(myDigitalPinState[Two]); out.putBool(getPin(DigitalPin::Two));
out.putBool(myDigitalPinState[Three]); out.putBool(getPin(DigitalPin::Three));
out.putBool(myDigitalPinState[Four]); out.putBool(getPin(DigitalPin::Four));
out.putBool(myDigitalPinState[Six]); out.putBool(getPin(DigitalPin::Six));
// Output the analog pins // Output the analog pins
out.putInt(myAnalogPinValue[Five]); out.putInt(getPin(AnalogPin::Five));
out.putInt(myAnalogPinValue[Nine]); out.putInt(getPin(AnalogPin::Nine));
} }
catch(...) catch(...)
{ {
@ -160,15 +86,15 @@ bool Controller::load(Serializer& in)
try try
{ {
// Input the digital pins // Input the digital pins
myDigitalPinState[One] = in.getBool(); setPin(DigitalPin::One, in.getBool());
myDigitalPinState[Two] = in.getBool(); setPin(DigitalPin::Two, in.getBool());
myDigitalPinState[Three] = in.getBool(); setPin(DigitalPin::Three, in.getBool());
myDigitalPinState[Four] = in.getBool(); setPin(DigitalPin::Four, in.getBool());
myDigitalPinState[Six] = in.getBool(); setPin(DigitalPin::Six, in.getBool());
// Input the analog pins // Input the analog pins
myAnalogPinValue[Five] = in.getInt(); setPin(AnalogPin::Five, in.getInt());
myAnalogPinValue[Nine] = in.getInt(); setPin(AnalogPin::Nine, in.getInt());
} }
catch(...) catch(...)
{ {

View File

@ -19,6 +19,7 @@
#define CONTROLLER_HXX #define CONTROLLER_HXX
class Controller; class Controller;
class ControllerLowLevel;
class Event; class Event;
class System; class System;
@ -64,30 +65,30 @@ class Controller : public Serializable
/** /**
Various classes that need special access to the underlying controller state Various classes that need special access to the underlying controller state
*/ */
friend class M6532; friend class M6532; // FIXME - only needs two methods from this class
friend class RiotDebug;
friend class CompuMate; friend class CompuMate;
friend class ControllerLowLevel;
public: public:
/** /**
Enumeration of the controller jacks Enumeration of the controller jacks
*/ */
enum Jack { Left = 0, Right = 1 }; enum class Jack { Left = 0, Right = 1 };
/** /**
Enumeration of the digital pins of a controller port Enumeration of the digital pins of a controller port
*/ */
enum DigitalPin { One, Two, Three, Four, Six }; enum class DigitalPin { One, Two, Three, Four, Six };
/** /**
Enumeration of the analog pins of a controller port Enumeration of the analog pins of a controller port
*/ */
enum AnalogPin { Five, Nine }; enum class AnalogPin { Five, Nine };
/** /**
Enumeration of the controller types Enumeration of the controller types
*/ */
enum Type enum class Type
{ {
AmigaMouse, AtariMouse, AtariVox, BoosterGrip, CompuMate, AmigaMouse, AtariMouse, AtariVox, BoosterGrip, CompuMate,
Driving, Genesis, Joystick, Keyboard, KidVid, MindLink, Driving, Genesis, Joystick, Keyboard, KidVid, MindLink,
@ -176,6 +177,11 @@ class Controller : public Serializable
*/ */
virtual void update() = 0; virtual void update() = 0;
/**
Returns the name of this controller.
*/
virtual string name() const = 0;
/** /**
Answers whether the controller is intrinsically an analog controller. Answers whether the controller is intrinsically an analog controller.
Specific controllers should override and implement this method. Specific controllers should override and implement this method.
@ -221,22 +227,10 @@ class Controller : public Serializable
*/ */
virtual string about(bool swappedPorts) const virtual string about(bool swappedPorts) const
{ {
return name() + " in " + (((myJack == Left) ^ swappedPorts) ? return name() + " in " + (((myJack == Jack::Left) ^ swappedPorts) ?
"left port" : "right port"); "left port" : "right port");
} }
/**
The following two functions are used by the debugger to set
the specified pins to the given value. Note that this isn't the
same as a write; the debugger is allowed special access and is
actually 'below' the controller level.
@param pin The pin of the controller jack to modify
@param value The value to set on the pin
*/
void set(DigitalPin pin, bool value);
void set(AnalogPin pin, Int32 value);
/** /**
Saves the current state of this controller to the given Serializer. Saves the current state of this controller to the given Serializer.
@ -253,11 +247,6 @@ class Controller : public Serializable
*/ */
bool load(Serializer& in) override; bool load(Serializer& in) override;
/**
Returns the name of this controller.
*/
string name() const { return myName; }
/** /**
Inject a callback to be notified on analog pin updates. Inject a callback to be notified on analog pin updates.
*/ */
@ -273,7 +262,35 @@ class Controller : public Serializable
static constexpr Int32 MIN_RESISTANCE = 0x00000000; static constexpr Int32 MIN_RESISTANCE = 0x00000000;
protected: protected:
void updateAnalogPin(AnalogPin, Int32 value); /**
Derived classes *must* use these accessor/mutator methods.
The read/write methods above are meant to be used at a higher level.
*/
inline bool setPin(DigitalPin pin, bool value) {
return myDigitalPinState[static_cast<int>(pin)] = value;
}
inline bool getPin(DigitalPin pin) const {
return myDigitalPinState[static_cast<int>(pin)];
}
inline void setPin(AnalogPin pin, Int32 value) {
myAnalogPinValue[static_cast<int>(pin)] = value;
if(myOnAnalogPinUpdateCallback)
myOnAnalogPinUpdateCallback(pin);
}
inline Int32 getPin(AnalogPin pin) const {
return myAnalogPinValue[static_cast<int>(pin)];
}
inline void resetDigitalPins() {
setPin(DigitalPin::One, true);
setPin(DigitalPin::Two, true);
setPin(DigitalPin::Three, true);
setPin(DigitalPin::Four, true);
setPin(DigitalPin::Six, true);
}
inline void resetAnalogPins() {
setPin(AnalogPin::Five, MAX_RESISTANCE);
setPin(AnalogPin::Nine, MAX_RESISTANCE);
}
protected: protected:
/// Specifies which jack the controller is plugged in /// Specifies which jack the controller is plugged in
@ -288,16 +305,13 @@ class Controller : public Serializable
/// Specifies which type of controller this is (defined by child classes) /// Specifies which type of controller this is (defined by child classes)
const Type myType; const Type myType;
/// Specifies the name of this controller based on type
string myName;
/// The boolean value on each digital pin
bool myDigitalPinState[5];
/// The callback that is dispatched whenver an analog pin has changed /// The callback that is dispatched whenver an analog pin has changed
onAnalogPinUpdateCallback myOnAnalogPinUpdateCallback; onAnalogPinUpdateCallback myOnAnalogPinUpdateCallback;
private: private:
/// The boolean value on each digital pin
bool myDigitalPinState[5];
/// The analog value on each analog pin /// The analog value on each analog pin
Int32 myAnalogPinValue[2]; Int32 myAnalogPinValue[2];

View File

@ -0,0 +1,73 @@
//============================================================================
//
// SSSS tt lll lll
// SS SS tt ll ll
// SS tttttt eeee ll ll aaaa
// SSSS tt ee ee ll ll aa
// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
// SS SS tt ee ll ll aa aa
// SSSS ttt eeeee llll llll aaaaa
//
// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony
// and the Stella Team
//
// See the file "License.txt" for information on usage and redistribution of
// this file, and for a DISCLAIMER OF ALL WARRANTIES.
//============================================================================
#ifndef CONTROLLER_LOW_LEVEL_HXX
#define CONTROLLER_LOW_LEVEL_HXX
#include "Control.hxx"
/**
Some subsystems (ie, the debugger) need low-level access to the controller
ports. In particular, they need to be able to bypass the normal read/write
methods and operate directly on the individual pins. This class provides
an abstraction for that functionality.
Classes that inherit from this class will have low-level access to the
Controller class, since it is a 'friend' of that class.
@author Stephen Anthony
*/
class ControllerLowLevel
{
public:
ControllerLowLevel(Controller& controller) : myController(controller) { }
virtual ~ControllerLowLevel() = default;
inline bool setPin(Controller::DigitalPin pin, bool value) {
return myController.setPin(pin, value);
}
inline bool togglePin(Controller::DigitalPin pin) { return false; }
inline bool getPin(Controller::DigitalPin pin) const {
return myController.getPin(pin);
}
inline void setPin(Controller::AnalogPin pin, Int32 value) {
myController.setPin(pin, value);
}
inline Int32 getPin(Controller::AnalogPin pin) const {
return myController.getPin(pin);
}
inline void resetDigitalPins() {
myController.resetDigitalPins();
}
inline void resetAnalogPins() {
myController.resetAnalogPins();
}
inline Controller& base() const { return myController; }
protected:
Controller& myController;
private:
// Following constructors and assignment operators not supported
ControllerLowLevel() = delete;
ControllerLowLevel(const ControllerLowLevel&) = delete;
ControllerLowLevel(ControllerLowLevel&&) = delete;
ControllerLowLevel& operator=(const ControllerLowLevel&) = delete;
ControllerLowLevel& operator=(ControllerLowLevel&&) = delete;
};
#endif

View File

@ -107,7 +107,7 @@ bool ControllerDetector::searchForBytes(const uInt8* image, uInt32 imagesize,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool ControllerDetector::usesJoystickButton(const uInt8* image, uInt32 size, Controller::Jack port) bool ControllerDetector::usesJoystickButton(const uInt8* image, uInt32 size, Controller::Jack port)
{ {
if(port == Controller::Left) if(port == Controller::Jack::Left)
{ {
// check for INPT4 access // check for INPT4 access
const int NUM_SIGS_0 = 17; const int NUM_SIGS_0 = 17;
@ -164,7 +164,7 @@ bool ControllerDetector::usesJoystickButton(const uInt8* image, uInt32 size, Con
if(searchForBytes(image, size, signature_2[i], SIG_SIZE_2)) if(searchForBytes(image, size, signature_2[i], SIG_SIZE_2))
return true; return true;
} }
else if(port == Controller::Right) else if(port == Controller::Jack::Right)
{ {
// check for INPT5 and indexed INPT4 access // check for INPT5 and indexed INPT4 access
const int NUM_SIGS_0 = 13; const int NUM_SIGS_0 = 13;
@ -217,7 +217,7 @@ bool ControllerDetector::usesJoystickButton(const uInt8* image, uInt32 size, Con
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool ControllerDetector::usesKeyboard(const uInt8* image, uInt32 size, Controller::Jack port) bool ControllerDetector::usesKeyboard(const uInt8* image, uInt32 size, Controller::Jack port)
{ {
if(port == Controller::Left) if(port == Controller::Jack::Left)
{ {
// check for INPT0 *AND* INPT1 access // check for INPT0 *AND* INPT1 access
const int NUM_SIGS_0_0 = 4; const int NUM_SIGS_0_0 = 4;
@ -279,7 +279,7 @@ bool ControllerDetector::usesKeyboard(const uInt8* image, uInt32 size, Controlle
} }
} }
} }
else if(port == Controller::Right) else if(port == Controller::Jack::Right)
{ {
// check for INPT2 *AND* INPT3 access // check for INPT2 *AND* INPT3 access
const int NUM_SIGS_0_0 = 3; const int NUM_SIGS_0_0 = 3;
@ -347,7 +347,7 @@ bool ControllerDetector::usesKeyboard(const uInt8* image, uInt32 size, Controlle
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool ControllerDetector::usesGenesisButton(const uInt8* image, uInt32 size, Controller::Jack port) bool ControllerDetector::usesGenesisButton(const uInt8* image, uInt32 size, Controller::Jack port)
{ {
if(port == Controller::Left) if(port == Controller::Jack::Left)
{ {
// check for INPT1 access // check for INPT1 access
const int NUM_SIGS_0 = 13; const int NUM_SIGS_0 = 13;
@ -371,7 +371,7 @@ bool ControllerDetector::usesGenesisButton(const uInt8* image, uInt32 size, Cont
if(searchForBytes(image, size, signature_0[i], SIG_SIZE_0)) if(searchForBytes(image, size, signature_0[i], SIG_SIZE_0))
return true; return true;
} }
else if(port == Controller::Right) else if(port == Controller::Jack::Right)
{ {
// check for INPT3 access // check for INPT3 access
const int NUM_SIGS_0 = 9; const int NUM_SIGS_0 = 9;
@ -398,7 +398,7 @@ bool ControllerDetector::usesGenesisButton(const uInt8* image, uInt32 size, Cont
bool ControllerDetector::usesPaddle(const uInt8* image, uInt32 size, bool ControllerDetector::usesPaddle(const uInt8* image, uInt32 size,
Controller::Jack port, const Settings& settings) Controller::Jack port, const Settings& settings)
{ {
if(port == Controller::Left) if(port == Controller::Jack::Left)
{ {
// check for INPT0 access // check for INPT0 access
const int NUM_SIGS_0 = 12; const int NUM_SIGS_0 = 12;
@ -448,7 +448,7 @@ bool ControllerDetector::usesPaddle(const uInt8* image, uInt32 size,
if(searchForBytes(image, size, signature_2[i], SIG_SIZE_2)) if(searchForBytes(image, size, signature_2[i], SIG_SIZE_2))
return true; return true;
} }
else if(port == Controller::Right) else if(port == Controller::Jack::Right)
{ {
// check for INPT2 and indexed INPT0 access // check for INPT2 and indexed INPT0 access
const int NUM_SIGS_0 = 18; const int NUM_SIGS_0 = 18;
@ -564,7 +564,7 @@ bool ControllerDetector::isProbablyAmigaMouse(const uInt8* image, uInt32 size)
bool ControllerDetector::isProbablySaveKey(const uInt8* image, uInt32 size, Controller::Jack port) bool ControllerDetector::isProbablySaveKey(const uInt8* image, uInt32 size, Controller::Jack port)
{ {
// check for known SaveKey code, only supports right port // check for known SaveKey code, only supports right port
if(port == Controller::Right) if(port == Controller::Jack::Right)
{ {
const int NUM_SIGS = 4; const int NUM_SIGS = 4;
const int SIG_SIZE = 9; const int SIG_SIZE = 9;

View File

@ -22,7 +22,7 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Driving::Driving(Jack jack, const Event& event, const System& system) Driving::Driving(Jack jack, const Event& event, const System& system)
: Controller(jack, event, system, Controller::Driving), : Controller(jack, event, system, Controller::Type::Driving),
myCounter(0), myCounter(0),
myGrayIndex(0), myGrayIndex(0),
myLastYaxis(0), myLastYaxis(0),
@ -30,7 +30,7 @@ Driving::Driving(Jack jack, const Event& event, const System& system)
myControlIDX(-1), myControlIDX(-1),
myControlIDY(-1) myControlIDY(-1)
{ {
if(myJack == Left) if(myJack == Jack::Left)
{ {
myCCWEvent = Event::JoystickZeroLeft; myCCWEvent = Event::JoystickZeroLeft;
myCWEvent = Event::JoystickZeroRight; myCWEvent = Event::JoystickZeroRight;
@ -48,7 +48,8 @@ Driving::Driving(Jack jack, const Event& event, const System& system)
} }
// Digital pins 3 and 4 are not connected // Digital pins 3 and 4 are not connected
myDigitalPinState[Three] = myDigitalPinState[Four] = true; setPin(DigitalPin::Three, true);
setPin(DigitalPin::Four, true);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -59,7 +60,7 @@ void Driving::update()
myCounter = (myGrayIndex << 2) | (myCounter & 3); myCounter = (myGrayIndex << 2) | (myCounter & 3);
// Digital events (from keyboard or joystick hats & buttons) // Digital events (from keyboard or joystick hats & buttons)
myDigitalPinState[Six] = (myEvent.get(myFireEvent) == 0); setPin(DigitalPin::Six, myEvent.get(myFireEvent) == 0);
int d_axis = myEvent.get(myXAxisValue); int d_axis = myEvent.get(myXAxisValue);
if(myEvent.get(myCCWEvent) != 0 || d_axis < -16384) --myCounter; if(myEvent.get(myCCWEvent) != 0 || d_axis < -16384) --myCounter;
else if(myEvent.get(myCWEvent) != 0 || d_axis > 16384) ++myCounter; else if(myEvent.get(myCWEvent) != 0 || d_axis > 16384) ++myCounter;
@ -72,7 +73,7 @@ void Driving::update()
else if(m_axis > 2) ++myCounter; else if(m_axis > 2) ++myCounter;
if(myEvent.get(Event::MouseButtonLeftValue) || if(myEvent.get(Event::MouseButtonLeftValue) ||
myEvent.get(Event::MouseButtonRightValue)) myEvent.get(Event::MouseButtonRightValue))
myDigitalPinState[Six] = false; setPin(DigitalPin::Six, false);
} }
else else
{ {
@ -84,7 +85,7 @@ void Driving::update()
if(m_axis < -2) --myCounter; if(m_axis < -2) --myCounter;
else if(m_axis > 2) ++myCounter; else if(m_axis > 2) ++myCounter;
if(myEvent.get(Event::MouseButtonLeftValue)) if(myEvent.get(Event::MouseButtonLeftValue))
myDigitalPinState[Six] = false; setPin(DigitalPin::Six, false);
} }
if(myControlIDY > -1) if(myControlIDY > -1)
{ {
@ -92,7 +93,7 @@ void Driving::update()
if(m_axis < -2) --myCounter; if(m_axis < -2) --myCounter;
else if(m_axis > 2) ++myCounter; else if(m_axis > 2) ++myCounter;
if(myEvent.get(Event::MouseButtonRightValue)) if(myEvent.get(Event::MouseButtonRightValue))
myDigitalPinState[Six] = false; setPin(DigitalPin::Six, false);
} }
} }
@ -123,8 +124,8 @@ void Driving::update()
// Determine which bits are set // Determine which bits are set
uInt8 gray = graytable[myGrayIndex]; uInt8 gray = graytable[myGrayIndex];
myDigitalPinState[One] = (gray & 0x1) != 0; setPin(DigitalPin::One, (gray & 0x1) != 0);
myDigitalPinState[Two] = (gray & 0x2) != 0; setPin(DigitalPin::Two, (gray & 0x2) != 0);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -133,10 +134,10 @@ bool Driving::setMouseControl(
{ {
// When the mouse emulates a single driving controller, only the X-axis is // When the mouse emulates a single driving controller, only the X-axis is
// used, and both mouse buttons map to the same 'fire' event // used, and both mouse buttons map to the same 'fire' event
if(xtype == Controller::Driving && ytype == Controller::Driving && xid == yid) if(xtype == Controller::Type::Driving && ytype == Controller::Type::Driving && xid == yid)
{ {
myControlID = ((myJack == Left && xid == 0) || myControlID = ((myJack == Jack::Left && xid == 0) ||
(myJack == Right && xid == 1) (myJack == Jack::Right && xid == 1)
) ? xid : -1; ) ? xid : -1;
myControlIDX = myControlIDY = -1; myControlIDX = myControlIDY = -1;
} }
@ -145,15 +146,15 @@ bool Driving::setMouseControl(
// Otherwise, each axis can be mapped to a separate driving controller, // Otherwise, each axis can be mapped to a separate driving controller,
// and the buttons map to separate (corresponding) controllers // and the buttons map to separate (corresponding) controllers
myControlID = -1; myControlID = -1;
if(myJack == Left) if(myJack == Jack::Left)
{ {
myControlIDX = (xtype == Controller::Driving && xid == 0) ? 0 : -1; myControlIDX = (xtype == Controller::Type::Driving && xid == 0) ? 0 : -1;
myControlIDY = (ytype == Controller::Driving && yid == 0) ? 0 : -1; myControlIDY = (ytype == Controller::Type::Driving && yid == 0) ? 0 : -1;
} }
else // myJack == Right else // myJack == Right
{ {
myControlIDX = (xtype == Controller::Driving && xid == 1) ? 1 : -1; myControlIDX = (xtype == Controller::Type::Driving && xid == 1) ? 1 : -1;
myControlIDY = (ytype == Controller::Driving && yid == 1) ? 1 : -1; myControlIDY = (ytype == Controller::Type::Driving && yid == 1) ? 1 : -1;
} }
} }

View File

@ -47,6 +47,11 @@ class Driving : public Controller
*/ */
void update() override; void update() override;
/**
Returns the name of this controller.
*/
string name() const override { return "Driving"; }
/** /**
Answers whether the controller is intrinsically an analog controller. Answers whether the controller is intrinsically an analog controller.
*/ */

View File

@ -1093,8 +1093,8 @@ void EventHandler::setMouseControllerMode(const string& enable)
usemouse = false; usemouse = false;
else // 'analog' else // 'analog'
{ {
usemouse = myOSystem.console().controller(Controller::Left).isAnalog() || usemouse = myOSystem.console().leftController().isAnalog() ||
myOSystem.console().controller(Controller::Right).isAnalog(); myOSystem.console().rightController().isAnalog();
} }
const string& control = usemouse ? const string& control = usemouse ?
@ -1202,7 +1202,7 @@ void EventHandler::setState(EventHandlerState state)
case EventHandlerState::EMULATION: case EventHandlerState::EMULATION:
myOSystem.sound().mute(false); myOSystem.sound().mute(false);
enableTextEvents(false); enableTextEvents(false);
if(myOSystem.console().leftController().type() == Controller::CompuMate) if(myOSystem.console().leftController().type() == Controller::Type::CompuMate)
myPKeyHandler->useCtrlKey() = false; myPKeyHandler->useCtrlKey() = false;
break; break;

View File

@ -759,8 +759,8 @@ void FrameBuffer::setCursorState()
bool emulation = bool emulation =
myOSystem.eventHandler().state() == EventHandlerState::EMULATION; myOSystem.eventHandler().state() == EventHandlerState::EMULATION;
bool analog = myOSystem.hasConsole() ? bool analog = myOSystem.hasConsole() ?
(myOSystem.console().controller(Controller::Left).isAnalog() || (myOSystem.console().leftController().isAnalog() ||
myOSystem.console().controller(Controller::Right).isAnalog()) : false; myOSystem.console().rightController().isAnalog()) : false;
bool alwaysUseMouse = BSPF::equalsIgnoreCase("always", myOSystem.settings().getString("usemouse")); bool alwaysUseMouse = BSPF::equalsIgnoreCase("always", myOSystem.settings().getString("usemouse"));
grabMouse(emulation && (analog || alwaysUseMouse) && myGrabMouse); grabMouse(emulation && (analog || alwaysUseMouse) && myGrabMouse);

View File

@ -20,10 +20,10 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Genesis::Genesis(Jack jack, const Event& event, const System& system) Genesis::Genesis(Jack jack, const Event& event, const System& system)
: Controller(jack, event, system, Controller::Genesis), : Controller(jack, event, system, Controller::Type::Genesis),
myControlID(-1) myControlID(-1)
{ {
if(myJack == Left) if(myJack == Jack::Left)
{ {
myUpEvent = Event::JoystickZeroUp; myUpEvent = Event::JoystickZeroUp;
myDownEvent = Event::JoystickZeroDown; myDownEvent = Event::JoystickZeroDown;
@ -42,25 +42,24 @@ Genesis::Genesis(Jack jack, const Event& event, const System& system)
myFire2Event = Event::JoystickOneFire5; myFire2Event = Event::JoystickOneFire5;
} }
updateAnalogPin(Five, MIN_RESISTANCE); setPin(AnalogPin::Five, MIN_RESISTANCE);
updateAnalogPin(Nine, MIN_RESISTANCE); setPin(AnalogPin::Nine, MIN_RESISTANCE);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Genesis::update() void Genesis::update()
{ {
// Digital events (from keyboard or joystick hats & buttons) // Digital events (from keyboard or joystick hats & buttons)
myDigitalPinState[One] = (myEvent.get(myUpEvent) == 0); setPin(DigitalPin::One, myEvent.get(myUpEvent) == 0);
myDigitalPinState[Two] = (myEvent.get(myDownEvent) == 0); setPin(DigitalPin::Two, myEvent.get(myDownEvent) == 0);
myDigitalPinState[Three] = (myEvent.get(myLeftEvent) == 0); setPin(DigitalPin::Three, myEvent.get(myLeftEvent) == 0);
myDigitalPinState[Four] = (myEvent.get(myRightEvent) == 0); setPin(DigitalPin::Four, myEvent.get(myRightEvent) == 0);
myDigitalPinState[Six] = (myEvent.get(myFire1Event) == 0); setPin(DigitalPin::Six, myEvent.get(myFire1Event) == 0);
// The Genesis has one more button (C) that can be read by the 2600 // The Genesis has one more button (C) that can be read by the 2600
// However, it seems to work opposite to the BoosterGrip controller, // However, it seems to work opposite to the BoosterGrip controller,
// in that the logic is inverted // in that the logic is inverted
updateAnalogPin( setPin(AnalogPin::Five,
Five,
(myEvent.get(myFire2Event) == 0) ? MIN_RESISTANCE : MAX_RESISTANCE (myEvent.get(myFire2Event) == 0) ? MIN_RESISTANCE : MAX_RESISTANCE
); );
@ -76,24 +75,24 @@ void Genesis::update()
if((!(abs(mousey) > abs(mousex) << 1)) && (abs(mousex) >= MJ_Threshold)) if((!(abs(mousey) > abs(mousex) << 1)) && (abs(mousex) >= MJ_Threshold))
{ {
if(mousex < 0) if(mousex < 0)
myDigitalPinState[Three] = false; setPin(DigitalPin::Three, false);
else if (mousex > 0) else if(mousex > 0)
myDigitalPinState[Four] = false; setPin(DigitalPin::Four, false);
} }
if((!(abs(mousex) > abs(mousey) << 1)) && (abs(mousey) >= MJ_Threshold)) if((!(abs(mousex) > abs(mousey) << 1)) && (abs(mousey) >= MJ_Threshold))
{ {
if(mousey < 0) if(mousey < 0)
myDigitalPinState[One] = false; setPin(DigitalPin::One, false);
else if(mousey > 0) else if(mousey > 0)
myDigitalPinState[Two] = false; setPin(DigitalPin::Two, false);
} }
} }
// Get mouse button state // Get mouse button state
if(myEvent.get(Event::MouseButtonLeftValue)) if(myEvent.get(Event::MouseButtonLeftValue))
myDigitalPinState[Six] = false; setPin(DigitalPin::Six, false);
if(myEvent.get(Event::MouseButtonRightValue)) if(myEvent.get(Event::MouseButtonRightValue))
updateAnalogPin(Five, MAX_RESISTANCE); setPin(AnalogPin::Five, MAX_RESISTANCE);
} }
} }
@ -104,10 +103,10 @@ bool Genesis::setMouseControl(
// Currently, the Genesis controller takes full control of the mouse, using // Currently, the Genesis controller takes full control of the mouse, using
// both axes for its two degrees of movement, and the left/right buttons for // both axes for its two degrees of movement, and the left/right buttons for
// 'B' and 'C', respectively // 'B' and 'C', respectively
if(xtype == Controller::Genesis && ytype == Controller::Genesis && xid == yid) if(xtype == Controller::Type::Genesis && ytype == Controller::Type::Genesis && xid == yid)
{ {
myControlID = ((myJack == Left && xid == 0) || myControlID = ((myJack == Jack::Left && xid == 0) ||
(myJack == Right && xid == 1) (myJack == Jack::Right && xid == 1)
) ? xid : -1; ) ? xid : -1;
} }
else else

View File

@ -50,6 +50,11 @@ class Genesis : public Controller
*/ */
void update() override; void update() override;
/**
Returns the name of this controller.
*/
string name() const override { return "Genesis"; }
/** /**
Determines how this controller will treat values received from the Determines how this controller will treat values received from the
X/Y axis and left/right buttons of the mouse. Since not all controllers X/Y axis and left/right buttons of the mouse. Since not all controllers

View File

@ -20,10 +20,10 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Joystick::Joystick(Jack jack, const Event& event, const System& system) Joystick::Joystick(Jack jack, const Event& event, const System& system)
: Controller(jack, event, system, Controller::Joystick), : Controller(jack, event, system, Controller::Type::Joystick),
myControlID(-1) myControlID(-1)
{ {
if(myJack == Left) if(myJack == Jack::Left)
{ {
myUpEvent = Event::JoystickZeroUp; myUpEvent = Event::JoystickZeroUp;
myDownEvent = Event::JoystickZeroDown; myDownEvent = Event::JoystickZeroDown;
@ -49,33 +49,33 @@ Joystick::Joystick(Jack jack, const Event& event, const System& system)
void Joystick::update() void Joystick::update()
{ {
// Digital events (from keyboard or joystick hats & buttons) // Digital events (from keyboard or joystick hats & buttons)
myDigitalPinState[One] = (myEvent.get(myUpEvent) == 0); setPin(DigitalPin::One, myEvent.get(myUpEvent) == 0);
myDigitalPinState[Two] = (myEvent.get(myDownEvent) == 0); setPin(DigitalPin::Two, myEvent.get(myDownEvent) == 0);
myDigitalPinState[Three] = (myEvent.get(myLeftEvent) == 0); setPin(DigitalPin::Three, myEvent.get(myLeftEvent) == 0);
myDigitalPinState[Four] = (myEvent.get(myRightEvent) == 0); setPin(DigitalPin::Four, myEvent.get(myRightEvent) == 0);
myDigitalPinState[Six] = (myEvent.get(myFireEvent) == 0); setPin(DigitalPin::Six, myEvent.get(myFireEvent) == 0);
// Axis events (usually generated by the Stelladaptor) // Axis events (usually generated by the Stelladaptor)
int xaxis = myEvent.get(myXAxisValue); int xaxis = myEvent.get(myXAxisValue);
int yaxis = myEvent.get(myYAxisValue); int yaxis = myEvent.get(myYAxisValue);
if(xaxis > 16384-4096) if(xaxis > 16384-4096)
{ {
myDigitalPinState[Four] = false; setPin(DigitalPin::Four, false);
// Stelladaptor sends "half moved right" for L+R pushed together // Stelladaptor sends "half moved right" for L+R pushed together
if(xaxis < 16384+4096) if(xaxis < 16384+4096)
myDigitalPinState[Three] = false; setPin(DigitalPin::Three, false);
} }
else if(xaxis < -16384) else if(xaxis < -16384)
myDigitalPinState[Three] = false; setPin(DigitalPin::Three, false);
if(yaxis > 16384-4096) if(yaxis > 16384-4096)
{ {
myDigitalPinState[Two] = false; setPin(DigitalPin::Two, false);
// Stelladaptor sends "half moved down" for U+D pushed together // Stelladaptor sends "half moved down" for U+D pushed together
if(yaxis < 16384+4096) if(yaxis < 16384+4096)
myDigitalPinState[One] = false; setPin(DigitalPin::One, false);
} }
else if(yaxis < -16384) else if(yaxis < -16384)
myDigitalPinState[One] = false; setPin(DigitalPin::One, false);
// Mouse motion and button events // Mouse motion and button events
if(myControlID > -1) if(myControlID > -1)
@ -89,23 +89,23 @@ void Joystick::update()
if((!(abs(mousey) > abs(mousex) << 1)) && (abs(mousex) >= MJ_Threshold)) if((!(abs(mousey) > abs(mousex) << 1)) && (abs(mousex) >= MJ_Threshold))
{ {
if(mousex < 0) if(mousex < 0)
myDigitalPinState[Three] = false; setPin(DigitalPin::Three, false);
else if (mousex > 0) else if(mousex > 0)
myDigitalPinState[Four] = false; setPin(DigitalPin::Four, false);
} }
if((!(abs(mousex) > abs(mousey) << 1)) && (abs(mousey) >= MJ_Threshold)) if((!(abs(mousex) > abs(mousey) << 1)) && (abs(mousey) >= MJ_Threshold))
{ {
if(mousey < 0) if(mousey < 0)
myDigitalPinState[One] = false; setPin(DigitalPin::One, false);
else if(mousey > 0) else if(mousey > 0)
myDigitalPinState[Two] = false; setPin(DigitalPin::Two, false);
} }
} }
// Get mouse button state // Get mouse button state
if(myEvent.get(Event::MouseButtonLeftValue) || if(myEvent.get(Event::MouseButtonLeftValue) ||
myEvent.get(Event::MouseButtonRightValue)) myEvent.get(Event::MouseButtonRightValue))
myDigitalPinState[Six] = false; setPin(DigitalPin::Six, false);
} }
} }
@ -116,10 +116,10 @@ bool Joystick::setMouseControl(
// Currently, the joystick takes full control of the mouse, using both // Currently, the joystick takes full control of the mouse, using both
// axes for its two degrees of movement, and both mouse buttons for the // axes for its two degrees of movement, and both mouse buttons for the
// single joystick button // single joystick button
if(xtype == Controller::Joystick && ytype == Controller::Joystick && xid == yid) if(xtype == Controller::Type::Joystick && ytype == Controller::Type::Joystick && xid == yid)
{ {
myControlID = ((myJack == Left && xid == 0) || myControlID = ((myJack == Jack::Left && xid == 0) ||
(myJack == Right && xid == 1) (myJack == Jack::Right && xid == 1)
) ? xid : -1; ) ? xid : -1;
} }
else else

View File

@ -47,6 +47,11 @@ class Joystick : public Controller
*/ */
void update() override; void update() override;
/**
Returns the name of this controller.
*/
string name() const override { return "Joystick"; }
/** /**
Determines how this controller will treat values received from the Determines how this controller will treat values received from the
X/Y axis and left/right buttons of the mouse. Since not all controllers X/Y axis and left/right buttons of the mouse. Since not all controllers

View File

@ -20,9 +20,9 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Keyboard::Keyboard(Jack jack, const Event& event, const System& system) Keyboard::Keyboard(Jack jack, const Event& event, const System& system)
: Controller(jack, event, system, Controller::Keyboard) : Controller(jack, event, system, Controller::Type::Keyboard)
{ {
if(myJack == Left) if(myJack == Jack::Left)
{ {
myOneEvent = Event::KeyboardZero1; myOneEvent = Event::KeyboardZero1;
myTwoEvent = Event::KeyboardZero2; myTwoEvent = Event::KeyboardZero2;
@ -57,43 +57,41 @@ Keyboard::Keyboard(Jack jack, const Event& event, const System& system)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Keyboard::write(DigitalPin pin, bool value) void Keyboard::write(DigitalPin pin, bool value)
{ {
myDigitalPinState[pin] = value; setPin(pin, value);
// Set defaults // Set defaults
myDigitalPinState[Six] = true; setPin(DigitalPin::Six, true);
Int32 resistanceFive = MIN_RESISTANCE; Int32 resistanceFive = MIN_RESISTANCE;
Int32 resistanceNine = MIN_RESISTANCE; Int32 resistanceNine = MIN_RESISTANCE;
// Now scan the rows and columns // Now scan the rows and columns
if(!myDigitalPinState[Four]) if(!getPin(DigitalPin::Four))
{ {
myDigitalPinState[Six] = (myEvent.get(myPoundEvent) == 0); setPin(DigitalPin::Six, myEvent.get(myPoundEvent) == 0);
if(myEvent.get(myZeroEvent) != 0) resistanceFive = MAX_RESISTANCE; if(myEvent.get(myZeroEvent) != 0) resistanceFive = MAX_RESISTANCE;
if(myEvent.get(myStarEvent) != 0) resistanceNine = MAX_RESISTANCE; if(myEvent.get(myStarEvent) != 0) resistanceNine = MAX_RESISTANCE;
} }
if(!myDigitalPinState[Three]) if(!getPin(DigitalPin::Three))
{ {
myDigitalPinState[Six] = (myEvent.get(myNineEvent) == 0); setPin(DigitalPin::Six, myEvent.get(myNineEvent) == 0);
if(myEvent.get(myEightEvent) != 0) resistanceFive = MAX_RESISTANCE; if(myEvent.get(myEightEvent) != 0) resistanceFive = MAX_RESISTANCE;
if(myEvent.get(mySevenEvent) != 0) resistanceNine = MAX_RESISTANCE; if(myEvent.get(mySevenEvent) != 0) resistanceNine = MAX_RESISTANCE;
} }
if(!myDigitalPinState[Two]) if(!getPin(DigitalPin::Two))
{ {
myDigitalPinState[Six] = (myEvent.get(mySixEvent) == 0); setPin(DigitalPin::Six, myEvent.get(mySixEvent) == 0);
if(myEvent.get(myFiveEvent) != 0) resistanceFive = MAX_RESISTANCE; if(myEvent.get(myFiveEvent) != 0) resistanceFive = MAX_RESISTANCE;
if(myEvent.get(myFourEvent) != 0) resistanceNine = MAX_RESISTANCE; if(myEvent.get(myFourEvent) != 0) resistanceNine = MAX_RESISTANCE;
} }
if(!myDigitalPinState[One]) if(!getPin(DigitalPin::One))
{ {
myDigitalPinState[Six] = (myEvent.get(myThreeEvent) == 0); setPin(DigitalPin::Six, myEvent.get(myThreeEvent) == 0);
if(myEvent.get(myTwoEvent) != 0) resistanceFive = MAX_RESISTANCE; if(myEvent.get(myTwoEvent) != 0) resistanceFive = MAX_RESISTANCE;
if(myEvent.get(myOneEvent) != 0) resistanceNine = MAX_RESISTANCE; if(myEvent.get(myOneEvent) != 0) resistanceNine = MAX_RESISTANCE;
} }
if (resistanceFive != read(Five)) { if(resistanceFive != read(AnalogPin::Five))
updateAnalogPin(Five, resistanceFive); setPin(AnalogPin::Five, resistanceFive);
} if(resistanceNine != read(AnalogPin::Nine))
setPin(AnalogPin::Nine, resistanceNine);
if (resistanceNine != read(Nine))
updateAnalogPin(Nine, resistanceNine);
} }

View File

@ -57,6 +57,11 @@ class Keyboard : public Controller
*/ */
void update() override { } void update() override { }
/**
Returns the name of this controller.
*/
string name() const override { return "Keyboard"; }
private: private:
// Pre-compute the events we care about based on given port // Pre-compute the events we care about based on given port
// This will eliminate test for left or right port in update() // This will eliminate test for left or right port in update()

View File

@ -23,8 +23,8 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
KidVid::KidVid(Jack jack, const Event& event, const System& system, KidVid::KidVid(Jack jack, const Event& event, const System& system,
const string& rommd5) const string& rommd5)
: Controller(jack, event, system, Controller::KidVid), : Controller(jack, event, system, Controller::Type::KidVid),
myEnabled(myJack == Right), myEnabled(myJack == Jack::Right),
// mySampleFile(nullptr), // mySampleFile(nullptr),
// mySharedSampleFile(nullptr), // mySharedSampleFile(nullptr),
myFileOpened(false), myFileOpened(false),
@ -104,16 +104,16 @@ cerr << "myTape = " << myTape << endl;
} }
// Convert separate pin states into a 'register' // Convert separate pin states into a 'register'
uInt8 IOPortA = 0xf0; uInt8 IOPortA = 0b11110000;
if(myDigitalPinState[One]) IOPortA |= 0x01; if(getPin(DigitalPin::One)) IOPortA |= 0b0001;
if(myDigitalPinState[Two]) IOPortA |= 0x02; if(getPin(DigitalPin::Two)) IOPortA |= 0b0010;
if(myDigitalPinState[Three]) IOPortA |= 0x04; if(getPin(DigitalPin::Three)) IOPortA |= 0b0100;
if(myDigitalPinState[Four]) IOPortA |= 0x08; if(getPin(DigitalPin::Four)) IOPortA |= 0b1000;
// Is the tape running? // Is the tape running?
if((myTape != 0) && ((IOPortA & 0x01) == 0x01) && !myTapeBusy) if((myTape != 0) && ((IOPortA & 0b0001) == 0b0001) && !myTapeBusy)
{ {
IOPortA = (IOPortA & 0xf7) | (((ourKVData[myIdx >> 3] << (myIdx & 0x07)) & 0x80) >> 4); IOPortA = (IOPortA & 0b11110111) | (((ourKVData[myIdx >> 3] << (myIdx & 0x07)) & 0x80) >> 4);
// increase to next bit // increase to next bit
++myIdx; ++myIdx;
@ -153,10 +153,10 @@ cerr << "myTape = " << myTape << endl;
} }
// Now convert the register back into separate boolean values // Now convert the register back into separate boolean values
myDigitalPinState[One] = IOPortA & 0x01; setPin(DigitalPin::One, IOPortA & 0b0001);
myDigitalPinState[Two] = IOPortA & 0x02; setPin(DigitalPin::Two, IOPortA & 0b0010);
myDigitalPinState[Three] = IOPortA & 0x04; setPin(DigitalPin::Three, IOPortA & 0b0100);
myDigitalPinState[Four] = IOPortA & 0x08; setPin(DigitalPin::Four, IOPortA & 0b1000);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -58,6 +58,11 @@ class KidVid : public Controller
*/ */
void update() override; void update() override;
/**
Returns the name of this controller.
*/
string name() const override { return "KidVid"; }
private: private:
// Open/close a WAV sample file // Open/close a WAV sample file
void openSampleFile(); void openSampleFile();

View File

@ -101,7 +101,7 @@ void M6532::update()
Controller& port1 = myConsole.rightController(); Controller& port1 = myConsole.rightController();
// Get current PA7 state // Get current PA7 state
bool prevPA7 = port0.myDigitalPinState[Controller::Four]; bool prevPA7 = port0.getPin(Controller::DigitalPin::Four);
// Update entire port state // Update entire port state
port0.update(); port0.update();
@ -109,7 +109,7 @@ void M6532::update()
myConsole.switches().update(); myConsole.switches().update();
// Get new PA7 state // Get new PA7 state
bool currPA7 = port0.myDigitalPinState[Controller::Four]; bool currPA7 = port0.getPin(Controller::DigitalPin::Four);
// PA7 Flag is set on active transition in appropriate direction // PA7 Flag is set on active transition in appropriate direction
if((!myEdgeDetectPositive && prevPA7 && !currPA7) || if((!myEdgeDetectPositive && prevPA7 && !currPA7) ||
@ -347,14 +347,14 @@ void M6532::setPinState(bool swcha)
uInt8 ioport = myOutA | ~myDDRA; uInt8 ioport = myOutA | ~myDDRA;
port0.write(Controller::One, ioport & 0x10); port0.write(Controller::DigitalPin::One, ioport & 0b00010000);
port0.write(Controller::Two, ioport & 0x20); port0.write(Controller::DigitalPin::Two, ioport & 0b00100000);
port0.write(Controller::Three, ioport & 0x40); port0.write(Controller::DigitalPin::Three, ioport & 0b01000000);
port0.write(Controller::Four, ioport & 0x80); port0.write(Controller::DigitalPin::Four, ioport & 0b10000000);
port1.write(Controller::One, ioport & 0x01); port1.write(Controller::DigitalPin::One, ioport & 0b00000001);
port1.write(Controller::Two, ioport & 0x02); port1.write(Controller::DigitalPin::Two, ioport & 0b00000010);
port1.write(Controller::Three, ioport & 0x04); port1.write(Controller::DigitalPin::Three, ioport & 0b00000100);
port1.write(Controller::Four, ioport & 0x08); port1.write(Controller::DigitalPin::Four, ioport & 0b00001000);
if(swcha) if(swcha)
{ {

View File

@ -20,24 +20,24 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
MindLink::MindLink(Jack jack, const Event& event, const System& system) MindLink::MindLink(Jack jack, const Event& event, const System& system)
: Controller(jack, event, system, Controller::MindLink), : Controller(jack, event, system, Controller::Type::MindLink),
myMindlinkPos(0x2800), myMindlinkPos(0x2800),
myMindlinkShift(1), myMindlinkShift(1),
myMouseEnabled(false) myMouseEnabled(false)
{ {
myDigitalPinState[One] = true; setPin(DigitalPin::One, true);
myDigitalPinState[Two] = true; setPin(DigitalPin::Two, true);
myDigitalPinState[Three] = true; setPin(DigitalPin::Three, true);
myDigitalPinState[Four] = true; setPin(DigitalPin::Four, true);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void MindLink::update() void MindLink::update()
{ {
myDigitalPinState[One] = setPin(DigitalPin::One, true);
myDigitalPinState[Two] = setPin(DigitalPin::Two, true);
myDigitalPinState[Three] = setPin(DigitalPin::Three, true);
myDigitalPinState[Four] = true; setPin(DigitalPin::Four, true);
if(!myMouseEnabled) if(!myMouseEnabled)
return; return;
@ -60,12 +60,12 @@ void MindLink::update()
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void MindLink::nextMindlinkBit() void MindLink::nextMindlinkBit()
{ {
if(myDigitalPinState[One]) if(getPin(DigitalPin::One))
{ {
myDigitalPinState[Three] = false; setPin(DigitalPin::Three, false);
myDigitalPinState[Four] = false; setPin(DigitalPin::Four, false);
if(myMindlinkPos & myMindlinkShift) if(myMindlinkPos & myMindlinkShift)
myDigitalPinState[Four] = true; setPin(DigitalPin::Four, true);
myMindlinkShift <<= 1; myMindlinkShift <<= 1;
} }
} }

View File

@ -59,7 +59,7 @@ class MindLink : public Controller
@param pin The pin of the controller jack to write to @param pin The pin of the controller jack to write to
@param value The value to write to the pin @param value The value to write to the pin
*/ */
void write(DigitalPin pin, bool value) override { myDigitalPinState[pin] = value; } void write(DigitalPin pin, bool value) override { setPin(pin, value); }
/** /**
Called after *all* digital pins have been written on Port A. Called after *all* digital pins have been written on Port A.
@ -72,6 +72,11 @@ class MindLink : public Controller
*/ */
void update() override; void update() override;
/**
Returns the name of this controller.
*/
string name() const override { return "MindLink"; }
/** /**
Answers whether the controller is intrinsically an analog controller. Answers whether the controller is intrinsically an analog controller.
*/ */

View File

@ -21,15 +21,15 @@
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Paddles::Paddles(Jack jack, const Event& event, const System& system, Paddles::Paddles(Jack jack, const Event& event, const System& system,
bool swappaddle, bool swapaxis, bool swapdir) bool swappaddle, bool swapaxis, bool swapdir)
: Controller(jack, event, system, Controller::Paddles), : Controller(jack, event, system, Controller::Type::Paddles),
myMPaddleID(-1), myMPaddleID(-1),
myMPaddleIDX(-1), myMPaddleIDX(-1),
myMPaddleIDY(-1) myMPaddleIDY(-1)
{ {
// We must start with minimum resistance; see commit // We must start with minimum resistance; see commit
// 38b452e1a047a0dca38c5bcce7c271d40f76736e for more information // 38b452e1a047a0dca38c5bcce7c271d40f76736e for more information
updateAnalogPin(Five, MIN_RESISTANCE); setPin(AnalogPin::Five, MIN_RESISTANCE);
updateAnalogPin(Nine, MIN_RESISTANCE); setPin(AnalogPin::Nine, MIN_RESISTANCE);
// The following logic reflects that mapping paddles to different // The following logic reflects that mapping paddles to different
// devices can be extremely complex // devices can be extremely complex
@ -46,7 +46,7 @@ Paddles::Paddles(Jack jack, const Event& event, const System& system,
// a given port; this will speed up processing in update() // a given port; this will speed up processing in update()
// Consider whether this is the left or right port // Consider whether this is the left or right port
if(myJack == Left) if(myJack == Jack::Left)
{ {
if(!swappaddle) // First paddle is 0, second is 1 if(!swappaddle) // First paddle is 0, second is 1
{ {
@ -215,9 +215,9 @@ Paddles::Paddles(Jack jack, const Event& event, const System& system,
} }
// Digital pins 1, 2 and 6 are not connected // Digital pins 1, 2 and 6 are not connected
myDigitalPinState[One] = setPin(DigitalPin::One, true);
myDigitalPinState[Two] = setPin(DigitalPin::Two, true);
myDigitalPinState[Six] = true; setPin(DigitalPin::Six, true);
// Digital emulation of analog paddle movement // Digital emulation of analog paddle movement
myKeyRepeat0 = myKeyRepeat1 = false; myKeyRepeat0 = myKeyRepeat1 = false;
@ -230,13 +230,14 @@ Paddles::Paddles(Jack jack, const Event& event, const System& system,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Paddles::update() void Paddles::update()
{ {
myDigitalPinState[Three] = myDigitalPinState[Four] = true; setPin(DigitalPin::Three, true);
setPin(DigitalPin::Four, true);
// Digital events (from keyboard or joystick hats & buttons) // Digital events (from keyboard or joystick hats & buttons)
myDigitalPinState[Three] = setPin(DigitalPin::Three,
(myEvent.get(myP1FireEvent1) == 0 && myEvent.get(myP1FireEvent2) == 0); myEvent.get(myP1FireEvent1) == 0 && myEvent.get(myP1FireEvent2) == 0);
myDigitalPinState[Four] = setPin(DigitalPin::Four,
(myEvent.get(myP0FireEvent1) == 0 && myEvent.get(myP0FireEvent2) == 0); myEvent.get(myP0FireEvent1) == 0 && myEvent.get(myP0FireEvent2) == 0);
// Paddle movement is a very difficult thing to accurately emulate, // Paddle movement is a very difficult thing to accurately emulate,
// since it originally came from an analog device that had very // since it originally came from an analog device that had very
@ -261,12 +262,12 @@ void Paddles::update()
int sa_yaxis = myEvent.get(myP1AxisValue); int sa_yaxis = myEvent.get(myP1AxisValue);
if(abs(myLastAxisX - sa_xaxis) > 10) if(abs(myLastAxisX - sa_xaxis) > 10)
{ {
updateAnalogPin(Nine, Int32(MAX_RESISTANCE * ((32767 - Int16(sa_xaxis)) / 65536.0))); setPin(AnalogPin::Nine, Int32(MAX_RESISTANCE * ((32767 - Int16(sa_xaxis)) / 65536.0)));
sa_changed = true; sa_changed = true;
} }
if(abs(myLastAxisY - sa_yaxis) > 10) if(abs(myLastAxisY - sa_yaxis) > 10)
{ {
updateAnalogPin(Five, Int32(MAX_RESISTANCE * ((32767 - Int16(sa_yaxis)) / 65536.0))); setPin(AnalogPin::Five, Int32(MAX_RESISTANCE * ((32767 - Int16(sa_yaxis)) / 65536.0)));
sa_changed = true; sa_changed = true;
} }
myLastAxisX = sa_xaxis; myLastAxisX = sa_xaxis;
@ -284,7 +285,7 @@ void Paddles::update()
TRIGMIN, TRIGRANGE); TRIGMIN, TRIGRANGE);
if(myEvent.get(Event::MouseButtonLeftValue) || if(myEvent.get(Event::MouseButtonLeftValue) ||
myEvent.get(Event::MouseButtonRightValue)) myEvent.get(Event::MouseButtonRightValue))
myDigitalPinState[ourButtonPin[myMPaddleID]] = false; setPin(ourButtonPin[myMPaddleID], false);
} }
else else
{ {
@ -296,7 +297,7 @@ void Paddles::update()
(myEvent.get(Event::MouseAxisXValue) * MOUSE_SENSITIVITY), (myEvent.get(Event::MouseAxisXValue) * MOUSE_SENSITIVITY),
TRIGMIN, TRIGRANGE); TRIGMIN, TRIGRANGE);
if(myEvent.get(Event::MouseButtonLeftValue)) if(myEvent.get(Event::MouseButtonLeftValue))
myDigitalPinState[ourButtonPin[myMPaddleIDX]] = false; setPin(ourButtonPin[myMPaddleIDX], false);
} }
if(myMPaddleIDY > -1) if(myMPaddleIDY > -1)
{ {
@ -304,7 +305,7 @@ void Paddles::update()
(myEvent.get(Event::MouseAxisYValue) * MOUSE_SENSITIVITY), (myEvent.get(Event::MouseAxisYValue) * MOUSE_SENSITIVITY),
TRIGMIN, TRIGRANGE); TRIGMIN, TRIGRANGE);
if(myEvent.get(Event::MouseButtonRightValue)) if(myEvent.get(Event::MouseButtonRightValue))
myDigitalPinState[ourButtonPin[myMPaddleIDY]] = false; setPin(ourButtonPin[myMPaddleIDY], false);
} }
} }
@ -353,9 +354,9 @@ void Paddles::update()
// Only change state if the charge has actually changed // Only change state if the charge has actually changed
if(myCharge[1] != myLastCharge[1]) if(myCharge[1] != myLastCharge[1])
updateAnalogPin(Five, Int32(MAX_RESISTANCE * (myCharge[1] / float(TRIGMAX)))); setPin(AnalogPin::Five, Int32(MAX_RESISTANCE * (myCharge[1] / float(TRIGMAX))));
if(myCharge[0] != myLastCharge[0]) if(myCharge[0] != myLastCharge[0])
updateAnalogPin(Nine, Int32(MAX_RESISTANCE * (myCharge[0] / float(TRIGMAX)))); setPin(AnalogPin::Nine, Int32(MAX_RESISTANCE * (myCharge[0] / float(TRIGMAX))));
myLastCharge[1] = myCharge[1]; myLastCharge[1] = myCharge[1];
myLastCharge[0] = myCharge[0]; myLastCharge[0] = myCharge[0];
@ -368,10 +369,10 @@ bool Paddles::setMouseControl(
// In 'automatic' mode, both axes on the mouse map to a single paddle, // In 'automatic' mode, both axes on the mouse map to a single paddle,
// and the paddle axis and direction settings are taken into account // and the paddle axis and direction settings are taken into account
// This overrides any other mode // This overrides any other mode
if(xtype == Controller::Paddles && ytype == Controller::Paddles && xid == yid) if(xtype == Controller::Type::Paddles && ytype == Controller::Type::Paddles && xid == yid)
{ {
myMPaddleID = ((myJack == Left && (xid == 0 || xid == 1)) || myMPaddleID = ((myJack == Jack::Left && (xid == 0 || xid == 1)) ||
(myJack == Right && (xid == 2 || xid == 3)) (myJack == Jack::Right && (xid == 2 || xid == 3))
) ? xid & 0x01 : -1; ) ? xid & 0x01 : -1;
myMPaddleIDX = myMPaddleIDY = -1; myMPaddleIDX = myMPaddleIDY = -1;
} }
@ -380,12 +381,12 @@ bool Paddles::setMouseControl(
// The following is somewhat complex, but we need to pre-process as much // The following is somewhat complex, but we need to pre-process as much
// as possible, so that ::update() can run quickly // as possible, so that ::update() can run quickly
myMPaddleID = -1; myMPaddleID = -1;
if(myJack == Left && xtype == Controller::Paddles) if(myJack == Jack::Left && xtype == Controller::Type::Paddles)
{ {
myMPaddleIDX = (xid == 0 || xid == 1) ? xid & 0x01 : -1; myMPaddleIDX = (xid == 0 || xid == 1) ? xid & 0x01 : -1;
myMPaddleIDY = (yid == 0 || yid == 1) ? yid & 0x01 : -1; myMPaddleIDY = (yid == 0 || yid == 1) ? yid & 0x01 : -1;
} }
else if(myJack == Right && ytype == Controller::Paddles) else if(myJack == Jack::Right && ytype == Controller::Type::Paddles)
{ {
myMPaddleIDX = (xid == 2 || xid == 3) ? xid & 0x01 : -1; myMPaddleIDX = (xid == 2 || xid == 3) ? xid & 0x01 : -1;
myMPaddleIDY = (yid == 2 || yid == 3) ? yid & 0x01 : -1; myMPaddleIDY = (yid == 2 || yid == 3) ? yid & 0x01 : -1;
@ -422,4 +423,6 @@ int Paddles::DIGITAL_DISTANCE = -1;
int Paddles::MOUSE_SENSITIVITY = -1; int Paddles::MOUSE_SENSITIVITY = -1;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
const Controller::DigitalPin Paddles::ourButtonPin[2] = { Four, Three }; const Controller::DigitalPin Paddles::ourButtonPin[2] = {
DigitalPin::Four, DigitalPin::Three
};

View File

@ -54,6 +54,11 @@ class Paddles : public Controller
*/ */
void update() override; void update() override;
/**
Returns the name of this controller.
*/
string name() const override { return "Paddles"; }
/** /**
Answers whether the controller is intrinsically an analog controller. Answers whether the controller is intrinsically an analog controller.
*/ */

View File

@ -71,10 +71,10 @@ uInt8 PointingDevice::read()
uInt8 portA = ioPortA(myCountH, myCountV, myTrackBallLeft, myTrackBallDown); uInt8 portA = ioPortA(myCountH, myCountV, myTrackBallLeft, myTrackBallDown);
myDigitalPinState[One] = portA & 0b0001; setPin(DigitalPin::One, portA & 0b0001);
myDigitalPinState[Two] = portA & 0b0010; setPin(DigitalPin::Two, portA & 0b0010);
myDigitalPinState[Three] = portA & 0b0100; setPin(DigitalPin::Three, portA & 0b0100);
myDigitalPinState[Four] = portA & 0b1000; setPin(DigitalPin::Four, portA & 0b1000);
return portA; return portA;
} }
@ -94,8 +94,8 @@ void PointingDevice::update()
myTrackBallDown, myTrackBallLinesV, myScanCountV, myFirstScanOffsetV); myTrackBallDown, myTrackBallLinesV, myScanCountV, myFirstScanOffsetV);
// Get mouse button state // Get mouse button state
myDigitalPinState[Six] = (myEvent.get(Event::MouseButtonLeftValue) == 0) && setPin(DigitalPin::Six, (myEvent.get(Event::MouseButtonLeftValue) == 0) &&
(myEvent.get(Event::MouseButtonRightValue) == 0); (myEvent.get(Event::MouseButtonRightValue) == 0));
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -95,6 +95,8 @@ class PointingDevice : public Controller
// IOPortA values are calculated // IOPortA values are calculated
virtual uInt8 ioPortA(uInt8 countH, uInt8 countV, uInt8 left, uInt8 down) = 0; virtual uInt8 ioPortA(uInt8 countH, uInt8 countV, uInt8 left, uInt8 down) = 0;
// virtual string pointingDeviceName() const = 0;
private: private:
void updateDirection(int counter, float& counterRemainder, void updateDirection(int counter, float& counterRemainder,
bool& trackBallDir, int& trackBallLines, bool& trackBallDir, int& trackBallLines,

View File

@ -127,8 +127,8 @@ bool ProfilingRunner::runOne(const ProfilingRun run)
TIA tia(consoleIO, []() { return ConsoleTiming::ntsc; }, mySettings); TIA tia(consoleIO, []() { return ConsoleTiming::ntsc; }, mySettings);
System system(rng, cpu, riot, tia, *cartridge); System system(rng, cpu, riot, tia, *cartridge);
consoleIO.myLeftControl = make_unique<Joystick>(Controller::Left, event, system); consoleIO.myLeftControl = make_unique<Joystick>(Controller::Jack::Left, event, system);
consoleIO.myRightControl = make_unique<Joystick>(Controller::Right, event, system); consoleIO.myRightControl = make_unique<Joystick>(Controller::Jack::Right, event, system);
consoleIO.mySwitches = make_unique<Switches>(event, myProps, mySettings); consoleIO.mySwitches = make_unique<Switches>(event, myProps, mySettings);
tia.bindToControllers(); tia.bindToControllers();

View File

@ -27,13 +27,14 @@ SaveKey::SaveKey(Jack jack, const Event& event, const System& system,
{ {
myEEPROM = make_unique<MT24LC256>(eepromfile, system, callback); myEEPROM = make_unique<MT24LC256>(eepromfile, system, callback);
myDigitalPinState[One] = myDigitalPinState[Two] = true; setPin(DigitalPin::One, true);
setPin(DigitalPin::Two, true);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
SaveKey::SaveKey(Jack jack, const Event& event, const System& system, SaveKey::SaveKey(Jack jack, const Event& event, const System& system,
const string& eepromfile, onMessageCallback callback) const string& eepromfile, onMessageCallback callback)
: SaveKey(jack, event, system, eepromfile, callback, Controller::SaveKey) : SaveKey(jack, event, system, eepromfile, callback, Controller::Type::SaveKey)
{ {
} }
@ -52,8 +53,8 @@ bool SaveKey::read(DigitalPin pin)
{ {
// Pin 3: EEPROM SDA // Pin 3: EEPROM SDA
// input data from the 24LC256 EEPROM using the I2C protocol // input data from the 24LC256 EEPROM using the I2C protocol
case Three: case DigitalPin::Three:
return myDigitalPinState[Three] = myEEPROM->readSDA(); return setPin(pin, myEEPROM->readSDA());
default: default:
return Controller::read(pin); return Controller::read(pin);
@ -68,15 +69,15 @@ void SaveKey::write(DigitalPin pin, bool value)
{ {
// Pin 3: EEPROM SDA // Pin 3: EEPROM SDA
// output data to the 24LC256 EEPROM using the I2C protocol // output data to the 24LC256 EEPROM using the I2C protocol
case Three: case DigitalPin::Three:
myDigitalPinState[Three] = value; setPin(pin, value);
myEEPROM->writeSDA(value); myEEPROM->writeSDA(value);
break; break;
// Pin 4: EEPROM SCL // Pin 4: EEPROM SCL
// output clock data to the 24LC256 EEPROM using the I2C protocol // output clock data to the 24LC256 EEPROM using the I2C protocol
case Four: case DigitalPin::Four:
myDigitalPinState[Four] = value; setPin(pin, value);
myEEPROM->writeSCL(value); myEEPROM->writeSCL(value);
break; break;

View File

@ -83,6 +83,11 @@ class SaveKey : public Controller
*/ */
void update() override { } void update() override { }
/**
Returns the name of this controller.
*/
string name() const override { return "SaveKey"; }
/** /**
Notification method invoked by the system after its reset method has Notification method invoked by the system after its reset method has
been called. It may be necessary to override this method for been called. It may be necessary to override this method for

View File

@ -31,10 +31,15 @@ class TrakBall : public PointingDevice
@param system The system using this controller @param system The system using this controller
*/ */
TrakBall(Jack jack, const Event& event, const System& system) TrakBall(Jack jack, const Event& event, const System& system)
: PointingDevice(jack, event, system, Controller::TrakBall, : PointingDevice(jack, event, system, Controller::Type::TrakBall,
trackballSensitivity) { } trackballSensitivity) { }
virtual ~TrakBall() = default; virtual ~TrakBall() = default;
/**
Returns the name of this controller.
*/
string name() const override { return "TrakBall"; }
protected: protected:
uInt8 ioPortA(uInt8 countH, uInt8 countV, uInt8 left, uInt8 down) override uInt8 ioPortA(uInt8 countH, uInt8 countV, uInt8 left, uInt8 down) override
{ {

View File

@ -515,13 +515,13 @@ uInt8 TIA::peek(uInt16 address)
case INPT4: case INPT4:
result = result =
myInput0.inpt(!myConsole.leftController().read(Controller::Six)) | myInput0.inpt(!myConsole.leftController().read(Controller::DigitalPin::Six)) |
(lastDataBusValue & 0x40); (lastDataBusValue & 0x40);
break; break;
case INPT5: case INPT5:
result = result =
myInput1.inpt(!myConsole.rightController().read(Controller::Six)) | myInput1.inpt(!myConsole.rightController().read(Controller::DigitalPin::Six)) |
(lastDataBusValue & 0x40); (lastDataBusValue & 0x40);
break; break;
@ -1673,19 +1673,19 @@ void TIA::updatePaddle(uInt8 idx)
Int32 resistance; Int32 resistance;
switch (idx) { switch (idx) {
case 0: case 0:
resistance = myConsole.leftController().read(Controller::Nine); resistance = myConsole.leftController().read(Controller::AnalogPin::Nine);
break; break;
case 1: case 1:
resistance = myConsole.leftController().read(Controller::Five); resistance = myConsole.leftController().read(Controller::AnalogPin::Five);
break; break;
case 2: case 2:
resistance = myConsole.rightController().read(Controller::Nine); resistance = myConsole.rightController().read(Controller::AnalogPin::Nine);
break; break;
case 3: case 3:
resistance = myConsole.rightController().read(Controller::Five); resistance = myConsole.rightController().read(Controller::AnalogPin::Five);
break; break;
default: default:

View File

@ -620,10 +620,10 @@ void GameInfoDialog::updateControllerStates()
const Controller& rport = instance().console().rightController(); const Controller& rport = instance().console().rightController();
// we only enable the button if we have a valid previous and new controller. // we only enable the button if we have a valid previous and new controller.
enableEEEraseButton = ((lport.type() == Controller::SaveKey && contrLeft == "SAVEKEY") || enableEEEraseButton = ((lport.type() == Controller::Type::SaveKey && contrLeft == "SAVEKEY") ||
(rport.type() == Controller::SaveKey && contrRight == "SAVEKEY") || (rport.type() == Controller::Type::SaveKey && contrRight == "SAVEKEY") ||
(lport.type() == Controller::AtariVox && contrLeft == "ATARIVOX") || (lport.type() == Controller::Type::AtariVox && contrLeft == "ATARIVOX") ||
(rport.type() == Controller::AtariVox && contrRight == "ATARIVOX")); (rport.type() == Controller::Type::AtariVox && contrRight == "ATARIVOX"));
} }
myLeftPortLabel->setEnabled(enableSelectControl); myLeftPortLabel->setEnabled(enableSelectControl);
@ -645,13 +645,13 @@ void GameInfoDialog::eraseEEPROM()
Controller& lport = instance().console().leftController(); Controller& lport = instance().console().leftController();
Controller& rport = instance().console().rightController(); Controller& rport = instance().console().rightController();
if(lport.type() == Controller::SaveKey || lport.type() == Controller::AtariVox) if(lport.type() == Controller::Type::SaveKey || lport.type() == Controller::Type::AtariVox)
{ {
SaveKey& skey = static_cast<SaveKey&>(lport); SaveKey& skey = static_cast<SaveKey&>(lport);
skey.eraseCurrent(); skey.eraseCurrent();
} }
if(rport.type() == Controller::SaveKey || rport.type() == Controller::AtariVox) if(rport.type() == Controller::Type::SaveKey || rport.type() == Controller::Type::AtariVox)
{ {
SaveKey& skey = static_cast<SaveKey&>(rport); SaveKey& skey = static_cast<SaveKey&>(rport);
skey.eraseCurrent(); skey.eraseCurrent();

View File

@ -282,8 +282,8 @@ void InputDialog::loadConfig()
Controller& lport = instance().console().leftController(); Controller& lport = instance().console().leftController();
Controller& rport = instance().console().rightController(); Controller& rport = instance().console().rightController();
myEraseEEPROMButton->setEnabled(lport.type() == Controller::SaveKey || lport.type() == Controller::AtariVox || myEraseEEPROMButton->setEnabled(lport.type() == Controller::Type::SaveKey || lport.type() == Controller::Type::AtariVox ||
rport.type() == Controller::SaveKey || rport.type() == Controller::AtariVox); rport.type() == Controller::Type::SaveKey || rport.type() == Controller::Type::AtariVox);
} }
else else
myEraseEEPROMButton->setEnabled(false); myEraseEEPROMButton->setEnabled(false);
@ -459,13 +459,13 @@ void InputDialog::eraseEEPROM()
Controller& lport = instance().console().leftController(); Controller& lport = instance().console().leftController();
Controller& rport = instance().console().rightController(); Controller& rport = instance().console().rightController();
if(lport.type() == Controller::SaveKey || lport.type() == Controller::AtariVox) if(lport.type() == Controller::Type::SaveKey || lport.type() == Controller::Type::AtariVox)
{ {
SaveKey& skey = static_cast<SaveKey&>(lport); SaveKey& skey = static_cast<SaveKey&>(lport);
skey.eraseCurrent(); skey.eraseCurrent();
} }
if(rport.type() == Controller::SaveKey || rport.type() == Controller::AtariVox) if(rport.type() == Controller::Type::SaveKey || rport.type() == Controller::Type::AtariVox)
{ {
SaveKey& skey = static_cast<SaveKey&>(rport); SaveKey& skey = static_cast<SaveKey&>(rport);
skey.eraseCurrent(); skey.eraseCurrent();