00001 00005 /* Copyright © 2009, 2010 James Legg. 00006 This program is free software: you can redistribute it and/or modify 00007 it under the terms of the GNU General Public License as published by 00008 the Free Software Foundation, either version 3 of the License, or 00009 (at your option) any later version. 00010 */ 00011 00012 #include "InputDeviceJoystick.h" 00013 #include <Debug.h> 00014 #include "GameObjects/Car.h" 00015 00016 namespace Engine 00017 { 00018 00019 InputDeviceJoystick::InputDeviceJoystick(int index) 00020 : joystick_index(index) 00021 , steering(0) 00022 , acceleration(0) 00023 , slide(0) 00024 , slide_left_down(false) 00025 , slide_right_down(false) 00026 { 00027 SDL_JoystickEventState(SDL_ENABLE); 00028 assert(SDL_NumJoysticks() > index); 00029 sdl_joystick_handle = SDL_JoystickOpen(joystick_index); 00030 } 00031 00032 InputDeviceJoystick::~InputDeviceJoystick() 00033 { 00034 if (SDL_JoystickOpen(joystick_index)) 00035 { 00036 SDL_JoystickClose(sdl_joystick_handle); 00037 } 00038 } 00039 00040 int InputDeviceJoystick::get_steering() 00041 { 00042 return steering; 00043 } 00044 00045 int InputDeviceJoystick::get_acceleration() 00046 { 00047 return acceleration; 00048 } 00049 00050 int InputDeviceJoystick::get_slide() 00051 { 00052 if (slide_left_down && !slide_right_down) return -32767; 00053 else if (slide_right_down && !slide_left_down) return 32767; 00054 else return slide; 00055 } 00056 00057 void InputDeviceJoystick::poll() 00058 { 00059 SDL_Event event; 00060 SDL_PumpEvents(); 00061 00062 // Messages about other events to put back on the queue when we've checked 00063 // them all. 00064 std::vector<SDL_Event> rejects; 00065 00066 while (SDL_PeepEvents 00067 (&event, 1, SDL_GETEVENT, 00068 SDL_EVENTMASK(SDL_JOYAXISMOTION) | 00069 SDL_EVENTMASK(SDL_JOYBUTTONDOWN) | 00070 SDL_EVENTMASK(SDL_JOYBUTTONUP) 00071 ) > 0 00072 ) 00073 { 00074 if (event.type == SDL_JOYAXISMOTION) 00075 { 00076 if (event.jaxis.which != joystick_index) 00077 { 00078 // This event is for a different joystick device. 00079 // add it to the rejects queue. 00080 rejects.push_back(event); 00081 } 00082 else 00083 { 00084 // an axis changed. 00085 int new_value = event.jaxis.value; 00086 switch (event.jaxis.axis) 00087 { 00088 case 0: 00089 // turn left or right. 00090 report(InputReport::RT_CHANGE_STEERING, new_value); 00091 if ((steering >= -16384) && (new_value < -16384)) 00092 { 00093 report(InputReport::RT_MENU_LEFT); 00094 } 00095 if ((steering < 16384) && (new_value >= 16384)) 00096 { 00097 report(InputReport::RT_MENU_RIGHT); 00098 } 00099 steering = new_value; 00100 break; 00101 case 1: 00102 // acceleration 00103 if (new_value == -32768) new_value = -32767; 00104 new_value = -new_value; 00105 report(InputReport::RT_CHANGE_ACCEL, new_value); 00106 // if it crosses the half way point consider it a menu selection too. 00107 if ((acceleration >= -16384) && (new_value < -16384)) 00108 { 00109 report(InputReport::RT_MENU_DOWN); 00110 } 00111 if ((acceleration < 16384) && (new_value >= 16384)) 00112 { 00113 report(InputReport::RT_MENU_UP); 00114 } 00115 acceleration = new_value; 00116 break; 00117 case 2: 00118 // slide 00119 if (new_value == -32768) new_value = -32767; 00120 report(InputReport::RT_CHANGE_SLIDE, new_value); 00121 slide = new_value; 00122 break; 00123 default: 00124 // unused axis 00125 break; 00126 } 00127 } 00128 } 00129 else 00130 { 00131 if (event.jbutton.which != joystick_index) 00132 { 00133 // This event is for a different joystick device. 00134 // add it to the rejects queue. 00135 rejects.push_back(event); 00136 } 00137 else 00138 { 00139 bool new_state = event.type == SDL_JOYBUTTONDOWN; 00140 switch (event.jbutton.button) 00141 { 00142 case 0: 00143 case 2: 00144 if (new_state) 00145 { 00146 report(InputReport::RT_MENU_SELECT); 00147 } 00148 break; 00149 case 1: 00150 case 3: 00151 if (new_state) 00152 { 00153 report(InputReport::RT_MENU_BACK); 00154 } 00155 break; 00156 case 4: 00157 slide_left_down = new_state; 00158 report(InputReport::RT_CHANGE_SLIDE, get_slide()); 00159 break; 00160 case 5: 00161 slide_right_down = new_state; 00162 report(InputReport::RT_CHANGE_SLIDE, get_slide()); 00163 break; 00164 default: 00165 // unhandled button. Don't report any events. 00166 break; 00167 } 00168 } 00169 } 00170 } 00171 // put messages about other joysticks back on the event queue. 00172 for (std::vector<SDL_Event>::iterator it = rejects.begin(); 00173 it != rejects.end(); it++) 00174 { 00175 SDL_PushEvent(&(*it)); 00176 } 00177 } 00178 00179 }
Generated at Mon Sep 6 00:41:12 2010 by Doxygen version 1.4.7 for Racer version svn335.