1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-02-01 00:32:52 +00:00

Lua package 'openmw.input'

This commit is contained in:
Petr Mikheev 2021-06-26 23:10:24 +02:00
parent ee1ec53cd9
commit 0e6fbbc126
25 changed files with 509 additions and 66 deletions

View File

@ -57,7 +57,8 @@ add_openmw_dir (mwscript
add_openmw_dir (mwlua add_openmw_dir (mwlua
luamanagerimp actions object worldview userdataserializer eventqueue query luamanagerimp actions object worldview userdataserializer eventqueue query
luabindings localscripts objectbindings cellbindings asyncbindings camerabindings uibindings settingsbindings luabindings localscripts objectbindings cellbindings asyncbindings settingsbindings
camerabindings uibindings inputbindings
) )
add_openmw_dir (mwsound add_openmw_dir (mwsound

View File

@ -5,6 +5,7 @@
#include <set> #include <set>
#include <vector> #include <vector>
#include <SDL_gamecontroller.h>
#include <stdint.h> #include <stdint.h>
namespace Loading namespace Loading
@ -51,9 +52,17 @@ namespace MWBase
virtual void toggleControlSwitch (const std::string& sw, bool value) = 0; virtual void toggleControlSwitch (const std::string& sw, bool value) = 0;
virtual bool getControlSwitch (const std::string& sw) = 0; virtual bool getControlSwitch (const std::string& sw) = 0;
virtual std::string getActionDescription (int action) = 0; virtual std::string getActionDescription (int action) const = 0;
virtual std::string getActionKeyBindingName (int action) = 0; virtual std::string getActionKeyBindingName (int action) const = 0;
virtual std::string getActionControllerBindingName (int action) = 0; virtual std::string getActionControllerBindingName (int action) const = 0;
virtual bool actionIsActive(int action) const = 0;
virtual float getActionValue(int action) const = 0; // returns value in range [0, 1]
virtual float getControllerAxisValue(SDL_GameControllerAxis axis) const = 0; // returns value in range [-1, 1]
virtual uint32_t getMouseButtonsState() const = 0;
virtual int getMouseMoveX() const = 0;
virtual int getMouseMoveY() const = 0;
///Actions available for binding to keyboard buttons ///Actions available for binding to keyboard buttons
virtual std::vector<int> getActionKeySorting() = 0; virtual std::vector<int> getActionKeySorting() = 0;
///Actions available for binding to controller buttons ///Actions available for binding to controller buttons
@ -74,6 +83,7 @@ namespace MWBase
virtual void readRecord(ESM::ESMReader& reader, uint32_t type) = 0; virtual void readRecord(ESM::ESMReader& reader, uint32_t type) = 0;
virtual void resetIdleTime() = 0; virtual void resetIdleTime() = 0;
virtual bool isIdle() const = 0;
virtual void executeAction(int action) = 0; virtual void executeAction(int action) = 0;

View File

@ -1,6 +1,7 @@
#ifndef GAME_MWBASE_LUAMANAGER_H #ifndef GAME_MWBASE_LUAMANAGER_H
#define GAME_MWBASE_LUAMANAGER_H #define GAME_MWBASE_LUAMANAGER_H
#include <variant>
#include <SDL_events.h> #include <SDL_events.h>
namespace MWWorld namespace MWWorld
@ -29,8 +30,6 @@ namespace MWBase
virtual ~LuaManager() = default; virtual ~LuaManager() = default;
virtual void newGameStarted() = 0; virtual void newGameStarted() = 0;
virtual void keyPressed(const SDL_KeyboardEvent &arg) = 0;
virtual void registerObject(const MWWorld::Ptr& ptr) = 0; virtual void registerObject(const MWWorld::Ptr& ptr) = 0;
virtual void deregisterObject(const MWWorld::Ptr& ptr) = 0; virtual void deregisterObject(const MWWorld::Ptr& ptr) = 0;
virtual void objectAddedToScene(const MWWorld::Ptr& ptr) = 0; virtual void objectAddedToScene(const MWWorld::Ptr& ptr) = 0;
@ -40,6 +39,13 @@ namespace MWBase
// virtual void objectOnHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object, // virtual void objectOnHit(const MWWorld::Ptr &ptr, float damage, bool ishealth, const MWWorld::Ptr &object,
// const MWWorld::Ptr &attacker, const osg::Vec3f &hitPosition, bool successful) = 0; // const MWWorld::Ptr &attacker, const osg::Vec3f &hitPosition, bool successful) = 0;
struct InputEvent
{
enum {KeyPressed, KeyReleased, ControllerPressed, ControllerReleased, Action} mType;
std::variant<SDL_Keysym, int> mValue;
};
virtual void inputEvent(const InputEvent& event) = 0;
struct ActorControls struct ActorControls
{ {
bool mDisableAI = false; bool mDisableAI = false;

View File

@ -9,6 +9,7 @@
#include "../mwbase/inputmanager.hpp" #include "../mwbase/inputmanager.hpp"
#include "../mwbase/statemanager.hpp" #include "../mwbase/statemanager.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/luamanager.hpp"
#include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
@ -195,6 +196,7 @@ namespace MWInput
void ActionManager::executeAction(int action) void ActionManager::executeAction(int action)
{ {
MWBase::Environment::get().getLuaManager()->inputEvent({MWBase::LuaManager::InputEvent::Action, action});
auto* inputManager = MWBase::Environment::get().getInputManager(); auto* inputManager = MWBase::Environment::get().getInputManager();
auto* windowManager = MWBase::Environment::get().getWindowManager(); auto* windowManager = MWBase::Environment::get().getWindowManager();
// trigger action activated // trigger action activated

View File

@ -48,6 +48,7 @@ namespace MWInput
void showQuickKeysMenu(); void showQuickKeysMenu();
void resetIdleTime(); void resetIdleTime();
float getIdleTime() const { return mTimeIdle; }
bool isAlwaysRunActive() const { return mAlwaysRunActive; }; bool isAlwaysRunActive() const { return mAlwaysRunActive; };
bool isSneaking() const { return mSneaking; }; bool isSneaking() const { return mSneaking; };

View File

@ -653,6 +653,16 @@ namespace MWInput
return mInputBinder->getKeyBinding(mInputBinder->getControl(actionId), ICS::Control::INCREASE); return mInputBinder->getKeyBinding(mInputBinder->getControl(actionId), ICS::Control::INCREASE);
} }
float BindingsManager::getControllerAxisValue(SDL_GameControllerAxis axis) const
{
const auto& controllers = mInputBinder->getJoystickInstanceMap();
if (controllers.empty())
return 0;
SDL_GameController* cntrl = controllers.begin()->second;
constexpr int AXIS_MAX_ABSOLUTE_VALUE = 32768;
return SDL_GameControllerGetAxis(cntrl, axis) / static_cast<float>(AXIS_MAX_ABSOLUTE_VALUE);
}
void BindingsManager::actionValueChanged(int action, float currentValue, float previousValue) void BindingsManager::actionValueChanged(int action, float currentValue, float previousValue)
{ {
MWBase::Environment::get().getInputManager()->resetIdleTime(); MWBase::Environment::get().getInputManager()->resetIdleTime();

View File

@ -42,7 +42,8 @@ namespace MWInput
bool isLeftOrRightButton(int action, bool joystick) const; bool isLeftOrRightButton(int action, bool joystick) const;
bool actionIsActive(int id) const; bool actionIsActive(int id) const;
float getActionValue(int id) const; float getActionValue(int id) const; // returns value in range [0, 1]
float getControllerAxisValue(SDL_GameControllerAxis axis) const; // returns value in range [-1, 1]
void mousePressed(const SDL_MouseButtonEvent &evt, int deviceID); void mousePressed(const SDL_MouseButtonEvent &evt, int deviceID);
void mouseReleased(const SDL_MouseButtonEvent &arg, int deviceID); void mouseReleased(const SDL_MouseButtonEvent &arg, int deviceID);

View File

@ -8,6 +8,7 @@
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/inputmanager.hpp" #include "../mwbase/inputmanager.hpp"
#include "../mwbase/luamanager.hpp"
#include "../mwbase/statemanager.hpp" #include "../mwbase/statemanager.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
@ -198,6 +199,9 @@ namespace MWInput
if (!mJoystickEnabled || mBindingsManager->isDetectingBindingState()) if (!mJoystickEnabled || mBindingsManager->isDetectingBindingState())
return; return;
MWBase::Environment::get().getLuaManager()->inputEvent(
{MWBase::LuaManager::InputEvent::ControllerPressed, arg.button});
mJoystickLastUsed = true; mJoystickLastUsed = true;
if (MWBase::Environment::get().getWindowManager()->isGuiMode()) if (MWBase::Environment::get().getWindowManager()->isGuiMode())
{ {
@ -240,6 +244,12 @@ namespace MWInput
return; return;
} }
if (mJoystickEnabled)
{
MWBase::Environment::get().getLuaManager()->inputEvent(
{MWBase::LuaManager::InputEvent::ControllerReleased, arg.button});
}
if (!mJoystickEnabled || MWBase::Environment::get().getInputManager()->controlsDisabled()) if (!mJoystickEnabled || MWBase::Environment::get().getInputManager()->controlsDisabled())
return; return;

View File

@ -150,21 +150,56 @@ namespace MWInput
mActionManager->resetIdleTime(); mActionManager->resetIdleTime();
} }
std::string InputManager::getActionDescription(int action) bool InputManager::isIdle() const
{
return mActionManager->getIdleTime() > 0.5;
}
std::string InputManager::getActionDescription(int action) const
{ {
return mBindingsManager->getActionDescription(action); return mBindingsManager->getActionDescription(action);
} }
std::string InputManager::getActionKeyBindingName(int action) std::string InputManager::getActionKeyBindingName(int action) const
{ {
return mBindingsManager->getActionKeyBindingName(action); return mBindingsManager->getActionKeyBindingName(action);
} }
std::string InputManager::getActionControllerBindingName(int action) std::string InputManager::getActionControllerBindingName(int action) const
{ {
return mBindingsManager->getActionControllerBindingName(action); return mBindingsManager->getActionControllerBindingName(action);
} }
bool InputManager::actionIsActive(int action) const
{
return mBindingsManager->actionIsActive(action);
}
float InputManager::getActionValue(int action) const
{
return mBindingsManager->getActionValue(action);
}
float InputManager::getControllerAxisValue(SDL_GameControllerAxis axis) const
{
return mBindingsManager->getControllerAxisValue(axis);
}
uint32_t InputManager::getMouseButtonsState() const
{
return mMouseManager->getButtonsState();
}
int InputManager::getMouseMoveX() const
{
return mMouseManager->getMouseMoveX();
}
int InputManager::getMouseMoveY() const
{
return mMouseManager->getMouseMoveY();
}
std::vector<int> InputManager::getActionKeySorting() std::vector<int> InputManager::getActionKeySorting()
{ {
return mBindingsManager->getActionKeySorting(); return mBindingsManager->getActionKeySorting();

View File

@ -73,9 +73,17 @@ namespace MWInput
void toggleControlSwitch (const std::string& sw, bool value) override; void toggleControlSwitch (const std::string& sw, bool value) override;
bool getControlSwitch (const std::string& sw) override; bool getControlSwitch (const std::string& sw) override;
std::string getActionDescription (int action) override; std::string getActionDescription (int action) const override;
std::string getActionKeyBindingName (int action) override; std::string getActionKeyBindingName (int action) const override;
std::string getActionControllerBindingName (int action) override; std::string getActionControllerBindingName (int action) const override;
bool actionIsActive(int action) const override;
float getActionValue(int action) const override;
float getControllerAxisValue(SDL_GameControllerAxis axis) const override;
uint32_t getMouseButtonsState() const override;
int getMouseMoveX() const override;
int getMouseMoveY() const override;
int getNumActions() override { return A_Last; } int getNumActions() override { return A_Last; }
std::vector<int> getActionKeySorting() override; std::vector<int> getActionKeySorting() override;
std::vector<int> getActionControllerSorting() override; std::vector<int> getActionControllerSorting() override;
@ -91,6 +99,7 @@ namespace MWInput
void readRecord(ESM::ESMReader& reader, uint32_t type) override; void readRecord(ESM::ESMReader& reader, uint32_t type) override;
void resetIdleTime() override; void resetIdleTime() override;
bool isIdle() const override;
void executeAction(int action) override; void executeAction(int action) override;

View File

@ -60,7 +60,10 @@ namespace MWInput
mBindingsManager->keyPressed(arg); mBindingsManager->keyPressed(arg);
if (!consumed) if (!consumed)
MWBase::Environment::get().getLuaManager()->keyPressed(arg); {
MWBase::Environment::get().getLuaManager()->inputEvent(
{MWBase::LuaManager::InputEvent::KeyPressed, arg.keysym});
}
input->setJoystickLastUsed(false); input->setJoystickLastUsed(false);
} }
@ -73,5 +76,6 @@ namespace MWInput
if (!mBindingsManager->isDetectingBindingState()) if (!mBindingsManager->isDetectingBindingState())
mBindingsManager->setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyRelease(kc)); mBindingsManager->setPlayerControlsEnabled(!MyGUI::InputManager::getInstance().injectKeyRelease(kc));
mBindingsManager->keyReleased(arg); mBindingsManager->keyReleased(arg);
MWBase::Environment::get().getLuaManager()->inputEvent({MWBase::LuaManager::InputEvent::KeyReleased, arg.keysym});
} }
} }

