mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'loop-camera' into 'master'
Loop camera + camera turning interpolation fix See merge request KartKrew/Kart!1557
This commit is contained in:
commit
f1c24d0eeb
8 changed files with 135 additions and 6 deletions
|
|
@ -502,6 +502,15 @@ typedef enum
|
|||
BOT_ITEM_PR__MAX
|
||||
} botItemPriority_e;
|
||||
|
||||
typedef struct {
|
||||
tic_t enter_tic, exit_tic;
|
||||
tic_t zoom_in_speed, zoom_out_speed;
|
||||
fixed_t dist;
|
||||
angle_t pan;
|
||||
fixed_t pan_speed; // in degrees
|
||||
tic_t pan_accel, pan_back;
|
||||
} sonicloopcamvars_t;
|
||||
|
||||
// player_t struct for loop state
|
||||
typedef struct {
|
||||
fixed_t radius;
|
||||
|
|
@ -511,6 +520,7 @@ typedef struct {
|
|||
vector2_t origin_shift;
|
||||
vector2_t shift;
|
||||
boolean flip;
|
||||
sonicloopcamvars_t camera;
|
||||
} sonicloopvars_t;
|
||||
|
||||
// player_t struct for power-ups
|
||||
|
|
|
|||
|
|
@ -295,6 +295,7 @@ Obj_LoopEndpointCollide
|
|||
{
|
||||
player_t *player = toucher->player;
|
||||
sonicloopvars_t *s = &player->loop;
|
||||
sonicloopcamvars_t *cam = &s->camera;
|
||||
|
||||
mobj_t *anchor = end_anchor(end);
|
||||
mobj_t *center = anchor ? anchor_center(anchor) : NULL;
|
||||
|
|
@ -352,6 +353,30 @@ Obj_LoopEndpointCollide
|
|||
|
||||
s->flip = center_has_flip(center);
|
||||
|
||||
cam->enter_tic = leveltime;
|
||||
cam->exit_tic = INFTICS;
|
||||
|
||||
if (center->thing_args[4]) // is camera distance set?
|
||||
{
|
||||
cam->zoom_out_speed = center->thing_args[2];
|
||||
cam->zoom_in_speed = center->thing_args[3];
|
||||
cam->dist = center->thing_args[4] * FRACUNIT;
|
||||
cam->pan = FixedAngle(center->thing_args[5] * FRACUNIT);
|
||||
cam->pan_speed = center->thing_args[6] * FRACUNIT;
|
||||
cam->pan_accel = center->thing_args[7];
|
||||
cam->pan_back = center->thing_args[8];
|
||||
}
|
||||
else
|
||||
{
|
||||
cam->zoom_out_speed = 20;
|
||||
cam->zoom_in_speed = 60;
|
||||
cam->dist = radius;
|
||||
cam->pan = ANGLE_22h;
|
||||
cam->pan_speed = 6*FRACUNIT;
|
||||
cam->pan_accel = 10;
|
||||
cam->pan_back = 40;
|
||||
}
|
||||
|
||||
player->speed =
|
||||
3 * (player->speed + toucher->momz) / 2;
|
||||
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ void P_HaltPlayerOrbit(player_t *player)
|
|||
player->mo->flags &= ~(MF_NOCLIPHEIGHT);
|
||||
|
||||
player->loop.radius = 0;
|
||||
player->loop.camera.exit_tic = leveltime;
|
||||
}
|
||||
|
||||
void P_ExitPlayerOrbit(player_t *player)
|
||||
|
|
|
|||
|
|
@ -684,6 +684,17 @@ static void P_NetArchivePlayers(savebuffer_t *save)
|
|||
WRITEFIXED(save->p, players[i].loop.shift.y);
|
||||
WRITEUINT8(save->p, players[i].loop.flip);
|
||||
|
||||
// sonicloopcamvars_t
|
||||
WRITEUINT32(save->p, players[i].loop.camera.enter_tic);
|
||||
WRITEUINT32(save->p, players[i].loop.camera.exit_tic);
|
||||
WRITEUINT32(save->p, players[i].loop.camera.zoom_in_speed);
|
||||
WRITEUINT32(save->p, players[i].loop.camera.zoom_out_speed);
|
||||
WRITEFIXED(save->p, players[i].loop.camera.dist);
|
||||
WRITEANGLE(save->p, players[i].loop.camera.pan);
|
||||
WRITEFIXED(save->p, players[i].loop.camera.pan_speed);
|
||||
WRITEUINT32(save->p, players[i].loop.camera.pan_accel);
|
||||
WRITEUINT32(save->p, players[i].loop.camera.pan_back);
|
||||
|
||||
// ACS has read access to this, so it has to be net-communicated.
|
||||
// It is the ONLY roundcondition that is sent over the wire and I'd like it to stay that way.
|
||||
WRITEUINT32(save->p, players[i].roundconditions.unlocktriggers);
|
||||
|
|
@ -1212,6 +1223,17 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
|
|||
players[i].loop.shift.y = READFIXED(save->p);
|
||||
players[i].loop.flip = READUINT8(save->p);
|
||||
|
||||
// sonicloopcamvars_t
|
||||
players[i].loop.camera.enter_tic = READUINT32(save->p);
|
||||
players[i].loop.camera.exit_tic = READUINT32(save->p);
|
||||
players[i].loop.camera.zoom_in_speed = READUINT32(save->p);
|
||||
players[i].loop.camera.zoom_out_speed = READUINT32(save->p);
|
||||
players[i].loop.camera.dist = READFIXED(save->p);
|
||||
players[i].loop.camera.pan = READANGLE(save->p);
|
||||
players[i].loop.camera.pan_speed = READFIXED(save->p);
|
||||
players[i].loop.camera.pan_accel = READUINT32(save->p);
|
||||
players[i].loop.camera.pan_back = READUINT32(save->p);
|
||||
|
||||
// ACS has read access to this, so it has to be net-communicated.
|
||||
// It is the ONLY roundcondition that is sent over the wire and I'd like it to stay that way.
|
||||
players[i].roundconditions.unlocktriggers = READUINT32(save->p);
|
||||
|
|
|
|||
61
src/p_user.c
61
src/p_user.c
|
|
@ -3083,6 +3083,10 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
fixed_t scaleDiff;
|
||||
fixed_t cameraScale = mapobjectscale;
|
||||
|
||||
sonicloopcamvars_t *loop = &player->loop.camera;
|
||||
tic_t loop_out = leveltime - loop->enter_tic;
|
||||
tic_t loop_in = max(leveltime, loop->exit_tic) - loop->exit_tic;
|
||||
|
||||
thiscam->old_x = thiscam->x;
|
||||
thiscam->old_y = thiscam->y;
|
||||
thiscam->old_z = thiscam->z;
|
||||
|
|
@ -3207,6 +3211,58 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
camdist = FixedMul(cv_cam_dist[num].value, cameraScale);
|
||||
camheight = FixedMul(cv_cam_height[num].value, cameraScale);
|
||||
|
||||
if (loop_in < loop->zoom_in_speed)
|
||||
{
|
||||
fixed_t f = loop_out < loop->zoom_out_speed
|
||||
? (loop_out * FRACUNIT) / loop->zoom_out_speed
|
||||
: FRACUNIT - ((loop_in * FRACUNIT) / loop->zoom_in_speed);
|
||||
|
||||
camspeed -= FixedMul(f, camspeed - (FRACUNIT/10));
|
||||
camdist += FixedMul(f, loop->dist);
|
||||
}
|
||||
|
||||
if (loop_in < max(loop->pan_back, 1))
|
||||
{
|
||||
fixed_t f = (loop_in * FRACUNIT) / max(loop->pan_back, 1);
|
||||
|
||||
fixed_t dx = mo->x - thiscam->x;
|
||||
fixed_t dy = mo->y - thiscam->y;
|
||||
|
||||
angle_t th = R_PointToAngle2(0, 0, dx, dy);
|
||||
fixed_t d = AngleFixed(focusangle - th);
|
||||
|
||||
if (d > 180*FRACUNIT)
|
||||
{
|
||||
d -= (360*FRACUNIT);
|
||||
}
|
||||
|
||||
focusangle = th + FixedAngle(FixedMul(f, d));
|
||||
|
||||
if (loop_in == 0)
|
||||
{
|
||||
focusaiming = R_PointToAngle2(0, thiscam->z, FixedHypot(dx, dy), mo->z);
|
||||
}
|
||||
}
|
||||
|
||||
if (loop_in == 0)
|
||||
{
|
||||
tic_t accel = max(loop->pan_accel, 1);
|
||||
fixed_t f = (min(loop_out, accel) * FRACUNIT) / accel;
|
||||
|
||||
INT32 turn = AngleDeltaSigned(focusangle, player->loop.yaw - loop->pan);
|
||||
INT32 turnspeed = FixedAngle(FixedMul(f, loop->pan_speed));
|
||||
|
||||
if (turn > turnspeed)
|
||||
{
|
||||
if (turn < ANGLE_90)
|
||||
{
|
||||
turnspeed = -(turnspeed);
|
||||
}
|
||||
|
||||
focusangle += turnspeed;
|
||||
}
|
||||
}
|
||||
|
||||
if (timeover)
|
||||
{
|
||||
const INT32 timeovercam = max(0, min(180, (player->karthud[khud_timeovercam] - 2*TICRATE)*15));
|
||||
|
|
@ -3889,6 +3945,11 @@ DoABarrelRoll (player_t *player)
|
|||
|
||||
fixed_t smoothing;
|
||||
|
||||
if (player->loop.radius)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (player->respawn.state != RESPAWNST_NONE)
|
||||
{
|
||||
player->tilt = 0;
|
||||
|
|
|
|||
10
src/r_fps.c
10
src/r_fps.c
|
|
@ -140,10 +140,6 @@ void R_InterpolateView(fixed_t frac)
|
|||
prevview = newview;
|
||||
}
|
||||
|
||||
viewx = R_LerpFixed(prevview->x, newview->x, frac);
|
||||
viewy = R_LerpFixed(prevview->y, newview->y, frac);
|
||||
viewz = R_LerpFixed(prevview->z, newview->z, frac);
|
||||
|
||||
viewangle = R_LerpAngle(prevview->angle, newview->angle, frac);
|
||||
aimingangle = R_LerpAngle(prevview->aim, newview->aim, frac);
|
||||
viewroll = R_LerpAngle(prevview->roll, newview->roll, frac);
|
||||
|
|
@ -151,6 +147,12 @@ void R_InterpolateView(fixed_t frac)
|
|||
viewsin = FINESINE(viewangle>>ANGLETOFINESHIFT);
|
||||
viewcos = FINECOSINE(viewangle>>ANGLETOFINESHIFT);
|
||||
|
||||
fixed_t zoom = R_LerpFixed(prevview->zoom, newview->zoom, frac);
|
||||
|
||||
viewx = R_LerpFixed(prevview->x, newview->x, frac) - FixedMul(viewcos, zoom);
|
||||
viewy = R_LerpFixed(prevview->y, newview->y, frac) - FixedMul(viewsin, zoom);
|
||||
viewz = R_LerpFixed(prevview->z, newview->z, frac);
|
||||
|
||||
viewplayer = newview->player;
|
||||
viewsector = R_PointInSubsector(viewx, viewy)->sector;
|
||||
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ struct viewvars_t {
|
|||
fixed_t x;
|
||||
fixed_t y;
|
||||
fixed_t z;
|
||||
fixed_t zoom;
|
||||
boolean sky;
|
||||
sector_t *sector;
|
||||
player_t *player;
|
||||
|
|
|
|||
|
|
@ -1244,6 +1244,7 @@ void R_SetupFrame(int s)
|
|||
newview->x = r_viewmobj->x;
|
||||
newview->y = r_viewmobj->y;
|
||||
newview->z = r_viewmobj->z;
|
||||
newview->zoom = 0;
|
||||
|
||||
R_SetupCommonFrame(player, r_viewmobj->subsector);
|
||||
}
|
||||
|
|
@ -1252,9 +1253,13 @@ void R_SetupFrame(int s)
|
|||
{
|
||||
r_viewmobj = NULL;
|
||||
|
||||
newview->x = thiscam->x;
|
||||
newview->y = thiscam->y;
|
||||
fixed_t x = player->mo ? player->mo->x : thiscam->x;
|
||||
fixed_t y = player->mo ? player->mo->y : thiscam->y;
|
||||
|
||||
newview->x = x;
|
||||
newview->y = y;
|
||||
newview->z = thiscam->z + (thiscam->height>>1);
|
||||
newview->zoom = FixedHypot(thiscam->x - x, thiscam->y - y);
|
||||
|
||||
R_SetupCommonFrame(player, thiscam->subsector);
|
||||
}
|
||||
|
|
@ -1267,6 +1272,7 @@ void R_SetupFrame(int s)
|
|||
newview->x = r_viewmobj->x;
|
||||
newview->y = r_viewmobj->y;
|
||||
newview->z = player->viewz;
|
||||
newview->zoom = 0;
|
||||
|
||||
R_SetupCommonFrame(player, r_viewmobj->subsector);
|
||||
}
|
||||
|
|
@ -1297,6 +1303,7 @@ void R_SkyboxFrame(int s)
|
|||
newview->x = r_viewmobj->x;
|
||||
newview->y = r_viewmobj->y;
|
||||
newview->z = r_viewmobj->z; // 26/04/17: use actual Z position instead of spawnpoint angle!
|
||||
newview->zoom = 0;
|
||||
|
||||
if (mapheaderinfo[gamemap-1])
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue