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