freelook bind, fix issues with spectator gyro

This commit is contained in:
minenice55 2026-04-04 19:13:50 -04:00
parent 4b5658d487
commit 03554c03ed
8 changed files with 62 additions and 19 deletions

View file

@ -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

View file

@ -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

View file

@ -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)

View file

@ -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

View file

@ -95,6 +95,7 @@ typedef enum
gc_respawn,
gc_director,
gc_horncode,
gc_freelook,
num_gamecontrols
} gamecontrols_e;

View file

@ -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;

View file

@ -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);
}

View file

@ -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))