View File

@ -34,6 +34,9 @@ namespace MWInput
, mMouseWheel(0) , mMouseWheel(0)
, mMouseLookEnabled(false) , mMouseLookEnabled(false)
, mGuiCursorEnabled(true) , mGuiCursorEnabled(true)
, mButtonsState(0)
, mMouseMoveX(0)
, mMouseMoveY(0)
{ {
int w,h; int w,h;
SDL_GetWindowSize(window, &w, &h); SDL_GetWindowSize(window, &w, &h);
@ -196,6 +199,8 @@ namespace MWInput
void MouseManager::update(float dt) void MouseManager::update(float dt)
{ {
mButtonsState = SDL_GetRelativeMouseState(&mMouseMoveX, &mMouseMoveY);
if (!mMouseLookEnabled) if (!mMouseLookEnabled)
return; return;

View File

@ -38,6 +38,10 @@ namespace MWInput
void setMouseLookEnabled(bool enabled) { mMouseLookEnabled = enabled; } void setMouseLookEnabled(bool enabled) { mMouseLookEnabled = enabled; }
void setGuiCursorEnabled(bool enabled) { mGuiCursorEnabled = enabled; } void setGuiCursorEnabled(bool enabled) { mGuiCursorEnabled = enabled; }
uint32_t getButtonsState() const { return mButtonsState; }
int getMouseMoveX() const { return mMouseMoveX; }
int getMouseMoveY() const { return mMouseMoveY; }
private: private:
bool mInvertX; bool mInvertX;
bool mInvertY; bool mInvertY;
@ -53,6 +57,10 @@ namespace MWInput
int mMouseWheel; int mMouseWheel;
bool mMouseLookEnabled; bool mMouseLookEnabled;
bool mGuiCursorEnabled; bool mGuiCursorEnabled;
uint32_t mButtonsState;
int mMouseMoveX;
int mMouseMoveY;
}; };
} }
#endif #endif

