- revert most of e474ebc2b7 and adjust player's angle/horizon in a way that's compatible with cl_syncinput 0 and cl_syncinput 1.

Previous attempts at leveraging `applylook()` and `sethorizon()` in different spots had pros and cons, but ultimately changing where these functions were called from was a net negative and had hard to diagnose issues.

Maintaining two types of player input is considerable work. Lessons have been learned and will be beneficial when it comes time to re-doing the other games. Ideas from PR #98 for optimising RRRA vehicle experience while `cl_syncinput 0` is in use have been implemented here.
This commit is contained in:
Mitchell Richters 2020-08-05 17:53:22 +10:00
parent 65428a2d1a
commit 0ee3ab4df8
9 changed files with 338 additions and 119 deletions

View file

@ -762,7 +762,15 @@ void movecrane(int i, int crane)
s->owner = -2;
ps[p].on_crane = i;
S_PlayActorSound(isRR() ? 390 : DUKE_GRUNT, ps[p].i);
ps[p].setang(s->ang + 1024, true);
int ang = s->ang + 1024;
if (!cl_syncinput)
{
ps[p].angAdjust += ps[p].getang() + ang;
}
else
{
ps[p].setang(ang);
}
}
else
{
@ -2685,7 +2693,15 @@ void handle_se00(int i, int LASERLINE)
{
if (ps[p].cursectnum == s->sectnum && ps[p].on_ground == 1)
{
ps[p].angAdjust += l * q;
int ang = l * q;
if (!cl_syncinput)
{
ps[p].angAdjust += ang;
}
else
{
ps[p].addang(ang);
}
ps[p].posz += zchange;
@ -2877,7 +2893,14 @@ void handle_se14(int i, bool checkstat, int RPG, int JIBS6)
ps[p].bobposx += m;
ps[p].bobposy += x;
if (!cl_syncinput)
{
ps[p].angAdjust += q;
}
else
{
ps[p].addang(q);
}
if (numplayers > 1)
{

View file

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

View file

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

View file

@ -249,5 +249,6 @@ void backuplook(player_struct* p);
void backupview(player_struct* p);
void backupweapon(player_struct* p);
void resetinputhelpers(player_struct* p);
void checkhardlanding(player_struct* p);
END_DUKE_NS

View file

@ -1242,22 +1242,18 @@ void GetInput()
processVehicleInput(p, info, input, scaleAdjust);
FinalizeInput(myconnectindex, input, true);
if (!cl_syncinput)
{
p->q16ang = (p->q16ang + input.q16avel) & 0x7FFFFFF;
p->q16horiz = clamp(p->q16horiz, F16(HORIZ_MIN), F16(HORIZ_MAX));
if (sprite[p->i].extra > 0)
if (!cl_syncinput && sprite[p->i].extra > 0)
{
apply_seasick(p, scaleAdjust);
}
}
}
else
{
processMovement(p, input, info, scaleAdjust);
checkCrouchToggle(p);
processInputBits(p, info);
FinalizeInput(myconnectindex, input, false);
}
if (!cl_syncinput)
{
@ -1267,7 +1263,6 @@ void GetInput()
sethorizon(myconnectindex, loc.bits, scaleAdjust, true, input.q16horz);
}
}
}
//---------------------------------------------------------------------------
//

View file

@ -163,7 +163,15 @@ void forceplayerangle(struct player_struct* p)
n = 128 - (krand() & 255);
p->horizAdjust += 64;
int horiz = 64;
if (!cl_syncinput)
{
p->horizAdjust += horiz;
}
else
{
p->addhoriz(horiz);
}
p->return_to_center = 9;
p->setlookang(n >> 1);
p->setrotscrnang(n >> 1);
@ -405,7 +413,15 @@ void dokneeattack(int snum, int pi, const std::initializer_list<int> & respawnli
if (p->knee_incs > 0)
{
p->knee_incs++;
p->horizAdjust -= 48;
int horiz = -48;
if (!cl_syncinput)
{
p->horizAdjust += horiz;
}
else
{
p->addhoriz(horiz);
}
p->return_to_center = 9;
if (p->knee_incs > 15)
{
@ -822,9 +838,16 @@ void applylook(int snum, double factor, fixed_t adjustment)
}
p->q16ang += add;
}
p->q16ang += fix16_from_dbl(factor * p->angAdjust) + adjustment;
apply_seasick(p, factor);
}
// Add angAdjust if input is unsynchronised.
if (!cl_syncinput)
{
p->q16ang += fix16_from_dbl(factor * p->angAdjust);
}
p->q16ang = (p->q16ang + adjustment) & 0x7FFFFFF;
}
//---------------------------------------------------------------------------
@ -911,6 +934,29 @@ void resetinputhelpers(player_struct* p)
//
//---------------------------------------------------------------------------
void checkhardlanding(player_struct* p)
{
if (p->hard_landing > 0)
{
int horiz = p->hard_landing << 4;
if (!cl_syncinput)
{
p->horizAdjust -= horiz;
}
else
{
p->addhoriz(-horiz);
}
p->hard_landing--;
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void checklook(int snum, int sb_snum)
{
auto p = &ps[snum];
@ -970,7 +1016,16 @@ void sethorizon(int snum, int sb_snum, double factor, bool frominput, fixed_t ad
}
}
p->q16horiz = clamp((F16(100) + xs_CRoundToInt(F16(128) * tan(horizAngle * (pi::pi() / 512.)))) + (factor * (p->horizAdjust * 65536.)), F16(HORIZ_MIN), F16(HORIZ_MAX));
// Convert back to Build's horizon.
p->q16horiz = F16(100) + xs_CRoundToInt(F16(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, F16(HORIZ_MIN), F16(HORIZ_MAX));
}
//---------------------------------------------------------------------------

View file

@ -3028,9 +3028,22 @@ HORIZONLY:
playerAimDown(snum, sb_snum);
}
if (cl_syncinput)
{
sethorizon(snum, sb_snum, 1, sync[snum].q16horz);
}
if (p->hard_landing > 0)
{
p->horizAdjust -= p->hard_landing << 4;
int horiz = p->hard_landing << 4;
if (!cl_syncinput)
{
p->horizAdjust -= horiz;
}
else
{
p->addhoriz(-horiz);
}
p->hard_landing--;
}
@ -3052,11 +3065,6 @@ HORIZONLY:
dokneeattack(snum, pi, { FEM1, FEM2, FEM3, FEM4, FEM5, FEM6, FEM7, FEM8, FEM9, FEM10, PODFEM1, NAKED1, STATUE });
if (cl_syncinput)
{
sethorizon(snum, sb_snum, 1, false, sync[snum].q16horz);
}
if (fi.doincrements(p)) return;
if (p->weapon_pos != 0)

View file

@ -1410,31 +1410,6 @@ int doincrements_r(struct player_struct* p)
else if (p->knuckle_incs == 22 || PlayerInput(snum, SKB_FIRE))
p->knuckle_incs = 0;
// Originally, these functions were called before this function in processinput_r(), however with unsynchronised input changes,
// we need to call them after calling processweapon(), which happens after this function is called.
// Since this function returning 1 causes processinput_r() to return, we call them here in the event this function will return 1.
if (cl_syncinput)
{
if (!movementBlocked(snum))
{
auto sb_avel = PlayerInputAngVel(snum);
if (sector[p->cursectnum].lotag == ST_2_UNDERWATER)
{
p->q16angvel = (sb_avel - (sb_avel >> 3)) * sgn(TICSPERFRAME);
}
else
{
p->q16angvel = sb_avel * sgn(TICSPERFRAME);
}
applylook(snum, 1, p->q16angvel);
p->crack_time = 777;
}
sethorizon(snum, PlayerInputBits(snum, SKB_ALL), 1, !cl_syncinput, sync[snum].q16horz);
}
return 1;
}
return 0;
@ -1528,6 +1503,18 @@ void checkweapons_r(struct player_struct* p)
}
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
static inline double calcVehicleHorizAdjust(fixed_t q16horiz, int adjustment)
{
return -1. * ((q16horiz / 65536.) - adjustment);
}
//---------------------------------------------------------------------------
//
//
@ -1705,19 +1692,28 @@ static void onMotorcycle(int snum, ESyncBits &sb_snum)
}
if (p->TurbCount)
{
int horiz;
if (p->TurbCount <= 1)
{
p->sethoriz(100);
horiz = 100;
p->TurbCount = 0;
p->VBumpTarget = 0;
p->VBumpNow = 0;
}
else
{
p->sethoriz(100 + ((krand() & 15) - 7));
horiz = 100 + ((krand() & 15) - 7);
p->TurbCount--;
p->moto_drink = (krand() & 3) - 2;
}
if (!cl_syncinput)
{
p->horizAdjust += calcVehicleHorizAdjust(p->q16horiz, horiz);
}
else
{
p->sethoriz(horiz);
}
}
else if (p->VBumpTarget > p->VBumpNow)
{
@ -1727,8 +1723,15 @@ static void onMotorcycle(int snum, ESyncBits &sb_snum)
p->VBumpNow++;
if (p->VBumpTarget < p->VBumpNow)
p->VBumpNow = p->VBumpTarget;
if (!cl_syncinput)
{
p->horizAdjust += calcVehicleHorizAdjust(p->q16horiz, 100 + p->VBumpNow / 3);
}
else
{
p->sethoriz(100 + p->VBumpNow / 3);
}
}
else if (p->VBumpTarget < p->VBumpNow)
{
if (p->moto_bump_fast)
@ -1737,8 +1740,15 @@ static void onMotorcycle(int snum, ESyncBits &sb_snum)
p->VBumpNow--;
if (p->VBumpTarget > p->VBumpNow)
p->VBumpNow = p->VBumpTarget;
if (!cl_syncinput)
{
p->horizAdjust += calcVehicleHorizAdjust(p->q16horiz, 100 + p->VBumpNow / 3);
}
else
{
p->sethoriz(100 + p->VBumpNow / 3);
}
}
else
{
p->VBumpTarget = 0;
@ -1757,6 +1767,7 @@ static void onMotorcycle(int snum, ESyncBits &sb_snum)
var98 = 350;
else
var98 = -350;
int ang;
if (p->moto_on_mud || p->moto_on_oil || !p->NotOnWater)
{
if (p->moto_on_oil)
@ -1767,13 +1778,13 @@ static void onMotorcycle(int snum, ESyncBits &sb_snum)
{
p->posxv += (var8c >> 5) * (sintable[(var94 * -51 + var90 + 512) & 2047] << 4);
p->posyv += (var8c >> 5) * (sintable[(var94 * -51 + var90) & 2047] << 4);
p->setang((var90 - (var98 >> 2)) & 2047);
ang = var98 >> 2;
}
else
{
p->posxv += (var8c >> 7) * (sintable[(var94 * -51 + var90 + 512) & 2047] << 4);
p->posyv += (var8c >> 7) * (sintable[(var94 * -51 + var90) & 2047] << 4);
p->setang((var90 - (var98 >> 6)) & 2047);
ang = var98 >> 6;
}
p->moto_on_mud = 0;
p->moto_on_oil = 0;
@ -1784,7 +1795,7 @@ static void onMotorcycle(int snum, ESyncBits &sb_snum)
{
p->posxv += (var8c >> 5) * (sintable[(var94 * -51 + var90 + 512) & 2047] << 4);
p->posyv += (var8c >> 5) * (sintable[(var94 * -51 + var90) & 2047] << 4);
p->setang((var90 - (var98 >> 4)) & 2047);
ang = var98 >> 4;
if (!S_CheckActorSoundPlaying(pi, 220))
S_PlayActorSound(220, pi);
}
@ -1792,9 +1803,17 @@ static void onMotorcycle(int snum, ESyncBits &sb_snum)
{
p->posxv += (var8c >> 7) * (sintable[(var94 * -51 + var90 + 512) & 2047] << 4);
p->posyv += (var8c >> 7) * (sintable[(var94 * -51 + var90) & 2047] << 4);
p->setang((var90 - (var98 >> 7)) & 2047);
ang = var98 >> 7;
}
}
if (!cl_syncinput)
{
p->angAdjust -= ang;
}
else
{
p->setang((var90 - ang) & 2047);
}
}
else if (p->MotoSpeed >= 20 && p->on_ground == 1 && (p->moto_on_mud || p->moto_on_oil))
{
@ -2025,19 +2044,28 @@ static void onBoat(int snum, ESyncBits& sb_snum)
}
if (p->TurbCount)
{
int horiz;
if (p->TurbCount <= 1)
{
p->sethoriz(100);
horiz = 100;
p->TurbCount = 0;
p->VBumpTarget = 0;
p->VBumpNow = 0;
}
else
{
p->sethoriz(100 + ((krand() & 15) - 7));
horiz = 100 + ((krand() & 15) - 7);
p->TurbCount--;
p->moto_drink = (krand() & 3) - 2;
}
if (!cl_syncinput)
{
p->horizAdjust += calcVehicleHorizAdjust(p->q16horiz, horiz);
}
else
{
p->sethoriz(horiz);
}
}
else if (p->VBumpTarget > p->VBumpNow)
{
@ -2047,8 +2075,15 @@ static void onBoat(int snum, ESyncBits& sb_snum)
p->VBumpNow++;
if (p->VBumpTarget < p->VBumpNow)
p->VBumpNow = p->VBumpTarget;
if (!cl_syncinput)
{
p->horizAdjust += calcVehicleHorizAdjust(p->q16horiz, 100 + p->VBumpNow / 3);
}
else
{
p->sethoriz(100 + p->VBumpNow / 3);
}
}
else if (p->VBumpTarget < p->VBumpNow)
{
if (p->moto_bump_fast)
@ -2057,8 +2092,15 @@ static void onBoat(int snum, ESyncBits& sb_snum)
p->VBumpNow--;
if (p->VBumpTarget > p->VBumpNow)
p->VBumpNow = p->VBumpTarget;
if (!cl_syncinput)
{
p->horizAdjust += calcVehicleHorizAdjust(p->q16horiz, 100 + p->VBumpNow / 3);
}
else
{
p->sethoriz(100 + p->VBumpNow / 3);
}
}
else
{
p->VBumpTarget = 0;
@ -2078,17 +2120,26 @@ static void onBoat(int snum, ESyncBits& sb_snum)
else
vare0 = -350;
vard4 <<= 2;
int ang;
if (p->moto_do_bump)
{
p->posxv += (vard4 >> 6) * (sintable[(vardc * -51 + vard8 + 512) & 2047] << 4);
p->posyv += (vard4 >> 6) * (sintable[(vardc * -51 + vard8) & 2047] << 4);
p->setang((vard8 - (vare0 >> 5)) & 2047);
ang = vare0 >> 5;
}
else
{
p->posxv += (vard4 >> 7) * (sintable[(vardc * -51 + vard8 + 512) & 2047] << 4);
p->posyv += (vard4 >> 7) * (sintable[(vardc * -51 + vard8) & 2047] << 4);
p->setang((vard8 - (vare0 >> 6)) & 2047);
ang = vare0 >> 6;
}
if (!cl_syncinput)
{
p->angAdjust -= ang;
}
else
{
p->setang((vard8 - ang) & 2047);
}
}
if (p->NotOnWater)
@ -2421,15 +2472,24 @@ void onMotorcycleMove(int snum, int psect, int j)
j &= (MAXWALLS - 1);
var108 = getangle(wall[wall[j].point2].x - wall[j].x, wall[wall[j].point2].y - wall[j].y);
var10c = abs(p->getang() - var108);
int ang;
switch (krand() & 1)
{
case 0:
p->angAdjust += p->MotoSpeed >> 1;
ang = p->MotoSpeed >> 1;
break;
case 1:
p->angAdjust -= p->MotoSpeed >> 1;
ang = -(p->MotoSpeed >> 1);
break;
}
if (!cl_syncinput)
{
p->angAdjust += ang;
}
else
{
p->addang(ang);
}
if (var10c >= 441 && var10c <= 581)
{
var104 = (p->MotoSpeed * p->MotoSpeed) >> 8;
@ -2486,15 +2546,24 @@ void onBoatMove(int snum, int psect, int j)
j &= (MAXWALLS - 1);
var114 = getangle(wall[wall[j].point2].x - wall[j].x, wall[wall[j].point2].y - wall[j].y);
var118 = abs(p->getang() - var114);
int ang;
switch (krand() & 1)
{
case 0:
p->angAdjust += p->MotoSpeed >> 2;
ang = p->MotoSpeed >> 2;
break;
case 1:
p->angAdjust -= p->MotoSpeed >> 2;
ang = -(p->MotoSpeed >> 2);
break;
}
if (!cl_syncinput)
{
p->angAdjust += ang;
}
else
{
p->addang(ang);
}
if (var118 >= 441 && var118 <= 581)
{
p->MotoSpeed = ((p->MotoSpeed >> 1) + (p->MotoSpeed >> 2)) >> 2;
@ -3028,7 +3097,14 @@ static void operateweapon(int snum, ESyncBits sb_snum, int psect)
case RIFLEGUN_WEAPON:
p->kickback_pic++;
if (!cl_syncinput)
{
p->horizAdjust += 1;
}
else
{
p->addhoriz(1);
}
p->recoil++;
if (p->kickback_pic <= 12)
@ -3117,13 +3193,27 @@ static void operateweapon(int snum, ESyncBits sb_snum, int psect)
checkavailweapon(p);
}
if (p->kickback_pic == 2)
{
if (!cl_syncinput)
{
p->angAdjust += 16;
}
else
{
p->addang(16);
}
}
else if (p->kickback_pic == 4)
{
if (!cl_syncinput)
{
p->angAdjust -= 16;
}
else
{
p->addang(-16);
}
}
if (p->kickback_pic > 4)
p->kickback_pic = 1;
if (!(sb_snum & SKB_FIRE))
@ -3147,12 +3237,27 @@ static void operateweapon(int snum, ESyncBits sb_snum, int psect)
checkavailweapon(p);
}
if (p->kickback_pic == 2)
{
int ang = 4;
if (!cl_syncinput)
{
p->angAdjust += 4;
}
else
{
p->addang(4);
}
}
else if (p->kickback_pic == 4)
{
p->angAdjust -= 4;
if (!cl_syncinput)
{
p->angAdjust -= -4;
}
else
{
p->addang(-4);
}
}
if (p->kickback_pic > 4)
p->kickback_pic = 1;
@ -3200,7 +3305,14 @@ 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;
if (!cl_syncinput)
{
p->horizAdjust += 20;
}
else
{
p->addhoriz(20);
}
p->recoil += 20;
}
if (p->kickback_pic > 20)
@ -3709,6 +3821,34 @@ void processinput_r(int snum)
movement(snum, sb_snum, psect, fz, cz, shrunk, truefdist);
}
//Do the quick lefts and rights
if (movementBlocked(snum))
{
doubvel = 0;
p->posxv = 0;
p->posyv = 0;
}
else if (cl_syncinput)
{
//p->ang += syncangvel * constant
//ENGINE calculates angvel for you
// may still be needed later for demo recording
if (psectlotag == ST_2_UNDERWATER)
{
p->q16angvel = (sb_avel - (sb_avel >> 3)) * sgn(doubvel);
}
else
{
p->q16angvel = sb_avel * sgn(doubvel);
}
applylook(snum, 1, p->q16angvel);
p->crack_time = 777;
}
if (p->spritebridge == 0)
{
j = sector[s->sectnum].floorpicnum;
@ -4056,13 +4196,23 @@ HORIZONLY:
if (!d)
d = 1;
p->recoil -= d;
if (!cl_syncinput)
{
p->horizAdjust -= d;
}
if (p->hard_landing > 0)
else
{
p->horizAdjust -= p->hard_landing << 4;
p->hard_landing--;
p->addhoriz(-d);
}
}
if (cl_syncinput)
{
sethorizon(snum, sb_snum, 1, sync[snum].q16horz);
}
checkhardlanding(p);
//Shooting code/changes
@ -4096,38 +4246,6 @@ HORIZONLY:
}
processweapon(snum, sb_snum, psect);
//Do the quick lefts and rights
if (movementBlocked(snum))
{
doubvel = 0;
p->posxv = 0;
p->posyv = 0;
}
else if (cl_syncinput)
{
//p->ang += syncangvel * constant
//ENGINE calculates angvel for you
// may still be needed later for demo recording
if (psectlotag == ST_2_UNDERWATER)
{
p->q16angvel = (sb_avel - (sb_avel >> 3)) * sgn(doubvel);
}
else
{
p->q16angvel = sb_avel * sgn(doubvel);
}
applylook(snum, 1, p->q16angvel);
p->crack_time = 777;
}
if (cl_syncinput)
{
sethorizon(snum, sb_snum, 1, !cl_syncinput, sync[snum].q16horz);
}
}
//---------------------------------------------------------------------------

