- multiple input fixes for both games, and for both cl_syncinput 0 and cl_syncinput 1 modes.

* For RR, `processweapon_r()` was performing angle and horizon changes directly which provided a harsh experience with the default `cl_syncinput 0` mode.
* Added `angAdjust` variable to `player_struct` for use with ticrate angle adjustments.
* Renamed `horizAngleAdjust` to `horizAdjust` so that there is less confusion with the new `angAdjust` variable.
* Removed `horizSkew` variable, can just use `horizAdjust` for this.
* Replaced all calls to `addang()` and `addhoriz()` with the appropriate additions/subtractions to `angAdjust` and `horizAdjust` respectively.
* Removed now unused `addang()` and `addhoriz()` setters from `player_struct`.
* Define new function `resetinputhelpers()` to eliminate code duplication between `processinput_d()` and `processinput_r()` functions.
* Remove `p->q16ang` and `p->q16horiz` direct setting from `FinalizeInput()`.
* Change `applylook()` to accept an `fixed_t adjustment` for changing the player's angle. This can either be `input.q16avel` when `cl_syncinput` is 0, or `sync[snum].q16angvel` when `cl_syncinput` is 1.
* Change `sethorizon()` to accept an `fixed_t adjustment` for changing the player's horizon. This can either be `input.q16horz` when `cl_syncinput` is 0, or `sync[snum].q16horz` when `cl_syncinput` is 1.
* Re-work `sethorizon()` to always adjust `p->q16horiz` using the true pitch code. This closer resembles the EDuke32 implementation as per SVN 7342.
* Re-work returning to center to work off the true pitch code and always ensure that the player returns to center.
* Implement work-around for RR where we need to call `sethorizon()` before the call to `fi.doincrements()` like the original game, but also after the call to `processweapon()` to apply any angle or horizon changes due to weapon recoil, etc. We work around this by calling `sethorizon()` from within `doincrements_r()` only if `cl_syncinput` is 1 and only if `doincrements_r()` is to return 1.
This commit is contained in:
Mitchell Richters 2020-08-03 21:19:45 +10:00
parent d9fab07c31
commit e474ebc2b7
10 changed files with 91 additions and 104 deletions

View file

@ -2660,8 +2660,7 @@ void handle_se00(int i, int LASERLINE)
{
if (ps[p].cursectnum == s->sectnum && ps[p].on_ground == 1)
{
ps[p].addang(l * q, true);
ps[p].angAdjust += l * q;
ps[p].posz += zchange;
@ -2853,7 +2852,7 @@ void handle_se14(int i, bool checkstat, int RPG, int JIBS6)
ps[p].bobposx += m;
ps[p].bobposy += x;
ps[p].addang(q, true);
ps[p].angAdjust += q;
if (numplayers > 1)
{

View file

@ -1852,7 +1852,7 @@ void moveweapons_d(void)
if (s->picnum == SPIT)
{
ps[p].addhoriz(32);
ps[p].horizAdjust += 32;
ps[p].return_to_center = 8;
if (ps[p].loogcnt == 0)

View file

@ -1398,7 +1398,7 @@ void moveweapons_r(void)
guts_r(s, RABBITJIBB, 2, myconnectindex);
guts_r(s, RABBITJIBC, 2, myconnectindex);
}
ps[p].addhoriz(32);
ps[p].horizAdjust += 32;
ps[p].return_to_center = 8;
if (ps[p].loogcnt == 0)

View file

@ -108,7 +108,7 @@ void footprints(int snum);
int makepainsounds(int snum, int type);
void playerCrouch(int snum);
void playerJump(int snum, int fz, int cz);
void applylook(int snum, double factor);
void applylook(int snum, double factor, fixed_t adjustment);
void checklook(int snum, int sb_snum);
void playerCenterView(int snum);
void playerLookUp(int snum, ESyncBits sb_snum);
@ -230,7 +230,7 @@ void PlayerColorChanged(void);
void nonsharedkeys(void);
void apply_seasick(player_struct* p, double scalefactor);
void calcviewpitch(player_struct* p, double factor);
void sethorizon(int snum, int sb_snum, double factor, bool frominput = false);
void sethorizon(int snum, int sb_snum, double factor, bool frominput, fixed_t adjustment);
bool movementBlocked(int snum);
void GetInput();
void startmainmenu();
@ -248,5 +248,6 @@ void backuppos(player_struct* p, bool noclipping = false);
void backuplook(player_struct* p);
void backupview(player_struct* p);
void backupweapon(player_struct* p);
void resetinputhelpers(player_struct* p);
END_DUKE_NS

View file

@ -1185,11 +1185,8 @@ static void FinalizeInput(int playerNum, input_t& input, bool vehicle)
if (p->on_crane < 0 && p->newowner == -1)
{
loc.q16avel += input.q16avel;
if (!cl_syncinput)
if (!cl_syncinput && input.q16avel)
{
p->q16ang = (p->q16ang + input.q16avel) & 0x7FFFFFF;
if (input.q16avel)
p->one_eighty_count = 0;
}
}
@ -1197,8 +1194,6 @@ static void FinalizeInput(int playerNum, input_t& input, bool vehicle)
if (p->newowner == -1 && p->return_to_center <= 0)
{
loc.q16horz = fix16_clamp(loc.q16horz + input.q16horz, F16(-MAXHORIZVEL), F16(MAXHORIZVEL));
if (!cl_syncinput)
p->q16horiz += input.q16horz; // will be clamped by the caller because further operations on q16horiz can follow.
}
}
}
@ -1264,9 +1259,9 @@ void GetInput()
if (!cl_syncinput)
{
// Do these in the same order as the old code.
applylook(myconnectindex, scaleAdjust);
applylook(myconnectindex, scaleAdjust, input.q16avel);
calcviewpitch(p, scaleAdjust);
sethorizon(myconnectindex, loc.bits, scaleAdjust, true);
sethorizon(myconnectindex, loc.bits, scaleAdjust, true, input.q16horz);
}
}
}

View file

@ -163,7 +163,7 @@ void forceplayerangle(struct player_struct* p)
n = 128 - (krand() & 255);
p->addhoriz(64);
p->horizAdjust += 64;
p->return_to_center = 9;
p->setlookang(n >> 1);
p->setrotscrnang(n >> 1);
@ -405,13 +405,7 @@ void dokneeattack(int snum, int pi, const std::initializer_list<int> & respawnli
if (p->knee_incs > 0)
{
p->knee_incs++;
if (cl_syncinput)
p->addhoriz(-48);
else
{
p->horizSkew = -48 * FRACUNIT;
}
p->horizAdjust -= 48;
p->return_to_center = 9;
if (p->knee_incs > 15)
{
@ -792,7 +786,7 @@ void apply_seasick(player_struct* p, double factor)
//
//---------------------------------------------------------------------------
void applylook(int snum, double factor)
void applylook(int snum, double factor, fixed_t adjustment)
{
auto p = &ps[snum];
@ -833,6 +827,7 @@ void applylook(int snum, double factor)
}
p->q16ang += add;
}
p->q16ang += fix16_from_dbl(factor * p->angAdjust) + adjustment;
apply_seasick(p, factor);
}
else
@ -915,6 +910,18 @@ void backupweapon(player_struct* p)
//
//---------------------------------------------------------------------------
void resetinputhelpers(player_struct* p)
{
p->horizAdjust = 0;
p->angAdjust = 0;
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void checklook(int snum, int sb_snum)
{
auto p = &ps[snum];
@ -941,9 +948,6 @@ void checklook(int snum, int sb_snum)
}
}
backuplook(p);
if (cl_syncinput)
applylook(snum, 1);
}
//---------------------------------------------------------------------------
@ -952,31 +956,32 @@ void checklook(int snum, int sb_snum)
//
//---------------------------------------------------------------------------
void sethorizon(int snum, int sb_snum, double factor, bool frominput)
void sethorizon(int snum, int sb_snum, double factor, bool frominput, fixed_t adjustment)
{
auto p = &ps[snum];
// Calculate adjustment as true pitch (Fixed point nath really sucks...)
if (p->horizAngleAdjust)
{
double horizAngle = atan2(p->q16horiz - F16(100), F16(128)) * (512. / pi::pi()) +factor * p->horizAngleAdjust;
p->q16horiz = F16(100) + int(F16(128) * tan(horizAngle * (pi::pi() / 512.)));
}
else if (p->return_to_center > 0 && (sb_snum & (SKB_LOOK_UP | SKB_LOOK_DOWN)) == 0) // only snap back if no relevant button is pressed.
{
if (!frominput) p->return_to_center--;
p->q16horiz += factor * (frominput? 2.016 : 1.) * (F16(33) - (p->q16horiz / 3)); // in P_GetInput this used different factors than in the original code. Hm...
}
// Calculate adjustment as true pitch (Fixed point math really sucks...)
double horizAngle = atan2(p->q16horiz - F16(100), F16(128)) * (512. / pi::pi()) + (factor * p->horizAdjust) + (adjustment / 65536.);
p->q16horiz += int(factor * p->horizSkew);
if (p->return_to_center > 0 && (sb_snum & (SKB_LOOK_UP | SKB_LOOK_DOWN)) == 0) // only snap back if no relevant button is pressed.
{
p->return_to_center -= factor * 1.;
horizAngle += factor * -(frominput? 1.1 : 0.55) * horizAngle; // in P_GetInput this used different factors than in the original code. Hm...
if (horizAngle > -1. && horizAngle < 1.)
{
horizAngle = 0.;
p->return_to_center = 0.;
}
if (p->aim_mode == 0)
{
// threshold was 5
if (p->q16horiz > F16(99) && p->q16horiz < F16(101)) p->sethoriz(100);
if (p->q16horizoff > F16(-1) && p->q16horizoff < F16(1)) p->sethorizoff(0);
}
p->q16horiz = clamp(p->q16horiz, F16(HORIZ_MIN), F16(HORIZ_MAX));
}
p->q16horiz = clamp(F16(100) + xs_CRoundToInt(F16(128) * tan(horizAngle * (pi::pi() / 512.))), F16(HORIZ_MIN), F16(HORIZ_MAX));
}
//---------------------------------------------------------------------------
@ -996,11 +1001,6 @@ void playerCenterView(int snum)
}
}
void horizAngleAdjust(int snum, int delta)
{
ps[snum].horizAngleAdjust = delta;
}
void playerLookUp(int snum, ESyncBits sb_snum)
{
auto p = &ps[snum];
@ -1009,7 +1009,7 @@ void playerLookUp(int snum, ESyncBits sb_snum)
if (GetGameVarID(g_iReturnVarID, p->i, snum) == 0)
{
p->return_to_center = 9;
horizAngleAdjust(snum, (sb_snum & SKB_RUN) ? 12 : 24);
p->horizAdjust += (sb_snum & SKB_RUN) ? 12 : 24;
}
}
@ -1021,7 +1021,7 @@ void playerLookDown(int snum, ESyncBits sb_snum)
if (GetGameVarID(g_iReturnVarID, p->i, snum) == 0)
{
p->return_to_center = 9;
horizAngleAdjust(snum, (sb_snum & SKB_RUN) ? -12 : -24);
p->horizAdjust -= (sb_snum & SKB_RUN) ? 12 : 24;
}
}
@ -1032,7 +1032,7 @@ void playerAimUp(int snum, ESyncBits sb_snum)
OnEvent(EVENT_AIMUP, p->i, snum, -1);
if (GetGameVarID(g_iReturnVarID, p->i, snum) == 0)
{
horizAngleAdjust(snum, (sb_snum & SKB_RUN) ? 6 : 12);
p->horizAdjust += (sb_snum & SKB_RUN) ? 6 : 12;
}
}
@ -1043,7 +1043,7 @@ void playerAimDown(int snum, ESyncBits sb_snum)
OnEvent(EVENT_AIMDOWN, p->i, snum, -1);
if (GetGameVarID(g_iReturnVarID, p->i, snum) == 0)
{
horizAngleAdjust(snum, (sb_snum & SKB_RUN) ? -6 : -12);
p->horizAdjust -= (sb_snum & SKB_RUN) ? 6 : 12;
}
}

View file

@ -2594,8 +2594,7 @@ void processinput_d(int snum)
pi = p->i;
s = &sprite[pi];
p->horizAngleAdjust = 0;
p->horizSkew = 0;
resetinputhelpers(p);
sb_snum = PlayerInputBits(snum, SKB_ALL);
@ -2782,7 +2781,7 @@ void processinput_d(int snum)
p->posxv = 0;
p->posyv = 0;
}
else if (sb_avel && cl_syncinput)
else if (cl_syncinput)
{
//p->ang += syncangvel * constant
//ENGINE calculates angvel for you
@ -2797,8 +2796,8 @@ void processinput_d(int snum)
p->q16angvel = sb_avel * sgn(doubvel);
}
p->q16ang += p->q16angvel;
p->q16ang &= 0x7FFFFFF;
applylook(snum, 1, p->q16angvel);
p->crack_time = 777;
}
@ -3007,12 +3006,6 @@ HORIZONLY:
fi.activatebysector(psect, pi);
}
if (!cl_syncinput)
{
if (p->return_to_center > 0)
p->return_to_center--;
}
// center_view
if (sb_snum & SKB_CENTER_VIEW || p->hard_landing)
{
@ -3037,14 +3030,13 @@ HORIZONLY:
if (p->hard_landing > 0)
{
p->horizSkew = (-(p->hard_landing << 4)) * FRACUNIT;
p->horizAdjust -= p->hard_landing << 4;
p->hard_landing--;
}
if (cl_syncinput)
{
p->q16horiz += sync[snum].q16horz;
sethorizon(snum, sb_snum, 1, false);
sethorizon(snum, sb_snum, 1, false, sync[snum].q16horz);
}
//Shooting code/changes

View file

@ -1410,6 +1410,14 @@ int doincrements_r(struct player_struct* p)
else if (p->knuckle_incs == 22 || PlayerInput(snum, SKB_FIRE))
p->knuckle_incs = 0;
// Originally, this was called before this function in processinput_r(), however with unsynchronised input changes,
// we need to call sethorizon() after calling processweapon(), which happens after this function is called.
// Since this function returning 1 causes processinput_r() to return, we call sethorizon() here in the event this function will return 1.
if (cl_syncinput)
{
sethorizon(snum, PlayerInputBits(snum, SKB_ALL), 1, !cl_syncinput, sync[snum].q16horz);
}
return 1;
}
return 0;
@ -2399,10 +2407,10 @@ void onMotorcycleMove(int snum, int psect, int j)
switch (krand() & 1)
{
case 0:
p->addang(p->MotoSpeed >> 1);
p->angAdjust += p->MotoSpeed >> 1;
break;
case 1:
p->addang(-p->MotoSpeed >> 1);
p->angAdjust -= p->MotoSpeed >> 1;
break;
}
if (var10c >= 441 && var10c <= 581)
@ -2464,10 +2472,10 @@ void onBoatMove(int snum, int psect, int j)
switch (krand() & 1)
{
case 0:
p->addang(p->MotoSpeed >> 2);
p->angAdjust += p->MotoSpeed >> 2;
break;
case 1:
p->addang(-p->MotoSpeed >> 2);
p->angAdjust -= p->MotoSpeed >> 2;
break;
}
if (var118 >= 441 && var118 <= 581)
@ -3003,7 +3011,7 @@ static void operateweapon(int snum, ESyncBits sb_snum, int psect)
case RIFLEGUN_WEAPON:
p->kickback_pic++;
p->addhoriz(1);
p->horizAdjust += 1;
p->recoil++;
if (p->kickback_pic <= 12)
@ -3093,11 +3101,11 @@ static void operateweapon(int snum, ESyncBits sb_snum, int psect)
}
if (p->kickback_pic == 2)
{
p->addang(16);
p->angAdjust += 16;
}
else if (p->kickback_pic == 4)
{
p->addang(-16);
p->angAdjust -= 16;
}
if (p->kickback_pic > 4)
p->kickback_pic = 1;
@ -3123,11 +3131,11 @@ static void operateweapon(int snum, ESyncBits sb_snum, int psect)
}
if (p->kickback_pic == 2)
{
p->addang(4);
p->angAdjust += 4;
}
else if (p->kickback_pic == 4)
{
p->addang(-4);
p->angAdjust -= 4;
}
if (p->kickback_pic > 4)
p->kickback_pic = 1;
@ -3175,7 +3183,7 @@ static void operateweapon(int snum, ESyncBits sb_snum, int psect)
{
p->posxv -= sintable[(p->getang() + 512) & 2047] << 4;
p->posyv -= sintable[p->getang() & 2047] << 4;
p->addhoriz(20);
p->horizAdjust += 20;
p->recoil += 20;
}
if (p->kickback_pic > 20)
@ -3392,8 +3400,7 @@ void processinput_r(int snum)
pi = p->i;
s = &sprite[pi];
p->horizAngleAdjust = 0;
p->horizSkew = 0;
resetinputhelpers(p);
sb_snum = PlayerInputBits(snum, SKB_ALL);
@ -3473,8 +3480,7 @@ void processinput_r(int snum)
if (cl_syncinput)
{
p->oq16horiz = p->q16horiz;
p->oq16horizoff = p->q16horizoff;
backupview(p);
calcviewpitch(p, 1);
}
@ -3694,7 +3700,7 @@ void processinput_r(int snum)
p->posxv = 0;
p->posyv = 0;
}
else if (sb_avel && cl_syncinput)
else if (cl_syncinput)
{
//p->ang += syncangvel * constant
//ENGINE calculates angvel for you
@ -3709,8 +3715,8 @@ void processinput_r(int snum)
p->q16angvel = sb_avel * sgn(doubvel);
}
p->q16ang += p->q16angvel;
p->q16ang &= 0x7FFFFFF;
applylook(snum, 1, p->q16angvel);
p->crack_time = 777;
}
@ -4064,20 +4070,14 @@ HORIZONLY:
if (!d)
d = 1;
p->recoil -= d;
p->addhoriz(-d);
p->horizAdjust -= d;
}
if (p->hard_landing > 0)
{
p->horizSkew = (-(p->hard_landing << 4)) * FRACUNIT;
p->horizAdjust -= p->hard_landing << 4;
p->hard_landing--;
}
if (cl_syncinput)
{
p->q16horiz += sync[snum].q16horz;
sethorizon(snum, sb_snum, 1, false);
}
//Shooting code/changes
if (p->show_empty_weapon > 0)
@ -4111,6 +4111,10 @@ HORIZONLY:
processweapon(snum, sb_snum, psect);
if (cl_syncinput)
{
sethorizon(snum, sb_snum, 1, !cl_syncinput, sync[snum].q16horz);
}
}
//---------------------------------------------------------------------------

