diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index d907091bd..34824ea33 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -25,7 +25,8 @@ add_openmw_dir (mwrender ) add_openmw_dir (mwinput - actions actionmanager controllermanager controlswitch inputmanagerimp mousemanager keyboardmanager sdlmappings sensormanager + actions actionmanager bindingsmanager controllermanager controlswitch + inputmanagerimp mousemanager keyboardmanager sdlmappings sensormanager ) add_openmw_dir (mwgui diff --git a/apps/openmw/mwbase/inputmanager.hpp b/apps/openmw/mwbase/inputmanager.hpp index 601dd90e5..932463e97 100644 --- a/apps/openmw/mwbase/inputmanager.hpp +++ b/apps/openmw/mwbase/inputmanager.hpp @@ -46,6 +46,7 @@ namespace MWBase virtual void setDragDrop(bool dragDrop) = 0; virtual void setGamepadGuiCursorEnabled(bool enabled) = 0; + virtual void setAttemptJump(bool jumping) = 0; virtual void toggleControlSwitch (const std::string& sw, bool value) = 0; virtual bool getControlSwitch (const std::string& sw) = 0; @@ -72,9 +73,9 @@ namespace MWBase virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress) = 0; virtual void readRecord(ESM::ESMReader& reader, uint32_t type) = 0; - virtual void setPlayerControlsEnabled(bool enabled) = 0; - virtual void resetIdleTime() = 0; + + virtual void executeAction(int action) = 0; }; } diff --git a/apps/openmw/mwinput/actionmanager.cpp b/apps/openmw/mwinput/actionmanager.cpp index 2240e7556..e90a4ddaf 100644 --- a/apps/openmw/mwinput/actionmanager.cpp +++ b/apps/openmw/mwinput/actionmanager.cpp @@ -4,8 +4,6 @@ #include -#include - #include #include "../mwbase/inputmanager.hpp" @@ -24,17 +22,17 @@ #include "../mwmechanics/actorutil.hpp" #include "actions.hpp" +#include "bindingsmanager.hpp" namespace MWInput { const float ZOOM_SCALE = 120.f; /// Used for scrolling camera in and out - const int fakeDeviceID = 1; - ActionManager::ActionManager(ICS::InputControlSystem* inputBinder, + ActionManager::ActionManager(BindingsManager* bindingsManager, osgViewer::ScreenCaptureHandler::CaptureOperation* screenCaptureOperation, osg::ref_ptr viewer, osg::ref_ptr screenCaptureHandler) - : mInputBinder(inputBinder) + : mBindingsManager(bindingsManager) , mViewer(viewer) , mScreenCaptureHandler(screenCaptureHandler) , mScreenCaptureOperation(screenCaptureOperation) @@ -65,19 +63,19 @@ namespace MWInput MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); - if (actionIsActive(A_MoveLeft) != actionIsActive(A_MoveRight)) + if (mBindingsManager->actionIsActive(A_MoveLeft) != mBindingsManager->actionIsActive(A_MoveRight)) { alwaysRunAllowed = true; triedToMove = true; - player.setLeftRight (actionIsActive(A_MoveRight) ? 1 : -1); + player.setLeftRight(mBindingsManager->actionIsActive(A_MoveRight) ? 1 : -1); } - if (actionIsActive(A_MoveForward) != actionIsActive(A_MoveBackward)) + if (mBindingsManager->actionIsActive(A_MoveForward) != mBindingsManager->actionIsActive(A_MoveBackward)) { alwaysRunAllowed = true; triedToMove = true; player.setAutoMove (false); - player.setForwardBackward (actionIsActive(A_MoveForward) ? 1 : -1); + player.setForwardBackward(mBindingsManager->actionIsActive(A_MoveForward) ? 1 : -1); } if (player.getAutoMove()) @@ -112,7 +110,7 @@ namespace MWInput if (MWBase::Environment::get().getInputManager()->getControlSwitch("playerviewswitch")) { - if (actionIsActive(A_TogglePOV)) + if (mBindingsManager->actionIsActive(A_TogglePOV)) { if (mPreviewPOVDelay <= 0.5 && (mPreviewPOVDelay += dt) > 0.5) @@ -140,27 +138,27 @@ namespace MWInput if (!isToggleSneak) { if(!MWBase::Environment::get().getInputManager()->joystickLastUsed()) - player.setSneak(actionIsActive(A_Sneak)); + player.setSneak(mBindingsManager->actionIsActive(A_Sneak)); } - float xAxis = mInputBinder->getChannel(A_MoveLeftRight)->getValue(); - float yAxis = mInputBinder->getChannel(A_MoveForwardBackward)->getValue(); + float xAxis = mBindingsManager->getActionValue(A_MoveLeftRight); + float yAxis = mBindingsManager->getActionValue(A_MoveForwardBackward); bool isRunning = xAxis > .75 || xAxis < .25 || yAxis > .75 || yAxis < .25; if ((mAlwaysRunActive && alwaysRunAllowed) || isRunning) - player.setRunState(!actionIsActive(A_Run)); + player.setRunState(!mBindingsManager->actionIsActive(A_Run)); else - player.setRunState(actionIsActive(A_Run)); + player.setRunState(mBindingsManager->actionIsActive(A_Run)); } - if (actionIsActive(A_MoveForward) || - actionIsActive(A_MoveBackward) || - actionIsActive(A_MoveLeft) || - actionIsActive(A_MoveRight) || - actionIsActive(A_Jump) || - actionIsActive(A_Sneak) || - actionIsActive(A_TogglePOV) || - actionIsActive(A_ZoomIn) || - actionIsActive(A_ZoomOut)) + if (mBindingsManager->actionIsActive(A_MoveForward) || + mBindingsManager->actionIsActive(A_MoveBackward) || + mBindingsManager->actionIsActive(A_MoveLeft) || + mBindingsManager->actionIsActive(A_MoveRight) || + mBindingsManager->actionIsActive(A_Jump) || + mBindingsManager->actionIsActive(A_Sneak) || + mBindingsManager->actionIsActive(A_TogglePOV) || + mBindingsManager->actionIsActive(A_ZoomIn) || + mBindingsManager->actionIsActive(A_ZoomOut)) { resetIdleTime(); } @@ -192,11 +190,6 @@ namespace MWInput } } - bool ActionManager::actionIsActive(int id) - { - return (mInputBinder->getChannel(id)->getValue ()==1.0); - } - void ActionManager::executeAction(int action) { // trigger action activated @@ -321,17 +314,6 @@ namespace MWInput } } - bool isLeftOrRightButton(int action, ICS::InputControlSystem* ics, int deviceId, bool joystick) - { - int mouseBinding = ics->getMouseButtonBinding(ics->getControl(action), ICS::Control::INCREASE); - if (mouseBinding != ICS_MAX_DEVICE_BUTTONS) - return true; - int buttonBinding = ics->getJoystickButtonBinding(ics->getControl(action), deviceId, ICS::Control::INCREASE); - if (joystick && (buttonBinding == 0 || buttonBinding == 1)) - return true; - return false; - } - bool ActionManager::checkAllowedToUseItems() const { MWWorld::Ptr player = MWMechanics::getPlayer(); @@ -559,7 +541,7 @@ namespace MWInput if (MWBase::Environment::get().getWindowManager()->isGuiMode()) { bool joystickUsed = MWBase::Environment::get().getInputManager()->joystickLastUsed(); - if (!SDL_IsTextInputActive() && !isLeftOrRightButton(A_Activate, mInputBinder, fakeDeviceID, joystickUsed)) + if (!SDL_IsTextInputActive() && !mBindingsManager->isLeftOrRightButton(A_Activate, joystickUsed)) MWBase::Environment::get().getWindowManager()->injectKeyPress(MyGUI::KeyCode::Return, 0, false); } else if (MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) @@ -612,7 +594,7 @@ namespace MWInput if (SDL_IsTextInputActive()) return; - if (isLeftOrRightButton(action, mInputBinder, fakeDeviceID, joystickUsed)) + if (mBindingsManager->isLeftOrRightButton(action, joystickUsed)) return; MyGUI::KeyCode key; diff --git a/apps/openmw/mwinput/actionmanager.hpp b/apps/openmw/mwinput/actionmanager.hpp index 399cb318c..31fd993c9 100644 --- a/apps/openmw/mwinput/actionmanager.hpp +++ b/apps/openmw/mwinput/actionmanager.hpp @@ -4,11 +4,6 @@ #include #include -namespace ICS -{ - class InputControlSystem; -} - namespace osgViewer { class Viewer; @@ -17,11 +12,13 @@ namespace osgViewer namespace MWInput { + class BindingsManager; + class ActionManager { public: - ActionManager(ICS::InputControlSystem* inputBinder, + ActionManager(BindingsManager* bindingsManager, osgViewer::ScreenCaptureHandler::CaptureOperation* screenCaptureOperation, osg::ref_ptr viewer, osg::ref_ptr screenCaptureHandler); @@ -64,11 +61,9 @@ namespace MWInput private: void handleGuiArrowKey(int action); - bool actionIsActive(int id); - void updateIdleTime(float dt); - ICS::InputControlSystem* mInputBinder; + BindingsManager* mBindingsManager; osg::ref_ptr mViewer; osg::ref_ptr mScreenCaptureHandler; osgViewer::ScreenCaptureHandler::CaptureOperation* mScreenCaptureOperation; diff --git a/apps/openmw/mwinput/bindingsmanager.cpp b/apps/openmw/mwinput/bindingsmanager.cpp new file mode 100644 index 000000000..f871f0c51 --- /dev/null +++ b/apps/openmw/mwinput/bindingsmanager.cpp @@ -0,0 +1,738 @@ +#include "bindingsmanager.hpp" + +#include + +#include +#include + +#include "../mwbase/environment.hpp" +#include "../mwbase/inputmanager.hpp" +#include "../mwbase/windowmanager.hpp" +#include "../mwbase/world.hpp" + +#include "../mwworld/player.hpp" + +#include "actions.hpp" +#include "sdlmappings.hpp" + +namespace MWInput +{ + static const int sFakeDeviceId = 1; //As we only support one controller at a time, use a fake deviceID so we don't lose bindings when switching controllers + + void clearAllKeyBindings(ICS::InputControlSystem* inputBinder, ICS::Control* control) + { + // right now we don't really need multiple bindings for the same action, so remove all others first + if (inputBinder->getKeyBinding(control, ICS::Control::INCREASE) != SDL_SCANCODE_UNKNOWN) + inputBinder->removeKeyBinding(inputBinder->getKeyBinding(control, ICS::Control::INCREASE)); + if (inputBinder->getMouseButtonBinding(control, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS) + inputBinder->removeMouseButtonBinding(inputBinder->getMouseButtonBinding(control, ICS::Control::INCREASE)); + if (inputBinder->getMouseWheelBinding(control, ICS::Control::INCREASE) != ICS::InputControlSystem::MouseWheelClick::UNASSIGNED) + inputBinder->removeMouseWheelBinding(inputBinder->getMouseWheelBinding(control, ICS::Control::INCREASE)); + } + + void clearAllControllerBindings(ICS::InputControlSystem* inputBinder, ICS::Control* control) + { + // right now we don't really need multiple bindings for the same action, so remove all others first + if (inputBinder->getJoystickAxisBinding(control, sFakeDeviceId, ICS::Control::INCREASE) != SDL_SCANCODE_UNKNOWN) + inputBinder->removeJoystickAxisBinding(sFakeDeviceId, inputBinder->getJoystickAxisBinding(control, sFakeDeviceId, ICS::Control::INCREASE)); + if (inputBinder->getJoystickButtonBinding(control, sFakeDeviceId, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS) + inputBinder->removeJoystickButtonBinding(sFakeDeviceId, inputBinder->getJoystickButtonBinding(control, sFakeDeviceId, ICS::Control::INCREASE)); + } + + class InputControlSystem : public ICS::InputControlSystem + { + public: + InputControlSystem(const std::string& bindingsFile) + : ICS::InputControlSystem(bindingsFile, true, nullptr, nullptr, A_Last) + { + } + }; + + class BindingsListener : + public ICS::ChannelListener, + public ICS::DetectingBindingListener + { + public: + BindingsListener(ICS::InputControlSystem* inputBinder, BindingsManager* bindingsManager) + : mInputBinder(inputBinder) + , mBindingsManager(bindingsManager) + , mDetectingKeyboard(false) + { + } + + virtual ~BindingsListener() = default; + + virtual void channelChanged(ICS::Channel* channel, float currentValue, float previousValue) + { + int action = channel->getNumber(); + mBindingsManager->actionValueChanged(action, currentValue, previousValue); + } + + virtual void keyBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control + , SDL_Scancode key, ICS::Control::ControlChangingDirection direction) + { + //Disallow binding escape key + if(key==SDL_SCANCODE_ESCAPE) + { + //Stop binding if esc pressed + mInputBinder->cancelDetectingBindingState(); + MWBase::Environment::get().getWindowManager()->notifyInputActionBound(); + return; + } + + // Disallow binding reserved keys + if (key == SDL_SCANCODE_F3 || key == SDL_SCANCODE_F4 || key == SDL_SCANCODE_F10) + return; + + #ifndef __APPLE__ + // Disallow binding Windows/Meta keys + if (key == SDL_SCANCODE_LGUI || key == SDL_SCANCODE_RGUI) + return; + #endif + + if(!mDetectingKeyboard) + return; + + clearAllKeyBindings(mInputBinder, control); + control->setInitialValue(0.0f); + ICS::DetectingBindingListener::keyBindingDetected(ICS, control, key, direction); + MWBase::Environment::get().getWindowManager()->notifyInputActionBound(); + } + + virtual void mouseAxisBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control + , ICS::InputControlSystem::NamedAxis axis, ICS::Control::ControlChangingDirection direction) + { + // we don't want mouse movement bindings + return; + } + + virtual void mouseButtonBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control + , unsigned int button, ICS::Control::ControlChangingDirection direction) + { + if(!mDetectingKeyboard) + return; + clearAllKeyBindings(mInputBinder, control); + control->setInitialValue(0.0f); + ICS::DetectingBindingListener::mouseButtonBindingDetected(ICS, control, button, direction); + MWBase::Environment::get().getWindowManager()->notifyInputActionBound(); + } + + virtual void mouseWheelBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control + , ICS::InputControlSystem::MouseWheelClick click, ICS::Control::ControlChangingDirection direction) + { + if(!mDetectingKeyboard) + return; + clearAllKeyBindings(mInputBinder, control); + control->setInitialValue(0.0f); + ICS::DetectingBindingListener::mouseWheelBindingDetected(ICS, control, click, direction); + MWBase::Environment::get().getWindowManager()->notifyInputActionBound(); + } + + virtual void joystickAxisBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control + , int axis, ICS::Control::ControlChangingDirection direction) + { + //only allow binding to the trigers + if(axis != SDL_CONTROLLER_AXIS_TRIGGERLEFT && axis != SDL_CONTROLLER_AXIS_TRIGGERRIGHT) + return; + if(mDetectingKeyboard) + return; + + clearAllControllerBindings(mInputBinder, control); + control->setValue(0.5f); //axis bindings must start at 0.5 + control->setInitialValue(0.5f); + ICS::DetectingBindingListener::joystickAxisBindingDetected(ICS, deviceID, control, axis, direction); + MWBase::Environment::get().getWindowManager()->notifyInputActionBound(); + } + + virtual void joystickButtonBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control + , unsigned int button, ICS::Control::ControlChangingDirection direction) + { + if(mDetectingKeyboard) + return; + clearAllControllerBindings(mInputBinder,control); + control->setInitialValue(0.0f); + ICS::DetectingBindingListener::joystickButtonBindingDetected (ICS, deviceID, control, button, direction); + MWBase::Environment::get().getWindowManager()->notifyInputActionBound(); + } + + void setDetectingKeyboard(bool detecting) + { + mDetectingKeyboard = detecting; + } + + private: + ICS::InputControlSystem* mInputBinder; + BindingsManager* mBindingsManager; + bool mDetectingKeyboard; + }; + + BindingsManager::BindingsManager(const std::string& userFile, bool userFileExists) + : mUserFile(userFile) + , mDragDrop(false) + { + std::string file = userFileExists ? userFile : ""; + mInputBinder = new InputControlSystem(file); + mListener = new BindingsListener(mInputBinder, this); + mInputBinder->setDetectingBindingListener(mListener); + + loadKeyDefaults(); + loadControllerDefaults(); + + for (int i = 0; i < A_Last; ++i) + { + mInputBinder->getChannel(i)->addListener(mListener); + } + } + + void BindingsManager::setDragDrop(bool dragDrop) + { + mDragDrop = dragDrop; + } + + BindingsManager::~BindingsManager() + { + mInputBinder->save(mUserFile); + delete mInputBinder; + } + + void BindingsManager::update(float dt) + { + // update values of channels (as a result of pressed keys) + mInputBinder->update(dt); + } + + bool BindingsManager::isLeftOrRightButton(int action, bool joystick) const + { + int mouseBinding = mInputBinder->getMouseButtonBinding(mInputBinder->getControl(action), ICS::Control::INCREASE); + if (mouseBinding != ICS_MAX_DEVICE_BUTTONS) + return true; + int buttonBinding = mInputBinder->getJoystickButtonBinding(mInputBinder->getControl(action), sFakeDeviceId, ICS::Control::INCREASE); + if (joystick && (buttonBinding == 0 || buttonBinding == 1)) + return true; + return false; + } + + void BindingsManager::setPlayerControlsEnabled(bool enabled) + { + int playerChannels[] = {A_AutoMove, A_AlwaysRun, A_ToggleWeapon, + A_ToggleSpell, A_Rest, A_QuickKey1, A_QuickKey2, + A_QuickKey3, A_QuickKey4, A_QuickKey5, A_QuickKey6, + A_QuickKey7, A_QuickKey8, A_QuickKey9, A_QuickKey10, + A_Use, A_Journal}; + + for(size_t i = 0; i < sizeof(playerChannels)/sizeof(playerChannels[0]); i++) { + int pc = playerChannels[i]; + mInputBinder->getChannel(pc)->setEnabled(enabled); + } + } + + float BindingsManager::getActionValue (int id) const + { + return mInputBinder->getChannel(id)->getValue(); + } + + bool BindingsManager::actionIsActive (int id) const + { + return getActionValue(id) == 1.0; + } + + void BindingsManager::loadKeyDefaults (bool force) + { + // using hardcoded key defaults is inevitable, if we want the configuration files to stay valid + // across different versions of OpenMW (in the case where another input action is added) + std::map defaultKeyBindings; + + //Gets the Keyvalue from the Scancode; gives the button in the same place reguardless of keyboard format + defaultKeyBindings[A_Activate] = SDL_SCANCODE_SPACE; + defaultKeyBindings[A_MoveBackward] = SDL_SCANCODE_S; + defaultKeyBindings[A_MoveForward] = SDL_SCANCODE_W; + defaultKeyBindings[A_MoveLeft] = SDL_SCANCODE_A; + defaultKeyBindings[A_MoveRight] = SDL_SCANCODE_D; + defaultKeyBindings[A_ToggleWeapon] = SDL_SCANCODE_F; + defaultKeyBindings[A_ToggleSpell] = SDL_SCANCODE_R; + defaultKeyBindings[A_CycleSpellLeft] = SDL_SCANCODE_MINUS; + defaultKeyBindings[A_CycleSpellRight] = SDL_SCANCODE_EQUALS; + defaultKeyBindings[A_CycleWeaponLeft] = SDL_SCANCODE_LEFTBRACKET; + defaultKeyBindings[A_CycleWeaponRight] = SDL_SCANCODE_RIGHTBRACKET; + + defaultKeyBindings[A_QuickKeysMenu] = SDL_SCANCODE_F1; + defaultKeyBindings[A_Console] = SDL_SCANCODE_GRAVE; + defaultKeyBindings[A_Run] = SDL_SCANCODE_LSHIFT; + defaultKeyBindings[A_Sneak] = SDL_SCANCODE_LCTRL; + defaultKeyBindings[A_AutoMove] = SDL_SCANCODE_Q; + defaultKeyBindings[A_Jump] = SDL_SCANCODE_E; + defaultKeyBindings[A_Journal] = SDL_SCANCODE_J; + defaultKeyBindings[A_Rest] = SDL_SCANCODE_T; + defaultKeyBindings[A_GameMenu] = SDL_SCANCODE_ESCAPE; + defaultKeyBindings[A_TogglePOV] = SDL_SCANCODE_TAB; + defaultKeyBindings[A_QuickKey1] = SDL_SCANCODE_1; + defaultKeyBindings[A_QuickKey2] = SDL_SCANCODE_2; + defaultKeyBindings[A_QuickKey3] = SDL_SCANCODE_3; + defaultKeyBindings[A_QuickKey4] = SDL_SCANCODE_4; + defaultKeyBindings[A_QuickKey5] = SDL_SCANCODE_5; + defaultKeyBindings[A_QuickKey6] = SDL_SCANCODE_6; + defaultKeyBindings[A_QuickKey7] = SDL_SCANCODE_7; + defaultKeyBindings[A_QuickKey8] = SDL_SCANCODE_8; + defaultKeyBindings[A_QuickKey9] = SDL_SCANCODE_9; + defaultKeyBindings[A_QuickKey10] = SDL_SCANCODE_0; + defaultKeyBindings[A_Screenshot] = SDL_SCANCODE_F12; + defaultKeyBindings[A_ToggleHUD] = SDL_SCANCODE_F11; + defaultKeyBindings[A_ToggleDebug] = SDL_SCANCODE_F10; + defaultKeyBindings[A_AlwaysRun] = SDL_SCANCODE_CAPSLOCK; + defaultKeyBindings[A_QuickSave] = SDL_SCANCODE_F5; + defaultKeyBindings[A_QuickLoad] = SDL_SCANCODE_F9; + + std::map defaultMouseButtonBindings; + defaultMouseButtonBindings[A_Inventory] = SDL_BUTTON_RIGHT; + defaultMouseButtonBindings[A_Use] = SDL_BUTTON_LEFT; + + std::map defaultMouseWheelBindings; + defaultMouseWheelBindings[A_ZoomIn] = ICS::InputControlSystem::MouseWheelClick::UP; + defaultMouseWheelBindings[A_ZoomOut] = ICS::InputControlSystem::MouseWheelClick::DOWN; + + for (int i = 0; i < A_Last; ++i) + { + ICS::Control* control; + bool controlExists = mInputBinder->getChannel(i)->getControlsCount () != 0; + if (!controlExists) + { + control = new ICS::Control(std::to_string(i), false, true, 0, ICS::ICS_MAX, ICS::ICS_MAX); + mInputBinder->addControl(control); + control->attachChannel(mInputBinder->getChannel(i), ICS::Channel::DIRECT); + } + else + { + control = mInputBinder->getChannel(i)->getAttachedControls ().front().control; + } + + if (!controlExists || force || + ( mInputBinder->getKeyBinding (control, ICS::Control::INCREASE) == SDL_SCANCODE_UNKNOWN + && mInputBinder->getMouseButtonBinding (control, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS + && mInputBinder->getMouseWheelBinding(control, ICS::Control::INCREASE) == ICS::InputControlSystem::MouseWheelClick::UNASSIGNED + )) + { + clearAllKeyBindings(mInputBinder, control); + + if (defaultKeyBindings.find(i) != defaultKeyBindings.end() + && (force || !mInputBinder->isKeyBound(defaultKeyBindings[i]))) + { + control->setInitialValue(0.0f); + mInputBinder->addKeyBinding(control, defaultKeyBindings[i], ICS::Control::INCREASE); + } + else if (defaultMouseButtonBindings.find(i) != defaultMouseButtonBindings.end() + && (force || !mInputBinder->isMouseButtonBound(defaultMouseButtonBindings[i]))) + { + control->setInitialValue(0.0f); + mInputBinder->addMouseButtonBinding (control, defaultMouseButtonBindings[i], ICS::Control::INCREASE); + } + else if (defaultMouseWheelBindings.find(i) != defaultMouseWheelBindings.end() + && (force || !mInputBinder->isMouseWheelBound(defaultMouseWheelBindings[i]))) + { + control->setInitialValue(0.f); + mInputBinder->addMouseWheelBinding(control, defaultMouseWheelBindings[i], ICS::Control::INCREASE); + } + + if (i == A_LookLeftRight && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_4) && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_6)) + { + mInputBinder->addKeyBinding(control, SDL_SCANCODE_KP_6, ICS::Control::INCREASE); + mInputBinder->addKeyBinding(control, SDL_SCANCODE_KP_4, ICS::Control::DECREASE); + } + if (i == A_LookUpDown && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_8) && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_2)) + { + mInputBinder->addKeyBinding(control, SDL_SCANCODE_KP_2, ICS::Control::INCREASE); + mInputBinder->addKeyBinding(control, SDL_SCANCODE_KP_8, ICS::Control::DECREASE); + } + } + } + } + + void BindingsManager::loadControllerDefaults(bool force) + { + // using hardcoded key defaults is inevitable, if we want the configuration files to stay valid + // across different versions of OpenMW (in the case where another input action is added) + std::map defaultButtonBindings; + + defaultButtonBindings[A_Activate] = SDL_CONTROLLER_BUTTON_A; + defaultButtonBindings[A_ToggleWeapon] = SDL_CONTROLLER_BUTTON_X; + defaultButtonBindings[A_ToggleSpell] = SDL_CONTROLLER_BUTTON_Y; + //defaultButtonBindings[A_QuickButtonsMenu] = SDL_GetButtonFromScancode(SDL_SCANCODE_F1); // Need to implement, should be ToggleSpell(5) AND Wait(9) + defaultButtonBindings[A_Sneak] = SDL_CONTROLLER_BUTTON_LEFTSTICK; + defaultButtonBindings[A_Journal] = SDL_CONTROLLER_BUTTON_LEFTSHOULDER; + defaultButtonBindings[A_Rest] = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER; + defaultButtonBindings[A_TogglePOV] = SDL_CONTROLLER_BUTTON_RIGHTSTICK; + defaultButtonBindings[A_Inventory] = SDL_CONTROLLER_BUTTON_B; + defaultButtonBindings[A_GameMenu] = SDL_CONTROLLER_BUTTON_START; + defaultButtonBindings[A_QuickSave] = SDL_CONTROLLER_BUTTON_GUIDE; + defaultButtonBindings[A_MoveForward] = SDL_CONTROLLER_BUTTON_DPAD_UP; + defaultButtonBindings[A_MoveLeft] = SDL_CONTROLLER_BUTTON_DPAD_LEFT; + defaultButtonBindings[A_MoveBackward] = SDL_CONTROLLER_BUTTON_DPAD_DOWN; + defaultButtonBindings[A_MoveRight] = SDL_CONTROLLER_BUTTON_DPAD_RIGHT; + + std::map defaultAxisBindings; + defaultAxisBindings[A_MoveForwardBackward] = SDL_CONTROLLER_AXIS_LEFTY; + defaultAxisBindings[A_MoveLeftRight] = SDL_CONTROLLER_AXIS_LEFTX; + defaultAxisBindings[A_LookUpDown] = SDL_CONTROLLER_AXIS_RIGHTY; + defaultAxisBindings[A_LookLeftRight] = SDL_CONTROLLER_AXIS_RIGHTX; + defaultAxisBindings[A_Use] = SDL_CONTROLLER_AXIS_TRIGGERRIGHT; + defaultAxisBindings[A_Jump] = SDL_CONTROLLER_AXIS_TRIGGERLEFT; + + for (int i = 0; i < A_Last; i++) + { + ICS::Control* control; + bool controlExists = mInputBinder->getChannel(i)->getControlsCount () != 0; + if (!controlExists) + { + float initial; + if (defaultAxisBindings.find(i) == defaultAxisBindings.end()) + initial = 0.0f; + else initial = 0.5f; + control = new ICS::Control(std::to_string(i), false, true, initial, ICS::ICS_MAX, ICS::ICS_MAX); + mInputBinder->addControl(control); + control->attachChannel(mInputBinder->getChannel(i), ICS::Channel::DIRECT); + } + else + { + control = mInputBinder->getChannel(i)->getAttachedControls ().front().control; + } + + if (!controlExists || force || ( mInputBinder->getJoystickAxisBinding (control, sFakeDeviceId, ICS::Control::INCREASE) == ICS::InputControlSystem::UNASSIGNED && mInputBinder->getJoystickButtonBinding (control, sFakeDeviceId, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS )) + { + clearAllControllerBindings(mInputBinder, control); + + if (defaultButtonBindings.find(i) != defaultButtonBindings.end() + && (force || !mInputBinder->isJoystickButtonBound(sFakeDeviceId, defaultButtonBindings[i]))) + { + control->setInitialValue(0.0f); + mInputBinder->addJoystickButtonBinding(control, sFakeDeviceId, defaultButtonBindings[i], ICS::Control::INCREASE); + } + else if (defaultAxisBindings.find(i) != defaultAxisBindings.end() && (force || !mInputBinder->isJoystickAxisBound(sFakeDeviceId, defaultAxisBindings[i]))) + { + control->setValue(0.5f); + control->setInitialValue(0.5f); + mInputBinder->addJoystickAxisBinding(control, sFakeDeviceId, defaultAxisBindings[i], ICS::Control::INCREASE); + } + } + } + } + + std::string BindingsManager::getActionDescription (int action) + { + std::map descriptions; + + if (action == A_Screenshot) + return "Screenshot"; + else if (action == A_ZoomIn) + return "Zoom In"; + else if (action == A_ZoomOut) + return "Zoom Out"; + else if (action == A_ToggleHUD) + return "Toggle HUD"; + + descriptions[A_Use] = "sUse"; + descriptions[A_Activate] = "sActivate"; + descriptions[A_MoveBackward] = "sBack"; + descriptions[A_MoveForward] = "sForward"; + descriptions[A_MoveLeft] = "sLeft"; + descriptions[A_MoveRight] = "sRight"; + descriptions[A_ToggleWeapon] = "sReady_Weapon"; + descriptions[A_ToggleSpell] = "sReady_Magic"; + descriptions[A_CycleSpellLeft] = "sPrevSpell"; + descriptions[A_CycleSpellRight] = "sNextSpell"; + descriptions[A_CycleWeaponLeft] = "sPrevWeapon"; + descriptions[A_CycleWeaponRight] = "sNextWeapon"; + descriptions[A_Console] = "sConsoleTitle"; + descriptions[A_Run] = "sRun"; + descriptions[A_Sneak] = "sCrouch_Sneak"; + descriptions[A_AutoMove] = "sAuto_Run"; + descriptions[A_Jump] = "sJump"; + descriptions[A_Journal] = "sJournal"; + descriptions[A_Rest] = "sRestKey"; + descriptions[A_Inventory] = "sInventory"; + descriptions[A_TogglePOV] = "sTogglePOVCmd"; + descriptions[A_QuickKeysMenu] = "sQuickMenu"; + descriptions[A_QuickKey1] = "sQuick1Cmd"; + descriptions[A_QuickKey2] = "sQuick2Cmd"; + descriptions[A_QuickKey3] = "sQuick3Cmd"; + descriptions[A_QuickKey4] = "sQuick4Cmd"; + descriptions[A_QuickKey5] = "sQuick5Cmd"; + descriptions[A_QuickKey6] = "sQuick6Cmd"; + descriptions[A_QuickKey7] = "sQuick7Cmd"; + descriptions[A_QuickKey8] = "sQuick8Cmd"; + descriptions[A_QuickKey9] = "sQuick9Cmd"; + descriptions[A_QuickKey10] = "sQuick10Cmd"; + descriptions[A_AlwaysRun] = "sAlways_Run"; + descriptions[A_QuickSave] = "sQuickSaveCmd"; + descriptions[A_QuickLoad] = "sQuickLoadCmd"; + + if (descriptions[action] == "") + return ""; // not configurable + + return "#{" + descriptions[action] + "}"; + } + + std::string BindingsManager::getActionKeyBindingName (int action) + { + if (mInputBinder->getChannel (action)->getControlsCount () == 0) + return "#{sNone}"; + + ICS::Control* c = mInputBinder->getChannel (action)->getAttachedControls ().front().control; + + SDL_Scancode key = mInputBinder->getKeyBinding (c, ICS::Control::INCREASE); + unsigned int mouse = mInputBinder->getMouseButtonBinding (c, ICS::Control::INCREASE); + ICS::InputControlSystem::MouseWheelClick wheel = mInputBinder->getMouseWheelBinding(c, ICS::Control::INCREASE); + if (key != SDL_SCANCODE_UNKNOWN) + return MyGUI::TextIterator::toTagsString(mInputBinder->scancodeToString (key)); + else if (mouse != ICS_MAX_DEVICE_BUTTONS) + return "#{sMouse} " + std::to_string(mouse); + else if (wheel != ICS::InputControlSystem::MouseWheelClick::UNASSIGNED) + switch (wheel) + { + case ICS::InputControlSystem::MouseWheelClick::UP: + return "Mouse Wheel Up"; + case ICS::InputControlSystem::MouseWheelClick::DOWN: + return "Mouse Wheel Down"; + case ICS::InputControlSystem::MouseWheelClick::RIGHT: + return "Mouse Wheel Right"; + case ICS::InputControlSystem::MouseWheelClick::LEFT: + return "Mouse Wheel Left"; + default: + return "#{sNone}"; + } + else + return "#{sNone}"; + } + + std::string BindingsManager::getActionControllerBindingName (int action) + { + if (mInputBinder->getChannel (action)->getControlsCount () == 0) + return "#{sNone}"; + + ICS::Control* c = mInputBinder->getChannel (action)->getAttachedControls ().front().control; + + if (mInputBinder->getJoystickAxisBinding (c, sFakeDeviceId, ICS::Control::INCREASE) != ICS::InputControlSystem::UNASSIGNED) + return sdlControllerAxisToString(mInputBinder->getJoystickAxisBinding (c, sFakeDeviceId, ICS::Control::INCREASE)); + else if (mInputBinder->getJoystickButtonBinding (c, sFakeDeviceId, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS ) + return sdlControllerButtonToString(mInputBinder->getJoystickButtonBinding (c, sFakeDeviceId, ICS::Control::INCREASE)); + else + return "#{sNone}"; + } + + std::vector BindingsManager::getActionKeySorting() + { + std::vector ret; + ret.push_back(A_MoveForward); + ret.push_back(A_MoveBackward); + ret.push_back(A_MoveLeft); + ret.push_back(A_MoveRight); + ret.push_back(A_TogglePOV); + ret.push_back(A_ZoomIn); + ret.push_back(A_ZoomOut); + ret.push_back(A_Run); + ret.push_back(A_AlwaysRun); + ret.push_back(A_Sneak); + ret.push_back(A_Activate); + ret.push_back(A_Use); + ret.push_back(A_ToggleWeapon); + ret.push_back(A_ToggleSpell); + ret.push_back(A_CycleSpellLeft); + ret.push_back(A_CycleSpellRight); + ret.push_back(A_CycleWeaponLeft); + ret.push_back(A_CycleWeaponRight); + ret.push_back(A_AutoMove); + ret.push_back(A_Jump); + ret.push_back(A_Inventory); + ret.push_back(A_Journal); + ret.push_back(A_Rest); + ret.push_back(A_Console); + ret.push_back(A_QuickSave); + ret.push_back(A_QuickLoad); + ret.push_back(A_ToggleHUD); + ret.push_back(A_Screenshot); + ret.push_back(A_QuickKeysMenu); + ret.push_back(A_QuickKey1); + ret.push_back(A_QuickKey2); + ret.push_back(A_QuickKey3); + ret.push_back(A_QuickKey4); + ret.push_back(A_QuickKey5); + ret.push_back(A_QuickKey6); + ret.push_back(A_QuickKey7); + ret.push_back(A_QuickKey8); + ret.push_back(A_QuickKey9); + ret.push_back(A_QuickKey10); + + return ret; + } + std::vector BindingsManager::getActionControllerSorting() + { + std::vector ret; + ret.push_back(A_TogglePOV); + ret.push_back(A_ZoomIn); + ret.push_back(A_ZoomOut); + ret.push_back(A_Sneak); + ret.push_back(A_Activate); + ret.push_back(A_Use); + ret.push_back(A_ToggleWeapon); + ret.push_back(A_ToggleSpell); + ret.push_back(A_AutoMove); + ret.push_back(A_Jump); + ret.push_back(A_Inventory); + ret.push_back(A_Journal); + ret.push_back(A_Rest); + ret.push_back(A_QuickSave); + ret.push_back(A_QuickLoad); + ret.push_back(A_ToggleHUD); + ret.push_back(A_Screenshot); + ret.push_back(A_QuickKeysMenu); + ret.push_back(A_QuickKey1); + ret.push_back(A_QuickKey2); + ret.push_back(A_QuickKey3); + ret.push_back(A_QuickKey4); + ret.push_back(A_QuickKey5); + ret.push_back(A_QuickKey6); + ret.push_back(A_QuickKey7); + ret.push_back(A_QuickKey8); + ret.push_back(A_QuickKey9); + ret.push_back(A_QuickKey10); + ret.push_back(A_CycleSpellLeft); + ret.push_back(A_CycleSpellRight); + ret.push_back(A_CycleWeaponLeft); + ret.push_back(A_CycleWeaponRight); + + return ret; + } + + void BindingsManager::enableDetectingBindingMode(int action, bool keyboard) + { + mListener->setDetectingKeyboard(keyboard); + ICS::Control* c = mInputBinder->getChannel(action)->getAttachedControls().front().control; + mInputBinder->enableDetectingBindingState(c, ICS::Control::INCREASE); + } + + bool BindingsManager::isDetectingBindingState() const + { + return mInputBinder->detectingBindingState(); + } + + void BindingsManager::mousePressed(const SDL_MouseButtonEvent &arg, int deviceID) + { + mInputBinder->mousePressed(arg, deviceID); + } + + void BindingsManager::mouseReleased(const SDL_MouseButtonEvent &arg, int deviceID) + { + mInputBinder->mouseReleased(arg, deviceID); + } + + void BindingsManager::mouseMoved(const SDLUtil::MouseMotionEvent &arg) + { + mInputBinder->mouseMoved(arg); + } + + void BindingsManager::mouseWheelMoved(const SDL_MouseWheelEvent &arg) + { + mInputBinder->mouseWheelMoved(arg); + } + + void BindingsManager::keyPressed(const SDL_KeyboardEvent &arg) + { + mInputBinder->keyPressed(arg); + } + + void BindingsManager::keyReleased(const SDL_KeyboardEvent &arg) + { + mInputBinder->keyReleased(arg); + } + + void BindingsManager::controllerAdded(int deviceID, const SDL_ControllerDeviceEvent &arg) + { + mInputBinder->controllerAdded(deviceID, arg); + } + + void BindingsManager::controllerRemoved(const SDL_ControllerDeviceEvent &arg) + { + mInputBinder->controllerRemoved(arg); + } + + void BindingsManager::controllerButtonPressed(int deviceID, const SDL_ControllerButtonEvent &arg) + { + mInputBinder->buttonPressed(deviceID, arg); + } + + void BindingsManager::controllerButtonReleased(int deviceID, const SDL_ControllerButtonEvent &arg) + { + mInputBinder->buttonReleased(deviceID, arg); + } + + void BindingsManager::controllerAxisMoved(int deviceID, const SDL_ControllerAxisEvent &arg) + { + mInputBinder->axisMoved(deviceID, arg); + } + + SDL_Scancode BindingsManager::getKeyBinding(int actionId) + { + return mInputBinder->getKeyBinding(mInputBinder->getControl(actionId), ICS::Control::INCREASE); + } + + void BindingsManager::actionValueChanged(int action, float currentValue, float previousValue) + { + MWBase::Environment::get().getInputManager()->resetIdleTime(); + + if (mDragDrop && action != A_GameMenu && action != A_Inventory) + return; + + if((previousValue == 1 || previousValue == 0) && (currentValue==1 || currentValue==0)) + { + //Is a normal button press, so don't change it at all + } + //Otherwise only trigger button presses as they go through specific points + else if(previousValue >= .8 && currentValue < .8) + { + currentValue = 0.0; + previousValue = 1.0; + } + else if(previousValue <= .6 && currentValue > .6) + { + currentValue = 1.0; + previousValue = 0.0; + } + else + { + //If it's not switching between those values, ignore the channel change. + return; + } + + if (MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) + { + bool joystickUsed = MWBase::Environment::get().getInputManager()->joystickLastUsed(); + if (action == A_Use) + { + if(joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleWeapon)) + action = A_CycleWeaponRight; + + else if (joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleSpell)) + action = A_CycleSpellRight; + + else + { + MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); + MWMechanics::DrawState_ state = player.getDrawState(); + player.setAttackingOrSpell(currentValue != 0 && state != MWMechanics::DrawState_Nothing); + } + } + else if (action == A_Jump) + { + if(joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleWeapon)) + action = A_CycleWeaponLeft; + + else if (joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleSpell)) + action = A_CycleSpellLeft; + + else + MWBase::Environment::get().getInputManager()->setAttemptJump(currentValue == 1.0 && previousValue == 0.0); + } + } + + if (currentValue == 1) + MWBase::Environment::get().getInputManager()->executeAction(action); + } +} diff --git a/apps/openmw/mwinput/bindingsmanager.hpp b/apps/openmw/mwinput/bindingsmanager.hpp new file mode 100644 index 000000000..35b26c877 --- /dev/null +++ b/apps/openmw/mwinput/bindingsmanager.hpp @@ -0,0 +1,73 @@ +#ifndef MWINPUT_MWBINDINGSMANAGER_H +#define MWINPUT_MWBINDINGSMANAGER_H + +#include +#include + +#include + +namespace MWInput +{ + class BindingsListener; + class InputControlSystem; + + class BindingsManager + { + public: + BindingsManager(const std::string& userFile, bool userFileExists); + + virtual ~BindingsManager(); + + std::string getActionDescription (int action); + std::string getActionKeyBindingName (int action); + std::string getActionControllerBindingName (int action); + std::vector getActionKeySorting(); + std::vector getActionControllerSorting(); + + void enableDetectingBindingMode (int action, bool keyboard); + bool isDetectingBindingState() const; + + void loadKeyDefaults(bool force = false); + void loadControllerDefaults(bool force = false); + + void setDragDrop(bool dragDrop); + + void update(float dt); + + void setPlayerControlsEnabled(bool enabled); + + bool isLeftOrRightButton(int action, bool joystick) const; + + bool actionIsActive(int id) const; + float getActionValue(int id) const; + + void mousePressed(const SDL_MouseButtonEvent &evt, int deviceID); + void mouseReleased(const SDL_MouseButtonEvent &arg, int deviceID); + void mouseMoved(const SDLUtil::MouseMotionEvent &arg); + void mouseWheelMoved(const SDL_MouseWheelEvent &arg); + + void keyPressed(const SDL_KeyboardEvent &arg); + void keyReleased(const SDL_KeyboardEvent &arg); + + void controllerAdded(int deviceID, const SDL_ControllerDeviceEvent &arg); + void controllerRemoved(const SDL_ControllerDeviceEvent &arg); + void controllerButtonPressed(int deviceID, const SDL_ControllerButtonEvent &arg); + void controllerButtonReleased(int deviceID, const SDL_ControllerButtonEvent &arg); + void controllerAxisMoved(int deviceID, const SDL_ControllerAxisEvent &arg); + + SDL_Scancode getKeyBinding(int actionId); + + void actionValueChanged(int action, float currentValue, float previousValue); + + private: + void setupSDLKeyMappings(); + + InputControlSystem* mInputBinder; + BindingsListener* mListener; + + std::string mUserFile; + + bool mDragDrop; + }; +} +#endif diff --git a/apps/openmw/mwinput/controllermanager.cpp b/apps/openmw/mwinput/controllermanager.cpp index 697d3ab91..b8fc0ca74 100644 --- a/apps/openmw/mwinput/controllermanager.cpp +++ b/apps/openmw/mwinput/controllermanager.cpp @@ -4,8 +4,6 @@ #include #include -#include - #include #include "../mwbase/environment.hpp" @@ -18,20 +16,18 @@ #include "actions.hpp" #include "actionmanager.hpp" +#include "bindingsmanager.hpp" #include "mousemanager.hpp" +#include "sdlmappings.hpp" namespace MWInput { - static const int sFakeDeviceID = 1; - - ControllerManager::ControllerManager(ICS::InputControlSystem* inputBinder, - SDLUtil::InputWrapper* inputWrapper, + ControllerManager::ControllerManager(BindingsManager* bindingsManager, ActionManager* actionManager, MouseManager* mouseManager, const std::string& userControllerBindingsFile, const std::string& controllerBindingsFile) - : mInputBinder(inputBinder) - , mInputWrapper(inputWrapper) + : mBindingsManager(bindingsManager) , mActionManager(actionManager) , mMouseManager(mouseManager) , mJoystickEnabled (Settings::Manager::getBool("enable controller", "Input")) @@ -62,7 +58,8 @@ namespace MWInput { SDL_ControllerDeviceEvent evt; evt.which = i; - controllerAdded(sFakeDeviceID, evt); + static const int fakeDeviceID = 1; + controllerAdded(fakeDeviceID, evt); Log(Debug::Info) << "Detected game controller: " << SDL_GameControllerNameForIndex(i); } else @@ -82,18 +79,13 @@ namespace MWInput void ControllerManager::processChangedSettings(const Settings::CategorySettingVector& changed) { - for (Settings::CategorySettingVector::const_iterator it = changed.begin(); it != changed.end(); ++it) + for (const auto& setting : changed) { - if (it->first == "Input" && it->second == "enable controller") + if (setting.first == "Input" && setting.second == "enable controller") mJoystickEnabled = Settings::Manager::getBool("enable controller", "Input"); } } - bool ControllerManager::actionIsActive (int id) - { - return (mInputBinder->getChannel (id)->getValue ()==1.0); - } - bool ControllerManager::update(float dt, bool disableControls) { mControlsDisabled = disableControls; @@ -101,12 +93,12 @@ namespace MWInput if (mGuiCursorEnabled && !(mJoystickLastUsed && !mGamepadGuiCursorEnabled)) { - float xAxis = mInputBinder->getChannel(A_MoveLeftRight)->getValue()*2.0f-1.0f; - float yAxis = mInputBinder->getChannel(A_MoveForwardBackward)->getValue()*2.0f-1.0f; - float zAxis = mInputBinder->getChannel(A_LookUpDown)->getValue()*2.0f-1.0f; + float xAxis = mBindingsManager->getActionValue(A_MoveLeftRight)*2.0f-1.0f; + float yAxis = mBindingsManager->getActionValue(A_MoveForwardBackward)*2.0f-1.0f; + float zAxis = mBindingsManager->getActionValue(A_LookUpDown)*2.0f-1.0f; - xAxis *= (1.5f - mInputBinder->getChannel(A_Use)->getValue()); - yAxis *= (1.5f - mInputBinder->getChannel(A_Use)->getValue()); + xAxis *= (1.5f - mBindingsManager->getActionValue(A_Use)); + yAxis *= (1.5f - mBindingsManager->getActionValue(A_Use)); // 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 @@ -137,8 +129,8 @@ namespace MWInput // be done in the physics system. if (MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols")) { - float xAxis = mInputBinder->getChannel(A_MoveLeftRight)->getValue(); - float yAxis = mInputBinder->getChannel(A_MoveForwardBackward)->getValue(); + float xAxis = mBindingsManager->getActionValue(A_MoveLeftRight); + float yAxis = mBindingsManager->getActionValue(A_MoveForwardBackward); if (xAxis != .5) { triedToMove = true; @@ -163,7 +155,7 @@ namespace MWInput { if(mJoystickLastUsed) { - if(actionIsActive(A_Sneak)) + if(mBindingsManager->actionIsActive(A_Sneak)) { if(mSneakToggleShortcutTimer) // New Sneak Button Press { @@ -189,13 +181,13 @@ namespace MWInput } } else - player.setSneak(actionIsActive(A_Sneak)); + player.setSneak(mBindingsManager->actionIsActive(A_Sneak)); } } if (MWBase::Environment::get().getInputManager()->getControlSwitch("playerviewswitch")) { - if (!actionIsActive(A_TogglePOV)) + if (!mBindingsManager->actionIsActive(A_TogglePOV)) mGamepadZoom = 0; if(mGamepadZoom) @@ -210,7 +202,7 @@ namespace MWInput void ControllerManager::buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg) { - if (!mJoystickEnabled || mInputBinder->detectingBindingState()) + if (!mJoystickEnabled || mBindingsManager->isDetectingBindingState()) return; mJoystickLastUsed = true; @@ -231,26 +223,26 @@ namespace MWInput MWBase::Environment::get().getWindowManager()->playSound("Menu Click"); } - MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(!mousePressSuccess); + mBindingsManager->setPlayerControlsEnabled(!mousePressSuccess); } } } else - MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(true); + mBindingsManager->setPlayerControlsEnabled(true); //esc, to leave initial movie screen - auto kc = mInputWrapper->sdl2OISKeyCode(SDLK_ESCAPE); - MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(kc), 0)); + auto kc = sdlKeyToMyGUI(SDLK_ESCAPE); + mBindingsManager->setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyPress(kc, 0)); if (!mControlsDisabled) - mInputBinder->buttonPressed(deviceID, arg); + mBindingsManager->controllerButtonPressed(deviceID, arg); } - void ControllerManager::buttonReleased(int deviceID, const SDL_ControllerButtonEvent &arg ) + void ControllerManager::buttonReleased(int deviceID, const SDL_ControllerButtonEvent &arg) { - if(mInputBinder->detectingBindingState()) + if (mBindingsManager->isDetectingBindingState()) { - mInputBinder->buttonReleased(deviceID, arg); + mBindingsManager->controllerButtonReleased(deviceID, arg); return; } if (!mJoystickEnabled || mControlsDisabled) @@ -265,21 +257,21 @@ namespace MWInput if (arg.button == SDL_CONTROLLER_BUTTON_A) // We'll pretend that A is left click. { bool mousePressSuccess = mMouseManager->injectMouseButtonRelease(SDL_BUTTON_LEFT); - if (mInputBinder->detectingBindingState()) // If the player just triggered binding, don't let button release bind. + if (mBindingsManager->isDetectingBindingState()) // If the player just triggered binding, don't let button release bind. return; - MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(!mousePressSuccess); + mBindingsManager->setPlayerControlsEnabled(!mousePressSuccess); } } } else - MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(true); + mBindingsManager->setPlayerControlsEnabled(true); //esc, to leave initial movie screen - auto kc = mInputWrapper->sdl2OISKeyCode(SDLK_ESCAPE); - MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc))); + auto kc = sdlKeyToMyGUI(SDLK_ESCAPE); + mBindingsManager->setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyRelease(kc)); - mInputBinder->buttonReleased(deviceID, arg); + mBindingsManager->controllerButtonReleased(deviceID, arg); } void ControllerManager::axisMoved(int deviceID, const SDL_ControllerAxisEvent &arg) @@ -308,17 +300,17 @@ namespace MWInput } } } - mInputBinder->axisMoved(deviceID, arg); + mBindingsManager->controllerAxisMoved(deviceID, arg); } void ControllerManager::controllerAdded(int deviceID, const SDL_ControllerDeviceEvent &arg) { - mInputBinder->controllerAdded(deviceID, arg); + mBindingsManager->controllerAdded(deviceID, arg); } void ControllerManager::controllerRemoved(const SDL_ControllerDeviceEvent &arg) { - mInputBinder->controllerRemoved(arg); + mBindingsManager->controllerRemoved(arg); } bool ControllerManager::gamepadToGuiControl(const SDL_ControllerButtonEvent &arg) diff --git a/apps/openmw/mwinput/controllermanager.hpp b/apps/openmw/mwinput/controllermanager.hpp index 1ab6ea76d..f1be50ee6 100644 --- a/apps/openmw/mwinput/controllermanager.hpp +++ b/apps/openmw/mwinput/controllermanager.hpp @@ -5,23 +5,17 @@ #include #include -#include - -namespace ICS -{ - class InputControlSystem; -} namespace MWInput { class ActionManager; + class BindingsManager; class MouseManager; class ControllerManager : public SDLUtil::ControllerListener { public: - ControllerManager(ICS::InputControlSystem* inputBinder, - SDLUtil::InputWrapper* inputWrapper, + ControllerManager(BindingsManager* bindingsManager, ActionManager* actionManager, MouseManager* mouseManager, const std::string& userControllerBindingsFile, @@ -54,10 +48,7 @@ namespace MWInput bool gamepadToGuiControl(const SDL_ControllerButtonEvent &arg); bool gamepadToGuiControl(const SDL_ControllerAxisEvent &arg); - bool actionIsActive(int id); - - ICS::InputControlSystem* mInputBinder; - SDLUtil::InputWrapper* mInputWrapper; + BindingsManager* mBindingsManager; ActionManager* mActionManager; MouseManager* mMouseManager; diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index f7f32b9a9..0a43a62fc 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -30,6 +30,7 @@ #include "../mwmechanics/actorutil.hpp" #include "actionmanager.hpp" +#include "bindingsmanager.hpp" #include "controllermanager.hpp" #include "controlswitch.hpp" #include "keyboardmanager.hpp" @@ -46,38 +47,25 @@ namespace MWInput osgViewer::ScreenCaptureHandler::CaptureOperation *screenCaptureOperation, const std::string& userFile, bool userFileExists, const std::string& userControllerBindingsFile, const std::string& controllerBindingsFile, bool grab) - : mUserFile(userFile) - , mDragDrop(false) - , mGrabCursor(Settings::Manager::getBool("grab cursor", "Input")) + : mGrabCursor(Settings::Manager::getBool("grab cursor", "Input")) , mGuiCursorEnabled(true) - , mDetectingKeyboard(false) - , mFakeDeviceID(1) { mInputWrapper = new SDLUtil::InputWrapper(window, viewer, grab); mInputWrapper->setWindowEventCallback(MWBase::Environment::get().getWindowManager()); - std::string file = userFileExists ? userFile : ""; - mInputBinder = new ICS::InputControlSystem(file, true, this, nullptr, A_Last); - - loadKeyDefaults(); - loadControllerDefaults(); - - for (int i = 0; i < A_Last; ++i) - { - mInputBinder->getChannel (i)->addListener (this); - } + mBindingsManager = new BindingsManager(userFile, userFileExists); mControlSwitch = new ControlSwitch(); - mActionManager = new ActionManager(mInputBinder, screenCaptureOperation, viewer, screenCaptureHandler); + mActionManager = new ActionManager(mBindingsManager, screenCaptureOperation, viewer, screenCaptureHandler); - mKeyboardManager = new KeyboardManager(mInputBinder, mInputWrapper, mActionManager); + mKeyboardManager = new KeyboardManager(mBindingsManager, mActionManager); mInputWrapper->setKeyboardEventCallback(mKeyboardManager); - mMouseManager = new MouseManager(mInputBinder, mInputWrapper, window); + mMouseManager = new MouseManager(mBindingsManager, mInputWrapper, window); mInputWrapper->setMouseEventCallback(mMouseManager); - mControllerManager = new ControllerManager(mInputBinder, mInputWrapper, mActionManager, mMouseManager, userControllerBindingsFile, controllerBindingsFile); + mControllerManager = new ControllerManager(mBindingsManager, mActionManager, mMouseManager, userControllerBindingsFile, controllerBindingsFile); mInputWrapper->setControllerEventCallback(mControllerManager); mSensorManager = new SensorManager(); @@ -105,89 +93,14 @@ namespace MWInput delete mControlSwitch; - mInputBinder->save(mUserFile); - delete mInputBinder; + delete mBindingsManager; delete mInputWrapper; } - void InputManager::setPlayerControlsEnabled(bool enabled) + void InputManager::setAttemptJump(bool jumping) { - int playerChannels[] = {A_AutoMove, A_AlwaysRun, A_ToggleWeapon, - A_ToggleSpell, A_Rest, A_QuickKey1, A_QuickKey2, - A_QuickKey3, A_QuickKey4, A_QuickKey5, A_QuickKey6, - A_QuickKey7, A_QuickKey8, A_QuickKey9, A_QuickKey10, - A_Use, A_Journal}; - - for(size_t i = 0; i < sizeof(playerChannels)/sizeof(playerChannels[0]); i++) { - int pc = playerChannels[i]; - mInputBinder->getChannel(pc)->setEnabled(enabled); - } - } - - void InputManager::channelChanged(ICS::Channel* channel, float currentValue, float previousValue) - { - resetIdleTime (); - - int action = channel->getNumber(); - - if (mDragDrop && action != A_GameMenu && action != A_Inventory) - return; - - if((previousValue == 1 || previousValue == 0) && (currentValue==1 || currentValue==0)) - { - //Is a normal button press, so don't change it at all - } - //Otherwise only trigger button presses as they go through specific points - else if(previousValue >= .8 && currentValue < .8) - { - currentValue = 0.0; - previousValue = 1.0; - } - else if(previousValue <= .6 && currentValue > .6) - { - currentValue = 1.0; - previousValue = 0.0; - } - else - { - //If it's not switching between those values, ignore the channel change. - return; - } - - if (mControlSwitch->get("playercontrols")) - { - bool joystickUsed = mControllerManager->joystickLastUsed(); - if (action == A_Use) - { - if(joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleWeapon)) - action = A_CycleWeaponRight; - - else if (joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleSpell)) - action = A_CycleSpellRight; - - else - { - MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer(); - MWMechanics::DrawState_ state = player.getDrawState(); - player.setAttackingOrSpell(currentValue != 0 && state != MWMechanics::DrawState_Nothing); - } - } - else if (action == A_Jump) - { - if(joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleWeapon)) - action = A_CycleWeaponLeft; - - else if (joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleSpell)) - action = A_CycleSpellLeft; - - else - mActionManager->setAttemptJump(currentValue == 1.0 && previousValue == 0.0); - } - } - - if (currentValue == 1) - mActionManager->executeAction(action); + mActionManager->setAttemptJump(jumping); } void InputManager::updateCursorMode() @@ -225,8 +138,7 @@ namespace MWInput return; } - // update values of channels (as a result of pressed keys) - mInputBinder->update(dt); + mBindingsManager->update(dt); updateCursorMode(); @@ -238,7 +150,7 @@ namespace MWInput void InputManager::setDragDrop(bool dragDrop) { - mDragDrop = dragDrop; + mBindingsManager->setDragDrop(dragDrop); } void InputManager::setGamepadGuiCursorEnabled(bool enabled) @@ -260,10 +172,9 @@ namespace MWInput void InputManager::processChangedSettings(const Settings::CategorySettingVector& changed) { - for (Settings::CategorySettingVector::const_iterator it = changed.begin(); - it != changed.end(); ++it) + for (const auto& setting : changed) { - if (it->first == "Input" && it->second == "grab cursor") + if (setting.first == "Input" && setting.second == "grab cursor") mGrabCursor = Settings::Manager::getBool("grab cursor", "Input"); } @@ -271,12 +182,12 @@ namespace MWInput mSensorManager->processChangedSettings(changed); } - bool InputManager::getControlSwitch (const std::string& sw) + bool InputManager::getControlSwitch(const std::string& sw) { return mControlSwitch->get(sw); } - void InputManager::toggleControlSwitch (const std::string& sw, bool value) + void InputManager::toggleControlSwitch(const std::string& sw, bool value) { mControlSwitch->set(sw, value); } @@ -286,488 +197,34 @@ namespace MWInput mActionManager->resetIdleTime(); } - bool InputManager::actionIsActive (int id) + std::string InputManager::getActionDescription(int action) { - return (mInputBinder->getChannel (id)->getValue ()==1.0); + return mBindingsManager->getActionDescription(action); } - void InputManager::loadKeyDefaults (bool force) + std::string InputManager::getActionKeyBindingName(int action) { - // using hardcoded key defaults is inevitable, if we want the configuration files to stay valid - // across different versions of OpenMW (in the case where another input action is added) - std::map defaultKeyBindings; - - //Gets the Keyvalue from the Scancode; gives the button in the same place reguardless of keyboard format - defaultKeyBindings[A_Activate] = SDL_SCANCODE_SPACE; - defaultKeyBindings[A_MoveBackward] = SDL_SCANCODE_S; - defaultKeyBindings[A_MoveForward] = SDL_SCANCODE_W; - defaultKeyBindings[A_MoveLeft] = SDL_SCANCODE_A; - defaultKeyBindings[A_MoveRight] = SDL_SCANCODE_D; - defaultKeyBindings[A_ToggleWeapon] = SDL_SCANCODE_F; - defaultKeyBindings[A_ToggleSpell] = SDL_SCANCODE_R; - defaultKeyBindings[A_CycleSpellLeft] = SDL_SCANCODE_MINUS; - defaultKeyBindings[A_CycleSpellRight] = SDL_SCANCODE_EQUALS; - defaultKeyBindings[A_CycleWeaponLeft] = SDL_SCANCODE_LEFTBRACKET; - defaultKeyBindings[A_CycleWeaponRight] = SDL_SCANCODE_RIGHTBRACKET; - - defaultKeyBindings[A_QuickKeysMenu] = SDL_SCANCODE_F1; - defaultKeyBindings[A_Console] = SDL_SCANCODE_GRAVE; - defaultKeyBindings[A_Run] = SDL_SCANCODE_LSHIFT; - defaultKeyBindings[A_Sneak] = SDL_SCANCODE_LCTRL; - defaultKeyBindings[A_AutoMove] = SDL_SCANCODE_Q; - defaultKeyBindings[A_Jump] = SDL_SCANCODE_E; - defaultKeyBindings[A_Journal] = SDL_SCANCODE_J; - defaultKeyBindings[A_Rest] = SDL_SCANCODE_T; - defaultKeyBindings[A_GameMenu] = SDL_SCANCODE_ESCAPE; - defaultKeyBindings[A_TogglePOV] = SDL_SCANCODE_TAB; - defaultKeyBindings[A_QuickKey1] = SDL_SCANCODE_1; - defaultKeyBindings[A_QuickKey2] = SDL_SCANCODE_2; - defaultKeyBindings[A_QuickKey3] = SDL_SCANCODE_3; - defaultKeyBindings[A_QuickKey4] = SDL_SCANCODE_4; - defaultKeyBindings[A_QuickKey5] = SDL_SCANCODE_5; - defaultKeyBindings[A_QuickKey6] = SDL_SCANCODE_6; - defaultKeyBindings[A_QuickKey7] = SDL_SCANCODE_7; - defaultKeyBindings[A_QuickKey8] = SDL_SCANCODE_8; - defaultKeyBindings[A_QuickKey9] = SDL_SCANCODE_9; - defaultKeyBindings[A_QuickKey10] = SDL_SCANCODE_0; - defaultKeyBindings[A_Screenshot] = SDL_SCANCODE_F12; - defaultKeyBindings[A_ToggleHUD] = SDL_SCANCODE_F11; - defaultKeyBindings[A_ToggleDebug] = SDL_SCANCODE_F10; - defaultKeyBindings[A_AlwaysRun] = SDL_SCANCODE_CAPSLOCK; - defaultKeyBindings[A_QuickSave] = SDL_SCANCODE_F5; - defaultKeyBindings[A_QuickLoad] = SDL_SCANCODE_F9; - - std::map defaultMouseButtonBindings; - defaultMouseButtonBindings[A_Inventory] = SDL_BUTTON_RIGHT; - defaultMouseButtonBindings[A_Use] = SDL_BUTTON_LEFT; - - std::map defaultMouseWheelBindings; - defaultMouseWheelBindings[A_ZoomIn] = ICS::InputControlSystem::MouseWheelClick::UP; - defaultMouseWheelBindings[A_ZoomOut] = ICS::InputControlSystem::MouseWheelClick::DOWN; - - for (int i = 0; i < A_Last; ++i) - { - ICS::Control* control; - bool controlExists = mInputBinder->getChannel(i)->getControlsCount () != 0; - if (!controlExists) - { - control = new ICS::Control(std::to_string(i), false, true, 0, ICS::ICS_MAX, ICS::ICS_MAX); - mInputBinder->addControl(control); - control->attachChannel(mInputBinder->getChannel(i), ICS::Channel::DIRECT); - } - else - { - control = mInputBinder->getChannel(i)->getAttachedControls ().front().control; - } - - if (!controlExists || force || - ( mInputBinder->getKeyBinding (control, ICS::Control::INCREASE) == SDL_SCANCODE_UNKNOWN - && mInputBinder->getMouseButtonBinding (control, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS - && mInputBinder->getMouseWheelBinding(control, ICS::Control::INCREASE) == ICS::InputControlSystem::MouseWheelClick::UNASSIGNED - )) - { - clearAllKeyBindings(control); - - if (defaultKeyBindings.find(i) != defaultKeyBindings.end() - && (force || !mInputBinder->isKeyBound(defaultKeyBindings[i]))) - { - control->setInitialValue(0.0f); - mInputBinder->addKeyBinding(control, defaultKeyBindings[i], ICS::Control::INCREASE); - } - else if (defaultMouseButtonBindings.find(i) != defaultMouseButtonBindings.end() - && (force || !mInputBinder->isMouseButtonBound(defaultMouseButtonBindings[i]))) - { - control->setInitialValue(0.0f); - mInputBinder->addMouseButtonBinding (control, defaultMouseButtonBindings[i], ICS::Control::INCREASE); - } - else if (defaultMouseWheelBindings.find(i) != defaultMouseWheelBindings.end() - && (force || !mInputBinder->isMouseWheelBound(defaultMouseWheelBindings[i]))) - { - control->setInitialValue(0.f); - mInputBinder->addMouseWheelBinding(control, defaultMouseWheelBindings[i], ICS::Control::INCREASE); - } - - if (i == A_LookLeftRight && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_4) && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_6)) - { - mInputBinder->addKeyBinding(control, SDL_SCANCODE_KP_6, ICS::Control::INCREASE); - mInputBinder->addKeyBinding(control, SDL_SCANCODE_KP_4, ICS::Control::DECREASE); - } - if (i == A_LookUpDown && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_8) && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_2)) - { - mInputBinder->addKeyBinding(control, SDL_SCANCODE_KP_2, ICS::Control::INCREASE); - mInputBinder->addKeyBinding(control, SDL_SCANCODE_KP_8, ICS::Control::DECREASE); - } - } - } - } - - void InputManager::loadControllerDefaults(bool force) - { - // using hardcoded key defaults is inevitable, if we want the configuration files to stay valid - // across different versions of OpenMW (in the case where another input action is added) - std::map defaultButtonBindings; - - defaultButtonBindings[A_Activate] = SDL_CONTROLLER_BUTTON_A; - defaultButtonBindings[A_ToggleWeapon] = SDL_CONTROLLER_BUTTON_X; - defaultButtonBindings[A_ToggleSpell] = SDL_CONTROLLER_BUTTON_Y; - //defaultButtonBindings[A_QuickButtonsMenu] = SDL_GetButtonFromScancode(SDL_SCANCODE_F1); // Need to implement, should be ToggleSpell(5) AND Wait(9) - defaultButtonBindings[A_Sneak] = SDL_CONTROLLER_BUTTON_LEFTSTICK; - defaultButtonBindings[A_Journal] = SDL_CONTROLLER_BUTTON_LEFTSHOULDER; - defaultButtonBindings[A_Rest] = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER; - defaultButtonBindings[A_TogglePOV] = SDL_CONTROLLER_BUTTON_RIGHTSTICK; - defaultButtonBindings[A_Inventory] = SDL_CONTROLLER_BUTTON_B; - defaultButtonBindings[A_GameMenu] = SDL_CONTROLLER_BUTTON_START; - defaultButtonBindings[A_QuickSave] = SDL_CONTROLLER_BUTTON_GUIDE; - defaultButtonBindings[A_MoveForward] = SDL_CONTROLLER_BUTTON_DPAD_UP; - defaultButtonBindings[A_MoveLeft] = SDL_CONTROLLER_BUTTON_DPAD_LEFT; - defaultButtonBindings[A_MoveBackward] = SDL_CONTROLLER_BUTTON_DPAD_DOWN; - defaultButtonBindings[A_MoveRight] = SDL_CONTROLLER_BUTTON_DPAD_RIGHT; - - std::map defaultAxisBindings; - defaultAxisBindings[A_MoveForwardBackward] = SDL_CONTROLLER_AXIS_LEFTY; - defaultAxisBindings[A_MoveLeftRight] = SDL_CONTROLLER_AXIS_LEFTX; - defaultAxisBindings[A_LookUpDown] = SDL_CONTROLLER_AXIS_RIGHTY; - defaultAxisBindings[A_LookLeftRight] = SDL_CONTROLLER_AXIS_RIGHTX; - defaultAxisBindings[A_Use] = SDL_CONTROLLER_AXIS_TRIGGERRIGHT; - defaultAxisBindings[A_Jump] = SDL_CONTROLLER_AXIS_TRIGGERLEFT; - - for (int i = 0; i < A_Last; i++) - { - ICS::Control* control; - bool controlExists = mInputBinder->getChannel(i)->getControlsCount () != 0; - if (!controlExists) - { - float initial; - if (defaultAxisBindings.find(i) == defaultAxisBindings.end()) - initial = 0.0f; - else initial = 0.5f; - control = new ICS::Control(std::to_string(i), false, true, initial, ICS::ICS_MAX, ICS::ICS_MAX); - mInputBinder->addControl(control); - control->attachChannel(mInputBinder->getChannel(i), ICS::Channel::DIRECT); - } - else - { - control = mInputBinder->getChannel(i)->getAttachedControls ().front().control; - } - - if (!controlExists || force || ( mInputBinder->getJoystickAxisBinding (control, mFakeDeviceID, ICS::Control::INCREASE) == ICS::InputControlSystem::UNASSIGNED && mInputBinder->getJoystickButtonBinding (control, mFakeDeviceID, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS )) - { - clearAllControllerBindings(control); - - if (defaultButtonBindings.find(i) != defaultButtonBindings.end() - && (force || !mInputBinder->isJoystickButtonBound(mFakeDeviceID, defaultButtonBindings[i]))) - { - control->setInitialValue(0.0f); - mInputBinder->addJoystickButtonBinding(control, mFakeDeviceID, defaultButtonBindings[i], ICS::Control::INCREASE); - } - else if (defaultAxisBindings.find(i) != defaultAxisBindings.end() && (force || !mInputBinder->isJoystickAxisBound(mFakeDeviceID, defaultAxisBindings[i]))) - { - control->setValue(0.5f); - control->setInitialValue(0.5f); - mInputBinder->addJoystickAxisBinding(control, mFakeDeviceID, defaultAxisBindings[i], ICS::Control::INCREASE); - } - } - } + return mBindingsManager->getActionKeyBindingName(action); } - std::string InputManager::getActionDescription (int action) + std::string InputManager::getActionControllerBindingName(int action) { - std::map descriptions; - - if (action == A_Screenshot) - return "Screenshot"; - else if (action == A_ZoomIn) - return "Zoom In"; - else if (action == A_ZoomOut) - return "Zoom Out"; - else if (action == A_ToggleHUD) - return "Toggle HUD"; - - descriptions[A_Use] = "sUse"; - descriptions[A_Activate] = "sActivate"; - descriptions[A_MoveBackward] = "sBack"; - descriptions[A_MoveForward] = "sForward"; - descriptions[A_MoveLeft] = "sLeft"; - descriptions[A_MoveRight] = "sRight"; - descriptions[A_ToggleWeapon] = "sReady_Weapon"; - descriptions[A_ToggleSpell] = "sReady_Magic"; - descriptions[A_CycleSpellLeft] = "sPrevSpell"; - descriptions[A_CycleSpellRight] = "sNextSpell"; - descriptions[A_CycleWeaponLeft] = "sPrevWeapon"; - descriptions[A_CycleWeaponRight] = "sNextWeapon"; - descriptions[A_Console] = "sConsoleTitle"; - descriptions[A_Run] = "sRun"; - descriptions[A_Sneak] = "sCrouch_Sneak"; - descriptions[A_AutoMove] = "sAuto_Run"; - descriptions[A_Jump] = "sJump"; - descriptions[A_Journal] = "sJournal"; - descriptions[A_Rest] = "sRestKey"; - descriptions[A_Inventory] = "sInventory"; - descriptions[A_TogglePOV] = "sTogglePOVCmd"; - descriptions[A_QuickKeysMenu] = "sQuickMenu"; - descriptions[A_QuickKey1] = "sQuick1Cmd"; - descriptions[A_QuickKey2] = "sQuick2Cmd"; - descriptions[A_QuickKey3] = "sQuick3Cmd"; - descriptions[A_QuickKey4] = "sQuick4Cmd"; - descriptions[A_QuickKey5] = "sQuick5Cmd"; - descriptions[A_QuickKey6] = "sQuick6Cmd"; - descriptions[A_QuickKey7] = "sQuick7Cmd"; - descriptions[A_QuickKey8] = "sQuick8Cmd"; - descriptions[A_QuickKey9] = "sQuick9Cmd"; - descriptions[A_QuickKey10] = "sQuick10Cmd"; - descriptions[A_AlwaysRun] = "sAlways_Run"; - descriptions[A_QuickSave] = "sQuickSaveCmd"; - descriptions[A_QuickLoad] = "sQuickLoadCmd"; - - if (descriptions[action] == "") - return ""; // not configurable - - return "#{" + descriptions[action] + "}"; - } - - std::string InputManager::getActionKeyBindingName (int action) - { - if (mInputBinder->getChannel (action)->getControlsCount () == 0) - return "#{sNone}"; - - ICS::Control* c = mInputBinder->getChannel (action)->getAttachedControls ().front().control; - - SDL_Scancode key = mInputBinder->getKeyBinding (c, ICS::Control::INCREASE); - unsigned int mouse = mInputBinder->getMouseButtonBinding (c, ICS::Control::INCREASE); - ICS::InputControlSystem::MouseWheelClick wheel = mInputBinder->getMouseWheelBinding(c, ICS::Control::INCREASE); - if (key != SDL_SCANCODE_UNKNOWN) - return MyGUI::TextIterator::toTagsString(mInputBinder->scancodeToString (key)); - else if (mouse != ICS_MAX_DEVICE_BUTTONS) - return "#{sMouse} " + std::to_string(mouse); - else if (wheel != ICS::InputControlSystem::MouseWheelClick::UNASSIGNED) - switch (wheel) - { - case ICS::InputControlSystem::MouseWheelClick::UP: - return "Mouse Wheel Up"; - case ICS::InputControlSystem::MouseWheelClick::DOWN: - return "Mouse Wheel Down"; - case ICS::InputControlSystem::MouseWheelClick::RIGHT: - return "Mouse Wheel Right"; - case ICS::InputControlSystem::MouseWheelClick::LEFT: - return "Mouse Wheel Left"; - default: - return "#{sNone}"; - } - else - return "#{sNone}"; - } - - std::string InputManager::getActionControllerBindingName (int action) - { - if (mInputBinder->getChannel (action)->getControlsCount () == 0) - return "#{sNone}"; - - ICS::Control* c = mInputBinder->getChannel (action)->getAttachedControls ().front().control; - - if (mInputBinder->getJoystickAxisBinding (c, mFakeDeviceID, ICS::Control::INCREASE) != ICS::InputControlSystem::UNASSIGNED) - return sdlControllerAxisToString(mInputBinder->getJoystickAxisBinding (c, mFakeDeviceID, ICS::Control::INCREASE)); - else if (mInputBinder->getJoystickButtonBinding (c, mFakeDeviceID, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS ) - return sdlControllerButtonToString(mInputBinder->getJoystickButtonBinding (c, mFakeDeviceID, ICS::Control::INCREASE)); - else - return "#{sNone}"; + return mBindingsManager->getActionControllerBindingName(action); } std::vector InputManager::getActionKeySorting() { - std::vector ret; - ret.push_back(A_MoveForward); - ret.push_back(A_MoveBackward); - ret.push_back(A_MoveLeft); - ret.push_back(A_MoveRight); - ret.push_back(A_TogglePOV); - ret.push_back(A_ZoomIn); - ret.push_back(A_ZoomOut); - ret.push_back(A_Run); - ret.push_back(A_AlwaysRun); - ret.push_back(A_Sneak); - ret.push_back(A_Activate); - ret.push_back(A_Use); - ret.push_back(A_ToggleWeapon); - ret.push_back(A_ToggleSpell); - ret.push_back(A_CycleSpellLeft); - ret.push_back(A_CycleSpellRight); - ret.push_back(A_CycleWeaponLeft); - ret.push_back(A_CycleWeaponRight); - ret.push_back(A_AutoMove); - ret.push_back(A_Jump); - ret.push_back(A_Inventory); - ret.push_back(A_Journal); - ret.push_back(A_Rest); - ret.push_back(A_Console); - ret.push_back(A_QuickSave); - ret.push_back(A_QuickLoad); - ret.push_back(A_ToggleHUD); - ret.push_back(A_Screenshot); - ret.push_back(A_QuickKeysMenu); - ret.push_back(A_QuickKey1); - ret.push_back(A_QuickKey2); - ret.push_back(A_QuickKey3); - ret.push_back(A_QuickKey4); - ret.push_back(A_QuickKey5); - ret.push_back(A_QuickKey6); - ret.push_back(A_QuickKey7); - ret.push_back(A_QuickKey8); - ret.push_back(A_QuickKey9); - ret.push_back(A_QuickKey10); - - return ret; - } - std::vector InputManager::getActionControllerSorting() - { - std::vector ret; - ret.push_back(A_TogglePOV); - ret.push_back(A_ZoomIn); - ret.push_back(A_ZoomOut); - ret.push_back(A_Sneak); - ret.push_back(A_Activate); - ret.push_back(A_Use); - ret.push_back(A_ToggleWeapon); - ret.push_back(A_ToggleSpell); - ret.push_back(A_AutoMove); - ret.push_back(A_Jump); - ret.push_back(A_Inventory); - ret.push_back(A_Journal); - ret.push_back(A_Rest); - ret.push_back(A_QuickSave); - ret.push_back(A_QuickLoad); - ret.push_back(A_ToggleHUD); - ret.push_back(A_Screenshot); - ret.push_back(A_QuickKeysMenu); - ret.push_back(A_QuickKey1); - ret.push_back(A_QuickKey2); - ret.push_back(A_QuickKey3); - ret.push_back(A_QuickKey4); - ret.push_back(A_QuickKey5); - ret.push_back(A_QuickKey6); - ret.push_back(A_QuickKey7); - ret.push_back(A_QuickKey8); - ret.push_back(A_QuickKey9); - ret.push_back(A_QuickKey10); - ret.push_back(A_CycleSpellLeft); - ret.push_back(A_CycleSpellRight); - ret.push_back(A_CycleWeaponLeft); - ret.push_back(A_CycleWeaponRight); - - return ret; - } - - void InputManager::enableDetectingBindingMode (int action, bool keyboard) - { - mDetectingKeyboard = keyboard; - ICS::Control* c = mInputBinder->getChannel (action)->getAttachedControls ().front().control; - mInputBinder->enableDetectingBindingState (c, ICS::Control::INCREASE); - } - - void InputManager::keyBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , SDL_Scancode key, ICS::Control::ControlChangingDirection direction) - { - //Disallow binding escape key - if(key==SDL_SCANCODE_ESCAPE) - { - //Stop binding if esc pressed - mInputBinder->cancelDetectingBindingState(); - MWBase::Environment::get().getWindowManager ()->notifyInputActionBound (); - return; - } - - // Disallow binding reserved keys - if (key == SDL_SCANCODE_F3 || key == SDL_SCANCODE_F4 || key == SDL_SCANCODE_F10) - return; - - #ifndef __APPLE__ - // Disallow binding Windows/Meta keys - if (key == SDL_SCANCODE_LGUI || key == SDL_SCANCODE_RGUI) - return; - #endif - - if(!mDetectingKeyboard) - return; - - clearAllKeyBindings(control); - control->setInitialValue(0.0f); - ICS::DetectingBindingListener::keyBindingDetected (ICS, control, key, direction); - MWBase::Environment::get().getWindowManager ()->notifyInputActionBound (); - } - - void InputManager::mouseAxisBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , ICS::InputControlSystem::NamedAxis axis, ICS::Control::ControlChangingDirection direction) - { - // we don't want mouse movement bindings - return; - } - - void InputManager::mouseButtonBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , unsigned int button, ICS::Control::ControlChangingDirection direction) - { - if(!mDetectingKeyboard) - return; - clearAllKeyBindings(control); - control->setInitialValue(0.0f); - ICS::DetectingBindingListener::mouseButtonBindingDetected (ICS, control, button, direction); - MWBase::Environment::get().getWindowManager ()->notifyInputActionBound (); + return mBindingsManager->getActionKeySorting(); } - void InputManager::mouseWheelBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , ICS::InputControlSystem::MouseWheelClick click, ICS::Control::ControlChangingDirection direction) - { - if(!mDetectingKeyboard) - return; - clearAllKeyBindings(control); - control->setInitialValue(0.0f); - ICS::DetectingBindingListener::mouseWheelBindingDetected(ICS, control, click, direction); - MWBase::Environment::get().getWindowManager()->notifyInputActionBound(); - } - - void InputManager::joystickAxisBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control - , int axis, ICS::Control::ControlChangingDirection direction) - { - //only allow binding to the trigers - if(axis != SDL_CONTROLLER_AXIS_TRIGGERLEFT && axis != SDL_CONTROLLER_AXIS_TRIGGERRIGHT) - return; - if(mDetectingKeyboard) - return; - - clearAllControllerBindings(control); - control->setValue(0.5f); //axis bindings must start at 0.5 - control->setInitialValue(0.5f); - ICS::DetectingBindingListener::joystickAxisBindingDetected (ICS, deviceID, control, axis, direction); - MWBase::Environment::get().getWindowManager ()->notifyInputActionBound (); - } - - void InputManager::joystickButtonBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control - , unsigned int button, ICS::Control::ControlChangingDirection direction) - { - if(mDetectingKeyboard) - return; - clearAllControllerBindings(control); - control->setInitialValue(0.0f); - ICS::DetectingBindingListener::joystickButtonBindingDetected (ICS, deviceID, control, button, direction); - MWBase::Environment::get().getWindowManager ()->notifyInputActionBound (); - } - - void InputManager::clearAllKeyBindings (ICS::Control* control) + std::vector InputManager::getActionControllerSorting() { - // right now we don't really need multiple bindings for the same action, so remove all others first - if (mInputBinder->getKeyBinding (control, ICS::Control::INCREASE) != SDL_SCANCODE_UNKNOWN) - mInputBinder->removeKeyBinding (mInputBinder->getKeyBinding (control, ICS::Control::INCREASE)); - if (mInputBinder->getMouseButtonBinding (control, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS) - mInputBinder->removeMouseButtonBinding (mInputBinder->getMouseButtonBinding (control, ICS::Control::INCREASE)); - if (mInputBinder->getMouseWheelBinding (control, ICS::Control::INCREASE) != ICS::InputControlSystem::MouseWheelClick::UNASSIGNED) - mInputBinder->removeMouseWheelBinding (mInputBinder->getMouseWheelBinding(control, ICS::Control::INCREASE)); + return mBindingsManager->getActionControllerSorting(); } - void InputManager::clearAllControllerBindings (ICS::Control* control) + void InputManager::enableDetectingBindingMode(int action, bool keyboard) { - // right now we don't really need multiple bindings for the same action, so remove all others first - if (mInputBinder->getJoystickAxisBinding (control, mFakeDeviceID, ICS::Control::INCREASE) != SDL_SCANCODE_UNKNOWN) - mInputBinder->removeJoystickAxisBinding (mFakeDeviceID, mInputBinder->getJoystickAxisBinding (control, mFakeDeviceID, ICS::Control::INCREASE)); - if (mInputBinder->getJoystickButtonBinding (control, mFakeDeviceID, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS) - mInputBinder->removeJoystickButtonBinding (mFakeDeviceID, mInputBinder->getJoystickButtonBinding (control, mFakeDeviceID, ICS::Control::INCREASE)); + mBindingsManager->enableDetectingBindingMode(action, keyboard); } int InputManager::countSavedGameRecords() const @@ -810,12 +267,12 @@ namespace MWInput void InputManager::resetToDefaultKeyBindings() { - loadKeyDefaults(true); + mBindingsManager->loadKeyDefaults(true); } void InputManager::resetToDefaultControllerBindings() { - loadControllerDefaults(true); + mBindingsManager->loadControllerDefaults(true); } void InputManager::setJoystickLastUsed(bool enabled) @@ -827,4 +284,9 @@ namespace MWInput { return mControllerManager->joystickLastUsed(); } + + void InputManager::executeAction(int action) + { + mActionManager->executeAction(action); + } } diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index ac056809e..8e8096d92 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -8,9 +8,6 @@ #include #include -#include -#include - #include #include #include @@ -23,6 +20,7 @@ namespace MWInput { class ControlSwitch; class ActionManager; + class BindingsManager; class ControllerManager; class KeyboardManager; class MouseManager; @@ -39,11 +37,6 @@ namespace MWBase class WindowManager; } -namespace ICS -{ - class InputControlSystem; -} - namespace Files { struct ConfigurationManager; @@ -62,9 +55,7 @@ namespace MWInput * @brief Class that handles all input and key bindings for OpenMW. */ class InputManager : - public MWBase::InputManager, - public ICS::ChannelListener, - public ICS::DetectingBindingListener + public MWBase::InputManager { public: InputManager( @@ -89,6 +80,7 @@ namespace MWInput virtual void setDragDrop(bool dragDrop); virtual void setGamepadGuiCursorEnabled(bool enabled); + virtual void setAttemptJump(bool jumping); virtual void toggleControlSwitch (const std::string& sw, bool value); virtual bool getControlSwitch (const std::string& sw); @@ -106,55 +98,25 @@ namespace MWInput virtual void setJoystickLastUsed(bool enabled); virtual bool joystickLastUsed(); - virtual void channelChanged(ICS::Channel* channel, float currentValue, float previousValue); - - virtual void keyBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , SDL_Scancode key, ICS::Control::ControlChangingDirection direction); - - virtual void mouseAxisBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , ICS::InputControlSystem::NamedAxis axis, ICS::Control::ControlChangingDirection direction); - - virtual void mouseButtonBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , unsigned int button, ICS::Control::ControlChangingDirection direction); - - virtual void mouseWheelBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control - , ICS::InputControlSystem::MouseWheelClick click, ICS::Control::ControlChangingDirection direction); - - virtual void joystickAxisBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control - , int axis, ICS::Control::ControlChangingDirection direction); - - virtual void joystickButtonBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control - , unsigned int button, ICS::Control::ControlChangingDirection direction); - - void clearAllKeyBindings (ICS::Control* control); - void clearAllControllerBindings (ICS::Control* control); - virtual int countSavedGameRecords() const; virtual void write(ESM::ESMWriter& writer, Loading::Listener& progress); virtual void readRecord(ESM::ESMReader& reader, uint32_t type); - virtual void setPlayerControlsEnabled(bool enabled); - virtual void resetIdleTime(); - private: - ICS::InputControlSystem* mInputBinder; + virtual void executeAction(int action); + private: SDLUtil::InputWrapper* mInputWrapper; - std::string mUserFile; - - bool mDragDrop; - bool mGrabCursor; bool mGuiCursorEnabled; - bool mDetectingKeyboard; - ControlSwitch* mControlSwitch; ActionManager* mActionManager; + BindingsManager* mBindingsManager; ControllerManager* mControllerManager; KeyboardManager* mKeyboardManager; MouseManager* mMouseManager; @@ -166,15 +128,11 @@ namespace MWInput void updateCursorMode(); - void quickKey (int index); + void quickKey(int index); void showQuickKeysMenu(); - bool actionIsActive (int id); - void loadKeyDefaults(bool force = false); void loadControllerDefaults(bool force = false); - - int mFakeDeviceID; //As we only support one controller at a time, use a fake deviceID so we don't lose bindings when switching controllers }; } #endif diff --git a/apps/openmw/mwinput/keyboardmanager.cpp b/apps/openmw/mwinput/keyboardmanager.cpp index 773ea4028..efe911593 100644 --- a/apps/openmw/mwinput/keyboardmanager.cpp +++ b/apps/openmw/mwinput/keyboardmanager.cpp @@ -2,10 +2,6 @@ #include -#include - -#include - #include "../mwbase/environment.hpp" #include "../mwbase/inputmanager.hpp" #include "../mwbase/statemanager.hpp" @@ -16,22 +12,18 @@ #include "actionmanager.hpp" #include "actions.hpp" +#include "bindingsmanager.hpp" +#include "sdlmappings.hpp" namespace MWInput { - KeyboardManager::KeyboardManager(ICS::InputControlSystem* inputBinder, SDLUtil::InputWrapper* inputWrapper, ActionManager* actionManager) - : mInputBinder(inputBinder) - , mInputWrapper(inputWrapper) + KeyboardManager::KeyboardManager(BindingsManager* bindingsManager, ActionManager* actionManager) + : mBindingsManager(bindingsManager) , mActionManager(actionManager) , mControlsDisabled(false) { } - bool KeyboardManager::actionIsActive (int id) - { - return (mInputBinder->getChannel(id)->getValue ()==1.0); - } - void KeyboardManager::textInput(const SDL_TextInputEvent &arg) { MyGUI::UString ustring(&arg.text[0]); @@ -42,39 +34,38 @@ namespace MWInput void KeyboardManager::keyPressed(const SDL_KeyboardEvent &arg) { - // HACK: to make Morrowind's default keybinding for the console work without printing an extra "^" upon closing + // HACK: to make default keybinding for the console work without printing an extra "^" upon closing // This assumes that SDL_TextInput events always come *after* the key event // (which is somewhat reasonable, and hopefully true for all SDL platforms) - OIS::KeyCode kc = mInputWrapper->sdl2OISKeyCode(arg.keysym.sym); - if (mInputBinder->getKeyBinding(mInputBinder->getControl(A_Console), ICS::Control::INCREASE) - == arg.keysym.scancode + auto kc = sdlKeyToMyGUI(arg.keysym.sym); + if (mBindingsManager->getKeyBinding(A_Console) == arg.keysym.scancode && MWBase::Environment::get().getWindowManager()->isConsoleMode()) SDL_StopTextInput(); bool consumed = false; - if (kc != OIS::KC_UNASSIGNED && !mInputBinder->detectingBindingState()) + if (kc != MyGUI::KeyCode::None && !mBindingsManager->isDetectingBindingState()) { - consumed = MWBase::Environment::get().getWindowManager()->injectKeyPress(MyGUI::KeyCode::Enum(kc), 0, arg.repeat); + consumed = MWBase::Environment::get().getWindowManager()->injectKeyPress(kc, 0, arg.repeat); if (SDL_IsTextInputActive() && // Little trick to check if key is printable - ( !(SDLK_SCANCODE_MASK & arg.keysym.sym) && std::isprint(arg.keysym.sym))) + (!(SDLK_SCANCODE_MASK & arg.keysym.sym) && std::isprint(arg.keysym.sym))) consumed = true; - MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(!consumed); + mBindingsManager->setPlayerControlsEnabled(!consumed); } if (arg.repeat) return; if (!mControlsDisabled && !consumed) - mInputBinder->keyPressed(arg); + mBindingsManager->keyPressed(arg); MWBase::Environment::get().getInputManager()->setJoystickLastUsed(false); } void KeyboardManager::keyReleased(const SDL_KeyboardEvent &arg) { MWBase::Environment::get().getInputManager()->setJoystickLastUsed(false); - OIS::KeyCode kc = mInputWrapper->sdl2OISKeyCode(arg.keysym.sym); + auto kc = sdlKeyToMyGUI(arg.keysym.sym); - if (!mInputBinder->detectingBindingState()) - MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc))); - mInputBinder->keyReleased(arg); + if (!mBindingsManager->isDetectingBindingState()) + mBindingsManager->setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyRelease(kc)); + mBindingsManager->keyReleased(arg); } } diff --git a/apps/openmw/mwinput/keyboardmanager.hpp b/apps/openmw/mwinput/keyboardmanager.hpp index 9d1c0b4fd..bba2f5dc4 100644 --- a/apps/openmw/mwinput/keyboardmanager.hpp +++ b/apps/openmw/mwinput/keyboardmanager.hpp @@ -9,19 +9,15 @@ namespace SDLUtil class InputWrapper; } -namespace ICS -{ - class InputControlSystem; -} - namespace MWInput { class ActionManager; + class BindingsManager; class KeyboardManager : public SDLUtil::KeyListener { public: - KeyboardManager(ICS::InputControlSystem* inputBinder, SDLUtil::InputWrapper* inputWrapper, ActionManager* actionManager); + KeyboardManager(BindingsManager* bindingsManager, ActionManager* actionManager); virtual ~KeyboardManager() = default; @@ -32,10 +28,7 @@ namespace MWInput void setControlsDisabled(bool disabled) { mControlsDisabled = disabled; } private: - bool actionIsActive(int id); - - ICS::InputControlSystem* mInputBinder; - SDLUtil::InputWrapper* mInputWrapper; + BindingsManager* mBindingsManager; ActionManager* mActionManager; diff --git a/apps/openmw/mwinput/mousemanager.cpp b/apps/openmw/mwinput/mousemanager.cpp index 3fbfc7813..30e32bef8 100644 --- a/apps/openmw/mwinput/mousemanager.cpp +++ b/apps/openmw/mwinput/mousemanager.cpp @@ -8,8 +8,6 @@ #include #include -#include - #include "../mwbase/environment.hpp" #include "../mwbase/inputmanager.hpp" #include "../mwbase/windowmanager.hpp" @@ -18,16 +16,17 @@ #include "../mwworld/player.hpp" #include "actions.hpp" +#include "bindingsmanager.hpp" #include "sdlmappings.hpp" namespace MWInput { - MouseManager::MouseManager(ICS::InputControlSystem* inputBinder, SDLUtil::InputWrapper* inputWrapper, SDL_Window* window) + MouseManager::MouseManager(BindingsManager* bindingsManager, SDLUtil::InputWrapper* inputWrapper, SDL_Window* window) : mInvertX(Settings::Manager::getBool("invert x axis", "Input")) , mInvertY(Settings::Manager::getBool("invert y axis", "Input")) , mCameraSensitivity (Settings::Manager::getFloat("camera sensitivity", "Input")) , mCameraYMultiplier (Settings::Manager::getFloat("camera y multiplier", "Input")) - , mInputBinder(inputBinder) + , mBindingsManager(bindingsManager) , mInputWrapper(inputWrapper) , mInvUiScalingFactor(1.f) , mGuiCursorX(0) @@ -54,22 +53,22 @@ namespace MWInput void MouseManager::processChangedSettings(const Settings::CategorySettingVector& changed) { - for (Settings::CategorySettingVector::const_iterator it = changed.begin(); it != changed.end(); ++it) + for (const auto& setting : changed) { - if (it->first == "Input" && it->second == "invert x axis") + if (setting.first == "Input" && setting.second == "invert x axis") mInvertX = Settings::Manager::getBool("invert x axis", "Input"); - if (it->first == "Input" && it->second == "invert y axis") + if (setting.first == "Input" && setting.second == "invert y axis") mInvertY = Settings::Manager::getBool("invert y axis", "Input"); - if (it->first == "Input" && it->second == "camera sensitivity") + if (setting.first == "Input" && setting.second == "camera sensitivity") mCameraSensitivity = Settings::Manager::getFloat("camera sensitivity", "Input"); } } void MouseManager::mouseMoved(const SDLUtil::MouseMotionEvent &arg) { - mInputBinder->mouseMoved (arg); + mBindingsManager->mouseMoved(arg); MWBase::InputManager* input = MWBase::Environment::get().getInputManager(); input->setJoystickLastUsed(false); @@ -122,26 +121,26 @@ namespace MWInput { MWBase::Environment::get().getInputManager()->setJoystickLastUsed(false); - if(mInputBinder->detectingBindingState()) + if(mBindingsManager->isDetectingBindingState()) { - mInputBinder->mouseReleased (arg, id); + mBindingsManager->mouseReleased(arg, id); } else { bool guiMode = MWBase::Environment::get().getWindowManager()->isGuiMode(); guiMode = MyGUI::InputManager::getInstance().injectMouseRelease(static_cast(mGuiCursorX), static_cast(mGuiCursorY), sdlButtonToMyGUI(id)) && guiMode; - if(mInputBinder->detectingBindingState()) return; // don't allow same mouseup to bind as initiated bind + if(mBindingsManager->isDetectingBindingState()) return; // don't allow same mouseup to bind as initiated bind - MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(!guiMode); - mInputBinder->mouseReleased (arg, id); + mBindingsManager->setPlayerControlsEnabled(!guiMode); + mBindingsManager->mouseReleased(arg, id); } } void MouseManager::mouseWheelMoved(const SDL_MouseWheelEvent &arg) { - if (mInputBinder->detectingBindingState() || !mControlsDisabled) - mInputBinder->mouseWheelMoved(arg); + if (mBindingsManager->isDetectingBindingState() || !mControlsDisabled) + mBindingsManager->mouseWheelMoved(arg); MWBase::Environment::get().getInputManager()->setJoystickLastUsed(false); } @@ -166,11 +165,11 @@ namespace MWInput MWBase::Environment::get().getWindowManager()->setCursorActive(true); } - MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(!guiMode); + mBindingsManager->setPlayerControlsEnabled(!guiMode); // Don't trigger any mouse bindings while in settings menu, otherwise rebinding controls becomes impossible if (MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_Settings) - mInputBinder->mousePressed (arg, id); + mBindingsManager->mousePressed(arg, id); } void MouseManager::update(float dt, bool disableControls) @@ -180,8 +179,8 @@ namespace MWInput if (!mMouseLookEnabled) return; - float xAxis = mInputBinder->getChannel(A_LookLeftRight)->getValue()*2.0f-1.0f; - float yAxis = mInputBinder->getChannel(A_LookUpDown)->getValue()*2.0f-1.0f; + float xAxis = mBindingsManager->getActionValue(A_LookLeftRight)*2.0f-1.0f; + float yAxis = mBindingsManager->getActionValue(A_LookUpDown)*2.0f-1.0f; if (xAxis == 0 && yAxis == 0) return; diff --git a/apps/openmw/mwinput/mousemanager.hpp b/apps/openmw/mwinput/mousemanager.hpp index 6e59a639b..2686c59b7 100644 --- a/apps/openmw/mwinput/mousemanager.hpp +++ b/apps/openmw/mwinput/mousemanager.hpp @@ -9,22 +9,14 @@ namespace SDLUtil class InputWrapper; } -namespace MWWorld -{ - class Player; -} - -namespace ICS -{ - class InputControlSystem; -} - namespace MWInput { + class BindingsManager; + class MouseManager : public SDLUtil::MouseListener { public: - MouseManager(ICS::InputControlSystem* inputBinder, SDLUtil::InputWrapper* inputWrapper, SDL_Window* window); + MouseManager(BindingsManager* bindingsManager, SDLUtil::InputWrapper* inputWrapper, SDL_Window* window); virtual ~MouseManager() = default; @@ -53,7 +45,7 @@ namespace MWInput float mCameraSensitivity; float mCameraYMultiplier; - ICS::InputControlSystem* mInputBinder; + BindingsManager* mBindingsManager; SDLUtil::InputWrapper* mInputWrapper; float mInvUiScalingFactor; diff --git a/apps/openmw/mwinput/sdlmappings.cpp b/apps/openmw/mwinput/sdlmappings.cpp index 53c9e77fe..8a9ccf4e7 100644 --- a/apps/openmw/mwinput/sdlmappings.cpp +++ b/apps/openmw/mwinput/sdlmappings.cpp @@ -1,5 +1,7 @@ #include "sdlmappings.hpp" +#include + #include #include @@ -78,4 +80,142 @@ namespace MWInput //MyGUI's buttons are 0 indexed return MyGUI::MouseButton::Enum(button - 1); } + + void initKeyMap(std::map& keyMap) + { + keyMap[SDLK_UNKNOWN] = MyGUI::KeyCode::None; + keyMap[SDLK_ESCAPE] = MyGUI::KeyCode::Escape; + keyMap[SDLK_1] = MyGUI::KeyCode::One; + keyMap[SDLK_2] = MyGUI::KeyCode::Two; + keyMap[SDLK_3] = MyGUI::KeyCode::Three; + keyMap[SDLK_4] = MyGUI::KeyCode::Four; + keyMap[SDLK_5] = MyGUI::KeyCode::Five; + keyMap[SDLK_6] = MyGUI::KeyCode::Six; + keyMap[SDLK_7] = MyGUI::KeyCode::Seven; + keyMap[SDLK_8] = MyGUI::KeyCode::Eight; + keyMap[SDLK_9] = MyGUI::KeyCode::Nine; + keyMap[SDLK_0] = MyGUI::KeyCode::Zero; + keyMap[SDLK_MINUS] = MyGUI::KeyCode::Minus; + keyMap[SDLK_EQUALS] = MyGUI::KeyCode::Equals; + keyMap[SDLK_BACKSPACE] = MyGUI::KeyCode::Backspace; + keyMap[SDLK_TAB] = MyGUI::KeyCode::Tab; + keyMap[SDLK_q] = MyGUI::KeyCode::Q; + keyMap[SDLK_w] = MyGUI::KeyCode::W; + keyMap[SDLK_e] = MyGUI::KeyCode::E; + keyMap[SDLK_r] = MyGUI::KeyCode::R; + keyMap[SDLK_t] = MyGUI::KeyCode::T; + keyMap[SDLK_y] = MyGUI::KeyCode::Y; + keyMap[SDLK_u] = MyGUI::KeyCode::U; + keyMap[SDLK_i] = MyGUI::KeyCode::I; + keyMap[SDLK_o] = MyGUI::KeyCode::O; + keyMap[SDLK_p] = MyGUI::KeyCode::P; + keyMap[SDLK_RETURN] = MyGUI::KeyCode::Return; + keyMap[SDLK_a] = MyGUI::KeyCode::A; + keyMap[SDLK_s] = MyGUI::KeyCode::S; + keyMap[SDLK_d] = MyGUI::KeyCode::D; + keyMap[SDLK_f] = MyGUI::KeyCode::F; + keyMap[SDLK_g] = MyGUI::KeyCode::G; + keyMap[SDLK_h] = MyGUI::KeyCode::H; + keyMap[SDLK_j] = MyGUI::KeyCode::J; + keyMap[SDLK_k] = MyGUI::KeyCode::K; + keyMap[SDLK_l] = MyGUI::KeyCode::L; + keyMap[SDLK_SEMICOLON] = MyGUI::KeyCode::Semicolon; + keyMap[SDLK_QUOTE] = MyGUI::KeyCode::Apostrophe; + keyMap[SDLK_BACKQUOTE] = MyGUI::KeyCode::Grave; + keyMap[SDLK_LSHIFT] = MyGUI::KeyCode::LeftShift; + keyMap[SDLK_BACKSLASH] = MyGUI::KeyCode::Backslash; + keyMap[SDLK_z] = MyGUI::KeyCode::Z; + keyMap[SDLK_x] = MyGUI::KeyCode::X; + keyMap[SDLK_c] = MyGUI::KeyCode::C; + keyMap[SDLK_v] = MyGUI::KeyCode::V; + keyMap[SDLK_b] = MyGUI::KeyCode::B; + keyMap[SDLK_n] = MyGUI::KeyCode::N; + keyMap[SDLK_m] = MyGUI::KeyCode::M; + keyMap[SDLK_COMMA] = MyGUI::KeyCode::Comma; + keyMap[SDLK_PERIOD] = MyGUI::KeyCode::Period; + keyMap[SDLK_SLASH] = MyGUI::KeyCode::Slash; + keyMap[SDLK_RSHIFT] = MyGUI::KeyCode::RightShift; + keyMap[SDLK_KP_MULTIPLY] = MyGUI::KeyCode::Multiply; + keyMap[SDLK_LALT] = MyGUI::KeyCode::LeftAlt; + keyMap[SDLK_SPACE] = MyGUI::KeyCode::Space; + keyMap[SDLK_CAPSLOCK] = MyGUI::KeyCode::Capital; + keyMap[SDLK_F1] = MyGUI::KeyCode::F1; + keyMap[SDLK_F2] = MyGUI::KeyCode::F2; + keyMap[SDLK_F3] = MyGUI::KeyCode::F3; + keyMap[SDLK_F4] = MyGUI::KeyCode::F4; + keyMap[SDLK_F5] = MyGUI::KeyCode::F5; + keyMap[SDLK_F6] = MyGUI::KeyCode::F6; + keyMap[SDLK_F7] = MyGUI::KeyCode::F7; + keyMap[SDLK_F8] = MyGUI::KeyCode::F8; + keyMap[SDLK_F9] = MyGUI::KeyCode::F9; + keyMap[SDLK_F10] = MyGUI::KeyCode::F10; + keyMap[SDLK_NUMLOCKCLEAR] = MyGUI::KeyCode::NumLock; + keyMap[SDLK_SCROLLLOCK] = MyGUI::KeyCode::ScrollLock; + keyMap[SDLK_KP_7] = MyGUI::KeyCode::Numpad7; + keyMap[SDLK_KP_8] = MyGUI::KeyCode::Numpad8; + keyMap[SDLK_KP_9] = MyGUI::KeyCode::Numpad9; + keyMap[SDLK_KP_MINUS] = MyGUI::KeyCode::Subtract; + keyMap[SDLK_KP_4] = MyGUI::KeyCode::Numpad4; + keyMap[SDLK_KP_5] = MyGUI::KeyCode::Numpad5; + keyMap[SDLK_KP_6] = MyGUI::KeyCode::Numpad6; + keyMap[SDLK_KP_PLUS] = MyGUI::KeyCode::Add; + keyMap[SDLK_KP_1] = MyGUI::KeyCode::Numpad1; + keyMap[SDLK_KP_2] = MyGUI::KeyCode::Numpad2; + keyMap[SDLK_KP_3] = MyGUI::KeyCode::Numpad3; + keyMap[SDLK_KP_0] = MyGUI::KeyCode::Numpad0; + keyMap[SDLK_KP_PERIOD] = MyGUI::KeyCode::Decimal; + keyMap[SDLK_F11] = MyGUI::KeyCode::F11; + keyMap[SDLK_F12] = MyGUI::KeyCode::F12; + keyMap[SDLK_F13] = MyGUI::KeyCode::F13; + keyMap[SDLK_F14] = MyGUI::KeyCode::F14; + keyMap[SDLK_F15] = MyGUI::KeyCode::F15; + keyMap[SDLK_KP_EQUALS] = MyGUI::KeyCode::NumpadEquals; + keyMap[SDLK_COLON] = MyGUI::KeyCode::Colon; + keyMap[SDLK_KP_ENTER] = MyGUI::KeyCode::NumpadEnter; + keyMap[SDLK_KP_DIVIDE] = MyGUI::KeyCode::Divide; + keyMap[SDLK_SYSREQ] = MyGUI::KeyCode::SysRq; + keyMap[SDLK_RALT] = MyGUI::KeyCode::RightAlt; + keyMap[SDLK_HOME] = MyGUI::KeyCode::Home; + keyMap[SDLK_UP] = MyGUI::KeyCode::ArrowUp; + keyMap[SDLK_PAGEUP] = MyGUI::KeyCode::PageUp; + keyMap[SDLK_LEFT] = MyGUI::KeyCode::ArrowLeft; + keyMap[SDLK_RIGHT] = MyGUI::KeyCode::ArrowRight; + keyMap[SDLK_END] = MyGUI::KeyCode::End; + keyMap[SDLK_DOWN] = MyGUI::KeyCode::ArrowDown; + keyMap[SDLK_PAGEDOWN] = MyGUI::KeyCode::PageDown; + keyMap[SDLK_INSERT] = MyGUI::KeyCode::Insert; + keyMap[SDLK_DELETE] = MyGUI::KeyCode::Delete; + keyMap[SDLK_APPLICATION] = MyGUI::KeyCode::AppMenu; + +//The function of the Ctrl and Meta keys are switched on macOS compared to other platforms. +//For instance] = Cmd+C versus Ctrl+C to copy from the system clipboard +#if defined(__APPLE__) + keyMap[SDLK_LGUI] = MyGUI::KeyCode::LeftControl; + keyMap[SDLK_RGUI] = MyGUI::KeyCode::RightControl; + keyMap[SDLK_LCTRL] = MyGUI::KeyCode::LeftWindows; + keyMap[SDLK_RCTRL] = MyGUI::KeyCode::RightWindows; +#else + keyMap[SDLK_LGUI] = MyGUI::KeyCode::LeftWindows; + keyMap[SDLK_RGUI] = MyGUI::KeyCode::RightWindows; + keyMap[SDLK_LCTRL] = MyGUI::KeyCode::LeftControl; + keyMap[SDLK_RCTRL] = MyGUI::KeyCode::RightControl; +#endif + } + + MyGUI::KeyCode sdlKeyToMyGUI(SDL_Keycode code) + { + static std::map keyMap; + if (keyMap.empty()) + { + initKeyMap(keyMap); + } + + MyGUI::KeyCode kc = MyGUI::KeyCode::None; + + auto foundKey = keyMap.find(code); + if(foundKey != keyMap.end()) + kc = foundKey->second; + + return kc; + } } diff --git a/apps/openmw/mwinput/sdlmappings.hpp b/apps/openmw/mwinput/sdlmappings.hpp index dd6d750cb..0cdd4694f 100644 --- a/apps/openmw/mwinput/sdlmappings.hpp +++ b/apps/openmw/mwinput/sdlmappings.hpp @@ -3,7 +3,9 @@ #include -#include +#include + +#include namespace MyGUI { @@ -17,5 +19,7 @@ namespace MWInput std::string sdlControllerAxisToString(int axis); MyGUI::MouseButton sdlButtonToMyGUI(Uint8 button); + + MyGUI::KeyCode sdlKeyToMyGUI(SDL_Keycode code); } #endif diff --git a/apps/openmw/mwinput/sensormanager.cpp b/apps/openmw/mwinput/sensormanager.cpp index 27879d214..f78607fa2 100644 --- a/apps/openmw/mwinput/sensormanager.cpp +++ b/apps/openmw/mwinput/sensormanager.cpp @@ -156,30 +156,30 @@ namespace MWInput void SensorManager::processChangedSettings(const Settings::CategorySettingVector& changed) { - for (Settings::CategorySettingVector::const_iterator it = changed.begin(); it != changed.end(); ++it) + for (const auto& setting : changed) { - if (it->first == "Input" && it->second == "invert x axis") + if (setting.first == "Input" && setting.second == "invert x axis") mInvertX = Settings::Manager::getBool("invert x axis", "Input"); - if (it->first == "Input" && it->second == "invert y axis") + if (setting.first == "Input" && setting.second == "invert y axis") mInvertY = Settings::Manager::getBool("invert y axis", "Input"); - if (it->first == "Input" && it->second == "gyro horizontal sensitivity") + if (setting.first == "Input" && setting.second == "gyro horizontal sensitivity") mGyroHSensitivity = Settings::Manager::getFloat("gyro horizontal sensitivity", "Input"); - if (it->first == "Input" && it->second == "gyro vertical sensitivity") + if (setting.first == "Input" && setting.second == "gyro vertical sensitivity") mGyroVSensitivity = Settings::Manager::getFloat("gyro vertical sensitivity", "Input"); - if (it->first == "Input" && it->second == "enable gyroscope") + if (setting.first == "Input" && setting.second == "enable gyroscope") init(); - if (it->first == "Input" && it->second == "gyro horizontal axis") + if (setting.first == "Input" && setting.second == "gyro horizontal axis") correctGyroscopeAxes(); - if (it->first == "Input" && it->second == "gyro vertical axis") + if (setting.first == "Input" && setting.second == "gyro vertical axis") correctGyroscopeAxes(); - if (it->first == "Input" && it->second == "gyro input threshold") + if (setting.first == "Input" && setting.second == "gyro input threshold") mGyroInputThreshold = Settings::Manager::getFloat("gyro input threshold", "Input"); } } diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 06c777c02..a7d70b4e0 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -139,7 +139,7 @@ add_component_dir (fontloader ) add_component_dir (sdlutil - sdlgraphicswindow imagetosurface sdlinputwrapper sdlvideowrapper OISCompat events sdlcursormanager + sdlgraphicswindow imagetosurface sdlinputwrapper sdlvideowrapper events sdlcursormanager ) add_component_dir (version diff --git a/components/sdlutil/OISCompat.hpp b/components/sdlutil/OISCompat.hpp deleted file mode 100644 index a0acc5837..000000000 --- a/components/sdlutil/OISCompat.hpp +++ /dev/null @@ -1,159 +0,0 @@ -#ifndef OIS_SDL_COMPAT_H -#define OIS_SDL_COMPAT_H - -#include -#include - -namespace OIS -{ -//! Keyboard scan codes -enum KeyCode -{ - KC_UNASSIGNED = 0x00, - KC_ESCAPE = 0x01, - KC_1 = 0x02, - KC_2 = 0x03, - KC_3 = 0x04, - KC_4 = 0x05, - KC_5 = 0x06, - KC_6 = 0x07, - KC_7 = 0x08, - KC_8 = 0x09, - KC_9 = 0x0A, - KC_0 = 0x0B, - KC_MINUS = 0x0C, // - on main keyboard - KC_EQUALS = 0x0D, - KC_BACK = 0x0E, // backspace - KC_TAB = 0x0F, - KC_Q = 0x10, - KC_W = 0x11, - KC_E = 0x12, - KC_R = 0x13, - KC_T = 0x14, - KC_Y = 0x15, - KC_U = 0x16, - KC_I = 0x17, - KC_O = 0x18, - KC_P = 0x19, - KC_LBRACKET = 0x1A, - KC_RBRACKET = 0x1B, - KC_RETURN = 0x1C, // Enter on main keyboard - KC_LCONTROL = 0x1D, - KC_A = 0x1E, - KC_S = 0x1F, - KC_D = 0x20, - KC_F = 0x21, - KC_G = 0x22, - KC_H = 0x23, - KC_J = 0x24, - KC_K = 0x25, - KC_L = 0x26, - KC_SEMICOLON = 0x27, - KC_APOSTROPHE = 0x28, - KC_GRAVE = 0x29, // accent - KC_LSHIFT = 0x2A, - KC_BACKSLASH = 0x2B, - KC_Z = 0x2C, - KC_X = 0x2D, - KC_C = 0x2E, - KC_V = 0x2F, - KC_B = 0x30, - KC_N = 0x31, - KC_M = 0x32, - KC_COMMA = 0x33, - KC_PERIOD = 0x34, // . on main keyboard - KC_SLASH = 0x35, // / on main keyboard - KC_RSHIFT = 0x36, - KC_MULTIPLY = 0x37, // * on numeric keypad - KC_LMENU = 0x38, // left Alt - KC_SPACE = 0x39, - KC_CAPITAL = 0x3A, - KC_F1 = 0x3B, - KC_F2 = 0x3C, - KC_F3 = 0x3D, - KC_F4 = 0x3E, - KC_F5 = 0x3F, - KC_F6 = 0x40, - KC_F7 = 0x41, - KC_F8 = 0x42, - KC_F9 = 0x43, - KC_F10 = 0x44, - KC_NUMLOCK = 0x45, - KC_SCROLL = 0x46, // Scroll Lock - KC_NUMPAD7 = 0x47, - KC_NUMPAD8 = 0x48, - KC_NUMPAD9 = 0x49, - KC_SUBTRACT = 0x4A, // - on numeric keypad - KC_NUMPAD4 = 0x4B, - KC_NUMPAD5 = 0x4C, - KC_NUMPAD6 = 0x4D, - KC_ADD = 0x4E, // + on numeric keypad - KC_NUMPAD1 = 0x4F, - KC_NUMPAD2 = 0x50, - KC_NUMPAD3 = 0x51, - KC_NUMPAD0 = 0x52, - KC_DECIMAL = 0x53, // . on numeric keypad - KC_OEM_102 = 0x56, // < > | on UK/Germany keyboards - KC_F11 = 0x57, - KC_F12 = 0x58, - KC_F13 = 0x64, // (NEC PC98) - KC_F14 = 0x65, // (NEC PC98) - KC_F15 = 0x66, // (NEC PC98) - KC_KANA = 0x70, // (Japanese keyboard) - KC_ABNT_C1 = 0x73, // / ? on Portugese (Brazilian) keyboards - KC_CONVERT = 0x79, // (Japanese keyboard) - KC_NOCONVERT = 0x7B, // (Japanese keyboard) - KC_YEN = 0x7D, // (Japanese keyboard) - KC_ABNT_C2 = 0x7E, // Numpad . on Portugese (Brazilian) keyboards - KC_NUMPADEQUALS= 0x8D, // = on numeric keypad (NEC PC98) - KC_PREVTRACK = 0x90, // Previous Track (KC_CIRCUMFLEX on Japanese keyboard) - KC_AT = 0x91, // (NEC PC98) - KC_COLON = 0x92, // (NEC PC98) - KC_UNDERLINE = 0x93, // (NEC PC98) - KC_KANJI = 0x94, // (Japanese keyboard) - KC_STOP = 0x95, // (NEC PC98) - KC_AX = 0x96, // (Japan AX) - KC_UNLABELED = 0x97, // (J3100) - KC_NEXTTRACK = 0x99, // Next Track - KC_NUMPADENTER = 0x9C, // Enter on numeric keypad - KC_RCONTROL = 0x9D, - KC_MUTE = 0xA0, // Mute - KC_CALCULATOR = 0xA1, // Calculator - KC_PLAYPAUSE = 0xA2, // Play / Pause - KC_MEDIASTOP = 0xA4, // Media Stop - KC_VOLUMEDOWN = 0xAE, // Volume - - KC_VOLUMEUP = 0xB0, // Volume + - KC_WEBHOME = 0xB2, // Web home - KC_NUMPADCOMMA = 0xB3, // , on numeric keypad (NEC PC98) - KC_DIVIDE = 0xB5, // / on numeric keypad - KC_SYSRQ = 0xB7, - KC_RMENU = 0xB8, // right Alt - KC_PAUSE = 0xC5, // Pause - KC_HOME = 0xC7, // Home on arrow keypad - KC_UP = 0xC8, // UpArrow on arrow keypad - KC_PGUP = 0xC9, // PgUp on arrow keypad - KC_LEFT = 0xCB, // LeftArrow on arrow keypad - KC_RIGHT = 0xCD, // RightArrow on arrow keypad - KC_END = 0xCF, // End on arrow keypad - KC_DOWN = 0xD0, // DownArrow on arrow keypad - KC_PGDOWN = 0xD1, // PgDn on arrow keypad - KC_INSERT = 0xD2, // Insert on arrow keypad - KC_DELETE = 0xD3, // Delete on arrow keypad - KC_LWIN = 0xDB, // Left Windows key - KC_RWIN = 0xDC, // Right Windows key - KC_APPS = 0xDD, // AppMenu key - KC_POWER = 0xDE, // System Power - KC_SLEEP = 0xDF, // System Sleep - KC_WAKE = 0xE3, // System Wake - KC_WEBSEARCH = 0xE5, // Web Search - KC_WEBFAVORITES= 0xE6, // Web Favorites - KC_WEBREFRESH = 0xE7, // Web Refresh - KC_WEBSTOP = 0xE8, // Web Stop - KC_WEBFORWARD = 0xE9, // Web Forward - KC_WEBBACK = 0xEA, // Web Back - KC_MYCOMPUTER = 0xEB, // My Computer - KC_MAIL = 0xEC, // Mail - KC_MEDIASELECT = 0xED // Media Select -}; -} -#endif diff --git a/components/sdlutil/sdlinputwrapper.cpp b/components/sdlutil/sdlinputwrapper.cpp index 3ea11c6d0..8d6a124e2 100644 --- a/components/sdlutil/sdlinputwrapper.cpp +++ b/components/sdlutil/sdlinputwrapper.cpp @@ -33,8 +33,6 @@ InputWrapper::InputWrapper(SDL_Window* window, osg::ref_ptr v mWindowHasFocus(true), mMouseInWindow(true) { - _setupOISKeys(); - Uint32 flags = SDL_GetWindowFlags(mSDLWindow); mWindowHasFocus = (flags & SDL_WINDOW_INPUT_FOCUS); mMouseInWindow = (flags & SDL_WINDOW_MOUSE_FOCUS); @@ -397,139 +395,4 @@ InputWrapper::InputWrapper(SDL_Window* window, osg::ref_ptr v return pack_evt; } - - OIS::KeyCode InputWrapper::sdl2OISKeyCode(SDL_Keycode code) - { - OIS::KeyCode kc = OIS::KC_UNASSIGNED; - - KeyMap::const_iterator ois_equiv = mKeyMap.find(code); - - if(ois_equiv != mKeyMap.end()) - kc = ois_equiv->second; - - return kc; - } - - void InputWrapper::_setupOISKeys() - { - //lifted from OIS's SDLKeyboard.cpp - - 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) ); - mKeyMap.insert( KeyMap::value_type(SDLK_2, OIS::KC_2) ); - mKeyMap.insert( KeyMap::value_type(SDLK_3, OIS::KC_3) ); - mKeyMap.insert( KeyMap::value_type(SDLK_4, OIS::KC_4) ); - mKeyMap.insert( KeyMap::value_type(SDLK_5, OIS::KC_5) ); - mKeyMap.insert( KeyMap::value_type(SDLK_6, OIS::KC_6) ); - mKeyMap.insert( KeyMap::value_type(SDLK_7, OIS::KC_7) ); - mKeyMap.insert( KeyMap::value_type(SDLK_8, OIS::KC_8) ); - mKeyMap.insert( KeyMap::value_type(SDLK_9, OIS::KC_9) ); - mKeyMap.insert( KeyMap::value_type(SDLK_0, OIS::KC_0) ); - mKeyMap.insert( KeyMap::value_type(SDLK_MINUS, OIS::KC_MINUS) ); - mKeyMap.insert( KeyMap::value_type(SDLK_EQUALS, OIS::KC_EQUALS) ); - mKeyMap.insert( KeyMap::value_type(SDLK_BACKSPACE, OIS::KC_BACK) ); - mKeyMap.insert( KeyMap::value_type(SDLK_TAB, OIS::KC_TAB) ); - mKeyMap.insert( KeyMap::value_type(SDLK_q, OIS::KC_Q) ); - mKeyMap.insert( KeyMap::value_type(SDLK_w, OIS::KC_W) ); - mKeyMap.insert( KeyMap::value_type(SDLK_e, OIS::KC_E) ); - mKeyMap.insert( KeyMap::value_type(SDLK_r, OIS::KC_R) ); - mKeyMap.insert( KeyMap::value_type(SDLK_t, OIS::KC_T) ); - mKeyMap.insert( KeyMap::value_type(SDLK_y, OIS::KC_Y) ); - mKeyMap.insert( KeyMap::value_type(SDLK_u, OIS::KC_U) ); - mKeyMap.insert( KeyMap::value_type(SDLK_i, OIS::KC_I) ); - mKeyMap.insert( KeyMap::value_type(SDLK_o, OIS::KC_O) ); - mKeyMap.insert( KeyMap::value_type(SDLK_p, OIS::KC_P) ); - mKeyMap.insert( KeyMap::value_type(SDLK_RETURN, OIS::KC_RETURN) ); - mKeyMap.insert( KeyMap::value_type(SDLK_a, OIS::KC_A) ); - mKeyMap.insert( KeyMap::value_type(SDLK_s, OIS::KC_S) ); - mKeyMap.insert( KeyMap::value_type(SDLK_d, OIS::KC_D) ); - mKeyMap.insert( KeyMap::value_type(SDLK_f, OIS::KC_F) ); - mKeyMap.insert( KeyMap::value_type(SDLK_g, OIS::KC_G) ); - mKeyMap.insert( KeyMap::value_type(SDLK_h, OIS::KC_H) ); - mKeyMap.insert( KeyMap::value_type(SDLK_j, OIS::KC_J) ); - mKeyMap.insert( KeyMap::value_type(SDLK_k, OIS::KC_K) ); - mKeyMap.insert( KeyMap::value_type(SDLK_l, OIS::KC_L) ); - mKeyMap.insert( KeyMap::value_type(SDLK_SEMICOLON, OIS::KC_SEMICOLON) ); - mKeyMap.insert( KeyMap::value_type(SDLK_COLON, OIS::KC_COLON) ); - mKeyMap.insert( KeyMap::value_type(SDLK_QUOTE, OIS::KC_APOSTROPHE) ); - mKeyMap.insert( KeyMap::value_type(SDLK_BACKQUOTE, OIS::KC_GRAVE) ); - mKeyMap.insert( KeyMap::value_type(SDLK_LSHIFT, OIS::KC_LSHIFT) ); - mKeyMap.insert( KeyMap::value_type(SDLK_BACKSLASH, OIS::KC_BACKSLASH) ); - mKeyMap.insert( KeyMap::value_type(SDLK_SLASH, OIS::KC_SLASH) ); - mKeyMap.insert( KeyMap::value_type(SDLK_z, OIS::KC_Z) ); - mKeyMap.insert( KeyMap::value_type(SDLK_x, OIS::KC_X) ); - mKeyMap.insert( KeyMap::value_type(SDLK_c, OIS::KC_C) ); - mKeyMap.insert( KeyMap::value_type(SDLK_v, OIS::KC_V) ); - mKeyMap.insert( KeyMap::value_type(SDLK_b, OIS::KC_B) ); - mKeyMap.insert( KeyMap::value_type(SDLK_n, OIS::KC_N) ); - mKeyMap.insert( KeyMap::value_type(SDLK_m, OIS::KC_M) ); - mKeyMap.insert( KeyMap::value_type(SDLK_COMMA, OIS::KC_COMMA) ); - mKeyMap.insert( KeyMap::value_type(SDLK_PERIOD, OIS::KC_PERIOD)); - mKeyMap.insert( KeyMap::value_type(SDLK_RSHIFT, OIS::KC_RSHIFT)); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_MULTIPLY, OIS::KC_MULTIPLY) ); - mKeyMap.insert( KeyMap::value_type(SDLK_LALT, OIS::KC_LMENU) ); - mKeyMap.insert( KeyMap::value_type(SDLK_SPACE, OIS::KC_SPACE)); - mKeyMap.insert( KeyMap::value_type(SDLK_CAPSLOCK, OIS::KC_CAPITAL) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F1, OIS::KC_F1) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F2, OIS::KC_F2) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F3, OIS::KC_F3) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F4, OIS::KC_F4) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F5, OIS::KC_F5) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F6, OIS::KC_F6) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F7, OIS::KC_F7) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F8, OIS::KC_F8) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F9, OIS::KC_F9) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F10, OIS::KC_F10) ); - mKeyMap.insert( KeyMap::value_type(SDLK_NUMLOCKCLEAR, OIS::KC_NUMLOCK) ); - mKeyMap.insert( KeyMap::value_type(SDLK_SCROLLLOCK, OIS::KC_SCROLL)); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_7, OIS::KC_NUMPAD7) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_8, OIS::KC_NUMPAD8) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_9, OIS::KC_NUMPAD9) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_MINUS, OIS::KC_SUBTRACT) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_4, OIS::KC_NUMPAD4) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_5, OIS::KC_NUMPAD5) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_6, OIS::KC_NUMPAD6) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_PLUS, OIS::KC_ADD) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_1, OIS::KC_NUMPAD1) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_2, OIS::KC_NUMPAD2) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_3, OIS::KC_NUMPAD3) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_0, OIS::KC_NUMPAD0) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_PERIOD, OIS::KC_DECIMAL) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F11, OIS::KC_F11) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F12, OIS::KC_F12) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F13, OIS::KC_F13) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F14, OIS::KC_F14) ); - mKeyMap.insert( KeyMap::value_type(SDLK_F15, OIS::KC_F15) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_EQUALS, OIS::KC_NUMPADEQUALS) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_DIVIDE, OIS::KC_DIVIDE) ); - mKeyMap.insert( KeyMap::value_type(SDLK_SYSREQ, OIS::KC_SYSRQ) ); - mKeyMap.insert( KeyMap::value_type(SDLK_RALT, OIS::KC_RMENU) ); - mKeyMap.insert( KeyMap::value_type(SDLK_HOME, OIS::KC_HOME) ); - mKeyMap.insert( KeyMap::value_type(SDLK_UP, OIS::KC_UP) ); - mKeyMap.insert( KeyMap::value_type(SDLK_PAGEUP, OIS::KC_PGUP) ); - mKeyMap.insert( KeyMap::value_type(SDLK_LEFT, OIS::KC_LEFT) ); - mKeyMap.insert( KeyMap::value_type(SDLK_RIGHT, OIS::KC_RIGHT) ); - mKeyMap.insert( KeyMap::value_type(SDLK_END, OIS::KC_END) ); - mKeyMap.insert( KeyMap::value_type(SDLK_DOWN, OIS::KC_DOWN) ); - mKeyMap.insert( KeyMap::value_type(SDLK_PAGEDOWN, OIS::KC_PGDOWN) ); - mKeyMap.insert( KeyMap::value_type(SDLK_INSERT, OIS::KC_INSERT) ); - mKeyMap.insert( KeyMap::value_type(SDLK_DELETE, OIS::KC_DELETE) ); - mKeyMap.insert( KeyMap::value_type(SDLK_KP_ENTER, OIS::KC_NUMPADENTER) ); - mKeyMap.insert( KeyMap::value_type(SDLK_APPLICATION, OIS::KC_APPS) ); - -//The function of the Ctrl and Meta keys are switched on macOS compared to other platforms. -//For instance, Cmd+C versus Ctrl+C to copy from the system clipboard -#if defined(__APPLE__) - mKeyMap.insert( KeyMap::value_type(SDLK_LGUI, OIS::KC_LCONTROL) ); - mKeyMap.insert( KeyMap::value_type(SDLK_RGUI, OIS::KC_RCONTROL) ); - mKeyMap.insert( KeyMap::value_type(SDLK_LCTRL, OIS::KC_LWIN)); - mKeyMap.insert( KeyMap::value_type(SDLK_RCTRL, OIS::KC_RWIN) ); -#else - mKeyMap.insert( KeyMap::value_type(SDLK_LGUI, OIS::KC_LWIN) ); - mKeyMap.insert( KeyMap::value_type(SDLK_RGUI, OIS::KC_RWIN) ); - mKeyMap.insert( KeyMap::value_type(SDLK_LCTRL, OIS::KC_LCONTROL)); - mKeyMap.insert( KeyMap::value_type(SDLK_RCTRL, OIS::KC_RCONTROL) ); -#endif - } } diff --git a/components/sdlutil/sdlinputwrapper.hpp b/components/sdlutil/sdlinputwrapper.hpp index fde37f35f..39b6530fe 100644 --- a/components/sdlutil/sdlinputwrapper.hpp +++ b/components/sdlutil/sdlinputwrapper.hpp @@ -8,7 +8,6 @@ #include #include -#include "OISCompat.hpp" #include "events.hpp" namespace osgViewer @@ -40,8 +39,6 @@ namespace SDLUtil bool getMouseRelative() { return mMouseRelative; } void setGrabPointer(bool grab); - OIS::KeyCode sdl2OISKeyCode(SDL_Keycode code); - void warpMouse(int x, int y); void updateMouseSettings(); @@ -53,8 +50,6 @@ namespace SDLUtil void _wrapMousePointer(const SDL_MouseMotionEvent &evt); MouseMotionEvent _packageMouseMotion(const SDL_Event& evt); - void _setupOISKeys(); - SDL_Window* mSDLWindow; osg::ref_ptr mViewer; @@ -64,9 +59,6 @@ namespace SDLUtil WindowListener* mWindowListener; ControllerListener* mConListener; - typedef std::map KeyMap; - KeyMap mKeyMap; - Uint16 mWarpX; Uint16 mWarpY; bool mWarpCompensate;