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