View File

@ -0,0 +1,150 @@
#include "luabindings.hpp"
#include <SDL_events.h>
#include <SDL_gamecontroller.h>
#include "../mwbase/inputmanager.hpp"
#include "../mwinput/actions.hpp"
namespace sol
{
template <>
struct is_automagical<SDL_Keysym> : std::false_type {};
}
namespace MWLua
{
sol::table initInputPackage(const Context& context)
{
sol::usertype<SDL_Keysym> keyEvent = context.mLua->sol().new_usertype<SDL_Keysym>("KeyEvent");
keyEvent["symbol"] = sol::readonly_property([](const SDL_Keysym& e) { return std::string(1, static_cast<char>(e.sym)); });
keyEvent["code"] = sol::readonly_property([](const SDL_Keysym& e) -> int { return e.sym; });
keyEvent["modifiers"] = sol::readonly_property([](const SDL_Keysym& e) -> int { return e.mod; });
keyEvent["withShift"] = sol::readonly_property([](const SDL_Keysym& e) -> bool { return e.mod & KMOD_SHIFT; });
keyEvent["withCtrl"] = sol::readonly_property([](const SDL_Keysym& e) -> bool { return e.mod & KMOD_CTRL; });
keyEvent["withAlt"] = sol::readonly_property([](const SDL_Keysym& e) -> bool { return e.mod & KMOD_ALT; });
keyEvent["withSuper"] = sol::readonly_property([](const SDL_Keysym& e) -> bool { return e.mod & KMOD_GUI; });
MWBase::InputManager* input = MWBase::Environment::get().getInputManager();
sol::table api(context.mLua->sol(), sol::create);
api["isIdle"] = [input]() { return input->isIdle(); };
api["isActionPressed"] = [input](int action) { return input->actionIsActive(action); };
api["isMouseButtonPressed"] = [input](int button) -> bool
{
return input->getMouseButtonsState() & (1 << (button - 1));
};
api["getMouseMoveX"] = [input]() { return input->getMouseMoveX(); };
api["getMouseMoveY"] = [input]() { return input->getMouseMoveY(); };
api["getAxisValue"] = [input](int axis)
{
if (axis < SDL_CONTROLLER_AXIS_MAX)
return input->getControllerAxisValue(static_cast<SDL_GameControllerAxis>(axis));
else
return input->getActionValue(axis - SDL_CONTROLLER_AXIS_MAX) * 2 - 1;
};
api["getControlSwitch"] = [input](const std::string& key) { return input->getControlSwitch(key); };
api["setControlSwitch"] = [input](const std::string& key, bool v) { input->toggleControlSwitch(key, v); };
api["ACTION"] = context.mLua->makeReadOnly(context.mLua->sol().create_table_with(
"GameMenu", MWInput::A_GameMenu,
"Screenshot", MWInput::A_Screenshot,
"Inventory", MWInput::A_Inventory,
"Console", MWInput::A_Console,
"MoveLeft", MWInput::A_MoveLeft,
"MoveRight", MWInput::A_MoveRight,
"MoveForward", MWInput::A_MoveForward,
"MoveBackward", MWInput::A_MoveBackward,
"Activate", MWInput::A_Activate,
"Use", MWInput::A_Use,
"Jump", MWInput::A_Jump,
"AutoMove", MWInput::A_AutoMove,
"Rest", MWInput::A_Rest,
"Journal", MWInput::A_Journal,
"Weapon", MWInput::A_Weapon,
"Spell", MWInput::A_Spell,
"Run", MWInput::A_Run,
"CycleSpellLeft", MWInput::A_CycleSpellLeft,
"CycleSpellRight", MWInput::A_CycleSpellRight,
"CycleWeaponLeft", MWInput::A_CycleWeaponLeft,
"CycleWeaponRight", MWInput::A_CycleWeaponRight,
"ToggleSneak", MWInput::A_ToggleSneak,
"AlwaysRun", MWInput::A_AlwaysRun,
"Sneak", MWInput::A_Sneak,
"QuickSave", MWInput::A_QuickSave,
"QuickLoad", MWInput::A_QuickLoad,
"QuickMenu", MWInput::A_QuickMenu,
"ToggleWeapon", MWInput::A_ToggleWeapon,
"ToggleSpell", MWInput::A_ToggleSpell,
"TogglePOV", MWInput::A_TogglePOV,
"QuickKey1", MWInput::A_QuickKey1,
"QuickKey2", MWInput::A_QuickKey2,
"QuickKey3", MWInput::A_QuickKey3,
"QuickKey4", MWInput::A_QuickKey4,
"QuickKey5", MWInput::A_QuickKey5,
"QuickKey6", MWInput::A_QuickKey6,
"QuickKey7", MWInput::A_QuickKey7,
"QuickKey8", MWInput::A_QuickKey8,
"QuickKey9", MWInput::A_QuickKey9,
"QuickKey10", MWInput::A_QuickKey10,
"QuickKeysMenu", MWInput::A_QuickKeysMenu,
"ToggleHUD", MWInput::A_ToggleHUD,
"ToggleDebug", MWInput::A_ToggleDebug,
"ZoomIn", MWInput::A_ZoomIn,
"ZoomOut", MWInput::A_ZoomOut
));
api["CONTROL_SWITCH"] = context.mLua->makeReadOnly(context.mLua->sol().create_table_with(
"Controls", "playercontrols",
"Fighting", "playerfighting",
"Jumping", "playerjumping",
"Looking", "playerlooking",
"Magic", "playermagic",
"ViewMode", "playerviewswitch",
"VanityMode", "vanitymode"
));
api["CONTROLLER_BUTTON"] = context.mLua->makeReadOnly(context.mLua->sol().create_table_with(
"A", SDL_CONTROLLER_BUTTON_A,
"B", SDL_CONTROLLER_BUTTON_B,
"X", SDL_CONTROLLER_BUTTON_X,
"Y", SDL_CONTROLLER_BUTTON_Y,
"Back", SDL_CONTROLLER_BUTTON_BACK,
"Guide", SDL_CONTROLLER_BUTTON_GUIDE,
"Start", SDL_CONTROLLER_BUTTON_START,
"LeftStick", SDL_CONTROLLER_BUTTON_LEFTSTICK,
"RightStick", SDL_CONTROLLER_BUTTON_RIGHTSTICK,
"LeftShoulder", SDL_CONTROLLER_BUTTON_LEFTSHOULDER,
"RightShoulder", SDL_CONTROLLER_BUTTON_RIGHTSHOULDER,
"DPadUp", SDL_CONTROLLER_BUTTON_DPAD_UP,
"DPadDown", SDL_CONTROLLER_BUTTON_DPAD_DOWN,
"DPadLeft", SDL_CONTROLLER_BUTTON_DPAD_LEFT,
"DPadRight", SDL_CONTROLLER_BUTTON_DPAD_RIGHT
));
api["CONTROLLER_AXIS"] = context.mLua->makeReadOnly(context.mLua->sol().create_table_with(
"LeftX", SDL_CONTROLLER_AXIS_LEFTX,
"LeftY", SDL_CONTROLLER_AXIS_LEFTY,
"RightX", SDL_CONTROLLER_AXIS_RIGHTX,
"RightY", SDL_CONTROLLER_AXIS_RIGHTY,
"TriggerLeft", SDL_CONTROLLER_AXIS_TRIGGERLEFT,
"TriggerRight", SDL_CONTROLLER_AXIS_TRIGGERRIGHT,
"LookUpDown", SDL_CONTROLLER_AXIS_MAX + MWInput::A_LookUpDown,
"LookLeftRight", SDL_CONTROLLER_AXIS_MAX + MWInput::A_LookLeftRight,
"MoveForwardBackward", SDL_CONTROLLER_AXIS_MAX + MWInput::A_MoveForwardBackward,
"MoveLeftRight", SDL_CONTROLLER_AXIS_MAX + MWInput::A_MoveLeftRight
));
return context.mLua->makeReadOnly(api);
}
}

