diff --git a/source/core/gameinput.cpp b/source/core/gameinput.cpp index 077e082b6..17a4fcaa5 100644 --- a/source/core/gameinput.cpp +++ b/source/core/gameinput.cpp @@ -370,6 +370,63 @@ void applylook(PlayerAngle* angle, float const avel, ESyncBits* actions, double } } +//--------------------------------------------------------------------------- +// +// Player's slope tilt when playing without a mouse and on a slope. +// +//--------------------------------------------------------------------------- + +void calcviewpitch(vec2_t const pos, fixedhoriz* horizoff, binangle const ang, bool const aimmode, bool const canslopetilt, int const cursectnum, double const scaleAdjust, bool const climbing) +{ + if (aimmode && canslopetilt) // If the floor is sloped + { + // Get a point, 512 units ahead of player's position + int x = pos.x + ang.bcos(-5); + int y = pos.y + ang.bsin(-5); + int16_t tempsect = cursectnum; + updatesector(x, y, &tempsect); + + if (tempsect >= 0) // If the new point is inside a valid sector... + { + // Get the floorz as if the new (x,y) point was still in + // your sector + int j = getflorzofslope(cursectnum, pos.x, pos.y); + int k = getflorzofslope(cursectnum, x, y); + + // If extended point is in same sector as you or the slopes + // of the sector of the extended point and your sector match + // closely (to avoid accidently looking straight out when + // you're at the edge of a sector line) then adjust horizon + // accordingly + if (cursectnum == tempsect || abs(getflorzofslope(tempsect, x, y) - k) <= (4 << 8)) + { + *horizoff += q16horiz(xs_CRoundToInt(scaleAdjust * ((j - k) * 160))); + } + } + } + + if (climbing) + { + // tilt when climbing but you can't even really tell it. + if (horizoff->asq16() < IntToFixed(100)) + *horizoff += q16horiz(xs_CRoundToInt(scaleAdjust * (((IntToFixed(100) - horizoff->asq16()) >> 3) + FRACUNIT))); + } + else + { + // Make horizoff grow towards 0 since horizoff is not modified when you're not on a slope. + if (horizoff->asq16() > 0) + { + *horizoff += q16horiz(xs_CRoundToInt(-scaleAdjust * ((horizoff->asq16() >> 3) + FRACUNIT))); + if (horizoff->asq16() < 0) *horizoff = q16horiz(0); + } + if (horizoff->asq16() < 0) + { + *horizoff += q16horiz(xs_CRoundToInt(-scaleAdjust * ((horizoff->asq16() >> 3) + FRACUNIT))); + if (horizoff->asq16() > 0) *horizoff = q16horiz(0); + } + } +} + FSerializer& Serialize(FSerializer& arc, const char* keyname, PlayerAngle& w, PlayerAngle* def) { if (arc.BeginObject(keyname)) diff --git a/source/core/gameinput.h b/source/core/gameinput.h index ff5deecd7..241591b91 100644 --- a/source/core/gameinput.h +++ b/source/core/gameinput.h @@ -272,3 +272,4 @@ FSerializer& Serialize(FSerializer& arc, const char* keyname, PlayerHorizon& w, 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(fixedhoriz* horiz, float const horz, ESyncBits* actions, double const scaleAdjust = 1); void applylook(PlayerAngle* angle, float const avel, ESyncBits* actions, double const scaleAdjust = 1); +void calcviewpitch(vec2_t const pos, fixedhoriz* horizoff, binangle const ang, bool const aimmode, bool const canslopetilt, int const cursectnum, double const scaleAdjust, bool const climbing = false); diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index 9c5ff1ddb..ea5c6d4fd 100644 --- a/source/games/duke/src/funct.h +++ b/source/games/duke/src/funct.h @@ -233,7 +233,6 @@ void donewgame(MapRecord* map, int sk); void startnewgame(MapRecord* map, int skill); int playercolor2lookup(int color); void PlayerColorChanged(void); -void calcviewpitch(player_struct* p, double factor); bool movementBlocked(int snum); void loadcons(); void recordoldspritepos(); diff --git a/source/games/duke/src/inlines.h b/source/games/duke/src/inlines.h index 799f18ab6..f39368bf9 100644 --- a/source/games/duke/src/inlines.h +++ b/source/games/duke/src/inlines.h @@ -193,6 +193,15 @@ inline double get16thOfHoriz(int const snum, bool const interpolate, double cons return (!interpolate ? ps[snum].horizon.sum() : ps[snum].horizon.interpolatedsum(smoothratio)).asq16() * (0.0625 / FRACUNIT); } +inline void doslopetilting(player_struct* p, double const scaleAdjust) +{ + if (cl_slopetilting) + { + bool const canslopetilt = p->on_ground && sector[p->cursectnum].lotag != ST_2_UNDERWATER && (sector[p->cursectnum].floorstat & 2); + calcviewpitch(p->pos.vec2, &p->horizon.horizoff, p->angle.ang, p->aim_mode == 0, canslopetilt, p->cursectnum, scaleAdjust); + } +} + //--------------------------------------------------------------------------- // diff --git a/source/games/duke/src/input.cpp b/source/games/duke/src/input.cpp index 58da321ea..471bb0ce5 100644 --- a/source/games/duke/src/input.cpp +++ b/source/games/duke/src/input.cpp @@ -881,7 +881,7 @@ void GameInterface::GetInput(InputPacket* packet, ControlInfo* const hidInput) if (p->GetActor()->s.extra > 0) { // Do these in the same order as the old code. - calcviewpitch(p, scaleAdjust); + doslopetilting(p, scaleAdjust); input.avel = p->adjustavel(input.avel); applylook(&p->angle, input.avel, &p->sync.actions, scaleAdjust); sethorizon(&p->horizon.horiz, input.horz, &p->sync.actions, scaleAdjust); diff --git a/source/games/duke/src/player.cpp b/source/games/duke/src/player.cpp index e73d95f8b..be4dbea6d 100644 --- a/source/games/duke/src/player.cpp +++ b/source/games/duke/src/player.cpp @@ -71,42 +71,6 @@ void PlayerColorChanged(void) pp.GetActor()->s.pal = ud.user_pals[myconnectindex]; } -//--------------------------------------------------------------------------- -// -// calculates automatic view pitch for playing without a mouse -// -//--------------------------------------------------------------------------- - -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 + p->angle.ang.bcos(-5); - int y = p->posy + p->angle.ang.bsin(-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->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); - } -} - //--------------------------------------------------------------------------- // // why is this such a mess? diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index 2285317d3..b93d62ac0 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -2779,7 +2779,7 @@ void processinput_d(int snum) if (SyncInput()) { p->horizon.backup(); - calcviewpitch(p, 1); + doslopetilting(p, 1); } if (chz.type == kHitSprite) diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index 56fc223a2..7afa1be35 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -3461,7 +3461,7 @@ void processinput_r(int snum) if (SyncInput()) { p->horizon.backup(); - calcviewpitch(p, 1); + doslopetilting(p, 1); } if (chz.type == kHitSprite) diff --git a/source/sw/src/player.cpp b/source/sw/src/player.cpp index d8e5c25c4..da36fec18 100644 --- a/source/sw/src/player.cpp +++ b/source/sw/src/player.cpp @@ -1664,71 +1664,15 @@ void SlipSlope(PLAYERp pp) pp->yvect += mulscale(bsin(ang), sector[pp->cursectnum].floorheinum, sectu->speed); } -void -PlayerAutoLook(PLAYERp pp, double const scaleAdjust) -{ - int x,y,k,j; - short tempsect; - - if (!TEST(pp->Flags, PF_FLYING|PF_SWIMMING|PF_DIVING|PF_CLIMBING|PF_JUMPING|PF_FALLING)) - { - if ((pp->input.actions & SB_AIMMODE) && TEST(sector[pp->cursectnum].floorstat, FLOOR_STAT_SLOPE)) // If the floor is sloped - { - // Get a point, 512 units ahead of player's position - x = pp->posx + pp->angle.ang.bcos(-5); - y = pp->posy + pp->angle.ang.bsin(-5); - tempsect = pp->cursectnum; - COVERupdatesector(x, y, &tempsect); - - if (tempsect >= 0) // If the new point is inside a valid sector... - { - // Get the floorz as if the new (x,y) point was still in - // your sector - j = getflorzofslope(pp->cursectnum, pp->posx, pp->posy); - k = getflorzofslope(pp->cursectnum, x, y); - - // If extended point is in same sector as you or the slopes - // of the sector of the extended point and your sector match - // closely (to avoid accidently looking straight out when - // you're at the edge of a sector line) then adjust horizon - // accordingly - if ((pp->cursectnum == tempsect) || (klabs(getflorzofslope(tempsect, x, y) - k) <= (4 << 8))) - { - pp->horizon.horizoff += q16horiz(xs_CRoundToInt(scaleAdjust * ((j - k) * 160))); - } - } - } - } - - if (TEST(pp->Flags, PF_CLIMBING) && pp->horizon.horizoff.asq16() < IntToFixed(100)) - { - // tilt when climbing but you can't even really tell it. - pp->horizon.horizoff += q16horiz(xs_CRoundToInt(scaleAdjust * (((IntToFixed(100) - pp->horizon.horizoff.asq16()) >> 3) + FRACUNIT))); - } - else - { - // Make horizoff grow towards 0 since horizoff is not modified when you're not on a slope. - if (pp->horizon.horizoff.asq16() > 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->horizon.horizoff.asq16() < 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, float const horz, double const scaleAdjust) { - // Fixme: This should probably be made optional. if (cl_slopetilting) - PlayerAutoLook(pp, scaleAdjust); + { + bool const canslopetilt = !TEST(pp->Flags, PF_FLYING|PF_SWIMMING|PF_DIVING|PF_CLIMBING|PF_JUMPING|PF_FALLING) && TEST(sector[pp->cursectnum].floorstat, FLOOR_STAT_SLOPE); + calcviewpitch(pp->pos.vec2, &pp->horizon.horizoff, pp->angle.ang, pp->input.actions & SB_AIMMODE, canslopetilt, pp->cursectnum, scaleAdjust, TEST(pp->Flags, PF_CLIMBING)); + } - // apply default horizon from backend sethorizon(&pp->horizon.horiz, horz, &pp->input.actions, scaleAdjust); }