- Initial conversion of game input into class GameInput.

This commit is contained in:
Mitchell Richters 2023-04-03 18:46:36 +10:00
parent 23186cd8bb
commit 8d11fef916
11 changed files with 117 additions and 95 deletions

View file

@ -72,7 +72,7 @@ bool G_Responder (event_t *ev)
if (ev->data1 == KEY_ESCAPE && gi->WantEscape())
{
// special case: This is hardcoded to the 'Escape' button. Only used by Duke's cameras.
ActionsToSend |= SB_ESCAPE;
gameInput.SendAction(SB_ESCAPE);
return true;
}
if (C_DoKey (ev, &Bindings, &DoubleBindings))

View file

@ -84,6 +84,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "hw_material.h"
#include "tiletexture.h"
#include "tilesetbuilder.h"
#include "gameinput.h"
#include "buildtiles.h"
@ -1408,6 +1409,17 @@ void GameInterface::FreeLevelData()
GC::FullGC();
}
//---------------------------------------------------------------------------
//
//
//
//---------------------------------------------------------------------------
void GameInterface::GetInput(HIDInput* const hidInput, InputPacket* const currInput, const double scaleAdjust)
{
gameInput.processMovement(hidInput, currInput, scaleAdjust);
}
//---------------------------------------------------------------------------
//
// DrawCrosshair

View file

