Fix #28014: joystick sensor not working. Broke this with an earlier commit
[blender.git] / source / gameengine / GameLogic / Joystick / SCA_Joystick.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  * The Original Code is: all of this file.
22  *
23  * Contributor(s): snailrose.
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file gameengine/GameLogic/Joystick/SCA_Joystick.cpp
29  *  \ingroup gamelogic
30  */
31
32 #ifndef DISABLE_SDL
33 #include <SDL.h>
34 #endif
35
36 #include <stdio.h>
37 #include <stdlib.h>
38
39 #include "SCA_Joystick.h"
40 #include "SCA_JoystickPrivate.h"
41
42 SCA_Joystick::SCA_Joystick(short int index)
43         :
44         m_joyindex(index),
45         m_prec(3200),
46         m_axismax(-1),
47         m_buttonmax(-1),
48         m_hatmax(-1),
49         m_isinit(0),
50         m_istrig_axis(0),
51         m_istrig_button(0),
52         m_istrig_hat(0)
53 {
54         for(int i=0; i<JOYAXIS_MAX; i++)
55                 m_axis_array[i]= 0;
56         
57         for(int i=0; i<JOYHAT_MAX; i++)
58                 m_hat_array[i]= 0;
59         
60 #ifndef DISABLE_SDL
61         m_private = new PrivateData();
62 #endif
63 }
64
65
66 SCA_Joystick::~SCA_Joystick()
67
68 {
69 #ifndef DISABLE_SDL
70         delete m_private;
71 #endif
72 }
73
74 SCA_Joystick *SCA_Joystick::m_instance[JOYINDEX_MAX];
75 int SCA_Joystick::m_joynum = 0;
76 int SCA_Joystick::m_refCount = 0;
77
78 SCA_Joystick *SCA_Joystick::GetInstance( short int joyindex )
79 {
80 #ifdef DISABLE_SDL
81         return NULL;
82 #else
83         if (joyindex < 0 || joyindex >= JOYINDEX_MAX) {
84                 echo("Error-invalid joystick index: " << joyindex);
85                 return NULL;
86         }
87
88         if (m_refCount == 0) 
89         {
90                 int i;
91                 // do this once only
92                 if(SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO) == -1 ){
93                         echo("Error-Initializing-SDL: " << SDL_GetError());
94                         return NULL;
95                 }
96                 
97                 m_joynum = SDL_NumJoysticks();
98                 
99                 for (i=0; i<JOYINDEX_MAX; i++) {
100                         m_instance[i] = new SCA_Joystick(i);
101                         m_instance[i]->CreateJoystickDevice();
102                 }
103                 m_refCount = 1;
104         }
105         else
106         {
107                 m_refCount++;
108         }
109         return m_instance[joyindex];
110 #endif
111 }
112
113 void SCA_Joystick::ReleaseInstance()
114 {
115         if (--m_refCount == 0)
116         {
117 #ifndef DISABLE_SDL
118                 int i;
119                 for (i=0; i<JOYINDEX_MAX; i++) {
120                         if (m_instance[i]) {
121                                 m_instance[i]->DestroyJoystickDevice();
122                                 delete m_instance[i];
123                         }
124                         m_instance[i]= NULL;
125                 }
126
127                 SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO);
128 #endif
129         }
130 }
131
132 void SCA_Joystick::cSetPrecision(int val)
133 {
134         m_prec = val;
135 }
136
137
138 bool SCA_Joystick::aAxisPairIsPositive(int axis)
139 {
140         return (pAxisTest(axis) > m_prec) ? true:false;
141 }
142
143 bool SCA_Joystick::aAxisPairDirectionIsPositive(int axis, int dir)
144 {
145
146         int res;
147
148         if (dir==JOYAXIS_UP || dir==JOYAXIS_DOWN)
149                 res = pGetAxis(axis, 1);
150         else /* JOYAXIS_LEFT || JOYAXIS_RIGHT */
151                 res = pGetAxis(axis, 0);
152         
153         if (dir==JOYAXIS_DOWN || dir==JOYAXIS_RIGHT)
154                 return (res > m_prec) ? true : false;
155         else /* JOYAXIS_UP || JOYAXIS_LEFT */
156                 return (res < -m_prec) ? true : false;
157 }
158
159 bool SCA_Joystick::aAxisIsPositive(int axis_single)
160 {
161         return abs(m_axis_array[axis_single]) > m_prec ? true:false;
162 }
163
164 bool SCA_Joystick::aAnyButtonPressIsPositive(void)
165 {
166 #ifndef DISABLE_SDL
167         /* this is needed for the "all events" option
168          * so we know if there are no buttons pressed */
169         for (int i=0; i<m_buttonmax; i++)
170                 if (SDL_JoystickGetButton(m_private->m_joystick, i))
171                         return true;
172 #endif
173         return false;
174 }
175
176 bool SCA_Joystick::aButtonPressIsPositive(int button)
177 {
178 #ifdef DISABLE_SDL
179         return false;
180 #else
181         bool result;
182         SDL_JoystickGetButton(m_private->m_joystick, button)? result = true:result = false;
183         return result;
184 #endif
185 }
186
187
188 bool SCA_Joystick::aButtonReleaseIsPositive(int button)
189 {
190 #ifdef DISABLE_SDL
191         return false;
192 #else
193         bool result;
194         SDL_JoystickGetButton(m_private->m_joystick, button)? result = false : result = true;
195         return result;
196 #endif
197 }
198
199
200 bool SCA_Joystick::aHatIsPositive(int hatnum, int dir)
201 {
202         return (GetHat(hatnum)==dir) ? true : false;
203 }
204
205 int SCA_Joystick::GetNumberOfAxes()
206 {
207         return m_axismax;
208 }
209
210
211 int SCA_Joystick::GetNumberOfButtons()
212 {
213         return m_buttonmax;
214 }
215
216
217 int SCA_Joystick::GetNumberOfHats()
218 {
219         return m_hatmax;
220 }
221
222 bool SCA_Joystick::CreateJoystickDevice(void)
223 {
224 #ifdef DISABLE_SDL
225         m_isinit = true;
226         m_axismax = m_buttonmax = m_hatmax = 0;
227         return false;
228 #else
229         if(m_isinit == false){
230                 if (m_joyindex>=m_joynum) {
231                         // don't print a message, because this is done anyway
232                         //echo("Joystick-Error: " << SDL_NumJoysticks() << " avaiable joystick(s)");
233                         
234                         // Need this so python args can return empty lists
235                         m_axismax = m_buttonmax = m_hatmax = 0;
236                         return false;
237                 }
238
239                 m_private->m_joystick = SDL_JoystickOpen(m_joyindex);
240                 SDL_JoystickEventState(SDL_ENABLE);
241                 m_isinit = true;
242                 
243                 echo("Joystick " << m_joyindex << " initialized");
244                 
245                 /* must run after being initialized */
246                 m_axismax =             SDL_JoystickNumAxes(m_private->m_joystick);
247                 m_buttonmax =   SDL_JoystickNumButtons(m_private->m_joystick);
248                 m_hatmax =              SDL_JoystickNumHats(m_private->m_joystick);
249                 
250                 if (m_axismax > JOYAXIS_MAX) m_axismax= JOYAXIS_MAX;            /* very unlikely */
251                 else if (m_axismax < 0) m_axismax = 0;
252                 
253                 if (m_hatmax > JOYHAT_MAX) m_hatmax= JOYHAT_MAX;                        /* very unlikely */
254                 else if(m_hatmax<0) m_hatmax= 0;
255                 
256                 if(m_buttonmax<0) m_buttonmax= 0;
257                 
258         }
259         return true;
260 #endif
261 }
262
263
264 void SCA_Joystick::DestroyJoystickDevice(void)
265 {
266 #ifndef DISABLE_SDL
267         if (m_isinit){
268                 if(SDL_JoystickOpened(m_joyindex)){
269                         echo("Closing-joystick " << m_joyindex);
270                         SDL_JoystickClose(m_private->m_joystick);
271                 }
272                 m_isinit = false;
273         }
274 #endif
275 }
276
277 int SCA_Joystick::Connected(void)
278 {
279 #ifndef DISABLE_SDL
280         if (m_isinit && SDL_JoystickOpened(m_joyindex))
281                 return 1;
282 #endif
283         return 0;
284 }
285
286 int SCA_Joystick::pGetAxis(int axisnum, int udlr)
287 {
288 #ifndef DISABLE_SDL
289         return m_axis_array[(axisnum*2)+udlr];
290 #endif
291         return 0;
292 }
293
294 int SCA_Joystick::pAxisTest(int axisnum)
295 {
296 #ifndef DISABLE_SDL
297         short i1= m_axis_array[(axisnum*2)];
298         short i2= m_axis_array[(axisnum*2)+1];
299         
300         /* long winded way to do
301          *   return MAX2(abs(i1), abs(i2))
302          * avoid abs from math.h */
303         if (i1 < 0) i1 = -i1;
304         if (i2 < 0) i2 = -i2;
305         if (i1 <i2) return i2;
306         else            return i1;
307 #else
308         return 0;
309 #endif
310 }