- Fix interpolation issues and do other minor fixes following shift to fixedhoriz and binangle.

* When interpolating on the initial setup, when binangle reached an overflow point when going lower than zero, the engine was spinning the player around clockwise to the new angle (2047, for instance).
* Interpolating after casting as uint64_t with a workflow similar to the original games, the issue went away.
* Cleaned up other interpolation functions to be of a consistent workflow.
* Scale keyboard input turning down to degree speeds.
* Uplift some remaining Q16.16 code in `applylook()` to full BAM precision.
* Move static calculations of aim and look speeds for `sethorizon()` back into function since GameTicRate isn't set right before calculation is done.
* Simplify the angle target setup back to a basic value like before.
* Repair SW interpolation issues of weapon sprite drawer when rotating left/right.
* Fix SW death horizon constant values following change of horizon center to 0.
This commit is contained in:
Mitchell Richters 2020-10-08 21:10:54 +11:00
parent 9bcdeae6cd
commit f35bec4a5d
4 changed files with 48 additions and 44 deletions

View file

@ -1501,12 +1501,12 @@ void processMovement(InputPacket* currInput, InputPacket* inputBuffer, ControlIn
if (buttonMap.ButtonDown(gamefunc_Turn_Left) || (buttonMap.ButtonDown(gamefunc_Strafe_Left) && !allowstrafe)) if (buttonMap.ButtonDown(gamefunc_Turn_Left) || (buttonMap.ButtonDown(gamefunc_Strafe_Left) && !allowstrafe))
{ {
turnheldtime += scaleAdjust * turnheldamt; turnheldtime += scaleAdjust * turnheldamt;
currInput->avel -= scaleAdjust * (turnheldtime >= turboturntime ? turnamount : preambleturn); currInput->avel -= scaleAdjust * (turnheldtime >= turboturntime ? turnamount : preambleturn) * (45. / 256.);
} }
else if (buttonMap.ButtonDown(gamefunc_Turn_Right) || (buttonMap.ButtonDown(gamefunc_Strafe_Right) && !allowstrafe)) else if (buttonMap.ButtonDown(gamefunc_Turn_Right) || (buttonMap.ButtonDown(gamefunc_Strafe_Right) && !allowstrafe))
{ {
turnheldtime += scaleAdjust * turnheldamt; turnheldtime += scaleAdjust * turnheldamt;
currInput->avel += scaleAdjust * (turnheldtime >= turboturntime ? turnamount : preambleturn); currInput->avel += scaleAdjust * (turnheldtime >= turboturntime ? turnamount : preambleturn) * (45. / 256.);
} }
else else
{ {
@ -1568,9 +1568,6 @@ void processMovement(InputPacket* currInput, InputPacket* inputBuffer, ControlIn
// //
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
static double const aimamount = HorizToPitch(250. / GameTicRate);
static double const lookamount = HorizToPitch(500. / GameTicRate);
void sethorizon(fixedhoriz* horiz, float const horz, ESyncBits* actions, double const scaleAdjust) void sethorizon(fixedhoriz* horiz, float const horz, ESyncBits* actions, double const scaleAdjust)
{ {
// Store current horizon as true pitch. // Store current horizon as true pitch.
@ -1586,24 +1583,26 @@ void sethorizon(fixedhoriz* horiz, float const horz, ESyncBits* actions, double
if (*actions & (SB_AIM_UP|SB_AIM_DOWN)) if (*actions & (SB_AIM_UP|SB_AIM_DOWN))
{ {
*actions &= ~SB_CENTERVIEW; *actions &= ~SB_CENTERVIEW;
double const amount = HorizToPitch(250. / GameTicRate);
if (*actions & SB_AIM_DOWN) if (*actions & SB_AIM_DOWN)
pitch -= scaleAdjust * aimamount; pitch -= scaleAdjust * amount;
if (*actions & SB_AIM_UP) if (*actions & SB_AIM_UP)
pitch += scaleAdjust * aimamount; pitch += scaleAdjust * amount;
} }
// this is the unlocked type // this is the unlocked type
if (*actions & (SB_LOOK_UP|SB_LOOK_DOWN)) if (*actions & (SB_LOOK_UP|SB_LOOK_DOWN))
{ {
*actions |= SB_CENTERVIEW; *actions |= SB_CENTERVIEW;
double const amount = HorizToPitch(500. / GameTicRate);
if (*actions & SB_LOOK_DOWN) if (*actions & SB_LOOK_DOWN)
pitch -= scaleAdjust * lookamount; pitch -= scaleAdjust * amount;
if (*actions & SB_LOOK_UP) if (*actions & SB_LOOK_UP)
pitch += scaleAdjust * lookamount; pitch += scaleAdjust * amount;
} }
// clamp pitch after processing // clamp pitch after processing
@ -1638,25 +1637,25 @@ void sethorizon(fixedhoriz* horiz, float const horz, ESyncBits* actions, double
void applylook(PlayerAngle* angle, float const avel, ESyncBits* actions, double const scaleAdjust, bool const crouching) void applylook(PlayerAngle* angle, float const avel, ESyncBits* actions, double const scaleAdjust, bool const crouching)
{ {
// return q16rotscrnang to 0 and set to 0 if less than a quarter of a unit // return q16rotscrnang to 0 and set to 0 if less than a quarter of a unit
angle->rotscrnang -= q16look(xs_CRoundToInt(scaleAdjust * (angle->rotscrnang.asq16() * (15. / GameTicRate)))); angle->rotscrnang -= bamlook(xs_CRoundToInt(scaleAdjust * angle->rotscrnang.asbam() * (15. / GameTicRate)));
if (abs(angle->rotscrnang.asq16()) < (FRACUNIT >> 2)) angle->rotscrnang = q16look(0); if (abs(angle->rotscrnang.asbam()) < (BAMUNIT >> 2)) angle->rotscrnang = bamlook(0);
// return q16look_ang to 0 and set to 0 if less than a quarter of a unit // return q16look_ang to 0 and set to 0 if less than a quarter of a unit
angle->look_ang -= q16look(xs_CRoundToInt(scaleAdjust * (angle->look_ang.asq16() * (7.5 / GameTicRate)))); angle->look_ang -= bamlook(xs_CRoundToInt(scaleAdjust * angle->look_ang.asbam() * (7.5 / GameTicRate)));
if (abs(angle->look_ang.asq16()) < (FRACUNIT >> 2)) angle->look_ang = q16look(0); if (abs(angle->look_ang.asbam()) < (BAMUNIT >> 2)) angle->look_ang = bamlook(0);
if (*actions & SB_LOOK_LEFT) if (*actions & SB_LOOK_LEFT)
{ {
// start looking left // start looking left
angle->look_ang -= q16look(FloatToFixed(scaleAdjust * (4560. / GameTicRate))); angle->look_ang -= bamlook(xs_CRoundToInt(scaleAdjust * (4560. / GameTicRate) * BAMUNIT));
angle->rotscrnang += q16look(FloatToFixed(scaleAdjust * (720. / GameTicRate))); angle->rotscrnang += bamlook(xs_CRoundToInt(scaleAdjust * (720. / GameTicRate) * BAMUNIT));
} }
if (*actions & SB_LOOK_RIGHT) if (*actions & SB_LOOK_RIGHT)
{ {
// start looking right // start looking right
angle->look_ang += q16look(FloatToFixed(scaleAdjust * (4560. / GameTicRate))); angle->look_ang += bamlook(xs_CRoundToInt(scaleAdjust * (4560. / GameTicRate) * BAMUNIT));
angle->rotscrnang -= q16look(FloatToFixed(scaleAdjust * (720. / GameTicRate))); angle->rotscrnang -= bamlook(xs_CRoundToInt(scaleAdjust * (720. / GameTicRate) * BAMUNIT));
} }
if (*actions & SB_TURNAROUND) if (*actions & SB_TURNAROUND)
@ -1672,15 +1671,15 @@ void applylook(PlayerAngle* angle, float const avel, ESyncBits* actions, double
if (angle->spin.asbam() < 0) if (angle->spin.asbam() < 0)
{ {
// return spin to 0 // return spin to 0
fixed_t add = FloatToFixed(scaleAdjust * ((!crouching ? 3840. : 1920.) / GameTicRate)); lookangle add = bamlook(xs_CRoundToUInt(scaleAdjust * ((!crouching ? 3840. : 1920.) / GameTicRate) * BAMUNIT));
angle->spin += q16look(add); angle->spin += add;
if (angle->spin.asbam() > 0) if (angle->spin.asbam() > 0)
{ {
// Don't overshoot our target. With variable factor this is possible. // Don't overshoot our target. With variable factor this is possible.
add -= angle->spin.asq16(); add -= angle->spin;
angle->spin = bamlook(0); angle->spin = bamlook(0);
} }
angle->ang += q16ang(add); angle->ang += bamang(add.asbam());
} }
if (avel) if (avel)

View file

@ -142,17 +142,18 @@ struct PlayerHorizon
fixedhoriz interpolatedsum(double const smoothratio) fixedhoriz interpolatedsum(double const smoothratio)
{ {
fixedhoriz prev = ohoriz + ohorizoff; double const ratio = smoothratio / FRACUNIT;
fixedhoriz curr = horiz + horizoff; fixed_t const prev = (ohoriz + ohorizoff).asq16();
return q16horiz(prev.asq16() + mulscale16(curr.asq16() - prev.asq16(), smoothratio)); fixed_t const curr = (horiz + horizoff).asq16();
return q16horiz(prev + xs_CRoundToInt(ratio * (curr - prev)));
} }
}; };
struct PlayerAngle struct PlayerAngle
{ {
binangle ang, oang, target; binangle ang, oang;
lookangle look_ang, olook_ang, rotscrnang, orotscrnang, spin; lookangle look_ang, olook_ang, rotscrnang, orotscrnang, spin;
double adjustment; double adjustment, target;
void backup() void backup()
{ {
@ -189,8 +190,8 @@ struct PlayerAngle
{ {
if (!cl_syncinput) if (!cl_syncinput)
{ {
target = bamang(xs_CRoundToUInt(value * BAMUNIT)); if (value == 0) value += (1. / BAMUNIT);
if (target.asbam() == 0) target += bamang(1); target = xs_CRoundToUInt(value * BAMUNIT);
} }
else else
{ {
@ -201,14 +202,14 @@ struct PlayerAngle
void processhelpers(double const scaleAdjust) void processhelpers(double const scaleAdjust)
{ {
if (target.asbam()) if (target)
{ {
ang = bamang(ang.asbam() + xs_CRoundToInt(scaleAdjust * (target - ang).asbam())); ang = bamang(ang.asbam() + xs_CRoundToInt(scaleAdjust * (target - ang.asbam())));
if (ang.asbam() - target.asbam() < BAMUNIT) if (ang.asbam() - target < BAMUNIT)
{ {
ang = target; ang = bamang(target);
target = bamang(0); target = 0;
} }
} }
else if (adjustment) else if (adjustment)
@ -224,14 +225,17 @@ struct PlayerAngle
binangle interpolatedsum(double const smoothratio) binangle interpolatedsum(double const smoothratio)
{ {
auto prev = oang.asbam() + olook_ang.asbam(); double const ratio = smoothratio / FRACUNIT;
auto curr = ang.asbam() + look_ang.asbam(); int32_t const dang = UINT32_MAX / 2;
return bamang(xs_CRoundToUInt(prev + fmulscale16(curr - prev, smoothratio))); int64_t const prev = oang.asbam() + olook_ang.asbam();
int64_t const curr = ang.asbam() + look_ang.asbam();
return bamang(prev + xs_CRoundToUInt(ratio * (((curr + dang - prev) & 0xFFFFFFFF) - dang)));
} }
lookangle interpolatedrotscrn(double const smoothratio) lookangle interpolatedrotscrn(double const smoothratio)
{ {
return bamlook(xs_CRoundToUInt(orotscrnang.asbam() + fmulscale16(rotscrnang.asbam() - orotscrnang.asbam(), smoothratio))); double const ratio = smoothratio / FRACUNIT;
return bamlook(orotscrnang.asbam() + xs_CRoundToInt(ratio * (rotscrnang.asbam() - orotscrnang.asbam())));
} }
}; };

View file

@ -6921,7 +6921,7 @@ pDisplaySprites(PLAYERp pp, double smoothratio)
short ang; short ang;
int flags; int flags;
double look_anghalf = getHalfLookAng(pp->angle.look_ang.asq16(), pp->angle.look_ang.asq16(), cl_syncinput, smoothratio); double look_anghalf = getHalfLookAng(pp->angle.olook_ang.asq16(), pp->angle.look_ang.asq16(), cl_syncinput, smoothratio);
double looking_arc = fabs(look_anghalf) / 4.5; double looking_arc = fabs(look_anghalf) / 4.5;
TRAVERSE(&pp->PanelSpriteList, psp, next) TRAVERSE(&pp->PanelSpriteList, psp, next)

View file

@ -5592,7 +5592,7 @@ DoPlayerStopOperate(PLAYERp pp)
} }
if (!cl_syncinput) if (!cl_syncinput)
pp->angle.target = buildang(0); pp->angle.target = 0;
if (pp->sop_control) if (pp->sop_control)
{ {
@ -5922,6 +5922,12 @@ DoPlayerDeathMessage(PLAYERp pp, PLAYERp killer)
} }
enum
{
PLAYER_DEATH_HORIZ_UP_VALUE = 65,
PLAYER_DEATH_HORIZ_JUMP_VALUE = 50,
PLAYER_DEATH_HORIZ_FALL_VALUE = -50
};
void void
DoPlayerBeginDie(PLAYERp pp) DoPlayerBeginDie(PLAYERp pp)
@ -5942,11 +5948,6 @@ DoPlayerBeginDie(PLAYERp pp)
DoPlayerDeathDrown, DoPlayerDeathDrown,
}; };
#define PLAYER_DEATH_TILT_VALUE (32)
#define PLAYER_DEATH_HORIZ_UP_VALUE (165)
#define PLAYER_DEATH_HORIZ_JUMP_VALUE (150)
#define PLAYER_DEATH_HORIZ_FALL_VALUE (50)
if (Prediction) if (Prediction)
return; return;