mirror of
https://github.com/fabiangreffrath/woof.git
synced 2025-09-23 12:04:38 -04:00
Refactor game input utility functions (#1705)
This commit is contained in:
parent
46bc8de658
commit
045b3a2797
@ -28,6 +28,7 @@ set(WOOF_SOURCES
|
|||||||
f_wipe.c f_wipe.h
|
f_wipe.c f_wipe.h
|
||||||
font.h
|
font.h
|
||||||
g_game.c g_game.h
|
g_game.c g_game.h
|
||||||
|
g_input.c g_input.h
|
||||||
hu_command.c hu_command.h
|
hu_command.c hu_command.h
|
||||||
hu_lib.c hu_lib.h
|
hu_lib.c hu_lib.h
|
||||||
hu_obituary.c hu_obituary.h
|
hu_obituary.c hu_obituary.h
|
||||||
|
32
src/d_main.c
32
src/d_main.c
@ -223,39 +223,13 @@ void D_ProcessEvents (void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean input_ready;
|
|
||||||
|
|
||||||
void D_UpdateDeltaTics(void)
|
|
||||||
{
|
|
||||||
if (uncapped && raw_input)
|
|
||||||
{
|
|
||||||
static uint64_t last_time;
|
|
||||||
const uint64_t current_time = I_GetTimeUS();
|
|
||||||
|
|
||||||
if (input_ready)
|
|
||||||
{
|
|
||||||
const uint64_t delta_time = current_time - last_time;
|
|
||||||
deltatics = (double)delta_time * TICRATE / 1000000.0;
|
|
||||||
deltatics = BETWEEN(0.0, 1.0, deltatics);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
deltatics = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
last_time = current_time;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
deltatics = 1.0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// D_Display
|
// D_Display
|
||||||
// draw current display, possibly wiping it from the previous
|
// draw current display, possibly wiping it from the previous
|
||||||
//
|
//
|
||||||
|
|
||||||
|
boolean input_ready;
|
||||||
|
|
||||||
// wipegamestate can be set to -1 to force a wipe on the next draw
|
// wipegamestate can be set to -1 to force a wipe on the next draw
|
||||||
gamestate_t wipegamestate = GS_DEMOSCREEN;
|
gamestate_t wipegamestate = GS_DEMOSCREEN;
|
||||||
static int screen_melt = wipe_Melt;
|
static int screen_melt = wipe_Melt;
|
||||||
@ -2504,7 +2478,7 @@ void D_DoomMain(void)
|
|||||||
|
|
||||||
G_UpdateSideMove();
|
G_UpdateSideMove();
|
||||||
G_UpdateAngleFunctions();
|
G_UpdateAngleFunctions();
|
||||||
I_UpdateAccelerateMouse();
|
G_UpdateAccelerateMouse();
|
||||||
|
|
||||||
MN_ResetTimeScale();
|
MN_ResetTimeScale();
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ boolean D_CheckEndDoom(void);
|
|||||||
// Called by IO functions when input is detected.
|
// Called by IO functions when input is detected.
|
||||||
void D_PostEvent(struct event_s *ev);
|
void D_PostEvent(struct event_s *ev);
|
||||||
|
|
||||||
void D_UpdateDeltaTics(void);
|
extern boolean input_ready;
|
||||||
|
|
||||||
void D_BindMiscVariables(void);
|
void D_BindMiscVariables(void);
|
||||||
|
|
||||||
|
348
src/g_game.c
348
src/g_game.c
@ -153,7 +153,7 @@ wbstartstruct_t wminfo; // parms for world map / intermission
|
|||||||
boolean haswolflevels = false;// jff 4/18/98 wolf levels present
|
boolean haswolflevels = false;// jff 4/18/98 wolf levels present
|
||||||
byte *savebuffer;
|
byte *savebuffer;
|
||||||
boolean autorun = false; // always running? // phares
|
boolean autorun = false; // always running? // phares
|
||||||
static boolean autostrafe50;
|
boolean autostrafe50;
|
||||||
boolean novert = false;
|
boolean novert = false;
|
||||||
boolean mouselook = false;
|
boolean mouselook = false;
|
||||||
boolean padlook = false;
|
boolean padlook = false;
|
||||||
@ -178,14 +178,16 @@ static ticcmd_t* last_cmd = NULL;
|
|||||||
int key_escape = KEY_ESCAPE; // phares 4/13/98
|
int key_escape = KEY_ESCAPE; // phares 4/13/98
|
||||||
int key_help = KEY_F1; // phares 4/13/98
|
int key_help = KEY_F1; // phares 4/13/98
|
||||||
|
|
||||||
static int mouse_sensitivity;
|
int mouse_sensitivity;
|
||||||
static int mouse_sensitivity_y;
|
int mouse_sensitivity_y;
|
||||||
static int mouse_sensitivity_strafe; // [FG] strafe
|
int mouse_sensitivity_strafe; // [FG] strafe
|
||||||
static int mouse_sensitivity_y_look; // [FG] look
|
int mouse_sensitivity_y_look; // [FG] look
|
||||||
// [FG] double click acts as "use"
|
// [FG] double click acts as "use"
|
||||||
static boolean dclick_use;
|
static boolean dclick_use;
|
||||||
// [FG] invert vertical axis
|
// [FG] invert vertical axis
|
||||||
static boolean mouse_y_invert;
|
boolean mouse_y_invert;
|
||||||
|
int mouse_acceleration;
|
||||||
|
int mouse_acceleration_threshold;
|
||||||
|
|
||||||
#define MAXPLMOVE (forwardmove[1])
|
#define MAXPLMOVE (forwardmove[1])
|
||||||
#define TURBOTHRESHOLD 0x32
|
#define TURBOTHRESHOLD 0x32
|
||||||
@ -193,11 +195,10 @@ static boolean mouse_y_invert;
|
|||||||
#define QUICKREVERSE 32768 // 180 degree reverse // phares
|
#define QUICKREVERSE 32768 // 180 degree reverse // phares
|
||||||
#define NUMKEYS 256
|
#define NUMKEYS 256
|
||||||
|
|
||||||
static fixed_t default_forwardmove[2] = {0x19, 0x32};
|
fixed_t forwardmove[2] = {0x19, 0x32};
|
||||||
static fixed_t default_sidemove[2] = {0x18, 0x28};
|
fixed_t default_sidemove[2] = {0x18, 0x28};
|
||||||
fixed_t *forwardmove = default_forwardmove;
|
|
||||||
fixed_t *sidemove = default_sidemove;
|
fixed_t *sidemove = default_sidemove;
|
||||||
fixed_t angleturn[3] = {640, 1280, 320}; // + slow turn
|
const fixed_t angleturn[3] = {640, 1280, 320}; // + slow turn
|
||||||
|
|
||||||
boolean gamekeydown[NUMKEYS];
|
boolean gamekeydown[NUMKEYS];
|
||||||
int turnheld; // for accelerative turning
|
int turnheld; // for accelerative turning
|
||||||
@ -205,26 +206,14 @@ int turnheld; // for accelerative turning
|
|||||||
boolean mousebuttons[NUM_MOUSE_BUTTONS];
|
boolean mousebuttons[NUM_MOUSE_BUTTONS];
|
||||||
|
|
||||||
// mouse values are used once
|
// mouse values are used once
|
||||||
static int mousex;
|
int mousex;
|
||||||
static int mousey;
|
int mousey;
|
||||||
boolean dclick;
|
boolean dclick;
|
||||||
|
|
||||||
typedef struct carry_s
|
|
||||||
{
|
|
||||||
double angle;
|
|
||||||
double pitch;
|
|
||||||
double side;
|
|
||||||
double vert;
|
|
||||||
} carry_t;
|
|
||||||
|
|
||||||
static carry_t prevcarry;
|
|
||||||
static carry_t carry;
|
|
||||||
static ticcmd_t basecmd;
|
static ticcmd_t basecmd;
|
||||||
|
|
||||||
boolean joybuttons[NUM_CONTROLLER_BUTTONS];
|
boolean joybuttons[NUM_CONTROLLER_BUTTONS];
|
||||||
|
|
||||||
static const int direction[] = { 1, -1 };
|
|
||||||
|
|
||||||
int savegameslot = -1;
|
int savegameslot = -1;
|
||||||
char savedescription[32];
|
char savedescription[32];
|
||||||
|
|
||||||
@ -391,267 +380,6 @@ static void G_DemoSkipTics(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int RoundSide_Strict(double side)
|
|
||||||
{
|
|
||||||
return lround(side * 0.5) * 2; // Even values only.
|
|
||||||
}
|
|
||||||
|
|
||||||
static int RoundSide_Full(double side)
|
|
||||||
{
|
|
||||||
return lround(side);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int (*RoundSide)(double side) = RoundSide_Full;
|
|
||||||
|
|
||||||
void G_UpdateSideMove(void)
|
|
||||||
{
|
|
||||||
if (strictmode || (netgame && !solonet))
|
|
||||||
{
|
|
||||||
RoundSide = RoundSide_Strict;
|
|
||||||
sidemove = default_sidemove;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
RoundSide = RoundSide_Full;
|
|
||||||
sidemove = autostrafe50 ? default_forwardmove : default_sidemove;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int CalcControllerForward(int speed)
|
|
||||||
{
|
|
||||||
const int forward = lroundf(forwardmove[speed] * axes[AXIS_FORWARD] *
|
|
||||||
direction[joy_invert_forward]);
|
|
||||||
return BETWEEN(-forwardmove[speed], forwardmove[speed], forward);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int CalcControllerSideTurn(int speed)
|
|
||||||
{
|
|
||||||
const int side = RoundSide(forwardmove[speed] * axes[AXIS_TURN] *
|
|
||||||
direction[joy_invert_turn]);
|
|
||||||
return BETWEEN(-forwardmove[speed], forwardmove[speed], side);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int CalcControllerSideStrafe(int speed)
|
|
||||||
{
|
|
||||||
const int side = RoundSide(forwardmove[speed] * axes[AXIS_STRAFE] *
|
|
||||||
direction[joy_invert_strafe]);
|
|
||||||
return BETWEEN(-sidemove[speed], sidemove[speed], side);
|
|
||||||
}
|
|
||||||
|
|
||||||
static double CalcControllerAngle(void)
|
|
||||||
{
|
|
||||||
return (angleturn[1] * axes[AXIS_TURN] * direction[joy_invert_turn]);
|
|
||||||
}
|
|
||||||
|
|
||||||
static double CalcControllerPitch(void)
|
|
||||||
{
|
|
||||||
return (angleturn[1] * axes[AXIS_LOOK] * direction[joy_invert_look]
|
|
||||||
* FRACUNIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int CarryError(double value, const double *prevcarry, double *carry)
|
|
||||||
{
|
|
||||||
const double desired = value + *prevcarry;
|
|
||||||
const int actual = lround(desired);
|
|
||||||
*carry = desired - actual;
|
|
||||||
return actual;
|
|
||||||
}
|
|
||||||
|
|
||||||
static short CarryAngleTic_Full(double angle)
|
|
||||||
{
|
|
||||||
return CarryError(angle, &prevcarry.angle, &carry.angle);
|
|
||||||
}
|
|
||||||
|
|
||||||
static short CarryAngle_Full(double angle)
|
|
||||||
{
|
|
||||||
const short fullres = CarryAngleTic_Full(angle);
|
|
||||||
localview.angle = fullres << FRACBITS;
|
|
||||||
return fullres;
|
|
||||||
}
|
|
||||||
|
|
||||||
static short CarryAngle_FakeLongTics(double angle)
|
|
||||||
{
|
|
||||||
return (localview.angleoffset = (CarryAngle_Full(angle) + 128) & 0xFF00);
|
|
||||||
}
|
|
||||||
|
|
||||||
static short CarryAngleTic_LowRes(double angle)
|
|
||||||
{
|
|
||||||
const double fullres = angle + prevcarry.angle;
|
|
||||||
const short lowres = ((short)lround(fullres) + 128) & 0xFF00;
|
|
||||||
carry.angle = fullres - lowres;
|
|
||||||
return lowres;
|
|
||||||
}
|
|
||||||
|
|
||||||
static short CarryAngle_LowRes(double angle)
|
|
||||||
{
|
|
||||||
const short lowres = CarryAngleTic_LowRes(angle);
|
|
||||||
localview.angle = lowres << FRACBITS;
|
|
||||||
return lowres;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void UpdateLocalView_Zero(void)
|
|
||||||
{
|
|
||||||
memset(&localview, 0, sizeof(localview));
|
|
||||||
}
|
|
||||||
|
|
||||||
static void UpdateLocalView_FakeLongTics(void)
|
|
||||||
{
|
|
||||||
localview.angle -= localview.angleoffset << FRACBITS;
|
|
||||||
localview.rawangle -= localview.angleoffset;
|
|
||||||
localview.angleoffset = 0;
|
|
||||||
localview.pitch = 0;
|
|
||||||
localview.rawpitch = 0.0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static short (*CarryAngleTic)(double angle);
|
|
||||||
static short (*CarryAngle)(double angle);
|
|
||||||
static void (*UpdateLocalView)(void);
|
|
||||||
|
|
||||||
void G_UpdateAngleFunctions(void)
|
|
||||||
{
|
|
||||||
CarryAngleTic = lowres_turn ? CarryAngleTic_LowRes : CarryAngleTic_Full;
|
|
||||||
CarryAngle = CarryAngleTic;
|
|
||||||
UpdateLocalView = UpdateLocalView_Zero;
|
|
||||||
|
|
||||||
if (raw_input && (!netgame || solonet))
|
|
||||||
{
|
|
||||||
if (lowres_turn && fake_longtics)
|
|
||||||
{
|
|
||||||
CarryAngle = CarryAngle_FakeLongTics;
|
|
||||||
UpdateLocalView = UpdateLocalView_FakeLongTics;
|
|
||||||
}
|
|
||||||
else if (uncapped)
|
|
||||||
{
|
|
||||||
CarryAngle = lowres_turn ? CarryAngle_LowRes : CarryAngle_Full;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static int CarryPitch(double pitch)
|
|
||||||
{
|
|
||||||
return (localview.pitch = CarryError(pitch, &prevcarry.pitch, &carry.pitch));
|
|
||||||
}
|
|
||||||
|
|
||||||
static int CarryMouseVert(double vert)
|
|
||||||
{
|
|
||||||
return CarryError(vert, &prevcarry.vert, &carry.vert);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int CarryMouseSide(double side)
|
|
||||||
{
|
|
||||||
const double desired = side + prevcarry.side;
|
|
||||||
const int actual = RoundSide(desired);
|
|
||||||
carry.side = desired - actual;
|
|
||||||
return actual;
|
|
||||||
}
|
|
||||||
|
|
||||||
static double CalcMouseAngle(int mousex)
|
|
||||||
{
|
|
||||||
if (!mouse_sensitivity)
|
|
||||||
return 0.0;
|
|
||||||
|
|
||||||
return (I_AccelerateMouse(mousex) * (mouse_sensitivity + 5) * 8 / 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
static double CalcMousePitch(int mousey)
|
|
||||||
{
|
|
||||||
if (!mouse_sensitivity_y_look)
|
|
||||||
return 0.0;
|
|
||||||
|
|
||||||
return (I_AccelerateMouse(mousey) * (mouse_sensitivity_y_look + 5) * 8 / 10
|
|
||||||
* direction[mouse_y_invert] * FRACUNIT);
|
|
||||||
}
|
|
||||||
|
|
||||||
static double CalcMouseSide(int mousex)
|
|
||||||
{
|
|
||||||
if (!mouse_sensitivity_strafe)
|
|
||||||
return 0.0;
|
|
||||||
|
|
||||||
return (I_AccelerateMouse(mousex) * (mouse_sensitivity_strafe + 5) * 2 / 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
static double CalcMouseVert(int mousey)
|
|
||||||
{
|
|
||||||
if (!mouse_sensitivity_y)
|
|
||||||
return 0.0;
|
|
||||||
|
|
||||||
return (I_AccelerateMouse(mousey) * (mouse_sensitivity_y + 5) / 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// ApplyQuickstartCache
|
|
||||||
// When recording a demo and the map is reloaded, cached input from a circular
|
|
||||||
// buffer can be applied prior to the screen wipe. Adapted from DSDA-Doom.
|
|
||||||
//
|
|
||||||
|
|
||||||
static int quickstart_cache_tics;
|
|
||||||
static boolean quickstart_queued;
|
|
||||||
static float axis_turn_tic;
|
|
||||||
static int mousex_tic;
|
|
||||||
|
|
||||||
static void ClearQuickstartTic(void)
|
|
||||||
{
|
|
||||||
axis_turn_tic = 0.0f;
|
|
||||||
mousex_tic = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void ApplyQuickstartCache(ticcmd_t *cmd, boolean strafe)
|
|
||||||
{
|
|
||||||
static float axis_turn_cache[TICRATE];
|
|
||||||
static int mousex_cache[TICRATE];
|
|
||||||
static short angleturn_cache[TICRATE];
|
|
||||||
static int index;
|
|
||||||
|
|
||||||
if (quickstart_cache_tics < 1)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (quickstart_queued)
|
|
||||||
{
|
|
||||||
axes[AXIS_TURN] = 0.0f;
|
|
||||||
mousex = 0;
|
|
||||||
|
|
||||||
if (strafe)
|
|
||||||
{
|
|
||||||
for (int i = 0; i < quickstart_cache_tics; i++)
|
|
||||||
{
|
|
||||||
axes[AXIS_TURN] += axis_turn_cache[i];
|
|
||||||
mousex += mousex_cache[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd->angleturn = 0;
|
|
||||||
localview.rawangle = 0.0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
short result = 0;
|
|
||||||
|
|
||||||
for (int i = 0; i < quickstart_cache_tics; i++)
|
|
||||||
{
|
|
||||||
result += angleturn_cache[i];
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd->angleturn = CarryAngleTic(result);
|
|
||||||
localview.rawangle = cmd->angleturn;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(axis_turn_cache, 0, sizeof(axis_turn_cache));
|
|
||||||
memset(mousex_cache, 0, sizeof(mousex_cache));
|
|
||||||
memset(angleturn_cache, 0, sizeof(angleturn_cache));
|
|
||||||
index = 0;
|
|
||||||
|
|
||||||
quickstart_queued = false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
axis_turn_cache[index] = axis_turn_tic;
|
|
||||||
mousex_cache[index] = mousex_tic;
|
|
||||||
angleturn_cache[index] = cmd->angleturn;
|
|
||||||
index = (index + 1) % quickstart_cache_tics;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void G_PrepTiccmd(void)
|
void G_PrepTiccmd(void)
|
||||||
{
|
{
|
||||||
const boolean strafe = M_InputGameActive(input_strafe);
|
const boolean strafe = M_InputGameActive(input_strafe);
|
||||||
@ -661,21 +389,18 @@ void G_PrepTiccmd(void)
|
|||||||
|
|
||||||
if (I_UseController() && I_CalcControllerAxes())
|
if (I_UseController() && I_CalcControllerAxes())
|
||||||
{
|
{
|
||||||
D_UpdateDeltaTics();
|
G_UpdateDeltaTics();
|
||||||
|
|
||||||
axis_turn_tic = axes[AXIS_TURN];
|
axis_turn_tic = axes[AXIS_TURN];
|
||||||
|
|
||||||
if (axes[AXIS_TURN] && !strafe)
|
if (axes[AXIS_TURN] && !strafe)
|
||||||
{
|
{
|
||||||
localview.rawangle -= CalcControllerAngle() * deltatics;
|
cmd->angleturn = G_CalcControllerAngle();
|
||||||
cmd->angleturn = CarryAngle(localview.rawangle);
|
|
||||||
axes[AXIS_TURN] = 0.0f;
|
axes[AXIS_TURN] = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (axes[AXIS_LOOK] && padlook)
|
if (axes[AXIS_LOOK] && padlook)
|
||||||
{
|
{
|
||||||
localview.rawpitch -= CalcControllerPitch() * deltatics;
|
cmd->pitch = G_CalcControllerPitch();
|
||||||
cmd->pitch = CarryPitch(localview.rawpitch);
|
|
||||||
axes[AXIS_LOOK] = 0.0f;
|
axes[AXIS_LOOK] = 0.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -684,15 +409,13 @@ void G_PrepTiccmd(void)
|
|||||||
|
|
||||||
if (mousex && !strafe)
|
if (mousex && !strafe)
|
||||||
{
|
{
|
||||||
localview.rawangle -= CalcMouseAngle(mousex);
|
cmd->angleturn = G_CalcMouseAngle();
|
||||||
cmd->angleturn = CarryAngle(localview.rawangle);
|
|
||||||
mousex = 0;
|
mousex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mousey && mouselook)
|
if (mousey && mouselook)
|
||||||
{
|
{
|
||||||
localview.rawpitch += CalcMousePitch(mousey);
|
cmd->pitch = G_CalcMousePitch();
|
||||||
cmd->pitch = CarryPitch(localview.rawpitch);
|
|
||||||
mousey = 0;
|
mousey = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -728,7 +451,7 @@ void G_BuildTiccmd(ticcmd_t* cmd)
|
|||||||
memcpy(cmd, &basecmd, sizeof(*cmd));
|
memcpy(cmd, &basecmd, sizeof(*cmd));
|
||||||
memset(&basecmd, 0, sizeof(basecmd));
|
memset(&basecmd, 0, sizeof(basecmd));
|
||||||
|
|
||||||
ApplyQuickstartCache(cmd, strafe);
|
G_ApplyQuickstartCache(cmd, strafe);
|
||||||
|
|
||||||
cmd->consistancy = consistancy[consoleplayer][maketic%BACKUPTICS];
|
cmd->consistancy = consistancy[consoleplayer][maketic%BACKUPTICS];
|
||||||
|
|
||||||
@ -787,17 +510,17 @@ void G_BuildTiccmd(ticcmd_t* cmd)
|
|||||||
{
|
{
|
||||||
if (axes[AXIS_TURN] && strafe && !cmd->angleturn)
|
if (axes[AXIS_TURN] && strafe && !cmd->angleturn)
|
||||||
{
|
{
|
||||||
side += CalcControllerSideTurn(speed);
|
side += G_CalcControllerSideTurn(speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (axes[AXIS_STRAFE])
|
if (axes[AXIS_STRAFE])
|
||||||
{
|
{
|
||||||
side += CalcControllerSideStrafe(speed);
|
side += G_CalcControllerSideStrafe(speed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (axes[AXIS_FORWARD])
|
if (axes[AXIS_FORWARD])
|
||||||
{
|
{
|
||||||
forward -= CalcControllerForward(speed);
|
forward -= G_CalcControllerForward(speed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -805,23 +528,19 @@ void G_BuildTiccmd(ticcmd_t* cmd)
|
|||||||
|
|
||||||
if (mousex && strafe && !cmd->angleturn)
|
if (mousex && strafe && !cmd->angleturn)
|
||||||
{
|
{
|
||||||
const double mouseside = CalcMouseSide(mousex);
|
side += G_CalcMouseSide();
|
||||||
side += CarryMouseSide(mouseside);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mousey && !mouselook && !novert)
|
if (mousey && !mouselook && !novert)
|
||||||
{
|
{
|
||||||
const double mousevert = CalcMouseVert(mousey);
|
forward += G_CalcMouseVert();
|
||||||
forward += CarryMouseVert(mousevert);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update/reset
|
// Update/reset
|
||||||
|
|
||||||
if (angle)
|
if (angle)
|
||||||
{
|
{
|
||||||
const short old_angleturn = cmd->angleturn;
|
G_UpdateTicAngleTurn(cmd, angle);
|
||||||
cmd->angleturn = CarryAngleTic(localview.rawangle + angle);
|
|
||||||
cmd->ticangleturn = cmd->angleturn - old_angleturn;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (forward > MAXPLMOVE)
|
if (forward > MAXPLMOVE)
|
||||||
@ -836,11 +555,11 @@ void G_BuildTiccmd(ticcmd_t* cmd)
|
|||||||
cmd->forwardmove = forward;
|
cmd->forwardmove = forward;
|
||||||
cmd->sidemove = side;
|
cmd->sidemove = side;
|
||||||
|
|
||||||
ClearQuickstartTic();
|
G_ClearQuickstartTic();
|
||||||
I_ResetControllerAxes();
|
I_ResetControllerAxes();
|
||||||
mousex = mousey = 0;
|
mousex = mousey = 0;
|
||||||
UpdateLocalView();
|
G_UpdateLocalView();
|
||||||
prevcarry = carry;
|
G_UpdateCarry();
|
||||||
|
|
||||||
// Buttons
|
// Buttons
|
||||||
|
|
||||||
@ -991,12 +710,11 @@ void G_BuildTiccmd(ticcmd_t* cmd)
|
|||||||
|
|
||||||
void G_ClearInput(void)
|
void G_ClearInput(void)
|
||||||
{
|
{
|
||||||
ClearQuickstartTic();
|
G_ClearQuickstartTic();
|
||||||
I_ResetControllerLevel();
|
I_ResetControllerLevel();
|
||||||
mousex = mousey = 0;
|
mousex = mousey = 0;
|
||||||
memset(&localview, 0, sizeof(localview));
|
G_ClearLocalView();
|
||||||
memset(&carry, 0, sizeof(carry));
|
G_ClearCarry();
|
||||||
memset(&prevcarry, 0, sizeof(prevcarry));
|
|
||||||
memset(&basecmd, 0, sizeof(basecmd));
|
memset(&basecmd, 0, sizeof(basecmd));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4637,6 +4355,10 @@ void G_BindGameInputVariables(void)
|
|||||||
"Horizontal mouse sensitivity for strafing");
|
"Horizontal mouse sensitivity for strafing");
|
||||||
BIND_NUM_GENERAL(mouse_sensitivity_y_look, 5, 0, UL,
|
BIND_NUM_GENERAL(mouse_sensitivity_y_look, 5, 0, UL,
|
||||||
"Vertical mouse sensitivity for looking");
|
"Vertical mouse sensitivity for looking");
|
||||||
|
BIND_NUM_GENERAL(mouse_acceleration, 10, 0, 40,
|
||||||
|
"Mouse acceleration (0 = 1.0; 40 = 5.0)");
|
||||||
|
BIND_NUM(mouse_acceleration_threshold, 10, 0, 32,
|
||||||
|
"Mouse acceleration threshold");
|
||||||
BIND_BOOL_GENERAL(mouse_y_invert, false, "Invert vertical mouse axis");
|
BIND_BOOL_GENERAL(mouse_y_invert, false, "Invert vertical mouse axis");
|
||||||
BIND_BOOL_GENERAL(dclick_use, true, "Double-click acts as use-button");
|
BIND_BOOL_GENERAL(dclick_use, true, "Double-click acts as use-button");
|
||||||
BIND_BOOL(novert, true, "Disable vertical mouse movement");
|
BIND_BOOL(novert, true, "Disable vertical mouse movement");
|
||||||
|
18
src/g_game.h
18
src/g_game.h
@ -20,6 +20,7 @@
|
|||||||
#include "doomdef.h"
|
#include "doomdef.h"
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
#include "doomtype.h"
|
#include "doomtype.h"
|
||||||
|
#include "g_input.h"
|
||||||
#include "m_fixed.h"
|
#include "m_fixed.h"
|
||||||
|
|
||||||
struct event_s;
|
struct event_s;
|
||||||
@ -53,8 +54,6 @@ void G_SecretExitLevel(void);
|
|||||||
void G_WorldDone(void);
|
void G_WorldDone(void);
|
||||||
void G_Ticker(void);
|
void G_Ticker(void);
|
||||||
void G_ScreenShot(void);
|
void G_ScreenShot(void);
|
||||||
void G_UpdateSideMove(void);
|
|
||||||
void G_UpdateAngleFunctions(void);
|
|
||||||
void G_ReloadDefaults(boolean keep_demover); // killough 3/1/98: loads game defaults
|
void G_ReloadDefaults(boolean keep_demover); // killough 3/1/98: loads game defaults
|
||||||
char *G_SaveGameName(int); // killough 3/22/98: sets savegame filename
|
char *G_SaveGameName(int); // killough 3/22/98: sets savegame filename
|
||||||
char *G_MBFSaveGameName(int); // MBF savegame filename
|
char *G_MBFSaveGameName(int); // MBF savegame filename
|
||||||
@ -104,12 +103,25 @@ extern int key_escape;
|
|||||||
extern int key_enter;
|
extern int key_enter;
|
||||||
extern int key_help;
|
extern int key_help;
|
||||||
extern boolean autorun; // always running? // phares
|
extern boolean autorun; // always running? // phares
|
||||||
|
extern boolean autostrafe50;
|
||||||
extern boolean novert;
|
extern boolean novert;
|
||||||
extern boolean mouselook;
|
extern boolean mouselook;
|
||||||
extern boolean padlook;
|
extern boolean padlook;
|
||||||
|
|
||||||
extern fixed_t *forwardmove;
|
extern int mouse_sensitivity;
|
||||||
|
extern int mouse_sensitivity_y;
|
||||||
|
extern int mouse_sensitivity_strafe;
|
||||||
|
extern int mouse_sensitivity_y_look;
|
||||||
|
extern boolean mouse_y_invert;
|
||||||
|
extern int mouse_acceleration;
|
||||||
|
extern int mouse_acceleration_threshold;
|
||||||
|
extern int mousex;
|
||||||
|
extern int mousey;
|
||||||
|
|
||||||
|
extern fixed_t forwardmove[2];
|
||||||
|
extern fixed_t default_sidemove[2];
|
||||||
extern fixed_t *sidemove;
|
extern fixed_t *sidemove;
|
||||||
|
extern const fixed_t angleturn[3];
|
||||||
|
|
||||||
extern int default_skill; //jff 3/24/98 default skill
|
extern int default_skill; //jff 3/24/98 default skill
|
||||||
extern boolean haswolflevels; //jff 4/18/98 wolf levels present
|
extern boolean haswolflevels; //jff 4/18/98 wolf levels present
|
||||||
|
456
src/g_input.c
Normal file
456
src/g_input.c
Normal file
@ -0,0 +1,456 @@
|
|||||||
|
//
|
||||||
|
// Copyright(C) 2024 ceski
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 2
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// DESCRIPTION:
|
||||||
|
// Game Input Utility Functions
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <math.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "d_main.h"
|
||||||
|
#include "g_game.h"
|
||||||
|
#include "i_gamepad.h"
|
||||||
|
#include "i_timer.h"
|
||||||
|
#include "i_video.h"
|
||||||
|
#include "p_mobj.h"
|
||||||
|
#include "r_state.h"
|
||||||
|
|
||||||
|
//
|
||||||
|
// Local View
|
||||||
|
//
|
||||||
|
|
||||||
|
void (*G_UpdateLocalView)(void);
|
||||||
|
|
||||||
|
void G_ClearLocalView(void)
|
||||||
|
{
|
||||||
|
memset(&localview, 0, sizeof(localview));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void UpdateLocalView_FakeLongTics(void)
|
||||||
|
{
|
||||||
|
localview.angle -= localview.angleoffset << FRACBITS;
|
||||||
|
localview.rawangle -= localview.angleoffset;
|
||||||
|
localview.angleoffset = 0;
|
||||||
|
localview.pitch = 0;
|
||||||
|
localview.rawpitch = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Side Movement
|
||||||
|
//
|
||||||
|
|
||||||
|
static int (*RoundSide)(double side);
|
||||||
|
|
||||||
|
static int RoundSide_Strict(double side)
|
||||||
|
{
|
||||||
|
return lround(side * 0.5) * 2; // Even values only.
|
||||||
|
}
|
||||||
|
|
||||||
|
static int RoundSide_Full(double side)
|
||||||
|
{
|
||||||
|
return lround(side);
|
||||||
|
}
|
||||||
|
|
||||||
|
void G_UpdateSideMove(void)
|
||||||
|
{
|
||||||
|
if (strictmode || (netgame && !solonet))
|
||||||
|
{
|
||||||
|
RoundSide = RoundSide_Strict;
|
||||||
|
sidemove = default_sidemove;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
RoundSide = RoundSide_Full;
|
||||||
|
sidemove = autostrafe50 ? forwardmove : default_sidemove;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Error Accumulation
|
||||||
|
//
|
||||||
|
|
||||||
|
// Round to nearest 256 for single byte turning. From Chocolate Doom.
|
||||||
|
#define BYTE_TURN(x) (((x) + 128) & 0xFF00)
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
double angle;
|
||||||
|
double pitch;
|
||||||
|
double side;
|
||||||
|
double vert;
|
||||||
|
} carry_t;
|
||||||
|
|
||||||
|
static carry_t prevcarry, carry;
|
||||||
|
static short (*CarryAngleTic)(double angle);
|
||||||
|
static short (*CarryAngle)(double angle);
|
||||||
|
|
||||||
|
void G_UpdateCarry(void)
|
||||||
|
{
|
||||||
|
prevcarry = carry;
|
||||||
|
}
|
||||||
|
|
||||||
|
void G_ClearCarry(void)
|
||||||
|
{
|
||||||
|
memset(&prevcarry, 0, sizeof(prevcarry));
|
||||||
|
memset(&carry, 0, sizeof(carry));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CarryError(double value, const double *prevcarry, double *carry)
|
||||||
|
{
|
||||||
|
const double desired = value + *prevcarry;
|
||||||
|
const int actual = lround(desired);
|
||||||
|
*carry = desired - actual;
|
||||||
|
return actual;
|
||||||
|
}
|
||||||
|
|
||||||
|
static short CarryAngleTic_Full(double angle)
|
||||||
|
{
|
||||||
|
return CarryError(angle, &prevcarry.angle, &carry.angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
static short CarryAngle_Full(double angle)
|
||||||
|
{
|
||||||
|
const short fullres = CarryAngleTic_Full(angle);
|
||||||
|
localview.angle = fullres << FRACBITS;
|
||||||
|
return fullres;
|
||||||
|
}
|
||||||
|
|
||||||
|
static short CarryAngle_FakeLongTics(double angle)
|
||||||
|
{
|
||||||
|
return (localview.angleoffset = BYTE_TURN(CarryAngle_Full(angle)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static short CarryAngleTic_LowRes(double angle)
|
||||||
|
{
|
||||||
|
const double fullres = angle + prevcarry.angle;
|
||||||
|
const short lowres = BYTE_TURN((short)lround(fullres));
|
||||||
|
carry.angle = fullres - lowres;
|
||||||
|
return lowres;
|
||||||
|
}
|
||||||
|
|
||||||
|
static short CarryAngle_LowRes(double angle)
|
||||||
|
{
|
||||||
|
const short lowres = CarryAngleTic_LowRes(angle);
|
||||||
|
localview.angle = lowres << FRACBITS;
|
||||||
|
return lowres;
|
||||||
|
}
|
||||||
|
|
||||||
|
void G_UpdateAngleFunctions(void)
|
||||||
|
{
|
||||||
|
CarryAngleTic = lowres_turn ? CarryAngleTic_LowRes : CarryAngleTic_Full;
|
||||||
|
CarryAngle = CarryAngleTic;
|
||||||
|
G_UpdateLocalView = G_ClearLocalView;
|
||||||
|
|
||||||
|
if (raw_input && (!netgame || solonet))
|
||||||
|
{
|
||||||
|
if (lowres_turn && fake_longtics)
|
||||||
|
{
|
||||||
|
CarryAngle = CarryAngle_FakeLongTics;
|
||||||
|
G_UpdateLocalView = UpdateLocalView_FakeLongTics;
|
||||||
|
}
|
||||||
|
else if (uncapped)
|
||||||
|
{
|
||||||
|
CarryAngle = lowres_turn ? CarryAngle_LowRes : CarryAngle_Full;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CarryPitch(double pitch)
|
||||||
|
{
|
||||||
|
return (localview.pitch =
|
||||||
|
CarryError(pitch, &prevcarry.pitch, &carry.pitch));
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CarrySide(double side)
|
||||||
|
{
|
||||||
|
const double desired = side + prevcarry.side;
|
||||||
|
const int actual = RoundSide(desired);
|
||||||
|
carry.side = desired - actual;
|
||||||
|
return actual;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int CarryVert(double vert)
|
||||||
|
{
|
||||||
|
return CarryError(vert, &prevcarry.vert, &carry.vert);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Gamepad
|
||||||
|
//
|
||||||
|
|
||||||
|
static const int direction[] = {1, -1};
|
||||||
|
static double deltatics;
|
||||||
|
|
||||||
|
void G_UpdateDeltaTics(void)
|
||||||
|
{
|
||||||
|
if (uncapped && raw_input)
|
||||||
|
{
|
||||||
|
static uint64_t last_time;
|
||||||
|
const uint64_t current_time = I_GetTimeUS();
|
||||||
|
|
||||||
|
if (input_ready)
|
||||||
|
{
|
||||||
|
const uint64_t delta_time = current_time - last_time;
|
||||||
|
deltatics = (double)delta_time * TICRATE / 1000000.0;
|
||||||
|
deltatics = BETWEEN(0.0, 1.0, deltatics);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
deltatics = 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
last_time = current_time;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
deltatics = 1.0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
short G_CalcControllerAngle(void)
|
||||||
|
{
|
||||||
|
localview.rawangle -= (deltatics * axes[AXIS_TURN] * angleturn[1]
|
||||||
|
* direction[joy_invert_turn]);
|
||||||
|
return CarryAngle(localview.rawangle);
|
||||||
|
}
|
||||||
|
|
||||||
|
int G_CalcControllerPitch(void)
|
||||||
|
{
|
||||||
|
localview.rawpitch -= (deltatics * axes[AXIS_LOOK] * angleturn[1]
|
||||||
|
* direction[joy_invert_look] * FRACUNIT);
|
||||||
|
return CarryPitch(localview.rawpitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
int G_CalcControllerSideTurn(int speed)
|
||||||
|
{
|
||||||
|
const int side = RoundSide(axes[AXIS_TURN] * forwardmove[speed]
|
||||||
|
* direction[joy_invert_turn]);
|
||||||
|
return BETWEEN(-forwardmove[speed], forwardmove[speed], side);
|
||||||
|
}
|
||||||
|
|
||||||
|
int G_CalcControllerSideStrafe(int speed)
|
||||||
|
{
|
||||||
|
const int side = RoundSide(axes[AXIS_STRAFE] * forwardmove[speed]
|
||||||
|
* direction[joy_invert_strafe]);
|
||||||
|
return BETWEEN(-sidemove[speed], sidemove[speed], side);
|
||||||
|
}
|
||||||
|
|
||||||
|
int G_CalcControllerForward(int speed)
|
||||||
|
{
|
||||||
|
const int forward = lroundf(axes[AXIS_FORWARD] * forwardmove[speed]
|
||||||
|
* direction[joy_invert_forward]);
|
||||||
|
return BETWEEN(-forwardmove[speed], forwardmove[speed], forward);
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Mouse
|
||||||
|
//
|
||||||
|
|
||||||
|
static double (*AccelerateMouse)(int val);
|
||||||
|
|
||||||
|
static double AccelerateMouse_Threshold(int val)
|
||||||
|
{
|
||||||
|
if (val < 0)
|
||||||
|
{
|
||||||
|
return -AccelerateMouse_Threshold(-val);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (val > mouse_acceleration_threshold)
|
||||||
|
{
|
||||||
|
return ((double)(val - mouse_acceleration_threshold)
|
||||||
|
* (mouse_acceleration + 10) / 10
|
||||||
|
+ mouse_acceleration_threshold);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static double AccelerateMouse_NoThreshold(int val)
|
||||||
|
{
|
||||||
|
return ((double)val * (mouse_acceleration + 10) / 10);
|
||||||
|
}
|
||||||
|
|
||||||
|
static double AccelerateMouse_Skip(int val)
|
||||||
|
{
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
void G_UpdateAccelerateMouse(void)
|
||||||
|
{
|
||||||
|
if (mouse_acceleration)
|
||||||
|
{
|
||||||
|
AccelerateMouse = raw_input ? AccelerateMouse_NoThreshold
|
||||||
|
: AccelerateMouse_Threshold;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
AccelerateMouse = AccelerateMouse_Skip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
short G_CalcMouseAngle(void)
|
||||||
|
{
|
||||||
|
if (mouse_sensitivity)
|
||||||
|
{
|
||||||
|
localview.rawangle -= (AccelerateMouse(mousex)
|
||||||
|
* (mouse_sensitivity + 5) * 8 / 10);
|
||||||
|
return CarryAngle(localview.rawangle);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int G_CalcMousePitch(void)
|
||||||
|
{
|
||||||
|
if (mouse_sensitivity_y_look)
|
||||||
|
{
|
||||||
|
localview.rawpitch += (AccelerateMouse(mousey)
|
||||||
|
* (mouse_sensitivity_y_look + 5) * 8 / 10
|
||||||
|
* direction[mouse_y_invert] * FRACUNIT);
|
||||||
|
return CarryPitch(localview.rawpitch);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int G_CalcMouseSide(void)
|
||||||
|
{
|
||||||
|
if (mouse_sensitivity_strafe)
|
||||||
|
{
|
||||||
|
const double side = (AccelerateMouse(mousex)
|
||||||
|
* (mouse_sensitivity_strafe + 5) * 2 / 10);
|
||||||
|
return CarrySide(side);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int G_CalcMouseVert(void)
|
||||||
|
{
|
||||||
|
if (mouse_sensitivity_y)
|
||||||
|
{
|
||||||
|
const double vert = (AccelerateMouse(mousey)
|
||||||
|
* (mouse_sensitivity_y + 5) / 10);
|
||||||
|
return CarryVert(vert);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Composite Turn
|
||||||
|
//
|
||||||
|
|
||||||
|
static angle_t saved_angle;
|
||||||
|
|
||||||
|
void G_SavePlayerAngle(const player_t *player)
|
||||||
|
{
|
||||||
|
saved_angle = player->mo->angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void G_AddToTicAngle(player_t *player)
|
||||||
|
{
|
||||||
|
player->ticangle += player->mo->angle - saved_angle;
|
||||||
|
}
|
||||||
|
|
||||||
|
void G_UpdateTicAngleTurn(ticcmd_t *cmd, int angle)
|
||||||
|
{
|
||||||
|
const short old_angleturn = cmd->angleturn;
|
||||||
|
cmd->angleturn = CarryAngleTic(localview.rawangle + angle);
|
||||||
|
cmd->ticangleturn = cmd->angleturn - old_angleturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Quickstart Cache
|
||||||
|
// When recording a demo and the map is reloaded, cached input from a circular
|
||||||
|
// buffer can be applied prior to the screen wipe. Adapted from DSDA-Doom.
|
||||||
|
//
|
||||||
|
|
||||||
|
int quickstart_cache_tics;
|
||||||
|
boolean quickstart_queued;
|
||||||
|
float axis_turn_tic;
|
||||||
|
int mousex_tic;
|
||||||
|
|
||||||
|
void G_ClearQuickstartTic(void)
|
||||||
|
{
|
||||||
|
axis_turn_tic = 0.0f;
|
||||||
|
mousex_tic = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void G_ApplyQuickstartCache(ticcmd_t *cmd, boolean strafe)
|
||||||
|
{
|
||||||
|
static float axis_turn_cache[TICRATE];
|
||||||
|
static int mousex_cache[TICRATE];
|
||||||
|
static short angleturn_cache[TICRATE];
|
||||||
|
static int index;
|
||||||
|
|
||||||
|
if (quickstart_cache_tics < 1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (quickstart_queued)
|
||||||
|
{
|
||||||
|
axes[AXIS_TURN] = 0.0f;
|
||||||
|
mousex = 0;
|
||||||
|
|
||||||
|
if (strafe)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < quickstart_cache_tics; i++)
|
||||||
|
{
|
||||||
|
axes[AXIS_TURN] += axis_turn_cache[i];
|
||||||
|
mousex += mousex_cache[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd->angleturn = 0;
|
||||||
|
localview.rawangle = 0.0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
short result = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < quickstart_cache_tics; i++)
|
||||||
|
{
|
||||||
|
result += angleturn_cache[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd->angleturn = CarryAngleTic(result);
|
||||||
|
localview.rawangle = cmd->angleturn;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(axis_turn_cache, 0, sizeof(axis_turn_cache));
|
||||||
|
memset(mousex_cache, 0, sizeof(mousex_cache));
|
||||||
|
memset(angleturn_cache, 0, sizeof(angleturn_cache));
|
||||||
|
index = 0;
|
||||||
|
|
||||||
|
quickstart_queued = false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
axis_turn_cache[index] = axis_turn_tic;
|
||||||
|
mousex_cache[index] = mousex_tic;
|
||||||
|
angleturn_cache[index] = cmd->angleturn;
|
||||||
|
index = (index + 1) % quickstart_cache_tics;
|
||||||
|
}
|
||||||
|
}
|
73
src/g_input.h
Normal file
73
src/g_input.h
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
//
|
||||||
|
// Copyright(C) 2024 ceski
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License
|
||||||
|
// as published by the Free Software Foundation; either version 2
|
||||||
|
// of the License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful,
|
||||||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
// GNU General Public License for more details.
|
||||||
|
//
|
||||||
|
// DESCRIPTION:
|
||||||
|
// Game Input Utility Functions
|
||||||
|
//
|
||||||
|
|
||||||
|
#ifndef __G_INPUT__
|
||||||
|
#define __G_INPUT__
|
||||||
|
|
||||||
|
#include "doomtype.h"
|
||||||
|
|
||||||
|
struct player_s;
|
||||||
|
struct ticcmd_s;
|
||||||
|
|
||||||
|
// Local View
|
||||||
|
|
||||||
|
extern void (*G_UpdateLocalView)(void);
|
||||||
|
void G_ClearLocalView(void);
|
||||||
|
|
||||||
|
// Side Movement
|
||||||
|
|
||||||
|
void G_UpdateSideMove(void);
|
||||||
|
|
||||||
|
// Error Accumulation
|
||||||
|
|
||||||
|
void G_UpdateCarry(void);
|
||||||
|
void G_ClearCarry(void);
|
||||||
|
void G_UpdateAngleFunctions(void);
|
||||||
|
|
||||||
|
// Gamepad
|
||||||
|
|
||||||
|
void G_UpdateDeltaTics(void);
|
||||||
|
short G_CalcControllerAngle(void);
|
||||||
|
int G_CalcControllerPitch(void);
|
||||||
|
int G_CalcControllerSideTurn(int speed);
|
||||||
|
int G_CalcControllerSideStrafe(int speed);
|
||||||
|
int G_CalcControllerForward(int speed);
|
||||||
|
|
||||||
|
// Mouse
|
||||||
|
|
||||||
|
void G_UpdateAccelerateMouse(void);
|
||||||
|
short G_CalcMouseAngle(void);
|
||||||
|
int G_CalcMousePitch(void);
|
||||||
|
int G_CalcMouseSide(void);
|
||||||
|
int G_CalcMouseVert(void);
|
||||||
|
|
||||||
|
// Composite Turn
|
||||||
|
|
||||||
|
void G_SavePlayerAngle(const struct player_s *player);
|
||||||
|
void G_AddToTicAngle(struct player_s *player);
|
||||||
|
void G_UpdateTicAngleTurn(struct ticcmd_s *cmd, int angle);
|
||||||
|
|
||||||
|
// Quickstart Cache
|
||||||
|
|
||||||
|
extern int quickstart_cache_tics;
|
||||||
|
extern boolean quickstart_queued;
|
||||||
|
extern float axis_turn_tic;
|
||||||
|
extern int mousex_tic;
|
||||||
|
void G_ClearQuickstartTic(void);
|
||||||
|
void G_ApplyQuickstartCache(struct ticcmd_s *cmd, boolean strafe);
|
||||||
|
|
||||||
|
#endif
|
@ -24,7 +24,6 @@
|
|||||||
#include "i_printf.h"
|
#include "i_printf.h"
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
#include "m_config.h"
|
#include "m_config.h"
|
||||||
#include "r_main.h"
|
|
||||||
|
|
||||||
#define AXIS_BUTTON_DEADZONE (SDL_JOYSTICK_AXIS_MAX / 3)
|
#define AXIS_BUTTON_DEADZONE (SDL_JOYSTICK_AXIS_MAX / 3)
|
||||||
|
|
||||||
@ -463,59 +462,6 @@ void I_DelayEvent(void)
|
|||||||
//
|
//
|
||||||
// Read the change in mouse state to generate mouse motion events
|
// Read the change in mouse state to generate mouse motion events
|
||||||
//
|
//
|
||||||
// This is to combine all mouse movement for a tic into one mouse
|
|
||||||
// motion event.
|
|
||||||
|
|
||||||
// The mouse input values are input directly to the game, but when the values
|
|
||||||
// exceed the value of mouse_acceleration_threshold, they are multiplied by
|
|
||||||
// mouse_acceleration to increase the speed.
|
|
||||||
|
|
||||||
static int mouse_acceleration;
|
|
||||||
static int mouse_acceleration_threshold;
|
|
||||||
|
|
||||||
static double AccelerateMouse_Thresh(int val)
|
|
||||||
{
|
|
||||||
if (val < 0)
|
|
||||||
{
|
|
||||||
return -AccelerateMouse_Thresh(-val);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (val > mouse_acceleration_threshold)
|
|
||||||
{
|
|
||||||
return ((double)(val - mouse_acceleration_threshold)
|
|
||||||
* (mouse_acceleration + 10) / 10
|
|
||||||
+ mouse_acceleration_threshold);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static double AccelerateMouse_NoThresh(int val)
|
|
||||||
{
|
|
||||||
return ((double)val * (mouse_acceleration + 10) / 10);
|
|
||||||
}
|
|
||||||
|
|
||||||
static double AccelerateMouse_Skip(int val)
|
|
||||||
{
|
|
||||||
return val;
|
|
||||||
}
|
|
||||||
|
|
||||||
double (*I_AccelerateMouse)(int val) = AccelerateMouse_NoThresh;
|
|
||||||
|
|
||||||
void I_UpdateAccelerateMouse(void)
|
|
||||||
{
|
|
||||||
if (mouse_acceleration)
|
|
||||||
{
|
|
||||||
I_AccelerateMouse =
|
|
||||||
raw_input ? AccelerateMouse_NoThresh : AccelerateMouse_Thresh;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
I_AccelerateMouse = AccelerateMouse_Skip;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void I_ReadMouse(void)
|
void I_ReadMouse(void)
|
||||||
{
|
{
|
||||||
@ -593,11 +539,3 @@ void I_HandleKeyboardEvent(SDL_Event *sdlevent)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void I_BindInputVariables(void)
|
|
||||||
{
|
|
||||||
BIND_NUM_GENERAL(mouse_acceleration, 10, 0, 40,
|
|
||||||
"Mouse acceleration (0 = 1.0; 40 = 5.0)");
|
|
||||||
BIND_NUM(mouse_acceleration_threshold, 10, 0, 32,
|
|
||||||
"Mouse acceleration threshold");
|
|
||||||
}
|
|
||||||
|
@ -26,8 +26,6 @@ void I_InitController(void);
|
|||||||
void I_OpenController(int which);
|
void I_OpenController(int which);
|
||||||
void I_CloseController(int which);
|
void I_CloseController(int which);
|
||||||
|
|
||||||
extern double (*I_AccelerateMouse)(int val);
|
|
||||||
void I_UpdateAccelerateMouse(void);
|
|
||||||
void I_ReadMouse(void);
|
void I_ReadMouse(void);
|
||||||
void I_UpdateJoystick(boolean axis_buttons);
|
void I_UpdateJoystick(boolean axis_buttons);
|
||||||
void I_UpdateJoystickMenu(void);
|
void I_UpdateJoystickMenu(void);
|
||||||
@ -37,6 +35,4 @@ void I_HandleJoystickEvent(SDL_Event *sdlevent);
|
|||||||
void I_HandleKeyboardEvent(SDL_Event *sdlevent);
|
void I_HandleKeyboardEvent(SDL_Event *sdlevent);
|
||||||
void I_HandleMouseEvent(SDL_Event *sdlevent);
|
void I_HandleMouseEvent(SDL_Event *sdlevent);
|
||||||
|
|
||||||
void I_BindInputVariables(void);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -37,7 +37,6 @@
|
|||||||
#include "hu_stuff.h"
|
#include "hu_stuff.h"
|
||||||
#include "i_gamepad.h"
|
#include "i_gamepad.h"
|
||||||
#include "i_printf.h"
|
#include "i_printf.h"
|
||||||
#include "i_input.h"
|
|
||||||
#include "i_sound.h"
|
#include "i_sound.h"
|
||||||
#include "i_system.h"
|
#include "i_system.h"
|
||||||
#include "i_video.h"
|
#include "i_video.h"
|
||||||
@ -117,7 +116,6 @@ void M_InitConfig(void)
|
|||||||
G_BindGameVariables();
|
G_BindGameVariables();
|
||||||
|
|
||||||
G_BindGameInputVariables();
|
G_BindGameInputVariables();
|
||||||
I_BindInputVariables();
|
|
||||||
I_BindGamepadVariables();
|
I_BindGamepadVariables();
|
||||||
M_BindInputVariables();
|
M_BindInputVariables();
|
||||||
|
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
#include "hu_lib.h"
|
#include "hu_lib.h"
|
||||||
#include "hu_stuff.h"
|
#include "hu_stuff.h"
|
||||||
#include "i_gamepad.h"
|
#include "i_gamepad.h"
|
||||||
#include "i_input.h"
|
|
||||||
#include "i_oalsound.h"
|
#include "i_oalsound.h"
|
||||||
#include "i_sound.h"
|
#include "i_sound.h"
|
||||||
#include "i_timer.h"
|
#include "i_timer.h"
|
||||||
@ -2158,7 +2157,7 @@ static setup_menu_t gen_settings3[] = {
|
|||||||
MI_GAP,
|
MI_GAP,
|
||||||
|
|
||||||
{"Mouse acceleration", S_THERMO, CNTR_X, M_THRM_SPC, {"mouse_acceleration"},
|
{"Mouse acceleration", S_THERMO, CNTR_X, M_THRM_SPC, {"mouse_acceleration"},
|
||||||
m_null, input_null, str_mouse_accel, I_UpdateAccelerateMouse},
|
m_null, input_null, str_mouse_accel, G_UpdateAccelerateMouse},
|
||||||
|
|
||||||
MI_END
|
MI_END
|
||||||
};
|
};
|
||||||
|
25
src/p_pspr.c
25
src/p_pspr.c
@ -22,6 +22,7 @@
|
|||||||
#include "d_items.h"
|
#include "d_items.h"
|
||||||
#include "d_player.h"
|
#include "d_player.h"
|
||||||
#include "doomstat.h"
|
#include "doomstat.h"
|
||||||
|
#include "g_input.h"
|
||||||
#include "i_printf.h"
|
#include "i_printf.h"
|
||||||
#include "i_video.h" // uncapped
|
#include "i_video.h" // uncapped
|
||||||
#include "m_random.h"
|
#include "m_random.h"
|
||||||
@ -649,18 +650,6 @@ void A_GunFlash(player_t *player, pspdef_t *psp)
|
|||||||
// WEAPON ATTACKS
|
// WEAPON ATTACKS
|
||||||
//
|
//
|
||||||
|
|
||||||
static angle_t saved_angle;
|
|
||||||
|
|
||||||
static void SavePlayerAngle(player_t *player)
|
|
||||||
{
|
|
||||||
saved_angle = player->mo->angle;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void AddToTicAngle(player_t *player)
|
|
||||||
{
|
|
||||||
player->ticangle += player->mo->angle - saved_angle;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// A_Punch
|
// A_Punch
|
||||||
//
|
//
|
||||||
@ -697,10 +686,10 @@ void A_Punch(player_t *player, pspdef_t *psp)
|
|||||||
|
|
||||||
// turn to face target
|
// turn to face target
|
||||||
|
|
||||||
SavePlayerAngle(player);
|
G_SavePlayerAngle(player);
|
||||||
player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y,
|
player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y,
|
||||||
linetarget->x, linetarget->y);
|
linetarget->x, linetarget->y);
|
||||||
AddToTicAngle(player);
|
G_AddToTicAngle(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
@ -743,7 +732,7 @@ void A_Saw(player_t *player, pspdef_t *psp)
|
|||||||
angle = R_PointToAngle2(player->mo->x, player->mo->y,
|
angle = R_PointToAngle2(player->mo->x, player->mo->y,
|
||||||
linetarget->x, linetarget->y);
|
linetarget->x, linetarget->y);
|
||||||
|
|
||||||
SavePlayerAngle(player);
|
G_SavePlayerAngle(player);
|
||||||
if (angle - player->mo->angle > ANG180)
|
if (angle - player->mo->angle > ANG180)
|
||||||
if ((signed int) (angle - player->mo->angle) < -ANG90/20)
|
if ((signed int) (angle - player->mo->angle) < -ANG90/20)
|
||||||
player->mo->angle = angle + ANG90/21;
|
player->mo->angle = angle + ANG90/21;
|
||||||
@ -754,7 +743,7 @@ void A_Saw(player_t *player, pspdef_t *psp)
|
|||||||
player->mo->angle = angle - ANG90/21;
|
player->mo->angle = angle - ANG90/21;
|
||||||
else
|
else
|
||||||
player->mo->angle += ANG90/20;
|
player->mo->angle += ANG90/20;
|
||||||
AddToTicAngle(player);
|
G_AddToTicAngle(player);
|
||||||
|
|
||||||
player->mo->flags |= MF_JUSTATTACKED;
|
player->mo->flags |= MF_JUSTATTACKED;
|
||||||
}
|
}
|
||||||
@ -1318,9 +1307,9 @@ void A_WeaponMeleeAttack(player_t *player, pspdef_t *psp)
|
|||||||
S_StartSound(player->mo, hitsound);
|
S_StartSound(player->mo, hitsound);
|
||||||
|
|
||||||
// turn to face target
|
// turn to face target
|
||||||
SavePlayerAngle(player);
|
G_SavePlayerAngle(player);
|
||||||
player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, linetarget->x, linetarget->y);
|
player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, linetarget->x, linetarget->y);
|
||||||
AddToTicAngle(player);
|
G_AddToTicAngle(player);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -70,7 +70,6 @@ fixed_t skyiscale;
|
|||||||
fixed_t viewx, viewy, viewz;
|
fixed_t viewx, viewy, viewz;
|
||||||
angle_t viewangle;
|
angle_t viewangle;
|
||||||
localview_t localview;
|
localview_t localview;
|
||||||
double deltatics;
|
|
||||||
boolean raw_input;
|
boolean raw_input;
|
||||||
fixed_t viewcos, viewsin;
|
fixed_t viewcos, viewsin;
|
||||||
player_t *viewplayer;
|
player_t *viewplayer;
|
||||||
|
@ -153,9 +153,6 @@ inline static angle_t LerpAngle(angle_t oangle, angle_t nangle)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extern double deltatics;
|
|
||||||
extern boolean raw_input;
|
|
||||||
|
|
||||||
extern int autodetect_hom;
|
extern int autodetect_hom;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -106,6 +106,7 @@ extern fixed_t viewy;
|
|||||||
extern fixed_t viewz;
|
extern fixed_t viewz;
|
||||||
extern angle_t viewangle;
|
extern angle_t viewangle;
|
||||||
extern localview_t localview; // View orientation offsets for current frame.
|
extern localview_t localview; // View orientation offsets for current frame.
|
||||||
|
extern boolean raw_input;
|
||||||
extern struct player_s *viewplayer;
|
extern struct player_s *viewplayer;
|
||||||
extern angle_t clipangle;
|
extern angle_t clipangle;
|
||||||
extern angle_t vx_clipangle;
|
extern angle_t vx_clipangle;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user