2012-08-11 15:53:39 +00:00
|
|
|
#include "inputmanagerimp.hpp"
|
2010-07-17 17:58:15 +00:00
|
|
|
|
2015-11-14 01:43:24 +00:00
|
|
|
#include <osgViewer/ViewerEventHandlers>
|
|
|
|
|
2012-08-12 18:45:02 +00:00
|
|
|
#include <MyGUI_InputManager.h>
|
2012-08-27 08:01:53 +00:00
|
|
|
#include <MyGUI_Widget.h>
|
|
|
|
#include <MyGUI_Button.h>
|
2014-01-04 00:13:19 +00:00
|
|
|
#include <MyGUI_EditBox.h>
|
2010-07-17 17:58:15 +00:00
|
|
|
|
2015-02-27 21:22:32 +00:00
|
|
|
#include <SDL_version.h>
|
|
|
|
|
2018-08-14 19:05:43 +00:00
|
|
|
#include <components/debug/debuglog.hpp>
|
2015-05-13 14:50:47 +00:00
|
|
|
#include <components/sdlutil/sdlinputwrapper.hpp>
|
2015-05-14 18:31:16 +00:00
|
|
|
#include <components/sdlutil/sdlvideowrapper.hpp>
|
2016-10-20 00:12:01 +00:00
|
|
|
#include <components/esm/esmwriter.hpp>
|
|
|
|
#include <components/esm/esmreader.hpp>
|
|
|
|
#include <components/esm/controlsstate.hpp>
|
2015-05-13 14:50:47 +00:00
|
|
|
|
2012-08-10 13:15:48 +00:00
|
|
|
#include "../mwbase/world.hpp"
|
2012-08-12 18:45:02 +00:00
|
|
|
#include "../mwbase/windowmanager.hpp"
|
2013-11-16 10:07:23 +00:00
|
|
|
#include "../mwbase/statemanager.hpp"
|
2015-11-14 01:43:24 +00:00
|
|
|
#include "../mwbase/environment.hpp"
|
2017-08-18 15:24:34 +00:00
|
|
|
#include "../mwbase/mechanicsmanager.hpp"
|
2014-02-23 19:11:05 +00:00
|
|
|
|
|
|
|
#include "../mwworld/player.hpp"
|
|
|
|
#include "../mwworld/class.hpp"
|
|
|
|
#include "../mwworld/inventorystore.hpp"
|
|
|
|
#include "../mwworld/esmstore.hpp"
|
|
|
|
|
2014-06-17 15:18:30 +00:00
|
|
|
#include "../mwmechanics/npcstats.hpp"
|
2015-08-21 09:12:39 +00:00
|
|
|
#include "../mwmechanics/actorutil.hpp"
|
2010-07-17 17:58:15 +00:00
|
|
|
|
2020-04-08 10:48:23 +00:00
|
|
|
#include "mousemanager.hpp"
|
2020-04-08 07:43:45 +00:00
|
|
|
#include "sdlmappings.hpp"
|
2020-04-08 06:55:35 +00:00
|
|
|
#include "sensormanager.hpp"
|
|
|
|
|
2010-07-17 17:58:15 +00:00
|
|
|
namespace MWInput
|
|
|
|
{
|
2015-05-03 15:24:35 +00:00
|
|
|
InputManager::InputManager(
|
2015-05-13 14:50:47 +00:00
|
|
|
SDL_Window* window,
|
|
|
|
osg::ref_ptr<osgViewer::Viewer> viewer,
|
2015-11-14 01:43:24 +00:00
|
|
|
osg::ref_ptr<osgViewer::ScreenCaptureHandler> screenCaptureHandler,
|
2017-11-09 17:26:27 +00:00
|
|
|
osgViewer::ScreenCaptureHandler::CaptureOperation *screenCaptureOperation,
|
2015-01-20 00:55:17 +00:00
|
|
|
const std::string& userFile, bool userFileExists,
|
2019-08-03 19:55:58 +00:00
|
|
|
const std::string& userControllerBindingsFile,
|
2015-01-20 00:55:17 +00:00
|
|
|
const std::string& controllerBindingsFile, bool grab)
|
2015-05-14 18:31:16 +00:00
|
|
|
: mWindow(window)
|
2015-09-04 01:44:14 +00:00
|
|
|
, mWindowVisible(true)
|
2015-05-14 18:31:16 +00:00
|
|
|
, mViewer(viewer)
|
2015-11-14 01:43:24 +00:00
|
|
|
, mScreenCaptureHandler(screenCaptureHandler)
|
2017-11-09 17:26:27 +00:00
|
|
|
, mScreenCaptureOperation(screenCaptureOperation)
|
2015-05-14 18:31:16 +00:00
|
|
|
, mJoystickLastUsed(false)
|
2018-10-09 06:21:12 +00:00
|
|
|
, mPlayer(nullptr)
|
|
|
|
, mInputManager(nullptr)
|
|
|
|
, mVideoWrapper(nullptr)
|
2013-02-05 18:22:08 +00:00
|
|
|
, mUserFile(userFile)
|
2015-04-25 18:37:42 +00:00
|
|
|
, mDragDrop(false)
|
|
|
|
, mGrabCursor (Settings::Manager::getBool("grab cursor", "Input"))
|
2018-12-01 15:14:51 +00:00
|
|
|
, mInvertX (Settings::Manager::getBool("invert x axis", "Input"))
|
2012-08-13 00:55:22 +00:00
|
|
|
, mInvertY (Settings::Manager::getBool("invert y axis", "Input"))
|
2015-04-25 18:37:42 +00:00
|
|
|
, mControlsDisabled(false)
|
2019-02-15 14:53:50 +00:00
|
|
|
, mJoystickEnabled (Settings::Manager::getBool("enable controller", "Input"))
|
2012-08-17 12:42:42 +00:00
|
|
|
, mPreviewPOVDelay(0.f)
|
2012-08-17 21:31:57 +00:00
|
|
|
, mTimeIdle(0.f)
|
2015-04-25 18:37:42 +00:00
|
|
|
, mGuiCursorEnabled(true)
|
2019-03-03 09:21:00 +00:00
|
|
|
, mGamepadGuiCursorEnabled(true)
|
2015-04-25 18:37:42 +00:00
|
|
|
, mDetectingKeyboard(false)
|
2013-02-25 15:31:48 +00:00
|
|
|
, mOverencumberedMessageDelay(0.f)
|
2019-02-27 13:29:48 +00:00
|
|
|
, mGamepadZoom(0)
|
2015-04-25 18:37:42 +00:00
|
|
|
, mUserFileExists(userFileExists)
|
2014-06-08 17:50:39 +00:00
|
|
|
, mAlwaysRunActive(Settings::Manager::getBool("always run", "Input"))
|
2015-03-08 20:23:46 +00:00
|
|
|
, mSneakToggles(Settings::Manager::getBool("toggle sneak", "Input"))
|
2019-02-27 22:03:16 +00:00
|
|
|
, mSneakToggleShortcutTimer(0.f)
|
|
|
|
, mSneakGamepadShortcut(false)
|
2015-03-08 20:23:46 +00:00
|
|
|
, mSneaking(false)
|
2014-05-27 17:12:27 +00:00
|
|
|
, mAttemptJump(false)
|
2019-07-02 11:19:10 +00:00
|
|
|
, mGamepadCursorSpeed(Settings::Manager::getFloat("gamepad cursor speed", "Input"))
|
2015-05-23 20:44:00 +00:00
|
|
|
, mFakeDeviceID(1)
|
2010-07-17 17:58:15 +00:00
|
|
|
{
|
2015-05-13 14:50:47 +00:00
|
|
|
mInputManager = new SDLUtil::InputWrapper(window, viewer, grab);
|
2013-01-08 10:19:05 +00:00
|
|
|
mInputManager->setKeyboardEventCallback (this);
|
2013-01-09 10:10:05 +00:00
|
|
|
mInputManager->setWindowEventCallback(this);
|
2014-12-09 03:57:32 +00:00
|
|
|
mInputManager->setControllerEventCallback(this);
|
2010-07-17 17:58:15 +00:00
|
|
|
|
2015-05-14 18:31:16 +00:00
|
|
|
mVideoWrapper = new SDLUtil::VideoWrapper(window, viewer);
|
|
|
|
mVideoWrapper->setGammaContrast(Settings::Manager::getFloat("gamma", "Video"),
|
|
|
|
Settings::Manager::getFloat("contrast", "Video"));
|
|
|
|
|
2013-01-08 10:19:05 +00:00
|
|
|
std::string file = userFileExists ? userFile : "";
|
2018-10-09 06:21:12 +00:00
|
|
|
mInputBinder = new ICS::InputControlSystem(file, true, this, nullptr, A_Last);
|
2010-07-17 17:58:15 +00:00
|
|
|
|
2012-08-12 20:59:58 +00:00
|
|
|
loadKeyDefaults();
|
2014-12-09 03:57:32 +00:00
|
|
|
loadControllerDefaults();
|
2011-11-28 15:51:11 +00:00
|
|
|
|
2012-08-12 23:26:15 +00:00
|
|
|
for (int i = 0; i < A_Last; ++i)
|
2012-08-12 18:45:02 +00:00
|
|
|
{
|
2013-01-10 21:21:47 +00:00
|
|
|
mInputBinder->getChannel (i)->addListener (this);
|
2012-08-12 18:45:02 +00:00
|
|
|
}
|
2011-11-28 15:51:11 +00:00
|
|
|
|
2012-08-12 18:45:02 +00:00
|
|
|
mControlSwitch["playercontrols"] = true;
|
|
|
|
mControlSwitch["playerfighting"] = true;
|
|
|
|
mControlSwitch["playerjumping"] = true;
|
|
|
|
mControlSwitch["playerlooking"] = true;
|
|
|
|
mControlSwitch["playermagic"] = true;
|
|
|
|
mControlSwitch["playerviewswitch"] = true;
|
|
|
|
mControlSwitch["vanitymode"] = true;
|
2014-12-20 20:46:11 +00:00
|
|
|
|
2015-09-16 18:45:37 +00:00
|
|
|
/* Joystick Init */
|
2014-12-20 20:46:11 +00:00
|
|
|
|
2015-09-16 18:45:37 +00:00
|
|
|
// Load controller mappings
|
2019-08-03 19:55:58 +00:00
|
|
|
if(!controllerBindingsFile.empty())
|
2014-12-20 20:46:11 +00:00
|
|
|
{
|
2015-01-20 00:55:17 +00:00
|
|
|
SDL_GameControllerAddMappingsFromFile(controllerBindingsFile.c_str());
|
2014-12-20 20:46:11 +00:00
|
|
|
}
|
2019-08-03 19:55:58 +00:00
|
|
|
if(!userControllerBindingsFile.empty())
|
|
|
|
{
|
|
|
|
SDL_GameControllerAddMappingsFromFile(userControllerBindingsFile.c_str());
|
|
|
|
}
|
2014-12-20 20:46:11 +00:00
|
|
|
|
2015-09-16 18:45:37 +00:00
|
|
|
// Open all presently connected sticks
|
|
|
|
int numSticks = SDL_NumJoysticks();
|
|
|
|
for(int i = 0; i < numSticks; i++)
|
|
|
|
{
|
2014-12-20 20:46:11 +00:00
|
|
|
if(SDL_IsGameController(i))
|
|
|
|
{
|
|
|
|
SDL_ControllerDeviceEvent evt;
|
|
|
|
evt.which = i;
|
2015-01-19 21:36:15 +00:00
|
|
|
controllerAdded(mFakeDeviceID, evt);
|
2018-08-14 19:05:43 +00:00
|
|
|
Log(Debug::Info) << "Detected game controller: " << SDL_GameControllerNameForIndex(i);
|
2014-12-20 20:46:11 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2018-08-14 19:05:43 +00:00
|
|
|
Log(Debug::Info) << "Detected unusable controller: " << SDL_JoystickNameForIndex(i);
|
2014-12-20 20:46:11 +00:00
|
|
|
}
|
2015-09-16 18:45:37 +00:00
|
|
|
}
|
2015-05-14 22:41:21 +00:00
|
|
|
|
2020-04-08 06:55:35 +00:00
|
|
|
mSensorManager = new SensorManager();
|
|
|
|
mInputManager->setSensorEventCallback (mSensorManager);
|
2020-03-14 18:24:36 +00:00
|
|
|
|
2020-04-08 10:48:23 +00:00
|
|
|
mMouseManager = new MouseManager(mInputBinder, mInputManager, window);
|
|
|
|
mInputManager->setMouseEventCallback (mMouseManager);
|
2010-08-03 14:26:43 +00:00
|
|
|
}
|
|
|
|
|
2014-03-09 02:34:49 +00:00
|
|
|
void InputManager::clear()
|
|
|
|
{
|
|
|
|
// Enable all controls
|
|
|
|
for (std::map<std::string, bool>::iterator it = mControlSwitch.begin(); it != mControlSwitch.end(); ++it)
|
|
|
|
it->second = true;
|
2020-04-08 06:55:35 +00:00
|
|
|
|
|
|
|
mSensorManager->clear();
|
2020-04-08 10:48:23 +00:00
|
|
|
mMouseManager->clear();
|
2014-03-09 02:34:49 +00:00
|
|
|
}
|
|
|
|
|
2012-08-12 18:45:02 +00:00
|
|
|
InputManager::~InputManager()
|
2011-01-14 14:52:28 +00:00
|
|
|
{
|
2013-01-10 21:21:47 +00:00
|
|
|
mInputBinder->save (mUserFile);
|
2011-01-18 14:20:36 +00:00
|
|
|
|
2020-04-08 06:55:35 +00:00
|
|
|
delete mSensorManager;
|
2020-03-14 18:24:36 +00:00
|
|
|
|
2013-01-10 21:21:47 +00:00
|
|
|
delete mInputBinder;
|
2011-01-16 15:47:03 +00:00
|
|
|
|
2015-05-13 14:50:47 +00:00
|
|
|
delete mInputManager;
|
2015-05-14 18:31:16 +00:00
|
|
|
|
|
|
|
delete mVideoWrapper;
|
2012-08-10 13:15:48 +00:00
|
|
|
}
|
|
|
|
|
2015-09-04 01:44:14 +00:00
|
|
|
bool InputManager::isWindowVisible()
|
|
|
|
{
|
|
|
|
return mWindowVisible;
|
|
|
|
}
|
|
|
|
|
2014-05-31 23:51:21 +00:00
|
|
|
void InputManager::setPlayerControlsEnabled(bool enabled)
|
|
|
|
{
|
2017-09-24 11:49:35 +00:00
|
|
|
int playerChannels[] = {A_AutoMove, A_AlwaysRun, A_ToggleWeapon,
|
2014-05-31 23:51:21 +00:00
|
|
|
A_ToggleSpell, A_Rest, A_QuickKey1, A_QuickKey2,
|
|
|
|
A_QuickKey3, A_QuickKey4, A_QuickKey5, A_QuickKey6,
|
2014-06-07 02:35:16 +00:00
|
|
|
A_QuickKey7, A_QuickKey8, A_QuickKey9, A_QuickKey10,
|
2017-03-26 18:56:36 +00:00
|
|
|
A_Use, A_Journal};
|
2014-05-31 23:51:21 +00:00
|
|
|
|
2017-09-24 11:49:35 +00:00
|
|
|
for(size_t i = 0; i < sizeof(playerChannels)/sizeof(playerChannels[0]); i++) {
|
2014-05-31 23:51:21 +00:00
|
|
|
int pc = playerChannels[i];
|
|
|
|
mInputBinder->getChannel(pc)->setEnabled(enabled);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-10 23:11:03 +00:00
|
|
|
bool isLeftOrRightButton(int action, ICS::InputControlSystem* ics, int deviceId, bool joystick)
|
|
|
|
{
|
|
|
|
int mouseBinding = ics->getMouseButtonBinding(ics->getControl(action), ICS::Control::INCREASE);
|
|
|
|
if (mouseBinding != ICS_MAX_DEVICE_BUTTONS)
|
|
|
|
return true;
|
|
|
|
int buttonBinding = ics->getJoystickButtonBinding(ics->getControl(action), deviceId, ICS::Control::INCREASE);
|
|
|
|
if (joystick && (buttonBinding == 0 || buttonBinding == 1))
|
|
|
|
return true;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2017-09-27 11:14:26 +00:00
|
|
|
void InputManager::handleGuiArrowKey(int action)
|
|
|
|
{
|
2019-07-29 13:13:52 +00:00
|
|
|
// This is currently keyboard-specific code
|
|
|
|
// TODO: see if GUI controls can be refactored into a single function
|
|
|
|
if (mJoystickLastUsed)
|
|
|
|
return;
|
|
|
|
|
2017-11-10 20:48:11 +00:00
|
|
|
if (SDL_IsTextInputActive())
|
|
|
|
return;
|
2018-02-10 23:11:03 +00:00
|
|
|
|
|
|
|
if (isLeftOrRightButton(action, mInputBinder, mFakeDeviceID, mJoystickLastUsed))
|
|
|
|
return;
|
|
|
|
|
2017-09-27 11:14:26 +00:00
|
|
|
MyGUI::KeyCode key;
|
|
|
|
switch (action)
|
|
|
|
{
|
|
|
|
case A_MoveLeft:
|
|
|
|
key = MyGUI::KeyCode::ArrowLeft;
|
|
|
|
break;
|
|
|
|
case A_MoveRight:
|
|
|
|
key = MyGUI::KeyCode::ArrowRight;
|
|
|
|
break;
|
|
|
|
case A_MoveForward:
|
|
|
|
key = MyGUI::KeyCode::ArrowUp;
|
|
|
|
break;
|
|
|
|
case A_MoveBackward:
|
|
|
|
default:
|
|
|
|
key = MyGUI::KeyCode::ArrowDown;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2018-09-09 19:10:09 +00:00
|
|
|
MWBase::Environment::get().getWindowManager()->injectKeyPress(key, 0, false);
|
2017-09-27 11:14:26 +00:00
|
|
|
}
|
|
|
|
|
2019-07-29 13:13:52 +00:00
|
|
|
bool InputManager::gamepadToGuiControl(const SDL_ControllerButtonEvent &arg)
|
2019-03-03 09:21:00 +00:00
|
|
|
{
|
|
|
|
// 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;
|
|
|
|
}
|
|
|
|
|
2012-08-12 18:45:02 +00:00
|
|
|
void InputManager::channelChanged(ICS::Channel* channel, float currentValue, float previousValue)
|
2010-07-20 19:10:51 +00:00
|
|
|
{
|
2012-08-19 20:09:22 +00:00
|
|
|
resetIdleTime ();
|
2010-07-17 17:58:15 +00:00
|
|
|
|
2012-08-12 18:45:02 +00:00
|
|
|
int action = channel->getNumber();
|
2013-07-16 14:25:41 +00:00
|
|
|
|
2017-09-22 21:25:20 +00:00
|
|
|
if (mDragDrop && action != A_GameMenu && action != A_Inventory)
|
|
|
|
return;
|
|
|
|
|
2015-01-20 00:20:49 +00:00
|
|
|
if((previousValue == 1 || previousValue == 0) && (currentValue==1 || currentValue==0))
|
|
|
|
{
|
|
|
|
//Is a normal button press, so don't change it at all
|
|
|
|
}
|
|
|
|
//Otherwise only trigger button presses as they go through specific points
|
|
|
|
else if(previousValue >= .8 && currentValue < .8)
|
|
|
|
{
|
|
|
|
currentValue = 0.0;
|
|
|
|
previousValue = 1.0;
|
|
|
|
}
|
|
|
|
else if(previousValue <= .6 && currentValue > .6)
|
|
|
|
{
|
|
|
|
currentValue = 1.0;
|
|
|
|
previousValue = 0.0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
//If it's not switching between those values, ignore the channel change.
|
|
|
|
return;
|
|
|
|
}
|
2014-12-09 03:57:32 +00:00
|
|
|
|
2014-11-28 14:54:38 +00:00
|
|
|
if (mControlSwitch["playercontrols"])
|
2013-07-16 14:25:41 +00:00
|
|
|
{
|
2014-11-28 14:54:38 +00:00
|
|
|
if (action == A_Use)
|
2017-11-24 14:25:57 +00:00
|
|
|
{
|
2019-02-27 13:29:48 +00:00
|
|
|
if(mJoystickLastUsed && currentValue == 1.0 && actionIsActive(A_ToggleWeapon))
|
|
|
|
action = A_CycleWeaponRight;
|
|
|
|
|
|
|
|
else if (mJoystickLastUsed && currentValue == 1.0 && actionIsActive(A_ToggleSpell))
|
|
|
|
action = A_CycleSpellRight;
|
|
|
|
|
|
|
|
else
|
|
|
|
{
|
|
|
|
MWMechanics::DrawState_ state = MWBase::Environment::get().getWorld()->getPlayer().getDrawState();
|
|
|
|
mPlayer->setAttackingOrSpell(currentValue != 0 && state != MWMechanics::DrawState_Nothing);
|
|
|
|
}
|
2017-11-24 14:25:57 +00:00
|
|
|
}
|
2014-11-28 14:54:38 +00:00
|
|
|
else if (action == A_Jump)
|
2019-02-27 13:29:48 +00:00
|
|
|
{
|
|
|
|
if(mJoystickLastUsed && currentValue == 1.0 && actionIsActive(A_ToggleWeapon))
|
|
|
|
action = A_CycleWeaponLeft;
|
|
|
|
|
|
|
|
else if (mJoystickLastUsed && currentValue == 1.0 && actionIsActive(A_ToggleSpell))
|
|
|
|
action = A_CycleSpellLeft;
|
|
|
|
|
|
|
|
else
|
|
|
|
mAttemptJump = (currentValue == 1.0 && previousValue == 0.0);
|
|
|
|
}
|
2014-05-27 17:12:27 +00:00
|
|
|
}
|
|
|
|
|
2012-08-12 18:45:02 +00:00
|
|
|
if (currentValue == 1)
|
|
|
|
{
|
|
|
|
// trigger action activated
|
|
|
|
switch (action)
|
|
|
|
{
|
|
|
|
case A_GameMenu:
|
2017-10-05 16:35:09 +00:00
|
|
|
toggleMainMenu ();
|
2012-08-12 18:45:02 +00:00
|
|
|
break;
|
|
|
|
case A_Screenshot:
|
2013-07-15 00:26:22 +00:00
|
|
|
screenshot();
|
2013-07-15 00:23:18 +00:00
|
|
|
break;
|
2012-08-12 18:45:02 +00:00
|
|
|
case A_Inventory:
|
|
|
|
toggleInventory ();
|
|
|
|
break;
|
|
|
|
case A_Console:
|
|
|
|
toggleConsole ();
|
|
|
|
break;
|
|
|
|
case A_Activate:
|
2012-08-17 21:31:57 +00:00
|
|
|
resetIdleTime();
|
2017-09-24 11:49:35 +00:00
|
|
|
activate();
|
2012-08-12 18:45:02 +00:00
|
|
|
break;
|
2017-09-27 11:14:26 +00:00
|
|
|
case A_MoveLeft:
|
|
|
|
case A_MoveRight:
|
|
|
|
case A_MoveForward:
|
|
|
|
case A_MoveBackward:
|
2019-07-29 13:13:52 +00:00
|
|
|
handleGuiArrowKey(action);
|
2017-09-27 11:14:26 +00:00
|
|
|
break;
|
2012-08-12 18:45:02 +00:00
|
|
|
case A_Journal:
|
|
|
|
toggleJournal ();
|
|
|
|
break;
|
|
|
|
case A_AutoMove:
|
|
|
|
toggleAutoMove ();
|
|
|
|
break;
|
2013-03-14 19:27:16 +00:00
|
|
|
case A_AlwaysRun:
|
2012-08-12 18:45:02 +00:00
|
|
|
toggleWalking ();
|
|
|
|
break;
|
|
|
|
case A_ToggleWeapon:
|
|
|
|
toggleWeapon ();
|
|
|
|
break;
|
2012-09-15 15:12:42 +00:00
|
|
|
case A_Rest:
|
|
|
|
rest();
|
|
|
|
break;
|
2012-08-12 18:45:02 +00:00
|
|
|
case A_ToggleSpell:
|
|
|
|
toggleSpell ();
|
|
|
|
break;
|
2012-08-26 08:52:06 +00:00
|
|
|
case A_QuickKey1:
|
|
|
|
quickKey(1);
|
|
|
|
break;
|
|
|
|
case A_QuickKey2:
|
|
|
|
quickKey(2);
|
|
|
|
break;
|
|
|
|
case A_QuickKey3:
|
|
|
|
quickKey(3);
|
|
|
|
break;
|
|
|
|
case A_QuickKey4:
|
|
|
|
quickKey(4);
|
|
|
|
break;
|
|
|
|
case A_QuickKey5:
|
|
|
|
quickKey(5);
|
|
|
|
break;
|
|
|
|
case A_QuickKey6:
|
|
|
|
quickKey(6);
|
|
|
|
break;
|
|
|
|
case A_QuickKey7:
|
|
|
|
quickKey(7);
|
|
|
|
break;
|
|
|
|
case A_QuickKey8:
|
|
|
|
quickKey(8);
|
|
|
|
break;
|
|
|
|
case A_QuickKey9:
|
|
|
|
quickKey(9);
|
|
|
|
break;
|
|
|
|
case A_QuickKey10:
|
|
|
|
quickKey(10);
|
|
|
|
break;
|
|
|
|
case A_QuickKeysMenu:
|
|
|
|
showQuickKeysMenu();
|
|
|
|
break;
|
2012-08-30 18:47:39 +00:00
|
|
|
case A_ToggleHUD:
|
2017-09-23 10:58:28 +00:00
|
|
|
MWBase::Environment::get().getWindowManager()->toggleHud();
|
2012-08-30 18:47:39 +00:00
|
|
|
break;
|
2014-09-28 15:57:14 +00:00
|
|
|
case A_ToggleDebug:
|
|
|
|
MWBase::Environment::get().getWindowManager()->toggleDebugWindow();
|
|
|
|
break;
|
2019-10-30 11:22:24 +00:00
|
|
|
case A_ZoomIn:
|
|
|
|
if (mControlSwitch["playerviewswitch"] && mControlSwitch["playercontrols"] && !MWBase::Environment::get().getWindowManager()->isGuiMode())
|
|
|
|
MWBase::Environment::get().getWorld()->setCameraDistance(ZOOM_SCALE, true, true);
|
|
|
|
break;
|
|
|
|
case A_ZoomOut:
|
|
|
|
if (mControlSwitch["playerviewswitch"] && mControlSwitch["playercontrols"] && !MWBase::Environment::get().getWindowManager()->isGuiMode())
|
|
|
|
MWBase::Environment::get().getWorld()->setCameraDistance(-ZOOM_SCALE, true, true);
|
|
|
|
break;
|
2014-04-24 01:02:09 +00:00
|
|
|
case A_QuickSave:
|
|
|
|
quickSave();
|
|
|
|
break;
|
|
|
|
case A_QuickLoad:
|
|
|
|
quickLoad();
|
|
|
|
break;
|
2014-12-15 14:23:03 +00:00
|
|
|
case A_CycleSpellLeft:
|
2019-09-19 18:43:53 +00:00
|
|
|
if (checkAllowedToUseItems() && MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Magic))
|
2015-12-26 17:15:57 +00:00
|
|
|
MWBase::Environment::get().getWindowManager()->cycleSpell(false);
|
2014-12-15 14:23:03 +00:00
|
|
|
break;
|
|
|
|
case A_CycleSpellRight:
|
2019-09-19 18:43:53 +00:00
|
|
|
if (checkAllowedToUseItems() && MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Magic))
|
2015-12-26 17:15:57 +00:00
|
|
|
MWBase::Environment::get().getWindowManager()->cycleSpell(true);
|
2014-12-15 14:23:03 +00:00
|
|
|
break;
|
|
|
|
case A_CycleWeaponLeft:
|
2019-09-19 18:43:53 +00:00
|
|
|
if (checkAllowedToUseItems() && MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory))
|
2015-12-26 17:15:57 +00:00
|
|
|
MWBase::Environment::get().getWindowManager()->cycleWeapon(false);
|
2014-12-15 14:23:03 +00:00
|
|
|
break;
|
|
|
|
case A_CycleWeaponRight:
|
2019-09-19 18:43:53 +00:00
|
|
|
if (checkAllowedToUseItems() && MWBase::Environment::get().getWindowManager()->isAllowed(MWGui::GW_Inventory))
|
2015-12-26 17:15:57 +00:00
|
|
|
MWBase::Environment::get().getWindowManager()->cycleWeapon(true);
|
2014-12-15 14:23:03 +00:00
|
|
|
break;
|
2015-03-08 21:08:45 +00:00
|
|
|
case A_Sneak:
|
|
|
|
if (mSneakToggles)
|
|
|
|
{
|
|
|
|
toggleSneaking();
|
|
|
|
}
|
|
|
|
break;
|
2013-02-05 19:26:13 +00:00
|
|
|
}
|
2012-08-12 18:45:02 +00:00
|
|
|
}
|
2012-05-13 08:18:17 +00:00
|
|
|
}
|
|
|
|
|
2015-01-13 03:53:49 +00:00
|
|
|
void InputManager::updateCursorMode()
|
2010-07-17 17:58:15 +00:00
|
|
|
{
|
2015-05-13 14:50:47 +00:00
|
|
|
bool grab = !MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu)
|
2019-05-16 06:28:56 +00:00
|
|
|
&& !MWBase::Environment::get().getWindowManager()->isConsoleMode();
|
2013-01-09 13:05:47 +00:00
|
|
|
|
2015-05-13 14:50:47 +00:00
|
|
|
bool was_relative = mInputManager->getMouseRelative();
|
2013-08-27 13:48:13 +00:00
|
|
|
bool is_relative = !MWBase::Environment::get().getWindowManager()->isGuiMode();
|
2013-01-09 13:05:47 +00:00
|
|
|
|
2013-06-16 18:39:40 +00:00
|
|
|
// don't keep the pointer away from the window edge in gui mode
|
|
|
|
// stop using raw mouse motions and switch to system cursor movements
|
2015-05-13 14:50:47 +00:00
|
|
|
mInputManager->setMouseRelative(is_relative);
|
2013-01-09 13:05:47 +00:00
|
|
|
|
2013-06-16 18:39:40 +00:00
|
|
|
//we let the mouse escape in the main menu
|
2015-05-13 14:50:47 +00:00
|
|
|
mInputManager->setGrabPointer(grab && (mGrabCursor || is_relative));
|
2013-06-15 13:33:47 +00:00
|
|
|
|
2013-06-16 18:39:40 +00:00
|
|
|
//we switched to non-relative mode, move our cursor to where the in-game
|
|
|
|
//cursor is
|
2020-04-08 10:48:23 +00:00
|
|
|
if(!is_relative && was_relative != is_relative)
|
2013-06-16 18:39:40 +00:00
|
|
|
{
|
2020-04-08 10:48:23 +00:00
|
|
|
mMouseManager->warpMouse();
|
2013-01-09 10:10:05 +00:00
|
|
|
}
|
2015-01-13 03:53:49 +00:00
|
|
|
}
|
|
|
|
|
2015-12-26 17:15:57 +00:00
|
|
|
bool InputManager::checkAllowedToUseItems() const
|
|
|
|
{
|
|
|
|
MWWorld::Ptr player = MWMechanics::getPlayer();
|
|
|
|
if (player.getClass().getNpcStats(player).isWerewolf())
|
|
|
|
{
|
|
|
|
// Cannot use items or spells while in werewolf form
|
|
|
|
MWBase::Environment::get().getWindowManager()->messageBox("#{sWerewolfRefusal}");
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2015-01-13 03:53:49 +00:00
|
|
|
void InputManager::update(float dt, bool disableControls, bool disableEvents)
|
|
|
|
{
|
|
|
|
mControlsDisabled = disableControls;
|
|
|
|
|
2015-05-13 14:50:47 +00:00
|
|
|
mInputManager->setMouseVisible(MWBase::Environment::get().getWindowManager()->getCursorVisible());
|
2015-01-13 03:53:49 +00:00
|
|
|
|
2015-05-13 14:50:47 +00:00
|
|
|
mInputManager->capture(disableEvents);
|
2015-01-13 03:53:49 +00:00
|
|
|
|
|
|
|
if (mControlsDisabled)
|
|
|
|
{
|
|
|
|
updateCursorMode();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
// update values of channels (as a result of pressed keys)
|
|
|
|
mInputBinder->update(dt);
|
|
|
|
|
|
|
|
updateCursorMode();
|
2013-01-09 10:10:05 +00:00
|
|
|
|
2019-03-03 09:21:00 +00:00
|
|
|
if (mGuiCursorEnabled && !(mJoystickLastUsed && !mGamepadGuiCursorEnabled))
|
2014-12-09 03:57:32 +00:00
|
|
|
{
|
2017-03-04 01:59:28 +00:00
|
|
|
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;
|
2014-12-09 03:57:32 +00:00
|
|
|
|
2017-03-04 01:59:28 +00:00
|
|
|
xAxis *= (1.5f - mInputBinder->getChannel(A_Use)->getValue());
|
|
|
|
yAxis *= (1.5f - mInputBinder->getChannel(A_Use)->getValue());
|
2015-08-12 02:45:02 +00:00
|
|
|
|
2017-03-04 01:59:28 +00:00
|
|
|
// 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
|
2020-04-08 10:48:23 +00:00
|
|
|
float xMove = xAxis * dt * 1500.0f * mInvUiScalingFactor * mGamepadCursorSpeed;
|
|
|
|
float yMove = yAxis * dt * 1500.0f * mInvUiScalingFactor * mGamepadCursorSpeed;
|
|
|
|
if (xMove != 0|| yMove != 0 || zAxis != 0)
|
2017-03-04 20:25:07 +00:00
|
|
|
{
|
2020-04-08 10:48:23 +00:00
|
|
|
int mouseWheelMove = static_cast<int>(-zAxis * dt * 1500.0f);
|
2014-12-09 03:57:32 +00:00
|
|
|
|
2020-04-08 10:48:23 +00:00
|
|
|
mMouseManager->injectMouseMove(xMove, yMove, mouseWheelMove);
|
|
|
|
mMouseManager->warpMouse();
|
2017-10-13 16:22:44 +00:00
|
|
|
MWBase::Environment::get().getWindowManager()->setCursorActive(true);
|
2017-03-04 20:25:07 +00:00
|
|
|
}
|
2017-03-04 01:59:28 +00:00
|
|
|
}
|
2014-12-09 03:57:32 +00:00
|
|
|
|
2020-04-08 10:48:23 +00:00
|
|
|
if (mMouseManager->update(dt, disableControls))
|
|
|
|
resetIdleTime();
|
2014-12-09 03:57:32 +00:00
|
|
|
|
2020-04-08 06:55:35 +00:00
|
|
|
if (mSensorManager->update(dt, mGuiCursorEnabled, mControlSwitch["playerlooking"]))
|
|
|
|
resetIdleTime();
|
2020-03-14 18:24:36 +00:00
|
|
|
|
2011-02-03 11:16:59 +00:00
|
|
|
// Disable movement in Gui mode
|
2014-05-27 17:12:27 +00:00
|
|
|
if (!(MWBase::Environment::get().getWindowManager()->isGuiMode()
|
|
|
|
|| MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_Running))
|
2012-08-12 18:45:02 +00:00
|
|
|
{
|
2014-05-27 17:12:27 +00:00
|
|
|
// Configure player movement according to keyboard input. Actual movement will
|
|
|
|
// be done in the physics system.
|
|
|
|
if (mControlSwitch["playercontrols"])
|
2012-08-04 07:54:42 +00:00
|
|
|
{
|
2014-05-27 17:12:27 +00:00
|
|
|
bool triedToMove = false;
|
2014-12-09 03:57:32 +00:00
|
|
|
bool isRunning = false;
|
2019-06-02 19:39:33 +00:00
|
|
|
bool alwaysRunAllowed = false;
|
2017-03-04 01:59:28 +00:00
|
|
|
|
|
|
|
// joystick movement
|
|
|
|
float xAxis = mInputBinder->getChannel(A_MoveLeftRight)->getValue();
|
|
|
|
float yAxis = mInputBinder->getChannel(A_MoveForwardBackward)->getValue();
|
2019-03-02 23:46:48 +00:00
|
|
|
if (xAxis != .5)
|
2014-05-27 17:12:27 +00:00
|
|
|
{
|
2017-03-04 01:59:28 +00:00
|
|
|
triedToMove = true;
|
2019-03-02 23:46:48 +00:00
|
|
|
mPlayer->setLeftRight((xAxis - 0.5f) * 2);
|
2017-03-04 01:59:28 +00:00
|
|
|
}
|
2012-08-04 07:54:42 +00:00
|
|
|
|
2019-03-02 23:46:48 +00:00
|
|
|
if (yAxis != .5)
|
2017-03-04 01:59:28 +00:00
|
|
|
{
|
|
|
|
triedToMove = true;
|
|
|
|
mPlayer->setAutoMove (false);
|
2019-03-02 23:46:48 +00:00
|
|
|
mPlayer->setForwardBackward((yAxis - 0.5f) * 2 * -1);
|
2017-03-04 01:59:28 +00:00
|
|
|
}
|
2019-06-08 12:06:04 +00:00
|
|
|
|
2017-03-04 01:59:28 +00:00
|
|
|
if (triedToMove)
|
|
|
|
mJoystickLastUsed = true;
|
2014-12-09 03:57:32 +00:00
|
|
|
|
2017-03-04 01:59:28 +00:00
|
|
|
// keyboard movement
|
|
|
|
isRunning = xAxis > .75 || xAxis < .25 || yAxis > .75 || yAxis < .25;
|
|
|
|
if(triedToMove) resetIdleTime();
|
|
|
|
|
2019-06-02 19:39:33 +00:00
|
|
|
if (actionIsActive(A_MoveLeft) != actionIsActive(A_MoveRight))
|
2017-03-04 01:59:28 +00:00
|
|
|
{
|
2019-06-02 19:39:33 +00:00
|
|
|
alwaysRunAllowed = true;
|
2017-03-04 01:59:28 +00:00
|
|
|
triedToMove = true;
|
2019-06-02 19:39:33 +00:00
|
|
|
mPlayer->setLeftRight (actionIsActive(A_MoveRight) ? 1 : -1);
|
2017-03-04 01:59:28 +00:00
|
|
|
}
|
2010-08-03 14:26:43 +00:00
|
|
|
|
2019-06-02 19:39:33 +00:00
|
|
|
if (actionIsActive(A_MoveForward) != actionIsActive(A_MoveBackward))
|
2017-03-04 01:59:28 +00:00
|
|
|
{
|
2019-06-02 19:39:33 +00:00
|
|
|
alwaysRunAllowed = true;
|
2017-03-04 01:59:28 +00:00
|
|
|
triedToMove = true;
|
|
|
|
mPlayer->setAutoMove (false);
|
2019-06-02 19:39:33 +00:00
|
|
|
mPlayer->setForwardBackward (actionIsActive(A_MoveForward) ? 1 : -1);
|
2017-03-04 01:59:28 +00:00
|
|
|
}
|
2019-06-08 12:06:04 +00:00
|
|
|
|
|
|
|
if (mPlayer->getAutoMove())
|
2017-03-04 01:59:28 +00:00
|
|
|
{
|
2019-06-02 19:39:33 +00:00
|
|
|
alwaysRunAllowed = true;
|
2017-03-04 01:59:28 +00:00
|
|
|
triedToMove = true;
|
|
|
|
mPlayer->setForwardBackward (1);
|
2014-05-27 17:12:27 +00:00
|
|
|
}
|
2013-04-07 17:04:30 +00:00
|
|
|
|
2015-03-08 21:08:45 +00:00
|
|
|
if (!mSneakToggles)
|
2015-03-08 20:23:46 +00:00
|
|
|
{
|
2019-02-27 22:03:16 +00:00
|
|
|
if(mJoystickLastUsed)
|
|
|
|
{
|
|
|
|
if(actionIsActive(A_Sneak))
|
|
|
|
{
|
|
|
|
if(mSneakToggleShortcutTimer) // New Sneak Button Press
|
|
|
|
{
|
|
|
|
if(mSneakToggleShortcutTimer <= 0.3f)
|
|
|
|
{
|
|
|
|
mSneakGamepadShortcut = true;
|
|
|
|
toggleSneaking();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
mSneakGamepadShortcut = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(!mSneaking)
|
|
|
|
toggleSneaking();
|
|
|
|
mSneakToggleShortcutTimer = 0.f;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if(!mSneakGamepadShortcut && mSneaking)
|
|
|
|
toggleSneaking();
|
|
|
|
if(mSneakToggleShortcutTimer <= 0.3f)
|
|
|
|
mSneakToggleShortcutTimer += dt;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
mPlayer->setSneak(actionIsActive(A_Sneak));
|
2015-03-08 21:08:45 +00:00
|
|
|
}
|
2010-08-03 14:26:43 +00:00
|
|
|
|
2014-05-27 17:12:27 +00:00
|
|
|
if (mAttemptJump && mControlSwitch["playerjumping"])
|
|
|
|
{
|
|
|
|
mPlayer->setUpDown (1);
|
|
|
|
triedToMove = true;
|
2014-12-02 17:42:13 +00:00
|
|
|
mOverencumberedMessageDelay = 0.f;
|
2014-05-27 17:12:27 +00:00
|
|
|
}
|
2012-08-12 11:50:37 +00:00
|
|
|
|
2019-06-02 19:39:33 +00:00
|
|
|
if ((mAlwaysRunActive && alwaysRunAllowed) || isRunning)
|
2014-05-27 17:12:27 +00:00
|
|
|
mPlayer->setRunState(!actionIsActive(A_Run));
|
|
|
|
else
|
|
|
|
mPlayer->setRunState(actionIsActive(A_Run));
|
2013-02-07 01:51:47 +00:00
|
|
|
|
2014-05-27 17:12:27 +00:00
|
|
|
// if player tried to start moving, but can't (due to being overencumbered), display a notification.
|
|
|
|
if (triedToMove)
|
2013-02-25 15:31:48 +00:00
|
|
|
{
|
2014-05-27 17:12:27 +00:00
|
|
|
MWWorld::Ptr player = MWBase::Environment::get().getWorld ()->getPlayerPtr();
|
|
|
|
mOverencumberedMessageDelay -= dt;
|
2014-10-05 13:52:33 +00:00
|
|
|
if (player.getClass().getEncumbrance(player) > player.getClass().getCapacity(player))
|
2013-02-25 15:31:48 +00:00
|
|
|
{
|
2014-05-27 17:12:27 +00:00
|
|
|
mPlayer->setAutoMove (false);
|
|
|
|
if (mOverencumberedMessageDelay <= 0)
|
|
|
|
{
|
|
|
|
MWBase::Environment::get().getWindowManager ()->messageBox("#{sNotifyMessage59}");
|
|
|
|
mOverencumberedMessageDelay = 1.0;
|
|
|
|
}
|
2013-02-25 15:31:48 +00:00
|
|
|
}
|
|
|
|
}
|
2012-08-27 17:25:30 +00:00
|
|
|
|
2014-05-27 17:12:27 +00:00
|
|
|
if (mControlSwitch["playerviewswitch"]) {
|
|
|
|
|
2015-01-09 23:07:40 +00:00
|
|
|
if (actionIsActive(A_TogglePOV)) {
|
2014-05-27 17:12:27 +00:00
|
|
|
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;
|
2019-02-27 13:29:48 +00:00
|
|
|
mGamepadZoom = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if(mGamepadZoom)
|
|
|
|
{
|
|
|
|
MWBase::Environment::get().getWorld()->changeVanityModeScale(mGamepadZoom);
|
|
|
|
MWBase::Environment::get().getWorld()->setCameraDistance(mGamepadZoom, true, true);
|
2012-08-19 20:09:22 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-05-27 17:12:27 +00:00
|
|
|
if (actionIsActive(A_MoveForward) ||
|
|
|
|
actionIsActive(A_MoveBackward) ||
|
|
|
|
actionIsActive(A_MoveLeft) ||
|
|
|
|
actionIsActive(A_MoveRight) ||
|
|
|
|
actionIsActive(A_Jump) ||
|
|
|
|
actionIsActive(A_Sneak) ||
|
2019-10-30 11:22:24 +00:00
|
|
|
actionIsActive(A_TogglePOV) ||
|
|
|
|
actionIsActive(A_ZoomIn) ||
|
|
|
|
actionIsActive(A_ZoomOut) )
|
2014-05-27 17:12:27 +00:00
|
|
|
{
|
|
|
|
resetIdleTime();
|
|
|
|
} else {
|
|
|
|
updateIdleTime(dt);
|
|
|
|
}
|
2012-08-19 20:09:22 +00:00
|
|
|
}
|
2019-02-27 13:29:48 +00:00
|
|
|
else
|
|
|
|
mGamepadZoom = 0;
|
2014-05-27 17:12:27 +00:00
|
|
|
mAttemptJump = false; // Can only jump on first frame input is on
|
2012-08-12 18:45:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InputManager::setDragDrop(bool dragDrop)
|
|
|
|
{
|
|
|
|
mDragDrop = dragDrop;
|
2010-07-17 17:58:15 +00:00
|
|
|
}
|
2010-09-15 12:48:19 +00:00
|
|
|
|
2020-04-08 10:48:23 +00:00
|
|
|
void InputManager::setGamepadGuiCursorEnabled(bool enabled)
|
|
|
|
{
|
|
|
|
mGamepadGuiCursorEnabled = enabled;
|
|
|
|
}
|
|
|
|
|
2012-08-12 18:45:02 +00:00
|
|
|
void InputManager::changeInputMode(bool guiMode)
|
2010-09-15 12:48:19 +00:00
|
|
|
{
|
2013-03-31 13:50:48 +00:00
|
|
|
mGuiCursorEnabled = guiMode;
|
2020-04-08 10:48:23 +00:00
|
|
|
mMouseManager->setGuiCursorEnabled(guiMode);
|
|
|
|
mMouseManager->setMouseLookEnabled(!guiMode);
|
2013-03-31 13:50:48 +00:00
|
|
|
if (guiMode)
|
2013-08-27 13:48:13 +00:00
|
|
|
MWBase::Environment::get().getWindowManager()->showCrosshair(false);
|
2019-04-12 04:29:45 +00:00
|
|
|
MWBase::Environment::get().getWindowManager()->setCursorVisible(guiMode && (!mJoystickLastUsed || mGamepadGuiCursorEnabled));
|
2013-03-31 13:50:48 +00:00
|
|
|
// if not in gui mode, the camera decides whether to show crosshair or not.
|
2012-08-12 18:45:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InputManager::processChangedSettings(const Settings::CategorySettingVector& changed)
|
|
|
|
{
|
2015-05-14 18:31:16 +00:00
|
|
|
bool changeRes = false;
|
|
|
|
|
2012-08-12 18:45:02 +00:00
|
|
|
for (Settings::CategorySettingVector::const_iterator it = changed.begin();
|
|
|
|
it != changed.end(); ++it)
|
|
|
|
{
|
2018-12-01 15:14:51 +00:00
|
|
|
if (it->first == "Input" && it->second == "invert x axis")
|
|
|
|
mInvertX = Settings::Manager::getBool("invert x axis", "Input");
|
|
|
|
|
2012-08-13 00:55:22 +00:00
|
|
|
if (it->first == "Input" && it->second == "invert y axis")
|
|
|
|
mInvertY = Settings::Manager::getBool("invert y axis", "Input");
|
2012-08-13 16:48:50 +00:00
|
|
|
|
2013-12-28 23:58:48 +00:00
|
|
|
if (it->first == "Input" && it->second == "grab cursor")
|
|
|
|
mGrabCursor = Settings::Manager::getBool("grab cursor", "Input");
|
|
|
|
|
2019-02-15 14:53:50 +00:00
|
|
|
if (it->first == "Input" && it->second == "enable controller")
|
|
|
|
mJoystickEnabled = Settings::Manager::getBool("enable controller", "Input");
|
|
|
|
|
2015-05-14 18:31:16 +00:00
|
|
|
if (it->first == "Video" && (
|
|
|
|
it->second == "resolution x"
|
|
|
|
|| it->second == "resolution y"
|
|
|
|
|| it->second == "fullscreen"
|
|
|
|
|| it->second == "window border"))
|
|
|
|
changeRes = true;
|
|
|
|
|
|
|
|
if (it->first == "Video" && it->second == "vsync")
|
|
|
|
mVideoWrapper->setSyncToVBlank(Settings::Manager::getBool("vsync", "Video"));
|
|
|
|
|
|
|
|
if (it->first == "Video" && (it->second == "gamma" || it->second == "contrast"))
|
|
|
|
mVideoWrapper->setGammaContrast(Settings::Manager::getFloat("gamma", "Video"),
|
|
|
|
Settings::Manager::getFloat("contrast", "Video"));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (changeRes)
|
|
|
|
{
|
|
|
|
mVideoWrapper->setVideoMode(Settings::Manager::getInt("resolution x", "Video"),
|
|
|
|
Settings::Manager::getInt("resolution y", "Video"),
|
|
|
|
Settings::Manager::getBool("fullscreen", "Video"),
|
|
|
|
Settings::Manager::getBool("window border", "Video"));
|
2010-09-15 12:48:19 +00:00
|
|
|
}
|
2020-04-08 06:55:35 +00:00
|
|
|
|
|
|
|
mSensorManager->processChangedSettings(changed);
|
2010-09-15 12:48:19 +00:00
|
|
|
}
|
2012-08-04 07:54:42 +00:00
|
|
|
|
2012-09-10 16:44:59 +00:00
|
|
|
bool InputManager::getControlSwitch (const std::string& sw)
|
|
|
|
{
|
|
|
|
return mControlSwitch[sw];
|
|
|
|
}
|
|
|
|
|
2012-08-12 18:45:02 +00:00
|
|
|
void InputManager::toggleControlSwitch (const std::string& sw, bool value)
|
2012-08-04 07:54:42 +00:00
|
|
|
{
|
|
|
|
/// \note 7 switches at all, if-else is relevant
|
2012-08-09 06:55:49 +00:00
|
|
|
if (sw == "playercontrols" && !value) {
|
2013-08-27 13:48:13 +00:00
|
|
|
mPlayer->setLeftRight(0);
|
|
|
|
mPlayer->setForwardBackward(0);
|
|
|
|
mPlayer->setAutoMove(false);
|
|
|
|
mPlayer->setUpDown(0);
|
2012-08-09 06:55:49 +00:00
|
|
|
} else if (sw == "playerjumping" && !value) {
|
2012-08-04 07:54:42 +00:00
|
|
|
/// \fixme maybe crouching at this time
|
2013-08-27 13:48:13 +00:00
|
|
|
mPlayer->setUpDown(0);
|
2012-08-17 09:23:02 +00:00
|
|
|
} else if (sw == "vanitymode") {
|
|
|
|
MWBase::Environment::get().getWorld()->allowVanityMode(value);
|
2019-06-29 22:50:17 +00:00
|
|
|
} else if (sw == "playerlooking" && !value) {
|
|
|
|
MWBase::Environment::get().getWorld()->rotateObject(mPlayer->getPlayer(), 0.f, 0.f, 0.f);
|
2012-08-04 07:54:42 +00:00
|
|
|
}
|
|
|
|
mControlSwitch[sw] = value;
|
|
|
|
}
|
|
|
|
|
2014-02-13 14:08:40 +00:00
|
|
|
void InputManager::keyPressed( const SDL_KeyboardEvent &arg )
|
2012-08-12 18:45:02 +00:00
|
|
|
{
|
2014-09-10 15:58:53 +00:00
|
|
|
// 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)
|
2013-01-10 21:21:47 +00:00
|
|
|
OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym);
|
2014-09-10 15:58:53 +00:00
|
|
|
if (mInputBinder->getKeyBinding(mInputBinder->getControl(A_Console), ICS::Control::INCREASE)
|
2014-09-13 18:39:32 +00:00
|
|
|
== arg.keysym.scancode
|
2019-05-16 06:28:56 +00:00
|
|
|
&& MWBase::Environment::get().getWindowManager()->isConsoleMode())
|
2014-09-10 15:58:53 +00:00
|
|
|
SDL_StopTextInput();
|
2013-01-10 21:21:47 +00:00
|
|
|
|
2014-08-25 16:55:21 +00:00
|
|
|
bool consumed = false;
|
2017-09-27 19:30:12 +00:00
|
|
|
if (kc != OIS::KC_UNASSIGNED && !mInputBinder->detectingBindingState())
|
2014-05-31 23:51:21 +00:00
|
|
|
{
|
2018-09-09 19:10:09 +00:00
|
|
|
consumed = MWBase::Environment::get().getWindowManager()->injectKeyPress(MyGUI::KeyCode::Enum(kc), 0, arg.repeat);
|
2017-09-24 10:47:50 +00:00
|
|
|
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);
|
2014-05-31 23:51:21 +00:00
|
|
|
}
|
2017-09-22 14:34:34 +00:00
|
|
|
if (arg.repeat)
|
|
|
|
return;
|
|
|
|
|
2014-08-25 16:55:21 +00:00
|
|
|
if (!mControlsDisabled && !consumed)
|
2014-05-31 23:58:21 +00:00
|
|
|
mInputBinder->keyPressed (arg);
|
2014-12-09 03:57:32 +00:00
|
|
|
mJoystickLastUsed = false;
|
2012-08-12 18:45:02 +00:00
|
|
|
}
|
2012-08-04 07:54:42 +00:00
|
|
|
|
2013-06-16 17:43:59 +00:00
|
|
|
void InputManager::textInput(const SDL_TextInputEvent &arg)
|
|
|
|
{
|
2015-06-10 14:59:35 +00:00
|
|
|
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)
|
2013-06-16 17:43:59 +00:00
|
|
|
MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::None, *it);
|
|
|
|
}
|
|
|
|
|
2014-02-13 14:08:40 +00:00
|
|
|
void InputManager::keyReleased(const SDL_KeyboardEvent &arg )
|
2012-08-04 07:54:42 +00:00
|
|
|
{
|
2014-12-09 03:57:32 +00:00
|
|
|
mJoystickLastUsed = false;
|
2013-01-10 21:21:47 +00:00
|
|
|
OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym);
|
2012-08-12 18:45:02 +00:00
|
|
|
|
2017-09-27 19:30:12 +00:00
|
|
|
if (!mInputBinder->detectingBindingState())
|
|
|
|
setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc)));
|
2014-06-07 02:25:23 +00:00
|
|
|
mInputBinder->keyReleased (arg);
|
2012-08-04 07:54:42 +00:00
|
|
|
}
|
2012-08-12 18:45:02 +00:00
|
|
|
|
2015-01-19 21:36:15 +00:00
|
|
|
void InputManager::buttonPressed(int deviceID, const SDL_ControllerButtonEvent &arg )
|
2014-12-09 03:57:32 +00:00
|
|
|
{
|
2019-03-03 09:21:00 +00:00
|
|
|
if (!mJoystickEnabled || mInputBinder->detectingBindingState())
|
2019-02-15 14:53:50 +00:00
|
|
|
return;
|
|
|
|
|
2014-12-09 03:57:32 +00:00
|
|
|
mJoystickLastUsed = true;
|
2019-03-03 09:21:00 +00:00
|
|
|
if (MWBase::Environment::get().getWindowManager()->isGuiMode())
|
2014-12-09 03:57:32 +00:00
|
|
|
{
|
2019-07-29 13:13:52 +00:00
|
|
|
if (gamepadToGuiControl(arg))
|
2019-03-03 09:21:00 +00:00
|
|
|
return;
|
2019-07-29 13:13:52 +00:00
|
|
|
if (mGamepadGuiCursorEnabled)
|
2014-12-09 03:57:32 +00:00
|
|
|
{
|
2019-03-03 09:21:00 +00:00
|
|
|
// Temporary mouse binding until keyboard controls are available:
|
|
|
|
if (arg.button == SDL_CONTROLLER_BUTTON_A) // We'll pretend that A is left click.
|
2014-12-09 03:57:32 +00:00
|
|
|
{
|
2020-04-08 10:48:23 +00:00
|
|
|
bool mousePressSuccess = mMouseManager->injectMouseButtonPress(SDL_BUTTON_LEFT);
|
2019-03-03 09:21:00 +00:00
|
|
|
if (MyGUI::InputManager::getInstance().getMouseFocusWidget())
|
2014-12-09 18:12:38 +00:00
|
|
|
{
|
2019-03-03 09:21:00 +00:00
|
|
|
MyGUI::Button* b = MyGUI::InputManager::getInstance().getMouseFocusWidget()->castType<MyGUI::Button>(false);
|
|
|
|
if (b && b->getEnabled())
|
|
|
|
MWBase::Environment::get().getWindowManager()->playSound("Menu Click");
|
2014-12-09 18:12:38 +00:00
|
|
|
}
|
2019-03-03 09:21:00 +00:00
|
|
|
|
|
|
|
setPlayerControlsEnabled(!mousePressSuccess);
|
2014-12-09 03:57:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-03-03 09:21:00 +00:00
|
|
|
else
|
|
|
|
setPlayerControlsEnabled(true);
|
2014-12-09 03:57:32 +00:00
|
|
|
|
2015-03-03 10:23:50 +00:00
|
|
|
//esc, to leave initial movie screen
|
2015-05-13 14:50:47 +00:00
|
|
|
OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(SDLK_ESCAPE);
|
2019-03-03 09:21:00 +00:00
|
|
|
setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(kc), 0));
|
2014-12-09 03:57:32 +00:00
|
|
|
|
|
|
|
if (!mControlsDisabled)
|
2015-01-19 21:36:15 +00:00
|
|
|
mInputBinder->buttonPressed(deviceID, arg);
|
2014-12-09 03:57:32 +00:00
|
|
|
}
|
|
|
|
|
2015-01-19 21:36:15 +00:00
|
|
|
void InputManager::buttonReleased(int deviceID, const SDL_ControllerButtonEvent &arg )
|
2014-12-09 03:57:32 +00:00
|
|
|
{
|
2019-03-03 09:21:00 +00:00
|
|
|
if(mInputBinder->detectingBindingState())
|
|
|
|
{
|
|
|
|
mInputBinder->buttonReleased(deviceID, arg);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!mJoystickEnabled || mControlsDisabled)
|
2019-02-15 14:53:50 +00:00
|
|
|
return;
|
|
|
|
|
2014-12-09 03:57:32 +00:00
|
|
|
mJoystickLastUsed = true;
|
2019-03-03 09:21:00 +00:00
|
|
|
if (MWBase::Environment::get().getWindowManager()->isGuiMode())
|
2014-12-09 03:57:32 +00:00
|
|
|
{
|
2019-07-29 13:13:52 +00:00
|
|
|
if (mGamepadGuiCursorEnabled)
|
2019-03-03 09:21:00 +00:00
|
|
|
{
|
|
|
|
// Temporary mouse binding until keyboard controls are available:
|
|
|
|
if (arg.button == SDL_CONTROLLER_BUTTON_A) // We'll pretend that A is left click.
|
|
|
|
{
|
2020-04-08 10:48:23 +00:00
|
|
|
bool mousePressSuccess = mMouseManager->injectMouseButtonRelease(SDL_BUTTON_LEFT);
|
2019-03-03 09:21:00 +00:00
|
|
|
if (mInputBinder->detectingBindingState()) // If the player just triggered binding, don't let button release bind.
|
|
|
|
return;
|
2014-12-09 03:57:32 +00:00
|
|
|
|
2019-03-03 09:21:00 +00:00
|
|
|
setPlayerControlsEnabled(!mousePressSuccess);
|
|
|
|
}
|
|
|
|
}
|
2014-12-09 03:57:32 +00:00
|
|
|
}
|
|
|
|
else
|
2019-03-03 09:21:00 +00:00
|
|
|
setPlayerControlsEnabled(true);
|
2014-12-09 03:57:32 +00:00
|
|
|
|
2019-03-03 09:21:00 +00:00
|
|
|
//esc, to leave initial movie screen
|
2015-05-13 14:50:47 +00:00
|
|
|
OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(SDLK_ESCAPE);
|
|
|
|
setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyRelease(MyGUI::KeyCode::Enum(kc)));
|
2019-03-03 09:21:00 +00:00
|
|
|
|
|
|
|
mInputBinder->buttonReleased(deviceID, arg);
|
2014-12-09 03:57:32 +00:00
|
|
|
}
|
|
|
|
|
2015-01-19 21:36:15 +00:00
|
|
|
void InputManager::axisMoved(int deviceID, const SDL_ControllerAxisEvent &arg )
|
2014-12-09 03:57:32 +00:00
|
|
|
{
|
2019-03-03 09:21:00 +00:00
|
|
|
if(!mJoystickEnabled || mControlsDisabled)
|
|
|
|
return;
|
|
|
|
|
|
|
|
mJoystickLastUsed = true;
|
|
|
|
if (MWBase::Environment::get().getWindowManager()->isGuiMode())
|
|
|
|
{
|
|
|
|
gamepadToGuiControl(arg);
|
|
|
|
}
|
|
|
|
else
|
2019-02-27 13:29:48 +00:00
|
|
|
{
|
2019-03-03 09:21:00 +00:00
|
|
|
if(mPreviewPOVDelay == 1.f && arg.value) // Preview Mode Gamepad Zooming
|
2019-02-27 13:29:48 +00:00
|
|
|
{
|
2019-03-03 09:21:00 +00:00
|
|
|
if(arg.axis == SDL_CONTROLLER_AXIS_TRIGGERRIGHT)
|
2019-02-27 13:29:48 +00:00
|
|
|
{
|
2019-11-02 16:47:05 +00:00
|
|
|
mGamepadZoom = arg.value * 0.85f / 1000.f;
|
|
|
|
return; // Do not propagate event.
|
2019-02-27 13:29:48 +00:00
|
|
|
}
|
2019-03-03 09:21:00 +00:00
|
|
|
else if(arg.axis == SDL_CONTROLLER_AXIS_TRIGGERLEFT)
|
2019-02-27 13:29:48 +00:00
|
|
|
{
|
2019-11-02 16:47:05 +00:00
|
|
|
mGamepadZoom = -arg.value * 0.85f / 1000.f;
|
|
|
|
return; // Do not propagate event.
|
2019-02-27 13:29:48 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2019-03-03 09:21:00 +00:00
|
|
|
mInputBinder->axisMoved(deviceID, arg);
|
2014-12-09 03:57:32 +00:00
|
|
|
}
|
|
|
|
|
2015-01-19 21:36:15 +00:00
|
|
|
void InputManager::controllerAdded(int deviceID, const SDL_ControllerDeviceEvent &arg)
|
2014-12-09 03:57:32 +00:00
|
|
|
{
|
2015-01-19 21:36:15 +00:00
|
|
|
mInputBinder->controllerAdded(deviceID, arg);
|
2014-12-09 03:57:32 +00:00
|
|
|
}
|
|
|
|
void InputManager::controllerRemoved(const SDL_ControllerDeviceEvent &arg)
|
|
|
|
{
|
|
|
|
mInputBinder->controllerRemoved(arg);
|
|
|
|
}
|
|
|
|
|
2013-07-29 00:32:08 +00:00
|
|
|
void InputManager::windowFocusChange(bool have_focus)
|
2013-01-09 10:10:05 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2013-07-29 00:32:08 +00:00
|
|
|
void InputManager::windowVisibilityChange(bool visible)
|
2013-01-09 10:10:05 +00:00
|
|
|
{
|
2015-09-04 01:44:14 +00:00
|
|
|
mWindowVisible = visible;
|
2013-07-29 00:32:08 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InputManager::windowResized(int x, int y)
|
|
|
|
{
|
2019-05-02 15:00:47 +00:00
|
|
|
// Note: this is a side effect of resolution change or window resize.
|
|
|
|
// There is no need to track these changes.
|
2015-05-13 14:50:47 +00:00
|
|
|
Settings::Manager::setInt("resolution x", "Video", x);
|
|
|
|
Settings::Manager::setInt("resolution y", "Video", y);
|
2019-05-04 17:38:36 +00:00
|
|
|
Settings::Manager::resetPendingChange("resolution x", "Video");
|
|
|
|
Settings::Manager::resetPendingChange("resolution y", "Video");
|
2015-05-13 14:50:47 +00:00
|
|
|
|
|
|
|
MWBase::Environment::get().getWindowManager()->windowResized(x, y);
|
2019-05-02 15:00:47 +00:00
|
|
|
|
|
|
|
// We should reload TrueType fonts to fit new resolution
|
|
|
|
MWBase::Environment::get().getWindowManager()->loadUserFonts();
|
2013-01-09 10:10:05 +00:00
|
|
|
}
|
|
|
|
|
2013-11-05 02:02:28 +00:00
|
|
|
void InputManager::windowClosed()
|
|
|
|
{
|
2013-11-16 10:07:23 +00:00
|
|
|
MWBase::Environment::get().getStateManager()->requestQuit();
|
2013-11-05 02:02:28 +00:00
|
|
|
}
|
|
|
|
|
2012-08-12 18:45:02 +00:00
|
|
|
void InputManager::toggleMainMenu()
|
|
|
|
{
|
2019-03-08 09:36:44 +00:00
|
|
|
if (MyGUI::InputManager::getInstance().isModalAny())
|
|
|
|
{
|
|
|
|
MWBase::Environment::get().getWindowManager()->exitCurrentModal();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-05-16 06:28:56 +00:00
|
|
|
if (MWBase::Environment::get().getWindowManager()->isConsoleMode())
|
2019-03-08 09:36:44 +00:00
|
|
|
{
|
2019-07-29 13:13:52 +00:00
|
|
|
MWBase::Environment::get().getWindowManager()->toggleConsole();
|
2019-03-08 09:36:44 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2019-07-29 13:13:52 +00:00
|
|
|
if (!MWBase::Environment::get().getWindowManager()->isGuiMode()) //No open GUIs, open up the MainMenu
|
|
|
|
{
|
|
|
|
MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu);
|
|
|
|
}
|
|
|
|
else //Close current GUI
|
|
|
|
{
|
|
|
|
MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode();
|
|
|
|
}
|
2012-08-12 18:45:02 +00:00
|
|
|
}
|
|
|
|
|
2014-04-24 01:02:09 +00:00
|
|
|
void InputManager::quickLoad() {
|
2014-07-12 04:43:04 +00:00
|
|
|
if (!MyGUI::InputManager::getInstance().isModalAny())
|
|
|
|
MWBase::Environment::get().getStateManager()->quickLoad();
|
2014-04-24 01:02:09 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InputManager::quickSave() {
|
2014-07-12 04:43:04 +00:00
|
|
|
if (!MyGUI::InputManager::getInstance().isModalAny())
|
|
|
|
MWBase::Environment::get().getStateManager()->quickSave();
|
2014-04-24 01:02:09 +00:00
|
|
|
}
|
2012-08-12 18:45:02 +00:00
|
|
|
void InputManager::toggleSpell()
|
|
|
|
{
|
2013-08-27 13:48:13 +00:00
|
|
|
if (MWBase::Environment::get().getWindowManager()->isGuiMode()) return;
|
2012-08-12 18:45:02 +00:00
|
|
|
|
2013-08-03 22:21:27 +00:00
|
|
|
// Not allowed before the magic window is accessible
|
2014-11-28 14:54:38 +00:00
|
|
|
if (!mControlSwitch["playermagic"] || !mControlSwitch["playercontrols"])
|
2013-08-03 22:21:27 +00:00
|
|
|
return;
|
|
|
|
|
2015-12-26 17:15:57 +00:00
|
|
|
if (!checkAllowedToUseItems())
|
|
|
|
return;
|
|
|
|
|
2014-02-11 15:34:51 +00:00
|
|
|
// Not allowed if no spell selected
|
2014-05-22 18:37:22 +00:00
|
|
|
MWWorld::InventoryStore& inventory = mPlayer->getPlayer().getClass().getInventoryStore(mPlayer->getPlayer());
|
2014-02-15 16:39:11 +00:00
|
|
|
if (MWBase::Environment::get().getWindowManager()->getSelectedSpell().empty() &&
|
|
|
|
inventory.getSelectedEnchantItem() == inventory.end())
|
2014-02-11 15:34:51 +00:00
|
|
|
return;
|
|
|
|
|
2017-08-18 15:24:34 +00:00
|
|
|
if (MWBase::Environment::get().getMechanicsManager()->isAttackingOrSpell(mPlayer->getPlayer()))
|
|
|
|
return;
|
|
|
|
|
2013-08-27 13:48:13 +00:00
|
|
|
MWMechanics::DrawState_ state = mPlayer->getDrawState();
|
2012-08-12 18:45:02 +00:00
|
|
|
if (state == MWMechanics::DrawState_Weapon || state == MWMechanics::DrawState_Nothing)
|
2013-08-27 13:48:13 +00:00
|
|
|
mPlayer->setDrawState(MWMechanics::DrawState_Spell);
|
2012-08-12 18:45:02 +00:00
|
|
|
else
|
2013-08-27 13:48:13 +00:00
|
|
|
mPlayer->setDrawState(MWMechanics::DrawState_Nothing);
|
2012-08-12 18:45:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InputManager::toggleWeapon()
|
|
|
|
{
|
2013-08-27 13:48:13 +00:00
|
|
|
if (MWBase::Environment::get().getWindowManager()->isGuiMode()) return;
|
2012-08-12 18:45:02 +00:00
|
|
|
|
2013-08-03 22:21:27 +00:00
|
|
|
// Not allowed before the inventory window is accessible
|
2014-11-28 14:54:38 +00:00
|
|
|
if (!mControlSwitch["playerfighting"] || !mControlSwitch["playercontrols"])
|
2013-08-03 22:21:27 +00:00
|
|
|
return;
|
|
|
|
|
2018-08-16 13:47:06 +00:00
|
|
|
// We want to interrupt animation only if attack is preparing, but still is not triggered
|
2017-09-01 05:34:15 +00:00
|
|
|
// Otherwise we will get a "speedshooting" exploit, when player can skip reload animation by hitting "Toggle Weapon" key twice
|
2018-08-16 13:47:06 +00:00
|
|
|
if (MWBase::Environment::get().getMechanicsManager()->isAttackPreparing(mPlayer->getPlayer()))
|
2017-09-01 05:34:15 +00:00
|
|
|
mPlayer->setAttackingOrSpell(false);
|
|
|
|
else if (MWBase::Environment::get().getMechanicsManager()->isAttackingOrSpell(mPlayer->getPlayer()))
|
2017-08-18 15:24:34 +00:00
|
|
|
return;
|
|
|
|
|
2013-08-27 13:48:13 +00:00
|
|
|
MWMechanics::DrawState_ state = mPlayer->getDrawState();
|
2012-08-12 18:45:02 +00:00
|
|
|
if (state == MWMechanics::DrawState_Spell || state == MWMechanics::DrawState_Nothing)
|
2013-08-27 13:48:13 +00:00
|
|
|
mPlayer->setDrawState(MWMechanics::DrawState_Weapon);
|
2012-08-12 18:45:02 +00:00
|
|
|
else
|
2013-08-27 13:48:13 +00:00
|
|
|
mPlayer->setDrawState(MWMechanics::DrawState_Nothing);
|
2012-08-12 18:45:02 +00:00
|
|
|
}
|
|
|
|
|
2012-09-15 15:12:42 +00:00
|
|
|
void InputManager::rest()
|
|
|
|
{
|
2014-11-28 14:54:38 +00:00
|
|
|
if (!mControlSwitch["playercontrols"])
|
|
|
|
return;
|
|
|
|
|
2013-08-27 13:48:13 +00:00
|
|
|
if (!MWBase::Environment::get().getWindowManager()->getRestEnabled () || MWBase::Environment::get().getWindowManager()->isGuiMode ())
|
2012-09-15 18:18:41 +00:00
|
|
|
return;
|
|
|
|
|
2014-04-25 02:47:45 +00:00
|
|
|
MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_Rest); //Open rest GUI
|
|
|
|
|
2012-09-15 15:12:42 +00:00
|
|
|
}
|
|
|
|
|
2012-08-12 18:45:02 +00:00
|
|
|
void InputManager::screenshot()
|
|
|
|
{
|
2017-11-11 12:51:42 +00:00
|
|
|
bool regularScreenshot = true;
|
2017-11-09 15:06:29 +00:00
|
|
|
|
2017-11-11 13:32:28 +00:00
|
|
|
std::string settingStr;
|
|
|
|
|
2018-06-13 09:12:46 +00:00
|
|
|
settingStr = Settings::Manager::getString("screenshot type","Video");
|
|
|
|
regularScreenshot = settingStr.size() == 0 || settingStr.compare("regular") == 0;
|
2017-11-11 12:51:42 +00:00
|
|
|
|
|
|
|
if (regularScreenshot)
|
|
|
|
{
|
|
|
|
mScreenCaptureHandler->setFramesToCapture(1);
|
|
|
|
mScreenCaptureHandler->captureNextFrame(*mViewer);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
osg::ref_ptr<osg::Image> screenshot (new osg::Image);
|
|
|
|
|
2017-11-11 13:32:28 +00:00
|
|
|
if (MWBase::Environment::get().getWorld()->screenshot360(screenshot.get(),settingStr))
|
2017-11-16 12:50:10 +00:00
|
|
|
{
|
2017-11-11 12:51:42 +00:00
|
|
|
(*mScreenCaptureOperation) (*(screenshot.get()),0);
|
2018-06-13 19:34:43 +00:00
|
|
|
// FIXME: mScreenCaptureHandler->getCaptureOperation() causes crash for some reason
|
2017-11-16 12:50:10 +00:00
|
|
|
}
|
2017-11-11 12:51:42 +00:00
|
|
|
}
|
2012-08-12 18:45:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InputManager::toggleInventory()
|
|
|
|
{
|
2014-11-28 14:54:38 +00:00
|
|
|
if (!mControlSwitch["playercontrols"])
|
|
|
|
return;
|
|
|
|
|
2013-03-30 15:32:24 +00:00
|
|
|
if (MyGUI::InputManager::getInstance ().isModalAny())
|
|
|
|
return;
|
|
|
|
|
2019-05-16 06:28:56 +00:00
|
|
|
if (MWBase::Environment::get().getWindowManager()->isConsoleMode())
|
|
|
|
return;
|
|
|
|
|
2012-08-12 18:45:02 +00:00
|
|
|
// Toggle between game mode and inventory mode
|
2013-08-27 13:48:13 +00:00
|
|
|
if(!MWBase::Environment::get().getWindowManager()->isGuiMode())
|
|
|
|
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Inventory);
|
2013-02-10 04:37:45 +00:00
|
|
|
else
|
|
|
|
{
|
2013-08-27 13:48:13 +00:00
|
|
|
MWGui::GuiMode mode = MWBase::Environment::get().getWindowManager()->getMode();
|
2013-02-10 04:37:45 +00:00
|
|
|
if(mode == MWGui::GM_Inventory || mode == MWGui::GM_Container)
|
2013-08-27 13:48:13 +00:00
|
|
|
MWBase::Environment::get().getWindowManager()->popGuiMode();
|
2013-02-10 04:37:45 +00:00
|
|
|
}
|
2012-08-12 18:45:02 +00:00
|
|
|
|
2013-02-10 04:37:45 +00:00
|
|
|
// .. but don't touch any other mode, except container.
|
2012-08-12 18:45:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InputManager::toggleConsole()
|
|
|
|
{
|
2013-02-25 05:57:32 +00:00
|
|
|
if (MyGUI::InputManager::getInstance ().isModalAny())
|
|
|
|
return;
|
|
|
|
|
2019-05-16 06:28:56 +00:00
|
|
|
MWBase::Environment::get().getWindowManager()->toggleConsole();
|
2012-08-12 18:45:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InputManager::toggleJournal()
|
|
|
|
{
|
2014-11-28 14:54:38 +00:00
|
|
|
if (!mControlSwitch["playercontrols"])
|
|
|
|
return;
|
2013-03-30 15:32:24 +00:00
|
|
|
if (MyGUI::InputManager::getInstance ().isModalAny())
|
|
|
|
return;
|
|
|
|
|
2014-08-01 17:40:17 +00:00
|
|
|
if(MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_Journal
|
2017-08-04 03:31:41 +00:00
|
|
|
&& MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_MainMenu
|
2018-10-10 15:33:56 +00:00
|
|
|
&& MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_Settings
|
2014-08-25 16:55:21 +00:00
|
|
|
&& MWBase::Environment::get().getWindowManager ()->getJournalAllowed())
|
2013-04-08 17:00:38 +00:00
|
|
|
{
|
2013-08-27 13:48:13 +00:00
|
|
|
MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Journal);
|
2013-04-08 17:00:38 +00:00
|
|
|
}
|
2014-08-01 17:40:17 +00:00
|
|
|
else if(MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_Journal))
|
2013-04-08 17:00:38 +00:00
|
|
|
{
|
2014-08-01 17:40:17 +00:00
|
|
|
MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Journal);
|
2013-04-08 17:00:38 +00:00
|
|
|
}
|
2012-08-12 18:45:02 +00:00
|
|
|
}
|
|
|
|
|
2012-08-26 08:52:06 +00:00
|
|
|
void InputManager::quickKey (int index)
|
|
|
|
{
|
2019-04-12 13:08:55 +00:00
|
|
|
if (!mControlSwitch["playercontrols"] || !mControlSwitch["playerfighting"] || !mControlSwitch["playermagic"])
|
2014-11-28 14:54:38 +00:00
|
|
|
return;
|
2015-12-26 17:15:57 +00:00
|
|
|
if (!checkAllowedToUseItems())
|
2014-06-17 15:18:30 +00:00
|
|
|
return;
|
|
|
|
|
2019-09-19 19:03:29 +00:00
|
|
|
if (MWBase::Environment::get().getWorld()->getGlobalFloat ("chargenstate")!=-1)
|
|
|
|
return;
|
|
|
|
|
2013-08-27 13:48:13 +00:00
|
|
|
if (!MWBase::Environment::get().getWindowManager()->isGuiMode())
|
|
|
|
MWBase::Environment::get().getWindowManager()->activateQuickKey (index);
|
2012-08-26 08:52:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InputManager::showQuickKeysMenu()
|
|
|
|
{
|
2014-02-05 11:15:07 +00:00
|
|
|
if (!MWBase::Environment::get().getWindowManager()->isGuiMode ()
|
|
|
|
&& MWBase::Environment::get().getWorld()->getGlobalFloat ("chargenstate")==-1)
|
2014-06-17 15:18:30 +00:00
|
|
|
{
|
2015-12-26 17:15:57 +00:00
|
|
|
if (!checkAllowedToUseItems())
|
2014-06-17 15:18:30 +00:00
|
|
|
return;
|
|
|
|
|
2013-08-27 13:48:13 +00:00
|
|
|
MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_QuickKeysMenu);
|
2014-06-17 15:18:30 +00:00
|
|
|
|
|
|
|
}
|
2014-05-29 10:19:25 +00:00
|
|
|
else if (MWBase::Environment::get().getWindowManager()->getMode () == MWGui::GM_QuickKeysMenu) {
|
|
|
|
while(MyGUI::InputManager::getInstance().isModalAny()) { //Handle any open Modal windows
|
2015-03-11 19:04:25 +00:00
|
|
|
MWBase::Environment::get().getWindowManager()->exitCurrentModal();
|
2014-05-29 10:19:25 +00:00
|
|
|
}
|
|
|
|
MWBase::Environment::get().getWindowManager()->exitCurrentGuiMode(); //And handle the actual main window
|
|
|
|
}
|
2012-08-26 08:52:06 +00:00
|
|
|
}
|
|
|
|
|
2012-08-12 18:45:02 +00:00
|
|
|
void InputManager::activate()
|
|
|
|
{
|
2017-09-24 11:49:35 +00:00
|
|
|
if (MWBase::Environment::get().getWindowManager()->isGuiMode())
|
2017-11-10 22:54:04 +00:00
|
|
|
{
|
2018-02-10 23:11:03 +00:00
|
|
|
if (!SDL_IsTextInputActive() && !isLeftOrRightButton(A_Activate, mInputBinder, mFakeDeviceID, mJoystickLastUsed))
|
2018-09-09 19:10:09 +00:00
|
|
|
MWBase::Environment::get().getWindowManager()->injectKeyPress(MyGUI::KeyCode::Return, 0, false);
|
2017-11-10 22:54:04 +00:00
|
|
|
}
|
2017-09-24 11:49:35 +00:00
|
|
|
else if (mControlSwitch["playercontrols"])
|
2015-11-14 01:43:24 +00:00
|
|
|
mPlayer->activate();
|
2012-08-12 18:45:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InputManager::toggleAutoMove()
|
|
|
|
{
|
2013-08-27 13:48:13 +00:00
|
|
|
if (MWBase::Environment::get().getWindowManager()->isGuiMode()) return;
|
2012-11-27 17:39:12 +00:00
|
|
|
|
|
|
|
if (mControlSwitch["playercontrols"])
|
2013-08-27 13:48:13 +00:00
|
|
|
mPlayer->setAutoMove (!mPlayer->getAutoMove());
|
2012-08-12 18:45:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InputManager::toggleWalking()
|
|
|
|
{
|
2018-12-12 20:40:15 +00:00
|
|
|
if (MWBase::Environment::get().getWindowManager()->isGuiMode() || SDL_IsTextInputActive()) return;
|
2013-03-14 20:08:19 +00:00
|
|
|
mAlwaysRunActive = !mAlwaysRunActive;
|
2014-06-08 17:50:39 +00:00
|
|
|
|
|
|
|
Settings::Manager::setBool("always run", "Input", mAlwaysRunActive);
|
2012-08-12 18:45:02 +00:00
|
|
|
}
|
|
|
|
|
2015-03-08 20:23:46 +00:00
|
|
|
void InputManager::toggleSneaking()
|
|
|
|
{
|
|
|
|
if (MWBase::Environment::get().getWindowManager()->isGuiMode()) return;
|
2019-05-06 19:30:07 +00:00
|
|
|
if (!mControlSwitch["playercontrols"]) return;
|
2015-03-08 20:23:46 +00:00
|
|
|
mSneaking = !mSneaking;
|
2015-03-08 21:08:45 +00:00
|
|
|
mPlayer->setSneak(mSneaking);
|
2015-03-08 20:23:46 +00:00
|
|
|
}
|
|
|
|
|
2012-08-17 21:31:57 +00:00
|
|
|
void InputManager::resetIdleTime()
|
|
|
|
{
|
2013-04-27 08:24:36 +00:00
|
|
|
if (mTimeIdle < 0)
|
|
|
|
MWBase::Environment::get().getWorld()->toggleVanityMode(false);
|
2012-08-17 21:31:57 +00:00
|
|
|
mTimeIdle = 0.f;
|
|
|
|
}
|
|
|
|
|
|
|
|
void InputManager::updateIdleTime(float dt)
|
|
|
|
{
|
2014-01-01 23:13:23 +00:00
|
|
|
static const float vanityDelay = MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>()
|
2018-08-29 15:38:12 +00:00
|
|
|
.find("fVanityDelay")->mValue.getFloat();
|
2013-04-27 08:24:36 +00:00
|
|
|
if (mTimeIdle >= 0.f)
|
2012-08-17 21:31:57 +00:00
|
|
|
mTimeIdle += dt;
|
2014-01-01 23:13:23 +00:00
|
|
|
if (mTimeIdle > vanityDelay) {
|
2013-04-27 08:24:36 +00:00
|
|
|
MWBase::Environment::get().getWorld()->toggleVanityMode(true);
|
2012-08-17 21:31:57 +00:00
|
|
|
mTimeIdle = -1.f;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-12 18:45:02 +00:00
|
|
|
bool InputManager::actionIsActive (int id)
|
|
|
|
{
|
2014-12-09 06:02:18 +00:00
|
|
|
return (mInputBinder->getChannel (id)->getValue ()==1.0);
|
2012-08-12 18:45:02 +00:00
|
|
|
}
|
|
|
|
|
2012-08-13 00:55:22 +00:00
|
|
|
void InputManager::loadKeyDefaults (bool force)
|
2012-08-12 20:59:58 +00:00
|
|
|
{
|
|
|
|
// using hardcoded key defaults is inevitable, if we want the configuration files to stay valid
|
|
|
|
// across different versions of OpenMW (in the case where another input action is added)
|
2014-09-13 18:39:32 +00:00
|
|
|
std::map<int, SDL_Scancode> defaultKeyBindings;
|
2012-08-12 20:59:58 +00:00
|
|
|
|
2014-04-20 04:34:58 +00:00
|
|
|
//Gets the Keyvalue from the Scancode; gives the button in the same place reguardless of keyboard format
|
2014-09-13 18:39:32 +00:00
|
|
|
defaultKeyBindings[A_Activate] = SDL_SCANCODE_SPACE;
|
|
|
|
defaultKeyBindings[A_MoveBackward] = SDL_SCANCODE_S;
|
|
|
|
defaultKeyBindings[A_MoveForward] = SDL_SCANCODE_W;
|
|
|
|
defaultKeyBindings[A_MoveLeft] = SDL_SCANCODE_A;
|
|
|
|
defaultKeyBindings[A_MoveRight] = SDL_SCANCODE_D;
|
|
|
|
defaultKeyBindings[A_ToggleWeapon] = SDL_SCANCODE_F;
|
|
|
|
defaultKeyBindings[A_ToggleSpell] = SDL_SCANCODE_R;
|
2014-12-15 14:23:03 +00:00
|
|
|
defaultKeyBindings[A_CycleSpellLeft] = SDL_SCANCODE_MINUS;
|
|
|
|
defaultKeyBindings[A_CycleSpellRight] = SDL_SCANCODE_EQUALS;
|
|
|
|
defaultKeyBindings[A_CycleWeaponLeft] = SDL_SCANCODE_LEFTBRACKET;
|
|
|
|
defaultKeyBindings[A_CycleWeaponRight] = SDL_SCANCODE_RIGHTBRACKET;
|
|
|
|
|
2014-09-13 18:39:32 +00:00
|
|
|
defaultKeyBindings[A_QuickKeysMenu] = SDL_SCANCODE_F1;
|
|
|
|
defaultKeyBindings[A_Console] = SDL_SCANCODE_GRAVE;
|
|
|
|
defaultKeyBindings[A_Run] = SDL_SCANCODE_LSHIFT;
|
|
|
|
defaultKeyBindings[A_Sneak] = SDL_SCANCODE_LCTRL;
|
|
|
|
defaultKeyBindings[A_AutoMove] = SDL_SCANCODE_Q;
|
|
|
|
defaultKeyBindings[A_Jump] = SDL_SCANCODE_E;
|
|
|
|
defaultKeyBindings[A_Journal] = SDL_SCANCODE_J;
|
|
|
|
defaultKeyBindings[A_Rest] = SDL_SCANCODE_T;
|
|
|
|
defaultKeyBindings[A_GameMenu] = SDL_SCANCODE_ESCAPE;
|
|
|
|
defaultKeyBindings[A_TogglePOV] = SDL_SCANCODE_TAB;
|
|
|
|
defaultKeyBindings[A_QuickKey1] = SDL_SCANCODE_1;
|
|
|
|
defaultKeyBindings[A_QuickKey2] = SDL_SCANCODE_2;
|
|
|
|
defaultKeyBindings[A_QuickKey3] = SDL_SCANCODE_3;
|
|
|
|
defaultKeyBindings[A_QuickKey4] = SDL_SCANCODE_4;
|
|
|
|
defaultKeyBindings[A_QuickKey5] = SDL_SCANCODE_5;
|
|
|
|
defaultKeyBindings[A_QuickKey6] = SDL_SCANCODE_6;
|
|
|
|
defaultKeyBindings[A_QuickKey7] = SDL_SCANCODE_7;
|
|
|
|
defaultKeyBindings[A_QuickKey8] = SDL_SCANCODE_8;
|
|
|
|
defaultKeyBindings[A_QuickKey9] = SDL_SCANCODE_9;
|
|
|
|
defaultKeyBindings[A_QuickKey10] = SDL_SCANCODE_0;
|
|
|
|
defaultKeyBindings[A_Screenshot] = SDL_SCANCODE_F12;
|
|
|
|
defaultKeyBindings[A_ToggleHUD] = SDL_SCANCODE_F11;
|
2014-09-28 15:57:14 +00:00
|
|
|
defaultKeyBindings[A_ToggleDebug] = SDL_SCANCODE_F10;
|
2014-09-13 18:39:32 +00:00
|
|
|
defaultKeyBindings[A_AlwaysRun] = SDL_SCANCODE_CAPSLOCK;
|
|
|
|
defaultKeyBindings[A_QuickSave] = SDL_SCANCODE_F5;
|
|
|
|
defaultKeyBindings[A_QuickLoad] = SDL_SCANCODE_F9;
|
2012-08-12 20:59:58 +00:00
|
|
|
|
|
|
|
std::map<int, int> defaultMouseButtonBindings;
|
2013-01-08 10:19:05 +00:00
|
|
|
defaultMouseButtonBindings[A_Inventory] = SDL_BUTTON_RIGHT;
|
|
|
|
defaultMouseButtonBindings[A_Use] = SDL_BUTTON_LEFT;
|
2012-08-12 20:59:58 +00:00
|
|
|
|
2019-10-30 11:22:24 +00:00
|
|
|
std::map<int, ICS::InputControlSystem::MouseWheelClick> defaultMouseWheelBindings;
|
|
|
|
defaultMouseWheelBindings[A_ZoomIn] = ICS::InputControlSystem::MouseWheelClick::UP;
|
|
|
|
defaultMouseWheelBindings[A_ZoomOut] = ICS::InputControlSystem::MouseWheelClick::DOWN;
|
|
|
|
|
2012-08-12 23:26:15 +00:00
|
|
|
for (int i = 0; i < A_Last; ++i)
|
2012-08-12 20:59:58 +00:00
|
|
|
{
|
2012-08-13 00:55:22 +00:00
|
|
|
ICS::Control* control;
|
2013-01-10 21:21:47 +00:00
|
|
|
bool controlExists = mInputBinder->getChannel(i)->getControlsCount () != 0;
|
2012-08-13 00:55:22 +00:00
|
|
|
if (!controlExists)
|
|
|
|
{
|
2017-05-06 21:05:13 +00:00
|
|
|
control = new ICS::Control(std::to_string(i), false, true, 0, ICS::ICS_MAX, ICS::ICS_MAX);
|
2013-01-10 21:21:47 +00:00
|
|
|
mInputBinder->addControl(control);
|
|
|
|
control->attachChannel(mInputBinder->getChannel(i), ICS::Channel::DIRECT);
|
2012-08-13 00:55:22 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-01-10 21:21:47 +00:00
|
|
|
control = mInputBinder->getChannel(i)->getAttachedControls ().front().control;
|
2012-08-13 00:55:22 +00:00
|
|
|
}
|
|
|
|
|
2012-08-27 13:51:01 +00:00
|
|
|
if (!controlExists || force ||
|
2014-09-13 18:39:32 +00:00
|
|
|
( mInputBinder->getKeyBinding (control, ICS::Control::INCREASE) == SDL_SCANCODE_UNKNOWN
|
2013-01-10 21:21:47 +00:00
|
|
|
&& mInputBinder->getMouseButtonBinding (control, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS
|
2019-10-30 11:22:24 +00:00
|
|
|
&& mInputBinder->getMouseWheelBinding(control, ICS::Control::INCREASE) == ICS::InputControlSystem::MouseWheelClick::UNASSIGNED
|
2012-08-27 13:51:01 +00:00
|
|
|
))
|
2012-08-12 20:59:58 +00:00
|
|
|
{
|
2014-12-09 03:57:32 +00:00
|
|
|
clearAllKeyBindings(control);
|
2012-08-12 20:59:58 +00:00
|
|
|
|
2014-10-01 15:54:18 +00:00
|
|
|
if (defaultKeyBindings.find(i) != defaultKeyBindings.end()
|
2018-01-11 01:47:42 +00:00
|
|
|
&& (force || !mInputBinder->isKeyBound(defaultKeyBindings[i])))
|
2014-12-09 03:57:32 +00:00
|
|
|
{
|
2014-12-09 17:16:17 +00:00
|
|
|
control->setInitialValue(0.0f);
|
2014-09-13 18:39:32 +00:00
|
|
|
mInputBinder->addKeyBinding(control, defaultKeyBindings[i], ICS::Control::INCREASE);
|
2014-12-09 03:57:32 +00:00
|
|
|
}
|
2014-10-01 15:54:18 +00:00
|
|
|
else if (defaultMouseButtonBindings.find(i) != defaultMouseButtonBindings.end()
|
2018-01-11 01:47:42 +00:00
|
|
|
&& (force || !mInputBinder->isMouseButtonBound(defaultMouseButtonBindings[i])))
|
2014-12-09 03:57:32 +00:00
|
|
|
{
|
2014-12-09 17:16:17 +00:00
|
|
|
control->setInitialValue(0.0f);
|
2013-01-10 21:21:47 +00:00
|
|
|
mInputBinder->addMouseButtonBinding (control, defaultMouseButtonBindings[i], ICS::Control::INCREASE);
|
2014-12-09 03:57:32 +00:00
|
|
|
}
|
2019-10-30 11:22:24 +00:00
|
|
|
else if (defaultMouseWheelBindings.find(i) != defaultMouseWheelBindings.end()
|
|
|
|
&& (force || !mInputBinder->isMouseWheelBound(defaultMouseWheelBindings[i])))
|
|
|
|
{
|
|
|
|
control->setInitialValue(0.f);
|
|
|
|
mInputBinder->addMouseWheelBinding(control, defaultMouseWheelBindings[i], ICS::Control::INCREASE);
|
|
|
|
}
|
2017-09-24 13:32:44 +00:00
|
|
|
|
|
|
|
if (i == A_LookLeftRight && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_4) && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_6))
|
|
|
|
{
|
|
|
|
mInputBinder->addKeyBinding(control, SDL_SCANCODE_KP_6, ICS::Control::INCREASE);
|
|
|
|
mInputBinder->addKeyBinding(control, SDL_SCANCODE_KP_4, ICS::Control::DECREASE);
|
|
|
|
}
|
|
|
|
if (i == A_LookUpDown && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_8) && !mInputBinder->isKeyBound(SDL_SCANCODE_KP_2))
|
|
|
|
{
|
|
|
|
mInputBinder->addKeyBinding(control, SDL_SCANCODE_KP_2, ICS::Control::INCREASE);
|
|
|
|
mInputBinder->addKeyBinding(control, SDL_SCANCODE_KP_8, ICS::Control::DECREASE);
|
|
|
|
}
|
2014-12-09 03:57:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void InputManager::loadControllerDefaults(bool force)
|
|
|
|
{
|
|
|
|
// using hardcoded key defaults is inevitable, if we want the configuration files to stay valid
|
|
|
|
// across different versions of OpenMW (in the case where another input action is added)
|
|
|
|
std::map<int, int> defaultButtonBindings;
|
|
|
|
|
|
|
|
defaultButtonBindings[A_Activate] = SDL_CONTROLLER_BUTTON_A;
|
|
|
|
defaultButtonBindings[A_ToggleWeapon] = SDL_CONTROLLER_BUTTON_X;
|
2019-02-27 13:29:48 +00:00
|
|
|
defaultButtonBindings[A_ToggleSpell] = SDL_CONTROLLER_BUTTON_Y;
|
2014-12-09 03:57:32 +00:00
|
|
|
//defaultButtonBindings[A_QuickButtonsMenu] = SDL_GetButtonFromScancode(SDL_SCANCODE_F1); // Need to implement, should be ToggleSpell(5) AND Wait(9)
|
2019-02-27 13:29:48 +00:00
|
|
|
defaultButtonBindings[A_Sneak] = SDL_CONTROLLER_BUTTON_LEFTSTICK;
|
|
|
|
defaultButtonBindings[A_Journal] = SDL_CONTROLLER_BUTTON_LEFTSHOULDER;
|
|
|
|
defaultButtonBindings[A_Rest] = SDL_CONTROLLER_BUTTON_RIGHTSHOULDER;
|
|
|
|
defaultButtonBindings[A_TogglePOV] = SDL_CONTROLLER_BUTTON_RIGHTSTICK;
|
2014-12-09 03:57:32 +00:00
|
|
|
defaultButtonBindings[A_Inventory] = SDL_CONTROLLER_BUTTON_B;
|
|
|
|
defaultButtonBindings[A_GameMenu] = SDL_CONTROLLER_BUTTON_START;
|
|
|
|
defaultButtonBindings[A_QuickSave] = SDL_CONTROLLER_BUTTON_GUIDE;
|
2019-03-02 14:28:26 +00:00
|
|
|
defaultButtonBindings[A_MoveForward] = SDL_CONTROLLER_BUTTON_DPAD_UP;
|
|
|
|
defaultButtonBindings[A_MoveLeft] = SDL_CONTROLLER_BUTTON_DPAD_LEFT;
|
|
|
|
defaultButtonBindings[A_MoveBackward] = SDL_CONTROLLER_BUTTON_DPAD_DOWN;
|
|
|
|
defaultButtonBindings[A_MoveRight] = SDL_CONTROLLER_BUTTON_DPAD_RIGHT;
|
2014-12-09 03:57:32 +00:00
|
|
|
|
|
|
|
std::map<int, int> defaultAxisBindings;
|
|
|
|
defaultAxisBindings[A_MoveForwardBackward] = SDL_CONTROLLER_AXIS_LEFTY;
|
|
|
|
defaultAxisBindings[A_MoveLeftRight] = SDL_CONTROLLER_AXIS_LEFTX;
|
|
|
|
defaultAxisBindings[A_LookUpDown] = SDL_CONTROLLER_AXIS_RIGHTY;
|
|
|
|
defaultAxisBindings[A_LookLeftRight] = SDL_CONTROLLER_AXIS_RIGHTX;
|
|
|
|
defaultAxisBindings[A_Use] = SDL_CONTROLLER_AXIS_TRIGGERRIGHT;
|
2019-02-27 13:29:48 +00:00
|
|
|
defaultAxisBindings[A_Jump] = SDL_CONTROLLER_AXIS_TRIGGERLEFT;
|
2014-12-09 03:57:32 +00:00
|
|
|
|
|
|
|
for (int i = 0; i < A_Last; i++)
|
|
|
|
{
|
|
|
|
ICS::Control* control;
|
|
|
|
bool controlExists = mInputBinder->getChannel(i)->getControlsCount () != 0;
|
|
|
|
if (!controlExists)
|
|
|
|
{
|
2015-03-03 10:23:50 +00:00
|
|
|
float initial;
|
2017-06-25 12:43:56 +00:00
|
|
|
if (defaultAxisBindings.find(i) == defaultAxisBindings.end())
|
2015-03-03 10:23:50 +00:00
|
|
|
initial = 0.0f;
|
|
|
|
else initial = 0.5f;
|
2017-05-06 21:05:13 +00:00
|
|
|
control = new ICS::Control(std::to_string(i), false, true, initial, ICS::ICS_MAX, ICS::ICS_MAX);
|
2014-12-09 03:57:32 +00:00
|
|
|
mInputBinder->addControl(control);
|
|
|
|
control->attachChannel(mInputBinder->getChannel(i), ICS::Channel::DIRECT);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
control = mInputBinder->getChannel(i)->getAttachedControls ().front().control;
|
|
|
|
}
|
|
|
|
|
2015-01-19 21:36:15 +00:00
|
|
|
if (!controlExists || force || ( mInputBinder->getJoystickAxisBinding (control, mFakeDeviceID, ICS::Control::INCREASE) == ICS::InputControlSystem::UNASSIGNED && mInputBinder->getJoystickButtonBinding (control, mFakeDeviceID, ICS::Control::INCREASE) == ICS_MAX_DEVICE_BUTTONS ))
|
2014-12-09 03:57:32 +00:00
|
|
|
{
|
|
|
|
clearAllControllerBindings(control);
|
|
|
|
|
2017-06-25 12:43:56 +00:00
|
|
|
if (defaultButtonBindings.find(i) != defaultButtonBindings.end()
|
2018-01-11 01:47:42 +00:00
|
|
|
&& (force || !mInputBinder->isJoystickButtonBound(mFakeDeviceID, defaultButtonBindings[i])))
|
2014-12-09 03:57:32 +00:00
|
|
|
{
|
2014-12-09 17:16:17 +00:00
|
|
|
control->setInitialValue(0.0f);
|
2015-01-19 21:36:15 +00:00
|
|
|
mInputBinder->addJoystickButtonBinding(control, mFakeDeviceID, defaultButtonBindings[i], ICS::Control::INCREASE);
|
2014-12-09 03:57:32 +00:00
|
|
|
}
|
2018-01-11 01:47:42 +00:00
|
|
|
else if (defaultAxisBindings.find(i) != defaultAxisBindings.end() && (force || !mInputBinder->isJoystickAxisBound(mFakeDeviceID, defaultAxisBindings[i])))
|
2014-12-09 03:57:32 +00:00
|
|
|
{
|
2014-12-09 17:16:17 +00:00
|
|
|
control->setValue(0.5f);
|
|
|
|
control->setInitialValue(0.5f);
|
2015-01-19 21:36:15 +00:00
|
|
|
mInputBinder->addJoystickAxisBinding(control, mFakeDeviceID, defaultAxisBindings[i], ICS::Control::INCREASE);
|
2014-12-09 03:57:32 +00:00
|
|
|
}
|
2012-08-12 20:59:58 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2012-08-12 23:26:15 +00:00
|
|
|
std::string InputManager::getActionDescription (int action)
|
|
|
|
{
|
|
|
|
std::map<int, std::string> descriptions;
|
|
|
|
|
2013-07-31 18:24:44 +00:00
|
|
|
if (action == A_Screenshot)
|
|
|
|
return "Screenshot";
|
2019-10-30 11:22:24 +00:00
|
|
|
else if (action == A_ZoomIn)
|
|
|
|
return "Zoom In";
|
|
|
|
else if (action == A_ZoomOut)
|
|
|
|
return "Zoom Out";
|
2020-01-10 10:29:04 +00:00
|
|
|
else if (action == A_ToggleHUD)
|
|
|
|
return "Toggle HUD";
|
2013-07-31 18:24:44 +00:00
|
|
|
|
2013-05-19 16:40:37 +00:00
|
|
|
descriptions[A_Use] = "sUse";
|
2012-08-12 23:26:15 +00:00
|
|
|
descriptions[A_Activate] = "sActivate";
|
|
|
|
descriptions[A_MoveBackward] = "sBack";
|
|
|
|
descriptions[A_MoveForward] = "sForward";
|
|
|
|
descriptions[A_MoveLeft] = "sLeft";
|
|
|
|
descriptions[A_MoveRight] = "sRight";
|
|
|
|
descriptions[A_ToggleWeapon] = "sReady_Weapon";
|
|
|
|
descriptions[A_ToggleSpell] = "sReady_Magic";
|
2014-12-15 14:23:03 +00:00
|
|
|
descriptions[A_CycleSpellLeft] = "sPrevSpell";
|
|
|
|
descriptions[A_CycleSpellRight] = "sNextSpell";
|
|
|
|
descriptions[A_CycleWeaponLeft] = "sPrevWeapon";
|
|
|
|
descriptions[A_CycleWeaponRight] = "sNextWeapon";
|
2012-08-12 23:26:15 +00:00
|
|
|
descriptions[A_Console] = "sConsoleTitle";
|
2013-02-07 01:51:47 +00:00
|
|
|
descriptions[A_Run] = "sRun";
|
2013-03-06 15:58:56 +00:00
|
|
|
descriptions[A_Sneak] = "sCrouch_Sneak";
|
2012-08-12 23:26:15 +00:00
|
|
|
descriptions[A_AutoMove] = "sAuto_Run";
|
|
|
|
descriptions[A_Jump] = "sJump";
|
|
|
|
descriptions[A_Journal] = "sJournal";
|
|
|
|
descriptions[A_Rest] = "sRestKey";
|
|
|
|
descriptions[A_Inventory] = "sInventory";
|
2012-08-19 20:09:22 +00:00
|
|
|
descriptions[A_TogglePOV] = "sTogglePOVCmd";
|
2012-08-26 08:52:06 +00:00
|
|
|
descriptions[A_QuickKeysMenu] = "sQuickMenu";
|
|
|
|
descriptions[A_QuickKey1] = "sQuick1Cmd";
|
|
|
|
descriptions[A_QuickKey2] = "sQuick2Cmd";
|
|
|
|
descriptions[A_QuickKey3] = "sQuick3Cmd";
|
|
|
|
descriptions[A_QuickKey4] = "sQuick4Cmd";
|
|
|
|
descriptions[A_QuickKey5] = "sQuick5Cmd";
|
|
|
|
descriptions[A_QuickKey6] = "sQuick6Cmd";
|
|
|
|
descriptions[A_QuickKey7] = "sQuick7Cmd";
|
|
|
|
descriptions[A_QuickKey8] = "sQuick8Cmd";
|
|
|
|
descriptions[A_QuickKey9] = "sQuick9Cmd";
|
|
|
|
descriptions[A_QuickKey10] = "sQuick10Cmd";
|
2013-03-14 19:27:16 +00:00
|
|
|
descriptions[A_AlwaysRun] = "sAlways_Run";
|
2014-04-24 01:02:09 +00:00
|
|
|
descriptions[A_QuickSave] = "sQuickSaveCmd";
|
|
|
|
descriptions[A_QuickLoad] = "sQuickLoadCmd";
|
2012-08-12 23:26:15 +00:00
|
|
|
|
|
|
|
if (descriptions[action] == "")
|
|
|
|
return ""; // not configurable
|
|
|
|
|
|
|
|
return "#{" + descriptions[action] + "}";
|
|
|
|
}
|
|
|
|
|
2014-12-09 03:57:32 +00:00
|
|
|
std::string InputManager::getActionKeyBindingName (int action)
|
2012-08-12 23:26:15 +00:00
|
|
|
{
|
2013-01-10 21:21:47 +00:00
|
|
|
if (mInputBinder->getChannel (action)->getControlsCount () == 0)
|
2012-08-12 23:26:15 +00:00
|
|
|
return "#{sNone}";
|
|
|
|
|
2013-01-10 21:21:47 +00:00
|
|
|
ICS::Control* c = mInputBinder->getChannel (action)->getAttachedControls ().front().control;
|
2012-08-12 23:26:15 +00:00
|
|
|
|
2016-03-28 23:12:18 +00:00
|
|
|
SDL_Scancode key = mInputBinder->getKeyBinding (c, ICS::Control::INCREASE);
|
|
|
|
unsigned int mouse = mInputBinder->getMouseButtonBinding (c, ICS::Control::INCREASE);
|
2019-10-30 11:22:24 +00:00
|
|
|
ICS::InputControlSystem::MouseWheelClick wheel = mInputBinder->getMouseWheelBinding(c, ICS::Control::INCREASE);
|
2016-03-28 23:12:18 +00:00
|
|
|
if (key != SDL_SCANCODE_UNKNOWN)
|
|
|
|
return MyGUI::TextIterator::toTagsString(mInputBinder->scancodeToString (key));
|
|
|
|
else if (mouse != ICS_MAX_DEVICE_BUTTONS)
|
2017-05-06 21:05:13 +00:00
|
|
|
return "#{sMouse} " + std::to_string(mouse);
|
2019-10-30 11:22:24 +00:00
|
|
|
else if (wheel != ICS::InputControlSystem::MouseWheelClick::UNASSIGNED)
|
|
|
|
switch (wheel)
|
|
|
|
{
|
|
|
|
case ICS::InputControlSystem::MouseWheelClick::UP:
|
|
|
|
return "Mouse Wheel Up";
|
|
|
|
case ICS::InputControlSystem::MouseWheelClick::DOWN:
|
|
|
|
return "Mouse Wheel Down";
|
|
|
|
case ICS::InputControlSystem::MouseWheelClick::RIGHT:
|
|
|
|
return "Mouse Wheel Right";
|
|
|
|
case ICS::InputControlSystem::MouseWheelClick::LEFT:
|
|
|
|
return "Mouse Wheel Left";
|
|
|
|
default:
|
|
|
|
return "#{sNone}";
|
|
|
|
}
|
2012-08-12 23:26:15 +00:00
|
|
|
else
|
|
|
|
return "#{sNone}";
|
|
|
|
}
|
|
|
|
|
2014-12-09 03:57:32 +00:00
|
|
|
std::string InputManager::getActionControllerBindingName (int action)
|
|
|
|
{
|
|
|
|
if (mInputBinder->getChannel (action)->getControlsCount () == 0)
|
|
|
|
return "#{sNone}";
|
|
|
|
|
|
|
|
ICS::Control* c = mInputBinder->getChannel (action)->getAttachedControls ().front().control;
|
|
|
|
|
2015-01-19 21:36:15 +00:00
|
|
|
if (mInputBinder->getJoystickAxisBinding (c, mFakeDeviceID, ICS::Control::INCREASE) != ICS::InputControlSystem::UNASSIGNED)
|
|
|
|
return sdlControllerAxisToString(mInputBinder->getJoystickAxisBinding (c, mFakeDeviceID, ICS::Control::INCREASE));
|
|
|
|
else if (mInputBinder->getJoystickButtonBinding (c, mFakeDeviceID, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS )
|
|
|
|
return sdlControllerButtonToString(mInputBinder->getJoystickButtonBinding (c, mFakeDeviceID, ICS::Control::INCREASE));
|
2014-12-09 03:57:32 +00:00
|
|
|
else
|
|
|
|
return "#{sNone}";
|
|
|
|
}
|
|
|
|
|
|
|
|
std::vector<int> InputManager::getActionKeySorting()
|
2012-08-12 23:26:15 +00:00
|
|
|
{
|
|
|
|
std::vector<int> ret;
|
|
|
|
ret.push_back(A_MoveForward);
|
|
|
|
ret.push_back(A_MoveBackward);
|
|
|
|
ret.push_back(A_MoveLeft);
|
|
|
|
ret.push_back(A_MoveRight);
|
2012-08-19 20:09:22 +00:00
|
|
|
ret.push_back(A_TogglePOV);
|
2019-10-30 11:22:24 +00:00
|
|
|
ret.push_back(A_ZoomIn);
|
|
|
|
ret.push_back(A_ZoomOut);
|
2013-02-07 01:51:47 +00:00
|
|
|
ret.push_back(A_Run);
|
2013-03-14 19:27:16 +00:00
|
|
|
ret.push_back(A_AlwaysRun);
|
2013-03-06 15:58:56 +00:00
|
|
|
ret.push_back(A_Sneak);
|
2012-08-12 23:26:15 +00:00
|
|
|
ret.push_back(A_Activate);
|
2013-05-19 16:40:37 +00:00
|
|
|
ret.push_back(A_Use);
|
2012-08-12 23:26:15 +00:00
|
|
|
ret.push_back(A_ToggleWeapon);
|
2012-08-13 00:55:22 +00:00
|
|
|
ret.push_back(A_ToggleSpell);
|
2014-12-15 14:23:03 +00:00
|
|
|
ret.push_back(A_CycleSpellLeft);
|
|
|
|
ret.push_back(A_CycleSpellRight);
|
|
|
|
ret.push_back(A_CycleWeaponLeft);
|
|
|
|
ret.push_back(A_CycleWeaponRight);
|
2012-08-12 23:26:15 +00:00
|
|
|
ret.push_back(A_AutoMove);
|
|
|
|
ret.push_back(A_Jump);
|
|
|
|
ret.push_back(A_Inventory);
|
|
|
|
ret.push_back(A_Journal);
|
|
|
|
ret.push_back(A_Rest);
|
|
|
|
ret.push_back(A_Console);
|
2014-04-24 01:02:09 +00:00
|
|
|
ret.push_back(A_QuickSave);
|
|
|
|
ret.push_back(A_QuickLoad);
|
2020-01-10 10:29:04 +00:00
|
|
|
ret.push_back(A_ToggleHUD);
|
2013-07-31 18:24:44 +00:00
|
|
|
ret.push_back(A_Screenshot);
|
2012-08-26 08:52:06 +00:00
|
|
|
ret.push_back(A_QuickKeysMenu);
|
|
|
|
ret.push_back(A_QuickKey1);
|
|
|
|
ret.push_back(A_QuickKey2);
|
|
|
|
ret.push_back(A_QuickKey3);
|
|
|
|
ret.push_back(A_QuickKey4);
|
|
|
|
ret.push_back(A_QuickKey5);
|
|
|
|
ret.push_back(A_QuickKey6);
|
|
|
|
ret.push_back(A_QuickKey7);
|
|
|
|
ret.push_back(A_QuickKey8);
|
|
|
|
ret.push_back(A_QuickKey9);
|
|
|
|
ret.push_back(A_QuickKey10);
|
2012-08-12 23:26:15 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2014-12-09 03:57:32 +00:00
|
|
|
std::vector<int> InputManager::getActionControllerSorting()
|
|
|
|
{
|
|
|
|
std::vector<int> ret;
|
|
|
|
ret.push_back(A_TogglePOV);
|
2019-10-30 11:22:24 +00:00
|
|
|
ret.push_back(A_ZoomIn);
|
|
|
|
ret.push_back(A_ZoomOut);
|
2014-12-09 03:57:32 +00:00
|
|
|
ret.push_back(A_Sneak);
|
|
|
|
ret.push_back(A_Activate);
|
|
|
|
ret.push_back(A_Use);
|
|
|
|
ret.push_back(A_ToggleWeapon);
|
|
|
|
ret.push_back(A_ToggleSpell);
|
|
|
|
ret.push_back(A_AutoMove);
|
|
|
|
ret.push_back(A_Jump);
|
|
|
|
ret.push_back(A_Inventory);
|
|
|
|
ret.push_back(A_Journal);
|
|
|
|
ret.push_back(A_Rest);
|
|
|
|
ret.push_back(A_QuickSave);
|
|
|
|
ret.push_back(A_QuickLoad);
|
2020-01-10 10:29:04 +00:00
|
|
|
ret.push_back(A_ToggleHUD);
|
2014-12-09 03:57:32 +00:00
|
|
|
ret.push_back(A_Screenshot);
|
|
|
|
ret.push_back(A_QuickKeysMenu);
|
|
|
|
ret.push_back(A_QuickKey1);
|
|
|
|
ret.push_back(A_QuickKey2);
|
|
|
|
ret.push_back(A_QuickKey3);
|
|
|
|
ret.push_back(A_QuickKey4);
|
|
|
|
ret.push_back(A_QuickKey5);
|
|
|
|
ret.push_back(A_QuickKey6);
|
|
|
|
ret.push_back(A_QuickKey7);
|
|
|
|
ret.push_back(A_QuickKey8);
|
|
|
|
ret.push_back(A_QuickKey9);
|
|
|
|
ret.push_back(A_QuickKey10);
|
2017-02-05 19:23:49 +00:00
|
|
|
ret.push_back(A_CycleSpellLeft);
|
|
|
|
ret.push_back(A_CycleSpellRight);
|
|
|
|
ret.push_back(A_CycleWeaponLeft);
|
|
|
|
ret.push_back(A_CycleWeaponRight);
|
2014-12-09 03:57:32 +00:00
|
|
|
|
|
|
|
return ret;
|
|
|
|
}
|
2012-08-12 23:26:15 +00:00
|
|
|
|
2014-12-09 03:57:32 +00:00
|
|
|
void InputManager::enableDetectingBindingMode (int action, bool keyboard)
|
2012-08-12 23:26:15 +00:00
|
|
|
{
|
2014-12-09 03:57:32 +00:00
|
|
|
mDetectingKeyboard = keyboard;
|
2013-01-10 21:21:47 +00:00
|
|
|
ICS::Control* c = mInputBinder->getChannel (action)->getAttachedControls ().front().control;
|
|
|
|
mInputBinder->enableDetectingBindingState (c, ICS::Control::INCREASE);
|
2012-08-12 23:26:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void InputManager::keyBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
|
2014-09-13 18:39:32 +00:00
|
|
|
, SDL_Scancode key, ICS::Control::ControlChangingDirection direction)
|
2012-08-12 23:26:15 +00:00
|
|
|
{
|
2013-06-15 11:22:29 +00:00
|
|
|
//Disallow binding escape key
|
2014-09-13 18:39:32 +00:00
|
|
|
if(key==SDL_SCANCODE_ESCAPE)
|
2014-12-09 03:57:32 +00:00
|
|
|
{
|
|
|
|
//Stop binding if esc pressed
|
|
|
|
mInputBinder->cancelDetectingBindingState();
|
|
|
|
MWBase::Environment::get().getWindowManager ()->notifyInputActionBound ();
|
|
|
|
return;
|
|
|
|
}
|
2019-03-23 19:56:30 +00:00
|
|
|
|
|
|
|
// Disallow binding reserved keys
|
2020-01-10 10:29:04 +00:00
|
|
|
if (key == SDL_SCANCODE_F3 || key == SDL_SCANCODE_F4 || key == SDL_SCANCODE_F10)
|
2019-03-23 19:56:30 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
#ifndef __APPLE__
|
|
|
|
// Disallow binding Windows/Meta keys
|
|
|
|
if (key == SDL_SCANCODE_LGUI || key == SDL_SCANCODE_RGUI)
|
|
|
|
return;
|
|
|
|
#endif
|
|
|
|
|
2014-12-09 03:57:32 +00:00
|
|
|
if(!mDetectingKeyboard)
|
2013-06-15 11:22:29 +00:00
|
|
|
return;
|
2013-05-03 10:44:27 +00:00
|
|
|
|
2014-12-09 03:57:32 +00:00
|
|
|
clearAllKeyBindings(control);
|
2014-12-09 17:16:17 +00:00
|
|
|
control->setInitialValue(0.0f);
|
2012-08-12 23:26:15 +00:00
|
|
|
ICS::DetectingBindingListener::keyBindingDetected (ICS, control, key, direction);
|
|
|
|
MWBase::Environment::get().getWindowManager ()->notifyInputActionBound ();
|
|
|
|
}
|
|
|
|
|
2019-10-30 11:22:24 +00:00
|
|
|
void InputManager::mouseAxisBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
|
|
|
|
, ICS::InputControlSystem::NamedAxis axis, ICS::Control::ControlChangingDirection direction)
|
|
|
|
{
|
|
|
|
// we don't want mouse movement bindings
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2012-08-12 23:26:15 +00:00
|
|
|
void InputManager::mouseButtonBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
|
|
|
|
, unsigned int button, ICS::Control::ControlChangingDirection direction)
|
|
|
|
{
|
2014-12-09 03:57:32 +00:00
|
|
|
if(!mDetectingKeyboard)
|
|
|
|
return;
|
|
|
|
clearAllKeyBindings(control);
|
2014-12-09 17:16:17 +00:00
|
|
|
control->setInitialValue(0.0f);
|
2012-08-12 23:26:15 +00:00
|
|
|
ICS::DetectingBindingListener::mouseButtonBindingDetected (ICS, control, button, direction);
|
|
|
|
MWBase::Environment::get().getWindowManager ()->notifyInputActionBound ();
|
|
|
|
}
|
|
|
|
|
2019-10-30 11:22:24 +00:00
|
|
|
void InputManager::mouseWheelBindingDetected(ICS::InputControlSystem* ICS, ICS::Control* control
|
|
|
|
, ICS::InputControlSystem::MouseWheelClick click, ICS::Control::ControlChangingDirection direction)
|
|
|
|
{
|
|
|
|
if(!mDetectingKeyboard)
|
|
|
|
return;
|
|
|
|
clearAllKeyBindings(control);
|
|
|
|
control->setInitialValue(0.0f);
|
|
|
|
ICS::DetectingBindingListener::mouseWheelBindingDetected(ICS, control, click, direction);
|
|
|
|
MWBase::Environment::get().getWindowManager()->notifyInputActionBound();
|
|
|
|
}
|
|
|
|
|
2015-01-19 21:36:15 +00:00
|
|
|
void InputManager::joystickAxisBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control
|
2014-12-09 03:57:32 +00:00
|
|
|
, int axis, ICS::Control::ControlChangingDirection direction)
|
2012-08-12 23:26:15 +00:00
|
|
|
{
|
2014-12-09 03:57:32 +00:00
|
|
|
//only allow binding to the trigers
|
|
|
|
if(axis != SDL_CONTROLLER_AXIS_TRIGGERLEFT && axis != SDL_CONTROLLER_AXIS_TRIGGERRIGHT)
|
|
|
|
return;
|
|
|
|
if(mDetectingKeyboard)
|
|
|
|
return;
|
2012-08-12 23:26:15 +00:00
|
|
|
|
2014-12-09 03:57:32 +00:00
|
|
|
clearAllControllerBindings(control);
|
|
|
|
control->setValue(0.5f); //axis bindings must start at 0.5
|
2014-12-09 17:16:17 +00:00
|
|
|
control->setInitialValue(0.5f);
|
2015-01-19 21:36:15 +00:00
|
|
|
ICS::DetectingBindingListener::joystickAxisBindingDetected (ICS, deviceID, control, axis, direction);
|
2012-08-12 23:26:15 +00:00
|
|
|
MWBase::Environment::get().getWindowManager ()->notifyInputActionBound ();
|
|
|
|
}
|
|
|
|
|
2015-01-19 21:36:15 +00:00
|
|
|
void InputManager::joystickButtonBindingDetected(ICS::InputControlSystem* ICS, int deviceID, ICS::Control* control
|
2014-12-09 03:57:32 +00:00
|
|
|
, unsigned int button, ICS::Control::ControlChangingDirection direction)
|
2012-08-12 23:26:15 +00:00
|
|
|
{
|
2014-12-09 03:57:32 +00:00
|
|
|
if(mDetectingKeyboard)
|
|
|
|
return;
|
|
|
|
clearAllControllerBindings(control);
|
2014-12-09 17:16:17 +00:00
|
|
|
control->setInitialValue(0.0f);
|
2015-01-19 21:36:15 +00:00
|
|
|
ICS::DetectingBindingListener::joystickButtonBindingDetected (ICS, deviceID, control, button, direction);
|
2012-08-12 23:26:15 +00:00
|
|
|
MWBase::Environment::get().getWindowManager ()->notifyInputActionBound ();
|
|
|
|
}
|
|
|
|
|
2014-12-09 03:57:32 +00:00
|
|
|
void InputManager::clearAllKeyBindings (ICS::Control* control)
|
2012-08-12 23:26:15 +00:00
|
|
|
{
|
|
|
|
// right now we don't really need multiple bindings for the same action, so remove all others first
|
2014-09-13 18:39:32 +00:00
|
|
|
if (mInputBinder->getKeyBinding (control, ICS::Control::INCREASE) != SDL_SCANCODE_UNKNOWN)
|
2013-01-10 21:21:47 +00:00
|
|
|
mInputBinder->removeKeyBinding (mInputBinder->getKeyBinding (control, ICS::Control::INCREASE));
|
|
|
|
if (mInputBinder->getMouseButtonBinding (control, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS)
|
|
|
|
mInputBinder->removeMouseButtonBinding (mInputBinder->getMouseButtonBinding (control, ICS::Control::INCREASE));
|
2019-10-30 11:22:24 +00:00
|
|
|
if (mInputBinder->getMouseWheelBinding (control, ICS::Control::INCREASE) != ICS::InputControlSystem::MouseWheelClick::UNASSIGNED)
|
|
|
|
mInputBinder->removeMouseWheelBinding (mInputBinder->getMouseWheelBinding(control, ICS::Control::INCREASE));
|
2014-12-09 03:57:32 +00:00
|
|
|
}
|
2012-08-12 23:26:15 +00:00
|
|
|
|
2014-12-09 03:57:32 +00:00
|
|
|
void InputManager::clearAllControllerBindings (ICS::Control* control)
|
|
|
|
{
|
|
|
|
// right now we don't really need multiple bindings for the same action, so remove all others first
|
2015-01-19 21:36:15 +00:00
|
|
|
if (mInputBinder->getJoystickAxisBinding (control, mFakeDeviceID, ICS::Control::INCREASE) != SDL_SCANCODE_UNKNOWN)
|
|
|
|
mInputBinder->removeJoystickAxisBinding (mFakeDeviceID, mInputBinder->getJoystickAxisBinding (control, mFakeDeviceID, ICS::Control::INCREASE));
|
|
|
|
if (mInputBinder->getJoystickButtonBinding (control, mFakeDeviceID, ICS::Control::INCREASE) != ICS_MAX_DEVICE_BUTTONS)
|
|
|
|
mInputBinder->removeJoystickButtonBinding (mFakeDeviceID, mInputBinder->getJoystickButtonBinding (control, mFakeDeviceID, ICS::Control::INCREASE));
|
2012-08-12 23:26:15 +00:00
|
|
|
}
|
|
|
|
|
2016-10-20 00:12:01 +00:00
|
|
|
int InputManager::countSavedGameRecords() const
|
|
|
|
{
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
void InputManager::write(ESM::ESMWriter& writer, Loading::Listener& /*progress*/)
|
|
|
|
{
|
|
|
|
ESM::ControlsState controls;
|
|
|
|
controls.mViewSwitchDisabled = !getControlSwitch("playerviewswitch");
|
|
|
|
controls.mControlsDisabled = !getControlSwitch("playercontrols");
|
|
|
|
controls.mJumpingDisabled = !getControlSwitch("playerjumping");
|
|
|
|
controls.mLookingDisabled = !getControlSwitch("playerlooking");
|
|
|
|
controls.mVanityModeDisabled = !getControlSwitch("vanitymode");
|
|
|
|
controls.mWeaponDrawingDisabled = !getControlSwitch("playerfighting");
|
|
|
|
controls.mSpellDrawingDisabled = !getControlSwitch("playermagic");
|
|
|
|
|
|
|
|
writer.startRecord (ESM::REC_INPU);
|
|
|
|
controls.save(writer);
|
|
|
|
writer.endRecord (ESM::REC_INPU);
|
|
|
|
}
|
|
|
|
|
|
|
|
void InputManager::readRecord(ESM::ESMReader& reader, uint32_t type)
|
|
|
|
{
|
|
|
|
if (type == ESM::REC_INPU)
|
|
|
|
{
|
|
|
|
ESM::ControlsState controls;
|
|
|
|
controls.load(reader);
|
|
|
|
|
|
|
|
toggleControlSwitch("playerviewswitch", !controls.mViewSwitchDisabled);
|
|
|
|
toggleControlSwitch("playercontrols", !controls.mControlsDisabled);
|
|
|
|
toggleControlSwitch("playerjumping", !controls.mJumpingDisabled);
|
|
|
|
toggleControlSwitch("playerlooking", !controls.mLookingDisabled);
|
|
|
|
toggleControlSwitch("vanitymode", !controls.mVanityModeDisabled);
|
|
|
|
toggleControlSwitch("playerfighting", !controls.mWeaponDrawingDisabled);
|
|
|
|
toggleControlSwitch("playermagic", !controls.mSpellDrawingDisabled);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-09 03:57:32 +00:00
|
|
|
void InputManager::resetToDefaultKeyBindings()
|
2012-08-13 00:55:22 +00:00
|
|
|
{
|
|
|
|
loadKeyDefaults(true);
|
|
|
|
}
|
2013-01-09 02:14:30 +00:00
|
|
|
|
2014-12-09 03:57:32 +00:00
|
|
|
void InputManager::resetToDefaultControllerBindings()
|
|
|
|
{
|
|
|
|
loadControllerDefaults(true);
|
|
|
|
}
|
|
|
|
|
2020-04-08 06:55:35 +00:00
|
|
|
void InputManager::setPlayer (MWWorld::Player* player)
|
|
|
|
{
|
|
|
|
mPlayer = player;
|
|
|
|
}
|
2010-07-17 17:58:15 +00:00
|
|
|
}
|