00001 /* 00002 * Copyright (C) 2003-2009 Olivier Boudeville 00003 * 00004 * This file is part of the OSDL library. 00005 * 00006 * The OSDL library is free software: you can redistribute it and/or modify 00007 * it under the terms of either the GNU Lesser General Public License or 00008 * the GNU General Public License, as they are published by the Free Software 00009 * Foundation, either version 3 of these Licenses, or (at your option) 00010 * any later version. 00011 * 00012 * The OSDL library is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU Lesser General Public License and the GNU General Public License 00016 * for more details. 00017 * 00018 * You should have received a copy of the GNU Lesser General Public 00019 * License and of the GNU General Public License along with the OSDL library. 00020 * If not, see <http://www.gnu.org/licenses/>. 00021 * 00022 * Author: Olivier Boudeville (olivier.boudeville@esperide.com) 00023 * 00024 */ 00025 00026 00027 #include "OSDLClassicalJoystick.h" 00028 00029 #include "OSDLController.h" // for joystickAxisChanged, etc. 00030 00031 00032 using std::string ; 00033 00034 00035 using namespace Ceylan::Log ; 00036 00037 using namespace OSDL::Events ; 00038 00039 00040 00041 const AxisPosition ClassicalJoystick::DefaultDeadZoneExtent = 100 ; 00042 00043 00044 00045 #ifdef OSDL_USES_CONFIG_H 00046 #include <OSDLConfig.h> // for OSDL_VERBOSE_JOYSTICK and al 00047 #endif // OSDL_USES_CONFIG_H 00048 00049 00050 #if OSDL_ARCH_NINTENDO_DS 00051 #include "OSDLConfigForNintendoDS.h" // for OSDL_USES_SDL and al 00052 #endif // OSDL_ARCH_NINTENDO_DS 00053 00054 00055 00056 #if OSDL_USES_SDL 00057 00058 #include "SDL.h" // for CD-ROM primitives 00059 00060 #endif // OSDL_USES_SDL 00061 00062 00063 00064 #if OSDL_VERBOSE_JOYSTICK 00065 00066 #include <iostream> 00067 #define OSDL_JOYSTICK_LOG( message ) std::cout << "[OSDL Joystick] " << message << std::endl ; 00068 00069 #else // OSDL_VERBOSE_JOYSTICK 00070 00071 #define OSDL_JOYSTICK_LOG( message ) 00072 00073 #endif // OSDL_VERBOSE_JOYSTICK 00074 00075 00076 00077 00078 /* 00079 * Not used currently since event loop is prefered to polling: 00080 * - SDL_JoystickUpdate 00081 * - SDL_JoystickEventState (used in OSDLJoysticksHandler) 00082 * 00083 */ 00084 00085 00086 00087 ClassicalJoystick::ClassicalJoystick( 00088 JoystickNumber index, AxisPosition deadZoneExtent ) : 00089 Joystick( index ), 00090 _deadZoneExtentFirstAxis( deadZoneExtent ), 00091 _deadZoneExtentSecondAxis( deadZoneExtent ) 00092 { 00093 00094 #if ! OSDL_USES_SDL 00095 00096 throw JoystickException( "ClassicalJoystick constructor failed: " 00097 "no SDL support available" ) ; 00098 00099 #endif // OSDL_USES_SDL 00100 00101 } 00102 00103 00104 00105 ClassicalJoystick::~ClassicalJoystick() throw() 00106 { 00107 00108 } 00109 00110 00111 00112 void ClassicalJoystick::getDeadZoneValues( AxisPosition & firstAxisExtent, 00113 AxisPosition & secondAxisExtent ) const 00114 { 00115 00116 firstAxisExtent = _deadZoneExtentFirstAxis ; 00117 secondAxisExtent = _deadZoneExtentSecondAxis ; 00118 00119 } 00120 00121 00122 00123 void ClassicalJoystick::setDeadZoneValues( AxisPosition firstAxisExtent, 00124 AxisPosition secondAxisExtent ) 00125 { 00126 00127 _deadZoneExtentFirstAxis = firstAxisExtent ; 00128 _deadZoneExtentSecondAxis = secondAxisExtent ; 00129 00130 } 00131 00132 00133 00134 const string ClassicalJoystick::toString( Ceylan::VerbosityLevels level ) const 00135 { 00136 00137 return "Classical joystick: " + Joystick::toString( level ) 00138 + ". The first axis deadzone extent is " 00139 + Ceylan::toString( _deadZoneExtentFirstAxis ) 00140 + ", the second axis deadzone extent is " 00141 + Ceylan::toString( _deadZoneExtentSecondAxis ) ; 00142 00143 } 00144 00145 00146 00147 00148 00149 // Protected section. 00150 00151 00152 00153 void ClassicalJoystick::axisChanged( const JoystickAxisEvent & joystickEvent ) 00154 { 00155 00156 #if OSDL_USES_SDL 00157 00158 if ( isLinkedToController() ) 00159 { 00160 00161 // If in deadzone, do not notify the controller. 00162 00163 if ( joystickEvent.axis == 0 ) 00164 { 00165 if ( joystickEvent.value > _deadZoneExtentFirstAxis ) 00166 getActualController().joystickRight( joystickEvent.value ) ; 00167 else 00168 { 00169 // -1 offset to avoid overflow (range: -32768 to 32767) 00170 AxisPosition pos = -1 - joystickEvent.value ; 00171 if ( pos > _deadZoneExtentFirstAxis ) 00172 getActualController().joystickLeft( pos ) ; 00173 } 00174 00175 return ; 00176 } 00177 00178 00179 if ( joystickEvent.axis == 1 ) 00180 { 00181 if ( joystickEvent.value > _deadZoneExtentSecondAxis ) 00182 getActualController().joystickDown( joystickEvent.value ) ; 00183 else 00184 { 00185 // -1 offset to avoid overflow (range: -32768 to 32767) 00186 AxisPosition pos = -1 - joystickEvent.value ; 00187 if ( pos > _deadZoneExtentSecondAxis ) 00188 getActualController().joystickUp( pos ) ; 00189 } 00190 00191 return ; 00192 } 00193 00194 } 00195 else 00196 { 00197 OSDL_JOYSTICK_LOG( 00198 "Axis changed for controller-less classical joystick #" 00199 + Ceylan::toNumericalString( joystickEvent.which ) + ": " 00200 + EventsModule::DescribeEvent( joystickEvent ) ) ; 00201 } 00202 00203 #endif // OSDL_USES_SDL 00204 00205 } 00206 00207 00208 00209 void ClassicalJoystick::buttonPressed( 00210 const JoystickButtonEvent & joystickEvent ) 00211 { 00212 00213 #if OSDL_USES_SDL 00214 00215 if ( isLinkedToController() ) 00216 { 00217 00218 switch( joystickEvent.button ) 00219 { 00220 00221 case 0: 00222 getActualController().joystickFirstButtonPressed() ; 00223 break ; 00224 00225 case 1: 00226 getActualController().joystickSecondButtonPressed() ; 00227 break ; 00228 00229 default: 00230 OSDL_JOYSTICK_LOG( 00231 "Button (neither first or second, hence ignored) " 00232 "pressed for classical joystick #" 00233 + Ceylan::toNumericalString( joystickEvent.which ) + ": " 00234 + EventsModule::DescribeEvent( joystickEvent ) ) ; 00235 break ; 00236 } 00237 00238 00239 } 00240 else 00241 { 00242 OSDL_JOYSTICK_LOG( 00243 "Button pressed for controller-less classical joystick #" 00244 + Ceylan::toNumericalString( joystickEvent.which ) + ": " 00245 + EventsModule::DescribeEvent( joystickEvent ) ) ; 00246 } 00247 00248 #endif // OSDL_USES_SDL 00249 00250 } 00251 00252 00253 00254 void ClassicalJoystick::buttonReleased( 00255 const JoystickButtonEvent & joystickEvent ) 00256 { 00257 00258 #if OSDL_USES_SDL 00259 00260 if ( isLinkedToController() ) 00261 { 00262 00263 switch( joystickEvent.button ) 00264 { 00265 00266 case 0: 00267 getActualController().joystickFirstButtonReleased() ; 00268 break ; 00269 00270 case 1: 00271 getActualController().joystickSecondButtonReleased() ; 00272 break ; 00273 00274 default: 00275 OSDL_JOYSTICK_LOG( 00276 "Button (neither first or second, hence ignored) " 00277 "released for classical joystick #" 00278 + Ceylan::toNumericalString( joystickEvent.which ) + ": " 00279 + EventsModule::DescribeEvent( joystickEvent ) ) ; 00280 break ; 00281 } 00282 00283 } 00284 else 00285 { 00286 00287 OSDL_JOYSTICK_LOG( 00288 "Button released for controller-less classical joystick #" 00289 + Ceylan::toNumericalString( joystickEvent.which ) + ": " 00290 + EventsModule::DescribeEvent( joystickEvent ) ) ; 00291 } 00292 00293 #endif // OSDL_USES_SDL 00294 00295 } 00296