00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 #include "OSDLJoystick.h"       
00028 
00029 #include "OSDLController.h"     
00030 
00031 
00032 using std::string ;
00033 
00034 
00035 using namespace Ceylan::Log ;
00036 
00037 using namespace OSDL::Events ;
00038 using namespace OSDL::MVC ;     
00039 
00040 
00041 #ifdef OSDL_USES_CONFIG_H
00042 #include "OSDLConfig.h"         
00043 #endif // OSDL_USES_CONFIG_H
00044 
00045 #if OSDL_ARCH_NINTENDO_DS
00046 #include "OSDLConfigForNintendoDS.h" 
00047 #endif // OSDL_ARCH_NINTENDO_DS
00048 
00049 
00050 
00051 
00052 
00053 #if OSDL_VERBOSE_JOYSTICK
00054 
00055 #include <iostream>
00056 #define OSDL_JOYSTICK_LOG( message ) std::cout << "[OSDL Joystick] " << message << std::endl ;
00057 
00058 #else // OSDL_VERBOSE_JOYSTICK
00059 
00060 #define OSDL_JOYSTICK_LOG( message )
00061 
00062 #endif // OSDL_VERBOSE_JOYSTICK
00063 
00064 
00065 
00077 
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 Joystick::Joystick( JoystickNumber index ) :
00086     OSDL::Events::InputDevice(),
00087 #if OSDL_USES_SDL
00088     _name( SDL_JoystickName( index ) ),
00089 #else 
00090     _name(),
00091 #endif 
00092     _index( index ),
00093     _internalJoystick( 0 ),
00094     _axisCount( 0 ),
00095     _trackballCount( 0 ),
00096     _hatCount( 0 ),
00097     _buttonCount( 0 )
00098 {
00099 
00100 #if OSDL_USES_SDL
00101 
00102     if ( _name.empty() )
00103         _name = "(unknown joystick)" ;
00104 
00105 #else // OSDL_USES_SDL
00106 
00107     throw JoystickException( "Joystick constructor failed: "
00108         "no SDL support available" ) ;
00109 
00110 #endif // OSDL_USES_SDL
00111     
00112 }
00113 
00114 
00115 
00116 Joystick::~Joystick() throw()
00117 {
00118 
00119     if ( isOpen() )
00120         close() ;
00121         
00122     
00123 
00124 
00125 
00126 
00127 
00128 
00129         
00130 }
00131 
00132 
00133 
00134 const string & Joystick::getName() const
00135 {
00136 
00137     return _name ;
00138     
00139 }
00140 
00141 
00142 
00143 bool Joystick::isOpen() const
00144 {
00145 
00146 #if OSDL_USES_SDL
00147     
00148     bool isOpened = ( SDL_JoystickOpened( _index ) == 1 ) ;
00149     
00150 #if OSDL_DEBUG
00151     if ( isOpened != ( _internalJoystick != 0 ) ) 
00152         LogPlug::error( "Joystick::isOpen: conflicting status: "
00153             "back-end (makes authority) says " + Ceylan::toString( isOpened ) 
00154             + " whereas internal status says " 
00155             + Ceylan::toString( ( _internalJoystick != 0 ) )
00156             + "." ) ;           
00157 #endif // OSDL_DEBUG 
00158     
00159     return isOpened ;
00160 
00161 #else // OSDL_USES_SDL
00162 
00163     return false ;
00164 
00165 #endif // OSDL_USES_SDL
00166     
00167 }
00168 
00169 
00170 
00171 void Joystick::open()
00172 {
00173 
00174 #if OSDL_USES_SDL
00175 
00176     if ( isOpen() )
00177         throw JoystickException( 
00178             "Joystick::open requested whereas was already open." ) ;
00179         
00180     _internalJoystick = SDL_JoystickOpen( _index ) ;
00181     
00182     update() ;
00183     
00184 #endif // OSDL_USES_SDL
00185     
00186 }
00187 
00188  
00189  
00190 void Joystick::close()
00191 {
00192 
00193 #if OSDL_USES_SDL
00194 
00195     if ( ! isOpen() )
00196         throw JoystickException( 
00197             "Joystick::close requested whereas was not open." ) ;
00198         
00199     SDL_JoystickClose( _internalJoystick ) ;
00200     
00201     
00202     _internalJoystick = 0 ;
00203 
00204 #endif // OSDL_USES_SDL
00205     
00206 }
00207 
00208 
00209 
00210 void Joystick::axisChanged( const JoystickAxisEvent & joystickEvent )
00211 {
00212     
00213     if ( isLinkedToController() )
00214         getActualController().joystickAxisChanged( joystickEvent ) ;            
00215     else
00216     {
00217         OSDL_JOYSTICK_LOG( "Axis changed for joystick #" 
00218             + Ceylan::toNumericalString( joystickEvent.which ) + ": "
00219             + EventsModule::DescribeEvent( joystickEvent ) ) ;
00220     }
00221             
00222 }
00223 
00224 
00225 
00226 void Joystick::trackballChanged( const JoystickTrackballEvent & joystickEvent )
00227 {
00228     
00229     if ( isLinkedToController() )
00230         getActualController().joystickTrackballChanged( joystickEvent ) ;       
00231     else
00232     {
00233         OSDL_JOYSTICK_LOG( "Trackball changed for joystick #" 
00234             + Ceylan::toNumericalString( joystickEvent.which ) + ": "
00235             + EventsModule::DescribeEvent( joystickEvent ) ) ;
00236     }
00237             
00238 }
00239 
00240 
00241 
00242 void Joystick::hatChanged( const JoystickHatEvent & joystickEvent )
00243 {
00244     
00245     if ( isLinkedToController() )
00246         getActualController().joystickHatChanged( joystickEvent ) ;         
00247     else
00248     {
00249         OSDL_JOYSTICK_LOG( "Hat changed for joystick #" 
00250             + Ceylan::toNumericalString( joystickEvent.which ) + ": "
00251             + EventsModule::DescribeEvent( joystickEvent ) ) ;
00252     }       
00253             
00254 }
00255 
00256 
00257 
00258 void Joystick::buttonPressed( const JoystickButtonEvent & joystickEvent )
00259 {
00260     
00261     if ( isLinkedToController() )
00262         getActualController().joystickButtonPressed( joystickEvent ) ;          
00263     else
00264     {
00265         OSDL_JOYSTICK_LOG( "Button pressed for joystick #" 
00266             + Ceylan::toNumericalString( joystickEvent.which ) + ": "
00267             + EventsModule::DescribeEvent( joystickEvent ) ) ;
00268     }
00269         
00270 }
00271 
00272 
00273 
00274 void Joystick::buttonReleased( const JoystickButtonEvent & joystickEvent )
00275 {
00276     
00277     if ( isLinkedToController() )
00278         getActualController().joystickButtonReleased( joystickEvent ) ;         
00279     else
00280     {
00281         OSDL_JOYSTICK_LOG( "Button released for joystick #" 
00282             + Ceylan::toNumericalString( joystickEvent.which ) + ": "
00283             + EventsModule::DescribeEvent( joystickEvent ) ) ;
00284     }       
00285             
00286 }
00287 
00288 
00289 
00290 JoystickAxesCount Joystick::getNumberOfAxes() const
00291 {
00292 
00293 #if OSDL_DEBUG
00294     if ( ! isOpen() )
00295         Ceylan::emergencyShutdown( 
00296             "Joystick::getNumberOfAxes: joystick not open." ) ; 
00297 #endif // OSDL_DEBUG
00298 
00299     return _axisCount ;
00300     
00301 }
00302 
00303 
00304 
00305 JoystickTrackballsCount Joystick::getNumberOfTrackballs() const
00306 {
00307 
00308 #if OSDL_DEBUG
00309     if ( ! isOpen() )
00310         Ceylan::emergencyShutdown( 
00311             "Joystick::getNumberOfTrackballs: joystick not open." ) ;   
00312 #endif // OSDL_DEBUG
00313 
00314     return _trackballCount ;
00315     
00316 }
00317 
00318 
00319 
00320 JoystickHatsCount Joystick::getNumberOfHats() const
00321 {
00322 
00323 #if OSDL_DEBUG
00324     if ( ! isOpen() )
00325         Ceylan::emergencyShutdown( 
00326             "Joystick::getNumberOfHats: joystick not open." ) ; 
00327 #endif // OSDL_DEBUG
00328     
00329     return _hatCount ;
00330     
00331 }
00332 
00333 
00334 
00335 JoystickButtonsCount Joystick::getNumberOfButtons() const
00336 {
00337 
00338 #if OSDL_DEBUG
00339     if ( ! isOpen() )
00340         Ceylan::emergencyShutdown( 
00341             "Joystick::getNumberOfButtons: joystick not open." ) ;  
00342 #endif // OSDL_DEBUG
00343     
00344     return _buttonCount ;
00345     
00346 }
00347 
00348 
00349 
00350 AxisPosition Joystick::getAbscissaPosition() const
00351 {
00352 
00353 #if OSDL_USES_SDL
00354 
00355 #if OSDL_DEBUG
00356     if ( ! isOpen() )
00357         Ceylan::emergencyShutdown( 
00358             "Joystick::getAbscissaPosition: joystick not open." ) ;
00359         
00360     if ( _axisCount == 0 )
00361         Ceylan::emergencyShutdown( 
00362             "Joystick::getAbscissaPosition: no X axe available." ) ;
00363     
00364 #endif // OSDL_DEBUG
00365     
00366     return SDL_JoystickGetAxis( _internalJoystick, 0 ) ;
00367 
00368 #else // OSDL_USES_SDL
00369 
00370     return 0 ;
00371 
00372 #endif // OSDL_USES_SDL
00373     
00374 }
00375 
00376 
00377 
00378 AxisPosition Joystick::getOrdinatePosition() const 
00379 {
00380 
00381 #if OSDL_USES_SDL
00382 
00383 #if OSDL_DEBUG
00384     if ( ! isOpen() )
00385         Ceylan::emergencyShutdown( 
00386             "Joystick::getOrdinatePosition: joystick not open." ) ;
00387         
00388     if ( _axisCount <= 1 )
00389         Ceylan::emergencyShutdown( 
00390             "Joystick::getOrdinatePosition: no Y axe available." ) ;
00391     
00392 #endif // OSDL_DEBUG
00393 
00394     return SDL_JoystickGetAxis( _internalJoystick, 1 ) ;
00395     
00396 #else // OSDL_USES_SDL
00397 
00398     return 0 ;
00399 
00400 #endif // OSDL_USES_SDL
00401 
00402 }
00403 
00404 
00405 
00406 AxisPosition Joystick::getPositionOfAxis( JoystickAxesCount index ) const
00407 {
00408 
00409 #if OSDL_USES_SDL
00410 
00411     if ( ! isOpen() )
00412         throw JoystickException( 
00413             "Joystick::getPositionOfAxis: joystick not open." ) ;
00414     
00415     if ( index >= _axisCount )
00416         throw JoystickException( "Joystick::getPositionOfAxis: axe index ( " 
00417             + Ceylan::toString( index ) + ") out of bounds." ) ;
00418         
00419     return SDL_JoystickGetAxis( _internalJoystick, index ) ;
00420 
00421 #else // OSDL_USES_SDL
00422 
00423     return 0 ;
00424 
00425 #endif // OSDL_USES_SDL
00426     
00427 }
00428 
00429 
00430 
00431 HatPosition Joystick::getPositionOfHat( JoystickHatsCount index ) const
00432 {
00433 
00434 #if OSDL_USES_SDL
00435 
00436     if ( ! isOpen() )
00437         throw JoystickException( 
00438             "Joystick::getPositionOfHat: joystick not open." ) ;
00439     
00440     if ( index >= _hatCount )
00441         throw JoystickException( "Joystick::getPositionOfHat: hat index ( " 
00442             + Ceylan::toString( index ) + ") out of bounds." ) ;
00443         
00444     return SDL_JoystickGetHat( _internalJoystick, index ) ;
00445 
00446 #else // OSDL_USES_SDL
00447 
00448     return 0 ;
00449 
00450 #endif // OSDL_USES_SDL
00451     
00452 }
00453 
00454 
00455 
00456 bool Joystick::isButtonPressed( JoystickButtonsCount buttonNumber ) const
00457 {
00458 
00459 #if OSDL_USES_SDL
00460 
00461     if ( ! isOpen() )
00462         throw JoystickException( 
00463             "Joystick::isButtonPressed: joystick not open." ) ;
00464     
00465     if ( buttonNumber >= _buttonCount )
00466         throw JoystickException( "Joystick::isButtonPressed: button number ( " 
00467             + Ceylan::toString( buttonNumber ) + ") out of bounds." ) ;
00468 
00469     return ( SDL_JoystickGetButton( _internalJoystick, buttonNumber ) == 1 ) ;
00470 
00471 #else // OSDL_USES_SDL
00472 
00473     return 0 ;
00474 
00475 #endif // OSDL_USES_SDL
00476     
00477 }
00478 
00479 
00480 
00481 bool Joystick::getPositionOfTrackball( JoystickTrackballsCount ball, 
00482     BallMotion & deltaX, BallMotion & deltaY ) const                
00483 {
00484 
00485 #if OSDL_USES_SDL
00486 
00487     if ( ! isOpen() )
00488         throw JoystickException( 
00489             "Joystick::getPositionOfTrackball: joystick not open." ) ;
00490     
00491     if ( ball >= _trackballCount )
00492         throw JoystickException( 
00493             "Joystick::getPositionOfTrackball: trackball number ( " 
00494             + Ceylan::toString( _trackballCount ) + ") out of bounds." ) ;
00495             
00496     return ( SDL_JoystickGetBall( 
00497         _internalJoystick, ball, & deltaX, & deltaY ) == 0 ) ;
00498 
00499 #else // OSDL_USES_SDL
00500 
00501     return 0 ;
00502 
00503 #endif // OSDL_USES_SDL
00504 
00505 }
00506 
00507 
00508     
00509 JoystickNumber Joystick::getIndex() const
00510 {
00511 
00512 #if OSDL_USES_SDL
00513 
00514     if ( _internalJoystick == 0 )
00515         Ceylan::emergencyShutdown( 
00516             "Joystick::getIndex: no internal joystick registered." ) ;
00517     
00518     JoystickNumber index = SDL_JoystickIndex( _internalJoystick ) ;
00519     
00520 #if OSDL_DEBUG
00521 
00522     if ( index != _index ) 
00523         LogPlug::error( "Joystick::getIndex: conflicting status: "
00524             "back-end (makes authority) says index is " 
00525             + Ceylan::toString( index ) 
00526             + " whereas internal index says " 
00527             + Ceylan::toString( _index ) + "." ) ;  
00528                     
00529 #endif // OSDL_DEBUG
00530 
00531     return index ;
00532 
00533 #else // OSDL_USES_SDL
00534 
00535     return 0 ;
00536 
00537 #endif // OSDL_USES_SDL
00538     
00539 }
00540 
00541 
00542 
00543 void Joystick::update()
00544 {
00545 
00546 #if OSDL_USES_SDL
00547 
00548     _axisCount      = SDL_JoystickNumAxes(    _internalJoystick ) ;
00549     _trackballCount = SDL_JoystickNumBalls(   _internalJoystick ) ;
00550     _hatCount       = SDL_JoystickNumHats(    _internalJoystick ) ;
00551     _buttonCount    = SDL_JoystickNumButtons( _internalJoystick ) ;
00552 
00553 #endif // OSDL_USES_SDL
00554     
00555 }
00556 
00557 
00558 
00559 const string Joystick::toString( Ceylan::VerbosityLevels level ) const
00560 {
00561 
00562     if ( ! isOpen() )
00563         return "Non-opened joystick whose index is #" 
00564             + Ceylan::toString( _index ) 
00565             + ", named '" + _name + "'";
00566         
00567     return "Opened joystick whose index is #" + Ceylan::toString( _index ) 
00568         + ", named '" + _name + "'. This joystick has "
00569         + Ceylan::toString( _axisCount ) + " axis, " 
00570         + Ceylan::toString( _trackballCount ) + " trackball(s), "
00571         + Ceylan::toString( _hatCount ) + " hat(s), and "
00572         + Ceylan::toString( _buttonCount ) + " button(s)" ;
00573                 
00574 }
00575