mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-03-28 20:36:42 +00:00
Move gamepads handling to the separate file
This commit is contained in:
parent
f9d6137a29
commit
e353647d15
6 changed files with 525 additions and 357 deletions
|
@ -25,7 +25,7 @@ add_openmw_dir (mwrender
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwinput
|
add_openmw_dir (mwinput
|
||||||
actions actionmanager inputmanagerimp mousemanager sdlmappings sensormanager
|
actions actionmanager controllermanager inputmanagerimp mousemanager sdlmappings sensormanager
|
||||||
)
|
)
|
||||||
|
|
||||||
add_openmw_dir (mwgui
|
add_openmw_dir (mwgui
|
||||||
|
|
409
apps/openmw/mwinput/controllermanager.cpp
Normal file
409
apps/openmw/mwinput/controllermanager.cpp
Normal file
|
@ -0,0 +1,409 @@
|
||||||
|
#include "controllermanager.hpp"
|
||||||
|
|
||||||
|
#include <MyGUI_Button.h>
|
||||||
|
#include <MyGUI_InputManager.h>
|
||||||
|
#include <MyGUI_Widget.h>
|
||||||
|
|
||||||
|
#include <extern/oics/ICSInputControlSystem.h>
|
||||||
|
|
||||||
|
#include <components/debug/debuglog.hpp>
|
||||||
|
|
||||||
|
#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 "actions.hpp"
|
||||||
|
#include "actionmanager.hpp"
|
||||||
|
#include "mousemanager.hpp"
|
||||||
|
|
||||||
|
namespace MWInput
|
||||||
|
{
|
||||||
|
static const int sFakeDeviceID = 1;
|
||||||
|
|
||||||
|
ControllerManager::ControllerManager(ICS::InputControlSystem* inputBinder,
|
||||||
|
SDLUtil::InputWrapper* inputWrapper,
|
||||||
|
ActionManager* actionManager,
|
||||||
|
MouseManager* mouseManager,
|
||||||
|
const std::string& userControllerBindingsFile,
|
||||||
|
const std::string& controllerBindingsFile)
|
||||||
|
: mInputBinder(inputBinder)
|
||||||
|
, mInputWrapper(inputWrapper)
|
||||||
|
, mActionManager(actionManager)
|
||||||
|
, mMouseManager(mouseManager)
|
||||||
|
, mJoystickEnabled (Settings::Manager::getBool("enable controller", "Input"))
|
||||||
|
, mGamepadCursorSpeed(Settings::Manager::getFloat("gamepad cursor speed", "Input"))
|
||||||
|
, mInvUiScalingFactor(1.f)
|
||||||
|
, mSneakToggleShortcutTimer(0.f)
|
||||||
|
, mGamepadZoom(0)
|
||||||
|
, mGamepadGuiCursorEnabled(true)
|
||||||
|
, mControlsDisabled(false)
|
||||||
|
, mJoystickLastUsed(false)
|
||||||
|
, mSneakGamepadShortcut(false)
|
||||||
|
, mGamepadPreviewMode(false)
|
||||||
|
{
|
||||||
|
if(!controllerBindingsFile.empty())
|
||||||
|
{
|
||||||
|
SDL_GameControllerAddMappingsFromFile(controllerBindingsFile.c_str());
|
||||||
|
}
|
||||||
|
if(!userControllerBindingsFile.empty())
|
||||||
|
{
|
||||||
|
SDL_GameControllerAddMappingsFromFile(userControllerBindingsFile.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Open all presently connected sticks
|
||||||
|
int numSticks = SDL_NumJoysticks();
|
||||||
|
for(int i = 0; i < numSticks; i++)
|
||||||
|
{
|
||||||
|
if(SDL_IsGameController(i))
|
||||||
|
{
|
||||||
|
SDL_ControllerDeviceEvent evt;
|
||||||
|
evt.which = i;
|
||||||
|
controllerAdded(sFakeDeviceID, evt);
|
||||||
|
Log(Debug::Info) << "Detected game controller: " << SDL_GameControllerNameForIndex(i);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log(Debug::Info) << "Detected unusable controller: " << SDL_JoystickNameForIndex(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float uiScale = Settings::Manager::getFloat("scaling factor", "GUI");
|
||||||
|
if (uiScale != 0.f)
|
||||||
|
mInvUiScalingFactor = 1.f / uiScale;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ControllerManager::clear()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void ControllerManager::processChangedSettings(const Settings::CategorySettingVector& changed)
|
||||||
|
{
|
||||||
|
for (Settings::CategorySettingVector::const_iterator it = changed.begin(); it != changed.end(); ++it)
|
||||||
|
{
|
||||||
|
if (it->first == "Input" && it->second == "enable controller")
|
||||||
|
mJoystickEnabled = Settings::Manager::getBool("enable controller", "Input");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ControllerManager::actionIsActive (int id)
|
||||||
|
{
|
||||||
|
return (mInputBinder->getChannel (id)->getValue ()==1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ControllerManager::update(float dt, bool disableControls, bool gamepadPreviewMode)
|
||||||
|
{
|
||||||
|
mControlsDisabled = disableControls;
|
||||||
|
mGamepadPreviewMode = gamepadPreviewMode;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
xAxis *= (1.5f - mInputBinder->getChannel(A_Use)->getValue());
|
||||||
|
yAxis *= (1.5f - mInputBinder->getChannel(A_Use)->getValue());
|
||||||
|
|
||||||
|
// 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
|
||||||
|
float xMove = xAxis * dt * 1500.0f * mInvUiScalingFactor * mGamepadCursorSpeed;
|
||||||
|
float yMove = yAxis * dt * 1500.0f * mInvUiScalingFactor * mGamepadCursorSpeed;
|
||||||
|
if (xMove != 0 || yMove != 0 || zAxis != 0)
|
||||||
|
{
|
||||||
|
int mouseWheelMove = static_cast<int>(-zAxis * dt * 1500.0f);
|
||||||
|
|
||||||
|
mMouseManager->injectMouseMove(xMove, yMove, mouseWheelMove);
|
||||||
|
mMouseManager->warpMouse();
|
||||||
|
MWBase::Environment::get().getWindowManager()->setCursorActive(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Configure player movement according to keyboard 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)
|
||||||
|
{
|
||||||
|
triedToMove = true;
|
||||||
|
player.setLeftRight((xAxis - 0.5f) * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (yAxis != .5)
|
||||||
|
{
|
||||||
|
triedToMove = true;
|
||||||
|
player.setAutoMove (false);
|
||||||
|
player.setForwardBackward((yAxis - 0.5f) * 2 * -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (triedToMove)
|
||||||
|
mJoystickLastUsed = true;
|
||||||
|
|
||||||
|
if(triedToMove) MWBase::Environment::get().getInputManager()->resetIdleTime();
|
||||||
|
|
||||||
|
static const bool isToggleSneak = Settings::Manager::getBool("toggle sneak", "Input");
|
||||||
|
if (!isToggleSneak)
|
||||||
|
{
|
||||||
|
if(mJoystickLastUsed)
|
||||||
|
{
|
||||||
|
if(actionIsActive(A_Sneak))
|
||||||
|
{
|
||||||
|
if(mSneakToggleShortcutTimer) // New Sneak Button Press
|
||||||
|
{
|
||||||
|
if(mSneakToggleShortcutTimer <= 0.3f)
|
||||||
|
{
|
||||||
|
mSneakGamepadShortcut = true;
|
||||||
|
mActionManager->toggleSneaking();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mSneakGamepadShortcut = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!mActionManager->isSneaking())
|
||||||
|
mActionManager->toggleSneaking();
|
||||||
|
mSneakToggleShortcutTimer = 0.f;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!mSneakGamepadShortcut && mActionManager->isSneaking())
|
||||||
|
mActionManager->toggleSneaking();
|
||||||
|
if(mSneakToggleShortcutTimer <= 0.3f)
|
||||||
|
mSneakToggleShortcutTimer += dt;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
player.setSneak(actionIsActive(A_Sneak));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (MWBase::Environment::get().getInputManager()->getControlSwitch("playerviewswitch"))
|
||||||
|
{
|
||||||
|
if (!actionIsActive(A_TogglePOV))
|
||||||
|
mGamepadZoom = 0;
|
||||||
|
|
||||||
|
if(mGamepadZoom)
|
||||||
|
{
|
||||||
|
MWBase::Environment::get().getWorld()->changeVanityModeScale(mGamepadZoom);
|
||||||
|
MWBase::Environment::get().getWorld()->setCameraDistance(mGamepadZoom, true, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ControllerManager::buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg )
|
||||||
|
{
|
||||||
|
if (!mJoystickEnabled || mInputBinder->detectingBindingState())
|
||||||
|
return;
|
||||||
|
|
||||||
|
mJoystickLastUsed = true;
|
||||||
|
if (MWBase::Environment::get().getWindowManager()->isGuiMode())
|
||||||
|
{
|
||||||
|
if (gamepadToGuiControl(arg))
|
||||||
|
return;
|
||||||
|
if (mGamepadGuiCursorEnabled)
|
||||||
|
{
|
||||||
|
// Temporary mouse binding until keyboard controls are available:
|
||||||
|
if (arg.button == SDL_CONTROLLER_BUTTON_A) // We'll pretend that A is left click.
|
||||||
|
{
|
||||||
|
bool mousePressSuccess = mMouseManager->injectMouseButtonPress(SDL_BUTTON_LEFT);
|
||||||
|
if (MyGUI::InputManager::getInstance().getMouseFocusWidget())
|
||||||
|
{
|
||||||
|
MyGUI::Button* b = MyGUI::InputManager::getInstance().getMouseFocusWidget()->castType<MyGUI::Button>(false);
|
||||||
|
if (b && b->getEnabled())
|
||||||
|
MWBase::Environment::get().getWindowManager()->playSound("Menu Click");
|
||||||
|
}
|
||||||
|
|
||||||
|
MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(!mousePressSuccess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
MWBase::Environment::get().getInputManager()->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));
|
||||||
|
|
||||||
|
if (!mControlsDisabled)
|
||||||
|
mInputBinder->buttonPressed(deviceID, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ControllerManager::buttonReleased(int deviceID, const SDL_ControllerButtonEvent &arg )
|
||||||
|
{
|
||||||
|
if(mInputBinder->detectingBindingState())
|
||||||
|
{
|
||||||
|
mInputBinder->buttonReleased(deviceID, arg);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!mJoystickEnabled || mControlsDisabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mJoystickLastUsed = true;
|
||||||
|
if (MWBase::Environment::get().getWindowManager()->isGuiMode())
|
||||||
|
{
|
||||||
|
if (mGamepadGuiCursorEnabled)
|
||||||
|
{
|
||||||
|
// Temporary mouse binding until keyboard controls are available:
|
||||||
|
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.
|
||||||
|
return;
|
||||||
|
|
||||||
|
MWBase::Environment::get().getInputManager()->setPlayerControlsEnabled(!mousePressSuccess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
MWBase::Environment::get().getInputManager()->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)));
|
||||||
|
|
||||||
|
mInputBinder->buttonReleased(deviceID, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ControllerManager::axisMoved(int deviceID, const SDL_ControllerAxisEvent &arg)
|
||||||
|
{
|
||||||
|
if(!mJoystickEnabled || mControlsDisabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mJoystickLastUsed = true;
|
||||||
|
if (MWBase::Environment::get().getWindowManager()->isGuiMode())
|
||||||
|
{
|
||||||
|
gamepadToGuiControl(arg);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(mGamepadPreviewMode && arg.value) // Preview Mode Gamepad Zooming
|
||||||
|
{
|
||||||
|
if(arg.axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT)
|
||||||
|
{
|
||||||
|
mGamepadZoom = arg.value * 0.85f / 1000.f;
|
||||||
|
return; // Do not propagate event.
|
||||||
|
}
|
||||||
|
else if(arg.axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT)
|
||||||
|
{
|
||||||
|
mGamepadZoom = -arg.value * 0.85f / 1000.f;
|
||||||
|
return; // Do not propagate event.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mInputBinder->axisMoved(deviceID, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ControllerManager::controllerAdded(int deviceID, const SDL_ControllerDeviceEvent &arg)
|
||||||
|
{
|
||||||
|
mInputBinder->controllerAdded(deviceID, arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ControllerManager::controllerRemoved(const SDL_ControllerDeviceEvent &arg)
|
||||||
|
{
|
||||||
|
mInputBinder->controllerRemoved(arg);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ControllerManager::gamepadToGuiControl(const SDL_ControllerButtonEvent &arg)
|
||||||
|
{
|
||||||
|
// Presumption of GUI mode will be removed in the future.
|
||||||
|
// MyGUI KeyCodes *may* change.
|
||||||
|
|
||||||
|
MyGUI::KeyCode key = MyGUI::KeyCode::None;
|
||||||
|
switch (arg.button)
|
||||||
|
{
|
||||||
|
case SDL_CONTROLLER_BUTTON_DPAD_UP:
|
||||||
|
key = MyGUI::KeyCode::ArrowUp;
|
||||||
|
break;
|
||||||
|
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT:
|
||||||
|
key = MyGUI::KeyCode::ArrowRight;
|
||||||
|
break;
|
||||||
|
case SDL_CONTROLLER_BUTTON_DPAD_DOWN:
|
||||||
|
key = MyGUI::KeyCode::ArrowDown;
|
||||||
|
break;
|
||||||
|
case SDL_CONTROLLER_BUTTON_DPAD_LEFT:
|
||||||
|
key = MyGUI::KeyCode::ArrowLeft;
|
||||||
|
break;
|
||||||
|
case SDL_CONTROLLER_BUTTON_A:
|
||||||
|
// If we are using the joystick as a GUI mouse, A must be handled via mouse.
|
||||||
|
if (mGamepadGuiCursorEnabled)
|
||||||
|
return false;
|
||||||
|
key = MyGUI::KeyCode::Space;
|
||||||
|
break;
|
||||||
|
case SDL_CONTROLLER_BUTTON_B:
|
||||||
|
if (MyGUI::InputManager::getInstance().isModalAny())
|
||||||
|
MWBase::Environment::get().getWindowManager()->exitCurrentModal();
|
||||||
|
else
|
||||||
|
MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode();
|
||||||
|
return true;
|
||||||
|
case SDL_CONTROLLER_BUTTON_X:
|
||||||
|
key = MyGUI::KeyCode::Semicolon;
|
||||||
|
break;
|
||||||
|
case SDL_CONTROLLER_BUTTON_Y:
|
||||||
|
key = MyGUI::KeyCode::Apostrophe;
|
||||||
|
break;
|
||||||
|
case SDL_CONTROLLER_BUTTON_LEFTSHOULDER:
|
||||||
|
key = MyGUI::KeyCode::Period;
|
||||||
|
break;
|
||||||
|
case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER:
|
||||||
|
key = MyGUI::KeyCode::Slash;
|
||||||
|
break;
|
||||||
|
case SDL_CONTROLLER_BUTTON_LEFTSTICK:
|
||||||
|
mGamepadGuiCursorEnabled = !mGamepadGuiCursorEnabled;
|
||||||
|
MWBase::Environment::get().getWindowManager()->setCursorActive(mGamepadGuiCursorEnabled);
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some keys will work even when Text Input windows/modals are in focus.
|
||||||
|
if (SDL_IsTextInputActive())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
MWBase::Environment::get().getWindowManager()->injectKeyPress(key, 0, false);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ControllerManager::gamepadToGuiControl(const SDL_ControllerAxisEvent &arg)
|
||||||
|
{
|
||||||
|
switch (arg.axis)
|
||||||
|
{
|
||||||
|
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
|
||||||
|
if (arg.value == 32767) // Treat like a button.
|
||||||
|
MWBase::Environment::get().getWindowManager()->injectKeyPress(MyGUI::KeyCode::Minus, 0, false);
|
||||||
|
break;
|
||||||
|
case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
|
||||||
|
if (arg.value == 32767) // Treat like a button.
|
||||||
|
MWBase::Environment::get().getWindowManager()->injectKeyPress(MyGUI::KeyCode::Equals, 0, false);
|
||||||
|
break;
|
||||||
|
case SDL_CONTROLLER_AXIS_LEFTX:
|
||||||
|
case SDL_CONTROLLER_AXIS_LEFTY:
|
||||||
|
case SDL_CONTROLLER_AXIS_RIGHTX:
|
||||||
|
case SDL_CONTROLLER_AXIS_RIGHTY:
|
||||||
|
// If we are using the joystick as a GUI mouse, process mouse movement elsewhere.
|
||||||
|
if (mGamepadGuiCursorEnabled)
|
||||||
|
return false;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
77
apps/openmw/mwinput/controllermanager.hpp
Normal file
77
apps/openmw/mwinput/controllermanager.hpp
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
#ifndef MWINPUT_MWCONTROLLERMANAGER_H
|
||||||
|
#define MWINPUT_MWCONTROLLERMANAGER_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include <components/settings/settings.hpp>
|
||||||
|
#include <components/sdlutil/events.hpp>
|
||||||
|
#include <components/sdlutil/sdlinputwrapper.hpp>
|
||||||
|
|
||||||
|
namespace ICS
|
||||||
|
{
|
||||||
|
class InputControlSystem;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace MWInput
|
||||||
|
{
|
||||||
|
class ActionManager;
|
||||||
|
class MouseManager;
|
||||||
|
|
||||||
|
class ControllerManager : public SDLUtil::ControllerListener
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ControllerManager(ICS::InputControlSystem* inputBinder,
|
||||||
|
SDLUtil::InputWrapper* inputWrapper,
|
||||||
|
ActionManager* actionManager,
|
||||||
|
MouseManager* mouseManager,
|
||||||
|
const std::string& userControllerBindingsFile,
|
||||||
|
const std::string& controllerBindingsFile);
|
||||||
|
|
||||||
|
virtual ~ControllerManager() = default;
|
||||||
|
|
||||||
|
void clear();
|
||||||
|
|
||||||
|
void 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);
|
||||||
|
virtual void axisMoved(int deviceID, const SDL_ControllerAxisEvent &arg);
|
||||||
|
virtual void controllerAdded(int deviceID, const SDL_ControllerDeviceEvent &arg);
|
||||||
|
virtual void controllerRemoved(const SDL_ControllerDeviceEvent &arg);
|
||||||
|
|
||||||
|
void processChangedSettings(const Settings::CategorySettingVector& changed);
|
||||||
|
|
||||||
|
void setJoystickLastUsed(bool enabled) { mJoystickLastUsed = enabled; }
|
||||||
|
bool joystickLastUsed() { return mJoystickLastUsed; }
|
||||||
|
|
||||||
|
void setGuiCursorEnabled(bool enabled) { mGuiCursorEnabled = enabled; }
|
||||||
|
|
||||||
|
void setGamepadGuiCursorEnabled(bool enabled) { mGamepadGuiCursorEnabled = enabled; }
|
||||||
|
bool gamepadGuiCursorEnabled() { return mGamepadGuiCursorEnabled; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
// Return true if GUI consumes input.
|
||||||
|
bool gamepadToGuiControl(const SDL_ControllerButtonEvent &arg);
|
||||||
|
bool gamepadToGuiControl(const SDL_ControllerAxisEvent &arg);
|
||||||
|
|
||||||
|
bool actionIsActive(int id);
|
||||||
|
|
||||||
|
ICS::InputControlSystem* mInputBinder;
|
||||||
|
SDLUtil::InputWrapper* mInputWrapper;
|
||||||
|
ActionManager* mActionManager;
|
||||||
|
MouseManager* mMouseManager;
|
||||||
|
|
||||||
|
bool mJoystickEnabled;
|
||||||
|
float mGamepadCursorSpeed;
|
||||||
|
float mInvUiScalingFactor;
|
||||||
|
float mSneakToggleShortcutTimer;
|
||||||
|
float mGamepadZoom;
|
||||||
|
bool mGamepadGuiCursorEnabled;
|
||||||
|
bool mControlsDisabled;
|
||||||
|
bool mJoystickLastUsed;
|
||||||
|
bool mGuiCursorEnabled;
|
||||||
|
bool mSneakGamepadShortcut;
|
||||||
|
bool mGamepadPreviewMode;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
#endif
|
|
@ -31,6 +31,7 @@
|
||||||
#include "../mwmechanics/actorutil.hpp"
|
#include "../mwmechanics/actorutil.hpp"
|
||||||
|
|
||||||
#include "actionmanager.hpp"
|
#include "actionmanager.hpp"
|
||||||
|
#include "controllermanager.hpp"
|
||||||
#include "mousemanager.hpp"
|
#include "mousemanager.hpp"
|
||||||
#include "sdlmappings.hpp"
|
#include "sdlmappings.hpp"
|
||||||
#include "sensormanager.hpp"
|
#include "sensormanager.hpp"
|
||||||
|
@ -46,31 +47,23 @@ namespace MWInput
|
||||||
const std::string& controllerBindingsFile, bool grab)
|
const std::string& controllerBindingsFile, bool grab)
|
||||||
: mWindow(window)
|
: mWindow(window)
|
||||||
, mWindowVisible(true)
|
, mWindowVisible(true)
|
||||||
, mJoystickLastUsed(false)
|
|
||||||
, mInputManager(nullptr)
|
, mInputManager(nullptr)
|
||||||
, mVideoWrapper(nullptr)
|
, mVideoWrapper(nullptr)
|
||||||
, mUserFile(userFile)
|
, mUserFile(userFile)
|
||||||
, mDragDrop(false)
|
, mDragDrop(false)
|
||||||
, mGrabCursor (Settings::Manager::getBool("grab cursor", "Input"))
|
, mGrabCursor (Settings::Manager::getBool("grab cursor", "Input"))
|
||||||
, mControlsDisabled(false)
|
, mControlsDisabled(false)
|
||||||
, mJoystickEnabled (Settings::Manager::getBool("enable controller", "Input"))
|
|
||||||
, mPreviewPOVDelay(0.f)
|
, mPreviewPOVDelay(0.f)
|
||||||
, mTimeIdle(0.f)
|
, mTimeIdle(0.f)
|
||||||
, mGuiCursorEnabled(true)
|
, mGuiCursorEnabled(true)
|
||||||
, mGamepadGuiCursorEnabled(true)
|
|
||||||
, mDetectingKeyboard(false)
|
, mDetectingKeyboard(false)
|
||||||
, mOverencumberedMessageDelay(0.f)
|
, mOverencumberedMessageDelay(0.f)
|
||||||
, mGamepadZoom(0)
|
|
||||||
, mSneakToggleShortcutTimer(0.f)
|
|
||||||
, mSneakGamepadShortcut(false)
|
|
||||||
, mAttemptJump(false)
|
, mAttemptJump(false)
|
||||||
, mGamepadCursorSpeed(Settings::Manager::getFloat("gamepad cursor speed", "Input"))
|
|
||||||
, mFakeDeviceID(1)
|
, mFakeDeviceID(1)
|
||||||
{
|
{
|
||||||
mInputManager = new SDLUtil::InputWrapper(window, viewer, grab);
|
mInputManager = new SDLUtil::InputWrapper(window, viewer, grab);
|
||||||
mInputManager->setKeyboardEventCallback (this);
|
mInputManager->setKeyboardEventCallback (this);
|
||||||
mInputManager->setWindowEventCallback(this);
|
mInputManager->setWindowEventCallback(this);
|
||||||
mInputManager->setControllerEventCallback(this);
|
|
||||||
|
|
||||||
mVideoWrapper = new SDLUtil::VideoWrapper(window, viewer);
|
mVideoWrapper = new SDLUtil::VideoWrapper(window, viewer);
|
||||||
mVideoWrapper->setGammaContrast(Settings::Manager::getFloat("gamma", "Video"),
|
mVideoWrapper->setGammaContrast(Settings::Manager::getFloat("gamma", "Video"),
|
||||||
|
@ -95,42 +88,16 @@ namespace MWInput
|
||||||
mControlSwitch["playerviewswitch"] = true;
|
mControlSwitch["playerviewswitch"] = true;
|
||||||
mControlSwitch["vanitymode"] = true;
|
mControlSwitch["vanitymode"] = true;
|
||||||
|
|
||||||
/* Joystick Init */
|
mActionManager = new ActionManager(mInputBinder, screenCaptureOperation, viewer, screenCaptureHandler);
|
||||||
|
|
||||||
// Load controller mappings
|
|
||||||
if(!controllerBindingsFile.empty())
|
|
||||||
{
|
|
||||||
SDL_GameControllerAddMappingsFromFile(controllerBindingsFile.c_str());
|
|
||||||
}
|
|
||||||
if(!userControllerBindingsFile.empty())
|
|
||||||
{
|
|
||||||
SDL_GameControllerAddMappingsFromFile(userControllerBindingsFile.c_str());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Open all presently connected sticks
|
|
||||||
int numSticks = SDL_NumJoysticks();
|
|
||||||
for(int i = 0; i < numSticks; i++)
|
|
||||||
{
|
|
||||||
if(SDL_IsGameController(i))
|
|
||||||
{
|
|
||||||
SDL_ControllerDeviceEvent evt;
|
|
||||||
evt.which = i;
|
|
||||||
controllerAdded(mFakeDeviceID, evt);
|
|
||||||
Log(Debug::Info) << "Detected game controller: " << SDL_GameControllerNameForIndex(i);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Log(Debug::Info) << "Detected unusable controller: " << SDL_JoystickNameForIndex(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mSensorManager = new SensorManager();
|
|
||||||
mInputManager->setSensorEventCallback (mSensorManager);
|
|
||||||
|
|
||||||
mMouseManager = new MouseManager(mInputBinder, mInputManager, window);
|
mMouseManager = new MouseManager(mInputBinder, mInputManager, window);
|
||||||
mInputManager->setMouseEventCallback (mMouseManager);
|
mInputManager->setMouseEventCallback (mMouseManager);
|
||||||
|
|
||||||
mActionManager = new ActionManager(mInputBinder, screenCaptureOperation, viewer, screenCaptureHandler);
|
mControllerManager = new ControllerManager(mInputBinder, mInputManager, mActionManager, mMouseManager, userControllerBindingsFile, controllerBindingsFile);
|
||||||
|
mInputManager->setControllerEventCallback(mControllerManager);
|
||||||
|
|
||||||
|
mSensorManager = new SensorManager();
|
||||||
|
mInputManager->setSensorEventCallback (mSensorManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputManager::clear()
|
void InputManager::clear()
|
||||||
|
@ -140,6 +107,7 @@ namespace MWInput
|
||||||
it->second = true;
|
it->second = true;
|
||||||
|
|
||||||
mActionManager->clear();
|
mActionManager->clear();
|
||||||
|
mControllerManager->clear();
|
||||||
mSensorManager->clear();
|
mSensorManager->clear();
|
||||||
mMouseManager->clear();
|
mMouseManager->clear();
|
||||||
}
|
}
|
||||||
|
@ -149,6 +117,7 @@ namespace MWInput
|
||||||
mInputBinder->save (mUserFile);
|
mInputBinder->save (mUserFile);
|
||||||
|
|
||||||
delete mActionManager;
|
delete mActionManager;
|
||||||
|
delete mControllerManager;
|
||||||
delete mMouseManager;
|
delete mMouseManager;
|
||||||
delete mSensorManager;
|
delete mSensorManager;
|
||||||
|
|
||||||
|
@ -178,93 +147,6 @@ namespace MWInput
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InputManager::gamepadToGuiControl(const SDL_ControllerButtonEvent &arg)
|
|
||||||
{
|
|
||||||
// Presumption of GUI mode will be removed in the future.
|
|
||||||
// MyGUI KeyCodes *may* change.
|
|
||||||
|
|
||||||
MyGUI::KeyCode key = MyGUI::KeyCode::None;
|
|
||||||
switch (arg.button)
|
|
||||||
{
|
|
||||||
case SDL_CONTROLLER_BUTTON_DPAD_UP:
|
|
||||||
key = MyGUI::KeyCode::ArrowUp;
|
|
||||||
break;
|
|
||||||
case SDL_CONTROLLER_BUTTON_DPAD_RIGHT:
|
|
||||||
key = MyGUI::KeyCode::ArrowRight;
|
|
||||||
break;
|
|
||||||
case SDL_CONTROLLER_BUTTON_DPAD_DOWN:
|
|
||||||
key = MyGUI::KeyCode::ArrowDown;
|
|
||||||
break;
|
|
||||||
case SDL_CONTROLLER_BUTTON_DPAD_LEFT:
|
|
||||||
key = MyGUI::KeyCode::ArrowLeft;
|
|
||||||
break;
|
|
||||||
case SDL_CONTROLLER_BUTTON_A:
|
|
||||||
// If we are using the joystick as a GUI mouse, A must be handled via mouse.
|
|
||||||
if (mGamepadGuiCursorEnabled)
|
|
||||||
return false;
|
|
||||||
key = MyGUI::KeyCode::Space;
|
|
||||||
break;
|
|
||||||
case SDL_CONTROLLER_BUTTON_B:
|
|
||||||
if (MyGUI::InputManager::getInstance().isModalAny())
|
|
||||||
MWBase::Environment::get().getWindowManager()->exitCurrentModal();
|
|
||||||
else
|
|
||||||
MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode();
|
|
||||||
return true;
|
|
||||||
case SDL_CONTROLLER_BUTTON_X:
|
|
||||||
key = MyGUI::KeyCode::Semicolon;
|
|
||||||
break;
|
|
||||||
case SDL_CONTROLLER_BUTTON_Y:
|
|
||||||
key = MyGUI::KeyCode::Apostrophe;
|
|
||||||
break;
|
|
||||||
case SDL_CONTROLLER_BUTTON_LEFTSHOULDER:
|
|
||||||
key = MyGUI::KeyCode::Period;
|
|
||||||
break;
|
|
||||||
case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER:
|
|
||||||
key = MyGUI::KeyCode::Slash;
|
|
||||||
break;
|
|
||||||
case SDL_CONTROLLER_BUTTON_LEFTSTICK:
|
|
||||||
mGamepadGuiCursorEnabled = !mGamepadGuiCursorEnabled;
|
|
||||||
MWBase::Environment::get().getWindowManager()->setCursorActive(mGamepadGuiCursorEnabled);
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Some keys will work even when Text Input windows/modals are in focus.
|
|
||||||
if (SDL_IsTextInputActive())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
MWBase::Environment::get().getWindowManager()->injectKeyPress(key, 0, false);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InputManager::gamepadToGuiControl(const SDL_ControllerAxisEvent &arg)
|
|
||||||
{
|
|
||||||
switch (arg.axis)
|
|
||||||
{
|
|
||||||
case SDL_CONTROLLER_AXIS_TRIGGERRIGHT:
|
|
||||||
if (arg.value == 32767) // Treat like a button.
|
|
||||||
MWBase::Environment::get().getWindowManager()->injectKeyPress(MyGUI::KeyCode::Minus, 0, false);
|
|
||||||
break;
|
|
||||||
case SDL_CONTROLLER_AXIS_TRIGGERLEFT:
|
|
||||||
if (arg.value == 32767) // Treat like a button.
|
|
||||||
MWBase::Environment::get().getWindowManager()->injectKeyPress(MyGUI::KeyCode::Equals, 0, false);
|
|
||||||
break;
|
|
||||||
case SDL_CONTROLLER_AXIS_LEFTX:
|
|
||||||
case SDL_CONTROLLER_AXIS_LEFTY:
|
|
||||||
case SDL_CONTROLLER_AXIS_RIGHTX:
|
|
||||||
case SDL_CONTROLLER_AXIS_RIGHTY:
|
|
||||||
// If we are using the joystick as a GUI mouse, process mouse movement elsewhere.
|
|
||||||
if (mGamepadGuiCursorEnabled)
|
|
||||||
return false;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputManager::channelChanged(ICS::Channel* channel, float currentValue, float previousValue)
|
void InputManager::channelChanged(ICS::Channel* channel, float currentValue, float previousValue)
|
||||||
{
|
{
|
||||||
resetIdleTime ();
|
resetIdleTime ();
|
||||||
|
@ -297,12 +179,13 @@ namespace MWInput
|
||||||
|
|
||||||
if (mControlSwitch["playercontrols"])
|
if (mControlSwitch["playercontrols"])
|
||||||
{
|
{
|
||||||
|
bool joystickUsed = mControllerManager->joystickLastUsed();
|
||||||
if (action == A_Use)
|
if (action == A_Use)
|
||||||
{
|
{
|
||||||
if(mJoystickLastUsed && currentValue == 1.0 && actionIsActive(A_ToggleWeapon))
|
if(joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleWeapon))
|
||||||
action = A_CycleWeaponRight;
|
action = A_CycleWeaponRight;
|
||||||
|
|
||||||
else if (mJoystickLastUsed && currentValue == 1.0 && actionIsActive(A_ToggleSpell))
|
else if (joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleSpell))
|
||||||
action = A_CycleSpellRight;
|
action = A_CycleSpellRight;
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -314,10 +197,10 @@ namespace MWInput
|
||||||
}
|
}
|
||||||
else if (action == A_Jump)
|
else if (action == A_Jump)
|
||||||
{
|
{
|
||||||
if(mJoystickLastUsed && currentValue == 1.0 && actionIsActive(A_ToggleWeapon))
|
if(joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleWeapon))
|
||||||
action = A_CycleWeaponLeft;
|
action = A_CycleWeaponLeft;
|
||||||
|
|
||||||
else if (mJoystickLastUsed && currentValue == 1.0 && actionIsActive(A_ToggleSpell))
|
else if (joystickUsed && currentValue == 1.0 && actionIsActive(A_ToggleSpell))
|
||||||
action = A_CycleSpellLeft;
|
action = A_CycleSpellLeft;
|
||||||
|
|
||||||
else
|
else
|
||||||
|
@ -371,28 +254,7 @@ namespace MWInput
|
||||||
|
|
||||||
updateCursorMode();
|
updateCursorMode();
|
||||||
|
|
||||||
if (mGuiCursorEnabled && !(mJoystickLastUsed && !mGamepadGuiCursorEnabled))
|
mControllerManager->update(dt, disableControls, mPreviewPOVDelay == 1.f);
|
||||||
{
|
|
||||||
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;
|
|
||||||
|
|
||||||
xAxis *= (1.5f - mInputBinder->getChannel(A_Use)->getValue());
|
|
||||||
yAxis *= (1.5f - mInputBinder->getChannel(A_Use)->getValue());
|
|
||||||
|
|
||||||
// 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
|
|
||||||
float xMove = xAxis * dt * 1500.0f * mInvUiScalingFactor * mGamepadCursorSpeed;
|
|
||||||
float yMove = yAxis * dt * 1500.0f * mInvUiScalingFactor * mGamepadCursorSpeed;
|
|
||||||
if (xMove != 0|| yMove != 0 || zAxis != 0)
|
|
||||||
{
|
|
||||||
int mouseWheelMove = static_cast<int>(-zAxis * dt * 1500.0f);
|
|
||||||
|
|
||||||
mMouseManager->injectMouseMove(xMove, yMove, mouseWheelMove);
|
|
||||||
mMouseManager->warpMouse();
|
|
||||||
MWBase::Environment::get().getWindowManager()->setCursorActive(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mMouseManager->update(dt, disableControls))
|
if (mMouseManager->update(dt, disableControls))
|
||||||
resetIdleTime();
|
resetIdleTime();
|
||||||
|
@ -414,28 +276,10 @@ namespace MWInput
|
||||||
bool isRunning = false;
|
bool isRunning = false;
|
||||||
bool alwaysRunAllowed = false;
|
bool alwaysRunAllowed = false;
|
||||||
|
|
||||||
// joystick movement
|
// keyboard movement
|
||||||
float xAxis = mInputBinder->getChannel(A_MoveLeftRight)->getValue();
|
float xAxis = mInputBinder->getChannel(A_MoveLeftRight)->getValue();
|
||||||
float yAxis = mInputBinder->getChannel(A_MoveForwardBackward)->getValue();
|
float yAxis = mInputBinder->getChannel(A_MoveForwardBackward)->getValue();
|
||||||
if (xAxis != .5)
|
|
||||||
{
|
|
||||||
triedToMove = true;
|
|
||||||
player.setLeftRight((xAxis - 0.5f) * 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (yAxis != .5)
|
|
||||||
{
|
|
||||||
triedToMove = true;
|
|
||||||
player.setAutoMove (false);
|
|
||||||
player.setForwardBackward((yAxis - 0.5f) * 2 * -1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (triedToMove)
|
|
||||||
mJoystickLastUsed = true;
|
|
||||||
|
|
||||||
// keyboard movement
|
|
||||||
isRunning = xAxis > .75 || xAxis < .25 || yAxis > .75 || yAxis < .25;
|
isRunning = xAxis > .75 || xAxis < .25 || yAxis > .75 || yAxis < .25;
|
||||||
if(triedToMove) resetIdleTime();
|
|
||||||
|
|
||||||
if (actionIsActive(A_MoveLeft) != actionIsActive(A_MoveRight))
|
if (actionIsActive(A_MoveLeft) != actionIsActive(A_MoveRight))
|
||||||
{
|
{
|
||||||
|
@ -462,34 +306,7 @@ namespace MWInput
|
||||||
static const bool isToggleSneak = Settings::Manager::getBool("toggle sneak", "Input");
|
static const bool isToggleSneak = Settings::Manager::getBool("toggle sneak", "Input");
|
||||||
if (!isToggleSneak)
|
if (!isToggleSneak)
|
||||||
{
|
{
|
||||||
if(mJoystickLastUsed)
|
if(!mControllerManager->joystickLastUsed())
|
||||||
{
|
|
||||||
if(actionIsActive(A_Sneak))
|
|
||||||
{
|
|
||||||
if(mSneakToggleShortcutTimer) // New Sneak Button Press
|
|
||||||
{
|
|
||||||
if(mSneakToggleShortcutTimer <= 0.3f)
|
|
||||||
{
|
|
||||||
mSneakGamepadShortcut = true;
|
|
||||||
mActionManager->toggleSneaking();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
mSneakGamepadShortcut = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!mActionManager->isSneaking())
|
|
||||||
mActionManager->toggleSneaking();
|
|
||||||
mSneakToggleShortcutTimer = 0.f;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(!mSneakGamepadShortcut && mActionManager->isSneaking())
|
|
||||||
mActionManager->toggleSneaking();
|
|
||||||
if(mSneakToggleShortcutTimer <= 0.3f)
|
|
||||||
mSneakToggleShortcutTimer += dt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
player.setSneak(actionIsActive(A_Sneak));
|
player.setSneak(actionIsActive(A_Sneak));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -537,13 +354,6 @@ namespace MWInput
|
||||||
MWBase::Environment::get().getWorld()->togglePOV();
|
MWBase::Environment::get().getWorld()->togglePOV();
|
||||||
}
|
}
|
||||||
mPreviewPOVDelay = 0.f;
|
mPreviewPOVDelay = 0.f;
|
||||||
mGamepadZoom = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(mGamepadZoom)
|
|
||||||
{
|
|
||||||
MWBase::Environment::get().getWorld()->changeVanityModeScale(mGamepadZoom);
|
|
||||||
MWBase::Environment::get().getWorld()->setCameraDistance(mGamepadZoom, true, true);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -562,8 +372,6 @@ namespace MWInput
|
||||||
updateIdleTime(dt);
|
updateIdleTime(dt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
mGamepadZoom = 0;
|
|
||||||
mAttemptJump = false; // Can only jump on first frame input is on
|
mAttemptJump = false; // Can only jump on first frame input is on
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -574,17 +382,18 @@ namespace MWInput
|
||||||
|
|
||||||
void InputManager::setGamepadGuiCursorEnabled(bool enabled)
|
void InputManager::setGamepadGuiCursorEnabled(bool enabled)
|
||||||
{
|
{
|
||||||
mGamepadGuiCursorEnabled = enabled;
|
mControllerManager->setGamepadGuiCursorEnabled(enabled);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputManager::changeInputMode(bool guiMode)
|
void InputManager::changeInputMode(bool guiMode)
|
||||||
{
|
{
|
||||||
mGuiCursorEnabled = guiMode;
|
mGuiCursorEnabled = guiMode;
|
||||||
mMouseManager->setGuiCursorEnabled(guiMode);
|
mControllerManager->setGuiCursorEnabled(mGuiCursorEnabled);
|
||||||
mMouseManager->setMouseLookEnabled(!guiMode);
|
mMouseManager->setGuiCursorEnabled(mGuiCursorEnabled);
|
||||||
|
mMouseManager->setMouseLookEnabled(!mGuiCursorEnabled);
|
||||||
if (guiMode)
|
if (guiMode)
|
||||||
MWBase::Environment::get().getWindowManager()->showCrosshair(false);
|
MWBase::Environment::get().getWindowManager()->showCrosshair(false);
|
||||||
MWBase::Environment::get().getWindowManager()->setCursorVisible(guiMode && (!mJoystickLastUsed || mGamepadGuiCursorEnabled));
|
MWBase::Environment::get().getWindowManager()->setCursorVisible(guiMode && (!mControllerManager->joystickLastUsed() || mControllerManager->gamepadGuiCursorEnabled()));
|
||||||
// if not in gui mode, the camera decides whether to show crosshair or not.
|
// if not in gui mode, the camera decides whether to show crosshair or not.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -598,9 +407,6 @@ namespace MWInput
|
||||||
if (it->first == "Input" && it->second == "grab cursor")
|
if (it->first == "Input" && it->second == "grab cursor")
|
||||||
mGrabCursor = Settings::Manager::getBool("grab cursor", "Input");
|
mGrabCursor = Settings::Manager::getBool("grab cursor", "Input");
|
||||||
|
|
||||||
if (it->first == "Input" && it->second == "enable controller")
|
|
||||||
mJoystickEnabled = Settings::Manager::getBool("enable controller", "Input");
|
|
||||||
|
|
||||||
if (it->first == "Video" && (
|
if (it->first == "Video" && (
|
||||||
it->second == "resolution x"
|
it->second == "resolution x"
|
||||||
|| it->second == "resolution y"
|
|| it->second == "resolution y"
|
||||||
|
@ -686,7 +492,7 @@ namespace MWInput
|
||||||
|
|
||||||
if (!mControlsDisabled && !consumed)
|
if (!mControlsDisabled && !consumed)
|
||||||
mInputBinder->keyPressed (arg);
|
mInputBinder->keyPressed (arg);
|
||||||
mJoystickLastUsed = false;
|
mControllerManager->setJoystickLastUsed(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputManager::textInput(const SDL_TextInputEvent &arg)
|
void InputManager::textInput(const SDL_TextInputEvent &arg)
|
||||||
|
@ -699,7 +505,7 @@ namespace MWInput
|
||||||
|
|
||||||
void InputManager::keyReleased(const SDL_KeyboardEvent &arg )
|
void InputManager::keyReleased(const SDL_KeyboardEvent &arg )
|
||||||
{
|
{
|
||||||
mJoystickLastUsed = false;
|
mControllerManager->setJoystickLastUsed(false);
|
||||||
OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym);
|
OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym);
|
||||||
|
|
||||||
if (!mInputBinder->detectingBindingState())
|
if (!mInputBinder->detectingBindingState())
|
||||||
|
@ -707,118 +513,6 @@ namespace MWInput
|
||||||
mInputBinder->keyReleased (arg);
|
mInputBinder->keyReleased (arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void InputManager::buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg )
|
|
||||||
{
|
|
||||||
if (!mJoystickEnabled || mInputBinder->detectingBindingState())
|
|
||||||
return;
|
|
||||||
|
|
||||||
mJoystickLastUsed = true;
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->isGuiMode())
|
|
||||||
{
|
|
||||||
if (gamepadToGuiControl(arg))
|
|
||||||
return;
|
|
||||||
if (mGamepadGuiCursorEnabled)
|
|
||||||
{
|
|
||||||
// Temporary mouse binding until keyboard controls are available:
|
|
||||||
if (arg.button == SDL_CONTROLLER_BUTTON_A) // We'll pretend that A is left click.
|
|
||||||
{
|
|
||||||
bool mousePressSuccess = mMouseManager->injectMouseButtonPress(SDL_BUTTON_LEFT);
|
|
||||||
if (MyGUI::InputManager::getInstance().getMouseFocusWidget())
|
|
||||||
{
|
|
||||||
MyGUI::Button* b = MyGUI::InputManager::getInstance().getMouseFocusWidget()->castType<MyGUI::Button>(false);
|
|
||||||
if (b && b->getEnabled())
|
|
||||||
MWBase::Environment::get().getWindowManager()->playSound("Menu Click");
|
|
||||||
}
|
|
||||||
|
|
||||||
setPlayerControlsEnabled(!mousePressSuccess);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
setPlayerControlsEnabled(true);
|
|
||||||
|
|
||||||
//esc, to leave initial movie screen
|
|
||||||
OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(SDLK_ESCAPE);
|
|
||||||
setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(kc), 0));
|
|
||||||
|
|
||||||
if (!mControlsDisabled)
|
|
||||||
mInputBinder->buttonPressed(deviceID, arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputManager::buttonReleased(int deviceID, const SDL_ControllerButtonEvent &arg )
|
|
||||||
{
|
|
||||||
if(mInputBinder->detectingBindingState())
|
|
||||||
{
|
|
||||||
mInputBinder->buttonReleased(deviceID, arg);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!mJoystickEnabled || mControlsDisabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mJoystickLastUsed = true;
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->isGuiMode())
|
|
||||||
{
|
|
||||||
if (mGamepadGuiCursorEnabled)
|
|
||||||
{
|
|
||||||
// Temporary mouse binding until keyboard controls are available:
|
|
||||||
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.
|
|
||||||
return;
|
|
||||||
|
|
||||||
setPlayerControlsEnabled(!mousePressSuccess);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
setPlayerControlsEnabled(true);
|
|
||||||
|
|
||||||
//esc, to leave initial movie screen
|
|
||||||
OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(SDLK_ESCAPE);
|
|
||||||
setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc)));
|
|
||||||
|
|
||||||
mInputBinder->buttonReleased(deviceID, arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputManager::axisMoved(int deviceID, const SDL_ControllerAxisEvent &arg )
|
|
||||||
{
|
|
||||||
if(!mJoystickEnabled || mControlsDisabled)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mJoystickLastUsed = true;
|
|
||||||
if (MWBase::Environment::get().getWindowManager()->isGuiMode())
|
|
||||||
{
|
|
||||||
gamepadToGuiControl(arg);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if(mPreviewPOVDelay == 1.f && arg.value) // Preview Mode Gamepad Zooming
|
|
||||||
{
|
|
||||||
if(arg.axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT)
|
|
||||||
{
|
|
||||||
mGamepadZoom = arg.value * 0.85f / 1000.f;
|
|
||||||
return; // Do not propagate event.
|
|
||||||
}
|
|
||||||
else if(arg.axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT)
|
|
||||||
{
|
|
||||||
mGamepadZoom = -arg.value * 0.85f / 1000.f;
|
|
||||||
return; // Do not propagate event.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
mInputBinder->axisMoved(deviceID, arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputManager::controllerAdded(int deviceID, const SDL_ControllerDeviceEvent &arg)
|
|
||||||
{
|
|
||||||
mInputBinder->controllerAdded(deviceID, arg);
|
|
||||||
}
|
|
||||||
void InputManager::controllerRemoved(const SDL_ControllerDeviceEvent &arg)
|
|
||||||
{
|
|
||||||
mInputBinder->controllerRemoved(arg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void InputManager::windowFocusChange(bool have_focus)
|
void InputManager::windowFocusChange(bool have_focus)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -1398,4 +1092,14 @@ namespace MWInput
|
||||||
{
|
{
|
||||||
loadControllerDefaults(true);
|
loadControllerDefaults(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InputManager::setJoystickLastUsed(bool enabled)
|
||||||
|
{
|
||||||
|
mControllerManager->setJoystickLastUsed(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool InputManager::joystickLastUsed()
|
||||||
|
{
|
||||||
|
return mControllerManager->joystickLastUsed();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,7 @@
|
||||||
namespace MWInput
|
namespace MWInput
|
||||||
{
|
{
|
||||||
class ActionManager;
|
class ActionManager;
|
||||||
|
class ControllerManager;
|
||||||
class MouseManager;
|
class MouseManager;
|
||||||
class SensorManager;
|
class SensorManager;
|
||||||
}
|
}
|
||||||
|
@ -63,7 +64,6 @@ namespace MWInput
|
||||||
public MWBase::InputManager,
|
public MWBase::InputManager,
|
||||||
public SDLUtil::KeyListener,
|
public SDLUtil::KeyListener,
|
||||||
public SDLUtil::WindowListener,
|
public SDLUtil::WindowListener,
|
||||||
public SDLUtil::ControllerListener,
|
|
||||||
public ICS::ChannelListener,
|
public ICS::ChannelListener,
|
||||||
public ICS::DetectingBindingListener
|
public ICS::DetectingBindingListener
|
||||||
{
|
{
|
||||||
|
@ -106,19 +106,13 @@ namespace MWInput
|
||||||
virtual void resetToDefaultKeyBindings();
|
virtual void resetToDefaultKeyBindings();
|
||||||
virtual void resetToDefaultControllerBindings();
|
virtual void resetToDefaultControllerBindings();
|
||||||
|
|
||||||
virtual void setJoystickLastUsed(bool enabled) { mJoystickLastUsed = enabled; }
|
virtual void setJoystickLastUsed(bool enabled);
|
||||||
virtual bool joystickLastUsed() {return mJoystickLastUsed;}
|
virtual bool joystickLastUsed();
|
||||||
|
|
||||||
virtual void keyPressed(const SDL_KeyboardEvent &arg );
|
virtual void keyPressed(const SDL_KeyboardEvent &arg );
|
||||||
virtual void keyReleased( const SDL_KeyboardEvent &arg );
|
virtual void keyReleased( const SDL_KeyboardEvent &arg );
|
||||||
virtual void textInput (const SDL_TextInputEvent &arg);
|
virtual void textInput (const SDL_TextInputEvent &arg);
|
||||||
|
|
||||||
virtual void buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg);
|
|
||||||
virtual void buttonReleased(int deviceID, const SDL_ControllerButtonEvent &arg);
|
|
||||||
virtual void axisMoved(int deviceID, const SDL_ControllerAxisEvent &arg);
|
|
||||||
virtual void controllerAdded(int deviceID, const SDL_ControllerDeviceEvent &arg);
|
|
||||||
virtual void controllerRemoved(const SDL_ControllerDeviceEvent &arg);
|
|
||||||
|
|
||||||
virtual void windowVisibilityChange( bool visible );
|
virtual void windowVisibilityChange( bool visible );
|
||||||
virtual void windowFocusChange( bool have_focus );
|
virtual void windowFocusChange( bool have_focus );
|
||||||
virtual void windowResized (int x, int y);
|
virtual void windowResized (int x, int y);
|
||||||
|
@ -159,9 +153,6 @@ namespace MWInput
|
||||||
SDL_Window* mWindow;
|
SDL_Window* mWindow;
|
||||||
bool mWindowVisible;
|
bool mWindowVisible;
|
||||||
|
|
||||||
bool mJoystickLastUsed;
|
|
||||||
MWWorld::Player* mPlayer;
|
|
||||||
|
|
||||||
ICS::InputControlSystem* mInputBinder;
|
ICS::InputControlSystem* mInputBinder;
|
||||||
|
|
||||||
SDLUtil::InputWrapper* mInputManager;
|
SDLUtil::InputWrapper* mInputManager;
|
||||||
|
@ -174,30 +165,22 @@ namespace MWInput
|
||||||
bool mGrabCursor;
|
bool mGrabCursor;
|
||||||
|
|
||||||
bool mControlsDisabled;
|
bool mControlsDisabled;
|
||||||
bool mJoystickEnabled;
|
|
||||||
|
|
||||||
float mPreviewPOVDelay;
|
float mPreviewPOVDelay;
|
||||||
float mTimeIdle;
|
float mTimeIdle;
|
||||||
|
|
||||||
bool mGuiCursorEnabled;
|
bool mGuiCursorEnabled;
|
||||||
bool mGamepadGuiCursorEnabled;
|
|
||||||
|
|
||||||
bool mDetectingKeyboard;
|
bool mDetectingKeyboard;
|
||||||
|
|
||||||
float mOverencumberedMessageDelay;
|
float mOverencumberedMessageDelay;
|
||||||
|
|
||||||
float mGamepadZoom;
|
|
||||||
bool mSneakToggles;
|
|
||||||
float mSneakToggleShortcutTimer;
|
|
||||||
bool mSneakGamepadShortcut;
|
|
||||||
bool mAttemptJump;
|
bool mAttemptJump;
|
||||||
|
|
||||||
std::map<std::string, bool> mControlSwitch;
|
std::map<std::string, bool> mControlSwitch;
|
||||||
|
|
||||||
float mInvUiScalingFactor;
|
|
||||||
float mGamepadCursorSpeed;
|
|
||||||
|
|
||||||
ActionManager* mActionManager;
|
ActionManager* mActionManager;
|
||||||
|
ControllerManager* mControllerManager;
|
||||||
MouseManager* mMouseManager;
|
MouseManager* mMouseManager;
|
||||||
SensorManager* mSensorManager;
|
SensorManager* mSensorManager;
|
||||||
|
|
||||||
|
@ -206,9 +189,6 @@ namespace MWInput
|
||||||
void updateIdleTime(float dt);
|
void updateIdleTime(float dt);
|
||||||
|
|
||||||
void handleGuiArrowKey(int action);
|
void handleGuiArrowKey(int action);
|
||||||
// Return true if GUI consumes input.
|
|
||||||
bool gamepadToGuiControl(const SDL_ControllerButtonEvent &arg);
|
|
||||||
bool gamepadToGuiControl(const SDL_ControllerAxisEvent &arg);
|
|
||||||
|
|
||||||
void updateCursorMode();
|
void updateCursorMode();
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
#ifndef MWINPUT_MWMOUSEMANAGER_H
|
#ifndef MWINPUT_MWMOUSEMANAGER_H
|
||||||
#define MWINPUT_MWMOUSEMANAGER_H
|
#define MWINPUT_MWMOUSEMANAGER_H
|
||||||
|
|
||||||
#include <SDL_sensor.h>
|
|
||||||
|
|
||||||
#include <components/settings/settings.hpp>
|
#include <components/settings/settings.hpp>
|
||||||
#include <components/sdlutil/events.hpp>
|
#include <components/sdlutil/events.hpp>
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue