The CompuMate emulation now correctly processes normal and

shifted keys from the keyboard.  Most control-keys are
supported too, but still TODO is allow the Control key to
pass to the CompuMate controller and not pre-process it
by the EventHandler (so pressing Ctrl-q) shouldn't quit
emulation in that case).


git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2414 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
stephena 2012-03-15 15:22:57 +00:00
parent 82a4bc13b1
commit 44b5cf66b9
6 changed files with 79 additions and 78 deletions

View File

@ -24,6 +24,9 @@
have only one 2600-daptor and want to use it as a left port
normally, but as a right port for Star Raiders, etc).
* Added CompuMate bankswitching/controller support; the CompuMate
NTSC and PAL ROMs now work correctly.
* Fixed bug in BoosterGrip controller emulation; the functionality
of the booster and trigger buttons was reversed. Related to this,
renamed these actions in the Event Mapping dialog to be more clear.

View File

@ -20,6 +20,8 @@
#ifndef STELLA_KEYS_HXX
#define STELLA_KEYS_HXX
#include <SDL.h>
/**
This class implements a thin wrapper around the SDL keysym enumerations,
such that SDL-specific code doesn't have to go into the internal parts of
@ -310,4 +312,12 @@ typedef enum {
// The underlying code doesn't need to know how it's implemented
typedef int StellaMod;
// Wrapper around the SDL_GetKeyState function
// This can be used as-is since KBDK keys and SDL keys are the same
class StellaKeys
{
public:
static uInt8* GetKeyState() { return SDL_GetKeyState(NULL); }
};
#endif /* StellaKeys */

View File

@ -83,8 +83,7 @@ uInt8 CartridgeCM::peek(uInt16 address)
{
// NOTE: This does not handle accessing cart ROM/RAM, however, this function
// should never be called for ROM/RAM because of the way page accessing
// has been setup
// It will only ever be called for RIOT reads
// has been setup (it will only ever be called for RIOT reads)
return mySystem->m6532().peek(address);
}
@ -118,8 +117,8 @@ bool CartridgeCM::bank(uInt16 bank)
uInt16 offset = myCurrentBank << 12;
uInt16 shift = mySystem->pageShift();
// Although this scheme contains four 4K banks and one 2K bank, it's easier
// to think of things in terms of 2K slices, as follows:
// Although this scheme contains four 4K ROM banks and one 2K RAM bank,
// it's easier to think of things in terms of 2K slices, as follows:
//
// The lower 2K of cart address space always points to the lower 2K of the
// current ROM bank

View File

