diff --git a/source/games/duke/src/funct.h b/source/games/duke/src/funct.h index 48c281b14..2df95f938 100644 --- a/source/games/duke/src/funct.h +++ b/source/games/duke/src/funct.h @@ -231,7 +231,7 @@ void setlocalplayerinput(player_struct *pp); void PlayerColorChanged(void); void nonsharedkeys(void); void apply_seasick(player_struct* p, double scalefactor); -void calcviewpitch(player_struct* p, int psectlotag, double factor); +void calcviewpitch(player_struct* p, double factor); void sethorizon(int snum, int sb_snum, double factor, bool frominput = false); END_DUKE_NS diff --git a/source/games/duke/src/input.cpp b/source/games/duke/src/input.cpp index d2e5d1962..4106f154f 100644 --- a/source/games/duke/src/input.cpp +++ b/source/games/duke/src/input.cpp @@ -681,10 +681,26 @@ void hud_input(int snum) } } +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- enum { - TURBOTURNTIME = (TICRATE/8) // 7 + TURBOTURNTIME = (TICRATE/8), // 7 + NORMALTURN = 15, + PREAMBLETURN = 5, + NORMALKEYMOVE = 40, + MAXVEL = ((NORMALKEYMOVE*2)+10), + MAXSVEL = ((NORMALKEYMOVE*2)+10), + MAXANGVEL = 1024, + MAXHORIZVEL = 256, + ONEEIGHTYSCALE = 4, + + MOTOTURN = 20, + MAXVELMOTO = 120, }; //--------------------------------------------------------------------------- @@ -713,12 +729,13 @@ fix16_t GetDeltaQ16Angle(fix16_t ang1, fix16_t ang2) //--------------------------------------------------------------------------- // -// common handler for all 3 input methods. +// handles the input bits // //--------------------------------------------------------------------------- -void processCommonInput(ControlInfo &info, bool onVehicle) +void processInputBits(player_struct *p, ControlInfo &info) { + bool onVehicle = p->OnMotorcycle || p->OnBoat; if (buttonMap.ButtonDown(gamefunc_Fire)) loc.bits |= SKB_FIRE; if (buttonMap.ButtonDown(gamefunc_Open)) loc.bits |= SKB_OPEN; @@ -731,42 +748,161 @@ void processCommonInput(ControlInfo &info, bool onVehicle) { if (info.dx < 0 || info.dyaw < 0) loc.bits |= SKB_INV_LEFT; if (info.dx > 0 || info.dyaw < 0) loc.bits |= SKB_INV_RIGHT; + } + + if (g_gameQuit) loc.bits |= SKB_GAMEQUIT; + //if (inputState.GetKeyStatus(sc_Escape)) loc.bits |= SKB_ESCAPE; fixme. This never gets here because the menu eats the escape key. + + if (!onVehicle) + { + if (buttonMap.ButtonDown(gamefunc_Jump)) loc.bits |= SKB_JUMP; + if (buttonMap.ButtonDown(gamefunc_Crouch) || buttonMap.ButtonDown(gamefunc_Toggle_Crouch) || p->crouch_toggle) + { + loc.bits |= SKB_CROUCH; + if (isRR()) loc.bits &= ~SKB_JUMP; + } + if (buttonMap.ButtonDown(gamefunc_Aim_Up) || (buttonMap.ButtonDown(gamefunc_Dpad_Aiming) && info.dz > 0)) loc.bits |= SKB_AIM_UP; + if ((buttonMap.ButtonDown(gamefunc_Aim_Down) || (buttonMap.ButtonDown(gamefunc_Dpad_Aiming) && info.dz < 0))) loc.bits |= SKB_AIM_DOWN; + if (G_CheckAutorun(buttonMap.ButtonDown(gamefunc_Run))) loc.bits |= SKB_RUN; + if (buttonMap.ButtonDown(gamefunc_Look_Left) || (isRR() && p->drink_amt > 88)) loc.bits |= SKB_LOOK_LEFT; + if (buttonMap.ButtonDown(gamefunc_Look_Right)) loc.bits |= SKB_LOOK_RIGHT; + if (buttonMap.ButtonDown(gamefunc_Look_Up)) loc.bits |= SKB_LOOK_UP; + if (buttonMap.ButtonDown(gamefunc_Look_Down) || (isRR() && p->drink_amt > 99)) loc.bits |= SKB_LOOK_DOWN; + if (buttonMap.ButtonDown(gamefunc_Quick_Kick)) loc.bits |= SKB_QUICK_KICK; + if (in_mousemode || buttonMap.ButtonDown(gamefunc_Mouse_Aiming)) loc.bits |= SKB_AIMMODE; + + int j = WeaponToSend; + WeaponToSend = 0; + if (VOLUMEONE && (j >= 7 && j <= 10)) j = 0; + + if (buttonMap.ButtonDown(gamefunc_Dpad_Select) && info.dz > 0) j = 11; + if (buttonMap.ButtonDown(gamefunc_Dpad_Select) && info.dz < 0) j = 12; + + if (j && (loc.bits & SKB_WEAPONMASK_BITS) == 0) + loc.bits |= ESyncBits::FromInt(j * SKB_FIRST_WEAPON_BIT); + + } + + if (buttonMap.ButtonDown(gamefunc_Dpad_Select)) + { // This eats the controller input for regular use info.dx = 0; info.dz = 0; info.dyaw = 0; } - if (g_gameQuit) loc.bits |= SKB_GAMEQUIT; - //if (inputState.GetKeyStatus(sc_Escape)) loc.bits |= SKB_ESCAPE; fixme. This never gets here because the menu eats the escape key. - if (buttonMap.ButtonDown(gamefunc_Dpad_Aiming)) info.dz = 0; } //--------------------------------------------------------------------------- // -// weapon selection bits. Using CVARs now instead of buttons. +// handles movement // //--------------------------------------------------------------------------- -void processSelectWeapon(input_t& input) +void processMovement(player_struct *p, input_t &input, ControlInfo &info, double scaleFactor) { - int j = WeaponToSend; - WeaponToSend = 0; - if (VOLUMEONE && (j >= 7 && j <= 10)) j = 0; + bool mouseaim = in_mousemode || buttonMap.ButtonDown(gamefunc_Mouse_Aiming); - if (buttonMap.ButtonDown(gamefunc_Dpad_Select) && input.fvel < 0) j = 11; - if (buttonMap.ButtonDown(gamefunc_Dpad_Select) && input.fvel < 0) j = 12; + // JBF: Run key behaviour is selectable + int running = G_CheckAutorun(buttonMap.ButtonDown(gamefunc_Run)); + int turnamount = NORMALTURN << running; + int keymove = NORMALKEYMOVE << running; - if (j && (loc.bits & SKB_WEAPONMASK_BITS) == 0) - loc.bits |= ESyncBits::FromInt(j * SKB_FIRST_WEAPON_BIT); + if (buttonMap.ButtonDown(gamefunc_Strafe)) + input.svel -= info.mousex * 4.f + scaleFactor * info.dyaw * keymove; + else + input.q16avel += fix16_from_float(info.mousex + scaleFactor * info.dyaw); + if (mouseaim) + input.q16horz += fix16_from_float(info.mousey); + else + input.fvel -= info.mousey * 8.f; + + if (!in_mouseflip) input.q16horz = -input.q16horz; + + input.q16horz -= fix16_from_dbl(scaleFactor * (info.dpitch)); + input.svel -= scaleFactor * (info.dx * keymove); + input.fvel -= scaleFactor * (info.dz * keymove); + + if (buttonMap.ButtonDown(gamefunc_Strafe)) + { + if (!loc.svel) + { + if (buttonMap.ButtonDown(gamefunc_Turn_Left)) + input.svel = keymove; + + if (buttonMap.ButtonDown(gamefunc_Turn_Right)) + input.svel = -keymove; + } + } + else + { + static int turnheldtime; + static int lastcontroltime; // MED + int tics = (int)totalclock - lastcontroltime; + lastcontroltime = (int)totalclock; + + if (buttonMap.ButtonDown(gamefunc_Turn_Left)) + { + turnheldtime += tics; + input.q16avel -= fix16_from_dbl(2 * scaleFactor * (turnheldtime >= TURBOTURNTIME) ? turnamount : PREAMBLETURN); + } + else if (buttonMap.ButtonDown(gamefunc_Turn_Right)) + { + turnheldtime += tics; + input.q16avel += fix16_from_dbl(2 * scaleFactor * (turnheldtime >= TURBOTURNTIME) ? turnamount : PREAMBLETURN); + } + else + turnheldtime = 0; + } + + if (loc.svel < abs(keymove)) + { + if (buttonMap.ButtonDown(gamefunc_Strafe_Left)) + input.svel += keymove; + + if (buttonMap.ButtonDown(gamefunc_Strafe_Right)) + input.svel += -keymove; + } + + if (loc.fvel < abs(keymove)) + { + if (isRR() && p->drink_amt >= 66 && p->drink_amt <= 87) + { + if (buttonMap.ButtonDown(gamefunc_Move_Forward)) + { + input.fvel += keymove; + if (p->drink_amt & 1) + input.svel += keymove; + else + input.svel -= keymove; + } + + if (buttonMap.ButtonDown(gamefunc_Move_Backward)) + { + input.fvel += -keymove; + if (p->drink_amt & 1) + input.svel -= keymove; + else + input.svel += keymove; + } + } + else + { + if (buttonMap.ButtonDown(gamefunc_Move_Forward)) + input.fvel += keymove; + + if (buttonMap.ButtonDown(gamefunc_Move_Backward)) + input.fvel += -keymove; + } + } } //--------------------------------------------------------------------------- // -// split out of playerinputmotocycle for readability purposes and condensed using ?: operators +// split out for readability // //--------------------------------------------------------------------------- @@ -958,9 +1094,9 @@ void processVehicleInput(player_struct *p, ControlInfo& info, input_t& input, do if (p->OnMotorcycle) { - bool moveBack = buttonMap.ButtonDown(gamefunc_Move_Backward) && p->MotoSpeed <= 0; + bool backward = buttonMap.ButtonDown(gamefunc_Move_Backward) && p->MotoSpeed <= 0; - turnvel = motoApplyTurn(p, turnl, turnr, turnspeed, moveBack, scaleAdjust); + turnvel = motoApplyTurn(p, turnl, turnr, turnspeed, backward, scaleAdjust); if (p->moto_underwater) p->MotoSpeed = 0; } else diff --git a/source/games/duke/src/player.cpp b/source/games/duke/src/player.cpp index 63287b0a0..23a2dbf65 100644 --- a/source/games/duke/src/player.cpp +++ b/source/games/duke/src/player.cpp @@ -88,9 +88,10 @@ void setlocalplayerinput(player_struct* pp) // //--------------------------------------------------------------------------- -void calcviewpitch(player_struct *p, int psectlotag, double factor) +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); diff --git a/source/games/duke/src/player_d.cpp b/source/games/duke/src/player_d.cpp index dd6e72e36..af8d5aa16 100644 --- a/source/games/duke/src/player_d.cpp +++ b/source/games/duke/src/player_d.cpp @@ -2642,7 +2642,7 @@ void processinput_d(int snum) { p->oq16horiz = p->q16horiz; p->oq16horizoff = p->q16horizoff; - calcviewpitch(p, psectlotag, 1); + calcviewpitch(p, 1); } if (hz >= 0 && (hz & 49152) == 49152) diff --git a/source/games/duke/src/player_r.cpp b/source/games/duke/src/player_r.cpp index f92cacc90..e3e0817f5 100644 --- a/source/games/duke/src/player_r.cpp +++ b/source/games/duke/src/player_r.cpp @@ -3478,7 +3478,7 @@ void processinput_r(int snum) { p->oq16horiz = p->q16horiz; p->oq16horizoff = p->q16horizoff; - calcviewpitch(p, psectlotag, 1); + calcviewpitch(p, 1); } if (hz >= 0 && (hz & 49152) == 49152) diff --git a/source/games/duke/src/zz_player.cpp b/source/games/duke/src/zz_player.cpp index 5c435d58e..a0bcd50f3 100644 --- a/source/games/duke/src/zz_player.cpp +++ b/source/games/duke/src/zz_player.cpp @@ -28,10 +28,10 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. BEGIN_DUKE_NS fix16_t GetDeltaQ16Angle(fix16_t ang1, fix16_t ang2); -void processCommonInput(ControlInfo& info, bool onVehicle); -void processSelectWeapon(input_t& input); +void processInputBits(player_struct *p, ControlInfo& info); int motoApplyTurn(player_struct* p, int turnl, int turnr, int bike_turn, bool goback, double factor); void processVehicleInput(player_struct* p, ControlInfo& info, input_t& input, double scaleAdjust); +void processMovement(player_struct* p, input_t& input, ControlInfo& info, double scaleFactor); int32_t PHEIGHT = PHEIGHT_DUKE; @@ -63,6 +63,12 @@ enum inputlock_t IL_NOTHING = IL_NOANGLE|IL_NOHORIZ|IL_NOMOVE, }; +//--------------------------------------------------------------------------- +// +// +// +//--------------------------------------------------------------------------- + static int P_CheckLockedMovement(int const playerNum) { auto& thisPlayer = g_player[playerNum]; @@ -88,6 +94,34 @@ static int P_CheckLockedMovement(int const playerNum) return 0; } +//--------------------------------------------------------------------------- +// +// split off so that it can later be integrated into the other games more easily. +// +//--------------------------------------------------------------------------- + +void checkCrouchToggle(player_struct* p) +{ + int const sectorLotag = p->cursectnum != -1 ? sector[p->cursectnum].lotag : 0; + int const crouchable = sectorLotag != ST_2_UNDERWATER && (sectorLotag != ST_1_ABOVE_WATER || p->spritebridge); + + if (buttonMap.ButtonDown(gamefunc_Toggle_Crouch)) + { + p->crouch_toggle = !p->crouch_toggle && crouchable; + + if (crouchable) + buttonMap.ClearButton(gamefunc_Toggle_Crouch); + } + + if (buttonMap.ButtonDown(gamefunc_Crouch) || buttonMap.ButtonDown(gamefunc_Jump) || p->jetpack_on || (!crouchable && p->on_ground)) + p->crouch_toggle = 0; +} + +//--------------------------------------------------------------------------- +// +// common code for all input modes (with one minor special check) +// +//--------------------------------------------------------------------------- void FinalizeInput(int playerNum, input_t &input, bool vehicle) { @@ -143,187 +177,32 @@ void FinalizeInput(int playerNum, input_t &input, bool vehicle) double elapsedInputTicks = -1; -static double scaleAdjustmentToInterval(double x) -{ - return x * REALGAMETICSPERSEC / (1000.0 / elapsedInputTicks); -} - void P_GetInput(int const playerNum) { - auto &thisPlayer = g_player[playerNum]; auto const pPlayer = &ps[playerNum]; - auto const pSprite = &sprite[pPlayer->i]; ControlInfo info; double scaleAdjust = elapsedInputTicks * REALGAMETICSPERSEC / 1000.0; - bool mouseaim = in_mousemode || buttonMap.ButtonDown(gamefunc_Mouse_Aiming); - CONTROL_GetInput(&info); - - // JBF: Run key behaviour is selectable - - int const playerRunning = G_CheckAutorun(buttonMap.ButtonDown(gamefunc_Run)); - int const turnAmount = playerRunning ? (NORMALTURN << 1) : NORMALTURN; - constexpr int analogTurnAmount = (NORMALTURN << 1); - int const keyMove = playerRunning ? (NORMALKEYMOVE << 1) : NORMALKEYMOVE; - constexpr int analogExtent = 32767; // KEEPINSYNC sdlayer.cpp - input_t input {}; - if (buttonMap.ButtonDown(gamefunc_Strafe)) - { - input.svel -= info.mousex * 4.f; - input.svel -= scaleAdjustmentToInterval(info.dyaw * keyMove); - } - else - { - input.q16avel = fix16_sadd(input.q16avel, fix16_from_float(info.mousex)); - input.q16avel = fix16_sadd(input.q16avel, fix16_from_dbl(scaleAdjustmentToInterval(info.dyaw))); - } - - if (mouseaim) - input.q16horz = fix16_sadd(input.q16horz, fix16_from_float(info.mousey)); - else - input.fvel -= info.mousey * 8.f; - - if (!in_mouseflip) input.q16horz = -input.q16horz; - - input.q16horz = fix16_ssub(input.q16horz, fix16_from_dbl(scaleAdjustmentToInterval(info.dpitch))); - input.svel -= scaleAdjustmentToInterval(info.dx * keyMove); - input.fvel -= scaleAdjustmentToInterval(info.dz * keyMove); - - if (buttonMap.ButtonDown(gamefunc_Strafe)) - { - if (!loc.svel) - { - if (buttonMap.ButtonDown(gamefunc_Turn_Left) && !loc.svel) - input.svel = keyMove; - - if (buttonMap.ButtonDown(gamefunc_Turn_Right) && !loc.svel) - input.svel = -keyMove; - } - } - else - { - static int32_t turnHeldTime; - static int32_t lastInputClock; // MED - int32_t const elapsedTics = (int32_t)totalclock - lastInputClock; - - lastInputClock = (int32_t) totalclock; - - if (buttonMap.ButtonDown(gamefunc_Turn_Left)) - { - turnHeldTime += elapsedTics; - input.q16avel = fix16_ssub(input.q16avel, fix16_from_dbl(scaleAdjustmentToInterval((turnHeldTime >= TURBOTURNTIME) ? (turnAmount << 1) : (PREAMBLETURN << 1)))); - } - else if (buttonMap.ButtonDown(gamefunc_Turn_Right)) - { - turnHeldTime += elapsedTics; - input.q16avel = fix16_sadd(input.q16avel, fix16_from_dbl(scaleAdjustmentToInterval((turnHeldTime >= TURBOTURNTIME) ? (turnAmount << 1) : (PREAMBLETURN << 1)))); - } - else - turnHeldTime = 0; - } - - if (loc.svel < keyMove && loc.svel > -keyMove) - { - if (buttonMap.ButtonDown(gamefunc_Strafe_Left)) - input.svel += keyMove; - - if (buttonMap.ButtonDown(gamefunc_Strafe_Right)) - input.svel += -keyMove; - } - - if (loc.fvel < keyMove && loc.fvel > -keyMove) - { - if (isRR() && pPlayer->drink_amt >= 66 && pPlayer->drink_amt <= 87) - { - if (buttonMap.ButtonDown(gamefunc_Move_Forward)) - { - input.fvel += keyMove; - if (pPlayer->drink_amt & 1) - input.svel += keyMove; - else - input.svel -= keyMove; - } - - if (buttonMap.ButtonDown(gamefunc_Move_Backward)) - { - input.fvel += -keyMove; - if (pPlayer->drink_amt & 1) - input.svel -= keyMove; - else - input.svel += keyMove; - } - } - else - { - if (buttonMap.ButtonDown(gamefunc_Move_Forward)) - input.fvel += keyMove; - - if (buttonMap.ButtonDown(gamefunc_Move_Backward)) - input.fvel += -keyMove; - } - } - - processSelectWeapon(input); // this must be done before processcommoninput! - - - int const sectorLotag = pPlayer->cursectnum != -1 ? sector[pPlayer->cursectnum].lotag : 0; - int const crouchable = sectorLotag != 2 && (sectorLotag != 1 || pPlayer->spritebridge); - - if (buttonMap.ButtonDown(gamefunc_Toggle_Crouch)) - { - pPlayer->crouch_toggle = !pPlayer->crouch_toggle && crouchable; - - if (crouchable) - buttonMap.ClearButton(gamefunc_Toggle_Crouch); - } - - if (buttonMap.ButtonDown(gamefunc_Crouch) || buttonMap.ButtonDown(gamefunc_Jump) || pPlayer->jetpack_on || (!crouchable && pPlayer->on_ground)) - pPlayer->crouch_toggle = 0; - - processCommonInput(info, false); - - int const crouching = buttonMap.ButtonDown(gamefunc_Crouch) || buttonMap.ButtonDown(gamefunc_Toggle_Crouch) || pPlayer->crouch_toggle; - - loc.bits |= (buttonMap.ButtonDown(gamefunc_Jump) << SK_JUMP) | (crouching << SK_CROUCH); - - loc.bits |= (buttonMap.ButtonDown(gamefunc_Aim_Up) || (buttonMap.ButtonDown(gamefunc_Dpad_Aiming) && input.fvel > 0)) << SK_AIM_UP; - loc.bits |= (buttonMap.ButtonDown(gamefunc_Aim_Down) || (buttonMap.ButtonDown(gamefunc_Dpad_Aiming) && input.fvel < 0)) << SK_AIM_DOWN; - - loc.bits |= (buttonMap.ButtonDown(gamefunc_Look_Left) << SK_LOOK_LEFT) | (buttonMap.ButtonDown(gamefunc_Look_Right) << SK_LOOK_RIGHT); - loc.bits |= (buttonMap.ButtonDown(gamefunc_Look_Up) << SK_LOOK_UP) | (buttonMap.ButtonDown(gamefunc_Look_Down) << SK_LOOK_DOWN); - - loc.bits |= (playerRunning << SK_RUN); - - loc.bits |= buttonMap.ButtonDown(gamefunc_Quick_Kick) << SK_QUICK_KICK; - - loc.bits |= (mouseaim << SK_AIMMODE); - - if (isRR()) - { - if (loc.bits & SKB_CROUCH) - loc.bits &= ~SKB_JUMP; - if (pPlayer->drink_amt > 88) - loc.bits |= SKB_LOOK_LEFT; - if (pPlayer->drink_amt > 99) - loc.bits |= SKB_LOOK_DOWN; - } - + // here it goes + processMovement(pPlayer, input, info, scaleAdjust); + checkCrouchToggle(pPlayer); + processInputBits(pPlayer, info); FinalizeInput(playerNum, input, false); if (!synchronized_input) { // don't adjust rotscrnang and look_ang if dead. - if (pSprite->extra > 0) + if (sprite[pPlayer->i].extra > 0) { applylook(playerNum, scaleAdjust); } // Do these in the same order as the old code. - calcviewpitch(pPlayer, sectorLotag, scaleAdjust); + calcviewpitch(pPlayer, scaleAdjust); sethorizon(playerNum, loc.bits, scaleAdjust, true); } } @@ -340,7 +219,7 @@ void P_GetInputVehicle(int playerNum) input_t input {}; pPlayer->crouch_toggle = 0; - processCommonInput(info, true); + processInputBits(pPlayer, info); processVehicleInput(pPlayer, info, input, scaleAdjust); FinalizeInput(playerNum, input, true);