View File

@ -1,7 +1,5 @@
#include "luabindings.hpp" #include "luabindings.hpp"
#include <SDL_events.h>
#include <components/lua/luastate.hpp> #include <components/lua/luastate.hpp>
#include <components/queries/luabindings.hpp> #include <components/queries/luabindings.hpp>
@ -12,12 +10,6 @@
#include "eventqueue.hpp" #include "eventqueue.hpp"
#include "worldview.hpp" #include "worldview.hpp"
namespace sol
{
template <>
struct is_automagical<SDL_Keysym> : std::false_type {};
}
namespace MWLua namespace MWLua
{ {
@ -33,7 +25,7 @@ namespace MWLua
{ {
auto* lua = context.mLua; auto* lua = context.mLua;
sol::table api(lua->sol(), sol::create); sol::table api(lua->sol(), sol::create);
api["API_REVISION"] = 3; api["API_REVISION"] = 4;
api["quit"] = [lua]() api["quit"] = [lua]()
{ {
std::string traceback = lua->sol()["debug"]["traceback"]().get<std::string>(); std::string traceback = lua->sol()["debug"]["traceback"]().get<std::string>();
@ -179,17 +171,5 @@ namespace MWLua
return context.mLua->makeReadOnly(res); return context.mLua->makeReadOnly(res);
} }
void initInputBindings(const Context& context)
{
sol::usertype<SDL_Keysym> keyEvent = context.mLua->sol().new_usertype<SDL_Keysym>("KeyEvent");
keyEvent["symbol"] = sol::readonly_property([](const SDL_Keysym& e) { return std::string(1, static_cast<char>(e.sym)); });
keyEvent["code"] = sol::readonly_property([](const SDL_Keysym& e) -> int { return e.sym; });
keyEvent["modifiers"] = sol::readonly_property([](const SDL_Keysym& e) -> int { return e.mod; });
keyEvent["withShift"] = sol::readonly_property([](const SDL_Keysym& e) -> bool { return e.mod & KMOD_SHIFT; });
keyEvent["withCtrl"] = sol::readonly_property([](const SDL_Keysym& e) -> bool { return e.mod & KMOD_CTRL; });
keyEvent["withAlt"] = sol::readonly_property([](const SDL_Keysym& e) -> bool { return e.mod & KMOD_ALT; });
keyEvent["withSuper"] = sol::readonly_property([](const SDL_Keysym& e) -> bool { return e.mod & KMOD_GUI; });
}
} }

View File

@ -26,8 +26,6 @@ namespace MWLua
sol::table initFieldGroup(const Context&, const QueryFieldGroup&); sol::table initFieldGroup(const Context&, const QueryFieldGroup&);
void initInputBindings(const Context&);
// Implemented in objectbindings.cpp // Implemented in objectbindings.cpp
void initObjectBindingsForLocalScripts(const Context&); void initObjectBindingsForLocalScripts(const Context&);
void initObjectBindingsForGlobalScripts(const Context&); void initObjectBindingsForGlobalScripts(const Context&);
@ -59,6 +57,9 @@ namespace MWLua
// Implemented in uibindings.cpp // Implemented in uibindings.cpp
sol::table initUserInterfacePackage(const Context&); sol::table initUserInterfacePackage(const Context&);
// Implemented in inputbindings.cpp
sol::table initInputPackage(const Context&);
// Implemented in settingsbindings.cpp // Implemented in settingsbindings.cpp
sol::table initGlobalSettingsPackage(const Context&); sol::table initGlobalSettingsPackage(const Context&);
sol::table initLocalSettingsPackage(const Context&); sol::table initLocalSettingsPackage(const Context&);

View File

@ -53,7 +53,6 @@ namespace MWLua
initObjectBindingsForLocalScripts(localContext); initObjectBindingsForLocalScripts(localContext);
initCellBindingsForLocalScripts(localContext); initCellBindingsForLocalScripts(localContext);
LocalScripts::initializeSelfPackage(localContext); LocalScripts::initializeSelfPackage(localContext);
initInputBindings(localContext);
mLua.addCommonPackage("openmw.async", getAsyncPackageInitializer(context)); mLua.addCommonPackage("openmw.async", getAsyncPackageInitializer(context));
mLua.addCommonPackage("openmw.util", LuaUtil::initUtilPackage(mLua.sol())); mLua.addCommonPackage("openmw.util", LuaUtil::initUtilPackage(mLua.sol()));
@ -63,11 +62,12 @@ namespace MWLua
mGlobalScripts.addPackage("openmw.settings", initGlobalSettingsPackage(context)); mGlobalScripts.addPackage("openmw.settings", initGlobalSettingsPackage(context));
mCameraPackage = initCameraPackage(localContext); mCameraPackage = initCameraPackage(localContext);
mUserInterfacePackage = initUserInterfacePackage(localContext); mUserInterfacePackage = initUserInterfacePackage(localContext);
mInputPackage = initInputPackage(localContext);
mNearbyPackage = initNearbyPackage(localContext); mNearbyPackage = initNearbyPackage(localContext);
mLocalSettingsPackage = initLocalSettingsPackage(localContext); mLocalSettingsPackage = initLocalSettingsPackage(localContext);
mPlayerSettingsPackage = initPlayerSettingsPackage(localContext); mPlayerSettingsPackage = initPlayerSettingsPackage(localContext);
mKeyPressEvents.clear(); mInputEvents.clear();
for (const std::string& path : mGlobalScriptList) for (const std::string& path : mGlobalScriptList)
if (mGlobalScripts.addNewScript(path)) if (mGlobalScripts.addNewScript(path))
Log(Debug::Info) << "Global script started: " << path; Log(Debug::Info) << "Global script started: " << path;
@ -93,7 +93,7 @@ namespace MWLua
if (paused) if (paused)
{ {
mKeyPressEvents.clear(); mInputEvents.clear();
return; return;
} }
@ -130,10 +130,10 @@ namespace MWLua
PlayerScripts* playerScripts = dynamic_cast<PlayerScripts*>(mPlayer.getRefData().getLuaScripts()); PlayerScripts* playerScripts = dynamic_cast<PlayerScripts*>(mPlayer.getRefData().getLuaScripts());
if (playerScripts) if (playerScripts)
{ {
for (const SDL_Keysym& key : mKeyPressEvents) for (const auto& event : mInputEvents)
playerScripts->keyPress(key); playerScripts->processInputEvent(event);
} }
mKeyPressEvents.clear(); mInputEvents.clear();
for (const LocalEngineEvent& e : mLocalEngineEvents) for (const LocalEngineEvent& e : mLocalEngineEvents)
{ {
@ -187,7 +187,7 @@ namespace MWLua
mActiveLocalScripts.clear(); mActiveLocalScripts.clear();
mLocalEvents.clear(); mLocalEvents.clear();
mGlobalEvents.clear(); mGlobalEvents.clear();
mKeyPressEvents.clear(); mInputEvents.clear();
mActorAddedEvents.clear(); mActorAddedEvents.clear();
mLocalEngineEvents.clear(); mLocalEngineEvents.clear();
mPlayerChanged = false; mPlayerChanged = false;
@ -253,11 +253,6 @@ namespace MWLua
mWorldView.getObjectRegistry()->deregisterPtr(ptr); mWorldView.getObjectRegistry()->deregisterPtr(ptr);
} }
void LuaManager::keyPressed(const SDL_KeyboardEvent& arg)
{
mKeyPressEvents.push_back(arg.keysym);
}
void LuaManager::appliedToObject(const MWWorld::Ptr& toPtr, std::string_view recordId, const MWWorld::Ptr& fromPtr) void LuaManager::appliedToObject(const MWWorld::Ptr& toPtr, std::string_view recordId, const MWWorld::Ptr& fromPtr)
{ {
mLocalEngineEvents.push_back({getId(toPtr), LocalScripts::OnConsume{std::string(recordId)}}); mLocalEngineEvents.push_back({getId(toPtr), LocalScripts::OnConsume{std::string(recordId)}});
@ -294,6 +289,7 @@ namespace MWLua
scripts = std::make_shared<PlayerScripts>(&mLua, LObject(getId(ptr), mWorldView.getObjectRegistry())); scripts = std::make_shared<PlayerScripts>(&mLua, LObject(getId(ptr), mWorldView.getObjectRegistry()));
scripts->addPackage("openmw.ui", mUserInterfacePackage); scripts->addPackage("openmw.ui", mUserInterfacePackage);
scripts->addPackage("openmw.camera", mCameraPackage); scripts->addPackage("openmw.camera", mCameraPackage);
scripts->addPackage("openmw.input", mInputPackage);
scripts->addPackage("openmw.settings", mPlayerSettingsPackage); scripts->addPackage("openmw.settings", mPlayerSettingsPackage);
} }
else else

View File

@ -41,7 +41,7 @@ namespace MWLua
void objectRemovedFromScene(const MWWorld::Ptr& ptr) override; void objectRemovedFromScene(const MWWorld::Ptr& ptr) override;
void registerObject(const MWWorld::Ptr& ptr) override; void registerObject(const MWWorld::Ptr& ptr) override;
void deregisterObject(const MWWorld::Ptr& ptr) override; void deregisterObject(const MWWorld::Ptr& ptr) override;
void keyPressed(const SDL_KeyboardEvent &arg) override; void inputEvent(const InputEvent& event) override { mInputEvents.push_back(event); }
void appliedToObject(const MWWorld::Ptr& toPtr, std::string_view recordId, const MWWorld::Ptr& fromPtr) override; void appliedToObject(const MWWorld::Ptr& toPtr, std::string_view recordId, const MWWorld::Ptr& fromPtr) override;
MWBase::LuaManager::ActorControls* getActorControls(const MWWorld::Ptr&) const override; MWBase::LuaManager::ActorControls* getActorControls(const MWWorld::Ptr&) const override;
@ -75,6 +75,7 @@ namespace MWLua
sol::table mNearbyPackage; sol::table mNearbyPackage;
sol::table mUserInterfacePackage; sol::table mUserInterfacePackage;
sol::table mCameraPackage; sol::table mCameraPackage;
sol::table mInputPackage;
sol::table mLocalSettingsPackage; sol::table mLocalSettingsPackage;
sol::table mPlayerSettingsPackage; sol::table mPlayerSettingsPackage;
@ -96,7 +97,7 @@ namespace MWLua
std::unique_ptr<LuaUtil::UserdataSerializer> mGlobalLoader; std::unique_ptr<LuaUtil::UserdataSerializer> mGlobalLoader;
std::unique_ptr<LuaUtil::UserdataSerializer> mLocalLoader; std::unique_ptr<LuaUtil::UserdataSerializer> mLocalLoader;
std::vector<SDL_Keysym> mKeyPressEvents; std::vector<MWBase::LuaManager::InputEvent> mInputEvents;
std::vector<ObjectId> mActorAddedEvents; std::vector<ObjectId> mActorAddedEvents;
struct LocalEngineEvent struct LocalEngineEvent

View File

@ -3,6 +3,8 @@
#include <SDL_events.h> #include <SDL_events.h>
#include "../mwbase/luamanager.hpp"
#include "localscripts.hpp" #include "localscripts.hpp"
namespace MWLua namespace MWLua
@ -13,13 +15,40 @@ namespace MWLua
public: public:
PlayerScripts(LuaUtil::LuaState* lua, const LObject& obj) : LocalScripts(lua, obj) PlayerScripts(LuaUtil::LuaState* lua, const LObject& obj) : LocalScripts(lua, obj)
{ {
registerEngineHandlers({&mKeyPressHandlers}); registerEngineHandlers({&mKeyPressHandlers, &mKeyReleaseHandlers,
&mControllerButtonPressHandlers, &mControllerButtonReleaseHandlers,
&mActionHandlers});
} }
void keyPress(const SDL_Keysym& key) { callEngineHandlers(mKeyPressHandlers, key); } void processInputEvent(const MWBase::LuaManager::InputEvent& event)
{
using InputEvent = MWBase::LuaManager::InputEvent;
switch (event.mType)
{
case InputEvent::KeyPressed:
callEngineHandlers(mKeyPressHandlers, std::get<SDL_Keysym>(event.mValue));
break;
case InputEvent::KeyReleased:
callEngineHandlers(mKeyReleaseHandlers, std::get<SDL_Keysym>(event.mValue));
break;
case InputEvent::ControllerPressed:
callEngineHandlers(mControllerButtonPressHandlers, std::get<int>(event.mValue));
break;
case InputEvent::ControllerReleased:
callEngineHandlers(mControllerButtonReleaseHandlers, std::get<int>(event.mValue));
break;
case InputEvent::Action:
callEngineHandlers(mActionHandlers, std::get<int>(event.mValue));
break;
}
}
private: private:
EngineHandlerList mKeyPressHandlers{"onKeyPress"}; EngineHandlerList mKeyPressHandlers{"onKeyPress"};
EngineHandlerList mKeyReleaseHandlers{"onKeyRelease"};
EngineHandlerList mControllerButtonPressHandlers{"onControllerButtonPress"};
EngineHandlerList mControllerButtonReleaseHandlers{"onControllerButtonRelease"};
EngineHandlerList mActionHandlers{"onInputAction"};
}; };
} }

