00001 #include "OSDLJoystickHandler.h"
00002
00003 #include "OSDLJoystick.h"
00004 #include "OSDLClassicalJoystick.h"
00005 #include "OSDLController.h"
00006
00007 #include "OSDLUtils.h"
00008 #include "OSDLBasic.h"
00009
00010
00011 #include "Ceylan.h"
00012
00013
00014 #include "SDL.h"
00015
00016
00017 using std::string ;
00018 using std::list ;
00019
00020 using namespace Ceylan::Log ;
00021
00022 using namespace OSDL::Events ;
00023
00024
00025 const string DebugPrefix = " " ;
00026
00027
00028 #ifdef OSDL_USES_CONFIG_H
00029 #include <OSDLConfig.h>
00030 #endif // OSDL_USES_CONFIG_H
00031
00032
00033 #if OSDL_VERBOSE_JOYSTICK_HANDLER
00034
00035 #include <iostream>
00036 #define OSDL_JOYSTICK_HANDLER_LOG( message ) std::cout << "[OSDL Joystick Handler] " << message << std::endl ;
00037
00038 #else // OSDL_VERBOSE_JOYSTICK_HANDLER
00039
00040 #define OSDL_JOYSTICK_HANDLER_LOG( message )
00041
00042 #endif // OSDL_VERBOSE_JOYSTICK_HANDLER
00043
00044
00045
00046 JoystickHandler::JoystickHandler( bool useClassicalJoysticks )
00047 throw( InputDeviceHandlerException ) :
00048 InputDeviceHandler(),
00049 _joystickCount( 0 ),
00050 _joysticks( 0 ),
00051 _useClassicalJoysticks( useClassicalJoysticks )
00052 {
00053
00054 send( "Initializing joystick subsystem." ) ;
00055
00056 if ( SDL_InitSubSystem( CommonModule::UseVideo )
00057 != CommonModule::BackendSuccess )
00058 throw JoystickException( "JoystickHandler constructor : "
00059 "unable to initialize joystick subsystem : "
00060 + Utils::getBackendLastError() ) ;
00061
00062
00063 SDL_JoystickEventState( SDL_ENABLE ) ;
00064
00065 update() ;
00066
00067 send( "Joystick subsystem initialized." ) ;
00068
00069 dropIdentifier() ;
00070
00071 }
00072
00073
00074 JoystickHandler::~JoystickHandler() throw()
00075 {
00076
00077 send( "Stopping joystick subsystem." ) ;
00078
00079
00080 blank() ;
00081
00082 SDL_QuitSubSystem( CommonModule::UseJoystick ) ;
00083
00084 send( "Joystick subsystem stopped." ) ;
00085
00086 }
00087
00088
00089
00090 void JoystickHandler::update() throw()
00091 {
00092
00093
00094
00095
00096
00097
00098
00099 blank() ;
00100
00101
00102
00103 _joystickCount = GetAvailableJoystickCount() ;
00104
00105 send( Ceylan::toString( _joystickCount ) + " joystick(s) auto-detected." ) ;
00106
00107
00108
00109
00110
00111
00112 _joysticks = new Joystick *[ _joystickCount ] ;
00113
00114 for ( JoystickNumber i = 0; i < _joystickCount; i++ )
00115 if ( _useClassicalJoysticks )
00116 _joysticks[i] = new ClassicalJoystick( i ) ;
00117 else
00118 _joysticks[i] = new Joystick( i ) ;
00119
00120 }
00121
00122
00123 void JoystickHandler::openJoystick( JoystickNumber index )
00124 throw( JoystickException )
00125 {
00126
00127
00128
00129
00130
00131
00132 if ( index >= GetAvailableJoystickCount() )
00133 throw JoystickException( "JoystickHandler::openJoystick : index "
00134 + Ceylan::toString( index) + " out of bounds ("
00135 + Ceylan::toString( GetAvailableJoystickCount() )
00136 + " joystick(s) attached)." ) ;
00137
00138 if ( index >= _joystickCount )
00139 throw JoystickException( "JoystickHandler::openJoystick : index "
00140 + Ceylan::toString( index) + " out of bounds ("
00141 + Ceylan::toString( _joystickCount )
00142 + " joystick(s) attached according to internal joystick list)." ) ;
00143
00144 #if OSDL_DEBUG
00145 if ( _joysticks[ index ] == 0 )
00146 throw JoystickException( "JoystickHandler::openJoystick : "
00147 "no known joystick for index " + Ceylan::toString( index ) + "." ) ;
00148 #endif // OSDL_DEBUG
00149
00150 if ( ! _joysticks[ index ]->isOpen() )
00151 _joysticks[ index ]->open() ;
00152
00153 }
00154
00155
00156 void JoystickHandler::linkToController( JoystickNumber index,
00157 OSDL::MVC::Controller & controller ) throw( JoystickException )
00158 {
00159
00160
00161
00162
00163
00164
00165 if ( index >= static_cast<JoystickNumber>( GetAvailableJoystickCount() ) )
00166 throw JoystickException( "JoystickHandler::linkToController : index "
00167 + Ceylan::toString( index) + " out of bounds ("
00168 + Ceylan::toString( GetAvailableJoystickCount() )
00169 + " joystick(s) attached)." ) ;
00170
00171 if ( index >= _joystickCount )
00172 throw JoystickException( "JoystickHandler::linkToController : index "
00173 + Ceylan::toString( index) + " out of bounds ("
00174 + Ceylan::toString( _joystickCount )
00175 + " joystick(s) attached according to internal joystick list)." ) ;
00176
00177 #if OSDL_DEBUG
00178 if ( _joysticks[ index ] == 0 )
00179 throw JoystickException( "JoystickHandler::linkToController : "
00180 "no known joystick for index " + Ceylan::toString( index ) + "." ) ;
00181 #endif // OSDL_DEBUG
00182
00183 _joysticks[ index ]->setController( controller ) ;
00184
00185 }
00186
00187
00188 const string JoystickHandler::toString( Ceylan::VerbosityLevels level )
00189 const throw()
00190 {
00191
00192 string res ;
00193
00194 if ( _joystickCount > 0 )
00195 res = "Joystick handler managing "
00196 + Ceylan::toString( _joystickCount ) + " joystick(s)" ;
00197 else
00198 return "Joystick handler does not manage any joystick" ;
00199
00200 if ( level == Ceylan::low )
00201 return res ;
00202
00203 res += ". Listing detected joystick(s) : " ;
00204
00205 list<string> joysticks ;
00206
00207 for ( JoystickNumber i = 0; i < _joystickCount; i++ )
00208 if ( _joysticks[i] != 0 )
00209 joysticks.push_back( _joysticks[i]->toString( level ) ) ;
00210 else
00211 joysticks.push_back( "no joystick at index "
00212 + Ceylan::toString( i ) + " (abnormal)" ) ;
00213
00214 return res + Ceylan::formatStringList( joysticks ) ;
00215
00216 }
00217
00218
00219
00220 JoystickNumber JoystickHandler::GetAvailableJoystickCount() throw()
00221 {
00222
00223 return static_cast<JoystickNumber>( SDL_NumJoysticks() ) ;
00224
00225 }
00226
00227
00228
00229
00230
00231
00232 void JoystickHandler::axisChanged( const JoystickAxisEvent & joystickEvent )
00233 const throw()
00234 {
00235
00236 #if OSDL_DEBUG
00237 checkJoystickAt( joystickEvent.which ) ;
00238 #endif // OSDL_DEBUG
00239
00240 _joysticks[ joystickEvent.which ]->axisChanged( joystickEvent ) ;
00241
00242 }
00243
00244
00245 void JoystickHandler::trackballChanged(
00246 const JoystickTrackballEvent & joystickEvent ) const throw()
00247 {
00248
00249 #if OSDL_DEBUG
00250 checkJoystickAt( joystickEvent.which ) ;
00251 #endif // OSDL_DEBUG
00252
00253 _joysticks[ joystickEvent.which ]->trackballChanged( joystickEvent ) ;
00254
00255 }
00256
00257
00258 void JoystickHandler::hatChanged( const JoystickHatEvent & joystickEvent )
00259 const throw()
00260 {
00261
00262 #if OSDL_DEBUG
00263 checkJoystickAt( joystickEvent.which ) ;
00264 #endif // OSDL_DEBUG
00265
00266 _joysticks[ joystickEvent.which ]->hatChanged( joystickEvent ) ;
00267
00268 }
00269
00270
00271 void JoystickHandler::buttonPressed( const JoystickButtonEvent & joystickEvent )
00272 const throw()
00273 {
00274
00275 #if OSDL_DEBUG
00276 checkJoystickAt( joystickEvent.which ) ;
00277 #endif // OSDL_DEBUG
00278
00279 _joysticks[ joystickEvent.which ]->buttonPressed( joystickEvent ) ;
00280
00281 }
00282
00283
00284 void JoystickHandler::buttonReleased(
00285 const JoystickButtonEvent & joystickEvent ) const throw()
00286 {
00287
00288 #if OSDL_DEBUG
00289 checkJoystickAt( joystickEvent.which ) ;
00290 #endif // OSDL_DEBUG
00291
00292 _joysticks[ joystickEvent.which ]->buttonReleased( joystickEvent ) ;
00293
00294 }
00295
00296
00297
00298 void JoystickHandler::blank() throw()
00299 {
00300
00301 if ( _joysticks != 0 )
00302 {
00303
00304 for ( JoystickNumber c = 0; c < _joystickCount; c++ )
00305 {
00306 delete _joysticks[c] ;
00307 }
00308
00309 delete [] _joysticks ;
00310 _joysticks = 0 ;
00311 }
00312
00313 _joystickCount = 0 ;
00314
00315 }
00316
00317
00318 void JoystickHandler::checkJoystickAt( JoystickNumber index ) const throw()
00319 {
00320
00321 if ( index >= _joystickCount )
00322 Ceylan::emergencyShutdown(
00323 "JoystickHandler::checkJoystickAt : index "
00324 + Ceylan::toNumericalString( index )
00325 + " out of bounds (maximum value is "
00326 + Ceylan::toNumericalString( _joystickCount - 1 ) + ")." ) ;
00327
00328 if ( _joysticks[ index ] == 0 )
00329 Ceylan::emergencyShutdown( "JoystickHandler::checkJoystickAt : "
00330 "no joystick intance at index "
00331 + Ceylan::toNumericalString( index ) + "." ) ;
00332
00333 if ( ! _joysticks[ index ]->isOpen() )
00334 Ceylan::emergencyShutdown(
00335 "JoystickHandler::checkJoystickAt : joystick at index "
00336 + Ceylan::toNumericalString( index ) + " was not open." ) ;
00337
00338 }
00339