diff --git a/source/blood/src/controls.cpp b/source/blood/src/controls.cpp index 15b2c4c27..8df024e9a 100644 --- a/source/blood/src/controls.cpp +++ b/source/blood/src/controls.cpp @@ -41,7 +41,7 @@ enum MAXHORIZVEL = 32 }; -void applylook(PLAYER *pPlayer, fixed_t const q16avel, double const scaleAdjust); +void UpdatePlayerSpriteAngle(PLAYER* pPlayer); //--------------------------------------------------------------------------- // @@ -138,7 +138,8 @@ static void processMovement(ControlInfo* const hidInput) // Perform unsynchronised angle/horizon if not dead. if (gView->pXSprite->health != 0) { - applylook(pPlayer, input.q16avel, scaleAdjust); + applylook(&pPlayer->q16ang, &pPlayer->q16look_ang, &pPlayer->q16rotscrnang, &pPlayer->spin, input.q16avel, &pPlayer->input.actions, scaleAdjust, gView->pXSprite->health == 0, pPlayer->posture != 0); + UpdatePlayerSpriteAngle(pPlayer); sethorizon(&pPlayer->q16horiz, input.q16horz, &pPlayer->input.actions, scaleAdjust); } diff --git a/source/blood/src/hudsprites.cpp b/source/blood/src/hudsprites.cpp index e969c1323..33aa3a9ae 100644 --- a/source/blood/src/hudsprites.cpp +++ b/source/blood/src/hudsprites.cpp @@ -96,14 +96,17 @@ static void viewBurnTime(int gScale) } -void hudDraw(PLAYER *gView, int nSectnum, double bobx, double boby, double zDelta, int basepal, int smoothratio) +void hudDraw(PLAYER *gView, VIEW *pView, int nSectnum, double bobx, double boby, double zDelta, int basepal, double smoothratio) { if (gViewPos == 0) { - DrawCrosshair(kCrosshairTile, gView->pXSprite->health >> 4, 0, 2); + double look_anghalf = getHalfLookAng(pView->q16look_ang, gView->q16look_ang, cl_syncinput, smoothratio); + double looking_arc = fabs(look_anghalf) / 4.5; - double cX = 160; - double cY = 220; + DrawCrosshair(kCrosshairTile, gView->pXSprite->health >> 4, -look_anghalf, 2); + + double cX = 160 - look_anghalf; + double cY = 220 + looking_arc; if (cl_weaponsway) { cX += (bobx / 256.); diff --git a/source/blood/src/player.cpp b/source/blood/src/player.cpp index b277f4b42..098aa8b97 100644 --- a/source/blood/src/player.cpp +++ b/source/blood/src/player.cpp @@ -1303,48 +1303,15 @@ int ActionScan(PLAYER *pPlayer, int *a2, int *a3) return -1; } -enum -{ - PLAYER_HORIZ_MIN = -79, - PLAYER_HORIZ_MAX = 219 -}; - //--------------------------------------------------------------------------- // -// Player's angle function, called in processInput() or from gi->GetInput() as required. +// Player's sprite angle function, called in ProcessInput() or from gi->GetInput() as required. // //--------------------------------------------------------------------------- -void applylook(PLAYER *pPlayer, fixed_t const q16avel, double const scaleAdjust) +void UpdatePlayerSpriteAngle(PLAYER *pPlayer) { spritetype *pSprite = pPlayer->pSprite; - InputPacket *pInput = &pPlayer->input; - - if (q16avel) - { - pPlayer->q16ang = (pPlayer->q16ang + q16avel) & 0x7FFFFFF; - } - - if (pInput->actions & SB_TURNAROUND) - { - if (pPlayer->spin == 0.) - { - pPlayer->spin = -1024.; - } - pInput->actions &= ~SB_TURNAROUND; - } - - if (pPlayer->spin < 0.) - { - double const speed = scaleAdjust * (pPlayer->posture == 1 ? 64. : 128.); - pPlayer->spin = min(pPlayer->spin + speed, 0.); - pPlayer->q16ang += FloatToFixed(speed); - - if (pPlayer->spin > -1.) - { - pPlayer->spin = 0.; - } - } pPlayer->q16ang = (pPlayer->q16ang + IntToFixed(pSprite->ang - pPlayer->angold)) & 0x7FFFFFF; pPlayer->angold = pSprite->ang = FixedToInt(pPlayer->q16ang); @@ -1544,7 +1511,8 @@ void ProcessInput(PLAYER *pPlayer) if (cl_syncinput) { - applylook(pPlayer, pInput->q16avel, 1); + applylook(&pPlayer->q16ang, &pPlayer->q16look_ang, &pPlayer->q16rotscrnang, &pPlayer->spin, pInput->q16avel, &pInput->actions, 1, gView->pXSprite->health == 0, pPlayer->posture != 0); + UpdatePlayerSpriteAngle(pPlayer); } if (!(pInput->actions & SB_JUMP)) diff --git a/source/blood/src/player.h b/source/blood/src/player.h index 3eb72a34e..531c12d64 100644 --- a/source/blood/src/player.h +++ b/source/blood/src/player.h @@ -154,7 +154,7 @@ struct PLAYER int restTime; int kickPower; int laughCount; - int spin; // turning around + fixed_t spin; // turning around bool godMode; bool fallScream; bool cantJump; @@ -184,6 +184,8 @@ struct PLAYER int player_par; int nWaterPal; POSTURE pPosture[kModeMax][kPostureMax]; + fixed_t q16look_ang; + fixed_t q16rotscrnang; // Input helper variables and setters. double horizAdjust, angAdjust; diff --git a/source/blood/src/view.cpp b/source/blood/src/view.cpp index 443f3f399..be7c50bb3 100644 --- a/source/blood/src/view.cpp +++ b/source/blood/src/view.cpp @@ -116,6 +116,8 @@ void viewBackupView(int nPlayer) pView->atc = pPlayer->bobWidth; pView->at18 = pPlayer->swayHeight; pView->at1c = pPlayer->swayWidth; + pView->q16look_ang = pPlayer->q16look_ang; + pView->q16rotscrnang = pPlayer->q16rotscrnang; } void viewCorrectViewOffsets(int nPlayer, vec3_t const *oldpos) @@ -631,7 +633,7 @@ void viewDrawScreen(bool sceneonly) renderSetAspect(v1, yxaspect); int cX, cY, cZ, v74, v8c; - fixed_t cA, q16horiz, q16slopehoriz; + fixed_t cA, q16horiz, q16slopehoriz, q16rotscrnang; double zDelta, v4c, v48; int nSectnum = gView->pSprite->sectnum; if (numplayers > 1 && gView == gMe && gPrediction && gMe->pXSprite->health > 0) @@ -649,13 +651,15 @@ void viewDrawScreen(bool sceneonly) if (!cl_syncinput) { - cA = predict.at30; + cA = predict.at30 + predict.q16look_ang; q16horiz = predict.at24; + q16rotscrnang = predict.q16rotscrnang; } else { - cA = interpolateangfix16(predictOld.at30, predict.at30, gInterpolate); + 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); } } else @@ -673,13 +677,15 @@ void viewDrawScreen(bool sceneonly) if (!cl_syncinput) { - cA = gView->q16ang; + cA = gView->q16ang + gView->q16look_ang; q16horiz = gView->q16horiz; + q16rotscrnang = gView->q16rotscrnang; } else { - cA = interpolateangfix16(pView->at30, gView->q16ang, gInterpolate); + 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); } } @@ -727,7 +733,7 @@ void viewDrawScreen(bool sceneonly) //int tiltcs, tiltdim; uint8_t v4 = powerupCheck(gView, kPwUpCrystalBall) > 0; #ifdef USE_OPENGL - renderSetRollAngle(0); + renderSetRollAngle(FixedToFloat(q16rotscrnang)); #endif if (v78 || bDelirium) { @@ -959,7 +965,7 @@ void viewDrawScreen(bool sceneonly) } } #endif - hudDraw(gView, nSectnum, v4c, v48, zDelta, basepal, (int)gInterpolate); + hudDraw(gView, &gPrevView[gViewIndex], nSectnum, v4c, v48, zDelta, basepal, gInterpolate); } UpdateDacs(0, true); // keep the view palette active only for the actual 3D view and its overlays. if (automapMode != am_off) diff --git a/source/blood/src/view.h b/source/blood/src/view.h index 0cba77c2a..48de4fd9c 100644 --- a/source/blood/src/view.h +++ b/source/blood/src/view.h @@ -66,6 +66,8 @@ struct VIEW { char at72; // underwater short at73; // sprite flags SPRITEHIT at75; + fixed_t q16look_ang; + fixed_t q16rotscrnang; }; extern VIEW gPrevView[kMaxPlayers]; @@ -140,7 +142,7 @@ extern LOCATION gPrevSpriteLoc[kMaxSprites]; extern int gLastPal; extern double gInterpolate; -void hudDraw(PLAYER* gView, int nSectnum, double bobx, double boby, double zDelta, int basepal, int smoothratio); +void hudDraw(PLAYER* gView, VIEW *pView, int nSectnum, double bobx, double boby, double zDelta, int basepal, double smoothratio); void viewInitializePrediction(void); void viewUpdatePrediction(InputPacket *pInput); void viewCorrectPrediction(void); diff --git a/source/core/gamecontrol.cpp b/source/core/gamecontrol.cpp index d7d825104..f7cd115f7 100644 --- a/source/core/gamecontrol.cpp +++ b/source/core/gamecontrol.cpp @@ -1490,7 +1490,7 @@ fixed_t getincangleq16(fixed_t a, fixed_t na) //--------------------------------------------------------------------------- // -// Player's horizon function, called in processInput() or from gi->GetInput() as required. +// Player's horizon function, called from game's ticker or from gi->GetInput() as required. // //--------------------------------------------------------------------------- @@ -1553,3 +1553,60 @@ void sethorizon(fixed_t* q16horiz, fixed_t const q16horz, ESyncBits* actions, do // clamp before returning *q16horiz = clamp(*q16horiz, gi->playerHorizMin(), gi->playerHorizMax()); } + +//--------------------------------------------------------------------------- +// +// Player's angle function, called from game's ticker or from gi->GetInput() as required. +// +//--------------------------------------------------------------------------- + +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 dead, bool const crouching) +{ + if (!dead) + { + *q16rotscrnang -= xs_CRoundToInt(scaleAdjust * (*q16rotscrnang * (15. / GameTicRate))); + if (abs(*q16rotscrnang) < (FRACUNIT >> 2)) *q16rotscrnang = 0; + + *q16look_ang -= xs_CRoundToInt(scaleAdjust * (*q16look_ang * (7.5 / GameTicRate))); + if (abs(*q16look_ang) < (FRACUNIT >> 2)) *q16look_ang = 0; + + if (*actions & SB_LOOK_LEFT) + { + *q16look_ang -= FloatToFixed(scaleAdjust * (4560. / GameTicRate)); + *q16rotscrnang += FloatToFixed(scaleAdjust * (720. / GameTicRate)); + } + + if (*actions & SB_LOOK_RIGHT) + { + *q16look_ang += FloatToFixed(scaleAdjust * (4560. / GameTicRate)); + *q16rotscrnang -= FloatToFixed(scaleAdjust * (720. / GameTicRate)); + } + + if (*actions & SB_TURNAROUND) + { + if (*spin == 0) + { + *spin = IntToFixed(-1024); + } + *actions &= ~SB_TURNAROUND; + } + + if (*spin < 0) + { + fixed_t add = FloatToFixed(scaleAdjust * ((!crouching ? 3840. : 1920.) / GameTicRate)); + *spin += add; + if (*spin > 0) + { + // Don't overshoot our target. With variable factor this is possible. + add -= *spin; + *spin = 0; + } + *q16ang += add; + } + + if (q16avel) + { + *q16ang = (*q16ang + q16avel) & 0x7FFFFFF; + } + } +} diff --git a/source/core/gamecontrol.h b/source/core/gamecontrol.h index 9b7fdf8b1..58bfac0af 100644 --- a/source/core/gamecontrol.h +++ b/source/core/gamecontrol.h @@ -11,6 +11,7 @@ #include "stats.h" #include "i_time.h" #include "palentry.h" +#include "pragmas.h" extern FString currentGame; extern FString LumpFilter; @@ -67,6 +68,7 @@ int getincangle(int c, int n); fixed_t getincangleq16(fixed_t c, fixed_t n); 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 dead, bool const crouching); struct UserConfig { @@ -229,3 +231,13 @@ extern int chatmodeon; extern bool sendPause; extern int lastTic; +//--------------------------------------------------------------------------- +// +// Return half player's q16look_ang directly or interpolated as required. +// +//--------------------------------------------------------------------------- + +inline double getHalfLookAng(fixed_t const oq16look_ang, fixed_t const q16look_ang, bool interpolate, double smoothratio) +{ + return (!interpolate ? q16look_ang : oq16look_ang + fmulscale16(q16look_ang - oq16look_ang, smoothratio)) * (0.5 / FRACUNIT); +} diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index 80affff71..7fd6a94db 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 applylook(int snum, double factor, fixed_t adjustment); +void processq16avel(player_struct* p, fixed_t* q16avel); void checklook(int snum, ESyncBits actions); void playerCenterView(int snum); void playerLookUp(int snum, ESyncBits actions); diff --git a/source/games/duke/src/game_misc.cpp b/source/games/duke/src/game_misc.cpp index 229bc2a43..1a61e29e7 100644 --- a/source/games/duke/src/game_misc.cpp +++ b/source/games/duke/src/game_misc.cpp @@ -300,7 +300,7 @@ void drawoverlays(double smoothratio) if (ps[myconnectindex].newowner == -1 && ud.camerasprite == -1) { - DrawCrosshair(TILE_CROSSHAIR, ps[screenpeek].last_extra, -getHalfLookAng(screenpeek, cl_syncinput, smoothratio), isRR() ? 0.5 : 1); + DrawCrosshair(TILE_CROSSHAIR, ps[screenpeek].last_extra, -getHalfLookAng(pp->oq16look_ang, pp->q16look_ang, cl_syncinput, smoothratio), isRR() ? 0.5 : 1); } if (paused == 2) diff --git a/source/games/duke/src/hudweapon_d.cpp b/source/games/duke/src/hudweapon_d.cpp index 506a9e49d..1424a9c1f 100644 --- a/source/games/duke/src/hudweapon_d.cpp +++ b/source/games/duke/src/hudweapon_d.cpp @@ -289,7 +289,7 @@ void displayweapon_d(int snum, double smoothratio) o = 0; horiz16th = get16thOfHoriz(snum, cl_syncinput, smoothratio); - look_anghalf = getHalfLookAng(snum, cl_syncinput, smoothratio); + look_anghalf = getHalfLookAng(p->oq16look_ang, p->q16look_ang, 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 9c973ee76..9a89e0bbd 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(snum, cl_syncinput, smoothratio); + look_anghalf = getHalfLookAng(p->oq16look_ang, p->q16look_ang, 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 c6d7e428d..85d778fcc 100644 --- a/source/games/duke/src/inlines.h +++ b/source/games/duke/src/inlines.h @@ -202,13 +202,7 @@ inline void backupplayer(player_struct* p) backupview(p); } -// the weapon display code uses these. -inline double getHalfLookAng(int snum, bool interpolate, double smoothratio) -{ - struct player_struct *p = &ps[snum]; - return (!interpolate ? p->q16look_ang : p->oq16look_ang + fmulscale16(p->q16look_ang - p->oq16look_ang, smoothratio)) * (0.5 / FRACUNIT); -} - +// the weapon display code uses this. inline double get16thOfHoriz(int snum, bool interpolate, double smoothratio) { struct player_struct *p = &ps[snum]; diff --git a/source/games/duke/src/input.cpp b/source/games/duke/src/input.cpp index dbcf20ba9..536f208b7 100644 --- a/source/games/duke/src/input.cpp +++ b/source/games/duke/src/input.cpp @@ -477,13 +477,13 @@ void hud_input(int snum) } } - if (PlayerInput(snum, SB_TURNAROUND) && p->one_eighty_count == 0) + if (PlayerInput(snum, SB_TURNAROUND) && p->one_eighty_count == 0 && p->on_crane < 0) { SetGameVarID(g_iReturnVarID, 0, -1, snum); OnEvent(EVENT_TURNAROUND, -1, snum, -1); - if (GetGameVarID(g_iReturnVarID, -1, snum) == 0) + if (GetGameVarID(g_iReturnVarID, -1, snum) != 0) { - p->one_eighty_count = -IntToFixed(1024); + sync[snum].actions &= ~SB_TURNAROUND; } } } @@ -884,15 +884,13 @@ static void processVehicleInput(player_struct *p, ControlInfo* const hidInput, I if (buttonMap.ButtonDown(gamefunc_Move_Forward) || buttonMap.ButtonDown(gamefunc_Strafe)) loc.actions |= SB_JUMP; if (buttonMap.ButtonDown(gamefunc_Move_Backward)) - loc.actions |= SB_AIM_UP; + p->vehicle_backwards = true; if (loc.actions & SB_RUN) loc.actions |= SB_CROUCH; } - if (turnl) - loc.actions |= SB_AIM_DOWN; - if (turnr) - loc.actions |= SB_LOOK_LEFT; + if (turnl) p->vehicle_turnl = true; + if (turnr) p->vehicle_turnr = true; double turnvel; @@ -1024,9 +1022,16 @@ static void GetInputInternal(InputPacket &locInput, ControlInfo* const hidInput) { // Do these in the same order as the old code. calcviewpitch(p, scaleAdjust); - applylook(myconnectindex, scaleAdjust, input.q16avel); + processq16avel(p, &input.q16avel); + applylook(&p->q16ang, &p->q16look_ang, &p->q16rotscrnang, &p->one_eighty_count, input.q16avel, &sync[myconnectindex].actions, scaleAdjust, p->dead_flag != 0, p->crouch_toggle || sync[myconnectindex].actions & SB_CROUCH); + apply_seasick(p, scaleAdjust); sethorizon(&p->q16horiz, input.q16horz, &sync[myconnectindex].actions, scaleAdjust); + if (p->angAdjust) + { + p->q16ang += FloatToFixed(scaleAdjust * p->angAdjust); + } + if (p->horizAdjust) { p->q16horiz += FloatToFixed(scaleAdjust * p->horizAdjust); diff --git a/source/games/duke/src/player.cpp b/source/games/duke/src/player.cpp index b6dc30f41..169b99f71 100644 --- a/source/games/duke/src/player.cpp +++ b/source/games/duke/src/player.cpp @@ -763,7 +763,7 @@ void playerJump(int snum, int fz, int cz) void apply_seasick(player_struct* p, double factor) { - if (isRRRA() && p->SeaSick) + if (isRRRA() && p->SeaSick && p->dead_flag == 0) { if (p->SeaSick < 250) { @@ -787,63 +787,17 @@ void apply_seasick(player_struct* p, double factor) // //--------------------------------------------------------------------------- -void applylook(int snum, double factor, fixed_t adjustment) +void processq16avel(player_struct* p, fixed_t* q16avel) { - auto p = &ps[snum]; - fixed_t q16avel; - - if (p->dead_flag == 0) - { - p->addrotscrnang(factor * -0.5 * FixedToFloat(p->q16rotscrnang)); - if (abs(p->q16rotscrnang) < FRACUNIT) p->q16rotscrnang = 0; - - p->addlookang(factor * -0.25 * FixedToFloat(p->q16look_ang)); - if (abs(p->q16look_ang) < FRACUNIT) p->q16look_ang = 0; - - if (p->lookLeft) - { - p->addlookang(factor * -152); - p->addrotscrnang(factor * 24); - } - - if (p->lookRight) - { - p->addlookang(factor * 152); - p->addrotscrnang(factor * -24); - } - - if (p->one_eighty_count < 0 && p->on_crane < 0) - { - fixed_t add = FloatToFixed(factor * 128); - p->one_eighty_count += add; - if (p->one_eighty_count > 0) - { - // Don't overshoot our target. With variable factor this is possible. - add -= p->one_eighty_count; - p->one_eighty_count = 0; - } - p->q16ang += add; - } - apply_seasick(p, factor); - } - - // Add angAdjust if input is unsynchronised. - if (!cl_syncinput) - { - p->q16ang += FloatToFixed(factor * p->angAdjust); - } - // Taken from processinput() for use with applying look while cl_syncinput is 0. if (p->psectlotag == ST_2_UNDERWATER) { - q16avel = (adjustment - (adjustment >> 3)) * sgn(TICSPERFRAME); + *q16avel = (*q16avel - (*q16avel >> 3)) * sgn(TICSPERFRAME); } else { - q16avel = adjustment * sgn(TICSPERFRAME); + *q16avel = *q16avel * sgn(TICSPERFRAME); } - - p->q16ang = (p->q16ang + q16avel) & 0x7FFFFFF; } //--------------------------------------------------------------------------- @@ -972,15 +926,13 @@ void checklook(int snum, ESyncBits actions) { auto p = &ps[snum]; - p->lookLeft = false; - p->lookRight = false; if ((actions & SB_LOOK_LEFT) && !p->OnMotorcycle) { SetGameVarID(g_iReturnVarID, 0, p->i, snum); OnEvent(EVENT_LOOKLEFT, p->i, snum, -1); - if (GetGameVarID(g_iReturnVarID, p->i, snum) == 0) + if (GetGameVarID(g_iReturnVarID, p->i, snum) != 0) { - p->lookLeft = true; + actions &= ~SB_LOOK_LEFT; } } @@ -988,9 +940,9 @@ void checklook(int snum, ESyncBits actions) { SetGameVarID(g_iReturnVarID, 0, p->i, snum); OnEvent(EVENT_LOOKRIGHT, p->i, snum, -1); - if (GetGameVarID(g_iReturnVarID, p->i, snum) == 0) + if (GetGameVarID(g_iReturnVarID, p->i, snum) != 0) { - p->lookRight = true; + actions &= ~SB_LOOK_RIGHT; } } backuplook(p); diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index 700ab020f..80d09468b 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -2846,7 +2846,8 @@ void processinput_d(int snum) //ENGINE calculates angvel for you // may still be needed later for demo recording - applylook(snum, 1, sb_avel); + processq16avel(p, &sb_avel); + applylook(&p->q16ang, &p->q16look_ang, &p->q16rotscrnang, &p->one_eighty_count, sb_avel, &actions, 1, p->dead_flag != 0, p->crouch_toggle || actions & SB_CROUCH); } if (p->spritebridge == 0) diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index 9b3cd60b6..806c976f3 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -1611,29 +1611,29 @@ static void onMotorcycle(int snum, ESyncBits &actions) if (!S_CheckActorSoundPlaying(pi, 189) && !S_CheckActorSoundPlaying(pi, 187)) S_PlayActorSound(187, pi); } - if (actions & SB_AIM_UP) + if (p->vehicle_backwards) { var6c = 1; - actions &= ~SB_AIM_UP; + p->vehicle_backwards = false; } else var6c = 0; - if (actions & SB_AIM_DOWN) + if (p->vehicle_turnl) { var70 = 1; var74 = 1; - actions &= ~SB_AIM_DOWN; + p->vehicle_turnl = false; } else { var70 = 0; var74 = 0; } - if (actions & SB_LOOK_LEFT) + if (p->vehicle_turnr) { var78 = 1; var7c = 1; - actions &= ~SB_LOOK_LEFT; + p->vehicle_turnr = false; } else { @@ -1914,17 +1914,17 @@ static void onBoat(int snum, ESyncBits &actions) } else varb0 = 0; - if (actions & SB_AIM_UP) + if (p->vehicle_backwards) { varb4 = 1; - actions &= ~SB_AIM_UP; + p->vehicle_backwards = false; } else varb4 = 0; - if (actions & SB_AIM_DOWN) + if (p->vehicle_turnl) { varb8 = 1; varbc = 1; - actions &= ~SB_AIM_DOWN; + p->vehicle_turnl = false; if (!S_CheckActorSoundPlaying(pi, 91) && p->MotoSpeed > 30 && !p->NotOnWater) S_PlayActorSound(91, pi); } @@ -1933,11 +1933,11 @@ static void onBoat(int snum, ESyncBits &actions) varb8 = 0; varbc = 0; } - if (actions & SB_LOOK_LEFT) + if (p->vehicle_turnr) { varc0 = 1; varc4 = 1; - actions &= ~SB_LOOK_LEFT; + p->vehicle_turnr = false; if (!S_CheckActorSoundPlaying(pi, 91) && p->MotoSpeed > 30 && !p->NotOnWater) S_PlayActorSound(91, pi); } @@ -3736,7 +3736,9 @@ void processinput_r(int snum) //ENGINE calculates angvel for you // may still be needed later for demo recording - applylook(snum, 1, sb_avel); + processq16avel(p, &sb_avel); + applylook(&p->q16ang, &p->q16look_ang, &p->q16rotscrnang, &p->one_eighty_count, sb_avel, &actions, 1, p->dead_flag != 0, p->crouch_toggle || actions & SB_CROUCH); + apply_seasick(p, 1); } if (p->spritebridge == 0) diff --git a/source/games/duke/src/savegame.cpp b/source/games/duke/src/savegame.cpp index 14fc52b17..f0de68fc0 100644 --- a/source/games/duke/src/savegame.cpp +++ b/source/games/duke/src/savegame.cpp @@ -298,8 +298,6 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, player_struct& w, w.ohard_landing = w.hard_landing; w.horizAdjust = 0; w.angAdjust = 0; - w.lookLeft = false; - w.lookRight = false; } return arc; } diff --git a/source/games/duke/src/types.h b/source/games/duke/src/types.h index 812af4888..d537685f5 100644 --- a/source/games/duke/src/types.h +++ b/source/games/duke/src/types.h @@ -203,12 +203,12 @@ struct player_struct uint8_t hurt_delay2, nocheat; uint8_t OnMotorcycle, OnBoat, moto_underwater, NotOnWater, MotoOnGround; uint8_t moto_do_bump, moto_bump_fast, moto_on_oil, moto_on_mud; + bool vehicle_turnl, vehicle_turnr, vehicle_backwards; int8_t crouch_toggle; // input stuff. double horizAdjust, angAdjust; - bool lookLeft, lookRight; // Access helpers for the widened angle and horizon fields. diff --git a/source/sw/src/draw.cpp b/source/sw/src/draw.cpp index 6293460e3..94771db49 100644 --- a/source/sw/src/draw.cpp +++ b/source/sw/src/draw.cpp @@ -1262,7 +1262,7 @@ void DrawCrosshair(PLAYERp pp) if (!(CameraTestMode) && !TEST(pp->Flags, PF_VIEW_FROM_OUTSIDE)) { USERp u = User[pp->PlayerSprite]; - ::DrawCrosshair(2326, u->Health, 0, 2, shadeToLight(10)); + ::DrawCrosshair(2326, u->Health, -getHalfLookAng(pp->oq16look_ang, pp->q16look_ang, cl_syncinput, smoothratio), 2, shadeToLight(10)); } } @@ -1611,7 +1611,7 @@ drawscreen(PLAYERp pp, double smoothratio) { extern bool CameraTestMode; int tx, ty, tz; - fixed_t tq16horiz, tq16ang; + fixed_t tq16horiz, tq16ang, tq16rotscrnang; short tsectnum; short i,j; int bob_amt = 0; @@ -1654,16 +1654,23 @@ 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 || (!cl_syncinput && pp->sop && !TEST(pp->Flags2, PF2_INPUT_CAN_TURN_TURRET))) { - tq16ang = camerapp->oq16ang + xs_CRoundToInt(fmulscale16(NORM_Q16ANGLE(camerapp->q16ang + IntToFixed(1024) - camerapp->oq16ang) - IntToFixed(1024), smoothratio)); + 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)); } else { - tq16ang = pp->q16ang; + tq16ang = pp->q16ang + pp->q16look_ang; tq16horiz = pp->q16horiz; + tq16rotscrnang = pp->q16rotscrnang; } tsectnum = camerapp->cursectnum; + renderSetRollAngle(FixedToFloat(tq16rotscrnang)); + COVERupdatesector(tx, ty, &tsectnum); if (tsectnum >= 0) diff --git a/source/sw/src/game.h b/source/sw/src/game.h index 63c7c4eea..8fd9ea8a2 100644 --- a/source/sw/src/game.h +++ b/source/sw/src/game.h @@ -832,6 +832,7 @@ struct PLAYERstruct int oposx, oposy, oposz; fixed_t oq16horiz, oq16ang; + fixed_t oq16look_ang, oq16rotscrnang; // holds last valid move position short lv_sectnum; @@ -882,6 +883,7 @@ 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; short recoil_amt; short recoil_speed; short recoil_ndx; @@ -1042,7 +1044,6 @@ enum PF_DIVING = (BIT(17)), PF_DIVING_IN_LAVA = (BIT(18)), PF_TWO_UZI = (BIT(19)), - PF_TURN_180 = (BIT(21)), PF_DEAD_HEAD = (BIT(22)), // are your a dead head PF_HEAD_CONTROL = (BIT(23)), // have control of turning when a head? PF_CLIP_CHEAT = (BIT(24)), // cheat for wall clipping diff --git a/source/sw/src/panel.cpp b/source/sw/src/panel.cpp index f9fbf3b61..aa80a0419 100644 --- a/source/sw/src/panel.cpp +++ b/source/sw/src/panel.cpp @@ -6921,13 +6921,16 @@ pDisplaySprites(PLAYERp pp, double smoothratio) short ang; int flags; + double look_anghalf = getHalfLookAng(pp->oq16look_ang, pp->q16look_ang, cl_syncinput, smoothratio); + double looking_arc = fabs(look_anghalf) / 4.5; + TRAVERSE(&pp->PanelSpriteList, psp, next) { ang = psp->rotate_ang; shade = 0; flags = 0; - x = psp->ox + fmulscale16(psp->x - psp->ox, smoothratio); - y = psp->oy + fmulscale16(psp->y - psp->oy, smoothratio); + x = (psp->ox + fmulscale16(psp->x - psp->ox, smoothratio)) - look_anghalf; + y = (psp->oy + fmulscale16(psp->y - psp->oy, smoothratio)) + looking_arc; // initilize pal here - jack with it below pal = psp->pal; diff --git a/source/sw/src/player.cpp b/source/sw/src/player.cpp index 622b3d3ec..ce9721a88 100644 --- a/source/sw/src/player.cpp +++ b/source/sw/src/player.cpp @@ -120,12 +120,6 @@ char PlayerGravity = PLAYER_JUMP_GRAV; extern bool DebugOperate; -enum -{ - TURN_SHIFT = 2, - HORIZ_SPEED = 14 -}; - //unsigned char synctics, lastsynctics; int ChopTics; @@ -1505,78 +1499,22 @@ DoPlayerCrawlHeight(PLAYERp pp) pp->posz = pp->posz - (DIV4(diff) + DIV8(diff)); } +void +UpdatePlayerSpriteAngle(PLAYERp pp) +{ + sprite[pp->PlayerSprite].ang = FixedToInt(pp->q16ang); + + if (!Prediction && pp->PlayerUnderSprite >= 0) + { + sprite[pp->PlayerUnderSprite].ang = FixedToInt(pp->q16ang); + } +} + void DoPlayerTurn(PLAYERp pp, fixed_t const q16avel, double const scaleAdjust) { - if (!TEST(pp->Flags, PF_TURN_180)) - { - if (pp->input.actions & SB_TURNAROUND) - { - if (pp->KeyPressBits & SB_TURNAROUND) - { - fixed_t delta_ang; - - pp->KeyPressBits &= ~SB_TURNAROUND; - - pp->turn180_target = pp->q16ang + IntToFixed(1024); - - // make the first turn in the clockwise direction - // the rest will follow - delta_ang = labs(getincangleq16(pp->q16ang, pp->turn180_target)) >> TURN_SHIFT; - pp->q16ang = (pp->q16ang + xs_CRoundToInt(scaleAdjust * delta_ang)) & 0x7FFFFFF; - - SET(pp->Flags, PF_TURN_180); - } - } - else - { - pp->KeyPressBits |= SB_TURNAROUND; - } - } - - if (TEST(pp->Flags, PF_TURN_180)) - { - fixed_t delta_ang; - - delta_ang = getincangleq16(pp->q16ang, pp->turn180_target) >> TURN_SHIFT; - pp->q16ang = (pp->q16ang + xs_CRoundToInt(scaleAdjust * delta_ang)) & 0x7FFFFFF; - - sprite[pp->PlayerSprite].ang = FixedToInt(pp->q16ang); - - if (!Prediction && pp->PlayerUnderSprite >= 0) - { - sprite[pp->PlayerUnderSprite].ang = FixedToInt(pp->q16ang); - } - - // get new delta to see how close we are - delta_ang = getincangleq16(pp->q16ang, pp->turn180_target); - - if (labs(delta_ang) < (IntToFixed(3) << TURN_SHIFT)) - { - pp->q16ang = pp->turn180_target; - RESET(pp->Flags, PF_TURN_180); - } - else - { - return; - } - } - - if (q16avel != 0) - { - pp->q16ang = (pp->q16ang + q16avel) & 0x7FFFFFF; - - // update players sprite angle - // NOTE: It's also updated in UpdatePlayerSprite, but needs to be - // here to cover - // all cases. - sprite[pp->PlayerSprite].ang = FixedToInt(pp->q16ang); - - if (!Prediction && pp->PlayerUnderSprite >= 0) - { - sprite[pp->PlayerUnderSprite].ang = FixedToInt(pp->q16ang); - } - } + applylook(&pp->q16ang, &pp->q16look_ang, &pp->q16rotscrnang, &pp->turn180_target, q16avel, &pp->input.actions, scaleAdjust, TEST(pp->Flags, PF_DEAD), pp->input.actions & (SB_CROUCH|SB_CROUCH_LOCK)); + UpdatePlayerSpriteAngle(pp); } #if 0 @@ -7022,6 +6960,8 @@ MoveSkipSavePos(void) pp->oq16ang = pp->q16ang; pp->oq16horiz = pp->q16horiz; pp->obob_z = pp->bob_z; + pp->oq16look_ang = pp->q16look_ang; + pp->oq16rotscrnang = pp->q16rotscrnang; } // save off stats for skip4 diff --git a/wadsrc/static/engine/menudef.txt b/wadsrc/static/engine/menudef.txt index c50fce455..1ea064533 100644 --- a/wadsrc/static/engine/menudef.txt +++ b/wadsrc/static/engine/menudef.txt @@ -520,7 +520,7 @@ OptionMenu "ActionControlsMenu"// protected Control "$CNTRLMNU_AIMDOWN" , "+aim_down" Control "$CNTRLMNU_LOOKUP" , "+look_up" Control "$CNTRLMNU_LOOKDOWN" , "+look_down" - ifgame(Duke, Nam, WW2GI, Redneck, RedneckRides) + ifnotgame(Exhumed) { Control "$CNTRLMNU_LOOKLEFT" , "+look_left" Control "$CNTRLMNU_LOOKRIGHT" , "+look_right"