mirror of
https://github.com/vcmi/vcmi.git
synced 2025-01-12 02:28:11 +02:00
Allow input configuration via config file
This commit is contained in:
parent
3749439702
commit
89d6ddd916
@ -38,6 +38,9 @@ InputHandler::InputHandler()
|
||||
, fingerHandler(std::make_unique<InputSourceTouch>())
|
||||
, textHandler(std::make_unique<InputSourceText>())
|
||||
, gameControllerHandler(std::make_unique<InputSourceGameController>())
|
||||
, enableMouse(settings["input"]["enableMouse"].Bool())
|
||||
, enableTouch(settings["input"]["enableTouch"].Bool())
|
||||
, enableController(settings["input"]["enableController"].Bool())
|
||||
{
|
||||
}
|
||||
|
||||
@ -48,35 +51,59 @@ void InputHandler::handleCurrentEvent(const SDL_Event & current)
|
||||
switch (current.type)
|
||||
{
|
||||
case SDL_KEYDOWN:
|
||||
return keyboardHandler->handleEventKeyDown(current.key);
|
||||
keyboardHandler->handleEventKeyDown(current.key);
|
||||
return;
|
||||
case SDL_KEYUP:
|
||||
return keyboardHandler->handleEventKeyUp(current.key);
|
||||
keyboardHandler->handleEventKeyUp(current.key);
|
||||
return;
|
||||
#ifndef VCMI_EMULATE_TOUCHSCREEN_WITH_MOUSE
|
||||
case SDL_MOUSEMOTION:
|
||||
return mouseHandler->handleEventMouseMotion(current.motion);
|
||||
if (enableMouse)
|
||||
mouseHandler->handleEventMouseMotion(current.motion);
|
||||
return;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
return mouseHandler->handleEventMouseButtonDown(current.button);
|
||||
if (enableMouse)
|
||||
mouseHandler->handleEventMouseButtonDown(current.button);
|
||||
return;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
return mouseHandler->handleEventMouseButtonUp(current.button);
|
||||
if (enableMouse)
|
||||
mouseHandler->handleEventMouseButtonUp(current.button);
|
||||
return;
|
||||
case SDL_MOUSEWHEEL:
|
||||
return mouseHandler->handleEventMouseWheel(current.wheel);
|
||||
if (enableMouse)
|
||||
mouseHandler->handleEventMouseWheel(current.wheel);
|
||||
return;
|
||||
#endif
|
||||
case SDL_TEXTINPUT:
|
||||
return textHandler->handleEventTextInput(current.text);
|
||||
textHandler->handleEventTextInput(current.text);
|
||||
return;
|
||||
case SDL_TEXTEDITING:
|
||||
return textHandler->handleEventTextEditing(current.edit);
|
||||
textHandler->handleEventTextEditing(current.edit);
|
||||
return;
|
||||
case SDL_FINGERMOTION:
|
||||
return fingerHandler->handleEventFingerMotion(current.tfinger);
|
||||
if (enableTouch)
|
||||
fingerHandler->handleEventFingerMotion(current.tfinger);
|
||||
return;
|
||||
case SDL_FINGERDOWN:
|
||||
return fingerHandler->handleEventFingerDown(current.tfinger);
|
||||
if (enableTouch)
|
||||
fingerHandler->handleEventFingerDown(current.tfinger);
|
||||
return;
|
||||
case SDL_FINGERUP:
|
||||
return fingerHandler->handleEventFingerUp(current.tfinger);
|
||||
if (enableTouch)
|
||||
fingerHandler->handleEventFingerUp(current.tfinger);
|
||||
return;
|
||||
case SDL_CONTROLLERAXISMOTION:
|
||||
return gameControllerHandler->handleEventAxisMotion(current.caxis);
|
||||
if (enableController)
|
||||
gameControllerHandler->handleEventAxisMotion(current.caxis);
|
||||
return;
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
return gameControllerHandler->handleEventButtonDown(current.cbutton);
|
||||
if (enableController)
|
||||
gameControllerHandler->handleEventButtonDown(current.cbutton);
|
||||
return;
|
||||
case SDL_CONTROLLERBUTTONUP:
|
||||
return gameControllerHandler->handleEventButtonUp(current.cbutton);
|
||||
if (enableController)
|
||||
gameControllerHandler->handleEventButtonUp(current.cbutton);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,10 @@ class InputHandler
|
||||
|
||||
Point cursorPosition;
|
||||
|
||||
const bool enableMouse;
|
||||
const bool enableTouch;
|
||||
const bool enableController;
|
||||
|
||||
std::vector<SDL_Event> acquireEvents();
|
||||
|
||||
void preprocessEvent(const SDL_Event & event);
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include "../gui/EventDispatcher.h"
|
||||
#include "../gui/ShortcutHandler.h"
|
||||
|
||||
#include "../../lib/CConfigHandler.h"
|
||||
|
||||
void InputSourceGameController::gameControllerDeleter(SDL_GameController * gameController)
|
||||
{
|
||||
if(gameController)
|
||||
@ -26,6 +28,13 @@ void InputSourceGameController::gameControllerDeleter(SDL_GameController * gameC
|
||||
}
|
||||
|
||||
InputSourceGameController::InputSourceGameController():
|
||||
configTriggerTreshold(settings["input"]["controllerTriggerTreshold"].Float()),
|
||||
configAxisDeadZone(settings["input"]["controllerAxisDeadZone"].Float()),
|
||||
configAxisFullZone(settings["input"]["controllerAxisFullZone"].Float()),
|
||||
configPointerSpeed(settings["input"]["controllerPointerSpeed"].Float()),
|
||||
configPointerScale(settings["input"]["controllerPointerScale"].Float()),
|
||||
configPanningSpeed(settings["input"]["controllerPanningSpeed"].Float()),
|
||||
configPanningScale(settings["input"]["controllerPanningScale"].Float()),
|
||||
cursorAxisValueX(0),
|
||||
cursorAxisValueY(0),
|
||||
cursorPlanDisX(0.0),
|
||||
@ -120,21 +129,22 @@ void InputSourceGameController::handleEventDeviceRemapped(const SDL_ControllerDe
|
||||
openGameController(device.which);
|
||||
}
|
||||
|
||||
int InputSourceGameController::getRealAxisValue(int value)
|
||||
double InputSourceGameController::getRealAxisValue(int value)
|
||||
{
|
||||
if(value < AXIS_DEAD_ZOOM && value > -AXIS_DEAD_ZOOM)
|
||||
double ratio = static_cast<double>(value) / SDL_JOYSTICK_AXIS_MAX;
|
||||
double greenZone = configAxisFullZone - configAxisDeadZone;
|
||||
|
||||
if (std::abs(ratio) < configAxisDeadZone)
|
||||
return 0;
|
||||
if(value > AXIS_MAX_ZOOM)
|
||||
return AXIS_MAX_ZOOM;
|
||||
if(value < -AXIS_MAX_ZOOM)
|
||||
return -AXIS_MAX_ZOOM;
|
||||
int base = value > 0 ? AXIS_DEAD_ZOOM : -AXIS_DEAD_ZOOM;
|
||||
return (value - base) * AXIS_MAX_ZOOM / (AXIS_MAX_ZOOM - AXIS_DEAD_ZOOM);
|
||||
|
||||
double scaledValue = (ratio - configAxisDeadZone) / greenZone;
|
||||
double clampedValue = std::clamp(scaledValue, -1.0, +1.0);
|
||||
return clampedValue;
|
||||
}
|
||||
|
||||
void InputSourceGameController::dispatchAxisShortcuts(const std::vector<EShortcut> & shortcutsVector, SDL_GameControllerAxis axisID, int axisValue)
|
||||
{
|
||||
if(axisValue >= TRIGGER_PRESS_THRESHOLD)
|
||||
if(getRealAxisValue(axisValue) > configTriggerTreshold)
|
||||
{
|
||||
if(!pressedAxes.count(axisID))
|
||||
{
|
||||
@ -256,12 +266,12 @@ void InputSourceGameController::handleCursorUpdate(int32_t deltaTimeMs)
|
||||
if(cursorAxisValueX == 0)
|
||||
cursorPlanDisX = 0;
|
||||
else
|
||||
cursorPlanDisX += deltaTimeSeconds * AXIS_MOVE_SPEED * cursorAxisValueX / AXIS_MAX_ZOOM;
|
||||
cursorPlanDisX += deltaTimeSeconds * configPointerSpeed * std::pow(cursorAxisValueX, configPointerScale);
|
||||
|
||||
if(cursorAxisValueY == 0)
|
||||
cursorPlanDisY = 0;
|
||||
else
|
||||
cursorPlanDisY += deltaTimeSeconds * AXIS_MOVE_SPEED * cursorAxisValueY / AXIS_MAX_ZOOM;
|
||||
cursorPlanDisY += deltaTimeSeconds * configPointerSpeed * std::pow(cursorAxisValueY, configPointerScale);
|
||||
|
||||
int moveDisX = getMoveDis(cursorPlanDisX);
|
||||
int moveDisY = getMoveDis(cursorPlanDisY);
|
||||
@ -290,8 +300,8 @@ void InputSourceGameController::handleScrollUpdate(int32_t deltaTimeMs)
|
||||
return;
|
||||
}
|
||||
float deltaTimeSeconds = static_cast<float>(deltaTimeMs) / 1000;
|
||||
scrollPlanDisX += deltaTimeSeconds * AXIS_MOVE_SPEED * scrollAxisValueX / AXIS_MAX_ZOOM;
|
||||
scrollPlanDisY += deltaTimeSeconds * AXIS_MOVE_SPEED * scrollAxisValueY / AXIS_MAX_ZOOM;
|
||||
scrollPlanDisX += deltaTimeSeconds * configPanningSpeed * std::pow(scrollAxisValueX, configPanningScale);
|
||||
scrollPlanDisY += deltaTimeSeconds * configPanningSpeed * std::pow(scrollAxisValueY, configPanningScale);
|
||||
int moveDisX = getMoveDis(scrollPlanDisX);
|
||||
int moveDisY = getMoveDis(scrollPlanDisY);
|
||||
if(moveDisX != 0 || moveDisY != 0)
|
||||
|
@ -44,9 +44,17 @@ class InputSourceGameController
|
||||
float scrollPlanDisX;
|
||||
float scrollPlanDisY;
|
||||
|
||||
const double configTriggerTreshold;
|
||||
const double configAxisDeadZone;
|
||||
const double configAxisFullZone;
|
||||
const double configPointerSpeed;
|
||||
const double configPointerScale;
|
||||
const double configPanningSpeed;
|
||||
const double configPanningScale;
|
||||
|
||||
void openGameController(int index);
|
||||
int getJoystickIndex(SDL_GameController * controller);
|
||||
int getRealAxisValue(int value);
|
||||
double getRealAxisValue(int value);
|
||||
void dispatchAxisShortcuts(const std::vector<EShortcut> & shortcutsVector, SDL_GameControllerAxis axisID, int axisValue);
|
||||
void tryToConvertCursor();
|
||||
void doCursorMove(int deltaX, int deltaY);
|
||||
|
@ -12,15 +12,18 @@
|
||||
#include "InputSourceMouse.h"
|
||||
#include "InputHandler.h"
|
||||
|
||||
#include "../../lib/Point.h"
|
||||
#include "../gui/CGuiHandler.h"
|
||||
#include "../gui/EventDispatcher.h"
|
||||
#include "../gui/MouseButton.h"
|
||||
|
||||
#include "../../lib/Point.h"
|
||||
#include "../../lib/CConfigHandler.h"
|
||||
|
||||
#include <SDL_events.h>
|
||||
#include <SDL_hints.h>
|
||||
|
||||
InputSourceMouse::InputSourceMouse()
|
||||
:mouseToleranceDistance(settings["input"]["mouseToleranceDistance"].Integer())
|
||||
{
|
||||
SDL_SetHint(SDL_HINT_MOUSE_FOCUS_CLICKTHROUGH, "1");
|
||||
}
|
||||
@ -48,12 +51,12 @@ void InputSourceMouse::handleEventMouseButtonDown(const SDL_MouseButtonEvent & b
|
||||
{
|
||||
case SDL_BUTTON_LEFT:
|
||||
if(button.clicks > 1)
|
||||
GH.events().dispatchMouseDoubleClick(position, 0);
|
||||
GH.events().dispatchMouseDoubleClick(position, mouseToleranceDistance);
|
||||
else
|
||||
GH.events().dispatchMouseLeftButtonPressed(position, 0);
|
||||
GH.events().dispatchMouseLeftButtonPressed(position, mouseToleranceDistance);
|
||||
break;
|
||||
case SDL_BUTTON_RIGHT:
|
||||
GH.events().dispatchShowPopup(position, 0);
|
||||
GH.events().dispatchShowPopup(position, mouseToleranceDistance);
|
||||
break;
|
||||
case SDL_BUTTON_MIDDLE:
|
||||
middleClickPosition = position;
|
||||
@ -74,7 +77,7 @@ void InputSourceMouse::handleEventMouseButtonUp(const SDL_MouseButtonEvent & but
|
||||
switch(button.button)
|
||||
{
|
||||
case SDL_BUTTON_LEFT:
|
||||
GH.events().dispatchMouseLeftButtonReleased(position, 0);
|
||||
GH.events().dispatchMouseLeftButtonReleased(position, mouseToleranceDistance);
|
||||
break;
|
||||
case SDL_BUTTON_RIGHT:
|
||||
GH.events().dispatchClosePopup(position);
|
||||
|
@ -23,6 +23,7 @@ class InputSourceMouse
|
||||
{
|
||||
Point middleClickPosition;
|
||||
int mouseButtonsMask = 0;
|
||||
const int mouseToleranceDistance;
|
||||
public:
|
||||
InputSourceMouse();
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
||||
#include "WindowHandler.h"
|
||||
#include "gui/Shortcut.h"
|
||||
|
||||
#include "../../lib/CConfigHandler.h"
|
||||
#include "../../lib/Rect.h"
|
||||
|
||||
template<typename Functor>
|
||||
@ -76,10 +77,10 @@ void EventDispatcher::dispatchShortcutPressed(const std::vector<EShortcut> & sho
|
||||
bool keysCaptured = false;
|
||||
|
||||
if (vstd::contains(shortcutsVector, EShortcut::MOUSE_LEFT))
|
||||
dispatchMouseLeftButtonPressed(GH.getCursorPosition(), 0);
|
||||
dispatchMouseLeftButtonPressed(GH.getCursorPosition(), settings["input"]["shortcutToleranceDistance"].Integer());
|
||||
|
||||
if (vstd::contains(shortcutsVector, EShortcut::MOUSE_RIGHT))
|
||||
dispatchShowPopup(GH.getCursorPosition(), 0);
|
||||
dispatchShowPopup(GH.getCursorPosition(), settings["input"]["shortcutToleranceDistance"].Integer());
|
||||
|
||||
for(auto & i : keyinterested)
|
||||
for(EShortcut shortcut : shortcutsVector)
|
||||
@ -105,7 +106,7 @@ void EventDispatcher::dispatchShortcutReleased(const std::vector<EShortcut> & sh
|
||||
bool keysCaptured = false;
|
||||
|
||||
if (vstd::contains(shortcutsVector, EShortcut::MOUSE_LEFT))
|
||||
dispatchMouseLeftButtonReleased(GH.getCursorPosition(), 0);
|
||||
dispatchMouseLeftButtonReleased(GH.getCursorPosition(), settings["input"]["shortcutToleranceDistance"].Integer());
|
||||
|
||||
if (vstd::contains(shortcutsVector, EShortcut::MOUSE_RIGHT))
|
||||
dispatchClosePopup(GH.getCursorPosition());
|
||||
@ -164,7 +165,7 @@ AEventsReceiver * EventDispatcher::findElementInToleranceRange(const EventReceiv
|
||||
if (distance.lengthSquared() == 0)
|
||||
continue;
|
||||
|
||||
Point moveDelta = distance * tolerance / distance.length();
|
||||
Point moveDelta = distance * std::min(1.0, static_cast<double>(tolerance) / distance.length());
|
||||
Point testPosition = position + moveDelta;
|
||||
|
||||
if( !i->receiveEvent(testPosition, eventToTest))
|
||||
|
@ -236,7 +236,22 @@
|
||||
"type" : "object",
|
||||
"additionalProperties" : false,
|
||||
"default" : {},
|
||||
"required" : [ "radialWheelGarrisonSwipe", "touchToleranceDistance" ],
|
||||
"required" : [
|
||||
"radialWheelGarrisonSwipe",
|
||||
"touchToleranceDistance",
|
||||
"mouseToleranceDistance",
|
||||
"shortcutToleranceDistance",
|
||||
"enableMouse",
|
||||
"enableTouch",
|
||||
"enableController",
|
||||
"controllerTriggerTreshold",
|
||||
"controllerAxisDeadZone",
|
||||
"controllerAxisFullZone",
|
||||
"controllerPointerSpeed",
|
||||
"controllerPointerScale",
|
||||
"controllerPanningSpeed",
|
||||
"controllerPanningScale",
|
||||
],
|
||||
"properties" : {
|
||||
"radialWheelGarrisonSwipe" : {
|
||||
"type" : "boolean",
|
||||
@ -245,7 +260,55 @@
|
||||
"touchToleranceDistance" : {
|
||||
"type" : "number",
|
||||
"default" : 20
|
||||
},
|
||||
"mouseToleranceDistance" : {
|
||||
"type" : "number",
|
||||
"default" : 0
|
||||
},
|
||||
"shortcutToleranceDistance" : {
|
||||
"type" : "number",
|
||||
"default" : 0
|
||||
},
|
||||
"enableMouse" : {
|
||||
"type" : "boolean",
|
||||
"default" : true
|
||||
},
|
||||
"enableTouch" : {
|
||||
"type" : "boolean",
|
||||
"default" : true
|
||||
},
|
||||
"enableController" : {
|
||||
"type" : "boolean",
|
||||
"default" : true
|
||||
},
|
||||
"controllerTriggerTreshold" : {
|
||||
"type" : "number",
|
||||
"default" : 0.3
|
||||
}
|
||||
"controllerAxisDeadZone" : {
|
||||
"type" : "number",
|
||||
"default" : 0.2
|
||||
},
|
||||
"controllerAxisFullZone" : {
|
||||
"type" : "number",
|
||||
"default" : 0.9
|
||||
},
|
||||
"controllerPointerSpeed" : {
|
||||
"type" : "number",
|
||||
"default" : 1
|
||||
},
|
||||
"controllerPointerScale" : {
|
||||
"type" : "number",
|
||||
"default" : 1
|
||||
},
|
||||
"controllerPanningSpeed" : {
|
||||
"type" : "number",
|
||||
"default" : 1
|
||||
},
|
||||
"controllerPanningScale" : {
|
||||
"type" : "number",
|
||||
"default" : 1
|
||||
},
|
||||
}
|
||||
},
|
||||
"adventure" : {
|
||||
|
Loading…
Reference in New Issue
Block a user