From 7a98e3e45b6743076a44d3ec91a69021a2e21cae Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Wed, 7 Sep 2022 21:38:15 +1000 Subject: [PATCH] - SW: Tidy up `drawscreen()` and floatify it. This includes the quake code as well. --- source/games/sw/src/draw.cpp | 129 ++++++++++++---------------------- source/games/sw/src/misc.h | 2 +- source/games/sw/src/quake.cpp | 44 +++++------- 3 files changed, 63 insertions(+), 112 deletions(-) diff --git a/source/games/sw/src/draw.cpp b/source/games/sw/src/draw.cpp index f84f9a7d6..f1cc600d3 100644 --- a/source/games/sw/src/draw.cpp +++ b/source/games/sw/src/draw.cpp @@ -1318,48 +1318,35 @@ void RestorePortalState() void drawscreen(PLAYER* pp, double smoothratio, bool sceneonly) { extern bool CameraTestMode; - int tx, ty, tz; DAngle tang, trotscrnang; fixedhoriz thoriz; sectortype* tsect; - short i,j; - int bobamt = 0; - int quake_z, quake_x, quake_y; - short quake_ang; - extern bool FAF_DebugView; - PLAYER* camerapp; // prediction player if prediction is on, else regular player + + // prediction player if prediction is on, else regular player + PLAYER* camerapp = (PredictionOn && CommEnabled && pp == Player+myconnectindex) ? ppp : pp; + + // temporary interpolation scaler. + double interpfrac = smoothratio * (1. / MaxSmoothRatio); DrawScreen = true; PreDraw(); - PreUpdatePanel(smoothratio * (1. / MaxSmoothRatio)); - int sr = (int)smoothratio; + PreUpdatePanel(interpfrac); if (!sceneonly) { - DoInterpolations(smoothratio * (1. / MaxSmoothRatio)); // Stick at beginning of drawscreen - if (cl_sointerpolation) - so_dointerpolations(sr); // Stick at beginning of drawscreen + // Stick at beginning of drawscreen + DoInterpolations(interpfrac); + if (cl_sointerpolation) so_dointerpolations((int)smoothratio); } - // TENSW: when rendering with prediction, the only thing that counts should - // be the predicted player. - if (PredictionOn && CommEnabled && pp == Player+myconnectindex) - camerapp = ppp; - else - camerapp = pp; - - tx = int(interpolatedvalue(camerapp->opos.X, camerapp->pos.X, smoothratio * (1. / MaxSmoothRatio)) * worldtoint); - ty = int(interpolatedvalue(camerapp->opos.Y, camerapp->pos.Y, smoothratio * (1. / MaxSmoothRatio)) * worldtoint); - tz = int(interpolatedvalue(camerapp->opos.Z, camerapp->pos.Z, smoothratio * (1. / MaxSmoothRatio)) * zworldtoint); - - // Interpolate the player's angle while on a sector object, just like VoidSW. - // This isn't needed for the turret as it was fixable, but moving sector objects are problematic. + // Get initial player position, interpolating if required. + DVector3 tpos = interpolatedvalue(camerapp->opos, camerapp->pos, interpfrac); if (SyncInput() || pp != Player+myconnectindex) { - tang = camerapp->angle.interpolatedsum(smoothratio * (1. / MaxSmoothRatio)); - thoriz = camerapp->horizon.interpolatedsum(smoothratio * (1. / MaxSmoothRatio)); - trotscrnang = camerapp->angle.interpolatedrotscrn(smoothratio * (1. / MaxSmoothRatio)); + tang = camerapp->angle.interpolatedsum(interpfrac); + thoriz = camerapp->horizon.interpolatedsum(interpfrac); + trotscrnang = camerapp->angle.interpolatedrotscrn(interpfrac); } else { @@ -1369,91 +1356,70 @@ void drawscreen(PLAYER* pp, double smoothratio, bool sceneonly) } tsect = camerapp->cursector; - updatesector(tx, ty, &tsect); + updatesector(tpos, &tsect); if (pp->sop_riding || pp->sop_control) { - if (pp->sop_control && - (!cl_sointerpolation || (CommEnabled && !pp->sop_remote))) + if (pp->sop_control && (!cl_sointerpolation || (CommEnabled && !pp->sop_remote))) { - tx = pp->int_ppos().X; - ty = pp->int_ppos().Y; - tz = pp->int_ppos().Z; + tpos = pp->pos; tang = pp->angle.ang; } tsect = pp->cursector; - updatesectorz(tx, ty, tz, &tsect); + updatesectorz(tpos, &tsect); } - pp->si.X = tx * inttoworld; - pp->si.Y = ty * inttoworld; - pp->si.Z = tz * zinttoworld - pp->pos.Z; + pp->si = tpos.plusZ(-pp->pos.Z); pp->siang = tang; - QuakeViewChange(camerapp, &quake_z, &quake_x, &quake_y, &quake_ang); + QuakeViewChange(camerapp, tpos, tang); int vis = g_visibility; VisViewChange(camerapp, &vis); g_relvisibility = vis - g_visibility; - tz = tz + quake_z; - tx = tx + quake_x; - ty = ty + quake_y; - //thoriz += buildhoriz(quake_x); - tang += DAngle::fromBuild(quake_ang); if (pp->sop_remote) { DSWActor* ractor = pp->remoteActor; - if (TEST_BOOL1(ractor)) - tang = ractor->spr.angle; - else - tang = VecToAngle(pp->sop_remote->int_pmid().X - tx, pp->sop_remote->int_pmid().Y - ty); + tang = TEST_BOOL1(ractor) ? ractor->spr.angle : (pp->sop_remote->pmid.XY() - tpos.XY()).Angle(); } if (pp->Flags & (PF_VIEW_FROM_OUTSIDE)) { - tz -= 8448; + tpos.Z -= 33; - if (!calcChaseCamPos(&tx, &ty, &tz, pp->actor, &tsect, tang, thoriz, smoothratio)) + if (!calcChaseCamPos(tpos, pp->actor, &tsect, tang, thoriz, interpfrac)) { - tz += 8448; - calcChaseCamPos(&tx, &ty, &tz, pp->actor, &tsect, tang, thoriz, smoothratio); + tpos.Z += 33; + calcChaseCamPos(tpos, pp->actor, &tsect, tang, thoriz, interpfrac); } } - else + else if(CameraTestMode) { - bobamt = camerapp->pbob_amt * zworldtoint; - - if (CameraTestMode) - { - DVector3 temp = { tx * inttoworld, ty * inttoworld, tz * zinttoworld }; - CameraView(camerapp, temp, &tsect, &tang, &thoriz); - tx = temp.X * worldtoint; - ty = temp.Y * worldtoint; - tz = temp.Z * zworldtoint; - } + CameraView(camerapp, tpos, &tsect, &tang, &thoriz); } if (!(pp->Flags & (PF_VIEW_FROM_CAMERA|PF_VIEW_FROM_OUTSIDE))) { if (cl_viewbob) { - tz += bobamt; - tz += interpolatedvalue(pp->obob_z, pp->bob_z, smoothratio * (1. / MaxSmoothRatio)) * zworldtoint; + tpos.Z += camerapp->pbob_amt + interpolatedvalue(pp->obob_z, pp->bob_z, interpfrac); } // recoil only when not in camera - thoriz = q16horiz(clamp(thoriz.asq16() + interpolatedvalue(pp->recoil_ohorizoff, pp->recoil_horizoff, smoothratio * (1. / MaxSmoothRatio)), gi->playerHorizMin(), gi->playerHorizMax())); + thoriz = q16horiz(clamp(thoriz.asq16() + interpolatedvalue(pp->recoil_ohorizoff, pp->recoil_horizoff, interpfrac), gi->playerHorizMin(), gi->playerHorizMax())); } if (automapMode != am_full) { // Cameras must be done before the main loop. - JS_CameraParms(pp, tx, ty, tz); + JS_CameraParms(pp, tpos.X * worldtoint, tpos.Y * worldtoint, tpos.Z * zworldtoint); } - if (!sceneonly) UpdatePanel(smoothratio * (1. / MaxSmoothRatio)); + if (!sceneonly) + UpdatePanel(interpfrac); + UpdateWallPortalState(); - render_drawrooms(pp->actor, vec3_t( tx, ty, tz ), sectnum(tsect), tang, thoriz, trotscrnang, smoothratio); + render_drawrooms(pp->actor, tpos, sectnum(tsect), tang, thoriz, trotscrnang, interpfrac); RestorePortalState(); if (sceneonly) @@ -1462,9 +1428,6 @@ void drawscreen(PLAYER* pp, double smoothratio, bool sceneonly) return; } - // if doing a screen save don't need to process the rest - - MarkSectorSeen(pp->cursector); if ((automapMode != am_off) && pp == Player+myconnectindex) @@ -1482,7 +1445,7 @@ void drawscreen(PLAYER* pp, double smoothratio, bool sceneonly) } } } - DrawOverheadMap(DVector2(tx, ty) * inttoworld, tang, smoothratio * (1. / MaxSmoothRatio)); + DrawOverheadMap(tpos.XY(), tang, interpfrac); } SWSpriteIterator it; @@ -1496,24 +1459,18 @@ void drawscreen(PLAYER* pp, double smoothratio, bool sceneonly) } } -#if SYNC_TEST - SyncStatMessage(); -#endif - UpdateStatusBar(); - DrawCrosshair(pp, smoothratio * (1. / MaxSmoothRatio)); - DoPlayerDiveMeter(pp); // Do the underwater breathing bar + DrawCrosshair(pp, interpfrac); + + // Do the underwater breathing bar + DoPlayerDiveMeter(pp); // Boss Health Meter, if Boss present BossHealthMeter(); -#if SYNC_TEST - SyncStatMessage(); -#endif - - RestoreInterpolations(); // Stick at end of drawscreen - if (cl_sointerpolation) - so_restoreinterpolations(); // Stick at end of drawscreen + // Stick at end of drawscreen + RestoreInterpolations(); + if (cl_sointerpolation) so_restoreinterpolations(); if (paused && !M_Active()) { diff --git a/source/games/sw/src/misc.h b/source/games/sw/src/misc.h index e181327a0..b532e18aa 100644 --- a/source/games/sw/src/misc.h +++ b/source/games/sw/src/misc.h @@ -94,7 +94,7 @@ void SpawnPlayerUnderSprite(PLAYER* pp); void DoQuakeMatch(short match); void ProcessQuakeOn(void); void ProcessQuakeSpot(void); -void QuakeViewChange(PLAYER* pp, int* z_diff, int* x_diff, int* y_diff, short* ang_diff); +void QuakeViewChange(PLAYER* pp, DVector3& tpos, DAngle& tang); void DoQuake(PLAYER* pp); bool SetQuake(PLAYER* pp, short tics, short amt); int SetExpQuake(DSWActor*); diff --git a/source/games/sw/src/quake.cpp b/source/games/sw/src/quake.cpp index 789cb4f18..502e2973d 100644 --- a/source/games/sw/src/quake.cpp +++ b/source/games/sw/src/quake.cpp @@ -149,20 +149,13 @@ void ProcessQuakeSpot(void) } } -void QuakeViewChange(PLAYER* pp, int *z_diff, int *x_diff, int *y_diff, short *ang_diff) +void QuakeViewChange(PLAYER* pp, DVector3& tpos, DAngle& tang) { - int i; DSWActor* save_act = nullptr; - int dist,save_dist = 999999; - int dist_diff, scale_value; - int ang_amt; - int radius; - int pos_amt; + double save_dist = 62500; - *z_diff = 0; - *x_diff = 0; - *y_diff = 0; - *ang_diff = 0; + DVector3 tposdiff; + DAngle tangdiff; if (paused) return; @@ -172,7 +165,7 @@ void QuakeViewChange(PLAYER* pp, int *z_diff, int *x_diff, int *y_diff, short *a SWStatIterator it(STAT_QUAKE_ON); while ((actor = it.Next())) { - dist = FindDistance3D(pp->int_ppos() - actor->int_pos()); + auto dist = (pp->pos - actor->spr.pos).Length(); // shake whole level if (QUAKE_TestDontTaper(actor)) @@ -194,30 +187,31 @@ void QuakeViewChange(PLAYER* pp, int *z_diff, int *x_diff, int *y_diff, short *a else actor = save_act; - radius = QUAKE_Radius(actor) * 8L; + double radius = QUAKE_Radius(actor) * 0.5; if (save_dist > radius) return; - *z_diff = Z(StdRandomRange(QUAKE_Zamt(actor)) - (QUAKE_Zamt(actor)/2)); + tposdiff.Z = StdRandomRange(QUAKE_Zamt(actor)) - (QUAKE_Zamt(actor)/2); - ang_amt = QUAKE_AngAmt(actor) * 4L; - *ang_diff = StdRandomRange(ang_amt) - (ang_amt/2); + int ang_amt = QUAKE_AngAmt(actor) * 4L; + tangdiff = DAngle::fromBuild(StdRandomRange(ang_amt) - (ang_amt/2)); - pos_amt = QUAKE_PosAmt(actor) * 4L; - *x_diff = StdRandomRange(pos_amt) - (pos_amt/2); - *y_diff = StdRandomRange(pos_amt) - (pos_amt/2); + int pos_amt = QUAKE_PosAmt(actor) * 4L; + tposdiff.XY() = DVector2(StdRandomRange(pos_amt) - (pos_amt/2), StdRandomRange(pos_amt) - (pos_amt/2)) * (1. / 4.); if (!QUAKE_TestDontTaper(actor)) { // scale values from epicenter - dist_diff = radius - save_dist; - scale_value = DivScale(dist_diff, radius, 16); + double dist_diff = radius - save_dist; + double scale_value = dist_diff / radius; - *z_diff = MulScale(*z_diff, scale_value, 16); - *ang_diff = MulScale(*ang_diff, scale_value, 16); - *x_diff = MulScale(*x_diff, scale_value, 16); - *y_diff = MulScale(*y_diff, scale_value, 16); + tposdiff *= scale_value; + tangdiff *= scale_value; } + + // Add difference values onto incoming references + tpos += tposdiff; + tang += tangdiff; } void SpawnQuake(sectortype* sect, const DVector3& pos, int tics, int amt, int radius)