00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "joystick.hpp"
00017 #include "preferences.hpp"
00018 #include "log.hpp"
00019
00020 #define PI 3.14159265
00021
00022 static lg::log_domain log_joystick("joystick");
00023 #define ERR_JOY LOG_STREAM(err, log_joystick)
00024 #define LOG_JOY LOG_STREAM(info, log_joystick)
00025 #define DBG_JOY LOG_STREAM(debug, log_joystick)
00026
00027 joystick_manager::joystick_manager()
00028 : joysticks_()
00029 , joystick_area_(0)
00030 , counter_(0)
00031 {
00032 init();
00033 }
00034
00035 joystick_manager::~joystick_manager() {
00036 close();
00037 }
00038
00039 bool joystick_manager::close() {
00040 if(SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
00041 return true;
00042
00043 int joysticks = joysticks_.size();
00044 bool all_closed = true;
00045
00046 for (int i = 0; i<joysticks; i++) {
00047 if (SDL_JoystickOpened(i)) {
00048 SDL_JoystickClose(joysticks_[i]);
00049 LOG_JOY << "Closed Joystick" << i;
00050 LOG_JOY << "Name: " << SDL_JoystickName(i);
00051 } else {
00052 ERR_JOY << "Joystick" << i << " closing failed.";
00053 all_closed = false;
00054 }
00055 }
00056
00057 joysticks_.clear();
00058 return all_closed;
00059 }
00060
00061 bool joystick_manager::init() {
00062
00063 close();
00064
00065 if (!preferences::joystick_support_enabled()) {
00066 LOG_JOY << "Joystick support is disabled.";
00067 return false;
00068 }
00069
00070 LOG_JOY << "Initializing joysticks...\n";
00071 if(SDL_WasInit(SDL_INIT_JOYSTICK) == 0)
00072 if(SDL_InitSubSystem(SDL_INIT_JOYSTICK) == -1)
00073 return false;
00074
00075 joysticks_.clear();
00076
00077 int joysticks = SDL_NumJoysticks();
00078 if (joysticks == 0) return false;
00079
00080 SDL_JoystickEventState(SDL_ENABLE);
00081
00082 bool joystick_found = false;
00083 for (int i = 0; i<joysticks; i++) {
00084 joysticks_.resize(i+1);
00085 joysticks_[i] = SDL_JoystickOpen(i);
00086
00087 if (joysticks_[i] && SDL_JoystickOpened(i)) {
00088
00089 joystick_found = true;
00090
00091 LOG_JOY << "Opened Joystick" << i;
00092 LOG_JOY << "Name: " << SDL_JoystickName(i);
00093 LOG_JOY << "Number of Axes: " << SDL_JoystickNumAxes(joysticks_[i]);
00094 LOG_JOY << "Number of Buttons: " << SDL_JoystickNumButtons(joysticks_[i]);
00095 LOG_JOY << "Number of Balls: " << SDL_JoystickNumBalls(joysticks_[i]);
00096 LOG_JOY << "Number of Hats: ", SDL_JoystickNumHats(joysticks_[i]);
00097 } else {
00098 ERR_JOY << "Couldn't open Joystick" << i;
00099 }
00100 }
00101 return joystick_found;
00102 }
00103
00104 std::pair<double, double> joystick_manager::get_mouse_axis_pair() {
00105
00106 const int mouse_joystick_x = preferences::joystick_num_mouse_xaxis();
00107 const int mouse_xaxis = preferences::joystick_mouse_xaxis_num();
00108
00109 const int mouse_joystick_y = preferences::joystick_num_mouse_yaxis();
00110 const int mouse_yaxis = preferences::joystick_mouse_yaxis_num();
00111
00112 std::pair<int, int> values;
00113 double thrust;
00114 {
00115 values = get_axis_pair(mouse_joystick_x, mouse_xaxis, mouse_joystick_y, mouse_yaxis);
00116 thrust = get_thrusta_axis();
00117 }
00118
00119 const int radius = round_double(sqrt(pow(values.first, 2.0f) + pow(values.second, 2.0f)));
00120 const int deadzone = preferences::joystick_mouse_deadzone();
00121 const double multiplier = 1.0 + thrust;
00122
00123 if (deadzone > radius)
00124 return std::make_pair(0.0, 0.0);
00125
00126
00127
00128
00129
00130
00131
00132 return std::make_pair(
00133 ((static_cast<double>(values.first)) / 32768.0) * multiplier
00134 , ((static_cast<double>(values.second)) / 32768.0) * multiplier );
00135
00136 }
00137
00138 std::pair<double, double> joystick_manager::get_scroll_axis_pair() {
00139
00140 if (!preferences::joystick_support_enabled()) return std::make_pair(0.0, 0.0);
00141
00142 const int scroll_joystick_x = preferences::joystick_num_scroll_xaxis();
00143 const int scroll_axis = preferences::joystick_scroll_xaxis_num();
00144
00145 const int scroll_joystick_y = preferences::joystick_num_scroll_yaxis();
00146 const int scroll_yaxis = preferences::joystick_scroll_yaxis_num();
00147
00148 std::pair<int, int> values;
00149 double thrust;
00150 {
00151 values = get_axis_pair(scroll_joystick_x, scroll_axis, scroll_joystick_y, scroll_yaxis);
00152 thrust = get_thrusta_axis();
00153 }
00154
00155 const int radius = round_double(sqrt(pow(values.first, 2.0f) + pow(values.second, 2.0f)));
00156 const int deadzone = preferences::joystick_scroll_deadzone();
00157 const double multiplier = 1.0 + thrust;
00158
00159 if (deadzone > radius)
00160 return std::make_pair(0.0, 0.0);
00161
00162 return std::make_pair(
00163 ((static_cast<double>(values.first)) / 32768.0) * multiplier
00164 , ((static_cast<double>(values.second)) / 32768.0) * multiplier );
00165 }
00166
00167 double joystick_manager::get_thrusta_axis() {
00168 if (!preferences::joystick_support_enabled()) return 0.0;
00169
00170 const int thrust_joystick_x = preferences::joystick_num_thrusta_axis();
00171 const int thrust_axis_x = preferences::joystick_thrusta_axis_num();
00172 const int thrust_deadzone = preferences::joystick_thrusta_deadzone();
00173
00174 const int value = get_axis(thrust_joystick_x, thrust_axis_x) + 32768;
00175 if (value < thrust_deadzone) return 0.0;
00176 return static_cast<double>(value) / 65536.0;
00177 }
00178
00179 double joystick_manager::get_thrustb_axis() {
00180 if (!preferences::joystick_support_enabled()) return 0.0;
00181
00182 const int thrustb_joystick = preferences::joystick_num_thrustb_axis();
00183 const int thrustb_axis = preferences::joystick_thrustb_axis_num();
00184 const int thrustb_deadzone = preferences::joystick_thrustb_deadzone();
00185
00186 const int value = get_axis(thrustb_joystick, thrustb_axis) + 32768;
00187 if (value < thrustb_deadzone) return 0.0;
00188 return static_cast<double>(value) / 65536.0;
00189 }
00190
00191 std::pair<double, double> joystick_manager::get_cursor_polar_coordinates() {
00192 const int cursor_joystick_xaxis = preferences::joystick_num_cursor_xaxis();
00193 const int cursor_xaxis = preferences::joystick_cursor_xaxis_num();
00194
00195 const int cursor_joystick_yaxis = preferences::joystick_num_cursor_yaxis();
00196 const int cursor_yaxis = preferences::joystick_cursor_yaxis_num();
00197
00198 return get_polar_coordinates(cursor_joystick_xaxis, cursor_xaxis, cursor_joystick_yaxis, cursor_yaxis);
00199 }
00200
00201 std::pair<double, double> joystick_manager::get_polar_coordinates(int joystick_xaxis, int xaxis, int joystick_yaxis, int yaxis) {
00202
00203 const std::pair<int, int> values = get_axis_pair(joystick_xaxis, xaxis, joystick_yaxis, yaxis);
00204 const double radius = (sqrt(pow(values.first, 2.0f) + pow(values.second, 2.0f))) / 32768.0;
00205 const double angle = (atan2(
00206 static_cast<double>(values.second)
00207 , static_cast<double>(values.first))) * 180.0 / PI;
00208
00209 return std::make_pair(radius, angle);
00210 }
00211
00212 std::pair<int, int> joystick_manager::get_axis_pair(int joystick_xaxis, int xaxis, int joystick_yaxis, int yaxis) {
00213
00214 if(!SDL_WasInit(SDL_INIT_JOYSTICK))
00215 return std::make_pair(0, 0);
00216
00217 int x_axis = 0, y_axis = 0;
00218 bool get_xaxis = false, get_yaxis = false;
00219
00220 if(SDL_JoystickOpened(joystick_xaxis))
00221 if(SDL_JoystickNumAxes(joysticks_[joystick_xaxis]) > xaxis)
00222 get_xaxis = true;
00223
00224 if(SDL_JoystickOpened(joystick_yaxis))
00225 if(SDL_JoystickNumAxes(joysticks_[joystick_yaxis]) > yaxis)
00226 get_yaxis = true;
00227
00228
00229
00230 {
00231 if (get_xaxis) x_axis = SDL_JoystickGetAxis(joysticks_[joystick_xaxis], xaxis);
00232 if (get_yaxis) y_axis = SDL_JoystickGetAxis(joysticks_[joystick_yaxis], yaxis);
00233 }
00234 return std::make_pair(x_axis, y_axis);
00235 }
00236
00237 int joystick_manager::get_axis(int joystick_axis, int axis) {
00238 if(!SDL_WasInit(SDL_INIT_JOYSTICK))
00239 return 0;
00240
00241 if(SDL_JoystickOpened(joystick_axis))
00242 if(SDL_JoystickNumAxes(joysticks_[joystick_axis]) > axis)
00243 return SDL_JoystickGetAxis(joysticks_[joystick_axis], axis);
00244 return 0;
00245 }
00246
00247
00248 bool joystick_manager::update_highlighted_hex(map_location& highlighted_hex, const map_location& selected_hex) {
00249
00250 const int cursor_joystick_xaxis = preferences::joystick_num_cursor_xaxis();
00251 const int cursor_xaxis = preferences::joystick_cursor_xaxis_num();
00252
00253 const int cursor_joystick_yaxis = preferences::joystick_num_cursor_yaxis();
00254 const int cursor_yaxis = preferences::joystick_cursor_yaxis_num();
00255
00256 const std::pair<int, int> values = get_axis_pair(cursor_joystick_xaxis, cursor_xaxis, cursor_joystick_yaxis, cursor_yaxis);
00257
00258 const int x_axis = values.first;
00259 const int y_axis = values.second;
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270 int x = selected_hex.x + round_double(x_axis / 3200);
00271 int y = selected_hex.y + round_double(y_axis / 3200);
00272 highlighted_hex = map_location(x,y);
00273
00274
00275
00276
00277
00278
00279
00280 return true;
00281 }
00282
00283
00284 bool joystick_manager::update_highlighted_hex(map_location& highlighted_hex) {
00285
00286 const int cursor_joystick_xaxis = preferences::joystick_num_cursor_xaxis();
00287 const int cursor_xaxis = preferences::joystick_cursor_xaxis_num();
00288
00289 const int cursor_joystick_yaxis = preferences::joystick_num_cursor_yaxis();
00290 const int cursor_yaxis = preferences::joystick_cursor_yaxis_num();
00291
00292 const std::pair<int, int> values = get_axis_pair(cursor_joystick_xaxis, cursor_xaxis, cursor_joystick_yaxis, cursor_yaxis);
00293
00294 const int x_axis = values.first;
00295 const int y_axis = values.second;
00296
00297 const int radius = round_double(sqrt(pow(x_axis, 2.0f) + pow(y_axis, 2.0f)));
00298
00299 const int deadzone = preferences::joystick_cursor_deadzone();
00300 const int threshold = deadzone + preferences::joystick_cursor_threshold();
00301
00302 const int max = 100000;
00303
00304 const bool greater_deadzone = radius > deadzone;
00305 const bool greater_threshold2 = radius > threshold;
00306
00307 if (!greater_deadzone) {
00308 counter_ = 0;
00309 joystick_area_ = 0;
00310 return false;
00311 } else {
00312 if (joystick_area_ == 0) {
00313 highlighted_hex = get_next_hex(x_axis, y_axis, highlighted_hex);
00314 }
00315 if (!greater_threshold2) {
00316 joystick_area_ = 1;
00317 } else {
00318 joystick_area_ = 2;
00319 counter_ += radius;
00320 if (counter_ > max) {
00321 counter_ -= max;
00322 highlighted_hex = get_next_hex(x_axis, y_axis, highlighted_hex);
00323 return true;
00324 } else return false;
00325 }
00326 }
00327
00328 return true;
00329 }
00330
00331 const map_location joystick_manager::get_direction(const map_location& loc, joystick_manager::DIRECTION direction) {
00332
00333 int x = loc.x;
00334 int y = loc.y;
00335
00336 switch(direction) {
00337 case NORTH: return map_location(x, y - 1);
00338 case SOUTH: return map_location(x, y + 1);
00339 case SOUTH_EAST: return map_location(x + 1, y + (1+is_odd(x))/2 );
00340 case SOUTH_WEST: return map_location(x - 1, y + (1+is_odd(x))/2 );
00341 case NORTH_EAST: return map_location(x + 1, y - (1+is_even(x))/2 );
00342 case NORTH_WEST: return map_location(x - 1, y - (1+is_even(x))/2 );
00343 case WEST: return map_location(x - 1, y);
00344 case EAST: return map_location(x + 1, y);
00345 default:
00346 assert(false);
00347 return map_location();
00348 }
00349 }
00350
00351 double joystick_manager::get_angle() {
00352
00353 const int cursor_joystick_xaxis = preferences::joystick_num_cursor_xaxis();
00354 const int cursor_xaxis = preferences::joystick_cursor_xaxis_num();
00355
00356 const int cursor_joystick_yaxis = preferences::joystick_num_cursor_yaxis();
00357 const int cursor_yaxis = preferences::joystick_cursor_yaxis_num();
00358
00359 const std::pair<int, int> values = get_axis_pair(cursor_joystick_xaxis, cursor_xaxis, cursor_joystick_yaxis, cursor_yaxis);
00360
00361 const int x_axis = values.first;
00362 const int y_axis = values.second;
00363
00364 const double angle = (atan2(
00365 static_cast<double>(y_axis)
00366 , static_cast<double>(x_axis))) * 180.0 / PI;
00367
00368 return angle;
00369 }
00370
00371
00372 const map_location joystick_manager::get_next_hex(int x_axis, int y_axis, map_location loc) {
00373
00374 map_location new_loc = map_location::null_location;
00375
00376 if (x_axis == 0) return (y_axis > 0) ? get_direction(loc, SOUTH) : get_direction(loc, NORTH);
00377 if (y_axis == 0) return (x_axis > 0) ? get_direction(loc, EAST) : get_direction(loc, WEST);
00378 const double angle = (atan2(
00379 static_cast<double>(y_axis)
00380 , static_cast<double>(x_axis))) * 180.0 / PI;
00381
00382 if (angle < -112.5 && angle > -157.5)
00383 new_loc = get_direction(loc, NORTH_WEST);
00384
00385 if (angle < -67.5 && angle > -112.5)
00386 new_loc = get_direction(loc, NORTH);
00387
00388 if (angle < -22.5 && angle > -67.5)
00389 new_loc = get_direction(loc, NORTH_EAST);
00390
00391 if (angle < 22.5 && angle > -22.5 )
00392 new_loc = get_direction(loc, EAST);
00393
00394 if (angle > 22.5 && angle < 67.5 )
00395 new_loc = get_direction(loc, SOUTH_EAST);
00396
00397 if (angle > 67.5 && angle < 113.5)
00398 new_loc = get_direction(loc, SOUTH);
00399
00400 if (angle > 113.5 && angle < 158.5)
00401 new_loc = get_direction(loc, SOUTH_WEST);
00402
00403 if (angle > 158.5 || angle < -157.5)
00404 new_loc = get_direction(loc, WEST);
00405
00406 return new_loc;
00407 }
00408