diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 308065e7e..358eb7b92 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -221,9 +221,10 @@ namespace MWInput bool main_menu = mWindows.containsMode(MWGui::GM_MainMenu); bool was_relative = mInputManager->getMouseRelative(); - bool is_relative = !main_menu; + bool is_relative = !mWindows.isGuiMode(); - //don't keep the pointer away from the window edge in the main menu + // don't keep the pointer away from the window edge in gui mode + // stop using raw mouse motions and switch to system cursor movements mInputManager->setMouseRelative(is_relative); //we switched to non-relative mode, move our cursor to where the in-game @@ -472,17 +473,11 @@ namespace MWInput // We keep track of our own mouse position, so that moving the mouse while in // game mode does not move the position of the GUI cursor - //FIXME: Except in the main menu, since we let the pointer escape - if(!mWindows.containsMode(MWGui::GM_MainMenu)) - { - mMouseX += float(arg.xrel) * mUISensitivity; - mMouseY += float(arg.yrel) * mUISensitivity * mUIYMultiplier; - } - else - { - mMouseX = arg.x; - mMouseY = arg.y; - } + // Don't support the UI sensitivity slider to reduce headache + // related to when the mouse can leave the window, and what to + // do when it re-enters + mMouseX = arg.x; + mMouseY = arg.y; mMouseX = std::max(0.f, std::min(mMouseX, float(viewSize.width))); mMouseY = std::max(0.f, std::min(mMouseY, float(viewSize.height))); diff --git a/extern/sdl4ogre/sdlinputwrapper.cpp b/extern/sdl4ogre/sdlinputwrapper.cpp index 93f00d4b5..a198542c7 100644 --- a/extern/sdl4ogre/sdlinputwrapper.cpp +++ b/extern/sdl4ogre/sdlinputwrapper.cpp @@ -3,7 +3,6 @@ #include #include -#include #if OGRE_PLATFORM == OGRE_PLATFORM_LINUX # include @@ -239,6 +238,36 @@ namespace SFO } } + MouseMotionEvent InputWrapper::_packageMouseMotion(const SDL_Event &evt) + { + MouseMotionEvent pack_evt; + pack_evt.x = mMouseX; + pack_evt.xrel = 0; + pack_evt.y = mMouseY; + pack_evt.yrel = 0; + pack_evt.z = mMouseZ; + pack_evt.zrel = 0; + + if(evt.type == SDL_MOUSEMOTION) + { + pack_evt.x = mMouseX = evt.motion.x; + pack_evt.y = mMouseY = evt.motion.y; + pack_evt.xrel = evt.motion.xrel; + pack_evt.yrel = evt.motion.yrel; + } + else if(evt.type == SDL_MOUSEWHEEL) + { + mMouseZ += pack_evt.zrel = (evt.wheel.y * 120); + pack_evt.z = mMouseZ; + } + else + { + throw new std::runtime_error("Tried to package non-motion event!"); + } + + return pack_evt; + } + void InputWrapper::_handleKeyPress(SDL_KeyboardEvent &evt) { //SDL keyboard events are followed by the actual text those keys would generate @@ -253,50 +282,58 @@ namespace SFO SDL_Event text_evts[1]; if(SDL_PeepEvents(text_evts, 1, SDL_GETEVENT, SDL_TEXTINPUT, SDL_TEXTINPUT) != 0) { - const char* symbol = text_evts[0].text.text; - - Uint32 num_bytes = strlen(symbol); - - //no valid character is more than 4 bytes - if(num_bytes > 0 && num_bytes <= 4) + if(strlen(text_evts[0].text.text) != 0) { - Uint32 u32_symbol = boost::locale::conv::utf_to_utf(symbol)[0]; - - evt.keysym.unicode = u32_symbol; + const unsigned char* symbol = reinterpret_cast(&(text_evts[0].text.text[0])); + evt.keysym.unicode = _UTF8ToUTF32(symbol); } } mKeyboardListener->keyPressed(evt); } - MouseMotionEvent InputWrapper::_packageMouseMotion(const SDL_Event &evt) + //Lifted from OIS' LinuxKeyboard.cpp + Uint32 InputWrapper::_UTF8ToUTF32(const unsigned char *buf) { - MouseMotionEvent pack_evt; - pack_evt.x = mMouseX; - pack_evt.xrel = 0; - pack_evt.y = mMouseY; - pack_evt.yrel = 0; - pack_evt.z = mMouseZ; - pack_evt.zrel = 0; + unsigned char FirstChar = buf[0]; - if(evt.type == SDL_MOUSEMOTION) + //it's an ascii char, bail out early. + if(FirstChar < 128) + return FirstChar; + + Uint32 val = 0; + Sint32 len = 0; + + if((FirstChar & 0xE0) == 0xC0) //2 Chars { - pack_evt.x = mMouseX = evt.motion.x; - pack_evt.y = mMouseY = evt.motion.y; - pack_evt.xrel = evt.motion.xrel; - pack_evt.yrel = evt.motion.yrel; + len = 2; + val = FirstChar & 0x1F; } - else if(evt.type == SDL_MOUSEWHEEL) + else if((FirstChar & 0xF0) == 0xE0) //3 Chars { - mMouseZ += pack_evt.zrel = (evt.wheel.y * 120); - pack_evt.z = mMouseZ; + len = 3; + val = FirstChar & 0x0F; } - else + else if((FirstChar & 0xF8) == 0xF0) //4 Chars { - throw new std::runtime_error("Tried to package non-motion event!"); + len = 4; + val = FirstChar & 0x07; + } + else if((FirstChar & 0xFC) == 0xF8) //5 Chars + { + len = 5; + val = FirstChar & 0x03; + } + else // if((FirstChar & 0xFE) == 0xFC) //6 Chars + { + len = 6; + val = FirstChar & 0x01; } - return pack_evt; + for(int i = 1; i < len; i++) + val = (val << 6) | (buf[i] & 0x3F); + + return val; } OIS::KeyCode InputWrapper::sdl2OISKeyCode(SDL_Keycode code) @@ -307,6 +344,8 @@ namespace SFO if(ois_equiv != mKeyMap.end()) kc = ois_equiv->second; + else + std::cerr << "Couldn't find OIS key for " << SDLK_SYSREQ << std::endl; return kc; } @@ -314,6 +353,10 @@ namespace SFO void InputWrapper::_setupOISKeys() { //lifted from OIS's SDLKeyboard.cpp + + //TODO: Consider switching to scancodes so we + //can properly support international keyboards + //look at SDL_GetKeyFromScancode and SDL_GetKeyName mKeyMap.insert( KeyMap::value_type(SDLK_UNKNOWN, OIS::KC_UNASSIGNED)); mKeyMap.insert( KeyMap::value_type(SDLK_ESCAPE, OIS::KC_ESCAPE) ); mKeyMap.insert( KeyMap::value_type(SDLK_1, OIS::KC_1) ); diff --git a/extern/sdl4ogre/sdlinputwrapper.hpp b/extern/sdl4ogre/sdlinputwrapper.hpp index 63b4c922b..55c45316f 100644 --- a/extern/sdl4ogre/sdlinputwrapper.hpp +++ b/extern/sdl4ogre/sdlinputwrapper.hpp @@ -32,13 +32,14 @@ namespace SFO void warpMouse(int x, int y); private: + bool _start(); + bool _handleWarpMotion(const SDL_MouseMotionEvent& evt); void _wrapMousePointer(const SDL_MouseMotionEvent &evt); - MouseMotionEvent _packageMouseMotion(const SDL_Event& evt); - void _handleKeyPress(SDL_KeyboardEvent& evt); - bool _start(); + void _handleKeyPress(SDL_KeyboardEvent& evt); + Uint32 _UTF8ToUTF32(const unsigned char *buf); void _setupOISKeys(); SFO::MouseListener* mMouseListener;