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-2014 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 // $Id: Booster.cxx 2838 2014-01-17 23:34:03Z stephena $
18 //============================================================================
19 
20 #include "Event.hxx"
21 #include "Booster.hxx"
22 
23 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
BoosterGrip(Jack jack,const Event & event,const System & system)24 BoosterGrip::BoosterGrip(Jack jack, const Event& event, const System& system)
25   : Controller(jack, event, system, Controller::BoosterGrip),
26     myControlID(-1)
27 {
28   if(myJack == Left)
29   {
30     myUpEvent      = Event::JoystickZeroUp;
31     myDownEvent    = Event::JoystickZeroDown;
32     myLeftEvent    = Event::JoystickZeroLeft;
33     myRightEvent   = Event::JoystickZeroRight;
34     myFireEvent    = Event::JoystickZeroFire;
35     myTriggerEvent = Event::JoystickZeroFire5;
36     myBoosterEvent = Event::JoystickZeroFire9;
37     myXAxisValue   = Event::SALeftAxis0Value;
38     myYAxisValue   = Event::SALeftAxis1Value;
39   }
40   else
41   {
42     myUpEvent      = Event::JoystickOneUp;
43     myDownEvent    = Event::JoystickOneDown;
44     myLeftEvent    = Event::JoystickOneLeft;
45     myRightEvent   = Event::JoystickOneRight;
46     myFireEvent    = Event::JoystickOneFire;
47     myTriggerEvent = Event::JoystickOneFire5;
48     myBoosterEvent = Event::JoystickOneFire9;
49     myXAxisValue   = Event::SARightAxis0Value;
50     myYAxisValue   = Event::SARightAxis1Value;
51   }
52 }
53 
54 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
~BoosterGrip()55 BoosterGrip::~BoosterGrip()
56 {
57 }
58 
59 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
update()60 void BoosterGrip::update()
61 {
62   // Digital events (from keyboard or joystick hats & buttons)
63   myDigitalPinState[One]   = (myEvent.get(myUpEvent) == 0);
64   myDigitalPinState[Two]   = (myEvent.get(myDownEvent) == 0);
65   myDigitalPinState[Three] = (myEvent.get(myLeftEvent) == 0);
66   myDigitalPinState[Four]  = (myEvent.get(myRightEvent) == 0);
67   myDigitalPinState[Six]   = (myEvent.get(myFireEvent) == 0);
68 
69   // The CBS Booster-grip has two more buttons on it.  These buttons are
70   // connected to the inputs usually used by paddles.
71   myAnalogPinValue[Five] = (myEvent.get(myTriggerEvent) != 0) ?
72                             minimumResistance : maximumResistance;
73   myAnalogPinValue[Nine] = (myEvent.get(myBoosterEvent) != 0) ?
74                             minimumResistance : maximumResistance;
75 
76   // Axis events (usually generated by the Stelladaptor)
77   int xaxis = myEvent.get(myXAxisValue);
78   int yaxis = myEvent.get(myYAxisValue);
79   if(xaxis > 16384-4096)
80   {
81     myDigitalPinState[Four] = false;
82     // Stelladaptor sends "half moved right" for L+R pushed together
83     if(xaxis < 16384+4096)
84       myDigitalPinState[Three] = false;
85   }
86   else if(xaxis < -16384)
87     myDigitalPinState[Three] = false;
88   if(yaxis > 16384-4096)
89   {
90     myDigitalPinState[Two] = false;
91     // Stelladaptor sends "half moved down" for U+D pushed together
92     if(yaxis < 16384+4096)
93       myDigitalPinState[One] = false;
94   }
95   else if(yaxis < -16384)
96     myDigitalPinState[One] = false;
97 
98   // Mouse motion and button events
99   if(myControlID > -1)
100   {
101     // The following code was taken from z26
102     #define MJ_Threshold 2
103     int mousex = myEvent.get(Event::MouseAxisXValue),
104         mousey = myEvent.get(Event::MouseAxisYValue);
105     if(mousex || mousey)
106     {
107       if((!(abs(mousey) > abs(mousex) << 1)) && (abs(mousex) >= MJ_Threshold))
108       {
109         if(mousex < 0)
110           myDigitalPinState[Three] = false;
111         else if (mousex > 0)
112           myDigitalPinState[Four] = false;
113       }
114 
115       if((!(abs(mousex) > abs(mousey) << 1)) && (abs(mousey) >= MJ_Threshold))
116       {
117         if(mousey < 0)
118           myDigitalPinState[One] = false;
119         else if(mousey > 0)
120           myDigitalPinState[Two] = false;
121       }
122     }
123     // Get mouse button state
124     if(myEvent.get(Event::MouseButtonLeftValue))
125       myDigitalPinState[Six] = false;
126     if(myEvent.get(Event::MouseButtonRightValue))
127       myAnalogPinValue[Nine] = minimumResistance;
128   }
129 }
130 
131 // - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
setMouseControl(Controller::Type xtype,int xid,Controller::Type ytype,int yid)132 bool BoosterGrip::setMouseControl(
133     Controller::Type xtype, int xid, Controller::Type ytype, int yid)
134 {
135   // Currently, the booster-grip takes full control of the mouse, using both
136   // axes for its two degrees of movement, and the left/right buttons for
137   // fire and booster, respectively
138   if(xtype == Controller::BoosterGrip && ytype == Controller::BoosterGrip &&
139      xid == yid)
140   {
141     myControlID = ((myJack == Left && xid == 0) ||
142                    (myJack == Right && xid == 1)
143                   ) ? xid : -1;
144   }
145   else
146     myControlID = -1;
147 
148   return true;
149 }
150