mirror of https://github.com/stella-emu/stella.git
Analog input refactoring and improvements
* Lazily update readout circuit simulation as soon as the pin changes * Always assume that "max resistance" means "connected to ground" * Minor accuracy improvements
This commit is contained in:
parent
706755ad7f
commit
0d5d3de420
|
@ -36,9 +36,6 @@ AmigaMouse::AmigaMouse(Jack jack, const Event& event, const System& system)
|
||||||
|
|
||||||
myTrakBallLeft = myTrakBallDown = myScanCountV = myScanCountH =
|
myTrakBallLeft = myTrakBallDown = myScanCountV = myScanCountH =
|
||||||
myCountV = myCountH = 0;
|
myCountV = myCountH = 0;
|
||||||
|
|
||||||
// Analog pins are never used by the trakball controller
|
|
||||||
myAnalogPinValue[Five] = myAnalogPinValue[Nine] = maximumResistance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -36,9 +36,6 @@ AtariMouse::AtariMouse(Jack jack, const Event& event, const System& system)
|
||||||
|
|
||||||
myTrakBallLeft = myTrakBallDown = myScanCountV = myScanCountH =
|
myTrakBallLeft = myTrakBallDown = myScanCountV = myScanCountH =
|
||||||
myCountV = myCountH = 0;
|
myCountV = myCountH = 0;
|
||||||
|
|
||||||
// Analog pins are never used by the Atari ST mouse controller
|
|
||||||
myAnalogPinValue[Five] = myAnalogPinValue[Nine] = maximumResistance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -39,8 +39,6 @@ AtariVox::AtariVox(Jack jack, const Event& event, const System& system,
|
||||||
|
|
||||||
myDigitalPinState[One] = myDigitalPinState[Two] =
|
myDigitalPinState[One] = myDigitalPinState[Two] =
|
||||||
myDigitalPinState[Three] = myDigitalPinState[Four] = true;
|
myDigitalPinState[Three] = myDigitalPinState[Four] = true;
|
||||||
|
|
||||||
myAnalogPinValue[Five] = myAnalogPinValue[Nine] = maximumResistance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -61,10 +61,14 @@ void BoosterGrip::update()
|
||||||
|
|
||||||
// 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.
|
||||||
myAnalogPinValue[Five] = (myEvent.get(myTriggerEvent) != 0) ?
|
updateAnalogPin(
|
||||||
minimumResistance : maximumResistance;
|
Five,
|
||||||
myAnalogPinValue[Nine] = (myEvent.get(myBoosterEvent) != 0) ?
|
(myEvent.get(myTriggerEvent) != 0) ? minimumResistance : maximumResistance
|
||||||
minimumResistance : maximumResistance;
|
);
|
||||||
|
updateAnalogPin(
|
||||||
|
Nine,
|
||||||
|
(myEvent.get(myBoosterEvent) != 0) ? minimumResistance : maximumResistance
|
||||||
|
);
|
||||||
|
|
||||||
// Axis events (usually generated by the Stelladaptor)
|
// Axis events (usually generated by the Stelladaptor)
|
||||||
int xaxis = myEvent.get(myXAxisValue);
|
int xaxis = myEvent.get(myXAxisValue);
|
||||||
|
@ -117,7 +121,7 @@ void BoosterGrip::update()
|
||||||
if(myEvent.get(Event::MouseButtonLeftValue))
|
if(myEvent.get(Event::MouseButtonLeftValue))
|
||||||
myDigitalPinState[Six] = false;
|
myDigitalPinState[Six] = false;
|
||||||
if(myEvent.get(Event::MouseButtonRightValue))
|
if(myEvent.get(Event::MouseButtonRightValue))
|
||||||
myAnalogPinValue[Nine] = minimumResistance;
|
updateAnalogPin(Nine, minimumResistance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,10 +32,10 @@ CompuMate::CompuMate(const Console& console, const Event& event,
|
||||||
myLeftController = make_ptr<CMControl>(*this, Controller::Left, event, system);
|
myLeftController = make_ptr<CMControl>(*this, Controller::Left, event, system);
|
||||||
myRightController = make_ptr<CMControl>(*this, Controller::Right, event, system);
|
myRightController = make_ptr<CMControl>(*this, Controller::Right, event, system);
|
||||||
|
|
||||||
myLeftController->myAnalogPinValue[Controller::Nine] = Controller::maximumResistance;
|
myLeftController->updateAnalogPin(Controller::Nine, Controller::maximumResistance);
|
||||||
myLeftController->myAnalogPinValue[Controller::Five] = Controller::minimumResistance;
|
myLeftController->updateAnalogPin(Controller::Five, Controller::minimumResistance);
|
||||||
myRightController->myAnalogPinValue[Controller::Nine] = Controller::minimumResistance;
|
myRightController->updateAnalogPin(Controller::Nine, Controller::minimumResistance);
|
||||||
myRightController->myAnalogPinValue[Controller::Five] = Controller::maximumResistance;
|
myRightController->updateAnalogPin(Controller::Five, Controller::maximumResistance);
|
||||||
|
|
||||||
enableKeyHandling(false);
|
enableKeyHandling(false);
|
||||||
}
|
}
|
||||||
|
@ -61,6 +61,7 @@ void CompuMate::update()
|
||||||
Controller& lp = myConsole.leftController();
|
Controller& lp = myConsole.leftController();
|
||||||
Controller& rp = myConsole.rightController();
|
Controller& rp = myConsole.rightController();
|
||||||
|
|
||||||
|
|
||||||
lp.myAnalogPinValue[Controller::Nine] = Controller::maximumResistance;
|
lp.myAnalogPinValue[Controller::Nine] = Controller::maximumResistance;
|
||||||
lp.myAnalogPinValue[Controller::Five] = Controller::minimumResistance;
|
lp.myAnalogPinValue[Controller::Five] = Controller::minimumResistance;
|
||||||
lp.myDigitalPinState[Controller::Six] = true;
|
lp.myDigitalPinState[Controller::Six] = true;
|
||||||
|
@ -196,4 +197,14 @@ void CompuMate::update()
|
||||||
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -855,6 +855,8 @@ void Console::setControllers(const string& rommd5)
|
||||||
myLeftControl = std::move(rightC);
|
myLeftControl = std::move(rightC);
|
||||||
myRightControl = std::move(leftC);
|
myRightControl = std::move(leftC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
myTIA->bindToControllers();
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -26,7 +26,8 @@ Controller::Controller(Jack jack, const Event& event, const System& system,
|
||||||
: myJack(jack),
|
: myJack(jack),
|
||||||
myEvent(event),
|
myEvent(event),
|
||||||
mySystem(system),
|
mySystem(system),
|
||||||
myType(type)
|
myType(type),
|
||||||
|
myOnAnalogPinUpdateCallback(0)
|
||||||
{
|
{
|
||||||
myDigitalPinState[One] =
|
myDigitalPinState[One] =
|
||||||
myDigitalPinState[Two] =
|
myDigitalPinState[Two] =
|
||||||
|
@ -115,8 +116,18 @@ void Controller::set(DigitalPin pin, bool value)
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void Controller::set(AnalogPin pin, Int32 value)
|
void Controller::set(AnalogPin pin, Int32 value)
|
||||||
|
{
|
||||||
|
updateAnalogPin(pin, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void Controller::updateAnalogPin(AnalogPin pin, Int32 value)
|
||||||
{
|
{
|
||||||
myAnalogPinValue[pin] = value;
|
myAnalogPinValue[pin] = value;
|
||||||
|
|
||||||
|
if (myOnAnalogPinUpdateCallback) {
|
||||||
|
myOnAnalogPinUpdateCallback(pin);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -22,6 +22,8 @@ class Controller;
|
||||||
class Event;
|
class Event;
|
||||||
class System;
|
class System;
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
|
|
||||||
#include "Serializable.hxx"
|
#include "Serializable.hxx"
|
||||||
#include "bspf.hxx"
|
#include "bspf.hxx"
|
||||||
|
|
||||||
|
@ -92,6 +94,11 @@ class Controller : public Serializable
|
||||||
Paddles, SaveKey, TrakBall
|
Paddles, SaveKey, TrakBall
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
Callback type for analog pin updates
|
||||||
|
*/
|
||||||
|
using onAnalogPinUpdateCallback = std::function<void(AnalogPin)>;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
Create a new controller plugged into the specified jack
|
Create a new controller plugged into the specified jack
|
||||||
|
@ -237,6 +244,13 @@ class Controller : public Serializable
|
||||||
*/
|
*/
|
||||||
string name() const override { return myName; }
|
string name() const override { return myName; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
Inject a callback to be notified on analog pin updates.
|
||||||
|
*/
|
||||||
|
void setOnAnalogPinUpdateCallback(onAnalogPinUpdateCallback callback) {
|
||||||
|
myOnAnalogPinUpdateCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// Constant which represents maximum resistance for analog pins
|
/// Constant which represents maximum resistance for analog pins
|
||||||
static constexpr Int32 maximumResistance = 0x7FFFFFFF;
|
static constexpr Int32 maximumResistance = 0x7FFFFFFF;
|
||||||
|
@ -244,6 +258,9 @@ class Controller : public Serializable
|
||||||
/// Constant which represents minimum resistance for analog pins
|
/// Constant which represents minimum resistance for analog pins
|
||||||
static constexpr Int32 minimumResistance = 0x00000000;
|
static constexpr Int32 minimumResistance = 0x00000000;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void updateAnalogPin(AnalogPin, Int32 value);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Specifies which jack the controller is plugged in
|
/// Specifies which jack the controller is plugged in
|
||||||
const Jack myJack;
|
const Jack myJack;
|
||||||
|
@ -263,6 +280,10 @@ class Controller : public Serializable
|
||||||
/// The boolean value on each digital pin
|
/// The boolean value on each digital pin
|
||||||
bool myDigitalPinState[5];
|
bool myDigitalPinState[5];
|
||||||
|
|
||||||
|
/// The callback that is dispatched whenver an analog pin has changed
|
||||||
|
onAnalogPinUpdateCallback myOnAnalogPinUpdateCallback;
|
||||||
|
|
||||||
|
private:
|
||||||
/// The analog value on each analog pin
|
/// The analog value on each analog pin
|
||||||
Int32 myAnalogPinValue[2];
|
Int32 myAnalogPinValue[2];
|
||||||
|
|
||||||
|
|
|
@ -49,9 +49,6 @@ 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;
|
myDigitalPinState[Three] = myDigitalPinState[Four] = true;
|
||||||
|
|
||||||
// Analog pins are not connected
|
|
||||||
myAnalogPinValue[Five] = myAnalogPinValue[Nine] = maximumResistance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -41,11 +41,6 @@ Genesis::Genesis(Jack jack, const Event& event, const System& system)
|
||||||
myFire1Event = Event::JoystickOneFire;
|
myFire1Event = Event::JoystickOneFire;
|
||||||
myFire2Event = Event::JoystickOneFire5;
|
myFire2Event = Event::JoystickOneFire5;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Analog pin 9 is not connected to this controller at all
|
|
||||||
// Analog pin 5 corresponds to button 'C' on the gamepad, and corresponds
|
|
||||||
// to the 'booster' button on a BoosterGrip controller
|
|
||||||
myAnalogPinValue[Five] = myAnalogPinValue[Nine] = maximumResistance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
@ -61,8 +56,10 @@ void Genesis::update()
|
||||||
// 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
|
||||||
myAnalogPinValue[Five] = (myEvent.get(myFire2Event) == 0) ?
|
updateAnalogPin(
|
||||||
minimumResistance : maximumResistance;
|
Five,
|
||||||
|
(myEvent.get(myFire2Event) == 0) ? minimumResistance : maximumResistance
|
||||||
|
);
|
||||||
|
|
||||||
// Mouse motion and button events
|
// Mouse motion and button events
|
||||||
if(myControlID > -1)
|
if(myControlID > -1)
|
||||||
|
@ -93,7 +90,7 @@ void Genesis::update()
|
||||||
if(myEvent.get(Event::MouseButtonLeftValue))
|
if(myEvent.get(Event::MouseButtonLeftValue))
|
||||||
myDigitalPinState[Six] = false;
|
myDigitalPinState[Six] = false;
|
||||||
if(myEvent.get(Event::MouseButtonRightValue))
|
if(myEvent.get(Event::MouseButtonRightValue))
|
||||||
myAnalogPinValue[Five] = maximumResistance;
|
updateAnalogPin(Five, maximumResistance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,9 +43,6 @@ Joystick::Joystick(Jack jack, const Event& event, const System& system)
|
||||||
myXAxisValue = Event::SARightAxis0Value;
|
myXAxisValue = Event::SARightAxis0Value;
|
||||||
myYAxisValue = Event::SARightAxis1Value;
|
myYAxisValue = Event::SARightAxis1Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Analog pins are never used by the joystick
|
|
||||||
myAnalogPinValue[Five] = myAnalogPinValue[Nine] = maximumResistance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -61,32 +61,39 @@ void Keyboard::write(DigitalPin pin, bool value)
|
||||||
|
|
||||||
// Set defaults
|
// Set defaults
|
||||||
myDigitalPinState[Six] = true;
|
myDigitalPinState[Six] = true;
|
||||||
myAnalogPinValue[Five] = minimumResistance;
|
Int32 resistanceFive = MIN_RESISTANCE;
|
||||||
myAnalogPinValue[Nine] = minimumResistance;
|
Int32 resistanceNine = MIN_RESISTANCE;
|
||||||
|
|
||||||
// Now scan the rows and columns
|
// Now scan the rows and columns
|
||||||
if(!myDigitalPinState[Four])
|
if(!myDigitalPinState[Four])
|
||||||
{
|
{
|
||||||
myDigitalPinState[Six] = (myEvent.get(myPoundEvent) == 0);
|
myDigitalPinState[Six] = (myEvent.get(myPoundEvent) == 0);
|
||||||
if(myEvent.get(myZeroEvent) != 0) myAnalogPinValue[Five] = maximumResistance;
|
if(myEvent.get(myZeroEvent) != 0) resistanceFive = maximumResistance;
|
||||||
if(myEvent.get(myStarEvent) != 0) myAnalogPinValue[Nine] = maximumResistance;
|
if(myEvent.get(myStarEvent) != 0) resistanceNine = maximumResistance;
|
||||||
}
|
}
|
||||||
if(!myDigitalPinState[Three])
|
if(!myDigitalPinState[Three])
|
||||||
{
|
{
|
||||||
myDigitalPinState[Six] = (myEvent.get(myNineEvent) == 0);
|
myDigitalPinState[Six] = (myEvent.get(myNineEvent) == 0);
|
||||||
if(myEvent.get(myEightEvent) != 0) myAnalogPinValue[Five] = maximumResistance;
|
if(myEvent.get(myEightEvent) != 0) resistanceFive = maximumResistance;
|
||||||
if(myEvent.get(mySevenEvent) != 0) myAnalogPinValue[Nine] = maximumResistance;
|
if(myEvent.get(mySevenEvent) != 0) resistanceNine = maximumResistance;
|
||||||
}
|
}
|
||||||
if(!myDigitalPinState[Two])
|
if(!myDigitalPinState[Two])
|
||||||
{
|
{
|
||||||
myDigitalPinState[Six] = (myEvent.get(mySixEvent) == 0);
|
myDigitalPinState[Six] = (myEvent.get(mySixEvent) == 0);
|
||||||
if(myEvent.get(myFiveEvent) != 0) myAnalogPinValue[Five] = maximumResistance;
|
if(myEvent.get(myFiveEvent) != 0) resistanceFive = maximumResistance;
|
||||||
if(myEvent.get(myFourEvent) != 0) myAnalogPinValue[Nine] = maximumResistance;
|
if(myEvent.get(myFourEvent) != 0) resistanceNine = maximumResistance;
|
||||||
}
|
}
|
||||||
if(!myDigitalPinState[One])
|
if(!myDigitalPinState[One])
|
||||||
{
|
{
|
||||||
myDigitalPinState[Six] = (myEvent.get(myThreeEvent) == 0);
|
myDigitalPinState[Six] = (myEvent.get(myThreeEvent) == 0);
|
||||||
if(myEvent.get(myTwoEvent) != 0) myAnalogPinValue[Five] = maximumResistance;
|
if(myEvent.get(myTwoEvent) != 0) resistanceFive = maximumResistance;
|
||||||
if(myEvent.get(myOneEvent) != 0) myAnalogPinValue[Nine] = maximumResistance;
|
if(myEvent.get(myOneEvent) != 0) resistanceNine = maximumResistance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (resistanceFive != read(Five)) {
|
||||||
|
updateAnalogPin(Five, resistanceFive);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resistanceNine != read(Nine))
|
||||||
|
updateAnalogPin(Nine, resistanceNine);
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,8 @@ class Keyboard : public Controller
|
||||||
mySevenEvent, myEightEvent, myNineEvent,
|
mySevenEvent, myEightEvent, myNineEvent,
|
||||||
myStarEvent, myZeroEvent, myPoundEvent;
|
myStarEvent, myZeroEvent, myPoundEvent;
|
||||||
|
|
||||||
|
static constexpr Int32 MIN_RESISTANCE = 5600;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// Following constructors and assignment operators not supported
|
// Following constructors and assignment operators not supported
|
||||||
Keyboard() = delete;
|
Keyboard() = delete;
|
||||||
|
|
|
@ -46,10 +46,6 @@ KidVid::KidVid(Jack jack, const Event& event, const System& system,
|
||||||
myGame = KVSMURFS; // Smurfs Save the Day
|
myGame = KVSMURFS; // Smurfs Save the Day
|
||||||
else
|
else
|
||||||
myEnabled = false;
|
myEnabled = false;
|
||||||
|
|
||||||
// Analog pins are never used by the KidVid controller
|
|
||||||
// (at least not in this implementation)
|
|
||||||
myAnalogPinValue[Five] = myAnalogPinValue[Nine] = maximumResistance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <bitset>
|
||||||
|
|
||||||
#include "Console.hxx"
|
#include "Console.hxx"
|
||||||
#include "Settings.hxx"
|
#include "Settings.hxx"
|
||||||
|
|
|
@ -29,9 +29,6 @@ MindLink::MindLink(Jack jack, const Event& event, const System& system)
|
||||||
myDigitalPinState[Two] = true;
|
myDigitalPinState[Two] = true;
|
||||||
myDigitalPinState[Three] = true;
|
myDigitalPinState[Three] = true;
|
||||||
myDigitalPinState[Four] = true;
|
myDigitalPinState[Four] = true;
|
||||||
|
|
||||||
// Analog pins are never used by the MindLink
|
|
||||||
myAnalogPinValue[Five] = myAnalogPinValue[Nine] = maximumResistance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -28,7 +28,8 @@ Paddles::Paddles(Jack jack, const Event& event, const System& system,
|
||||||
{
|
{
|
||||||
// We must start with minimum resistance; see commit
|
// We must start with minimum resistance; see commit
|
||||||
// 38b452e1a047a0dca38c5bcce7c271d40f76736e for more information
|
// 38b452e1a047a0dca38c5bcce7c271d40f76736e for more information
|
||||||
myAnalogPinValue[Nine] = myAnalogPinValue[Five] = minimumResistance;
|
updateAnalogPin(Five, minimumResistance);
|
||||||
|
updateAnalogPin(Nine, minimumResistance);
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -260,12 +261,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)
|
||||||
{
|
{
|
||||||
myAnalogPinValue[Nine] = Int32(MAX_RESISTANCE * ((32767 - Int16(sa_xaxis)) / 65536.0));
|
updateAnalogPin(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)
|
||||||
{
|
{
|
||||||
myAnalogPinValue[Five] = Int32(MAX_RESISTANCE * ((32767 - Int16(sa_yaxis)) / 65536.0));
|
updateAnalogPin(Five, Int32(MAX_RESISTANCE * ((32767 - Int16(sa_yaxis)) / 65536.0)));
|
||||||
sa_changed = true;
|
sa_changed = true;
|
||||||
}
|
}
|
||||||
myLastAxisX = sa_xaxis;
|
myLastAxisX = sa_xaxis;
|
||||||
|
@ -352,11 +353,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])
|
||||||
myAnalogPinValue[Five] =
|
updateAnalogPin(Five, Int32(MAX_RESISTANCE * (myCharge[1] / float(TRIGMAX))));
|
||||||
Int32(MAX_RESISTANCE * (myCharge[1] / float(TRIGMAX)));
|
|
||||||
if(myCharge[0] != myLastCharge[0])
|
if(myCharge[0] != myLastCharge[0])
|
||||||
myAnalogPinValue[Nine] =
|
updateAnalogPin(Nine, Int32(MAX_RESISTANCE * (myCharge[0] / float(TRIGMAX))));
|
||||||
Int32(MAX_RESISTANCE * (myCharge[0] / float(TRIGMAX)));
|
|
||||||
|
|
||||||
myLastCharge[1] = myCharge[1];
|
myLastCharge[1] = myCharge[1];
|
||||||
myLastCharge[0] = myCharge[0];
|
myLastCharge[0] = myCharge[0];
|
||||||
|
|
|
@ -27,7 +27,6 @@ SaveKey::SaveKey(Jack jack, const Event& event, const System& system,
|
||||||
myEEPROM = make_ptr<MT24LC256>(eepromfile, system);
|
myEEPROM = make_ptr<MT24LC256>(eepromfile, system);
|
||||||
|
|
||||||
myDigitalPinState[One] = myDigitalPinState[Two] = true;
|
myDigitalPinState[One] = myDigitalPinState[Two] = true;
|
||||||
myAnalogPinValue[Five] = myAnalogPinValue[Nine] = maximumResistance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -38,9 +38,6 @@ TrakBall::TrakBall(Jack jack, const Event& event, const System& system)
|
||||||
|
|
||||||
myTrakBallLeft = myTrakBallDown = myScanCountV = myScanCountH =
|
myTrakBallLeft = myTrakBallDown = myScanCountV = myScanCountH =
|
||||||
myCountV = myCountH = 0;
|
myCountV = myCountH = 0;
|
||||||
|
|
||||||
// Analog pins are never used by the trakball controller
|
|
||||||
myAnalogPinValue[Five] = myAnalogPinValue[Nine] = maximumResistance;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
|
@ -22,10 +22,10 @@
|
||||||
static constexpr double
|
static constexpr double
|
||||||
C = 68e-9,
|
C = 68e-9,
|
||||||
RPOT = 1e6,
|
RPOT = 1e6,
|
||||||
R0 = 1.8e3,
|
R0 = 1.5e3,
|
||||||
USUPP = 5;
|
USUPP = 5;
|
||||||
|
|
||||||
static constexpr double TRIPPOINT_LINES = 380;
|
static constexpr double TRIPPOINT_LINES = 379;
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
PaddleReader::PaddleReader()
|
PaddleReader::PaddleReader()
|
||||||
|
@ -79,9 +79,18 @@ void PaddleReader::update(double value, double timestamp, ConsoleTiming consoleT
|
||||||
|
|
||||||
if (value != myValue) {
|
if (value != myValue) {
|
||||||
myValue = value;
|
myValue = value;
|
||||||
|
|
||||||
|
if (myValue < 0) {
|
||||||
|
// value < 0 signifies either maximum resistance OR analog input connected to
|
||||||
|
// ground (keyboard controllers). As we have no way to tell these apart we just
|
||||||
|
// assume ground and discharge.
|
||||||
|
myU = 0;
|
||||||
|
myTimestamp = timestamp;
|
||||||
|
} else {
|
||||||
updateCharge(timestamp);
|
updateCharge(timestamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
void PaddleReader::setConsoleTiming(ConsoleTiming consoleTiming)
|
void PaddleReader::setConsoleTiming(ConsoleTiming consoleTiming)
|
||||||
|
|
|
@ -334,6 +334,45 @@ bool TIA::load(Serializer& in)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
void TIA::bindToControllers()
|
||||||
|
{
|
||||||
|
myConsole.leftController().setOnAnalogPinUpdateCallback(
|
||||||
|
[this] (Controller::AnalogPin pin) {
|
||||||
|
TIA& tia = mySystem->tia();
|
||||||
|
|
||||||
|
switch (pin) {
|
||||||
|
case Controller::AnalogPin::Five:
|
||||||
|
tia.updatePaddle(1);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Controller::AnalogPin::Nine:
|
||||||
|
tia.updatePaddle(0);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
myConsole.rightController().setOnAnalogPinUpdateCallback(
|
||||||
|
[this] (Controller::AnalogPin pin) {
|
||||||
|
TIA& tia = mySystem->tia();
|
||||||
|
|
||||||
|
switch (pin) {
|
||||||
|
case Controller::AnalogPin::Five:
|
||||||
|
tia.updatePaddle(3);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Controller::AnalogPin::Nine:
|
||||||
|
tia.updatePaddle(2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
for (uInt8 i = 0; i < 4; i++)
|
||||||
|
updatePaddle(i);
|
||||||
|
}
|
||||||
|
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
uInt8 TIA::peek(uInt16 address)
|
uInt8 TIA::peek(uInt16 address)
|
||||||
{
|
{
|
||||||
|
@ -1032,9 +1071,6 @@ void TIA::onFrameStart()
|
||||||
{
|
{
|
||||||
myXAtRenderingStart = 0;
|
myXAtRenderingStart = 0;
|
||||||
|
|
||||||
for (uInt8 i = 0; i < 4; i++)
|
|
||||||
updatePaddle(i);
|
|
||||||
|
|
||||||
// Check for colour-loss emulation
|
// Check for colour-loss emulation
|
||||||
if (myColorLossEnabled)
|
if (myColorLossEnabled)
|
||||||
{
|
{
|
||||||
|
@ -1452,7 +1488,7 @@ void TIA::updatePaddle(uInt8 idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
myPaddleReaders[idx].update(
|
myPaddleReaders[idx].update(
|
||||||
(resistance == Controller::maximumResistance ? -1 : double(resistance)) / Paddles::MAX_RESISTANCE,
|
(resistance == Controller::maximumResistance) ? -1 : (double(resistance) / Paddles::MAX_RESISTANCE),
|
||||||
myTimestamp,
|
myTimestamp,
|
||||||
consoleTiming()
|
consoleTiming()
|
||||||
);
|
);
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "LatchedInput.hxx"
|
#include "LatchedInput.hxx"
|
||||||
#include "PaddleReader.hxx"
|
#include "PaddleReader.hxx"
|
||||||
#include "DelayQueueIterator.hxx"
|
#include "DelayQueueIterator.hxx"
|
||||||
|
#include "Control.hxx"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
This class is a device that emulates the Television Interface Adaptor
|
This class is a device that emulates the Television Interface Adaptor
|
||||||
|
@ -146,6 +147,11 @@ class TIA : public Device
|
||||||
*/
|
*/
|
||||||
void installDelegate(System& system, Device& device);
|
void installDelegate(System& system, Device& device);
|
||||||
|
|
||||||
|
/**
|
||||||
|
Bind to controllers.
|
||||||
|
*/
|
||||||
|
void bindToControllers();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
The following are very similar to save() and load(), except they
|
The following are very similar to save() and load(), except they
|
||||||
do a 'deeper' save of the display data itself.
|
do a 'deeper' save of the display data itself.
|
||||||
|
|
Loading…
Reference in New Issue