diff --git a/src/d_main.cpp b/src/d_main.cpp index a6508b31d..697ee1dbe 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -93,7 +93,7 @@ #define ASSET_HASH_TEXTURES_KART 0xb4211b2f32b6a291 #define ASSET_HASH_CHARS_KART 0x1e68a3e01aa5c68b #define ASSET_HASH_MAPS_KART 0x38558ed00da41ce9 -#define ASSET_HASH_MAIN_PK3 0x2821ce9a351cf736 +#define ASSET_HASH_MAIN_PK3 0xc15d8361362b3ed7 #define ASSET_HASH_MAPPATCH_PK3 0x7d1f6b96dd119296 #define ASSET_HASH_BONUSCHARS_KART 0x60e6f13d822a7461 #ifdef USE_PATCH_FILE diff --git a/src/d_netcmd.c b/src/d_netcmd.c index f40503967..dc4db789c 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1259,6 +1259,8 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_shrinkme[i]); CV_RegisterVar(&cv_deadzone[i]); CV_RegisterVar(&cv_deadzonestyle[i]); + CV_RegisterVar(&cv_litesteer[i]); + CV_RegisterVar(&cv_turnsmooth[i]); } // filesrch.c @@ -1270,7 +1272,6 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_addons_search_case); CV_RegisterVar(&cv_controlperkey); - CV_RegisterVar(&cv_turnsmooth); CV_RegisterVar(&cv_usemouse); CV_RegisterVar(&cv_invertmouse); diff --git a/src/g_game.c b/src/g_game.c index c9224d710..30a907ec6 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -342,6 +342,21 @@ typedef struct joystickvector2_s INT32 yaxis; } joystickvector2_t; +consvar_t cv_litesteer[MAXSPLITSCREENPLAYERS] = { + CVAR_INIT ("litesteer", "Off", CV_SAVE, CV_OnOff, NULL), + CVAR_INIT ("litesteer2", "Off", CV_SAVE, CV_OnOff, NULL), + CVAR_INIT ("litesteer3", "Off", CV_SAVE, CV_OnOff, NULL), + CVAR_INIT ("litesteer4", "Off", CV_SAVE, CV_OnOff, NULL) +}; + +static CV_PossibleValue_t turnsmooth_cons_t[] = {{2, "Slow"}, {1, "Fast"}, {0, "Off"}, {0, NULL}}; +consvar_t cv_turnsmooth[MAXSPLITSCREENPLAYERS] = { + CVAR_INIT ("turnsmoothing", "Off", CV_SAVE, turnsmooth_cons_t, NULL), + CVAR_INIT ("turnsmoothing2", "Off", CV_SAVE, turnsmooth_cons_t, NULL), + CVAR_INIT ("turnsmoothing3", "Off", CV_SAVE, turnsmooth_cons_t, NULL), + CVAR_INIT ("turnsmoothing4", "Off", CV_SAVE, turnsmooth_cons_t, NULL) +}; + INT16 prevmap, nextmap; INT16 kartmap2native[NEXTMAP_SPECIAL] = {0}, nativemap2kart[NEXTMAP_SPECIAL] = {0}; @@ -1152,14 +1167,14 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) { turnheld[forplayer] += realtics; - if (turnheld[forplayer] < cv_turnsmooth.value * 3) + if (turnheld[forplayer] < cv_turnsmooth[forplayer].value * 3) { // check turn input again, but this time digital only // if it's false, an analog stick is inputting the turn; no smoothing! if (G_PlayerInputDown(forplayer, gc_turnleft, true) || G_PlayerInputDown(forplayer, gc_turnright, true)) { - I_Assert(cv_turnsmooth.value); - tspeed /= cv_turnsmooth.value * 2; + I_Assert(cv_turnsmooth[forplayer].value); + tspeed /= cv_turnsmooth[forplayer].value * 2; } } } @@ -1183,6 +1198,19 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) cmd->angle -= (mousex * 8) * (encoremode ? -1 : 1); } + // Digital users can input diagonal-back for shallow turns. + // + // There's probably some principled way of doing this in the gamepad handler itself, + // by only applying this filtering to inputs sourced from an axis. This is a little + // ugly with the current abstractions, though, and there's a fortunate trick here: + // if you can input full strength turns on both axes, either you're using a fucking + // square gate, or you're not on an analog device. + if (cv_litesteer[forplayer].value && joystickvector.yaxis >= JOYAXISRANGE && abs(cmd->angle) == KART_FULLTURN) + { + // >= beacuse some analog devices can go past JOYAXISRANGE (?!) + cmd->angle /= 2; + } + if (spectating || objectplacing) // SRB2Kart: spectators need special controls { if (G_PlayerInputDown(forplayer, gc_accelerate, false)) diff --git a/src/g_game.h b/src/g_game.h index fa8ca8763..9bff6d5ee 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -92,6 +92,8 @@ extern consvar_t cv_resetspecialmusic; extern consvar_t cv_resume; +extern consvar_t cv_litesteer[MAXSPLITSCREENPLAYERS]; +extern consvar_t cv_turnsmooth[MAXSPLITSCREENPLAYERS]; void weaponPrefChange(void); void weaponPrefChange2(void); diff --git a/src/g_input.c b/src/g_input.c index b2fe32cbe..2b45c0690 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -26,7 +26,6 @@ static CV_PossibleValue_t mousesens_cons_t[] = {{1, "MIN"}, {MAXMOUSESENSITIVITY, "MAX"}, {0, NULL}}; static CV_PossibleValue_t onecontrolperkey_cons_t[] = {{1, "One"}, {2, "Several"}, {0, NULL}}; -static CV_PossibleValue_t turnsmooth_cons_t[] = {{2, "Slow"}, {1, "Fast"}, {0, "Off"}, {0, NULL}}; // mouse values are used once consvar_t cv_mousesens = CVAR_INIT ("mousesens", "20", CV_SAVE, mousesens_cons_t, NULL); @@ -34,8 +33,6 @@ consvar_t cv_mousesens2 = CVAR_INIT ("mousesens2", "20", CV_SAVE, mousesens_cons consvar_t cv_mouseysens = CVAR_INIT ("mouseysens", "20", CV_SAVE, mousesens_cons_t, NULL); consvar_t cv_mouseysens2 = CVAR_INIT ("mouseysens2", "20", CV_SAVE, mousesens_cons_t, NULL); consvar_t cv_controlperkey = CVAR_INIT ("controlperkey", "One", CV_SAVE, onecontrolperkey_cons_t, NULL); -consvar_t cv_turnsmooth = CVAR_INIT ("turnsmoothing", "Off", CV_SAVE, turnsmooth_cons_t, NULL); - // current state of the keys // JOYAXISRANGE for fully pressed, 0 for not pressed INT32 gamekeydown[MAXDEVICES][NUMINPUTS]; diff --git a/src/g_input.h b/src/g_input.h index 8f05eec71..e151732a2 100644 --- a/src/g_input.h +++ b/src/g_input.h @@ -93,7 +93,7 @@ typedef enum // mouse values are used once extern consvar_t cv_mousesens, cv_mouseysens; extern consvar_t cv_mousesens2, cv_mouseysens2; -extern consvar_t cv_controlperkey, cv_turnsmooth; +extern consvar_t cv_controlperkey; // current state of the keys: JOYAXISRANGE or 0 when boolean. // Or anything inbetween for analog values diff --git a/src/m_menu.c b/src/m_menu.c index ef8a18508..e96235471 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -7996,6 +7996,8 @@ INT32 MR_SetupControlsMenu(INT32 arg) M_SetItemArgument(MN_OP_CHANGECONTROLS, "SETJOY", arg); M_SetItemCvar(MN_OP_CHANGECONTROLS, "DEADZ", &cv_deadzone[arg]); M_SetItemCvar(MN_OP_CHANGECONTROLS, "DEAZS", &cv_deadzonestyle[arg]); + M_SetItemCvar(MN_OP_CHANGECONTROLS, "TURNSMOOTHING", &cv_turnsmooth[arg]); + M_SetItemCvar(MN_OP_CHANGECONTROLS, "LITESTEER", &cv_litesteer[arg]); M_SetItemVisible(MN_OP_CHANGECONTROLS, "TALK", player1); // Chat //M_SetItemVisible(MN_OP_CHANGECONTROLS, "TEAM", player1); // Team-chat