View File

@ -14,6 +14,7 @@ Lua API reference
openmw_world openmw_world
openmw_self openmw_self
openmw_nearby openmw_nearby
openmw_input
openmw_ui openmw_ui
openmw_aux_util openmw_aux_util
@ -53,6 +54,8 @@ Player scripts are local scripts that are attached to a player.
+---------------------------------------------------------+--------------------+---------------------------------------------------------------+ +---------------------------------------------------------+--------------------+---------------------------------------------------------------+
|:ref:`openmw.nearby <Package openmw.nearby>` | by local scripts | | Read-only access to the nearest area of the game world. | |:ref:`openmw.nearby <Package openmw.nearby>` | by local scripts | | Read-only access to the nearest area of the game world. |
+---------------------------------------------------------+--------------------+---------------------------------------------------------------+ +---------------------------------------------------------+--------------------+---------------------------------------------------------------+
|:ref:`openmw.input <Package openmw.input>` | by player scripts | | User input |
+---------------------------------------------------------+--------------------+---------------------------------------------------------------+
|:ref:`openmw.ui <Package openmw.ui>` | by player scripts | | Controls user interface | |:ref:`openmw.ui <Package openmw.ui>` | by player scripts | | Controls user interface |
+---------------------------------------------------------+--------------------+---------------------------------------------------------------+ +---------------------------------------------------------+--------------------+---------------------------------------------------------------+
|openmw.camera | by player scripts | | Controls camera (not implemented) | |openmw.camera | by player scripts | | Controls camera (not implemented) |

