mirror of
https://github.com/fabiangreffrath/woof.git
synced 2025-09-22 11:22:18 -04:00
Add fake high-resolution turning setting (#1691)
This commit is contained in:
parent
9011fbcfd8
commit
62ddc5c1b8
@ -2738,7 +2738,7 @@ void D_DoomMain(void)
|
||||
D_CheckNetGame();
|
||||
|
||||
G_UpdateSideMove();
|
||||
G_UpdateCarryAngle();
|
||||
G_UpdateAngleFunctions();
|
||||
I_UpdateAccelerateMouse();
|
||||
|
||||
MN_ResetTimeScale();
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
@ -37,6 +37,7 @@ typedef struct ticcmd_s
|
||||
byte buttons;
|
||||
|
||||
int pitch;
|
||||
short ticangleturn; // Local angle delta for composite input only.
|
||||
} ticcmd_t;
|
||||
|
||||
#endif
|
||||
|
@ -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;
|
||||
|
||||
|
109
src/g_game.c
109
src/g_game.c
@ -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;
|
||||
|
||||
void G_UpdateCarryAngle(void)
|
||||
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 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,
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
18
src/p_pspr.c
18
src/p_pspr.c
@ -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);
|
||||
}
|
||||
|
||||
//
|
||||
|
14
src/p_user.c
14
src/p_user.c
@ -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;
|
||||
|
17
src/r_main.c
17
src/r_main.c
@ -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)");
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
|
@ -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;
|
||||
|
||||
//
|
||||
|
Loading…
x
Reference in New Issue
Block a user