0
0
Fork 0
mirror of https://github.com/DrBeef/Raze.git synced 2025-03-05 08:51:02 +00:00

- Implement new scaled angle change setup and remove enforcement of synchronised input.

This commit is contained in:
Mitchell Richters 2022-12-09 17:55:13 +11:00 committed by Christoph Oelckers
parent 9437ea9622
commit 968d0ae0d2
19 changed files with 89 additions and 46 deletions

View file

@ -178,33 +178,33 @@ void PlayerAngles::applyPitch(float const horz, ESyncBits* actions, double const
// Process mouse input. // Process mouse input.
if (horz) if (horz)
{ {
pActor->spr.Angles.Pitch += DAngle::fromDeg(horz); activeAngles().Pitch += DAngle::fromDeg(horz);
*actions &= ~SB_CENTERVIEW; *actions &= ~SB_CENTERVIEW;
} }
// Process keyboard input. // Process keyboard input.
if (auto aiming = !!(*actions & SB_AIM_DOWN) - !!(*actions & SB_AIM_UP)) if (auto aiming = !!(*actions & SB_AIM_DOWN) - !!(*actions & SB_AIM_UP))
{ {
pActor->spr.Angles.Pitch += getTicrateScale(PITCH_AIMSPEED) * scaleAdjust * aiming; activeAngles().Pitch += getTicrateScale(PITCH_AIMSPEED) * scaleAdjust * aiming;
*actions &= ~SB_CENTERVIEW; *actions &= ~SB_CENTERVIEW;
} }
if (auto looking = !!(*actions & SB_LOOK_DOWN) - !!(*actions & SB_LOOK_UP)) if (auto looking = !!(*actions & SB_LOOK_DOWN) - !!(*actions & SB_LOOK_UP))
{ {
pActor->spr.Angles.Pitch += getTicrateScale(PITCH_LOOKSPEED) * scaleAdjust * looking; activeAngles().Pitch += getTicrateScale(PITCH_LOOKSPEED) * scaleAdjust * looking;
*actions |= SB_CENTERVIEW; *actions |= SB_CENTERVIEW;
} }
// Do return to centre. // Do return to centre.
if ((*actions & SB_CENTERVIEW) && !(*actions & (SB_LOOK_UP|SB_LOOK_DOWN))) if ((*actions & SB_CENTERVIEW) && !(*actions & (SB_LOOK_UP|SB_LOOK_DOWN)))
{ {
const auto pitch = abs(pActor->spr.Angles.Pitch); const auto pitch = abs(activeAngles().Pitch);
const auto scale = pitch > PITCH_CNTRSINEOFFSET ? (pitch - PITCH_CNTRSINEOFFSET).Cos() : 1.; const auto scale = pitch > PITCH_CNTRSINEOFFSET ? (pitch - PITCH_CNTRSINEOFFSET).Cos() : 1.;
scaletozero(pActor->spr.Angles.Pitch, PITCH_CENTERSPEED * scale, scaleAdjust); scaletozero(activeAngles().Pitch, PITCH_CENTERSPEED * scale, scaleAdjust);
if (!pActor->spr.Angles.Pitch.Sgn()) *actions &= ~SB_CENTERVIEW; if (!activeAngles().Pitch.Sgn()) *actions &= ~SB_CENTERVIEW;
} }
// clamp before we finish, even if it's clamped in the drawer. // clamp before we finish, even if it's clamped in the drawer.
pActor->spr.Angles.Pitch = ClampViewPitch(pActor->spr.Angles.Pitch); activeAngles().Pitch = ClampViewPitch(activeAngles().Pitch);
} }
@ -217,7 +217,7 @@ void PlayerAngles::applyPitch(float const horz, ESyncBits* actions, double const
void PlayerAngles::applyYaw(float const avel, ESyncBits* actions, double const scaleAdjust) void PlayerAngles::applyYaw(float const avel, ESyncBits* actions, double const scaleAdjust)
{ {
// add player's input // add player's input
pActor->spr.Angles.Yaw += DAngle::fromDeg(avel); activeAngles().Yaw += DAngle::fromDeg(avel);
if (*actions & SB_TURNAROUND) if (*actions & SB_TURNAROUND)
{ {
@ -240,7 +240,7 @@ void PlayerAngles::applyYaw(float const avel, ESyncBits* actions, double const s
add -= YawSpin; add -= YawSpin;
YawSpin = nullAngle; YawSpin = nullAngle;
} }
pActor->spr.Angles.Yaw += add; activeAngles().Yaw += add;
} }
} }
@ -336,7 +336,7 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, PlayerAngles& w, P
if (arc.isReading()) if (arc.isReading())
{ {
w.backupViewAngles(); w.resetRenderAngles();
} }
} }
return arc; return arc;

View file

@ -11,6 +11,9 @@ struct PlayerAngles
// Player viewing angles, separate from the camera. // Player viewing angles, separate from the camera.
DRotator PrevViewAngles, ViewAngles; DRotator PrevViewAngles, ViewAngles;
// Player camera angles, not for direct manipulation within the playsim.
DRotator RenderAngles;
// Holder of current yaw spin state for the 180 degree turn. // Holder of current yaw spin state for the 180 degree turn.
DAngle YawSpin; DAngle YawSpin;
@ -25,13 +28,20 @@ struct PlayerAngles
void doViewYaw(const ESyncBits actions); void doViewYaw(const ESyncBits actions);
// General methods. // General methods.
void backupViewAngles() { PrevViewAngles = ViewAngles; } void initialize(DCoreActor* const actor, const DAngle viewyaw = nullAngle)
void setActor(DCoreActor* const actor) { pActor = actor; } {
if ((pActor = actor)) RenderAngles = PrevLerpAngles = pActor->spr.Angles;
// Angle getters. PrevViewAngles.Yaw = ViewAngles.Yaw = viewyaw;
}
DAngle getPitchWithView() DAngle getPitchWithView()
{ {
return pActor->spr.Angles.Pitch + ViewAngles.Pitch; return ClampViewPitch(pActor->spr.Angles.Pitch + ViewAngles.Pitch);
}
// Render angle functions.
DRotator& activeAngles()
{
return !SyncInput() ? RenderAngles : pActor->spr.Angles;
} }
DRotator lerpViewAngles(const double interpfrac) DRotator lerpViewAngles(const double interpfrac)
{ {
@ -39,7 +49,24 @@ struct PlayerAngles
} }
DRotator getRenderAngles(const double interpfrac) DRotator getRenderAngles(const double interpfrac)
{ {
return (!SyncInput() ? pActor->spr.Angles : pActor->interpolatedangles(interpfrac)) + lerpViewAngles(interpfrac); // Get angles and return with clamped off pitch.
auto angles = RenderAngles + lerpViewAngles(interpfrac);
angles.Pitch = ClampViewPitch(angles.Pitch);
return angles;
}
void updateRenderAngles(const double interpfrac)
{
// Apply the current interpolated angle state to the render angles.
const auto lerpAngles = pActor->interpolatedangles(interpfrac);
RenderAngles += lerpAngles - PrevLerpAngles;
PrevLerpAngles = lerpAngles;
}
void resetRenderAngles()
{
// Apply any last remaining ticrate angle updates and reset variables.
RenderAngles += pActor->spr.Angles - PrevLerpAngles;
PrevLerpAngles = pActor->spr.Angles = RenderAngles;
PrevViewAngles = ViewAngles;
} }
// Draw code helpers. // Draw code helpers.
@ -84,6 +111,7 @@ private:
}; };
// Private data which should never be accessed publically. // Private data which should never be accessed publically.
DRotator PrevLerpAngles;
DCoreActor* pActor; DCoreActor* pActor;
// Internal angle updater to reduce boilerplate from the public setters. // Internal angle updater to reduce boilerplate from the public setters.

View file

