Skip to content

Commit

Permalink
Merge pull request #354 from Kanuan/rework-rumble
Browse files Browse the repository at this point in the history
Reworked rumble configuration and processing
  • Loading branch information
nefarius authored Apr 25, 2024
2 parents 007a078 + bb68f85 commit da4ed11
Show file tree
Hide file tree
Showing 5 changed files with 324 additions and 261 deletions.
193 changes: 93 additions & 100 deletions sys/Configuration.c
Original file line number Diff line number Diff line change
Expand Up @@ -134,99 +134,90 @@ ConfigParseRumbleSettings(
{
cJSON* pNode = NULL;

if ((pNode = cJSON_GetObjectItem(RumbleSettings, "DisableBM")))
if ((pNode = cJSON_GetObjectItem(RumbleSettings, "DisableLeft")))
{
Config->RumbleSettings.DisableBM = (BOOLEAN)cJSON_IsTrue(pNode);
EventWriteOverrideSettingUInt(RumbleSettings->string, "DisableBM", Config->RumbleSettings.DisableBM);
Config->RumbleSettings.DisableLeft = (BOOLEAN)cJSON_IsTrue(pNode);
EventWriteOverrideSettingUInt(RumbleSettings->string, "RumbleSettings.DisableLeft", Config->RumbleSettings.DisableLeft);
}

if ((pNode = cJSON_GetObjectItem(RumbleSettings, "DisableSM")))
if ((pNode = cJSON_GetObjectItem(RumbleSettings, "DisableRight")))
{
Config->RumbleSettings.DisableSM = (BOOLEAN)cJSON_IsTrue(pNode);
EventWriteOverrideSettingUInt(RumbleSettings->string, "DisableSM", Config->RumbleSettings.DisableSM);
Config->RumbleSettings.DisableRight = (BOOLEAN)cJSON_IsTrue(pNode);
EventWriteOverrideSettingUInt(RumbleSettings->string, "RumbleSettings.DisableRight", Config->RumbleSettings.DisableRight);
}

const cJSON* pBMStrRescale = cJSON_GetObjectItem(RumbleSettings, "BMStrRescale");
const cJSON* pHeavyRescale = cJSON_GetObjectItem(RumbleSettings, "HeavyRescale");

if (pBMStrRescale)
if (pHeavyRescale)
{
if ((pNode = cJSON_GetObjectItem(pBMStrRescale, "Enabled")))
if ((pNode = cJSON_GetObjectItem(pHeavyRescale, "IsEnabled")))
{
Config->RumbleSettings.BMStrRescale.Enabled = (BOOLEAN)cJSON_IsTrue(pNode);
EventWriteOverrideSettingUInt(RumbleSettings->string, "BMStrRescale.Enabled", Config->RumbleSettings.BMStrRescale.Enabled);
Config->RumbleSettings.HeavyRescaling.IsEnabled = (BOOLEAN)cJSON_IsTrue(pNode);
EventWriteOverrideSettingUInt(RumbleSettings->string, "RumbleSettings.HeavyRescaling.IsEnabled", Config->RumbleSettings.HeavyRescaling.IsEnabled);
}

if ((pNode = cJSON_GetObjectItem(pBMStrRescale, "MinValue")))
if ((pNode = cJSON_GetObjectItem(pHeavyRescale, "RescaleMinRange")))
{
Config->RumbleSettings.BMStrRescale.MinValue = (UCHAR)cJSON_GetNumberValue(pNode);
EventWriteOverrideSettingUInt(RumbleSettings->string, "BMStrRescale.MinValue",
Config->RumbleSettings.BMStrRescale.MinValue);
Config->RumbleSettings.HeavyRescaling.MinRange = (UCHAR)cJSON_GetNumberValue(pNode);
EventWriteOverrideSettingUInt(RumbleSettings->string, "RumbleSettings.HeavyRescaling.MinRange", Config->RumbleSettings.HeavyRescaling.MinRange);
}

if ((pNode = cJSON_GetObjectItem(pBMStrRescale, "MaxValue")))
if ((pNode = cJSON_GetObjectItem(pHeavyRescale, "RescaleMaxRange")))
{
Config->RumbleSettings.BMStrRescale.MaxValue = (UCHAR)cJSON_GetNumberValue(pNode);
EventWriteOverrideSettingUInt(RumbleSettings->string, "BMStrRescale.MaxValue",
Config->RumbleSettings.BMStrRescale.MaxValue);
Config->RumbleSettings.HeavyRescaling.MaxRange = (UCHAR)cJSON_GetNumberValue(pNode);
EventWriteOverrideSettingUInt(RumbleSettings->string, "RumbleSettings.HeavyRescaling.MaxRange", Config->RumbleSettings.HeavyRescaling.MaxRange);
}
}

const cJSON* pSMToBMConversion = cJSON_GetObjectItem(RumbleSettings, "SMToBMConversion");
const cJSON* pAlternativeMode = cJSON_GetObjectItem(RumbleSettings, "AlternativeMode");

if (pSMToBMConversion)
if (pAlternativeMode)
{
if ((pNode = cJSON_GetObjectItem(pSMToBMConversion, "Enabled")))
if ((pNode = cJSON_GetObjectItem(pAlternativeMode, "IsEnabled")))
{
Config->RumbleSettings.SMToBMConversion.Enabled = (BOOLEAN)cJSON_IsTrue(pNode);
EventWriteOverrideSettingUInt(RumbleSettings->string, "SMToBMConversion.Enabled",
Config->RumbleSettings.SMToBMConversion.Enabled);
Config->RumbleSettings.AlternativeMode.IsEnabled = (BOOLEAN)cJSON_IsTrue(pNode);
EventWriteOverrideSettingUInt(RumbleSettings->string, "RumbleSettings.AlternativeMode.IsEnabled", Config->RumbleSettings.AlternativeMode.IsEnabled);
}

if ((pNode = cJSON_GetObjectItem(pSMToBMConversion, "RescaleMinValue")))
if ((pNode = cJSON_GetObjectItem(pAlternativeMode, "RescaleMinRange")))
{
Config->RumbleSettings.SMToBMConversion.RescaleMinValue = (UCHAR)cJSON_GetNumberValue(pNode);
EventWriteOverrideSettingUInt(RumbleSettings->string, "SMToBMConversion.RescaleMinValue",
Config->RumbleSettings.SMToBMConversion.RescaleMinValue);
Config->RumbleSettings.AlternativeMode.MinRange = (UCHAR)cJSON_GetNumberValue(pNode);
EventWriteOverrideSettingUInt(RumbleSettings->string, "RumbleSettings.AlternativeMode.MinRange", Config->RumbleSettings.AlternativeMode.MinRange);
}

if ((pNode = cJSON_GetObjectItem(pSMToBMConversion, "RescaleMaxValue")))
if ((pNode = cJSON_GetObjectItem(pAlternativeMode, "RescaleMaxRange")))
{
Config->RumbleSettings.SMToBMConversion.RescaleMaxValue = (UCHAR)cJSON_GetNumberValue(pNode);
EventWriteOverrideSettingUInt(RumbleSettings->string, "SMToBMConversion.RescaleMaxValue",
Config->RumbleSettings.SMToBMConversion.RescaleMaxValue);
Config->RumbleSettings.AlternativeMode.MaxRange = (UCHAR)cJSON_GetNumberValue(pNode);
EventWriteOverrideSettingUInt(RumbleSettings->string, "RumbleSettings.AlternativeMode.MaxRange", Config->RumbleSettings.AlternativeMode.MaxRange);
}
}

const cJSON* pForcedSM = cJSON_GetObjectItem(RumbleSettings, "ForcedSM");
const cJSON* pForced = cJSON_GetObjectItem(pAlternativeMode, "ForcedRight");

if (pForcedSM)
{
if ((pNode = cJSON_GetObjectItem(pForcedSM, "BMThresholdEnabled")))
if (pForced)
{
Config->RumbleSettings.ForcedSM.BMThresholdEnabled = (BOOLEAN)cJSON_IsTrue(pNode);
EventWriteOverrideSettingUInt(RumbleSettings->string, "ForcedSM.BMThresholdEnabled",
Config->RumbleSettings.ForcedSM.BMThresholdEnabled);
}
if ((pNode = cJSON_GetObjectItem(pForced, "IsHeavyThresholdEnabled")))
{
Config->RumbleSettings.AlternativeMode.ForcedRight.IsHeavyThresholdEnabled = (BOOLEAN)cJSON_IsTrue(pNode);
EventWriteOverrideSettingUInt(RumbleSettings->string, "RumbleSettings.AlternativeMode.ForcedRight.IsHeavyThresholdEnabled", Config->RumbleSettings.AlternativeMode.ForcedRight.IsHeavyThresholdEnabled);
}

if ((pNode = cJSON_GetObjectItem(pForcedSM, "BMThresholdValue")))
{
Config->RumbleSettings.ForcedSM.BMThresholdValue = (UCHAR)cJSON_GetNumberValue(pNode);
EventWriteOverrideSettingUInt(RumbleSettings->string, "ForcedSM.BMThresholdValue",
Config->RumbleSettings.ForcedSM.BMThresholdValue);
}
if ((pNode = cJSON_GetObjectItem(pForced, "IsLightThresholdEnabled")))
{
Config->RumbleSettings.AlternativeMode.ForcedRight.IsLightThresholdEnabled = (BOOLEAN)cJSON_IsTrue(pNode);
EventWriteOverrideSettingUInt(RumbleSettings->string, "RumbleSettings.AlternativeMode.ForcedRight.IsLightThresholdEnabled", Config->RumbleSettings.AlternativeMode.ForcedRight.IsLightThresholdEnabled);
}

if ((pNode = cJSON_GetObjectItem(pForcedSM, "SMThresholdEnabled")))
{
Config->RumbleSettings.ForcedSM.SMThresholdEnabled = (BOOLEAN)cJSON_IsTrue(pNode);
EventWriteOverrideSettingUInt(RumbleSettings->string, "ForcedSM.SMThresholdEnabled",
Config->RumbleSettings.ForcedSM.SMThresholdEnabled);
}
if ((pNode = cJSON_GetObjectItem(pForced, "HeavyThreshold")))
{
Config->RumbleSettings.AlternativeMode.ForcedRight.HeavyThreshold = (UCHAR)cJSON_GetNumberValue(pNode);
EventWriteOverrideSettingUInt(RumbleSettings->string, "RumbleSettings.AlternativeMode.ForcedRight.HeavyThreshold", Config->RumbleSettings.AlternativeMode.ForcedRight.HeavyThreshold);
}

if ((pNode = cJSON_GetObjectItem(pForcedSM, "SMThresholdValue")))
{
Config->RumbleSettings.ForcedSM.SMThresholdValue = (UCHAR)cJSON_GetNumberValue(pNode);
EventWriteOverrideSettingUInt(RumbleSettings->string, "ForcedSM.SMThresholdValue",
Config->RumbleSettings.ForcedSM.SMThresholdValue);
if ((pNode = cJSON_GetObjectItem(pForced, "LightThreshold")))
{
Config->RumbleSettings.AlternativeMode.ForcedRight.LightThreshold = (UCHAR)cJSON_GetNumberValue(pNode);
EventWriteOverrideSettingUInt(RumbleSettings->string, "RumbleSettings.AlternativeMode.ForcedRight.LightThreshold", Config->RumbleSettings.AlternativeMode.ForcedRight.LightThreshold);
}
}
}
}
Expand Down Expand Up @@ -826,69 +817,71 @@ ConfigLoadForDevice(
} while (FALSE);

//
// Verify if SMtoBMConversion values are valid and attempt to calculate rescaling constants in case they are
// Verify if desired new range for heavy rumbling rescale is valid and attempt to calculate rescaling constants if so
//
DS_RUMBLE_SETTINGS* rumbSet = &Context->Configuration.RumbleSettings;
if (
Context->Configuration.RumbleSettings.SMToBMConversion.RescaleMaxValue > Context->Configuration.RumbleSettings.SMToBMConversion.
RescaleMinValue
&& Context->Configuration.RumbleSettings.SMToBMConversion.RescaleMinValue > 0
rumbSet->AlternativeMode.MaxRange > rumbSet->AlternativeMode.MinRange
&& rumbSet->AlternativeMode.MinRange > 0
)
{
Context->Configuration.RumbleSettings.SMToBMConversion.ConstA =
(DOUBLE)(Context->Configuration.RumbleSettings.SMToBMConversion.RescaleMaxValue - Context->Configuration.RumbleSettings.
SMToBMConversion.RescaleMinValue) / (254);
Context->RumbleControlState.AltModeEnabled = rumbSet->AlternativeMode.IsEnabled;

DOUBLE LConstA = (DOUBLE)(rumbSet->AlternativeMode.MaxRange - rumbSet->AlternativeMode.MinRange) / (254);
DOUBLE LConstB = rumbSet->AlternativeMode.MaxRange - LConstA * 255;

Context->Configuration.RumbleSettings.SMToBMConversion.ConstB =
Context->Configuration.RumbleSettings.SMToBMConversion.RescaleMaxValue - Context->Configuration.RumbleSettings.SMToBMConversion.
ConstA * 255;
Context->RumbleControlState.LightRescale.ConstA = LConstA;
Context->RumbleControlState.LightRescale.ConstB = LConstB;
Context->RumbleControlState.LightRescale.IsAllowed = TRUE;

TraceVerbose(
TRACE_CONFIG,
"SMToBMConversion rescaling constants: A = %f and B = %f.",
Context->Configuration.RumbleSettings.SMToBMConversion.ConstA,
Context->Configuration.RumbleSettings.SMToBMConversion.ConstB
"Light rumble rescaling constants: A = %f and B = %f.",
Context->RumbleControlState.LightRescale.ConstA,
Context->RumbleControlState.LightRescale.ConstB
);

}
else
{
TraceVerbose(
TRACE_CONFIG,
"Invalid values found for SMToBMConversion. Setting disabled."
"Disallowing light rumble rescalling because an invalid range was defined"
);
Context->Configuration.RumbleSettings.SMToBMConversion.Enabled = FALSE;
Context->RumbleControlState.LightRescale.IsAllowed = FALSE;
}

//
// Verify if BMStrRescale values are valid and attempt to calculate rescaling constants in case they are
// Verify if desired new range for light rumbling rescale when in alternative mode is valid and attempt to calculate rescaling constants if so
//
if (
Context->Configuration.RumbleSettings.BMStrRescale.MaxValue > Context->Configuration.RumbleSettings.BMStrRescale.MinValue
&& Context->Configuration.RumbleSettings.BMStrRescale.MinValue > 0
rumbSet->HeavyRescaling.MaxRange > rumbSet->HeavyRescaling.MinRange
&& rumbSet->HeavyRescaling.MinRange > 0
)
{
Context->Configuration.RumbleSettings.BMStrRescale.ConstA =
(DOUBLE)(Context->Configuration.RumbleSettings.BMStrRescale.MaxValue - Context->Configuration.RumbleSettings.BMStrRescale.
MinValue) / (254);
Context->RumbleControlState.HeavyRescaleEnabled = rumbSet->HeavyRescaling.IsEnabled;

Context->Configuration.RumbleSettings.BMStrRescale.ConstB =
Context->Configuration.RumbleSettings.BMStrRescale.MaxValue - Context->Configuration.RumbleSettings.BMStrRescale.ConstA * 255;
DOUBLE HConstA = (DOUBLE)(rumbSet->HeavyRescaling.MaxRange - rumbSet->HeavyRescaling.MinRange) / (254);
DOUBLE HConstB = rumbSet->HeavyRescaling.MaxRange - HConstA * 255;

Context->RumbleControlState.HeavyRescale.ConstA = HConstA;
Context->RumbleControlState.HeavyRescale.ConstB = HConstB;
Context->RumbleControlState.HeavyRescale.IsAllowed = TRUE;

TraceVerbose(
TRACE_CONFIG,
"BMStrRescale rescaling constants: A = %f and B = %f.",
Context->Configuration.RumbleSettings.BMStrRescale.ConstA,
Context->Configuration.RumbleSettings.BMStrRescale.ConstB
"Heavy rumble rescaling constants: A = %f and B = %f.",
Context->RumbleControlState.HeavyRescale.ConstA,
Context->RumbleControlState.HeavyRescale.ConstB
);
}
else
{
TraceVerbose(
TRACE_CONFIG,
"Invalid values found for BMStrRescale. Setting disabled."
"Disallowing heavy rumble rescalling because an invalid range was defined"
);

Context->Configuration.RumbleSettings.BMStrRescale.Enabled = FALSE;
Context->RumbleControlState.HeavyRescale.IsAllowed = FALSE;
}

if (config_json)
Expand Down Expand Up @@ -943,18 +936,18 @@ ConfigSetDefaults(
Config->ThumbSettings.DeadZoneRight.Apply = TRUE;
Config->ThumbSettings.DeadZoneRight.PolarValue = 3.0;

Config->RumbleSettings.DisableBM = FALSE;
Config->RumbleSettings.DisableSM = FALSE;
Config->RumbleSettings.BMStrRescale.Enabled = TRUE;
Config->RumbleSettings.BMStrRescale.MinValue = 64;
Config->RumbleSettings.BMStrRescale.MaxValue = 255;
Config->RumbleSettings.SMToBMConversion.Enabled = FALSE;
Config->RumbleSettings.SMToBMConversion.RescaleMinValue = 1;
Config->RumbleSettings.SMToBMConversion.RescaleMaxValue = 140;
Config->RumbleSettings.ForcedSM.BMThresholdEnabled = TRUE;
Config->RumbleSettings.ForcedSM.BMThresholdValue = 230;
Config->RumbleSettings.ForcedSM.SMThresholdEnabled = FALSE;
Config->RumbleSettings.ForcedSM.SMThresholdValue = 230;
Config->RumbleSettings.DisableLeft = FALSE;
Config->RumbleSettings.DisableRight = FALSE;
Config->RumbleSettings.HeavyRescaling.IsEnabled = TRUE;
Config->RumbleSettings.HeavyRescaling.MinRange = 64;
Config->RumbleSettings.HeavyRescaling.MaxRange = 255;
Config->RumbleSettings.AlternativeMode.IsEnabled = FALSE;
Config->RumbleSettings.AlternativeMode.MinRange = 1;
Config->RumbleSettings.AlternativeMode.MaxRange = 110;
Config->RumbleSettings.AlternativeMode.ForcedRight.IsHeavyThresholdEnabled = TRUE;
Config->RumbleSettings.AlternativeMode.ForcedRight.HeavyThreshold = 242;
Config->RumbleSettings.AlternativeMode.ForcedRight.IsLightThresholdEnabled = FALSE;
Config->RumbleSettings.AlternativeMode.ForcedRight.LightThreshold = 242;

Config->LEDSettings.Mode = DsLEDModeBatteryIndicatorPlayerIndex;
Config->LEDSettings.CustomPatterns.LEDFlags = 0x02;
Expand Down
39 changes: 36 additions & 3 deletions sys/Device.h
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,19 @@ typedef struct _DS_OUTPUT_REPORT_CACHE

} DS_OUTPUT_REPORT_CACHE, *PDS_OUTPUT_REPORT_CACHE;

//
// Stores the constants used for rumble rescaling and if it is allowed
//
typedef struct _DS_RESCALE_STATE
{
BOOLEAN IsAllowed;

DOUBLE ConstA;

DOUBLE ConstB;

} DS_RESCALE_STATE, * PDS_RESCALE_STATE;

typedef struct _DEVICE_CONTEXT
{
//
Expand Down Expand Up @@ -296,14 +309,34 @@ typedef struct _DEVICE_CONTEXT
//
// Cache for last received Small Motor Strength value
//
UCHAR Small;
UCHAR LightCache;

//
// Cache for last received Big Motor Strength value
//
UCHAR Big;
UCHAR HeavyCache;

//
// Defines if heavy rumble strength rescaling is requested
//
BOOLEAN HeavyRescaleEnabled;

//
// Defines if alternative rumble mode is enabled
//
BOOLEAN AltModeEnabled;

//
// Current state of heavy rumble rescaling parameters
//
DS_RESCALE_STATE HeavyRescale;

//
// Current state of light rumble rescaling parameters
//
DS_RESCALE_STATE LightRescale;

} MotorStrCache;
} RumbleControlState;

} DEVICE_CONTEXT, * PDEVICE_CONTEXT;

Expand Down
Loading

0 comments on commit da4ed11

Please sign in to comment.