diff --git a/port/include/input.h b/port/include/input.h index 85b14641b..e3f21f0b3 100644 --- a/port/include/input.h +++ b/port/include/input.h @@ -99,6 +99,12 @@ void inputControllerSetSticksSwapped(s32 swapped); s32 inputControllerGetDualAnalog(void); void inputControllerSetDualAnalog(s32 enable); +f32 inputControllerGetAxisScale(s32 stick, s32 axis); +void inputControllerSetAxisScale(s32 stick, s32 axis, f32 value); + +f32 inputControllerGetAxisDeadzone(s32 stick, s32 axis); +void inputControllerSetAxisDeadzone(s32 stick, s32 axis, f32 value); + // vk is a value from the virtkey enum above s32 inputKeyPressed(u32 vk); diff --git a/port/src/input.c b/port/src/input.c index 2a1b291af..5103dd037 100644 --- a/port/src/input.c +++ b/port/src/input.c @@ -408,8 +408,25 @@ void inputSaveConfig(void) { inputSaveBinds(); + configSetInt("Input.MouseEnabled", mouseEnabled); configSetFloat("Input.MouseSpeedX", mouseSensX); configSetFloat("Input.MouseSpeedY", mouseSensY); + + configSetInt("Input.LStickDeadzoneX", deadzone[0]); + configSetInt("Input.LStickDeadzoneY", deadzone[1]); + configSetInt("Input.RStickDeadzoneX", deadzone[2]); + configSetInt("Input.RStickDeadzoneY", deadzone[3]); + + configSetFloat("Input.LStickScaleX", stickSens[0]); + configSetFloat("Input.LStickScaleY", stickSens[1]); + configSetFloat("Input.RStickScaleX", stickSens[2]); + configSetFloat("Input.RStickScaleY", stickSens[3]); + + configSetFloat("Input.RumbleScale", rumbleScale); + + configSetInt("Input.StickCButtons", stickCButtons); + + configGetInt("Input.SwapSticks", axisMap[0][0] == SDL_CONTROLLER_AXIS_RIGHTX); } s32 inputInit(void) @@ -694,6 +711,26 @@ void inputControllerSetDualAnalog(s32 enable) stickCButtons = !enable; } +f32 inputControllerGetAxisScale(s32 stick, s32 axis) +{ + return stickSens[stick * 2 + axis]; +} + +void inputControllerSetAxisScale(s32 stick, s32 axis, f32 value) +{ + stickSens[stick * 2 + axis] = value; +} + +f32 inputControllerGetAxisDeadzone(s32 stick, s32 axis) +{ + return (f32)deadzone[stick * 2 + axis] / 32767.f; +} + +void inputControllerSetAxisDeadzone(s32 stick, s32 axis, f32 value) +{ + deadzone[stick * 2 + axis] = value * 32767.f; +} + void inputKeyBind(s32 idx, u32 ck, s32 bind, u32 vk) { if (idx < 0 || idx >= INPUT_MAX_CONTROLLERS || bind >= MAX_BINDS || ck >= CK_TOTAL_COUNT) { diff --git a/port/src/optionsmenu.c b/port/src/optionsmenu.c index 33efa966d..f1d827108 100644 --- a/port/src/optionsmenu.c +++ b/port/src/optionsmenu.c @@ -142,10 +142,18 @@ struct menuitem g_ExtendedMouseMenuItems[] = { 0, menuhandlerMouseAimLock, }, + { + MENUITEMTYPE_SEPARATOR, + 0, + 0, + 0, + 0, + NULL, + }, { MENUITEMTYPE_SLIDER, 0, - MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_ALTSIZE, + MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE, (uintptr_t)"Mouse Speed X", 100, menuhandlerMouseSpeedX, @@ -153,7 +161,7 @@ struct menuitem g_ExtendedMouseMenuItems[] = { { MENUITEMTYPE_SLIDER, 0, - MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_ALTSIZE, + MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE, (uintptr_t)"Mouse Speed Y", 100, menuhandlerMouseSpeedY, @@ -161,7 +169,7 @@ struct menuitem g_ExtendedMouseMenuItems[] = { { MENUITEMTYPE_SLIDER, 0, - MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_ALTSIZE, + MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE, (uintptr_t)"Crosshair Speed X", 100, menuhandlerMouseAimSpeedX, @@ -169,7 +177,7 @@ struct menuitem g_ExtendedMouseMenuItems[] = { { MENUITEMTYPE_SLIDER, 0, - MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_ALTSIZE, + MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE, (uintptr_t)"Crosshair Speed Y", 100, menuhandlerMouseAimSpeedY, @@ -202,14 +210,154 @@ struct menudialogdef g_ExtendedMouseMenuDialog = { NULL, }; +static MenuItemHandlerResult menuhandlerStickSpeed(s32 operation, struct menuitem *item, union handlerdata *data); +static MenuItemHandlerResult menuhandlerStickDeadzone(s32 operation, struct menuitem *item, union handlerdata *data); + +struct menuitem g_ExtendedStickMenuItems[] = { + { + MENUITEMTYPE_SLIDER, + 0, + MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE, + (uintptr_t)"LStick Scale X", + 20, + menuhandlerStickSpeed, + }, + { + MENUITEMTYPE_SLIDER, + 0, + MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE, + (uintptr_t)"LStick Scale Y", + 20, + menuhandlerStickSpeed, + }, + { + MENUITEMTYPE_SLIDER, + 0, + MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE, + (uintptr_t)"RStick Scale X", + 20, + menuhandlerStickSpeed, + }, + { + MENUITEMTYPE_SLIDER, + 0, + MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE, + (uintptr_t)"RStick Scale Y", + 20, + menuhandlerStickSpeed, + }, + { + MENUITEMTYPE_SEPARATOR, + 0, + 0, + 0, + 0, + NULL, + }, + { + MENUITEMTYPE_SLIDER, + 0, + MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE, + (uintptr_t)"LStick Deadzone X", + 32, + menuhandlerStickDeadzone, + }, + { + MENUITEMTYPE_SLIDER, + 0, + MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE, + (uintptr_t)"LStick Deadzone Y", + 32, + menuhandlerStickDeadzone, + }, + { + MENUITEMTYPE_SLIDER, + 0, + MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE, + (uintptr_t)"RStick Deadzone X", + 32, + menuhandlerStickDeadzone, + }, + { + MENUITEMTYPE_SLIDER, + 0, + MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE, + (uintptr_t)"RStick Deadzone Y", + 32, + menuhandlerStickDeadzone, + }, + { + MENUITEMTYPE_SEPARATOR, + 0, + 0, + 0, + 0, + NULL, + }, + { + MENUITEMTYPE_SELECTABLE, + 0, + MENUITEMFLAG_SELECTABLE_CLOSESDIALOG, + L_OPTIONS_213, // "Back" + 0, + NULL, + }, + { MENUITEMTYPE_END }, +}; + +static MenuItemHandlerResult menuhandlerStickSpeed(s32 operation, struct menuitem *item, union handlerdata *data) +{ + const s32 idx = item - g_ExtendedStickMenuItems; + const s32 stick = idx / 2; + const s32 axis = idx % 2; + + switch (operation) { + case MENUOP_GETSLIDER: + data->slider.value = inputControllerGetAxisScale(stick, axis) * 10.f + 0.5f; + break; + case MENUOP_SET: + inputControllerSetAxisScale(stick, axis, (f32)data->slider.value / 10.f); + break; + } + + return 0; +} + +static MenuItemHandlerResult menuhandlerStickDeadzone(s32 operation, struct menuitem *item, union handlerdata *data) +{ + const s32 idx = item - (g_ExtendedStickMenuItems + 5); + const s32 stick = idx / 2; + const s32 axis = idx % 2; + + switch (operation) { + case MENUOP_GETSLIDER: + data->slider.value = inputControllerGetAxisDeadzone(stick, axis) * 32.f + 0.5f; + break; + case MENUOP_SET: + inputControllerSetAxisDeadzone(stick, axis, (f32)data->slider.value / 32.f); + break; + } + + return 0; +} + +struct menudialogdef g_ExtendedStickMenuDialog = { + MENUDIALOGTYPE_DEFAULT, + (uintptr_t)"Analog Stick Settings", + g_ExtendedStickMenuItems, + NULL, + MENUDIALOGFLAG_LITERAL_TEXT, + NULL, +}; + static MenuItemHandlerResult menuhandlerVibration(s32 operation, struct menuitem *item, union handlerdata *data) { switch (operation) { case MENUOP_GETSLIDER: - data->slider.value = inputRumbleGetStrength() * 100.f + 0.5f; + data->slider.value = inputRumbleGetStrength() * 10.f + 0.5f; break; case MENUOP_SET: - inputRumbleSetStrength((f32)data->slider.value / 100.f); + inputRumbleSetStrength((f32)data->slider.value / 10.f); break; } @@ -259,12 +407,20 @@ struct menuitem g_ExtendedControllerMenuItems[] = { 0, menuhandlerSwapSticks, }, + { + MENUITEMTYPE_SELECTABLE, + 0, + MENUITEMFLAG_SELECTABLE_OPENSDIALOG | MENUITEMFLAG_LITERAL_TEXT, + (uintptr_t)"Stick Settings...\n", + 0, + (void *)&g_ExtendedStickMenuDialog, + }, { MENUITEMTYPE_SLIDER, 0, MENUITEMFLAG_LITERAL_TEXT, (uintptr_t)"Vibration", - 100, + 10, menuhandlerVibration, }, { @@ -494,7 +650,7 @@ struct menuitem g_ExtendedGameMenuItems[] = { { MENUITEMTYPE_SLIDER, 0, - MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_ALTSIZE, + MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE, (uintptr_t)"Crosshair Sway", 20, menuhandlerCrosshairSway, @@ -502,7 +658,7 @@ struct menuitem g_ExtendedGameMenuItems[] = { { MENUITEMTYPE_SLIDER, 0, - MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_ALTSIZE, + MENUITEMFLAG_LITERAL_TEXT | MENUITEMFLAG_SLIDER_WIDE, (uintptr_t)"Explosion Shake", 20, menuhandlerScreenShake, diff --git a/src/game/menu.c b/src/game/menu.c index fa29c900d..b8d1633e9 100644 --- a/src/game/menu.c +++ b/src/game/menu.c @@ -670,6 +670,9 @@ void menuCalculateItemSize(struct menuitem *item, s16 *width, s16 *height, struc if (item->flags & MENUITEMFLAG_SLIDER_ALTSIZE) { *height = 22; *width = 120; + } else if (item->flags & MENUITEMFLAG_SLIDER_WIDE) { + *width = 200; + *height = VERSION == VERSION_JPN_FINAL ? 14 : 12; } break; case MENUITEMTYPE_CHECKBOX: diff --git a/src/include/constants.h b/src/include/constants.h index e2751bdcf..cb7b93a7f 100644 --- a/src/include/constants.h +++ b/src/include/constants.h @@ -1662,6 +1662,7 @@ #define MENUITEMFLAG_LESSHEIGHT 0x02000000 #define MENUITEMFLAG_CAROUSEL_04000000 0x04000000 #define MENUITEMFLAG_LITERAL_TEXT 0x08000000 +#define MENUITEMFLAG_SLIDER_WIDE 0x10000000 #define MENUITEMTYPE_LABEL 0x01 #define MENUITEMTYPE_LIST 0x02