mirror of https://github.com/stella-emu/stella.git
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:
parent
82a4bc13b1
commit
44b5cf66b9
|
@ -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.
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue