- Blood/Duke/RR/SW: Unify the player's horizon function.

* For Duke/SW, we continually apply `SB_CENTERVIEW` only if it was previously a toggled action, similar to Blood.
* For SW, we remove two SW-specific bits (`PF_LOCK_HORIZ` and `PF_LOOKING`) that are no longer needed.
* For Duke, we remove `return_to_center` and just use the `SB_CENTERVIEW` action bit as required.
* For `sethorizon()`, feature set and adjustment speeds are an averaged out accumulation across Duke/SW:
** GameTicRate is factored in for adjustment decisions to provide consistency for SW being the faster game.
** Adjustment amounts are half way between Duke/SW.
This commit is contained in:
Mitchell Richters 2020-09-20 20:01:05 +10:00
parent 0c4fe5f91b
commit 0ab3b33a6c
25 changed files with 126 additions and 220 deletions

View File

@ -99,6 +99,8 @@ struct GameInterface : ::GameInterface
void LevelCompleted(MapRecord* map, int skill) override;
bool DrawAutomapPlayer(int x, int y, int z, int a) override;
void SetTileProps(int til, int surf, int vox, int shade) override;
fixed_t playerHorizMin() override { return IntToFixed(-79); }
fixed_t playerHorizMax() override { return IntToFixed(219); }
GameStats getStats() override;
};

View File

@ -42,7 +42,6 @@ enum
};
void applylook(PLAYER *pPlayer, fixed_t const q16avel, double const scaleAdjust);
void sethorizon(PLAYER *pPlayer, fixed_t const q16horz, double const scaleAdjust);
//---------------------------------------------------------------------------
//
@ -140,7 +139,7 @@ static void processMovement(ControlInfo* const hidInput)
if (gView->pXSprite->health != 0)
{
applylook(pPlayer, input.q16avel, scaleAdjust);
sethorizon(pPlayer, input.q16horz, scaleAdjust);
sethorizon(&pPlayer->q16horiz, input.q16horz, &pPlayer->input.actions, scaleAdjust);
}
// Process angle amendments from the game's ticker.

View File

@ -1350,75 +1350,6 @@ void applylook(PLAYER *pPlayer, fixed_t const q16avel, double const scaleAdjust)
pPlayer->angold = pSprite->ang = FixedToInt(pPlayer->q16ang);
}
//---------------------------------------------------------------------------
//
// Player's horizon function, called in processInput() or from gi->GetInput() as required.
//
//---------------------------------------------------------------------------
void sethorizon(PLAYER *pPlayer, fixed_t const q16horz, double const scaleAdjust)
{
InputPacket *pInput = &pPlayer->input;
// Calculate adjustment as true pitch (Fixed point math really sucks...)
double horizAngle = clamp(atan2(pPlayer->q16horiz - IntToFixed(100), IntToFixed(128)) * (512. / pi::pi()), -180, 180);
if (q16horz)
{
pInput->actions &= ~SB_CENTERVIEW;
horizAngle += FixedToFloat(q16horz);
}
// this is the locked type
if (pInput->actions & (SB_AIM_UP|SB_AIM_DOWN))
{
pInput->actions &= ~SB_CENTERVIEW;
// adjust q16horiz negative
if (pInput->actions & SB_AIM_DOWN)
horizAngle -= scaleAdjust * (210. / GameTicRate);
// adjust q16horiz positive
if (pInput->actions & SB_AIM_UP)
horizAngle += scaleAdjust * (210. / GameTicRate);
}
// this is the unlocked type
if (pInput->actions & (SB_LOOK_UP|SB_LOOK_DOWN))
{
pInput->actions |= SB_CENTERVIEW;
// adjust q16horiz negative
if (pInput->actions & SB_LOOK_DOWN)
horizAngle -= scaleAdjust * (420. / GameTicRate);
// adjust q16horiz positive
if (pInput->actions & SB_LOOK_UP)
horizAngle += scaleAdjust * (420. / GameTicRate);
}
if (pInput->actions & SB_CENTERVIEW)
{
if (!(pInput->actions & (SB_LOOK_UP|SB_LOOK_DOWN)))
{
// not pressing the q16horiz keys
if (horizAngle != 0)
{
// move q16horiz back to 100
horizAngle += scaleAdjust * ((1. / 65536.) - (horizAngle * (10. / GameTicRate)));
}
else
{
// not looking anymore because q16horiz is back at 100
pInput->actions &= ~SB_CENTERVIEW;
}
}
}
// Convert back to Build's horizon and clamp.
pPlayer->q16horiz = clamp(IntToFixed(100) + xs_CRoundToInt(IntToFixed(128) * tan(horizAngle * (pi::pi() / 512.))), IntToFixed(PLAYER_HORIZ_MIN), IntToFixed(PLAYER_HORIZ_MAX));
}
//---------------------------------------------------------------------------
//
// Unsynchronised input helpers.
@ -1429,7 +1360,6 @@ void resetinputhelpers(PLAYER* pPlayer)
{
pPlayer->horizAdjust = 0;
pPlayer->angAdjust = 0;
pPlayer->pitchAdjust = 0;
}
void playerAddAngle(PLAYER* pPlayer, double ang)
@ -1725,7 +1655,7 @@ void ProcessInput(PLAYER *pPlayer)
if (cl_syncinput)
{
sethorizon(pPlayer, pInput->q16horz, 1);
sethorizon(&pPlayer->q16horiz, pInput->q16horz, &pInput->actions, 1);
}
int nSector = pSprite->sectnum;

View File

@ -186,7 +186,7 @@ struct PLAYER
POSTURE pPosture[kModeMax][kPostureMax];
// Input helper variables and setters.
double horizAdjust, angAdjust, pitchAdjust;
double horizAdjust, angAdjust;
fixed_t horizTarget, angTarget;
void addang(int v) { q16ang = (q16ang + IntToFixed(v)) & 0x7FFFFFF; }
void setang(int v) { q16ang = IntToFixed(v); }

View File

@ -873,7 +873,7 @@ void viewDrawScreen(bool sceneonly)
{
cZ = vfc + (gLowerLink[nSectnum] >= 0 ? 0 : (8 << 8));
}
q16horiz = ClipRange(q16horiz, IntToFixed(-200), IntToFixed(200));
q16horiz = ClipRange(q16horiz, gi->playerHorizMin(), gi->playerHorizMax());
RORHACK:
int ror_status[16];
for (int i = 0; i < 16; i++)

View File

@ -1487,3 +1487,69 @@ fixed_t getincangleq16(fixed_t a, fixed_t na)
return (na-a);
}
}
//---------------------------------------------------------------------------
//
// Player's horizon function, called in processInput() or from gi->GetInput() as required.
//
//---------------------------------------------------------------------------
void sethorizon(fixed_t* q16horiz, fixed_t const q16horz, ESyncBits* actions, double const scaleAdjust)
{
// Calculate adjustment as true pitch (Fixed point math really sucks...)
double horizAngle = atan2(*q16horiz - IntToFixed(100), IntToFixed(128)) * (512. / pi::pi());
if (q16horz)
{
*actions &= ~SB_CENTERVIEW;
horizAngle = clamp(horizAngle + FixedToFloat(q16horz), -180, 180);
}
// this is the locked type
if (*actions & (SB_AIM_UP|SB_AIM_DOWN))
{
*actions &= ~SB_CENTERVIEW;
double const amount = 250. / GameTicRate;
if (*actions & SB_AIM_DOWN)
horizAngle -= scaleAdjust * amount;
if (*actions & SB_AIM_UP)
horizAngle += scaleAdjust * amount;
}
// this is the unlocked type
if (*actions & (SB_LOOK_UP|SB_LOOK_DOWN))
{
*actions |= SB_CENTERVIEW;
double const amount = 500. / GameTicRate;
if (*actions & SB_LOOK_DOWN)
horizAngle -= scaleAdjust * amount;
if (*actions & SB_LOOK_UP)
horizAngle += scaleAdjust * amount;
}
// convert back to Build's horizon
*q16horiz = IntToFixed(100) + xs_CRoundToInt(IntToFixed(128) * tan(horizAngle * (pi::pi() / 512.)));
// return to center if conditions met.
if ((*actions & SB_CENTERVIEW) && !(*actions & (SB_LOOK_UP|SB_LOOK_DOWN)))
{
if (*q16horiz < FloatToFixed(99.75) || *q16horiz > FloatToFixed(100.25))
{
// move *q16horiz back to 100
*q16horiz += xs_CRoundToInt(scaleAdjust * (((1000. / GameTicRate) * FRACUNIT) - (*q16horiz * (10. / GameTicRate))));
}
else
{
// not looking anymore because *q16horiz is back at 100
*q16horiz = IntToFixed(100);
*actions &= ~SB_CENTERVIEW;
}
}
// clamp before returning
*q16horiz = clamp(*q16horiz, gi->playerHorizMin(), gi->playerHorizMax());
}

