separate all analog settings per stick (#1401)
* separate all analog settings per stick * remove old variables * align toggles * merge fix
This commit is contained in:
@@ -47,30 +47,58 @@
|
||||
#define FORCED_CIRCULARITY_ENABLED 0
|
||||
#endif
|
||||
|
||||
#ifndef FORCED_CIRCULARITY2_ENABLED
|
||||
#define FORCED_CIRCULARITY2_ENABLED 0
|
||||
#endif
|
||||
|
||||
#ifndef DEFAULT_INNER_DEADZONE
|
||||
#define DEFAULT_INNER_DEADZONE 5
|
||||
#endif
|
||||
|
||||
#ifndef DEFAULT_INNER_DEADZONE2
|
||||
#define DEFAULT_INNER_DEADZONE2 5
|
||||
#endif
|
||||
|
||||
#ifndef DEFAULT_OUTER_DEADZONE
|
||||
#define DEFAULT_OUTER_DEADZONE 95
|
||||
#endif
|
||||
|
||||
#ifndef DEFAULT_OUTER_DEADZONE2
|
||||
#define DEFAULT_OUTER_DEADZONE2 95
|
||||
#endif
|
||||
|
||||
#ifndef AUTO_CALIBRATE_ENABLED
|
||||
#define AUTO_CALIBRATE_ENABLED 0
|
||||
#endif
|
||||
|
||||
#ifndef AUTO_CALIBRATE2_ENABLED
|
||||
#define AUTO_CALIBRATE2_ENABLED 0
|
||||
#endif
|
||||
|
||||
#ifndef ANALOG_SMOOTHING_ENABLED
|
||||
#define ANALOG_SMOOTHING_ENABLED 0
|
||||
#endif
|
||||
|
||||
#ifndef ANALOG_SMOOTHING2_ENABLED
|
||||
#define ANALOG_SMOOTHING2_ENABLED 0
|
||||
#endif
|
||||
|
||||
#ifndef SMOOTHING_FACTOR
|
||||
#define SMOOTHING_FACTOR 5
|
||||
#endif
|
||||
|
||||
#ifndef SMOOTHING_FACTOR2
|
||||
#define SMOOTHING_FACTOR2 5
|
||||
#endif
|
||||
|
||||
#ifndef ANALOG_ERROR
|
||||
#define ANALOG_ERROR 1000
|
||||
#endif
|
||||
|
||||
#ifndef ANALOG_ERROR2
|
||||
#define ANALOG_ERROR2 1000
|
||||
#endif
|
||||
|
||||
// Analog Module Name
|
||||
#define AnalogName "Analog"
|
||||
|
||||
@@ -93,6 +121,13 @@ typedef struct
|
||||
DpadMode analog_dpad;
|
||||
float x_ema;
|
||||
float y_ema;
|
||||
bool ema_option;
|
||||
float ema_smoothing;
|
||||
float error_rate;
|
||||
float in_deadzone;
|
||||
float out_deadzone;
|
||||
bool auto_calibration;
|
||||
bool forced_circularity;
|
||||
} adc_instance;
|
||||
|
||||
class AnalogInput : public GPAddon {
|
||||
@@ -105,19 +140,12 @@ public:
|
||||
virtual void reinit() {}
|
||||
virtual std::string name() { return AnalogName; }
|
||||
private:
|
||||
float readPin(Pin_t pin, uint16_t center);
|
||||
float emaCalculation(float ema_value, float ema_previous);
|
||||
float readPin(int stick_num, Pin_t pin, uint16_t center);
|
||||
float emaCalculation(int stick_num, float ema_value, float ema_previous);
|
||||
uint16_t map(uint16_t x, uint16_t in_min, uint16_t in_max, uint16_t out_min, uint16_t out_max);
|
||||
float magnitudeCalculation(adc_instance & adc_inst);
|
||||
void radialDeadzone(adc_instance & adc_inst);
|
||||
float magnitudeCalculation(int stick_num, adc_instance & adc_inst);
|
||||
void radialDeadzone(int stick_num, adc_instance & adc_inst);
|
||||
adc_instance adc_pairs[ADC_COUNT];
|
||||
bool ema_option;
|
||||
float ema_smoothing;
|
||||
float error_rate;
|
||||
float in_deadzone;
|
||||
float out_deadzone;
|
||||
bool auto_calibration;
|
||||
bool forced_circularity;
|
||||
};
|
||||
|
||||
#endif // _Analog_H_
|
||||
@@ -411,6 +411,13 @@ message AnalogOptions
|
||||
optional bool analog_smoothing = 14;
|
||||
optional float smoothing_factor = 15;
|
||||
optional uint32 analog_error = 16;
|
||||
optional bool analog_smoothing2 = 17;
|
||||
optional float smoothing_factor2 = 18;
|
||||
optional uint32 analog_error2 = 19;
|
||||
optional uint32 inner_deadzone2 = 20;
|
||||
optional uint32 outer_deadzone2 = 21;
|
||||
optional bool auto_calibrate2 = 22;
|
||||
optional bool forced_circularity2 = 23;
|
||||
}
|
||||
|
||||
message TurboOptions
|
||||
|
||||
@@ -26,10 +26,25 @@ void AnalogInput::setup() {
|
||||
adc_pairs[0].y_pin = analogOptions.analogAdc1PinY;
|
||||
adc_pairs[0].analog_invert = analogOptions.analogAdc1Invert;
|
||||
adc_pairs[0].analog_dpad = analogOptions.analogAdc1Mode;
|
||||
adc_pairs[0].ema_option = analogOptions.analog_smoothing;
|
||||
adc_pairs[0].ema_smoothing = analogOptions.smoothing_factor / 1000.0f;
|
||||
adc_pairs[0].error_rate = analogOptions.analog_error / 1000.0f;
|
||||
adc_pairs[0].in_deadzone = analogOptions.inner_deadzone / 100.0f;
|
||||
adc_pairs[0].out_deadzone = analogOptions.outer_deadzone / 100.0f;
|
||||
adc_pairs[0].auto_calibration = analogOptions.auto_calibrate;
|
||||
adc_pairs[0].forced_circularity = analogOptions.forced_circularity;
|
||||
adc_pairs[1].x_pin = analogOptions.analogAdc2PinX;
|
||||
adc_pairs[1].y_pin = analogOptions.analogAdc2PinY;
|
||||
adc_pairs[1].analog_invert = analogOptions.analogAdc2Invert;
|
||||
adc_pairs[1].analog_dpad = analogOptions.analogAdc2Mode;
|
||||
adc_pairs[1].ema_option = analogOptions.analog_smoothing2;
|
||||
adc_pairs[1].ema_smoothing = analogOptions.smoothing_factor2 / 1000.0f;
|
||||
adc_pairs[1].error_rate = analogOptions.analog_error2 / 1000.0f;
|
||||
adc_pairs[1].in_deadzone = analogOptions.inner_deadzone2 / 100.0f;
|
||||
adc_pairs[1].out_deadzone = analogOptions.outer_deadzone2 / 100.0f;
|
||||
adc_pairs[1].auto_calibration = analogOptions.auto_calibrate2;
|
||||
adc_pairs[1].forced_circularity = analogOptions.forced_circularity2;
|
||||
|
||||
|
||||
// Setup defaults and helpers
|
||||
for (int i = 0; i < ADC_COUNT; i++) {
|
||||
@@ -48,28 +63,19 @@ void AnalogInput::setup() {
|
||||
for (int i = 0; i < ADC_COUNT; i++) {
|
||||
if(isValidPin(adc_pairs[i].x_pin)) {
|
||||
adc_gpio_init(adc_pairs[i].x_pin);
|
||||
if (analogOptions.auto_calibrate) {
|
||||
if (adc_pairs[i].auto_calibration) {
|
||||
adc_select_input(adc_pairs[i].x_pin - ADC_PIN_OFFSET);
|
||||
adc_pairs[i].x_center = adc_read();
|
||||
}
|
||||
}
|
||||
if(isValidPin(adc_pairs[i].y_pin)) {
|
||||
adc_gpio_init(adc_pairs[i].y_pin);
|
||||
if (analogOptions.auto_calibrate) {
|
||||
if (adc_pairs[i].auto_calibration) {
|
||||
adc_select_input(adc_pairs[i].y_pin - ADC_PIN_OFFSET);
|
||||
adc_pairs[i].y_center = adc_read();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Read options from Analog Options
|
||||
ema_option = analogOptions.analog_smoothing;
|
||||
ema_smoothing = analogOptions.smoothing_factor / 1000.0f;
|
||||
error_rate = analogOptions.analog_error / 1000.0f;
|
||||
in_deadzone = analogOptions.inner_deadzone / 100.0f;
|
||||
out_deadzone = analogOptions.outer_deadzone / 100.0f;
|
||||
auto_calibration = analogOptions.auto_calibrate;
|
||||
forced_circularity = analogOptions.forced_circularity;
|
||||
}
|
||||
|
||||
void AnalogInput::process() {
|
||||
@@ -83,35 +89,35 @@ void AnalogInput::process() {
|
||||
for(int i = 0; i < ADC_COUNT; i++) {
|
||||
// Read X-Axis
|
||||
if (isValidPin(adc_pairs[i].x_pin)) {
|
||||
adc_pairs[i].x_value = readPin(adc_pairs[i].x_pin_adc, adc_pairs[i].x_center);
|
||||
adc_pairs[i].x_value = readPin(i, adc_pairs[i].x_pin_adc, adc_pairs[i].x_center);
|
||||
if (adc_pairs[i].analog_invert == InvertMode::INVERT_X ||
|
||||
adc_pairs[i].analog_invert == InvertMode::INVERT_XY) {
|
||||
adc_pairs[i].x_value = ANALOG_MAX - adc_pairs[i].x_value;
|
||||
}
|
||||
if (ema_option) {
|
||||
adc_pairs[i].x_value = emaCalculation(adc_pairs[i].x_value, adc_pairs[i].x_ema);
|
||||
if (adc_pairs[i].ema_option) {
|
||||
adc_pairs[i].x_value = emaCalculation(i, adc_pairs[i].x_value, adc_pairs[i].x_ema);
|
||||
adc_pairs[i].x_ema = adc_pairs[i].x_value;
|
||||
}
|
||||
}
|
||||
// Read Y-Axis
|
||||
if (isValidPin(adc_pairs[i].y_pin)) {
|
||||
adc_pairs[i].y_value = readPin(adc_pairs[i].y_pin_adc, adc_pairs[i].y_center);
|
||||
adc_pairs[i].y_value = readPin(i, adc_pairs[i].y_pin_adc, adc_pairs[i].y_center);
|
||||
if (adc_pairs[i].analog_invert == InvertMode::INVERT_Y ||
|
||||
adc_pairs[i].analog_invert == InvertMode::INVERT_XY) {
|
||||
adc_pairs[i].y_value = ANALOG_MAX - adc_pairs[i].y_value;
|
||||
}
|
||||
if (ema_option) {
|
||||
adc_pairs[i].y_value = emaCalculation(adc_pairs[i].y_value, adc_pairs[i].y_ema);
|
||||
if (adc_pairs[i].ema_option) {
|
||||
adc_pairs[i].y_value = emaCalculation(i, adc_pairs[i].y_value, adc_pairs[i].y_ema);
|
||||
adc_pairs[i].y_ema = adc_pairs[i].y_value;
|
||||
}
|
||||
}
|
||||
// Look for dead-zones and circularity
|
||||
adc_pairs[i].xy_magnitude = magnitudeCalculation(adc_pairs[i]);
|
||||
if (adc_pairs[i].xy_magnitude < in_deadzone) {
|
||||
adc_pairs[i].xy_magnitude = magnitudeCalculation(i, adc_pairs[i]);
|
||||
if (adc_pairs[i].xy_magnitude < adc_pairs[i].in_deadzone) {
|
||||
adc_pairs[i].x_value = ANALOG_CENTER;
|
||||
adc_pairs[i].y_value = ANALOG_CENTER;
|
||||
} else {
|
||||
radialDeadzone(adc_pairs[i]);
|
||||
radialDeadzone(i, adc_pairs[i]);
|
||||
}
|
||||
|
||||
if (adc_pairs[i].analog_dpad == DpadMode::DPAD_MODE_LEFT_ANALOG) {
|
||||
@@ -134,10 +140,10 @@ void AnalogInput::process() {
|
||||
}
|
||||
}
|
||||
|
||||
float AnalogInput::readPin(Pin_t pin_adc, uint16_t center) {
|
||||
float AnalogInput::readPin(int stick_num, Pin_t pin_adc, uint16_t center) {
|
||||
adc_select_input(pin_adc);
|
||||
uint16_t adc_value = adc_read();
|
||||
if (auto_calibration) {
|
||||
if (adc_pairs[stick_num].auto_calibration) {
|
||||
if (adc_value > center) {
|
||||
adc_value = map(adc_value, center, ADC_MAX, ADC_MAX / 2, ADC_MAX);
|
||||
} else if (adc_value == center) {
|
||||
@@ -149,23 +155,23 @@ float AnalogInput::readPin(Pin_t pin_adc, uint16_t center) {
|
||||
return ((float)adc_value) / ADC_MAX;
|
||||
}
|
||||
|
||||
float AnalogInput::emaCalculation(float ema_value, float ema_previous) {
|
||||
return (ema_smoothing * ema_value) + ((1.0f - ema_smoothing) * ema_previous);
|
||||
float AnalogInput::emaCalculation(int stick_num, float ema_value, float ema_previous) {
|
||||
return (adc_pairs[stick_num].ema_smoothing * ema_value) + ((1.0f - adc_pairs[stick_num].ema_smoothing) * ema_previous);
|
||||
}
|
||||
|
||||
uint16_t AnalogInput::map(uint16_t x, uint16_t in_min, uint16_t in_max, uint16_t out_min, uint16_t out_max) {
|
||||
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
|
||||
}
|
||||
|
||||
float AnalogInput::magnitudeCalculation(adc_instance & adc_inst) {
|
||||
float AnalogInput::magnitudeCalculation(int stick_num, adc_instance & adc_inst) {
|
||||
adc_inst.x_magnitude = adc_inst.x_value - ANALOG_CENTER;
|
||||
adc_inst.y_magnitude = adc_inst.y_value - ANALOG_CENTER;
|
||||
return error_rate * std::sqrt((adc_inst.x_magnitude * adc_inst.x_magnitude) + (adc_inst.y_magnitude * adc_inst.y_magnitude));
|
||||
return adc_pairs[stick_num].error_rate * std::sqrt((adc_inst.x_magnitude * adc_inst.x_magnitude) + (adc_inst.y_magnitude * adc_inst.y_magnitude));
|
||||
}
|
||||
|
||||
void AnalogInput::radialDeadzone(adc_instance & adc_inst) {
|
||||
float scaling_factor = (adc_inst.xy_magnitude - in_deadzone) / (out_deadzone - in_deadzone);
|
||||
if (forced_circularity == true) {
|
||||
void AnalogInput::radialDeadzone(int stick_num, adc_instance & adc_inst) {
|
||||
float scaling_factor = (adc_inst.xy_magnitude - adc_pairs[stick_num].in_deadzone) / (adc_pairs[stick_num].out_deadzone - adc_pairs[stick_num].in_deadzone);
|
||||
if (adc_pairs[stick_num].forced_circularity == true) {
|
||||
scaling_factor = std::fmin(scaling_factor, ANALOG_CENTER);
|
||||
}
|
||||
adc_inst.x_value = ((adc_inst.x_magnitude / adc_inst.xy_magnitude) * scaling_factor) + ANALOG_CENTER;
|
||||
|
||||
@@ -609,6 +609,13 @@ void ConfigUtils::initUnsetPropertiesWithDefaults(Config& config)
|
||||
INIT_UNSET_PROPERTY(config.addonOptions.analogOptions, analog_smoothing, !!ANALOG_SMOOTHING_ENABLED);
|
||||
INIT_UNSET_PROPERTY(config.addonOptions.analogOptions, smoothing_factor, !!SMOOTHING_FACTOR);
|
||||
INIT_UNSET_PROPERTY(config.addonOptions.analogOptions, analog_error, ANALOG_ERROR);
|
||||
INIT_UNSET_PROPERTY(config.addonOptions.analogOptions, analog_smoothing2, !!ANALOG_SMOOTHING2_ENABLED);
|
||||
INIT_UNSET_PROPERTY(config.addonOptions.analogOptions, smoothing_factor2, !!SMOOTHING_FACTOR2);
|
||||
INIT_UNSET_PROPERTY(config.addonOptions.analogOptions, analog_error2, ANALOG_ERROR2);
|
||||
INIT_UNSET_PROPERTY(config.addonOptions.analogOptions, inner_deadzone2, DEFAULT_INNER_DEADZONE2);
|
||||
INIT_UNSET_PROPERTY(config.addonOptions.analogOptions, outer_deadzone2, DEFAULT_OUTER_DEADZONE2);
|
||||
INIT_UNSET_PROPERTY(config.addonOptions.analogOptions, auto_calibrate2, !!AUTO_CALIBRATE2_ENABLED);
|
||||
INIT_UNSET_PROPERTY(config.addonOptions.analogOptions, forced_circularity2, !!FORCED_CIRCULARITY2_ENABLED);
|
||||
|
||||
// addonOptions.turboOptions
|
||||
INIT_UNSET_PROPERTY(config.addonOptions.turboOptions, enabled, !!TURBO_ENABLED);
|
||||
|
||||
@@ -1508,12 +1508,19 @@ std::string setAddonOptions()
|
||||
docToValue(analogOptions.analogAdc2Mode, doc, "analogAdc2Mode");
|
||||
docToValue(analogOptions.analogAdc2Invert, doc, "analogAdc2Invert");
|
||||
docToValue(analogOptions.forced_circularity, doc, "forced_circularity");
|
||||
docToValue(analogOptions.forced_circularity2, doc, "forced_circularity2");
|
||||
docToValue(analogOptions.inner_deadzone, doc, "inner_deadzone");
|
||||
docToValue(analogOptions.inner_deadzone2, doc, "inner_deadzone2");
|
||||
docToValue(analogOptions.outer_deadzone, doc, "outer_deadzone");
|
||||
docToValue(analogOptions.outer_deadzone2, doc, "outer_deadzone2");
|
||||
docToValue(analogOptions.auto_calibrate, doc, "auto_calibrate");
|
||||
docToValue(analogOptions.auto_calibrate2, doc, "auto_calibrate2");
|
||||
docToValue(analogOptions.analog_smoothing, doc, "analog_smoothing");
|
||||
docToValue(analogOptions.analog_smoothing2, doc, "analog_smoothing2");
|
||||
docToValue(analogOptions.smoothing_factor, doc, "smoothing_factor");
|
||||
docToValue(analogOptions.smoothing_factor2, doc, "smoothing_factor2");
|
||||
docToValue(analogOptions.analog_error, doc, "analog_error");
|
||||
docToValue(analogOptions.analog_error2, doc, "analog_error2");
|
||||
docToValue(analogOptions.enabled, doc, "AnalogInputEnabled");
|
||||
|
||||
BootselButtonOptions& bootselButtonOptions = Storage::getInstance().getAddonOptions().bootselButtonOptions;
|
||||
@@ -1930,12 +1937,19 @@ std::string getAddonOptions()
|
||||
writeDoc(doc, "analogAdc2Mode", analogOptions.analogAdc2Mode);
|
||||
writeDoc(doc, "analogAdc2Invert", analogOptions.analogAdc2Invert);
|
||||
writeDoc(doc, "forced_circularity", analogOptions.forced_circularity);
|
||||
writeDoc(doc, "forced_circularity2", analogOptions.forced_circularity2);
|
||||
writeDoc(doc, "inner_deadzone", analogOptions.inner_deadzone);
|
||||
writeDoc(doc, "inner_deadzone2", analogOptions.inner_deadzone2);
|
||||
writeDoc(doc, "outer_deadzone", analogOptions.outer_deadzone);
|
||||
writeDoc(doc, "outer_deadzone2", analogOptions.outer_deadzone2);
|
||||
writeDoc(doc, "auto_calibrate", analogOptions.auto_calibrate);
|
||||
writeDoc(doc, "auto_calibrate2", analogOptions.auto_calibrate2);
|
||||
writeDoc(doc, "analog_smoothing", analogOptions.analog_smoothing);
|
||||
writeDoc(doc, "analog_smoothing2", analogOptions.analog_smoothing2);
|
||||
writeDoc(doc, "smoothing_factor", analogOptions.smoothing_factor);
|
||||
writeDoc(doc, "smoothing_factor2", analogOptions.smoothing_factor2);
|
||||
writeDoc(doc, "analog_error", analogOptions.analog_error);
|
||||
writeDoc(doc, "analog_error2", analogOptions.analog_error2);
|
||||
writeDoc(doc, "AnalogInputEnabled", analogOptions.enabled);
|
||||
|
||||
const BootselButtonOptions& bootselButtonOptions = Storage::getInstance().getAddonOptions().bootselButtonOptions;
|
||||
|
||||
@@ -460,12 +460,19 @@ app.get('/api/getAddonsOptions', (req, res) => {
|
||||
analogAdc2Mode: 2,
|
||||
analogAdc2Invert: 0,
|
||||
forced_circularity: 0,
|
||||
forced_circularity2: 0,
|
||||
inner_deadzone: 5,
|
||||
inner_deadzone2: 5,
|
||||
outer_deadzone: 95,
|
||||
outer_deadzone2: 95,
|
||||
auto_calibrate: 0,
|
||||
auto_calibrate2: 0,
|
||||
analog_smoothing: 0,
|
||||
analog_smoothing2: 0,
|
||||
smoothing_factor: 5,
|
||||
smoothing_factor2: 5,
|
||||
analog_error: 1000,
|
||||
analog_error2: 1000,
|
||||
bootselButtonMap: 0,
|
||||
buzzerPin: -1,
|
||||
buzzerEnablePin: -1,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useContext } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { FormCheck, Row } from 'react-bootstrap';
|
||||
import { FormCheck, Row, Tab, Tabs } from 'react-bootstrap';
|
||||
import * as yup from 'yup';
|
||||
|
||||
import Section from '../Components/Section';
|
||||
@@ -80,30 +80,58 @@ export const analogScheme = {
|
||||
.number()
|
||||
.label('Force Circularity')
|
||||
.validateRangeWhenValue('AnalogInputEnabled', 0, 1),
|
||||
forced_circularity2: yup
|
||||
.number()
|
||||
.label('Force Circularity')
|
||||
.validateRangeWhenValue('AnalogInputEnabled', 0, 1),
|
||||
inner_deadzone: yup
|
||||
.number()
|
||||
.label('Inner Deadzone Size (%)')
|
||||
.validateRangeWhenValue('AnalogInputEnabled', 0, 100),
|
||||
inner_deadzone2: yup
|
||||
.number()
|
||||
.label('Inner Deadzone Size (%)')
|
||||
.validateRangeWhenValue('AnalogInputEnabled', 0, 100),
|
||||
outer_deadzone: yup
|
||||
.number()
|
||||
.label('Outer Deadzone Size (%)')
|
||||
.validateRangeWhenValue('AnalogInputEnabled', 0, 100),
|
||||
outer_deadzone2: yup
|
||||
.number()
|
||||
.label('Outer Deadzone Size (%)')
|
||||
.validateRangeWhenValue('AnalogInputEnabled', 0, 100),
|
||||
auto_calibrate: yup
|
||||
.number()
|
||||
.label('Auto Calibration')
|
||||
.validateRangeWhenValue('AnalogInputEnabled', 0, 1),
|
||||
auto_calibrate2: yup
|
||||
.number()
|
||||
.label('Auto Calibration')
|
||||
.validateRangeWhenValue('AnalogInputEnabled', 0, 1),
|
||||
analog_smoothing: yup
|
||||
.number()
|
||||
.label('Analog Smoothing')
|
||||
.validateRangeWhenValue('AnalogInputEnabled', 0, 1),
|
||||
analog_smoothing2: yup
|
||||
.number()
|
||||
.label('Analog Smoothing 2')
|
||||
.validateRangeWhenValue('AnalogInputEnabled', 0, 1),
|
||||
smoothing_factor: yup
|
||||
.number()
|
||||
.label('Smoothing Factor')
|
||||
.validateRangeWhenValue('AnalogInputEnabled', 0, 100),
|
||||
smoothing_factor2: yup
|
||||
.number()
|
||||
.label('Smoothing Factor 2')
|
||||
.validateRangeWhenValue('AnalogInputEnabled', 0, 100),
|
||||
analog_error: yup
|
||||
.number()
|
||||
.label('Error Rate')
|
||||
.validateSelectionWhenValue('AnalogInputEnabled', ANALOG_ERROR_RATES),
|
||||
analog_error2: yup
|
||||
.number()
|
||||
.label('Error Rate 2')
|
||||
.validateSelectionWhenValue('AnalogInputEnabled', ANALOG_ERROR_RATES),
|
||||
};
|
||||
|
||||
export const analogState = {
|
||||
@@ -118,11 +146,17 @@ export const analogState = {
|
||||
analogAdc2Invert: 0,
|
||||
forced_circularity: 0,
|
||||
inner_deadzone: 5,
|
||||
inner_deadzone2: 5,
|
||||
outer_deadzone: 95,
|
||||
outer_deadzone2: 95,
|
||||
auto_calibrate: 0,
|
||||
auto_calibrate2: 0,
|
||||
analog_smoothing: 0,
|
||||
analog_smoothing2: 0,
|
||||
smoothing_factor: 5,
|
||||
smoothing_factor2: 5,
|
||||
analog_error: 1,
|
||||
analog_error2: 1,
|
||||
};
|
||||
|
||||
const Analog = ({ values, errors, handleChange, handleCheckbox }) => {
|
||||
@@ -152,222 +186,345 @@ const Analog = ({ values, errors, handleChange, handleCheckbox }) => {
|
||||
pins: availableAnalogPins.join(', '),
|
||||
})}
|
||||
</div>
|
||||
<Row className="mb-3">
|
||||
<FormSelect
|
||||
label={t('AddonsConfig:analog-adc-1-pin-x-label')}
|
||||
name="analogAdc1PinX"
|
||||
className="form-select-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.analogAdc1PinX}
|
||||
error={errors.analogAdc1PinX}
|
||||
isInvalid={errors.analogAdc1PinX}
|
||||
onChange={handleChange}
|
||||
<Tabs
|
||||
defaultActiveKey="analog1Config"
|
||||
id="analogConfigTabs"
|
||||
className="mb-3 pb-0"
|
||||
fill
|
||||
>
|
||||
<AnalogPinOptions />
|
||||
</FormSelect>
|
||||
<FormSelect
|
||||
label={t('AddonsConfig:analog-adc-1-pin-y-label')}
|
||||
name="analogAdc1PinY"
|
||||
className="form-select-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.analogAdc1PinY}
|
||||
error={errors.analogAdc1PinY}
|
||||
isInvalid={errors.analogAdc1PinY}
|
||||
onChange={handleChange}
|
||||
>
|
||||
<AnalogPinOptions />
|
||||
</FormSelect>
|
||||
<FormSelect
|
||||
label={t('AddonsConfig:analog-adc-1-mode-label')}
|
||||
name="analogAdc1Mode"
|
||||
className="form-select-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.analogAdc1Mode}
|
||||
error={errors.analogAdc1Mode}
|
||||
isInvalid={errors.analogAdc1Mode}
|
||||
onChange={handleChange}
|
||||
>
|
||||
{ANALOG_STICK_MODES.map((o, i) => (
|
||||
<option key={`button-analogAdc1Mode-option-${i}`} value={o.value}>
|
||||
{o.label}
|
||||
</option>
|
||||
))}
|
||||
</FormSelect>
|
||||
<FormSelect
|
||||
label={t('AddonsConfig:analog-adc-1-invert-label')}
|
||||
name="analogAdc1Invert"
|
||||
className="form-select-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.analogAdc1Invert}
|
||||
error={errors.analogAdc1Invert}
|
||||
isInvalid={errors.analogAdc1Invert}
|
||||
onChange={handleChange}
|
||||
>
|
||||
{INVERT_MODES.map((o, i) => (
|
||||
<option
|
||||
key={`button-analogAdc1Invert-option-${i}`}
|
||||
value={o.value}
|
||||
>
|
||||
{o.label}
|
||||
</option>
|
||||
))}
|
||||
</FormSelect>
|
||||
</Row>
|
||||
<Row className="mb-3">
|
||||
<FormSelect
|
||||
label={t('AddonsConfig:analog-adc-2-pin-x-label')}
|
||||
name="analogAdc2PinX"
|
||||
className="form-select-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.analogAdc2PinX}
|
||||
error={errors.analogAdc2PinX}
|
||||
isInvalid={errors.analogAdc2PinX}
|
||||
onChange={handleChange}
|
||||
>
|
||||
<AnalogPinOptions />
|
||||
</FormSelect>
|
||||
<FormSelect
|
||||
label={t('AddonsConfig:analog-adc-2-pin-y-label')}
|
||||
name="analogAdc2PinY"
|
||||
className="form-select-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.analogAdc2PinY}
|
||||
error={errors.analogAdc2PinY}
|
||||
isInvalid={errors.analogAdc2PinY}
|
||||
onChange={handleChange}
|
||||
>
|
||||
<AnalogPinOptions />
|
||||
</FormSelect>
|
||||
<FormSelect
|
||||
label={t('AddonsConfig:analog-adc-2-mode-label')}
|
||||
name="analogAdc2Mode"
|
||||
className="form-select-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.analogAdc2Mode}
|
||||
error={errors.analogAdc2Mode}
|
||||
isInvalid={errors.analogAdc2Mode}
|
||||
onChange={handleChange}
|
||||
>
|
||||
{ANALOG_STICK_MODES.map((o, i) => (
|
||||
<option key={`button-analogAdc2Mode-option-${i}`} value={o.value}>
|
||||
{o.label}
|
||||
</option>
|
||||
))}
|
||||
</FormSelect>
|
||||
<FormSelect
|
||||
label={t('AddonsConfig:analog-adc-2-invert-label')}
|
||||
name="analogAdc2Invert"
|
||||
className="form-select-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.analogAdc2Invert}
|
||||
error={errors.analogAdc2Invert}
|
||||
isInvalid={errors.analogAdc2Invert}
|
||||
onChange={handleChange}
|
||||
>
|
||||
{INVERT_MODES.map((o, i) => (
|
||||
<option
|
||||
key={`button-analogAdc2Invert-option-${i}`}
|
||||
value={o.value}
|
||||
>
|
||||
{o.label}
|
||||
</option>
|
||||
))}
|
||||
</FormSelect>
|
||||
</Row>
|
||||
<Row className="mb-3">
|
||||
<FormControl
|
||||
type="number"
|
||||
label={t('AddonsConfig:inner-deadzone-size')}
|
||||
name="inner_deadzone"
|
||||
className="form-control-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.inner_deadzone}
|
||||
error={errors.inner_deadzone}
|
||||
isInvalid={errors.inner_deadzone}
|
||||
onChange={handleChange}
|
||||
min={0}
|
||||
max={100}
|
||||
/>
|
||||
<FormControl
|
||||
type="number"
|
||||
label={t('AddonsConfig:outer-deadzone-size')}
|
||||
name="outer_deadzone"
|
||||
className="form-control-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.outer_deadzone}
|
||||
error={errors.outer_deadzone}
|
||||
isInvalid={errors.outer_deadzone}
|
||||
onChange={handleChange}
|
||||
min={0}
|
||||
max={100}
|
||||
/>
|
||||
|
||||
<FormSelect
|
||||
hidden={!values.forced_circularity}
|
||||
label={t('AddonsConfig:analog-error-label')}
|
||||
name="analog_error"
|
||||
className="form-control-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.analog_error}
|
||||
onChange={handleChange}
|
||||
>
|
||||
{ANALOG_ERROR_RATES.map((o, i) => (
|
||||
<option key={`analog_error-option-${i}`} value={o.value}>
|
||||
{o.label}
|
||||
</option>
|
||||
))}
|
||||
</FormSelect>
|
||||
<FormControl
|
||||
hidden={!values.analog_smoothing}
|
||||
type="number"
|
||||
label={t('AddonsConfig:smoothing-factor')}
|
||||
name="smoothing_factor"
|
||||
className="form-control-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.smoothing_factor}
|
||||
error={errors.smoothing_factor}
|
||||
isInvalid={errors.smoothing_factor}
|
||||
onChange={handleChange}
|
||||
min={0}
|
||||
max={100}
|
||||
/>
|
||||
<FormCheck
|
||||
label={t('AddonsConfig:analog-force-circularity')}
|
||||
type="switch"
|
||||
id="Forced_circularity"
|
||||
className="col-sm-3 ms-2"
|
||||
isInvalid={false}
|
||||
checked={Boolean(values.forced_circularity)}
|
||||
onChange={(e) => {
|
||||
handleCheckbox('forced_circularity', values);
|
||||
handleChange(e);
|
||||
}}
|
||||
/>
|
||||
<FormCheck
|
||||
label={t('AddonsConfig:analog-auto-calibrate')}
|
||||
type="switch"
|
||||
id="Auto_calibrate"
|
||||
className="col-sm-3 ms-2"
|
||||
isInvalid={false}
|
||||
checked={Boolean(values.auto_calibrate)}
|
||||
onChange={(e) => {
|
||||
handleCheckbox('auto_calibrate', values);
|
||||
handleChange(e);
|
||||
}}
|
||||
/>
|
||||
<FormCheck
|
||||
label={t('AddonsConfig:analog-smoothing')}
|
||||
type="switch"
|
||||
id="Analog_smoothing"
|
||||
className="col-sm-3 ms-2"
|
||||
isInvalid={false}
|
||||
checked={Boolean(values.analog_smoothing)}
|
||||
onChange={(e) => {
|
||||
handleCheckbox('analog_smoothing', values);
|
||||
handleChange(e);
|
||||
}}
|
||||
/>
|
||||
</Row>
|
||||
<Tab
|
||||
key="analog1Config"
|
||||
eventKey="analog1Config"
|
||||
title={t('Analog Stick 1')}
|
||||
>
|
||||
<Row className="mb-3">
|
||||
<FormSelect
|
||||
label={t('AddonsConfig:analog-adc-1-pin-x-label')}
|
||||
name="analogAdc1PinX"
|
||||
className="form-select-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.analogAdc1PinX}
|
||||
error={errors.analogAdc1PinX}
|
||||
isInvalid={errors.analogAdc1PinX}
|
||||
onChange={handleChange}
|
||||
>
|
||||
<AnalogPinOptions />
|
||||
</FormSelect>
|
||||
<FormSelect
|
||||
label={t('AddonsConfig:analog-adc-1-pin-y-label')}
|
||||
name="analogAdc1PinY"
|
||||
className="form-select-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.analogAdc1PinY}
|
||||
error={errors.analogAdc1PinY}
|
||||
isInvalid={errors.analogAdc1PinY}
|
||||
onChange={handleChange}
|
||||
>
|
||||
<AnalogPinOptions />
|
||||
</FormSelect>
|
||||
<Row className="mb-3">
|
||||
<FormSelect
|
||||
label={t('AddonsConfig:analog-adc-1-mode-label')}
|
||||
name="analogAdc1Mode"
|
||||
className="form-select-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.analogAdc1Mode}
|
||||
error={errors.analogAdc1Mode}
|
||||
isInvalid={errors.analogAdc1Mode}
|
||||
onChange={handleChange}
|
||||
>
|
||||
{ANALOG_STICK_MODES.map((o, i) => (
|
||||
<option key={`button-analogAdc1Mode-option-${i}`} value={o.value}>
|
||||
{o.label}
|
||||
</option>
|
||||
))}
|
||||
</FormSelect>
|
||||
<FormSelect
|
||||
label={t('AddonsConfig:analog-adc-1-invert-label')}
|
||||
name="analogAdc1Invert"
|
||||
className="form-select-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.analogAdc1Invert}
|
||||
error={errors.analogAdc1Invert}
|
||||
isInvalid={errors.analogAdc1Invert}
|
||||
onChange={handleChange}
|
||||
>
|
||||
{INVERT_MODES.map((o, i) => (
|
||||
<option
|
||||
key={`button-analogAdc1Invert-option-${i}`}
|
||||
value={o.value}
|
||||
>
|
||||
{o.label}
|
||||
</option>
|
||||
))}
|
||||
</FormSelect>
|
||||
</Row>
|
||||
<Row className="mb-3">
|
||||
<FormControl
|
||||
type="number"
|
||||
label={t('AddonsConfig:inner-deadzone-size')}
|
||||
name="inner_deadzone"
|
||||
className="form-control-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.inner_deadzone}
|
||||
error={errors.inner_deadzone}
|
||||
isInvalid={errors.inner_deadzone}
|
||||
onChange={handleChange}
|
||||
min={0}
|
||||
max={100}
|
||||
/>
|
||||
<FormControl
|
||||
type="number"
|
||||
label={t('AddonsConfig:outer-deadzone-size')}
|
||||
name="outer_deadzone"
|
||||
className="form-control-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.outer_deadzone}
|
||||
error={errors.outer_deadzone}
|
||||
isInvalid={errors.outer_deadzone}
|
||||
onChange={handleChange}
|
||||
min={0}
|
||||
max={100}
|
||||
/>
|
||||
</Row>
|
||||
<Row className="mb-3">
|
||||
<FormCheck
|
||||
label={t('AddonsConfig:analog-smoothing')}
|
||||
type="switch"
|
||||
id="Analog_smoothing"
|
||||
className="col-sm-3 ms-3"
|
||||
isInvalid={false}
|
||||
checked={Boolean(values.analog_smoothing)}
|
||||
onChange={(e) => {
|
||||
handleCheckbox('analog_smoothing', values);
|
||||
handleChange(e);
|
||||
}}
|
||||
/>
|
||||
<FormControl
|
||||
hidden={!values.analog_smoothing}
|
||||
type="number"
|
||||
label={t('AddonsConfig:smoothing-factor')}
|
||||
name="smoothing_factor"
|
||||
className="form-control-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.smoothing_factor}
|
||||
error={errors.smoothing_factor}
|
||||
isInvalid={errors.smoothing_factor}
|
||||
onChange={handleChange}
|
||||
min={0}
|
||||
max={100}
|
||||
/>
|
||||
</Row>
|
||||
<Row className="mb-3">
|
||||
<FormCheck
|
||||
label={t('AddonsConfig:analog-force-circularity')}
|
||||
type="switch"
|
||||
id="Forced_circularity"
|
||||
className="col-sm-3 ms-3"
|
||||
isInvalid={false}
|
||||
checked={Boolean(values.forced_circularity)}
|
||||
onChange={(e) => {
|
||||
handleCheckbox('forced_circularity', values);
|
||||
handleChange(e);
|
||||
}}
|
||||
/>
|
||||
<FormSelect
|
||||
hidden={!values.forced_circularity}
|
||||
label={t('AddonsConfig:analog-error-label')}
|
||||
name="analog_error"
|
||||
className="form-control-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.analog_error}
|
||||
onChange={handleChange}
|
||||
>
|
||||
{ANALOG_ERROR_RATES.map((o, i) => (
|
||||
<option key={`analog_error-option-${i}`} value={o.value}>
|
||||
{o.label}
|
||||
</option>
|
||||
))}
|
||||
</FormSelect>
|
||||
</Row>
|
||||
<FormCheck
|
||||
label={t('AddonsConfig:analog-auto-calibrate')}
|
||||
type="switch"
|
||||
id="Auto_calibrate"
|
||||
className="col-sm-3 ms-3"
|
||||
isInvalid={false}
|
||||
checked={Boolean(values.auto_calibrate)}
|
||||
onChange={(e) => {
|
||||
handleCheckbox('auto_calibrate', values);
|
||||
handleChange(e);
|
||||
}}
|
||||
/>
|
||||
</Row>
|
||||
</Tab>
|
||||
<Tab
|
||||
key="analog2Config"
|
||||
eventKey="analog2Config"
|
||||
title={t('Analog Stick 2')}
|
||||
>
|
||||
<Row className="mb-3">
|
||||
<FormSelect
|
||||
label={t('AddonsConfig:analog-adc-2-pin-x-label')}
|
||||
name="analogAdc2PinX"
|
||||
className="form-select-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.analogAdc2PinX}
|
||||
error={errors.analogAdc2PinX}
|
||||
isInvalid={errors.analogAdc2PinX}
|
||||
onChange={handleChange}
|
||||
>
|
||||
<AnalogPinOptions />
|
||||
</FormSelect>
|
||||
<FormSelect
|
||||
label={t('AddonsConfig:analog-adc-2-pin-y-label')}
|
||||
name="analogAdc2PinY"
|
||||
className="form-select-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.analogAdc2PinY}
|
||||
error={errors.analogAdc2PinY}
|
||||
isInvalid={errors.analogAdc2PinY}
|
||||
onChange={handleChange}
|
||||
>
|
||||
<AnalogPinOptions />
|
||||
</FormSelect>
|
||||
<Row className="mb-3">
|
||||
<FormSelect
|
||||
label={t('AddonsConfig:analog-adc-2-mode-label')}
|
||||
name="analogAdc2Mode"
|
||||
className="form-select-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.analogAdc2Mode}
|
||||
error={errors.analogAdc2Mode}
|
||||
isInvalid={errors.analogAdc2Mode}
|
||||
onChange={handleChange}
|
||||
>
|
||||
{ANALOG_STICK_MODES.map((o, i) => (
|
||||
<option key={`button-analogAdc2Mode-option-${i}`} value={o.value}>
|
||||
{o.label}
|
||||
</option>
|
||||
))}
|
||||
</FormSelect>
|
||||
<FormSelect
|
||||
label={t('AddonsConfig:analog-adc-2-invert-label')}
|
||||
name="analogAdc2Invert"
|
||||
className="form-select-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.analogAdc2Invert}
|
||||
error={errors.analogAdc2Invert}
|
||||
isInvalid={errors.analogAdc2Invert}
|
||||
onChange={handleChange}
|
||||
>
|
||||
{INVERT_MODES.map((o, i) => (
|
||||
<option
|
||||
key={`button-analogAdc2Invert-option-${i}`}
|
||||
value={o.value}
|
||||
>
|
||||
{o.label}
|
||||
</option>
|
||||
))}
|
||||
</FormSelect>
|
||||
</Row>
|
||||
<Row className="mb-3">
|
||||
<FormControl
|
||||
type="number"
|
||||
label={t('AddonsConfig:inner-deadzone-size')}
|
||||
name="inner_deadzone2"
|
||||
className="form-control-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.inner_deadzone2}
|
||||
error={errors.inner_deadzone2}
|
||||
isInvalid={errors.inner_deadzone2}
|
||||
onChange={handleChange}
|
||||
min={0}
|
||||
max={100}
|
||||
/>
|
||||
<FormControl
|
||||
type="number"
|
||||
label={t('AddonsConfig:outer-deadzone-size')}
|
||||
name="outer_deadzone2"
|
||||
className="form-control-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.outer_deadzone2}
|
||||
error={errors.outer_deadzone2}
|
||||
isInvalid={errors.outer_deadzone2}
|
||||
onChange={handleChange}
|
||||
min={0}
|
||||
max={100}
|
||||
/>
|
||||
</Row>
|
||||
<Row className="mb-3">
|
||||
<FormCheck
|
||||
label={t('AddonsConfig:analog-smoothing')}
|
||||
type="switch"
|
||||
id="Analog_smoothing2"
|
||||
className="col-sm-3 ms-3"
|
||||
isInvalid={false}
|
||||
checked={Boolean(values.analog_smoothing2)}
|
||||
onChange={(e) => {
|
||||
handleCheckbox('analog_smoothing2', values);
|
||||
handleChange(e);
|
||||
}}
|
||||
/>
|
||||
<FormControl
|
||||
hidden={!values.analog_smoothing2}
|
||||
type="number"
|
||||
label={t('AddonsConfig:smoothing-factor')}
|
||||
name="smoothing_factor2"
|
||||
className="form-control-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.smoothing_factor2}
|
||||
error={errors.smoothing_factor2}
|
||||
isInvalid={errors.smoothing_factor2}
|
||||
onChange={handleChange}
|
||||
min={0}
|
||||
max={100}
|
||||
/>
|
||||
</Row>
|
||||
<Row className="mb-3">
|
||||
<FormCheck
|
||||
label={t('AddonsConfig:analog-force-circularity')}
|
||||
type="switch"
|
||||
id="Forced_circularity2"
|
||||
className="col-sm-3 ms-3"
|
||||
isInvalid={false}
|
||||
checked={Boolean(values.forced_circularity2)}
|
||||
onChange={(e) => {
|
||||
handleCheckbox('forced_circularity2', values);
|
||||
handleChange(e);
|
||||
}}
|
||||
/>
|
||||
<FormSelect
|
||||
hidden={!values.forced_circularity2}
|
||||
label={t('AddonsConfig:analog-error-label')}
|
||||
name="analog_error2"
|
||||
className="form-control-sm"
|
||||
groupClassName="col-sm-3 mb-3"
|
||||
value={values.analog_error2}
|
||||
onChange={handleChange}
|
||||
>
|
||||
{ANALOG_ERROR_RATES.map((o, i) => (
|
||||
<option key={`analog_error-option-${i}`} value={o.value}>
|
||||
{o.label}
|
||||
</option>
|
||||
))}
|
||||
</FormSelect>
|
||||
</Row>
|
||||
<FormCheck
|
||||
label={t('AddonsConfig:analog-auto-calibrate')}
|
||||
type="switch"
|
||||
id="Auto_calibrate2"
|
||||
className="col-sm-3 ms-3"
|
||||
isInvalid={false}
|
||||
checked={Boolean(values.auto_calibrate2)}
|
||||
onChange={(e) => {
|
||||
handleCheckbox('auto_calibrate2', values);
|
||||
handleChange(e);
|
||||
}}
|
||||
/>
|
||||
</Row>
|
||||
</Tab>
|
||||
</Tabs>
|
||||
</div>
|
||||
<FormCheck
|
||||
label={t('Common:switch-enabled')}
|
||||
|
||||
Reference in New Issue
Block a user