1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-03-29 13:20:35 +00:00

Move keyboard-specific code to the separate file

This commit is contained in:
Andrei Kortunov 2020-04-16 11:03:34 +04:00
parent c368250e6a
commit d3a9f893c8
8 changed files with 224 additions and 129 deletions

View File

@ -25,7 +25,7 @@ add_openmw_dir (mwrender
)
add_openmw_dir (mwinput
actions actionmanager controllermanager inputmanagerimp mousemanager sdlmappings sensormanager
actions actionmanager controllermanager inputmanagerimp mousemanager keyboardmanager sdlmappings sensormanager
)
add_openmw_dir (mwgui

View File

@ -94,7 +94,7 @@ namespace MWInput
return (mInputBinder->getChannel (id)->getValue ()==1.0);
}
void ControllerManager::update(float dt, bool disableControls, bool gamepadPreviewMode)
bool ControllerManager::update(float dt, bool disableControls, bool gamepadPreviewMode)
{
mControlsDisabled = disableControls;
mGamepadPreviewMode = gamepadPreviewMode;
@ -122,23 +122,21 @@ namespace MWInput
}
}
MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer();
// Disable movement in Gui mode
if (MWBase::Environment::get().getWindowManager()->isGuiMode()
|| MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_Running)
{
mGamepadZoom = 0;
return;
return false;
}
// Configure player movement according to keyboard input. Actual movement will
MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer();
bool triedToMove = false;
// Configure player movement according to controller input. Actual movement will
// be done in the physics system.
if (MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols"))
{
bool triedToMove = false;
// joystick movement
float xAxis = mInputBinder->getChannel(A_MoveLeftRight)->getValue();
float yAxis = mInputBinder->getChannel(A_MoveForwardBackward)->getValue();
if (xAxis != .5)
@ -157,7 +155,8 @@ namespace MWInput
if (triedToMove)
mJoystickLastUsed = true;
if(triedToMove) MWBase::Environment::get().getInputManager()->resetIdleTime();
if (triedToMove)
MWBase::Environment::get().getInputManager()->resetIdleTime();
static const bool isToggleSneak = Settings::Manager::getBool("toggle sneak", "Input");
if (!isToggleSneak)
@ -205,6 +204,8 @@ namespace MWInput
MWBase::Environment::get().getWorld()->setCameraDistance(mGamepadZoom, true, true);
}
}
return triedToMove;
}
void ControllerManager::buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg )

View File

@ -31,7 +31,7 @@ namespace MWInput
void clear();
void update(float dt, bool disableControls, bool gamepadPreviewMode);
bool update(float dt, bool disableControls, bool gamepadPreviewMode);
virtual void buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg);
virtual void buttonReleased(int deviceID, const SDL_ControllerButtonEvent &arg);

View File

@ -32,6 +32,7 @@
#include "actionmanager.hpp"
#include "controllermanager.hpp"
#include "keyboardmanager.hpp"
#include "mousemanager.hpp"
#include "sdlmappings.hpp"
#include "sensormanager.hpp"
@ -47,12 +48,9 @@ namespace MWInput
const std::string& controllerBindingsFile, bool grab)
: mWindow(window)
, mWindowVisible(true)
, mInputWrapper(nullptr)
, mVideoWrapper(nullptr)
, mUserFile(userFile)
, mDragDrop(false)
, mGrabCursor (Settings::Manager::getBool("grab cursor", "Input"))
, mControlsDisabled(false)
, mPreviewPOVDelay(0.f)
, mTimeIdle(0.f)
, mGuiCursorEnabled(true)
@ -62,7 +60,6 @@ namespace MWInput
, mFakeDeviceID(1)
{
mInputWrapper = new SDLUtil::InputWrapper(window, viewer, grab);
mInputWrapper->setKeyboardEventCallback (this);
mInputWrapper->setWindowEventCallback(this);
mVideoWrapper = new SDLUtil::VideoWrapper(window, viewer);
@ -90,14 +87,17 @@ namespace MWInput
mActionManager = new ActionManager(mInputBinder, screenCaptureOperation, viewer, screenCaptureHandler);
mKeyboardManager = new KeyboardManager(mInputBinder, mInputWrapper, mActionManager);
mInputWrapper->setKeyboardEventCallback(mKeyboardManager);
mMouseManager = new MouseManager(mInputBinder, mInputWrapper, window);
mInputWrapper->setMouseEventCallback (mMouseManager);
mInputWrapper->setMouseEventCallback(mMouseManager);
mControllerManager = new ControllerManager(mInputBinder, mInputWrapper, mActionManager, mMouseManager, userControllerBindingsFile, controllerBindingsFile);
mInputWrapper->setControllerEventCallback(mControllerManager);
mSensorManager = new SensorManager();
mInputWrapper->setSensorEventCallback (mSensorManager);
mInputWrapper->setSensorEventCallback(mSensorManager);
}
void InputManager::clear()
@ -118,6 +118,7 @@ namespace MWInput
delete mActionManager;
delete mControllerManager;
delete mKeyboardManager;
delete mMouseManager;
delete mSensorManager;
@ -236,13 +237,11 @@ namespace MWInput
void InputManager::update(float dt, bool disableControls, bool disableEvents)
{
mControlsDisabled = disableControls;
mInputWrapper->setMouseVisible(MWBase::Environment::get().getWindowManager()->getCursorVisible());
mInputWrapper->capture(disableEvents);
if (mControlsDisabled)
if (disableControls)
{
updateCursorMode();
return;
@ -253,7 +252,8 @@ namespace MWInput
updateCursorMode();
mControllerManager->update(dt, disableControls, mPreviewPOVDelay == 1.f);
bool controllerMove = mControllerManager->update(dt, disableControls, mPreviewPOVDelay == 1.f);
bool keyboardMove = mKeyboardManager->update(dt, disableControls);
if (mMouseManager->update(dt, disableControls))
resetIdleTime();
@ -265,64 +265,20 @@ namespace MWInput
if (!(MWBase::Environment::get().getWindowManager()->isGuiMode()
|| MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_Running))
{
// Configure player movement according to keyboard input. Actual movement will
// be done in the physics system.
if (mControlSwitch["playercontrols"])
{
MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer();
bool triedToMove = false;
bool isRunning = false;
bool alwaysRunAllowed = false;
// keyboard movement
float xAxis = mInputBinder->getChannel(A_MoveLeftRight)->getValue();
float yAxis = mInputBinder->getChannel(A_MoveForwardBackward)->getValue();
isRunning = xAxis > .75 || xAxis < .25 || yAxis > .75 || yAxis < .25;
if (actionIsActive(A_MoveLeft) != actionIsActive(A_MoveRight))
{
alwaysRunAllowed = true;
triedToMove = true;
player.setLeftRight (actionIsActive(A_MoveRight) ? 1 : -1);
}
if (actionIsActive(A_MoveForward) != actionIsActive(A_MoveBackward))
{
alwaysRunAllowed = true;
triedToMove = true;
player.setAutoMove (false);
player.setForwardBackward (actionIsActive(A_MoveForward) ? 1 : -1);
}
if (player.getAutoMove())
{
alwaysRunAllowed = true;
triedToMove = true;
player.setForwardBackward (1);
}
static const bool isToggleSneak = Settings::Manager::getBool("toggle sneak", "Input");
if (!isToggleSneak)
{
if(!mControllerManager->joystickLastUsed())
player.setSneak(actionIsActive(A_Sneak));
}
bool attemptToJump = false;
if (mAttemptJump && mControlSwitch["playerjumping"])
{
player.setUpDown (1);
triedToMove = true;
player.setUpDown(1);
attemptToJump = true;
mOverencumberedMessageDelay = 0.f;
}
if ((mActionManager->isAlwaysRunActive() && alwaysRunAllowed) || isRunning)
player.setRunState(!actionIsActive(A_Run));
else
player.setRunState(actionIsActive(A_Run));
// if player tried to start moving, but can't (due to being overencumbered), display a notification.
if (triedToMove)
if (controllerMove || keyboardMove || attemptToJump)
{
MWWorld::Ptr playerPtr = MWBase::Environment::get().getWorld ()->getPlayerPtr();
mOverencumberedMessageDelay -= dt;
@ -466,52 +422,6 @@ namespace MWInput
mControlSwitch[sw] = value;
}
void InputManager::keyPressed( const SDL_KeyboardEvent &arg )
{
// HACK: to make Morrowind's 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
&& MWBase::Environment::get().getWindowManager()->isConsoleMode())
SDL_StopTextInput();
bool consumed = false;
if (kc != OIS::KC_UNASSIGNED && !mInputBinder->detectingBindingState())
{
consumed = MWBase::Environment::get().getWindowManager()->injectKeyPress(MyGUI::KeyCode::Enum(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)))
consumed = true;
setPlayerControlsEnabled(!consumed);
}
if (arg.repeat)
return;
if (!mControlsDisabled && !consumed)
mInputBinder->keyPressed (arg);
mControllerManager->setJoystickLastUsed(false);
}
void InputManager::textInput(const SDL_TextInputEvent &arg)
{
MyGUI::UString ustring(&arg.text[0]);
MyGUI::UString::utf32string utf32string = ustring.asUTF32();
for (MyGUI::UString::utf32string::const_iterator it = utf32string.begin(); it != utf32string.end(); ++it)
MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::None, *it);
}
void InputManager::keyReleased(const SDL_KeyboardEvent &arg )
{
mControllerManager->setJoystickLastUsed(false);
OIS::KeyCode kc = mInputWrapper->sdl2OISKeyCode(arg.keysym.sym);
if (!mInputBinder->detectingBindingState())
setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc)));
mInputBinder->keyReleased (arg);
}
void InputManager::windowFocusChange(bool have_focus)
{
}

View File

@ -23,6 +23,7 @@ namespace MWInput
{
class ActionManager;
class ControllerManager;
class KeyboardManager;
class MouseManager;
class SensorManager;
}
@ -62,7 +63,6 @@ namespace MWInput
*/
class InputManager :
public MWBase::InputManager,
public SDLUtil::KeyListener,
public SDLUtil::WindowListener,
public ICS::ChannelListener,
public ICS::DetectingBindingListener
@ -109,10 +109,6 @@ namespace MWInput
virtual void setJoystickLastUsed(bool enabled);
virtual bool joystickLastUsed();
virtual void keyPressed(const SDL_KeyboardEvent &arg );
virtual void keyReleased( const SDL_KeyboardEvent &arg );
virtual void textInput (const SDL_TextInputEvent &arg);
virtual void windowVisibilityChange( bool visible );
virtual void windowFocusChange( bool have_focus );
virtual void windowResized (int x, int y);
@ -164,8 +160,6 @@ namespace MWInput
bool mGrabCursor;
bool mControlsDisabled;
float mPreviewPOVDelay;
float mTimeIdle;
@ -181,6 +175,7 @@ namespace MWInput
ActionManager* mActionManager;
ControllerManager* mControllerManager;
KeyboardManager* mKeyboardManager;
MouseManager* mMouseManager;
SensorManager* mSensorManager;

View File

