diff --git a/source/core/gameinput.h b/source/core/gameinput.h index 23f21659a..097db9406 100644 --- a/source/core/gameinput.h +++ b/source/core/gameinput.h @@ -91,6 +91,12 @@ struct PlayerHorizon fixed_t const curr = sum().asq16(); return q16horiz(prev + xs_CRoundToInt(ratio * (curr - prev))); } + + fixedhoriz interpolatedoff(double const smoothratio) + { + double const ratio = smoothratio * (1. / FRACUNIT); + return q16horiz(ohorizoff.asq16() + xs_CRoundToInt(ratio * (horizoff - ohorizoff).asq16())); + } }; struct PlayerAngle diff --git a/source/games/whaven/src/ai.cpp b/source/games/whaven/src/ai.cpp index 99a858517..e554af68b 100644 --- a/source/games/whaven/src/ai.cpp +++ b/source/games/whaven/src/ai.cpp @@ -211,7 +211,7 @@ void aiProcess() { PLAYER& plr = player[0]; // short daang = (short) plr.ang; - // int daz2 = (int) (100 - plr.horiz) * 2000; + // int daz2 = -mulscale16(plr.horizon.horiz.asq16(), 2000); // hitscan(plr.x, plr.y, plr.z, plr.sector, // Start position // sintable[(daang + 2560) & 2047], // X vector of 3D ang // sintable[(daang + 2048) & 2047], // Y vector of 3D ang diff --git a/source/games/whaven/src/input.cpp b/source/games/whaven/src/input.cpp index d7bda7f04..ca83e82a7 100644 --- a/source/games/whaven/src/input.cpp +++ b/source/games/whaven/src/input.cpp @@ -207,7 +207,9 @@ void processinput(int num) { oldposx = plr.x; oldposy = plr.y; - auto bits = plr.plInput.actions; + plr.horizon.resetadjustment(); + + auto& bits = plr.plInput.actions; if ((bits & SB_JUMP) == 0) plr.keytoggle = false; @@ -217,8 +219,8 @@ void processinput(int num) { if (plr.health <= 0) { playerdead(plr); if (plr.dead) { - if (plr.horiz < 100 + (200 >> 1)) - plr.horiz += (TICSPERFRAME << 1); + if (plr.horizon.horiz.asbuild() < gi->playerHorizMax()) + plr.horizon.addadjustment(TICSPERFRAME << 1); } return; } @@ -260,18 +262,9 @@ void processinput(int num) { tics += tics >> 1; } - plr.horiz = clamp(plr.horiz + plr.plInput.horz, -(200 >> 1), 100 + (200 >> 1)); - - if ((bits & SB_AIM_DOWN) != 0) { - if (plr.horiz > 100 - (200 >> 1)) { - plr.horiz -= (TICSPERFRAME << 1); - autohoriz = 0; - } - } - else if ((bits & SB_AIM_UP) != 0) { - if (plr.horiz < 100 + (200 >> 1)) - plr.horiz += (TICSPERFRAME << 1); - autohoriz = 0; + if (cl_syncinput) + { + sethorizon(&plr.horizon.horiz, plr.plInput.horz, &bits, 1); } if ((bits & SB_FLYSTOP) != 0) @@ -483,7 +476,7 @@ void processinput(int num) { } // walking on sprite - plr.horiz -= oldhoriz; + plr.horizon.addadjustment(-oldhoriz); dist = ksqrt((plr.x - oldposx) * (plr.x - oldposx) + (plr.y - oldposy) * (plr.y - oldposy)); @@ -492,13 +485,11 @@ void processinput(int num) { if (dist > 0 && feetoffground <= (plr.height << 8) || onsprite != -1) { oldhoriz = ((dist * sintable[(lockclock << 5) & 2047]) >> 19) >> 2; - plr.horiz += oldhoriz; + plr.horizon.addadjustment(oldhoriz); } else oldhoriz = 0; - plr.horiz = clamp(plr.horiz, -(200 >> 1), 100 + (200 >> 1)); - if (onsprite != -1 && dist > 50 && lopoint == 1 && justplayed == 0) { switch (sprite[onsprite].picnum) { @@ -607,19 +598,6 @@ void processinput(int num) { if (plr.sector >= 0 && getceilzofslope(plr.sector, plr.x, plr.y) > getflorzofslope(plr.sector, plr.x, plr.y) - (8 << 8)) addhealth(plr, -10); - if ((bits & SB_CENTERVIEW) != 0) { - autohoriz = 1; - } - - if (autohoriz == 1) - { - if (plr.horiz < 100) - plr.horiz = std::min(plr.horiz + (TICSPERFRAME << 2), 100); - if (plr.horiz > 100) - plr.horiz = std::max(plr.horiz - (TICSPERFRAME << 2), 100); - if (plr.horiz == 100) - autohoriz = 0; - } if (plr.currweaponfired != 1 && plr.currweaponfired != 6) plr.hasshot = 0; weaponchange(num); @@ -629,4 +607,4 @@ void processinput(int num) { END_WH_NS - \ No newline at end of file + diff --git a/source/games/whaven/src/items.cpp b/source/games/whaven/src/items.cpp index 20967b08b..3285f294a 100644 --- a/source/games/whaven/src/items.cpp +++ b/source/games/whaven/src/items.cpp @@ -1062,7 +1062,7 @@ void InitItems() { if (plr.invincibletime <= 0 && !plr.godMode && !justteleported) { addhealth(plr, -plr.health); - plr.horiz = 200; + plr.horizon.settarget(100); plr.spiked = 1; } }); @@ -1071,7 +1071,7 @@ void InitItems() { if (plr.invincibletime <= 0 && !plr.godMode && !justteleported) { addhealth(plr, -plr.health); - plr.horiz = 200; + plr.horizon.settarget(100); plr.spiked = 1; } }); @@ -1080,7 +1080,7 @@ void InitItems() { if (plr.invincibletime <= 0 && !plr.godMode && !justteleported) { addhealth(plr, -plr.health); - plr.horiz = 200; + plr.horizon.settarget(100); plr.spiked = 1; } }); diff --git a/source/games/whaven/src/player.h b/source/games/whaven/src/player.h index 2d4a93022..19d529276 100644 --- a/source/games/whaven/src/player.h +++ b/source/games/whaven/src/player.h @@ -1,6 +1,7 @@ #pragma once #include "packet.h" +#include "gameinput.h" BEGIN_WH_NS @@ -10,7 +11,7 @@ struct PLAYER { int spellnum; int x,y,z; float ang; - float horiz, jumphoriz; + PlayerHorizon horizon; int height; int hvel; short sector; diff --git a/source/games/whaven/src/render.cpp b/source/games/whaven/src/render.cpp index 8f75b8642..1935bf243 100644 --- a/source/games/whaven/src/render.cpp +++ b/source/games/whaven/src/render.cpp @@ -17,32 +17,26 @@ void drawscreen(int num, double dasmoothratio, bool sceneonly) int cposy = plr.y; int cposz = plr.z; float cang = plr.ang; - float choriz = plr.horiz + plr.jumphoriz; + fixedhoriz choriz = plr.horizon.horiz + plr.horizon.interpolatedoff(dasmoothratio); if (!paused) { auto& prevloc = gPrevPlayerLoc[num]; - int ix = prevloc.x; - int iy = prevloc.y; - int iz = prevloc.z; - float iHoriz = prevloc.horiz; - float inAngle = prevloc.ang; + cposx = prevloc.x + mulscale16(cposx - prevloc.x, dasmoothratio); + cposy = prevloc.y + mulscale16(cposy - prevloc.y, dasmoothratio); + cposz = prevloc.z + mulscale16(cposz - prevloc.z, dasmoothratio); - ix += mulscale(cposx - prevloc.x, dasmoothratio, 16); - iy += mulscale(cposy - prevloc.y, dasmoothratio, 16); - iz += mulscale(cposz - prevloc.z, dasmoothratio, 16); - iHoriz += ((choriz - prevloc.horiz) * dasmoothratio) / 65536.0f; + float inAngle = prevloc.ang; inAngle += ((BClampAngle(cang - prevloc.ang + 1024) - 1024) * dasmoothratio) / 65536.0f; - cposx = ix; - cposy = iy; - cposz = iz; + if (cl_syncinput) + { + choriz = plr.horizon.interpolatedsum(dasmoothratio); + } - choriz = iHoriz; cang = inAngle; } - choriz -= 100; // make it 0-based like the rest of the engine expects. // wango if ((gotpic[FLOORMIRROR >> 3] & (1 << (FLOORMIRROR & 7))) != 0) { @@ -61,7 +55,7 @@ void drawscreen(int num, double dasmoothratio, bool sceneonly) // Todo: render this with 30% light only. inpreparemirror = true; renderSetRollAngle(1024); - renderDrawRoomsQ16(cposx, cposy, cposz, FloatToFixed(cang), FloatToFixed(101 - choriz), floormirrorsector[i]); + renderDrawRoomsQ16(cposx, cposy, cposz, FloatToFixed(cang), choriz.asq16(), floormirrorsector[i]); analyzesprites(plr, dasmoothratio); renderDrawMasks(); renderSetRollAngle(0); @@ -78,7 +72,7 @@ void drawscreen(int num, double dasmoothratio, bool sceneonly) if (cposz > floorz - lz) cposz = floorz - lz; - renderDrawRoomsQ16(cposx, cposy, cposz, FloatToFixed(cang), FloatToFixed(choriz), plr.sector); + renderDrawRoomsQ16(cposx, cposy, cposz, FloatToFixed(cang), choriz.asq16(), plr.sector); analyzesprites(plr, dasmoothratio); renderDrawMasks(); if (!sceneonly) diff --git a/source/games/whaven/src/weapons.cpp b/source/games/whaven/src/weapons.cpp index 05b71d2c0..615b2cda8 100644 --- a/source/games/whaven/src/weapons.cpp +++ b/source/games/whaven/src/weapons.cpp @@ -901,7 +901,7 @@ void shootgun(PLAYER& plr, float ang, int guntype) { Hitscan pHitInfo; switch (guntype) { case 0: - daz2 = (int) (100 - plr.horiz) * 2000; + daz2 = -mulscale16(plr.horizon.horiz.asq16(), 2000); hitscan(plr.x, plr.y, plr.z, plr.sector, // Start position sintable[(daang + 2560) & 2047], // X vector of 3D ang @@ -1673,7 +1673,7 @@ void shootgun(PLAYER& plr, float ang, int guntype) { } break; case 1: //bow's arrow - daz2 = (int) (100 - plr.horiz) * 2000; + daz2 = -mulscale16(plr.horizon.horiz.asq16(), 2000); hitscan(plr.x, plr.y, plr.z, plr.sector, // Start position sintable[(daang + 2560) & 2047], // X vector of 3D ang @@ -1887,7 +1887,7 @@ void shootgun(PLAYER& plr, float ang, int guntype) { break; case 7: // KNOCKSPELL { - daz2 = (int)(100 - plr.horiz) * 2000; + daz2 = -mulscale16(plr.horizon.horiz.asq16(), 2000); Neartag ntag; hitscan(plr.x, plr.y, plr.z, plr.sector, // Start position @@ -1949,7 +1949,7 @@ void shootgun(PLAYER& plr, float ang, int guntype) { sprite[j].zvel = (short) shootgunzvel; shootgunzvel = 0; } else { - sprite[j].zvel = (short) ((100 - (int) plr.horiz) << 4); + sprite[j].zvel = plr.horizon.horiz.asq16() >> 12; } sprite[j].owner = sprite[plr.spritenum].owner; sprite[j].lotag = 1024; @@ -1974,7 +1974,7 @@ void shootgun(PLAYER& plr, float ang, int guntype) { sprite[j].shade = -15; sprite[j].xvel = (short) ((krand() & 256) - 128); sprite[j].yvel = (short) ((krand() & 256) - 128); - sprite[j].zvel = (short) ((100 - (int) plr.horiz) << 4); + sprite[j].zvel = plr.horizon.horiz.asq16() >> 12; sprite[j].owner = sprite[plr.spritenum].owner; sprite[j].lotag = 1024; sprite[j].hitag = 0; @@ -2001,7 +2001,7 @@ void shootgun(PLAYER& plr, float ang, int guntype) { sprite[j].xvel = (short) ((krand() & 256) - 128); sprite[j].yvel = (short) ((krand() & 256) - 128); // sprite[j].zvel=((krand()&256)-128); - sprite[j].zvel = (short) ((int) (100 - plr.horiz) << 4); + sprite[j].zvel = plr.horizon.horiz.asq16() >> 12; sprite[j].owner = sprite[plr.spritenum].owner; sprite[j].lotag = 1024; sprite[j].hitag = 0; @@ -2039,7 +2039,7 @@ void shootgun(PLAYER& plr, float ang, int guntype) { sprite[j].shade = -15; sprite[j].xvel = (short) ((krand() & 256) - 128); sprite[j].yvel = (short) ((krand() & 256) - 128); - sprite[j].zvel = (short) ((100 - (int) plr.horiz) << 4); + sprite[j].zvel = plr.horizon.horiz.asq16() >> 12; sprite[j].owner = sprite[plr.spritenum].owner; sprite[j].lotag = 1024; sprite[j].hitag = 0; @@ -2063,7 +2063,7 @@ void shootgun(PLAYER& plr, float ang, int guntype) { sprite[j].shade = -15; sprite[j].xvel = (short) ((krand() & 256) - 128); sprite[j].yvel = (short) ((krand() & 256) - 128); - sprite[j].zvel = (short) ((100 - (int) plr.horiz) << 4); + sprite[j].zvel = plr.horizon.horiz.asq16() >> 12; sprite[j].owner = sprite[plr.spritenum].owner; sprite[j].lotag = 1024; sprite[j].hitag = 0; @@ -2122,7 +2122,7 @@ void shootgun(PLAYER& plr, float ang, int guntype) { sprite[j].zvel = (short) shootgunzvel; shootgunzvel = 0; } else { - sprite[j].zvel = (short) ((int) (100 - plr.horiz) << 4); + sprite[j].zvel = plr.horizon.horiz.asq16() >> 12; } sprite[j].owner = sprite[plr.spritenum].owner; @@ -2159,7 +2159,7 @@ void shootgun(PLAYER& plr, float ang, int guntype) { sprite[j].zvel = (short) shootgunzvel; shootgunzvel = 0; } else { - sprite[j].zvel = (short) ((int) (100 - plr.horiz) << 4); + sprite[j].zvel = plr.horizon.horiz.asq16() >> 12; } sprite[j].owner = sprite[plr.spritenum].owner; diff --git a/source/games/whaven/src/wh.h b/source/games/whaven/src/wh.h index 6441ccbc4..3a55081fc 100644 --- a/source/games/whaven/src/wh.h +++ b/source/games/whaven/src/wh.h @@ -135,7 +135,6 @@ struct PLOCATION { int y; int z; float ang; - float horiz; }; extern int killcnt, kills; @@ -206,7 +205,6 @@ extern short monsterangle[MAXSPRITESONSCREEN], monsterlist[MAXSPRITESONSCREEN]; extern int shootgunzvel; extern boolean justteleported; extern int victor; -extern int autohoriz; // XXX NOT FOR MULTIPLAYER extern int pyrn; extern int mapon; @@ -539,6 +537,8 @@ struct GameInterface : public ::GameInterface void LevelCompleted(MapRecord* map, int skill) override; //bool DrawAutomapPlayer(int x, int y, int z, int a) override; int playerKeyMove() override { return isWh2()? 20:15; } + fixed_t playerHorizMin() override { return IntToFixed(-145); } + fixed_t playerHorizMax() override { return IntToFixed(145); } }; diff --git a/source/games/whaven/src/whldsv.cpp b/source/games/whaven/src/whldsv.cpp index cacd48a41..203c6bcd2 100644 --- a/source/games/whaven/src/whldsv.cpp +++ b/source/games/whaven/src/whldsv.cpp @@ -32,8 +32,7 @@ FSerializer& Serialize(FSerializer& arc, const char* key, PLAYER& sw, PLAYER* de ("y", sw.y) ("z", sw.z) ("ang", sw.ang) - ("horiz", sw.horiz) - ("jumphoriz", sw.jumphoriz) + ("horizon", sw.horizon) ("height", sw.height) ("hvel", sw.hvel) ("sector", sw.sector) diff --git a/source/games/whaven/src/whplr.cpp b/source/games/whaven/src/whplr.cpp index 1f8ff4e57..58ffa6a20 100644 --- a/source/games/whaven/src/whplr.cpp +++ b/source/games/whaven/src/whplr.cpp @@ -14,7 +14,6 @@ int shootgunzvel; boolean justteleported; int victor = 0; -int autohoriz = 0; // XXX NOT FOR MULTIPLAYER int pyrn; int mapon; @@ -28,7 +27,7 @@ void viewBackupPlayerLoc( int nPlayer ) pPLocation.y = pSprite.y; pPLocation.z = player[nPlayer].z; pPLocation.ang = player[nPlayer].ang; - pPLocation.horiz = player[nPlayer].horiz + player[nPlayer].jumphoriz; + player[nPlayer].horizon.backup(); } void playerdead(PLAYER& plr) { @@ -88,7 +87,7 @@ void initplayersprite(PLAYER& plr) { plr.poisontime = -1; plr.oldsector = plr.sector; - plr.horiz = 100; + plr.horizon.horiz = q16horiz(0); plr.height = getPlayerHeight(); plr.z = sector[plr.sector].floorz - (plr.height << 8); @@ -245,7 +244,7 @@ void plruse(PLAYER& plr) { operatesector(plr, nt.tagsector); } else { short daang = (short) plr.ang; - int daz2 = (int) (100 - plr.horiz) * 2000; + int daz2 = -mulscale16(plr.horizon.horiz.asq16(), 2000); Hitscan pHitInfo; hitscan(plr.x, plr.y, plr.z, plr.sector, // Start position sintable[(daang + 2560) & 2047], // X vector of 3D ang @@ -601,9 +600,10 @@ void lockon(PLAYER& plr, int numshots, int shootguntype) { void dophysics(PLAYER& plr, int goalz, int flyupdn, int v) { if (plr.orbactive[5] > 0) { if (v > 0) { - if (plr.horiz > 125) + auto horiz = plr.horizon.horiz.asbuild(); + if (horiz > 25) plr.hvel -= (TICSPERFRAME << 8); - else if (plr.horiz < 75) + else if (horiz < -25) plr.hvel += (TICSPERFRAME << 8); } if (flyupdn > 0) { @@ -664,7 +664,7 @@ void dophysics(PLAYER& plr, int goalz, int flyupdn, int v) { } } } - plr.jumphoriz = -(plr.hvel >> 8); + plr.horizon.horizoff = q16horiz(-plr.hvel << 8); }