1//============================================================================
2//
3// SSSS tt lll lll
4// SS SS tt ll ll
5// SS tttttt eeee ll ll aaaa
6// SSSS tt ee ee ll ll aa
7// SS tt eeeeee ll ll aaaaa -- "An Atari 2600 VCS Emulator"
8// SS SS tt ee ll ll aa aa
9// SSSS ttt eeeee llll llll aaaaa
10//
11// Copyright (c) 1995-2019 by Bradford W. Mott, Stephen Anthony
12// and the Stella Team
13//
14// See the file "License.txt" for information on usage and redistribution of
15// this file, and for a DISCLAIMER OF ALL WARRANTIES.
16//============================================================================
17
18#ifndef POINTING_DEVICE_HXX
19#define POINTING_DEVICE_HXX
20
21class Controller;
22class Event;
23
24#include "Control.hxx"
25#include "bspf.hxx"
26
27/**
28 Common controller class for pointing devices (Atari Mouse, Amiga Mouse, Trak-Ball)
29 This code was heavily borrowed from z26.
30
31 @author Stephen Anthony, Thomas Jentzsch & z26 team
32*/
33class PointingDevice : public Controller
34{
35 friend class PointingDeviceWidget;
36
37 public:
38 PointingDevice(Jack jack, const Event& event,
39 const System& system, Controller::Type type,
40 float sensitivity);
41 virtual ~PointingDevice() = default;
42
43 public:
44 using Controller::read;
45
46 /**
47 Read the entire state of all digital pins for this controller.
48 Note that this method must use the lower 4 bits, and zero the upper bits.
49
50 @return The state of all digital pins
51 */
52 uInt8 read() override;
53
54 /**
55 Update the entire digital and analog pin state according to the
56 events currently set.
57 */
58 void update() override;
59
60 /**
61 Answers whether the controller is intrinsically an analog controller.
62 */
63 bool isAnalog() const override { return true; }
64
65 /**
66 Determines how this controller will treat values received from the
67 X/Y axis and left/right buttons of the mouse. Since not all controllers
68 use the mouse the same way (or at all), it's up to the specific class to
69 decide how to use this data.
70
71 In the current implementation, the left button is tied to the X axis,
72 and the right one tied to the Y axis.
73
74 @param xtype The controller to use for x-axis data
75 @param xid The controller ID to use for x-axis data (-1 for no id)
76 @param ytype The controller to use for y-axis data
77 @param yid The controller ID to use for y-axis data (-1 for no id)
78
79 @return Whether the controller supports using the mouse
80 */
81 bool setMouseControl(Controller::Type xtype, int xid,
82 Controller::Type ytype, int yid) override;
83
84 /**
85 Sets the sensitivity for analog emulation of trackball movement
86 using a mouse.
87
88 @param sensitivity Value from 1 to 20, with larger values causing
89 more movement (10 represents the baseline)
90 */
91 static void setSensitivity(int sensitivity);
92
93 protected:
94 // Each derived class must implement this, to determine how its
95 // IOPortA values are calculated
96 virtual uInt8 ioPortA(uInt8 countH, uInt8 countV, uInt8 left, uInt8 down) = 0;
97
98// virtual string pointingDeviceName() const = 0;
99
100 private:
101 void updateDirection(int counter, float& counterRemainder,
102 bool& trackBallDir, int& trackBallLines,
103 int& scanCount, int& firstScanOffset);
104
105 private:
106 // Mouse input to sensitivity emulation
107 float mySensitivity, myHCounterRemainder, myVCounterRemainder;
108
109 // How many lines to wait between sending new horz and vert values
110 int myTrackBallLinesH, myTrackBallLinesV;
111
112 // Was TrackBall moved left or moved right instead
113 bool myTrackBallLeft;
114
115 // Was TrackBall moved down or moved up instead
116 bool myTrackBallDown;
117
118 // Counter to iterate through the gray codes
119 uInt8 myCountH, myCountV;
120
121 // Next scanline for change
122 int myScanCountH, myScanCountV;
123
124 // Offset factor for first scanline, 0..(1 << 12 - 1)
125 int myFirstScanOffsetH, myFirstScanOffsetV;
126
127 // Whether to use the mouse to emulate this controller
128 bool myMouseEnabled;
129
130 // User-defined sensitivity; adjustable since end-users may have different
131 // mouse speeds
132 static float TB_SENSITIVITY;
133
134private:
135 // Following constructors and assignment operators not supported
136 PointingDevice() = delete;
137 PointingDevice(const PointingDevice&) = delete;
138 PointingDevice(PointingDevice&&) = delete;
139 PointingDevice& operator=(const PointingDevice&) = delete;
140 PointingDevice& operator=(PointingDevice&&) = delete;
141};
142
143#endif // POINTING_DEVICE_HXX
144