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#include "Event.hxx"
19#include "Joystick.hxx"
20
21// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
22Joystick::Joystick(Jack jack, const Event& event, const System& system)
23 : Controller(jack, event, system, Controller::Type::Joystick),
24 myControlID(-1)
25{
26 if(myJack == Jack::Left)
27 {
28 myUpEvent = Event::JoystickZeroUp;
29 myDownEvent = Event::JoystickZeroDown;
30 myLeftEvent = Event::JoystickZeroLeft;
31 myRightEvent = Event::JoystickZeroRight;
32 myFireEvent = Event::JoystickZeroFire;
33 myXAxisValue = Event::PaddleZeroAnalog;
34 myYAxisValue = Event::PaddleOneAnalog;
35 }
36 else
37 {
38 myUpEvent = Event::JoystickOneUp;
39 myDownEvent = Event::JoystickOneDown;
40 myLeftEvent = Event::JoystickOneLeft;
41 myRightEvent = Event::JoystickOneRight;
42 myFireEvent = Event::JoystickOneFire;
43 myXAxisValue = Event::PaddleTwoAnalog;
44 myYAxisValue = Event::PaddleThreeAnalog;
45 }
46}
47
48// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
49void Joystick::update()
50{
51 // Digital events (from keyboard or joystick hats & buttons)
52 setPin(DigitalPin::One, myEvent.get(myUpEvent) == 0);
53 setPin(DigitalPin::Two, myEvent.get(myDownEvent) == 0);
54 setPin(DigitalPin::Three, myEvent.get(myLeftEvent) == 0);
55 setPin(DigitalPin::Four, myEvent.get(myRightEvent) == 0);
56 setPin(DigitalPin::Six, myEvent.get(myFireEvent) == 0);
57
58 // Axis events (usually generated by the Stelladaptor)
59 int xaxis = myEvent.get(myXAxisValue);
60 int yaxis = myEvent.get(myYAxisValue);
61 if(xaxis > 16384-4096)
62 {
63 setPin(DigitalPin::Four, false);
64 // Stelladaptor sends "half moved right" for L+R pushed together
65 if(xaxis < 16384+4096)
66 setPin(DigitalPin::Three, false);
67 }
68 else if(xaxis < -16384)
69 setPin(DigitalPin::Three, false);
70 if(yaxis > 16384-4096)
71 {
72 setPin(DigitalPin::Two, false);
73 // Stelladaptor sends "half moved down" for U+D pushed together
74 if(yaxis < 16384+4096)
75 setPin(DigitalPin::One, false);
76 }
77 else if(yaxis < -16384)
78 setPin(DigitalPin::One, false);
79
80 // Mouse motion and button events
81 if(myControlID > -1)
82 {
83 // The following code was taken from z26
84 #define MJ_Threshold 2
85 int mousex = myEvent.get(Event::MouseAxisXValue),
86 mousey = myEvent.get(Event::MouseAxisYValue);
87 if(mousex || mousey)
88 {
89 if((!(abs(mousey) > abs(mousex) << 1)) && (abs(mousex) >= MJ_Threshold))
90 {
91 if(mousex < 0)
92 setPin(DigitalPin::Three, false);
93 else if(mousex > 0)
94 setPin(DigitalPin::Four, false);
95 }
96
97 if((!(abs(mousex) > abs(mousey) << 1)) && (abs(mousey) >= MJ_Threshold))
98 {
99 if(mousey < 0)
100 setPin(DigitalPin::One, false);
101 else if(mousey > 0)
102 setPin(DigitalPin::Two, false);
103 }
104 }
105 // Get mouse button state
106 if(myEvent.get(Event::MouseButtonLeftValue) ||
107 myEvent.get(Event::MouseButtonRightValue))
108 setPin(DigitalPin::Six, false);
109 }
110}
111
112// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
113bool Joystick::setMouseControl(
114 Controller::Type xtype, int xid, Controller::Type ytype, int yid)
115{
116 // Currently, the joystick takes full control of the mouse, using both
117 // axes for its two degrees of movement, and both mouse buttons for the
118 // single joystick button
119 if(xtype == Controller::Type::Joystick && ytype == Controller::Type::Joystick && xid == yid)
120 {
121 myControlID = ((myJack == Jack::Left && xid == 0) ||
122 (myJack == Jack::Right && xid == 1)
123 ) ? xid : -1;
124 }
125 else
126 myControlID = -1;
127
128 return true;
129}
130
131// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
132void Joystick::setDeadZone(int deadzone)
133{
134 deadzone = BSPF::clamp(deadzone, 0, 29);
135
136 _DEAD_ZONE = 3200 + deadzone * 1000;
137}
138
139// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
140int Joystick::_DEAD_ZONE = 3200;
141