Implemented saving, ccmd, and options menu
This commit is contained in:
parent
92e66479fc
commit
33b22d99da
5 changed files with 460 additions and 1 deletions
|
|
@ -33,6 +33,7 @@
|
|||
// HEADER FILES ------------------------------------------------------------
|
||||
|
||||
#include <math.h>
|
||||
#include "c_dispatch.h"
|
||||
#include "vectors.h"
|
||||
#include "m_joy.h"
|
||||
#include "configfile.h"
|
||||
|
|
@ -163,6 +164,48 @@ bool M_LoadJoystickConfig(IJoystickConfig *joy)
|
|||
joy->SetAxisScale(i, (float)atof(value));
|
||||
}
|
||||
|
||||
mysnprintf(key + axislen, countof(key) - axislen, "threshold");
|
||||
value = GameConfig->GetValueForKey(key);
|
||||
if (value)
|
||||
{
|
||||
joy->SetAxisDigitalThreshold(i, (float)atof(value));
|
||||
}
|
||||
|
||||
mysnprintf(key + axislen, countof(key) - axislen, "curve");
|
||||
value = GameConfig->GetValueForKey(key);
|
||||
if (value)
|
||||
{
|
||||
joy->SetAxisResponseCurve(i, (EJoyCurve)clamp(atoi(value), (int)JOYCURVE_CUSTOM, (int)NUM_JOYCURVE-1));
|
||||
}
|
||||
|
||||
mysnprintf(key + axislen, countof(key) - axislen, "curve-x1");
|
||||
value = GameConfig->GetValueForKey(key);
|
||||
if (value)
|
||||
{
|
||||
joy->SetAxisResponseCurvePoint(i, 0, (float)atof(value));
|
||||
}
|
||||
|
||||
mysnprintf(key + axislen, countof(key) - axislen, "curve-y1");
|
||||
value = GameConfig->GetValueForKey(key);
|
||||
if (value)
|
||||
{
|
||||
joy->SetAxisResponseCurvePoint(i, 1, (float)atof(value));
|
||||
}
|
||||
|
||||
mysnprintf(key + axislen, countof(key) - axislen, "curve-x2");
|
||||
value = GameConfig->GetValueForKey(key);
|
||||
if (value)
|
||||
{
|
||||
joy->SetAxisResponseCurvePoint(i, 2, (float)atof(value));
|
||||
}
|
||||
|
||||
mysnprintf(key + axislen, countof(key) - axislen, "curve-y2");
|
||||
value = GameConfig->GetValueForKey(key);
|
||||
if (value)
|
||||
{
|
||||
joy->SetAxisResponseCurvePoint(i, 3, (float)atof(value));
|
||||
}
|
||||
|
||||
mysnprintf(key + axislen, countof(key) - axislen, "map");
|
||||
value = GameConfig->GetValueForKey(key);
|
||||
if (value)
|
||||
|
|
@ -227,6 +270,33 @@ void M_SaveJoystickConfig(IJoystickConfig *joy)
|
|||
mysnprintf(value, countof(value), "%g", joy->GetAxisScale(i));
|
||||
GameConfig->SetValueForKey(key, value);
|
||||
}
|
||||
if (!joy->IsAxisDigitalThresholdDefault(i))
|
||||
{
|
||||
mysnprintf(key + axislen, countof(key) - axislen, "threshold");
|
||||
mysnprintf(value, countof(value), "%g", joy->GetAxisDigitalThreshold(i));
|
||||
GameConfig->SetValueForKey(key, value);
|
||||
}
|
||||
if (!joy->IsAxisResponseCurveDefault(i))
|
||||
{
|
||||
mysnprintf(key + axislen, countof(key) - axislen, "curve");
|
||||
mysnprintf(value, countof(value), "%d", joy->GetAxisResponseCurve(i));
|
||||
GameConfig->SetValueForKey(key, value);
|
||||
}
|
||||
if (joy->GetAxisResponseCurve(i) == JOYCURVE_CUSTOM)
|
||||
{
|
||||
mysnprintf(key + axislen, countof(key) - axislen, "curve-x1");
|
||||
mysnprintf(value, countof(value), "%g", joy->GetAxisResponseCurvePoint(i, 0));
|
||||
GameConfig->SetValueForKey(key, value);
|
||||
mysnprintf(key + axislen, countof(key) - axislen, "curve-y1");
|
||||
mysnprintf(value, countof(value), "%g", joy->GetAxisResponseCurvePoint(i, 1));
|
||||
GameConfig->SetValueForKey(key, value);
|
||||
mysnprintf(key + axislen, countof(key) - axislen, "curve-x2");
|
||||
mysnprintf(value, countof(value), "%g", joy->GetAxisResponseCurvePoint(i, 2));
|
||||
GameConfig->SetValueForKey(key, value);
|
||||
mysnprintf(key + axislen, countof(key) - axislen, "curve-y2");
|
||||
mysnprintf(value, countof(value), "%g", joy->GetAxisResponseCurvePoint(i, 3));
|
||||
GameConfig->SetValueForKey(key, value);
|
||||
}
|
||||
if (!joy->IsAxisMapDefault(i))
|
||||
{
|
||||
mysnprintf(key + axislen, countof(key) - axislen, "map");
|
||||
|
|
@ -243,6 +313,174 @@ void M_SaveJoystickConfig(IJoystickConfig *joy)
|
|||
}
|
||||
}
|
||||
|
||||
CCMD (gamepad)
|
||||
{
|
||||
int COMMAND = 1, IDENTIFIER = 2, VALUE = 3;
|
||||
int argc = argv.argc()-1;
|
||||
|
||||
TArray<IJoystickConfig *> sticks;
|
||||
I_GetJoysticks(sticks);
|
||||
|
||||
auto usage = []()
|
||||
{
|
||||
Printf(
|
||||
"usage:"
|
||||
"\n\tgamepad list"
|
||||
"\n\tgamepad reset pad"
|
||||
"\n\tgamepad enabled pad [0|1]"
|
||||
"\n\tgamepad background pad [0|1]"
|
||||
"\n\tgamepad sensitivity pad [float]"
|
||||
"\n\tgamepad deadzone pad.axis [float]"
|
||||
"\n\tgamepad scale pad.axis [float]"
|
||||
"\n\tgamepad threshold pad.axis [float]"
|
||||
"\n\tgamepad curve pad.axis [-1|0|1|2|3]"
|
||||
"\n\tgamepad curve-x1 pad.axis [float]"
|
||||
"\n\tgamepad curve-y1 pad.axis [float]"
|
||||
"\n\tgamepad curve-x2 pad.axis [float]"
|
||||
"\n\tgamepad curve-y2 pad.axis [float]"
|
||||
"\n\tgamepad map pad.axis [-1|0|1|2|3|4]"
|
||||
"\n"
|
||||
);
|
||||
};
|
||||
|
||||
if (argc < COMMAND)
|
||||
{
|
||||
return usage();
|
||||
};
|
||||
|
||||
FName command = argv[COMMAND];
|
||||
|
||||
if (argc < IDENTIFIER)
|
||||
{
|
||||
if (command == "list")
|
||||
{
|
||||
for (int i = 0; i < sticks.SSize(); i++)
|
||||
{
|
||||
Printf("%d: '%s'\n", i, sticks[i]->GetName().GetChars());
|
||||
for (int j = 0; j < sticks[i]->GetNumAxes(); j++)
|
||||
{
|
||||
Printf(" %d.%d: '%s'\n", i, j, sticks[i]->GetAxisName(j));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
return usage();
|
||||
}
|
||||
|
||||
const char * id = argv[IDENTIFIER];
|
||||
const char * hasAxis = strchr(id, '.');
|
||||
|
||||
int pad, axis;
|
||||
|
||||
try {
|
||||
pad = (int)std::stod(id);
|
||||
|
||||
if (pad < 0 || pad >= sticks.SSize())
|
||||
{
|
||||
return (void) Printf("Pad # out of range\n");
|
||||
}
|
||||
} catch (...) {
|
||||
return (void) Printf("Failed to parse pad #\n");
|
||||
}
|
||||
|
||||
if (hasAxis)
|
||||
{
|
||||
try {
|
||||
axis = (int)std::stod(hasAxis+1);
|
||||
|
||||
if (axis < 0 || axis >= sticks[pad]->GetNumAxes())
|
||||
{
|
||||
return (void) Printf("Axis # out of range\n");
|
||||
}
|
||||
} catch (...) {
|
||||
return (void) Printf("Failed to parse axis #\n");
|
||||
}
|
||||
}
|
||||
|
||||
float value = 0;
|
||||
bool set = argc >= VALUE;
|
||||
|
||||
if (set)
|
||||
{
|
||||
try {
|
||||
value = std::stod(argv[VALUE]);
|
||||
} catch (...) {
|
||||
return (void) Printf("Failed to parse args\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (command == "reset")
|
||||
{
|
||||
if (set) return usage();
|
||||
sticks[pad]->SetDefaultConfig();
|
||||
sticks[pad]->SetEnabled(true);
|
||||
sticks[pad]->SetEnabledInBackground(sticks[pad]->AllowsEnabledInBackground());
|
||||
sticks[pad]->SetSensitivity(1);
|
||||
return;
|
||||
}
|
||||
if (command == "enabled")
|
||||
{
|
||||
if (set) sticks[pad]->SetEnabled((int)value);
|
||||
return (void) Printf("%d\n", sticks[pad]->GetEnabled());
|
||||
}
|
||||
if (command == "background")
|
||||
{
|
||||
if (set) sticks[pad]->SetEnabledInBackground((int)value);
|
||||
return (void) Printf("%d\n", sticks[pad]->GetEnabledInBackground());
|
||||
}
|
||||
if (command == "sensitivity")
|
||||
{
|
||||
if (set) sticks[pad]->SetSensitivity(value);
|
||||
return (void) Printf("%g\n", sticks[pad]->GetSensitivity());
|
||||
}
|
||||
if (command == "deadzone")
|
||||
{
|
||||
if (set) sticks[pad]->SetAxisDeadZone(axis, value);
|
||||
return (void) Printf("%g\n", sticks[pad]->GetAxisDeadZone(axis));
|
||||
}
|
||||
if (command == "scale")
|
||||
{
|
||||
if (set) sticks[pad]->SetAxisScale(axis, value);
|
||||
return (void) Printf("%g\n", sticks[pad]->GetAxisScale(axis));
|
||||
}
|
||||
if (command == "threshold")
|
||||
{
|
||||
if (set) sticks[pad]->SetAxisDigitalThreshold(axis, value);
|
||||
return (void) Printf("%g\n", sticks[pad]->GetAxisDigitalThreshold(axis));
|
||||
}
|
||||
if (command == "curve")
|
||||
{
|
||||
if (set) sticks[pad]->SetAxisResponseCurve(axis, (EJoyCurve)value);
|
||||
return (void) Printf("%d\n", sticks[pad]->GetAxisResponseCurve(axis));
|
||||
}
|
||||
if (command == "curve-x1")
|
||||
{
|
||||
if (set) sticks[pad]->SetAxisResponseCurvePoint(axis, 0, value);
|
||||
return (void) Printf("%g\n", sticks[pad]->GetAxisResponseCurvePoint(axis, 0));
|
||||
}
|
||||
if (command == "curve-y1")
|
||||
{
|
||||
if (set) sticks[pad]->SetAxisResponseCurvePoint(axis, 1, value);
|
||||
return (void) Printf("%g\n", sticks[pad]->GetAxisResponseCurvePoint(axis, 1));
|
||||
}
|
||||
if (command == "curve-x2")
|
||||
{
|
||||
if (set) sticks[pad]->SetAxisResponseCurvePoint(axis, 2, value);
|
||||
return (void) Printf("%g\n", sticks[pad]->GetAxisResponseCurvePoint(axis, 2));
|
||||
}
|
||||
if (command == "curve-y2")
|
||||
{
|
||||
if (set) sticks[pad]->SetAxisResponseCurvePoint(axis, 3, value);
|
||||
return (void) Printf("%g\n", sticks[pad]->GetAxisResponseCurvePoint(axis, 3));
|
||||
}
|
||||
if (command == "map")
|
||||
{
|
||||
if (set) sticks[pad]->SetAxisMap(axis, (EJoyAxis)value);
|
||||
return (void) Printf("%d\n", sticks[pad]->GetAxisMap(axis));
|
||||
}
|
||||
|
||||
return usage();
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
//
|
||||
|
|
|
|||
|
|
@ -84,6 +84,56 @@ DEFINE_ACTION_FUNCTION(IJoystickConfig, SetAxisDeadZone)
|
|||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(IJoystickConfig, GetAxisDigitalThreshold)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(IJoystickConfig);
|
||||
PARAM_INT(axis);
|
||||
ACTION_RETURN_FLOAT(self->GetAxisDigitalThreshold(axis));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(IJoystickConfig, SetAxisDigitalThreshold)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(IJoystickConfig);
|
||||
PARAM_INT(axis);
|
||||
PARAM_FLOAT(dt);
|
||||
self->SetAxisDigitalThreshold(axis, (float)dt);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(IJoystickConfig, GetAxisResponseCurve)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(IJoystickConfig);
|
||||
PARAM_INT(axis);
|
||||
ACTION_RETURN_INT(self->GetAxisResponseCurve(axis));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(IJoystickConfig, SetAxisResponseCurve)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(IJoystickConfig);
|
||||
PARAM_INT(axis);
|
||||
PARAM_INT(curve);
|
||||
self->SetAxisResponseCurve(axis, (EJoyCurve)curve);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(IJoystickConfig, GetAxisResponseCurvePoint)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(IJoystickConfig);
|
||||
PARAM_INT(axis);
|
||||
PARAM_INT(point);
|
||||
ACTION_RETURN_FLOAT(self->GetAxisResponseCurvePoint(axis, point));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(IJoystickConfig, SetAxisResponseCurvePoint)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(IJoystickConfig);
|
||||
PARAM_INT(axis);
|
||||
PARAM_INT(point);
|
||||
PARAM_FLOAT(value);
|
||||
self->SetAxisResponseCurvePoint(axis, point, value);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(IJoystickConfig, GetAxisMap)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(IJoystickConfig);
|
||||
|
|
|
|||
|
|
@ -837,6 +837,15 @@ OptionMenu "JoystickOptions" protected
|
|||
Title "$JOYMNU_OPTIONS"
|
||||
}
|
||||
|
||||
OptionValue "JoyAxisCurveNames"
|
||||
{
|
||||
-1, "$OPTVAL_CUSTOM"
|
||||
0, "$OPTVAL_DEFAULT"
|
||||
1, "$OPTVAL_LINEAR"
|
||||
2, "$OPTVAL_QUADRATIC"
|
||||
3, "$OPTVAL_CUBIC"
|
||||
}
|
||||
|
||||
OptionValue "JoyAxisMapNames"
|
||||
{
|
||||
-1, "$OPTVAL_NONE"
|
||||
|
|
|
|||
|
|
@ -100,6 +100,50 @@ class OptionMenuSliderJoyScale : OptionMenuSliderBase
|
|||
//
|
||||
//=============================================================================
|
||||
|
||||
class OptionMenuSliderJoyCurve : OptionMenuSliderBase
|
||||
{
|
||||
int mAxis;
|
||||
int mNeg;
|
||||
int mPoint;
|
||||
bool mShown;
|
||||
JoystickConfig mJoy;
|
||||
|
||||
OptionMenuSliderJoyCurve Init(String label, int axis, double min, double max, double step, int showval, JoystickConfig joy, int point)
|
||||
{
|
||||
Super.Init(label, min, max, step, showval);
|
||||
mAxis = axis;
|
||||
mNeg = 1;
|
||||
mJoy = joy;
|
||||
mPoint = point;
|
||||
mShown = false;
|
||||
return self;
|
||||
}
|
||||
|
||||
override bool Visible()
|
||||
{
|
||||
mShown |= mJoy.GetAxisResponseCurve(mAxis) == JoystickConfig.JOYCURVE_CUSTOM;
|
||||
return mShown;
|
||||
}
|
||||
|
||||
override double GetSliderValue()
|
||||
{
|
||||
double d = mJoy.GetAxisResponseCurvePoint(mAxis, mPoint);
|
||||
mNeg = d < 0? -1:1;
|
||||
return d;
|
||||
}
|
||||
|
||||
override void SetSliderValue(double val)
|
||||
{
|
||||
mJoy.SetAxisResponseCurvePoint(mAxis, mPoint, val * mNeg);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class OptionMenuSliderJoyDeadZone : OptionMenuSliderBase
|
||||
{
|
||||
int mAxis;
|
||||
|
|
@ -130,7 +174,94 @@ class OptionMenuSliderJoyDeadZone : OptionMenuSliderBase
|
|||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class OptionMenuSliderJoyDigitalThreshold : OptionMenuSliderBase
|
||||
{
|
||||
int mAxis;
|
||||
int mNeg;
|
||||
JoystickConfig mJoy;
|
||||
|
||||
OptionMenuSliderJoyDigitalThreshold Init(String label, int axis, double min, double max, double step, int showval, JoystickConfig joy)
|
||||
{
|
||||
Super.Init(label, min, max, step, showval);
|
||||
mAxis = axis;
|
||||
mNeg = 1;
|
||||
mJoy = joy;
|
||||
return self;
|
||||
}
|
||||
|
||||
override double GetSliderValue()
|
||||
{
|
||||
double d = mJoy.GetAxisDigitalThreshold(mAxis);
|
||||
mNeg = d < 0? -1:1;
|
||||
return d;
|
||||
}
|
||||
|
||||
override void SetSliderValue(double val)
|
||||
{
|
||||
mJoy.SetAxisDigitalThreshold(mAxis, val * mNeg);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
class OptionMenuItemJoyCurve : OptionMenuItemOptionBase
|
||||
{
|
||||
int mAxis;
|
||||
JoystickConfig mJoy;
|
||||
|
||||
OptionMenuItemJoyCurve Init(String label, int axis, Name values, int center, JoystickConfig joy)
|
||||
{
|
||||
Super.Init(label, 'none', values, null, center);
|
||||
mAxis = axis;
|
||||
mJoy = joy;
|
||||
return self;
|
||||
}
|
||||
|
||||
override int GetSelection()
|
||||
{
|
||||
double f = mJoy.GetAxisResponseCurve(mAxis);
|
||||
let opt = OptionValues.GetCount(mValues);
|
||||
if (opt > 0)
|
||||
{
|
||||
// Map from joystick curve to menu selection.
|
||||
for(int i = 0; i < opt; i++)
|
||||
{
|
||||
if (f ~== OptionValues.GetValue(mValues, i))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
}
|
||||
return JoystickConfig.JOYCURVE_CUSTOM;
|
||||
}
|
||||
|
||||
override void SetSelection(int selection)
|
||||
{
|
||||
let opt = OptionValues.GetCount(mValues);
|
||||
// Map from menu selection to joystick curve.
|
||||
if (opt == 0 || selection >= opt)
|
||||
{
|
||||
selection = JoystickConfig.JOYCURVE_DEFAULT;
|
||||
}
|
||||
else
|
||||
{
|
||||
selection = int(OptionValues.GetValue(mValues, selection));
|
||||
}
|
||||
mJoy.setAxisResponseCurve(mAxis, selection);
|
||||
}
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//=============================================================================
|
||||
|
||||
|
|
@ -340,8 +471,20 @@ class OptionMenuItemJoyConfigMenu : OptionMenuItemSubmenu
|
|||
opt.mItems.Push(it);
|
||||
it = new("OptionMenuItemInverter").Init("$JOYMNU_INVERT", i, false, joy);
|
||||
opt.mItems.Push(it);
|
||||
it = new("OptionMenuItemJoyCurve").Init("$JOYMNU_CURVE", i, "JoyAxisCurveNames", false, joy);
|
||||
opt.mItems.Push(it);
|
||||
it = new("OptionMenuSliderJoyCurve").Init("$JOYMNU_CURVE_X1", i, 0, 0.9, 0.05, 3, joy, 0);
|
||||
opt.mItems.Push(it);
|
||||
it = new("OptionMenuSliderJoyCurve").Init("$JOYMNU_CURVE_Y1", i, 0, 0.9, 0.05, 3, joy, 1);
|
||||
opt.mItems.Push(it);
|
||||
it = new("OptionMenuSliderJoyCurve").Init("$JOYMNU_CURVE_X2", i, 0, 0.9, 0.05, 3, joy, 2);
|
||||
opt.mItems.Push(it);
|
||||
it = new("OptionMenuSliderJoyCurve").Init("$JOYMNU_CURVE_Y2", i, 0, 0.9, 0.05, 3, joy, 3);
|
||||
opt.mItems.Push(it);
|
||||
it = new("OptionMenuSliderJoyDeadZone").Init("$JOYMNU_DEADZONE", i, 0, 0.9, 0.05, 3, joy);
|
||||
opt.mItems.Push(it);
|
||||
it = new("OptionMenuSliderJoyDigitalThreshold").Init("$JOYMNU_THRESHOLD", i, 0, 0.9, 0.05, 3, joy);
|
||||
opt.mItems.Push(it);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
|
|
@ -68,6 +68,16 @@ struct JoystickConfig native version("2.4")
|
|||
NUM_JOYAXIS,
|
||||
};
|
||||
|
||||
enum EJoyCurve {
|
||||
JOYCURVE_CUSTOM = -1,
|
||||
JOYCURVE_DEFAULT,
|
||||
JOYCURVE_LINEAR,
|
||||
JOYCURVE_QUADRATIC,
|
||||
JOYCURVE_CUBIC,
|
||||
|
||||
NUM_JOYCURVE
|
||||
};
|
||||
|
||||
native float GetSensitivity();
|
||||
native void SetSensitivity(float scale);
|
||||
|
||||
|
|
@ -77,6 +87,15 @@ struct JoystickConfig native version("2.4")
|
|||
native float GetAxisDeadZone(int axis);
|
||||
native void SetAxisDeadZone(int axis, float zone);
|
||||
|
||||
native float GetAxisDigitalThreshold(int axis);
|
||||
native void SetAxisDigitalThreshold(int axis, float thresh);
|
||||
|
||||
native int GetAxisResponseCurve(int axis);
|
||||
native void SetAxisResponseCurve(int axis, int preset);
|
||||
|
||||
native float GetAxisResponseCurvePoint(int axis, int point);
|
||||
native void SetAxisResponseCurvePoint(int axis, int point, float value);
|
||||
|
||||
native int GetAxisMap(int axis);
|
||||
native void SetAxisMap(int axis, int gameaxis);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue