InputDeviceJoystick.cpp

Go to the documentation of this file.
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 }

Get Racer at SourceForge.net. Fast, secure and Free Open Source software downloads

Generated at Mon Sep 6 00:41:12 2010 by Doxygen version 1.4.7 for Racer version svn335.