View File

@ -66,6 +66,8 @@ void CompleteLevel(MapRecord* map);
int getincangle(int c, int n);
fixed_t getincangleq16(fixed_t c, fixed_t n);
void sethorizon(fixed_t* q16horiz, fixed_t const q16horz, ESyncBits* actions, double const scaleAdjust);
struct UserConfig
{
FString gamegrp;

View File

@ -108,6 +108,8 @@ struct GameInterface
virtual void LevelCompleted(MapRecord* map, int skill) {}
virtual bool DrawAutomapPlayer(int x, int y, int z, int a) { return false; }
virtual void SetTileProps(int tile, int surf, int vox, int shade) {}
virtual fixed_t playerHorizMin() { return IntToFixed(-99); }
virtual fixed_t playerHorizMax() { return IntToFixed(299); }
virtual FString statFPS()
{

View File

@ -1853,7 +1853,7 @@ void moveweapons_d(void)
if (s->picnum == SPIT)
{
playerAddHoriz(&ps[p], 32);
ps[p].return_to_center = 8;
sync[p].actions |= SB_CENTERVIEW;
if (ps[p].loogcnt == 0)
{

View File

@ -1400,7 +1400,7 @@ void moveweapons_r(void)
}
playerAddHoriz(&ps[p], 32);
ps[p].return_to_center = 8;
sync[p].actions |= SB_CENTERVIEW;
if (ps[p].loogcnt == 0)
{

View File

@ -261,7 +261,6 @@ LABELS playerlabels[]=
{ "pals", PLAYER_PALS, LABEL_HASPARM2, 3 },
{ "max_actors_killed", PLAYER_MAX_ACTORS_KILLED, 0, 0 },
{ "actors_killed", PLAYER_ACTORS_KILLED, 0, 0 },
{ "return_to_center", PLAYER_RETURN_TO_CENTER, 0, 0 },
{ "", -1, 0, 0 } // END OF LIST

View File

@ -229,7 +229,6 @@ int playercolor2lookup(int color);
void PlayerColorChanged(void);
void apply_seasick(player_struct* p, double scalefactor);
void calcviewpitch(player_struct* p, double factor);
void sethorizon(int snum, ESyncBits actions, double factor, fixed_t adjustment);
bool movementBlocked(int snum);
void loadcons();
void recordoldspritepos();

View File

@ -84,7 +84,7 @@ void fakebubbaspawn(int g_i, int g_p);
void tearitup(int sect);
void destroyit(int g_i);
void mamaspawn(int g_i);
void forceplayerangle(struct player_struct* p);
void forceplayerangle(int snum);
bool killthesprite = false;
@ -909,11 +909,6 @@ void DoPlayer(bool bSet, int lVar1, int lLabelID, int lVar2, int sActor, int sPl
else SetGameVarID((int)lVar2, ps[iPlayer].actors_killed, sActor, sPlayer);
break;
case PLAYER_RETURN_TO_CENTER:
if (bSet) ps[iPlayer].return_to_center = lValue;
else SetGameVarID((int)lVar2, ps[iPlayer].return_to_center, sActor, sPlayer);
break;
default:
if (!bSet) SetGameVarID((int)lVar2, 0, sActor, sPlayer);
break;
@ -2461,14 +2456,14 @@ int ParseState::parse(void)
break;
case concmd_slapplayer:
insptr++;
forceplayerangle(&ps[g_p]);
forceplayerangle(g_p);
ps[g_p].posxv -= sintable[(ps[g_p].getang() + 512) & 2047] << 7;
ps[g_p].posyv -= sintable[ps[g_p].getang() & 2047] << 7;
return 0;
case concmd_wackplayer:
insptr++;
if (!isRR())
forceplayerangle(&ps[g_p]);
forceplayerangle(g_p);
else
{
ps[g_p].posxv -= sintable[(ps[g_p].getang() + 512) & 2047] << 10;

View File

@ -49,7 +49,9 @@ void GameInterface::Ticker()
// Make copies so that the originals do not have to be modified.
for (int i = 0; i < MAXPLAYERS; i++)
{
auto oldactions = sync[i].actions;
sync[i] = playercmds[i].ucmd;
if (oldactions & SB_CENTERVIEW) sync[i].actions |= SB_CENTERVIEW;
}
if (rtsplaying > 0) rtsplaying--;

View File

@ -67,7 +67,7 @@ void hud_input(int snum)
i = p->aim_mode;
p->aim_mode = !PlayerInput(snum, SB_AIMMODE);
if (p->aim_mode < i)
p->return_to_center = 9;
sync[snum].actions |= SB_CENTERVIEW;
// Backup weapon here as hud_input() is the first function where any one of the weapon variables can change.
backupweapon(p);
@ -965,7 +965,7 @@ static void FinalizeInput(int playerNum, InputPacket& input, bool vehicle)
loc.q16avel = input.q16avel = 0;
}
if (p->newowner == -1 && p->return_to_center <= 0)
if (p->newowner == -1 && !(sync[playerNum].actions & SB_CENTERVIEW))
{
loc.q16horz = clamp(loc.q16horz + input.q16horz, IntToFixed(-MAXHORIZVEL), IntToFixed(MAXHORIZVEL));
}
@ -1025,7 +1025,12 @@ static void GetInputInternal(InputPacket &locInput, ControlInfo* const hidInput)
// Do these in the same order as the old code.
calcviewpitch(p, scaleAdjust);
applylook(myconnectindex, scaleAdjust, input.q16avel);
sethorizon(myconnectindex, loc.actions, scaleAdjust, input.q16horz);
sethorizon(&p->q16horiz, input.q16horz, &sync[myconnectindex].actions, scaleAdjust);
if (p->horizAdjust)
{
p->q16horiz += FloatToFixed(scaleAdjust * p->horizAdjust);
}
}
}

View File

@ -157,14 +157,15 @@ void quickkill(struct player_struct* p)
//
//---------------------------------------------------------------------------
void forceplayerangle(struct player_struct* p)
void forceplayerangle(int snum)
{
player_struct* p = &ps[snum];
int n;
n = 128 - (krand() & 255);
playerAddHoriz(p, 64);
p->return_to_center = 9;
sync[snum].actions |= SB_CENTERVIEW;
p->setlookang(n >> 1);
p->setrotscrnang(n >> 1);
}
@ -406,7 +407,7 @@ void dokneeattack(int snum, int pi, const std::initializer_list<int> & respawnli
{
p->knee_incs++;
playerAddHoriz(p, -48);
p->return_to_center = 9;
sync[snum].actions |= SB_CENTERVIEW;
if (p->knee_incs > 15)
{
p->knee_incs = 0;
@ -920,7 +921,6 @@ void resetinputhelpers(player_struct* p)
{
p->horizAdjust = 0;
p->angAdjust = 0;
p->pitchAdjust = 0;
}
//---------------------------------------------------------------------------
@ -1002,43 +1002,6 @@ void checklook(int snum, ESyncBits actions)
//
//---------------------------------------------------------------------------
void sethorizon(int snum, ESyncBits actions, double factor, fixed_t adjustment)
{
auto p = &ps[snum];
// Calculate adjustment as true pitch (Fixed point math really sucks...)
double horizAngle = clamp(atan2(p->q16horiz - IntToFixed(100), IntToFixed(128)) * (512. / pi::pi()) + (factor * p->pitchAdjust) + (adjustment / 65536.), -180, 180);
if (p->return_to_center > 0 && (actions & (SB_LOOK_UP | SB_LOOK_DOWN)) == 0) // only snap back if no relevant button is pressed.
{
p->return_to_center += -factor * (p->return_to_center / 2);
horizAngle += -factor * (horizAngle / 2);
if (horizAngle > -0.5 && horizAngle < 0.5)
{
horizAngle = 0.;
p->return_to_center = 0.;
}
}
// Convert back to Build's horizon.
p->q16horiz = IntToFixed(100) + xs_CRoundToInt(IntToFixed(128) * tan(horizAngle * (pi::pi() / 512.)));
// Add horizAdjust if input is unsynchronised.
if (!cl_syncinput)
{
p->q16horiz += xs_CRoundToInt(factor * (p->horizAdjust * 65536.));
}
p->q16horiz = clamp(p->q16horiz, IntToFixed(HORIZ_MIN), IntToFixed(HORIZ_MAX));
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void playerCenterView(int snum)
{
auto p = &ps[snum];
@ -1046,7 +1009,11 @@ void playerCenterView(int snum)
OnEvent(EVENT_RETURNTOCENTER, p->i, snum, -1);
if (GetGameVarID(g_iReturnVarID, p->i, snum) == 0)
{
p->return_to_center = 9;
sync[snum].actions |= SB_CENTERVIEW;
}
else
{
sync[snum].actions &= ~SB_CENTERVIEW;
}
}
@ -1057,8 +1024,11 @@ void playerLookUp(int snum, ESyncBits actions)
OnEvent(EVENT_LOOKUP, p->i, snum, -1);
if (GetGameVarID(g_iReturnVarID, p->i, snum) == 0)
{
p->return_to_center = 9;
p->pitchAdjust += (actions & SB_RUN) ? 12 : 24;
sync[snum].actions |= SB_CENTERVIEW;
}
else
{
sync[snum].actions &= ~SB_LOOK_UP;
}
}
@ -1069,8 +1039,11 @@ void playerLookDown(int snum, ESyncBits actions)
OnEvent(EVENT_LOOKDOWN, p->i, snum, -1);
if (GetGameVarID(g_iReturnVarID, p->i, snum) == 0)
{
p->return_to_center = 9;
p->pitchAdjust -= (actions & SB_RUN) ? 12 : 24;
sync[snum].actions |= SB_CENTERVIEW;
}
else
{
sync[snum].actions &= ~SB_LOOK_DOWN;
}
}
@ -1079,9 +1052,9 @@ void playerAimUp(int snum, ESyncBits actions)
auto p = &ps[snum];
SetGameVarID(g_iReturnVarID, 0, p->i, snum);
OnEvent(EVENT_AIMUP, p->i, snum, -1);
if (GetGameVarID(g_iReturnVarID, p->i, snum) == 0)
if (GetGameVarID(g_iReturnVarID, p->i, snum) != 0)
{
p->pitchAdjust += (actions & SB_RUN) ? 6 : 12;
sync[snum].actions &= ~SB_AIM_UP;
}
}
@ -1090,9 +1063,9 @@ void playerAimDown(int snum, ESyncBits actions)
auto p = &ps[snum];
SetGameVarID(g_iReturnVarID, 0, p->i, snum);
OnEvent(EVENT_AIMDOWN, p->i, snum, -1);
if (GetGameVarID(g_iReturnVarID, p->i, snum) == 0)
if (GetGameVarID(g_iReturnVarID, p->i, snum) != 0)
{
p->pitchAdjust -= (actions & SB_RUN) ? 6 : 12;
sync[snum].actions &= ~SB_AIM_DOWN;
}
}

View File

@ -3078,7 +3078,7 @@ HORIZONLY:
if (cl_syncinput)
{
sethorizon(snum, actions, 1, PlayerHorizon(snum));
sethorizon(&p->q16horiz, PlayerHorizon(snum), &actions, 1);
}
checkhardlanding(p);

View File

@ -4091,7 +4091,7 @@ HORIZONLY:
if (cl_syncinput)
{
sethorizon(snum, actions, 1, PlayerHorizon(snum));
sethorizon(&p->q16horiz, PlayerHorizon(snum), &actions, 1);
}
checkhardlanding(p);

View File

@ -62,7 +62,6 @@ void resetmys()
myjumpingtoggle = ps[myconnectindex].jumping_toggle;
myonground = ps[myconnectindex].on_ground;
myhardlanding = ps[myconnectindex].hard_landing;
myreturntocenter = ps[myconnectindex].return_to_center;
}
#if 0 // todo: fix this when networking works again
@ -90,7 +89,6 @@ void fakedomovethingscorrect(void)
myjumpingtoggle = p->jumping_toggle;
myonground = p->on_ground;
myhardlanding = p->hard_landing;
myreturntocenter = p->return_to_center;
fakemovefifoplc = movefifoplc;
while (fakemovefifoplc < movefifoend[myconnectindex])

View File

@ -119,7 +119,7 @@ void resetplayerstats(int snum)
p->bobcounter = 0;
p->on_ground = 0;
p->player_par = 0;
p->return_to_center = 9;
sync[snum].actions |= SB_CENTERVIEW;
p->airleft = 15*26;
p->rapid_fire_hold = 0;
p->toggle_key_flag = 0;

View File

@ -229,7 +229,6 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, player_struct& w,
("walking_snd_toggle", w.walking_snd_toggle)
("palookup", w.palookup)
("hard_landing", w.hard_landing)
("return_to_center", w.return_to_center)
("max_secret_rooms", w.max_secret_rooms)
("secret_rooms", w.secret_rooms)
("max_actors_killed", w.max_actors_killed)
@ -299,7 +298,6 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, player_struct& w,
w.ohard_landing = w.hard_landing;
w.horizAdjust = 0;
w.angAdjust = 0;
w.pitchAdjust = 0;
w.lookLeft = false;
w.lookRight = false;
}

View File

@ -169,7 +169,6 @@ struct player_struct
unsigned char toggle_key_flag, knuckle_incs; // ,select_dir;
unsigned char walking_snd_toggle, palookup;
double return_to_center;
bool quick_kick_msg;
int max_secret_rooms, secret_rooms, max_actors_killed, actors_killed;
@ -208,7 +207,7 @@ struct player_struct
int8_t crouch_toggle;
// input stuff.
double horizAdjust, angAdjust, pitchAdjust;
double horizAdjust, angAdjust;
bool lookLeft, lookRight;

View File

@ -625,6 +625,7 @@ void GameInterface::Ticker(void)
auto pp = Player + i;
pp->lastinput = pp->input;
pp->input = playercmds[i].ucmd;
if (pp->lastinput.actions & SB_CENTERVIEW) pp->input.actions |= SB_CENTERVIEW;
}
domovethings();

View File

@ -1008,7 +1008,7 @@ struct PLAYERstruct
char WpnReloadState;
// Input helper variables and setters.
double horizAdjust, angAdjust, pitchAdjust;
double horizAdjust, angAdjust;
fixed_t horizTarget, angTarget;
void addang(int v) { q16ang = (q16ang + IntToFixed(v)) & 0x7FFFFFF; }
void setang(int v) { q16ang = IntToFixed(v); }
@ -1029,8 +1029,6 @@ enum
PF_JUMPING = (BIT(2)),
PF_FALLING = (BIT(3)),
PF_LOCK_CRAWL = (BIT(4)),
PF_LOCK_HORIZ = (BIT(5)),
PF_LOOKING = (BIT(6)),
PF_PLAYER_MOVED = (BIT(7)),
PF_PLAYER_RIDING = (BIT(8)),
PF_AUTO_AIM = (BIT(9)),

View File

@ -1785,68 +1785,8 @@ DoPlayerHorizon(PLAYERp pp, fixed_t const q16horz, double const scaleAdjust)
if (cl_slopetilting)
PlayerAutoLook(pp, scaleAdjust);
// Calculate adjustment as true pitch (Fixed point math really sucks...)
double horizAngle = clamp(atan2(pp->q16horizbase - IntToFixed(100), IntToFixed(128)) * (512. / pi::pi()), -180, 180);
if (q16horz)
{
horizAngle += FixedToFloat(q16horz);
SET(pp->Flags, PF_LOCK_HORIZ | PF_LOOKING);
}
// this is the locked type
if (pp->input.actions & (SB_AIM_UP|SB_AIM_DOWN))
{
// set looking because player is manually looking.
SET(pp->Flags, PF_LOCK_HORIZ | PF_LOOKING);
// adjust q16horiz negative
if (pp->input.actions & SB_AIM_DOWN)
horizAngle -= scaleAdjust * (HORIZ_SPEED >> 1);
// adjust q16horiz positive
if (pp->input.actions & SB_AIM_UP)
horizAngle += scaleAdjust * (HORIZ_SPEED >> 1);
}
// this is the unlocked type
if (pp->input.actions & (SB_LOOK_UP|SB_LOOK_DOWN|SB_CENTERVIEW))
{
RESET(pp->Flags, PF_LOCK_HORIZ);
SET(pp->Flags, PF_LOOKING);
// adjust q16horiz negative
if (pp->input.actions & SB_LOOK_DOWN)
horizAngle -= scaleAdjust * HORIZ_SPEED;
// adjust q16horiz positive
if (pp->input.actions & SB_LOOK_UP)
horizAngle += scaleAdjust * HORIZ_SPEED;
if (pp->input.actions & SB_CENTERVIEW)
pp->q16horizoff = 0;
}
if (!TEST(pp->Flags, PF_LOCK_HORIZ))
{
if (!(pp->input.actions & (SB_LOOK_UP|SB_LOOK_DOWN)))
{
// not pressing the q16horiz keys
if (horizAngle != 0)
{
// move q16horiz back to 100
horizAngle += scaleAdjust * ((1. / 65536.) - (horizAngle * 0.25));
}
else
{
// not looking anymore because q16horiz is back at 100
RESET(pp->Flags, PF_LOOKING);
}
}
}
// Convert back to Build's horizon and clamp.
pp->q16horizbase = clamp(IntToFixed(100) + xs_CRoundToInt(IntToFixed(128) * tan(horizAngle * (pi::pi() / 512.))), IntToFixed(PLAYER_HORIZ_MIN), IntToFixed(PLAYER_HORIZ_MAX));
// apply default horizon from backend
sethorizon(&pp->q16horizbase, q16horz, &pp->input.actions, scaleAdjust);
// bound adjust q16horizoff
if (pp->q16horizbase + pp->q16horizoff < IntToFixed(PLAYER_HORIZ_MIN))
@ -3408,10 +3348,9 @@ DoPlayerFall(PLAYERp pp)
}
else if (pp->jump_speed > 1300)
{
if (TEST(pp->Flags, PF_LOCK_HORIZ))
if (!(pp->input.actions & SB_CENTERVIEW))
{
RESET(pp->Flags, PF_LOCK_HORIZ);
SET(pp->Flags, PF_LOOKING);
pp->input.actions |= SB_CENTERVIEW;
}
}
@ -6139,7 +6078,7 @@ DoPlayerBeginDie(PLAYERp pp)
// Get rid of all panel spells that are currently working
KillAllPanelInv(pp);
SET(pp->Flags, PF_LOCK_HORIZ);
pp->input.actions &= ~SB_CENTERVIEW;
pp->friction = PLAYER_RUN_FRICTION;
pp->slide_xvect = pp->slide_yvect = 0;
@ -6402,9 +6341,9 @@ void DoPlayerDeathCheckKeys(PLAYERp pp)
RESET(pp->Flags, PF_WEAPON_DOWN|PF_WEAPON_RETRACT);
RESET(pp->Flags, PF_DEAD);
RESET(pp->Flags, PF_LOCK_HORIZ);
RESET(sp->cstat, CSTAT_SPRITE_YCENTER);
SET(sp->cstat, CSTAT_SPRITE_BLOCK|CSTAT_SPRITE_BLOCK_HITSCAN);
pp->input.actions |= SB_CENTERVIEW;
sp->xrepeat = PLAYER_NINJA_XREPEAT;
sp->yrepeat = PLAYER_NINJA_YREPEAT;
@ -7748,7 +7687,6 @@ void resetinputhelpers(PLAYERp pp)
{
pp->horizAdjust = 0;
pp->angAdjust = 0;
pp->pitchAdjust = 0;
}
void playerAddAngle(PLAYERp pp, double ang)