doxygen: prevent GPL license block from being parsed as doxygen comment.
[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 #ifndef DISABLE_SDL
28 #include <SDL.h>
29 #endif
30
31 #include <stdio.h>
32 #include <stdlib.h>
33
34 #include "SCA_Joystick.h"
35 #include "SCA_JoystickPrivate.h"
36
37 SCA_Joystick::SCA_Joystick(short int index)
38         :
39         m_joyindex(index),
40         m_prec(3200),
41         m_axismax(-1),
42         m_buttonmax(-1),
43         m_hatmax(-1),
44         m_isinit(0),
45         m_istrig_axis(0),
46         m_istrig_button(0),
47         m_istrig_hat(0)
48 {
49         for(int i=0; i<JOYAXIS_MAX; i++)
50                 m_axis_array[i]= 0;
51         
52         for(int i=0; i<JOYHAT_MAX; i++)
53                 m_hat_array[i]= 0;
54         
55 #ifndef DISABLE_SDL
56         m_private = new PrivateData();
57 #endif
58 }
59
60
61 SCA_Joystick::~SCA_Joystick()
62
63 {
64 #ifndef DISABLE_SDL
65         delete m_private;
66 #endif
67 }
68
69 SCA_Joystick *SCA_Joystick::m_instance[JOYINDEX_MAX];
70 int SCA_Joystick::m_joynum = 0;
71 int SCA_Joystick::m_refCount = 0;
72
73 SCA_Joystick *SCA_Joystick::GetInstance( short int joyindex )
74 {
75 #ifdef DISABLE_SDL
76         return NULL;
77 #else
78         if (joyindex < 0 || joyindex >= JOYINDEX_MAX) {
79                 echo("Error-invalid joystick index: " << joyindex);
80                 return NULL;
81         }
82
83         if (m_refCount == 0) 
84         {
85                 int i;
86                 // do this once only
87                 if(SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO ) == -1 ){
88                         echo("Error-Initializing-SDL: " << SDL_GetError());
89                         return NULL;
90                 }
91                 
92                 m_joynum = SDL_NumJoysticks();
93                 
94                 for (i=0; i<JOYINDEX_MAX; i++) {
95                         m_instance[i] = new SCA_Joystick(i);
96                         m_instance[i]->CreateJoystickDevice();
97                 }
98                 m_refCount = 1;
99         }
100         else
101         {
102                 m_refCount++;
103         }
104         return m_instance[joyindex];
105 #endif
106 }
107
108 void SCA_Joystick::ReleaseInstance()
109 {
110         if (--m_refCount == 0)
111         {
112 #ifndef DISABLE_SDL
113                 int i;
114                 for (i=0; i<JOYINDEX_MAX; i++) {
115                         if (m_instance[i]) {
116                                 m_instance[i]->DestroyJoystickDevice();
117                                 delete m_instance[i];
118                         }
119                         m_instance[i]= NULL;
120                 }
121
122                 SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO );
123 #endif
124         }
125 }
126
127 void SCA_Joystick::cSetPrecision(int val)
128 {
129         m_prec = val;
130 }
131
132
133 bool SCA_Joystick::aAxisPairIsPositive(int axis)
134 {
135         return (pAxisTest(axis) > m_prec) ? true:false;
136 }
137
138 bool SCA_Joystick::aAxisPairDirectionIsPositive(int axis, int dir)
139 {
140
141         int res;
142
143         if (dir==JOYAXIS_UP || dir==JOYAXIS_DOWN)
144                 res = pGetAxis(axis, 1);
145         else /* JOYAXIS_LEFT || JOYAXIS_RIGHT */
146                 res = pGetAxis(axis, 0);
147         
148         if (dir==JOYAXIS_DOWN || dir==JOYAXIS_RIGHT)
149                 return (res > m_prec) ? true : false;
150         else /* JOYAXIS_UP || JOYAXIS_LEFT */
151                 return (res < -m_prec) ? true : false;
152 }
153
154 bool SCA_Joystick::aAxisIsPositive(int axis_single)
155 {
156         return abs(m_axis_array[axis_single]) > m_prec ? true:false;
157 }
158
159 bool SCA_Joystick::aAnyButtonPressIsPositive(void)
160 {
161 #ifndef DISABLE_SDL
162         /* this is needed for the "all events" option
163          * so we know if there are no buttons pressed */
164         for (int i=0; i<m_buttonmax; i++)
165                 if (SDL_JoystickGetButton(m_private->m_joystick, i))
166                         return true;
167 #endif
168         return false;
169 }
170
171 bool SCA_Joystick::aButtonPressIsPositive(int button)
172 {
173 #ifdef DISABLE_SDL
174         return false;
175 #else
176         bool result;
177         SDL_JoystickGetButton(m_private->m_joystick, button)? result = true:result = false;
178         return result;
179 #endif
180 }
181
182
183 bool SCA_Joystick::aButtonReleaseIsPositive(int button)
184 {
185 #ifdef DISABLE_SDL
186         return false;
187 #else
188         bool result;
189         SDL_JoystickGetButton(m_private->m_joystick, button)? result = false : result = true;
190         return result;
191 #endif
192 }
193
194
195 bool SCA_Joystick::aHatIsPositive(int hatnum, int dir)
196 {
197         return (GetHat(hatnum)==dir) ? true : false;
198 }
199
200 int SCA_Joystick::GetNumberOfAxes()
201 {
202         return m_axismax;
203 }
204
205
206 int SCA_Joystick::GetNumberOfButtons()
207 {
208         return m_buttonmax;
209 }
210
211
212 int SCA_Joystick::GetNumberOfHats()
213 {
214         return m_hatmax;
215 }
216
217 bool SCA_Joystick::CreateJoystickDevice(void)
218 {
219 #ifdef DISABLE_SDL
220         m_isinit = true;
221         m_axismax = m_buttonmax = m_hatmax = 0;
222         return false;
223 #else
224         if(m_isinit == false){
225                 if (m_joyindex>=m_joynum) {
226                         // don't print a message, because this is done anyway
227                         //echo("Joystick-Error: " << SDL_NumJoysticks() << " avaiable joystick(s)");
228                         
229                         // Need this so python args can return empty lists
230                         m_axismax = m_buttonmax = m_hatmax = 0;
231                         return false;
232                 }
233
234                 m_private->m_joystick = SDL_JoystickOpen(m_joyindex);
235                 SDL_JoystickEventState(SDL_ENABLE);
236                 m_isinit = true;
237                 
238                 echo("Joystick " << m_joyindex << " initialized");
239                 
240                 /* must run after being initialized */
241                 m_axismax =             SDL_JoystickNumAxes(m_private->m_joystick);
242                 m_buttonmax =   SDL_JoystickNumButtons(m_private->m_joystick);
243                 m_hatmax =              SDL_JoystickNumHats(m_private->m_joystick);
244                 
245                 if (m_axismax > JOYAXIS_MAX) m_axismax= JOYAXIS_MAX;            /* very unlikely */
246                 else if (m_axismax < 0) m_axismax = 0;
247                 
248                 if (m_hatmax > JOYHAT_MAX) m_hatmax= JOYHAT_MAX;                        /* very unlikely */
249                 else if(m_hatmax<0) m_hatmax= 0;
250                 
251                 if(m_buttonmax<0) m_buttonmax= 0;
252                 
253         }
254         return true;
255 #endif
256 }
257
258
259 void SCA_Joystick::DestroyJoystickDevice(void)
260 {
261 #ifndef DISABLE_SDL
262         if (m_isinit){
263                 if(SDL_JoystickOpened(m_joyindex)){
264                         echo("Closing-joystick " << m_joyindex);
265                         SDL_JoystickClose(m_private->m_joystick);
266                 }
267                 m_isinit = false;
268         }
269 #endif
270 }
271
272 int SCA_Joystick::Connected(void)
273 {
274 #ifndef DISABLE_SDL
275         if (m_isinit && SDL_JoystickOpened(m_joyindex))
276                 return 1;
277 #endif
278         return 0;
279 }
280
281 int SCA_Joystick::pGetAxis(int axisnum, int udlr)
282 {
283 #ifndef DISABLE_SDL
284         return m_axis_array[(axisnum*2)+udlr];
285 #endif
286         return 0;
287 }
288
289 int SCA_Joystick::pAxisTest(int axisnum)
290 {
291 #ifndef DISABLE_SDL
292         short i1= m_axis_array[(axisnum*2)];
293         short i2= m_axis_array[(axisnum*2)+1];
294         
295         /* long winded way to do
296          *   return MAX2(abs(i1), abs(i2))
297          * avoid abs from math.h */
298         if (i1 < 0) i1 = -i1;
299         if (i2 < 0) i2 = -i2;
300         if (i1 <i2) return i2;
301         else            return i1;
302 #else
303         return 0;
304 #endif
305 }