View file

@ -214,23 +214,25 @@ struct player_struct
int8_t crouch_toggle;
// input stuff.
int horizAdjust, angAdjust, pitchAdjust;
double horizAdjust, angAdjust, pitchAdjust;
bool lookLeft, lookRight;
// Access helpers for the widened angle and horizon fields.
void setlookang(int b) { q16look_ang = b << FRACBITS; }
void addlookang(int b) { q16look_ang += b << FRACBITS; }
void addlookang(double b) { q16look_ang += int(b *65536.); }
void addlookang(double b) { q16look_ang += xs_CRoundToInt(b * FRACUNIT); }
void setrotscrnang(int b) { q16rotscrnang = b << FRACBITS; }
void addrotscrnang(int b) { q16rotscrnang += b << FRACBITS; }
void addrotscrnang(double b) { q16rotscrnang += int(b *65536.); }
void addrotscrnang(double b) { q16rotscrnang += xs_CRoundToInt(b * FRACUNIT); }
int getang() { return q16ang >> FRACBITS; }
int getoang() { return oq16ang >> FRACBITS; }
void setang(int v, bool smooth = false) { q16ang = v << FRACBITS; }
void setang(int v) { q16ang = v << FRACBITS; }
void addang(int v) { q16ang = (q16ang + (v << FRACBITS)) & 0x7FFFFFF; }
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 addhorizoff(double v) { q16horiz += xs_CRoundToInt(v * FRACUNIT); }
void sethoriz(int v) { q16horiz = (v << FRACBITS); }
void sethorizoff(int v) { q16horizoff = (v << FRACBITS); }
int gethoriz() { return q16horiz >> FRACBITS; }