Blender  V2.59
SCA_Joystick.cpp
Go to the documentation of this file.
00001 /*
00002  * ***** BEGIN GPL LICENSE BLOCK *****
00003  *
00004  * This program is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU General Public License
00006  * as published by the Free Software Foundation; either version 2
00007  * of the License, or (at your option) any later version.
00008  *
00009  * This program is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  * GNU General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU General Public License
00015  * along with this program; if not, write to the Free Software Foundation,
00016  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
00017  *
00018  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
00019  * All rights reserved.
00020  *
00021  * The Original Code is: all of this file.
00022  *
00023  * Contributor(s): snailrose.
00024  *
00025  * ***** END GPL LICENSE BLOCK *****
00026  */
00027 
00032 #ifndef DISABLE_SDL
00033 #include <SDL.h>
00034 #endif
00035 
00036 #include <stdio.h>
00037 #include <stdlib.h>
00038 
00039 #include "SCA_Joystick.h"
00040 #include "SCA_JoystickPrivate.h"
00041 
00042 SCA_Joystick::SCA_Joystick(short int index)
00043         :
00044         m_joyindex(index),
00045         m_prec(3200),
00046         m_axismax(-1),
00047         m_buttonmax(-1),
00048         m_hatmax(-1),
00049         m_isinit(0),
00050         m_istrig_axis(0),
00051         m_istrig_button(0),
00052         m_istrig_hat(0)
00053 {
00054         for(int i=0; i<JOYAXIS_MAX; i++)
00055                 m_axis_array[i]= 0;
00056         
00057         for(int i=0; i<JOYHAT_MAX; i++)
00058                 m_hat_array[i]= 0;
00059         
00060 #ifndef DISABLE_SDL
00061         m_private = new PrivateData();
00062 #endif
00063 }
00064 
00065 
00066 SCA_Joystick::~SCA_Joystick()
00067 
00068 {
00069 #ifndef DISABLE_SDL
00070         delete m_private;
00071 #endif
00072 }
00073 
00074 SCA_Joystick *SCA_Joystick::m_instance[JOYINDEX_MAX];
00075 int SCA_Joystick::m_joynum = 0;
00076 int SCA_Joystick::m_refCount = 0;
00077 
00078 SCA_Joystick *SCA_Joystick::GetInstance( short int joyindex )
00079 {
00080 #ifdef DISABLE_SDL
00081         return NULL;
00082 #else
00083         if (joyindex < 0 || joyindex >= JOYINDEX_MAX) {
00084                 echo("Error-invalid joystick index: " << joyindex);
00085                 return NULL;
00086         }
00087 
00088         if (m_refCount == 0) 
00089         {
00090                 int i;
00091                 // do this once only
00092                 if(SDL_InitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO) == -1 ){
00093                         echo("Error-Initializing-SDL: " << SDL_GetError());
00094                         return NULL;
00095                 }
00096                 
00097                 m_joynum = SDL_NumJoysticks();
00098                 
00099                 for (i=0; i<JOYINDEX_MAX; i++) {
00100                         m_instance[i] = new SCA_Joystick(i);
00101                         m_instance[i]->CreateJoystickDevice();
00102                 }
00103                 m_refCount = 1;
00104         }
00105         else
00106         {
00107                 m_refCount++;
00108         }
00109         return m_instance[joyindex];
00110 #endif
00111 }
00112 
00113 void SCA_Joystick::ReleaseInstance()
00114 {
00115         if (--m_refCount == 0)
00116         {
00117 #ifndef DISABLE_SDL
00118                 int i;
00119                 for (i=0; i<JOYINDEX_MAX; i++) {
00120                         if (m_instance[i]) {
00121                                 m_instance[i]->DestroyJoystickDevice();
00122                                 delete m_instance[i];
00123                         }
00124                         m_instance[i]= NULL;
00125                 }
00126 
00127                 SDL_QuitSubSystem(SDL_INIT_JOYSTICK | SDL_INIT_VIDEO);
00128 #endif
00129         }
00130 }
00131 
00132 void SCA_Joystick::cSetPrecision(int val)
00133 {
00134         m_prec = val;
00135 }
00136 
00137 
00138 bool SCA_Joystick::aAxisPairIsPositive(int axis)
00139 {
00140         return (pAxisTest(axis) > m_prec) ? true:false;
00141 }
00142 
00143 bool SCA_Joystick::aAxisPairDirectionIsPositive(int axis, int dir)
00144 {
00145 
00146         int res;
00147 
00148         if (dir==JOYAXIS_UP || dir==JOYAXIS_DOWN)
00149                 res = pGetAxis(axis, 1);
00150         else /* JOYAXIS_LEFT || JOYAXIS_RIGHT */
00151                 res = pGetAxis(axis, 0);
00152         
00153         if (dir==JOYAXIS_DOWN || dir==JOYAXIS_RIGHT)
00154                 return (res > m_prec) ? true : false;
00155         else /* JOYAXIS_UP || JOYAXIS_LEFT */
00156                 return (res < -m_prec) ? true : false;
00157 }
00158 
00159 bool SCA_Joystick::aAxisIsPositive(int axis_single)
00160 {
00161         return abs(m_axis_array[axis_single]) > m_prec ? true:false;
00162 }
00163 
00164 bool SCA_Joystick::aAnyButtonPressIsPositive(void)
00165 {
00166 #ifndef DISABLE_SDL
00167         /* this is needed for the "all events" option
00168          * so we know if there are no buttons pressed */
00169         for (int i=0; i<m_buttonmax; i++)
00170                 if (SDL_JoystickGetButton(m_private->m_joystick, i))
00171                         return true;
00172 #endif
00173         return false;
00174 }
00175 
00176 bool SCA_Joystick::aButtonPressIsPositive(int button)
00177 {
00178 #ifdef DISABLE_SDL
00179         return false;
00180 #else
00181         bool result;
00182         SDL_JoystickGetButton(m_private->m_joystick, button)? result = true:result = false;
00183         return result;
00184 #endif
00185 }
00186 
00187 
00188 bool SCA_Joystick::aButtonReleaseIsPositive(int button)
00189 {
00190 #ifdef DISABLE_SDL
00191         return false;
00192 #else
00193         bool result;
00194         SDL_JoystickGetButton(m_private->m_joystick, button)? result = false : result = true;
00195         return result;
00196 #endif
00197 }
00198 
00199 
00200 bool SCA_Joystick::aHatIsPositive(int hatnum, int dir)
00201 {
00202         return (GetHat(hatnum)==dir) ? true : false;
00203 }
00204 
00205 int SCA_Joystick::GetNumberOfAxes()
00206 {
00207         return m_axismax;
00208 }
00209 
00210 
00211 int SCA_Joystick::GetNumberOfButtons()
00212 {
00213         return m_buttonmax;
00214 }
00215 
00216 
00217 int SCA_Joystick::GetNumberOfHats()
00218 {
00219         return m_hatmax;
00220 }
00221 
00222 bool SCA_Joystick::CreateJoystickDevice(void)
00223 {
00224 #ifdef DISABLE_SDL
00225         m_isinit = true;
00226         m_axismax = m_buttonmax = m_hatmax = 0;
00227         return false;
00228 #else
00229         if(m_isinit == false){
00230                 if (m_joyindex>=m_joynum) {
00231                         // don't print a message, because this is done anyway
00232                         //echo("Joystick-Error: " << SDL_NumJoysticks() << " avaiable joystick(s)");
00233                         
00234                         // Need this so python args can return empty lists
00235                         m_axismax = m_buttonmax = m_hatmax = 0;
00236                         return false;
00237                 }
00238 
00239                 m_private->m_joystick = SDL_JoystickOpen(m_joyindex);
00240                 SDL_JoystickEventState(SDL_ENABLE);
00241                 m_isinit = true;
00242                 
00243                 echo("Joystick " << m_joyindex << " initialized");
00244                 
00245                 /* must run after being initialized */
00246                 m_axismax =             SDL_JoystickNumAxes(m_private->m_joystick);
00247                 m_buttonmax =   SDL_JoystickNumButtons(m_private->m_joystick);
00248                 m_hatmax =              SDL_JoystickNumHats(m_private->m_joystick);
00249                 
00250                 if (m_axismax > JOYAXIS_MAX) m_axismax= JOYAXIS_MAX;            /* very unlikely */
00251                 else if (m_axismax < 0) m_axismax = 0;
00252                 
00253                 if (m_hatmax > JOYHAT_MAX) m_hatmax= JOYHAT_MAX;                        /* very unlikely */
00254                 else if(m_hatmax<0) m_hatmax= 0;
00255                 
00256                 if(m_buttonmax<0) m_buttonmax= 0;
00257                 
00258         }
00259         return true;
00260 #endif
00261 }
00262 
00263 
00264 void SCA_Joystick::DestroyJoystickDevice(void)
00265 {
00266 #ifndef DISABLE_SDL
00267         if (m_isinit){
00268                 if(SDL_JoystickOpened(m_joyindex)){
00269                         echo("Closing-joystick " << m_joyindex);
00270                         SDL_JoystickClose(m_private->m_joystick);
00271                 }
00272                 m_isinit = false;
00273         }
00274 #endif
00275 }
00276 
00277 int SCA_Joystick::Connected(void)
00278 {
00279 #ifndef DISABLE_SDL
00280         if (m_isinit && SDL_JoystickOpened(m_joyindex))
00281                 return 1;
00282 #endif
00283         return 0;
00284 }
00285 
00286 int SCA_Joystick::pGetAxis(int axisnum, int udlr)
00287 {
00288 #ifndef DISABLE_SDL
00289         return m_axis_array[(axisnum*2)+udlr];
00290 #endif
00291         return 0;
00292 }
00293 
00294 int SCA_Joystick::pAxisTest(int axisnum)
00295 {
00296 #ifndef DISABLE_SDL
00297         short i1= m_axis_array[(axisnum*2)];
00298         short i2= m_axis_array[(axisnum*2)+1];
00299         
00300         /* long winded way to do
00301          *   return MAX2(abs(i1), abs(i2))
00302          * avoid abs from math.h */
00303         if (i1 < 0) i1 = -i1;
00304         if (i2 < 0) i2 = -i2;
00305         if (i1 <i2) return i2;
00306         else            return i1;
00307 #else
00308         return 0;
00309 #endif
00310 }