View File

@ -36,8 +36,21 @@ Engine handler is a function defined by a script, that can be called by the engi
+----------------------------------+----------------------------------------------------------------------+ +----------------------------------+----------------------------------------------------------------------+
| **Only for local scripts attached to a player** | | **Only for local scripts attached to a player** |
+----------------------------------+----------------------------------------------------------------------+ +----------------------------------+----------------------------------------------------------------------+
| onKeyPress(key) | | `Key <openmw_core.html##(KeyboardEvent)>`_ pressed. Usage example: | | onKeyPress(key) | | `Key <openmw_input.html##(KeyboardEvent)>`_ is pressed. |
| | | ``if key.symbol == 'z' and key.withShift then ...`` | | | | Usage example: ``if key.symbol == 'z' and key.withShift then ...`` |
+----------------------------------+----------------------------------------------------------------------+
| onKeyRelease(key) | | `Key <openmw_input.html##(KeyboardEvent)>`_ is released. |
| | | Usage example: ``if key.symbol == 'z' and key.withShift then ...`` |
+----------------------------------+----------------------------------------------------------------------+
| onControllerButtonPress(id) | | A `button <openmw_input.html##(CONTROLLER_BUTTON)>`_ on a game |
| | controller is pressed. Usage example: |
| | | ``if id == input.CONTROLLER_BUTTON.LeftStick then ...`` |
+----------------------------------+----------------------------------------------------------------------+
| onControllerButtonRelease(id) | | A `button <openmw_input.html##(CONTROLLER_BUTTON)>`_ on a game |
| | controller is released. Usage example: |
| | | ``if id == input.CONTROLLER_BUTTON.LeftStick then ...`` |
+----------------------------------+----------------------------------------------------------------------+
| onInputAction(id) | | `Game control <openmw_input.html##(ACTION)>`_ is pressed. |
| | | Usage example: ``if id == input.ACTION.ToggleWeapon then ...`` |
+----------------------------------+----------------------------------------------------------------------+ +----------------------------------+----------------------------------------------------------------------+

