mirror of https://github.com/stella-emu/stella.git
Added classes for MindLink and CompuMate controllers. Note that
these aren't fully activated yet, but they're the next thing I plan to work on. git-svn-id: svn://svn.code.sf.net/p/stella/code/trunk@2322 8b62c5a3-ac7e-4cc8-8f21-d9a121418aba
This commit is contained in:
parent
d8b59f7083
commit
b7125a26ee
|
@ -0,0 +1,53 @@
|
|||
//============================================================================
|
||||
//
|
||||
// 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-2012 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.
|
||||
//
|
||||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#include "Event.hxx"
|
||||
#include "CompuMate.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CompuMate::CompuMate(Jack jack, const Event& event, const System& system)
|
||||
: Controller(jack, event, system, Controller::CompuMate),
|
||||
myIOPort(0xff)
|
||||
{
|
||||
if(myJack == Left)
|
||||
{
|
||||
myAnalogPinValue[Five] = minimumResistance;
|
||||
myAnalogPinValue[Nine] = maximumResistance;
|
||||
}
|
||||
else
|
||||
{
|
||||
myAnalogPinValue[Five] = maximumResistance;
|
||||
myAnalogPinValue[Nine] = minimumResistance;
|
||||
}
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
CompuMate::~CompuMate()
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CompuMate::controlWrite()
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void CompuMate::update()
|
||||
{
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
//============================================================================
|
||||
//
|
||||
// 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-2012 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.
|
||||
//
|
||||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#ifndef COMPUMATE_HXX
|
||||
#define COMPUMATE_HXX
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "Control.hxx"
|
||||
#include "Event.hxx"
|
||||
|
||||
/**
|
||||
The Spectravideo CompuMate SV010 was a home computer expansion for the
|
||||
Atari VCS / 2600 video game system.
|
||||
|
||||
It consists of a membrane keyboard unit with interface connectors. These
|
||||
connectors were placed in the module slot and both controller ports of the
|
||||
Atari console. As the user could place the keyboard on the old style VCS
|
||||
consoles, the two devices resulted in one compact unit. When using with the
|
||||
2600jr console, resulted in a desktop computer look with separated keyboard.
|
||||
|
||||
The CompuMate was equipped with an audio jack for use with a standard tape
|
||||
connector as a possibility of permanent data storage.
|
||||
|
||||
This code was heavily borrowed from z26, and uses conventions defined
|
||||
there. Specifically, IOPortA is treated as a complete uInt8, whereas
|
||||
the Stella core actually stores this information in boolean arrays
|
||||
addressable by DigitalPin number.
|
||||
|
||||
@author Stephen Anthony & z26 team
|
||||
@version $Id$
|
||||
*/
|
||||
class CompuMate : public Controller
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Create a new MindLink controller plugged into the specified jack
|
||||
|
||||
@param jack The jack the controller is plugged into
|
||||
@param event The event object to use for events
|
||||
@param system The system using this controller
|
||||
*/
|
||||
CompuMate(Jack jack, const Event& event, const System& system);
|
||||
|
||||
/**
|
||||
Destructor
|
||||
*/
|
||||
virtual ~CompuMate();
|
||||
|
||||
public:
|
||||
/**
|
||||
Called after *all* digital pins have been written on Port A.
|
||||
*/
|
||||
void controlWrite();
|
||||
|
||||
/**
|
||||
Update the entire digital and analog pin state according to the
|
||||
events currently set.
|
||||
*/
|
||||
void update();
|
||||
|
||||
private:
|
||||
// Internal state of the port pins
|
||||
uInt8 myIOPort;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -34,6 +34,8 @@
|
|||
#include "Keyboard.hxx"
|
||||
#include "KidVid.hxx"
|
||||
#include "Genesis.hxx"
|
||||
#include "MindLink.hxx"
|
||||
#include "CompuMate.hxx"
|
||||
#include "M6502.hxx"
|
||||
#include "M6532.hxx"
|
||||
#include "Paddles.hxx"
|
||||
|
@ -664,6 +666,14 @@ void Console::setControllers(const string& rommd5)
|
|||
{
|
||||
myControllers[leftPort] = new Genesis(Controller::Left, *myEvent, *mySystem);
|
||||
}
|
||||
else if(left == "COMPUMATE")
|
||||
{
|
||||
myControllers[leftPort] = new CompuMate(Controller::Left, *myEvent, *mySystem);
|
||||
}
|
||||
else if(left == "MINDLINK")
|
||||
{
|
||||
myControllers[leftPort] = new MindLink(Controller::Left, *myEvent, *mySystem);
|
||||
}
|
||||
else
|
||||
{
|
||||
myControllers[leftPort] = new Joystick(Controller::Left, *myEvent, *mySystem);
|
||||
|
@ -723,13 +733,21 @@ void Console::setControllers(const string& rommd5)
|
|||
myControllers[rightPort] = new SaveKey(Controller::Right, *myEvent, *mySystem,
|
||||
eepromfile);
|
||||
}
|
||||
else if(right == "GENESIS")
|
||||
{
|
||||
myControllers[rightPort] = new Genesis(Controller::Right, *myEvent, *mySystem);
|
||||
}
|
||||
else if(right == "COMPUMATE")
|
||||
{
|
||||
myControllers[rightPort] = new CompuMate(Controller::Right, *myEvent, *mySystem);
|
||||
}
|
||||
else if(right == "KIDVID")
|
||||
{
|
||||
myControllers[rightPort] = new KidVid(Controller::Right, *myEvent, *mySystem, rommd5);
|
||||
}
|
||||
else if(right == "GENESIS")
|
||||
else if(right == "MINDLINK")
|
||||
{
|
||||
myControllers[rightPort] = new Genesis(Controller::Right, *myEvent, *mySystem);
|
||||
myControllers[rightPort] = new MindLink(Controller::Right, *myEvent, *mySystem);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -77,6 +77,12 @@ Controller::Controller(Jack jack, const Event& event, const System& system,
|
|||
case Genesis:
|
||||
myName = "Genesis";
|
||||
break;
|
||||
case MindLink:
|
||||
myName = "MindLink";
|
||||
break;
|
||||
case CompuMate:
|
||||
myName = "CompuMate";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,6 +97,18 @@ const Controller::Type Controller::type() const
|
|||
return myType;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
uInt8 Controller::read()
|
||||
{
|
||||
uInt8 ioport = 0x00;
|
||||
if(myDigitalPinState[One]) ioport |= 0x01;
|
||||
if(myDigitalPinState[Two]) ioport |= 0x02;
|
||||
if(myDigitalPinState[Three]) ioport |= 0x04;
|
||||
if(myDigitalPinState[Four]) ioport |= 0x08;
|
||||
|
||||
return myJack == Left ? (ioport << 4) : ioport;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool Controller::read(DigitalPin pin)
|
||||
{
|
||||
|
|
|
@ -90,7 +90,7 @@ class Controller : public Serializable
|
|||
{
|
||||
BoosterGrip, Driving, Keyboard, Paddles, Joystick,
|
||||
TrackBall22, TrackBall80, AmigaMouse, AtariVox, SaveKey,
|
||||
KidVid, Genesis
|
||||
KidVid, Genesis, MindLink, CompuMate
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -124,6 +124,19 @@ class Controller : public Serializable
|
|||
*/
|
||||
const Type type() const;
|
||||
|
||||
/**
|
||||
Read the entire state of all digital pins for this controller.
|
||||
|
||||
Note that this method must take into account the location of the
|
||||
pin data in the bitfield, and zero the remaining data:
|
||||
|
||||
Left port : upper 4 bits valid, lower 4 bits zero'ed
|
||||
Right port: lower 4 bits valid, upper 4 bits zero'ed
|
||||
|
||||
@return The state of all digital pins
|
||||
*/
|
||||
virtual uInt8 read();
|
||||
|
||||
/**
|
||||
Read the value of the specified digital pin for this controller.
|
||||
|
||||
|
@ -151,12 +164,19 @@ class Controller : public Serializable
|
|||
*/
|
||||
virtual void write(DigitalPin pin, bool value) { };
|
||||
|
||||
/**
|
||||
Called after *all* digital pins have been written on Port A.
|
||||
Most controllers don't do anything in this case.
|
||||
*/
|
||||
virtual void controlWrite() { };
|
||||
|
||||
/**
|
||||
Update the entire digital and analog pin state according to the
|
||||
events currently set.
|
||||
*/
|
||||
virtual void update() = 0;
|
||||
|
||||
|
||||
/**
|
||||
Notification method invoked by the system right before the
|
||||
system resets its cycle counter to zero. It may be necessary
|
||||
|
|
|
@ -119,19 +119,8 @@ uInt8 M6532::peek(uInt16 addr)
|
|||
{
|
||||
case 0x00: // SWCHA - Port A I/O Register (Joystick)
|
||||
{
|
||||
uInt8 value = 0x00;
|
||||
|
||||
Controller& port0 = myConsole.controller(Controller::Left);
|
||||
if(port0.read(Controller::One)) value |= 0x10;
|
||||
if(port0.read(Controller::Two)) value |= 0x20;
|
||||
if(port0.read(Controller::Three)) value |= 0x40;
|
||||
if(port0.read(Controller::Four)) value |= 0x80;
|
||||
|
||||
Controller& port1 = myConsole.controller(Controller::Right);
|
||||
if(port1.read(Controller::One)) value |= 0x01;
|
||||
if(port1.read(Controller::Two)) value |= 0x02;
|
||||
if(port1.read(Controller::Three)) value |= 0x04;
|
||||
if(port1.read(Controller::Four)) value |= 0x08;
|
||||
uInt8 value = myConsole.controller(Controller::Left).read() |
|
||||
myConsole.controller(Controller::Right).read();
|
||||
|
||||
// Each pin is high (1) by default and will only go low (0) if either
|
||||
// (a) External device drives the pin low
|
||||
|
@ -231,14 +220,14 @@ bool M6532::poke(uInt16 addr, uInt8 value)
|
|||
case 0: // SWCHA - Port A I/O Register (Joystick)
|
||||
{
|
||||
myOutA = value;
|
||||
setPinState();
|
||||
setPinState(true);
|
||||
break;
|
||||
}
|
||||
|
||||
case 1: // SWACNT - Port A Data Direction Register
|
||||
{
|
||||
myDDRA = value;
|
||||
setPinState();
|
||||
setPinState(false);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -271,7 +260,7 @@ void M6532::setTimerRegister(uInt8 value, uInt8 interval)
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void M6532::setPinState()
|
||||
void M6532::setPinState(bool swcha)
|
||||
{
|
||||
/*
|
||||
When a bit in the DDR is set as input, +5V is placed on its output
|
||||
|
@ -290,12 +279,14 @@ void M6532::setPinState()
|
|||
port0.write(Controller::Two, a & 0x20);
|
||||
port0.write(Controller::Three, a & 0x40);
|
||||
port0.write(Controller::Four, a & 0x80);
|
||||
if(swcha) port0.controlWrite();
|
||||
|
||||
Controller& port1 = myConsole.controller(Controller::Right);
|
||||
port1.write(Controller::One, a & 0x01);
|
||||
port1.write(Controller::Two, a & 0x02);
|
||||
port1.write(Controller::Three, a & 0x04);
|
||||
port1.write(Controller::Four, a & 0x08);
|
||||
if(swcha) port1.controlWrite();
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
|
|
@ -134,7 +134,7 @@ class M6532 : public Device
|
|||
{ return myTimer - (mySystem->cycles() - myCyclesWhenTimerSet); }
|
||||
|
||||
void setTimerRegister(uInt8 data, uInt8 interval);
|
||||
void setPinState();
|
||||
void setPinState(bool shcha);
|
||||
|
||||
private:
|
||||
// Reference to the console
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
//============================================================================
|
||||
//
|
||||
// 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-2012 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.
|
||||
//
|
||||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#include "Event.hxx"
|
||||
#include "MindLink.hxx"
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
MindLink::MindLink(Jack jack, const Event& event, const System& system)
|
||||
: Controller(jack, event, system, Controller::MindLink),
|
||||
myIOPort(0xff),
|
||||
myMindlinkPos(0x2800),
|
||||
myMindlinkPos1(0x2800),
|
||||
myMindlinkPos2(0x1000),
|
||||
myMindlinkShift(1)
|
||||
{
|
||||
// Analog pins are never used by the MindLink
|
||||
myAnalogPinValue[Five] = myAnalogPinValue[Nine] = maximumResistance;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
MindLink::~MindLink()
|
||||
{
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void MindLink::update()
|
||||
{
|
||||
myIOPort |= 0xf0;
|
||||
if(0)//MPdirection & 0x01)
|
||||
myMindlinkPos = myMindlinkPos2 + 0x1800;
|
||||
else
|
||||
myMindlinkPos = myMindlinkPos1;
|
||||
|
||||
myMindlinkPos = (myMindlinkPos & 0x3fffffff) +
|
||||
(myEvent.get(Event::MouseAxisXValue) << 3);
|
||||
if(myMindlinkPos < 0x2800)
|
||||
myMindlinkPos = 0x2800;
|
||||
if(myMindlinkPos >= 0x3800)
|
||||
myMindlinkPos = 0x3800;
|
||||
|
||||
|
||||
if(0)//MPdirection & 0x01)
|
||||
{
|
||||
myMindlinkPos2 = myMindlinkPos - 0x1800;
|
||||
myMindlinkPos = myMindlinkPos2;
|
||||
}
|
||||
else
|
||||
myMindlinkPos1 = myMindlinkPos;
|
||||
|
||||
myMindlinkShift = 1;
|
||||
nextMindlinkBit();
|
||||
|
||||
if(myEvent.get(Event::MouseButtonValue))
|
||||
myMindlinkPos |= 0x4000; /* this bit starts a game */
|
||||
|
||||
//cerr << HEX4 << (int)myMindlinkPos << " : " << HEX2 << (int)myIOPort << endl;
|
||||
|
||||
// Convert IOPort values back to booleans
|
||||
myDigitalPinState[One] = myIOPort & 0x10;
|
||||
myDigitalPinState[Two] = myIOPort & 0x20;
|
||||
myDigitalPinState[Three] = myIOPort & 0x40;
|
||||
myDigitalPinState[Four] = myIOPort & 0x80;
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void MindLink::nextMindlinkBit()
|
||||
{
|
||||
if(myIOPort & 0x10)
|
||||
{
|
||||
myIOPort &= 0x3f;
|
||||
if(myMindlinkPos & myMindlinkShift)
|
||||
myIOPort |= 0x80;
|
||||
myMindlinkShift <<= 1;
|
||||
|
||||
myDigitalPinState[One] = myIOPort & 0x10;
|
||||
myDigitalPinState[Two] = myIOPort & 0x20;
|
||||
myDigitalPinState[Three] = myIOPort & 0x40;
|
||||
myDigitalPinState[Four] = myIOPort & 0x80;
|
||||
|
||||
|
||||
cerr << dec << (int)myMindlinkShift << " : " << HEX2 << (int)myIOPort << endl;
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,95 @@
|
|||
//============================================================================
|
||||
//
|
||||
// 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-2012 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.
|
||||
//
|
||||
// $Id$
|
||||
//============================================================================
|
||||
|
||||
#ifndef MINDLINK_HXX
|
||||
#define MINDLINK_HXX
|
||||
|
||||
#include "bspf.hxx"
|
||||
#include "Control.hxx"
|
||||
|
||||
/**
|
||||
The Atari Mindlink was an unreleased video game controller intended for
|
||||
release in 1984. The Mindlink was unique in that one had to move the
|
||||
muscles in one's head to control the game. These movements would be read by
|
||||
infrared sensors and transferred as movement in the game. For more
|
||||
information, see the following link:
|
||||
|
||||
http://www.atarimuseum.com/videogames/consoles/2600/mindlink.html
|
||||
|
||||
This code was heavily borrowed from z26, and uses conventions defined
|
||||
there. Specifically, IOPortA is treated as a complete uInt8, whereas
|
||||
the Stella core actually stores this information in boolean arrays
|
||||
addressable by DigitalPin number.
|
||||
|
||||
@author Stephen Anthony & z26 team
|
||||
@version $Id$
|
||||
*/
|
||||
class MindLink : public Controller
|
||||
{
|
||||
public:
|
||||
/**
|
||||
Create a new MindLink controller plugged into the specified jack
|
||||
|
||||
@param jack The jack the controller is plugged into
|
||||
@param event The event object to use for events
|
||||
@param system The system using this controller
|
||||
*/
|
||||
MindLink(Jack jack, const Event& event, const System& system);
|
||||
|
||||
/**
|
||||
Destructor
|
||||
*/
|
||||
virtual ~MindLink();
|
||||
|
||||
public:
|
||||
/**
|
||||
Called after *all* digital pins have been written on Port A.
|
||||
*/
|
||||
void controlWrite() { nextMindlinkBit(); }
|
||||
|
||||
/**
|
||||
Update the entire digital and analog pin state according to the
|
||||
events currently set.
|
||||
*/
|
||||
void update();
|
||||
|
||||
private:
|
||||
void nextMindlinkBit();
|
||||
|
||||
private:
|
||||
uInt8 myMask1, myMask2, myMask3;
|
||||
|
||||
// Internal state of the port pins
|
||||
uInt8 myIOPort;
|
||||
|
||||
// Position value in Mindlink controller
|
||||
// Gets transferred bitwise (16 bits)
|
||||
int myMindlinkPos;
|
||||
|
||||
// Position for player 1 (0x2800-0x3800)
|
||||
int myMindlinkPos1;
|
||||
|
||||
// Position for player 2 (0x1000-0x2000)
|
||||
int myMindlinkPos2;
|
||||
|
||||
// Which bit to transfer next
|
||||
int myMindlinkShift;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -29,23 +29,11 @@ TrackBall::TrackBall(Jack jack, const Event& event, const System& system,
|
|||
Type type)
|
||||
: Controller(jack, event, system, type),
|
||||
myHCounter(0),
|
||||
myVCounter(0),
|
||||
myCyclesWhenSWCHARead(0)
|
||||
myVCounter(0)
|
||||
{
|
||||
if(myJack == Left)
|
||||
{
|
||||
myPin1Mask = 0x10;
|
||||
myPin2Mask = 0x20;
|
||||
myPin3Mask = 0x40;
|
||||
myPin4Mask = 0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
myPin1Mask = 0x01;
|
||||
myPin2Mask = 0x02;
|
||||
myPin3Mask = 0x04;
|
||||
myPin4Mask = 0x08;
|
||||
}
|
||||
// This code in ::read() is set up to always return IOPortA values in
|
||||
// the lower 4 bits data value
|
||||
// As such, the jack type (left or right) isn't necessary here
|
||||
|
||||
myTrakBallCountH = myTrakBallCountV = 0;
|
||||
myTrakBallLinesH = myTrakBallLinesV = 1;
|
||||
|
@ -63,76 +51,65 @@ TrackBall::~TrackBall()
|
|||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
bool TrackBall::read(DigitalPin pin)
|
||||
uInt8 TrackBall::read()
|
||||
{
|
||||
// Only update the controller pins when an SWCHA read is actually
|
||||
// different from a previous one
|
||||
// This is done since Stella tends to read several pins consecutively
|
||||
// in the same processor 'cycle', and it would be incorrect to do this
|
||||
// work multiple times per processor cycle
|
||||
if(myCyclesWhenSWCHARead != mySystem.cycles())
|
||||
int scanline = ((System&)mySystem).tia().scanlines();
|
||||
|
||||
if(myScanCountV > scanline) myScanCountV = 0;
|
||||
if(myScanCountH > scanline) myScanCountH = 0;
|
||||
while((myScanCountV + myTrakBallLinesV) < scanline)
|
||||
{
|
||||
int scanline = ((System&)mySystem).tia().scanlines();
|
||||
|
||||
if(myScanCountV > scanline) myScanCountV = 0;
|
||||
if(myScanCountH > scanline) myScanCountH = 0;
|
||||
while((myScanCountV + myTrakBallLinesV) < scanline)
|
||||
if(myTrakBallCountV)
|
||||
{
|
||||
if(myTrakBallCountV)
|
||||
{
|
||||
if(myTrakBallDown) myCountV--;
|
||||
else myCountV++;
|
||||
myTrakBallCountV--;
|
||||
}
|
||||
myScanCountV += myTrakBallLinesV;
|
||||
if(myTrakBallDown) myCountV--;
|
||||
else myCountV++;
|
||||
myTrakBallCountV--;
|
||||
}
|
||||
myScanCountV += myTrakBallLinesV;
|
||||
}
|
||||
|
||||
while((myScanCountH + myTrakBallLinesH) < scanline)
|
||||
while((myScanCountH + myTrakBallLinesH) < scanline)
|
||||
{
|
||||
if(myTrakBallCountH)
|
||||
{
|
||||
if(myTrakBallCountH)
|
||||
{
|
||||
if(myTrakBallLeft) myCountH--;
|
||||
else myCountH++;
|
||||
myTrakBallCountH--;
|
||||
}
|
||||
myScanCountH += myTrakBallLinesH;
|
||||
if(myTrakBallLeft) myCountH--;
|
||||
else myCountH++;
|
||||
myTrakBallCountH--;
|
||||
}
|
||||
|
||||
myCountV &= 0x03;
|
||||
myCountH &= 0x03;
|
||||
|
||||
uInt8 IOPortA = 0x00;
|
||||
switch(myType)
|
||||
{
|
||||
case Controller::TrackBall80:
|
||||
IOPortA = IOPortA
|
||||
| ourTrakBallTableST_V[myCountV]
|
||||
| ourTrakBallTableST_H[myCountH];
|
||||
break;
|
||||
case Controller::TrackBall22:
|
||||
IOPortA = IOPortA
|
||||
| ourTrakBallTableTB_V[myCountV & 0x01][myTrakBallDown]
|
||||
| ourTrakBallTableTB_H[myCountH & 0x01][myTrakBallLeft];
|
||||
break;
|
||||
case Controller::AmigaMouse:
|
||||
IOPortA = IOPortA
|
||||
| ourTrakBallTableAM_V[myCountV]
|
||||
| ourTrakBallTableAM_H[myCountH];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
myDigitalPinState[One] = IOPortA & myPin1Mask;
|
||||
myDigitalPinState[Two] = IOPortA & myPin2Mask;
|
||||
myDigitalPinState[Three] = IOPortA & myPin3Mask;
|
||||
myDigitalPinState[Four] = IOPortA & myPin4Mask;
|
||||
myScanCountH += myTrakBallLinesH;
|
||||
}
|
||||
|
||||
// Remember when the SWCHA read was issued
|
||||
myCyclesWhenSWCHARead = mySystem.cycles();
|
||||
myCountV &= 0x03;
|
||||
myCountH &= 0x03;
|
||||
|
||||
return Controller::read(pin);
|
||||
uInt8 IOPortA = 0x00;
|
||||
switch(myType)
|
||||
{
|
||||
case Controller::TrackBall80:
|
||||
IOPortA = IOPortA
|
||||
| ourTrakBallTableST_V[myCountV]
|
||||
| ourTrakBallTableST_H[myCountH];
|
||||
break;
|
||||
case Controller::TrackBall22:
|
||||
IOPortA = IOPortA
|
||||
| ourTrakBallTableTB_V[myCountV & 0x01][myTrakBallDown]
|
||||
| ourTrakBallTableTB_H[myCountH & 0x01][myTrakBallLeft];
|
||||
break;
|
||||
case Controller::AmigaMouse:
|
||||
IOPortA = IOPortA
|
||||
| ourTrakBallTableAM_V[myCountV]
|
||||
| ourTrakBallTableAM_H[myCountH];
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
myDigitalPinState[One] = IOPortA & 0x10;
|
||||
myDigitalPinState[Two] = IOPortA & 0x20;
|
||||
myDigitalPinState[Three] = IOPortA & 0x40;
|
||||
myDigitalPinState[Four] = IOPortA & 0x80;
|
||||
|
||||
return myJack == Left ? IOPortA : (IOPortA >> 4);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
|
@ -157,13 +134,6 @@ void TrackBall::update()
|
|||
myDigitalPinState[Six] = (myEvent.get(Event::MouseButtonValue) == 0);
|
||||
}
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
void TrackBall::systemCyclesReset()
|
||||
{
|
||||
myCyclesWhenSWCHARead -= mySystem.cycles();
|
||||
}
|
||||
|
||||
|
||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
const uInt32 TrackBall::ourTrakBallTableTB_H[2][2] = {
|
||||
{ 0x40, 0x00 }, { 0xc0, 0x80 }
|
||||
|
|
|
@ -58,12 +58,20 @@ class TrackBall : public Controller
|
|||
|
||||
public:
|
||||
/**
|
||||
Read the value of the specified digital pin for this controller.
|
||||
Read the entire state of all digital pins for this controller.
|
||||
|
||||
@param pin The pin of the controller jack to read
|
||||
@return The state of the pin
|
||||
Note that this method must take into account the location of the
|
||||
pin data in the bitfield, and zero the remaining data:
|
||||
|
||||
Left port : upper 4 bits valid, lower 4 bits zero'ed
|
||||
Right port: lower 4 bits valid, upper 4 bits zero'ed
|
||||
|
||||
This method completely takes over reading of the port;
|
||||
it doesn't call Controller::read() at all.
|
||||
|
||||
@return The state of all digital pins
|
||||
*/
|
||||
bool read(DigitalPin pin);
|
||||
uInt8 read();
|
||||
|
||||
/**
|
||||
Update the entire digital and analog pin state according to the
|
||||
|
@ -71,24 +79,10 @@ class TrackBall : public Controller
|
|||
*/
|
||||
void update();
|
||||
|
||||
/**
|
||||
Notification method invoked by the system right before the
|
||||
system resets its cycle counter to zero. It may be necessary
|
||||
to override this method for devices that remember cycle counts.
|
||||
*/
|
||||
void systemCyclesReset();
|
||||
|
||||
private:
|
||||
// Counter to iterate through the gray codes
|
||||
int myHCounter, myVCounter;
|
||||
|
||||
// Indicates the processor cycle when SWCHA was last read
|
||||
uInt32 myCyclesWhenSWCHARead;
|
||||
|
||||
// Masks to indicate how to access the pins (differentiate between
|
||||
// left and right ports)
|
||||
uInt8 myPin1Mask, myPin2Mask, myPin3Mask, myPin4Mask;
|
||||
|
||||
// How many new horizontal and vertical values this frame
|
||||
int myTrakBallCountH, myTrakBallCountV;
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ MODULE_OBJS := \
|
|||
src/emucore/CartUA.o \
|
||||
src/emucore/Cart0840.o \
|
||||
src/emucore/CartX07.o \
|
||||
src/emucore/CompuMate.o \
|
||||
src/emucore/Console.o \
|
||||
src/emucore/Control.o \
|
||||
src/emucore/Driving.o \
|
||||
|
@ -41,6 +42,7 @@ MODULE_OBJS := \
|
|||
src/emucore/Joystick.o \
|
||||
src/emucore/Keyboard.o \
|
||||
src/emucore/KidVid.o \
|
||||
src/emucore/MindLink.o \
|
||||
src/emucore/M6502.o \
|
||||
src/emucore/M6532.o \
|
||||
src/emucore/MT24LC256.o \
|
||||
|
|
|
@ -238,7 +238,9 @@ GameInfoDialog::GameInfoDialog(
|
|||
ctrls.push_back("AtariVox", "ATARIVOX" );
|
||||
ctrls.push_back("SaveKey", "SAVEKEY" );
|
||||
ctrls.push_back("Sega Genesis", "GENESIS" );
|
||||
// TODO ctrls.push_back("KidVid", "KIDVID" );
|
||||
// ctrls.push_back("CompuMate", "COMPUMATE" );
|
||||
// ctrls.push_back("KidVid", "KIDVID" );
|
||||
// ctrls.push_back("MindLink", "MINDLINK" );
|
||||
myP0Controller = new PopUpWidget(myTab, font, xpos+lwidth, ypos,
|
||||
pwidth, lineHeight, ctrls, "", 0, 0);
|
||||
wid.push_back(myP0Controller);
|
||||
|
|
Loading…
Reference in New Issue