@ -109,7 +109,7 @@ extern double inputScale;
inline bool SyncInput() inline bool SyncInput()
{ {
return true; //gamesetinput || cl_syncinput || cl_capfps; return gamesetinput || cl_syncinput || cl_capfps;
} }
inline float backendinputscale() inline float backendinputscale()

View file

@ -423,6 +423,9 @@ void GameInterface::Ticker()
thinktime.Clock(); thinktime.Clock();
for (int i = connecthead; i >= 0; i = connectpoint2[i]) for (int i = connecthead; i >= 0; i = connectpoint2[i])
{ {
// this must be done before the view is backed up.
gPlayer[i].Angles.resetRenderAngles();
viewBackupView(i); viewBackupView(i);
playerProcess(&gPlayer[i]); playerProcess(&gPlayer[i]);
} }

View file

@ -801,7 +801,8 @@ void playerStart(int nPlayer, int bNewLevel)
auto actor = actSpawnSprite(pStartZone->sector, pStartZone->pos, 6, 1); auto actor = actSpawnSprite(pStartZone->sector, pStartZone->pos, 6, 1);
assert(actor->hasX()); assert(actor->hasX());
pPlayer->actor = actor; pPlayer->actor = actor;
pPlayer->Angles.setActor(actor); pPlayer->Angles = {};
pPlayer->Angles.initialize(pPlayer->actor);
DUDEINFO* pDudeInfo = &dudeInfo[kDudePlayer1 + nPlayer - kDudeBase]; DUDEINFO* pDudeInfo = &dudeInfo[kDudePlayer1 + nPlayer - kDudeBase];
pPlayer->pDudeInfo = pDudeInfo; pPlayer->pDudeInfo = pDudeInfo;
playerSetRace(pPlayer, kModeHuman); playerSetRace(pPlayer, kModeHuman);
@ -1522,8 +1523,6 @@ void ProcessInput(PLAYER* pPlayer)
Item_JumpBoots = 3 Item_JumpBoots = 3
}; };
pPlayer->Angles.backupViewAngles();
DBloodActor* actor = pPlayer->actor; DBloodActor* actor = pPlayer->actor;
POSTURE* pPosture = &pPlayer->pPosture[pPlayer->lifeMode][pPlayer->posture]; POSTURE* pPosture = &pPlayer->pPosture[pPlayer->lifeMode][pPlayer->posture];
InputPacket* pInput = &pPlayer->input; InputPacket* pInput = &pPlayer->input;

View file

