Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

User-definable input modes on boot #635

Merged
merged 1 commit into from
Nov 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions headers/gp2040.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
#ifndef GP2040_H_
#define GP2040_H_

#include <map>

// GP2040 Classes
#include "gamepad.h"
#include "addonmanager.h"
Expand Down Expand Up @@ -48,6 +50,9 @@ class GP2040 {
SET_INPUT_MODE_PS4
};
BootAction getBootAction();

// input mask, action
std::map<uint32_t, int32_t> bootActions;
};

#endif
8 changes: 8 additions & 0 deletions proto/config.proto
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,14 @@ message GamepadOptions
optional uint32 profileNumber = 9;
optional PS4ControllerType ps4ControllerType = 10;
optional uint32 debounceDelay = 11;
optional int32 inputModeB1 = 12;
optional int32 inputModeB2 = 13;
optional int32 inputModeB3 = 14;
optional int32 inputModeB4 = 15;
optional int32 inputModeL1 = 16;
optional int32 inputModeL2 = 17;
optional int32 inputModeR1 = 18;
optional int32 inputModeR2 = 19;
}

message KeyboardMapping
Expand Down
32 changes: 32 additions & 0 deletions src/config_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,30 @@
#ifndef DEFAULT_INPUT_MODE
#define DEFAULT_INPUT_MODE INPUT_MODE_XINPUT
#endif
#ifndef DEFAULT_INPUT_MODE_B1
#define DEFAULT_INPUT_MODE_B1 INPUT_MODE_SWITCH
#endif
#ifndef DEFAULT_INPUT_MODE_B2
#define DEFAULT_INPUT_MODE_B2 INPUT_MODE_XINPUT
#endif
#ifndef DEFAULT_INPUT_MODE_B3
#define DEFAULT_INPUT_MODE_B3 INPUT_MODE_HID
#endif
#ifndef DEFAULT_INPUT_MODE_B4
#define DEFAULT_INPUT_MODE_B4 INPUT_MODE_PS4
#endif
#ifndef DEFAULT_INPUT_MODE_L1
#define DEFAULT_INPUT_MODE_L1 -1
#endif
#ifndef DEFAULT_INPUT_MODE_L2
#define DEFAULT_INPUT_MODE_L2 -1
#endif
#ifndef DEFAULT_INPUT_MODE_R1
#define DEFAULT_INPUT_MODE_R1 -1
#endif
#ifndef DEFAULT_INPUT_MODE_R2
#define DEFAULT_INPUT_MODE_R2 INPUT_MODE_KEYBOARD
#endif
#ifndef DEFAULT_DPAD_MODE
#define DEFAULT_DPAD_MODE DPAD_MODE_DIGITAL
#endif
Expand Down Expand Up @@ -114,6 +138,14 @@ void ConfigUtils::initUnsetPropertiesWithDefaults(Config& config)
INIT_UNSET_PROPERTY(config.gamepadOptions, profileNumber, 1);
INIT_UNSET_PROPERTY(config.gamepadOptions, ps4ControllerType, DEFAULT_PS4CONTROLLER_TYPE);
INIT_UNSET_PROPERTY(config.gamepadOptions, debounceDelay, 5);
INIT_UNSET_PROPERTY(config.gamepadOptions, inputModeB1, DEFAULT_INPUT_MODE_B1);
INIT_UNSET_PROPERTY(config.gamepadOptions, inputModeB2, DEFAULT_INPUT_MODE_B2);
INIT_UNSET_PROPERTY(config.gamepadOptions, inputModeB3, DEFAULT_INPUT_MODE_B3);
INIT_UNSET_PROPERTY(config.gamepadOptions, inputModeB4, DEFAULT_INPUT_MODE_B4);
INIT_UNSET_PROPERTY(config.gamepadOptions, inputModeL1, DEFAULT_INPUT_MODE_L1);
INIT_UNSET_PROPERTY(config.gamepadOptions, inputModeL2, DEFAULT_INPUT_MODE_L2);
INIT_UNSET_PROPERTY(config.gamepadOptions, inputModeR1, DEFAULT_INPUT_MODE_R1);
INIT_UNSET_PROPERTY(config.gamepadOptions, inputModeR2, DEFAULT_INPUT_MODE_R2);