View file

@ -296,8 +296,8 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, player_struct& w,
w.oposy = w.posy;
w.oposz = w.posz;
w.opyoff = w.pyoff;
w.horizAngleAdjust = 0;
w.horizSkew = 0;
w.horizAdjust = 0;
w.angAdjust = 0;
w.lookLeft = false;
w.lookRight = false;
}

View file

@ -175,7 +175,7 @@ struct player_struct
unsigned char toggle_key_flag, knuckle_incs; // ,select_dir;
unsigned char walking_snd_toggle, palookup;
unsigned char return_to_center;
double return_to_center;
bool quick_kick_msg;
int max_secret_rooms, secret_rooms, max_actors_killed, actors_killed;
@ -214,10 +214,8 @@ struct player_struct
int8_t crouch_toggle;
// input stuff.
float horizAngleAdjust;
fix16_t horizSkew;
bool lookLeft;
bool lookRight;
int horizAdjust, angAdjust;
bool lookLeft, lookRight;
// Access helpers for the widened angle and horizon fields.
@ -232,9 +230,7 @@ struct player_struct
int getang() { return q16ang >> FRACBITS; }
int getoang() { return oq16ang >> FRACBITS; }
void setang(int v, bool smooth = false) { q16ang = v << FRACBITS; }
void addang(int v, bool smooth = false) { q16ang = (q16ang + (v << FRACBITS)) & ((2048 << FRACBITS) - 1); }
void setoang(int v) { oq16ang = v << FRACBITS; }
void addhoriz(int v) { q16horiz += (v << FRACBITS); }
void addhorizoff(int v) { q16horiz += (v << FRACBITS); }
void addhorizoff(double v) { q16horiz += int(v * 65536.); }
void sethoriz(int v) { q16horiz = (v << FRACBITS); }