refactor CompuMate key handling (uses events now too)

This commit is contained in:
thrust26 2019-06-16 19:52:14 +02:00
parent 802b5a33bc
commit c20035ccce
8 changed files with 178 additions and 194 deletions

View File

@ -46,8 +46,10 @@ PhysicalKeyboardHandler::PhysicalKeyboardHandler(
OSystem& system, EventHandler& handler, Event& event) OSystem& system, EventHandler& handler, Event& event)
: myOSystem(system), : myOSystem(system),
myHandler(handler), myHandler(handler),
myEvent(event), #ifdef BSPF_UNIX
myAltKeyCounter(0) myAltKeyCounter(0),
#endif
myEvent(event)
{ {
Int32 version = myOSystem.settings().getInt("event_ver"); Int32 version = myOSystem.settings().getInt("event_ver");
@ -120,6 +122,8 @@ void PhysicalKeyboardHandler::setDefaultMapping(Event::Type event, EventMode mod
setDefaultKey(item, event, kPaddlesMode, updateDefaults); setDefaultKey(item, event, kPaddlesMode, updateDefaults);
for (const auto& item: DefaultKeypadMapping) for (const auto& item: DefaultKeypadMapping)
setDefaultKey(item, event, kKeypadMode, updateDefaults); setDefaultKey(item, event, kKeypadMode, updateDefaults);
for (const auto& item : CompuMateMapping)
setDefaultKey(item, event, kCompuMateMode, updateDefaults);
break; break;
case kMenuMode: case kMenuMode:
@ -150,6 +154,10 @@ void PhysicalKeyboardHandler::defineControllerMappings(const string& controllerN
else else
myRightMode = kPaddlesMode; myRightMode = kPaddlesMode;
} }
else if (controllerName == "CM")
{
myLeftMode = myRightMode = kCompuMateMode;
}
else else
{ {
if (port == Controller::Jack::Left) if (port == Controller::Jack::Left)
@ -177,6 +185,11 @@ void PhysicalKeyboardHandler::enableEmulationMappings()
enableMappings(RightKeypadEvents, kKeypadMode); enableMappings(RightKeypadEvents, kKeypadMode);
break; break;
case kCompuMateMode:
// see below
break;
default: default:
enableMappings(RightJoystickEvents, kJoystickMode); enableMappings(RightJoystickEvents, kJoystickMode);
break; break;
@ -192,6 +205,11 @@ void PhysicalKeyboardHandler::enableEmulationMappings()
enableMappings(LeftKeypadEvents, kKeypadMode); enableMappings(LeftKeypadEvents, kKeypadMode);
break; break;
case kCompuMateMode:
for (const auto& item : CompuMateMapping)
enableMapping(item.event, kCompuMateMode);
break;
default: default:
enableMappings(LeftJoystickEvents, kJoystickMode); enableMappings(LeftJoystickEvents, kJoystickMode);
break; break;
@ -316,24 +334,21 @@ bool PhysicalKeyboardHandler::addMapping(Event::Type event, EventMode mode,
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void PhysicalKeyboardHandler::handleEvent(StellaKey key, StellaMod mod, bool pressed, bool repeated) void PhysicalKeyboardHandler::handleEvent(StellaKey key, StellaMod mod, bool pressed, bool repeated)
{ {
#ifdef BSPF_UNIX
// Swallow KBDK_TAB under certain conditions // Swallow KBDK_TAB under certain conditions
// See commments on 'myAltKeyCounter' for more information // See commments on 'myAltKeyCounter' for more information
#ifdef BSPF_UNIX
if(myAltKeyCounter > 1 && key == KBDK_TAB) if(myAltKeyCounter > 1 && key == KBDK_TAB)
{ {
myAltKeyCounter = 0; myAltKeyCounter = 0;
return; return;
} }
#endif if (key == KBDK_TAB && pressed && StellaModTest::isAlt(mod))
{
// Immediately store the key state // Swallow Alt-Tab, but remember that it happened
myEvent.setKey(key, pressed); myAltKeyCounter = 1;
// An attempt to speed up event processing; we quickly check for
// Control or Alt/Cmd combos first
// and don't pass the key on if we've already taken care of it
if(handleAltEvent(key, mod, pressed))
return; return;
}
#endif
EventHandlerState estate = myHandler.state(); EventHandlerState estate = myHandler.state();
@ -341,19 +356,21 @@ void PhysicalKeyboardHandler::handleEvent(StellaKey key, StellaMod mod, bool pre
if ((estate == EventHandlerState::EMULATION || estate == EventHandlerState::PAUSE) && if ((estate == EventHandlerState::EMULATION || estate == EventHandlerState::PAUSE) &&
myOSystem.console().leftController().type() == Controller::Type::CompuMate) myOSystem.console().leftController().type() == Controller::Type::CompuMate)
{ {
Event::Type event = myKeyMap.get(kCompuMateMode, key, mod);
// (potential) CompuMate events are handled directly.
if (myKeyMap.get(kEmulationMode, key, mod) != Event::ExitMode && if (myKeyMap.get(kEmulationMode, key, mod) != Event::ExitMode &&
CompuMateKeys.find(key) != CompuMateKeys.end()) !StellaModTest::isAlt(mod) && event != Event::NoType)
// supress all events (except exit mode) using CompuMate keys {
myHandler.handleEvent(event, pressed, repeated);
return; return;
}
} }
// Arrange the logic to take advantage of short-circuit evaluation // Arrange the logic to take advantage of short-circuit evaluation
if(!(StellaModTest::isControl(mod) || StellaModTest::isShift(mod) || StellaModTest::isAlt(mod))) // Handle keys which switch eventhandler state
{ if (!pressed && myHandler.changeStateByEvent(myKeyMap.get(kEmulationMode, key, mod)))
// Handle keys which switch eventhandler state return;
if (!pressed && myHandler.changeStateByEvent(myKeyMap.get(kEmulationMode, key, mod)))
return;
}
// Otherwise, let the event handler deal with it // Otherwise, let the event handler deal with it
switch(estate) switch(estate)
@ -373,19 +390,6 @@ void PhysicalKeyboardHandler::handleEvent(StellaKey key, StellaMod mod, bool pre
} }
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
bool PhysicalKeyboardHandler::handleAltEvent(StellaKey key, StellaMod mod, bool pressed)
{
if(StellaModTest::isAlt(mod) && pressed && key == KBDK_TAB)
{
// Swallow Alt-Tab, but remember that it happened
myAltKeyCounter = 1;
return true;
} // alt
return false;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
EventSet PhysicalKeyboardHandler::LeftJoystickEvents = { EventSet PhysicalKeyboardHandler::LeftJoystickEvents = {
Event::JoystickZeroUp, Event::JoystickZeroDown, Event::JoystickZeroLeft, Event::JoystickZeroRight, Event::JoystickZeroUp, Event::JoystickZeroDown, Event::JoystickZeroLeft, Event::JoystickZeroRight,
@ -640,25 +644,62 @@ PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::DefaultKeypa
{Event::KeyboardOnePound, KBDK_SLASH}, {Event::KeyboardOnePound, KBDK_SLASH},
}; };
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
PhysicalKeyboardHandler::StellaKeySet PhysicalKeyboardHandler::CompuMateKeys = { PhysicalKeyboardHandler::EventMappingArray PhysicalKeyboardHandler::CompuMateMapping = {
KBDK_0, KBDK_1, KBDK_2, KBDK_3, KBDK_4, {Event::CompuMateShift, KBDK_LSHIFT},
KBDK_5, KBDK_6, KBDK_7, KBDK_8, KBDK_9, {Event::CompuMateShift, KBDK_RSHIFT},
KBDK_A, KBDK_B, KBDK_C, KBDK_D, KBDK_E, {Event::CompuMateFunc, KBDK_LCTRL},
KBDK_F, KBDK_G, KBDK_H, KBDK_I, KBDK_J, {Event::CompuMateFunc, KBDK_RCTRL},
KBDK_K, KBDK_L, KBDK_M, KBDK_N, KBDK_O, {Event::CompuMate0, KBDK_0},
KBDK_P, KBDK_Q, KBDK_R, KBDK_S, KBDK_T, {Event::CompuMate1, KBDK_1},
KBDK_U, KBDK_V, KBDK_W, KBDK_X, KBDK_Y, {Event::CompuMate2, KBDK_2},
KBDK_Z, {Event::CompuMate3, KBDK_3},
KBDK_COMMA, {Event::CompuMate4, KBDK_4},
KBDK_PERIOD, {Event::CompuMate5, KBDK_5},
KBDK_RETURN, KBDK_KP_ENTER, {Event::CompuMate6, KBDK_6},
KBDK_SPACE, {Event::CompuMate7, KBDK_7},
KBDK_BACKSPACE, {Event::CompuMate8, KBDK_8},
KBDK_EQUALS, {Event::CompuMate9, KBDK_9},
KBDK_MINUS, {Event::CompuMateA, KBDK_A},
KBDK_SLASH, {Event::CompuMateB, KBDK_B},
KBDK_LEFTBRACKET, {Event::CompuMateC, KBDK_C},
KBDK_RIGHTBRACKET, {Event::CompuMateD, KBDK_D},
KBDK_APOSTROPHE {Event::CompuMateE, KBDK_E},
{Event::CompuMateF, KBDK_F},
{Event::CompuMateG, KBDK_G},
{Event::CompuMateH, KBDK_H},
{Event::CompuMateI, KBDK_I},
{Event::CompuMateJ, KBDK_J},
{Event::CompuMateK, KBDK_K},
{Event::CompuMateL, KBDK_L},
{Event::CompuMateM, KBDK_M},
{Event::CompuMateN, KBDK_N},
{Event::CompuMateO, KBDK_O},
{Event::CompuMateP, KBDK_P},
{Event::CompuMateQ, KBDK_Q},
{Event::CompuMateR, KBDK_R},
{Event::CompuMateS, KBDK_S},
{Event::CompuMateT, KBDK_T},
{Event::CompuMateU, KBDK_U},
{Event::CompuMateV, KBDK_V},
{Event::CompuMateW, KBDK_W},
{Event::CompuMateX, KBDK_X},
{Event::CompuMateY, KBDK_Y},
{Event::CompuMateZ, KBDK_Z},
{Event::CompuMateComma, KBDK_COMMA},
{Event::CompuMatePeriod, KBDK_PERIOD},
{Event::CompuMateEnter, KBDK_RETURN},
{Event::CompuMateEnter, KBDK_KP_ENTER},
{Event::CompuMateSpace, KBDK_SPACE},
// extra emulated keys
{Event::CompuMateQuestion, KBDK_SLASH, KBDM_SHIFT},
{Event::CompuMateLeftBracket, KBDK_LEFTBRACKET},
{Event::CompuMateRightBracket, KBDK_RIGHTBRACKET},
{Event::CompuMateMinus, KBDK_MINUS},
{Event::CompuMateQuote, KBDK_APOSTROPHE, KBDM_SHIFT},
{Event::CompuMateBackspace, KBDK_BACKSPACE},
{Event::CompuMateEquals, KBDK_EQUALS},
{Event::CompuMatePlus, KBDK_EQUALS, KBDM_SHIFT},
{Event::CompuMateSlash, KBDK_SLASH}
}; };

View File

@ -72,8 +72,10 @@ class PhysicalKeyboardHandler
return myKeyMap.get(mode, key, mod); return myKeyMap.get(mode, key, mod);
} }
#ifdef BSPF_UNIX
/** See comments on 'myAltKeyCounter' for more information. */ /** See comments on 'myAltKeyCounter' for more information. */
uInt8& altKeyCount() { return myAltKeyCounter; } uInt8& altKeyCount() { return myAltKeyCounter; }
#endif
/** See comments on KeyMap.myModEnabled for more information. */ /** See comments on KeyMap.myModEnabled for more information. */
bool& useModKeys() { return myKeyMap.enableMod(); } bool& useModKeys() { return myKeyMap.enableMod(); }
@ -88,14 +90,9 @@ class PhysicalKeyboardHandler
}; };
using EventMappingArray = std::vector<EventMapping>; using EventMappingArray = std::vector<EventMapping>;
// Used for CompuMate keys only
using StellaKeySet = std::set<StellaKey>;
void setDefaultKey(EventMapping map, Event::Type event = Event::NoType, void setDefaultKey(EventMapping map, Event::Type event = Event::NoType,
EventMode mode = kEmulationMode, bool updateDefaults = false); EventMode mode = kEmulationMode, bool updateDefaults = false);
bool handleAltEvent(StellaKey key, StellaMod mod, bool pressed);
/** returns the event's controller mode */ /** returns the event's controller mode */
EventMode getEventMode(const Event::Type event, const EventMode mode) const; EventMode getEventMode(const Event::Type event, const EventMode mode) const;
/** Checks event type. */ /** Checks event type. */
@ -119,6 +116,7 @@ class PhysicalKeyboardHandler
EventMode myLeftMode; EventMode myLeftMode;
EventMode myRightMode; EventMode myRightMode;
#ifdef BSPF_UNIX
// Sometimes key combos with the Alt key become 'stuck' after the // Sometimes key combos with the Alt key become 'stuck' after the
// window changes state, and we want to ignore that event // window changes state, and we want to ignore that event
// For example, press Alt-Tab and then upon re-entering the window, // For example, press Alt-Tab and then upon re-entering the window,
@ -131,6 +129,7 @@ class PhysicalKeyboardHandler
// TODO - This may be a bug in SDL, and might be removed in the future // TODO - This may be a bug in SDL, and might be removed in the future
// It only seems to be an issue in Linux // It only seems to be an issue in Linux
uInt8 myAltKeyCounter; uInt8 myAltKeyCounter;
#endif
// Hold controller related events // Hold controller related events
static EventSet LeftJoystickEvents; static EventSet LeftJoystickEvents;
@ -145,8 +144,7 @@ class PhysicalKeyboardHandler
static EventMappingArray DefaultJoystickMapping; static EventMappingArray DefaultJoystickMapping;
static EventMappingArray DefaultPaddleMapping; static EventMappingArray DefaultPaddleMapping;
static EventMappingArray DefaultKeypadMapping; static EventMappingArray DefaultKeypadMapping;
static EventMappingArray CompuMateMapping;
static StellaKeySet CompuMateKeys;
}; };
#endif #endif

View File

@ -24,7 +24,7 @@ CompuMate::CompuMate(const Console& console, const Event& event,
const System& system) const System& system)
: myConsole(console), : myConsole(console),
myColumn(0), myColumn(0),
myKeyTable(event.getKeys()) myEvent(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
@ -35,14 +35,6 @@ CompuMate::CompuMate(const Console& console, const Event& event,
myLeftController->setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE); myLeftController->setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE);
myRightController->setPin(Controller::AnalogPin::Nine, Controller::MIN_RESISTANCE); myRightController->setPin(Controller::AnalogPin::Nine, Controller::MIN_RESISTANCE);
myRightController->setPin(Controller::AnalogPin::Five, Controller::MAX_RESISTANCE); myRightController->setPin(Controller::AnalogPin::Five, Controller::MAX_RESISTANCE);
enableKeyHandling(false);
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void CompuMate::enableKeyHandling(bool enable)
{
myKeyTable.enable(enable);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -59,9 +51,9 @@ void CompuMate::update()
rp.setPin(Controller::AnalogPin::Five, Controller::MAX_RESISTANCE); rp.setPin(Controller::AnalogPin::Five, Controller::MAX_RESISTANCE);
rp.setPin(Controller::DigitalPin::Six, true); rp.setPin(Controller::DigitalPin::Six, true);
if (myKeyTable[KBDK_LSHIFT] || myKeyTable[KBDK_RSHIFT]) if (myEvent.get(Event::CompuMateShift))
rp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE); rp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE);
if (myKeyTable[KBDK_LCTRL] || myKeyTable[KBDK_RCTRL]) if (myEvent.get(Event::CompuMateFunc))
lp.setPin(Controller::AnalogPin::Nine, Controller::MIN_RESISTANCE); lp.setPin(Controller::AnalogPin::Nine, Controller::MIN_RESISTANCE);
rp.setPin(Controller::DigitalPin::Three, true); rp.setPin(Controller::DigitalPin::Three, true);
@ -70,119 +62,118 @@ void CompuMate::update()
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.setPin(Controller::DigitalPin::Six, false); if (myEvent.get(Event::CompuMate7)) lp.setPin(Controller::DigitalPin::Six, false);
if (myKeyTable[KBDK_U]) rp.setPin(Controller::DigitalPin::Three, false); if (myEvent.get(Event::CompuMateU)) rp.setPin(Controller::DigitalPin::Three, false);
if (myKeyTable[KBDK_J]) rp.setPin(Controller::DigitalPin::Six, false); if (myEvent.get(Event::CompuMateJ)) rp.setPin(Controller::DigitalPin::Six, false);
if (myKeyTable[KBDK_M]) rp.setPin(Controller::DigitalPin::Four, false); if (myEvent.get(Event::CompuMateM)) rp.setPin(Controller::DigitalPin::Four, false);
break; break;
case 1: case 1:
if (myKeyTable[KBDK_6]) lp.setPin(Controller::DigitalPin::Six, false); if (myEvent.get(Event::CompuMate6)) 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 (myEvent.get(Event::CompuMateQuestion))
{ {
rp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE); rp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE);
lp.setPin(Controller::DigitalPin::Six, false); lp.setPin(Controller::DigitalPin::Six, false);
} }
if (myKeyTable[KBDK_Y]) rp.setPin(Controller::DigitalPin::Three, false); if (myEvent.get(Event::CompuMateY)) rp.setPin(Controller::DigitalPin::Three, false);
if (myKeyTable[KBDK_H]) rp.setPin(Controller::DigitalPin::Six, false); if (myEvent.get(Event::CompuMateH)) rp.setPin(Controller::DigitalPin::Six, false);
if (myKeyTable[KBDK_N]) rp.setPin(Controller::DigitalPin::Four, false); if (myEvent.get(Event::CompuMateN)) rp.setPin(Controller::DigitalPin::Four, false);
break; break;
case 2: case 2:
if (myKeyTable[KBDK_8]) lp.setPin(Controller::DigitalPin::Six, false); if (myEvent.get(Event::CompuMate8)) 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 (myEvent.get(Event::CompuMateLeftBracket))
{ {
rp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE); rp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE);
lp.setPin(Controller::DigitalPin::Six, false); lp.setPin(Controller::DigitalPin::Six, false);
} }
if (myKeyTable[KBDK_I]) rp.setPin(Controller::DigitalPin::Three, false); if (myEvent.get(Event::CompuMateI)) rp.setPin(Controller::DigitalPin::Three, false);
if (myKeyTable[KBDK_K]) rp.setPin(Controller::DigitalPin::Six, false); if (myEvent.get(Event::CompuMateK)) rp.setPin(Controller::DigitalPin::Six, false);
if (myKeyTable[KBDK_COMMA]) rp.setPin(Controller::DigitalPin::Four, false); if (myEvent.get(Event::CompuMateComma)) rp.setPin(Controller::DigitalPin::Four, false);
break; break;
case 3: case 3:
if (myKeyTable[KBDK_2]) lp.setPin(Controller::DigitalPin::Six, false); if (myEvent.get(Event::CompuMate2)) 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 (myEvent.get(Event::CompuMateMinus))
{ {
rp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE); rp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE);
lp.setPin(Controller::DigitalPin::Six, false); lp.setPin(Controller::DigitalPin::Six, false);
} }
if (myKeyTable[KBDK_W]) rp.setPin(Controller::DigitalPin::Three, false); if (myEvent.get(Event::CompuMateW)) rp.setPin(Controller::DigitalPin::Three, false);
if (myKeyTable[KBDK_S]) rp.setPin(Controller::DigitalPin::Six, false); if (myEvent.get(Event::CompuMateS)) rp.setPin(Controller::DigitalPin::Six, false);
if (myKeyTable[KBDK_X]) rp.setPin(Controller::DigitalPin::Four, false); if (myEvent.get(Event::CompuMateX)) rp.setPin(Controller::DigitalPin::Four, false);
break; break;
case 4: case 4:
if (myKeyTable[KBDK_3]) lp.setPin(Controller::DigitalPin::Six, false); if (myEvent.get(Event::CompuMate3)) lp.setPin(Controller::DigitalPin::Six, false);
if (myKeyTable[KBDK_E]) rp.setPin(Controller::DigitalPin::Three, false); if (myEvent.get(Event::CompuMateE)) rp.setPin(Controller::DigitalPin::Three, false);
if (myKeyTable[KBDK_D]) rp.setPin(Controller::DigitalPin::Six, false); if (myEvent.get(Event::CompuMateD)) rp.setPin(Controller::DigitalPin::Six, false);
if (myKeyTable[KBDK_C]) rp.setPin(Controller::DigitalPin::Four, false); if (myEvent.get(Event::CompuMateC)) rp.setPin(Controller::DigitalPin::Four, false);
break; break;
case 5: case 5:
if (myKeyTable[KBDK_0]) lp.setPin(Controller::DigitalPin::Six, false); if (myEvent.get(Event::CompuMate0)) 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 (myEvent.get(Event::CompuMateQuote))
{ {
rp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE); rp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE);
lp.setPin(Controller::DigitalPin::Six, false); lp.setPin(Controller::DigitalPin::Six, false);
} }
if (myKeyTable[KBDK_P]) rp.setPin(Controller::DigitalPin::Three, false); if (myEvent.get(Event::CompuMateP)) rp.setPin(Controller::DigitalPin::Three, false);
if (myKeyTable[KBDK_RETURN] || myKeyTable[KBDK_KP_ENTER]) if (myEvent.get(Event::CompuMateEnter)) rp.setPin(Controller::DigitalPin::Six, false);
rp.setPin(Controller::DigitalPin::Six, false); if (myEvent.get(Event::CompuMateSpace)) rp.setPin(Controller::DigitalPin::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 (myEvent.get(Event::CompuMateBackspace))
{ {
lp.setPin(Controller::AnalogPin::Nine, Controller::MIN_RESISTANCE); lp.setPin(Controller::AnalogPin::Nine, Controller::MIN_RESISTANCE);
rp.setPin(Controller::DigitalPin::Four, false); rp.setPin(Controller::DigitalPin::Four, false);
} }
break; break;
case 6: case 6:
if (myKeyTable[KBDK_9]) lp.setPin(Controller::DigitalPin::Six, false); if (myEvent.get(Event::CompuMate9)) 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 (myEvent.get(Event::CompuMateRightBracket))
{ {
rp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE); rp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE);
lp.setPin(Controller::DigitalPin::Six, false); lp.setPin(Controller::DigitalPin::Six, false);
} }
if (myKeyTable[KBDK_O]) rp.setPin(Controller::DigitalPin::Three, false); if (myEvent.get(Event::CompuMateO)) rp.setPin(Controller::DigitalPin::Three, false);
if (myKeyTable[KBDK_L]) rp.setPin(Controller::DigitalPin::Six, false); if (myEvent.get(Event::CompuMateL)) rp.setPin(Controller::DigitalPin::Six, false);
if (myKeyTable[KBDK_PERIOD]) rp.setPin(Controller::DigitalPin::Four, false); if (myEvent.get(Event::CompuMatePeriod)) rp.setPin(Controller::DigitalPin::Four, false);
break; break;
case 7: case 7:
if (myKeyTable[KBDK_5]) lp.setPin(Controller::DigitalPin::Six, false); if (myEvent.get(Event::CompuMate5)) 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 (myEvent.get(Event::CompuMateEquals))
{ {
rp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE); rp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE);
lp.setPin(Controller::DigitalPin::Six, false); lp.setPin(Controller::DigitalPin::Six, false);
} }
if (myKeyTable[KBDK_T]) rp.setPin(Controller::DigitalPin::Three, false); if (myEvent.get(Event::CompuMateT)) rp.setPin(Controller::DigitalPin::Three, false);
if (myKeyTable[KBDK_G]) rp.setPin(Controller::DigitalPin::Six, false); if (myEvent.get(Event::CompuMateG)) rp.setPin(Controller::DigitalPin::Six, false);
if (myKeyTable[KBDK_B]) rp.setPin(Controller::DigitalPin::Four, false); if (myEvent.get(Event::CompuMateB)) rp.setPin(Controller::DigitalPin::Four, false);
break; break;
case 8: case 8:
if (myKeyTable[KBDK_1]) lp.setPin(Controller::DigitalPin::Six, false); if (myEvent.get(Event::CompuMate1)) 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 (myEvent.get(Event::CompuMatePlus))
{ {
rp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE); rp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE);
lp.setPin(Controller::DigitalPin::Six, false); lp.setPin(Controller::DigitalPin::Six, false);
} }
if (myKeyTable[KBDK_Q]) rp.setPin(Controller::DigitalPin::Three, false); if (myEvent.get(Event::CompuMateQ)) rp.setPin(Controller::DigitalPin::Three, false);
if (myKeyTable[KBDK_A]) rp.setPin(Controller::DigitalPin::Six, false); if (myEvent.get(Event::CompuMateA)) rp.setPin(Controller::DigitalPin::Six, false);
if (myKeyTable[KBDK_Z]) rp.setPin(Controller::DigitalPin::Four, false); if (myEvent.get(Event::CompuMateZ)) rp.setPin(Controller::DigitalPin::Four, false);
break; break;
case 9: case 9:
if (myKeyTable[KBDK_4]) lp.setPin(Controller::DigitalPin::Six, false); if (myEvent.get(Event::CompuMate4)) 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 (myEvent.get(Event::CompuMateSlash))
{ {
rp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE); rp.setPin(Controller::AnalogPin::Five, Controller::MIN_RESISTANCE);
lp.setPin(Controller::DigitalPin::Six, false); lp.setPin(Controller::DigitalPin::Six, false);
} }
if (myKeyTable[KBDK_R]) rp.setPin(Controller::DigitalPin::Three, false); if (myEvent.get(Event::CompuMateR)) rp.setPin(Controller::DigitalPin::Three, false);
if (myKeyTable[KBDK_F]) rp.setPin(Controller::DigitalPin::Six, false); if (myEvent.get(Event::CompuMateF)) rp.setPin(Controller::DigitalPin::Six, false);
if (myKeyTable[KBDK_V]) rp.setPin(Controller::DigitalPin::Four, false); if (myEvent.get(Event::CompuMateV)) rp.setPin(Controller::DigitalPin::Four, false);
break; break;
default: default:
break; break;

View File

@ -59,21 +59,6 @@ class CompuMate
unique_ptr<Controller>& leftController() { return myLeftController; } unique_ptr<Controller>& leftController() { return myLeftController; }
unique_ptr<Controller>& rightController() { return myRightController; } unique_ptr<Controller>& rightController() { return myRightController; }
/**
In normal key-handling mode, the update handler receives key events
from the keyboard. This is meant to be used during emulation.
Otherwise, the update handler ignores keys from the keyboard and uses
its own internal buffer, which essentially can only be set directly
within the class itself (by the debugger).
This is necessary since Stella is otherwise event-based, whereas
reading from the keyboard (in the current code) bypasses the event
system. This leads to issues where typing commands in the debugger
would then be processed by the update handler as if they were
entered on the CompuMate keyboard.
*/
void enableKeyHandling(bool enable);
/** Needed for communication with CartCM class */ /** Needed for communication with CartCM class */
uInt8& column() { return myColumn; } uInt8& column() { return myColumn; }
@ -146,8 +131,8 @@ class CompuMate
// Column currently active // Column currently active
uInt8 myColumn; uInt8 myColumn;
// The keyboard state array (tells us the current state of the keyboard) /// Reference to the event object this controller uses
Event::KeyTable myKeyTable; const Event& myEvent;
private: private:
// Following constructors and assignment operators not supported // Following constructors and assignment operators not supported