// hotkeyOptions
HotkeyOptions& hotkeyOptions = config.hotkeyOptions;
Expand Down
16 changes: 16 additions & 0 deletions src/configs/webconfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,14 @@ std::string setGamepadOptions()
readDoc(gamepadOptions.profileNumber, doc, "profileNumber");
readDoc(gamepadOptions.ps4ControllerType, doc, "ps4ControllerType");
readDoc(gamepadOptions.debounceDelay, doc, "debounceDelay");
readDoc(gamepadOptions.inputModeB1, doc, "inputModeB1");
readDoc(gamepadOptions.inputModeB2, doc, "inputModeB2");
readDoc(gamepadOptions.inputModeB3, doc, "inputModeB3");
readDoc(gamepadOptions.inputModeB4, doc, "inputModeB4");
readDoc(gamepadOptions.inputModeL1, doc, "inputModeL1");
readDoc(gamepadOptions.inputModeL2, doc, "inputModeL2");
readDoc(gamepadOptions.inputModeR1, doc, "inputModeR1");
readDoc(gamepadOptions.inputModeR2, doc, "inputModeR2");

HotkeyOptions& hotkeyOptions = Storage::getInstance().getHotkeyOptions();
save_hotkey(&hotkeyOptions.hotkey01, doc, "hotkey01");
Expand Down Expand Up @@ -660,6 +668,14 @@ std::string getGamepadOptions()
writeDoc(doc, "profileNumber", gamepadOptions.profileNumber);
writeDoc(doc, "ps4ControllerType", gamepadOptions.ps4ControllerType);
writeDoc(doc, "debounceDelay", gamepadOptions.debounceDelay);
writeDoc(doc, "inputModeB1", gamepadOptions.inputModeB1);
writeDoc(doc, "inputModeB2", gamepadOptions.inputModeB2);
writeDoc(doc, "inputModeB3", gamepadOptions.inputModeB3);
writeDoc(doc, "inputModeB4", gamepadOptions.inputModeB4);
writeDoc(doc, "inputModeL1", gamepadOptions.inputModeL1);
writeDoc(doc, "inputModeL2", gamepadOptions.inputModeL2);
writeDoc(doc, "inputModeR1", gamepadOptions.inputModeR1);
writeDoc(doc, "inputModeR2", gamepadOptions.inputModeR2);