@ -43,25 +43,11 @@ CVARD(Bool, invertmouse, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG, "invert vertic
//---------------------------------------------------------------------------
//
// Static constants used throughout functions.
// Initialised variables.
//
//---------------------------------------------------------------------------
enum
{
BUILDTICRATE = 120,
TURBOTURNBASE = 590,
};
static InputPacket inputBuffer{};
static double turnheldtime = 0;
static int WeaponToSend = 0;
static int dpad_lock = 0;
ESyncBits ActionsToSend = 0;
static constexpr float backendmousescale = 1.f / 16.f;
static constexpr double YAW_TURNSPEEDS[3] = { 41.1987304, 156.555175, 272.24121 };
static constexpr double YAW_PREAMBLESCALE = YAW_TURNSPEEDS[0] / YAW_TURNSPEEDS[1];
GameInput gameInput{};
//---------------------------------------------------------------------------
@ -70,11 +56,6 @@ static constexpr double YAW_PREAMBLESCALE = YAW_TURNSPEEDS[0] / YAW_TURNSPEEDS[1
//
//---------------------------------------------------------------------------
static inline double getTicrateScale(const double value)
{
return value / GameTicRate;
}
static inline DAngle getscaledangle(const DAngle angle, const double scale, const DAngle push)
{
return (angle.Normalized180() * getTicrateScale(scale)) + push;
@ -93,28 +74,6 @@ static inline bool scaletozero(DAngle& angle, const double scale, const DAngle p
}
//---------------------------------------------------------------------------
//
// Functions for determining whether its turbo turn time (turn key held for a number of tics).
//
//---------------------------------------------------------------------------
static inline void updateTurnHeldAmt(const double scaleAdjust)
{
turnheldtime += getTicrateScale(BUILDTICRATE) * scaleAdjust;
}
static inline bool isTurboTurnTime()
{
return turnheldtime >= getTicrateScale(TURBOTURNBASE);
}
static inline void resetTurnHeldAmt()
{
turnheldtime = 0;
}
//---------------------------------------------------------------------------
//
// Handle all the game-side crouch requirements.
@ -147,7 +106,7 @@ void processCrouchToggle(bool& toggle, ESyncBits& actions, const bool crouchable
//
//---------------------------------------------------------------------------
void processMovement(HIDInput* const hidInput, InputPacket* const currInput, const double scaleAdjust, const int drink_amt, const bool allowstrafe, const double turnscale)
void GameInput::processMovement(HIDInput* const hidInput, InputPacket* const currInput, const double scaleAdjust, const int drink_amt, const bool allowstrafe, const double turnscale)
{
// set up variables.
const int keymove = 1 << int(!!(inputBuffer.actions & SB_RUN));
@ -165,7 +124,7 @@ void processMovement(HIDInput* const hidInput, InputPacket* const currInput, con
const float turndir = clamp(turning + strafing * !allowstrafe, -1.f, 1.f);
const float turnspeed = float(getTicrateScale(YAW_TURNSPEEDS[keymove]) * turnscale * (isTurboTurnTime() ? 1. : YAW_PREAMBLESCALE));
currInput->avel += hidInput->mouse.X * m_yaw - (hidInput->joyaxes[JOYAXIS_Yaw] * hidspeed - turndir * turnspeed) * scaleAdjustf;
if (turndir) updateTurnHeldAmt(scaleAdjust); else resetTurnHeldAmt();
if (turndir) updateTurnHeldAmt(scaleAdjust); else turnheldtime = 0;
}
else
{
@ -200,7 +159,7 @@ void processMovement(HIDInput* const hidInput, InputPacket* const currInput, con
//
//---------------------------------------------------------------------------
void processVehicleInput(HIDInput* const hidInput, InputPacket* const currInput, const double scaleAdjust, const float baseVel, const float velScale, const bool canMove, const bool canTurn, const bool attenuate)
void GameInput::processVehicle(HIDInput* const hidInput, InputPacket* const currInput, const double scaleAdjust, const float baseVel, const float velScale, const bool canMove, const bool canTurn, const bool attenuate)
{
// mask out all actions not compatible with vehicles.
inputBuffer.actions &= ~(SB_WEAPONMASK_BITS | SB_TURNAROUND | SB_CENTERVIEW | SB_HOLSTER | SB_JUMP | SB_CROUCH | SB_RUN |
@ -217,7 +176,7 @@ void processVehicleInput(HIDInput* const hidInput, InputPacket* const currInput,
if (canTurn)
{
// Cancel out micro-movement
hidInput->mouse.X *= fabs(hidInput->mouse.X) >= (m_sensitivity_x * backendmousescale * 2.f);
hidInput->mouse.X *= fabs(hidInput->mouse.X) >= (m_sensitivity_x * MOUSESCALE * 2.f);
const auto kbdLeft = buttonMap.ButtonDown(gamefunc_Turn_Left) || buttonMap.ButtonDown(gamefunc_Strafe_Left);
const auto kbdRight = buttonMap.ButtonDown(gamefunc_Turn_Right) || buttonMap.ButtonDown(gamefunc_Strafe_Right);
@ -229,11 +188,11 @@ void processVehicleInput(HIDInput* const hidInput, InputPacket* const currInput,
currInput->avel += turnVel * -hidInput->joyaxes[JOYAXIS_Yaw] + turnVel * kbdDir;
currInput->avel += sqrtf(abs(turnVel * hidInput->mouse.X * m_yaw / (float)scaleAdjust) * (7.f / 20.f)) * Sgn(turnVel) * Sgn(hidInput->mouse.X);
currInput->avel *= (float)scaleAdjust;
if (kbdDir) updateTurnHeldAmt(scaleAdjust); else resetTurnHeldAmt();
if (kbdDir) updateTurnHeldAmt(scaleAdjust); else turnheldtime = 0;
}
else
{
resetTurnHeldAmt();
turnheldtime = 0;
}
inputBuffer.fvel = clamp(inputBuffer.fvel + currInput->fvel, -1.00f, 1.00f);
@ -247,12 +206,12 @@ void processVehicleInput(HIDInput* const hidInput, InputPacket* const currInput,
//
//---------------------------------------------------------------------------
static void ApplyGlobalInput(HIDInput* const hidInput)
void GameInput::ApplyGlobalInput(HIDInput* const hidInput)
{
inputState.GetMouseDelta(hidInput->mouse);
if (use_joystick) I_GetAxes(hidInput->joyaxes);
hidInput->mouse *= backendmousescale;
hidInput->mouse *= MOUSESCALE;
if (invertmousex)
hidInput->mouse.X = -hidInput->mouse.X;
@ -353,16 +312,7 @@ static void ApplyGlobalInput(HIDInput* const hidInput)
//
//---------------------------------------------------------------------------
void clearLocalInputBuffer()
{
inputBuffer = {};
ActionsToSend = 0;
WeaponToSend = 0;
dpad_lock = 0;
resetTurnHeldAmt();
}
void getInput(const double scaleAdjust, PlayerAngles* const plrAngles, InputPacket* packet)
void GameInput::getInput(const double scaleAdjust, PlayerAngles* const plrAngles, InputPacket* packet)
{
if (M_Active() || gamestate != GS_LEVEL || !plrAngles || !plrAngles->pActor)
{
@ -596,23 +546,23 @@ CCMD(slot)
if (slot >= 1 && slot <= max)
{
WeaponToSend = slot;
gameInput.SendWeapon(slot);
}
}
CCMD(weapprev)
{
WeaponToSend = WeaponSel_Prev;
gameInput.SendWeapon(WeaponSel_Prev);
}
CCMD(weapnext)
{
WeaponToSend = WeaponSel_Next;
gameInput.SendWeapon(WeaponSel_Next);
}
CCMD(weapalt)
{
WeaponToSend = WeaponSel_Alt; // Only used by SW - should also be made usable by Blood ans Duke which put multiple weapons in the same slot.
gameInput.SendWeapon(WeaponSel_Alt); // Only used by SW - should also be made usable by Blood ans Duke which put multiple weapons in the same slot.
}
CCMD(useitem)
@ -629,38 +579,38 @@ CCMD(useitem)
if (slot >= 1 && slot <= max)
{
ActionsToSend |= ESyncBits::FromInt(SB_ITEM_BIT_1 << (slot - 1));
gameInput.SendAction(ESyncBits::FromInt(SB_ITEM_BIT_1 << (slot - 1)));
}
}
CCMD(invprev)
{
ActionsToSend |= SB_INVPREV;
gameInput.SendAction(SB_INVPREV);
}
CCMD(invnext)
{
ActionsToSend |= SB_INVNEXT;
gameInput.SendAction(SB_INVNEXT);
}
CCMD(invuse)
{
ActionsToSend |= SB_INVUSE;
gameInput.SendAction(SB_INVUSE);
}
CCMD(centerview)
{
ActionsToSend |= SB_CENTERVIEW;
gameInput.SendAction(SB_CENTERVIEW);
}
CCMD(turnaround)
{
ActionsToSend |= SB_TURNAROUND;
gameInput.SendAction(SB_TURNAROUND);
}
CCMD(holsterweapon)
{
ActionsToSend |= SB_HOLSTER;
gameInput.SendAction(SB_HOLSTER);
}
CCMD(warptocoords)

View file

@ -3,7 +3,75 @@
#include "serializer.h"
#include "gamefuncs.h"
extern ESyncBits ActionsToSend;
inline double getTicrateScale(const double value)
{
return value / GameTicRate;
}
struct HIDInput
{
float joyaxes[NUM_JOYAXIS];
FVector2 mouse;
};
class GameInput
{
enum
{
BUILDTICRATE = 120,
TURBOTURNBASE = 590,
};
static constexpr float MOUSESCALE = (1.f / 16.f);
static constexpr double YAW_TURNSPEEDS[3] = { 41.1987304, 156.555175, 272.24121 };
static constexpr double YAW_PREAMBLESCALE = YAW_TURNSPEEDS[0] / YAW_TURNSPEEDS[1];
// Internal variables when generating a packet.
InputPacket inputBuffer;
double turnheldtime;
int WeaponToSend;
int dpad_lock;
ESyncBits ActionsToSend;
// Turn speed doubling after x amount of tics.
void updateTurnHeldAmt(const double scaleAdjust)
{
turnheldtime += getTicrateScale(BUILDTICRATE) * scaleAdjust;
}
bool isTurboTurnTime()
{
return turnheldtime >= getTicrateScale(TURBOTURNBASE);
}
// Prototypes for private member functions.
void ApplyGlobalInput(HIDInput* const hidInput);
public:
// Bit sender updates.
void SendWeapon(const int weapon)
{
WeaponToSend = weapon;
}
void SendAction(const ESyncBits action)
{
ActionsToSend |= action;
}
// Clear all values within this object.
void Clear()
{
inputBuffer = {};
ActionsToSend = 0;
WeaponToSend = 0;
dpad_lock = 0;
turnheldtime = 0;
}
// Prototypes for large member functions.
void processMovement(HIDInput* const hidInput, InputPacket* const currInput, const double scaleAdjust, const int drink_amt = 0, const bool allowstrafe = true, const double turnscale = 1.);
void processVehicle(HIDInput* const hidInput, InputPacket* const currInput, const double scaleAdjust, const float baseVel, const float velScale, const bool canMove, const bool canTurn, const bool attenuate);
void getInput(const double scaleAdjust, PlayerAngles* const plrAngles, InputPacket* packet = nullptr);
};
struct PlayerAngles
{
@ -14,7 +82,7 @@ struct PlayerAngles
DAngle YawSpin;
friend FSerializer& Serialize(FSerializer& arc, const char* keyname, PlayerAngles& w, PlayerAngles* def);
friend void getInput(const double scaleAdjust, PlayerAngles* const plrAngles, InputPacket* packet);
friend void GameInput::getInput(const double scaleAdjust, PlayerAngles* const plrAngles, InputPacket* packet);
// Prototypes.
void doPitchKeys(InputPacket* const input);
@ -94,15 +162,8 @@ private:
static constexpr DAngle PITCH_HORIZOFFPUSH = DAngle::fromDeg(0.4476);
};
extern GameInput gameInput;
class FSerializer;
FSerializer& Serialize(FSerializer& arc, const char* keyname, PlayerAngles& w, PlayerAngles* def);
struct HIDInput
{
float joyaxes[NUM_JOYAXIS];
FVector2 mouse;
};
void processCrouchToggle(bool& toggle, ESyncBits& actions, const bool crouchable, const bool disabletoggle);
void processVehicleInput(HIDInput* const hidInput, InputPacket* const currInput, const double scaleAdjust, const float baseVel, const float velScale, const bool canMove, const bool canTurn, const bool attenuate);
void getInput(const double scaleAdjust, PlayerAngles* const plrAngles, InputPacket* packet = nullptr);

View file

@ -20,8 +20,6 @@ struct MapRecord;
struct PlayerAngles;
struct HIDInput;
void processMovement(HIDInput* const hidInput, InputPacket* const currInput, const double scaleAdjust, const int drink_amt = 0, const bool allowstrafe = true, const double turnscale = 1.);
struct GameStats
{
int kill, tkill;
@ -122,7 +120,7 @@ struct GameInterface
virtual bool WantEscape() { return false; }
virtual void StartSoundEngine() = 0;
virtual void reapplyInputBits(InputPacket* const input) = 0;
virtual void GetInput(HIDInput* const hidInput, InputPacket* const currInput, const double scaleAdjust) { processMovement(hidInput, currInput, scaleAdjust); }
virtual void GetInput(HIDInput* const hidInput, InputPacket* const currInput, const double scaleAdjust);
virtual FString statFPS()
{

View file

@ -13,8 +13,6 @@
#include "packet.h"
#include "vectors.h"
void clearLocalInputBuffer();
class InputState
{
uint8_t KeyStatus[NUM_KEYS];
@ -62,7 +60,6 @@ public:
memset(KeyStatus, 0, sizeof(KeyStatus));
AnyKeyStatus = false;
buttonMap.ResetButtonStates(); // this is important. If all input is cleared, the buttons must be cleared as well.
clearLocalInputBuffer(); // also clear game local input state.
}
bool CheckAllInput()

View file

@ -137,7 +137,7 @@ void G_BuildTiccmd(ticcmd_t* cmd)
}
cmd->ucmd = {};
I_GetEvent();
getInput(inputScale, gi->getConsoleAngles(), &cmd->ucmd);
gameInput.getInput(inputScale, gi->getConsoleAngles(), &cmd->ucmd);
cmd->consistency = consistency[myconnectindex][(maketic / ticdup) % BACKUPTICS];
}
@ -261,6 +261,7 @@ static void GameTicker()
case ga_level:
Net_ClearFifo();
inputState.ClearAllInput();
gameInput.Clear();
gamestate = GS_LEVEL;
return;
@ -605,7 +606,7 @@ void TryRunTics (void)
if (!SyncInput())
{
I_GetEvent();
getInput(inputScale, gi->getConsoleAngles());
gameInput.getInput(inputScale, gi->getConsoleAngles());
}
return;
}

View file

@ -525,11 +525,11 @@ void GameInterface::GetInput(HIDInput* const hidInput, InputPacket* const currIn
const auto canTurn = p->OnMotorcycle || p->MotoSpeed || p->moto_drink;
const auto attenuate = p->OnMotorcycle && p->MotoSpeed <= 0;
processVehicleInput(hidInput, currInput, scaleAdjust, baseVel, velScale, canMove, canTurn, attenuate);
gameInput.processVehicle(hidInput, currInput, scaleAdjust, baseVel, velScale, canMove, canTurn, attenuate);
}
else
{
processMovement(hidInput, currInput, scaleAdjust, p->drink_amt);
gameInput.processMovement(hidInput, currInput, scaleAdjust, p->drink_amt);
}
}

View file

@ -1892,6 +1892,7 @@ static bool doPlayerDeathRestart(Player* const pPlayer)
// will invalidate nPlayerSprite
RestartPlayer(pPlayer->nPlayer);
inputState.ClearAllInput();
gameInput.Clear();
}
else
{

View file

@ -224,12 +224,14 @@ void DrawView(double interpfrac, bool sceneonly)
subtitleOverlay.ReadyCinemaText(currentLevel->ex_ramses_text);
}
inputState.ClearAllInput();
gameInput.Clear();
}
else if (nHeadStage == 5)
{
if ((bSubTitles && !subtitleOverlay.AdvanceCinemaText(I_GetTimeNS() * (120. / 1'000'000'000))) || inputState.CheckAllInput())
{
inputState.ClearAllInput();
gameInput.Clear();
LevelFinished();
EndLevel = 1;

View file

@ -1891,7 +1891,7 @@ struct GameInterface : public ::GameInterface
void reapplyInputBits(InputPacket* const input) override { input->actions |= Player[myconnectindex].input.actions & SB_CENTERVIEW; }
void GetInput(HIDInput* const hidInput, InputPacket* const currInput, const double scaleAdjust) override
{
processMovement(hidInput, currInput, scaleAdjust, 0, !Player[myconnectindex].sop, Player[myconnectindex].sop_control ? 3. / 1.40625 : 1.);
gameInput.processMovement(hidInput, currInput, scaleAdjust, 0, !Player[myconnectindex].sop, Player[myconnectindex].sop_control ? 3. / 1.40625 : 1.);
}