@ -611,6 +611,9 @@ void viewDrawScreen(bool sceneonly)
} }
else interpfrac = 1.; else interpfrac = 1.;
// update render angles.
pPlayer->Angles.updateRenderAngles(interpfrac);
if (cl_interpolate) if (cl_interpolate)
{ {
DoInterpolations(interpfrac); DoInterpolations(interpfrac);

View file

@ -69,6 +69,9 @@ void GameInterface::Ticker()
ud.cameraactor = nullptr; ud.cameraactor = nullptr;
everyothertime++; everyothertime++;
// this must be done before the view is backed up.
ps[myconnectindex].Angles.resetRenderAngles();
DukeSpriteIterator it; DukeSpriteIterator it;
while (auto ac = it.Next()) while (auto ac = it.Next())
{ {

View file

@ -2700,8 +2700,6 @@ void processinput_d(int snum)
p = &ps[snum]; p = &ps[snum];
auto pact = p->GetActor(); auto pact = p->GetActor();
p->Angles.backupViewAngles();
ESyncBits& actions = p->sync.actions; ESyncBits& actions = p->sync.actions;
auto sb_fvel = PlayerInputForwardVel(snum); auto sb_fvel = PlayerInputForwardVel(snum);

View file

@ -3214,8 +3214,6 @@ void processinput_r(int snum)
auto p = &ps[snum]; auto p = &ps[snum];
auto pact = p->GetActor(); auto pact = p->GetActor();
p->Angles.backupViewAngles();
ESyncBits& actions = p->sync.actions; ESyncBits& actions = p->sync.actions;
auto sb_fvel = PlayerInputForwardVel(snum); auto sb_fvel = PlayerInputForwardVel(snum);

View file

@ -125,7 +125,6 @@ void resetplayerstats(int snum)
p->footprintpal = 0; p->footprintpal = 0;
p->footprintshade = 0; p->footprintshade = 0;
p->jumping_toggle = 0; p->jumping_toggle = 0;
p->Angles.PrevViewAngles.Pitch = p->Angles.ViewAngles.Pitch = nullAngle;
p->bobcounter = 0; p->bobcounter = 0;
p->on_ground = 0; p->on_ground = 0;
p->player_par = 0; p->player_par = 0;
@ -149,10 +148,6 @@ void resetplayerstats(int snum)
p->heat_on = 0; p->heat_on = 0;
p->jetpack_on = 0; p->jetpack_on = 0;
p->holoduke_on = nullptr; p->holoduke_on = nullptr;
p->Angles.PrevViewAngles.Yaw = p->Angles.ViewAngles.Yaw = (currentLevel->levelNumber & 1)? DAngle90 : -DAngle90;
p->Angles.PrevViewAngles.Roll = p->Angles.ViewAngles.Roll = nullAngle;
p->newOwner =nullptr; p->newOwner =nullptr;
p->jumping_counter = 0; p->jumping_counter = 0;
p->hard_landing = 0; p->hard_landing = 0;
@ -160,7 +155,6 @@ void resetplayerstats(int snum)
p->fric.X = 0; p->fric.X = 0;
p->fric.Y = 0; p->fric.Y = 0;
p->somethingonplayer = nullptr; p->somethingonplayer = nullptr;
p->Angles.YawSpin = nullAngle;
p->on_crane = nullptr; p->on_crane = nullptr;
@ -622,7 +616,8 @@ void resetpspritevars(int g, const DVector3& startpos, const DAngle startang)
act->spr.pal = ps[j].palookup = ud.user_pals[j]; act->spr.pal = ps[j].palookup = ud.user_pals[j];
ps[j].actor = act; ps[j].actor = act;
ps[j].Angles.setActor(act); ps[j].Angles = {};
ps[j].Angles.initialize(ps[j].actor, (currentLevel->levelNumber & 1)? DAngle90 : -DAngle90);
ps[j].frag_ps = j; ps[j].frag_ps = j;
act->SetOwner(act); act->SetOwner(act);

View file

@ -221,6 +221,9 @@ void displayrooms(int snum, double interpfrac, bool sceneonly)
player_struct* p = &ps[snum]; player_struct* p = &ps[snum];
// update render angles.
p->Angles.updateRenderAngles(interpfrac);
if (automapMode == am_full || !p->insector()) if (automapMode == am_full || !p->insector())
return; return;

View file

@ -369,6 +369,10 @@ void GameInterface::Ticker()
} }
else if (EndLevel == 0) else if (EndLevel == 0)
{ {
// this must be done before the view is backed up.
PlayerList[nLocalPlayer].Angles.resetRenderAngles();
UpdatePlayerSpriteAngle(&PlayerList[nLocalPlayer]);
inita = inita.Normalized360(); inita = inita.Normalized360();
auto& lPlayerVel = sPlayerInput[nLocalPlayer].vel; auto& lPlayerVel = sPlayerInput[nLocalPlayer].vel;

View file

@ -156,7 +156,7 @@ uint8_t LoadLevel(MapRecord* map)
for (i = 0; i < kMaxPlayers; i++) for (i = 0; i < kMaxPlayers; i++)
{ {
PlayerList[i].pActor = nullptr; PlayerList[i].pActor = nullptr;
PlayerList[i].Angles.setActor(nullptr); PlayerList[i].Angles = {};
} }
g_visibility = 1024; g_visibility = 1024;

View file

@ -181,7 +181,7 @@ void InitPlayer()
{ {
for (int i = 0; i < kMaxPlayers; i++) { for (int i = 0; i < kMaxPlayers; i++) {
PlayerList[i].pActor = nullptr; PlayerList[i].pActor = nullptr;
PlayerList[i].Angles.setActor(nullptr); PlayerList[i].Angles = {};
PlayerList[i].pPlayerPushSect = nullptr; PlayerList[i].pPlayerPushSect = nullptr;
PlayerList[i].pPlayerViewSect = nullptr; PlayerList[i].pPlayerViewSect = nullptr;
} }
@ -210,7 +210,7 @@ void InitPlayerInventory(int nPlayer)
PlayerList[nPlayer].nLives = kDefaultLives; PlayerList[nPlayer].nLives = kDefaultLives;
PlayerList[nPlayer].pActor = nullptr; PlayerList[nPlayer].pActor = nullptr;
PlayerList[nPlayer].Angles.setActor(nullptr); PlayerList[nPlayer].Angles = {};
PlayerList[nPlayer].nRun = -1; PlayerList[nPlayer].nRun = -1;
PlayerList[nPlayer].nPistolClip = 6; PlayerList[nPlayer].nPistolClip = 6;
@ -262,7 +262,7 @@ void RestartPlayer(int nPlayer)
ChangeActorStat(pActor, 0); ChangeActorStat(pActor, 0);
plr->pActor = nullptr; plr->pActor = nullptr;
plr->Angles.setActor(nullptr); plr->Angles = {};
DExhumedActor* pFloorSprite = plr->pPlayerFloorSprite; DExhumedActor* pFloorSprite = plr->pPlayerFloorSprite;
if (pFloorSprite != nullptr) { if (pFloorSprite != nullptr) {
@ -356,7 +356,8 @@ void RestartPlayer(int nPlayer)
plr->nSeqSize = 0; plr->nSeqSize = 0;
plr->pActor = pActor; plr->pActor = pActor;
plr->Angles.setActor(pActor); plr->Angles = {};
plr->Angles.initialize(plr->pActor);
plr->bIsMummified = false; plr->bIsMummified = false;
if (plr->invincibility >= 0) { if (plr->invincibility >= 0) {
@ -904,8 +905,6 @@ void AIPlayer::Tick(RunListEvent* ev)
int nAction = PlayerList[nPlayer].nAction; int nAction = PlayerList[nPlayer].nAction;
int nActionB = PlayerList[nPlayer].nAction; int nActionB = PlayerList[nPlayer].nAction;
PlayerList[nPlayer].Angles.backupViewAngles();
pPlayerActor->vel.XY() = sPlayerInput[nPlayer].vel; pPlayerActor->vel.XY() = sPlayerInput[nPlayer].vel;
if (sPlayerInput[nPlayer].nItem > -1) if (sPlayerInput[nPlayer].nItem > -1)

View file

@ -201,6 +201,10 @@ void DrawView(double interpfrac, bool sceneonly)
auto pDop = pPlayer->pDoppleSprite; auto pDop = pPlayer->pDoppleSprite;
auto nDoppleOldCstat = pDop->spr.cstat; auto nDoppleOldCstat = pDop->spr.cstat;
// update render angles.
pPlayer->Angles.updateRenderAngles(interpfrac);
UpdatePlayerSpriteAngle(pPlayer);
if (nSnakeCam >= 0 && !sceneonly) if (nSnakeCam >= 0 && !sceneonly)
{ {
DExhumedActor* pActor = SnakeList[nSnakeCam].pSprites[0]; DExhumedActor* pActor = SnakeList[nSnakeCam].pSprites[0];

View file

@ -1237,6 +1237,9 @@ void drawscreen(PLAYER* pp, double interpfrac, bool sceneonly)
if (cl_sointerpolation) so_dointerpolations(interpfrac); if (cl_sointerpolation) so_dointerpolations(interpfrac);
} }
// update render angles.
pp->Angles.updateRenderAngles(interpfrac);
// Get initial player position, interpolating if required. // Get initial player position, interpolating if required.
DVector3 tpos = camerapp->actor->getRenderPos(interpfrac); DVector3 tpos = camerapp->actor->getRenderPos(interpfrac);
DRotator tangles = camerapp->Angles.getRenderAngles(interpfrac); DRotator tangles = camerapp->Angles.getRenderAngles(interpfrac);

View file

@ -572,7 +572,7 @@ void TerminateLevel(void)
pp->DoPlayerAction = nullptr; pp->DoPlayerAction = nullptr;
pp->actor = nullptr; pp->actor = nullptr;
pp->Angles.setActor(nullptr); pp->Angles = {};
pp->PlayerUnderActor = nullptr; pp->PlayerUnderActor = nullptr;

View file

@ -2407,7 +2407,8 @@ void InitPlayerSprite(PLAYER* pp, const DVector3& spawnpos, const DAngle startan
pp->actor = actor; pp->actor = actor;
pp->pnum = pnum; pp->pnum = pnum;
pp->Angles.setActor(actor); pp->Angles = {};
pp->Angles.initialize(pp->actor);
actor->spr.cstat |= (CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN); actor->spr.cstat |= (CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN);
actor->spr.extra |= (SPRX_PLAYER_OR_ENEMY); actor->spr.extra |= (SPRX_PLAYER_OR_ENEMY);

View file

@ -1553,10 +1553,10 @@ void DoPlayerTurnVehicle(PLAYER* pp, float avel, double zz, double floordist)
if (avel != 0) if (avel != 0)
{ {
auto sum = pp->actor->spr.Angles.Yaw + DAngle::fromDeg(avel); auto sum = pp->Angles.activeAngles().Yaw + DAngle::fromDeg(avel);
if (MultiClipTurn(pp, sum, zz, floordist)) if (MultiClipTurn(pp, sum, zz, floordist))
{ {
pp->actor->spr.Angles.Yaw = sum; pp->Angles.activeAngles().Yaw = sum;
} }
} }
} }
@ -1619,7 +1619,7 @@ void DoPlayerTurnTurret(PLAYER* pp, float avel)
if (fabs(avel) >= FLT_EPSILON) if (fabs(avel) >= FLT_EPSILON)
{ {
new_ang = pp->actor->spr.Angles.Yaw + DAngle::fromDeg(avel); new_ang = pp->Angles.activeAngles().Yaw + DAngle::fromDeg(avel);
if (sop->limit_ang_center >= nullAngle) if (sop->limit_ang_center >= nullAngle)
{ {
@ -1634,10 +1634,10 @@ void DoPlayerTurnTurret(PLAYER* pp, float avel)
} }
} }
pp->actor->spr.Angles.Yaw = new_ang; pp->Angles.activeAngles().Yaw = new_ang;
} }
OperateSectorObject(pp->sop, pp->actor->spr.Angles.Yaw, pp->sop->pmid); OperateSectorObject(pp->sop, pp->Angles.activeAngles().Yaw, pp->sop->pmid);
} }
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
@ -6697,6 +6697,9 @@ void MoveSkipSavePos(void)
{ {
pp = Player + pnum; pp = Player + pnum;
// this must be done before the view is backed up.
pp->Angles.resetRenderAngles();
pp->actor->backuploc(); pp->actor->backuploc();
pp->obob_z = pp->bob_z; pp->obob_z = pp->bob_z;
pp->opbob_amt = pp->pbob_amt; pp->opbob_amt = pp->pbob_amt;
@ -6991,7 +6994,6 @@ void domovethings(void)
// Reset flags used while tying input to framerate // Reset flags used while tying input to framerate
pp->Flags2 &= ~(PF2_INPUT_CAN_AIM|PF2_INPUT_CAN_TURN_GENERAL|PF2_INPUT_CAN_TURN_VEHICLE|PF2_INPUT_CAN_TURN_TURRET); pp->Flags2 &= ~(PF2_INPUT_CAN_AIM|PF2_INPUT_CAN_TURN_GENERAL|PF2_INPUT_CAN_TURN_VEHICLE|PF2_INPUT_CAN_TURN_TURRET);
pp->Angles.backupViewAngles();
// disable synchronised input if set by game. // disable synchronised input if set by game.
resetForcedSyncInput(); resetForcedSyncInput();