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 PADDLES_HXX
19#define PADDLES_HXX
20
21#include "bspf.hxx"
22#include "Control.hxx"
23#include "Event.hxx"
24
25/**
26 The standard Atari 2600 pair of paddle controllers.
27
28 @author Bradford W. Mott
29*/
30class Paddles : public Controller
31{
32 public:
33 /**
34 Create a new pair of paddle controllers plugged into the specified jack
35
36 @param jack The jack the controller is plugged into
37 @param event The event object to use for events
38 @param system The system using this controller
39
40 @param swappaddle Whether to swap the paddles plugged into this jack
41 @param swapaxis Whether to swap the axis on the paddle (x <-> y)
42 @param swapdir Whether to swap the direction for which an axis
43 causes movement (lesser axis values cause paddle
44 resistance to decrease instead of increase)
45 */
46 Paddles(Jack jack, const Event& event, const System& system,
47 bool swappaddle, bool swapaxis, bool swapdir);
48 virtual ~Paddles() = default;
49
50 public:
51
52 static constexpr int MAX_DIGITAL_SENSE = 20;
53 static constexpr int MAX_MOUSE_SENSE = 20;
54 static constexpr int MIN_DEJITTER = 0;
55 static constexpr int MAX_DEJITTER = 10;
56
57 /**
58 Update the entire digital and analog pin state according to the
59 events currently set.
60 */
61 void update() override;
62
63 /**
64 Returns the name of this controller.
65 */
66 string name() const override { return "Paddles"; }
67
68 /**
69 Answers whether the controller is intrinsically an analog controller.
70 */
71 bool isAnalog() const override { return true; }
72
73 /**
74 Determines how this controller will treat values received from the
75 X/Y axis and left/right buttons of the mouse. Since not all controllers
76 use the mouse the same way (or at all), it's up to the specific class to
77 decide how to use this data.
78
79 In the current implementation, the left button is tied to the X axis,
80 and the right one tied to the Y axis.
81
82 @param xtype The controller to use for x-axis data
83 @param xid The controller ID to use for x-axis data (-1 for no id)
84 @param ytype The controller to use for y-axis data
85 @param yid The controller ID to use for y-axis data (-1 for no id)
86
87 @return Whether the controller supports using the mouse
88 */
89 bool setMouseControl(Controller::Type xtype, int xid,
90 Controller::Type ytype, int yid) override;
91
92 /**
93 @param strength Value from 0 to 10
94 */
95 static void setDejitterBase(int strength);
96
97 /**
98 @param strength Value from 0 to 10
99 */
100 static void setDejitterDiff(int strength);
101
102 /**
103 Sets the sensitivity for digital emulation of paddle movement.
104 This is only used for *digital* events (ie, buttons or keys,
105 or digital joystick axis events); Stelladaptors or the mouse are
106 not modified.
107
108 @param sensitivity Value from 1 to MAX_DIGITAL_SENSE, with larger
109 values causing more movement
110 */
111 static void setDigitalSensitivity(int sensitivity);
112
113 /**
114 Sets the sensitivity for analog emulation of paddle movement
115 using a mouse.
116
117 @param sensitivity Value from 1 to MAX_MOUSE_SENSE, with larger
118 values causing more movement
119 */
120 static void setMouseSensitivity(int sensitivity);
121
122 /**
123 Sets the maximum upper range for digital/mouse emulation of paddle
124 movement (ie, a value of 50 means to only use 50% of the possible
125 range of movement). Note that this specfically does not apply to
126 Stelladaptor-like devices, which uses an absolute value range.
127
128 @param range Value from 1 to 100, representing the percentage
129 of the range to use
130 */
131 static void setPaddleRange(int range);
132
133 static constexpr double MAX_RESISTANCE = 1400000.0;
134
135 private:
136 // Pre-compute the events we care about based on given port
137 // This will eliminate test for left or right port in update()
138 Event::Type myP0AxisValue, myP1AxisValue,
139 myP0DecEvent, myP0IncEvent,
140 myP1DecEvent, myP1IncEvent,
141 myP0FireEvent, myP1FireEvent,
142 myAxisMouseMotion;
143
144 // The following are used for the various mouse-axis modes
145 int myMPaddleID; // paddle to emulate in 'automatic' mode
146 int myMPaddleIDX, myMPaddleIDY; // paddles to emulate in 'specific axis' mode
147
148 bool myKeyRepeat0, myKeyRepeat1;
149 int myPaddleRepeat0, myPaddleRepeat1;
150 int myCharge[2], myLastCharge[2];
151 int myLastAxisX, myLastAxisY;
152 int myAxisDigitalZero, myAxisDigitalOne;
153
154 // Range of values over which digital and mouse movement is scaled
155 // to paddle resistance
156 static constexpr int TRIGMIN = 1;
157 static constexpr int TRIGMAX = 4096;
158 static int TRIGRANGE; // This one is variable for the upper range
159
160 static int DIGITAL_SENSITIVITY, DIGITAL_DISTANCE;
161 static int DEJITTER_BASE, DEJITTER_DIFF;
162 static int MOUSE_SENSITIVITY;
163
164 // Lookup table for associating paddle buttons with controller pins
165 // Yes, this is hideously complex
166 static const Controller::DigitalPin ourButtonPin[2];
167
168 private:
169 // Following constructors and assignment operators not supported
170 Paddles() = delete;
171 Paddles(const Paddles&) = delete;
172 Paddles(Paddles&&) = delete;
173 Paddles& operator=(const Paddles&) = delete;
174 Paddles& operator=(Paddles&&) = delete;
175};
176
177#endif
178