00001 #include "OSDLJoystick.h"
00002
00003 #include "OSDLController.h"
00004
00005 #include "SDL.h"
00006
00007
00008
00009 using std::string ;
00010
00011
00012 using namespace Ceylan::Log ;
00013
00014 using namespace OSDL::Events ;
00015 using namespace OSDL::MVC ;
00016
00017
00018 #ifdef OSDL_USES_CONFIG_H
00019 #include <OSDLConfig.h>
00020 #endif // OSDL_USES_CONFIG_H
00021
00022
00023
00024 #if OSDL_VERBOSE_JOYSTICK
00025
00026 #include <iostream>
00027 #define OSDL_JOYSTICK_LOG( message ) std::cout << "[OSDL Joystick] " << message << std::endl ;
00028
00029 #else // OSDL_VERBOSE_JOYSTICK
00030
00031 #define OSDL_JOYSTICK_LOG( message )
00032
00033 #endif // OSDL_VERBOSE_JOYSTICK
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044 Joystick::Joystick( JoystickNumber index ) throw() :
00045 OSDL::Events::InputDevice(),
00046 _name( SDL_JoystickName( index ) ),
00047 _index( index ),
00048 _internalJoystick( 0 ),
00049 _axisCount( 0 ),
00050 _trackballCount( 0 ),
00051 _hatCount( 0 ),
00052 _buttonCount( 0 )
00053 {
00054
00055 if ( _name.empty() )
00056 _name = "(unknown joystick)" ;
00057
00058 }
00059
00060
00061 Joystick::~Joystick() throw()
00062 {
00063
00064 if ( isOpen() )
00065 close() ;
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075 }
00076
00077
00078 const string & Joystick::getName() const throw()
00079 {
00080 return _name ;
00081 }
00082
00083
00084 bool Joystick::isOpen() const throw()
00085 {
00086
00087 bool isOpened = ( SDL_JoystickOpened( _index ) == 1 ) ;
00088
00089 #if OSDL_DEBUG
00090 if ( isOpened != ( _internalJoystick != 0 ) )
00091 LogPlug::error( "Joystick::isOpen : conflicting status : "
00092 "back-end (makes authority) says " + Ceylan::toString( isOpened )
00093 + " whereas internal status says "
00094 + Ceylan::toString( ( _internalJoystick != 0 ) )
00095 + "." ) ;
00096 #endif // OSDL_DEBUG
00097
00098 return isOpened ;
00099
00100 }
00101
00102
00103 void Joystick::open() throw( JoystickException )
00104 {
00105
00106 if ( isOpen() )
00107 throw JoystickException(
00108 "Joystick::open requested whereas was already open." ) ;
00109
00110 _internalJoystick = SDL_JoystickOpen( _index ) ;
00111
00112 update() ;
00113
00114 }
00115
00116
00117 void Joystick::close() throw( JoystickException )
00118 {
00119
00120 if ( ! isOpen() )
00121 throw JoystickException(
00122 "Joystick::close requested whereas was not open." ) ;
00123
00124 SDL_JoystickClose( _internalJoystick ) ;
00125
00126
00127 _internalJoystick = 0 ;
00128
00129 }
00130
00131
00132 void Joystick::axisChanged( const JoystickAxisEvent & joystickEvent ) throw()
00133 {
00134
00135 if ( isLinkedToController() )
00136 getActualController().joystickAxisChanged( joystickEvent ) ;
00137 else
00138 {
00139 OSDL_JOYSTICK_LOG( "Axis changed for joystick #"
00140 + Ceylan::toNumericalString( joystickEvent.which ) + " : "
00141 + EventsModule::DescribeEvent( joystickEvent ) ) ;
00142 }
00143
00144 }
00145
00146
00147 void Joystick::trackballChanged( const JoystickTrackballEvent & joystickEvent )
00148 throw()
00149 {
00150
00151 if ( isLinkedToController() )
00152 getActualController().joystickTrackballChanged( joystickEvent ) ;
00153 else
00154 {
00155 OSDL_JOYSTICK_LOG( "Trackball changed for joystick #"
00156 + Ceylan::toNumericalString( joystickEvent.which ) + " : "
00157 + EventsModule::DescribeEvent( joystickEvent ) ) ;
00158 }
00159
00160 }
00161
00162
00163 void Joystick::hatChanged( const JoystickHatEvent & joystickEvent ) throw()
00164 {
00165
00166 if ( isLinkedToController() )
00167 getActualController().joystickHatChanged( joystickEvent ) ;
00168 else
00169 {
00170 OSDL_JOYSTICK_LOG( "Hat changed for joystick #"
00171 + Ceylan::toNumericalString( joystickEvent.which ) + " : "
00172 + EventsModule::DescribeEvent( joystickEvent ) ) ;
00173 }
00174
00175 }
00176
00177
00178 void Joystick::buttonPressed( const JoystickButtonEvent & joystickEvent )
00179 throw()
00180 {
00181
00182 if ( isLinkedToController() )
00183 getActualController().joystickButtonPressed( joystickEvent ) ;
00184 else
00185 {
00186 OSDL_JOYSTICK_LOG( "Button pressed for joystick #"
00187 + Ceylan::toNumericalString( joystickEvent.which ) + " : "
00188 + EventsModule::DescribeEvent( joystickEvent ) ) ;
00189 }
00190
00191 }
00192
00193
00194 void Joystick::buttonReleased( const JoystickButtonEvent & joystickEvent )
00195 throw()
00196 {
00197
00198 if ( isLinkedToController() )
00199 getActualController().joystickButtonReleased( joystickEvent ) ;
00200 else
00201 {
00202 OSDL_JOYSTICK_LOG( "Button released for joystick #"
00203 + Ceylan::toNumericalString( joystickEvent.which ) + " : "
00204 + EventsModule::DescribeEvent( joystickEvent ) ) ;
00205 }
00206
00207 }
00208
00209
00210 JoystickAxesCount Joystick::getNumberOfAxes() const throw()
00211 {
00212
00213 #if OSDL_DEBUG
00214 if ( ! isOpen() )
00215 Ceylan::emergencyShutdown(
00216 "Joystick::getNumberOfAxes : joystick not open." ) ;
00217 #endif // OSDL_DEBUG
00218
00219 return _axisCount ;
00220
00221 }
00222
00223
00224 JoystickTrackballsCount Joystick::getNumberOfTrackballs() const throw()
00225 {
00226
00227 #if OSDL_DEBUG
00228 if ( ! isOpen() )
00229 Ceylan::emergencyShutdown(
00230 "Joystick::getNumberOfTrackballs : joystick not open." ) ;
00231 #endif // OSDL_DEBUG
00232
00233 return _trackballCount ;
00234
00235 }
00236
00237
00238 JoystickHatsCount Joystick::getNumberOfHats() const throw()
00239 {
00240
00241 #if OSDL_DEBUG
00242 if ( ! isOpen() )
00243 Ceylan::emergencyShutdown(
00244 "Joystick::getNumberOfHats : joystick not open." ) ;
00245 #endif // OSDL_DEBUG
00246
00247 return _hatCount ;
00248
00249 }
00250
00251
00252 JoystickButtonsCount Joystick::getNumberOfButtons() const throw()
00253 {
00254
00255 #if OSDL_DEBUG
00256 if ( ! isOpen() )
00257 Ceylan::emergencyShutdown(
00258 "Joystick::getNumberOfButtons : joystick not open." ) ;
00259 #endif // OSDL_DEBUG
00260
00261 return _buttonCount ;
00262
00263 }
00264
00265
00266 AxisPosition Joystick::getAbscissaPosition() const throw()
00267 {
00268
00269 #if OSDL_DEBUG
00270 if ( ! isOpen() )
00271 Ceylan::emergencyShutdown(
00272 "Joystick::getAbscissaPosition : joystick not open." ) ;
00273
00274 if ( _axisCount == 0 )
00275 Ceylan::emergencyShutdown(
00276 "Joystick::getAbscissaPosition : no X axe available." ) ;
00277
00278 #endif // OSDL_DEBUG
00279
00280 return SDL_JoystickGetAxis( _internalJoystick, 0 ) ;
00281
00282 }
00283
00284
00285 AxisPosition Joystick::getOrdinatePosition() const throw()
00286 {
00287
00288 #if OSDL_DEBUG
00289 if ( ! isOpen() )
00290 Ceylan::emergencyShutdown(
00291 "Joystick::getOrdinatePosition : joystick not open." ) ;
00292
00293 if ( _axisCount <= 1 )
00294 Ceylan::emergencyShutdown(
00295 "Joystick::getOrdinatePosition : no Y axe available." ) ;
00296
00297 #endif // OSDL_DEBUG
00298
00299 return SDL_JoystickGetAxis( _internalJoystick, 1 ) ;
00300
00301 }
00302
00303
00304 AxisPosition Joystick::getPositionOfAxis( JoystickAxesCount index )
00305 const throw( JoystickException )
00306 {
00307
00308 if ( ! isOpen() )
00309 throw JoystickException(
00310 "Joystick::getPositionOfAxis : joystick not open." ) ;
00311
00312 if ( index >= _axisCount )
00313 throw JoystickException( "Joystick::getPositionOfAxis : axe index ( "
00314 + Ceylan::toString( index ) + ") out of bounds." ) ;
00315
00316 return SDL_JoystickGetAxis( _internalJoystick, index ) ;
00317
00318 }
00319
00320
00321 HatPosition Joystick::getPositionOfHat( JoystickHatsCount index )
00322 const throw( JoystickException )
00323 {
00324
00325 if ( ! isOpen() )
00326 throw JoystickException(
00327 "Joystick::getPositionOfHat : joystick not open." ) ;
00328
00329 if ( index >= _hatCount )
00330 throw JoystickException( "Joystick::getPositionOfHat : hat index ( "
00331 + Ceylan::toString( index ) + ") out of bounds." ) ;
00332
00333 return SDL_JoystickGetHat( _internalJoystick, index ) ;
00334
00335 }
00336
00337
00338 bool Joystick::isButtonPressed( JoystickButtonsCount buttonNumber )
00339 const throw( JoystickException )
00340 {
00341
00342 if ( ! isOpen() )
00343 throw JoystickException(
00344 "Joystick::isButtonPressed : joystick not open." ) ;
00345
00346 if ( buttonNumber >= _buttonCount )
00347 throw JoystickException( "Joystick::isButtonPressed : button number ( "
00348 + Ceylan::toString( buttonNumber ) + ") out of bounds." ) ;
00349
00350 return ( SDL_JoystickGetButton( _internalJoystick, buttonNumber ) == 1 ) ;
00351
00352 }
00353
00354
00355 bool Joystick::getPositionOfTrackball( JoystickTrackballsCount ball,
00356 BallMotion & deltaX, BallMotion & deltaY ) const throw( JoystickException )
00357 {
00358
00359 if ( ! isOpen() )
00360 throw JoystickException(
00361 "Joystick::getPositionOfTrackball : joystick not open." ) ;
00362
00363 if ( ball >= _trackballCount )
00364 throw JoystickException(
00365 "Joystick::getPositionOfTrackball : trackball number ( "
00366 + Ceylan::toString( _trackballCount ) + ") out of bounds." ) ;
00367
00368 return ( SDL_JoystickGetBall(
00369 _internalJoystick, ball, & deltaX, & deltaY ) == 0 ) ;
00370
00371 }
00372
00373
00374 JoystickNumber Joystick::getIndex() const throw()
00375 {
00376
00377 if ( _internalJoystick == 0 )
00378 Ceylan::emergencyShutdown(
00379 "Joystick::getIndex : no internal joystick registered." ) ;
00380
00381 JoystickNumber index = SDL_JoystickIndex( _internalJoystick ) ;
00382
00383 #if OSDL_DEBUG
00384
00385 if ( index != _index )
00386 LogPlug::error( "Joystick::getIndex : conflicting status : "
00387 "back-end (makes authority) says index is "
00388 + Ceylan::toString( index )
00389 + " whereas internal index says "
00390 + Ceylan::toString( _index ) + "." ) ;
00391
00392 #endif // OSDL_DEBUG
00393
00394 return index ;
00395
00396 }
00397
00398
00399 void Joystick::update() throw()
00400 {
00401
00402 _axisCount = SDL_JoystickNumAxes( _internalJoystick ) ;
00403 _trackballCount = SDL_JoystickNumBalls( _internalJoystick ) ;
00404 _hatCount = SDL_JoystickNumHats( _internalJoystick ) ;
00405 _buttonCount = SDL_JoystickNumButtons( _internalJoystick ) ;
00406
00407 }
00408
00409
00410 const string Joystick::toString( Ceylan::VerbosityLevels level ) const throw()
00411 {
00412
00413 if ( ! isOpen() )
00414 return "Non-opened joystick whose index is #"
00415 + Ceylan::toString( _index )
00416 + ", named '" + _name + "'";
00417
00418 return "Opened joystick whose index is #" + Ceylan::toString( _index )
00419 + ", named '" + _name + "'. This joystick has "
00420 + Ceylan::toString( _axisCount ) + " axis, "
00421 + Ceylan::toString( _trackballCount ) + " trackball(s), "
00422 + Ceylan::toString( _hatCount ) + " hat(s), and "
00423 + Ceylan::toString( _buttonCount ) + " button(s)" ;
00424
00425 }
00426