From f49ded7962cad7352e3d46cee26d52424d745424 Mon Sep 17 00:00:00 2001 From: Mitchell Richters Date: Tue, 28 Jul 2020 22:12:09 +1000 Subject: [PATCH] - make `cl_syncinput` work for Duke. * Current setup was broken and unusable. * Fixed interpolation issues. * Only call `GetInput()` at frame-rate when `cl_syncinput` is 0. * Create `oq16look_ang` and interpolate it for enhanced smoothness. * Always reset `horizAngleAdjust` and `horizSkew` in `processinput_d()`. * Don't pre-scale `sb_avel` in `processinput_d()` and `processinput_r()`. * Promote `p->angvel` from short to fixed_t. * Don't descale `sync[snum].q16horz` in `processinput_d()` and `processinput_r()`. * Ensure `false` bool is provided to `sethorizon()` call in `processinput_d()` and `processinput_r()`. * Reset `p->q16angvel` in `resetplayerstats()`. --- source/games/duke/src/actors.cpp | 7 ------ source/games/duke/src/gameloop.cpp | 6 +++-- source/games/duke/src/player.cpp | 1 + source/games/duke/src/player_d.cpp | 39 +++++++++++++++--------------- source/games/duke/src/player_r.cpp | 32 ++++++++++++------------ source/games/duke/src/premap.cpp | 2 +- source/games/duke/src/render.cpp | 20 ++++++++------- source/games/duke/src/savegame.cpp | 2 +- source/games/duke/src/types.h | 6 ++--- 9 files changed, 57 insertions(+), 58 deletions(-) diff --git a/source/games/duke/src/actors.cpp b/source/games/duke/src/actors.cpp index 317b68e4f..29f184c16 100644 --- a/source/games/duke/src/actors.cpp +++ b/source/games/duke/src/actors.cpp @@ -442,13 +442,6 @@ void moveplayers(void) //Players execute(i, s->yvel, otherx); - //thisPlayer.smoothcamera = false; - //p->q16angvel = G_GetQ16AngleDelta(pPlayer->oq16ang, pPlayer->q16ang); - p->oq16ang = p->q16ang; - p->oq16horiz = p->q16horiz; - p->oq16horizoff = p->q16horizoff; - - if (ud.multimode > 1) if (sprite[ps[otherp].i].extra > 0) { diff --git a/source/games/duke/src/gameloop.cpp b/source/games/duke/src/gameloop.cpp index 9c787701e..f08c30fa2 100644 --- a/source/games/duke/src/gameloop.cpp +++ b/source/games/duke/src/gameloop.cpp @@ -352,8 +352,10 @@ bool GameTicker() exitlevel(); } - - GetInput(); + if (!cl_syncinput) + { + GetInput(); + } int const smoothRatio = calc_smoothratio(totalclock, ototalclock); diff --git a/source/games/duke/src/player.cpp b/source/games/duke/src/player.cpp index 1074506b1..d67f3b906 100644 --- a/source/games/duke/src/player.cpp +++ b/source/games/duke/src/player.cpp @@ -880,6 +880,7 @@ void checklook(int snum, int sb_snum) } } p->oq16ang = p->q16ang; + p->oq16look_ang = p->q16look_ang; if (cl_syncinput) applylook(snum, 1); diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index e5cda012b..ab060fe74 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -2596,11 +2596,8 @@ void processinput_d(int snum) pi = p->i; s = &sprite[pi]; - if (!cl_syncinput) - { - p->horizAngleAdjust = 0; - p->horizSkew = 0; - } + p->horizAngleAdjust = 0; + p->horizSkew = 0; sb_snum = PlayerInputBits(snum, SKB_ALL); @@ -2794,21 +2791,23 @@ void processinput_d(int snum) p->posxv = 0; p->posyv = 0; } - else if (sb_avel) //p->ang += syncangvel * constant - { //ENGINE calculates angvel for you - if (cl_syncinput) + else if (sb_avel && cl_syncinput) + { + //p->ang += syncangvel * constant + //ENGINE calculates angvel for you + // may still be needed later for demo recording + + if (psectlotag == ST_2_UNDERWATER) { - // may still be needed later for demo recording - int tempang; - - tempang = sb_avel << 1; // this is fixed point! - - if (psectlotag == ST_2_UNDERWATER) p->angvel = (tempang - (tempang >> 3)) * sgn(doubvel); - else p->angvel = tempang * sgn(doubvel); - - p->addang(p->angvel); - p->q16ang &= (2048 << FRACBITS) - 1; + p->q16angvel = (sb_avel - (sb_avel >> 3)) * sgn(doubvel); } + else + { + p->q16angvel = sb_avel * sgn(doubvel); + } + + p->q16ang += p->q16angvel; + p->q16ang &= 0x7FFFFFF; p->crack_time = 777; } @@ -3053,8 +3052,8 @@ HORIZONLY: if (cl_syncinput) { - p->q16horiz += (sync[snum].q16horz >> 1); - sethorizon(snum, sb_snum, 1); + p->q16horiz += sync[snum].q16horz; + sethorizon(snum, sb_snum, 1, false); } //Shooting code/changes diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index 41505d45c..42631308d 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -3702,21 +3702,23 @@ void processinput_r(int snum) p->posxv = 0; p->posyv = 0; } - else if (sb_avel) //p->ang += syncangvel * constant - { //ENGINE calculates angvel for you - if (cl_syncinput) + else if (sb_avel && cl_syncinput) + { + //p->ang += syncangvel * constant + //ENGINE calculates angvel for you + // may still be needed later for demo recording + + if (psectlotag == ST_2_UNDERWATER) { - // may still be needed later for demo recording - int tempang; - - tempang = sb_avel << 1; // this is fixed point! - - if (psectlotag == 2) p->angvel = (tempang - (tempang >> 3)) * sgn(doubvel); - else p->angvel = tempang * sgn(doubvel); - - p->addang(p->angvel); - p->q16ang &= (2048 << FRACBITS) - 1; + p->q16angvel = (sb_avel - (sb_avel >> 3)) * sgn(doubvel); } + else + { + p->q16angvel = sb_avel * sgn(doubvel); + } + + p->q16ang += p->q16angvel; + p->q16ang &= 0x7FFFFFF; p->crack_time = 777; } @@ -4080,8 +4082,8 @@ HORIZONLY: if (cl_syncinput) { - p->q16horiz += (sync[snum].q16horz >> 1); - sethorizon(snum, sb_snum, 1); + p->q16horiz += sync[snum].q16horz; + sethorizon(snum, sb_snum, 1, false); } //Shooting code/changes diff --git a/source/games/duke/src/premap.cpp b/source/games/duke/src/premap.cpp index ee509d6fc..842964751 100644 --- a/source/games/duke/src/premap.cpp +++ b/source/games/duke/src/premap.cpp @@ -94,7 +94,7 @@ void resetplayerstats(int snum) p->pyoff = 0; p->opyoff = 0; p->loogcnt = 0; - //p->angvel = 0; + p->q16angvel = 0; p->weapon_sway = 0; // p->select_dir = 0; p->extra_extra8 = 0; diff --git a/source/games/duke/src/render.cpp b/source/games/duke/src/render.cpp index ee21e510c..9216a7551 100644 --- a/source/games/duke/src/render.cpp +++ b/source/games/duke/src/render.cpp @@ -551,10 +551,10 @@ void displayrooms(int snum, int smoothratio) cposz = omyz + mulscale16((int)(myz - omyz), smoothratio); if (cl_syncinput) { - cang.interpolate(q16ang(oq16myang), q16ang(q16myang), smoothratio); - fix16_t osum = (oq16myhoriz + oq16myhorizoff); - fix16_t sum = (q16myhoriz + q16myhorizoff); + fixed_t osum = (oq16myhoriz + oq16myhorizoff); + fixed_t sum = (q16myhoriz + q16myhorizoff); choriz = q16horiz(osum + mulscale16(sum - osum, smoothratio)); + cang = q16ang(oq16myang + mulscale16(((q16myang + (1024 << FRACBITS) - oq16myang) & 0x7FFFFFF) - (1024 << FRACBITS), smoothratio)); } else { @@ -571,19 +571,21 @@ void displayrooms(int snum, int smoothratio) if (cl_syncinput /*|| smoothcamera*/) { // Original code for when the values are passed through the sync struct - cang.interpolate(q16ang(p->oq16ang), q16ang(p->q16ang), smoothratio); - fix16_t osum = (p->oq16horiz + p->oq16horizoff); - fix16_t sum = (p->q16horiz + p->q16horizoff); - choriz = q16horiz(osum + mulscale16(sum - osum, smoothratio)); + fixed_t ohorz = (p->oq16horiz + p->oq16horizoff); + fixed_t horz = (p->q16horiz + p->q16horizoff); + choriz = q16horiz(ohorz + mulscale16(horz - ohorz, smoothratio)); + + fixed_t oang = (p->oq16ang + p->oq16look_ang); + fixed_t ang = (p->q16ang + p->q16look_ang); + cang = q16ang(oang + mulscale16(((ang + (1024 << FRACBITS) - oang) & 0x7FFFFFF) - (1024 << FRACBITS), smoothratio)); } else { // This is for real time updating of the view direction. - cang = q16ang(p->q16ang); + cang = q16ang(p->q16ang + p->q16look_ang); choriz = q16horiz(p->q16horiz + p->q16horizoff); } } - cang += q16ang(p->q16look_ang); if (p->newowner >= 0) { diff --git a/source/games/duke/src/savegame.cpp b/source/games/duke/src/savegame.cpp index 57cf983e7..328ab4d23 100644 --- a/source/games/duke/src/savegame.cpp +++ b/source/games/duke/src/savegame.cpp @@ -149,7 +149,7 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, player_struct& w, ("crack_time", w.crack_time) ("aim.mode", w.aim_mode) ("auto_aim", w.auto_aim) - ("angvel", w.angvel) + ("q16angvel", w.q16angvel) ("cursectnum", w.cursectnum) ("last_extra", w.last_extra) ("subweapon", w.subweapon) diff --git a/source/games/duke/src/types.h b/source/games/duke/src/types.h index 9b079bce9..348c498da 100644 --- a/source/games/duke/src/types.h +++ b/source/games/duke/src/types.h @@ -101,8 +101,8 @@ struct player_struct }; // input handles angle and horizon as fixed16 numbers. We need to account for that as well. - fixed_t q16ang, q16horiz, q16horizoff, q16rotscrnang, q16look_ang; - fixed_t oq16ang, oq16horiz, oq16horizoff, oq16rotscrnang; // These are only needed with synchronous mouse input. + fixed_t q16ang, q16horiz, q16horizoff, q16rotscrnang, q16look_ang, q16angvel; + fixed_t oq16ang, oq16horiz, oq16horizoff, oq16rotscrnang, oq16look_ang; // These are only needed with synchronous mouse input. fixed_t one_eighty_count; // using a bit field for this to save a bit of space. @@ -126,7 +126,7 @@ struct player_struct int aim_mode, auto_aim; - short angvel, cursectnum, last_extra, subweapon; + short cursectnum, last_extra, subweapon; short ammo_amount[MAX_WEAPONS], wackedbyactor, frag, fraggedself; short curr_weapon, last_weapon, tipincs, wantweaponfire;