00001 #include "sfml_input_impl.hpp"
00002 #include <utils_string.hpp>
00003
00004 #include <SFML/Window/Window.hpp>
00005 #include <SFML/Window/Event.hpp>
00006 #include <SFML/Window/Keyboard.hpp>
00007 #include <SFML/Window/Mouse.hpp>
00008
00009 #warning "Note : SFML input handler is not fully functional, since \
00010 SFML doesn't provide keyboard layout independent key codes."
00011
00012 using sf::Keyboard;
00013 using sf::Mouse;
00014
00015 namespace input
00016 {
00017 const int sfml_handler::lKeyToSFML[100][2] =
00018 {
00019 {key::K_ESCAPE,Keyboard::Escape},
00020 {key::K_0,Keyboard::Num0},
00021 {key::K_1,Keyboard::Num1},
00022 {key::K_2,Keyboard::Num2},
00023 {key::K_3,Keyboard::Num3},
00024 {key::K_4,Keyboard::Num4},
00025 {key::K_5,Keyboard::Num5},
00026 {key::K_6,Keyboard::Num6},
00027 {key::K_7,Keyboard::Num7},
00028 {key::K_8,Keyboard::Num8},
00029 {key::K_9,Keyboard::Num9},
00030 {key::K_MINUS,Keyboard::Dash},
00031 {key::K_EQUALS,Keyboard::Equal},
00032 {key::K_BACK,Keyboard::BackSpace},
00033 {key::K_TAB,Keyboard::Tab},
00034 {key::K_Q,Keyboard::Q},
00035 {key::K_W,Keyboard::W},
00036 {key::K_E,Keyboard::E},
00037 {key::K_R,Keyboard::R},
00038 {key::K_T,Keyboard::T},
00039 {key::K_Y,Keyboard::Y},
00040 {key::K_U,Keyboard::U},
00041 {key::K_I,Keyboard::I},
00042 {key::K_O,Keyboard::O},
00043 {key::K_P,Keyboard::P},
00044 {key::K_LBRACKET,Keyboard::LBracket},
00045 {key::K_RBRACKET,Keyboard::RBracket},
00046 {key::K_RETURN,Keyboard::Return},
00047 {key::K_LCONTROL,Keyboard::LControl},
00048 {key::K_A,Keyboard::A},
00049 {key::K_S,Keyboard::S},
00050 {key::K_D,Keyboard::D},
00051 {key::K_F,Keyboard::F},
00052 {key::K_G,Keyboard::G},
00053 {key::K_H,Keyboard::H},
00054 {key::K_J,Keyboard::J},
00055 {key::K_K,Keyboard::K},
00056 {key::K_L,Keyboard::L},
00057 {key::K_SEMICOLON,Keyboard::SemiColon},
00058 {key::K_APOSTROPHE,Keyboard::Quote},
00059
00060 {key::K_LSHIFT,Keyboard::LShift},
00061 {key::K_BACKSLASH,Keyboard::BackSlash},
00062 {key::K_Z,Keyboard::Z},
00063 {key::K_X,Keyboard::X},
00064 {key::K_C,Keyboard::C},
00065 {key::K_V,Keyboard::V},
00066 {key::K_B,Keyboard::B},
00067 {key::K_N,Keyboard::N},
00068 {key::K_M,Keyboard::M},
00069 {key::K_COMMA,Keyboard::Comma},
00070 {key::K_PERIOD,Keyboard::Period},
00071 {key::K_SLASH,Keyboard::Slash},
00072 {key::K_RSHIFT,Keyboard::RShift},
00073 {key::K_MULTIPLY,Keyboard::Multiply},
00074 {key::K_LMENU,Keyboard::LAlt},
00075 {key::K_SPACE,Keyboard::Space},
00076
00077 {key::K_F1,Keyboard::F1},
00078 {key::K_F2,Keyboard::F2},
00079 {key::K_F3,Keyboard::F3},
00080 {key::K_F4,Keyboard::F4},
00081 {key::K_F5,Keyboard::F5},
00082 {key::K_F6,Keyboard::F6},
00083 {key::K_F7,Keyboard::F7},
00084 {key::K_F8,Keyboard::F8},
00085 {key::K_F9,Keyboard::F9},
00086 {key::K_F10,Keyboard::F10},
00087 {key::K_NUMPAD7,Keyboard::Numpad7},
00088 {key::K_NUMPAD8,Keyboard::Numpad8},
00089 {key::K_NUMPAD9,Keyboard::Numpad9},
00090 {key::K_SUBTRACT,Keyboard::Subtract},
00091 {key::K_NUMPAD4,Keyboard::Numpad4},
00092 {key::K_NUMPAD5,Keyboard::Numpad5},
00093 {key::K_NUMPAD6,Keyboard::Numpad6},
00094 {key::K_ADD,Keyboard::Add},
00095 {key::K_NUMPAD1,Keyboard::Numpad1},
00096 {key::K_NUMPAD2,Keyboard::Numpad2},
00097 {key::K_NUMPAD3,Keyboard::Numpad3},
00098 {key::K_NUMPAD0,Keyboard::Numpad0},
00099
00100
00101 {key::K_F11,Keyboard::F11},
00102 {key::K_F12,Keyboard::F12},
00103 {key::K_F13,Keyboard::F13},
00104 {key::K_F14,Keyboard::F14},
00105 {key::K_F15,Keyboard::F15},
00106 {key::K_RCONTROL,Keyboard::RControl},
00107 {key::K_DIVIDE,Keyboard::Divide},
00108 {key::K_RMENU,Keyboard::RAlt},
00109 {key::K_PAUSE,Keyboard::Pause},
00110 {key::K_HOME,Keyboard::Home},
00111 {key::K_UP,Keyboard::Up},
00112 {key::K_PGUP,Keyboard::PageUp},
00113 {key::K_LEFT,Keyboard::Left},
00114 {key::K_RIGHT,Keyboard::Right},
00115 {key::K_END,Keyboard::End},
00116 {key::K_DOWN,Keyboard::Down},
00117 {key::K_PGDOWN,Keyboard::PageDown},
00118 {key::K_INSERT,Keyboard::Insert},
00119 {key::K_DELETE,Keyboard::Delete},
00120 {key::K_LWIN,Keyboard::LSystem},
00121 {key::K_RWIN,Keyboard::RSystem},
00122 {key::K_APPS,Keyboard::Menu}
00123 };
00124
00125 sfml_handler::sfml_handler(const sf::Window& mWindow, bool bMouseGrab) :
00126 mWindow_(mWindow), bMouseGrab_(bMouseGrab), bFirst_(true), fWheelCache_(0.0f)
00127 {
00128 if (bMouseGrab_)
00129 {
00130 fOldMouseX_ = mWindow_.getSize().x/2;
00131 fOldMouseY_ = mWindow_.getSize().y/2;
00132 }
00133
00134 mMouse.bHasDelta = true;
00135 }
00136
00137 int sfml_handler::to_sfml_(key::code mKey) const
00138 {
00139 for (size_t i = 0; i < 100; ++i)
00140 {
00141 if (lKeyToSFML[i][0] == mKey)
00142 return lKeyToSFML[i][1];
00143 }
00144
00145 return Keyboard::Unknown;
00146 }
00147
00148 void sfml_handler::toggle_mouse_grab()
00149 {
00150 bMouseGrab_ = !bMouseGrab_;
00151 if (bMouseGrab_)
00152 {
00153 fOldMouseX_ = mWindow_.getSize().x/2;
00154 fOldMouseY_ = mWindow_.getSize().y/2;
00155 }
00156 }
00157
00158 #ifdef WIN32
00159 #include <windows.h>
00160
00161 #ifndef VK_OEM_COMMA
00162 #define VK_OEM_PLUS 0xBB
00163 #define VK_OEM_COMMA 0xBC
00164 #define VK_OEM_MINUS 0xBD
00165 #define VK_OEM_PERIOD 0xBE
00166 #endif
00167
00168 int to_vkey_(Keyboard::Key key)
00169 {
00170 switch (key)
00171 {
00172 default: return 0;
00173 case Keyboard::A: return 'A';
00174 case Keyboard::B: return 'B';
00175 case Keyboard::C: return 'C';
00176 case Keyboard::D: return 'D';
00177 case Keyboard::E: return 'E';
00178 case Keyboard::F: return 'F';
00179 case Keyboard::G: return 'G';
00180 case Keyboard::H: return 'H';
00181 case Keyboard::I: return 'I';
00182 case Keyboard::J: return 'J';
00183 case Keyboard::K: return 'K';
00184 case Keyboard::L: return 'L';
00185 case Keyboard::M: return 'M';
00186 case Keyboard::N: return 'N';
00187 case Keyboard::O: return 'O';
00188 case Keyboard::P: return 'P';
00189 case Keyboard::Q: return 'Q';
00190 case Keyboard::R: return 'R';
00191 case Keyboard::S: return 'S';
00192 case Keyboard::T: return 'T';
00193 case Keyboard::U: return 'U';
00194 case Keyboard::V: return 'V';
00195 case Keyboard::W: return 'W';
00196 case Keyboard::X: return 'X';
00197 case Keyboard::Y: return 'Y';
00198 case Keyboard::Z: return 'Z';
00199 case Keyboard::Num0: return '0';
00200 case Keyboard::Num1: return '1';
00201 case Keyboard::Num2: return '2';
00202 case Keyboard::Num3: return '3';
00203 case Keyboard::Num4: return '4';
00204 case Keyboard::Num5: return '5';
00205 case Keyboard::Num6: return '6';
00206 case Keyboard::Num7: return '7';
00207 case Keyboard::Num8: return '8';
00208 case Keyboard::Num9: return '9';
00209 case Keyboard::Escape: return VK_ESCAPE;
00210 case Keyboard::LControl: return VK_LCONTROL;
00211 case Keyboard::LShift: return VK_LSHIFT;
00212 case Keyboard::LAlt: return VK_LMENU;
00213 case Keyboard::LSystem: return VK_LWIN;
00214 case Keyboard::RControl: return VK_RCONTROL;
00215 case Keyboard::RShift: return VK_RSHIFT;
00216 case Keyboard::RAlt: return VK_RMENU;
00217 case Keyboard::RSystem: return VK_RWIN;
00218 case Keyboard::Menu: return VK_APPS;
00219 case Keyboard::LBracket: return VK_OEM_4;
00220 case Keyboard::RBracket: return VK_OEM_6;
00221 case Keyboard::SemiColon: return VK_OEM_1;
00222 case Keyboard::Comma: return VK_OEM_COMMA;
00223 case Keyboard::Period: return VK_OEM_PERIOD;
00224 case Keyboard::Quote: return VK_OEM_7;
00225 case Keyboard::Slash: return VK_OEM_2;
00226 case Keyboard::BackSlash: return VK_OEM_5;
00227 case Keyboard::Tilde: return VK_OEM_3;
00228 case Keyboard::Equal: return VK_OEM_PLUS;
00229 case Keyboard::Dash: return VK_OEM_MINUS;
00230 case Keyboard::Space: return VK_SPACE;
00231 case Keyboard::Return: return VK_RETURN;
00232 case Keyboard::BackSpace: return VK_BACK;
00233 case Keyboard::Tab: return VK_TAB;
00234 case Keyboard::PageUp: return VK_PRIOR;
00235 case Keyboard::PageDown: return VK_NEXT;
00236 case Keyboard::End: return VK_END;
00237 case Keyboard::Home: return VK_HOME;
00238 case Keyboard::Insert: return VK_INSERT;
00239 case Keyboard::Delete: return VK_DELETE;
00240 case Keyboard::Add: return VK_ADD;
00241 case Keyboard::Subtract: return VK_SUBTRACT;
00242 case Keyboard::Multiply: return VK_MULTIPLY;
00243 case Keyboard::Divide: return VK_DIVIDE;
00244 case Keyboard::Left: return VK_LEFT;
00245 case Keyboard::Right: return VK_RIGHT;
00246 case Keyboard::Up: return VK_UP;
00247 case Keyboard::Down: return VK_DOWN;
00248 case Keyboard::Numpad0: return VK_NUMPAD0;
00249 case Keyboard::Numpad1: return VK_NUMPAD1;
00250 case Keyboard::Numpad2: return VK_NUMPAD2;
00251 case Keyboard::Numpad3: return VK_NUMPAD3;
00252 case Keyboard::Numpad4: return VK_NUMPAD4;
00253 case Keyboard::Numpad5: return VK_NUMPAD5;
00254 case Keyboard::Numpad6: return VK_NUMPAD6;
00255 case Keyboard::Numpad7: return VK_NUMPAD7;
00256 case Keyboard::Numpad8: return VK_NUMPAD8;
00257 case Keyboard::Numpad9: return VK_NUMPAD9;
00258 case Keyboard::F1: return VK_F1;
00259 case Keyboard::F2: return VK_F2;
00260 case Keyboard::F3: return VK_F3;
00261 case Keyboard::F4: return VK_F4;
00262 case Keyboard::F5: return VK_F5;
00263 case Keyboard::F6: return VK_F6;
00264 case Keyboard::F7: return VK_F7;
00265 case Keyboard::F8: return VK_F8;
00266 case Keyboard::F9: return VK_F9;
00267 case Keyboard::F10: return VK_F10;
00268 case Keyboard::F11: return VK_F11;
00269 case Keyboard::F12: return VK_F12;
00270 case Keyboard::F13: return VK_F13;
00271 case Keyboard::F14: return VK_F14;
00272 case Keyboard::F15: return VK_F16;
00273 case Keyboard::Pause: return VK_PAUSE;
00274 }
00275 }
00276
00277 #else
00278 #include <X11/Xlib.h>
00279 #include <X11/keysym.h>
00280
00281 KeySym to_xkey_(Keyboard::Key key)
00282 {
00283 switch (key)
00284 {
00285 case Keyboard::A: return XK_A;
00286 case Keyboard::B: return XK_B;
00287 case Keyboard::C: return XK_C;
00288 case Keyboard::D: return XK_D;
00289 case Keyboard::E: return XK_E;
00290 case Keyboard::F: return XK_F;
00291 case Keyboard::G: return XK_G;
00292 case Keyboard::H: return XK_H;
00293 case Keyboard::I: return XK_I;
00294 case Keyboard::J: return XK_J;
00295 case Keyboard::K: return XK_K;
00296 case Keyboard::L: return XK_L;
00297 case Keyboard::M: return XK_M;
00298 case Keyboard::N: return XK_N;
00299 case Keyboard::O: return XK_O;
00300 case Keyboard::P: return XK_P;
00301 case Keyboard::Q: return XK_Q;
00302 case Keyboard::R: return XK_R;
00303 case Keyboard::S: return XK_S;
00304 case Keyboard::T: return XK_T;
00305 case Keyboard::U: return XK_U;
00306 case Keyboard::V: return XK_V;
00307 case Keyboard::W: return XK_W;
00308 case Keyboard::X: return XK_X;
00309 case Keyboard::Y: return XK_Y;
00310 case Keyboard::Z: return XK_Z;
00311 case Keyboard::Num0: return XK_0;
00312 case Keyboard::Num1: return XK_1;
00313 case Keyboard::Num2: return XK_2;
00314 case Keyboard::Num3: return XK_3;
00315 case Keyboard::Num4: return XK_4;
00316 case Keyboard::Num5: return XK_5;
00317 case Keyboard::Num6: return XK_6;
00318 case Keyboard::Num7: return XK_7;
00319 case Keyboard::Num8: return XK_8;
00320 case Keyboard::Num9: return XK_9;
00321 case Keyboard::Escape: return XK_Escape;
00322 case Keyboard::LControl: return XK_Control_L;
00323 case Keyboard::LShift: return XK_Shift_L;
00324 case Keyboard::LAlt: return XK_Alt_L;
00325 case Keyboard::LSystem: return XK_Super_L;
00326 case Keyboard::RControl: return XK_Control_R;
00327 case Keyboard::RShift: return XK_Shift_R;
00328 case Keyboard::RAlt: return XK_Alt_R;
00329 case Keyboard::RSystem: return XK_Super_R;
00330 case Keyboard::Menu: return XK_Menu;
00331 case Keyboard::LBracket: return XK_bracketleft;
00332 case Keyboard::RBracket: return XK_bracketright;
00333 case Keyboard::SemiColon: return XK_semicolon;
00334 case Keyboard::Comma: return XK_comma;
00335 case Keyboard::Period: return XK_period;
00336 case Keyboard::Quote: return XK_dead_acute;
00337 case Keyboard::Slash: return XK_slash;
00338 case Keyboard::BackSlash: return XK_backslash;
00339 case Keyboard::Tilde: return XK_dead_grave;
00340 case Keyboard::Equal: return XK_equal;
00341 case Keyboard::Dash: return XK_minus;
00342 case Keyboard::Space: return XK_space;
00343 case Keyboard::Return: return XK_Return;
00344 case Keyboard::BackSpace: return XK_BackSpace;
00345 case Keyboard::Tab: return XK_Tab;
00346 case Keyboard::PageUp: return XK_Prior;
00347 case Keyboard::PageDown: return XK_Next;
00348 case Keyboard::End: return XK_End;
00349 case Keyboard::Home: return XK_Home;
00350 case Keyboard::Insert: return XK_Insert;
00351 case Keyboard::Delete: return XK_Delete;
00352 case Keyboard::Add: return XK_KP_Add;
00353 case Keyboard::Subtract: return XK_KP_Subtract;
00354 case Keyboard::Multiply: return XK_KP_Multiply;
00355 case Keyboard::Divide: return XK_KP_Divide;
00356 case Keyboard::Left: return XK_Left;
00357 case Keyboard::Right: return XK_Right;
00358 case Keyboard::Up: return XK_Up;
00359 case Keyboard::Down: return XK_Down;
00360 case Keyboard::Numpad0: return XK_KP_0;
00361 case Keyboard::Numpad1: return XK_KP_1;
00362 case Keyboard::Numpad2: return XK_KP_2;
00363 case Keyboard::Numpad3: return XK_KP_3;
00364 case Keyboard::Numpad4: return XK_KP_4;
00365 case Keyboard::Numpad5: return XK_KP_5;
00366 case Keyboard::Numpad6: return XK_KP_6;
00367 case Keyboard::Numpad7: return XK_KP_7;
00368 case Keyboard::Numpad8: return XK_KP_8;
00369 case Keyboard::Numpad9: return XK_KP_9;
00370 case Keyboard::F1: return XK_F1;
00371 case Keyboard::F2: return XK_F2;
00372 case Keyboard::F3: return XK_F3;
00373 case Keyboard::F4: return XK_F4;
00374 case Keyboard::F5: return XK_F5;
00375 case Keyboard::F6: return XK_F6;
00376 case Keyboard::F7: return XK_F7;
00377 case Keyboard::F8: return XK_F8;
00378 case Keyboard::F9: return XK_F9;
00379 case Keyboard::F10: return XK_F10;
00380 case Keyboard::F11: return XK_F11;
00381 case Keyboard::F12: return XK_F12;
00382 case Keyboard::F13: return XK_F13;
00383 case Keyboard::F14: return XK_F14;
00384 case Keyboard::F15: return XK_F15;
00385 case Keyboard::Pause: return XK_Pause;
00386 default: return 0;
00387 }
00388 }
00389
00390 #endif
00391
00392 std::string sfml_handler::get_key_name(key::code mKey) const
00393 {
00394 #ifdef WIN32
00395 int vkey = to_vkey_((sf::Keyboard::Key)to_sfml_(mKey));
00396 unsigned int code = MapVirtualKey(vkey, 0 );
00397
00398 char name[50];
00399 if (GetKeyNameText(code << 16, name, sizeof(name)) != 0)
00400 return name;
00401 else
00402 return "Unknown";
00403
00404 #else
00405
00406 KeySym keysym = to_xkey_((sf::Keyboard::Key)to_sfml_(mKey));
00407 if (keysym == 0)
00408 return "Unknown";
00409
00410
00411 char* name = XKeysymToString(keysym);
00412 if (name != 0)
00413 {
00414 std::string s(name);
00415
00416 if (s.substr(0, 3) == "KP_")
00417 {
00418 s.erase(0, 3);
00419 s.append(" (Num.)");
00420 }
00421
00422 s[0] = toupper(s[0]);
00423 bool bPrevUnderscore = false;
00424 for (auto& c : s)
00425 {
00426 if (c == '_')
00427 {
00428 c = ' ';
00429 bPrevUnderscore = true;
00430 }
00431 else if (bPrevUnderscore)
00432 {
00433 c = toupper(c);
00434 bPrevUnderscore = false;
00435 }
00436 }
00437
00438 return s;
00439 }
00440 else
00441 return "Unknown";
00442 #endif
00443
00444
00445
00446 }
00447
00448 void sfml_handler::update()
00449 {
00450 for (int i = 0; i < 100; ++i)
00451 mKeyboard.lKeyState[lKeyToSFML[i][0]] = Keyboard::isKeyPressed((Keyboard::Key)lKeyToSFML[i][1]);
00452
00453 const float width = mWindow_.getSize().x;
00454 const float height = mWindow_.getSize().y;
00455
00456 if (bFirst_)
00457 {
00458 mMouse.fAbsX = Mouse::getPosition(mWindow_).x;
00459 mMouse.fAbsY = Mouse::getPosition(mWindow_).y;
00460 mMouse.fRelX = mMouse.fAbsX/width;
00461 mMouse.fRelY = mMouse.fAbsY/height;
00462
00463 mMouse.fDX = mMouse.fDY = mMouse.fRelDX = mMouse.fRelDY = 0.0f;
00464 bFirst_ = false;
00465
00466 if (!bMouseGrab_)
00467 {
00468 fOldMouseX_ = mMouse.fAbsX;
00469 fOldMouseY_ = mMouse.fAbsY;
00470 }
00471 }
00472 else
00473 {
00474 mMouse.fDX = Mouse::getPosition(mWindow_).x - fOldMouseX_;
00475 mMouse.fDY = Mouse::getPosition(mWindow_).y - fOldMouseY_;
00476 mMouse.fRelDX = mMouse.fDX/width;
00477 mMouse.fRelDY = mMouse.fDY/height;
00478
00479 mMouse.fAbsX += mMouse.fDX;
00480 mMouse.fAbsY += mMouse.fDY;
00481 mMouse.fRelX = mMouse.fAbsX/width;
00482 mMouse.fRelY = mMouse.fAbsY/height;
00483
00484 if (bMouseGrab_)
00485 Mouse::setPosition(sf::Vector2i(fOldMouseX_, fOldMouseY_), mWindow_);
00486 else
00487 {
00488 fOldMouseX_ = mMouse.fAbsX;
00489 fOldMouseY_ = mMouse.fAbsY;
00490 }
00491 }
00492
00493 mMouse.fRelWheel = 0.0f;
00494 std::swap(mMouse.fRelWheel, fWheelCache_);
00495
00496 static const Mouse::Button lMouseToSFML[3] = {Mouse::Left, Mouse::Right, Mouse::Middle};
00497
00498 for (int i = 0; i < INPUT_MOUSE_BUTTON_NUMBER; ++i)
00499 mMouse.lButtonState[i] = Mouse::isButtonPressed(lMouseToSFML[i]);
00500 }
00501
00502 void sfml_handler::on_sfml_event(const sf::Event& mEvent)
00503 {
00504 if (mEvent.type == sf::Event::TextEntered)
00505 {
00506 auto c = mEvent.text.unicode;
00507
00508 if (c >= 32 && c != 127)
00509 lCharsCache_.push_back(c);
00510 }
00511 else if (mEvent.type == sf::Event::MouseWheelMoved)
00512 {
00513 fWheelCache_ += mEvent.mouseWheel.delta;
00514 }
00515 }
00516 }