mirror of
https://github.com/DrBeef/Raze.git
synced 2025-02-01 05:20:43 +00:00
- Implement new scaled angle change setup and remove enforcement of synchronised input.
This commit is contained in:
parent
9437ea9622
commit
968d0ae0d2
19 changed files with 89 additions and 46 deletions
|
@ -178,33 +178,33 @@ void PlayerAngles::applyPitch(float const horz, ESyncBits* actions, double const
|
|||
// Process mouse input.
|
||||
if (horz)
|
||||
{
|
||||
pActor->spr.Angles.Pitch += DAngle::fromDeg(horz);
|
||||
activeAngles().Pitch += DAngle::fromDeg(horz);
|
||||
*actions &= ~SB_CENTERVIEW;
|
||||
}
|
||||
|
||||
// Process keyboard input.
|
||||
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;
|
||||
}
|
||||
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;
|
||||
}
|
||||
|
||||
// Do return to centre.
|
||||
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.;
|
||||
scaletozero(pActor->spr.Angles.Pitch, PITCH_CENTERSPEED * scale, scaleAdjust);
|
||||
if (!pActor->spr.Angles.Pitch.Sgn()) *actions &= ~SB_CENTERVIEW;
|
||||
scaletozero(activeAngles().Pitch, PITCH_CENTERSPEED * scale, scaleAdjust);
|
||||
if (!activeAngles().Pitch.Sgn()) *actions &= ~SB_CENTERVIEW;
|
||||
}
|
||||
|
||||
// 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)
|
||||
{
|
||||
// add player's input
|
||||
pActor->spr.Angles.Yaw += DAngle::fromDeg(avel);
|
||||
activeAngles().Yaw += DAngle::fromDeg(avel);
|
||||
|
||||
if (*actions & SB_TURNAROUND)
|
||||
{
|
||||
|
@ -240,7 +240,7 @@ void PlayerAngles::applyYaw(float const avel, ESyncBits* actions, double const s
|
|||
add -= YawSpin;
|
||||
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())
|
||||
{
|
||||
w.backupViewAngles();
|
||||
w.resetRenderAngles();
|
||||
}
|
||||
}
|
||||
return arc;
|
||||
|
|
|
@ -11,6 +11,9 @@ struct PlayerAngles
|
|||
// Player viewing angles, separate from the camera.
|
||||
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.
|
||||
DAngle YawSpin;
|
||||
|
||||
|
@ -25,13 +28,20 @@ struct PlayerAngles
|
|||
void doViewYaw(const ESyncBits actions);
|
||||
|
||||
// General methods.
|
||||
void backupViewAngles() { PrevViewAngles = ViewAngles; }
|
||||
void setActor(DCoreActor* const actor) { pActor = actor; }
|
||||
|
||||
// Angle getters.
|
||||
void initialize(DCoreActor* const actor, const DAngle viewyaw = nullAngle)
|
||||
{
|
||||
if ((pActor = actor)) RenderAngles = PrevLerpAngles = pActor->spr.Angles;
|
||||
PrevViewAngles.Yaw = ViewAngles.Yaw = viewyaw;
|
||||
}
|
||||
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)
|
||||
{
|
||||
|
@ -39,7 +49,24 @@ struct PlayerAngles
|
|||
}
|
||||
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.
|
||||
|
@ -84,6 +111,7 @@ private:
|
|||
};
|
||||
|
||||
// Private data which should never be accessed publically.
|
||||
DRotator PrevLerpAngles;
|
||||
DCoreActor* pActor;
|
||||
|
||||
// Internal angle updater to reduce boilerplate from the public setters.
|
||||
|
|
|
@ -109,7 +109,7 @@ extern double inputScale;
|
|||
|
||||
inline bool SyncInput()
|
||||
{
|
||||
return true; //gamesetinput || cl_syncinput || cl_capfps;
|
||||
return gamesetinput || cl_syncinput || cl_capfps;
|
||||
}
|
||||
|
||||
inline float backendinputscale()
|
||||
|
|
|
@ -423,6 +423,9 @@ void GameInterface::Ticker()
|
|||
thinktime.Clock();
|
||||
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);
|
||||
playerProcess(&gPlayer[i]);
|
||||
}
|
||||
|
|
|
@ -801,7 +801,8 @@ void playerStart(int nPlayer, int bNewLevel)
|
|||
auto actor = actSpawnSprite(pStartZone->sector, pStartZone->pos, 6, 1);
|
||||
assert(actor->hasX());
|
||||
pPlayer->actor = actor;
|
||||
pPlayer->Angles.setActor(actor);
|
||||
pPlayer->Angles = {};
|
||||
pPlayer->Angles.initialize(pPlayer->actor);
|
||||
DUDEINFO* pDudeInfo = &dudeInfo[kDudePlayer1 + nPlayer - kDudeBase];
|
||||
pPlayer->pDudeInfo = pDudeInfo;
|
||||
playerSetRace(pPlayer, kModeHuman);
|
||||
|
@ -1522,8 +1523,6 @@ void ProcessInput(PLAYER* pPlayer)
|
|||
Item_JumpBoots = 3
|
||||
};
|
||||
|
||||
pPlayer->Angles.backupViewAngles();
|
||||
|
||||
DBloodActor* actor = pPlayer->actor;
|
||||
POSTURE* pPosture = &pPlayer->pPosture[pPlayer->lifeMode][pPlayer->posture];
|
||||
InputPacket* pInput = &pPlayer->input;
|
||||
|
|
|
@ -611,6 +611,9 @@ void viewDrawScreen(bool sceneonly)
|
|||
}
|
||||
else interpfrac = 1.;
|
||||
|
||||
// update render angles.
|
||||
pPlayer->Angles.updateRenderAngles(interpfrac);
|
||||
|
||||
if (cl_interpolate)
|
||||
{
|
||||
DoInterpolations(interpfrac);
|
||||
|
|
|
@ -69,6 +69,9 @@ void GameInterface::Ticker()
|
|||
ud.cameraactor = nullptr;
|
||||
everyothertime++;
|
||||
|
||||
// this must be done before the view is backed up.
|
||||
ps[myconnectindex].Angles.resetRenderAngles();
|
||||
|
||||
DukeSpriteIterator it;
|
||||
while (auto ac = it.Next())
|
||||
{
|
||||
|
|
|
@ -2700,8 +2700,6 @@ void processinput_d(int snum)
|
|||
p = &ps[snum];
|
||||
auto pact = p->GetActor();
|
||||
|
||||
p->Angles.backupViewAngles();
|
||||
|
||||
ESyncBits& actions = p->sync.actions;
|
||||
|
||||
auto sb_fvel = PlayerInputForwardVel(snum);
|
||||
|
|
|
@ -3214,8 +3214,6 @@ void processinput_r(int snum)
|
|||
auto p = &ps[snum];
|
||||
auto pact = p->GetActor();
|
||||
|
||||
p->Angles.backupViewAngles();
|
||||
|
||||
ESyncBits& actions = p->sync.actions;
|
||||
|
||||
auto sb_fvel = PlayerInputForwardVel(snum);
|
||||
|
|
|
@ -125,7 +125,6 @@ void resetplayerstats(int snum)
|
|||
p->footprintpal = 0;
|
||||
p->footprintshade = 0;
|
||||
p->jumping_toggle = 0;
|
||||
p->Angles.PrevViewAngles.Pitch = p->Angles.ViewAngles.Pitch = nullAngle;
|
||||
p->bobcounter = 0;
|
||||
p->on_ground = 0;
|
||||
p->player_par = 0;
|
||||
|
@ -149,10 +148,6 @@ void resetplayerstats(int snum)
|
|||
p->heat_on = 0;
|
||||
p->jetpack_on = 0;
|
||||
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->jumping_counter = 0;
|
||||
p->hard_landing = 0;
|
||||
|
@ -160,7 +155,6 @@ void resetplayerstats(int snum)
|
|||
p->fric.X = 0;
|
||||
p->fric.Y = 0;
|
||||
p->somethingonplayer = nullptr;
|
||||
p->Angles.YawSpin = nullAngle;
|
||||
|
||||
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];
|
||||
|
||||
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;
|
||||
act->SetOwner(act);
|
||||
|
||||
|
|
|
@ -221,6 +221,9 @@ void displayrooms(int snum, double interpfrac, bool sceneonly)
|
|||
|
||||
player_struct* p = &ps[snum];
|
||||
|
||||
// update render angles.
|
||||
p->Angles.updateRenderAngles(interpfrac);
|
||||
|
||||
if (automapMode == am_full || !p->insector())
|
||||
return;
|
||||
|
||||
|
|
|
@ -369,6 +369,10 @@ void GameInterface::Ticker()
|
|||
}
|
||||
else if (EndLevel == 0)
|
||||
{
|
||||
// this must be done before the view is backed up.
|
||||
PlayerList[nLocalPlayer].Angles.resetRenderAngles();
|
||||
UpdatePlayerSpriteAngle(&PlayerList[nLocalPlayer]);
|
||||
|
||||
inita = inita.Normalized360();
|
||||
|
||||
auto& lPlayerVel = sPlayerInput[nLocalPlayer].vel;
|
||||
|
|
|
@ -156,7 +156,7 @@ uint8_t LoadLevel(MapRecord* map)
|
|||
for (i = 0; i < kMaxPlayers; i++)
|
||||
{
|
||||
PlayerList[i].pActor = nullptr;
|
||||
PlayerList[i].Angles.setActor(nullptr);
|
||||
PlayerList[i].Angles = {};
|
||||
}
|
||||
|
||||
g_visibility = 1024;
|
||||
|
|
|
@ -181,7 +181,7 @@ void InitPlayer()
|
|||
{
|
||||
for (int i = 0; i < kMaxPlayers; i++) {
|
||||
PlayerList[i].pActor = nullptr;
|
||||
PlayerList[i].Angles.setActor(nullptr);
|
||||
PlayerList[i].Angles = {};
|
||||
PlayerList[i].pPlayerPushSect = nullptr;
|
||||
PlayerList[i].pPlayerViewSect = nullptr;
|
||||
}
|
||||
|
@ -210,7 +210,7 @@ void InitPlayerInventory(int nPlayer)
|
|||
PlayerList[nPlayer].nLives = kDefaultLives;
|
||||
|
||||
PlayerList[nPlayer].pActor = nullptr;
|
||||
PlayerList[nPlayer].Angles.setActor(nullptr);
|
||||
PlayerList[nPlayer].Angles = {};
|
||||
PlayerList[nPlayer].nRun = -1;
|
||||
|
||||
PlayerList[nPlayer].nPistolClip = 6;
|
||||
|
@ -262,7 +262,7 @@ void RestartPlayer(int nPlayer)
|
|||
ChangeActorStat(pActor, 0);
|
||||
|
||||
plr->pActor = nullptr;
|
||||
plr->Angles.setActor(nullptr);
|
||||
plr->Angles = {};
|
||||
|
||||
DExhumedActor* pFloorSprite = plr->pPlayerFloorSprite;
|
||||
if (pFloorSprite != nullptr) {
|
||||
|
@ -356,7 +356,8 @@ void RestartPlayer(int nPlayer)
|
|||
|
||||
plr->nSeqSize = 0;
|
||||
plr->pActor = pActor;
|
||||
plr->Angles.setActor(pActor);
|
||||
plr->Angles = {};
|
||||
plr->Angles.initialize(plr->pActor);
|
||||
plr->bIsMummified = false;
|
||||
|
||||
if (plr->invincibility >= 0) {
|
||||
|
@ -904,8 +905,6 @@ void AIPlayer::Tick(RunListEvent* ev)
|
|||
int nAction = PlayerList[nPlayer].nAction;
|
||||
int nActionB = PlayerList[nPlayer].nAction;
|
||||
|
||||
PlayerList[nPlayer].Angles.backupViewAngles();
|
||||
|
||||
pPlayerActor->vel.XY() = sPlayerInput[nPlayer].vel;
|
||||
|
||||
if (sPlayerInput[nPlayer].nItem > -1)
|
||||
|
|
|
@ -201,6 +201,10 @@ void DrawView(double interpfrac, bool sceneonly)
|
|||
auto pDop = pPlayer->pDoppleSprite;
|
||||
auto nDoppleOldCstat = pDop->spr.cstat;
|
||||
|
||||
// update render angles.
|
||||
pPlayer->Angles.updateRenderAngles(interpfrac);
|
||||
UpdatePlayerSpriteAngle(pPlayer);
|
||||
|
||||
if (nSnakeCam >= 0 && !sceneonly)
|
||||
{
|
||||
DExhumedActor* pActor = SnakeList[nSnakeCam].pSprites[0];
|
||||
|
|
|
@ -1237,6 +1237,9 @@ void drawscreen(PLAYER* pp, double interpfrac, bool sceneonly)
|
|||
if (cl_sointerpolation) so_dointerpolations(interpfrac);
|
||||
}
|
||||
|
||||
// update render angles.
|
||||
pp->Angles.updateRenderAngles(interpfrac);
|
||||
|
||||
// Get initial player position, interpolating if required.
|
||||
DVector3 tpos = camerapp->actor->getRenderPos(interpfrac);
|
||||
DRotator tangles = camerapp->Angles.getRenderAngles(interpfrac);
|
||||
|
|
|
@ -572,7 +572,7 @@ void TerminateLevel(void)
|
|||
pp->DoPlayerAction = nullptr;
|
||||
|
||||
pp->actor = nullptr;
|
||||
pp->Angles.setActor(nullptr);
|
||||
pp->Angles = {};
|
||||
|
||||
pp->PlayerUnderActor = nullptr;
|
||||
|
||||
|
|
|
@ -2407,7 +2407,8 @@ void InitPlayerSprite(PLAYER* pp, const DVector3& spawnpos, const DAngle startan
|
|||
pp->actor = actor;
|
||||
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.extra |= (SPRX_PLAYER_OR_ENEMY);
|
||||
|
|
|
@ -1553,10 +1553,10 @@ void DoPlayerTurnVehicle(PLAYER* pp, float avel, double zz, double floordist)
|
|||
|
||||
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))
|
||||
{
|
||||
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)
|
||||
{
|
||||
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)
|
||||
{
|
||||
|
@ -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;
|
||||
|
||||
// this must be done before the view is backed up.
|
||||
pp->Angles.resetRenderAngles();
|
||||
|
||||
pp->actor->backuploc();
|
||||
pp->obob_z = pp->bob_z;
|
||||
pp->opbob_amt = pp->pbob_amt;
|
||||
|
@ -6991,7 +6994,6 @@ void domovethings(void)
|
|||
|
||||
// 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->Angles.backupViewAngles();
|
||||
|
||||
// disable synchronised input if set by game.
|
||||
resetForcedSyncInput();
|
||||
|
|
Loading…
Reference in a new issue