diff --git a/source/blood/src/blood.h b/source/blood/src/blood.h index 80a49bd88..c1bbc48ce 100644 --- a/source/blood/src/blood.h +++ b/source/blood/src/blood.h @@ -97,8 +97,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(-80); } - fixed_t playerHorizMax() override { return IntToFixed(220); } + fixed_t playerHorizMin() override { return IntToFixed(-180); } + fixed_t playerHorizMax() override { return IntToFixed(120); } int playerKeyMove() override { return 1024; } GameStats getStats() override; diff --git a/source/blood/src/common_game.h b/source/blood/src/common_game.h index fb9b4dcb0..711bce245 100644 --- a/source/blood/src/common_game.h +++ b/source/blood/src/common_game.h @@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "misc.h" #include "printf.h" #include "v_text.h" +#include "binaryangle.h" BEGIN_BLD_NS @@ -562,6 +563,16 @@ inline fixed_t interpolateangfix16(fixed_t a, fixed_t b, int c) return a+mulscale16(((b-a+0x4000000)&0x7ffffff)-0x4000000, c); } +inline binangle interpolateangbin(uint32_t a, uint32_t b, double c) +{ + return bamang(xs_CRoundToUInt(a + fmulscale16(b - a, c))); +} + +inline lookangle interpolateanglook(int32_t a, int32_t b, double c) +{ + return bamlook(xs_CRoundToUInt(a + fmulscale16(b - a, c))); +} + inline char Chance(int a1) { return wrand() < (a1>>1); diff --git a/source/blood/src/controls.cpp b/source/blood/src/controls.cpp index 7045e49c2..0030fb304 100644 --- a/source/blood/src/controls.cpp +++ b/source/blood/src/controls.cpp @@ -55,11 +55,12 @@ void GameInterface::GetInput(InputPacket* packet, ControlInfo* const hidInput) // Perform unsynchronised angle/horizon if not dead. if (gView->pXSprite->health != 0) { - applylook(&pPlayer->q16ang, &pPlayer->q16look_ang, &pPlayer->q16rotscrnang, &pPlayer->spin, input.q16avel, &pPlayer->input.actions, scaleAdjust, pPlayer->posture != 0); - sethorizon(&pPlayer->q16horiz, input.q16horz, &pPlayer->input.actions, scaleAdjust); + applylook(&pPlayer->angle, input.avel, &pPlayer->input.actions, scaleAdjust, pPlayer->posture != 0); + sethorizon(&pPlayer->horizon.horiz, input.horz, &pPlayer->input.actions, scaleAdjust); } - playerProcessHelpers(&pPlayer->q16ang, &pPlayer->angAdjust, &pPlayer->angTarget, &pPlayer->q16horiz, &pPlayer->horizAdjust, &pPlayer->horizTarget, scaleAdjust); + pPlayer->angle.processhelpers(scaleAdjust); + pPlayer->horizon.processhelpers(scaleAdjust); UpdatePlayerSpriteAngle(pPlayer); } diff --git a/source/blood/src/hudsprites.cpp b/source/blood/src/hudsprites.cpp index 30860b12d..5a5b6bec2 100644 --- a/source/blood/src/hudsprites.cpp +++ b/source/blood/src/hudsprites.cpp @@ -98,7 +98,7 @@ static void viewBurnTime(int gScale) void hudDraw(PLAYER *gView, VIEW *pView, int nSectnum, double bobx, double boby, double zDelta, int basepal, double smoothratio) { - double look_anghalf = getHalfLookAng(pView->q16look_ang, gView->q16look_ang, cl_syncinput, smoothratio); + double look_anghalf = getHalfLookAng(pView->look_ang.asq16(), gView->angle.look_ang.asq16(), cl_syncinput, smoothratio); DrawCrosshair(kCrosshairTile, gView->pXSprite->health >> 4, -look_anghalf, 0, 2); diff --git a/source/blood/src/nnexts.cpp b/source/blood/src/nnexts.cpp index ff8be0fe4..b015339ba 100644 --- a/source/blood/src/nnexts.cpp +++ b/source/blood/src/nnexts.cpp @@ -1488,15 +1488,15 @@ void trPlayerCtrlSetLookAngle(XSPRITE* pXSource, PLAYER* pPlayer) if (abs(look) > 0) { - if (pPlayer->q16horiz != IntToFixed(100)) + if (pPlayer->horizon.horiz.asq16() != 0) { - // move q16horiz back to 100 - pPlayer->q16horiz += IntToFixed(25) - (pPlayer->q16horiz >> 2); + // move horiz back to 0 + pPlayer->horizon.horiz += q16horiz(xs_CRoundToInt(-pPlayer->horizon.horiz.asq16() * (1. / 3.))); } } else { - pPlayer->q16horiz = IntToFixed(100); + pPlayer->horizon.horiz = q16horiz(0); } } @@ -2113,7 +2113,7 @@ void useTeleportTarget(XSPRITE* pXSource, spritetype* pSprite) { if (pXSource->data2 == 1) { - if (pPlayer) pPlayer->q16ang = IntToFixed(pSource->ang); + if (pPlayer) pPlayer->angle.ang = buildang(pSource->ang); else if (isDude) xsprite[pSprite->extra].goalAng = pSprite->ang = pSource->ang; else pSprite->ang = pSource->ang; } @@ -3965,8 +3965,8 @@ bool modernTypeOperateSprite(int nSprite, spritetype* pSprite, XSPRITE* pXSprite case 9: // 73 (set player's sprite angle, TO-DO: if tx > 0, take a look on TX ID sprite) //data4 is reserved if (pXSprite->data4 != 0) break; - else if (pSprite->flags & kModernTypeFlag1) pPlayer->q16ang = IntToFixed(pSprite->ang); - else if (valueIsBetween(pXSprite->data2, -kAng360, kAng360)) pPlayer->q16ang = IntToFixed(pXSprite->data2); + else if (pSprite->flags & kModernTypeFlag1) pPlayer->angle.ang = buildang(pSprite->ang); + else if (valueIsBetween(pXSprite->data2, -kAng360, kAng360)) pPlayer->angle.ang = buildang(pXSprite->data2); break; } } diff --git a/source/blood/src/osdcmd.cpp b/source/blood/src/osdcmd.cpp index a12b4fe07..dcd7e5cad 100644 --- a/source/blood/src/osdcmd.cpp +++ b/source/blood/src/osdcmd.cpp @@ -44,23 +44,22 @@ static int osdcmd_warptocoords(CCmdFuncPtr parm) return CCMD_SHOWHELP; PLAYER *pPlayer = &gPlayer[myconnectindex]; + VIEW* pView = &gPrevView[myconnectindex]; - pPlayer->pSprite->x = gView->pSprite->x = atoi(parm->parms[0]); - pPlayer->pSprite->y = gView->pSprite->y = atoi(parm->parms[1]); - pPlayer->zView = gView->zView = atoi(parm->parms[2]); + pPlayer->pSprite->x = pView->at50 = gView->pSprite->x = atoi(parm->parms[0]); + pPlayer->pSprite->y = pView->at54 = gView->pSprite->y = atoi(parm->parms[1]); + pPlayer->zView = pView->at38 = gView->zView = atoi(parm->parms[2]); if (parm->numparms >= 4) { - pPlayer->q16ang = gView->q16ang = IntToFixed(atoi(parm->parms[3])); + pPlayer->angle.oang = pPlayer->angle.ang = pView->at30 = gView->angle.ang = buildang(atoi(parm->parms[3])); } if (parm->numparms == 5) { - pPlayer->q16horiz = gView->q16horiz = IntToFixed(atoi(parm->parms[4])); + pPlayer->horizon.ohoriz = pPlayer->horizon.horiz = pView->at24 = gView->horizon.horiz = buildhoriz(atoi(parm->parms[4])); } - viewBackupView(pPlayer->nPlayer); - return CCMD_OK; } diff --git a/source/blood/src/player.cpp b/source/blood/src/player.cpp index cbb6c9115..42f8986a0 100644 --- a/source/blood/src/player.cpp +++ b/source/blood/src/player.cpp @@ -712,7 +712,7 @@ void playerStart(int nPlayer, int bNewLevel) pSprite->z -= bottom - pSprite->z; pSprite->pal = 11+(pPlayer->teamId&3); pPlayer->angold = pSprite->ang = pStartZone->ang; - pPlayer->q16ang = IntToFixed(pSprite->ang); + pPlayer->angle.ang = buildang(pSprite->ang); pSprite->type = kDudePlayer1+nPlayer; pSprite->clipdist = pDudeInfo->clipdist; pSprite->flags = 15; @@ -721,8 +721,7 @@ void playerStart(int nPlayer, int bNewLevel) pPlayer->pXSprite->health = pDudeInfo->startHealth<<4; pPlayer->pSprite->cstat &= (unsigned short)~32768; pPlayer->bloodlust = 0; - pPlayer->q16horiz = IntToFixed(100); - pPlayer->q16slopehoriz = 0; + pPlayer->horizon.horiz = pPlayer->horizon.horizoff = q16horiz(0); pPlayer->slope = 0; pPlayer->fraggerId = -1; pPlayer->underwaterTime = 1200; @@ -734,7 +733,7 @@ void playerStart(int nPlayer, int bNewLevel) pPlayer->restTime = 0; pPlayer->kickPower = 0; pPlayer->laughCount = 0; - pPlayer->spin = 0; + pPlayer->angle.spin = buildlook(0); pPlayer->posture = 0; pPlayer->voodooTarget = -1; pPlayer->voodooTargets = 0; @@ -763,11 +762,11 @@ void playerStart(int nPlayer, int bNewLevel) pPlayer->deathTime = 0; pPlayer->nextWeapon = 0; xvel[pSprite->index] = yvel[pSprite->index] = zvel[pSprite->index] = 0; - pInput->q16avel = 0; + pInput->avel = 0; pInput->actions = 0; pInput->fvel = 0; pInput->svel = 0; - pInput->q16horz = 0; + pInput->horz = 0; pPlayer->flickerEffect = 0; pPlayer->quakeEffect = 0; pPlayer->tiltEffect = 0; @@ -1313,8 +1312,8 @@ void UpdatePlayerSpriteAngle(PLAYER *pPlayer) { spritetype *pSprite = pPlayer->pSprite; - pPlayer->q16ang = (pPlayer->q16ang + IntToFixed(pSprite->ang - pPlayer->angold)) & 0x7FFFFFF; - pPlayer->angold = pSprite->ang = FixedToInt(pPlayer->q16ang); + pPlayer->angle.ang += buildang(pSprite->ang - pPlayer->angold); + pPlayer->angold = pSprite->ang = pPlayer->angle.ang.asbuild(); } //--------------------------------------------------------------------------- @@ -1325,8 +1324,8 @@ void UpdatePlayerSpriteAngle(PLAYER *pPlayer) static void resetinputhelpers(PLAYER* pPlayer) { - pPlayer->horizAdjust = 0; - pPlayer->angAdjust = 0; + pPlayer->horizon.resetadjustment(); + pPlayer->angle.resetadjustment(); } void ProcessInput(PLAYER *pPlayer) @@ -1348,7 +1347,7 @@ void ProcessInput(PLAYER *pPlayer) InputPacket *pInput = &pPlayer->input; pPlayer->isRunning = !!(pInput->actions & SB_RUN); - if ((pInput->actions & SB_BUTTON_MASK) || pInput->fvel || pInput->svel || pInput->q16avel) + if ((pInput->actions & SB_BUTTON_MASK) || pInput->fvel || pInput->svel || pInput->avel) pPlayer->restTime = 0; else if (pPlayer->restTime >= 0) pPlayer->restTime += 4; @@ -1360,11 +1359,11 @@ void ProcessInput(PLAYER *pPlayer) { fixed_t fraggerAng = gethiq16angle(sprite[pPlayer->fraggerId].x - pSprite->x, sprite[pPlayer->fraggerId].y - pSprite->y); pPlayer->angold = pSprite->ang = FixedToInt(fraggerAng); - playerAddAngle(&pPlayer->q16ang, &pPlayer->angAdjust, FixedToFloat(getincangleq16(pPlayer->q16ang, fraggerAng))); + pPlayer->angle.addadjustment(FixedToFloat(getincangleq16(pPlayer->angle.ang.asq16(), fraggerAng))); } pPlayer->deathTime += 4; if (!bSeqStat) - playerAddHoriz(&pPlayer->q16horiz, &pPlayer->horizAdjust, FixedToFloat(mulscale16(0x8000-(Cos(ClipHigh(pPlayer->deathTime<<3, 1024))>>15), gi->playerHorizMax()) - pPlayer->q16horiz)); + pPlayer->horizon.addadjustment(FixedToFloat(mulscale16(0x8000-(Cos(ClipHigh(pPlayer->deathTime<<3, 1024))>>15), gi->playerHorizMax()) - pPlayer->horizon.horiz.asq16())); if (pPlayer->curWeapon) pInput->setNewWeapon(pPlayer->curWeapon); if (pInput->actions & SB_OPEN) @@ -1446,7 +1445,7 @@ void ProcessInput(PLAYER *pPlayer) if (cl_syncinput) { - applylook(&pPlayer->q16ang, &pPlayer->q16look_ang, &pPlayer->q16rotscrnang, &pPlayer->spin, pInput->q16avel, &pInput->actions, 1, pPlayer->posture != 0); + applylook(&pPlayer->angle, pInput->avel, &pInput->actions, 1, pPlayer->posture != 0); UpdatePlayerSpriteAngle(pPlayer); } @@ -1558,7 +1557,7 @@ void ProcessInput(PLAYER *pPlayer) if (cl_syncinput) { - sethorizon(&pPlayer->q16horiz, pInput->q16horz, &pInput->actions, 1); + sethorizon(&pPlayer->horizon.horiz, pInput->horz, &pInput->actions, 1); } int nSector = pSprite->sectnum; @@ -1578,16 +1577,16 @@ void ProcessInput(PLAYER *pPlayer) if (nSector2 == nSector) { int z2 = getflorzofslope(nSector2, x2, y2); - pPlayer->q16slopehoriz = interpolate(pPlayer->q16slopehoriz, IntToFixed(z1-z2)>>3, 0x4000); + pPlayer->horizon.horizoff = q16horiz(interpolate(pPlayer->horizon.horizoff.asq16(), IntToFixed(z1-z2)>>3, 0x4000)); } } else { - pPlayer->q16slopehoriz = interpolate(pPlayer->q16slopehoriz, 0, 0x4000); - if (klabs(pPlayer->q16slopehoriz) < 4) - pPlayer->q16slopehoriz = 0; + pPlayer->horizon.horizoff = q16horiz(interpolate(pPlayer->horizon.horizoff.asq16(), 0, 0x4000)); + if (klabs(pPlayer->horizon.horizoff.asq16()) < 4) + pPlayer->horizon.horizoff = q16horiz(0); } - pPlayer->slope = -(pPlayer->q16horiz - IntToFixed(100)) >> 9; + pPlayer->slope = -pPlayer->horizon.horiz.asq16() >> 9; if (pInput->actions & SB_INVPREV) { pInput->actions&= ~SB_INVPREV; diff --git a/source/blood/src/player.h b/source/blood/src/player.h index d9d558788..96b49b711 100644 --- a/source/blood/src/player.h +++ b/source/blood/src/player.h @@ -84,7 +84,9 @@ struct PLAYER spritetype* pSprite; XSPRITE* pXSprite; DUDEINFO* pDudeInfo; - InputPacket input; + InputPacket input; + PlayerHorizon horizon; + PlayerAngle angle; uint8_t newWeapon; int used1; // something related to game checksum int weaponQav; @@ -108,8 +110,6 @@ struct PLAYER int zViewVel; int zWeapon; int zWeaponVel; - fixed_t q16horiz; // horiz - fixed_t q16slopehoriz; // horizoff int slope; bool isUnderwater; bool hasKey[8]; @@ -154,7 +154,6 @@ struct PLAYER int restTime; int kickPower; int laughCount; - fixed_t spin; // turning around bool godMode; bool fallScream; bool cantJump; @@ -179,17 +178,10 @@ struct PLAYER int pickupEffect; bool flashEffect; // if true, reduce pPlayer->visibility counter int quakeEffect; - fixed_t q16ang; int angold; int player_par; int nWaterPal; POSTURE pPosture[kModeMax][kPostureMax]; - fixed_t q16look_ang; - fixed_t q16rotscrnang; - - // Input helper variables. - double horizAdjust, angAdjust; - fixed_t horizTarget, angTarget; }; struct PROFILE diff --git a/source/blood/src/prediction.cpp b/source/blood/src/prediction.cpp index 847ed7639..825bbc492 100644 --- a/source/blood/src/prediction.cpp +++ b/source/blood/src/prediction.cpp @@ -57,9 +57,9 @@ static VIEW predictFifo[256]; void viewInitializePrediction(void) { - predict.at30 = gMe->q16ang; - predict.at24 = gMe->q16horiz; - predict.at28 = gMe->q16slopehoriz; + predict.at30 = gMe->angle.ang; + predict.at24 = gMe->horizon.horiz; + predict.at28 = gMe->horizon.horizoff; predict.at2c = gMe->slope; predict.at6f = gMe->cantJump; predict.at70 = gMe->isRunning; @@ -75,7 +75,7 @@ void viewInitializePrediction(void) predict.at64 = zvel[gMe->pSprite->index]; predict.at6a = gMe->pXSprite->height; predict.at48 = gMe->posture; - predict.at4c = gMe->spin; + predict.at4c = gMe->angle.spin; predict.at6e = !!(gMe->input.actions & SB_CENTERVIEW); memcpy(&predict.at75,&gSpriteHit[gMe->pSprite->extra],sizeof(SPRITEHIT)); predict.TotalKills = gMe->bobPhase; @@ -120,8 +120,8 @@ static void fakeProcessInput(PLAYER *pPlayer, InputPacket *pInput) predict.at71 = !!(gMe->input.actions & SB_JUMP); if (predict.at48 == 1) { - int x = Cos(FixedToInt(predict.at30)); - int y = Sin(FixedToInt(predict.at30)); + int x = Cos(predict.at30.asbuild()); + int y = Sin(predict.at30.asbuild()); if (pInput->fvel) { int forward = pInput->fvel; @@ -145,8 +145,8 @@ static void fakeProcessInput(PLAYER *pPlayer, InputPacket *pInput) int speed = 0x10000; if (predict.at6a > 0) speed -= divscale16(predict.at6a, 0x100); - int x = Cos(FixedToInt(predict.at30)); - int y = Sin(FixedToInt(predict.at30)); + int x = Cos(predict.at30.asbuild()); + int y = Sin(predict.at30.asbuild()); if (pInput->fvel) { int forward = pInput->fvel; @@ -169,12 +169,12 @@ static void fakeProcessInput(PLAYER *pPlayer, InputPacket *pInput) predict.at60 -= mulscale30(strafe, x); } } - if (pInput->q16avel) - predict.at30 = (predict.at30+pInput->q16avel)&0x7ffffff; + if (pInput->avel) + predict.at30 = degang(pInput->avel); if (pInput->actions & SB_TURNAROUND) - if (!predict.at4c) - predict.at4c = -1024; - if (predict.at4c < 0) + if (!predict.at4c.asbuild()) + predict.at4c = buildlook(-1024); + if (predict.at4c.asbuild() < 0) { int speed; if (predict.at48 == 1) @@ -182,8 +182,8 @@ static void fakeProcessInput(PLAYER *pPlayer, InputPacket *pInput) else speed = 128; - predict.at4c = min(predict.at4c+speed, 0); - predict.at30 += IntToFixed(speed); + predict.at4c = buildlook(min(predict.at4c.asbuild()+speed, 0)); + predict.at30 += buildang(speed); } if (!predict.at71) @@ -212,6 +212,7 @@ static void fakeProcessInput(PLAYER *pPlayer, InputPacket *pInput) break; } +#if 0 if (predict.at6e && !(pInput->actions & (SB_LOOK_UP | SB_LOOK_DOWN))) { if (predict.at20 < 0) @@ -228,7 +229,7 @@ static void fakeProcessInput(PLAYER *pPlayer, InputPacket *pInput) if (pInput->actions & SB_LOOK_DOWN) predict.at20 = max(predict.at20-IntToFixed(4), IntToFixed(-60)); } - predict.at20 = clamp(predict.at20+pInput->q16horz, IntToFixed(-60), IntToFixed(60)); + predict.at20 = clamp(predict.at20+pInput->horz, IntToFixed(-60), IntToFixed(60)); if (predict.at20 > 0) predict.at24 = FloatToFixed(fmulscale30(120., Sinf(FixedToFloat(predict.at20) * 8.))); @@ -236,6 +237,7 @@ static void fakeProcessInput(PLAYER *pPlayer, InputPacket *pInput) predict.at24 = FloatToFixed(fmulscale30(180., Sinf(FixedToFloat(predict.at20) * 8.))); else predict.at24 = 0; +#endif int nSector = predict.at68; int florhit = predict.at75.florhit & 0xc000; @@ -247,23 +249,23 @@ static void fakeProcessInput(PLAYER *pPlayer, InputPacket *pInput) if (va && (sector[nSector].floorstat&2) != 0) { int z1 = getflorzofslope(nSector, predict.at50, predict.at54); - int x2 = predict.at50+mulscale30(64, Cos(FixedToInt(predict.at30))); - int y2 = predict.at54+mulscale30(64, Sin(FixedToInt(predict.at30))); + int x2 = predict.at50+mulscale30(64, Cos(predict.at30.asbuild())); + int y2 = predict.at54+mulscale30(64, Sin(predict.at30.asbuild())); short nSector2 = nSector; updatesector(x2, y2, &nSector2); if (nSector2 == nSector) { int z2 = getflorzofslope(nSector2, x2, y2); - predict.at28 = interpolate(predict.at28, IntToFixed(z1-z2)>>3, 0x4000); + predict.at28 = q16horiz(interpolate(predict.at28.asq16(), IntToFixed(z1 - z2) >> 3, 0x4000)); } } else { - predict.at28 = interpolate(predict.at28, 0, 0x4000); - if (klabs(predict.at28) < 4) - predict.at28 = 0; + predict.at28 = q16horiz(interpolate(predict.at28.asq16(), 0, 0x4000)); + if (klabs(predict.at28.asq16()) < 4) + predict.at28 = q16horiz(0); } - predict.at2c = -(predict.at24 - IntToFixed(100)) >> 9; + predict.at2c = -predict.at24.asq16() >> 9; } void fakePlayerProcess(PLAYER *pPlayer, InputPacket *pInput) @@ -654,7 +656,7 @@ void viewCorrectPrediction(void) #if 0 spritetype *pSprite = gMe->pSprite; VIEW *pView = &predictFifo[(gNetFifoTail-1)&255]; - if (gMe->q16ang != pView->at30 || pView->at24 != gMe->q16horiz || pView->at50 != pSprite->x || pView->at54 != pSprite->y || pView->at58 != pSprite->z) + if (gMe->angle.ang != pView->at30 || pView->at24 != gMe->horizon.horiz || pView->at50 != pSprite->x || pView->at54 != pSprite->y || pView->at58 != pSprite->z) { viewInitializePrediction(); predictOld = gPrevView[myconnectindex]; diff --git a/source/blood/src/view.cpp b/source/blood/src/view.cpp index 84d5eb90a..77cd339be 100644 --- a/source/blood/src/view.cpp +++ b/source/blood/src/view.cpp @@ -105,20 +105,22 @@ void viewBackupView(int nPlayer) { PLAYER *pPlayer = &gPlayer[nPlayer]; VIEW *pView = &gPrevView[nPlayer]; - pView->at30 = pPlayer->q16ang; + pView->at30 = pPlayer->angle.ang; pView->at50 = pPlayer->pSprite->x; pView->at54 = pPlayer->pSprite->y; pView->at38 = pPlayer->zView; pView->at34 = pPlayer->zWeapon-pPlayer->zView-0xc00; - pView->at24 = pPlayer->q16horiz; - pView->at28 = pPlayer->q16slopehoriz; + pView->at24 = pPlayer->horizon.horiz; + pView->at28 = pPlayer->horizon.horizoff; pView->at2c = pPlayer->slope; pView->at8 = pPlayer->bobHeight; pView->atc = pPlayer->bobWidth; pView->at18 = pPlayer->swayHeight; pView->at1c = pPlayer->swayWidth; - pView->q16look_ang = pPlayer->q16look_ang; - pView->q16rotscrnang = pPlayer->q16rotscrnang; + pView->look_ang = pPlayer->angle.look_ang; + pView->rotscrnang = pPlayer->angle.rotscrnang; + pPlayer->angle.backup(); + pPlayer->horizon.backup(); } void viewCorrectViewOffsets(int nPlayer, vec3_t const *oldpos) @@ -292,7 +294,7 @@ void CalcOtherPosition(spritetype *pSprite, int *pX, int *pY, int *pZ, int *vsec { int vX = mulscale30(-Cos(nAng), 1280); int vY = mulscale30(-Sin(nAng), 1280); - int vZ = FixedToInt(mulscale(zm - IntToFixed(100), 1280, 3))-(16<<8); + int vZ = FixedToInt(mulscale(zm, 1280, 3))-(16<<8); int bakCstat = pSprite->cstat; pSprite->cstat &= ~256; assert(*vsectnum >= 0 && *vsectnum < kMaxSectors); @@ -338,7 +340,7 @@ void CalcPosition(spritetype *pSprite, int *pX, int *pY, int *pZ, int *vsectnum, { int vX = mulscale30(-Cos(nAng), 1280); int vY = mulscale30(-Sin(nAng), 1280); - int vZ = FixedToInt(mulscale(zm - IntToFixed(100), 1280, 3))-(16<<8); + int vZ = FixedToInt(mulscale(zm, 1280, 3))-(16<<8); int bakCstat = pSprite->cstat; pSprite->cstat &= ~256; assert(*vsectnum >= 0 && *vsectnum < kMaxSectors); @@ -634,7 +636,9 @@ void viewDrawScreen(bool sceneonly) renderSetAspect(v1, yxaspect); int cX, cY, cZ, v74, v8c; - fixed_t cA, q16horiz, q16slopehoriz, q16rotscrnang; + lookangle rotscrnang; + binangle cA; + fixedhoriz cH, cOff; double zDelta, v4c, v48; int nSectnum = gView->pSprite->sectnum; if (numplayers > 1 && gView == gMe && gPrediction && gMe->pXSprite->health > 0) @@ -644,7 +648,7 @@ void viewDrawScreen(bool sceneonly) cY = interpolate(predictOld.at54, predict.at54, gInterpolate); cZ = interpolate(predictOld.at38, predict.at38, gInterpolate); zDelta = finterpolate(predictOld.at34, predict.at34, gInterpolate); - q16slopehoriz = interpolate(predictOld.at28, predict.at28, gInterpolate); + cOff = q16horiz(interpolate(predictOld.at28.asq16(), predict.at28.asq16(), gInterpolate)); v74 = interpolate(predictOld.atc, predict.atc, gInterpolate); v8c = interpolate(predictOld.at8, predict.at8, gInterpolate); v4c = finterpolate(predictOld.at1c, predict.at1c, gInterpolate); @@ -652,15 +656,17 @@ void viewDrawScreen(bool sceneonly) if (!cl_syncinput) { - cA = predict.at30 + predict.q16look_ang; - q16horiz = predict.at24; - q16rotscrnang = predict.q16rotscrnang; + cA = bamang(predict.at30.asbam() + predict.look_ang.asbam()); + cH = predict.at24; + rotscrnang = predict.rotscrnang; } else { - cA = interpolateangfix16(predictOld.at30 + predictOld.q16look_ang, predict.at30 + predict.q16look_ang, gInterpolate); - q16horiz = interpolate(predictOld.at24, predict.at24, gInterpolate); - q16rotscrnang = interpolateangfix16(predictOld.q16rotscrnang, predict.q16rotscrnang, gInterpolate); + uint32_t oang = predictOld.at30.asbam() + predictOld.look_ang.asbam(); + uint32_t ang = predict.at30.asbam() + predict.look_ang.asbam(); + cA = interpolateangbin(oang, ang, gInterpolate); + cH = q16horiz(interpolate(predictOld.at24.asq16(), predict.at24.asq16(), gInterpolate)); + rotscrnang = interpolateanglook(predictOld.rotscrnang.asbam(), predict.rotscrnang.asbam(), gInterpolate); } } else @@ -670,7 +676,7 @@ void viewDrawScreen(bool sceneonly) cY = interpolate(pView->at54, gView->pSprite->y, gInterpolate); cZ = interpolate(pView->at38, gView->zView, gInterpolate); zDelta = finterpolate(pView->at34, gView->zWeapon - gView->zView - (12 << 8), gInterpolate); - q16slopehoriz = interpolate(pView->at28, gView->q16slopehoriz, gInterpolate); + cOff = q16horiz(interpolate(pView->at28.asq16(), gView->horizon.horizoff.asq16(), gInterpolate)); v74 = interpolate(pView->atc, gView->bobWidth, gInterpolate); v8c = interpolate(pView->at8, gView->bobHeight, gInterpolate); v4c = finterpolate(pView->at1c, gView->swayWidth, gInterpolate); @@ -678,35 +684,35 @@ void viewDrawScreen(bool sceneonly) if (!cl_syncinput) { - cA = gView->q16ang + gView->q16look_ang; - q16horiz = gView->q16horiz; - q16rotscrnang = gView->q16rotscrnang; + cA = gView->angle.sum(); + cH = gView->horizon.horiz; + rotscrnang = gView->angle.rotscrnang; } else { - cA = interpolateangfix16(pView->at30 + pView->q16look_ang, gView->q16ang + gView->q16look_ang, gInterpolate); - q16horiz = interpolate(pView->at24, gView->q16horiz, gInterpolate); - q16rotscrnang = interpolateangfix16(pView->q16rotscrnang, gView->q16rotscrnang, gInterpolate); + cA = gView->angle.interpolatedsum(gInterpolate); + cH = q16horiz(interpolate(pView->at24.asq16(), gView->horizon.horiz.asq16(), gInterpolate)); + rotscrnang = gView->angle.interpolatedrotscrn(gInterpolate); } } viewUpdateShake(); - q16horiz += IntToFixed(shakeHoriz); - cA += IntToFixed(shakeAngle); + cH += buildhoriz(shakeHoriz); + cA += buildang(shakeAngle); cX += shakeX; cY += shakeY; cZ += shakeZ; v4c += shakeBobX; v48 += shakeBobY; - q16horiz += IntToFixed(mulscale30(0x40000000 - Cos(gView->tiltEffect << 2), 30)); + cH += buildhoriz(mulscale30(0x40000000 - Cos(gView->tiltEffect << 2), 30)); if (gViewPos == 0) { if (cl_viewbob) { if (cl_viewhbob) { - cX -= mulscale30(v74, Sin(FixedToInt(cA))) >> 4; - cY += mulscale30(v74, Cos(FixedToInt(cA))) >> 4; + cX -= mulscale30(v74, Sin(cA.asbuild())) >> 4; + cY += mulscale30(v74, Cos(cA.asbuild())) >> 4; } if (cl_viewvbob) { @@ -715,15 +721,15 @@ void viewDrawScreen(bool sceneonly) } if (cl_slopetilting) { - q16horiz += q16slopehoriz; + cH += cOff; } - cZ += xs_CRoundToInt((q16horiz - IntToFixed(100)) / 6553.6); + cZ += xs_CRoundToInt(cH.asq16() / 6553.6); cameradist = -1; cameraclock = gFrameClock +mulscale16(4, (int)gInterpolate); } else { - CalcPosition(gView->pSprite, (int*)&cX, (int*)&cY, (int*)&cZ, &nSectnum, FixedToInt(cA), q16horiz, (int)gInterpolate); + CalcPosition(gView->pSprite, (int*)&cX, (int*)&cY, (int*)&cZ, &nSectnum, cA.asbuild(), cH.asq16(), (int)gInterpolate); } CheckLink((int*)&cX, (int*)&cY, (int*)&cZ, &nSectnum); int v78 = interpolateang(gScreenTiltO, gScreenTilt, gInterpolate); @@ -734,7 +740,7 @@ void viewDrawScreen(bool sceneonly) //int tiltcs, tiltdim; uint8_t v4 = powerupCheck(gView, kPwUpCrystalBall) > 0; #ifdef USE_OPENGL - renderSetRollAngle(FixedToFloat(q16rotscrnang)); + renderSetRollAngle(rotscrnang.asbam() / (double)(BAMUNIT)); #endif if (v78 || bDelirium) { @@ -869,7 +875,7 @@ void viewDrawScreen(bool sceneonly) nSprite = nextspritestat[nSprite]; } g_visibility = (int32_t)(ClipLow(gVisibility - 32 * gView->visibility - unk, 0)); - cA = (cA + interpolateangfix16(IntToFixed(deliriumTurnO), IntToFixed(deliriumTurn), gInterpolate)) & 0x7ffffff; + cA += q16ang(interpolateangfix16(IntToFixed(deliriumTurnO), IntToFixed(deliriumTurn), gInterpolate)); int vfc, vf8; getzsofslope(nSectnum, cX, cY, &vfc, &vf8); if (cZ >= vf8) @@ -880,13 +886,13 @@ void viewDrawScreen(bool sceneonly) { cZ = vfc + (gLowerLink[nSectnum] >= 0 ? 0 : (8 << 8)); } - q16horiz = ClipRange(q16horiz, gi->playerHorizMin(), gi->playerHorizMax()); + cH = q16horiz(ClipRange(cH.asq16(), gi->playerHorizMin(), gi->playerHorizMax())); RORHACK: int ror_status[16]; for (int i = 0; i < 16; i++) ror_status[i] = TestBitString(gotpic, 4080 + i); fixed_t deliriumPitchI = interpolate(IntToFixed(deliriumPitchO), IntToFixed(deliriumPitch), gInterpolate); - DrawMirrors(cX, cY, cZ, cA, q16horiz + deliriumPitchI, gInterpolate, gViewIndex); + DrawMirrors(cX, cY, cZ, cA.asq16(), cH.asq16() + deliriumPitchI, gInterpolate, gViewIndex); int bakCstat = gView->pSprite->cstat; if (gViewPos == 0) { @@ -897,8 +903,8 @@ void viewDrawScreen(bool sceneonly) gView->pSprite->cstat |= 514; } - renderDrawRoomsQ16(cX, cY, cZ, cA, q16horiz + deliriumPitchI, nSectnum); - viewProcessSprites(cX, cY, cZ, FixedToInt(cA), gInterpolate); + renderDrawRoomsQ16(cX, cY, cZ, cA.asq16(), cH.asq16() + deliriumPitchI, nSectnum); + viewProcessSprites(cX, cY, cZ, cA.asbuild(), gInterpolate); bool do_ror_hack = false; for (int i = 0; i < 16; i++) if (ror_status[i] != TestBitString(gotpic, 4080 + i)) @@ -955,7 +961,7 @@ void viewDrawScreen(bool sceneonly) int v8 = byte_1CE5C2 > 0 && (sector[tmpSect].ceilingstat & 1); if (gWeather.at12d8 > 0 || v8) { - gWeather.Draw(cX, cY, cZ, cA, q16horiz + deliriumPitch, gWeather.at12d8); + gWeather.Draw(cX, cY, cZ, cA.asq16(), cH.asq16() + deliriumPitch, gWeather.at12d8); if (v8) { gWeather.at12d8 = ClipRange(delta * 8 + gWeather.at12d8, 0, 4095); diff --git a/source/blood/src/view.h b/source/blood/src/view.h index 6c2127a33..f40cd50fc 100644 --- a/source/blood/src/view.h +++ b/source/blood/src/view.h @@ -39,18 +39,17 @@ struct VIEW { int at14; int at18; // bob sway y int at1c; // bob sway x - fixed_t at20; - fixed_t at24; // horiz - int at28; // horizoff + fixedhoriz at24; // horiz + fixedhoriz at28; // horizoff int at2c; - fixed_t at30; // angle + binangle at30; // angle int at34; // weapon z int at38; // view z int at3c; int at40; int at44; int at48; // posture - int at4c; // spin + lookangle at4c; // spin int at50; // x int at54; // y int at58; // z @@ -66,8 +65,8 @@ struct VIEW { char at72; // underwater short at73; // sprite flags SPRITEHIT at75; - fixed_t q16look_ang; - fixed_t q16rotscrnang; + lookangle look_ang; + lookangle rotscrnang; }; extern VIEW gPrevView[kMaxPlayers]; diff --git a/source/build/include/compat.h b/source/build/include/compat.h index 9e9dfded8..70de736da 100644 --- a/source/build/include/compat.h +++ b/source/build/include/compat.h @@ -189,7 +189,6 @@ static FORCE_INLINE uint16_t B_UNBUF16(void const * const buf) { return *(uint16 ////////// Abstract data operations ////////// -template constexpr T clamp(T in, X min, Y max) { return in <= (T) min ? (T) min : (in >= (T) max ? (T) max : in); } using std::min; using std::max; diff --git a/source/build/src/engine.cpp b/source/build/src/engine.cpp index d35a5a155..7b10b1589 100644 --- a/source/build/src/engine.cpp +++ b/source/build/src/engine.cpp @@ -170,7 +170,7 @@ int32_t ydimen; int32_t rxi[8], ryi[8]; -int32_t globalposx, globalposy, globalposz, globalhoriz; +int32_t globalposx, globalposy, globalposz; fixed_t qglobalhoriz; float fglobalposx, fglobalposy, fglobalposz; int16_t globalang, globalcursectnum; @@ -1092,8 +1092,7 @@ int32_t renderDrawRoomsQ16(int32_t daposx, int32_t daposy, int32_t daposz, // xdimenscale is scale(xdimen,yxaspect,320); // normalization by viewingrange so that center-of-aim doesn't depend on it - qglobalhoriz = mulscale16(dahoriz-IntToFixed(100), divscale16(xdimenscale, viewingrange))+IntToFixed(ydimen>>1); - globalhoriz = FixedToInt(qglobalhoriz); + qglobalhoriz = mulscale16(dahoriz, divscale16(xdimenscale, viewingrange))+IntToFixed(ydimen>>1); globalcursectnum = dacursectnum; diff --git a/source/build/src/engine_priv.h b/source/build/src/engine_priv.h index d9485d1c2..ec9d814c4 100644 --- a/source/build/src/engine_priv.h +++ b/source/build/src/engine_priv.h @@ -87,7 +87,7 @@ extern int16_t maskwall[MAXWALLSB], maskwallcnt; extern tspriteptr_t tspriteptr[MAXSPRITESONSCREEN + 1]; extern int32_t xdimen, xdimenrecip, halfxdimen, xdimenscale, xdimscale, ydimen; extern float fxdimen; -extern int32_t globalposx, globalposy, globalposz, globalhoriz; +extern int32_t globalposx, globalposy, globalposz; extern fixed_t qglobalhoriz, qglobalang; extern float fglobalposx, fglobalposy, fglobalposz; extern int16_t globalang, globalcursectnum; diff --git a/source/build/src/polymost.cpp b/source/build/src/polymost.cpp index 34addb9d9..869cd1ea5 100644 --- a/source/build/src/polymost.cpp +++ b/source/build/src/polymost.cpp @@ -2873,8 +2873,7 @@ void polymost_prepareMirror(int32_t dax, int32_t day, int32_t daz, fixed_t daang set_globalpos(dax, day, daz); set_globalang(daang); - globalhoriz = mulscale16(FixedToInt(dahoriz)-100,divscale16(xdimenscale,viewingrange))+(ydimen>>1); - qglobalhoriz = mulscale16(dahoriz-IntToFixed(100), divscale16(xdimenscale, viewingrange))+IntToFixed(ydimen>>1); + qglobalhoriz = mulscale16(dahoriz, divscale16(xdimenscale, viewingrange))+IntToFixed(ydimen>>1); gyxscale = ((float)xdimenscale)*(1.0f/131072.f); gxyaspect = ((double)xyaspect*fviewingrange)*(5.0/(65536.0*262144.0)); gviewxrange = fviewingrange * fxdimen * (1.f/(32768.f*1024.f)); diff --git a/source/common/utility/templates.h b/source/common/utility/templates.h index 48d306cf8..3f3e596f0 100644 --- a/source/common/utility/templates.h +++ b/source/common/utility/templates.h @@ -136,11 +136,11 @@ const T MAX (const T a, const T b) // Clamps in to the range [min,max]. //========================================================================== -template -inline -T clamp (const T in, const T min, const T max) +template +inline constexpr +T clamp (const T in, const X min, const Y max) { - return in <= min ? min : in >= max ? max : in; + return in <= (T) min ? (T) min : in >= (T) max ? (T) max : in; } #endif //__TEMPLATES_H__ diff --git a/source/core/binaryangle.h b/source/core/binaryangle.h index 1986f2d83..cc3b65f9f 100644 --- a/source/core/binaryangle.h +++ b/source/core/binaryangle.h @@ -39,22 +39,29 @@ #include #include "m_fixed.h" #include "xs_Float.h" // needed for reliably overflowing float->int conversions. +#include "serializer.h" #include "build.h" +class FSerializer; + +enum +{ + BAMUNIT = 1 << 21 +}; class binangle { - unsigned int value; + uint32_t value; - inline static constexpr double pi() { return 3.14159265358979323846; } + constexpr binangle(uint32_t v) : value(v) {} - constexpr binangle(unsigned int v) : value(v) {} - - friend constexpr binangle bamang(unsigned int v); - friend constexpr binangle q16ang(unsigned int v); - friend constexpr binangle buildang(unsigned int v); + friend constexpr binangle bamang(uint32_t v); + friend constexpr binangle q16ang(uint32_t v); + friend constexpr binangle buildang(uint32_t v); friend binangle radang(double v); friend binangle degang(double v); + + friend FSerializer &Serialize(FSerializer &arc, const char *key, binangle &obj, binangle *defval); public: binangle() = default; @@ -63,36 +70,15 @@ public: constexpr short asbuild() const { return value >> 21; } constexpr fixed_t asq16() const { return value >> 5; } constexpr double asrad() const { return value * (pi::pi() / 0x80000000u); } - constexpr double asdeg() const { return value * (90. / 0x40000000); } - constexpr unsigned asbam() const { return value; } + constexpr double asdeg() const { return AngleToFloat(value); } + constexpr uint32_t asbam() const { return value; } double fsin() const { return sin(asrad()); } double fcos() const { return cos(asrad()); } double ftan() const { return tan(asrad()); } int bsin() const { return sintable[asbuild()]; } int bcos() const { return sintable[(asbuild() + 512) & 2047]; } - -#if 0 // This makes no sense - bool operator< (binangle other) const - { - return value < other.value; - } - bool operator> (binangle other) const - { - return value > other.value; - } - - bool operator<= (binangle other) const - { - return value <= other.value; - } - - bool operator>= (binangle other) const - { - return value >= other.value; - } -#endif constexpr bool operator== (binangle other) const { return value == other.value; @@ -124,34 +110,116 @@ public: { return binangle(value - other.value); } - - void interpolate(binangle a1, binangle a2, fixed_t smoothratio) - { - // Calculate in floating point to reduce the error caused by overflows which are to be expected here and then downconvert using a method that is safe to overflow. - // We do not want fixed point multiplications here to trash the result. - double smooth = smoothratio / 65536.f; - value = xs_CRoundToUInt(double(a1.asbam()) + smooth * (double(a2.asbam()) - double(a1.asbam()))); - } - }; +class lookangle +{ + int32_t value; + + constexpr lookangle(int32_t v) : value(v) {} + + friend constexpr lookangle bamlook(int32_t v); + friend constexpr lookangle q16look(int32_t v); + friend constexpr lookangle buildlook(int32_t v); + friend lookangle radlook(double v); + friend lookangle deglook(double v); + + friend FSerializer &Serialize(FSerializer &arc, const char *key, lookangle &obj, lookangle *defval); + +public: + lookangle() = default; + lookangle(const lookangle &other) = default; + // This class intentionally makes no allowances for implicit type conversions because those would render it ineffective. + constexpr short asbuild() const { return value >> 21; } + constexpr fixed_t asq16() const { return value >> 5; } + constexpr double asrad() const { return value * (pi::pi() / 0x80000000u); } + constexpr double asdeg() const { return AngleToFloat(value); } + constexpr int32_t asbam() const { return value; } + + double fsin() const { return sin(asrad()); } + double fcos() const { return cos(asrad()); } + double ftan() const { return tan(asrad()); } + + constexpr bool operator== (lookangle other) const + { + return value == other.value; + } + + constexpr bool operator!= (lookangle other) const + { + return value != other.value; + } + + constexpr lookangle &operator+= (lookangle other) + { + value += other.value; + return *this; + } + + constexpr lookangle &operator-= (lookangle other) + { + value -= other.value; + return *this; + } + + constexpr lookangle operator+ (lookangle other) const + { + return lookangle(value + other.value); + } + + constexpr lookangle operator- (lookangle other) const + { + return lookangle(value - other.value); + } + +}; + +//--------------------------------------------------------------------------- +// +// Constants and functions for use with fixedhoriz and friendly functions. +// +//--------------------------------------------------------------------------- + +// 280039127 is the maximum horizon in Q16.16 the engine will handle before wrapping around. +constexpr double horizDiff = 280039127 * 3. / 100.; + +// Degrees needed to convert horizAngle into pitch degrees. +constexpr double horizDegrees = 183.503609961216825; + +// Ratio to convert inverse tangent to -90/90 degrees of pitch. +constexpr double horizRatio = horizDegrees / pi::pi(); + +// Horizon conversion functions. +inline double HorizToPitch(double horiz) { return atan2(horiz, horizDiff / 65536.) * horizRatio; } +inline double HorizToPitch(fixed_t q16horiz) { return atan2(q16horiz, horizDiff) * horizRatio; } +inline fixed_t PitchToHoriz(double horizAngle) { return xs_CRoundToInt(horizDiff * tan(horizAngle * (pi::pi() / horizDegrees))); } +inline int32_t PitchToBAM(double horizAngle) { return xs_CRoundToInt(clamp(horizAngle * (1073741823.5 / 45.), -INT32_MAX, INT32_MAX)); } +inline constexpr double BAMToPitch(int32_t bam) { return bam * (45. / 1073741823.5); } + + class fixedhoriz { - int value; + fixed_t value; - constexpr fixedhoriz(int v) : value(v) {} + constexpr fixedhoriz(fixed_t v) : value(v) {} - friend constexpr fixedhoriz q16horiz(int v); + friend constexpr fixedhoriz q16horiz(fixed_t v); friend constexpr fixedhoriz buildhoriz(int v); + friend fixedhoriz pitchhoriz(double v); + friend fixedhoriz bamhoriz(int32_t v); + + friend FSerializer &Serialize(FSerializer &arc, const char *key, fixedhoriz &obj, fixedhoriz *defval); public: fixedhoriz() = default; fixedhoriz(const fixedhoriz &other) = default; // This class intentionally makes no allowances for implicit type conversions because those would render it ineffective. - short asbuild() const { return FixedToInt(value); } + constexpr short asbuild() const { return FixedToInt(value); } constexpr fixed_t asq16() const { return value; } + double aspitch() const { return HorizToPitch(value); } + int32_t asbam() const { return PitchToBAM(aspitch()); } bool operator< (fixedhoriz other) const { @@ -212,12 +280,34 @@ public: }; -inline constexpr binangle bamang(unsigned int v) { return binangle(v); } -inline constexpr binangle q16ang(unsigned int v) { return binangle(v << 5); } -inline constexpr binangle buildang(unsigned int v) { return binangle(v << 21); } -inline binangle radang(double v) { return binangle(xs_CRoundToUInt(v * (0x80000000u / binangle::pi()))); } -inline binangle degang(double v) { return binangle(xs_CRoundToUInt(v * (0x40000000 / 90.))); } +inline constexpr binangle bamang(uint32_t v) { return binangle(v); } +inline constexpr binangle q16ang(uint32_t v) { return binangle(v << 5); } +inline constexpr binangle buildang(uint32_t v) { return binangle(v << 21); } +inline binangle radang(double v) { return binangle(xs_CRoundToUInt(v * (0x80000000u / pi::pi()))); } +inline binangle degang(double v) { return binangle(FloatToAngle(v)); } -inline constexpr fixedhoriz q16horiz(int v) { return fixedhoriz(v); } +inline constexpr lookangle bamlook(int32_t v) { return lookangle(v); } +inline constexpr lookangle q16look(int32_t v) { return lookangle(v << 5); } +inline constexpr lookangle buildlook(int32_t v) { return lookangle(v << 21); } +inline lookangle radlook(double v) { return lookangle(xs_CRoundToUInt(v * (0x80000000u / pi::pi()))); } +inline lookangle deglook(double v) { return lookangle(FloatToAngle(v)); } + +inline constexpr fixedhoriz q16horiz(fixed_t v) { return fixedhoriz(v); } inline constexpr fixedhoriz buildhoriz(int v) { return fixedhoriz(IntToFixed(v)); } +inline fixedhoriz pitchhoriz(double v) { return fixedhoriz(PitchToHoriz(v)); } +inline fixedhoriz bamhoriz(int32_t v) { return pitchhoriz(BAMToPitch(v)); } +inline FSerializer &Serialize(FSerializer &arc, const char *key, binangle &obj, binangle *defval) +{ + return Serialize(arc, key, obj.value, defval ? &defval->value : nullptr); +} + +inline FSerializer &Serialize(FSerializer &arc, const char *key, lookangle &obj, lookangle *defval) +{ + return Serialize(arc, key, obj.value, defval ? &defval->value : nullptr); +} + +inline FSerializer &Serialize(FSerializer &arc, const char *key, fixedhoriz &obj, fixedhoriz *defval) +{ + return Serialize(arc, key, obj.value, defval ? &defval->value : nullptr); +} diff --git a/source/core/d_net.cpp b/source/core/d_net.cpp index e159034b4..32c7864e1 100644 --- a/source/core/d_net.cpp +++ b/source/core/d_net.cpp @@ -1036,30 +1036,30 @@ void NetUpdate (void) int svel = 0; int fvel = 0; - int64_t q16avel = 0; - int64_t q16horz = 0; + float avel = 0; + float horz = 0; for (j = 0; j < ticdup; ++j) { modp = (mod + j) % LOCALCMDTICS; svel += localcmds[modp].ucmd.svel; fvel += localcmds[modp].ucmd.fvel; - q16avel += localcmds[modp].ucmd.q16avel; - q16horz += localcmds[modp].ucmd.q16horz; + avel += localcmds[modp].ucmd.avel; + horz += localcmds[modp].ucmd.horz; } svel /= ticdup; fvel /= ticdup; - q16avel /= ticdup; - q16horz /= ticdup; + avel /= ticdup; + horz /= ticdup; for (j = 0; j < ticdup; ++j) { modp = (mod + j) % LOCALCMDTICS; localcmds[modp].ucmd.svel = svel; localcmds[modp].ucmd.fvel = fvel; - localcmds[modp].ucmd.q16avel = q16avel; - localcmds[modp].ucmd.q16horz = q16horz; + localcmds[modp].ucmd.avel = avel; + localcmds[modp].ucmd.horz = horz; } Net_NewMakeTic (); diff --git a/source/core/d_protocol.cpp b/source/core/d_protocol.cpp index 0a7fe8802..7b5972ee1 100644 --- a/source/core/d_protocol.cpp +++ b/source/core/d_protocol.cpp @@ -160,9 +160,9 @@ int UnpackUserCmd (InputPacket *ucmd, const InputPacket *basis, uint8_t **stream if (flags & UCMDF_BUTTONS) ucmd->actions = ESyncBits::FromInt(ReadLong(stream)); if (flags & UCMDF_PITCH) - ucmd->q16horz = ReadLong(stream); + ucmd->horz = ReadFloat(stream); if (flags & UCMDF_YAW) - ucmd->q16avel = ReadLong(stream); + ucmd->avel = ReadFloat(stream); if (flags & UCMDF_FORWARDMOVE) ucmd->fvel = ReadWord (stream); if (flags & UCMDF_SIDEMOVE) @@ -193,15 +193,15 @@ int PackUserCmd (const InputPacket *ucmd, const InputPacket *basis, uint8_t **st flags |= UCMDF_BUTTONS; WriteLong(ucmd->actions, stream); } - if (ucmd->q16horz != basis->q16horz) + if (ucmd->horz != basis->horz) { flags |= UCMDF_PITCH; - WriteLong (ucmd->q16horz, stream); + WriteFloat (ucmd->horz, stream); } - if (ucmd->q16avel != basis->q16avel) + if (ucmd->avel != basis->avel) { flags |= UCMDF_YAW; - WriteLong (ucmd->q16avel, stream); + WriteFloat (ucmd->avel, stream); } if (ucmd->fvel != basis->fvel) { @@ -236,8 +236,8 @@ FSerializer &Serialize(FSerializer &arc, const char *key, InputPacket &cmd, Inpu if (arc.BeginObject(key)) { arc("actions", cmd.actions) - ("horz", cmd.q16horz) - ("avel", cmd.q16avel) + ("horz", cmd.horz) + ("avel", cmd.avel) ("fvel", cmd.fvel) ("svwl", cmd.svel) .EndObject(); @@ -250,8 +250,8 @@ int WriteUserCmdMessage (InputPacket *ucmd, const InputPacket *basis, uint8_t ** if (basis == NULL) { if (ucmd->actions != 0 || - ucmd->q16horz != 0 || - ucmd->q16avel != 0 || + ucmd->horz != 0 || + ucmd->avel != 0 || ucmd->fvel != 0 || ucmd->svel != 0) { @@ -261,8 +261,8 @@ int WriteUserCmdMessage (InputPacket *ucmd, const InputPacket *basis, uint8_t ** } else if (ucmd->actions != basis->actions || - ucmd->q16horz != basis->q16horz || - ucmd->q16avel != basis->q16avel || + ucmd->horz != basis->horz || + ucmd->avel != basis->avel || ucmd->fvel != basis->fvel || ucmd->svel != basis->svel) { diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index 05f8e1303..4b55f6a91 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -1455,26 +1455,28 @@ void processMovement(InputPacket* currInput, InputPacket* inputBuffer, ControlIn int const keymove = gi->playerKeyMove() << running; int const cntrlvelscale = g_gameType & GAMEFLAG_PSEXHUMED ? 8 : 1; float const mousevelscale = keymove / 160.f; + double const angtodegscale = 45. / 256.; + double const hidspeed = ((running ? 43375. / 27. : 867.5) / GameTicRate) * angtodegscale; // process mouse and initial controller input. if (buttonMap.ButtonDown(gamefunc_Strafe) && allowstrafe) - currInput->svel -= xs_CRoundToInt(hidInput->mousemovex * mousevelscale + (scaleAdjust * (hidInput->dyaw / 60) * keymove * cntrlvelscale)); + currInput->svel -= xs_CRoundToInt((hidInput->mousemovex * mousevelscale) + (scaleAdjust * (hidInput->dyaw / 60) * keymove * cntrlvelscale)); else - currInput->q16avel += FloatToFixed(hidInput->mouseturnx + (scaleAdjust * hidInput->dyaw)); + currInput->avel += hidInput->mouseturnx + (scaleAdjust * hidInput->dyaw * hidspeed * turnscale); if (!(inputBuffer->actions & SB_AIMMODE)) - currInput->q16horz -= FloatToFixed(hidInput->mouseturny); + currInput->horz -= hidInput->mouseturny; else currInput->fvel -= xs_CRoundToInt(hidInput->mousemovey * mousevelscale); if (invertmouse) - currInput->q16horz = -currInput->q16horz; + currInput->horz = -currInput->horz; if (invertmousex) - currInput->q16avel = -currInput->q16avel; + currInput->avel = -currInput->avel; // process remaining controller input. - currInput->q16horz -= FloatToFixed(scaleAdjust * hidInput->dpitch); + currInput->horz -= scaleAdjust * hidInput->dpitch * hidspeed; currInput->svel -= xs_CRoundToInt(scaleAdjust * hidInput->dx * keymove * cntrlvelscale); currInput->fvel -= xs_CRoundToInt(scaleAdjust * hidInput->dz * keymove * cntrlvelscale); @@ -1495,24 +1497,24 @@ void processMovement(InputPacket* currInput, InputPacket* inputBuffer, ControlIn static double turnheldtime; int const turnheldamt = 120 / GameTicRate; double const turboturntime = 590. / GameTicRate; - double turnamount = ((running ? 43375. / 27. : 867.5) / GameTicRate) * turnscale; - double preambleturn = turnamount / (347. / 92.); + double turnamount = hidspeed * turnscale; + double preambleturn = turnamount * (92. / 347.); // allow Exhumed to use its legacy values given the drastic difference from the other games. if ((g_gameType & GAMEFLAG_PSEXHUMED) && cl_exhumedoldturn) { - preambleturn = turnamount = running ? 12 : 8; + preambleturn = turnamount = (running ? 12 : 8) * angtodegscale; } if (buttonMap.ButtonDown(gamefunc_Turn_Left) || (buttonMap.ButtonDown(gamefunc_Strafe_Left) && !allowstrafe)) { turnheldtime += scaleAdjust * turnheldamt; - currInput->q16avel -= FloatToFixed(scaleAdjust * (turnheldtime >= turboturntime ? turnamount : preambleturn)); + currInput->avel -= scaleAdjust * (turnheldtime >= turboturntime ? turnamount : preambleturn); } else if (buttonMap.ButtonDown(gamefunc_Turn_Right) || (buttonMap.ButtonDown(gamefunc_Strafe_Right) && !allowstrafe)) { turnheldtime += scaleAdjust * turnheldamt; - currInput->q16avel += FloatToFixed(scaleAdjust * (turnheldtime >= turboturntime ? turnamount : preambleturn)); + currInput->avel += scaleAdjust * (turnheldtime >= turboturntime ? turnamount : preambleturn); } else { @@ -1564,8 +1566,8 @@ void processMovement(InputPacket* currInput, InputPacket* inputBuffer, ControlIn // add collected input to game's local input accumulation packet. inputBuffer->fvel = clamp(inputBuffer->fvel + currInput->fvel, -keymove, keymove); inputBuffer->svel = clamp(inputBuffer->svel + currInput->svel, -keymove, keymove); - inputBuffer->q16avel += currInput->q16avel; - inputBuffer->q16horz += currInput->q16horz; + inputBuffer->avel += currInput->avel; + inputBuffer->horz += currInput->horz; } //--------------------------------------------------------------------------- @@ -1574,64 +1576,64 @@ void processMovement(InputPacket* currInput, InputPacket* inputBuffer, ControlIn // //--------------------------------------------------------------------------- -void sethorizon(fixed_t* q16horiz, fixed_t const q16horz, ESyncBits* actions, double const scaleAdjust) +void sethorizon(fixedhoriz* horiz, float const horz, 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()); + // Store current horizon as true pitch. + double pitch = horiz->aspitch(); - if (q16horz) + if (horz) { *actions &= ~SB_CENTERVIEW; - horizAngle = clamp(horizAngle + FixedToFloat(q16horz), -180, 180); + pitch += horz; } // this is the locked type if (*actions & (SB_AIM_UP|SB_AIM_DOWN)) { *actions &= ~SB_CENTERVIEW; - double const amount = 250. / GameTicRate; + double const amount = HorizToPitch(250. / GameTicRate); if (*actions & SB_AIM_DOWN) - horizAngle -= scaleAdjust * amount; + pitch -= scaleAdjust * amount; if (*actions & SB_AIM_UP) - horizAngle += scaleAdjust * amount; + pitch += scaleAdjust * amount; } // this is the unlocked type if (*actions & (SB_LOOK_UP|SB_LOOK_DOWN)) { *actions |= SB_CENTERVIEW; - double const amount = 500. / GameTicRate; + double const amount = HorizToPitch(500. / GameTicRate); if (*actions & SB_LOOK_DOWN) - horizAngle -= scaleAdjust * amount; + pitch -= scaleAdjust * amount; if (*actions & SB_LOOK_UP) - horizAngle += scaleAdjust * amount; + pitch += scaleAdjust * amount; } - // convert back to Build's horizon - *q16horiz = IntToFixed(100) + xs_CRoundToInt(IntToFixed(128) * tan(horizAngle * (pi::pi() / 512.))); + // clamp pitch after processing + pitch = clamp(pitch, -90, 90); // 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)) + if (abs(pitch) > 0.1375) { - // move *q16horiz back to 100 - *q16horiz += xs_CRoundToInt(scaleAdjust * (((1000. / GameTicRate) * FRACUNIT) - (*q16horiz * (10. / GameTicRate)))); + // move pitch back to 0 + pitch += -scaleAdjust * pitch * (9. / GameTicRate); } else { - // not looking anymore because *q16horiz is back at 100 - *q16horiz = IntToFixed(100); + // not looking anymore because pitch is back at 0 + pitch = 0; *actions &= ~SB_CENTERVIEW; } } // clamp before returning - *q16horiz = clamp(*q16horiz, gi->playerHorizMin(), gi->playerHorizMax()); + *horiz = q16horiz(clamp(PitchToHoriz(pitch), gi->playerHorizMin(), gi->playerHorizMax())); } //--------------------------------------------------------------------------- @@ -1640,161 +1642,58 @@ void sethorizon(fixed_t* q16horiz, fixed_t const q16horz, ESyncBits* actions, do // //--------------------------------------------------------------------------- -void applylook(fixed_t* q16ang, fixed_t* q16look_ang, fixed_t* q16rotscrnang, fixed_t* spin, fixed_t const q16avel, ESyncBits* actions, double const scaleAdjust, bool const crouching) +void applylook(PlayerAngle* angle, float const avel, ESyncBits* actions, double const scaleAdjust, bool const crouching) { - // return q16rotscrnang to 0 and set to 0 if less than a quarter of a FRACUNIT (16384) - *q16rotscrnang -= xs_CRoundToInt(scaleAdjust * (*q16rotscrnang * (15. / GameTicRate))); - if (abs(*q16rotscrnang) < (FRACUNIT >> 2)) *q16rotscrnang = 0; + // return q16rotscrnang to 0 and set to 0 if less than a quarter of a unit + angle->rotscrnang -= bamlook(xs_CRoundToInt(scaleAdjust * angle->rotscrnang.asbam() * (15. / GameTicRate))); + if (abs(angle->rotscrnang.asbam()) < (BAMUNIT >> 2)) angle->rotscrnang = bamlook(0); - // return q16look_ang to 0 and set to 0 if less than a quarter of a FRACUNIT (16384) - *q16look_ang -= xs_CRoundToInt(scaleAdjust * (*q16look_ang * (7.5 / GameTicRate))); - if (abs(*q16look_ang) < (FRACUNIT >> 2)) *q16look_ang = 0; + // return q16look_ang to 0 and set to 0 if less than a quarter of a unit + angle->look_ang -= bamlook(xs_CRoundToInt(scaleAdjust * angle->look_ang.asbam() * (7.5 / GameTicRate))); + if (abs(angle->look_ang.asbam()) < (BAMUNIT >> 2)) angle->look_ang = bamlook(0); if (*actions & SB_LOOK_LEFT) { // start looking left - *q16look_ang -= FloatToFixed(scaleAdjust * (4560. / GameTicRate)); - *q16rotscrnang += FloatToFixed(scaleAdjust * (720. / GameTicRate)); + angle->look_ang -= bamlook(xs_CRoundToInt(scaleAdjust * (4560. / GameTicRate) * BAMUNIT)); + angle->rotscrnang += bamlook(xs_CRoundToInt(scaleAdjust * (720. / GameTicRate) * BAMUNIT)); } if (*actions & SB_LOOK_RIGHT) { // start looking right - *q16look_ang += FloatToFixed(scaleAdjust * (4560. / GameTicRate)); - *q16rotscrnang -= FloatToFixed(scaleAdjust * (720. / GameTicRate)); + angle->look_ang += bamlook(xs_CRoundToInt(scaleAdjust * (4560. / GameTicRate) * BAMUNIT)); + angle->rotscrnang -= bamlook(xs_CRoundToInt(scaleAdjust * (720. / GameTicRate) * BAMUNIT)); } if (*actions & SB_TURNAROUND) { - if (*spin == 0) + if (angle->spin.asbam() == 0) { // currently not spinning, so start a spin - *spin = IntToFixed(-1024); + angle->spin = buildlook(-1024); } *actions &= ~SB_TURNAROUND; } - if (*spin < 0) + if (angle->spin.asbam() < 0) { // return spin to 0 - fixed_t add = FloatToFixed(scaleAdjust * ((!crouching ? 3840. : 1920.) / GameTicRate)); - *spin += add; - if (*spin > 0) + lookangle add = bamlook(xs_CRoundToUInt(scaleAdjust * ((!crouching ? 3840. : 1920.) / GameTicRate) * BAMUNIT)); + angle->spin += add; + if (angle->spin.asbam() > 0) { // Don't overshoot our target. With variable factor this is possible. - add -= *spin; - *spin = 0; + add -= angle->spin; + angle->spin = bamlook(0); } - *q16ang += add; + angle->ang += bamang(add.asbam()); } - if (q16avel) + if (avel) { // add player's input - *q16ang = (*q16ang + q16avel) & 0x7FFFFFF; - } -} - -//--------------------------------------------------------------------------- -// -// Player's ticrate helper functions. -// -//--------------------------------------------------------------------------- - -void playerAddAngle(fixed_t* q16ang, double* helper, double adjustment) -{ - if (!cl_syncinput) - { - *helper += adjustment; - } - else - { - *q16ang = (*q16ang + FloatToFixed(adjustment)) & 0x7FFFFFF; - } -} - -void playerSetAngle(fixed_t* q16ang, fixed_t* helper, double adjustment) -{ - if (!cl_syncinput) - { - // Add slight offset if adjustment is coming in as absolute 0. - if (adjustment == 0) adjustment += (1. / (FRACUNIT >> 1)); - - *helper = *q16ang + getincangleq16(*q16ang, FloatToFixed(adjustment)); - } - else - { - *q16ang = FloatToFixed(adjustment); - } -} - -void playerAddHoriz(fixed_t* q16horiz, double* helper, double adjustment) -{ - if (!cl_syncinput) - { - *helper += adjustment; - } - else - { - *q16horiz += FloatToFixed(adjustment); - } -} - -void playerSetHoriz(fixed_t* q16horiz, fixed_t* helper, double adjustment) -{ - if (!cl_syncinput) - { - // Add slight offset if adjustment is coming in as absolute 0. - if (adjustment == 0) adjustment += (1. / (FRACUNIT >> 1)); - - *helper = FloatToFixed(adjustment); - } - else - { - *q16horiz = FloatToFixed(adjustment); - } -} - -//--------------------------------------------------------------------------- -// -// Player's ticrate helper processor. -// -//--------------------------------------------------------------------------- - -void playerProcessHelpers(fixed_t* q16ang, double* angAdjust, fixed_t* angTarget, fixed_t* q16horiz, double* horizAdjust, fixed_t* horizTarget, double const scaleAdjust) -{ - // Process angle amendments from the game's ticker. - if (*angTarget) - { - fixed_t angDelta = getincangleq16(*q16ang, *angTarget); - *q16ang = (*q16ang + xs_CRoundToInt(scaleAdjust * angDelta)); - - if (abs(*q16ang - *angTarget) < FRACUNIT) - { - *q16ang = *angTarget; - *angTarget = 0; - } - } - else if (*angAdjust) - { - *q16ang = (*q16ang + FloatToFixed(scaleAdjust * *angAdjust)) & 0x7FFFFFF; - } - - // Process horizon amendments from the game's ticker. - if (*horizTarget) - { - fixed_t horizDelta = *horizTarget - *q16horiz; - *q16horiz += xs_CRoundToInt(scaleAdjust * horizDelta); - - if (abs(*q16horiz - *horizTarget) < FRACUNIT) - { - *q16horiz = *horizTarget; - *horizTarget = 0; - } - } - else if (*horizAdjust) - { - *q16horiz += FloatToFixed(scaleAdjust * *horizAdjust); + angle->ang += degang(avel); } } diff --git a/source/core/gamecontrol.h b/source/core/gamecontrol.h index 6c97c8894..0e289548a 100644 --- a/source/core/gamecontrol.h +++ b/source/core/gamecontrol.h @@ -12,6 +12,7 @@ #include "i_time.h" #include "palentry.h" #include "pragmas.h" +#include "binaryangle.h" extern FString currentGame; extern FString LumpFilter; @@ -63,14 +64,180 @@ void CompleteLevel(MapRecord* map); int getincangle(int c, int n); fixed_t getincangleq16(fixed_t c, fixed_t n); +struct PlayerHorizon +{ + fixedhoriz horiz, ohoriz, horizoff, ohorizoff; + fixed_t target; + double adjustment; + + void backup() + { + ohoriz = horiz; + ohorizoff = horizoff; + } + + void restore() + { + horiz = ohoriz; + horizoff = ohorizoff; + } + + void addadjustment(double value) + { + if (!cl_syncinput) + { + adjustment += value; + } + else + { + horiz += q16horiz(FloatToFixed(value)); + } + } + + void resetadjustment() + { + adjustment = 0; + } + + void settarget(double value, bool backup = false) + { + if (!cl_syncinput) + { + target = FloatToFixed(value); + if (target == 0) target += 1; + } + else + { + horiz = q16horiz(FloatToFixed(value)); + if (backup) ohoriz = horiz; + } + } + + void processhelpers(double const scaleAdjust) + { + if (target) + { + horiz += q16horiz(xs_CRoundToInt(scaleAdjust * (target - horiz.asq16()))); + + if (abs(horiz.asq16() - target) < FRACUNIT) + { + horiz = q16horiz(target); + target = 0; + } + } + else if (adjustment) + { + horiz += q16horiz(FloatToFixed(scaleAdjust * adjustment)); + } + } + + fixedhoriz sum() + { + return horiz + horizoff; + } + + fixedhoriz interpolatedsum(double const smoothratio) + { + double const ratio = smoothratio / FRACUNIT; + fixed_t const prev = (ohoriz + ohorizoff).asq16(); + fixed_t const curr = (horiz + horizoff).asq16(); + return q16horiz(prev + xs_CRoundToInt(ratio * (curr - prev))); + } +}; + +struct PlayerAngle +{ + binangle ang, oang; + lookangle look_ang, olook_ang, rotscrnang, orotscrnang, spin; + double adjustment, target; + + void backup() + { + oang = ang; + olook_ang = look_ang; + orotscrnang = rotscrnang; + } + + void restore() + { + ang = oang; + look_ang = olook_ang; + rotscrnang = orotscrnang; + } + + void addadjustment(double value) + { + if (!cl_syncinput) + { + adjustment += value; + } + else + { + ang += bamang(xs_CRoundToUInt(value * BAMUNIT)); + } + } + + void resetadjustment() + { + adjustment = 0; + } + + void settarget(double value, bool backup = false) + { + if (!cl_syncinput) + { + if (value == 0) value += (1. / BAMUNIT); + target = xs_CRoundToUInt(value * BAMUNIT); + } + else + { + ang = bamang(xs_CRoundToUInt(value * BAMUNIT)); + if (backup) oang = ang; + } + } + + void processhelpers(double const scaleAdjust) + { + if (target) + { + ang = bamang(ang.asbam() + xs_CRoundToInt(scaleAdjust * (target - ang.asbam()))); + + if (ang.asbam() - target < BAMUNIT) + { + ang = bamang(target); + target = 0; + } + } + else if (adjustment) + { + ang += bamang(xs_CRoundToUInt(scaleAdjust * adjustment * BAMUNIT)); + } + } + + binangle sum() + { + return bamang(ang.asbam() + look_ang.asbam()); + } + + binangle interpolatedsum(double const smoothratio) + { + double const ratio = smoothratio / FRACUNIT; + int32_t const dang = UINT32_MAX / 2; + int64_t const prev = oang.asbam() + olook_ang.asbam(); + int64_t const curr = ang.asbam() + look_ang.asbam(); + return bamang(prev + xs_CRoundToUInt(ratio * (((curr + dang - prev) & 0xFFFFFFFF) - dang))); + } + + lookangle interpolatedrotscrn(double const smoothratio) + { + double const ratio = smoothratio / FRACUNIT; + return bamlook(orotscrnang.asbam() + xs_CRoundToInt(ratio * (rotscrnang.asbam() - orotscrnang.asbam()))); + } +}; + void processMovement(InputPacket* currInput, InputPacket* inputBuffer, ControlInfo* const hidInput, double const scaleAdjust, int const drink_amt = 0, bool const allowstrafe = true, double const turnscale = 1); -void sethorizon(fixed_t* q16horiz, fixed_t const q16horz, ESyncBits* actions, double const scaleAdjust); -void applylook(fixed_t* q16ang, fixed_t* q16look_ang, fixed_t* q16rotscrnang, fixed_t* spin, fixed_t const q16avel, ESyncBits* actions, double const scaleAdjust, bool const crouching); -void playerAddAngle(fixed_t* q16ang, double* helper, double adjustment); -void playerSetAngle(fixed_t* q16ang, fixed_t* helper, double adjustment); -void playerAddHoriz(fixed_t* q16horiz, double* helper, double adjustment); -void playerSetHoriz(fixed_t* q16horiz, fixed_t* helper, double adjustment); -void playerProcessHelpers(fixed_t* q16ang, double* angAdjust, fixed_t* angTarget, fixed_t* q16horiz, double* horizAdjust, fixed_t* horizTarget, double const scaleAdjust); +void sethorizon(fixedhoriz* horiz, float const horz, ESyncBits* actions, double const scaleAdjust); +void applylook(PlayerAngle* angle, float const avel, ESyncBits* actions, double const scaleAdjust, bool const crouching); struct UserConfig { diff --git a/source/core/gamestruct.h b/source/core/gamestruct.h index 3808c8672..e7fd4bf3f 100644 --- a/source/core/gamestruct.h +++ b/source/core/gamestruct.h @@ -89,8 +89,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 fixed_t playerHorizMin() { return IntToFixed(-200); } + virtual fixed_t playerHorizMax() { return IntToFixed(200); } virtual int playerKeyMove() { return 0; } virtual FString statFPS() diff --git a/source/core/inputstate.cpp b/source/core/inputstate.cpp index d701e5210..ce88497f4 100644 --- a/source/core/inputstate.cpp +++ b/source/core/inputstate.cpp @@ -62,8 +62,8 @@ CVAR(Float, m_side, 1.f, CVAR_GLOBALCONFIG | CVAR_ARCHIVE) void InputState::GetMouseDelta(ControlInfo * hidInput) { - hidInput->mouseturnx = g_mousePos.x * m_yaw * (1.f / 4.f); - hidInput->mouseturny = g_mousePos.y * m_pitch * (1.f / 5.f); + hidInput->mouseturnx = g_mousePos.x * m_yaw * (1.f / 18.f); + hidInput->mouseturny = g_mousePos.y * m_pitch * (1.f / 14.f); hidInput->mousemovex = g_mousePos.x * m_side; hidInput->mousemovey = g_mousePos.y * m_forward; @@ -181,10 +181,10 @@ ControlInfo CONTROL_GetInput() I_GetAxes(joyaxes); - hidInput.dyaw += -joyaxes[JOYAXIS_Yaw] * (1350.f / GameTicRate); - hidInput.dx += -joyaxes[JOYAXIS_Side] * 0.75f; - hidInput.dz += -joyaxes[JOYAXIS_Forward] * 0.75f; - hidInput.dpitch += -joyaxes[JOYAXIS_Pitch] * (675.f / GameTicRate); + hidInput.dyaw += -joyaxes[JOYAXIS_Yaw]; + hidInput.dx += -joyaxes[JOYAXIS_Side] * .5f; + hidInput.dz += -joyaxes[JOYAXIS_Forward] * .5f; + hidInput.dpitch += -joyaxes[JOYAXIS_Pitch]; } return hidInput; diff --git a/source/core/packet.h b/source/core/packet.h index 645f019e2..a3704b23c 100644 --- a/source/core/packet.h +++ b/source/core/packet.h @@ -72,8 +72,8 @@ struct InputPacket { int16_t svel; int16_t fvel; - fixed_t q16avel; - fixed_t q16horz; + float avel; + float horz; ESyncBits actions; diff --git a/source/exhumed/src/exhumed.cpp b/source/exhumed/src/exhumed.cpp index 7f4edd710..646918a32 100644 --- a/source/exhumed/src/exhumed.cpp +++ b/source/exhumed/src/exhumed.cpp @@ -429,8 +429,8 @@ void GameInterface::Ticker() sPlayerInput[nLocalPlayer].actions = localInput.actions; if (oldactions & SB_CENTERVIEW) sPlayerInput[nLocalPlayer].actions |= SB_CENTERVIEW; - sPlayerInput[nLocalPlayer].nAngle = localInput.q16avel; - sPlayerInput[nLocalPlayer].pan = localInput.q16horz; + sPlayerInput[nLocalPlayer].nAngle = localInput.avel; + sPlayerInput[nLocalPlayer].pan = localInput.horz; Ra[nLocalPlayer].nTarget = besttarget; diff --git a/source/exhumed/src/exhumed.h b/source/exhumed/src/exhumed.h index 70bdcb025..9dc236dcb 100644 --- a/source/exhumed/src/exhumed.h +++ b/source/exhumed/src/exhumed.h @@ -264,8 +264,8 @@ struct GameInterface : ::GameInterface void LevelCompleted(MapRecord *map, int skill) override; void NextLevel(MapRecord *map, int skill) override; bool DrawAutomapPlayer(int x, int y, int z, int a) override; - fixed_t playerHorizMin() override { return IntToFixed(-50); } - fixed_t playerHorizMax() override { return IntToFixed(250); } + fixed_t playerHorizMin() override { return IntToFixed(-150); } + fixed_t playerHorizMax() override { return IntToFixed(150); } int playerKeyMove() override { return 6; } ::GameStats getStats() override; diff --git a/source/exhumed/src/gameloop.cpp b/source/exhumed/src/gameloop.cpp index 41212bb16..432632144 100644 --- a/source/exhumed/src/gameloop.cpp +++ b/source/exhumed/src/gameloop.cpp @@ -90,7 +90,7 @@ void GameInterface::Render() } double const smoothratio = calc_smoothratio(); - double const look_anghalf = getHalfLookAng(PlayerList[nLocalPlayer].oq16look_ang, PlayerList[nLocalPlayer].q16look_ang, cl_syncinput, smoothratio); + double const look_anghalf = getHalfLookAng(PlayerList[nLocalPlayer].angle.olook_ang.asq16(), PlayerList[nLocalPlayer].angle.look_ang.asq16(), cl_syncinput, smoothratio); DrawView(smoothratio); DrawStatusBar(); diff --git a/source/exhumed/src/gun.cpp b/source/exhumed/src/gun.cpp index a662b4225..f66fd606e 100644 --- a/source/exhumed/src/gun.cpp +++ b/source/exhumed/src/gun.cpp @@ -739,7 +739,7 @@ loc_flag: // loc_27266: case kWeaponSword: { - nHeight += (IntToFixed(100) - PlayerList[nLocalPlayer].q16horiz) >> 10; + nHeight += -PlayerList[nLocalPlayer].horizon.horiz.asq16() >> 10; theZ += nHeight; @@ -844,7 +844,7 @@ loc_flag: } case kWeaponPistol: { - int var_50 = (PlayerList[nLocalPlayer].q16horiz - IntToFixed(100)) >> 14; + int var_50 = PlayerList[nLocalPlayer].horizon.horiz.asq16() >> 14; nHeight -= var_50; if (sPlayerInput[nPlayer].nTarget >= 0 && cl_autoaim) @@ -859,7 +859,7 @@ loc_flag: case kWeaponGrenade: { - ThrowGrenade(nPlayer, ebp, ebx, nHeight - 2560, FixedToInt(PlayerList[nLocalPlayer].q16horiz) - 100); + ThrowGrenade(nPlayer, ebp, ebx, nHeight - 2560, FixedToInt(PlayerList[nLocalPlayer].horizon.horiz.asq16())); break; } case kWeaponStaff: @@ -985,7 +985,7 @@ void DrawWeapons(double smooth) nShade = sprite[PlayerList[nLocalPlayer].nSprite].shade; } - double const look_anghalf = getHalfLookAng(PlayerList[nLocalPlayer].oq16look_ang, PlayerList[nLocalPlayer].q16look_ang, cl_syncinput, smooth); + double const look_anghalf = getHalfLookAng(PlayerList[nLocalPlayer].angle.olook_ang.asq16(), PlayerList[nLocalPlayer].angle.look_ang.asq16(), cl_syncinput, smooth); double const looking_arc = fabs(look_anghalf) / 4.5; xOffset -= look_anghalf; diff --git a/source/exhumed/src/input.cpp b/source/exhumed/src/input.cpp index ef8662fbe..1f48cb7a9 100644 --- a/source/exhumed/src/input.cpp +++ b/source/exhumed/src/input.cpp @@ -128,11 +128,12 @@ void GameInterface::GetInput(InputPacket* packet, ControlInfo* const hidInput) if (!nFreeze) { - applylook(&pPlayer->q16angle, &pPlayer->q16look_ang, &pPlayer->q16rotscrnang, &pPlayer->spin, input.q16avel, &sPlayerInput[nLocalPlayer].actions, scaleAdjust, eyelevel[nLocalPlayer] > -14080); - sethorizon(&pPlayer->q16horiz, input.q16horz, &sPlayerInput[nLocalPlayer].actions, scaleAdjust); + applylook(&pPlayer->angle, input.avel, &sPlayerInput[nLocalPlayer].actions, scaleAdjust, eyelevel[nLocalPlayer] > -14080); + sethorizon(&pPlayer->horizon.horiz, input.horz, &sPlayerInput[nLocalPlayer].actions, scaleAdjust); } - playerProcessHelpers(&pPlayer->q16angle, &pPlayer->angAdjust, &pPlayer->angTarget, &pPlayer->q16horiz, &pPlayer->horizAdjust, &pPlayer->horizTarget, scaleAdjust); + pPlayer->angle.processhelpers(scaleAdjust); + pPlayer->horizon.processhelpers(scaleAdjust); UpdatePlayerSpriteAngle(pPlayer); } diff --git a/source/exhumed/src/osdcmds.cpp b/source/exhumed/src/osdcmds.cpp index 34ec72d51..eef22a001 100644 --- a/source/exhumed/src/osdcmds.cpp +++ b/source/exhumed/src/osdcmds.cpp @@ -50,12 +50,12 @@ static int osdcmd_warptocoords(CCmdFuncPtr parm) if (parm->numparms >= 4) { - nPlayer->q16angle = IntToFixed(atoi(parm->parms[3])); + nPlayer->angle.oang = nPlayer->angle.ang = buildang(atoi(parm->parms[3])); } if (parm->numparms == 5) { - nPlayer->q16horiz = IntToFixed(atoi(parm->parms[4])); + nPlayer->horizon.ohoriz = nPlayer->horizon.horiz = buildhoriz(atoi(parm->parms[4])); } return CCMD_OK; diff --git a/source/exhumed/src/player.cpp b/source/exhumed/src/player.cpp index 2773caca1..3680ce8a1 100644 --- a/source/exhumed/src/player.cpp +++ b/source/exhumed/src/player.cpp @@ -309,8 +309,8 @@ void RestartPlayer(short nPlayer) sprite[nSprite].y = sprite[nNStartSprite].y; sprite[nSprite].z = sprite[nNStartSprite].z; mychangespritesect(nSprite, sprite[nNStartSprite].sectnum); - PlayerList[nPlayer].q16angle = IntToFixed(sprite[nNStartSprite].ang&kAngleMask); - sprite[nSprite].ang = FixedToInt(PlayerList[nPlayer].q16angle); + PlayerList[nPlayer].angle.ang = buildang(sprite[nNStartSprite].ang&kAngleMask); + sprite[nSprite].ang = PlayerList[nPlayer].angle.ang.asbuild(); floorspr = insertsprite(sprite[nSprite].sectnum, 0); assert(floorspr >= 0 && floorspr < kMaxSprites); @@ -328,17 +328,15 @@ void RestartPlayer(short nPlayer) sprite[nSprite].x = sPlayerSave[nPlayer].x; sprite[nSprite].y = sPlayerSave[nPlayer].y; sprite[nSprite].z = sector[sPlayerSave[nPlayer].nSector].floorz; - PlayerList[nPlayer].q16angle = IntToFixed(sPlayerSave[nPlayer].nAngle&kAngleMask); - sprite[nSprite].ang = FixedToInt(PlayerList[nPlayer].q16angle); + PlayerList[nPlayer].angle.ang = buildang(sPlayerSave[nPlayer].nAngle&kAngleMask); + sprite[nSprite].ang = PlayerList[nPlayer].angle.ang.asbuild(); floorspr = -1; } PlayerList[nPlayer].opos = sprite[nSprite].pos; - PlayerList[nPlayer].oq16angle = PlayerList[nPlayer].q16angle; - PlayerList[nPlayer].oq16horiz = PlayerList[nPlayer].q16horiz; - PlayerList[nPlayer].oq16look_ang = PlayerList[nPlayer].q16look_ang = 0; - PlayerList[nPlayer].oq16rotscrnang = PlayerList[nPlayer].q16rotscrnang = 0; + PlayerList[nPlayer].angle.backup(); + PlayerList[nPlayer].horizon.backup(); nPlayerFloorSprite[nPlayer] = floorspr; @@ -438,7 +436,7 @@ void RestartPlayer(short nPlayer) nYDamage[nPlayer] = 0; nXDamage[nPlayer] = 0; - PlayerList[nPlayer].oq16horiz = PlayerList[nPlayer].q16horiz = IntToFixed(100); + PlayerList[nPlayer].horizon.ohoriz = PlayerList[nPlayer].horizon.horiz = q16horiz(0); nBreathTimer[nPlayer] = 90; nTauntTimer[nPlayer] = RandomSize(3) + 3; @@ -535,7 +533,7 @@ void StartDeathSeq(int nPlayer, int nVal) StopFiringWeapon(nPlayer); - PlayerList[nPlayer].oq16horiz = PlayerList[nPlayer].q16horiz = IntToFixed(100); + PlayerList[nPlayer].horizon.ohoriz = PlayerList[nPlayer].horizon.horiz = q16horiz(0); oeyelevel[nPlayer] = eyelevel[nPlayer] = -14080; nPlayerInvisible[nPlayer] = 0; dVertPan[nPlayer] = 15; @@ -702,7 +700,7 @@ static void pickupMessage(int no) void UpdatePlayerSpriteAngle(Player* pPlayer) { - sprite[pPlayer->nSprite].ang = FixedToInt(pPlayer->q16angle); + sprite[pPlayer->nSprite].ang = pPlayer->angle.ang.asbuild(); } void FuncPlayer(int a, int nDamage, int nRun) @@ -725,13 +723,11 @@ void FuncPlayer(int a, int nDamage, int nRun) short nSprite2; - PlayerList[nPlayer].angAdjust = 0; - PlayerList[nPlayer].horizAdjust = 0; PlayerList[nPlayer].opos = sprite[nPlayerSprite].pos; - PlayerList[nPlayer].oq16angle = PlayerList[nPlayer].q16angle; - PlayerList[nPlayer].oq16horiz = PlayerList[nPlayer].q16horiz; - PlayerList[nPlayer].oq16look_ang = PlayerList[nPlayer].q16look_ang; - PlayerList[nPlayer].oq16rotscrnang = PlayerList[nPlayer].q16rotscrnang; + PlayerList[nPlayer].angle.backup(); + PlayerList[nPlayer].horizon.backup(); + PlayerList[nPlayer].angle.resetadjustment(); + PlayerList[nPlayer].horizon.resetadjustment(); oeyelevel[nPlayer] = eyelevel[nPlayer]; switch (nMessage) @@ -948,7 +944,7 @@ void FuncPlayer(int a, int nDamage, int nRun) if (cl_syncinput) { Player* pPlayer = &PlayerList[nPlayer]; - applylook(&pPlayer->q16angle, &pPlayer->q16look_ang, &pPlayer->q16rotscrnang, &pPlayer->spin, sPlayerInput[nPlayer].nAngle, &sPlayerInput[nLocalPlayer].actions, 1, eyelevel[nLocalPlayer] > -14080); + applylook(&pPlayer->angle, sPlayerInput[nPlayer].nAngle, &sPlayerInput[nLocalPlayer].actions, 1, eyelevel[nLocalPlayer] > -14080); UpdatePlayerSpriteAngle(pPlayer); } @@ -1046,12 +1042,10 @@ void FuncPlayer(int a, int nDamage, int nRun) if (nTotalPlayers <= 1) { auto ang = GetAngleToSprite(nPlayerSprite, nSpiritSprite) & kAngleMask; - playerSetAngle(&PlayerList[nPlayer].q16angle, &PlayerList[nPlayer].angTarget, ang); - PlayerList[nPlayer].oq16angle = PlayerList[nPlayer].q16angle; + PlayerList[nPlayer].angle.settarget(ang, true); sprite[nPlayerSprite].ang = ang; - playerSetHoriz(&PlayerList[nPlayer].q16horiz, &PlayerList[nPlayer].horizTarget, 100); - PlayerList[nPlayer].oq16horiz = PlayerList[nPlayer].q16horiz; + PlayerList[nPlayer].horizon.settarget(0, true); lPlayerXVel = 0; lPlayerYVel = 0; @@ -1069,11 +1063,11 @@ void FuncPlayer(int a, int nDamage, int nRun) if (currentLevel->levelNumber == 11) { - playerSetHoriz(&PlayerList[nPlayer].q16horiz, &PlayerList[nPlayer].horizTarget, 146); + PlayerList[nPlayer].horizon.settarget(46); } else { - playerSetHoriz(&PlayerList[nPlayer].q16horiz, &PlayerList[nPlayer].horizTarget, 111); + PlayerList[nPlayer].horizon.settarget(11); } } } @@ -1101,7 +1095,7 @@ void FuncPlayer(int a, int nDamage, int nRun) zVelB = -zVelB; } - if (zVelB > 512 && PlayerList[nPlayer].q16angle != IntToFixed(100) && (sPlayerInput[nPlayer].actions & (SB_AIMMODE))) { + if (zVelB > 512 && PlayerList[nPlayer].horizon.horiz.asq16() != 0 && (sPlayerInput[nPlayer].actions & (SB_AIMMODE))) { sPlayerInput[nPlayer].actions |= SB_CENTERVIEW; } } @@ -2669,7 +2663,7 @@ loc_1BD2E: if (cl_syncinput) { Player* pPlayer = &PlayerList[nPlayer]; - sethorizon(&pPlayer->q16horiz, sPlayerInput[nPlayer].pan, &sPlayerInput[nLocalPlayer].actions, 1); + sethorizon(&pPlayer->horizon.horiz, sPlayerInput[nPlayer].pan, &sPlayerInput[nLocalPlayer].actions, 1); } } else // else, player's health is less than 0 @@ -2789,20 +2783,20 @@ loc_1BD2E: } else { - if (PlayerList[nPlayer].q16horiz < IntToFixed(100)) + if (PlayerList[nPlayer].horizon.horiz.asq16() < 0) { - playerSetHoriz(&PlayerList[nPlayer].q16horiz, &PlayerList[nPlayer].horizTarget, 100); + PlayerList[nPlayer].horizon.settarget(0); eyelevel[nPlayer] -= (dVertPan[nPlayer] << 8); } else { - playerAddHoriz(&PlayerList[nPlayer].q16horiz, &PlayerList[nPlayer].horizAdjust, dVertPan[nPlayer]); + PlayerList[nPlayer].horizon.addadjustment(dVertPan[nPlayer]); - if (PlayerList[nPlayer].q16horiz > gi->playerHorizMax()) + if (PlayerList[nPlayer].horizon.horiz.asq16() > gi->playerHorizMax()) { - playerSetHoriz(&PlayerList[nPlayer].q16horiz, &PlayerList[nPlayer].horizTarget, gi->playerHorizMax()); + PlayerList[nPlayer].horizon.settarget(gi->playerHorizMax()); } - else if (PlayerList[nPlayer].q16horiz <= IntToFixed(100)) + else if (PlayerList[nPlayer].horizon.horiz.asq16() <= 0) { if (!(SectFlag[sprite[nPlayerSprite].sectnum] & kSectUnderwater)) { diff --git a/source/exhumed/src/player.h b/source/exhumed/src/player.h index 6f8ce7a49..ef99d6de5 100644 --- a/source/exhumed/src/player.h +++ b/source/exhumed/src/player.h @@ -19,6 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #pragma once #include "compat.h" +#include "gamecontrol.h" BEGIN_PS_NS @@ -71,13 +72,8 @@ struct Player short field_3C; short nRun; - fixed_t oq16angle, q16angle; - fixed_t oq16horiz, q16horiz; - fixed_t oq16look_ang, q16look_ang; - fixed_t oq16rotscrnang, q16rotscrnang; - fixed_t spin; - fixed_t angTarget, horizTarget; - double angAdjust, horizAdjust; + PlayerHorizon horizon; + PlayerAngle angle; vec3_t opos; }; diff --git a/source/exhumed/src/ps_input.h b/source/exhumed/src/ps_input.h index 0c7b4953a..f0fa8eb7a 100644 --- a/source/exhumed/src/ps_input.h +++ b/source/exhumed/src/ps_input.h @@ -37,8 +37,8 @@ struct PlayerInput int yVel; uint16_t buttons; short nTarget; - fixed_t nAngle; - fixed_t pan; + float nAngle; + float pan; int8_t nItem; ESyncBits actions; diff --git a/source/exhumed/src/sequence.cpp b/source/exhumed/src/sequence.cpp index a627f73a3..4899bb10a 100644 --- a/source/exhumed/src/sequence.cpp +++ b/source/exhumed/src/sequence.cpp @@ -379,7 +379,7 @@ void seq_DrawPilotLightSeq(double xOffset, double yOffset) double x = ChunkXpos[nFrameBase] + (160 + xOffset); double y = ChunkYpos[nFrameBase] + (100 + yOffset); - hud_drawsprite(x, y, 65536, fmod(-2 * FixedToFloat(PlayerList[nLocalPlayer].q16angle), kAngleMask + 1), nTile, 0, 0, 1); + hud_drawsprite(x, y, 65536, fmod(-2 * (PlayerList[nLocalPlayer].angle.ang.asbam() / (double)BAMUNIT), kAngleMask + 1), nTile, 0, 0, 1); nFrameBase++; } } diff --git a/source/exhumed/src/view.cpp b/source/exhumed/src/view.cpp index f293f7153..96b0195ae 100644 --- a/source/exhumed/src/view.cpp +++ b/source/exhumed/src/view.cpp @@ -48,8 +48,8 @@ short nQuake[kMaxPlayers] = { 0 }; short nChunkTotal = 0; -fixed_t nCameraa; -fixed_t nCamerapan; +binangle nCameraa; +fixedhoriz nCamerapan; short nViewTop; bool bCamera = false; @@ -235,9 +235,9 @@ void DrawView(double smoothRatio, bool sceneonly) int playerY; int playerZ; short nSector; - fixed_t nAngle; - fixed_t pan; - fixed_t q16rotscrnang; + binangle nAngle; + fixedhoriz pan; + lookangle rotscrnang; fixed_t dang = IntToFixed(1024); @@ -255,7 +255,7 @@ void DrawView(double smoothRatio, bool sceneonly) playerY = sprite[nSprite].y; playerZ = sprite[nSprite].z; nSector = sprite[nSprite].sectnum; - nAngle = IntToFixed(sprite[nSprite].ang); + nAngle = buildang(sprite[nSprite].ang); SetGreenPal(); @@ -282,20 +282,13 @@ void DrawView(double smoothRatio, bool sceneonly) if (!cl_syncinput) { - nAngle = PlayerList[nLocalPlayer].q16angle + PlayerList[nLocalPlayer].q16look_ang; - q16rotscrnang = PlayerList[nLocalPlayer].q16rotscrnang; + nAngle = PlayerList[nLocalPlayer].angle.sum(); + rotscrnang = PlayerList[nLocalPlayer].angle.rotscrnang; } else { - fixed_t oang, ang; - - oang = PlayerList[nLocalPlayer].oq16angle + PlayerList[nLocalPlayer].oq16look_ang; - ang = PlayerList[nLocalPlayer].q16angle + PlayerList[nLocalPlayer].q16look_ang; - nAngle = oang + xs_CRoundToInt(fmulscale16(((ang + dang - oang) & 0x7FFFFFF) - dang, smoothRatio)); - - oang = PlayerList[nLocalPlayer].oq16rotscrnang + PlayerList[nLocalPlayer].oq16rotscrnang; - ang = PlayerList[nLocalPlayer].q16rotscrnang + PlayerList[nLocalPlayer].q16rotscrnang; - q16rotscrnang = oang + xs_CRoundToInt(fmulscale16(((ang + dang - oang) & 0x7FFFFFF) - dang, smoothRatio)); + nAngle = PlayerList[nLocalPlayer].angle.interpolatedsum(smoothRatio); + rotscrnang = PlayerList[nLocalPlayer].angle.interpolatedrotscrn(smoothRatio); } if (!bCamera) @@ -304,7 +297,7 @@ void DrawView(double smoothRatio, bool sceneonly) sprite[nDoppleSprite[nLocalPlayer]].cstat |= CSTAT_SPRITE_INVISIBLE; } - renderSetRollAngle(FixedToFloat(q16rotscrnang)); + renderSetRollAngle(rotscrnang.asbam() / (double)BAMUNIT); } nCameraa = nAngle; @@ -313,7 +306,7 @@ void DrawView(double smoothRatio, bool sceneonly) { if (nSnakeCam >= 0 && !sceneonly) { - pan = IntToFixed(100); + pan = q16horiz(0); viewz = playerZ; } else @@ -323,18 +316,17 @@ void DrawView(double smoothRatio, bool sceneonly) if (!cl_syncinput) { - pan = PlayerList[nLocalPlayer].q16horiz; + pan = PlayerList[nLocalPlayer].horizon.sum(); } else { - pan = PlayerList[nLocalPlayer].oq16horiz + xs_CRoundToInt(fmulscale16(PlayerList[nLocalPlayer].q16horiz - PlayerList[nLocalPlayer].oq16horiz, smoothRatio)); + pan = PlayerList[nLocalPlayer].horizon.interpolatedsum(smoothRatio); } if (viewz > floorZ) viewz = floorZ; - nCameraa += IntToFixed((nQuake[nLocalPlayer] >> 7) % 31); - nCameraa &= 0x7FFFFFF; + nCameraa += buildang((nQuake[nLocalPlayer] >> 7) % 31); } } else @@ -344,11 +336,11 @@ void DrawView(double smoothRatio, bool sceneonly) -2000 * Sin(inita), 4, 0, 0, CLIPMASK1); - pan = IntToFixed(100); + pan = q16horiz(0); viewz = playerZ; } - pan = clamp(pan, gi->playerHorizMin(), gi->playerHorizMax()); + pan = q16horiz(clamp(pan.asq16(), gi->playerHorizMin(), gi->playerHorizMax())); nCamerax = playerX; nCameray = playerY; @@ -404,7 +396,7 @@ void DrawView(double smoothRatio, bool sceneonly) } } - renderDrawRoomsQ16(nCamerax, nCameray, viewz, nCameraa, nCamerapan, nSector); + renderDrawRoomsQ16(nCamerax, nCameray, viewz, nCameraa.asq16(), nCamerapan.asq16(), nSector); analyzesprites(); renderDrawMasks(); @@ -436,7 +428,7 @@ void DrawView(double smoothRatio, bool sceneonly) sprite[nPlayerSprite].cstat |= 0x8000; - int ang2 = FixedToInt(nCameraa) - sprite[nPlayerSprite].ang; + int ang2 = nCameraa.asbuild() - sprite[nPlayerSprite].ang; if (ang2 < 0) ang2 = -ang2; diff --git a/source/games/duke/src/actors.cpp b/source/games/duke/src/actors.cpp index ac8e1f05c..78c1153b0 100644 --- a/source/games/duke/src/actors.cpp +++ b/source/games/duke/src/actors.cpp @@ -203,7 +203,7 @@ void clearcamera(player_struct* ps) ps->posx = ps->oposx; ps->posy = ps->oposy; ps->posz = ps->oposz; - ps->q16ang = ps->oq16ang; + ps->angle.restore(); updatesector(ps->posx, ps->posy, &ps->cursectnum); setpal(ps); @@ -383,7 +383,7 @@ void movedummyplayers(void) { sprite[i].cstat = CSTAT_SPRITE_BLOCK_ALL; sprite[i].z = sector[sprite[i].sectnum].ceilingz + (27 << 8); - sprite[i].ang = ps[p].getang(); + sprite[i].ang = ps[p].angle.ang.asbuild(); if (hittype[i].temp_data[0] == 8) hittype[i].temp_data[0] = 0; else hittype[i].temp_data[0]++; @@ -429,7 +429,7 @@ void moveplayers(void) //Players s->x = p->oposx; s->y = p->oposy; hittype[i].bposz = s->z = p->oposz + PHEIGHT; - s->ang = p->getoang(); + s->ang = p->angle.oang.asbuild(); setsprite(i, s->x, s->y, s->z); } else @@ -468,7 +468,7 @@ void moveplayers(void) //Players if (p->actorsqu >= 0) { - playerAddAngle(&p->q16ang, &p->angAdjust, getincangle(p->getang(), getangle(sprite[p->actorsqu].x - p->posx, sprite[p->actorsqu].y - p->posy)) >> 2); + p->angle.addadjustment(FixedToFloat(getincangleq16(p->angle.ang.asq16(), gethiq16angle(sprite[p->actorsqu].x - p->posx, sprite[p->actorsqu].y - p->posy)) >> 2)); } if (s->extra > 0) @@ -491,10 +491,10 @@ void moveplayers(void) //Players if (p->wackedbyactor >= 0 && sprite[p->wackedbyactor].statnum < MAXSTATUS) { - playerAddAngle(&p->q16ang, &p->angAdjust, getincangle(p->getang(), getangle(sprite[p->wackedbyactor].x - p->posx, sprite[p->wackedbyactor].y - p->posy)) >> 1); + p->angle.addadjustment(FixedToFloat(getincangleq16(p->angle.ang.asq16(), gethiq16angle(sprite[p->wackedbyactor].x - p->posx, sprite[p->wackedbyactor].y - p->posy)) >> 1)); } } - s->ang = p->getang(); + s->ang = p->angle.ang.asbuild(); } } else @@ -532,7 +532,7 @@ void moveplayers(void) //Players if (s->extra < 8) { s->xvel = 128; - s->ang = p->getang(); + s->ang = p->angle.ang.asbuild(); s->extra++; //IFMOVING; // JBF 20040825: is really "if (ssp(i,CLIPMASK0)) ;" which is probably ssp(i, CLIPMASK0); // not the safest of ideas because a zealous optimiser probably sees @@ -540,7 +540,7 @@ void moveplayers(void) //Players } else { - s->ang = 2047 - (p->getang()); + s->ang = 2047 - (p->angle.ang.asbuild()); setsprite(i, s->x, s->y, s->z); } } @@ -748,7 +748,7 @@ void movecrane(int i, int crane) s->owner = -2; ps[p].on_crane = i; S_PlayActorSound(isRR() ? 390 : DUKE_GRUNT, ps[p].i); - playerSetAngle(&ps[p].q16ang, &ps[p].angTarget, s->ang + 1024); + ps[p].angle.addadjustment(s->ang + 1024); } else { @@ -834,7 +834,7 @@ void movecrane(int i, int crane) } else if (s->owner == -2) { - auto ang = ps[p].getang(); + auto ang = ps[p].angle.ang.asbuild(); ps[p].oposx = ps[p].posx; ps[p].oposy = ps[p].posy; ps[p].oposz = ps[p].posz; @@ -1521,7 +1521,7 @@ bool queball(int i, int pocket, int queball, int stripeball) // if(s->pal == 12) { - j = getincangle(ps[p].getang(), getangle(s->x - ps[p].posx, s->y - ps[p].posy)); + j = getincangle(ps[p].angle.ang.asbuild(), getangle(s->x - ps[p].posx, s->y - ps[p].posy)); if (j > -64 && j < 64 && PlayerInput(p, SB_OPEN)) if (ps[p].toggle_key_flag == 1) { @@ -1530,7 +1530,7 @@ bool queball(int i, int pocket, int queball, int stripeball) { if (sprite[a].picnum == queball || sprite[a].picnum == stripeball) { - j = getincangle(ps[p].getang(), getangle(sprite[a].x - ps[p].posx, sprite[a].y - ps[p].posy)); + j = getincangle(ps[p].angle.ang.asbuild(), getangle(sprite[a].x - ps[p].posx, sprite[a].y - ps[p].posy)); if (j > -64 && j < 64) { int l; @@ -1545,7 +1545,7 @@ bool queball(int i, int pocket, int queball, int stripeball) if (s->pal == 12) s->xvel = 164; else s->xvel = 140; - s->ang = ps[p].getang(); + s->ang = ps[p].angle.ang.asbuild(); ps[p].toggle_key_flag = 2; } } @@ -2698,7 +2698,7 @@ void handle_se00(int i, int LASERLINE) { if (ps[p].cursectnum == s->sectnum && ps[p].on_ground == 1) { - playerAddAngle(&ps[p].q16ang, &ps[p].angAdjust, l * q); + ps[p].angle.addadjustment(l * q); ps[p].posz += zchange; @@ -2890,7 +2890,7 @@ void handle_se14(int i, bool checkstat, int RPG, int JIBS6) ps[p].bobposx += m; ps[p].bobposy += x; - playerAddAngle(&ps[p].q16ang, &ps[p].angAdjust, q); + ps[p].angle.addadjustment(q); if (numplayers > 1) { diff --git a/source/games/duke/src/actors_d.cpp b/source/games/duke/src/actors_d.cpp index 2cfaa5791..8aa6a81b6 100644 --- a/source/games/duke/src/actors_d.cpp +++ b/source/games/duke/src/actors_d.cpp @@ -1852,7 +1852,7 @@ void moveweapons_d(void) if (s->picnum == SPIT) { - playerAddHoriz(&ps[p].q16horiz, &ps[p].horizAdjust, 32); + ps[p].horizon.addadjustment(32); ps[p].sync.actions |= SB_CENTERVIEW; if (ps[p].loogcnt == 0) @@ -2098,7 +2098,7 @@ void movetransports_d(void) sprite[ps[k].i].extra = 0; } - ps[p].setang(sprite[sprite[i].owner].ang); + ps[p].angle.ang = buildang(sprite[sprite[i].owner].ang); if (sprite[sprite[i].owner].owner != sprite[i].owner) { @@ -2454,7 +2454,7 @@ static void greenslime(int i) } else if (x < 1024 && ps[p].quick_kick == 0) { - j = getincangle(ps[p].getang(), getangle(sprite[i].x - ps[p].posx, sprite[i].y - ps[p].posy)); + j = getincangle(ps[p].angle.ang.asbuild(), getangle(sprite[i].x - ps[p].posx, sprite[i].y - ps[p].posy)); if (j > -128 && j < 128) ps[p].quick_kick = 14; } @@ -2476,7 +2476,7 @@ static void greenslime(int i) setsprite(i, s->x, s->y, s->z); - s->ang = ps[p].getang(); + s->ang = ps[p].angle.ang.asbuild(); if ((PlayerInput(p, SB_FIRE) || (ps[p].quick_kick > 0)) && sprite[ps[p].i].extra > 0) if (ps[p].quick_kick > 0 || (ps[p].curr_weapon != HANDREMOTE_WEAPON && ps[p].curr_weapon != HANDBOMB_WEAPON && ps[p].curr_weapon != TRIPBOMB_WEAPON && ps[p].ammo_amount[ps[p].curr_weapon] >= 0)) @@ -2504,7 +2504,7 @@ static void greenslime(int i) s->z = ps[p].posz + ps[p].pyoff - t[2] + (8 << 8); - s->z += (IntToFixed(100) - ps[p].getq16horiz()) >> 12; + s->z += -ps[p].horizon.horiz.asq16() >> 12; if (t[2] > 512) t[2] -= 128; @@ -2518,7 +2518,7 @@ static void greenslime(int i) ps[p].posx = ps[p].oposx; ps[p].posy = ps[p].oposy; ps[p].posz = ps[p].oposz; - ps[p].q16ang = ps[p].oq16ang; + ps[p].angle.restore(); updatesector(ps[p].posx, ps[p].posy, &ps[p].cursectnum); setpal(&ps[p]); @@ -2557,8 +2557,8 @@ static void greenslime(int i) s->xrepeat = 20 + (sintable[t[1] & 2047] >> 13); s->yrepeat = 15 + (sintable[t[1] & 2047] >> 13); - s->x = ps[p].posx + (sintable[(ps[p].getang() + 512) & 2047] >> 7); - s->y = ps[p].posy + (sintable[ps[p].getang() & 2047] >> 7); + s->x = ps[p].posx + (sintable[(ps[p].angle.ang.asbuild() + 512) & 2047] >> 7); + s->y = ps[p].posy + (sintable[ps[p].angle.ang.asbuild() & 2047] >> 7); return; } diff --git a/source/games/duke/src/actors_r.cpp b/source/games/duke/src/actors_r.cpp index 0e7abd482..2dd5934a5 100644 --- a/source/games/duke/src/actors_r.cpp +++ b/source/games/duke/src/actors_r.cpp @@ -1399,7 +1399,7 @@ void moveweapons_r(void) guts_r(s, RABBITJIBC, 2, myconnectindex); } - playerAddHoriz(&ps[p].q16horiz, &ps[p].horizAdjust, 32); + ps[p].horizon.addadjustment(32); ps[p].sync.actions |= SB_CENTERVIEW; if (ps[p].loogcnt == 0) @@ -1730,7 +1730,7 @@ void movetransports_r(void) sprite[ps[k].i].extra = 0; } - ps[p].setang(sprite[OW].ang); + ps[p].angle.ang = buildang(sprite[OW].ang); if (sprite[OW].owner != OW) { @@ -2633,7 +2633,7 @@ void rr_specialstats() nextj = nextspritestat[j]; if (sprite[j].picnum == RRTILE297) { - ps[p].setang(sprite[j].ang); + ps[p].angle.ang = buildang(sprite[j].ang); ps[p].bobposx = ps[p].oposx = ps[p].posx = sprite[j].x; ps[p].bobposy = ps[p].oposy = ps[p].posy = sprite[j].y; ps[p].oposz = ps[p].posz = sprite[j].z - (36 << 8); diff --git a/source/games/duke/src/animatesprites_d.cpp b/source/games/duke/src/animatesprites_d.cpp index d19e77a47..fdf1803ab 100644 --- a/source/games/duke/src/animatesprites_d.cpp +++ b/source/games/duke/src/animatesprites_d.cpp @@ -326,7 +326,7 @@ void animatesprites_d(int x,int y,int a,int smoothratio) t->x = omyx + mulscale16((int)(myx - omyx), smoothratio); t->y = omyy + mulscale16((int)(myy - omyy), smoothratio); t->z = omyz + mulscale16((int)(myz - omyz), smoothratio) + (40 << 8); - t->ang = FixedToInt(oq16myang + mulscale16((int)(((q16myang + IntToFixed(1024) - oq16myang) & 0x7FFFFFF) - IntToFixed(1024)), smoothratio)); + t->ang = myang.asbuild() + mulscale16((((myang.asbuild() + 1024 - myang.asbuild()) & 2047) - 1024), smoothratio); t->sectnum = mycursectnum; } } diff --git a/source/games/duke/src/animatesprites_r.cpp b/source/games/duke/src/animatesprites_r.cpp index a0cc0acfb..2e3cc3a49 100644 --- a/source/games/duke/src/animatesprites_r.cpp +++ b/source/games/duke/src/animatesprites_r.cpp @@ -373,9 +373,7 @@ void animatesprites_r(int x,int y,int a,int smoothratio) t->x = omyx + mulscale16((int)(myx - omyx), smoothratio); t->y = omyy + mulscale16((int)(myy - omyy), smoothratio); t->z = omyz + mulscale16((int)(myz - omyz), smoothratio) + (40 << 8); - int omyang = FixedToInt(oq16myang); - int myang = FixedToInt(q16myang); - t->ang = omyang + mulscale16((int)(((myang + 1024 - omyang) & 2047) - 1024), smoothratio); + t->ang = omyang.asbuild() + mulscale16((((myang.asbuild() + 1024 - omyang.asbuild()) & 2047) - 1024), smoothratio); t->sectnum = mycursectnum; } } diff --git a/source/games/duke/src/ccmds.cpp b/source/games/duke/src/ccmds.cpp index 50640206e..bd5c83bd1 100644 --- a/source/games/duke/src/ccmds.cpp +++ b/source/games/duke/src/ccmds.cpp @@ -114,12 +114,12 @@ static int osdcmd_warptocoords(CCmdFuncPtr parm) if (parm->numparms >= 4) { - p->oq16ang = p->q16ang = IntToFixed(atoi(parm->parms[3])); + p->angle.oang = p->angle.ang = buildang(atoi(parm->parms[3])); } if (parm->numparms == 5) { - p->oq16horiz = p->q16horiz = IntToFixed(atoi(parm->parms[4])); + p->horizon.ohoriz = p->horizon.horiz = buildhoriz(atoi(parm->parms[4])); } return CCMD_OK; diff --git a/source/games/duke/src/constants.h b/source/games/duke/src/constants.h index 4fd2b27b1..d9d7fa553 100644 --- a/source/games/duke/src/constants.h +++ b/source/games/duke/src/constants.h @@ -376,8 +376,6 @@ enum miscConstants FOURSLEIGHT = (1 << 8), MOVEFIFOSIZ =256, - HORIZ_MIN =-99, - HORIZ_MAX =299, AUTO_AIM_ANGLE =48, PHEIGHT_DUKE =(38<<8), PHEIGHT_RR =(40<<8), diff --git a/source/games/duke/src/duke3d.h b/source/games/duke/src/duke3d.h index e1652c96d..b6ebea8d9 100644 --- a/source/games/duke/src/duke3d.h +++ b/source/games/duke/src/duke3d.h @@ -18,7 +18,6 @@ #include "rts.h" #include "sounds.h" #include "soundefs.h" -#include "binaryangle.h" #include "gamestruct.h" #include "v_draw.h" diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index 1c3c7c8c3..dde5708eb 100644 --- a/source/games/duke/src/funct.h +++ b/source/games/duke/src/funct.h @@ -109,7 +109,7 @@ void footprints(int snum); int makepainsounds(int snum, int type); void playerCrouch(int snum); void playerJump(int snum, int fz, int cz); -void processq16avel(player_struct* p, fixed_t* q16avel); +void processavel(player_struct* p, float* avel); void checklook(int snum, ESyncBits actions); void playerCenterView(int snum); void playerLookUp(int snum, ESyncBits actions); @@ -241,8 +241,6 @@ void dointerpolations(int smoothratio); int* animateptr(int i); 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); void checkhardlanding(player_struct* p); diff --git a/source/games/duke/src/game_misc.cpp b/source/games/duke/src/game_misc.cpp index ec84d13ac..66c635aa0 100644 --- a/source/games/duke/src/game_misc.cpp +++ b/source/games/duke/src/game_misc.cpp @@ -62,7 +62,7 @@ FString GameInterface::GetCoordString() FString out; out.Format("pos= %d, %d, %d - angle = %2.3f - sector = %d, lotag = %d, hitag = %d", - ps[snum].posx, ps[snum].posy, ps[snum].posz, ps[snum].q16ang / 65536., ps[snum].cursectnum, + ps[snum].posx, ps[snum].posy, ps[snum].posz, ps[snum].angle.ang.asbuild(), ps[snum].cursectnum, sector[ps[snum].cursectnum].lotag, sector[ps[snum].cursectnum].hitag); return out; @@ -274,20 +274,20 @@ void drawoverlays(double smoothratio) { cposx = omyx + mulscale16(myx - omyx, smoothratio); cposy = omyy + mulscale16(myy - omyy, smoothratio); - cang = FixedToInt(oq16myang + mulscale16(((q16myang + IntToFixed(1024) - oq16myang) & 0x7FFFFFF) - IntToFixed(1024), smoothratio)); + cang = omyang.asbuild() + mulscale16(((myang.asbuild() + 1024 - omyang.asbuild()) & 2047) - 1024, smoothratio); } else { cposx = pp->oposx + mulscale16(pp->posx - pp->oposx, smoothratio); cposy = pp->oposy + mulscale16(pp->posy - pp->oposy, smoothratio); - cang = pp->getoang() + mulscale16(((pp->getang() + 1024 - pp->getoang()) & 2047) - 1024, smoothratio); + cang = pp->angle.oang.asbuild() + mulscale16(((pp->angle.ang.asbuild() + 1024 - pp->angle.oang.asbuild()) & 2047) - 1024, smoothratio); } } else { cposx = pp->oposx; cposy = pp->oposy; - cang = pp->getoang(); + cang = pp->angle.oang.asbuild(); } DrawOverheadMap(cposx, cposy, cang); restoreinterpolations(); @@ -300,7 +300,7 @@ void drawoverlays(double smoothratio) if (ps[myconnectindex].newowner == -1 && ud.camerasprite == -1) { - DrawCrosshair(TILE_CROSSHAIR, ps[screenpeek].last_extra, -getHalfLookAng(pp->oq16look_ang, pp->q16look_ang, cl_syncinput, smoothratio), pp->over_shoulder_on ? 2.5 : 0, isRR() ? 0.5 : 1); + DrawCrosshair(TILE_CROSSHAIR, ps[screenpeek].last_extra, -getHalfLookAng(pp->angle.olook_ang.asq16(), pp->angle.look_ang.asq16(), cl_syncinput, smoothratio), pp->over_shoulder_on ? 2.5 : 0, isRR() ? 0.5 : 1); } if (paused == 2) diff --git a/source/games/duke/src/gameexec.cpp b/source/games/duke/src/gameexec.cpp index 21e181084..9b1a337e7 100644 --- a/source/games/duke/src/gameexec.cpp +++ b/source/games/duke/src/gameexec.cpp @@ -330,16 +330,21 @@ void DoPlayer(bool bSet, int lVar1, int lLabelID, int lVar2, int sActor, int sPl break; case PLAYER_HORIZ: - if (bSet) playerSetHoriz(&ps[iPlayer].q16horiz, &ps[iPlayer].horizTarget, lValue); - else SetGameVarID((int)lVar2, FixedToInt(ps[iPlayer].q16horiz), sActor, sPlayer); + if (bSet) ps[iPlayer].horizon.settarget(lValue - 100); + else SetGameVarID((int)lVar2, ps[iPlayer].horizon.horiz.asbuild() + 100, sActor, sPlayer); break; case PLAYER_OHORIZ: - if (!bSet) SetGameVarID((int)lVar2, FixedToInt(ps[iPlayer].q16horiz), sActor, sPlayer); + if (!bSet) SetGameVarID((int)lVar2, ps[iPlayer].horizon.ohoriz.asbuild() + 100, sActor, sPlayer); + break; + + case PLAYER_HORIZOFF: + if (bSet) ps[iPlayer].horizon.horizoff = buildhoriz(lValue); + else SetGameVarID((int)lVar2, ps[iPlayer].horizon.horizoff.asbuild(), sActor, sPlayer); break; case PLAYER_OHORIZOFF: - if (!bSet) SetGameVarID((int)lVar2, FixedToInt(ps[iPlayer].q16horizoff), sActor, sPlayer); + if (!bSet) SetGameVarID((int)lVar2, ps[iPlayer].horizon.ohorizoff.asbuild(), sActor, sPlayer); break; case PLAYER_INVDISPTIME: @@ -452,12 +457,12 @@ void DoPlayer(bool bSet, int lVar1, int lLabelID, int lVar2, int sActor, int sPl break; case PLAYER_ANG: - if (bSet) playerSetAngle(&ps[iPlayer].q16ang, &ps[iPlayer].angTarget, lValue); - else SetGameVarID((int)lVar2, ps[iPlayer].getang(), sActor, sPlayer); + if (bSet) ps[iPlayer].angle.settarget(lValue); + else SetGameVarID((int)lVar2, ps[iPlayer].angle.ang.asbuild(), sActor, sPlayer); break; case PLAYER_OANG: - if (!bSet) SetGameVarID((int)lVar2, ps[iPlayer].getang(), sActor, sPlayer); + if (!bSet) SetGameVarID((int)lVar2, ps[iPlayer].angle.oang.asbuild(), sActor, sPlayer); break; case PLAYER_ANGVEL: // This no longer exists. @@ -470,8 +475,8 @@ void DoPlayer(bool bSet, int lVar1, int lLabelID, int lVar2, int sActor, int sPl break; case PLAYER_LOOK_ANG: - if (bSet) ps[iPlayer].q16look_ang = IntToFixed(lValue); - else SetGameVarID((int)lVar2, FixedToInt(ps[iPlayer].q16look_ang), sActor, sPlayer); + if (bSet) ps[iPlayer].angle.look_ang = buildlook(lValue); + else SetGameVarID((int)lVar2, ps[iPlayer].angle.look_ang.asbuild(), sActor, sPlayer); break; case PLAYER_LAST_EXTRA: @@ -520,11 +525,6 @@ void DoPlayer(bool bSet, int lVar1, int lLabelID, int lVar2, int sActor, int sPl else SetGameVarID((int)lVar2, ps[iPlayer].tipincs, sActor, sPlayer); break; - case PLAYER_HORIZOFF: - if (bSet) ps[iPlayer].q16horizoff = IntToFixed(lValue); - else SetGameVarID((int)lVar2, FixedToInt(ps[iPlayer].q16horizoff), sActor, sPlayer); - break; - case PLAYER_WANTWEAPONFIRE: if (bSet) ps[iPlayer].wantweaponfire = lValue; else SetGameVarID((int)lVar2, ps[iPlayer].wantweaponfire, sActor, sPlayer); @@ -636,8 +636,8 @@ void DoPlayer(bool bSet, int lVar1, int lLabelID, int lVar2, int sActor, int sPl break; case PLAYER_ONE_EIGHTY_COUNT: - if (bSet) ps[iPlayer].one_eighty_count = lValue; - else SetGameVarID((int)lVar2, ps[iPlayer].one_eighty_count, sActor, sPlayer); + if (bSet) ps[iPlayer].angle.spin = buildlook(lValue); + else SetGameVarID((int)lVar2, ps[iPlayer].angle.spin.asbuild(), sActor, sPlayer); break; case PLAYER_CHEAT_PHASE: @@ -696,8 +696,8 @@ void DoPlayer(bool bSet, int lVar1, int lLabelID, int lVar2, int sActor, int sPl break; case PLAYER_ROTSCRNANG: - if (bSet) ps[iPlayer].setrotscrnang(lValue); - else SetGameVarID((int)lVar2, FixedToInt(ps[iPlayer].q16rotscrnang), sActor, sPlayer); + if (bSet) ps[iPlayer].angle.rotscrnang = buildlook(lValue); + else SetGameVarID((int)lVar2, ps[iPlayer].angle.rotscrnang.asbuild(), sActor, sPlayer); break; case PLAYER_DEAD_FLAG: @@ -909,6 +909,18 @@ 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].sync.actions |= SB_CENTERVIEW; + } + else + { + auto center = ps[iPlayer].sync.actions & SB_CENTERVIEW ? xs_CRoundToInt(ps[iPlayer].horizon.horiz.asq16() * (9. / gi->playerHorizMax())) : 0; + SetGameVarID((int)lVar2, center, sActor, sPlayer); + } + break; + default: if (!bSet) SetGameVarID((int)lVar2, 0, sActor, sPlayer); break; @@ -2054,7 +2066,7 @@ int ParseState::parse(void) ps[g_p].posx = ps[g_p].oposx; ps[g_p].posy = ps[g_p].oposy; ps[g_p].posz = ps[g_p].oposz; - ps[g_p].q16ang = ps[g_p].oq16ang; + ps[g_p].angle.restore(); updatesector(ps[g_p].posx,ps[g_p].posy,&ps[g_p].cursectnum); setpal(&ps[g_p]); @@ -2246,10 +2258,10 @@ int ParseState::parse(void) ps[g_p].last_extra = g_sp->extra = max_player_health; ps[g_p].wantweaponfire = -1; - ps[g_p].sethoriz(100); + ps[g_p].horizon.ohoriz = ps[g_p].horizon.horiz = q16horiz(0); ps[g_p].on_crane = -1; ps[g_p].frag_ps = g_p; - ps[g_p].sethorizoff(0); + ps[g_p].horizon.ohorizoff = ps[g_p].horizon.horizoff = q16horiz(0); ps[g_p].opyoff = 0; ps[g_p].wackedbyactor = -1; ps[g_p].shield_amount = max_armour_amount; @@ -2259,7 +2271,7 @@ int ParseState::parse(void) ps[g_p].weapreccnt = 0; ps[g_p].ftq = 0; ps[g_p].posxv = ps[g_p].posyv = 0; - if (!isRR()) ps[g_p].setrotscrnang(0); + if (!isRR()) ps[g_p].angle.orotscrnang = ps[g_p].angle.rotscrnang = buildlook(0); ps[g_p].falling_counter = 0; @@ -2431,9 +2443,9 @@ int ParseState::parse(void) else if( (l& pfacing) ) { if (g_sp->picnum == TILE_APLAYER && ud.multimode > 1) - j = getincangle(ps[otherp].getang(), getangle(ps[g_p].posx - ps[otherp].posx, ps[g_p].posy - ps[otherp].posy)); + j = getincangle(ps[otherp].angle.ang.asbuild(), getangle(ps[g_p].posx - ps[otherp].posx, ps[g_p].posy - ps[otherp].posy)); else - j = getincangle(ps[g_p].getang(), getangle(g_sp->x - ps[g_p].posx, g_sp->y - ps[g_p].posy)); + j = getincangle(ps[g_p].angle.ang.asbuild(), getangle(g_sp->x - ps[g_p].posx, g_sp->y - ps[g_p].posy)); if( j > -128 && j < 128 ) j = 1; @@ -2457,8 +2469,8 @@ int ParseState::parse(void) case concmd_slapplayer: insptr++; 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; + ps[g_p].posxv -= sintable[(ps[g_p].angle.ang.asbuild() + 512) & 2047] << 7; + ps[g_p].posyv -= sintable[ps[g_p].angle.ang.asbuild() & 2047] << 7; return 0; case concmd_wackplayer: insptr++; @@ -2466,8 +2478,8 @@ int ParseState::parse(void) forceplayerangle(g_p); else { - ps[g_p].posxv -= sintable[(ps[g_p].getang() + 512) & 2047] << 10; - ps[g_p].posyv -= sintable[ps[g_p].getang() & 2047] << 10; + ps[g_p].posxv -= sintable[(ps[g_p].angle.ang.asbuild() + 512) & 2047] << 10; + ps[g_p].posyv -= sintable[ps[g_p].angle.ang.asbuild() & 2047] << 10; ps[g_p].jumping_counter = 767; ps[g_p].jumping_toggle = 1; } @@ -2828,7 +2840,7 @@ int ParseState::parse(void) case concmd_ifangdiffl: insptr++; - j = abs(getincangle(ps[g_p].getang(),g_sp->ang)); + j = abs(getincangle(ps[g_p].angle.ang.asbuild(),g_sp->ang)); parseifelse( j <= *insptr); break; @@ -3138,7 +3150,7 @@ int ParseState::parse(void) int i; insptr++; i = *(insptr++); // ID of def - SetGameVarID(i, ps[g_p].getang(), g_i, g_p); + SetGameVarID(i, ps[g_p].angle.ang.asbuild(), g_i, g_p); break; } case concmd_setplayerangle: @@ -3146,7 +3158,7 @@ int ParseState::parse(void) int i; insptr++; i = *(insptr++); // ID of def - ps[g_p].setang(GetGameVarID(i, g_i, g_p) & 2047); + ps[g_p].angle.ang = buildang(GetGameVarID(i, g_i, g_p) & 2047); break; } case concmd_getactorangle: diff --git a/source/games/duke/src/hudweapon_d.cpp b/source/games/duke/src/hudweapon_d.cpp index bfd4627dc..5ec059087 100644 --- a/source/games/duke/src/hudweapon_d.cpp +++ b/source/games/duke/src/hudweapon_d.cpp @@ -287,7 +287,7 @@ void displayweapon_d(int snum, double smoothratio) o = 0; horiz16th = get16thOfHoriz(snum, cl_syncinput, smoothratio); - look_anghalf = getHalfLookAng(p->oq16look_ang, p->q16look_ang, cl_syncinput, smoothratio); + look_anghalf = getHalfLookAng(p->angle.olook_ang.asq16(), p->angle.look_ang.asq16(), cl_syncinput, smoothratio); looking_arc = fabs(look_anghalf) / 4.5; weapon_sway = p->oweapon_sway + fmulscale16(p->weapon_sway - p->oweapon_sway, smoothratio); kickback_pic = p->okickback_pic + fmulscale16(*kb - p->okickback_pic, smoothratio); diff --git a/source/games/duke/src/hudweapon_r.cpp b/source/games/duke/src/hudweapon_r.cpp index 30fc5f02d..39558a0fd 100644 --- a/source/games/duke/src/hudweapon_r.cpp +++ b/source/games/duke/src/hudweapon_r.cpp @@ -124,7 +124,7 @@ void displayweapon_r(int snum, double smoothratio) o = 0; - look_anghalf = getHalfLookAng(p->oq16look_ang, p->q16look_ang, cl_syncinput, smoothratio); + look_anghalf = getHalfLookAng(p->angle.olook_ang.asq16(), p->angle.look_ang.asq16(), cl_syncinput, smoothratio); looking_arc = fabs(look_anghalf) / 4.5; weapon_sway = p->oweapon_sway + fmulscale16((p->weapon_sway - p->oweapon_sway), smoothratio); TiltStatus = !cl_syncinput ? p->TiltStatus : p->oTiltStatus + fmulscale16((p->TiltStatus - p->oTiltStatus), smoothratio); diff --git a/source/games/duke/src/inlines.h b/source/games/duke/src/inlines.h index d51800a40..851a0f3db 100644 --- a/source/games/duke/src/inlines.h +++ b/source/games/duke/src/inlines.h @@ -159,14 +159,14 @@ inline int PlayerInputForwardVel(int pl) return ps[pl].sync.fvel; } -inline fixed_t PlayerInputAngVel(int pl) +inline float PlayerInputAngVel(int pl) { - return ps[pl].sync.q16avel; + return ps[pl].sync.avel; } -inline fixed_t PlayerHorizon(int pl) +inline float PlayerHorizon(int pl) { - return ps[pl].sync.q16horz; + return ps[pl].sync.horz; } inline void clearfriction() @@ -190,17 +190,14 @@ inline bool playrunning() inline void backupplayer(player_struct* p) { backuppos(p); - backuplook(p); - backupview(p); + p->angle.backup(); + p->horizon.backup(); } // the weapon display code uses this. -inline double get16thOfHoriz(int snum, bool interpolate, double smoothratio) +inline double get16thOfHoriz(int const snum, bool const interpolate, double const smoothratio) { - struct player_struct *p = &ps[snum]; - fixed_t ohorz = p->oq16horiz - p->oq16horizoff; - fixed_t horz = p->q16horiz - p->q16horizoff; - return (!interpolate ? horz : ohorz + fmulscale16(horz - ohorz, smoothratio)) * (0.0625 / FRACUNIT); + return (!interpolate ? ps[snum].horizon.sum() : ps[snum].horizon.interpolatedsum(smoothratio)).asq16() * (0.0625 / FRACUNIT); } diff --git a/source/games/duke/src/input.cpp b/source/games/duke/src/input.cpp index 014c26449..0474ac738 100644 --- a/source/games/duke/src/input.cpp +++ b/source/games/duke/src/input.cpp @@ -286,7 +286,7 @@ void hud_input(int snum) EGS(p->cursectnum, p->posx, p->posy, - p->posz + (30 << 8), TILE_APLAYER, -64, 0, 0, p->getang(), 0, 0, -1, 10); + p->posz + (30 << 8), TILE_APLAYER, -64, 0, 0, p->angle.ang.asbuild(), 0, 0, -1, 10); hittype[i].temp_data[3] = hittype[i].temp_data[4] = 0; sprite[i].yvel = snum; sprite[i].extra = 0; @@ -477,7 +477,7 @@ void hud_input(int snum) } } - if (PlayerInput(snum, SB_TURNAROUND) && p->one_eighty_count == 0 && p->on_crane < 0) + if (PlayerInput(snum, SB_TURNAROUND) && p->angle.spin.asbam() == 0 && p->on_crane < 0) { SetGameVarID(g_iReturnVarID, 0, -1, snum); OnEvent(EVENT_TURNAROUND, -1, snum, -1); @@ -805,7 +805,7 @@ static void processVehicleInput(player_struct *p, ControlInfo* const hidInput, I turnvel *= clamp(turnspeed * turnspeed, 0., 1.); input.fvel = p->MotoSpeed; - input.q16avel = FloatToFixed(turnvel); + input.avel = turnvel; } //--------------------------------------------------------------------------- @@ -823,8 +823,8 @@ static void FinalizeInput(int playerNum, InputPacket& input, bool vehicle) { // neutralize all movement when blocked or in automap follow mode loc.fvel = loc.svel = 0; - loc.q16avel = loc.q16horz = 0; - input.q16avel = input.q16horz = 0; + loc.avel = loc.horz = 0; + input.avel = input.horz = 0; } else { @@ -846,26 +846,26 @@ static void FinalizeInput(int playerNum, InputPacket& input, bool vehicle) if (p->on_crane < 0 && p->newowner == -1) { - // input.q16avel already added to loc in processMovement() - loc.q16avel = clamp(loc.q16avel, IntToFixed(-MAXANGVEL), IntToFixed(MAXANGVEL)); - if (!cl_syncinput && input.q16avel) + // input.avel already added to loc in processMovement() + loc.avel = clamp(loc.avel, -MAXANGVEL, MAXANGVEL); + if (!cl_syncinput && input.avel) { - p->one_eighty_count = 0; + p->angle.spin = bamlook(0); } } else { - loc.q16avel = input.q16avel = 0; + loc.avel = input.avel = 0; } if (p->newowner == -1 && !(p->sync.actions & SB_CENTERVIEW)) { - // input.q16horz already added to loc in processMovement() - loc.q16horz = clamp(loc.q16horz, IntToFixed(-MAXHORIZVEL), IntToFixed(MAXHORIZVEL)); + // input.horz already added to loc in processMovement() + loc.horz = clamp(loc.horz, -MAXHORIZVEL, MAXHORIZVEL); } else { - loc.q16horz = input.q16horz = 0; + loc.horz = input.horz = 0; } } } @@ -921,27 +921,28 @@ void GameInterface::GetInput(InputPacket* packet, ControlInfo* const hidInput) { // Do these in the same order as the old code. calcviewpitch(p, scaleAdjust); - processq16avel(p, &input.q16avel); - applylook(&p->q16ang, &p->q16look_ang, &p->q16rotscrnang, &p->one_eighty_count, input.q16avel, &p->sync.actions, scaleAdjust, p->crouch_toggle || p->sync.actions & SB_CROUCH); - sethorizon(&p->q16horiz, input.q16horz, &p->sync.actions, scaleAdjust); + processavel(p, &input.avel); + applylook(&p->angle, input.avel, &p->sync.actions, scaleAdjust, p->crouch_toggle || p->sync.actions & SB_CROUCH); + sethorizon(&p->horizon.horiz, input.horz, &p->sync.actions, scaleAdjust); } - playerProcessHelpers(&p->q16ang, &p->angAdjust, &p->angTarget, &p->q16horiz, &p->horizAdjust, &p->horizTarget, scaleAdjust); + p->angle.processhelpers(scaleAdjust); + p->horizon.processhelpers(scaleAdjust); } if (packet) { auto const pPlayer = &ps[myconnectindex]; - auto const q16ang = FixedToInt(pPlayer->q16ang); + auto const ang = pPlayer->angle.ang.asbuild(); *packet = loc; auto fvel = loc.fvel; auto svel = loc.svel; - packet->fvel = mulscale9(fvel, sintable[(q16ang + 2560) & 2047]) + - mulscale9(svel, sintable[(q16ang + 2048) & 2047]) + + packet->fvel = mulscale9(fvel, sintable[(ang + 2560) & 2047]) + + mulscale9(svel, sintable[(ang + 2048) & 2047]) + pPlayer->fric.x; - packet->svel = mulscale9(fvel, sintable[(q16ang + 2048) & 2047]) + - mulscale9(svel, sintable[(q16ang + 1536) & 2047]) + + packet->svel = mulscale9(fvel, sintable[(ang + 2048) & 2047]) + + mulscale9(svel, sintable[(ang + 1536) & 2047]) + pPlayer->fric.y; loc = {}; } diff --git a/source/games/duke/src/player.cpp b/source/games/duke/src/player.cpp index 94115c9d3..e1d15b27f 100644 --- a/source/games/duke/src/player.cpp +++ b/source/games/duke/src/player.cpp @@ -91,30 +91,30 @@ void calcviewpitch(player_struct *p, double factor) { int psect = p->cursectnum; int psectlotag = sector[psect].lotag; - if (p->aim_mode == 0 && p->on_ground && psectlotag != ST_2_UNDERWATER && (sector[psect].floorstat & 2)) - { - int x = p->posx + (sintable[(p->getang() + 512) & 2047] >> 5); - int y = p->posy + (sintable[p->getang() & 2047] >> 5); - short tempsect = psect; - updatesector(x, y, &tempsect); + if (p->aim_mode == 0 && p->on_ground && psectlotag != ST_2_UNDERWATER && (sector[psect].floorstat & 2)) + { + int x = p->posx + (sintable[(p->angle.ang.asbuild() + 512) & 2047] >> 5); + int y = p->posy + (sintable[p->angle.ang.asbuild() & 2047] >> 5); + short tempsect = psect; + updatesector(x, y, &tempsect); - if (tempsect >= 0) - { - int k = getflorzofslope(psect, x, y); - if (psect == tempsect || abs(getflorzofslope(tempsect, x, y) - k) <= (4 << 8)) - p->addhorizoff(factor * mulscale16(p->truefz - k, 160)); - } - } - if (p->q16horizoff > 0) - { - p->addhorizoff(-factor * FixedToFloat((p->q16horizoff >> 3) + FRACUNIT)); - if (p->q16horizoff < 0) p->q16horizoff = 0; - } - else if (p->q16horizoff < 0) - { - p->addhorizoff(-factor * FixedToFloat((p->q16horizoff >> 3) + FRACUNIT)); - if (p->q16horizoff > 0) p->q16horizoff = 0; - } + if (tempsect >= 0) + { + int k = getflorzofslope(psect, x, y); + if (psect == tempsect || abs(getflorzofslope(tempsect, x, y) - k) <= (4 << 8)) + p->horizon.horizoff += q16horiz(FloatToFixed(factor * mulscale16(p->truefz - k, 160))); + } + } + if (p->horizon.horizoff.asq16() > 0) + { + p->horizon.horizoff += q16horiz(xs_CRoundToInt(-factor * ((p->horizon.horizoff.asq16() >> 3) + FRACUNIT))); + if (p->horizon.horizoff.asq16() < 0) p->horizon.horizoff = q16horiz(0); + } + else if (p->horizon.horizoff.asq16() < 0) + { + p->horizon.horizoff += q16horiz(xs_CRoundToInt(-factor * ((p->horizon.horizoff.asq16() >> 3) + FRACUNIT))); + if (p->horizon.horizoff.asq16() > 0) p->horizon.horizoff = q16horiz(0); + } } //--------------------------------------------------------------------------- @@ -164,10 +164,9 @@ void forceplayerangle(int snum) n = 128 - (krand() & 255); - playerAddHoriz(&p->q16horiz, &p->horizAdjust, 64); + p->horizon.addadjustment(64); p->sync.actions |= SB_CENTERVIEW; - p->setlookang(n >> 1); - p->setrotscrnang(n >> 1); + p->angle.rotscrnang = p->angle.look_ang = buildlook(n >> 1); } //--------------------------------------------------------------------------- @@ -264,7 +263,7 @@ int hitawall(struct player_struct* p, int* hitw) short sect, hs, hitw1; hitscan(p->posx, p->posy, p->posz, p->cursectnum, - sintable[(p->getang() + 512) & 2047], sintable[p->getang() & 2047], 0, §, &hitw1, &hs, &sx, &sy, &sz, CLIPMASK0); + sintable[(p->angle.ang.asbuild() + 512) & 2047], sintable[p->angle.ang.asbuild() & 2047], 0, §, &hitw1, &hs, &sx, &sy, &sz, CLIPMASK0); *hitw = hitw1; return (FindDistance2D(sx - p->posx, sy - p->posy)); @@ -375,7 +374,7 @@ int aim(spritetype* s, int aang) if (sdist > 512 && sdist < smax) { if (s->picnum == TILE_APLAYER) - a = (abs(scale(sp->z - s->z, 10, sdist) - (ps[s->yvel].gethorizsum() - 100)) < 100); + a = (abs(scale(sp->z - s->z, 10, sdist) - ps[s->yvel].horizon.sum().asbuild()) < 100); else a = 1; cans = cansee(sp->x, sp->y, sp->z - (32 << 8) + actorinfo[sp->picnum].aimoffset, sp->sectnum, s->x, s->y, s->z - (32 << 8), s->sectnum); @@ -406,7 +405,7 @@ void dokneeattack(int snum, int pi, const std::initializer_list & respawnli if (p->knee_incs > 0) { p->knee_incs++; - playerAddHoriz(&p->q16horiz, &p->horizAdjust, -48); + p->horizon.addadjustment(-48); p->sync.actions |= SB_CENTERVIEW; if (p->knee_incs > 15) { @@ -649,15 +648,14 @@ void playerisdead(int snum, int psectlotag, int fz, int cz) backupplayer(p); - p->sethoriz(100); - p->q16horizoff = 0; + p->horizon.horizoff = p->horizon.horiz = q16horiz(0); updatesector(p->posx, p->posy, &p->cursectnum); pushmove(&p->posx, &p->posy, &p->posz, &p->cursectnum, 128L, (4L << 8), (20L << 8), CLIPMASK0); if (fz > cz + (16 << 8) && s->pal != 1) - p->setrotscrnang((p->dead_flag + ((fz + p->posz) >> 7)) & 2047); + p->angle.rotscrnang = buildlook(p->dead_flag + ((fz + p->posz) >> 7)); p->on_warping_sector = 0; @@ -768,16 +766,16 @@ void apply_seasick(player_struct* p, double factor) if (p->SeaSick < 250) { if (p->SeaSick >= 180) - p->addrotscrnang(24 * factor); + p->angle.rotscrnang += bamlook(xs_CRoundToUInt(24 * factor * BAMUNIT)); else if (p->SeaSick >= 130) - p->addrotscrnang(-24 * factor); + p->angle.rotscrnang -= bamlook(xs_CRoundToUInt(24 * factor * BAMUNIT)); else if (p->SeaSick >= 70) - p->addrotscrnang(24 * factor); + p->angle.rotscrnang += bamlook(xs_CRoundToUInt(24 * factor * BAMUNIT)); else if (p->SeaSick >= 20) - p->addrotscrnang(-24 * factor); + p->angle.rotscrnang -= bamlook(xs_CRoundToUInt(24 * factor * BAMUNIT)); } if (p->SeaSick < 250) - p->addlookang(((krand() & 255) - 128) * factor); + p->angle.look_ang = bamlook(xs_CRoundToUInt(((krand() & 255) - 128) * factor * BAMUNIT)); } } @@ -787,16 +785,16 @@ void apply_seasick(player_struct* p, double factor) // //--------------------------------------------------------------------------- -void processq16avel(player_struct* p, fixed_t* q16avel) +void processavel(player_struct* p, float* avel) { // Taken from processinput() for use with applying look while cl_syncinput is 0. if (p->psectlotag == ST_2_UNDERWATER) { - *q16avel = (*q16avel - (*q16avel >> 3)) * sgn(TICSPERFRAME); + *avel = (*avel - (*avel / 8.f)) * sgn(TICSPERFRAME); } else { - *q16avel = *q16avel * sgn(TICSPERFRAME); + *avel = *avel * sgn(TICSPERFRAME); } } @@ -831,31 +829,6 @@ void backuppos(player_struct* p, bool noclipping) // //--------------------------------------------------------------------------- -void backuplook(player_struct* p) -{ - p->oq16ang = p->q16ang; - p->oq16look_ang = p->q16look_ang; - p->oq16rotscrnang = p->q16rotscrnang; -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - -void backupview(player_struct* p) -{ - p->oq16horiz = p->q16horiz; - p->oq16horizoff = p->q16horizoff; -} - -//--------------------------------------------------------------------------- -// -// -// -//--------------------------------------------------------------------------- - void backupweapon(player_struct* p) { p->oweapon_sway = p->weapon_sway; @@ -873,8 +846,8 @@ void backupweapon(player_struct* p) void resetinputhelpers(player_struct* p) { - p->horizAdjust = 0; - p->angAdjust = 0; + p->horizon.resetadjustment(); + p->angle.resetadjustment(); } //--------------------------------------------------------------------------- @@ -887,7 +860,7 @@ void checkhardlanding(player_struct* p) { if (p->hard_landing > 0) { - playerAddHoriz(&p->q16horiz, &p->horizAdjust, -(p->hard_landing << 4)); + p->horizon.addadjustment(-(p->hard_landing << 4)); p->hard_landing--; } } @@ -945,7 +918,7 @@ void checklook(int snum, ESyncBits actions) actions &= ~SB_LOOK_RIGHT; } } - backuplook(p); + p->angle.backup(); } //--------------------------------------------------------------------------- @@ -1094,7 +1067,7 @@ bool view(struct player_struct* pp, int* vx, int* vy, int* vz, short* vsectnum, nx = (sintable[(ang + 1536) & 2047] >> 4); ny = (sintable[(ang + 1024) & 2047] >> 4); - nz = (q16horiz - IntToFixed(100)) >> 9; + nz = q16horiz >> 9; sp = &sprite[pp->i]; diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index 4112bca6b..8001f9f03 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -118,7 +118,7 @@ void shoot_d(int i, int atwith) sx = ps[p].posx; sy = ps[p].posy; sz = ps[p].posz + ps[p].pyoff + (4 << 8); - sa = ps[p].getang(); + sa = ps[p].angle.ang.asbuild(); ps[p].crack_time = CRACK_TIME; @@ -166,7 +166,7 @@ void shoot_d(int i, int atwith) } else { - zvel = xs_CRoundToInt((IntToFixed(100) - ps[p].getq16horizsum()) * (98. / FRACUNIT)); + zvel = -mulscale16(ps[p].horizon.sum().asq16(), 98); sx += sintable[(sa + 860) & 0x7FF] / 448; sy += sintable[(sa + 348) & 0x7FF] / 448; sz += (3 << 8); @@ -224,7 +224,7 @@ void shoot_d(int i, int atwith) } else { - zvel = xs_CRoundToInt((IntToFixed(100) - ps[p].getq16horizsum()) * (81. / FRACUNIT)); + zvel = -mulscale16(ps[p].horizon.sum().asq16(), 81); if (sprite[ps[p].i].xvel != 0) vel = (int)((((512 - (1024 - abs(abs(getangle(sx - ps[p].oposx, sy - ps[p].oposy) - sa) - 1024))) @@ -292,7 +292,7 @@ void shoot_d(int i, int atwith) { if (p >= 0) { - zvel = (IntToFixed(100) - ps[p].getq16horizsum()) >> 11; + zvel = -ps[p].horizon.sum().asq16() >> 11; sz += (6 << 8); sa += 15; } @@ -403,7 +403,7 @@ void shoot_d(int i, int atwith) j = fi.spawn(ps[p].i, WATERSPLASH2); sprite[j].x = hitx; sprite[j].y = hity; - sprite[j].ang = ps[p].getang(); // Total tweek + sprite[j].ang = ps[p].angle.ang.asbuild(); // Total tweek sprite[j].xvel = 32; ssp(i, CLIPMASK0); sprite[j].xvel = 0; @@ -464,14 +464,14 @@ void shoot_d(int i, int atwith) if (j == -1) { // no target - zvel = (IntToFixed(100) - ps[p].getq16horizsum()) >> 11; + zvel = -ps[p].horizon.sum().asq16() >> 11; } zvel += (zRange / 2) - (krand() & (zRange - 1)); } else if (j == -1) { sa += 16 - (krand() & 31); - zvel = (IntToFixed(100) - ps[p].getq16horizsum()) >> 11; + zvel = -ps[p].horizon.sum().asq16() >> 11; zvel += 128 - (krand() & 255); } @@ -681,7 +681,7 @@ void shoot_d(int i, int atwith) sa = getangle(sprite[j].x - sx, sprite[j].y - sy); } else - zvel = xs_CRoundToInt((IntToFixed(100) - ps[p].getq16horizsum()) * (98. / FRACUNIT)); + zvel = -mulscale16(ps[p].horizon.sum().asq16(), 98); } else { @@ -769,7 +769,7 @@ void shoot_d(int i, int atwith) if (sprite[j].picnum != RECON) sa = getangle(sprite[j].x - sx, sprite[j].y - sy); } - else zvel = xs_CRoundToInt((IntToFixed(100) - ps[p].getq16horizsum()) * (81. / FRACUNIT)); + else zvel = -mulscale16(ps[p].horizon.sum().asq16(), 81); if (atwith == RPG) S_PlayActorSound(RPG_SHOOT, i); @@ -914,7 +914,7 @@ void shoot_d(int i, int atwith) case HANDHOLDINGLASER: if (p >= 0) - zvel = (IntToFixed(100) - ps[p].getq16horizsum()) >> 11; + zvel = -ps[p].horizon.sum().asq16() >> 11; else zvel = 0; hitscan(sx, sy, sz - ps[p].pyoff, sect, @@ -1015,7 +1015,7 @@ void shoot_d(int i, int atwith) else { sa += 16 - (krand() & 31); - zvel = (IntToFixed(100) - ps[p].getq16horizsum()) >> 11; + zvel = -ps[p].horizon.sum().asq16() >> 11; zvel += 128 - (krand() & 255); } @@ -1090,7 +1090,7 @@ void shoot_d(int i, int atwith) zvel = ((sprite[j].z - sz - dal - (4 << 8)) * 768) / (ldist(&sprite[ps[p].i], &sprite[j])); sa = getangle(sprite[j].x - sx, sprite[j].y - sy); } - else zvel = xs_CRoundToInt((IntToFixed(100) - ps[p].getq16horizsum()) * (98. / FRACUNIT)); + else zvel = -mulscale16(ps[p].horizon.sum().asq16(), 98); } else if (s->statnum != 3) { @@ -1915,9 +1915,9 @@ static void underwater(int snum, ESyncBits actions, int psect, int fz, int cz) { j = fi.spawn(pi, WATERBUBBLE); sprite[j].x += - sintable[(p->getang() + 512 + 64 - (global_random & 128)) & 2047] >> 6; + sintable[(p->angle.ang.asbuild() + 512 + 64 - (global_random & 128)) & 2047] >> 6; sprite[j].y += - sintable[(p->getang() + 64 - (global_random & 128)) & 2047] >> 6; + sintable[(p->angle.ang.asbuild() + 64 - (global_random & 128)) & 2047] >> 6; sprite[j].xrepeat = 3; sprite[j].yrepeat = 2; sprite[j].z = p->posz + (8 << 8); @@ -1939,8 +1939,8 @@ int operateTripbomb(int snum) short sect, hw, hitsp; hitscan(p->posx, p->posy, p->posz, - p->cursectnum, sintable[(p->getang() + 512) & 2047], - sintable[p->getang() & 2047], (IntToFixed(100) - p->getq16horizsum()) >> 11, + p->cursectnum, sintable[(p->angle.ang.asbuild() + 512) & 2047], + sintable[p->angle.ang.asbuild() & 2047], -p->horizon.sum().asq16() >> 11, §, &hw, &hitsp, &sx, &sy, &sz, CLIPMASK1); if (sect < 0 || hitsp >= 0) @@ -2122,19 +2122,19 @@ static void operateweapon(int snum, ESyncBits actions, int psect) if (p->on_ground && (actions & SB_CROUCH)) { k = 15; - i = xs_CRoundToInt((p->getq16horizsum() - IntToFixed(100)) * (20. / FRACUNIT)); + i = mulscale16(p->horizon.sum().asq16(), 20); } else { k = 140; - i = -512 - xs_CRoundToInt((p->getq16horizsum() - IntToFixed(100)) * (20. / FRACUNIT)); + i = -512 - mulscale16(p->horizon.sum().asq16(), 20); } j = EGS(p->cursectnum, - p->posx + (sintable[(p->getang() + 512) & 2047] >> 6), - p->posy + (sintable[p->getang() & 2047] >> 6), + p->posx + (sintable[(p->angle.ang.asbuild() + 512) & 2047] >> 6), + p->posy + (sintable[p->angle.ang.asbuild() & 2047] >> 6), p->posz, HEAVYHBOMB, -16, 9, 9, - p->getang(), (k + (p->hbomb_hold_delay << 5)), i, pi, 1); + p->angle.ang.asbuild(), (k + (p->hbomb_hold_delay << 5)), i, pi, 1); if (isNam()) { @@ -2707,7 +2707,7 @@ void processinput_d(int snum) if (cl_syncinput) { - backupview(p); + p->horizon.backup(); calcviewpitch(p, 1); } @@ -2839,8 +2839,8 @@ void processinput_d(int snum) //ENGINE calculates angvel for you // may still be needed later for demo recording - processq16avel(p, &sb_avel); - applylook(&p->q16ang, &p->q16look_ang, &p->q16rotscrnang, &p->one_eighty_count, sb_avel, &p->sync.actions, 1, p->crouch_toggle || actions & SB_CROUCH); + processavel(p, &sb_avel); + applylook(&p->angle, sb_avel, &p->sync.actions, 1, p->crouch_toggle || actions & SB_CROUCH); } if (p->spritebridge == 0) @@ -3072,7 +3072,7 @@ HORIZONLY: if (cl_syncinput) { - sethorizon(&p->q16horiz, PlayerHorizon(snum), &p->sync.actions, 1); + sethorizon(&p->horizon.horiz, PlayerHorizon(snum), &p->sync.actions, 1); } checkhardlanding(p); diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index b558f1127..0b688a2cc 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -105,7 +105,7 @@ void shoot_r(int i, int atwith) sx = ps[p].posx; sy = ps[p].posy; sz = ps[p].posz + ps[p].pyoff + (4 << 8); - sa = ps[p].getang(); + sa = ps[p].angle.ang.asbuild(); if (isRRRA()) ps[p].crack_time = CRACK_TIME; } @@ -154,7 +154,7 @@ void shoot_r(int i, int atwith) { if (p >= 0) { - zvel = (IntToFixed(100) - ps[p].getq16horizsum()) >> 11; + zvel = -ps[p].horizon.sum().asq16() >> 11; sz += (6 << 8); sa += 15; } @@ -302,7 +302,7 @@ void shoot_r(int i, int atwith) j = fi.spawn(ps[p].i, WATERSPLASH2); sprite[j].x = hitx; sprite[j].y = hity; - sprite[j].ang = ps[p].getang(); // Total tweek + sprite[j].ang = ps[p].angle.ang.asbuild(); // Total tweek sprite[j].xvel = 32; ssp(i, 0); sprite[j].xvel = 0; @@ -333,7 +333,7 @@ void shoot_r(int i, int atwith) if (j == -1) { sa += 16 - (krand() & 31); - zvel = (IntToFixed(100) - ps[p].getq16horizsum()) >> 11; + zvel = -ps[p].horizon.sum().asq16() >> 11; zvel += 128 - (krand() & 255); } } @@ -343,7 +343,7 @@ void shoot_r(int i, int atwith) sa += 64 - (krand() & 127); else sa += 16 - (krand() & 31); - if (j == -1) zvel = (IntToFixed(100) - ps[p].getq16horizsum()) >> 11; + if (j == -1) zvel = -ps[p].horizon.sum().asq16() >> 11; zvel += 128 - (krand() & 255); } sz -= (2 << 8); @@ -602,7 +602,7 @@ void shoot_r(int i, int atwith) sa = getangle(sprite[j].x - sx, sprite[j].y - sy); } else - zvel = xs_CRoundToInt((IntToFixed(100) - ps[p].getq16horizsum()) * (98. / FRACUNIT)); + zvel = -mulscale16(ps[p].horizon.sum().asq16(), 98); } else { @@ -693,7 +693,7 @@ void shoot_r(int i, int atwith) { sx += sintable[(s->ang + 512 + 160) & 2047] >> 7; sy += sintable[(s->ang + 160) & 2047] >> 7; - zvel = xs_CRoundToInt((IntToFixed(100) - ps[p].getq16horizsum()) * (98. / FRACUNIT)); + zvel = -mulscale16(ps[p].horizon.sum().asq16(), 98); } } else @@ -804,7 +804,7 @@ void shoot_r(int i, int atwith) if (sprite[j].picnum != RECON) sa = getangle(sprite[j].x - sx, sprite[j].y - sy); } - else zvel = xs_CRoundToInt((IntToFixed(100) - ps[p].getq16horizsum()) * (81. / FRACUNIT)); + else zvel = -mulscale16(ps[p].horizon.sum().asq16(), 81); if (atwith == RPG) S_PlayActorSound(RPG_SHOOT, i); else if (isRRRA()) @@ -1275,8 +1275,8 @@ int doincrements_r(struct player_struct* p) { p->noise_radius = 16384; madenoise(screenpeek); - p->posxv += sintable[(p->getang() + 512) & 2047] << 4; - p->posyv += sintable[p->getang() & 2047] << 4; + p->posxv += sintable[(p->angle.ang.asbuild() + 512) & 2047] << 4; + p->posyv += sintable[p->angle.ang.asbuild() & 2047] << 4; } p->eat -= 4; if (p->eat < 0) @@ -1472,11 +1472,11 @@ void checkweapons_r(struct player_struct* p) if (p->OnMotorcycle && numplayers > 1) { j = fi.spawn(p->i, 7220); - sprite[j].ang = p->getang(); + sprite[j].ang = p->angle.ang.asbuild(); sprite[j].owner = p->ammo_amount[MOTORCYCLE_WEAPON]; p->OnMotorcycle = 0; p->gotweapon.Clear(MOTORCYCLE_WEAPON); - p->sethoriz(100); + p->horizon.horiz = q16horiz(0); p->moto_do_bump = 0; p->MotoSpeed = 0; p->TiltStatus = 0; @@ -1488,11 +1488,11 @@ void checkweapons_r(struct player_struct* p) else if (p->OnBoat && numplayers > 1) { j = fi.spawn(p->i, 7233); - sprite[j].ang = p->getang(); + sprite[j].ang = p->angle.ang.asbuild(); sprite[j].owner = p->ammo_amount[BOAT_WEAPON]; p->OnBoat = 0; p->gotweapon.Clear(BOAT_WEAPON); - p->sethoriz(100); + p->horizon.horiz = q16horiz(0); p->moto_do_bump = 0; p->MotoSpeed = 0; p->TiltStatus = 0; @@ -1762,14 +1762,14 @@ static void onMotorcycle(int snum, ESyncBits &actions) } if (horiz != 0) { - playerAddHoriz(&p->q16horiz, &p->horizAdjust, horiz - FixedToFloat(p->q16horiz)); + p->horizon.addadjustment(horiz - FixedToFloat(p->horizon.horiz.asq16())); } if (p->MotoSpeed >= 20 && p->on_ground == 1 && (var74 || var7c)) { short var8c, var90, var94, var98; var8c = p->MotoSpeed; - var90 = p->getang(); + var90 = p->angle.ang.asbuild(); if (var74) var94 = -10; else @@ -1817,13 +1817,13 @@ static void onMotorcycle(int snum, ESyncBits &actions) ang = var98 >> 7; } } - playerAddAngle(&p->q16ang, &p->angAdjust, FixedToFloat(getincangleq16(p->q16ang, IntToFixed(var90 - ang)))); + p->angle.addadjustment(FixedToFloat(getincangleq16(p->angle.ang.asq16(), IntToFixed(var90 - ang)))); } else if (p->MotoSpeed >= 20 && p->on_ground == 1 && (p->moto_on_mud || p->moto_on_oil)) { short var9c, vara0, vara4=0; var9c = p->MotoSpeed; - vara0 = p->getang(); + vara0 = p->angle.ang.asbuild(); var84 = krand() & 1; if (var84 == 0) vara4 = -10; @@ -2091,14 +2091,14 @@ static void onBoat(int snum, ESyncBits &actions) } if (horiz != 0) { - playerAddHoriz(&p->q16horiz, &p->horizAdjust, horiz - FixedToFloat(p->q16horiz)); + p->horizon.addadjustment(horiz - FixedToFloat(p->horizon.horiz.asq16())); } if (p->MotoSpeed > 0 && p->on_ground == 1 && (varbc || varc4)) { short vard4, vard8, vardc, vare0; vard4 = p->MotoSpeed; - vard8 = p->getang(); + vard8 = p->angle.ang.asbuild(); if (varbc) vardc = -10; else @@ -2121,7 +2121,7 @@ static void onBoat(int snum, ESyncBits &actions) p->posyv += (vard4 >> 7) * (sintable[(vardc * -51 + vard8) & 2047] << 4); ang = vare0 >> 6; } - playerAddAngle(&p->q16ang, &p->angAdjust, FixedToFloat(getincangleq16(p->q16ang, IntToFixed(vard8 - ang)))); + p->angle.addadjustment(FixedToFloat(getincangleq16(p->angle.ang.asq16(), IntToFixed(vard8 - ang)))); } if (p->NotOnWater) if (p->MotoSpeed > 50) @@ -2427,9 +2427,9 @@ static void underwater(int snum, ESyncBits actions, int psect, int fz, int cz) { j = fi.spawn(pi, WATERBUBBLE); sprite[j].x += - sintable[(p->getang() + 512 + 64 - (global_random & 128) + 128) & 2047] >> 6; + sintable[(p->angle.ang.asbuild() + 512 + 64 - (global_random & 128) + 128) & 2047] >> 6; sprite[j].y += - sintable[(p->getang() + 64 - (global_random & 128) + 128) & 2047] >> 6; + sintable[(p->angle.ang.asbuild() + 64 - (global_random & 128) + 128) & 2047] >> 6; sprite[j].xrepeat = 3; sprite[j].yrepeat = 2; sprite[j].z = p->posz + (8 << 8); @@ -2454,7 +2454,7 @@ void onMotorcycleMove(int snum, int psect, int j) var104 = 0; 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); + var10c = abs(p->angle.ang.asbuild() - var108); int ang; switch (krand() & 1) { @@ -2465,7 +2465,7 @@ void onMotorcycleMove(int snum, int psect, int j) ang = -(p->MotoSpeed >> 1); break; } - playerAddAngle(&p->q16ang, &p->angAdjust, ang); + p->angle.addadjustment(ang); if (var10c >= 441 && var10c <= 581) { var104 = (p->MotoSpeed * p->MotoSpeed) >> 8; @@ -2521,7 +2521,7 @@ void onBoatMove(int snum, int psect, int j) short var114, var118; 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); + var118 = abs(p->angle.ang.asbuild() - var114); int ang; switch (krand() & 1) { @@ -2532,7 +2532,7 @@ void onBoatMove(int snum, int psect, int j) ang = -(p->MotoSpeed >> 2); break; } - playerAddAngle(&p->q16ang, &p->angAdjust, ang); + p->angle.addadjustment(ang); if (var118 >= 441 && var118 <= 581) { p->MotoSpeed = ((p->MotoSpeed >> 1) + (p->MotoSpeed >> 2)) >> 2; @@ -2580,8 +2580,8 @@ void onMotorcycleHit(int snum, int var60) { if (numplayers == 1) { - fi.movesprite(var60, sintable[int(p->TiltStatus * 20 + p->getang() + 512) & 2047] >> 8, - sintable[int(p->TiltStatus * 20 + p->getang()) & 2047] >> 8, sprite[var60].zvel, CLIPMASK0); + fi.movesprite(var60, sintable[int(p->TiltStatus * 20 + p->angle.ang.asbuild() + 512) & 2047] >> 8, + sintable[int(p->TiltStatus * 20 + p->angle.ang.asbuild()) & 2047] >> 8, sprite[var60].zvel, CLIPMASK0); } } else @@ -2637,8 +2637,8 @@ void onBoatHit(int snum, int var60) { if (numplayers == 1) { - fi.movesprite(var60, sintable[int(p->TiltStatus * 20 + p->getang() + 512) & 2047] >> 9, - sintable[int(p->TiltStatus * 20 + p->getang()) & 2047] >> 9, sprite[var60].zvel, CLIPMASK0); + fi.movesprite(var60, sintable[int(p->TiltStatus * 20 + p->angle.ang.asbuild() + 512) & 2047] >> 9, + sintable[int(p->TiltStatus * 20 + p->angle.ang.asbuild()) & 2047] >> 9, sprite[var60].zvel, CLIPMASK0); } } else @@ -2843,19 +2843,19 @@ static void operateweapon(int snum, ESyncBits actions, int psect) if (p->on_ground && (actions & SB_CROUCH) && !p->OnMotorcycle) { k = 15; - i = xs_CRoundToInt((p->getq16horizsum() - IntToFixed(100)) * (20. / FRACUNIT)); + i = -mulscale16(p->horizon.sum().asq16(), 20); } else { k = 140; - i = -512 - xs_CRoundToInt((p->getq16horizsum() - IntToFixed(100)) * (20. / FRACUNIT)); + i = -512 - -mulscale16(p->horizon.sum().asq16(), 20); } j = EGS(p->cursectnum, - p->posx + (sintable[(p->getang() + 512) & 2047] >> 6), - p->posy + (sintable[p->getang() & 2047] >> 6), + p->posx + (sintable[(p->angle.ang.asbuild() + 512) & 2047] >> 6), + p->posy + (sintable[p->angle.ang.asbuild() & 2047] >> 6), p->posz, HEAVYHBOMB, -16, 9, 9, - p->getang(), (k + (p->hbomb_hold_delay << 5)) * 2, i, pi, 1); + p->angle.ang.asbuild(), (k + (p->hbomb_hold_delay << 5)) * 2, i, pi, 1); if (k == 15) { @@ -2904,8 +2904,8 @@ static void operateweapon(int snum, ESyncBits actions, int psect) p->visibility = 0; if (psectlotag != 857) { - p->posxv -= sintable[(p->getang() + 512) & 2047] << 4; - p->posyv -= sintable[p->getang() & 2047] << 4; + p->posxv -= sintable[(p->angle.ang.asbuild() + 512) & 2047] << 4; + p->posyv -= sintable[p->angle.ang.asbuild() & 2047] << 4; } } else if (p->kickback_pic == 2) @@ -3004,14 +3004,14 @@ static void operateweapon(int snum, ESyncBits actions, int psect) if (psectlotag != 857) { - p->posxv -= sintable[(p->getang() + 512) & 2047] << 5; - p->posyv -= sintable[p->getang() & 2047] << 5; + p->posxv -= sintable[(p->angle.ang.asbuild() + 512) & 2047] << 5; + p->posyv -= sintable[p->angle.ang.asbuild() & 2047] << 5; } } else if (psectlotag != 857) { - p->posxv -= sintable[(p->getang() + 512) & 2047] << 4; - p->posyv -= sintable[p->getang() & 2047] << 4; + p->posxv -= sintable[(p->angle.ang.asbuild() + 512) & 2047] << 4; + p->posyv -= sintable[p->angle.ang.asbuild() & 2047] << 4; } } @@ -3066,7 +3066,7 @@ static void operateweapon(int snum, ESyncBits actions, int psect) case RIFLEGUN_WEAPON: p->kickback_pic++; - playerAddHoriz(&p->q16horiz, &p->horizAdjust, 1); + p->horizon.addadjustment(1); p->recoil++; if (p->kickback_pic <= 12) @@ -3095,8 +3095,8 @@ static void operateweapon(int snum, ESyncBits actions, int psect) if (psectlotag != 857) { - p->posxv -= sintable[(p->getang() + 512) & 2047] << 4; - p->posyv -= sintable[p->getang() & 2047] << 4; + p->posxv -= sintable[(p->angle.ang.asbuild() + 512) & 2047] << 4; + p->posyv -= sintable[p->angle.ang.asbuild() & 2047] << 4; } checkavailweapon(p); @@ -3156,11 +3156,11 @@ static void operateweapon(int snum, ESyncBits actions, int psect) } if (p->kickback_pic == 2) { - playerAddAngle(&p->q16ang, &p->angAdjust, 16); + p->angle.addadjustment(16); } else if (p->kickback_pic == 4) { - playerAddAngle(&p->q16ang, &p->angAdjust, -16); + p->angle.addadjustment(-16); } if (p->kickback_pic > 4) p->kickback_pic = 1; @@ -3186,11 +3186,11 @@ static void operateweapon(int snum, ESyncBits actions, int psect) } if (p->kickback_pic == 2) { - playerAddAngle(&p->q16ang, &p->angAdjust, 4); + p->angle.addadjustment(4); } else if (p->kickback_pic == 4) { - playerAddAngle(&p->q16ang, &p->angAdjust, -4); + p->angle.addadjustment(-4); } if (p->kickback_pic > 4) p->kickback_pic = 1; @@ -3236,9 +3236,9 @@ static void operateweapon(int snum, ESyncBits actions, int psect) } else if (p->kickback_pic == 12) { - p->posxv -= sintable[(p->getang() + 512) & 2047] << 4; - p->posyv -= sintable[p->getang() & 2047] << 4; - playerAddHoriz(&p->q16horiz, &p->horizAdjust, 20); + p->posxv -= sintable[(p->angle.ang.asbuild() + 512) & 2047] << 4; + p->posyv -= sintable[p->angle.ang.asbuild() & 2047] << 4; + p->horizon.addadjustment(20); p->recoil += 20; } if (p->kickback_pic > 20) @@ -3253,19 +3253,19 @@ static void operateweapon(int snum, ESyncBits actions, int psect) if (p->on_ground && (actions & SB_CROUCH) && !p->OnMotorcycle) { k = 15; - i = xs_CRoundToInt((p->getq16horizsum() - IntToFixed(100)) * (20. / FRACUNIT)); + i = mulscale16(p->horizon.sum().asq16(), 20); } else { k = 32; - i = -512 - xs_CRoundToInt((p->getq16horizsum() - IntToFixed(100)) * (20. / FRACUNIT)); + i = -512 - mulscale16(p->horizon.sum().asq16(), 20); } j = EGS(p->cursectnum, - p->posx + (sintable[(p->getang() + 512) & 2047] >> 6), - p->posy + (sintable[p->getang() & 2047] >> 6), + p->posx + (sintable[(p->angle.ang.asbuild() + 512) & 2047] >> 6), + p->posy + (sintable[p->angle.ang.asbuild() & 2047] >> 6), p->posz, TRIPBOMBSPRITE, -16, 9, 9, - p->getang(), k * 2, i, pi, 1); + p->angle.ang.asbuild(), k * 2, i, pi, 1); } p->kickback_pic++; if (p->kickback_pic > 20) @@ -3286,8 +3286,8 @@ static void operateweapon(int snum, ESyncBits actions, int psect) } if (p->kickback_pic < 30) { - p->posxv += sintable[(p->getang() + 512) & 2047] << 4; - p->posyv += sintable[p->getang() & 2047] << 4; + p->posxv += sintable[(p->angle.ang.asbuild() + 512) & 2047] << 4; + p->posyv += sintable[p->angle.ang.asbuild() & 2047] << 4; } p->kickback_pic++; if (p->kickback_pic > 40) @@ -3535,7 +3535,7 @@ void processinput_r(int snum) if (cl_syncinput) { - backupview(p); + p->horizon.backup(); calcviewpitch(p, 1); } @@ -3740,8 +3740,8 @@ void processinput_r(int snum) //ENGINE calculates angvel for you // may still be needed later for demo recording - processq16avel(p, &sb_avel); - applylook(&p->q16ang, &p->q16look_ang, &p->q16rotscrnang, &p->one_eighty_count, sb_avel, &p->sync.actions, 1, p->crouch_toggle || actions & SB_CROUCH); + processavel(p, &sb_avel); + applylook(&p->angle, sb_avel, &p->sync.actions, 1, p->crouch_toggle || actions & SB_CROUCH); apply_seasick(p, 1); } @@ -4092,12 +4092,12 @@ HORIZONLY: if (!d) d = 1; p->recoil -= d; - playerAddHoriz(&p->q16horiz, &p->horizAdjust, -d); + p->horizon.addadjustment(-d); } if (cl_syncinput) { - sethorizon(&p->q16horiz, PlayerHorizon(snum), &p->sync.actions, 1); + sethorizon(&p->horizon.horiz, PlayerHorizon(snum), &p->sync.actions, 1); } checkhardlanding(p); @@ -4170,7 +4170,7 @@ void OnMotorcycle(struct player_struct *p, int motosprite) { p->posx = sprite[motosprite].x; p->posy = sprite[motosprite].y; - p->setang(sprite[motosprite].ang); + p->angle.ang = buildang(sprite[motosprite].ang); p->ammo_amount[MOTORCYCLE_WEAPON] = sprite[motosprite].owner; deletesprite(motosprite); } @@ -4181,7 +4181,7 @@ void OnMotorcycle(struct player_struct *p, int motosprite) p->gotweapon.Set(MOTORCYCLE_WEAPON); p->posxv = 0; p->posyv = 0; - p->sethoriz(100); + p->horizon.horiz = q16horiz(0); } if (!S_CheckActorSoundPlaying(p->i,186)) S_PlayActorSound(186, p->i); @@ -4212,7 +4212,7 @@ void OffMotorcycle(struct player_struct *p) p->gotweapon.Clear(MOTORCYCLE_WEAPON); p->curr_weapon = p->last_full_weapon; checkavailweapon(p); - p->sethoriz(100); + p->horizon.horiz = q16horiz(0); p->moto_do_bump = 0; p->MotoSpeed = 0; p->TiltStatus = 0; @@ -4222,13 +4222,13 @@ void OffMotorcycle(struct player_struct *p) p->TurbCount = 0; p->posxv = 0; p->posyv = 0; - p->posxv -= sintable[(p->getang()+512)&2047]<<7; - p->posyv -= sintable[p->getang()&2047]<<7; + p->posxv -= sintable[(p->angle.ang.asbuild()+512)&2047]<<7; + p->posyv -= sintable[p->angle.ang.asbuild()&2047]<<7; p->moto_underwater = 0; j = fi.spawn(p->i, EMPTYBIKE); - sprite[j].ang = p->getang(); - sprite[j].xvel += sintable[(p->getang()+512)&2047]<<7; - sprite[j].yvel += sintable[p->getang()&2047]<<7; + sprite[j].ang = p->angle.ang.asbuild(); + sprite[j].xvel += sintable[(p->angle.ang.asbuild()+512)&2047]<<7; + sprite[j].yvel += sintable[p->angle.ang.asbuild()&2047]<<7; sprite[j].owner = p->ammo_amount[MOTORCYCLE_WEAPON]; } } @@ -4247,7 +4247,7 @@ void OnBoat(struct player_struct *p, int boatsprite) { p->posx = sprite[boatsprite].x; p->posy = sprite[boatsprite].y; - p->setang(sprite[boatsprite].ang); + p->angle.ang = buildang(sprite[boatsprite].ang); p->ammo_amount[BOAT_WEAPON] = sprite[boatsprite].owner; deletesprite(boatsprite); } @@ -4258,7 +4258,7 @@ void OnBoat(struct player_struct *p, int boatsprite) p->gotweapon.Set(BOAT_WEAPON); p->posxv = 0; p->posyv = 0; - p->sethoriz(100); + p->horizon.horiz = q16horiz(0); } } @@ -4277,7 +4277,7 @@ void OffBoat(struct player_struct *p) p->gotweapon.Clear(BOAT_WEAPON); p->curr_weapon = p->last_full_weapon; checkavailweapon(p); - p->sethoriz(100); + p->horizon.horiz = q16horiz(0); p->moto_do_bump = 0; p->MotoSpeed = 0; p->TiltStatus = 0; @@ -4287,13 +4287,13 @@ void OffBoat(struct player_struct *p) p->TurbCount = 0; p->posxv = 0; p->posyv = 0; - p->posxv -= sintable[(p->getang()+512)&2047]<<7; - p->posyv -= sintable[p->getang()&2047]<<7; + p->posxv -= sintable[(p->angle.ang.asbuild()+512)&2047]<<7; + p->posyv -= sintable[p->angle.ang.asbuild()&2047]<<7; p->moto_underwater = 0; j = fi.spawn(p->i, EMPTYBOAT); - sprite[j].ang = p->getang(); - sprite[j].xvel += sintable[(p->getang()+512)&2047]<<7; - sprite[j].yvel += sintable[p->getang()&2047]<<7; + sprite[j].ang = p->angle.ang.asbuild(); + sprite[j].xvel += sintable[(p->angle.ang.asbuild()+512)&2047]<<7; + sprite[j].yvel += sintable[p->angle.ang.asbuild()&2047]<<7; sprite[j].owner = p->ammo_amount[BOAT_WEAPON]; } } diff --git a/source/games/duke/src/player_w.cpp b/source/games/duke/src/player_w.cpp index 091380e7c..bfdf2d542 100644 --- a/source/games/duke/src/player_w.cpp +++ b/source/games/duke/src/player_w.cpp @@ -333,19 +333,19 @@ void operateweapon_ww(int snum, ESyncBits actions, int psect) if (p->on_ground && (actions & SB_CROUCH)) { k = 15; - i = xs_CRoundToInt((p->getq16horizsum() - IntToFixed(100)) * (20. / FRACUNIT)); + i = mulscale16(p->horizon.sum().asq16(), 20); } else { k = 140; - i = -512 - xs_CRoundToInt((p->getq16horizsum() - IntToFixed(100)) * (20. / FRACUNIT)); + i = -512 - mulscale16(p->horizon.sum().asq16(), 20); } j = EGS(p->cursectnum, - p->posx + (sintable[(p->getang() + 512) & 2047] >> 6), - p->posy + (sintable[p->getang() & 2047] >> 6), + p->posx + (sintable[(p->angle.ang.asbuild() + 512) & 2047] >> 6), + p->posy + (sintable[p->angle.ang.asbuild() & 2047] >> 6), p->posz, HEAVYHBOMB, -16, 9, 9, - p->getang(), (k + (p->hbomb_hold_delay << 5)), i, pi, 1); + p->angle.ang.asbuild(), (k + (p->hbomb_hold_delay << 5)), i, pi, 1); { int lGrenadeLifetime = GetGameVar("GRENADE_LIFETIME", NAM_GRENADE_LIFETIME, -1, snum); diff --git a/source/games/duke/src/prediction.cpp b/source/games/duke/src/prediction.cpp index 0a777b6c6..0f3297a88 100644 --- a/source/games/duke/src/prediction.cpp +++ b/source/games/duke/src/prediction.cpp @@ -39,7 +39,8 @@ BEGIN_DUKE_NS int myx, omyx, myxvel, myy, omyy, myyvel, myz, omyz, myzvel; short globalskillsound; -fixed_t q16myang, oq16myang, q16myhoriz, oq16myhoriz, q16myhorizoff, oq16myhorizoff; +binangle myang, omyang; +fixedhoriz myhoriz, omyhoriz, myhorizoff, omyhorizoff; short mycursectnum, myjumpingcounter; char myjumpingtoggle, myonground, myhardlanding,myreturntocenter; int fakemovefifoplc; @@ -54,9 +55,9 @@ void resetmys() myy = omyy = ps[myconnectindex].posy; myz = omyz = ps[myconnectindex].posz; myxvel = myyvel = myzvel = 0; - q16myang = oq16myang = ps[myconnectindex].q16ang; - q16myhoriz = oq16myhoriz = ps[myconnectindex].q16horiz; - q16myhorizoff = oq16myhorizoff = ps[myconnectindex].q16horizoff; + myang = myang = ps[myconnectindex].angle.ang; + myhoriz = omyhoriz = ps[myconnectindex].horizon.horiz; + myhorizoff = omyhorizoff = ps[myconnectindex].horizon.horizoff; mycursectnum = ps[myconnectindex].cursectnum; myjumpingcounter = ps[myconnectindex].jumping_counter; myjumpingtoggle = ps[myconnectindex].jumping_toggle; @@ -213,7 +214,7 @@ void fakedomovethings(void) if(p->on_crane >= 0) goto FAKEHORIZONLY; - if(p->one_eighty_count < 0) myang += 128; + if(p->angle.spin.asbam() < 0) myang += 128; i = 40; diff --git a/source/games/duke/src/prediction.h b/source/games/duke/src/prediction.h index 6f9be8992..ed31b59eb 100644 --- a/source/games/duke/src/prediction.h +++ b/source/games/duke/src/prediction.h @@ -5,7 +5,8 @@ BEGIN_DUKE_NS extern int myx, omyx, myxvel, myy, omyy, myyvel, myz, omyz, myzvel; extern short globalskillsound; extern short mycursectnum, myjumpingcounter; -extern fixed_t q16myang, oq16myang, q16myhoriz, oq16myhoriz, q16myhorizoff, oq16myhorizoff; +extern binangle myang, omyang; +extern fixedhoriz myhoriz, omyhoriz, myhorizoff, omyhorizoff; extern char myjumpingtoggle, myonground, myhardlanding,myreturntocenter; extern int fakemovefifoplc; extern int myxbak[MOVEFIFOSIZ], myybak[MOVEFIFOSIZ], myzbak[MOVEFIFOSIZ]; diff --git a/source/games/duke/src/premap.cpp b/source/games/duke/src/premap.cpp index 621419e95..bc80d1939 100644 --- a/source/games/duke/src/premap.cpp +++ b/source/games/duke/src/premap.cpp @@ -59,8 +59,7 @@ void pickrandomspot(int snum) p->bobposx = p->oposx = p->posx = po[i].ox; p->bobposy = p->oposy = p->posy = po[i].oy; p->oposz = p->posz = po[i].oz; - p->setang(po[i].oa); - p->setoang(po[i].oa); + p->angle.oang = p->angle.ang = buildang(po[i].oa); p->cursectnum = po[i].os; } @@ -112,10 +111,8 @@ void resetplayerstats(int snum) p->footprintpal = 0; p->footprintshade = 0; p->jumping_toggle = 0; - p->sethoriz(140); //!! - p->oq16horiz = p->q16horiz; - p->sethorizoff(0); - p->oq16horizoff = p->q16horizoff; + p->horizon.ohoriz = p->horizon.horiz = q16horiz(40); + p->horizon.ohorizoff = p->horizon.horizoff = q16horiz(0); p->bobcounter = 0; p->on_ground = 0; p->player_par = 0; @@ -141,11 +138,9 @@ void resetplayerstats(int snum) p->jetpack_on = 0; p->holoduke_on = -1; - p->setlookang(512 - ((currentLevel->levelNumber & 1) << 10)); - p->oq16look_ang = p->q16look_ang; + p->angle.olook_ang = p->angle.look_ang = buildlook(512 - ((currentLevel->levelNumber & 1) << 10)); + p->angle.orotscrnang = p->angle.rotscrnang = buildlook(0); - p->setrotscrnang(0); - p->oq16rotscrnang = p->q16rotscrnang; p->newowner =-1; p->jumping_counter = 0; p->hard_landing = 0; @@ -155,7 +150,7 @@ void resetplayerstats(int snum) p->fric.x = 0; p->fric.y = 0; p->somethingonplayer =-1; - p->one_eighty_count = 0; + p->angle.spin = bamlook(0); p->on_crane = -1; @@ -513,7 +508,7 @@ void resetpspritevars(int g) STATUSBARTYPE tsbar[MAXPLAYERS]; EGS(ps[0].cursectnum, ps[0].posx, ps[0].posy, ps[0].posz, - TILE_APLAYER, 0, 0, 0, ps[0].getang(), 0, 0, 0, 10); + TILE_APLAYER, 0, 0, 0, ps[0].angle.ang.asbuild(), 0, 0, 0, 10); if (ud.recstat != 2) for (i = 0; i < MAXPLAYERS; i++) { @@ -638,8 +633,7 @@ void resetpspritevars(int g) hittype[i].bposx = ps[j].bobposx = ps[j].oposx = ps[j].posx = s->x; hittype[i].bposy = ps[j].bobposy = ps[j].oposy = ps[j].posy = s->y; hittype[i].bposz = ps[j].oposz = ps[j].posz = s->z; - ps[j].setang(s->ang); - ps[j].setoang(s->ang); + ps[j].angle.oang = ps[j].angle.ang = buildang(s->ang); updatesector(s->x, s->y, &ps[j].cursectnum); @@ -876,7 +870,7 @@ static int LoadTheMap(MapRecord *mi, struct player_struct *p, int gamemode) ps[0].ammo_amount[i] = 0; ps[0].gotweapon.Clear(KNEE_WEAPON); } - p->setang(lbang); + p->angle.ang = buildang(lbang); memset(gotpic, 0, sizeof(gotpic)); diff --git a/source/games/duke/src/render.cpp b/source/games/duke/src/render.cpp index b577ca8ab..fb5ad0dd4 100644 --- a/source/games/duke/src/render.cpp +++ b/source/games/duke/src/render.cpp @@ -478,8 +478,8 @@ void displayrooms(int snum, double smoothratio) int cposx, cposy, cposz, fz, cz; short sect; binangle cang; + lookangle rotscrnang; fixedhoriz choriz; - fixed_t q16rotscrnang; struct player_struct* p; int tiltcs = 0; // JBF 20030807 @@ -545,7 +545,7 @@ void displayrooms(int snum, double smoothratio) } // set screen rotation. - q16rotscrnang = !cl_syncinput ? p->q16rotscrnang : p->oq16rotscrnang + fmulscale16(((p->q16rotscrnang - p->oq16rotscrnang + dang) & 0x7FFFFFF) - dang, smoothratio); + rotscrnang = !cl_syncinput ? p->angle.rotscrnang : p->angle.interpolatedrotscrn(smoothratio); if ((snum == myconnectindex) && (numplayers > 1)) { @@ -554,15 +554,15 @@ void displayrooms(int snum, double smoothratio) cposz = omyz + xs_CRoundToInt(fmulscale16(myz - omyz, smoothratio)); if (cl_syncinput) { - fixed_t ohorz = (oq16myhoriz + oq16myhorizoff); - fixed_t horz = (q16myhoriz + q16myhorizoff); + fixed_t ohorz = (omyhoriz.asq16() + omyhorizoff.asq16()); + fixed_t horz = (myhoriz.asq16() + myhorizoff.asq16()); choriz = q16horiz(ohorz + xs_CRoundToInt(fmulscale16(horz - ohorz, smoothratio))); - cang = q16ang(oq16myang + xs_CRoundToInt(fmulscale16(((q16myang + dang - oq16myang) & 0x7FFFFFF) - dang, smoothratio))); + cang = bamang(xs_CRoundToUInt(omyang.asbam() + fmulscale16(myang.asbam() - omyang.asbam(), smoothratio))); } else { - cang = q16ang(q16myang); - choriz = q16horiz(q16myhoriz + q16myhorizoff); + cang = myang; + choriz = myhoriz + myhorizoff; } sect = mycursectnum; } @@ -574,31 +574,26 @@ void displayrooms(int snum, double smoothratio) if (cl_syncinput) { // Original code for when the values are passed through the sync struct - fixed_t ohorz = (p->oq16horiz + p->oq16horizoff); - fixed_t horz = (p->q16horiz + p->q16horizoff); - choriz = q16horiz(ohorz + xs_CRoundToInt(fmulscale16(horz - ohorz, smoothratio))); - - fixed_t oang = (p->oq16ang + p->oq16look_ang); - fixed_t ang = (p->q16ang + p->q16look_ang); - cang = q16ang(oang + xs_CRoundToInt(fmulscale16(((ang + dang - oang) & 0x7FFFFFF) - dang, smoothratio))); + choriz = p->horizon.interpolatedsum(smoothratio); + cang = p->angle.interpolatedsum(smoothratio); } else { // This is for real time updating of the view direction. - cang = q16ang(p->q16ang + p->q16look_ang); - choriz = q16horiz(p->q16horiz + p->q16horizoff); + cang = p->angle.sum(); + choriz = p->horizon.sum(); } } if (p->newowner >= 0) { cang = buildang(getcamspriteang(p->newowner, smoothratio)); - choriz = q16horiz(p->q16horiz + p->q16horizoff); + choriz = buildhoriz(sprite[p->newowner].shade); cposx = sprite[p->newowner].pos.x; cposy = sprite[p->newowner].pos.y; cposz = sprite[p->newowner].pos.z; sect = sprite[p->newowner].sectnum; - q16rotscrnang = 0; + rotscrnang = buildlook(0); smoothratio = MaxSmoothRatio; } else if (p->over_shoulder_on == 0) @@ -617,7 +612,7 @@ void displayrooms(int snum, double smoothratio) } // do screen rotation. - renderSetRollAngle(FixedToInt(q16rotscrnang)); + renderSetRollAngle(rotscrnang.asbam() / (double)(BAMUNIT)); cz = hittype[p->i].ceilingz; fz = hittype[p->i].floorz; @@ -630,10 +625,7 @@ void displayrooms(int snum, double smoothratio) if (sprite[p->i].pal == 1) cposz -= (18 << 8); - if (p->newowner >= 0) - choriz = buildhoriz(100 + sprite[p->newowner].shade); - - else if (p->spritebridge == 0) + else if (p->spritebridge == 0 && p->newowner < 0) { if (cposz < (p->truecz + (4 << 8))) cposz = cz + (4 << 8); else if (cposz > (p->truefz - (4 << 8))) cposz = fz - (4 << 8); @@ -646,7 +638,7 @@ void displayrooms(int snum, double smoothratio) if (cposz > fz - (4 << 8)) cposz = fz - (4 << 8); } - choriz = clamp(choriz, buildhoriz(HORIZ_MIN), buildhoriz(HORIZ_MAX)); + choriz = clamp(choriz, q16horiz(gi->playerHorizMin()), q16horiz(gi->playerHorizMax())); if (isRR() && sector[sect].lotag == 848) { diff --git a/source/games/duke/src/savegame.cpp b/source/games/duke/src/savegame.cpp index 4590d7232..998fb26a5 100644 --- a/source/games/duke/src/savegame.cpp +++ b/source/games/duke/src/savegame.cpp @@ -113,12 +113,12 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, player_struct& w, arc("posx", w.posx) ("posy", w.posy) ("posz", w.posz) - ("q16ang", w.q16ang) - ("q16horiz", w.q16horiz) - ("q16horizoff", w.q16horizoff) - ("q16rotscrnang", w.q16rotscrnang) - ("q16look_ang", w.q16look_ang) - ("one_eighty_count", w.one_eighty_count) + ("ang", w.angle.ang) + ("look_ang", w.angle.look_ang) + ("rotscrnang", w.angle.rotscrnang) + ("horiz", w.horizon.horiz) + ("horizoff", w.horizon.horizoff) + ("spin", w.angle.spin) ("gotweapon", w.gotweapon) ("palette", w.palette) ("pals", w.pals) @@ -284,10 +284,11 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, player_struct& w, .EndObject(); w.invdisptime = 0; - w.oq16ang = w.q16ang; - w.oq16horiz = w.q16horiz; - w.oq16horizoff = w.q16horizoff; - w.oq16rotscrnang = w.q16rotscrnang; + w.angle.oang = w.angle.ang; + w.angle.olook_ang = w.angle.look_ang; + w.angle.orotscrnang = w.angle.rotscrnang; + w.horizon.ohoriz = w.horizon.horiz; + w.horizon.ohorizoff = w.horizon.horizoff; w.oposx = w.posx; w.oposy = w.posy; w.oposz = w.posz; @@ -297,8 +298,6 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, player_struct& w, w.okickback_pic = w.kickback_pic; w.orandom_club_frame = w.random_club_frame; w.ohard_landing = w.hard_landing; - w.horizAdjust = 0; - w.angAdjust = 0; w.sync.actions &= SB_CENTERVIEW; // this is the only bit we need to preserve. } return arc; diff --git a/source/games/duke/src/sectors.cpp b/source/games/duke/src/sectors.cpp index f4de87abc..ccdd60ee2 100644 --- a/source/games/duke/src/sectors.cpp +++ b/source/games/duke/src/sectors.cpp @@ -1148,8 +1148,8 @@ void moveclouds(double smoothratio) cloudclock = myclock + 6; // cloudx/y were an array, but all entries were always having the same value so a single pair is enough. - cloudx += (sintable[(ps[screenpeek].getang() + 512) & 2047] >> 9); - cloudy += (sintable[ps[screenpeek].getang() & 2047] >> 9); + cloudx += (sintable[(ps[screenpeek].angle.ang.asbuild() + 512) & 2047] >> 9); + cloudy += (sintable[ps[screenpeek].angle.ang.asbuild() & 2047] >> 9); for (int i = 0; i < numclouds; i++) { sector[clouds[i]].ceilingxpanning = cloudx >> 6; diff --git a/source/games/duke/src/sectors_d.cpp b/source/games/duke/src/sectors_d.cpp index 2c9bc69b2..10ca07370 100644 --- a/source/games/duke/src/sectors_d.cpp +++ b/source/games/duke/src/sectors_d.cpp @@ -719,7 +719,7 @@ void checkhitwall_d(int spr, int dawallnum, int x, int y, int z, int atwith) if (wal->nextwall >= 0) wall[wal->nextwall].cstat = 0; - i = EGS(sn, x, y, z, SECTOREFFECTOR, 0, 0, 0, ps[0].getang(), 0, 0, spr, 3); + i = EGS(sn, x, y, z, SECTOREFFECTOR, 0, 0, 0, ps[0].angle.ang.asbuild(), 0, 0, spr, 3); sprite[i].lotag = 128; hittype[i].temp_data[1] = 5; hittype[i].temp_data[2] = dawallnum; S_PlayActorSound(GLASS_BREAKING, i); return; @@ -921,13 +921,13 @@ void checkplayerhurt_d(struct player_struct* p, int j) p->hurt_delay = 16; SetPlayerPal(p, PalEntry(32, 32, 0, 0)); - p->posxv = -(sintable[(p->getang() + 512) & 2047] << 8); - p->posyv = -(sintable[(p->getang()) & 2047] << 8); + p->posxv = -(sintable[(p->angle.ang.asbuild() + 512) & 2047] << 8); + p->posyv = -(sintable[(p->angle.ang.asbuild()) & 2047] << 8); S_PlayActorSound(DUKE_LONGTERM_PAIN, p->i); fi.checkhitwall(p->i, j, - p->posx + (sintable[(p->getang() + 512) & 2047] >> 9), - p->posy + (sintable[p->getang() & 2047] >> 9), + p->posx + (sintable[(p->angle.ang.asbuild() + 512) & 2047] >> 9), + p->posy + (sintable[p->angle.ang.asbuild() & 2047] >> 9), p->posz, -1); break; @@ -935,8 +935,8 @@ void checkplayerhurt_d(struct player_struct* p, int j) case BIGFORCE: p->hurt_delay = 26; fi.checkhitwall(p->i, j, - p->posx + (sintable[(p->getang() + 512) & 2047] >> 9), - p->posy + (sintable[p->getang() & 2047] >> 9), + p->posx + (sintable[(p->angle.ang.asbuild() + 512) & 2047] >> 9), + p->posy + (sintable[p->angle.ang.asbuild() & 2047] >> 9), p->posz, -1); break; @@ -1460,7 +1460,7 @@ void checkhitsprite_d(int i, int sn) ps[p].posx = ps[p].oposx; ps[p].posy = ps[p].oposy; ps[p].posz = ps[p].oposz; - ps[p].q16ang = ps[p].oq16ang; + ps[p].angle.restore(); updatesector(ps[p].posx, ps[p].posy, &ps[p].cursectnum); setpal(&ps[p]); @@ -1580,17 +1580,17 @@ void checksectors_d(int snum) return; if (p->newowner >= 0) - neartag(p->oposx, p->oposy, p->oposz, sprite[p->i].sectnum, p->getoang(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); + neartag(p->oposx, p->oposy, p->oposz, sprite[p->i].sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); else { - neartag(p->posx, p->posy, p->posz, sprite[p->i].sectnum, p->getoang(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); + neartag(p->posx, p->posy, p->posz, sprite[p->i].sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); if (neartagsprite == -1 && neartagwall == -1 && neartagsector == -1) - neartag(p->posx, p->posy, p->posz + (8 << 8), sprite[p->i].sectnum, p->getoang(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); + neartag(p->posx, p->posy, p->posz + (8 << 8), sprite[p->i].sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); if (neartagsprite == -1 && neartagwall == -1 && neartagsector == -1) - neartag(p->posx, p->posy, p->posz + (16 << 8), sprite[p->i].sectnum, p->getoang(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); + neartag(p->posx, p->posy, p->posz + (16 << 8), sprite[p->i].sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); if (neartagsprite == -1 && neartagwall == -1 && neartagsector == -1) { - neartag(p->posx, p->posy, p->posz + (16 << 8), sprite[p->i].sectnum, p->getoang(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 3); + neartag(p->posx, p->posy, p->posz + (16 << 8), sprite[p->i].sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 3); if (neartagsprite >= 0) { switch (sprite[neartagsprite].picnum) diff --git a/source/games/duke/src/sectors_r.cpp b/source/games/duke/src/sectors_r.cpp index 0ed8f7bfc..1afa4c932 100644 --- a/source/games/duke/src/sectors_r.cpp +++ b/source/games/duke/src/sectors_r.cpp @@ -1033,7 +1033,7 @@ void checkhitwall_r(int spr, int dawallnum, int x, int y, int z, int atwith) if (wal->nextwall >= 0) wall[wal->nextwall].cstat = 0; - i = EGS(sn, x, y, z, SECTOREFFECTOR, 0, 0, 0, ps[0].getang(), 0, 0, spr, 3); + i = EGS(sn, x, y, z, SECTOREFFECTOR, 0, 0, 0, ps[0].angle.ang.asbuild(), 0, 0, spr, 3); sprite[i].lotag = 128; hittype[i].temp_data[1] = 2; hittype[i].temp_data[2] = dawallnum; S_PlayActorSound(GLASS_BREAKING, i); return; @@ -1047,7 +1047,7 @@ void checkhitwall_r(int spr, int dawallnum, int x, int y, int z, int atwith) if (wal->nextwall >= 0) wall[wal->nextwall].cstat = 0; - i = EGS(sn, x, y, z, SECTOREFFECTOR, 0, 0, 0, ps[0].getang(), 0, 0, spr, 3); + i = EGS(sn, x, y, z, SECTOREFFECTOR, 0, 0, 0, ps[0].angle.ang.asbuild(), 0, 0, spr, 3); sprite[i].lotag = 128; hittype[i].temp_data[1] = 2; hittype[i].temp_data[2] = dawallnum; S_PlayActorSound(GLASS_BREAKING, i); return; @@ -1419,8 +1419,8 @@ void checkplayerhurt_r(struct player_struct* p, int j) case BIGFORCE: p->hurt_delay = 26; fi.checkhitwall(p->i, j, - p->posx + (sintable[(p->getang() + 512) & 2047] >> 9), - p->posy + (sintable[p->getang() & 2047] >> 9), + p->posx + (sintable[(p->angle.ang.asbuild() + 512) & 2047] >> 9), + p->posy + (sintable[p->angle.ang.asbuild() & 2047] >> 9), p->posz, -1); break; @@ -2555,21 +2555,21 @@ void checksectors_r(int snum) } return; } - neartag(p->posx, p->posy, p->posz, sprite[p->i].sectnum, p->getoang(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 3); + neartag(p->posx, p->posy, p->posz, sprite[p->i].sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 3); } if (p->newowner >= 0) - neartag(p->oposx, p->oposy, p->oposz, sprite[p->i].sectnum, p->getoang(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); + neartag(p->oposx, p->oposy, p->oposz, sprite[p->i].sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); else { - neartag(p->posx, p->posy, p->posz, sprite[p->i].sectnum, p->getoang(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); + neartag(p->posx, p->posy, p->posz, sprite[p->i].sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); if (neartagsprite == -1 && neartagwall == -1 && neartagsector == -1) - neartag(p->posx, p->posy, p->posz + (8 << 8), sprite[p->i].sectnum, p->getoang(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); + neartag(p->posx, p->posy, p->posz + (8 << 8), sprite[p->i].sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); if (neartagsprite == -1 && neartagwall == -1 && neartagsector == -1) - neartag(p->posx, p->posy, p->posz + (16 << 8), sprite[p->i].sectnum, p->getoang(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); + neartag(p->posx, p->posy, p->posz + (16 << 8), sprite[p->i].sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 1); if (neartagsprite == -1 && neartagwall == -1 && neartagsector == -1) { - neartag(p->posx, p->posy, p->posz + (16 << 8), sprite[p->i].sectnum, p->getoang(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 3); + neartag(p->posx, p->posy, p->posz + (16 << 8), sprite[p->i].sectnum, p->angle.oang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1280L, 3); if (neartagsprite >= 0) { switch (sprite[neartagsprite].picnum) diff --git a/source/games/duke/src/sounds.cpp b/source/games/duke/src/sounds.cpp index c61dc6026..8010bda7e 100644 --- a/source/games/duke/src/sounds.cpp +++ b/source/games/duke/src/sounds.cpp @@ -298,7 +298,7 @@ void S_GetCamera(vec3_t** c, int32_t* ca, int32_t* cs) auto p = &ps[screenpeek]; if (c) *c = &p->pos; if (cs) *cs = p->cursectnum; - if (ca) *ca = p->getang(); + if (ca) *ca = p->angle.ang.asbuild(); } else { diff --git a/source/games/duke/src/spawn.cpp b/source/games/duke/src/spawn.cpp index f2a47f670..ab057dbbd 100644 --- a/source/games/duke/src/spawn.cpp +++ b/source/games/duke/src/spawn.cpp @@ -435,10 +435,10 @@ void initshell(int j, int i, bool isshell) if (sprite[j].picnum == TILE_APLAYER) { snum = sprite[j].yvel; - a = ps[snum].getang() - (krand() & 63) + 8; //Fine tune + a = ps[snum].angle.ang.asbuild() - (krand() & 63) + 8; //Fine tune t[0] = krand() & 1; - sp->z = (3 << 8) + ps[snum].pyoff + ps[snum].posz - ((ps[snum].q16horizoff + ps[snum].q16horiz - IntToFixed(100)) >> 12) + (!isshell ? (3 << 8) : 0); + sp->z = (3 << 8) + ps[snum].pyoff + ps[snum].posz - (ps[snum].horizon.sum().asq16() >> 12) + (!isshell ? (3 << 8) : 0); sp->zvel = -(krand() & 255); } else diff --git a/source/games/duke/src/types.h b/source/games/duke/src/types.h index 5f2090402..849737d4e 100644 --- a/source/games/duke/src/types.h +++ b/source/games/duke/src/types.h @@ -95,10 +95,9 @@ struct player_struct struct { int32_t posx, posy, posz; }; }; - // 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, oq16look_ang; // These are only needed with synchronous mouse input. - fixed_t one_eighty_count; + // player's horizon and angle structs. + PlayerHorizon horizon; + PlayerAngle angle; // using a bit field for this to save a bit of space. FixedBitArray gotweapon; @@ -207,34 +206,7 @@ struct player_struct int8_t crouch_toggle; // input stuff. - double horizAdjust, angAdjust; - fixed_t horizTarget, angTarget; InputPacket sync; - - - // Access helpers for the widened angle and horizon fields. - void setlookang(int b) { q16look_ang = IntToFixed(b); } - void addlookang(int b) { q16look_ang += IntToFixed(b); } - void addlookang(double b) { q16look_ang += FloatToFixed(b); } - void setrotscrnang(int b) { q16rotscrnang = IntToFixed(b); } - void addrotscrnang(int b) { q16rotscrnang += IntToFixed(b); } - void addrotscrnang(double b) { q16rotscrnang += FloatToFixed(b); } - int getang() { return FixedToInt(q16ang); } - int getoang() { return FixedToInt(oq16ang); } - void setang(int v) { q16ang = IntToFixed(v); } - void addang(int v) { q16ang = (q16ang + IntToFixed(v)) & 0x7FFFFFF; } - void setoang(int v) { oq16ang = IntToFixed(v); } - void addhoriz(int v) { q16horiz += (IntToFixed(v)); } - void addhorizoff(int v) { q16horiz += (IntToFixed(v)); } - void addhorizoff(double v) { q16horiz += FloatToFixed(v); } - void sethoriz(int v) { q16horiz = IntToFixed(v); } - void sethorizoff(int v) { q16horizoff = IntToFixed(v); } - int gethoriz() { return FixedToInt(q16horiz); } - int gethorizof() { return FixedToInt(q16horizoff); } - int gethorizsum() { return FixedToInt(q16horiz + q16horizoff); } - int getq16horiz() { return q16horiz; } - int getq16horizof() { return q16horizoff; } - int getq16horizsum() { return q16horiz + q16horizoff; } }; diff --git a/source/sw/src/draw.cpp b/source/sw/src/draw.cpp index 0693b2444..ce45d14cb 100644 --- a/source/sw/src/draw.cpp +++ b/source/sw/src/draw.cpp @@ -786,7 +786,7 @@ analyzesprites(int viewx, int viewy, int viewz, bool mirror) tsp->x -= mulscale16(pp->posx - pp->oposx, 65536-smoothratio); tsp->y -= mulscale16(pp->posy - pp->oposy, 65536-smoothratio); tsp->z -= mulscale16(pp->posz - pp->oposz, 65536-smoothratio); - tsp->ang -= FixedToInt(mulscale16(pp->q16ang - pp->oq16ang, 65536-smoothratio)); + tsp->ang -= mulscale16(pp->angle.ang.asbuild() - pp->angle.oang.asbuild(), 65536-smoothratio); } } @@ -929,7 +929,7 @@ post_analyzesprites(void) bool -BackView(int *nx, int *ny, int *nz, short *vsect, fixed_t *nq16ang, fixed_t q16horiz) +BackView(int *nx, int *ny, int *nz, short *vsect, binangle *nang, fixed_t q16horiz) { vec3_t n = { *nx, *ny, *nz }; SPRITEp sp; @@ -941,12 +941,12 @@ BackView(int *nx, int *ny, int *nz, short *vsect, fixed_t *nq16ang, fixed_t q16h ASSERT(*vsect >= 0 && *vsect < MAXSECTORS); - ang = FixedToInt(*nq16ang) + pp->view_outside_dang; + ang = nang->asbuild() + pp->view_outside_dang; // Calculate the vector (nx,ny,nz) to shoot backwards vx = (sintable[NORM_ANGLE(ang + 1536)] >> 3); vy = (sintable[NORM_ANGLE(ang + 1024)] >> 3); - vz = (q16horiz - IntToFixed(100)) >> 8; + vz = q16horiz >> 8; // Player sprite of current view sp = &sprite[pp->PlayerSprite]; @@ -1009,7 +1009,7 @@ BackView(int *nx, int *ny, int *nz, short *vsect, fixed_t *nq16ang, fixed_t q16h flag_backup = hsp->cstat; RESET(hsp->cstat, CSTAT_SPRITE_BLOCK|CSTAT_SPRITE_BLOCK_HITSCAN); ASSERT(*vsect >= 0 && *vsect < MAXSECTORS); - BackView(nx, ny, nz, vsect, nq16ang, q16horiz); + BackView(nx, ny, nz, vsect, nang, q16horiz); hsp->cstat = flag_backup; return false; } @@ -1050,12 +1050,12 @@ BackView(int *nx, int *ny, int *nz, short *vsect, fixed_t *nq16ang, fixed_t q16h // Make sure vsect is correct updatesectorz(*nx, *ny, *nz, vsect); - *nq16ang += IntToFixed(pp->view_outside_dang); + *nang += buildang(pp->view_outside_dang); return true; } void -CircleCamera(int *nx, int *ny, int *nz, short *vsect, int *nq16ang, fixed_t q16horiz) +CircleCamera(int *nx, int *ny, int *nz, short *vsect, binangle *nang, fixed_t q16horiz) { vec3_t n = { *nx, *ny, *nz }; SPRITEp sp; @@ -1063,19 +1063,19 @@ CircleCamera(int *nx, int *ny, int *nz, short *vsect, int *nq16ang, fixed_t q16h int i, vx, vy, vz, hx, hy; short bakcstat, daang; PLAYERp pp = &Player[screenpeek]; - short ang; + binangle ang; - ang = FixedToInt(*nq16ang) + pp->circle_camera_ang; + ang = *nang + buildang(pp->circle_camera_ang); // Calculate the vector (nx,ny,nz) to shoot backwards - vx = (sintable[NORM_ANGLE(ang + 1536)] >> 4); - vy = (sintable[NORM_ANGLE(ang + 1024)] >> 4); + vx = (sintable[NORM_ANGLE(ang.asbuild() + 1536)] >> 4); + vy = (sintable[NORM_ANGLE(ang.asbuild() + 1024)] >> 4); // lengthen the vector some vx += DIV2(vx); vy += DIV2(vy); - vz = (q16horiz - IntToFixed(100)) >> 8; + vz = q16horiz >> 8; // Player sprite of current view sp = &sprite[pp->PlayerSprite]; @@ -1131,7 +1131,7 @@ CircleCamera(int *nx, int *ny, int *nz, short *vsect, int *nq16ang, fixed_t q16h flag_backup = hsp->cstat; RESET(hsp->cstat, CSTAT_SPRITE_BLOCK|CSTAT_SPRITE_BLOCK_HITSCAN); - CircleCamera(nx, ny, nz, vsect, nq16ang, q16horiz); + CircleCamera(nx, ny, nz, vsect, nang, q16horiz); hsp->cstat = flag_backup; return; } @@ -1160,7 +1160,7 @@ CircleCamera(int *nx, int *ny, int *nz, short *vsect, int *nq16ang, fixed_t q16h // Make sure vsect is correct updatesectorz(*nx, *ny, *nz, vsect); - *nq16ang = IntToFixed(ang); + *nang = ang; } FString GameInterface::GetCoordString() @@ -1170,7 +1170,7 @@ FString GameInterface::GetCoordString() out.AppendFormat("POSX:%d ", pp->posx); out.AppendFormat("POSY:%d ", pp->posy); out.AppendFormat("POSZ:%d ", pp->posz); - out.AppendFormat("ANG:%d\n", FixedToInt(pp->q16ang)); + out.AppendFormat("ANG:%d\n", pp->angle.ang.asbuild()); return out; } @@ -1256,14 +1256,14 @@ void DrawCrosshair(PLAYERp pp) if (!(CameraTestMode)) { USERp u = User[pp->PlayerSprite]; - ::DrawCrosshair(2326, u->Health, -getHalfLookAng(pp->oq16look_ang, pp->q16look_ang, cl_syncinput, smoothratio), TEST(pp->Flags, PF_VIEW_FROM_OUTSIDE) ? 5 : 0, 2, shadeToLight(10)); + ::DrawCrosshair(2326, u->Health, -getHalfLookAng(pp->angle.olook_ang.asq16(), pp->angle.look_ang.asq16(), cl_syncinput, smoothratio), TEST(pp->Flags, PF_VIEW_FROM_OUTSIDE) ? 5 : 0, 2, shadeToLight(10)); } } -void CameraView(PLAYERp pp, int *tx, int *ty, int *tz, short *tsectnum, fixed_t *tq16ang, fixed_t *tq16horiz) +void CameraView(PLAYERp pp, int *tx, int *ty, int *tz, short *tsectnum, binangle *tang, fixedhoriz *thoriz) { int i,nexti; - short ang; + binangle ang; SPRITEp sp; bool found_camera = false; bool player_in_camera = false; @@ -1276,8 +1276,8 @@ void CameraView(PLAYERp pp, int *tx, int *ty, int *tz, short *tsectnum, fixed_t { sp = &sprite[i]; - ang = getangle(*tx - sp->x, *ty - sp->y); - ang_test = getincangle(ang, sp->ang) < sp->lotag; + ang = q16ang(gethiq16angle(*tx - sp->x, *ty - sp->y)); + ang_test = getincangle(ang.asbuild(), sp->ang) < sp->lotag; FAFcansee_test = (FAFcansee(sp->x, sp->y, sp->z, sp->sectnum, *tx, *ty, *tz, pp->cursectnum) || @@ -1301,7 +1301,7 @@ void CameraView(PLAYERp pp, int *tx, int *ty, int *tz, short *tsectnum, fixed_t { case 1: pp->last_camera_sp = sp; - CircleCamera(tx, ty, tz, tsectnum, tq16ang, IntToFixed(100)); + CircleCamera(tx, ty, tz, tsectnum, tang, 0); found_camera = true; break; @@ -1311,8 +1311,8 @@ void CameraView(PLAYERp pp, int *tx, int *ty, int *tz, short *tsectnum, fixed_t pp->last_camera_sp = sp; - xvect = sintable[NORM_ANGLE(ang + 512)] >> 3; - yvect = sintable[NORM_ANGLE(ang)] >> 3; + xvect = sintable[NORM_ANGLE(ang.asbuild() + 512)] >> 3; + yvect = sintable[NORM_ANGLE(ang.asbuild())] >> 3; zdiff = sp->z - *tz; if (labs(sp->x - *tx) > 1000) @@ -1327,14 +1327,12 @@ void CameraView(PLAYERp pp, int *tx, int *ty, int *tz, short *tsectnum, fixed_t zvect = 0; // new horiz to player - *tq16horiz = IntToFixed(100) - (zvect << 8); - *tq16horiz = max(*tq16horiz, IntToFixed(PLAYER_HORIZ_MIN)); - *tq16horiz = min(*tq16horiz, IntToFixed(PLAYER_HORIZ_MAX)); + *thoriz = q16horiz(clamp(-(zvect << 8), gi->playerHorizMin(), gi->playerHorizMax())); - //DSPRINTF(ds,"xvect %d,yvect %d,zvect %d,tq16horiz %d",xvect,yvect,zvect,*tq16horiz); + //DSPRINTF(ds,"xvect %d,yvect %d,zvect %d,thoriz %d",xvect,yvect,zvect,*thoriz.asbuild()); MONO_PRINT(ds); - *tq16ang = IntToFixed(ang); + *tang = ang; *tx = sp->x; *ty = sp->y; *tz = sp->z; @@ -1605,7 +1603,9 @@ drawscreen(PLAYERp pp, double smoothratio) { extern bool CameraTestMode; int tx, ty, tz; - fixed_t tq16horiz, tq16ang, tq16rotscrnang; + lookangle trotscrnang; + binangle tang; + fixedhoriz thoriz; short tsectnum; short i,j; int bob_amt = 0; @@ -1648,22 +1648,19 @@ drawscreen(PLAYERp pp, double smoothratio) // This isn't needed for the turret as it was fixable, but moving sector objects are problematic. if (cl_syncinput || pp != Player+myconnectindex) { - fixed_t dang = IntToFixed(1024); - fixed_t oang = camerapp->oq16ang + camerapp->oq16look_ang; - fixed_t ang = camerapp->q16ang + camerapp->q16look_ang; - tq16ang = oang + xs_CRoundToInt(fmulscale16(NORM_Q16ANGLE(ang + dang - oang) - dang, smoothratio)); - tq16horiz = camerapp->oq16horiz + xs_CRoundToInt(fmulscale16(camerapp->q16horiz - camerapp->oq16horiz, smoothratio)); - tq16rotscrnang = camerapp->oq16rotscrnang + xs_CRoundToInt(fmulscale16(NORM_Q16ANGLE(camerapp->q16rotscrnang + dang - camerapp->oq16rotscrnang) - dang, smoothratio)); + tang = camerapp->angle.interpolatedsum(smoothratio); + thoriz = camerapp->horizon.interpolatedsum(smoothratio); + trotscrnang = camerapp->angle.interpolatedrotscrn(smoothratio); } else { - tq16ang = pp->q16ang + pp->q16look_ang; - tq16horiz = pp->q16horiz; - tq16rotscrnang = pp->q16rotscrnang; + tang = pp->angle.sum(); + thoriz = pp->horizon.sum(); + trotscrnang = pp->angle.rotscrnang; } tsectnum = camerapp->cursectnum; - renderSetRollAngle(FixedToFloat(tq16rotscrnang)); + renderSetRollAngle(trotscrnang.asbam() / (double)BAMUNIT); COVERupdatesector(tx, ty, &tsectnum); @@ -1684,7 +1681,7 @@ drawscreen(PLAYERp pp, double smoothratio) tx = pp->posx; ty = pp->posy; tz = pp->posz; - tq16ang = pp->q16ang; + tang = pp->angle.ang; } tsectnum = pp->cursectnum; updatesectorz(tx, ty, tz, &tsectnum); @@ -1693,32 +1690,32 @@ drawscreen(PLAYERp pp, double smoothratio) pp->six = tx; pp->siy = ty; pp->siz = tz - pp->posz; - pp->siang = FixedToInt(tq16ang); + pp->siang = tang.asbuild(); QuakeViewChange(camerapp, &quake_z, &quake_x, &quake_y, &quake_ang); VisViewChange(camerapp, &g_visibility); tz = tz + quake_z; tx = tx + quake_x; ty = ty + quake_y; - //tq16horiz = tq16horiz + IntToFixed(quake_x); - tq16ang = NORM_Q16ANGLE(tq16ang + IntToFixed(quake_ang)); + //thoriz += buildhoriz(quake_x); + tang += buildang(quake_ang); if (pp->sop_remote) { if (TEST_BOOL1(pp->remote_sprite)) - tq16ang = IntToFixed(pp->remote_sprite->ang); + tang = buildang(pp->remote_sprite->ang); else - tq16ang = gethiq16angle(pp->sop_remote->xmid - tx, pp->sop_remote->ymid - ty); + tang = q16ang(gethiq16angle(pp->sop_remote->xmid - tx, pp->sop_remote->ymid - ty)); } if (TEST(pp->Flags, PF_VIEW_FROM_OUTSIDE)) { tz -= 8448; - if (!BackView(&tx, &ty, &tz, &tsectnum, &tq16ang, tq16horiz)) + if (!BackView(&tx, &ty, &tz, &tsectnum, &tang, thoriz.asq16())) { tz += 8448; - BackView(&tx, &ty, &tz, &tsectnum, &tq16ang, tq16horiz); + BackView(&tx, &ty, &tz, &tsectnum, &tang, thoriz.asq16()); } } else @@ -1727,7 +1724,7 @@ drawscreen(PLAYERp pp, double smoothratio) if (CameraTestMode) { - CameraView(camerapp, &tx, &ty, &tz, &tsectnum, &tq16ang, &tq16horiz); + CameraView(camerapp, &tx, &ty, &tz, &tsectnum, &tang, &thoriz); } } @@ -1740,9 +1737,7 @@ drawscreen(PLAYERp pp, double smoothratio) } // recoil only when not in camera - tq16horiz = tq16horiz + pp->recoil_horizoff; - tq16horiz = max(tq16horiz, IntToFixed(PLAYER_HORIZ_MIN)); - tq16horiz = min(tq16horiz, IntToFixed(PLAYER_HORIZ_MAX)); + thoriz = q16horiz(clamp(thoriz.asq16() + pp->recoil_horizoff, gi->playerHorizMin(), gi->playerHorizMax())); } if (automapMode != am_full)// && !ScreenSavePic) @@ -1755,20 +1750,20 @@ drawscreen(PLAYERp pp, double smoothratio) videoSetCorrectedAspect(); renderSetAspect(xs_CRoundToInt(double(viewingrange)* tan(r_fov* (PI / 360.))), yxaspect); OverlapDraw = true; - DrawOverlapRoom(tx, ty, tz, tq16ang, tq16horiz, tsectnum); + DrawOverlapRoom(tx, ty, tz, tang.asq16(), thoriz.asq16(), tsectnum); OverlapDraw = false; if (automapMode != am_full)// && !ScreenSavePic) { // TEST this! Changed to camerapp - //JS_DrawMirrors(camerapp, tx, ty, tz, tq16ang, tq16horiz); - JS_DrawMirrors(pp, tx, ty, tz, tq16ang, tq16horiz); + //JS_DrawMirrors(camerapp, tx, ty, tz, tang.asq16(), thoriz.asq16()); + JS_DrawMirrors(pp, tx, ty, tz, tang.asq16(), thoriz.asq16()); } // TODO: This call is redundant if the tiled overhead map is shown, but the // HUD elements should be properly outputted with hardware rendering first. if (!FAF_DebugView) - FAF_DrawRooms(tx, ty, tz, tq16ang, tq16horiz, tsectnum); + FAF_DrawRooms(tx, ty, tz, tang.asq16(), thoriz.asq16(), tsectnum); analyzesprites(tx, ty, tz, false); post_analyzesprites(); @@ -1816,7 +1811,7 @@ drawscreen(PLAYERp pp, double smoothratio) } } } - DrawOverheadMap(tx, ty, FixedToInt(tq16ang)); + DrawOverheadMap(tx, ty, tang.asbuild()); } for (j = 0; j < MAXSPRITES; j++) diff --git a/source/sw/src/game.cpp b/source/sw/src/game.cpp index e90e16148..834470143 100644 --- a/source/sw/src/game.cpp +++ b/source/sw/src/game.cpp @@ -350,7 +350,7 @@ void InitLevel(MapRecord *maprec) currentLevel = maprec; SECRET_SetMapName(currentLevel->DisplayName(), currentLevel->name); STAT_NewLevel(currentLevel->fileName); - Player[0].q16ang = IntToFixed(ang); + Player[0].angle.ang = buildang(ang); SetupPreCache(); diff --git a/source/sw/src/game.h b/source/sw/src/game.h index df7ef09df..b106e7372 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -356,11 +356,11 @@ int StdRandomRange(int range); #define KENFACING_PLAYER(pp,sp) (sintable[NORM_ANGLE(sp->ang+512)]*(pp->posy-sp->y) >= sintable[NORM_ANGLE(sp-ang)]*(pp->posx-sp->x)) #define FACING_PLAYER(pp,sp) (abs(getincangle(getangle((pp)->posx - (sp)->x, (pp)->posy - (sp)->y), (sp)->ang)) < 512) -#define PLAYER_FACING(pp,sp) (abs(getincangle(getangle((sp)->x - (pp)->posx, (sp)->y - (pp)->posy), FixedToInt((pp)->q16ang))) < 320) +#define PLAYER_FACING(pp,sp) (abs(getincangle(getangle((sp)->x - (pp)->posx, (sp)->y - (pp)->posy), (pp)->angle.ang.asbuild())) < 320) #define FACING(sp1,sp2) (abs(getincangle(getangle((sp1)->x - (sp2)->x, (sp1)->y - (sp2)->y), (sp2)->ang)) < 512) #define FACING_PLAYER_RANGE(pp,sp,range) (abs(getincangle(getangle((pp)->posx - (sp)->x, (pp)->posy - (sp)->y), (sp)->ang)) < (range)) -#define PLAYER_FACING_RANGE(pp,sp,range) (abs(getincangle(getangle((sp)->x - (pp)->posx, (sp)->y - (pp)->posy), FixedToInt((pp)->q16ang))) < (range)) +#define PLAYER_FACING_RANGE(pp,sp,range) (abs(getincangle(getangle((sp)->x - (pp)->posx, (sp)->y - (pp)->posy), (pp)->angle.ang.asbuild())) < (range)) #define FACING_RANGE(sp1,sp2,range) (abs(getincangle(getangle((sp1)->x - (sp2)->x, (sp1)->y - (sp2)->y), (sp2)->ang)) < (range)) // two vectors @@ -829,10 +829,7 @@ struct PLAYERstruct // variable that fit in the sprite or user structure int32_t posx, posy, posz; // interpolation - int - oposx, oposy, oposz; - fixed_t oq16horiz, oq16ang; - fixed_t oq16look_ang, oq16rotscrnang; + int oposx, oposy, oposz; // holds last valid move position short lv_sectnum; @@ -864,7 +861,7 @@ struct PLAYERstruct int slide_xvect, slide_yvect; short slide_ang; int slide_dec; - int drive_q16avel; + float drive_avel; @@ -882,8 +879,8 @@ struct PLAYERstruct // variables that do not fit into sprite structure int hvel,tilt,tilt_dest; - fixed_t q16horiz, q16horizbase, q16horizoff, q16ang; - fixed_t q16look_ang, q16rotscrnang; + PlayerHorizon horizon; + PlayerAngle angle; short recoil_amt; short recoil_speed; short recoil_ndx; @@ -892,7 +889,7 @@ struct PLAYERstruct int oldposx,oldposy,oldposz; int RevolveX, RevolveY; short RevolveDeltaAng; - fixed_t RevolveQ16Ang; + binangle RevolveAng; // under vars are for wading and swimming short PlayerSprite, PlayerUnderSprite; @@ -1008,10 +1005,6 @@ struct PLAYERstruct int cookieTime; char WpnReloadState; - - // Input helper variables. - double horizAdjust, angAdjust; - fixed_t horizTarget, angTarget; }; extern PLAYER Player[MAX_SW_PLAYERS_REG+1]; diff --git a/source/sw/src/input.cpp b/source/sw/src/input.cpp index fdd8d2e7f..f711d8283 100644 --- a/source/sw/src/input.cpp +++ b/source/sw/src/input.cpp @@ -34,10 +34,10 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms BEGIN_SW_NS -void DoPlayerHorizon(PLAYERp pp, fixed_t const q16horz, double const scaleAdjust); -void DoPlayerTurn(PLAYERp pp, fixed_t const q16avel, double const scaleAdjust); -void DoPlayerTurnVehicle(PLAYERp pp, fixed_t q16avel, int z, int floor_dist); -void DoPlayerTurnTurret(PLAYERp pp, fixed_t q16avel); +void DoPlayerHorizon(PLAYERp pp, float const horz, double const scaleAdjust); +void DoPlayerTurn(PLAYERp pp, float const avel, double const scaleAdjust); +void DoPlayerTurnVehicle(PLAYERp pp, float avel, int z, int floor_dist); +void DoPlayerTurnTurret(PLAYERp pp, float avel); static InputPacket loc; static int32_t turnheldtime; @@ -212,30 +212,31 @@ void GameInterface::GetInput(InputPacket *packet, ControlInfo* const hidInput) { if (TEST(pp->Flags2, PF2_INPUT_CAN_AIM)) { - DoPlayerHorizon(pp, input.q16horz, scaleAdjust); + DoPlayerHorizon(pp, input.horz, scaleAdjust); } if (TEST(pp->Flags2, PF2_INPUT_CAN_TURN_GENERAL)) { - DoPlayerTurn(pp, input.q16avel, scaleAdjust); + DoPlayerTurn(pp, input.avel, scaleAdjust); } if (TEST(pp->Flags2, PF2_INPUT_CAN_TURN_VEHICLE)) { - DoPlayerTurnVehicle(pp, input.q16avel, pp->posz + Z(10), labs(pp->posz + Z(10) - pp->sop->floor_loz)); + DoPlayerTurnVehicle(pp, input.avel, pp->posz + Z(10), labs(pp->posz + Z(10) - pp->sop->floor_loz)); } if (TEST(pp->Flags2, PF2_INPUT_CAN_TURN_TURRET)) { - DoPlayerTurnTurret(pp, input.q16avel); + DoPlayerTurnTurret(pp, input.avel); } - playerProcessHelpers(&pp->q16ang, &pp->angAdjust, &pp->angTarget, &pp->q16horiz, &pp->horizAdjust, &pp->horizTarget, scaleAdjust); + pp->angle.processhelpers(scaleAdjust); + pp->horizon.processhelpers(scaleAdjust); } if (packet) { - auto const ang = FixedToInt(pp->q16ang); + auto const ang = pp->angle.ang.asbuild(); *packet = loc; diff --git a/source/sw/src/jsector.cpp b/source/sw/src/jsector.cpp index a9384c6ed..3680c5a51 100644 --- a/source/sw/src/jsector.cpp +++ b/source/sw/src/jsector.cpp @@ -685,14 +685,10 @@ void JS_DrawCameras(PLAYERp pp, int tx, int ty, int tz) // 100! if (SP_TAG7(sp) != 0) { - camhoriz = SP_TAG7(sp); - if (camhoriz > PLAYER_HORIZ_MAX) - camhoriz = PLAYER_HORIZ_MAX; - else if (camhoriz < PLAYER_HORIZ_MIN) - camhoriz = PLAYER_HORIZ_MIN; + camhoriz = clamp(SP_TAG7(sp), gi->playerHorizMin(), gi->playerHorizMax()); } else - camhoriz = 100; // Default + camhoriz = 0; // Default // If player is dead still then update at MoveSkip4 // rate. @@ -710,7 +706,7 @@ void JS_DrawCameras(PLAYERp pp, int tx, int ty, int tz) if (TEST_BOOL11(sp) && numplayers > 1) { - drawroomstotile(cp->posx, cp->posy, cp->posz, cp->q16ang, cp->q16horiz, cp->cursectnum, mirror[cnt].campic); + drawroomstotile(cp->posx, cp->posy, cp->posz, cp->angle.ang.asq16(), cp->horizon.horiz.asq16(), cp->cursectnum, mirror[cnt].campic); } else { @@ -762,7 +758,7 @@ void JS_DrawMirrors(PLAYERp pp, int tx, int ty, int tz, fixed_t tpq16ang, fixed // tx = pp->oposx + mulscale16(pp->posx - pp->oposx, smoothratio); // ty = pp->oposy + mulscale16(pp->posy - pp->oposy, smoothratio); // tz = pp->oposz + mulscale16(pp->posz - pp->oposz, smoothratio); -// tpq16ang = pp->q16ang; +// tpq16ang = pp->angle.ang.asq16(); dist = 0x7fffffff; diff --git a/source/sw/src/jweapon.cpp b/source/sw/src/jweapon.cpp index 4429ffded..311079a0c 100644 --- a/source/sw/src/jweapon.cpp +++ b/source/sw/src/jweapon.cpp @@ -1388,7 +1388,7 @@ PlayerInitChemBomb(PLAYERp pp) // Spawn a shot // Inserting and setting up variables w = SpawnSprite(STAT_MISSILE, CHEMBOMB, s_ChemBomb, pp->cursectnum, - nx, ny, nz, FixedToInt(pp->q16ang), CHEMBOMB_VELOCITY); + nx, ny, nz, pp->angle.ang.asbuild(), CHEMBOMB_VELOCITY); wp = &sprite[w]; wu = User[w]; @@ -1418,10 +1418,10 @@ PlayerInitChemBomb(PLAYERp pp) if (TEST(pp->Flags, PF_DIVING) || SpriteInUnderwaterArea(wp)) SET(wu->Flags, SPR_UNDERWATER); - wp->zvel = (IntToFixed(100) - pp->q16horiz) >> 9; + wp->zvel = -pp->horizon.horiz.asq16() >> 9; - // //DSPRINTF(ds,"horiz %d, ho %d, ho+ho %d",FixedToInt(pp->q16horiz), FixedToInt(pp->q16horizoff), - // FixedToInt(pp->q16horizoff + pp->q16horiz)); + // //DSPRINTF(ds,"horiz %d, ho %d, ho+ho %d", pp->horizon.horiz.asbuild(), pp->horizon.horizoff.asbuild(), + // pp->horizon.horizoff.asbuild() + pp->horizon.horiz.asbuild()); // MONO_PRINT(ds); oclipdist = pp->SpriteP->clipdist; @@ -1489,7 +1489,7 @@ InitSpriteChemBomb(int16_t SpriteNum) SET(wp->cstat, CSTAT_SPRITE_YCENTER); SET(wp->cstat, CSTAT_SPRITE_BLOCK); - wp->zvel = ((-100 - RANDOM_RANGE(100)) * HORIZ_MULT); + wp->zvel = -RANDOM_RANGE(100) * HORIZ_MULT; wp->clipdist = 80L >> 2; @@ -1551,7 +1551,7 @@ InitChemBomb(short SpriteNum) if (SpriteInUnderwaterArea(wp)) SET(wu->Flags, SPR_UNDERWATER); - wp->zvel = ((-100 - RANDOM_RANGE(100)) * HORIZ_MULT); + wp->zvel = -RANDOM_RANGE(100) * HORIZ_MULT; wp->clipdist = 0; if (u->ID == MUSHROOM_CLOUD || u->ID == 3121 || u->ID == SUMO_RUN_R0) // 3121 == GRENADE_EXP @@ -1832,7 +1832,7 @@ PlayerInitCaltrops(PLAYERp pp) // Spawn a shot // Inserting and setting up variables w = SpawnSprite(STAT_DEAD_ACTOR, CALTROPS, s_Caltrops, pp->cursectnum, - nx, ny, nz, FixedToInt(pp->q16ang), (CHEMBOMB_VELOCITY + RANDOM_RANGE(CHEMBOMB_VELOCITY)) / 2); + nx, ny, nz, pp->angle.ang.asbuild(), (CHEMBOMB_VELOCITY + RANDOM_RANGE(CHEMBOMB_VELOCITY)) / 2); wp = &sprite[w]; wu = User[w]; @@ -1860,9 +1860,9 @@ PlayerInitCaltrops(PLAYERp pp) SET(wu->Flags, SPR_UNDERWATER); // They go out at different angles -// wp->ang = NORM_ANGLE(FixedToInt(pp->q16ang) + (RANDOM_RANGE(50) - 25)); +// wp->ang = NORM_ANGLE(pp->angle.ang.asbuild() + (RANDOM_RANGE(50) - 25)); - wp->zvel = (IntToFixed(100) - pp->q16horiz) >> 9; + wp->zvel = -pp->horizon.horiz.asq16() >> 9; oclipdist = pp->SpriteP->clipdist; pp->SpriteP->clipdist = 0; @@ -1928,7 +1928,7 @@ InitCaltrops(int16_t SpriteNum) wu->floor_dist = Z(3); wu->Counter = 0; - wp->zvel = ((-100 - RANDOM_RANGE(100)) * HORIZ_MULT); + wp->zvel = -RANDOM_RANGE(100) * HORIZ_MULT; // wp->clipdist = 80L>>2; @@ -1990,7 +1990,7 @@ InitPhosphorus(int16_t SpriteNum) wu->floor_dist = Z(3); wu->Counter = 0; - wp->zvel = ((-100 - RANDOM_RANGE(100)) * HORIZ_MULT); + wp->zvel = -RANDOM_RANGE(100) * HORIZ_MULT; wu->xchange = MOVEx(wp->xvel, wp->ang); wu->ychange = MOVEy(wp->xvel, wp->ang); @@ -2496,7 +2496,7 @@ InitShell(int16_t SpriteNum, int16_t ShellNum) if (u->PlayerP) { - wp->z += xs_CRoundToInt((IntToFixed(100) - u->PlayerP->q16horiz) * ((HORIZ_MULT / 3.) / FRACUNIT)); + wp->z += xs_CRoundToInt(-fmulscale16(u->PlayerP->horizon.horiz.asq16(), HORIZ_MULT / 3.)); } switch (wu->ID) diff --git a/source/sw/src/mclip.cpp b/source/sw/src/mclip.cpp index ca6a1d616..48068a5c6 100644 --- a/source/sw/src/mclip.cpp +++ b/source/sw/src/mclip.cpp @@ -60,7 +60,7 @@ int MultiClipMove(PLAYERp pp, int z, int floor_dist) { // move the box to position instead of using offset- this prevents small rounding errors // allowing you to move through wall - ang = NORM_ANGLE(FixedToInt(pp->q16ang) + sop->clipbox_ang[i]); + ang = NORM_ANGLE(pp->angle.ang.asbuild() + sop->clipbox_ang[i]); xs = pp->posx; ys = pp->posy; diff --git a/source/sw/src/ninja.cpp b/source/sw/src/ninja.cpp index 2c75f5d07..dc30970b1 100644 --- a/source/sw/src/ninja.cpp +++ b/source/sw/src/ninja.cpp @@ -2398,7 +2398,7 @@ InitPlayerSprite(PLAYERp pp) COVER_SetReverb(0); // Turn off any echoing that may have been going before pp->Reverb = 0; sp_num = pp->PlayerSprite = SpawnSprite(STAT_PLAYER0 + pnum, NINJA_RUN_R0, NULL, pp->cursectnum, pp->posx, - pp->posy, pp->posz, FixedToInt(pp->q16ang), 0); + pp->posy, pp->posz, pp->angle.ang.asbuild(), 0); pp->SpriteP = sp = &sprite[sp_num]; pp->pnum = pnum; @@ -2473,7 +2473,7 @@ SpawnPlayerUnderSprite(PLAYERp pp) int pnum = pp - Player, sp_num; sp_num = pp->PlayerUnderSprite = SpawnSprite(STAT_PLAYER_UNDER0 + pnum, - NINJA_RUN_R0, NULL, pp->cursectnum, pp->posx, pp->posy, pp->posz, FixedToInt(pp->q16ang), 0); + NINJA_RUN_R0, NULL, pp->cursectnum, pp->posx, pp->posy, pp->posz, pp->angle.ang.asbuild(), 0); sp = &sprite[sp_num]; u = User[sp_num]; diff --git a/source/sw/src/osdcmds.cpp b/source/sw/src/osdcmds.cpp index c83f51c97..9d5e3bf1a 100644 --- a/source/sw/src/osdcmds.cpp +++ b/source/sw/src/osdcmds.cpp @@ -59,12 +59,12 @@ static int osdcmd_warptocoords(CCmdFuncPtr parm) if (parm->numparms >= 4) { - Player->oq16ang = Player->q16ang = IntToFixed(atoi(parm->parms[3])); + Player->angle.oang = Player->angle.ang = buildang(atoi(parm->parms[3])); } if (parm->numparms == 5) { - Player->oq16horiz = Player->q16horiz = IntToFixed(atoi(parm->parms[4])); + Player->horizon.ohoriz = Player->horizon.horiz = buildhoriz(atoi(parm->parms[4])); } return CCMD_OK; diff --git a/source/sw/src/panel.cpp b/source/sw/src/panel.cpp index 3b7582bcd..b80ddc564 100644 --- a/source/sw/src/panel.cpp +++ b/source/sw/src/panel.cpp @@ -6921,7 +6921,7 @@ pDisplaySprites(PLAYERp pp, double smoothratio) short ang; int flags; - double look_anghalf = getHalfLookAng(pp->oq16look_ang, pp->q16look_ang, cl_syncinput, smoothratio); + double look_anghalf = getHalfLookAng(pp->angle.olook_ang.asq16(), pp->angle.look_ang.asq16(), cl_syncinput, smoothratio); double looking_arc = fabs(look_anghalf) / 4.5; TRAVERSE(&pp->PanelSpriteList, psp, next) diff --git a/source/sw/src/player.cpp b/source/sw/src/player.cpp index feca8c111..868e10502 100644 --- a/source/sw/src/player.cpp +++ b/source/sw/src/player.cpp @@ -1073,8 +1073,8 @@ STATEp sg_PlayerNinjaFly[] = static void resetinputhelpers(PLAYERp pp) { - pp->horizAdjust = 0; - pp->angAdjust = 0; + pp->angle.resetadjustment(); + pp->horizon.resetadjustment(); } void @@ -1211,7 +1211,7 @@ DoPickTarget(SPRITEp sp, uint32_t max_delta_ang, int skip_targets) angle2 = NORM_ANGLE(getangle(ep->x - sp->x, ep->y - sp->y)); // Get the angle difference - // delta_ang = labs(FixedToInt(pp->q16ang) - angle2); + // delta_ang = labs(pp->angle.ang.asbuild() - angle2); delta_ang = labs(getincangle(angle2, sp->ang)); @@ -1282,7 +1282,7 @@ DoPlayerResetMovement(PLAYERp pp) pp->yvect = pp->oxvect = 0; pp->slide_xvect = 0; pp->slide_yvect = 0; - pp->drive_q16avel = 0; + pp->drive_avel = 0; RESET(pp->Flags, PF_PLAYER_MOVED); } @@ -1314,7 +1314,7 @@ DoPlayerTeleportPause(PLAYERp pp) void DoPlayerTeleportToSprite(PLAYERp pp, SPRITEp sp) { - pp->q16ang = pp->oq16ang = IntToFixed(sp->ang); + pp->angle.ang = pp->angle.oang = buildang(sp->ang); pp->posx = pp->oposx = pp->oldposx = sp->x; pp->posy = pp->oposy = pp->oldposy = sp->y; @@ -1520,70 +1520,71 @@ DoPlayerCrawlHeight(PLAYERp pp) void UpdatePlayerSpriteAngle(PLAYERp pp) { - sprite[pp->PlayerSprite].ang = FixedToInt(pp->q16ang); + sprite[pp->PlayerSprite].ang = pp->angle.ang.asbuild(); if (!Prediction && pp->PlayerUnderSprite >= 0) { - sprite[pp->PlayerUnderSprite].ang = FixedToInt(pp->q16ang); + sprite[pp->PlayerUnderSprite].ang = pp->angle.ang.asbuild(); } } void -DoPlayerTurn(PLAYERp pp, fixed_t const q16avel, double const scaleAdjust) +DoPlayerTurn(PLAYERp pp, float const avel, double const scaleAdjust) { - applylook(&pp->q16ang, &pp->q16look_ang, &pp->q16rotscrnang, &pp->turn180_target, q16avel, &pp->input.actions, scaleAdjust, pp->input.actions & (SB_CROUCH|SB_CROUCH_LOCK)); + applylook(&pp->angle, avel, &pp->input.actions, scaleAdjust, pp->input.actions & (SB_CROUCH|SB_CROUCH_LOCK)); UpdatePlayerSpriteAngle(pp); } #if 0 void -DoPlayerTurnBoat(PLAYERp pp, fixed_t q16avel) +DoPlayerTurnBoat(PLAYERp pp, float avel) { SECTOR_OBJECTp sop = pp->sop; if (sop->drive_angspeed) { - fixed_t drive_oq16avel = pp->drive_q16avel; - pp->drive_q16avel = (mulscale16(q16avel, sop->drive_angspeed) + (drive_oq16avel * (sop->drive_angslide - 1))) / sop->drive_angslide; + float drive_oavel = pp->drive_avel; + pp->drive_avel = (fmulscale16(avel, sop->drive_angspeed) + (drive_oavel * (sop->drive_angslide - 1))) / sop->drive_angslide; - q16avel = pp->drive_q16avel; + avel = pp->drive_avel; } else { - q16avel = xs_CRoundToInt(q16avel * 1.4); + avel *= 1.4; } - if (q16avel != 0) + if (avel != 0) { - pp->q16ang = (pp->q16ang + q16avel) & 0x7FFFFFF; - sprite[pp->PlayerSprite].ang = FixedToInt(pp->q16ang); + pp->angle.ang += degang(avel); + sprite[pp->PlayerSprite].ang = pp->angle.ang.asbuild(); } } #endif void -DoPlayerTurnVehicle(PLAYERp pp, fixed_t q16avel, int z, int floor_dist) +DoPlayerTurnVehicle(PLAYERp pp, float avel, int z, int floor_dist) { SECTOR_OBJECTp sop = pp->sop; if (sop->drive_angspeed) { - fixed_t drive_oq16avel = pp->drive_q16avel; - pp->drive_q16avel = (mulscale16(q16avel, sop->drive_angspeed) + (drive_oq16avel * (sop->drive_angslide - 1))) / sop->drive_angslide; + float drive_oavel = pp->drive_avel; + pp->drive_avel = (fmulscale16(avel, sop->drive_angspeed) + (drive_oavel * (sop->drive_angslide - 1))) / sop->drive_angslide; - q16avel = pp->drive_q16avel; + avel = pp->drive_avel; } else { - q16avel = DIV8(q16avel * synctics); + avel = avel * synctics * 0.125; } - if (q16avel != 0) + if (avel != 0) { - if (MultiClipTurn(pp, NORM_ANGLE(FixedToInt(pp->q16ang + q16avel)), z, floor_dist)) + auto sum = pp->angle.ang + degang(avel); + if (MultiClipTurn(pp, NORM_ANGLE(sum.asbuild()), z, floor_dist)) { - pp->q16ang = (pp->q16ang + q16avel) & 0x7FFFFFF; - sprite[pp->PlayerSprite].ang = FixedToInt(pp->q16ang); + pp->angle.ang = sum; + sprite[pp->PlayerSprite].ang = pp->angle.ang.asbuild(); } } } @@ -1591,71 +1592,73 @@ DoPlayerTurnVehicle(PLAYERp pp, fixed_t q16avel, int z, int floor_dist) void DoPlayerTurnVehicleRect(PLAYERp pp, int *x, int *y, int *ox, int *oy) { - fixed_t q16avel; + float avel; SECTOR_OBJECTp sop = pp->sop; if (sop->drive_angspeed) { - fixed_t drive_oq16avel = pp->drive_q16avel; - pp->drive_q16avel = (mulscale16(pp->input.q16avel, sop->drive_angspeed) + (drive_oq16avel * (sop->drive_angslide - 1))) / sop->drive_angslide; + float drive_oavel = pp->drive_avel; + pp->drive_avel = (fmulscale16(pp->input.avel, sop->drive_angspeed) + (drive_oavel * (sop->drive_angslide - 1))) / sop->drive_angslide; - q16avel = pp->drive_q16avel; + avel = pp->drive_avel; } else { - q16avel = DIV8(pp->input.q16avel * synctics); + avel = pp->input.avel * synctics * 0.125; } - if (q16avel != 0) + if (avel != 0) { - if (RectClipTurn(pp, NORM_ANGLE(FixedToInt(pp->q16ang + q16avel)), x, y, ox, oy)) + auto sum = pp->angle.ang + degang(avel); + if (RectClipTurn(pp, NORM_ANGLE(sum.asbuild()), x, y, ox, oy)) { - pp->q16ang = (pp->q16ang + q16avel) & 0x7FFFFFF; - sprite[pp->PlayerSprite].ang = FixedToInt(pp->q16ang); + pp->angle.ang = sum; + sprite[pp->PlayerSprite].ang = pp->angle.ang.asbuild(); } } } void -DoPlayerTurnTurret(PLAYERp pp, fixed_t q16avel) +DoPlayerTurnTurret(PLAYERp pp, float avel) { - fixed_t new_ang, diff; + fixed_t diff; + binangle new_ang; SECTOR_OBJECTp sop = pp->sop; if (sop->drive_angspeed) { - fixed_t drive_oq16avel = pp->drive_q16avel; - pp->drive_q16avel = (mulscale16(q16avel, sop->drive_angspeed) + (drive_oq16avel * (sop->drive_angslide - 1))) / sop->drive_angslide; + float drive_oavel = pp->drive_avel; + pp->drive_avel = (fmulscale16(avel, sop->drive_angspeed) + (drive_oavel * (sop->drive_angslide - 1))) / sop->drive_angslide; - q16avel = pp->drive_q16avel; + avel = pp->drive_avel; } else { - q16avel = DIV4(q16avel * synctics); + avel = avel * synctics * 0.25; } - if (q16avel != 0) + if (avel != 0) { - new_ang = (pp->q16ang + q16avel) & 0x7FFFFFF; + new_ang = pp->angle.ang + degang(avel); if (sop->limit_ang_center >= 0) { - diff = getincangleq16(IntToFixed(sop->limit_ang_center), new_ang); + diff = getincangleq16(IntToFixed(sop->limit_ang_center), new_ang.asq16()); if (labs(diff) >= IntToFixed(sop->limit_ang_delta)) { if (diff < 0) - new_ang = IntToFixed(sop->limit_ang_center - sop->limit_ang_delta); + new_ang = buildang(sop->limit_ang_center - sop->limit_ang_delta); else - new_ang = IntToFixed(sop->limit_ang_center + sop->limit_ang_delta); + new_ang = buildang(sop->limit_ang_center + sop->limit_ang_delta); } } - pp->q16ang = new_ang; - sprite[pp->PlayerSprite].ang = FixedToInt(pp->q16ang); + pp->angle.ang = new_ang; + sprite[pp->PlayerSprite].ang = pp->angle.ang.asbuild(); } - OperateSectorObject(pp->sop, FixedToInt(pp->q16ang), pp->sop->xmid, pp->sop->ymid); + OperateSectorObject(pp->sop, pp->angle.ang.asbuild(), pp->sop->xmid, pp->sop->ymid); } void SlipSlope(PLAYERp pp) @@ -1687,7 +1690,7 @@ PlayerAutoLook(PLAYERp pp, double const scaleAdjust) if (!TEST(pp->Flags, PF_MOUSE_AIMING_ON) && TEST(sector[pp->cursectnum].floorstat, FLOOR_STAT_SLOPE)) // If the floor is sloped { // Get a point, 512 units ahead of player's position - auto const ang = FixedToInt(pp->q16ang); + auto const ang = pp->angle.ang.asbuild(); x = pp->posx + (sintable[(ang + 512) & 2047] >> 5); y = pp->posy + (sintable[ang & 2047] >> 5); tempsect = pp->cursectnum; @@ -1707,51 +1710,42 @@ PlayerAutoLook(PLAYERp pp, double const scaleAdjust) // accordingly if ((pp->cursectnum == tempsect) || (klabs(getflorzofslope(tempsect, x, y) - k) <= (4 << 8))) { - pp->q16horizoff += xs_CRoundToInt(scaleAdjust * ((j - k) * 160)); + pp->horizon.horizoff += q16horiz(xs_CRoundToInt(scaleAdjust * ((j - k) * 160))); } } } } - if (TEST(pp->Flags, PF_CLIMBING) && pp->q16horizoff < IntToFixed(100)) + if (TEST(pp->Flags, PF_CLIMBING) && pp->horizon.horizoff.asq16() < IntToFixed(100)) { // tilt when climbing but you can't even really tell it. - pp->q16horizoff += xs_CRoundToInt(scaleAdjust * (((IntToFixed(100) - pp->q16horizoff) >> 3) + FRACUNIT)); + pp->horizon.horizoff += q16horiz(xs_CRoundToInt(scaleAdjust * (((IntToFixed(100) - pp->horizon.horizoff.asq16()) >> 3) + FRACUNIT))); } else { - // Make q16horizoff grow towards 0 since q16horizoff is not modified when you're not on a slope. - if (pp->q16horizoff > 0) + // Make horizoff grow towards 0 since horizoff is not modified when you're not on a slope. + if (pp->horizon.horizoff.asq16() > 0) { - pp->q16horizoff -= xs_CRoundToInt(scaleAdjust * ((pp->q16horizoff >> 3) + FRACUNIT)); - pp->q16horizoff = max(pp->q16horizoff, 0); + pp->horizon.horizoff -= q16horiz(xs_CRoundToInt(scaleAdjust * ((pp->horizon.horizoff.asq16() >> 3) + FRACUNIT))); + pp->horizon.horizoff = q16horiz(max(pp->horizon.horizoff.asq16(), 0)); } - if (pp->q16horizoff < 0) + if (pp->horizon.horizoff.asq16() < 0) { - pp->q16horizoff += xs_CRoundToInt(scaleAdjust * ((pp->q16horizoff >> 3) + FRACUNIT)); - pp->q16horizoff = min(pp->q16horizoff, 0); + pp->horizon.horizoff += q16horiz(xs_CRoundToInt(scaleAdjust * ((pp->horizon.horizoff.asq16() >> 3) + FRACUNIT))); + pp->horizon.horizoff = q16horiz(min(pp->horizon.horizoff.asq16(), 0)); } } } void -DoPlayerHorizon(PLAYERp pp, fixed_t const q16horz, double const scaleAdjust) +DoPlayerHorizon(PLAYERp pp, float const horz, double const scaleAdjust) { // Fixme: This should probably be made optional. if (cl_slopetilting) PlayerAutoLook(pp, scaleAdjust); // 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)) - pp->q16horizoff = IntToFixed(PLAYER_HORIZ_MIN) - pp->q16horizbase; - else if (pp->q16horizbase + pp->q16horizoff > IntToFixed(PLAYER_HORIZ_MAX)) - pp->q16horizoff = IntToFixed(PLAYER_HORIZ_MAX) - pp->q16horizbase; - - // add base and offsets - pp->q16horiz = pp->q16horizbase + pp->q16horizoff; + sethorizon(&pp->horizon.horiz, horz, &pp->input.actions, scaleAdjust); } void @@ -1937,7 +1931,7 @@ UpdatePlayerSprite(PLAYERp pp) if (TEST(pp->Flags, PF_DEAD)) { changespritesect(pp->PlayerSprite, pp->cursectnum); - sprite[pp->PlayerSprite].ang = FixedToInt(pp->q16ang); + sprite[pp->PlayerSprite].ang = pp->angle.ang.asbuild(); UpdatePlayerUnderSprite(pp); return; } @@ -2012,7 +2006,7 @@ UpdatePlayerSprite(PLAYERp pp) UpdatePlayerUnderSprite(pp); - sprite[pp->PlayerSprite].ang = FixedToInt(pp->q16ang); + sprite[pp->PlayerSprite].ang = pp->angle.ang.asbuild(); } void @@ -2180,7 +2174,7 @@ DoPlayerMove(PLAYERp pp) } else { - DoPlayerTurn(pp, pp->input.q16avel, 1); + DoPlayerTurn(pp, pp->input.avel, 1); } pp->oldposx = pp->posx; @@ -2289,7 +2283,7 @@ DoPlayerMove(PLAYERp pp) if (interpolate_ride) { pp->oposz = pp->posz; - pp->oq16ang = pp->q16ang; + pp->angle.backup(); } // check for warp - probably can remove from CeilingHit @@ -2308,7 +2302,7 @@ DoPlayerMove(PLAYERp pp) } else { - DoPlayerHorizon(pp, pp->input.q16horz, 1); + DoPlayerHorizon(pp, pp->input.horz, 1); } if (pp->cursectnum >= 0 && TEST(sector[pp->cursectnum].extra, SECTFX_DYNAMIC_AREA)) @@ -2469,7 +2463,7 @@ DoPlayerMoveBoat(PLAYERp pp) } else { - DoPlayerTurnBoat(pp, pp->input.q16avel); + DoPlayerTurnBoat(pp, pp->input.avel); } if (PLAYER_MOVING(pp) == 0) @@ -2509,13 +2503,13 @@ DoPlayerMoveBoat(PLAYERp pp) z = pp->posz + Z(10); save_sectnum = pp->cursectnum; - OperateSectorObject(pp->sop, FixedToInt(pp->q16ang), MAXSO, MAXSO); + OperateSectorObject(pp->sop, pp->angle.ang.asbuild(), MAXSO, MAXSO); pp->cursectnum = pp->sop->op_main_sector; // for speed floor_dist = labs(z - pp->sop->floor_loz); clipmove_old(&pp->posx, &pp->posy, &z, &pp->cursectnum, pp->xvect, pp->yvect, (int)pp->sop->clipdist, Z(4), floor_dist, CLIPMASK_PLAYER); - OperateSectorObject(pp->sop, FixedToInt(pp->q16ang), pp->posx, pp->posy); + OperateSectorObject(pp->sop, pp->angle.ang.asbuild(), pp->posx, pp->posy); pp->cursectnum = save_sectnum; // for speed if (!cl_syncinput) @@ -2524,7 +2518,7 @@ DoPlayerMoveBoat(PLAYERp pp) } else { - DoPlayerHorizon(pp, pp->input.q16horz, 1); + DoPlayerHorizon(pp, pp->input.horz, 1); } } #endif @@ -2543,7 +2537,7 @@ void DoTankTreads(PLAYERp pp) return; vel = FindDistance2D(pp->xvect>>8, pp->yvect>>8); - dot = DOT_PRODUCT_2D(pp->xvect, pp->yvect, sintable[NORM_ANGLE(FixedToInt(pp->q16ang)+512)], sintable[FixedToInt(pp->q16ang)]); + dot = DOT_PRODUCT_2D(pp->xvect, pp->yvect, sintable[NORM_ANGLE(pp->angle.ang.asbuild()+512)], sintable[pp->angle.ang.asbuild()]); if (dot < 0) reverse = true; @@ -2664,7 +2658,7 @@ DriveCrush(PLAYERp pp, int *x, int *y) return; // not moving - don't crush - if ((pp->xvect|pp->yvect) == 0 && pp->input.q16avel == 0) + if ((pp->xvect|pp->yvect) == 0 && pp->input.avel == 0) return; // main sector @@ -2770,7 +2764,7 @@ DriveCrush(PLAYERp pp, int *x, int *y) continue; damage = -(u->Health + 100); - PlayerDamageSlide(u->PlayerP, damage, FixedToInt(pp->q16ang)); + PlayerDamageSlide(u->PlayerP, damage, pp->angle.ang.asbuild()); PlayerUpdateHealth(u->PlayerP, damage); //PlayerCheckDeath(u->PlayerP, -1); PlayerCheckDeath(u->PlayerP, pp->PlayerSprite); @@ -2905,7 +2899,7 @@ DoPlayerMoveVehicle(PLAYERp pp) } save_sectnum = pp->cursectnum; - OperateSectorObject(pp->sop, FixedToInt(pp->q16ang), MAXSO, MAXSO); + OperateSectorObject(pp->sop, pp->angle.ang.asbuild(), MAXSO, MAXSO); pp->cursectnum = pp->sop->op_main_sector; // for speed floor_dist = labs(z - pp->sop->floor_loz); @@ -2935,7 +2929,7 @@ DoPlayerMoveVehicle(PLAYERp pp) hitscan(&hit_pos, pp->cursectnum, //pp->xvect, pp->yvect, 0, - MOVEx(256, FixedToInt(pp->q16ang)), MOVEy(256, FixedToInt(pp->q16ang)), 0, + MOVEx(256, pp->angle.ang.asbuild()), MOVEy(256, pp->angle.ang.asbuild()), 0, &hitinfo, CLIPMASK_PLAYER); ////DSPRINTF(ds,"hitinfo.sect %d, hitinfo.wall %d, hitinfo.pos.x %d, hitinfo.pos.y %d, hitinfo.pos.z %d",hitinfo.sect, hitinfo.wall, hitinfo.pos.x, hitinfo.pos.y, hitinfo.pos.z); @@ -2973,7 +2967,7 @@ DoPlayerMoveVehicle(PLAYERp pp) } else { - DoPlayerTurnVehicle(pp, pp->input.q16avel, z, floor_dist); + DoPlayerTurnVehicle(pp, pp->input.avel, z, floor_dist); } save_cstat = pp->SpriteP->cstat; @@ -3009,7 +3003,7 @@ DoPlayerMoveVehicle(PLAYERp pp) } } - OperateSectorObject(pp->sop, FixedToInt(pp->q16ang), pp->posx, pp->posy); + OperateSectorObject(pp->sop, pp->angle.ang.asbuild(), pp->posx, pp->posy); pp->cursectnum = save_sectnum; // for speed if (!cl_syncinput) @@ -3018,7 +3012,7 @@ DoPlayerMoveVehicle(PLAYERp pp) } else { - DoPlayerHorizon(pp, pp->input.q16horz, 1); + DoPlayerHorizon(pp, pp->input.horz, 1); } DoTankTreads(pp); @@ -3029,9 +3023,9 @@ DoPlayerMoveTurret(PLAYERp pp) { if (!Prediction) { - if (pp->input.q16avel && !pp->lastinput.q16avel) + if (pp->input.avel && !pp->lastinput.avel) PlaySOsound(pp->sop->mid_sector, SO_DRIVE_SOUND); - else if (!pp->input.q16avel && pp->lastinput.q16avel) + else if (!pp->input.avel && pp->lastinput.avel) PlaySOsound(pp->sop->mid_sector, SO_IDLE_SOUND); } @@ -3041,7 +3035,7 @@ DoPlayerMoveTurret(PLAYERp pp) } else { - DoPlayerTurnTurret(pp, pp->input.q16avel); + DoPlayerTurnTurret(pp, pp->input.avel); } if (PLAYER_MOVING(pp) == 0) @@ -3055,7 +3049,7 @@ DoPlayerMoveTurret(PLAYERp pp) } else { - DoPlayerHorizon(pp, pp->input.q16horz, 1); + DoPlayerHorizon(pp, pp->input.horz, 1); } } @@ -3479,7 +3473,7 @@ DoPlayerClimb(PLAYERp pp) pp->xvect = pp->yvect = 0; climbvel = FindDistance2D(pp->xvect, pp->yvect)>>9; - dot = DOT_PRODUCT_2D(pp->xvect, pp->yvect, sintable[NORM_ANGLE(FixedToInt(pp->q16ang)+512)], sintable[FixedToInt(pp->q16ang)]); + dot = DOT_PRODUCT_2D(pp->xvect, pp->yvect, sintable[NORM_ANGLE(pp->angle.ang.asbuild()+512)], sintable[pp->angle.ang.asbuild()]); if (dot < 0) climbvel = -climbvel; @@ -3634,7 +3628,7 @@ DoPlayerClimb(PLAYERp pp) } else { - DoPlayerHorizon(pp, pp->input.q16horz, 1); + DoPlayerHorizon(pp, pp->input.horz, 1); } if (FAF_ConnectArea(pp->cursectnum)) @@ -3656,7 +3650,7 @@ DoPlayerClimb(PLAYERp pp) // constantly look for new ladder sector because of warping at any time neartag(pp->posx, pp->posy, pp->posz, - pp->cursectnum, FixedToInt(pp->q16ang), + pp->cursectnum, pp->angle.ang.asbuild(), &sec, &wal, &spr, &dist, 800L, NTAG_SEARCH_LO_HI, NULL); @@ -3681,7 +3675,7 @@ DoPlayerClimb(PLAYERp pp) pp->lx = lsp->x + nx * 5; pp->ly = lsp->y + ny * 5; - playerSetAngle(&pp->q16ang, &pp->angTarget, pp->LadderAngle); + pp->angle.settarget(pp->LadderAngle); } } } @@ -3701,8 +3695,8 @@ DoPlayerWadeSuperJump(PLAYERp pp) for (i = 0; i < SIZ(angs); i++) { FAFhitscan(pp->posx, pp->posy, zh, pp->cursectnum, // Start position - sintable[NORM_ANGLE(FixedToInt(pp->q16ang) + angs[i] + 512)], // X vector of 3D ang - sintable[NORM_ANGLE(FixedToInt(pp->q16ang) + angs[i])], // Y vector of 3D ang + sintable[NORM_ANGLE(pp->angle.ang.asbuild() + angs[i] + 512)], // X vector of 3D ang + sintable[NORM_ANGLE(pp->angle.ang.asbuild() + angs[i])], // Y vector of 3D ang 0, // Z vector of 3D ang &hitinfo, CLIPMASK_MISSILE); @@ -4058,11 +4052,11 @@ PlayerOnLadder(PLAYERp pp) if (Prediction) return false; - neartag(pp->posx, pp->posy, pp->posz, pp->cursectnum, FixedToInt(pp->q16ang), + neartag(pp->posx, pp->posy, pp->posz, pp->cursectnum, pp->angle.ang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, 1024L+768L, NTAG_SEARCH_LO_HI, NULL); - dir = DOT_PRODUCT_2D(pp->xvect, pp->yvect, sintable[NORM_ANGLE(FixedToInt(pp->q16ang)+512)], sintable[FixedToInt(pp->q16ang)]); + dir = DOT_PRODUCT_2D(pp->xvect, pp->yvect, sintable[NORM_ANGLE(pp->angle.ang.asbuild()+512)], sintable[pp->angle.ang.asbuild()]); if (dir < 0) return false; @@ -4072,7 +4066,7 @@ PlayerOnLadder(PLAYERp pp) for (i = 0; i < SIZ(angles); i++) { - neartag(pp->posx, pp->posy, pp->posz, pp->cursectnum, NORM_ANGLE(FixedToInt(pp->q16ang) + angles[i]), + neartag(pp->posx, pp->posy, pp->posz, pp->cursectnum, NORM_ANGLE(pp->angle.ang.asbuild() + angles[i]), &sec, &wal, &spr, &dist, 600L, NTAG_SEARCH_LO_HI, NULL); @@ -4080,8 +4074,8 @@ PlayerOnLadder(PLAYERp pp) return false; FAFhitscan(pp->posx, pp->posy, pp->posz, pp->cursectnum, - sintable[NORM_ANGLE(FixedToInt(pp->q16ang) + angles[i] + 512)], - sintable[NORM_ANGLE(FixedToInt(pp->q16ang) + angles[i])], + sintable[NORM_ANGLE(pp->angle.ang.asbuild() + angles[i] + 512)], + sintable[NORM_ANGLE(pp->angle.ang.asbuild() + angles[i])], 0, &hitinfo, CLIPMASK_MISSILE); @@ -4136,7 +4130,7 @@ PlayerOnLadder(PLAYERp pp) pp->lx = lsp->x + nx * 5; pp->ly = lsp->y + ny * 5; - playerSetAngle(&pp->q16ang, &pp->angTarget, pp->LadderAngle); + pp->angle.settarget(pp->LadderAngle); return true; } @@ -5375,7 +5369,7 @@ DoPlayerBeginOperate(PLAYERp pp) pp->sop = pp->sop_control = sop; sop->controller = pp->SpriteP; - playerSetAngle(&pp->q16ang, &pp->angTarget, sop->ang); + pp->angle.settarget(sop->ang); pp->posx = sop->xmid; pp->posy = sop->ymid; COVERupdatesector(pp->posx, pp->posy, &pp->cursectnum); @@ -5410,7 +5404,7 @@ DoPlayerBeginOperate(PLAYERp pp) break; case SO_TURRET_MGUN: case SO_TURRET: - if (pp->input.q16avel) + if (pp->input.avel) PlaySOsound(pp->sop->mid_sector, SO_DRIVE_SOUND); else PlaySOsound(pp->sop->mid_sector, SO_IDLE_SOUND); @@ -5462,7 +5456,7 @@ DoPlayerBeginRemoteOperate(PLAYERp pp, SECTOR_OBJECTp sop) save_sectnum = pp->cursectnum; - playerSetAngle(&pp->q16ang, &pp->angTarget, sop->ang); + pp->angle.settarget(sop->ang); pp->posx = sop->xmid; pp->posy = sop->ymid; COVERupdatesector(pp->posx, pp->posy, &pp->cursectnum); @@ -5500,7 +5494,7 @@ DoPlayerBeginRemoteOperate(PLAYERp pp, SECTOR_OBJECTp sop) break; case SO_TURRET_MGUN: case SO_TURRET: - if (pp->input.q16avel) + if (pp->input.avel) PlaySOsound(pp->sop->mid_sector, SO_DRIVE_SOUND); else PlaySOsound(pp->sop->mid_sector, SO_IDLE_SOUND); @@ -5593,13 +5587,13 @@ DoPlayerStopOperate(PLAYERp pp) if (pp->sop_remote) { if (TEST_BOOL1(pp->remote_sprite)) - pp->q16ang = pp->oq16ang = IntToFixed(pp->remote_sprite->ang); + pp->angle.ang = pp->angle.oang = buildang(pp->remote_sprite->ang); else - pp->q16ang = pp->oq16ang = gethiq16angle(pp->sop_remote->xmid - pp->posx, pp->sop_remote->ymid - pp->posy); + pp->angle.ang = pp->angle.oang = q16ang(gethiq16angle(pp->sop_remote->xmid - pp->posx, pp->sop_remote->ymid - pp->posy)); } if (!cl_syncinput) - pp->angTarget = 0; + pp->angle.target = 0; if (pp->sop_control) { @@ -5929,6 +5923,12 @@ DoPlayerDeathMessage(PLAYERp pp, PLAYERp killer) } +enum +{ + PLAYER_DEATH_HORIZ_UP_VALUE = 65, + PLAYER_DEATH_HORIZ_JUMP_VALUE = 50, + PLAYER_DEATH_HORIZ_FALL_VALUE = -50 +}; void DoPlayerBeginDie(PLAYERp pp) @@ -5949,11 +5949,6 @@ DoPlayerBeginDie(PLAYERp pp) DoPlayerDeathDrown, }; -#define PLAYER_DEATH_TILT_VALUE (32) -#define PLAYER_DEATH_HORIZ_UP_VALUE (165) -#define PLAYER_DEATH_HORIZ_JUMP_VALUE (150) -#define PLAYER_DEATH_HORIZ_FALL_VALUE (50) - if (Prediction) return; @@ -6148,14 +6143,14 @@ DoPlayerBeginDie(PLAYERp pp) void DoPlayerDeathHoriz(PLAYERp pp, short target, short speed) { - if ((pp->q16horiz - IntToFixed(target)) > FRACUNIT) + if ((pp->horizon.horiz.asq16() - IntToFixed(target)) > FRACUNIT) { - playerAddHoriz(&pp->q16horiz, &pp->horizAdjust, -speed); + pp->horizon.addadjustment(-speed); } - if ((IntToFixed(target) - pp->q16horiz) > FRACUNIT) + if ((IntToFixed(target) - pp->horizon.horiz.asq16()) > FRACUNIT) { - playerAddHoriz(&pp->q16horiz, &pp->horizAdjust, speed); + pp->horizon.addadjustment(speed); } } @@ -6241,7 +6236,7 @@ void DoPlayerDeathFollowKiller(PLAYERp pp) } else { - DoPlayerTurn(pp, pp->input.q16avel, 1); + DoPlayerTurn(pp, pp->input.avel, 1); } } @@ -6252,7 +6247,7 @@ void DoPlayerDeathFollowKiller(PLAYERp pp) if (FAFcansee(kp->x, kp->y, SPRITEp_TOS(kp), kp->sectnum, pp->posx, pp->posy, pp->posz, pp->cursectnum)) { - playerAddAngle(&pp->q16ang, &pp->angAdjust, getincangleq16(pp->q16ang, gethiq16angle(kp->x - pp->posx, kp->y - pp->posy)) / (double)(FRACUNIT << 4)); + pp->angle.addadjustment(getincangleq16(pp->angle.ang.asq16(), gethiq16angle(kp->x - pp->posx, kp->y - pp->posy)) / (double)(FRACUNIT << 4)); } } } @@ -6288,7 +6283,7 @@ void DoPlayerDeathCheckKeys(PLAYERp pp) pp->SpriteP->x = pp->posx; pp->SpriteP->y = pp->posy; pp->SpriteP->z = pp->posz+PLAYER_HEIGHT; - pp->SpriteP->ang = FixedToInt(pp->q16ang); + pp->SpriteP->ang = pp->angle.ang.asbuild(); DoSpawnTeleporterEffect(pp->SpriteP); PlaySound(DIGI_TELEPORT, pp, v3df_none); @@ -6309,7 +6304,7 @@ void DoPlayerDeathCheckKeys(PLAYERp pp) sp->yrepeat = PLAYER_NINJA_YREPEAT; //pp->tilt = 0; - pp->q16horiz = pp->q16horizbase = IntToFixed(100); + pp->horizon.horiz = q16horiz(0); DoPlayerResetMovement(pp); u->ID = NINJA_RUN_R0; PlayerDeathReset(pp); @@ -6980,11 +6975,9 @@ MoveSkipSavePos(void) pp->oposx = pp->posx; pp->oposy = pp->posy; pp->oposz = pp->posz; - pp->oq16ang = pp->q16ang; - pp->oq16horiz = pp->q16horiz; pp->obob_z = pp->bob_z; - pp->oq16look_ang = pp->q16look_ang; - pp->oq16rotscrnang = pp->q16rotscrnang; + pp->angle.backup(); + pp->horizon.backup(); } // save off stats for skip4 @@ -7048,7 +7041,7 @@ void ChopsCheck(PLAYERp pp) { if (!M_Active() && !TEST(pp->Flags, PF_DEAD) && !pp->sop_riding && numplayers <= 1) { - if (pp->input.actions & ~SB_RUN || pp->input.fvel || pp->input.svel || pp->input.q16avel || pp->input.q16horz || + if (pp->input.actions & ~SB_RUN || pp->input.fvel || pp->input.svel || pp->input.avel || pp->input.horz || TEST(pp->Flags, PF_CLIMBING | PF_FALLING | PF_DIVING)) { // Hit a input key or other reason to stop chops @@ -7292,7 +7285,7 @@ domovethings(void) // auto tracking mode for single player multi-game if (numplayers <= 1 && PlayerTrackingMode && pnum == screenpeek && screenpeek != myconnectindex) { - playerSetAngle(&Player[screenpeek].q16ang, &Player[screenpeek].angTarget, FixedToFloat(gethiq16angle(Player[myconnectindex].posx - Player[screenpeek].posx, Player[myconnectindex].posy - Player[screenpeek].posy))); + Player[screenpeek].angle.settarget(FixedToFloat(gethiq16angle(Player[myconnectindex].posx - Player[screenpeek].posx, Player[myconnectindex].posy - Player[screenpeek].posy))); } if (!TEST(pp->Flags, PF_DEAD)) @@ -7361,7 +7354,7 @@ InitAllPlayers(void) //getzsofslope(pfirst->cursectnum, pfirst->posx, pfirst->posy, &cz, &fz); //pfirst->posz = fz - PLAYER_HEIGHT; - pfirst->q16horiz = pfirst->q16horizbase = IntToFixed(100); + pfirst->horizon.horiz = q16horiz(0); // Initialize all [MAX_SW_PLAYERS] arrays here! for (pp = Player; pp < &Player[MAX_SW_PLAYERS]; pp++) @@ -7369,15 +7362,14 @@ InitAllPlayers(void) pp->posx = pp->oposx = pfirst->posx; pp->posy = pp->oposy = pfirst->posy; pp->posz = pp->oposz = pfirst->posz; - pp->q16ang = pp->oq16ang = pfirst->q16ang; - pp->q16horiz = pp->oq16horiz = pfirst->q16horiz; + pp->angle.ang = pp->angle.oang = pfirst->angle.ang; + pp->horizon.horiz = pp->horizon.ohoriz = pfirst->horizon.horiz; pp->cursectnum = pfirst->cursectnum; // set like this so that player can trigger something on start of the level pp->lastcursectnum = pfirst->cursectnum+1; //pp->MaxHealth = 100; - pp->q16horizbase = pfirst->q16horizbase; pp->oldposx = 0; pp->oldposy = 0; pp->climb_ndx = 10; @@ -7408,7 +7400,7 @@ InitAllPlayers(void) pp->FadeAmt = 0; pp->FadeTics = 0; pp->StartColor = 0; - pp->q16horizoff = 0; + pp->horizon.horizoff = q16horiz(0); INITLIST(&pp->PanelSpriteList); } @@ -7517,7 +7509,7 @@ PlayerSpawnPosition(PLAYERp pp) pp->posx = pp->oposx = sp->x; pp->posy = pp->oposy = sp->y; pp->posz = pp->oposz = sp->z; - pp->q16ang = pp->oq16ang = IntToFixed(sp->ang); + pp->angle.ang = pp->angle.oang = buildang(sp->ang); pp->cursectnum = sp->sectnum; getzsofslope(pp->cursectnum, pp->posx, pp->posy, &cz, &fz); @@ -7576,7 +7568,7 @@ InitMultiPlayerInfo(void) continue; } - start0 = SpawnSprite(MultiStatList[stat], ST1, NULL, pp->cursectnum, pp->posx, pp->posy, pp->posz, FixedToInt(pp->q16ang), 0); + start0 = SpawnSprite(MultiStatList[stat], ST1, NULL, pp->cursectnum, pp->posx, pp->posy, pp->posz, pp->angle.ang.asbuild(), 0); ASSERT(start0 >= 0); if (User[start0]) { diff --git a/source/sw/src/player.h b/source/sw/src/player.h index 9f3ca775b..a4cf513a4 100644 --- a/source/sw/src/player.h +++ b/source/sw/src/player.h @@ -28,10 +28,6 @@ Prepared for public release: 03/28/2005 - Charlie Wiederhold, 3D Realms #define PLAYER_H -#define PLAYER_HORIZ_MAX 299 // !JIM! was 199 and 5 -#define PLAYER_HORIZ_MIN -99 // Had to make plax sky pan up/down like in Duke -// But this is MUCH better! - #define MIN_SWIM_DEPTH 15 // Player view height diff --git a/source/sw/src/predict.cpp b/source/sw/src/predict.cpp index 991918a2c..29473ff64 100644 --- a/source/sw/src/predict.cpp +++ b/source/sw/src/predict.cpp @@ -45,7 +45,8 @@ PLAYERp ppp = &PredictPlayer; typedef struct { int x,y,z; - fixed_t q16horiz, q16ang; + binangle ang; + fixedhoriz horiz; short filler; } PREDICT, *PREDICTp; @@ -95,11 +96,11 @@ DoPrediction(PLAYERp ppp) u = User[ppp->PlayerSprite]; User[ppp->PlayerSprite] = &PredictUser; - ppp->oq16ang = ppp->q16ang; ppp->oposx = ppp->posx; ppp->oposy = ppp->posy; ppp->oposz = ppp->posz; - ppp->oq16horiz = ppp->q16horiz; + ppp->angle.backup(); + ppp->horizon.backup(); // go through the player MOVEMENT code only Prediction = true; @@ -113,11 +114,11 @@ DoPrediction(PLAYERp ppp) sprite[Player[myconnectindex].PlayerSprite] = spr; randomseed = bakrandomseed; - Predict[predictmovefifoplc & (MOVEFIFOSIZ-1)].q16ang = ppp->q16ang; Predict[predictmovefifoplc & (MOVEFIFOSIZ-1)].x = ppp->posx; Predict[predictmovefifoplc & (MOVEFIFOSIZ-1)].y = ppp->posy; Predict[predictmovefifoplc & (MOVEFIFOSIZ-1)].z = ppp->posz; - Predict[predictmovefifoplc & (MOVEFIFOSIZ-1)].q16horiz = ppp->q16horiz; + Predict[predictmovefifoplc & (MOVEFIFOSIZ-1)].ang = ppp->angle.ang; + Predict[predictmovefifoplc & (MOVEFIFOSIZ-1)].horiz = ppp->horizon.horiz; predictmovefifoplc++; #endif } @@ -135,17 +136,17 @@ CorrectPrediction(int actualfifoplc) return; // see if player position is predicted position - if (predict->q16ang == Player[myconnectindex].q16ang && + if (predict->ang == Player[myconnectindex].angle.ang && predict->x == Player[myconnectindex].posx && predict->y == Player[myconnectindex].posy && predict->z == Player[myconnectindex].posz && - predict->q16horiz == Player[myconnectindex].q16horiz + predict->horiz == Player[myconnectindex].horizon.horiz ) { return; } -// //DSPRINTF(ds,"PREDICT ERROR: %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld", FixedToInt(predict->q16ang), FixedToInt(Player[myconnectindex].q16ang), predict->x, Player[myconnectindex].posx, predict->y, Player[myconnectindex].posy, predict->z, Player[myconnectindex].posz, FixedToInt(predict->q16horiz),FixedToInt(Player[myconnectindex].q16horiz)); +// //DSPRINTF(ds,"PREDICT ERROR: %ld %ld %ld %ld %ld %ld %ld %ld %ld %ld", predict->angle.ang.asbuild(), Player[myconnectindex].angle.ang.asbuild(), predict->x, Player[myconnectindex].posx, predict->y, Player[myconnectindex].posy, predict->z, Player[myconnectindex].posz, predict->horiz.asbuild(), Player[myconnectindex].horizon.horiz.asbuild())); // MONO_PRINT(ds); InitPrediction(&Player[myconnectindex]); diff --git a/source/sw/src/sbar.cpp b/source/sw/src/sbar.cpp index df3b0efbd..9b3d78524 100644 --- a/source/sw/src/sbar.cpp +++ b/source/sw/src/sbar.cpp @@ -637,7 +637,7 @@ private: 25, 19, 15, 9, 1, 1, 9, 15, 19, 25 }; - ang = FixedToInt(pp->q16ang); + ang = pp->angle.ang.asbuild(); if (pp->sop_remote) ang = 0; diff --git a/source/sw/src/sector.cpp b/source/sw/src/sector.cpp index 5a1603ad5..de1382ae6 100644 --- a/source/sw/src/sector.cpp +++ b/source/sw/src/sector.cpp @@ -2317,7 +2317,7 @@ bool NearThings(PLAYERp pp) return false; } - neartag(pp->posx, pp->posy, pp->posz, pp->cursectnum, FixedToInt(pp->q16ang), + neartag(pp->posx, pp->posy, pp->posz, pp->cursectnum, pp->angle.ang.asbuild(), &neartagsect, &neartagwall, &neartagsprite, &neartaghitdist, 1024L, NTAG_SEARCH_LO_HI, NULL); @@ -2351,7 +2351,7 @@ bool NearThings(PLAYERp pp) // This only gets called if nothing else worked, check for nearness to a wall { hitdata_t hitinfo = { { 0, 0, 0 }, 0, 0, 0 }; - short dang = FixedToInt(pp->q16ang); + short dang = pp->angle.ang.asbuild(); FAFhitscan(pp->posx, pp->posy, pp->posz - Z(30), pp->cursectnum, // Start position sintable[NORM_ANGLE(dang + 512)], // X vector of 3D ang @@ -2415,7 +2415,7 @@ NearTagList(NEAR_TAG_INFOp ntip, PLAYERp pp, int z, int dist, int type, int coun int neartaghitdist; - neartag(pp->posx, pp->posy, z, pp->cursectnum, FixedToInt(pp->q16ang), + neartag(pp->posx, pp->posy, z, pp->cursectnum, pp->angle.ang.asbuild(), &neartagsector, &neartagwall, &neartagsprite, &neartaghitdist, dist, type, NULL); diff --git a/source/sw/src/sounds.cpp b/source/sw/src/sounds.cpp index cd1340909..d4370f346 100644 --- a/source/sw/src/sounds.cpp +++ b/source/sw/src/sounds.cpp @@ -589,7 +589,7 @@ void GameInterface::UpdateSounds(void) PLAYERp pp = Player + screenpeek; SoundListener listener; - listener.angle = -FixedToFloat(pp->q16ang) * pi::pi() / 1024; // Build uses a period of 2048. + listener.angle = -(pp->angle.ang.asbam() / (double)BAMUNIT) * pi::pi() / 1024; // Build uses a period of 2048. listener.velocity.Zero(); listener.position = GetSoundPos((vec3_t*)&pp->posx); listener.underwater = false; diff --git a/source/sw/src/track.cpp b/source/sw/src/track.cpp index b36178bf2..c35c451d8 100644 --- a/source/sw/src/track.cpp +++ b/source/sw/src/track.cpp @@ -788,7 +788,7 @@ SectorObjectSetupBounds(SECTOR_OBJECTp sop) if (pp->posx > xlow && pp->posx < xhigh && pp->posy > ylow && pp->posy < yhigh) { - pp->RevolveQ16Ang = pp->q16ang; + pp->RevolveAng = pp->angle.ang; pp->RevolveX = pp->posx; pp->RevolveY = pp->posy; pp->RevolveDeltaAng = 0; @@ -1624,7 +1624,7 @@ MovePlayer(PLAYERp pp, SECTOR_OBJECTp sop, int nx, int ny) { SET(pp->Flags, PF_PLAYER_RIDING); - pp->RevolveQ16Ang = pp->q16ang; + pp->RevolveAng = pp->angle.ang; pp->RevolveX = pp->posx; pp->RevolveY = pp->posy; @@ -1648,7 +1648,7 @@ MovePlayer(PLAYERp pp, SECTOR_OBJECTp sop, int nx, int ny) // save the current information so when Player stops // moving then you // know where he was last - pp->RevolveQ16Ang = pp->q16ang; + pp->RevolveAng = pp->angle.ang; pp->RevolveX = pp->posx; pp->RevolveY = pp->posy; @@ -1664,7 +1664,7 @@ MovePlayer(PLAYERp pp, SECTOR_OBJECTp sop, int nx, int ny) pp->RevolveY += BOUND_4PIX(ny); // Last known angle is now adjusted by the delta angle - pp->RevolveQ16Ang = NORM_Q16ANGLE(pp->q16ang - IntToFixed(pp->RevolveDeltaAng)); + pp->RevolveAng = pp->angle.ang - buildang(pp->RevolveDeltaAng); } // increment Players delta angle @@ -1678,7 +1678,7 @@ MovePlayer(PLAYERp pp, SECTOR_OBJECTp sop, int nx, int ny) // New angle is formed by taking last known angle and // adjusting by the delta angle - playerAddAngle(&pp->q16ang, &pp->angAdjust, FixedToFloat(getincangleq16(pp->q16ang, pp->RevolveQ16Ang + IntToFixed(pp->RevolveDeltaAng)))); + pp->angle.addadjustment((pp->angle.ang - (pp->RevolveAng + buildang(pp->RevolveDeltaAng))).asbam() / (double)BAMUNIT); UpdatePlayerSprite(pp); } diff --git a/source/sw/src/weapon.cpp b/source/sw/src/weapon.cpp index 26aced2fc..392d88a7b 100644 --- a/source/sw/src/weapon.cpp +++ b/source/sw/src/weapon.cpp @@ -12826,7 +12826,7 @@ DoRing(int16_t Weapon) sp->x += ((int) u->Dist * (int) sintable[NORM_ANGLE(sp->ang + 512)]) >> 14; sp->y += ((int) u->Dist * (int) sintable[sp->ang]) >> 14; if (User[sp->owner]->PlayerP) - sp->z += (u->Dist * ((IntToFixed(100) - pp->q16horiz) >> 9)) >> 9; + sp->z += (u->Dist * (-pp->horizon.horiz.asq16() >> 9)) >> 9; //sp->ang = NORM_ANGLE(sp->ang + 512); //updatesector(sp->x, sp->y); @@ -12874,7 +12874,7 @@ InitSpellRing(PLAYERp pp) ang_diff = 2048 / max_missiles; - ang_start = NORM_ANGLE(FixedToInt(pp->q16ang) - DIV2(2048)); + ang_start = NORM_ANGLE(pp->angle.ang.asbuild() - DIV2(2048)); if (!SW_SHAREWARE) PlaySound(DIGI_RFWIZ, pp, v3df_none); @@ -12913,7 +12913,7 @@ InitSpellRing(PLAYERp pp) // put it out there sp->x += ((int) u->Dist * (int) sintable[NORM_ANGLE(sp->ang + 512)]) >> 14; sp->y += ((int) u->Dist * (int) sintable[sp->ang]) >> 14; - sp->z = pp->posz + Z(20) + ((u->Dist * ((IntToFixed(100) - pp->q16horiz) >> 9)) >> 9); + sp->z = pp->posz + Z(20) + ((u->Dist * (-pp->horizon.horiz.asq16() >> 9)) >> 9); sp->ang = NORM_ANGLE(sp->ang + 512); @@ -13433,7 +13433,7 @@ InitSpellNapalm(PLAYERp pp) for (i = 0; i < SIZ(mp); i++) { SpriteNum = SpawnSprite(STAT_MISSILE, FIREBALL1, s_Napalm, pp->cursectnum, - pp->posx, pp->posy, pp->posz + Z(12), FixedToInt(pp->q16ang), NAPALM_VELOCITY*2); + pp->posx, pp->posy, pp->posz + Z(12), pp->angle.ang.asbuild(), NAPALM_VELOCITY*2); sp = &sprite[SpriteNum]; u = User[SpriteNum]; @@ -13452,7 +13452,7 @@ InitSpellNapalm(PLAYERp pp) sp->xrepeat = 32; sp->yrepeat = 32; sp->clipdist = 0; - sp->zvel = (IntToFixed(100) - pp->q16horiz) >> 9; + sp->zvel = -pp->horizon.horiz.asq16() >> 9; SET(sp->cstat, CSTAT_SPRITE_TRANSLUCENT | CSTAT_SPRITE_YCENTER); RESET(sp->cstat, CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN); SET(u->Flags2, SPR2_BLUR_TAPER_FAST); @@ -13593,7 +13593,7 @@ InitSpellMirv(PLAYERp pp) return 0; SpriteNum = SpawnSprite(STAT_MISSILE, FIREBALL1, s_Mirv, pp->cursectnum, - pp->posx, pp->posy, pp->posz + Z(12), FixedToInt(pp->q16ang), MIRV_VELOCITY); + pp->posx, pp->posy, pp->posz + Z(12), pp->angle.ang.asbuild(), MIRV_VELOCITY); sp = &sprite[SpriteNum]; u = User[SpriteNum]; @@ -13607,7 +13607,7 @@ InitSpellMirv(PLAYERp pp) sp->xrepeat = 72; sp->yrepeat = 72; sp->clipdist = 32L >> 2; - sp->zvel = (IntToFixed(100) - pp->q16horiz) >> 9; + sp->zvel = -pp->horizon.horiz.asq16() >> 9; SET(sp->cstat, CSTAT_SPRITE_TRANSLUCENT | CSTAT_SPRITE_YCENTER); RESET(sp->cstat, CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN); @@ -13708,7 +13708,7 @@ InitSwordAttack(PLAYERp pp) { bp = &sprite[bubble]; - bp->ang = FixedToInt(pp->q16ang); + bp->ang = pp->angle.ang.asbuild(); random_amt = (RANDOM_P2(32<<8)>>8) - 16; @@ -13757,8 +13757,8 @@ InitSwordAttack(PLAYERp pp) short daang; int daz; - daang = FixedToInt(pp->q16ang); - daz = xs_CRoundToInt((IntToFixed(100) - pp->q16horiz) * (2000. / FRACUNIT)) + (RANDOM_RANGE(24000) - 12000); + daang = pp->angle.ang.asbuild(); + daz = -mulscale16(pp->horizon.horiz.asq16(), 2000) + (RANDOM_RANGE(24000) - 12000); FAFhitscan(pp->posx, pp->posy, pp->posz, pp->cursectnum, // Start position sintable[NORM_ANGLE(daang + 512)], // X vector of 3D ang @@ -13885,7 +13885,7 @@ InitFistAttack(PLAYERp pp) { bp = &sprite[bubble]; - bp->ang = FixedToInt(pp->q16ang); + bp->ang = pp->angle.ang.asbuild(); random_amt = (RANDOM_P2(32<<8)>>8) - 16; @@ -13947,8 +13947,8 @@ InitFistAttack(PLAYERp pp) short daang; int daz; - daang = FixedToInt(pp->q16ang); - daz = xs_CRoundToInt((IntToFixed(100) - pp->q16horiz) * (2000. / FRACUNIT)) + (RANDOM_RANGE(24000) - 12000); + daang = pp->angle.ang.asbuild(); + daz = -mulscale16(pp->horizon.horiz.asq16(), 2000) + (RANDOM_RANGE(24000) - 12000); FAFhitscan(pp->posx, pp->posy, pp->posz, pp->cursectnum, // Start position sintable[NORM_ANGLE(daang + 512)], // X vector of 3D ang @@ -14606,7 +14606,7 @@ InitStar(PLAYERp pp) // Spawn a shot // Inserting and setting up variables - w = SpawnSprite(STAT_MISSILE, STAR1, s_Star, pp->cursectnum, nx, ny, nz, FixedToInt(pp->q16ang), STAR_VELOCITY); + w = SpawnSprite(STAT_MISSILE, STAR1, s_Star, pp->cursectnum, nx, ny, nz, pp->angle.ang.asbuild(), STAR_VELOCITY); wp = &sprite[w]; wu = User[w]; @@ -14621,7 +14621,7 @@ InitStar(PLAYERp pp) wp->clipdist = 32L >> 2; // wp->zvel was overflowing with this calculation - had to move to a local // long var - zvel = xs_CRoundToInt((IntToFixed(100) - pp->q16horiz) * ((double)(HORIZ_MULT+STAR_HORIZ_ADJ) / FRACUNIT)); + zvel = -mulscale16(pp->horizon.horiz.asq16(), HORIZ_MULT+STAR_HORIZ_ADJ); wu->ceiling_dist = Z(1); wu->floor_dist = Z(1); @@ -14678,7 +14678,7 @@ InitStar(PLAYERp pp) if (TEST(pp->Flags, PF_DIVING) || SpriteInUnderwaterArea(np)) SET(nu->Flags, SPR_UNDERWATER); - zvel = xs_CRoundToInt((IntToFixed(100) - pp->q16horiz) * ((double)(HORIZ_MULT+STAR_HORIZ_ADJ) / FRACUNIT)); + zvel = -mulscale16(pp->horizon.horiz.asq16(), HORIZ_MULT+STAR_HORIZ_ADJ); np->zvel = zvel >> 1; if (MissileSetPos(nw, DoStar, 1000)) @@ -14729,7 +14729,7 @@ InitHeartAttack(PLAYERp pp) return; SpriteNum = SpawnSprite(STAT_MISSILE_SKIP4, BLOOD_WORM, s_BloodWorm, pp->cursectnum, - pp->posx, pp->posy, pp->posz + Z(12), FixedToInt(pp->q16ang), BLOOD_WORM_VELOCITY*2); + pp->posx, pp->posy, pp->posz + Z(12), pp->angle.ang.asbuild(), BLOOD_WORM_VELOCITY*2); sp = &sprite[SpriteNum]; u = User[SpriteNum]; @@ -14742,7 +14742,7 @@ InitHeartAttack(PLAYERp pp) sp->xrepeat = 52; sp->yrepeat = 52; sp->clipdist = 0; - sp->zvel = (IntToFixed(100) - pp->q16horiz) >> 9; + sp->zvel = -pp->horizon.horiz.asq16() >> 9; RESET(sp->cstat, CSTAT_SPRITE_BLOCK | CSTAT_SPRITE_BLOCK_HITSCAN); SET(u->Flags2, SPR2_DONT_TARGET_OWNER); SET(sp->cstat, CSTAT_SPRITE_INVISIBLE); @@ -14805,7 +14805,7 @@ InitHeartAttack(PLAYERp pp) return; SpriteNum = SpawnSprite(STAT_MISSILE_SKIP4, BLOOD_WORM, s_BloodWorm, pp->cursectnum, - pp->posx, pp->posy, pp->posz + Z(12), FixedToInt(pp->q16ang), BLOOD_WORM_VELOCITY*2); + pp->posx, pp->posy, pp->posz + Z(12), pp->angle.ang.asbuild(), BLOOD_WORM_VELOCITY*2); sp = &sprite[SpriteNum]; u = User[SpriteNum]; @@ -14966,8 +14966,8 @@ InitShotgun(PLAYERp pp) } else { - daz = xs_CRoundToInt((IntToFixed(100) - pp->q16horiz) * (2000. / FRACUNIT)); - daang = FixedToInt(pp->q16ang); + daz = -mulscale16(pp->horizon.horiz.asq16(), 2000); + daang = pp->angle.ang.asbuild(); } for (i = 0; i < 12; i++) @@ -15129,7 +15129,7 @@ InitLaser(PLAYERp pp) // Inserting and setting up variables w = SpawnSprite(STAT_MISSILE, BOLT_THINMAN_R0, s_Laser, pp->cursectnum, - nx, ny, nz, FixedToInt(pp->q16ang), 300); + nx, ny, nz, pp->angle.ang.asbuild(), 300); wp = &sprite[w]; wu = User[w]; @@ -15142,7 +15142,7 @@ InitLaser(PLAYERp pp) wp->clipdist = 64L>>2; // the slower the missile travels the less of a zvel it needs - wp->zvel = (IntToFixed(100) - pp->q16horiz) >> 11; + wp->zvel = -pp->horizon.horiz.asq16() >> 11; wu->WeaponNum = u->WeaponNum; wu->Radius = 200; @@ -15240,7 +15240,7 @@ InitRail(PLAYERp pp) // Inserting and setting up variables w = SpawnSprite(STAT_MISSILE, BOLT_THINMAN_R1, &s_Rail[0][0], pp->cursectnum, - nx, ny, nz, FixedToInt(pp->q16ang), 1200); + nx, ny, nz, pp->angle.ang.asbuild(), 1200); wp = &sprite[w]; wu = User[w]; @@ -15249,7 +15249,7 @@ InitRail(PLAYERp pp) wp->yrepeat = 52; wp->xrepeat = 52; wp->shade = -15; - zvel = xs_CRoundToInt((IntToFixed(100) - pp->q16horiz) * ((HORIZ_MULT + 17.) / FRACUNIT)); + zvel = -mulscale16(pp->horizon.horiz.asq16(), HORIZ_MULT + 17); wu->RotNum = 5; NewStateGroup(w, &sg_Rail[0]); @@ -15440,7 +15440,7 @@ InitRocket(PLAYERp pp) //nz = pp->posz + pp->bob_z + Z(12); nz = pp->posz + pp->bob_z + Z(8); w = SpawnSprite(STAT_MISSILE, BOLT_THINMAN_R0, &s_Rocket[0][0], pp->cursectnum, - nx, ny, nz, FixedToInt(pp->q16ang), ROCKET_VELOCITY); + nx, ny, nz, pp->angle.ang.asbuild(), ROCKET_VELOCITY); wp = &sprite[w]; wu = User[w]; @@ -15450,7 +15450,7 @@ InitRocket(PLAYERp pp) wp->yrepeat = 90; wp->xrepeat = 90; wp->shade = -15; - zvel = xs_CRoundToInt((IntToFixed(100) - pp->q16horiz) * ((HORIZ_MULT + 35.) / FRACUNIT)); + zvel = -mulscale16(pp->horizon.horiz.asq16(), HORIZ_MULT + 35); wp->clipdist = 64L>>2; @@ -15571,7 +15571,7 @@ InitBunnyRocket(PLAYERp pp) //nz = pp->posz + pp->bob_z + Z(12); nz = pp->posz + pp->bob_z + Z(8); w = SpawnSprite(STAT_MISSILE, BOLT_THINMAN_R4, &s_BunnyRocket[0][0], pp->cursectnum, - nx, ny, nz, FixedToInt(pp->q16ang), ROCKET_VELOCITY); + nx, ny, nz, pp->angle.ang.asbuild(), ROCKET_VELOCITY); wp = &sprite[w]; wu = User[w]; @@ -15581,7 +15581,7 @@ InitBunnyRocket(PLAYERp pp) wp->yrepeat = 64; wp->xrepeat = 64; wp->shade = -15; - zvel = xs_CRoundToInt((IntToFixed(100) - pp->q16horiz) * ((HORIZ_MULT + 35.) / FRACUNIT)); + zvel = -mulscale16(pp->horizon.horiz.asq16(), HORIZ_MULT + 35); wp->clipdist = 64L>>2; @@ -15685,7 +15685,7 @@ InitNuke(PLAYERp pp) //nz = pp->posz + pp->bob_z + Z(12); nz = pp->posz + pp->bob_z + Z(8); w = SpawnSprite(STAT_MISSILE, BOLT_THINMAN_R0, &s_Rocket[0][0], pp->cursectnum, - nx, ny, nz, FixedToInt(pp->q16ang), 700); + nx, ny, nz, pp->angle.ang.asbuild(), 700); wp = &sprite[w]; wu = User[w]; @@ -15695,7 +15695,7 @@ InitNuke(PLAYERp pp) wp->yrepeat = 128; wp->xrepeat = 128; wp->shade = -15; - zvel = xs_CRoundToInt((IntToFixed(100) - pp->q16horiz) * ((HORIZ_MULT - 36.) / FRACUNIT)); + zvel = -mulscale16(pp->horizon.horiz.asq16(), HORIZ_MULT + 36); wp->clipdist = 64L>>2; // Set to red palette @@ -15748,7 +15748,7 @@ InitNuke(PLAYERp pp) wu->ychange = MOVEy(wp->xvel, wp->ang); wu->zchange = zvel; - PlayerDamageSlide(pp, -40, NORM_ANGLE(FixedToInt(pp->q16ang)+1024)); // Recoil slide + PlayerDamageSlide(pp, -40, NORM_ANGLE(pp->angle.ang.asbuild()+1024)); // Recoil slide return 0; } @@ -15883,7 +15883,7 @@ InitMicro(PLAYERp pp) { hp = NULL; hu = NULL; - ang = FixedToInt(pp->q16ang); + ang = pp->angle.ang.asbuild(); } nz = pp->posz + pp->bob_z + Z(14); @@ -15902,7 +15902,7 @@ InitMicro(PLAYERp pp) wp->yrepeat = 24; wp->xrepeat = 24; wp->shade = -15; - wp->zvel = (IntToFixed(100) - pp->q16horiz) >> 9; + wp->zvel = -pp->horizon.horiz.asq16() >> 9; wp->clipdist = 64L>>2; // randomize zvelocity @@ -17432,14 +17432,14 @@ InitTracerUzi(PLAYERp pp) nx = pp->posx; ny = pp->posy; //nz = pp->posz + pp->bob_z + Z(8); - //nz = pp->posz + pp->bob_z + Z(8) + xs_CRoundToInt((IntToFixed(100) - pp->q16horiz) * (72. / FRACUNIT)); - nz = pp->posz + Z(8) + xs_CRoundToInt((IntToFixed(100) - pp->q16horiz) * (72. / FRACUNIT)); + //nz = pp->posz + pp->bob_z + Z(8) + -mulscale16(pp->horizon.horiz.asq16(), 72); + nz = pp->posz + Z(8) + -mulscale16(pp->horizon.horiz.asq16(), 72); // Spawn a shot // Inserting and setting up variables w = SpawnSprite(STAT_MISSILE, 0, s_Tracer, pp->cursectnum, - nx, ny, nz, FixedToInt(pp->q16ang), TRACER_VELOCITY); + nx, ny, nz, pp->angle.ang.asbuild(), TRACER_VELOCITY); wp = &sprite[w]; wu = User[w]; @@ -17451,7 +17451,7 @@ InitTracerUzi(PLAYERp pp) wp->xrepeat = 10; wp->shade = -40; wp->zvel = 0; - //wp->zvel = (IntToFixed(100) - pp->q16horiz) >> 9; + //wp->zvel = -pp->horizon.horiz.asq16() >> 9; wp->clipdist = 32 >> 2; wu->WeaponNum = u->WeaponNum; @@ -17478,7 +17478,7 @@ InitTracerUzi(PLAYERp pp) return 0; } - wp->zvel = xs_CRoundToInt((IntToFixed(100) - pp->q16horiz) * ((wp->xvel / 8.) / FRACUNIT)); + wp->zvel = xs_CRoundToInt(-fmulscale16(pp->horizon.horiz.asq16(), wp->xvel / 8.)); pp->SpriteP->clipdist = oclipdist; @@ -17498,7 +17498,7 @@ InitTracerUzi(PLAYERp pp) } int -InitTracerTurret(short SpriteNum, short Operator, int horiz) +InitTracerTurret(short SpriteNum, short Operator, fixed_t q16horiz) { USERp u = User[SpriteNum]; SPRITEp sp = u->SpriteP; @@ -17510,7 +17510,7 @@ InitTracerTurret(short SpriteNum, short Operator, int horiz) nx = sp->x; ny = sp->y; - nz = sp->z + ((100 - horiz) * 72); + nz = sp->z + -mulscale16(q16horiz, 72); // Spawn a shot // Inserting and setting up variables @@ -17537,7 +17537,7 @@ InitTracerTurret(short SpriteNum, short Operator, int horiz) SET(wp->cstat, CSTAT_SPRITE_YCENTER); SET(wp->cstat, CSTAT_SPRITE_INVISIBLE); - wp->zvel = ((100 - horiz) * (wp->xvel/8)); + wp->zvel = xs_CRoundToInt(-fmulscale16(q16horiz, wp->xvel / 8.)); WeaponAutoAim(sp, w, 32, false); @@ -17721,8 +17721,8 @@ int SpawnWallHole(short hit_sect, short hit_wall, int hit_x, int hit_y, int hit_ sp->ang = NORM_ANGLE(wall_ang + 1024); // int nx,ny; - //nx = (sintable[(512 + FixedToInt(Player[0].q16ang)) & 2047] >> 7); - //ny = (sintable[FixedToInt(Player[0].q16ang)] >> 7); + //nx = (sintable[(512 + Player[0].angle.ang.asbuild()) & 2047] >> 7); + //ny = (sintable[Player[0].angle.ang.asbuild()] >> 7); //sp->x -= nx; //sp->y -= ny; @@ -17828,9 +17828,9 @@ InitUzi(PLAYERp pp) } else { - //daang = NORM_ANGLE(FixedToInt(pp->q16ang) + (RANDOM_RANGE(50) - 25)); - daang = NORM_ANGLE(FixedToInt(pp->q16ang) + (RANDOM_RANGE(24) - 12)); - daz = xs_CRoundToInt((IntToFixed(100) - pp->q16horiz) * (2000. / FRACUNIT)) + (RANDOM_RANGE(24000) - 12000); + //daang = NORM_ANGLE(pp->angle.ang.asbuild() + (RANDOM_RANGE(50) - 25)); + daang = NORM_ANGLE(pp->angle.ang.asbuild() + (RANDOM_RANGE(24) - 12)); + daz = -mulscale16(pp->horizon.horiz.asq16(), 2000) + (RANDOM_RANGE(24000) - 12000); } @@ -18005,8 +18005,8 @@ InitEMP(PLAYERp pp) InitTracerUzi(pp); - //daz = nz = pp->posz + Z(8) + xs_CRoundToInt((IntToFixed(100) - pp->q16horiz) * (72. / FRACUNIT)); - //daang = NORM_ANGLE(FixedToInt(pp->q16ang) + (RANDOM_RANGE(50) - 25)); + //daz = nz = pp->posz + Z(8) + -mulscale16(pp->horizon.horiz.asq16(), 72); + //daang = NORM_ANGLE(pp->angle.ang.asbuild() + (RANDOM_RANGE(50) - 25)); daz = nz = pp->posz + pp->bob_z; daang = 64; @@ -18015,8 +18015,8 @@ InitEMP(PLAYERp pp) } else { - daz = xs_CRoundToInt((IntToFixed(100) - pp->q16horiz) * (2000. / FRACUNIT)); - daang = FixedToInt(pp->q16ang); + daz = -mulscale16(pp->horizon.horiz.asq16(), 2000); + daang = pp->angle.ang.asbuild(); } FAFhitscan(pp->posx, pp->posy, nz, pp->cursectnum, // Start position @@ -18189,7 +18189,7 @@ InitTankShell(short SpriteNum, PLAYERp pp) SET(wp->cstat, CSTAT_SPRITE_YCENTER); SET(wp->cstat, CSTAT_SPRITE_INVISIBLE); - wp->zvel = xs_CRoundToInt((IntToFixed(100) - pp->q16horiz) * ((wp->xvel / 8.) / FRACUNIT)); + wp->zvel = xs_CRoundToInt(-fmulscale16(pp->horizon.horiz.asq16(), wp->xvel / 8.)); WeaponAutoAim(sp, w, 64, false); // a bit of randomness @@ -18268,7 +18268,7 @@ InitTurretMicro(short SpriteNum, PLAYERp pp) wp->yrepeat = 24; wp->xrepeat = 24; wp->shade = -15; - wp->zvel = (IntToFixed(100) - pp->q16horiz) >> 9; + wp->zvel = -pp->horizon.horiz.asq16() >> 9; wp->clipdist = 64L>>2; // randomize zvelocity @@ -18349,7 +18349,7 @@ InitTurretRocket(short SpriteNum, PLAYERp pp) SET(wu->Flags2, SPR2_SO_MISSILE); SET(wp->cstat, CSTAT_SPRITE_YCENTER); - wp->zvel = xs_CRoundToInt((IntToFixed(100) - pp->q16horiz) * ((wp->xvel / 8.) / FRACUNIT)); + wp->zvel = xs_CRoundToInt(-fmulscale16(pp->horizon.horiz.asq16(), wp->xvel / 8.)); WeaponAutoAim(sp, w, 64, false); // a bit of randomness @@ -18396,7 +18396,7 @@ InitTurretFireball(short SpriteNum, PLAYERp pp) SET(wu->Flags2, SPR2_SO_MISSILE); SET(wp->cstat, CSTAT_SPRITE_YCENTER); - wp->zvel = xs_CRoundToInt((IntToFixed(100) - pp->q16horiz) * ((wp->xvel / 8.) / FRACUNIT)); + wp->zvel = xs_CRoundToInt(-fmulscale16(pp->horizon.horiz.asq16(), wp->xvel / 8.)); WeaponAutoAim(sp, w, 64, false); // a bit of randomness @@ -18445,7 +18445,7 @@ InitTurretRail(short SpriteNum, PLAYERp pp) wp->yrepeat = 52; wp->xrepeat = 52; wp->shade = -15; - wp->zvel = (IntToFixed(100) - pp->q16horiz) >> 9; + wp->zvel = -pp->horizon.horiz.asq16() >> 9; wu->RotNum = 5; NewStateGroup(w, &sg_Rail[0]); @@ -18505,7 +18505,7 @@ InitTurretLaser(short SpriteNum, PLAYERp pp) wp->shade = -15; // the slower the missile travels the less of a zvel it needs - wp->zvel = (IntToFixed(100) - pp->q16horiz) >> 11; + wp->zvel = -pp->horizon.horiz.asq16() >> 11; wu->Radius = 200; wu->ceiling_dist = Z(1); @@ -18551,7 +18551,7 @@ InitSobjMachineGun(short SpriteNum, PLAYERp pp) nsect = sp->sectnum; if (RANDOM_P2(1024) < 200) - InitTracerTurret(sp - sprite, pp->PlayerSprite, FixedToInt(pp->q16horiz)); + InitTracerTurret(sp - sprite, pp->PlayerSprite, pp->horizon.horiz.asq16()); daang = 64; if (WeaponAutoAimHitscan(sp, &daz, &daang, false) != -1) @@ -18561,12 +18561,11 @@ InitSobjMachineGun(short SpriteNum, PLAYERp pp) } else { - fixed_t q16horiz = pp->q16horiz; - fixed_t horizmin = IntToFixed(75); - if (q16horiz < horizmin) - q16horiz = horizmin; + auto horizmin = 75; + if (pp->horizon.horiz.asbuild() < horizmin) + pp->horizon.settarget(horizmin); - daz = xs_CRoundToInt((IntToFixed(100) - q16horiz) * (2000. / FRACUNIT)) + (RANDOM_RANGE(Z(80)) - Z(40)); + daz = -mulscale16(pp->horizon.horiz.asq16(), 2000) + (RANDOM_RANGE(Z(80)) - Z(40)); daang = sp->ang; } @@ -19272,7 +19271,7 @@ InitGrenade(PLAYERp pp) // Inserting and setting up variables w = SpawnSprite(STAT_MISSILE, GRENADE, &s_Grenade[0][0], pp->cursectnum, - nx, ny, nz, FixedToInt(pp->q16ang), GRENADE_VELOCITY); + nx, ny, nz, pp->angle.ang.asbuild(), GRENADE_VELOCITY); wp = &sprite[w]; wu = User[w]; @@ -19304,9 +19303,9 @@ InitGrenade(PLAYERp pp) if (TEST(pp->Flags, PF_DIVING) || SpriteInUnderwaterArea(wp)) SET(wu->Flags, SPR_UNDERWATER); - wp->zvel = (IntToFixed(100) - pp->q16horiz) >> 9; + wp->zvel = -pp->horizon.horiz.asq16() >> 9; - ////DSPRINTF(ds,"horiz %d, ho %d, ho+ho %d",FixedToInt(pp->q16horiz), FixedToInt(pp->q16horizoff), FixedToInt(pp->q16horizoff + pp->q16horiz)); + ////DSPRINTF(ds,"horiz %d, ho %d, ho+ho %d", pp->horizon.horiz.asbuild()), pp->horizon.horizoff.asbuild()), pp->horizon.horizoff.asbuild() + pp->horizon.horiz.asbuild()); //MONO_PRINT(ds); oclipdist = pp->SpriteP->clipdist; @@ -19441,7 +19440,7 @@ InitMine(PLAYERp pp) // Inserting and setting up variables w = SpawnSprite(STAT_MISSILE, MINE, s_Mine, pp->cursectnum, - nx, ny, nz, FixedToInt(pp->q16ang), MINE_VELOCITY); + nx, ny, nz, pp->angle.ang.asbuild(), MINE_VELOCITY); wp = &sprite[w]; wu = User[w]; @@ -19451,7 +19450,7 @@ InitMine(PLAYERp pp) wp->xrepeat = 32; wp->shade = -15; wp->clipdist = 128L>>2; - wp->zvel = (IntToFixed(100) - pp->q16horiz) >> 9; + wp->zvel = -pp->horizon.horiz.asq16() >> 9; wu->WeaponNum = u->WeaponNum; wu->Radius = 200; wu->ceiling_dist = Z(5); @@ -19464,7 +19463,7 @@ InitMine(PLAYERp pp) if (TEST(pp->Flags, PF_DIVING) || SpriteInUnderwaterArea(wp)) SET(wu->Flags, SPR_UNDERWATER); - //wp->zvel = (IntToFixed(100) - pp->q16horiz) >> 9; + //wp->zvel = -pp->horizon.horiz.asq16() >> 9; MissileSetPos(w, DoMine, 800); @@ -19472,7 +19471,7 @@ InitMine(PLAYERp pp) wu->xchange = MOVEx(wp->xvel, wp->ang); wu->ychange = MOVEy(wp->xvel, wp->ang); - dot = DOT_PRODUCT_2D(pp->xvect, pp->yvect, sintable[NORM_ANGLE(FixedToInt(pp->q16ang)+512)], sintable[FixedToInt(pp->q16ang)]); + dot = DOT_PRODUCT_2D(pp->xvect, pp->yvect, sintable[NORM_ANGLE(pp->angle.ang.asbuild()+512)], sintable[pp->angle.ang.asbuild()]); // don't adjust for strafing if (labs(dot) > 10000) @@ -19602,7 +19601,7 @@ InitFireball(PLAYERp pp) nz = pp->posz + pp->bob_z + Z(15); - w = SpawnSprite(STAT_MISSILE, FIREBALL1, s_Fireball, pp->cursectnum, nx, ny, nz, FixedToInt(pp->q16ang), FIREBALL_VELOCITY); + w = SpawnSprite(STAT_MISSILE, FIREBALL1, s_Fireball, pp->cursectnum, nx, ny, nz, pp->angle.ang.asbuild(), FIREBALL_VELOCITY); wp = &sprite[w]; wu = User[w]; @@ -19617,8 +19616,8 @@ InitFireball(PLAYERp pp) wu->ceiling_dist = Z(6); wu->floor_dist = Z(6); - //zvel = xs_CRoundToInt((IntToFixed(100) - pp->q16horiz) * ((100. + ADJUST) / FRACUNIT)); - zvel = xs_CRoundToInt((IntToFixed(100) - pp->q16horiz) * (240. / FRACUNIT)); + //zvel = -mulscale16(pp->horizon.horiz.asq16(), 100 + ADJUST); + zvel = -mulscale16(pp->horizon.horiz.asq16(), 240); //wu->RotNum = 5; //NewStateGroup(w, &sg_Fireball); diff --git a/source/sw/src/zombie.cpp b/source/sw/src/zombie.cpp index 15dcc017b..454e3e5b5 100644 --- a/source/sw/src/zombie.cpp +++ b/source/sw/src/zombie.cpp @@ -788,7 +788,7 @@ SpawnZombie(PLAYERp pp, short Weapon) //Zombies++; - New = SpawnSprite(STAT_ENEMY, ZOMBIE_RUN_R0, s_ZombieRun[0], pp->cursectnum, pp->posx, pp->posy, pp->posz, FixedToInt(pp->q16ang), 0); + New = SpawnSprite(STAT_ENEMY, ZOMBIE_RUN_R0, s_ZombieRun[0], pp->cursectnum, pp->posx, pp->posy, pp->posz, pp->angle.ang.asbuild(), 0); np = &sprite[New]; nu = User[New]; np->sectnum = pp->cursectnum;