@ -0,0 +1,146 @@
#include "keyboardmanager.hpp"
#include <MyGUI_InputManager.h>
#include <components/sdlutil/sdlinputwrapper.hpp>
#include <extern/oics/ICSInputControlSystem.h>
#include "../mwbase/environment.hpp"
#include "../mwbase/inputmanager.hpp"
#include "../mwbase/statemanager.hpp"
#include "../mwbase/windowmanager.hpp"
#include "../mwbase/world.hpp"
#include "../mwworld/player.hpp"
#include "actionmanager.hpp"
#include "actions.hpp"
namespace MWInput
{
KeyboardManager::KeyboardManager(ICS::InputControlSystem* inputBinder, SDLUtil::InputWrapper* inputWrapper, ActionManager* actionManager)
: mInputBinder(inputBinder)
, mInputWrapper(inputWrapper)
, mActionManager(actionManager)
, mControlsDisabled(false)
{
}
bool KeyboardManager::update(float dt, bool disableControls)
{
mControlsDisabled = disableControls;
// Disable movement in Gui mode
if (MWBase::Environment::get().getWindowManager()->isGuiMode()
|| MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_Running)
{
return false;
}
// Configure player movement according to keyboard input. Actual movement will
// be done in the physics system.
if (!MWBase::Environment::get().getInputManager()->getControlSwitch("playercontrols"))
{
return false;
}
bool triedToMove = false;
bool alwaysRunAllowed = false;
MWWorld::Player& player = MWBase::Environment::get().getWorld()->getPlayer();
if (actionIsActive(A_MoveLeft) != actionIsActive(A_MoveRight))
{
alwaysRunAllowed = true;
triedToMove = true;
player.setLeftRight (actionIsActive(A_MoveRight) ? 1 : -1);
}
if (actionIsActive(A_MoveForward) != actionIsActive(A_MoveBackward))
{
alwaysRunAllowed = true;
triedToMove = true;
player.setAutoMove (false);
player.setForwardBackward (actionIsActive(A_MoveForward) ? 1 : -1);
}
if (player.getAutoMove())
{
alwaysRunAllowed = true;
triedToMove = true;
player.setForwardBackward (1);
}
if (triedToMove)
MWBase::Environment::get().getInputManager()->resetIdleTime();
static const bool isToggleSneak = Settings::Manager::getBool("toggle sneak", "Input");
if (!isToggleSneak)
{
if(!MWBase::Environment::get().getInputManager()->joystickLastUsed())
player.setSneak(actionIsActive(A_Sneak));
}
float xAxis = mInputBinder->getChannel(A_MoveLeftRight)->getValue();
float yAxis = mInputBinder->getChannel(A_MoveForwardBackward)->getValue();
bool isRunning = xAxis > .75 || xAxis < .25 || yAxis > .75 || yAxis < .25;
if ((mActionManager->isAlwaysRunActive() && alwaysRunAllowed) || isRunning)
player.setRunState(!actionIsActive(A_Run));
else
player.setRunState(actionIsActive(A_Run));
return triedToMove;
}
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]);
MyGUI::UString::utf32string utf32string = ustring.asUTF32();
for (MyGUI::UString::utf32string::const_iterator it = utf32string.begin(); it != utf32string.end(); ++it)
MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::None, *it);
}
void KeyboardManager::keyPressed(const SDL_KeyboardEvent &arg)
{
// HACK: to make Morrowind's 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
&& MWBase::Environment::get().getWindowManager()->isConsoleMode())
SDL_StopTextInput();
bool consumed = false;
if (kc != OIS::KC_UNASSIGNED && !mInputBinder->detectingBindingState())
{
consumed = MWBase::Environment::get().getWindowManager()->injectKeyPress(MyGUI::KeyCode::Enum(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)))
consumed = true;
MWBase::Environment::get().getInputManager()->setJoystickLastUsed(!consumed);
}
if (arg.repeat)
return;
if (!mControlsDisabled && !consumed)
mInputBinder->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);
if (!mInputBinder->detectingBindingState())
MWBase::Environment::get().getInputManager()->setJoystickLastUsed(!MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc)));
mInputBinder->keyReleased(arg);
}
}

View File

@ -0,0 +1,45 @@
#ifndef MWINPUT_MWKEYBOARDMANAGER_H
#define MWINPUT_MWKEYBOARDMANAGER_H
#include <components/settings/settings.hpp>
#include <components/sdlutil/events.hpp>
namespace SDLUtil
{
class InputWrapper;
}
namespace ICS
{
class InputControlSystem;
}
namespace MWInput
{
class ActionManager;
class KeyboardManager : public SDLUtil::KeyListener
{
public:
KeyboardManager(ICS::InputControlSystem* inputBinder, SDLUtil::InputWrapper* inputWrapper, ActionManager* actionManager);
virtual ~KeyboardManager() = default;
bool update(float dt, bool disableControls);
virtual void textInput(const SDL_TextInputEvent &arg);
virtual void keyPressed(const SDL_KeyboardEvent &arg);
virtual void keyReleased(const SDL_KeyboardEvent &arg);
private:
bool actionIsActive(int id);
ICS::InputControlSystem* mInputBinder;
SDLUtil::InputWrapper* mInputWrapper;
ActionManager* mActionManager;
bool mControlsDisabled;
};
}
#endif

View File

@ -31,7 +31,6 @@ namespace MWInput
bool update(float dt, bool isCursorEnabled, bool isTurningEnabled);
public:
virtual void sensorUpdated(const SDL_SensorEvent &arg);
virtual void displayOrientationChanged();
void processChangedSettings(const Settings::CategorySettingVector& changed);
@ -48,6 +47,11 @@ namespace MWInput
Minus_Z = -3
};
void updateSensors();
void correctGyroscopeAxes();
GyroscopeAxis mapGyroscopeAxis(const std::string& axis);
float getGyroAxisSpeed(GyroscopeAxis axis, const SDL_SensorEvent &arg) const;
bool mInvertX;
bool mInvertY;
@ -61,12 +65,6 @@ namespace MWInput
GyroscopeAxis mGyroVAxis;
float mGyroInputThreshold;
private:
void updateSensors();
void correctGyroscopeAxes();
GyroscopeAxis mapGyroscopeAxis(const std::string& axis);
float getGyroAxisSpeed(GyroscopeAxis axis, const SDL_SensorEvent &arg) const;
SDL_Sensor* mGyroscope;
};
}