From 91f4967614795effdb0ade4cae408fc01a602313 Mon Sep 17 00:00:00 2001 From: Fil Krynicki Date: Tue, 27 May 2014 13:12:27 -0400 Subject: [PATCH 01/10] Fix for bug 1196. This bug would cause the player to jump when jump was assigned to Space and they closed a dialog with Space. I tested vanilla MW for behaviour and found that Jump was the only basic input which MW does not allow when closing dialogs (i.e. if Space is assigned to move forward, MW will move you forward after closing the dialog). There were two reasons for the bug: 1) OpenMW GUI does not consume UI events 2) Jump occurs so long as key is down (not only on first key down) To minimally fix the bug, I made it so that keypress events can be consumed by the GUI and not passed along to the player control input manager (1). However, if the player holds space, they will still jump (as the subsequent key held events will be captured and cause a jump). Unfortunately, there is no idiomatic way that I could find in the OpenMW input manager to perform events only on key down. Instead, I introduced a variable which tracks whether the jump key has been pressed for the first time within the current frame (2). Note: I was initially concerned that limiting the jump event to KeyDown and not Key Hold would cause issues with swimming, levitating, or variable height jumping. However, after a bunch of testing in vanilla MW and exploration of the OpenMW codebase I could find nothing suggesting the need to capture the jump key being held. --- apps/openmw/mwinput/inputmanagerimp.cpp | 181 ++++++++++++------------ apps/openmw/mwinput/inputmanagerimp.hpp | 1 + 2 files changed, 95 insertions(+), 87 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index e2d4f8cb2..9c263e52d 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -113,6 +113,7 @@ namespace MWInput , mTimeIdle(0.f) , mOverencumberedMessageDelay(0.f) , mAlwaysRunActive(false) + , mAttemptJump(false) { Ogre::RenderWindow* window = ogre.getWindow (); @@ -173,6 +174,11 @@ namespace MWInput MWWorld::Class::get(mPlayer->getPlayer()).getCreatureStats(mPlayer->getPlayer()).setAttackingOrSpell(currentValue); } + if (action == A_Jump) + { + mAttemptJump = (currentValue == 1.0 && previousValue == 0.0); + } + if (currentValue == 1) { // trigger action activated @@ -292,107 +298,107 @@ namespace MWInput } // Disable movement in Gui mode - if (MWBase::Environment::get().getWindowManager()->isGuiMode() - || MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_Running) - return; - - - // Configure player movement according to keyboard input. Actual movement will - // be done in the physics system. - if (mControlSwitch["playercontrols"]) + if (!(MWBase::Environment::get().getWindowManager()->isGuiMode() + || MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_Running)) { - bool triedToMove = false; - if (actionIsActive(A_MoveLeft)) + // Configure player movement according to keyboard input. Actual movement will + // be done in the physics system. + if (mControlSwitch["playercontrols"]) { - triedToMove = true; - mPlayer->setLeftRight (-1); - } - else if (actionIsActive(A_MoveRight)) - { - triedToMove = true; - mPlayer->setLeftRight (1); - } + bool triedToMove = false; + if (actionIsActive(A_MoveLeft)) + { + triedToMove = true; + mPlayer->setLeftRight (-1); + } + else if (actionIsActive(A_MoveRight)) + { + triedToMove = true; + mPlayer->setLeftRight (1); + } - if (actionIsActive(A_MoveForward)) - { - triedToMove = true; - mPlayer->setAutoMove (false); - mPlayer->setForwardBackward (1); - } - else if (actionIsActive(A_MoveBackward)) - { - triedToMove = true; - mPlayer->setAutoMove (false); - mPlayer->setForwardBackward (-1); - } + if (actionIsActive(A_MoveForward)) + { + triedToMove = true; + mPlayer->setAutoMove (false); + mPlayer->setForwardBackward (1); + } + else if (actionIsActive(A_MoveBackward)) + { + triedToMove = true; + mPlayer->setAutoMove (false); + mPlayer->setForwardBackward (-1); + } - else if(mPlayer->getAutoMove()) - { - triedToMove = true; - mPlayer->setForwardBackward (1); - } + else if(mPlayer->getAutoMove()) + { + triedToMove = true; + mPlayer->setForwardBackward (1); + } - mPlayer->setSneak(actionIsActive(A_Sneak)); + mPlayer->setSneak(actionIsActive(A_Sneak)); - if (actionIsActive(A_Jump) && mControlSwitch["playerjumping"]) - { - mPlayer->setUpDown (1); - triedToMove = true; - } + if (mAttemptJump && mControlSwitch["playerjumping"]) + { + mPlayer->setUpDown (1); + triedToMove = true; + } - if (mAlwaysRunActive) - mPlayer->setRunState(!actionIsActive(A_Run)); - else - mPlayer->setRunState(actionIsActive(A_Run)); + if (mAlwaysRunActive) + mPlayer->setRunState(!actionIsActive(A_Run)); + else + mPlayer->setRunState(actionIsActive(A_Run)); - // if player tried to start moving, but can't (due to being overencumbered), display a notification. - if (triedToMove) - { - MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); - mOverencumberedMessageDelay -= dt; - if (MWWorld::Class::get(player).getEncumbrance(player) >= MWWorld::Class::get(player).getCapacity(player)) + // if player tried to start moving, but can't (due to being overencumbered), display a notification. + if (triedToMove) { - mPlayer->setAutoMove (false); - if (mOverencumberedMessageDelay <= 0) + MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr(); + mOverencumberedMessageDelay -= dt; + if (MWWorld::Class::get(player).getEncumbrance(player) >= MWWorld::Class::get(player).getCapacity(player)) { - MWBase::Environment::get().getWindowManager ()->messageBox("#{sNotifyMessage59}"); - mOverencumberedMessageDelay = 1.0; + mPlayer->setAutoMove (false); + if (mOverencumberedMessageDelay <= 0) + { + MWBase::Environment::get().getWindowManager ()->messageBox("#{sNotifyMessage59}"); + mOverencumberedMessageDelay = 1.0; + } } } - } - - if (mControlSwitch["playerviewswitch"]) { - // work around preview mode toggle when pressing Alt+Tab - if (actionIsActive(A_TogglePOV) && !mInputManager->isModifierHeld(SDL_Keymod(KMOD_ALT))) { - if (mPreviewPOVDelay <= 0.5 && - (mPreviewPOVDelay += dt) > 0.5) - { - mPreviewPOVDelay = 1.f; - MWBase::Environment::get().getWorld()->togglePreviewMode(true); + if (mControlSwitch["playerviewswitch"]) { + + // work around preview mode toggle when pressing Alt+Tab + if (actionIsActive(A_TogglePOV) && !mInputManager->isModifierHeld(SDL_Keymod(KMOD_ALT))) { + if (mPreviewPOVDelay <= 0.5 && + (mPreviewPOVDelay += dt) > 0.5) + { + mPreviewPOVDelay = 1.f; + MWBase::Environment::get().getWorld()->togglePreviewMode(true); + } + } else { + //disable preview mode + MWBase::Environment::get().getWorld()->togglePreviewMode(false); + if (mPreviewPOVDelay > 0.f && mPreviewPOVDelay <= 0.5) { + MWBase::Environment::get().getWorld()->togglePOV(); + } + mPreviewPOVDelay = 0.f; } - } else { - //disable preview mode - MWBase::Environment::get().getWorld()->togglePreviewMode(false); - if (mPreviewPOVDelay > 0.f && mPreviewPOVDelay <= 0.5) { - MWBase::Environment::get().getWorld()->togglePOV(); - } - mPreviewPOVDelay = 0.f; } } + if (actionIsActive(A_MoveForward) || + actionIsActive(A_MoveBackward) || + actionIsActive(A_MoveLeft) || + actionIsActive(A_MoveRight) || + actionIsActive(A_Jump) || + actionIsActive(A_Sneak) || + actionIsActive(A_TogglePOV)) + { + resetIdleTime(); + } else { + updateIdleTime(dt); + } } - if (actionIsActive(A_MoveForward) || - actionIsActive(A_MoveBackward) || - actionIsActive(A_MoveLeft) || - actionIsActive(A_MoveRight) || - actionIsActive(A_Jump) || - actionIsActive(A_Sneak) || - actionIsActive(A_TogglePOV)) - { - resetIdleTime(); - } else { - updateIdleTime(dt); - } + mAttemptJump = false; // Can only jump on first frame input is on } void InputManager::setDragDrop(bool dragDrop) @@ -502,12 +508,13 @@ namespace MWInput } } - mInputBinder->keyPressed (arg); - OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym); + bool passToBinder = true; if (kc != OIS::KC_UNASSIGNED) - MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(kc), 0); + passToBinder = !MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(kc), 0); + if(passToBinder) + mInputBinder->keyPressed (arg); } void InputManager::textInput(const SDL_TextInputEvent &arg) diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 87fbda25c..537c3a182 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -161,6 +161,7 @@ namespace MWInput int mMouseWheel; bool mUserFileExists; bool mAlwaysRunActive; + bool mAttemptJump; std::map mControlSwitch; From 6cc6172779e4df88da9accf17de1facfe04f6c03 Mon Sep 17 00:00:00 2001 From: Fil Krynicki Date: Fri, 30 May 2014 15:12:57 -0400 Subject: [PATCH 02/10] Update in response to comments. It turns out I was erroneous about problem (1) in my original commit message. I thought that in an edge case the OpenMWGUI could both handle the same event on the frame the GUI was closed. My test for this was broken. So after brainstorming many possible unsatisfactory solutions to this event handling, it's luckily not necessary! --- apps/openmw/mwinput/inputmanagerimp.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 9c263e52d..344da5be1 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -510,11 +510,9 @@ namespace MWInput OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym); - bool passToBinder = true; if (kc != OIS::KC_UNASSIGNED) - passToBinder = !MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(kc), 0); - if(passToBinder) - mInputBinder->keyPressed (arg); + MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(kc), 0); + mInputBinder->keyPressed (arg); } void InputManager::textInput(const SDL_TextInputEvent &arg) From cd131e7f867fbc0c9a8d28259960dab40a23f248 Mon Sep 17 00:00:00 2001 From: Fil Krynicki Date: Sat, 31 May 2014 19:51:21 -0400 Subject: [PATCH 03/10] 1196/1217 fix Fixes an issue where inputs could be processed by both GUI and gameplay systems. An enabled/disable has been added to OIS channels, and OpenMW now disables player gameplay hotkeys when a GUI element has focus. GUI hotkeys are left enabled. --- apps/openmw/mwinput/inputmanagerimp.cpp | 19 ++++++++++++++++++- apps/openmw/mwinput/inputmanagerimp.hpp | 2 ++ extern/oics/ICSChannel.cpp | 13 +++++++++++-- extern/oics/ICSChannel.h | 6 +++++- 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 344da5be1..73399ee78 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -160,6 +160,20 @@ namespace MWInput delete mInputManager; } + void InputManager::setPlayerControlsEnabled(bool enabled) + { + int nPlayerChannels = 15; + int playerChannels[] = {A_Activate, 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}; + + for(int i = 0; i < nPlayerChannels; i++) { + int pc = playerChannels[i]; + mInputBinder->getChannel(pc)->setEnabled(enabled); + } + } + void InputManager::channelChanged(ICS::Channel* channel, float currentValue, float previousValue) { if (mDragDrop) @@ -511,7 +525,10 @@ namespace MWInput OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym); if (kc != OIS::KC_UNASSIGNED) - MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(kc), 0); + { + bool guiFocus = MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(kc), 0); + setPlayerControlsEnabled(!guiFocus); + } mInputBinder->keyPressed (arg); } diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 537c3a182..dbd13e793 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -172,6 +172,8 @@ namespace MWInput void resetIdleTime(); void updateIdleTime(float dt); + void setPlayerControlsEnabled(bool enabled); + private: void toggleMainMenu(); void toggleSpell(); diff --git a/extern/oics/ICSChannel.cpp b/extern/oics/ICSChannel.cpp index 703f2207c..268615c92 100644 --- a/extern/oics/ICSChannel.cpp +++ b/extern/oics/ICSChannel.cpp @@ -38,6 +38,7 @@ namespace ICS , mValue(initialValue) , mSymmetricAt(symmetricAt) , mBezierStep(bezierStep) + , mEnabled(true) { mBezierMidPoint.x = bezierMidPointX; mBezierMidPoint.y = bezierMidPointY; @@ -45,6 +46,11 @@ namespace ICS setBezierFunction(bezierMidPointY, bezierMidPointX, symmetricAt, bezierStep); } + void Channel::setEnabled(bool enabled) + { + mEnabled = enabled; + } + float Channel::getValue() { if(mValue == 0 || mValue == 1) @@ -124,7 +130,10 @@ namespace ICS void Channel::update() { - if(this->getControlsCount() == 1) + if(!mEnabled) + return; + + if(this->getControlsCount() == 1) { ControlChannelBinderItem ccBinderItem = mAttachedControls.back(); float diff = ccBinderItem.control->getValue() - ccBinderItem.control->getInitialValue(); @@ -255,4 +264,4 @@ namespace ICS t += 1.0f / ((endX-startX)/step); } } -} \ No newline at end of file +} diff --git a/extern/oics/ICSChannel.h b/extern/oics/ICSChannel.h index 5ec6cd575..3da53369c 100644 --- a/extern/oics/ICSChannel.h +++ b/extern/oics/ICSChannel.h @@ -89,6 +89,8 @@ namespace ICS IntervalList& getIntervals(){ return mIntervals; }; + void setEnabled(bool enabled); + protected: int mNumber; @@ -112,7 +114,9 @@ namespace ICS std::vector mAttachedControls; std::list mListeners; - void notifyListeners(float previousValue); + void notifyListeners(float previousValue); + + bool mEnabled; }; From 13c953cbb290433b7f9dbbd04e5191b67a84f60a Mon Sep 17 00:00:00 2001 From: Fil Krynicki Date: Fri, 6 Jun 2014 16:21:28 -0400 Subject: [PATCH 04/10] Made recommended changes Maybe introduced a bug not allowing punching. Testing. --- apps/openmw/mwinput/inputmanagerimp.cpp | 46 ++++++++++++++++--------- 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 80cd834d5..12e3cdbf7 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -168,11 +168,12 @@ namespace MWInput void InputManager::setPlayerControlsEnabled(bool enabled) { - int nPlayerChannels = 15; + int nPlayerChannels = 17; int playerChannels[] = {A_Activate, 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_QuickKey7, A_QuickKey8, A_QuickKey9, A_QuickKey10, + A_Use}; for(int i = 0; i < nPlayerChannels; i++) { int pc = playerChannels[i]; @@ -558,41 +559,49 @@ namespace MWInput void InputManager::keyReleased(const SDL_KeyboardEvent &arg ) { - mInputBinder->keyReleased (arg); - OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym); - MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc)); + if (kc != OIS::KC_UNASSIGNED) + { + bool guiFocus = MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc)); + setPlayerControlsEnabled(!guiFocus); + } + mInputBinder->keyReleased (arg); + } void InputManager::mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id ) { - mInputBinder->mousePressed (arg, id); + bool guiFocus = false; - if (id != SDL_BUTTON_LEFT && id != SDL_BUTTON_RIGHT) - return; // MyGUI has no use for these events - - MyGUI::InputManager::getInstance().injectMousePress(mMouseX, mMouseY, sdlButtonToMyGUI(id)); - if (MyGUI::InputManager::getInstance ().getMouseFocusWidget () != 0) + if (!(id != SDL_BUTTON_LEFT && id != SDL_BUTTON_RIGHT)) // MyGUI has no use for these events { - MyGUI::Button* b = MyGUI::InputManager::getInstance ().getMouseFocusWidget ()->castType(false); - if (b && b->getEnabled()) + guiFocus = MyGUI::InputManager::getInstance().injectMousePress(mMouseX, mMouseY, sdlButtonToMyGUI(id)); + if (MyGUI::InputManager::getInstance ().getMouseFocusWidget () != 0) { - MWBase::Environment::get().getSoundManager ()->playSound ("Menu Click", 1.f, 1.f); + MyGUI::Button* b = MyGUI::InputManager::getInstance ().getMouseFocusWidget ()->castType(false); + if (b && b->getEnabled()) + { + MWBase::Environment::get().getSoundManager ()->playSound ("Menu Click", 1.f, 1.f); + } } } + setPlayerControlsEnabled(!guiFocus); + + mInputBinder->mousePressed (arg, id); } void InputManager::mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id ) { + bool guiFocus = MyGUI::InputManager::getInstance().injectMouseRelease(mMouseX, mMouseY, sdlButtonToMyGUI(id)); + setPlayerControlsEnabled(!guiFocus); mInputBinder->mouseReleased (arg, id); - MyGUI::InputManager::getInstance().injectMouseRelease(mMouseX, mMouseY, sdlButtonToMyGUI(id)); } void InputManager::mouseMoved(const SFO::MouseMotionEvent &arg ) { - mInputBinder->mouseMoved (arg); + bool guiFocus = false; resetIdleTime (); @@ -610,7 +619,7 @@ namespace MWInput mMouseWheel = int(arg.z); - MyGUI::InputManager::getInstance().injectMouseMove( int(mMouseX), int(mMouseY), mMouseWheel); + guiFocus = MyGUI::InputManager::getInstance().injectMouseMove( int(mMouseX), int(mMouseY), mMouseWheel); } if (mMouseLookEnabled) @@ -638,6 +647,9 @@ namespace MWInput MWBase::Environment::get().getWorld()->setCameraDistance(arg.zrel, true, true); } } + + setPlayerControlsEnabled(!guiFocus); + mInputBinder->mouseMoved (arg); } void InputManager::windowFocusChange(bool have_focus) From 97caa1f8a40d2b94046198c9216dca160c5f3a5f Mon Sep 17 00:00:00 2001 From: Fil Krynicki Date: Fri, 6 Jun 2014 22:25:23 -0400 Subject: [PATCH 05/10] Alternative fix strategy by checking for binding state --- apps/openmw/mwinput/inputmanagerimp.cpp | 45 ++++++++++++++++--------- extern/oics/ICSInputControlSystem.cpp | 5 +++ extern/oics/ICSInputControlSystem.h | 1 + 3 files changed, 36 insertions(+), 15 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 80cd834d5..ec1c0aa92 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -558,36 +558,51 @@ namespace MWInput void InputManager::keyReleased(const SDL_KeyboardEvent &arg ) { - mInputBinder->keyReleased (arg); - OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym); - MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc)); + setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc))); + mInputBinder->keyReleased (arg); } void InputManager::mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id ) { - mInputBinder->mousePressed (arg, id); + bool guiMode = false; - if (id != SDL_BUTTON_LEFT && id != SDL_BUTTON_RIGHT) - return; // MyGUI has no use for these events - - MyGUI::InputManager::getInstance().injectMousePress(mMouseX, mMouseY, sdlButtonToMyGUI(id)); - if (MyGUI::InputManager::getInstance ().getMouseFocusWidget () != 0) + if (id == SDL_BUTTON_LEFT || id == SDL_BUTTON_RIGHT) // MyGUI has no use for these events { - MyGUI::Button* b = MyGUI::InputManager::getInstance ().getMouseFocusWidget ()->castType(false); - if (b && b->getEnabled()) + MyGUI::InputManager::getInstance().injectMousePress(mMouseX, mMouseY, sdlButtonToMyGUI(id)); + guiMode = guiMode && MWBase::Environment::get().getWindowManager()->isGuiMode(); + if (MyGUI::InputManager::getInstance ().getMouseFocusWidget () != 0) { - MWBase::Environment::get().getSoundManager ()->playSound ("Menu Click", 1.f, 1.f); + MyGUI::Button* b = MyGUI::InputManager::getInstance ().getMouseFocusWidget ()->castType(false); + if (b && b->getEnabled()) + { + MWBase::Environment::get().getSoundManager ()->playSound ("Menu Click", 1.f, 1.f); + } } } + + setPlayerControlsEnabled(!guiMode); + mInputBinder->mousePressed (arg, id); + + } void InputManager::mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id ) - { - mInputBinder->mouseReleased (arg, id); + { - MyGUI::InputManager::getInstance().injectMouseRelease(mMouseX, mMouseY, sdlButtonToMyGUI(id)); + if(mInputBinder->detectingBindingState()) + { + mInputBinder->mouseReleased (arg, id); + } else { + bool guiMode = MyGUI::InputManager::getInstance().injectMouseRelease(mMouseX, mMouseY, sdlButtonToMyGUI(id)); + guiMode = guiMode && MWBase::Environment::get().getWindowManager()->isGuiMode(); + + if(mInputBinder->detectingBindingState()) return; // don't allow same mouseup to bind as initiated bind + + setPlayerControlsEnabled(!guiMode); + mInputBinder->mouseReleased (arg, id); + } } void InputManager::mouseMoved(const SFO::MouseMotionEvent &arg ) diff --git a/extern/oics/ICSInputControlSystem.cpp b/extern/oics/ICSInputControlSystem.cpp index cdf8fbfe2..a053bbab4 100644 --- a/extern/oics/ICSInputControlSystem.cpp +++ b/extern/oics/ICSInputControlSystem.cpp @@ -796,6 +796,11 @@ namespace ICS mMouseAxisBindingInitialValues[0] = ICS_MOUSE_AXIS_BINDING_NULL_VALUE; } + bool InputControlSystem::detectingBindingState() + { + return mDetectingBindingControl != NULL; + } + void InputControlSystem::cancelDetectingBindingState() { mDetectingBindingControl = NULL; diff --git a/extern/oics/ICSInputControlSystem.h b/extern/oics/ICSInputControlSystem.h index a83ae539e..4aaecdea9 100644 --- a/extern/oics/ICSInputControlSystem.h +++ b/extern/oics/ICSInputControlSystem.h @@ -146,6 +146,7 @@ namespace ICS void enableDetectingBindingState(Control* control, Control::ControlChangingDirection direction); void cancelDetectingBindingState(); + bool detectingBindingState(); bool save(std::string fileName = ""); From 1d3a220d947a6cf44f5e3dfc7c588a53f3aec232 Mon Sep 17 00:00:00 2001 From: Fil Krynicki Date: Fri, 6 Jun 2014 22:35:16 -0400 Subject: [PATCH 06/10] Added A_Use command to player controls. --- apps/openmw/mwinput/inputmanagerimp.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index ec1c0aa92..0ca55ea58 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -168,11 +168,12 @@ namespace MWInput void InputManager::setPlayerControlsEnabled(bool enabled) { - int nPlayerChannels = 15; + int nPlayerChannels = 17; int playerChannels[] = {A_Activate, 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_QuickKey7, A_QuickKey8, A_QuickKey9, A_QuickKey10, + A_Use}; for(int i = 0; i < nPlayerChannels; i++) { int pc = playerChannels[i]; From cd693b6d37dc6a5b0413e500d0fb1570449156e6 Mon Sep 17 00:00:00 2001 From: Fil Krynicki Date: Sat, 7 Jun 2014 20:08:29 -0400 Subject: [PATCH 07/10] Fixed mouse closing containers, and injection/gui test order Called setEnabled on channels now effects whether those channels notify listeners, rather than whether they register changes to their controls. This was making channels get stuck on "1" when the GUI was activated. Also ensured GUI activity can invalidate player controls even if that activity is closing the GUI, by re-ordering a check. And fixed a comment. --- apps/openmw/mwinput/inputmanagerimp.cpp | 10 +++++----- extern/oics/ICSChannel.cpp | 5 +---- 2 files changed, 6 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 0ca55ea58..85d5cdb8e 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -569,10 +569,10 @@ namespace MWInput { bool guiMode = false; - if (id == SDL_BUTTON_LEFT || id == SDL_BUTTON_RIGHT) // MyGUI has no use for these events + if (id == SDL_BUTTON_LEFT || id == SDL_BUTTON_RIGHT) // MyGUI only uses these mouse events { - MyGUI::InputManager::getInstance().injectMousePress(mMouseX, mMouseY, sdlButtonToMyGUI(id)); - guiMode = guiMode && MWBase::Environment::get().getWindowManager()->isGuiMode(); + guiMode = MWBase::Environment::get().getWindowManager()->isGuiMode(); + guiMode = MyGUI::InputManager::getInstance().injectMousePress(mMouseX, mMouseY, sdlButtonToMyGUI(id)) && guiMode; if (MyGUI::InputManager::getInstance ().getMouseFocusWidget () != 0) { MyGUI::Button* b = MyGUI::InputManager::getInstance ().getMouseFocusWidget ()->castType(false); @@ -596,8 +596,8 @@ namespace MWInput { mInputBinder->mouseReleased (arg, id); } else { - bool guiMode = MyGUI::InputManager::getInstance().injectMouseRelease(mMouseX, mMouseY, sdlButtonToMyGUI(id)); - guiMode = guiMode && MWBase::Environment::get().getWindowManager()->isGuiMode(); + bool guiMode = MWBase::Environment::get().getWindowManager()->isGuiMode(); + guiMode = MyGUI::InputManager::getInstance().injectMouseRelease(mMouseX, mMouseY, sdlButtonToMyGUI(id)) && guiMode; if(mInputBinder->detectingBindingState()) return; // don't allow same mouseup to bind as initiated bind diff --git a/extern/oics/ICSChannel.cpp b/extern/oics/ICSChannel.cpp index 268615c92..178fe5aa3 100644 --- a/extern/oics/ICSChannel.cpp +++ b/extern/oics/ICSChannel.cpp @@ -84,7 +84,7 @@ namespace ICS mValue = value; - if(previousValue != value) + if(previousValue != value && mEnabled) { notifyListeners(previousValue); } @@ -130,9 +130,6 @@ namespace ICS void Channel::update() { - if(!mEnabled) - return; - if(this->getControlsCount() == 1) { ControlChannelBinderItem ccBinderItem = mAttachedControls.back(); From 51c45796b183a5b4d71323602045674a0c4be71c Mon Sep 17 00:00:00 2001 From: slothlife Date: Sat, 7 Jun 2014 19:26:12 -0500 Subject: [PATCH 08/10] Fix physics to not trigger Bullet assert in Debug When physics attempts to move by a very small amount, precision losses caused Bullet to trigger an assert in debug from normalizing a zero length vector. --- apps/openmw/mwworld/physicssystem.cpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index b0b00c6db..fde774662 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -299,17 +299,33 @@ namespace MWWorld continue; // velocity updated, calculate nextpos again } - // trace to where character would go if there were no obstructions - tracer.doTrace(colobj, newPosition, nextpos, engine); + if(!newPosition.positionCloses(nextpos, 0.00000001)) + { + // trace to where character would go if there were no obstructions + tracer.doTrace(colobj, newPosition, nextpos, engine); - // check for obstructions - if(tracer.mFraction >= 1.0f) + // check for obstructions + if(tracer.mFraction >= 1.0f) + { + newPosition = tracer.mEndPos; // ok to move, so set newPosition + remainingTime *= (1.0f-tracer.mFraction); // FIXME: remainingTime is no longer used so don't set it? + break; + } + } + else { - newPosition = tracer.mEndPos; // ok to move, so set newPosition + // The current position and next position are nearly the same, so just exit. + // Note: Bullet can trigger an assert in debug modes if the positions + // are the same, since that causes it to attempt to normalize a zero + // length vector (which can also happen with nearly identical vectors, since + // precision can be lost due to any math Bullet does internally). Since we + // aren't performing any collision detection, we want to reject the next + // position, so that we don't slowly move inside another object. remainingTime *= (1.0f-tracer.mFraction); // FIXME: remainingTime is no longer used so don't set it? break; } + Ogre::Vector3 oldPosition = newPosition; // We hit something. Try to step up onto it. (NOTE: stepMove does not allow stepping over) // NOTE: stepMove modifies newPosition if successful From 803a7514dfbfabd58678ad3a551deebb0c6f628e Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 8 Jun 2014 11:33:39 +0200 Subject: [PATCH 09/10] updated credits file --- credits.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/credits.txt b/credits.txt index da5417034..092f5c15e 100644 --- a/credits.txt +++ b/credits.txt @@ -36,6 +36,7 @@ Eli2 Emanuel Guével (potatoesmaster) Fil Krynicki (filkry) gugus/gus +Hallfaer Tuilinn Jacob Essex (Yacoby) Jannik Heller (scrawl) Jason Hooks (jhooks) From 8419002393d89bd20222773a1872efb858f7ea32 Mon Sep 17 00:00:00 2001 From: Bret Curtis Date: Tue, 10 Jun 2014 11:25:39 +0200 Subject: [PATCH 10/10] Task #940: Move licenses to appropriate place in docs. Additional cleanup. --- .gitignore | 2 +- CMakeLists.txt | 2 +- credits.txt | 4 ++-- {Docs => docs}/Doxyfile | 2 +- {Docs => docs}/DoxyfilePages | 2 +- .../license/DejaVu Font License.txt | 0 GPL3.txt => docs/license/GPL3.txt | 0 {Docs => docs}/mainpage.hpp.cmake | 0 8 files changed, 6 insertions(+), 6 deletions(-) rename {Docs => docs}/Doxyfile (99%) rename {Docs => docs}/DoxyfilePages (99%) rename DejaVu Font License.txt => docs/license/DejaVu Font License.txt (100%) rename GPL3.txt => docs/license/GPL3.txt (100%) rename {Docs => docs}/mainpage.hpp.cmake (100%) diff --git a/.gitignore b/.gitignore index 3975c4521..08bf0bad6 100644 --- a/.gitignore +++ b/.gitignore @@ -41,7 +41,7 @@ resources ## generated objects apps/openmw/config.hpp components/version/version.hpp -Docs/mainpage.hpp +docs/mainpage.hpp moc_*.cxx *.cxx_parameters *qrc_launcher.cxx diff --git a/CMakeLists.txt b/CMakeLists.txt index 3632f1e08..7038e05ba 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,7 +56,7 @@ include(OpenMWMacros) # doxygen main page -configure_file ("${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp") +configure_file ("${OpenMW_SOURCE_DIR}/docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_DIR}/docs/mainpage.hpp") option(MYGUI_STATIC "Link static build of Mygui into the binaries" FALSE) option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binaries" FALSE) diff --git a/credits.txt b/credits.txt index 092f5c15e..791db0433 100644 --- a/credits.txt +++ b/credits.txt @@ -19,8 +19,8 @@ Alexander Olofsson (Ace) Artem Kotsynyak (greye) Arthur Moore (EmperorArthur) athile +Bret Curtis (psi29a) Britt Mathis (galdor557) -BrotherBrick cc9cii Chris Boyce (slothlife) Chris Robinson (KittyCat) @@ -79,7 +79,7 @@ Torben Leif Carrington (TorbenC) Packagers: Alexander Olofsson (Ace) - Windows -BrotherBrick - Ubuntu Linux +Bret Curtis (psi29a) - Ubuntu Linux Edmondo Tommasina (edmondo) - Gentoo Linux Julian Ospald (hasufell) - Gentoo Linux Karl-Felix Glatzer (k1ll) - Linux Binaries diff --git a/Docs/Doxyfile b/docs/Doxyfile similarity index 99% rename from Docs/Doxyfile rename to docs/Doxyfile index 43c3312ad..156e23abd 100644 --- a/Docs/Doxyfile +++ b/docs/Doxyfile @@ -576,7 +576,7 @@ WARN_LOGFILE = INPUT = apps \ components \ libs \ - Docs + docs # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is diff --git a/Docs/DoxyfilePages b/docs/DoxyfilePages similarity index 99% rename from Docs/DoxyfilePages rename to docs/DoxyfilePages index 5ce82a7c2..dca9d7a12 100644 --- a/Docs/DoxyfilePages +++ b/docs/DoxyfilePages @@ -576,7 +576,7 @@ WARN_LOGFILE = INPUT = apps \ components \ libs \ - Docs + docs # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is diff --git a/DejaVu Font License.txt b/docs/license/DejaVu Font License.txt similarity index 100% rename from DejaVu Font License.txt rename to docs/license/DejaVu Font License.txt diff --git a/GPL3.txt b/docs/license/GPL3.txt similarity index 100% rename from GPL3.txt rename to docs/license/GPL3.txt diff --git a/Docs/mainpage.hpp.cmake b/docs/mainpage.hpp.cmake similarity index 100% rename from Docs/mainpage.hpp.cmake rename to docs/mainpage.hpp.cmake