@ -108,8 +108,6 @@ class System;
*/
class CartridgeCM : public Cartridge
{
friend class CompuMate;
public:
/**
Create a new cartridge using the specified image
@ -213,6 +211,13 @@ class CartridgeCM : public Cartridge
*/
bool poke(uInt16 address, uInt8 value);
/**
Get the current keybord column
@return The column referenced by SWCHA D6 and D5
*/
uInt8 column() const { return myColumn; }
private:
// Indicates which bank is currently active
uInt16 myCurrentBank;

View File

@ -19,6 +19,7 @@
#include "Control.hxx"
#include "System.hxx"
#include "StellaKeys.hxx"
#include "CompuMate.hxx"
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -29,11 +30,15 @@ CompuMate::CompuMate(CartridgeCM& cart, const Event& event,
mySystem(system),
myLeftController(0),
myRightController(0),
myCycleAtLastUpdate(0),
myColumn(0)
myCycleAtLastUpdate(0)
{
myLeftController = new CMControl(*this, Controller::Left, event, system);
myRightController = new CMControl(*this, Controller::Right, event, system);
myLeftController->myAnalogPinValue[Controller::Nine] = Controller::maximumResistance;
myLeftController->myAnalogPinValue[Controller::Five] = Controller::minimumResistance;
myRightController->myAnalogPinValue[Controller::Nine] = Controller::minimumResistance;
myRightController->myAnalogPinValue[Controller::Five] = Controller::maximumResistance;
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
@ -52,92 +57,85 @@ void CompuMate::update()
// Handle SWCHA changes - the following comes almost directly from z26
Controller& lp = *myLeftController;
Controller& rp = *myRightController;
uInt8 IOPortA = (lp.read() << 4) | rp.read();
uInt8* KeyTable = StellaKeys::GetKeyState();
lp.myAnalogPinValue[Controller::Nine] = Controller::maximumResistance;
lp.myAnalogPinValue[Controller::Five] = Controller::minimumResistance;
lp.myDigitalPinState[Controller::Six] = true;
rp.myAnalogPinValue[Controller::Nine] = Controller::minimumResistance;
rp.myAnalogPinValue[Controller::Five] = Controller::maximumResistance;
rp.myDigitalPinState[Controller::Six] = true;
rp.myDigitalPinState[Controller::Three] = true;
rp.myDigitalPinState[Controller::Four] = true;
uInt8& column = myCart.myColumn;
if(IOPortA & 0x20) column = 0;
if(IOPortA & 0x40) column = (column + 1) % 10;
if (KeyTable[KBDK_LSHIFT])
rp.myAnalogPinValue[Controller::Five] = Controller::minimumResistance;
if (KeyTable[KBDK_LCTRL])
lp.myAnalogPinValue[Controller::Nine] = Controller::minimumResistance;
IOPortA = IOPortA | (0x0c & 0x7f);
#if 0
switch(column)
switch(myCart.column())
{
case 0:
if (KeyTable[Key7]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyU]) IOPortA = IOPortA & 0xfb;
if (KeyTable[KeyJ]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyM]) IOPortA = IOPortA & 0xf7;
if (KeyTable[KBDK_7]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KBDK_u]) rp.myDigitalPinState[Controller::Three] = false;
if (KeyTable[KBDK_j]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KBDK_m]) rp.myDigitalPinState[Controller::Four] = false;
break;
case 1:
if (KeyTable[Key6]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyY]) IOPortA = IOPortA & 0xfb;
if (KeyTable[KeyH]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyN]) IOPortA = IOPortA & 0xf7;
if (KeyTable[KBDK_6]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KBDK_y]) rp.myDigitalPinState[Controller::Three] = false;
if (KeyTable[KBDK_h]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KBDK_n]) rp.myDigitalPinState[Controller::Four] = false;
break;
case 2:
if (KeyTable[Key8]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyI]) IOPortA = IOPortA & 0xfb;
if (KeyTable[KeyK]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyComma]) IOPortA = IOPortA & 0xf7;
if (KeyTable[KBDK_8]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KBDK_i]) rp.myDigitalPinState[Controller::Three] = false;
if (KeyTable[KBDK_k]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KBDK_COMMA]) rp.myDigitalPinState[Controller::Four] = false;
break;
case 3:
if (KeyTable[Key2]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyW]) IOPortA = IOPortA & 0xfb;
if (KeyTable[KeyS]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyX]) IOPortA = IOPortA & 0xf7;
if (KeyTable[KBDK_2]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KBDK_w]) rp.myDigitalPinState[Controller::Three] = false;
if (KeyTable[KBDK_s]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KBDK_x]) rp.myDigitalPinState[Controller::Four] = false;
break;
case 4:
if (KeyTable[Key3]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyE]) IOPortA = IOPortA & 0xfb;
if (KeyTable[KeyD]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyC]) IOPortA = IOPortA & 0xf7;
if (KeyTable[KBDK_3]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KBDK_e]) rp.myDigitalPinState[Controller::Three] = false;
if (KeyTable[KBDK_d]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KBDK_c]) rp.myDigitalPinState[Controller::Four] = false;
break;
case 5:
if (KeyTable[Key0]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyP]) IOPortA = IOPortA & 0xfb;
if (KeyTable[KeyColon]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeySlash]) IOPortA = IOPortA & 0xf7;
if (KeyTable[KBDK_0]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KBDK_p]) rp.myDigitalPinState[Controller::Three] = false;
if (KeyTable[KBDK_COLON]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KBDK_SLASH]) rp.myDigitalPinState[Controller::Four] = false;
break;
case 6:
if (KeyTable[Key9]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyO]) IOPortA = IOPortA & 0xfb;
if (KeyTable[KeyL]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyDot]) IOPortA = IOPortA & 0xf7;
if (KeyTable[KBDK_9]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KBDK_o]) rp.myDigitalPinState[Controller::Three] = false;
if (KeyTable[KBDK_l]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KBDK_PERIOD]) rp.myDigitalPinState[Controller::Four] = false;
break;
case 7:
if (KeyTable[Key5]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyT]) IOPortA = IOPortA & 0xfb;
if (KeyTable[KeyG]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyB]) IOPortA = IOPortA & 0xf7;
if (KeyTable[KBDK_5]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KBDK_t]) rp.myDigitalPinState[Controller::Three] = false;
if (KeyTable[KBDK_g]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KBDK_b]) rp.myDigitalPinState[Controller::Four] = false;
break;
case 8:
if (KeyTable[Key1]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyQ]) IOPortA = IOPortA & 0xfb;
if (KeyTable[KeyA]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyZ]) IOPortA = IOPortA & 0xf7;
if (KeyTable[KBDK_1]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KBDK_q]) rp.myDigitalPinState[Controller::Three] = false;
if (KeyTable[KBDK_a]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KBDK_z]) rp.myDigitalPinState[Controller::Four] = false;
break;
case 9:
if (KeyTable[Key4]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyR]) IOPortA = IOPortA & 0xfb;
if (KeyTable[KeyF]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KeyV]) IOPortA = IOPortA & 0xf7;
if (KeyTable[KBDK_4]) lp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KBDK_r]) rp.myDigitalPinState[Controller::Three] = false;
if (KeyTable[KBDK_f]) rp.myDigitalPinState[Controller::Six] = false;
if (KeyTable[KBDK_v]) rp.myDigitalPinState[Controller::Four] = false;
break;
default:
break;
}
#endif
// Convert back to digital pins
rp.myDigitalPinState[Controller::One] = IOPortA & 0x01;
rp.myDigitalPinState[Controller::Two] = IOPortA & 0x02;
rp.myDigitalPinState[Controller::Three] = IOPortA & 0x04;
rp.myDigitalPinState[Controller::Four] = IOPortA & 0x08;
}

View File

@ -89,18 +89,7 @@ class CompuMate
const System& system)
: Controller(jack, event, system, Controller::CompuMate),
myHandler(handler)
{
if(myJack == Left)
{
myAnalogPinValue[Five] = minimumResistance;
myAnalogPinValue[Nine] = maximumResistance;
}
else
{
myAnalogPinValue[Five] = maximumResistance;
myAnalogPinValue[Nine] = minimumResistance;
}
}
{ }
/**
Destructor
@ -135,9 +124,6 @@ class CompuMate
// System cycle at which the update() method is called
// Multiple calls at the same cycle should be ignored
uInt32 myCycleAtLastUpdate;
// Column currently active
uInt8 myColumn;
};
#endif