Go to the documentation of this file.00001
00010 #include "UsbJoystick.h"
00011 #include "SdlJoystickInit.h"
00012 #include <SDL.h>
00013 #include <SDL_joystick.h>
00014 #include <vector>
00015 #include <string>
00016
00017 using namespace qrk;
00018 using namespace std;
00019
00020
00021 struct UsbJoystick::pImpl : private SdlJoystickInit
00022 {
00024 class JoystickGroup
00025 {
00026 public:
00027
00029 class JoystickInfo
00030 {
00031 public:
00032 SDL_Joystick* ptr_;
00033 int own_index_;
00034 vector<short> axis_value_;
00035 vector<bool> button_value_;
00036
00037 JoystickInfo(void) : ptr_(NULL), own_index_(-1)
00038 {
00039 }
00040 };
00041 vector<JoystickInfo> js_;
00042
00043 static JoystickGroup* object(void)
00044 {
00045 static JoystickGroup singleton_object;
00046 return &singleton_object;
00047 }
00048 };
00049
00050 JoystickGroup* joysticks_;
00051 string error_message_;
00052 size_t own_id_;
00053 size_t axis_num_;
00054 size_t buttons_num_;
00055
00056 pImpl(void)
00057 : joysticks_(JoystickGroup::object()), error_message_("no error"),
00058 own_id_(joysticks_->js_.size()), axis_num_(0), buttons_num_(0)
00059 {
00060 JoystickGroup::JoystickInfo joystick_info_;
00061 joysticks_->js_.push_back(joystick_info_);
00062 }
00063
00064
00065 bool connect(int index)
00066 {
00067 if (SDL_JoystickOpened(index)) {
00068 error_message_ = "already connected.";
00069 return false;
00070 }
00071
00072 SDL_Joystick* p = SDL_JoystickOpen(index);
00073 if (p == NULL) {
00074 error_message_ = SDL_GetError();
00075 return false;
00076 }
00077 joysticks_->js_[own_id_].ptr_ = p;
00078 joysticks_->js_[own_id_].own_index_ = index;
00079 axis_num_ = SDL_JoystickNumAxes(p);
00080 buttons_num_ = SDL_JoystickNumButtons(p);
00081 for (size_t i = 0; i < axis_num_; ++i) {
00082 joysticks_->js_[own_id_].axis_value_.push_back(0);
00083 }
00084 for (size_t i = 0; i < buttons_num_; ++i) {
00085 joysticks_->js_[own_id_].button_value_.push_back(false);
00086 }
00087 return true;
00088 }
00089
00090
00091 void joyAxisEventHandler(SDL_JoyAxisEvent& event)
00092 {
00093 joysticks_->js_[event.which].axis_value_[event.axis] = event.value;
00094 }
00095
00096
00097 void joyButtonEventHandler(SDL_JoyButtonEvent& event)
00098 {
00099 joysticks_->js_[event.which].button_value_[event.button] =
00100 (event.state == SDL_PRESSED) ? true : false;
00101 }
00102 };
00103
00104
00105 UsbJoystick::UsbJoystick(void) : pimpl(new pImpl)
00106 {
00107 }
00108
00109
00110 UsbJoystick::~UsbJoystick(void)
00111 {
00112 disconnect();
00113 }
00114
00115
00116 const char* UsbJoystick::what(void) const
00117 {
00118 return pimpl->error_message_.c_str();
00119 }
00120
00121
00122 bool UsbJoystick::connect(int id)
00123 {
00124 if (id >= 0) {
00125 return pimpl->connect(id);
00126
00127 } else {
00128 size_t n = joystickNum();
00129 if (n <= 0) {
00130 pimpl->error_message_ = "No joystick device.";
00131 return false;
00132 }
00133 for (size_t i = 0; i < n; ++i) {
00134 if (pimpl->connect(i)) {
00135 return true;
00136 }
00137 }
00138 }
00139 pimpl->error_message_ = "Joystick devices are full connected.";
00140 return false;
00141 }
00142
00143
00144 void UsbJoystick::disconnect(void)
00145 {
00146 if (isConnected()) {
00147 SDL_JoystickClose(pimpl->joysticks_->js_[pimpl->own_id_].ptr_);
00148 }
00149 }
00150
00151
00152 bool UsbJoystick::isConnected(void) const
00153 {
00154 return (pimpl->joysticks_->js_[pimpl->own_id_].ptr_ == NULL) ? false : true;
00155 }
00156
00157
00158 size_t UsbJoystick::axisNum(void) const
00159 {
00160 return pimpl->axis_num_;
00161 }
00162
00163
00164 int UsbJoystick::axisValue(size_t index)
00165 {
00166 if (! isConnected()) {
00167 pimpl->error_message_ = "not connected.";
00168 return 0;
00169 }
00170 return pimpl->joysticks_->js_[pimpl->own_id_].axis_value_[index];
00171 }
00172
00173
00174 size_t UsbJoystick::buttonsNum(void) const
00175 {
00176 return pimpl->buttons_num_;
00177 }
00178
00179
00180 bool UsbJoystick::isButtonPressed(size_t index)
00181 {
00182 if (! isConnected()) {
00183 pimpl->error_message_ = "not connected.";
00184 return 0;
00185 }
00186 return pimpl->joysticks_->js_[pimpl->own_id_].button_value_[index];
00187 }
00188
00189
00190 size_t UsbJoystick::joystickNum(void)
00191 {
00192 return SDL_NumJoysticks();
00193 }
00194
00195
00196 void UsbJoystick::setEvent(void* event)
00197 {
00198 SDL_Event* sdl_event = static_cast<SDL_Event*>(event);
00199 switch (sdl_event->type) {
00200
00201 case SDL_JOYAXISMOTION:
00202 pimpl->joyAxisEventHandler(sdl_event->jaxis);
00203 break;
00204
00205 #if 0
00206 case SDL_JOYBALLMOTION:
00207 pimpl->joyBallEventHandler(event.jball);
00208 break;
00209
00210 case SDL_JOYHATMOTION:
00211 pimpl->joyHatEventHandler(event.jhat);
00212 break;
00213 #endif
00214
00215 case SDL_JOYBUTTONDOWN:
00216 case SDL_JOYBUTTONUP:
00217 pimpl->joyButtonEventHandler(sdl_event->jbutton);
00218 break;
00219 }
00220 }