- SW: Tidy up drawscreen() and floatify it. This includes the quake code as well.

This commit is contained in:
Mitchell Richters 2022-09-07 21:38:15 +10:00 committed by Christoph Oelckers
parent 53b32ea161
commit 7a98e3e45b
3 changed files with 63 additions and 112 deletions

View file

@ -1318,48 +1318,35 @@ void RestorePortalState()
void drawscreen(PLAYER* pp, double smoothratio, bool sceneonly) void drawscreen(PLAYER* pp, double smoothratio, bool sceneonly)
{ {
extern bool CameraTestMode; extern bool CameraTestMode;
int tx, ty, tz;
DAngle tang, trotscrnang; DAngle tang, trotscrnang;
fixedhoriz thoriz; fixedhoriz thoriz;
sectortype* tsect; sectortype* tsect;
short i,j;
int bobamt = 0; // prediction player if prediction is on, else regular player
int quake_z, quake_x, quake_y; PLAYER* camerapp = (PredictionOn && CommEnabled && pp == Player+myconnectindex) ? ppp : pp;
short quake_ang;
extern bool FAF_DebugView; // temporary interpolation scaler.
PLAYER* camerapp; // prediction player if prediction is on, else regular player double interpfrac = smoothratio * (1. / MaxSmoothRatio);
DrawScreen = true; DrawScreen = true;
PreDraw(); PreDraw();
PreUpdatePanel(smoothratio * (1. / MaxSmoothRatio)); PreUpdatePanel(interpfrac);
int sr = (int)smoothratio;
if (!sceneonly) if (!sceneonly)
{ {
DoInterpolations(smoothratio * (1. / MaxSmoothRatio)); // Stick at beginning of drawscreen // Stick at beginning of drawscreen
if (cl_sointerpolation) DoInterpolations(interpfrac);
so_dointerpolations(sr); // Stick at beginning of drawscreen if (cl_sointerpolation) so_dointerpolations((int)smoothratio);
} }
// TENSW: when rendering with prediction, the only thing that counts should // Get initial player position, interpolating if required.
// be the predicted player. DVector3 tpos = interpolatedvalue(camerapp->opos, camerapp->pos, interpfrac);
if (PredictionOn && CommEnabled && pp == Player+myconnectindex)
camerapp = ppp;
else
camerapp = pp;
tx = int(interpolatedvalue<double>(camerapp->opos.X, camerapp->pos.X, smoothratio * (1. / MaxSmoothRatio)) * worldtoint);
ty = int(interpolatedvalue<double>(camerapp->opos.Y, camerapp->pos.Y, smoothratio * (1. / MaxSmoothRatio)) * worldtoint);
tz = int(interpolatedvalue<double>(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.
if (SyncInput() || pp != Player+myconnectindex) if (SyncInput() || pp != Player+myconnectindex)
{ {
tang = camerapp->angle.interpolatedsum(smoothratio * (1. / MaxSmoothRatio)); tang = camerapp->angle.interpolatedsum(interpfrac);
thoriz = camerapp->horizon.interpolatedsum(smoothratio * (1. / MaxSmoothRatio)); thoriz = camerapp->horizon.interpolatedsum(interpfrac);
trotscrnang = camerapp->angle.interpolatedrotscrn(smoothratio * (1. / MaxSmoothRatio)); trotscrnang = camerapp->angle.interpolatedrotscrn(interpfrac);
} }
else else
{ {
@ -1369,91 +1356,70 @@ void drawscreen(PLAYER* pp, double smoothratio, bool sceneonly)
} }
tsect = camerapp->cursector; tsect = camerapp->cursector;
updatesector(tx, ty, &tsect); updatesector(tpos, &tsect);
if (pp->sop_riding || pp->sop_control) if (pp->sop_riding || pp->sop_control)
{ {
if (pp->sop_control && if (pp->sop_control && (!cl_sointerpolation || (CommEnabled && !pp->sop_remote)))
(!cl_sointerpolation || (CommEnabled && !pp->sop_remote)))
{ {
tx = pp->int_ppos().X; tpos = pp->pos;
ty = pp->int_ppos().Y;
tz = pp->int_ppos().Z;
tang = pp->angle.ang; tang = pp->angle.ang;
} }
tsect = pp->cursector; tsect = pp->cursector;
updatesectorz(tx, ty, tz, &tsect); updatesectorz(tpos, &tsect);
} }
pp->si.X = tx * inttoworld; pp->si = tpos.plusZ(-pp->pos.Z);
pp->si.Y = ty * inttoworld;
pp->si.Z = tz * zinttoworld - pp->pos.Z;
pp->siang = tang; pp->siang = tang;
QuakeViewChange(camerapp, &quake_z, &quake_x, &quake_y, &quake_ang); QuakeViewChange(camerapp, tpos, tang);
int vis = g_visibility; int vis = g_visibility;
VisViewChange(camerapp, &vis); VisViewChange(camerapp, &vis);
g_relvisibility = vis - g_visibility; 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) if (pp->sop_remote)
{ {
DSWActor* ractor = pp->remoteActor; DSWActor* ractor = pp->remoteActor;
if (TEST_BOOL1(ractor)) tang = TEST_BOOL1(ractor) ? ractor->spr.angle : (pp->sop_remote->pmid.XY() - tpos.XY()).Angle();
tang = ractor->spr.angle;
else
tang = VecToAngle(pp->sop_remote->int_pmid().X - tx, pp->sop_remote->int_pmid().Y - ty);
} }
if (pp->Flags & (PF_VIEW_FROM_OUTSIDE)) 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; tpos.Z += 33;
calcChaseCamPos(&tx, &ty, &tz, pp->actor, &tsect, tang, thoriz, smoothratio); calcChaseCamPos(tpos, pp->actor, &tsect, tang, thoriz, interpfrac);
} }
} }
else else if(CameraTestMode)
{ {
bobamt = camerapp->pbob_amt * zworldtoint; CameraView(camerapp, tpos, &tsect, &tang, &thoriz);
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;
}
} }
if (!(pp->Flags & (PF_VIEW_FROM_CAMERA|PF_VIEW_FROM_OUTSIDE))) if (!(pp->Flags & (PF_VIEW_FROM_CAMERA|PF_VIEW_FROM_OUTSIDE)))
{ {
if (cl_viewbob) if (cl_viewbob)
{ {
tz += bobamt; tpos.Z += camerapp->pbob_amt + interpolatedvalue(pp->obob_z, pp->bob_z, interpfrac);
tz += interpolatedvalue(pp->obob_z, pp->bob_z, smoothratio * (1. / MaxSmoothRatio)) * zworldtoint;
} }
// recoil only when not in camera // 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) if (automapMode != am_full)
{ {
// Cameras must be done before the main loop. // 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(); 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(); RestorePortalState();
if (sceneonly) if (sceneonly)
@ -1462,9 +1428,6 @@ void drawscreen(PLAYER* pp, double smoothratio, bool sceneonly)
return; return;
} }
// if doing a screen save don't need to process the rest
MarkSectorSeen(pp->cursector); MarkSectorSeen(pp->cursector);
if ((automapMode != am_off) && pp == Player+myconnectindex) 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; SWSpriteIterator it;
@ -1496,24 +1459,18 @@ void drawscreen(PLAYER* pp, double smoothratio, bool sceneonly)
} }
} }
#if SYNC_TEST
SyncStatMessage();
#endif
UpdateStatusBar(); UpdateStatusBar();
DrawCrosshair(pp, smoothratio * (1. / MaxSmoothRatio)); DrawCrosshair(pp, interpfrac);
DoPlayerDiveMeter(pp); // Do the underwater breathing bar
// Do the underwater breathing bar
DoPlayerDiveMeter(pp);
// Boss Health Meter, if Boss present // Boss Health Meter, if Boss present
BossHealthMeter(); BossHealthMeter();
#if SYNC_TEST // Stick at end of drawscreen
SyncStatMessage(); RestoreInterpolations();
#endif if (cl_sointerpolation) so_restoreinterpolations();
RestoreInterpolations(); // Stick at end of drawscreen
if (cl_sointerpolation)
so_restoreinterpolations(); // Stick at end of drawscreen
if (paused && !M_Active()) if (paused && !M_Active())
{ {

View file

@ -94,7 +94,7 @@ void SpawnPlayerUnderSprite(PLAYER* pp);
void DoQuakeMatch(short match); void DoQuakeMatch(short match);
void ProcessQuakeOn(void); void ProcessQuakeOn(void);
void ProcessQuakeSpot(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); void DoQuake(PLAYER* pp);
bool SetQuake(PLAYER* pp, short tics, short amt); bool SetQuake(PLAYER* pp, short tics, short amt);
int SetExpQuake(DSWActor*); int SetExpQuake(DSWActor*);

View file

@ -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; DSWActor* save_act = nullptr;
int dist,save_dist = 999999; double save_dist = 62500;
int dist_diff, scale_value;
int ang_amt;
int radius;
int pos_amt;
*z_diff = 0; DVector3 tposdiff;
*x_diff = 0; DAngle tangdiff;
*y_diff = 0;
*ang_diff = 0;
if (paused) if (paused)
return; 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); SWStatIterator it(STAT_QUAKE_ON);
while ((actor = it.Next())) while ((actor = it.Next()))
{ {
dist = FindDistance3D(pp->int_ppos() - actor->int_pos()); auto dist = (pp->pos - actor->spr.pos).Length();
// shake whole level // shake whole level
if (QUAKE_TestDontTaper(actor)) if (QUAKE_TestDontTaper(actor))
@ -194,30 +187,31 @@ void QuakeViewChange(PLAYER* pp, int *z_diff, int *x_diff, int *y_diff, short *a
else else
actor = save_act; actor = save_act;
radius = QUAKE_Radius(actor) * 8L; double radius = QUAKE_Radius(actor) * 0.5;
if (save_dist > radius) if (save_dist > radius)
return; 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; int ang_amt = QUAKE_AngAmt(actor) * 4L;
*ang_diff = StdRandomRange(ang_amt) - (ang_amt/2); tangdiff = DAngle::fromBuild(StdRandomRange(ang_amt) - (ang_amt/2));
pos_amt = QUAKE_PosAmt(actor) * 4L; int pos_amt = QUAKE_PosAmt(actor) * 4L;
*x_diff = StdRandomRange(pos_amt) - (pos_amt/2); tposdiff.XY() = DVector2(StdRandomRange(pos_amt) - (pos_amt/2), StdRandomRange(pos_amt) - (pos_amt/2)) * (1. / 4.);
*y_diff = StdRandomRange(pos_amt) - (pos_amt/2);
if (!QUAKE_TestDontTaper(actor)) if (!QUAKE_TestDontTaper(actor))
{ {
// scale values from epicenter // scale values from epicenter
dist_diff = radius - save_dist; double dist_diff = radius - save_dist;
scale_value = DivScale(dist_diff, radius, 16); double scale_value = dist_diff / radius;
*z_diff = MulScale(*z_diff, scale_value, 16); tposdiff *= scale_value;
*ang_diff = MulScale(*ang_diff, scale_value, 16); tangdiff *= scale_value;
*x_diff = MulScale(*x_diff, scale_value, 16);
*y_diff = MulScale(*y_diff, scale_value, 16);
} }
// Add difference values onto incoming references
tpos += tposdiff;
tang += tangdiff;
} }
void SpawnQuake(sectortype* sect, const DVector3& pos, int tics, int amt, int radius) void SpawnQuake(sectortype* sect, const DVector3& pos, int tics, int amt, int radius)