View File

@ -0,0 +1,6 @@
Package openmw.input
====================
.. raw:: html
:file: generated_html/openmw_input.html

View File

@ -314,6 +314,8 @@ Player scripts are local scripts that are attached to a player.
+---------------------------------------------------------+--------------------+---------------------------------------------------------------+ +---------------------------------------------------------+--------------------+---------------------------------------------------------------+
|:ref:`openmw.nearby <Package openmw.nearby>` | by local scripts | | Read-only access to the nearest area of the game world. | |:ref:`openmw.nearby <Package openmw.nearby>` | by local scripts | | Read-only access to the nearest area of the game world. |
+---------------------------------------------------------+--------------------+---------------------------------------------------------------+ +---------------------------------------------------------+--------------------+---------------------------------------------------------------+
|:ref:`openmw.input <Package openmw.input>` | by player scripts | | User input |
+---------------------------------------------------------+--------------------+---------------------------------------------------------------+
|:ref:`openmw.ui <Package openmw.ui>` | by player scripts | | Controls user interface | |:ref:`openmw.ui <Package openmw.ui>` | by player scripts | | Controls user interface |
+---------------------------------------------------------+--------------------+---------------------------------------------------------------+ +---------------------------------------------------------+--------------------+---------------------------------------------------------------+
|openmw.camera | by player scripts | | Controls camera (not implemented) | |openmw.camera | by player scripts | | Controls camera (not implemented) |

View File

@ -318,15 +318,5 @@
-- @return #ObjectList -- @return #ObjectList
-------------------------------------------------------------------------------
-- Argument of `onKeyPress` engine handler
-- @type KeyboardEvent
-- @field [parent=#KeyboardEvent] #string symbol The pressed symbol (1-symbol string).
-- @field [parent=#KeyboardEvent] #string code Key code.
-- @field [parent=#KeyboardEvent] #boolean withShift Is `Shift` key pressed.
-- @field [parent=#KeyboardEvent] #boolean withCtrl Is `Control` key pressed.
-- @field [parent=#KeyboardEvent] #boolean withAlt Is `Alt` key pressed.
-- @field [parent=#KeyboardEvent] #boolean withSuper Is `Super`/`Win` key pressed.
return nil return nil

View File

@ -0,0 +1,170 @@
-------------------------------------------------------------------------------
-- `openmw.input` can be used only in scripts attached to a player.
-- @module input
-- @usage local input = require('openmw.input')
-------------------------------------------------------------------------------
-- Is player idle.
-- @function [parent=#input] isIdle
-- @return #boolean
-------------------------------------------------------------------------------
-- Is a specific control currently pressed.
-- Input bindings can be changed ingame using Options/Controls menu.
-- @function [parent=#input] isActionPressed
-- @param #number actionId One of @{openmw.input#ACTION}
-- @return #boolean
-------------------------------------------------------------------------------
-- Is a mouse button currently pressed.
-- @function [parent=#input] isMouseButtonPressed
-- @param #number buttonId Button index (1 - left, 2 - middle, 3 - right, 4 - X1, 5 - X2)
-- @return #boolean
-------------------------------------------------------------------------------
-- Horizontal mouse movement during the last frame.
-- @function [parent=#input] getMouseMoveX
-- @return #number
-------------------------------------------------------------------------------
-- Vertical mouse movement during the last frame.
-- @function [parent=#input] getMouseMoveY
-- @return #number
-------------------------------------------------------------------------------
-- Get value of an axis of a game controller.
-- @function [parent=#input] getAxisValue
-- @param #number axisId Index of a controller axis, one of @{openmw.input#CONTROLLER_AXIS}.
-- @return #number Value in range [-1, 1].
-------------------------------------------------------------------------------
-- Get state of a control switch. I.e. is player able to move/fight/jump/etc.
-- @function [parent=#input] getControlSwitch
-- @param #string key Control type (see @{openmw.input#CONTROL_SWITCH})
-- @return #boolean
-------------------------------------------------------------------------------
-- Set state of a control switch. I.e. forbid or allow player to move/fight/jump/etc.
-- @function [parent=#input] setControlSwitch
-- @param #string key Control type (see @{openmw.input#CONTROL_SWITCH})
-- @param #boolean value
-------------------------------------------------------------------------------
-- @type CONTROL_SWITCH
-- @field [parent=#CONTROL_SWITCH] #string Controls Ability to move
-- @field [parent=#CONTROL_SWITCH] #string Fighting Ability to attack
-- @field [parent=#CONTROL_SWITCH] #string Jumping Ability to jump
-- @field [parent=#CONTROL_SWITCH] #string Looking Ability to change view direction
-- @field [parent=#CONTROL_SWITCH] #string Magic Ability to use magic
-- @field [parent=#CONTROL_SWITCH] #string ViewMode Ability to toggle 1st/3rd person view
-- @field [parent=#CONTROL_SWITCH] #string VanityMode Vanity view if player doesn't touch controls for a long time
-------------------------------------------------------------------------------
-- Values that can be used with getControlSwitch/setControlSwitch.
-- @field [parent=#input] #CONTROL_SWITCH CONTROL_SWITCH
-------------------------------------------------------------------------------
-- @type ACTION
-- @field [parent=#ACTION] #number GameMenu
-- @field [parent=#ACTION] #number Screenshot
-- @field [parent=#ACTION] #number Inventory
-- @field [parent=#ACTION] #number Console
-- @field [parent=#ACTION] #number MoveLeft
-- @field [parent=#ACTION] #number MoveRight
-- @field [parent=#ACTION] #number MoveForward
-- @field [parent=#ACTION] #number MoveBackward
-- @field [parent=#ACTION] #number Activate
-- @field [parent=#ACTION] #number Use
-- @field [parent=#ACTION] #number Jump
-- @field [parent=#ACTION] #number AutoMove
-- @field [parent=#ACTION] #number Journal
-- @field [parent=#ACTION] #number Weapon
-- @field [parent=#ACTION] #number Spell
-- @field [parent=#ACTION] #number Run
-- @field [parent=#ACTION] #number CycleSpellLeft
-- @field [parent=#ACTION] #number CycleSpellRight
-- @field [parent=#ACTION] #number CycleWeaponLeft
-- @field [parent=#ACTION] #number CycleWeaponRight
-- @field [parent=#ACTION] #number ToggleSneak
-- @field [parent=#ACTION] #number AlwaysRun
-- @field [parent=#ACTION] #number Sneak
-- @field [parent=#ACTION] #number QuickSave
-- @field [parent=#ACTION] #number QuickLoad
-- @field [parent=#ACTION] #number QuickMenu
-- @field [parent=#ACTION] #number ToggleWeapon
-- @field [parent=#ACTION] #number ToggleSpell
-- @field [parent=#ACTION] #number TogglePOV
-- @field [parent=#ACTION] #number QuickKey1
-- @field [parent=#ACTION] #number QuickKey2
-- @field [parent=#ACTION] #number QuickKey3
-- @field [parent=#ACTION] #number QuickKey4
-- @field [parent=#ACTION] #number QuickKey5
-- @field [parent=#ACTION] #number QuickKey6
-- @field [parent=#ACTION] #number QuickKey7
-- @field [parent=#ACTION] #number QuickKey8
-- @field [parent=#ACTION] #number QuickKey9
-- @field [parent=#ACTION] #number QuickKey10
-- @field [parent=#ACTION] #number QuickKeysMenu
-- @field [parent=#ACTION] #number ToggleHUD
-- @field [parent=#ACTION] #number ToggleDebug
-- @field [parent=#ACTION] #number ZoomIn
-- @field [parent=#ACTION] #number ZoomOut
-------------------------------------------------------------------------------
-- Values that can be used with isActionPressed.
-- @field [parent=#input] #ACTION ACTION
-------------------------------------------------------------------------------
-- @type CONTROLLER_BUTTON
-- @field [parent=#CONTROLLER_BUTTON] #number A
-- @field [parent=#CONTROLLER_BUTTON] #number B
-- @field [parent=#CONTROLLER_BUTTON] #number X
-- @field [parent=#CONTROLLER_BUTTON] #number Y
-- @field [parent=#CONTROLLER_BUTTON] #number Back
-- @field [parent=#CONTROLLER_BUTTON] #number Guide
-- @field [parent=#CONTROLLER_BUTTON] #number Start
-- @field [parent=#CONTROLLER_BUTTON] #number LeftStick
-- @field [parent=#CONTROLLER_BUTTON] #number RightStick
-- @field [parent=#CONTROLLER_BUTTON] #number LeftShoulder
-- @field [parent=#CONTROLLER_BUTTON] #number RightShoulder
-- @field [parent=#CONTROLLER_BUTTON] #number DPadUp
-- @field [parent=#CONTROLLER_BUTTON] #number DPadDown
-- @field [parent=#CONTROLLER_BUTTON] #number DPadLeft
-- @field [parent=#CONTROLLER_BUTTON] #number DPadRight
-------------------------------------------------------------------------------
-- Values that can be passed to onControllerButtonPress/onControllerButtonRelease engine handlers.
-- @field [parent=#input] #CONTROLLER_BUTTON CONTROLLER_BUTTON
-------------------------------------------------------------------------------
-- Ids of game controller axises. Used as an argument in getAxisValue.
-- @type CONTROLLER_AXIS
-- @field [parent=#CONTROLLER_AXIS] #number LeftX Left stick horizontal axis (from -1 to 1)
-- @field [parent=#CONTROLLER_AXIS] #number LeftY Left stick vertical axis (from -1 to 1)
-- @field [parent=#CONTROLLER_AXIS] #number RightX Right stick horizontal axis (from -1 to 1)
-- @field [parent=#CONTROLLER_AXIS] #number RightY Right stick vertical axis (from -1 to 1)
-- @field [parent=#CONTROLLER_AXIS] #number TriggerLeft Left trigger (from 0 to 1)
-- @field [parent=#CONTROLLER_AXIS] #number TriggerRight Right trigger (from 0 to 1)
-- @field [parent=#CONTROLLER_AXIS] #number LookUpDown View direction vertical axis (RightY by default, can be mapped to another axis in Options/Controls menu)
-- @field [parent=#CONTROLLER_AXIS] #number LookLeftRight View direction horizontal axis (RightX by default, can be mapped to another axis in Options/Controls menu)
-- @field [parent=#CONTROLLER_AXIS] #number MoveForwardBackward Movement forward/backward (LeftY by default, can be mapped to another axis in Options/Controls menu)
-- @field [parent=#CONTROLLER_AXIS] #number MoveLeftRight Side movement (LeftX by default, can be mapped to another axis in Options/Controls menu)
-------------------------------------------------------------------------------
-- Values that can be used with getAxisValue.
-- @field [parent=#input] #CONTROLLER_AXIS CONTROLLER_AXIS
-------------------------------------------------------------------------------
-- The argument of `onKeyPress`/`onKeyRelease` engine handlers.
-- @type KeyboardEvent
-- @field [parent=#KeyboardEvent] #string symbol The pressed symbol (1-symbol string).
-- @field [parent=#KeyboardEvent] #string code Key code.
-- @field [parent=#KeyboardEvent] #boolean withShift Is `Shift` key pressed.
-- @field [parent=#KeyboardEvent] #boolean withCtrl Is `Control` key pressed.
-- @field [parent=#KeyboardEvent] #boolean withAlt Is `Alt` key pressed.
-- @field [parent=#KeyboardEvent] #boolean withSuper Is `Super`/`Win` key pressed.
return nil