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