From 03554c03ed779848377c40af7db05bb8c60b6846 Mon Sep 17 00:00:00 2001 From: minenice55 Date: Sat, 4 Apr 2026 19:13:50 -0400 Subject: [PATCH] freelook bind, fix issues with spectator gyro --- src/d_main.cpp | 2 +- src/deh_tables.c | 1 + src/g_game.c | 17 ++++++++++------- src/g_input.c | 1 + src/g_input.h | 1 + src/p_local.h | 11 +++++++---- src/p_tick.c | 44 +++++++++++++++++++++++++++++++++++++++----- src/p_user.c | 4 ++-- 8 files changed, 62 insertions(+), 19 deletions(-) diff --git a/src/d_main.cpp b/src/d_main.cpp index f9032717a..dd5f633ba 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -102,7 +102,7 @@ #define ASSET_HASH_TEXTURES_KART 0xb4211b2f32b6a291 #define ASSET_HASH_CHARS_KART 0x1e68a3e01aa5c68b #define ASSET_HASH_MAPS_KART 0x38558ed00da41ce9 -#define ASSET_HASH_MAIN_PK3 0xa83b5f0cfc1ffd7b +#define ASSET_HASH_MAIN_PK3 0x9260d8dd984ea7c4 #define ASSET_HASH_MAPPATCH_PK3 0x1745690024efbaf8 #define ASSET_HASH_BONUSCHARS_KART 0x60e6f13d822a7461 #ifdef USE_PATCH_FILE diff --git a/src/deh_tables.c b/src/deh_tables.c index e172647af..c9b457a2a 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -1574,6 +1574,7 @@ struct int_const_s const INT_CONST[] = { {"GC_RESPAWN",gc_respawn}, {"GC_DIRECTOR",gc_director}, {"GC_HORNCODE",gc_horncode}, + {"GC_FREELOOK",gc_freelook}, {"NUM_GAMECONTROLS",num_gamecontrols}, // screen.h constants diff --git a/src/g_game.c b/src/g_game.c index c33bd5976..005603746 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1561,18 +1561,21 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) // player space gyro from http://gyrowiki.jibbsmart.com/blog:player-space-gyro-and-alternatives-explained if (spectating) { - fixed_t yawRelaxFactor = 141*FRACUNIT/100; - fixed_t worldYaw; fixed_t deltaseconds = FixedDiv(FRACUNIT, max(cv_timescale.value, FRACUNIT/20))/TICRATE; + fixed_t yawRelaxFactor = 141*FRACUNIT/100; vector3_t gyro = G_GetGamepadCalibratedGyro(forplayer); vector3_t gravnorm = G_GetGamepadGravity(forplayer); vector2_t gyroYZ = {gyro.y, gyro.z}; - FV3_Normalize(&gravnorm); + // use world yaw for yaw direction, local combined yaw for magnitude - worldYaw = FixedMul(gyroYZ.x, gravnorm.y) + FixedMul(gyroYZ.y, gravnorm.z); // dot product but just yaw and roll - // yes this is backwards intentionally - cmd->angle += ((FixedMul(min(FixedMul(abs(worldYaw), yawRelaxFactor), FV2_Magnitude(&gyroYZ)), deltaseconds)*180)/FRACUNIT) * intsign(worldYaw) * (encoremode ? -1 : 1); - cmd->aiming -= (((FixedMul(gyro.x, deltaseconds)*180)/FRACUNIT)); + FV3_Normalize(&gravnorm); + fixed_t worldYaw = FixedMul(gyro.y, gravnorm.y) + FixedMul(gyro.z, gravnorm.z); // dot product but just yaw and roll + + fixed_t yaw = intsign(worldYaw) * (encoremode ? -1 : 1) * + min(FixedMul(-abs(worldYaw), yawRelaxFactor), FV2_Magnitude(&gyroYZ)); + + cmd->angle -= FixedMul(yaw, deltaseconds*180)/FRACUNIT; + cmd->aiming -= FixedMul(gyro.x, deltaseconds*180)/FRACUNIT; } } else if (joystickvector.xaxis != 0) diff --git a/src/g_input.c b/src/g_input.c index 521977c90..4a6b93930 100644 --- a/src/g_input.c +++ b/src/g_input.c @@ -179,6 +179,7 @@ INT32 gamecontroldefault[num_gamecontrols][MAXINPUTMAPPING] = { [gc_centerview ] = {KEY_END }, [gc_camreset ] = {KEY_HOME }, [gc_camtoggle ] = {KEY_BACKSPACE }, + [gc_freelook ] = {KEY_RCTRL }, }; // lists of GC codes for selective operation diff --git a/src/g_input.h b/src/g_input.h index 09fc49f5c..f21f3f092 100644 --- a/src/g_input.h +++ b/src/g_input.h @@ -95,6 +95,7 @@ typedef enum gc_respawn, gc_director, gc_horncode, + gc_freelook, num_gamecontrols } gamecontrols_e; diff --git a/src/p_local.h b/src/p_local.h index aaa8be214..d754bac74 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -132,14 +132,17 @@ struct camera_t fixed_t pan; // SRB2Kart: camera pitches on slopes angle_t pitch; - + // Freecam: A button was held since entering from menu, so don't move camera UINT8 button_a_held; - + boolean reset_aiming; // camera aiming needs to be reset from chase camera - + // Hold up/down to pan the camera vertically - SINT8 dpad_y_held; + SINT8 freelook_held; + // between -45 deg and 45 deg + fixed_t freelook_pitch; + fixed_t freelook_pitch_add; // Interpolation data fixed_t old_x, old_y, old_z; diff --git a/src/p_tick.c b/src/p_tick.c index ed2c17128..5cba9224b 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -650,16 +650,50 @@ void P_RunChaseCameras(void) { if (camera[i].chase) { - player_t *p = &players[displayplayers[i]]; + INT32 forplayer = displayplayers[i]; + player_t *p = &players[forplayer]; camera_t *cam = &camera[i]; - if (p->mo && p->cmd.throwdir != 0) + // client sided + if (p->mo && G_PlayerInputDown(forplayer, gc_freelook, false, DEADZONE_BUTTON)) { - if (p->speed < 6 * p->mo->scale && abs(cam->dpad_y_held) < 2*TICRATE) - cam->dpad_y_held += intsign(p->cmd.throwdir); + // instantly able to move camera + if (p->speed < 6 * p->mo->scale && abs(cam->freelook_held) < 2*TICRATE) + { + cam->freelook_held = 2*TICRATE; + } + + if (abs(cam->freelook_held) >= 2*TICRATE) + { + cam->freelook_pitch = (45*FixedDiv(p->cmd.throwdir, KART_FULLTURN)); + + // gyro aiming + if (G_GetGamepadCanUseTilt(forplayer) && cv_tiltcontrol[forplayer].value == 1) + { + fixed_t deltaseconds = FixedDiv(FRACUNIT, max(cv_timescale.value, FRACUNIT/20))/TICRATE; + vector3_t gyro = G_GetGamepadCalibratedGyro(forplayer); + cam->freelook_pitch_add -= FixedMul(gyro.x, deltaseconds); + } + } + } + else if (p->mo && p->cmd.throwdir != 0) + { + if (p->speed < 6 * p->mo->scale && abs(cam->freelook_held) < 2*TICRATE) + { + cam->freelook_held += intsign(p->cmd.throwdir); + } + + if (abs(cam->freelook_held) >= 2*TICRATE) + { + cam->freelook_pitch = 45*FRACUNIT*intsign(p->cmd.throwdir); + } } else - cam->dpad_y_held = 0; + { + cam->freelook_held = 0; + cam->freelook_pitch = 0; + cam->freelook_pitch_add = 0; + } P_MoveChaseCamera(p, cam, false); } diff --git a/src/p_user.c b/src/p_user.c index 882f09c3a..747994780 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3098,9 +3098,9 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall focusaiming = player->aiming; } - if (abs(thiscam->dpad_y_held) >= 2*TICRATE) + if (abs(thiscam->freelook_held) >= 2*TICRATE) { - focusaiming += ANGLE_45 * intsign(thiscam->dpad_y_held) * P_MobjFlip(mo); + focusaiming += FixedAngle(CLAMP(thiscam->freelook_pitch + thiscam->freelook_pitch_add, -45*FRACUNIT, 45*FRACUNIT) * P_MobjFlip(mo)); } if (P_CameraThinker(player, thiscam, resetcalled))