From 884d3ea4d8662b7ba3a17f75906d217d457aba08 Mon Sep 17 00:00:00 2001 From: Jordan Milne Date: Tue, 8 Jan 2013 06:19:05 -0400 Subject: [PATCH] Rip out OIS, fill the holes with SDL goodness. WIP. --- CMakeLists.txt | 8 +- apps/openmw/CMakeLists.txt | 3 +- apps/openmw/mwinput/inputmanagerimp.cpp | 153 ++++++----- apps/openmw/mwinput/inputmanagerimp.hpp | 36 ++- apps/openmw/mwinput/sdlinputwrapper.cpp | 70 +++++ apps/openmw/mwinput/sdlinputwrapper.hpp | 35 +++ cmake/FindSDL2.cmake | 180 +++++++++++++ extern/oics/CMakeLists.txt | 1 + extern/oics/ICSInputControlSystem.cpp | 245 +++++++++--------- extern/oics/ICSInputControlSystem.h | 56 ++-- .../oics/ICSInputControlSystem_joystick.cpp | 113 ++++---- .../oics/ICSInputControlSystem_keyboard.cpp | 26 +- extern/oics/ICSInputControlSystem_mouse.cpp | 32 +-- extern/oics/ICSPrerequisites.h | 14 +- extern/oics/OISCompat.h | 90 +++++++ 15 files changed, 724 insertions(+), 338 deletions(-) create mode 100644 apps/openmw/mwinput/sdlinputwrapper.cpp create mode 100644 apps/openmw/mwinput/sdlinputwrapper.hpp create mode 100644 cmake/FindSDL2.cmake create mode 100644 extern/oics/OISCompat.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 766167672e..b1eb91d766 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -204,7 +204,7 @@ endif() find_package(OGRE REQUIRED) find_package(MyGUI REQUIRED) find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS}) -find_package(OIS REQUIRED) +find_package(SDL2 REQUIRED) find_package(OpenAL REQUIRED) find_package(Bullet REQUIRED) IF(OGRE_STATIC) @@ -218,7 +218,8 @@ ENDIF(OGRE_STATIC) include_directories("." ${OGRE_INCLUDE_DIR} ${OGRE_INCLUDE_DIR}/Ogre ${OGRE_INCLUDE_DIR}/OGRE ${OGRE_PLUGIN_INCLUDE_DIRS} ${OGRE_Terrain_INCLUDE_DIR} - ${OIS_INCLUDE_DIRS} ${Boost_INCLUDE_DIR} + ${SDL2_INCLUDE_DIR} + ${Boost_INCLUDE_DIR} ${PLATFORM_INCLUDE_DIR} ${MYGUI_INCLUDE_DIRS} ${MYGUI_PLATFORM_INCLUDE_DIRS} @@ -227,7 +228,7 @@ include_directories("." ${LIBDIR} ) -link_directories(${Boost_LIBRARY_DIRS} ${OGRE_LIB_DIR} ${MYGUI_LIB_DIR}) +link_directories(${SDL2_LIBRARY_DIRS} ${Boost_LIBRARY_DIRS} ${OGRE_LIB_DIR} ${MYGUI_LIB_DIR}) if (APPLE) # List used Ogre plugins @@ -361,6 +362,7 @@ if(DPKG_PROGRAM) SET(CPACK_DEBIAN_PACKAGE_NAME "openmw") SET(CPACK_DEBIAN_PACKAGE_VERSION "${VERSION_STRING}") SET(CPACK_PACKAGE_EXECUTABLES "openmw;OpenMW esmtool;Esmtool omwlauncher;OMWLauncher mwiniimporter;MWiniImporter") + #TODO: should SDL2 be mentioned in here somewhere? SET(CPACK_DEBIAN_PACKAGE_DEPENDS "libc6 (>= 2.11.2), libfreetype6 (>= 2.2.1), libgcc1 (>= 1:4.1.1), libmpg123-0 (>= 1.12.1), libois-1.3.0 (>= 1.3.0), libopenal1 (>= 1:1.12.854), libsndfile1 (>= 1.0.23), libstdc++6 (>= 4.4.5), libuuid1 (>= 2.17.2), libqtgui4 (>= 4.7.0)") SET(CPACK_DEBIAN_PACKAGE_SECTION "Games") diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 56147b5008..88a05c8104 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -20,7 +20,7 @@ add_openmw_dir (mwrender ) add_openmw_dir (mwinput - inputmanagerimp + inputmanagerimp sdlinputwrapper ) add_openmw_dir (mwgui @@ -103,6 +103,7 @@ target_link_libraries(openmw ${SOUND_INPUT_LIBRARY} ${BULLET_LIBRARIES} ${MYGUI_LIBRARIES} + ${SDL2_LIBRARY} ${MYGUI_PLATFORM_LIBRARIES} "shiny" "shiny.OgrePlatform" diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 995da8f34b..a6f0f64d46 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -9,8 +9,6 @@ #include -#include - #include #include #include @@ -25,6 +23,8 @@ #include "../mwbase/windowmanager.hpp" #include "../mwbase/soundmanager.hpp" +using namespace ICS; + namespace MWInput { InputManager::InputManager(OEngine::Render::OgreRenderer &ogre, @@ -59,14 +59,19 @@ namespace MWInput window->getCustomAttribute("WINDOW", &windowHnd); + + // Set non-exclusive mouse and keyboard input if the user requested + // it. + + //TODO: re-enable this and make it work with SDL + /* + std::ostringstream windowHndStr; OIS::ParamList pl; windowHndStr << windowHnd; pl.insert(std::make_pair(std::string("WINDOW"), windowHndStr.str())); - // Set non-exclusive mouse and keyboard input if the user requested - // it. if (debug) { #if defined OIS_WIN32_PLATFORM @@ -89,6 +94,7 @@ namespace MWInput std::string("true"))); #endif } + */ #if defined(__APPLE__) && !defined(__LP64__) // Give the application window focus to receive input events @@ -97,23 +103,16 @@ namespace MWInput SetFrontProcess(&psn); #endif - mInputManager = OIS::InputManager::createInputSystem( pl ); + mInputManager = new MWSDLInputWrapper(window); + mInputManager->setMouseEventCallback (this); + mInputManager->setKeyboardEventCallback (this); - // Create all devices - mKeyboard = static_cast(mInputManager->createInputObject - ( OIS::OISKeyboard, true )); - mMouse = static_cast(mInputManager->createInputObject - ( OIS::OISMouse, true )); - - mKeyboard->setEventCallback (this); - mMouse->setEventCallback (this); + std::string file = userFileExists ? userFile : ""; + mInputCtrl = new ICS::InputControlSystem(file, true, this, NULL, A_Last); adjustMouseRegion (window->getWidth(), window->getHeight()); - MyGUI::InputManager::getInstance().injectMouseMove(mMouseX, mMouseY, mMouse->getMouseState ().Z.abs); - - std::string file = userFileExists ? userFile : ""; - mInputCtrl = new ICS::InputControlSystem(file, true, this, NULL, A_Last); + MyGUI::InputManager::getInstance().injectMouseMove(mMouseX, mMouseY, 0); loadKeyDefaults(); @@ -139,9 +138,7 @@ namespace MWInput delete mInputCtrl; - mInputManager->destroyInputObject(mKeyboard); - mInputManager->destroyInputObject(mMouse); - OIS::InputManager::destroyInputSystem(mInputManager); + delete mInputManager; } void InputManager::channelChanged(ICS::Channel* channel, float currentValue, float previousValue) @@ -240,8 +237,7 @@ namespace MWInput void InputManager::update(float dt, bool loading) { // Tell OIS to handle all input events - mKeyboard->capture(); - mMouse->capture(); + mInputManager->capture(); // inject some fake mouse movement to force updating MyGUI's widget states // this shouldn't do any harm since we're moving back to the original position afterwards @@ -304,7 +300,7 @@ namespace MWInput if (mControlSwitch["playerviewswitch"]) { // work around preview mode toggle when pressing Alt+Tab - if (actionIsActive(A_TogglePOV) && !mKeyboard->isModifierDown (OIS::Keyboard::Alt)) { + if (actionIsActive(A_TogglePOV) && !mInputManager->isModifierHeld(KMOD_ALT)) { if (mPreviewPOVDelay <= 0.5 && (mPreviewPOVDelay += dt) > 0.5) { @@ -419,37 +415,38 @@ namespace MWInput void InputManager::adjustMouseRegion(int width, int height) { - const OIS::MouseState &ms = mMouse->getMouseState(); - ms.width = width; - ms.height = height; + mInputCtrl->adjustMouseRegion(width, height); } - bool InputManager::keyPressed( const OIS::KeyEvent &arg ) + bool InputManager::keyPressed( const SDL_KeyboardEvent &arg ) { mInputCtrl->keyPressed (arg); - unsigned int text = arg.text; + unsigned int text = arg.keysym.unicode; + + //TODO: Check if we need this with SDL + /* #ifdef __APPLE__ // filter \016 symbol for F-keys on OS X - if ((arg.key >= OIS::KC_F1 && arg.key <= OIS::KC_F10) || - (arg.key >= OIS::KC_F11 && arg.key <= OIS::KC_F15)) { + if ((arg.key >= SDLK_F1 && arg.key <= SDLK_F10) || + (arg.key >= SDLK_F11 && arg.key <= SDLK_F15)) { text = 0; } #endif - - MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(arg.key), text); + */ + MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(arg.keysym.sym), text); return true; } - bool InputManager::keyReleased( const OIS::KeyEvent &arg ) + bool InputManager::keyReleased(const SDL_KeyboardEvent &arg ) { mInputCtrl->keyReleased (arg); - MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(arg.key)); + MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(arg.keysym.sym)); return true; } - bool InputManager::mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id ) + bool InputManager::mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id ) { mInputCtrl->mousePressed (arg, id); @@ -467,7 +464,7 @@ namespace MWInput return true; } - bool InputManager::mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id ) + bool InputManager::mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id ) { mInputCtrl->mouseReleased (arg, id); @@ -476,7 +473,7 @@ namespace MWInput return true; } - bool InputManager::mouseMoved( const OIS::MouseEvent &arg ) + bool InputManager::mouseMoved( const ICS::MWSDLMouseMotionEvent &arg ) { mInputCtrl->mouseMoved (arg); @@ -488,11 +485,13 @@ 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 - mMouseX += float(arg.state.X.rel) * mUISensitivity; - mMouseY += float(arg.state.Y.rel) * mUISensitivity * mUIYMultiplier; + mMouseX += float(arg.xrel) * mUISensitivity; + mMouseY += float(arg.yrel) * mUISensitivity * mUIYMultiplier; mMouseX = std::max(0.f, std::min(mMouseX, float(viewSize.width))); mMouseY = std::max(0.f, std::min(mMouseY, float(viewSize.height))); - mMouseWheel = arg.state.Z.abs; + + //there's no such thing as an absolute z position, so let's keep track of it ourselves + mMouseWheel += arg.zrel; MyGUI::InputManager::getInstance().injectMouseMove( int(mMouseX), int(mMouseY), mMouseWheel); } @@ -501,8 +500,8 @@ namespace MWInput { resetIdleTime(); - float x = arg.state.X.rel * mCameraSensitivity * 0.2; - float y = arg.state.Y.rel * mCameraSensitivity * 0.2 * (mInvertY ? -1 : 1) * mUIYMultiplier; + float x = arg.xrel * mCameraSensitivity * 0.2; + float y = arg.yrel * mCameraSensitivity * 0.2 * (mInvertY ? -1 : 1) * mUIYMultiplier; MWBase::World *world = MWBase::Environment::get().getWorld(); world->rotateObject(world->getPlayer().getPlayer(), -y, 0.f, x, true); @@ -679,38 +678,38 @@ namespace MWInput // across different versions of OpenMW (in the case where another input action is added) std::map defaultKeyBindings; - defaultKeyBindings[A_Activate] = OIS::KC_SPACE; - defaultKeyBindings[A_MoveBackward] = OIS::KC_S; - defaultKeyBindings[A_MoveForward] = OIS::KC_W; - defaultKeyBindings[A_MoveLeft] = OIS::KC_A; - defaultKeyBindings[A_MoveRight] = OIS::KC_D; - defaultKeyBindings[A_ToggleWeapon] = OIS::KC_F; - defaultKeyBindings[A_ToggleSpell] = OIS::KC_R; - defaultKeyBindings[A_QuickKeysMenu] = OIS::KC_F1; - defaultKeyBindings[A_Console] = OIS::KC_F2; - defaultKeyBindings[A_Crouch] = OIS::KC_LCONTROL; - defaultKeyBindings[A_AutoMove] = OIS::KC_Q; - defaultKeyBindings[A_Jump] = OIS::KC_E; - defaultKeyBindings[A_Journal] = OIS::KC_J; - defaultKeyBindings[A_Rest] = OIS::KC_T; - defaultKeyBindings[A_GameMenu] = OIS::KC_ESCAPE; - defaultKeyBindings[A_TogglePOV] = OIS::KC_TAB; - defaultKeyBindings[A_QuickKey1] = OIS::KC_1; - defaultKeyBindings[A_QuickKey2] = OIS::KC_2; - defaultKeyBindings[A_QuickKey3] = OIS::KC_3; - defaultKeyBindings[A_QuickKey4] = OIS::KC_4; - defaultKeyBindings[A_QuickKey5] = OIS::KC_5; - defaultKeyBindings[A_QuickKey6] = OIS::KC_6; - defaultKeyBindings[A_QuickKey7] = OIS::KC_7; - defaultKeyBindings[A_QuickKey8] = OIS::KC_8; - defaultKeyBindings[A_QuickKey9] = OIS::KC_9; - defaultKeyBindings[A_QuickKey10] = OIS::KC_0; - defaultKeyBindings[A_Screenshot] = OIS::KC_SYSRQ; - defaultKeyBindings[A_ToggleHUD] = OIS::KC_F12; + defaultKeyBindings[A_Activate] = SDLK_SPACE; + defaultKeyBindings[A_MoveBackward] = SDLK_s; + defaultKeyBindings[A_MoveForward] = SDLK_w; + defaultKeyBindings[A_MoveLeft] = SDLK_a; + defaultKeyBindings[A_MoveRight] = SDLK_d; + defaultKeyBindings[A_ToggleWeapon] = SDLK_f; + defaultKeyBindings[A_ToggleSpell] = SDLK_r; + defaultKeyBindings[A_QuickKeysMenu] = SDLK_F1; + defaultKeyBindings[A_Console] = SDLK_F2; + defaultKeyBindings[A_Crouch] = SDLK_LCTRL; + defaultKeyBindings[A_AutoMove] = SDLK_q; + defaultKeyBindings[A_Jump] = SDLK_e; + defaultKeyBindings[A_Journal] = SDLK_j; + defaultKeyBindings[A_Rest] = SDLK_t; + defaultKeyBindings[A_GameMenu] = SDLK_ESCAPE; + defaultKeyBindings[A_TogglePOV] = SDLK_TAB; + defaultKeyBindings[A_QuickKey1] = SDLK_1; + defaultKeyBindings[A_QuickKey2] = SDLK_2; + defaultKeyBindings[A_QuickKey3] = SDLK_3; + defaultKeyBindings[A_QuickKey4] = SDLK_4; + defaultKeyBindings[A_QuickKey5] = SDLK_5; + defaultKeyBindings[A_QuickKey6] = SDLK_6; + defaultKeyBindings[A_QuickKey7] = SDLK_7; + defaultKeyBindings[A_QuickKey8] = SDLK_8; + defaultKeyBindings[A_QuickKey9] = SDLK_9; + defaultKeyBindings[A_QuickKey10] = SDLK_0; + defaultKeyBindings[A_Screenshot] = SDLK_SYSREQ; + defaultKeyBindings[A_ToggleHUD] = SDLK_F12; std::map defaultMouseButtonBindings; - defaultMouseButtonBindings[A_Inventory] = OIS::MB_Right; - defaultMouseButtonBindings[A_Use] = OIS::MB_Left; + defaultMouseButtonBindings[A_Inventory] = SDL_BUTTON_RIGHT; + defaultMouseButtonBindings[A_Use] = SDL_BUTTON_LEFT; for (int i = 0; i < A_Last; ++i) { @@ -728,14 +727,14 @@ namespace MWInput } if (!controlExists || force || - ( mInputCtrl->getKeyBinding (control, ICS::Control::INCREASE) == OIS::KC_UNASSIGNED + ( mInputCtrl->getKeyBinding (control, ICS::Control::INCREASE) == SDLK_UNKNOWN && mInputCtrl->getMouseButtonBinding (control, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS )) { clearAllBindings (control); if (defaultKeyBindings.find(i) != defaultKeyBindings.end()) - mInputCtrl->addKeyBinding(control, static_cast(defaultKeyBindings[i]), ICS::Control::INCREASE); + mInputCtrl->addKeyBinding(control, static_cast(defaultKeyBindings[i]), ICS::Control::INCREASE); else if (defaultMouseButtonBindings.find(i) != defaultMouseButtonBindings.end()) mInputCtrl->addMouseButtonBinding (control, defaultMouseButtonBindings[i], ICS::Control::INCREASE); } @@ -786,7 +785,7 @@ namespace MWInput ICS::Control* c = mInputCtrl->getChannel (action)->getAttachedControls ().front().control; - if (mInputCtrl->getKeyBinding (c, ICS::Control::INCREASE) != OIS::KC_UNASSIGNED) + if (mInputCtrl->getKeyBinding (c, ICS::Control::INCREASE) != SDLK_UNKNOWN) return mInputCtrl->keyCodeToString (mInputCtrl->getKeyBinding (c, ICS::Control::INCREASE)); else if (mInputCtrl->getMouseButtonBinding (c, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS) return "#{sMouse} " + boost::lexical_cast(mInputCtrl->getMouseButtonBinding (c, ICS::Control::INCREASE)); @@ -842,7 +841,7 @@ namespace MWInput } void InputManager::keyBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , OIS::KeyCode key, ICS::Control::ControlChangingDirection direction) + , SDL_Keycode key, ICS::Control::ControlChangingDirection direction) { clearAllBindings(control); ICS::DetectingBindingListener::keyBindingDetected (ICS, control, key, direction); @@ -892,7 +891,7 @@ namespace MWInput void InputManager::clearAllBindings (ICS::Control* control) { // right now we don't really need multiple bindings for the same action, so remove all others first - if (mInputCtrl->getKeyBinding (control, ICS::Control::INCREASE) != OIS::KC_UNASSIGNED) + if (mInputCtrl->getKeyBinding (control, ICS::Control::INCREASE) != SDLK_UNKNOWN) mInputCtrl->removeKeyBinding (mInputCtrl->getKeyBinding (control, ICS::Control::INCREASE)); if (mInputCtrl->getMouseButtonBinding (control, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS) mInputCtrl->removeMouseButtonBinding (mInputCtrl->getMouseButtonBinding (control, ICS::Control::INCREASE)); diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 9deed1f285..3677f9070a 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -6,6 +6,7 @@ #include #include "../mwbase/inputmanager.hpp" +#include "sdlinputwrapper.hpp" namespace OEngine { @@ -35,18 +36,9 @@ namespace ICS class InputControlSystem; } -namespace OIS -{ - class Keyboard; - class Mouse; - class InputManager; -} - -#include -#include - #include #include +#include namespace MWInput { @@ -54,7 +46,12 @@ namespace MWInput /** * @brief Class that handles all input and key bindings for OpenMW. */ - class InputManager : public MWBase::InputManager, public OIS::KeyListener, public OIS::MouseListener, public ICS::ChannelListener, public ICS::DetectingBindingListener + class InputManager : + public MWBase::InputManager, + public ICS::MWSDLKeyListener, + public ICS::MWSDLMouseListener, + public ICS::ChannelListener, + public ICS::DetectingBindingListener { public: InputManager(OEngine::Render::OgreRenderer &_ogre, @@ -85,12 +82,12 @@ namespace MWInput virtual void resetToDefaultBindings(); public: - virtual bool keyPressed( const OIS::KeyEvent &arg ); - virtual bool keyReleased( const OIS::KeyEvent &arg ); + virtual bool keyPressed(const SDL_KeyboardEvent &arg ); + virtual bool keyReleased( const SDL_KeyboardEvent &arg ); - virtual bool mousePressed( const OIS::MouseEvent &arg, OIS::MouseButtonID id ); - virtual bool mouseReleased( const OIS::MouseEvent &arg, OIS::MouseButtonID id ); - virtual bool mouseMoved( const OIS::MouseEvent &arg ); + virtual bool mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id ); + virtual bool mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id ); + virtual bool mouseMoved( const ICS::MWSDLMouseMotionEvent &arg ); virtual void channelChanged(ICS::Channel* channel, float currentValue, float previousValue); @@ -98,7 +95,7 @@ namespace MWInput , ICS::InputControlSystem::NamedAxis axis, ICS::Control::ControlChangingDirection direction); virtual void keyBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , OIS::KeyCode key, ICS::Control::ControlChangingDirection direction); + , SDL_Keycode key, ICS::Control::ControlChangingDirection direction); virtual void mouseButtonBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control , unsigned int button, ICS::Control::ControlChangingDirection direction); @@ -125,9 +122,8 @@ namespace MWInput ICS::InputControlSystem* mInputCtrl; - OIS::Keyboard* mKeyboard; - OIS::Mouse* mMouse; - OIS::InputManager* mInputManager; + + MWSDLInputWrapper* mInputManager; std::string mUserFile; diff --git a/apps/openmw/mwinput/sdlinputwrapper.cpp b/apps/openmw/mwinput/sdlinputwrapper.cpp new file mode 100644 index 0000000000..60c7e8f7a3 --- /dev/null +++ b/apps/openmw/mwinput/sdlinputwrapper.cpp @@ -0,0 +1,70 @@ +#include "sdlinputwrapper.hpp" +#include + +namespace MWInput +{ + MWSDLInputWrapper::MWSDLInputWrapper(Ogre::RenderWindow *window) : + mWindow(window), mStarted(false), mSDLWindow(NULL) + { + _start(); + } + + MWSDLInputWrapper::~MWSDLInputWrapper() + { + SDL_DestroyWindow(mSDLWindow); + mSDLWindow = NULL; + SDL_Quit(); + } + + void MWSDLInputWrapper::capture() + { + _start(); + + SDL_Event evt; + while(SDL_PollEvent(&evt)) + { + switch(evt.type) + { + case SDL_MOUSEMOTION: + mMouseListener->mouseMoved(ICS::MWSDLMouseMotionEvent(evt.motion)); + break; + case SDL_MOUSEWHEEL: + mMouseListener->mouseMoved(ICS::MWSDLMouseMotionEvent(evt.wheel)); + break; + case SDL_MOUSEBUTTONDOWN: + mMouseListener->mousePressed(evt.button, evt.button.button); + break; + case SDL_MOUSEBUTTONUP: + mMouseListener->mouseReleased(evt.button, evt.button.button); + break; + + case SDL_KEYDOWN: + mKeyboardListener->keyPressed(evt.key); + break; + case SDL_KEYUP: + mKeyboardListener->keyReleased(evt.key); + break; + } + } + } + + bool MWSDLInputWrapper::isModifierHeld(int mod) + { + return SDL_GetModState() & mod; + } + + void MWSDLInputWrapper::_start() + { + Uint32 flags = SDL_INIT_VIDEO; + if(SDL_WasInit(flags) == 0) + { + //get the HWND from ogre's renderwindow + size_t windowHnd; + mWindow->getCustomAttribute("WINDOW", &windowHnd); + + //just use that one for input + SDL_Init(flags); + mSDLWindow = SDL_CreateWindowFrom((void*)windowHnd); + } + } +} diff --git a/apps/openmw/mwinput/sdlinputwrapper.hpp b/apps/openmw/mwinput/sdlinputwrapper.hpp new file mode 100644 index 0000000000..ee07efbdb4 --- /dev/null +++ b/apps/openmw/mwinput/sdlinputwrapper.hpp @@ -0,0 +1,35 @@ +#ifndef _MWINPUT_SDLINPUTWRAPPER_H +#define _MWINPUT_SDLINPUTWRAPPER_H + +#include "SDL2/SDL_events.h" +#include +#include + + +namespace MWInput +{ + class MWSDLInputWrapper + { + public: + MWSDLInputWrapper(Ogre::RenderWindow* window); + ~MWSDLInputWrapper(); + + void setMouseEventCallback(ICS::MWSDLMouseListener* listen) { mMouseListener = listen; } + void setKeyboardEventCallback(ICS::MWSDLKeyListener* listen) { mKeyboardListener = listen; } + + void capture(); + bool isModifierHeld(int mod); + + private: + ICS::MWSDLMouseListener* mMouseListener; + ICS::MWSDLKeyListener* mKeyboardListener; + Ogre::RenderWindow* mWindow; + SDL_Window* mSDLWindow; + + bool mStarted; + void _start(); + + }; +} + +#endif diff --git a/cmake/FindSDL2.cmake b/cmake/FindSDL2.cmake new file mode 100644 index 0000000000..614426cccf --- /dev/null +++ b/cmake/FindSDL2.cmake @@ -0,0 +1,180 @@ +# Locate SDL2 library +# This module defines +# SDL2_LIBRARY, the name of the library to link against +# SDL2_FOUND, if false, do not try to link to SDL2 +# SDL2_INCLUDE_DIR, where to find SDL.h +# +# This module responds to the the flag: +# SDL2_BUILDING_LIBRARY +# If this is defined, then no SDL2_main will be linked in because +# only applications need main(). +# Otherwise, it is assumed you are building an application and this +# module will attempt to locate and set the the proper link flags +# as part of the returned SDL2_LIBRARY variable. +# +# Don't forget to include SDL2main.h and SDL2main.m your project for the +# OS X framework based version. (Other versions link to -lSDL2main which +# this module will try to find on your behalf.) Also for OS X, this +# module will automatically add the -framework Cocoa on your behalf. +# +# +# Additional Note: If you see an empty SDL2_LIBRARY_TEMP in your configuration +# and no SDL2_LIBRARY, it means CMake did not find your SDL2 library +# (SDL2.dll, libsdl2.so, SDL2.framework, etc). +# Set SDL2_LIBRARY_TEMP to point to your SDL2 library, and configure again. +# Similarly, if you see an empty SDL2MAIN_LIBRARY, you should set this value +# as appropriate. These values are used to generate the final SDL2_LIBRARY +# variable, but when these values are unset, SDL2_LIBRARY does not get created. +# +# +# $SDL2DIR is an environment variable that would +# correspond to the ./configure --prefix=$SDL2DIR +# used in building SDL2. +# l.e.galup 9-20-02 +# +# Modified by Eric Wing. +# Added code to assist with automated building by using environmental variables +# and providing a more controlled/consistent search behavior. +# Added new modifications to recognize OS X frameworks and +# additional Unix paths (FreeBSD, etc). +# Also corrected the header search path to follow "proper" SDL2 guidelines. +# Added a search for SDL2main which is needed by some platforms. +# Added a search for threads which is needed by some platforms. +# Added needed compile switches for MinGW. +# +# On OSX, this will prefer the Framework version (if found) over others. +# People will have to manually change the cache values of +# SDL2_LIBRARY to override this selection or set the CMake environment +# CMAKE_INCLUDE_PATH to modify the search paths. +# +# Note that the header path has changed from SDL2/SDL.h to just SDL.h +# This needed to change because "proper" SDL2 convention +# is #include "SDL.h", not . This is done for portability +# reasons because not all systems place things in SDL2/ (see FreeBSD). +# +# Ported by Johnny Patterson. This is a literal port for SDL2 of the FindSDL.cmake +# module with the minor edit of changing "SDL" to "SDL2" where necessary. This +# was not created for redistribution, and exists temporarily pending official +# SDL2 CMake modules. + +#============================================================================= +# Copyright 2003-2009 Kitware, Inc. +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + +FIND_PATH(SDL2_INCLUDE_DIR SDL.h + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES include/SDL2 include + PATHS + ~/Library/Frameworks + /Library/Frameworks + /usr/local/include/SDL2 + /usr/include/SDL2 + /sw # Fink + /opt/local # DarwinPorts + /opt/csw # Blastwave + /opt +) +#MESSAGE("SDL2_INCLUDE_DIR is ${SDL2_INCLUDE_DIR}") + +FIND_LIBRARY(SDL2_LIBRARY_TEMP + NAMES SDL2 + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES lib64 lib + PATHS + /sw + /opt/local + /opt/csw + /opt +) + +#MESSAGE("SDL2_LIBRARY_TEMP is ${SDL2_LIBRARY_TEMP}") + +IF(NOT SDL2_BUILDING_LIBRARY) + IF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") + # Non-OS X framework versions expect you to also dynamically link to + # SDL2main. This is mainly for Windows and OS X. Other (Unix) platforms + # seem to provide SDL2main for compatibility even though they don't + # necessarily need it. + FIND_LIBRARY(SDL2MAIN_LIBRARY + NAMES SDL2main + HINTS + $ENV{SDL2DIR} + PATH_SUFFIXES lib64 lib + PATHS + /sw + /opt/local + /opt/csw + /opt + ) + ENDIF(NOT ${SDL2_INCLUDE_DIR} MATCHES ".framework") +ENDIF(NOT SDL2_BUILDING_LIBRARY) + +# SDL2 may require threads on your system. +# The Apple build may not need an explicit flag because one of the +# frameworks may already provide it. +# But for non-OSX systems, I will use the CMake Threads package. +IF(NOT APPLE) + FIND_PACKAGE(Threads) +ENDIF(NOT APPLE) + +# MinGW needs an additional library, mwindows +# It's total link flags should look like -lmingw32 -lSDL2main -lSDL2 -lmwindows +# (Actually on second look, I think it only needs one of the m* libraries.) +IF(MINGW) + SET(MINGW32_LIBRARY mingw32 CACHE STRING "mwindows for MinGW") +ENDIF(MINGW) + +SET(SDL2_FOUND "NO") +IF(SDL2_LIBRARY_TEMP) + # For SDL2main + IF(NOT SDL2_BUILDING_LIBRARY) + IF(SDL2MAIN_LIBRARY) + SET(SDL2_LIBRARY_TEMP ${SDL2MAIN_LIBRARY} ${SDL2_LIBRARY_TEMP}) + ENDIF(SDL2MAIN_LIBRARY) + ENDIF(NOT SDL2_BUILDING_LIBRARY) + + # For OS X, SDL2 uses Cocoa as a backend so it must link to Cocoa. + # CMake doesn't display the -framework Cocoa string in the UI even + # though it actually is there if I modify a pre-used variable. + # I think it has something to do with the CACHE STRING. + # So I use a temporary variable until the end so I can set the + # "real" variable in one-shot. + IF(APPLE) + SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} "-framework Cocoa") + ENDIF(APPLE) + + # For threads, as mentioned Apple doesn't need this. + # In fact, there seems to be a problem if I used the Threads package + # and try using this line, so I'm just skipping it entirely for OS X. + IF(NOT APPLE) + SET(SDL2_LIBRARY_TEMP ${SDL2_LIBRARY_TEMP} ${CMAKE_THREAD_LIBS_INIT}) + ENDIF(NOT APPLE) + + # For MinGW library + IF(MINGW) + SET(SDL2_LIBRARY_TEMP ${MINGW32_LIBRARY} ${SDL2_LIBRARY_TEMP}) + ENDIF(MINGW) + + # Set the final string here so the GUI reflects the final state. + SET(SDL2_LIBRARY ${SDL2_LIBRARY_TEMP} CACHE STRING "Where the SDL2 Library can be found") + # Set the temp variable to INTERNAL so it is not seen in the CMake GUI + SET(SDL2_LIBRARY_TEMP "${SDL2_LIBRARY_TEMP}" CACHE INTERNAL "") + + SET(SDL2_FOUND "YES") +ENDIF(SDL2_LIBRARY_TEMP) + +INCLUDE(FindPackageHandleStandardArgs) + +FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 + REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR) diff --git a/extern/oics/CMakeLists.txt b/extern/oics/CMakeLists.txt index 7c14387a4b..2e2a7a6d6b 100644 --- a/extern/oics/CMakeLists.txt +++ b/extern/oics/CMakeLists.txt @@ -9,6 +9,7 @@ set(OICS_SOURCE_FILES ICSInputControlSystem_keyboard.cpp ICSInputControlSystem_mouse.cpp ICSInputControlSystem_joystick.cpp + OISCompat.h tinyxml.cpp tinyxmlparser.cpp tinyxmlerror.cpp diff --git a/extern/oics/ICSInputControlSystem.cpp b/extern/oics/ICSInputControlSystem.cpp index 1702c853ed..159b3241ff 100644 --- a/extern/oics/ICSInputControlSystem.cpp +++ b/extern/oics/ICSInputControlSystem.cpp @@ -41,7 +41,7 @@ namespace ICS this->mActive = active; - this->fillOISKeysMap(); + this->fillSDLKeysMap(); ICS_LOG("Channel count = " + ToString(channelCount) ); for(size_t i=0;i::iterator it = mKeys.begin() + mKeys["UNASSIGNED"]= SDLK_UNKNOWN; + mKeys["ESCAPE"]= SDLK_ESCAPE; + mKeys["1"]= SDLK_1; + mKeys["2"]= SDLK_2; + mKeys["3"]= SDLK_3; + mKeys["4"]= SDLK_4; + mKeys["5"]= SDLK_5; + mKeys["6"]= SDLK_6; + mKeys["7"]= SDLK_7; + mKeys["8"]= SDLK_8; + mKeys["9"]= SDLK_9; + mKeys["0"]= SDLK_0; + mKeys["MINUS"]= SDLK_MINUS; + mKeys["EQUALS"]= SDLK_EQUALS; + mKeys["BACK"]= SDLK_BACKSPACE; + mKeys["TAB"]= SDLK_TAB; + mKeys["Q"]= SDLK_q; + mKeys["W"]= SDLK_w; + mKeys["E"]= SDLK_e; + mKeys["R"]= SDLK_r; + mKeys["T"]= SDLK_t; + mKeys["Y"]= SDLK_y; + mKeys["U"]= SDLK_u; + mKeys["I"]= SDLK_i; + mKeys["O"]= SDLK_o; + mKeys["P"]= SDLK_p; + mKeys["LBRACKET"]= SDLK_LEFTBRACKET; + mKeys["RBRACKET"]= SDLK_RIGHTBRACKET; + mKeys["RETURN"]= SDLK_RETURN; + mKeys["LCONTROL"]= SDLK_LCTRL; + mKeys["A"]= SDLK_a; + mKeys["S"]= SDLK_s; + mKeys["D"]= SDLK_d; + mKeys["F"]= SDLK_f; + mKeys["G"]= SDLK_g; + mKeys["H"]= SDLK_h; + mKeys["J"]= SDLK_j; + mKeys["K"]= SDLK_k; + mKeys["L"]= SDLK_l; + mKeys["SEMICOLON"]= SDLK_SEMICOLON; + mKeys["APOSTROPHE"]= SDLK_QUOTE; + mKeys["GRAVE"]= SDLK_BACKQUOTE; + mKeys["LSHIFT"]= SDLK_LSHIFT; + mKeys["BACKSLASH"]= SDLK_BACKSLASH; + mKeys["Z"]= SDLK_z; + mKeys["X"]= SDLK_x; + mKeys["C"]= SDLK_c; + mKeys["V"]= SDLK_v; + mKeys["B"]= SDLK_b; + mKeys["N"]= SDLK_n; + mKeys["M"]= SDLK_m; + mKeys["COMMA"]= SDLK_COMMA; + mKeys["PERIOD"]= SDLK_PERIOD; + mKeys["SLASH"]= SDLK_SLASH; + mKeys["RSHIFT"]= SDLK_RSHIFT; + mKeys["MULTIPLY"]= SDLK_ASTERISK; + mKeys["LMENU"]= SDLK_LALT; + mKeys["SPACE"]= SDLK_SPACE; + mKeys["CAPITAL"]= SDLK_CAPSLOCK; + mKeys["F1"]= SDLK_F1; + mKeys["F2"]= SDLK_F2; + mKeys["F3"]= SDLK_F3; + mKeys["F4"]= SDLK_F4; + mKeys["F5"]= SDLK_F5; + mKeys["F6"]= SDLK_F6; + mKeys["F7"]= SDLK_F7; + mKeys["F8"]= SDLK_F8; + mKeys["F9"]= SDLK_F9; + mKeys["F10"]= SDLK_F10; + mKeys["F11"]= SDLK_F11; + mKeys["F12"]= SDLK_F12; + mKeys["NUMLOCK"]= SDLK_NUMLOCKCLEAR; + mKeys["SCROLL"]= SDLK_SCROLLLOCK; + mKeys["NUMPAD7"]= SDLK_KP_7; + mKeys["NUMPAD8"]= SDLK_KP_8; + mKeys["NUMPAD9"]= SDLK_KP_9; + mKeys["SUBTRACT"]= SDLK_KP_MINUS; + mKeys["NUMPAD4"]= SDLK_KP_4; + mKeys["NUMPAD5"]= SDLK_KP_5; + mKeys["NUMPAD6"]= SDLK_KP_6; + mKeys["ADD"]= SDLK_KP_PLUS; + mKeys["NUMPAD1"]= SDLK_KP_1; + mKeys["NUMPAD2"]= SDLK_KP_2; + mKeys["NUMPAD3"]= SDLK_KP_3; + mKeys["NUMPAD0"]= SDLK_KP_0; + mKeys["DECIMAL"]= SDLK_KP_DECIMAL; + mKeys["RCONTROL"]= SDLK_RCTRL; + mKeys["DIVIDE"]= SDLK_SLASH; + mKeys["SYSRQ"]= SDLK_SYSREQ; + mKeys["RMENU"]= SDLK_RALT; + mKeys["PAUSE"]= SDLK_PAUSE; + mKeys["HOME"]= SDLK_HOME; + mKeys["UP"]= SDLK_UP; + mKeys["PGUP"]= SDLK_PAGEUP; + mKeys["LEFT"]= SDLK_LEFT; + mKeys["RIGHT"]= SDLK_RIGHT; + mKeys["END"]= SDLK_END; + mKeys["DOWN"]= SDLK_DOWN; + mKeys["PGDOWN"]= SDLK_PAGEDOWN; + mKeys["INSERT"]= SDLK_INSERT; + mKeys["DELETE"]= SDLK_DELETE; + + mKeys["NUMPADENTER"]= SDLK_KP_ENTER; + + for(std::map::iterator it = mKeys.begin() ; it != mKeys.end() ; it++) { mKeyCodes[ it->second ] = it->first; } } - std::string InputControlSystem::keyCodeToString(OIS::KeyCode key) + std::string InputControlSystem::keyCodeToString(SDL_Keycode key) { return mKeyCodes[key]; } - OIS::KeyCode InputControlSystem::stringToKeyCode(std::string key) + SDL_Keycode InputControlSystem::stringToKeyCode(std::string key) { return mKeys[key]; } -} \ No newline at end of file + + void InputControlSystem::adjustMouseRegion(Uint16 width, Uint16 height) + { + mClientWidth = width; + mClientHeight = height; + } +} diff --git a/extern/oics/ICSInputControlSystem.h b/extern/oics/ICSInputControlSystem.h index f1c12d3b59..5d30b35cfb 100644 --- a/extern/oics/ICSInputControlSystem.h +++ b/extern/oics/ICSInputControlSystem.h @@ -32,6 +32,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "ICSControl.h" #include "ICSChannel.h" +#include "OISCompat.h" + #define ICS_LOG(text) if(mLog) mLog->logMessage( ("ICS: " + std::string(text)).c_str() ); #define ICS_MAX_JOYSTICK_AXIS 16 #define ICS_MOUSE_BINDING_MARGIN 30 @@ -48,9 +50,9 @@ namespace ICS }; class DllExport InputControlSystem : - public OIS::MouseListener, - public OIS::KeyListener, - public OIS::JoyStickListener + public MWSDLMouseListener, + public MWSDLKeyListener, + public MWSDLJoyStickListener { public: @@ -100,29 +102,30 @@ namespace ICS JoystickIDList& getJoystickIdList(){ return mJoystickIDList; }; // MouseListener - bool mouseMoved(const OIS::MouseEvent &evt); - bool mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID); - bool mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID); + bool mouseMoved(const MWSDLMouseMotionEvent &evt); + bool mousePressed(const SDL_MouseButtonEvent &evt, Uint8); + bool mouseReleased(const SDL_MouseButtonEvent &evt, Uint8); // KeyListener - bool keyPressed(const OIS::KeyEvent &evt); - bool keyReleased(const OIS::KeyEvent &evt); + bool keyPressed(const SDL_KeyboardEvent &evt); + bool keyReleased(const SDL_KeyboardEvent &evt); // JoyStickListener - bool buttonPressed(const OIS::JoyStickEvent &evt, int button); - bool buttonReleased(const OIS::JoyStickEvent &evt, int button); - bool axisMoved(const OIS::JoyStickEvent &evt, int axis); - bool povMoved(const OIS::JoyStickEvent &evt, int index); - bool sliderMoved(const OIS::JoyStickEvent &evt, int index); - - void addKeyBinding(Control* control, OIS::KeyCode key, Control::ControlChangingDirection direction); + bool buttonPressed(const SDL_JoyButtonEvent &evt, int button); + bool buttonReleased(const SDL_JoyButtonEvent &evt, int button); + bool axisMoved(const SDL_JoyAxisEvent &evt, int axis); + bool povMoved(const SDL_JoyHatEvent &evt, int index); + //TODO: does this have an SDL equivalent? + //bool sliderMoved(const OIS::JoyStickEvent &evt, int index); + + void addKeyBinding(Control* control, SDL_Keycode key, Control::ControlChangingDirection direction); void addMouseAxisBinding(Control* control, NamedAxis axis, Control::ControlChangingDirection direction); void addMouseButtonBinding(Control* control, unsigned int button, Control::ControlChangingDirection direction); void addJoystickAxisBinding(Control* control, int deviceId, int axis, Control::ControlChangingDirection direction); void addJoystickButtonBinding(Control* control, int deviceId, unsigned int button, Control::ControlChangingDirection direction); void addJoystickPOVBinding(Control* control, int deviceId, int index, POVAxis axis, Control::ControlChangingDirection direction); void addJoystickSliderBinding(Control* control, int deviceId, int index, Control::ControlChangingDirection direction); - void removeKeyBinding(OIS::KeyCode key); + void removeKeyBinding(SDL_Keycode key); void removeMouseAxisBinding(NamedAxis axis); void removeMouseButtonBinding(unsigned int button); void removeJoystickAxisBinding(int deviceId, int axis); @@ -130,7 +133,7 @@ namespace ICS void removeJoystickPOVBinding(int deviceId, int index, POVAxis axis); void removeJoystickSliderBinding(int deviceId, int index); - OIS::KeyCode getKeyBinding(Control* control, ICS::Control::ControlChangingDirection direction); + SDL_Keycode getKeyBinding(Control* control, ICS::Control::ControlChangingDirection direction); NamedAxis getMouseAxisBinding(Control* control, ICS::Control::ControlChangingDirection direction); unsigned int getMouseButtonBinding(Control* control, ICS::Control::ControlChangingDirection direction); int getJoystickAxisBinding(Control* control, int deviceId, ICS::Control::ControlChangingDirection direction); @@ -138,14 +141,16 @@ namespace ICS POVBindingPair getJoystickPOVBinding(Control* control, int deviceId, ICS::Control::ControlChangingDirection direction); int getJoystickSliderBinding(Control* control, int deviceId, ICS::Control::ControlChangingDirection direction); - std::string keyCodeToString(OIS::KeyCode key); - OIS::KeyCode stringToKeyCode(std::string key); + std::string keyCodeToString(SDL_Keycode key); + SDL_Keycode stringToKeyCode(std::string key); void enableDetectingBindingState(Control* control, Control::ControlChangingDirection direction); void cancelDetectingBindingState(); bool save(std::string fileName = ""); + void adjustMouseRegion (Uint16 width, Uint16 height); + protected: void loadKeyBinders(TiXmlElement* xmlControlNode); @@ -180,7 +185,7 @@ namespace ICS std::string mFileName; - typedef std::map ControlsKeyBinderMapType; // + typedef std::map ControlsKeyBinderMapType; // typedef std::map ControlsAxisBinderMapType; // typedef std::map ControlsButtonBinderMapType; // typedef std::map ControlsPOVBinderMapType; // @@ -202,8 +207,8 @@ namespace ICS std::vector mChannels; ControlsKeyBinderMapType mControlsKeyBinderMap; - std::map mKeys; - std::map mKeyCodes; + std::map mKeys; + std::map mKeyCodes; bool mActive; InputControlSystemLog* mLog; @@ -221,14 +226,17 @@ namespace ICS private: - void fillOISKeysMap(); + void fillSDLKeysMap(); + + Uint16 mClientWidth; + Uint16 mClientHeight; }; class DllExport DetectingBindingListener { public: virtual void keyBindingDetected(InputControlSystem* ICS, Control* control - , OIS::KeyCode key, Control::ControlChangingDirection direction); + , SDL_Keycode key, Control::ControlChangingDirection direction); virtual void mouseAxisBindingDetected(InputControlSystem* ICS, Control* control , InputControlSystem::NamedAxis axis, Control::ControlChangingDirection direction); diff --git a/extern/oics/ICSInputControlSystem_joystick.cpp b/extern/oics/ICSInputControlSystem_joystick.cpp index 1e66599ead..8e501d5018 100644 --- a/extern/oics/ICSInputControlSystem_joystick.cpp +++ b/extern/oics/ICSInputControlSystem_joystick.cpp @@ -26,6 +26,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "ICSInputControlSystem.h" +#define SDL_JOY_AXIS_MIN -32768 +#define SDL_JOY_AXIS_MAX 32767 + namespace ICS { // load xml @@ -315,16 +318,16 @@ namespace ICS } // joyStick listeners - bool InputControlSystem::buttonPressed(const OIS::JoyStickEvent &evt, int button) + bool InputControlSystem::buttonPressed(const SDL_JoyButtonEvent &evt, int button) { if(mActive) { if(!mDetectingBindingControl) { - if(mControlsJoystickButtonBinderMap.find(evt.device->getID()) != mControlsJoystickButtonBinderMap.end()) + if(mControlsJoystickButtonBinderMap.find(evt.which) != mControlsJoystickButtonBinderMap.end()) { - ControlsButtonBinderMapType::const_iterator it = mControlsJoystickButtonBinderMap[evt.device->getID()].find(button); - if(it != mControlsJoystickButtonBinderMap[evt.device->getID()].end()) + ControlsButtonBinderMapType::const_iterator it = mControlsJoystickButtonBinderMap[evt.which].find(button); + if(it != mControlsJoystickButtonBinderMap[evt.which].end()) { it->second.control->setIgnoreAutoReverse(false); if(!it->second.control->getAutoChangeDirectionOnLimitsAfterStop()) @@ -348,21 +351,21 @@ namespace ICS else if(mDetectingBindingListener) { mDetectingBindingListener->joystickButtonBindingDetected(this, - mDetectingBindingControl, evt.device->getID(), button, mDetectingBindingDirection); + mDetectingBindingControl, evt.which, button, mDetectingBindingDirection); } } return true; } - bool InputControlSystem::buttonReleased(const OIS::JoyStickEvent &evt, int button) + bool InputControlSystem::buttonReleased(const SDL_JoyButtonEvent &evt, int button) { if(mActive) { - if(mControlsJoystickButtonBinderMap.find(evt.device->getID()) != mControlsJoystickButtonBinderMap.end()) + if(mControlsJoystickButtonBinderMap.find(evt.which) != mControlsJoystickButtonBinderMap.end()) { - ControlsButtonBinderMapType::const_iterator it = mControlsJoystickButtonBinderMap[evt.device->getID()].find(button); - if(it != mControlsJoystickButtonBinderMap[evt.device->getID()].end()) + ControlsButtonBinderMapType::const_iterator it = mControlsJoystickButtonBinderMap[evt.which].find(button); + if(it != mControlsJoystickButtonBinderMap[evt.which].end()) { it->second.control->setChangingDirection(Control::STOP); } @@ -371,31 +374,29 @@ namespace ICS return true; } - bool InputControlSystem::axisMoved(const OIS::JoyStickEvent &evt, int axis) - { + bool InputControlSystem::axisMoved(const SDL_JoyAxisEvent &evt, int axis) + { if(mActive) { if(!mDetectingBindingControl) { - if(mControlsJoystickAxisBinderMap.find(evt.device->getID()) != mControlsJoystickAxisBinderMap.end()) + if(mControlsJoystickAxisBinderMap.find(evt.which) != mControlsJoystickAxisBinderMap.end()) { - ControlAxisBinderItem joystickBinderItem = mControlsJoystickAxisBinderMap[ evt.device->getID() ][ axis ]; // joystic axis start at 0 index + ControlAxisBinderItem joystickBinderItem = mControlsJoystickAxisBinderMap[ evt.which ][ axis ]; // joystic axis start at 0 index Control* ctrl = joystickBinderItem.control; if(ctrl) { ctrl->setIgnoreAutoReverse(true); + + float axisRange = SDL_JOY_AXIS_MAX - SDL_JOY_AXIS_MAX; + float valDisplaced = (float)(evt.value - SDL_JOY_AXIS_MIN); + if(joystickBinderItem.direction == Control::INCREASE) { - float axisRange = OIS::JoyStick::MAX_AXIS - OIS::JoyStick::MIN_AXIS; - float valDisplaced = (float)( evt.state.mAxes[axis].abs - OIS::JoyStick::MIN_AXIS); - ctrl->setValue( valDisplaced / axisRange ); } else if(joystickBinderItem.direction == Control::DECREASE) { - float axisRange = OIS::JoyStick::MAX_AXIS - OIS::JoyStick::MIN_AXIS; - float valDisplaced = (float)(evt.state.mAxes[axis].abs - OIS::JoyStick::MIN_AXIS); - ctrl->setValue( 1 - ( valDisplaced / axisRange ) ); } } @@ -403,15 +404,15 @@ namespace ICS } else if(mDetectingBindingListener) { - //ControlAxisBinderItem joystickBinderItem = mControlsJoystickAxisBinderMap[ evt.device->getID() ][ axis ]; // joystic axis start at 0 index + //ControlAxisBinderItem joystickBinderItem = mControlsJoystickAxisBinderMap[ evt.which ][ axis ]; // joystic axis start at 0 index //Control* ctrl = joystickBinderItem.control; //if(ctrl && ctrl->isAxisBindable()) if(mDetectingBindingControl && mDetectingBindingControl->isAxisBindable()) { - if( abs( evt.state.mAxes[axis].abs ) > ICS_JOYSTICK_AXIS_BINDING_MARGIN) + if( abs( evt.value ) > ICS_JOYSTICK_AXIS_BINDING_MARGIN) { mDetectingBindingListener->joystickAxisBindingDetected(this, - mDetectingBindingControl, evt.device->getID(), axis, mDetectingBindingDirection); + mDetectingBindingControl, evt.which, axis, mDetectingBindingDirection); } } } @@ -420,20 +421,21 @@ namespace ICS return true; } - bool InputControlSystem::povMoved(const OIS::JoyStickEvent &evt, int index) - { + //Here be dragons, apparently + bool InputControlSystem::povMoved(const SDL_JoyHatEvent &evt, int index) + { if(mActive) { if(!mDetectingBindingControl) { - if(mControlsJoystickPOVBinderMap.find(evt.device->getID()) != mControlsJoystickPOVBinderMap.end()) + if(mControlsJoystickPOVBinderMap.find(evt.which) != mControlsJoystickPOVBinderMap.end()) { - std::map::const_iterator i = mControlsJoystickPOVBinderMap[ evt.device->getID() ].find(index); - if(i != mControlsJoystickPOVBinderMap[ evt.device->getID() ].end()) + std::map::const_iterator i = mControlsJoystickPOVBinderMap[ evt.which ].find(index); + if(i != mControlsJoystickPOVBinderMap[ evt.which ].end()) { - if(evt.state.mPOV[index].direction != OIS::Pov::West - && evt.state.mPOV[index].direction != OIS::Pov::East - && evt.state.mPOV[index].direction != OIS::Pov::Centered) + if(evt.value != SDL_HAT_LEFT + && evt.value != SDL_HAT_RIGHT + && evt.value != SDL_HAT_CENTERED) { ControlsPOVBinderMapType::const_iterator it = i->second.find( /*POVAxis::*/NorthSouth ); if(it != i->second.end()) @@ -441,9 +443,9 @@ namespace ICS it->second.control->setIgnoreAutoReverse(false); if(!it->second.control->getAutoChangeDirectionOnLimitsAfterStop()) { - if(evt.state.mPOV[index].direction == OIS::Pov::North - || evt.state.mPOV[index].direction == OIS::Pov::NorthWest - || evt.state.mPOV[index].direction == OIS::Pov::NorthEast) + if(evt.value == SDL_HAT_UP + || evt.value == SDL_HAT_LEFTUP + || evt.value == SDL_HAT_RIGHTUP) { it->second.control->setChangingDirection(it->second.direction); } @@ -453,7 +455,7 @@ namespace ICS } } else - { + { if(it->second.control->getValue() == 1) { it->second.control->setChangingDirection(Control::DECREASE); @@ -466,9 +468,9 @@ namespace ICS } } - if(evt.state.mPOV[index].direction != OIS::Pov::North - && evt.state.mPOV[index].direction != OIS::Pov::South - && evt.state.mPOV[index].direction != OIS::Pov::Centered) + if(evt.value != SDL_HAT_UP + && evt.value != SDL_HAT_DOWN + && evt.value != SDL_HAT_CENTERED) { ControlsPOVBinderMapType::const_iterator it = i->second.find( /*POVAxis::*/EastWest ); if(it != i->second.end()) @@ -476,9 +478,9 @@ namespace ICS it->second.control->setIgnoreAutoReverse(false); if(!it->second.control->getAutoChangeDirectionOnLimitsAfterStop()) { - if(evt.state.mPOV[index].direction == OIS::Pov::East - || evt.state.mPOV[index].direction == OIS::Pov::NorthEast - || evt.state.mPOV[index].direction == OIS::Pov::SouthEast) + if(evt.value == SDL_HAT_RIGHT + || evt.value == SDL_HAT_RIGHTUP + || evt.value == SDL_HAT_RIGHTDOWN) { it->second.control->setChangingDirection(it->second.direction); } @@ -488,7 +490,7 @@ namespace ICS } } else - { + { if(it->second.control->getValue() == 1) { it->second.control->setChangingDirection(Control::DECREASE); @@ -501,7 +503,7 @@ namespace ICS } } - if(evt.state.mPOV[index].direction == OIS::Pov::Centered) + if(evt.value == SDL_HAT_CENTERED) { ControlsPOVBinderMapType::const_iterator it = i->second.find( /*POVAxis::*/NorthSouth ); if(it != i->second.end()) @@ -522,28 +524,30 @@ namespace ICS { if(mDetectingBindingControl && mDetectingBindingControl->isAxisBindable()) { - if(evt.state.mPOV[index].direction == OIS::Pov::West - || evt.state.mPOV[index].direction == OIS::Pov::East - || evt.state.mPOV[index].direction == OIS::Pov::North - || evt.state.mPOV[index].direction == OIS::Pov::South) + if(evt.value == SDL_HAT_LEFT + || evt.value == SDL_HAT_RIGHT + || evt.value == SDL_HAT_UP + || evt.value == SDL_HAT_DOWN) { POVAxis povAxis = NorthSouth; - if(evt.state.mPOV[index].direction == OIS::Pov::West - || evt.state.mPOV[index].direction == OIS::Pov::East) + if(evt.value == SDL_HAT_LEFT + || evt.value == SDL_HAT_RIGHT) { povAxis = EastWest; } mDetectingBindingListener->joystickPOVBindingDetected(this, - mDetectingBindingControl, evt.device->getID(), index, povAxis, mDetectingBindingDirection); + mDetectingBindingControl, evt.which, index, povAxis, mDetectingBindingDirection); } } } } - + return true; } + //TODO: does this have an SDL equivalent? + /* bool InputControlSystem::sliderMoved(const OIS::JoyStickEvent &evt, int index) { if(mActive) @@ -552,7 +556,7 @@ namespace ICS { if(mControlsJoystickSliderBinderMap.find(evt.device->getID()) != mControlsJoystickSliderBinderMap.end()) { - ControlSliderBinderItem joystickBinderItem = mControlsJoystickSliderBinderMap[ evt.device->getID() ][ index ]; + ControlSliderBinderItem joystickBinderItem = mControlsJoystickSliderBinderMap[ evt.device->getID() ][ index ]; Control* ctrl = joystickBinderItem.control; if(ctrl) { @@ -576,10 +580,6 @@ namespace ICS } else if(mDetectingBindingListener) { - /*ControlSliderBinderItem joystickBinderItem = mControlsJoystickSliderBinderMap[ evt.device->getID() ][ index ]; - Control* ctrl = joystickBinderItem.control; - if(ctrl && ctrl->isAxisBindable()) - {*/ if(mDetectingBindingControl && mDetectingBindingControl->isAxisBindable()) { if( abs( evt.state.mSliders[index].abX ) > ICS_JOYSTICK_SLIDER_BINDING_MARGIN) @@ -593,6 +593,7 @@ namespace ICS return true; } + */ // joystick auto bindings void DetectingBindingListener::joystickAxisBindingDetected(InputControlSystem* ICS, Control* control @@ -662,4 +663,4 @@ namespace ICS ICS->addJoystickSliderBinding(control, deviceId, slider, direction); ICS->cancelDetectingBindingState(); } -} \ No newline at end of file +} diff --git a/extern/oics/ICSInputControlSystem_keyboard.cpp b/extern/oics/ICSInputControlSystem_keyboard.cpp index 8ef81d9794..01d68f7843 100644 --- a/extern/oics/ICSInputControlSystem_keyboard.cpp +++ b/extern/oics/ICSInputControlSystem_keyboard.cpp @@ -49,7 +49,7 @@ namespace ICS } } - void InputControlSystem::addKeyBinding(Control* control, OIS::KeyCode key, Control::ControlChangingDirection direction) + void InputControlSystem::addKeyBinding(Control* control, SDL_Keycode key, Control::ControlChangingDirection direction) { ICS_LOG("\tAdding KeyBinder [key=" + keyCodeToString(key) + ", direction=" @@ -61,7 +61,7 @@ namespace ICS mControlsKeyBinderMap[ key ] = controlKeyBinderItem; } - void InputControlSystem::removeKeyBinding(OIS::KeyCode key) + void InputControlSystem::removeKeyBinding(SDL_Keycode key) { ControlsKeyBinderMapType::iterator it = mControlsKeyBinderMap.find(key); if(it != mControlsKeyBinderMap.end()) @@ -70,7 +70,7 @@ namespace ICS } } - OIS::KeyCode InputControlSystem::getKeyBinding(Control* control + SDL_Keycode InputControlSystem::getKeyBinding(Control* control , ICS::Control::ControlChangingDirection direction) { ControlsKeyBinderMapType::iterator it = mControlsKeyBinderMap.begin(); @@ -83,15 +83,15 @@ namespace ICS it++; } - return OIS::KC_UNASSIGNED; + return SDLK_UNKNOWN; } - bool InputControlSystem::keyPressed(const OIS::KeyEvent &evt) + bool InputControlSystem::keyPressed(const SDL_KeyboardEvent &evt) { if(mActive) { if(!mDetectingBindingControl) { - ControlsKeyBinderMapType::const_iterator it = mControlsKeyBinderMap.find(evt.key); + ControlsKeyBinderMapType::const_iterator it = mControlsKeyBinderMap.find(evt.keysym.sym); if(it != mControlsKeyBinderMap.end()) { it->second.control->setIgnoreAutoReverse(false); @@ -115,18 +115,18 @@ namespace ICS else if(mDetectingBindingListener) { mDetectingBindingListener->keyBindingDetected(this, - mDetectingBindingControl, evt.key, mDetectingBindingDirection); + mDetectingBindingControl, evt.keysym.sym, mDetectingBindingDirection); } } return true; } - bool InputControlSystem::keyReleased(const OIS::KeyEvent &evt) + bool InputControlSystem::keyReleased(const SDL_KeyboardEvent &evt) { if(mActive) { - ControlsKeyBinderMapType::const_iterator it = mControlsKeyBinderMap.find(evt.key); + ControlsKeyBinderMapType::const_iterator it = mControlsKeyBinderMap.find(evt.keysym.sym); if(it != mControlsKeyBinderMap.end()) { it->second.control->setChangingDirection(Control::STOP); @@ -137,14 +137,14 @@ namespace ICS } void DetectingBindingListener::keyBindingDetected(InputControlSystem* ICS, Control* control - , OIS::KeyCode key, Control::ControlChangingDirection direction) + , SDL_Keycode key, Control::ControlChangingDirection direction) { // if the key is used by another control, remove it ICS->removeKeyBinding(key); // if the control has a key assigned, remove it - OIS::KeyCode oldKey = ICS->getKeyBinding(control, direction); - if(oldKey != OIS::KC_UNASSIGNED) + SDL_Keycode oldKey = ICS->getKeyBinding(control, direction); + if(oldKey != SDLK_UNKNOWN) { ICS->removeKeyBinding(oldKey); } @@ -153,4 +153,4 @@ namespace ICS ICS->cancelDetectingBindingState(); } -} \ No newline at end of file +} diff --git a/extern/oics/ICSInputControlSystem_mouse.cpp b/extern/oics/ICSInputControlSystem_mouse.cpp index c62f1765e6..96197426a9 100644 --- a/extern/oics/ICSInputControlSystem_mouse.cpp +++ b/extern/oics/ICSInputControlSystem_mouse.cpp @@ -78,15 +78,15 @@ namespace ICS int button = 0; if(std::string(xmlMouseButtonBinder->Attribute("button")) == "LEFT") { - button = OIS::/*MouseButtonID::*/MB_Left; + button = SDL_BUTTON_LEFT; } else if(std::string(xmlMouseButtonBinder->Attribute("button")) == "RIGHT") { - button = OIS::/*MouseButtonID::*/MB_Right; + button = SDL_BUTTON_RIGHT; } else if(std::string(xmlMouseButtonBinder->Attribute("button")) == "MIDDLE") { - button = OIS::/*MouseButtonID::*/MB_Middle; + button = SDL_BUTTON_MIDDLE; } else { @@ -219,39 +219,39 @@ namespace ICS } // mouse Listeners - bool InputControlSystem::mouseMoved(const OIS::MouseEvent &evt) + bool InputControlSystem::mouseMoved(const MWSDLMouseMotionEvent& evt) { if(mActive) { if(!mDetectingBindingControl) { - if(mXmouseAxisBinded && evt.state.X.rel) + if(mXmouseAxisBinded && evt.xrel) { ControlAxisBinderItem mouseBinderItem = mControlsMouseAxisBinderMap[ /*NamedAxis::*/X ]; Control* ctrl = mouseBinderItem.control; ctrl->setIgnoreAutoReverse(true); if(mouseBinderItem.direction == Control::INCREASE) { - ctrl->setValue( float( (evt.state.X.abs) / float(evt.state.width) ) ); + ctrl->setValue( float( (evt.x) / float(mClientWidth) ) ); } else if(mouseBinderItem.direction == Control::DECREASE) { - ctrl->setValue( 1 - float( evt.state.X.abs / float(evt.state.width) ) ); + ctrl->setValue( 1 - float( evt.x / float(mClientWidth) ) ); } } - if(mYmouseAxisBinded && evt.state.Y.rel) + if(mYmouseAxisBinded && evt.yrel) { ControlAxisBinderItem mouseBinderItem = mControlsMouseAxisBinderMap[ /*NamedAxis::*/Y ]; Control* ctrl = mouseBinderItem.control; ctrl->setIgnoreAutoReverse(true); if(mouseBinderItem.direction == Control::INCREASE) { - ctrl->setValue( float( (evt.state.Y.abs) / float(evt.state.height) ) ); + ctrl->setValue( float( (evt.y) / float(mClientHeight) ) ); } else if(mouseBinderItem.direction == Control::DECREASE) { - ctrl->setValue( 1 - float( evt.state.Y.abs / float(evt.state.height) ) ); + ctrl->setValue( 1 - float( evt.y / float(mClientHeight) ) ); } } @@ -282,9 +282,9 @@ namespace ICS mMouseAxisBindingInitialValues[2] = 0; } - mMouseAxisBindingInitialValues[0] += evt.state.X.rel; - mMouseAxisBindingInitialValues[1] += evt.state.Y.rel; - mMouseAxisBindingInitialValues[2] += evt.state.Z.rel; + mMouseAxisBindingInitialValues[0] += evt.xrel; + mMouseAxisBindingInitialValues[1] += evt.yrel; + mMouseAxisBindingInitialValues[2] += evt.zrel; if( abs(mMouseAxisBindingInitialValues[0]) > ICS_MOUSE_BINDING_MARGIN ) { @@ -308,7 +308,7 @@ namespace ICS return true; } - bool InputControlSystem::mousePressed(const OIS::MouseEvent &evt, OIS::MouseButtonID btn) + bool InputControlSystem::mousePressed(const SDL_MouseButtonEvent &evt, Uint8 btn) { if(mActive) { @@ -345,7 +345,7 @@ namespace ICS return true; } - bool InputControlSystem::mouseReleased(const OIS::MouseEvent &evt, OIS::MouseButtonID btn) + bool InputControlSystem::mouseReleased(const SDL_MouseButtonEvent &evt, Uint8 btn) { if(mActive) { @@ -394,4 +394,4 @@ namespace ICS ICS->cancelDetectingBindingState(); } -} \ No newline at end of file +} diff --git a/extern/oics/ICSPrerequisites.h b/extern/oics/ICSPrerequisites.h index 3b5d1935b4..82c95c86ab 100644 --- a/extern/oics/ICSPrerequisites.h +++ b/extern/oics/ICSPrerequisites.h @@ -39,11 +39,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "tinyxml.h" -#include -#include -#include -#include -#include +#include "SDL2/SDL_input.h" +#include "SDL2/SDL_keyboard.h" +#include "SDL2/SDL_mouse.h" +#include "SDL2/SDL_joystick.h" +#include "SDL2/SDL_events.h" /// Define the dll export qualifier if compiling for Windows @@ -65,8 +65,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /// Version defines #define ICS_VERSION_MAJOR 0 -#define ICS_VERSION_MINOR 3 -#define ICS_VERSION_PATCH 1 +#define ICS_VERSION_MINOR 4 +#define ICS_VERSION_PATCH 0 #define ICS_MAX_DEVICE_BUTTONS 30 diff --git a/extern/oics/OISCompat.h b/extern/oics/OISCompat.h new file mode 100644 index 0000000000..18bdd6bae0 --- /dev/null +++ b/extern/oics/OISCompat.h @@ -0,0 +1,90 @@ +#ifndef _OIS_SDL_COMPAT_H +#define _OIS_SDL_COMPAT_H + +#include +#include + +//TODO: Remove this. Right now we want to remain as close to OIS as possible +//So we can easily test the SDL backend + +//////////// +// Events // +//////////// + +namespace ICS { + +/** Extended mouse event struct where we treat the wheel like an axis, like everyone expects */ +struct MWSDLMouseMotionEvent : SDL_MouseMotionEvent { + + Sint16 zrel; + + MWSDLMouseMotionEvent() + { + x = 0; + y = 0; + xrel = 0; + yrel = 0; + state = 0; + zrel = 0; + } + + MWSDLMouseMotionEvent( const SDL_MouseMotionEvent& evt) : + MWSDLMouseMotionEvent() + { + x = evt.x; + y = evt.y; + xrel = evt.xrel; + yrel = evt.yrel; + state = evt.state; + } + + MWSDLMouseMotionEvent (const SDL_MouseWheelEvent& evt) : + MWSDLMouseMotionEvent() + { + zrel = evt.y; + } +}; + + +/////////////// +// Listeners // +/////////////// + +class MWSDLMouseListener +{ +public: + virtual ~MWSDLMouseListener() {} + virtual bool mouseMoved( const MWSDLMouseMotionEvent &arg ) = 0; + virtual bool mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id ) = 0; + virtual bool mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id ) = 0; +}; + +class MWSDLKeyListener +{ +public: + virtual ~MWSDLKeyListener() {} + virtual bool keyPressed(const SDL_KeyboardEvent &arg) = 0; + virtual bool keyReleased(const SDL_KeyboardEvent &arg) = 0; +}; + +class MWSDLJoyStickListener +{ +public: + virtual ~MWSDLJoyStickListener() {} + /** @remarks Joystick button down event */ + virtual bool buttonPressed( const SDL_JoyButtonEvent &evt, int button ) = 0; + + /** @remarks Joystick button up event */ + virtual bool buttonReleased( const SDL_JoyButtonEvent &evt, int button ) = 0; + + /** @remarks Joystick axis moved event */ + virtual bool axisMoved( const SDL_JoyAxisEvent &arg, int axis ) = 0; + + //-- Not so common control events, so are not required --// + + //! Joystick Event, and povID + virtual bool povMoved( const SDL_JoyHatEvent &arg, int index) {return true;} +}; + +} +#endif