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:
Christian Speckner 2017-07-22 00:35:55 +02:00
parent 706755ad7f
commit 0d5d3de420
22 changed files with 148 additions and 67 deletions

View File

@ -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;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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);
} }
} }

View File

@ -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);
}
} }

View File

@ -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();
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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);
}
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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];

View File

@ -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;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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);
} }
} }

View File

@ -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;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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);
} }

View File

@ -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;

View File

@ -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;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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"

View File

@ -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;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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];

View File

@ -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;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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;
} }
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@ -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)

View File

@ -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()
); );

View File

@ -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.