writeDoc(doc, "fnButtonPin", -1);
GpioMappingInfo* gpioMappings = Storage::getInstance().getGpioMappings().pins;
Expand Down
57 changes: 38 additions & 19 deletions src/gp2040.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,19 @@ void GP2040::setup() {
Gamepad * gamepad = Storage::getInstance().GetGamepad();
gamepad->setup();

const GamepadOptions& gamepadOptions = Storage::getInstance().getGamepadOptions();

// check setup options and add modes to the list
// user modes
bootActions.insert({GAMEPAD_MASK_B1, gamepadOptions.inputModeB1});
bootActions.insert({GAMEPAD_MASK_B2, gamepadOptions.inputModeB2});
bootActions.insert({GAMEPAD_MASK_B3, gamepadOptions.inputModeB3});
bootActions.insert({GAMEPAD_MASK_B4, gamepadOptions.inputModeB4});
bootActions.insert({GAMEPAD_MASK_L1, gamepadOptions.inputModeL1});
bootActions.insert({GAMEPAD_MASK_L2, gamepadOptions.inputModeL2});
bootActions.insert({GAMEPAD_MASK_R1, gamepadOptions.inputModeR1});
bootActions.insert({GAMEPAD_MASK_R2, gamepadOptions.inputModeR2});

// Initialize our ADC (various add-ons)
adc_init();

Expand All @@ -79,7 +92,6 @@ void GP2040::setup() {
addons.LoadAddon(new TiltInput(), CORE0_INPUT);
addons.LoadAddon(new InputMacro(), CORE0_INPUT);


const BootAction bootAction = getBootAction();

switch (bootAction) {
Expand Down Expand Up @@ -205,30 +217,37 @@ GP2040::BootAction GP2040::getBootAction() {
// Copy Processed Gamepad for Core1 (race condition otherwise)
memcpy(&processedGamepad->state, &gamepad->state, sizeof(GamepadState));

ForcedSetupOptions& forcedSetupOptions = Storage::getInstance().getForcedSetupOptions();
bool modeSwitchLocked = forcedSetupOptions.mode == FORCED_SETUP_MODE_LOCK_MODE_SWITCH ||
forcedSetupOptions.mode == FORCED_SETUP_MODE_LOCK_BOTH;
const ForcedSetupOptions& forcedSetupOptions = Storage::getInstance().getForcedSetupOptions();
bool modeSwitchLocked = forcedSetupOptions.mode == FORCED_SETUP_MODE_LOCK_MODE_SWITCH ||
forcedSetupOptions.mode == FORCED_SETUP_MODE_LOCK_BOTH;

bool webConfigLocked = forcedSetupOptions.mode == FORCED_SETUP_MODE_LOCK_WEB_CONFIG ||
forcedSetupOptions.mode == FORCED_SETUP_MODE_LOCK_BOTH;
bool webConfigLocked = forcedSetupOptions.mode == FORCED_SETUP_MODE_LOCK_WEB_CONFIG ||
forcedSetupOptions.mode == FORCED_SETUP_MODE_LOCK_BOTH;

if (gamepad->pressedS1() && gamepad->pressedS2() && gamepad->pressedUp()) {
return BootAction::ENTER_USB_MODE;
} else if (!webConfigLocked && gamepad->pressedS2()) {
return BootAction::ENTER_WEBCONFIG_MODE;
} else if (!modeSwitchLocked && gamepad->pressedB3()) { // P1
return BootAction::SET_INPUT_MODE_HID;
} else if (!modeSwitchLocked && gamepad->pressedB4()) { // P2
return BootAction::SET_INPUT_MODE_PS4;
} else if (!modeSwitchLocked && gamepad->pressedB1()) { // K1
return BootAction::SET_INPUT_MODE_SWITCH;
} else if (!modeSwitchLocked && gamepad->pressedB2()) { // K2
return BootAction::SET_INPUT_MODE_XINPUT;
} else if (!modeSwitchLocked && gamepad->pressedR2()) { // K3
return BootAction::SET_INPUT_MODE_KEYBOARD;
} else {
return BootAction::NONE;
}
} else {
if (!modeSwitchLocked) {
if (auto search = bootActions.find(gamepad->state.buttons); search != bootActions.end()) {
switch (search->second) {
case INPUT_MODE_XINPUT:
return BootAction::SET_INPUT_MODE_XINPUT;
case INPUT_MODE_SWITCH:
return BootAction::SET_INPUT_MODE_SWITCH;
case INPUT_MODE_HID:
return BootAction::SET_INPUT_MODE_HID;
case INPUT_MODE_KEYBOARD:
return BootAction::SET_INPUT_MODE_KEYBOARD;
case INPUT_MODE_PS4:
return BootAction::SET_INPUT_MODE_PS4;
default:
return BootAction::NONE;
}
}
}
}

break;
}
Expand Down
8 changes: 8 additions & 0 deletions www/server/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,14 @@ app.get('/api/getGamepadOptions', (req, res) => {
profileNumber: 1,
ps4ControllerType: 0,
debounceDelay: 5,
inputModeB1: 1,
inputModeB2: 0,
inputModeB3: 2,
inputModeB4: 4,
inputModeL1: -1,
inputModeL2: -1,
inputModeR1: -1,
inputModeR2: 3,
hotkey01: {
auxMask: 32768,
buttonsMask: 66304,
Expand Down
2 changes: 2 additions & 0 deletions www/src/Locales/en/SettingsPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ export default {
'input-mode-label': 'Input Mode',
'input-mode-extra-label': 'Switch Touchpad and Share',
'input-mode-options': {
none: 'No Mode Selected',
xinput: 'XInput',
'nintendo-switch': 'Nintendo Switch',
ps3: 'PS3/DirectInput',
keyboard: 'Keyboard',
ps4: 'PS4',
},
'boot-input-mode-label': 'Boot Input Modes',
'ps4-mode-options': {
controller: 'Controller',
arcadestick: 'Arcade Stick',
Expand Down
91 changes: 91 additions & 0 deletions www/src/Pages/SettingsPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@ const INPUT_MODES = [
{ labelKey: 'input-mode-options.ps4', value: PS4Mode },
];

const INPUT_BOOT_MODES = [
{ labelKey: 'input-mode-options.none', value: -1 },
{ labelKey: 'input-mode-options.xinput', value: 0 },
{ labelKey: 'input-mode-options.nintendo-switch', value: 1 },
{ labelKey: 'input-mode-options.ps3', value: 2 },
{ labelKey: 'input-mode-options.keyboard', value: 3 },
{ labelKey: 'input-mode-options.ps4', value: PS4Mode },
];

const DPAD_MODES = [
{ labelKey: 'd-pad-mode-options.d-pad', value: 0 },
{ labelKey: 'd-pad-mode-options.left-analog', value: 1 },
Expand Down Expand Up @@ -83,6 +92,17 @@ const FORCED_SETUP_MODES = [
{ labelKey: 'forced-setup-mode-options.disable-both', value: 3 },
];

const INPUT_MODES_BINDS = [
{ value: 'B1' },
{ value: 'B2' },
{ value: 'B3' },
{ value: 'B4' },
{ value: 'L1' },
{ value: 'L2' },
{ value: 'R1' },
{ value: 'R2' },
];

const hotkeySchema = {
action: yup
.number()
Expand Down Expand Up @@ -140,6 +160,46 @@ const schema = yup.object().shape({
.oneOf(PS4_MODES.map((o) => o.value))
.label('PS4 Controller Type'),
debounceDelay: yup.number().required().label('Debounce Delay'),
inputModeB1: yup
.number()
.required()
.oneOf(INPUT_BOOT_MODES.map((o) => o.value))
.label('B1 Input Mode'),
inputModeB2: yup
.number()
.required()
.oneOf(INPUT_BOOT_MODES.map((o) => o.value))
.label('B2 Input Mode'),
inputModeB3: yup
.number()
.required()
.oneOf(INPUT_BOOT_MODES.map((o) => o.value))
.label('B3 Input Mode'),
inputModeB4: yup
.number()
.required()
.oneOf(INPUT_BOOT_MODES.map((o) => o.value))
.label('B4 Input Mode'),
inputModeL1: yup
.number()
.required()
.oneOf(INPUT_BOOT_MODES.map((o) => o.value))
.label('L1 Input Mode'),
inputModeL2: yup
.number()
.required()
.oneOf(INPUT_BOOT_MODES.map((o) => o.value))
.label('L2 Input Mode'),
inputModeR1: yup
.number()
.required()
.oneOf(INPUT_BOOT_MODES.map((o) => o.value))
.label('R1 Input Mode'),
inputModeR2: yup
.number()
.required()
.oneOf(INPUT_BOOT_MODES.map((o) => o.value))
.label('R2 Input Mode'),
});

const FormContext = ({ setButtonLabels }) => {
Expand Down Expand Up @@ -239,6 +299,7 @@ export default function SettingsPage() {

const { t } = useTranslation('');

const translatedInputBootModes = translateArray(INPUT_BOOT_MODES);
const translatedInputModes = translateArray(INPUT_MODES);
const translatedDpadModes = translateArray(DPAD_MODES);
const translatedSocdModes = translateArray(SOCD_MODES);
Expand Down Expand Up @@ -462,6 +523,36 @@ export default function SettingsPage() {
</div>
</Form.Group>
</Section>
<Section title={t('SettingsPage:boot-input-mode-label')}>
<div className="row col-sm-3">
{INPUT_MODES_BINDS.map((mode) => (
<Form.Group className="mb-3 col-sm-6">
<Form.Label>{ (mode.value in currentButtonLabels)? currentButtonLabels[mode.value]:mode.value}</Form.Label>
<div className="col-12">
<Form.Select
name={`inputMode${mode.value}`}
className="form-select-sm"
value={values[`inputMode${mode.value}`]}
onChange={handleChange}
isInvalid={errors[`inputMode${mode.value}`]}
>
{translatedInputBootModes.map((o, i) => (
<option
key={`button-inputMode-${mode.value.toString().toLowerCase()}-option-${i}`}
value={o.value}
>
{o.label}
</option>
))}
</Form.Select>
<Form.Control.Feedback type="invalid">
{errors[`inputMode${mode.value}`]}
</Form.Control.Feedback>
</div>
</Form.Group>
))}
</div>
</Section>
<Section title={t('SettingsPage:hotkey-settings-label')}>
<div className="mb-3">
<Trans ns="SettingsPage" i18nKey="hotkey-settings-sub-header">
Expand Down