Add fake high-resolution turning setting (#1691)

This commit is contained in:
ceski 2024-05-22 06:28:43 -07:00 committed by GitHub
parent 9011fbcfd8
commit 62ddc5c1b8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 120 additions and 60 deletions

View File

@ -2738,7 +2738,7 @@ void D_DoomMain(void)
D_CheckNetGame();
G_UpdateSideMove();
G_UpdateCarryAngle();
G_UpdateAngleFunctions();
I_UpdateAccelerateMouse();
MN_ResetTimeScale();

View File

@ -25,6 +25,7 @@
// animation states (closely tied to the sprites
// used to represent them, unfortunately).
#include "p_pspr.h"
#include "tables.h"
// In addition, the player is just a special
// case of the generic moving object/actor.
@ -210,6 +211,9 @@ typedef struct player_s
// DSDA UV Max category requirements
int maxkilldiscount;
// Local angle for blending per-frame and per-tic turning.
angle_t ticangle, oldticangle;
} player_t;

View File

@ -37,6 +37,7 @@ typedef struct ticcmd_s
byte buttons;
int pitch;
short ticangleturn; // Local angle delta for composite input only.
} ticcmd_t;
#endif

View File

@ -293,6 +293,9 @@ extern boolean lowres_turn;
// Config key for low resolution turning.
extern boolean shorttics;
// Fake longtics when using shorttics.
extern boolean fake_longtics;
// cph's doom 1.91 longtics hack
extern boolean longtics;

View File

@ -142,6 +142,7 @@ int max_kill_requirement; // DSDA UV Max category requirements
int totalleveltimes; // [FG] total time for all completed levels
boolean demorecording;
boolean longtics; // cph's doom 1.91 longtics hack
boolean fake_longtics; // Fake longtics when using shorttics.
boolean shorttics; // Config key for low resolution turning.
boolean lowres_turn; // low resolution turning for longtics
boolean demoplayback;
@ -213,7 +214,6 @@ typedef struct carry_s
double pitch;
double side;
double vert;
short lowres;
} carry_t;
static carry_t prevcarry;
@ -444,8 +444,8 @@ static double CalcControllerAngle(void)
static double CalcControllerPitch(void)
{
const double pitch = angleturn[1] * axes[AXIS_LOOK];
return (pitch * FRACUNIT * direction[joy_invert_look]);
return (angleturn[1] * axes[AXIS_LOOK] * direction[joy_invert_look]
* FRACUNIT);
}
static int CarryError(double value, const double *prevcarry, double *carry)
@ -456,30 +456,79 @@ static int CarryError(double value, const double *prevcarry, double *carry)
return actual;
}
static short CarryAngle_Full(double angle)
static short CarryAngleTic_Full(double angle)
{
return CarryError(angle, &prevcarry.angle, &carry.angle);
}
static short CarryAngle_LowRes(double angle)
static short CarryAngle_Full(double angle)
{
const short desired = CarryAngle_Full(angle) + prevcarry.lowres;
// Round to nearest 256 for single byte turning. From Chocolate Doom.
const short actual = (desired + 128) & 0xFF00;
carry.lowres = desired - actual;
return actual;
const short fullres = CarryAngleTic_Full(angle);
localview.angle = fullres << FRACBITS;
return fullres;
}
static short (*CarryAngle)(double angle) = CarryAngle_Full;
static short CarryAngle_FakeLongTics(double angle)
{
return (localview.angleoffset = (CarryAngle_Full(angle) + 128) & 0xFF00);
}
void G_UpdateCarryAngle(void)
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 CarryError(pitch, &prevcarry.pitch, &carry.pitch);
return (localview.pitch = CarryError(pitch, &prevcarry.pitch, &carry.pitch));
}
static int CarryMouseVert(double vert)
@ -505,14 +554,11 @@ static double CalcMouseAngle(int mousex)
static double CalcMousePitch(int mousey)
{
double pitch;
if (!mouse_sensitivity_y_look)
return 0.0;
pitch = I_AccelerateMouse(mousey) * (mouse_sensitivity_y_look + 5) * 8 / 10;
return pitch * FRACUNIT * direction[mouse_y_invert];
return (I_AccelerateMouse(mousey) * (mouse_sensitivity_y_look + 5) * 8 / 10
* direction[mouse_y_invert] * FRACUNIT);
}
static double CalcMouseSide(int mousex)
@ -520,8 +566,7 @@ static double CalcMouseSide(int mousex)
if (!mouse_sensitivity_strafe)
return 0.0;
return (I_AccelerateMouse(mousex) *
(mouse_sensitivity_strafe + 5) * 2 / 10);
return (I_AccelerateMouse(mousex) * (mouse_sensitivity_strafe + 5) * 2 / 10);
}
static double CalcMouseVert(int mousey)
@ -586,7 +631,7 @@ static void ApplyQuickstartCache(ticcmd_t *cmd, boolean strafe)
result += angleturn_cache[i];
}
cmd->angleturn = CarryAngle(result);
cmd->angleturn = CarryAngleTic(result);
localview.rawangle = cmd->angleturn;
}
@ -623,7 +668,6 @@ void G_PrepTiccmd(void)
{
localview.rawangle -= CalcControllerAngle() * deltatics;
cmd->angleturn = CarryAngle(localview.rawangle);
localview.angle = cmd->angleturn << 16;
axes[AXIS_TURN] = 0.0f;
}
@ -631,7 +675,6 @@ void G_PrepTiccmd(void)
{
localview.rawpitch -= CalcControllerPitch() * deltatics;
cmd->pitch = CarryPitch(localview.rawpitch);
localview.pitch = cmd->pitch;
axes[AXIS_LOOK] = 0.0f;
}
}
@ -642,7 +685,6 @@ void G_PrepTiccmd(void)
{
localview.rawangle -= CalcMouseAngle(mousex);
cmd->angleturn = CarryAngle(localview.rawangle);
localview.angle = cmd->angleturn << 16;
mousex = 0;
}
@ -650,7 +692,6 @@ void G_PrepTiccmd(void)
{
localview.rawpitch += CalcMousePitch(mousey);
cmd->pitch = CarryPitch(localview.rawpitch);
localview.pitch = cmd->pitch;
mousey = 0;
}
}
@ -778,8 +819,8 @@ void G_BuildTiccmd(ticcmd_t* cmd)
if (angle)
{
const short old_angleturn = cmd->angleturn;
cmd->angleturn = CarryAngle(localview.rawangle + angle);
localview.ticangleturn = cmd->angleturn - old_angleturn;
cmd->angleturn = CarryAngleTic(localview.rawangle + angle);
cmd->ticangleturn = cmd->angleturn - old_angleturn;
}
if (forward > MAXPLMOVE)
@ -797,10 +838,7 @@ void G_BuildTiccmd(ticcmd_t* cmd)
ClearQuickstartTic();
I_ResetControllerAxes();
mousex = mousey = 0;
localview.angle = 0;
localview.pitch = 0;
localview.rawangle = 0.0;
localview.rawpitch = 0.0;
UpdateLocalView();
prevcarry = carry;
// Buttons
@ -1625,6 +1663,7 @@ static void G_PlayerFinishLevel(int player)
p->centering = false;
p->slope = 0;
p->recoilpitch = p->oldrecoilpitch = 0;
p->ticangle = p->oldticangle = 0;
}
// [crispy] format time for level statistics
@ -4596,8 +4635,12 @@ void G_BindGameInputVariables(void)
void G_BindGameVariables(void)
{
BIND_BOOL(raw_input, true,
"Raw gamepad/mouse input for turning/looking (0 = Interpolate; 1 = Raw)");
BIND_BOOL(fake_longtics, true,
"Fake high-resolution turning when using low-resolution turning");
BIND_BOOL(shorttics, false, "Always use low-resolution turning");
BIND_NUM(quickstart_cache_tics, 0, 0, TICRATE, "Quickstart cache tics");
BIND_BOOL(shorttics, false, "Low-resolution turning");
BIND_NUM_GENERAL(default_skill, 3, 1, 5,
"Default skill level (1 = ITYTD; 2 = HNTR; 3 = HMP; 4 = UV; 5 = NM)");
BIND_NUM_GENERAL(realtic_clock_rate, 100, 10, 1000,

View File

@ -54,7 +54,7 @@ void G_WorldDone(void);
void G_Ticker(void);
void G_ScreenShot(void);
void G_UpdateSideMove(void);
void G_UpdateCarryAngle(void);
void G_UpdateAngleFunctions(void);
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_MBFSaveGameName(int); // MBF savegame filename

View File

@ -2359,6 +2359,8 @@ void MN_UpdateAdvancedSoundItems(boolean toggle)
void MN_UpdateFpsLimitItem(void)
{
DisableItem(!uncapped, gen_settings1, "fpslimit");
G_ClearInput();
G_UpdateAngleFunctions();
}
void MN_DisableVoxelsRenderingItem(void)

View File

@ -649,6 +649,18 @@ void A_GunFlash(player_t *player, pspdef_t *psp)
// 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
//
@ -685,8 +697,10 @@ void A_Punch(player_t *player, pspdef_t *psp)
// turn to face target
SavePlayerAngle(player);
player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y,
linetarget->x, linetarget->y);
AddToTicAngle(player);
}
//
@ -729,6 +743,7 @@ void A_Saw(player_t *player, pspdef_t *psp)
angle = R_PointToAngle2(player->mo->x, player->mo->y,
linetarget->x, linetarget->y);
SavePlayerAngle(player);
if (angle - player->mo->angle > ANG180)
if ((signed int) (angle - player->mo->angle) < -ANG90/20)
player->mo->angle = angle + ANG90/21;
@ -739,6 +754,7 @@ void A_Saw(player_t *player, pspdef_t *psp)
player->mo->angle = angle - ANG90/21;
else
player->mo->angle += ANG90/20;
AddToTicAngle(player);
player->mo->flags |= MF_JUSTATTACKED;
}
@ -1302,7 +1318,9 @@ void A_WeaponMeleeAttack(player_t *player, pspdef_t *psp)
S_StartSound(player->mo, hitsound);
// turn to face target
SavePlayerAngle(player);
player->mo->angle = R_PointToAngle2(player->mo->x, player->mo->y, linetarget->x, linetarget->y);
AddToTicAngle(player);
}
//

View File

@ -215,12 +215,7 @@ void P_MovePlayer (player_t* player)
mo->angle += cmd->angleturn << 16;
onground = mo->z <= mo->floorz;
if (player == &players[consoleplayer])
{
localview.ticangle += localview.ticangleturn << 16;
localview.ticangleturn = 0;
}
player->ticangle += cmd->ticangleturn << FRACBITS;
// killough 10/98:
//
@ -377,11 +372,7 @@ void P_PlayerThink (player_t* player)
player->oldviewz = player->viewz;
player->oldpitch = player->pitch;
player->oldrecoilpitch = player->recoilpitch;
if (player == &players[consoleplayer])
{
localview.oldticangle = localview.ticangle;
}
player->oldticangle = player->ticangle;
// killough 2/8/98, 3/21/98:
// (this code is necessary despite questions raised elsewhere in a comment)
@ -397,6 +388,7 @@ void P_PlayerThink (player_t* player)
if (player->mo->flags & MF_JUSTATTACKED)
{
cmd->angleturn = 0;
cmd->ticangleturn = 0;
cmd->forwardmove = 0xc800/512;
cmd->sidemove = 0;
player->mo->flags &= ~MF_JUSTATTACKED;

View File

@ -723,6 +723,7 @@ void R_SetupFrame (player_t *player)
{
int i, cm;
fixed_t pitch;
const boolean use_localview = CheckLocalView(player);
viewplayer = player;
// [AM] Interpolate the player camera if the feature is enabled.
@ -736,10 +737,6 @@ void R_SetupFrame (player_t *player)
// Don't interpolate during a paused state
leveltime > oldleveltime)
{
// Use localview unless the player or game is in an invalid state, in which
// case fall back to interpolation.
const boolean use_localview = CheckLocalView(player);
// Interpolate player camera from their old position to their current one.
viewx = LerpFixed(player->mo->oldx, player->mo->x);
viewy = LerpFixed(player->mo->oldy, player->mo->y);
@ -747,8 +744,8 @@ void R_SetupFrame (player_t *player)
if (use_localview)
{
viewangle = (player->mo->angle + localview.angle - localview.ticangle +
LerpAngle(localview.oldticangle, localview.ticangle));
viewangle = (player->mo->angle + localview.angle - player->ticangle +
LerpAngle(player->oldticangle, player->ticangle));
}
else
{
@ -776,6 +773,11 @@ void R_SetupFrame (player_t *player)
viewangle = player->mo->angle;
// [crispy] pitch is actual lookdir and weapon pitch
pitch = player->pitch + player->recoilpitch;
if (use_localview && lowres_turn && fake_longtics)
{
viewangle += localview.angle;
}
}
if (pitch != viewpitch)
@ -994,9 +996,6 @@ void R_BindRenderVariables(void)
BIND_BOOL(draw_nearby_sprites, true,
"Draw sprites overlapping into visible sectors");
BIND_BOOL(raw_input, true,
"Raw gamepad/mouse input for turning/looking (0 = Interpolate; 1 = Raw)");
}
//----------------------------------------------------------------------------

View File

@ -91,13 +91,11 @@ extern side_t *sides;
typedef struct localview_s
{
angle_t oldticangle;
angle_t ticangle;
short ticangleturn;
double rawangle;
double rawpitch;
angle_t angle;
int pitch;
fixed_t pitch;
short angleoffset;
} localview_t;
//