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