Further improvements to the trakball and friends cursor movement.

This commit is contained in:
Stephen Anthony 2017-07-30 20:19:00 -02:30
parent 5a5c520443
commit 6e4503f762
4 changed files with 73 additions and 49 deletions

View File

@ -34,7 +34,7 @@ namespace {
public: public:
static constexpr Controller::Type controllerType = Controller::AmigaMouse; static constexpr Controller::Type controllerType = Controller::AmigaMouse;
static constexpr uInt8 counterDivide = 2; static constexpr double trackballSensitivity = 0.8; // TODO: make configurable
}; };
} }

View File

@ -34,7 +34,7 @@ namespace {
public: public:
static constexpr Controller::Type controllerType = Controller::AtariMouse; static constexpr Controller::Type controllerType = Controller::AtariMouse;
static constexpr uInt8 counterDivide = 2; static constexpr double trackballSensitivity = 0.8; // TODO: make configurable
}; };
} }

View File

@ -74,14 +74,9 @@ class PointingDevice : public Controller
Controller::Type ytype, int yid) override; Controller::Type ytype, int yid) override;
private: private:
// Counter to iterate through the gray codes float myHCounterRemainder, myVCounterRemainder;
int myHCounter, myVCounter;
int myHCounterRemainder, myVCounterRemainder;
// How many new horizontal and vertical values this frame // How many lines to wait between sending new horz and vert values
int myTrakBallCountH, myTrakBallCountV;
// How many lines to wait before sending new horz and vert val
int myTrakBallLinesH, myTrakBallLinesV; int myTrakBallLinesH, myTrakBallLinesV;
// Was TrakBall moved left or moved right instead // Was TrakBall moved left or moved right instead
@ -90,6 +85,7 @@ class PointingDevice : public Controller
// Was TrakBall moved down or moved up instead // Was TrakBall moved down or moved up instead
uInt8 myTrakBallDown; uInt8 myTrakBallDown;
// Counter to iterate through the gray codes
uInt8 myCountH, myCountV; uInt8 myCountH, myCountV;
int myScanCountH, myScanCountV; int myScanCountH, myScanCountV;
@ -114,11 +110,8 @@ class PointingDevice : public Controller
template<class T> template<class T>
PointingDevice<T>::PointingDevice(Jack jack, const Event& event, const System& system) PointingDevice<T>::PointingDevice(Jack jack, const Event& event, const System& system)
: Controller(jack, event, system, T::controllerType), : Controller(jack, event, system, T::controllerType),
myHCounter(0), myHCounterRemainder(0.0),
myVCounter(0), myVCounterRemainder(0.0),
myHCounterRemainder(0),
myVCounterRemainder(0),
myTrakBallCountH(0), myTrakBallCountV(0),
myTrakBallLinesH(1), myTrakBallLinesV(1), myTrakBallLinesH(1), myTrakBallLinesV(1),
myTrakBallLeft(0), myTrakBallDown(0), myTrakBallLeft(0), myTrakBallDown(0),
myCountH(0), myCountV(0), myCountH(0), myCountV(0),
@ -136,34 +129,30 @@ uInt8 PointingDevice<T>::read()
{ {
int scanline = mySystem.tia().scanlines(); int scanline = mySystem.tia().scanlines();
if(myScanCountV > scanline) myScanCountV = 0; // Loop over all missed changes
if(myScanCountH > scanline) myScanCountH = 0; while(myScanCountH < scanline)
while((myScanCountV + myTrakBallLinesV) < scanline)
{ {
if(myTrakBallCountV) if(myTrakBallLeft) myCountH--;
{ else myCountH++;
if(myTrakBallDown) myCountV--;
else myCountV++;
myTrakBallCountV--;
}
myScanCountV += myTrakBallLinesV;
}
while((myScanCountH + myTrakBallLinesH) < scanline) // Define scanline of next change
{
if(myTrakBallCountH)
{
if(myTrakBallLeft) myCountH--;
else myCountH++;
myTrakBallCountH--;
}
myScanCountH += myTrakBallLinesH; myScanCountH += myTrakBallLinesH;
} }
myCountV &= 0x03; // Loop over all missed changes
myCountH &= 0x03; while(myScanCountV < scanline)
{
if(myTrakBallDown) myCountV--;
else myCountV++;
uInt8 ioPortA = T::ioPortA(myCountH, myCountV, myTrakBallLeft, myTrakBallDown); // Define scanline of next change
myScanCountV += myTrakBallLinesV;
}
myCountH &= 0x03;
myCountV &= 0x03;
uInt8 ioPortA = T::ioPortA(myCountV, myCountH, myTrakBallDown, myTrakBallLeft);
myDigitalPinState[One] = ioPortA & 0x10; myDigitalPinState[One] = ioPortA & 0x10;
myDigitalPinState[Two] = ioPortA & 0x20; myDigitalPinState[Two] = ioPortA & 0x20;
@ -181,22 +170,57 @@ void PointingDevice<T>::update()
return; return;
// Get the current mouse position // Get the current mouse position
myHCounter = myEvent.get(Event::MouseAxisXValue) + myHCounterRemainder; int hCounter = myEvent.get(Event::MouseAxisXValue);
myVCounter = myEvent.get(Event::MouseAxisYValue) + myVCounterRemainder; int vCounter = myEvent.get(Event::MouseAxisYValue);
myTrakBallDown = (myHCounter < 0) ? 0 : 1; // Apply sensitivity and calculate remainders
myTrakBallLeft = (myVCounter < 0) ? 1 : 0; float fTrakBallCountH = hCounter * T::trackballSensitivity + myHCounterRemainder;
int trakBallCountH = std::lround(fTrakBallCountH);
myHCounterRemainder = fTrakBallCountH - trakBallCountH;
myHCounterRemainder = myHCounter % T::counterDivide; float fTrakBallCountV = vCounter * T::trackballSensitivity + myVCounterRemainder;
myVCounterRemainder = myVCounter % T::counterDivide; int trakBallCountV = std::lround(fTrakBallCountV);
myVCounterRemainder = fTrakBallCountV - trakBallCountV;
myTrakBallCountH = abs(myVCounter / T::counterDivide); if(trakBallCountH)
myTrakBallCountV = abs(myHCounter / T::counterDivide); {
myTrakBallLeft = (trakBallCountH < 0) ? 0 : 1;
trakBallCountH = abs(trakBallCountH);
myTrakBallLinesH = mySystem.tia().scanlinesLastFrame() / (myTrakBallCountH + 1); // Calculate lines to wait between sending new horz values
if(myTrakBallLinesH == 0) myTrakBallLinesH = 1; myTrakBallLinesH = mySystem.tia().scanlinesLastFrame() / trakBallCountH;
myTrakBallLinesV = mySystem.tia().scanlinesLastFrame() / (myTrakBallCountV + 1);
if(myTrakBallLinesV == 0) myTrakBallLinesV = 1; // Set lower limit in case of (unrealistic) ultra fast mouse movements
if (myTrakBallLinesH == 0) myTrakBallLinesH = 1;
// Define random scanline of first change
myScanCountH = rand() % myTrakBallLinesH;
}
else
{
// Prevent any change
myScanCountH = INT_MAX;
}
if(trakBallCountV)
{
myTrakBallDown = (trakBallCountV < 0) ? 1 : 0;
trakBallCountV = abs(trakBallCountV);
// Calculate lines to wait between sending new vert values
myTrakBallLinesV = mySystem.tia().scanlinesLastFrame() / trakBallCountV;
// Set lower limit in case of (unrealistic) ultra fast mouse movements
if (myTrakBallLinesV == 0) myTrakBallLinesV = 1;
// Define random scanline of first change
myScanCountV = rand() % myTrakBallLinesV;
}
else
{
// Prevent any change
myScanCountV = INT_MAX;
}
// Get mouse button state // Get mouse button state
myDigitalPinState[Six] = (myEvent.get(Event::MouseButtonLeftValue) == 0) && myDigitalPinState[Six] = (myEvent.get(Event::MouseButtonLeftValue) == 0) &&

View File

@ -34,7 +34,7 @@ namespace {
public: public:
static constexpr Controller::Type controllerType = Controller::TrakBall; static constexpr Controller::Type controllerType = Controller::TrakBall;
static constexpr uInt8 counterDivide = 4; static constexpr double trackballSensitivity = 0.4; // 50% of Atari and Amiga mouse; TODO: make configurable
}; };
} }