View File

@ -803,6 +803,7 @@ void Console::setControllers(const string& rommd5)
myLeftControl = std::move(myCMHandler->leftController()); myLeftControl = std::move(myCMHandler->leftController());
myRightControl = std::move(myCMHandler->rightController()); myRightControl = std::move(myCMHandler->rightController());
myOSystem.eventHandler().defineKeyControllerMappings("CM", Controller::Jack::Left);
} }
else else
{ {
@ -1091,9 +1092,7 @@ void Console::attachDebugger(Debugger& dbg)
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
void Console::stateChanged(EventHandlerState state) void Console::stateChanged(EventHandlerState state)
{ {
// For now, only the CompuMate cares about state changes // only the CompuMate used to care about state changes
if(myCMHandler)
myCMHandler->enableKeyHandling(state == EventHandlerState::EMULATION);
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -108,43 +108,27 @@ class Event
ToggleAutoSlot, ToggleAutoSlot,
CompuMateFunc, CompuMateShift,
CompuMate0, CompuMate1, CompuMate2, CompuMate3, CompuMate4,
CompuMate5, CompuMate6, CompuMate7, CompuMate8, CompuMate9,
CompuMateA, CompuMateB, CompuMateC, CompuMateD, CompuMateE,
CompuMateF, CompuMateG, CompuMateH, CompuMateI, CompuMateJ,
CompuMateK, CompuMateL, CompuMateM, CompuMateN, CompuMateO,
CompuMateP, CompuMateQ, CompuMateR, CompuMateS, CompuMateT,
CompuMateU, CompuMateV, CompuMateW, CompuMateX, CompuMateY,
CompuMateZ,
CompuMateComma, CompuMatePeriod, CompuMateEnter, CompuMateSpace,
CompuMateQuestion, CompuMateLeftBracket, CompuMateRightBracket, CompuMateMinus,
CompuMateQuote, CompuMateBackspace, CompuMateEquals, CompuMatePlus,
CompuMateSlash,
LastType LastType
}; };
// Event list version, update if the id of existing event types changed // Event list version, update if the id of existing event types changed
static constexpr Int32 VERSION = 2; static constexpr Int32 VERSION = 2;
class KeyTable {
public:
KeyTable(const bool* keyTable, std::mutex& mutex)
: myKeyTable(keyTable),
myMutex(mutex),
myIsEnabled(true)
{
}
bool operator[](int type) const {
if (!myIsEnabled) return false;
std::lock_guard<std::mutex> lock(myMutex);
return myKeyTable[type];
}
void enable(bool isEnabled) {
myIsEnabled = isEnabled;
}
private:
const bool *myKeyTable;
std::mutex& myMutex;
bool myIsEnabled;
};
public: public:
/** /**
Create a new event object. Create a new event object.
@ -179,24 +163,8 @@ class Event
for(Int32 i = 0; i < LastType; ++i) for(Int32 i = 0; i < LastType; ++i)
myValues[i] = Event::NoType; myValues[i] = Event::NoType;
for(Int32 i = 0; i < KBDK_LAST; ++i)
myKeyTable[i] = false;
} }
/**
Get the keytable associated with this event.
*/
KeyTable getKeys() const { return KeyTable(myKeyTable, myMutex); }
/**
Set the value associated with the event of the specified type.
*/
void setKey(StellaKey key, bool pressed) {
std::lock_guard<std::mutex> lock(myMutex);
myKeyTable[key] = pressed;
}
/** /**
Tests if a given event represents continuous or analog values. Tests if a given event represents continuous or analog values.
@ -220,7 +188,7 @@ class Event
Int32 myValues[LastType]; Int32 myValues[LastType];
// Array of keyboard key states // Array of keyboard key states
bool myKeyTable[KBDK_LAST]; //bool myKeyTable[KBDK_LAST];
mutable std::mutex myMutex; mutable std::mutex myMutex;

View File

@ -314,13 +314,14 @@ void EventHandler::handleSystemEvent(SystemEvent e, int, int)
case SystemEvent::WINDOW_RESIZED: case SystemEvent::WINDOW_RESIZED:
myOSystem.frameBuffer().update(true); // force full update myOSystem.frameBuffer().update(true); // force full update
break; break;
#ifdef BSPF_UNIX
case SystemEvent::WINDOW_FOCUS_GAINED: case SystemEvent::WINDOW_FOCUS_GAINED:
// Used to handle Alt-x key combos; sometimes the key associated with // Used to handle Alt-x key combos; sometimes the key associated with
// Alt gets 'stuck' and is passed to the core for processing // Alt gets 'stuck' and is passed to the core for processing
if(myPKeyHandler->altKeyCount() > 0) if(myPKeyHandler->altKeyCount() > 0)
myPKeyHandler->altKeyCount() = 2; myPKeyHandler->altKeyCount() = 2;
break; break;
#endif
#if 0 #if 0
case SystemEvent::WINDOW_MINIMIZED: case SystemEvent::WINDOW_MINIMIZED:
if(myState == EventHandlerState::EMULATION) enterMenuMode(EventHandlerState::OPTIONSMENU); if(myState == EventHandlerState::EMULATION) enterMenuMode(EventHandlerState::OPTIONSMENU);

View File

@ -71,10 +71,11 @@ enum EventMode {
kEmulationMode = 0, // make sure these are set correctly, kEmulationMode = 0, // make sure these are set correctly,
kMenuMode = 1, // since they'll be used as array indices kMenuMode = 1, // since they'll be used as array indices
kNumModes = 2, kNumModes = 2,
kJoystickMode = kNumModes, // 3 extra modes for mapping controller keys separately kJoystickMode = kNumModes, // 5 extra modes for mapping controller keys separately
kPaddlesMode = kNumModes + 1, kPaddlesMode,
kKeypadMode = kNumModes + 2, kKeypadMode,
kCommonMode = kNumModes + 3 kCompuMateMode,
kCommonMode
}; };