mirror of
https://github.com/spice2x/spice2x.github.io.git
synced 2026-08-01 14:20:42 -07:00
pc: add option to translate absolute analog values to fader input (#375)
## Link to GitHub Issue, if one exists n/a ## Description of change Add a new option that allows absolute position analog input, such as SDVX controller knobs and IIDX turntables, to be bound as input for Polaris Chord faders. In practice this means turning a knob counter-clockwise results in fader being held left (relative to velocity), and vice versa. ## Testing Tested using FauceTwo and a mouse.
This commit is contained in:
@@ -7,8 +7,68 @@
|
||||
#include "games/io.h"
|
||||
#include "io.h"
|
||||
#include "util/tapeled.h"
|
||||
#include "pc.h"
|
||||
#include "util/utils.h"
|
||||
|
||||
namespace games::pc {
|
||||
bool PC_KNOB_MODE = false;
|
||||
|
||||
constexpr float RELATIVE_DECAY = 0.02f;
|
||||
struct FADER_RELATIVE {
|
||||
// ranges from 0.f to 1.f
|
||||
float previous_raw = 0.5f;
|
||||
|
||||
// ranges from -1.f to +1.f
|
||||
float effective_value = 0.f;
|
||||
};
|
||||
|
||||
FADER_RELATIVE fader_l_relative;
|
||||
FADER_RELATIVE fader_r_relative;
|
||||
|
||||
float calculate_analog_raw_delta(float old_value, float new_value) {
|
||||
// assumed that values are between 0.f and 1.f
|
||||
|
||||
float delta = 0.f;
|
||||
if ((old_value < 0.25f) && (0.75f < new_value)) {
|
||||
// wrapped around: going left
|
||||
delta = -((1.f - new_value) + old_value);
|
||||
|
||||
} else if ((new_value < 0.25f) && (0.75f < old_value)) {
|
||||
// wrapped around: going right
|
||||
delta = (1.f - old_value) + new_value;
|
||||
|
||||
} else {
|
||||
delta = new_value - old_value;
|
||||
}
|
||||
return delta;
|
||||
}
|
||||
|
||||
float apply_decay(float val) {
|
||||
// return to center over time
|
||||
if (RELATIVE_DECAY < val) {
|
||||
return val - RELATIVE_DECAY;
|
||||
} else if (val < -RELATIVE_DECAY) {
|
||||
return val + RELATIVE_DECAY;
|
||||
} else {
|
||||
return 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
float get_fader_knob_mode_value(float raw_analog, FADER_RELATIVE &fader) {
|
||||
// add new value...
|
||||
const float delta = calculate_analog_raw_delta(fader.previous_raw, raw_analog);
|
||||
fader.effective_value += (delta * 20.f);
|
||||
fader.previous_raw = raw_analog;
|
||||
|
||||
// capture the result after adding new input value
|
||||
fader.effective_value = CLAMP(fader.effective_value, -1.f, 1.f);
|
||||
const float result = fader.effective_value;
|
||||
|
||||
// post-process for next iteration: apply decay (return to center over time)
|
||||
fader.effective_value = apply_decay(fader.effective_value);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*
|
||||
* class definitions
|
||||
@@ -270,7 +330,13 @@ namespace games::pc {
|
||||
// FADER-L
|
||||
float val = 0.f;
|
||||
if (analogs[Analogs::FaderL].isSet()) {
|
||||
val = (GameAPI::Analogs::getState(RI_MGR, analogs[Analogs::FaderL]) - 0.5f) * 2;
|
||||
if (PC_KNOB_MODE) {
|
||||
val = get_fader_knob_mode_value(
|
||||
GameAPI::Analogs::getState(RI_MGR, analogs[Analogs::FaderL]),
|
||||
fader_l_relative);
|
||||
} else {
|
||||
val = (GameAPI::Analogs::getState(RI_MGR, analogs[Analogs::FaderL]) - 0.5f) * 2;
|
||||
}
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::FaderL_Left]) &&
|
||||
GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::FaderL_Right])) {
|
||||
@@ -289,7 +355,13 @@ namespace games::pc {
|
||||
// FADER-R
|
||||
val = 0.f;
|
||||
if (analogs[Analogs::FaderR].isSet()) {
|
||||
val = (GameAPI::Analogs::getState(RI_MGR, analogs[Analogs::FaderR]) - 0.5f) * 2;
|
||||
if (PC_KNOB_MODE) {
|
||||
val = get_fader_knob_mode_value(
|
||||
GameAPI::Analogs::getState(RI_MGR, analogs[Analogs::FaderR]),
|
||||
fader_r_relative);
|
||||
} else {
|
||||
val = (GameAPI::Analogs::getState(RI_MGR, analogs[Analogs::FaderR]) - 0.5f) * 2;
|
||||
}
|
||||
}
|
||||
if (GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::FaderR_Left]) &&
|
||||
GameAPI::Buttons::getState(RI_MGR, buttons[Buttons::FaderR_Right])) {
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
namespace games::pc {
|
||||
extern std::string PC_INJECT_ARGS;
|
||||
extern bool PC_NO_IO;
|
||||
extern bool PC_KNOB_MODE;
|
||||
|
||||
class PCGame : public games::Game {
|
||||
public:
|
||||
|
||||
@@ -1112,6 +1112,9 @@ int main_implementation(int argc, char *argv[]) {
|
||||
if (options[launcher::Options::PCNoIO].is_active()) {
|
||||
games::pc::PC_NO_IO = options[launcher::Options::PCNoIO].value_bool();
|
||||
}
|
||||
if (options[launcher::Options::PCKnobMode].value_bool()) {
|
||||
games::pc::PC_KNOB_MODE = true;
|
||||
}
|
||||
if (options[launcher::Options::spice2x_EnableSMXStage].value_bool()) {
|
||||
rawinput::ENABLE_SMX_STAGE = true;
|
||||
}
|
||||
|
||||
@@ -1806,6 +1806,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
||||
.category = "Game Options (Advanced)"
|
||||
},
|
||||
{
|
||||
// PCArgs
|
||||
.title = "PC Arguments Override",
|
||||
.name = "pcargs",
|
||||
.desc = "Command line arguments passed to the game.",
|
||||
@@ -1815,6 +1816,7 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
||||
.category = "Game Options (Advanced)",
|
||||
},
|
||||
{
|
||||
// PCNoIO
|
||||
.title = "PC Disable IO Emulation",
|
||||
.name = "pcnoio",
|
||||
.desc = "Disables BI2X hooks for PC",
|
||||
@@ -1823,6 +1825,15 @@ static const std::vector<OptionDefinition> OPTION_DEFINITIONS = {
|
||||
.game_name = "Polaris Chord",
|
||||
.category = "Game Options (Advanced)"
|
||||
},
|
||||
{
|
||||
// PCKnobMode
|
||||
.title = "PC Fader Knobs Mode",
|
||||
.name = "pcknobs",
|
||||
.desc = "Allows SDVX knobs and IIDX turntables to be bound as Polaris Chord faders",
|
||||
.type = OptionType::Bool,
|
||||
.game_name = "Polaris Chord",
|
||||
.category = "Game Options",
|
||||
},
|
||||
{
|
||||
// spice2x_LightsOverallBrightness
|
||||
.title = "Lights Brightness Adjustment",
|
||||
|
||||
@@ -205,6 +205,7 @@ namespace launcher {
|
||||
MFGNoIO,
|
||||
PCArgs,
|
||||
PCNoIO,
|
||||
PCKnobMode,
|
||||
spice2x_LightsOverallBrightness,
|
||||
spice2x_WindowBorder,
|
||||
spice2x_WindowSize,
|
||||
|
||||
Reference in New Issue
Block a user