initial freelook implementation, rendering part (#472)

* initial freelook implementation, rendering part

* fix freelook for different view sizes

* simplify implementation

* correct view angle for different screen sizes

* implement view angle centering

* go the cmd->look route

* mouselook config toggle and key binding

* remove unnecessary restriction

* save mouselook in config file

* enable vertical mouse by default

* remove obsolete comments

* do not center view when hitting ground anymore

* sprite clipping optimizations

* center player view in G_PlayerReborn()

* Revert "center player view in G_PlayerReborn()"

This reverts commit b307511ac27781adb9173e2c108e71c57993cebc.

* minor simplification
This commit is contained in:
Fabian Greffrath 2022-03-25 09:10:24 +01:00 committed by GitHub
parent 56717231b0
commit e70e9a88d8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 130 additions and 12 deletions

View File

@ -178,6 +178,10 @@ typedef struct player_s
// [Woof!] show centered "A secret is revealed!" message
char* centermessage;
// [crispy] free look / mouse look
int lookdir, oldlookdir;
boolean centering;
} player_t;

View File

@ -44,6 +44,8 @@ typedef struct
short consistancy; // checks for net game
byte chatchar;
byte buttons;
int lookdir;
} ticcmd_t;
#endif

View File

@ -124,6 +124,7 @@ boolean haswolflevels = false;// jff 4/18/98 wolf levels present
byte *savebuffer;
int autorun = false; // always running? // phares
int novert = false;
int mouselook = false;
int default_complevel;
@ -311,6 +312,13 @@ void G_BuildTiccmd(ticcmd_t* cmd)
else
tspeed = speed;
// [crispy] mouse look
if (mouselook == -1)
{
mouselook = 0;
cmd->lookdir = TOCENTER;
}
// turn 180 degrees in one keystroke? // phares
// |
if (M_InputGameActive(input_reverse)) // V
@ -472,7 +480,12 @@ void G_BuildTiccmd(ticcmd_t* cmd)
cmd->buttons |= BT_USE;
}
if (!novert)
// [crispy] mouse look
if (mouselook)
{
cmd->lookdir = mousey;
}
else if (!novert)
{
forward += mousey;
}
@ -969,6 +982,9 @@ static void G_PlayerFinishLevel(int player)
p->fixedcolormap = 0; // cancel ir gogles
p->damagecount = 0; // no palette changes
p->bonuscount = 0;
// [crispy] reset additional player properties
p->oldlookdir = p->lookdir = 0;
p->centering = false;
}
// [crispy] format time for level statistics

View File

@ -79,6 +79,7 @@ extern int key_enter;
extern int key_help;
extern int autorun; // always running? // phares
extern int novert;
extern int mouselook;
extern int defaultskill; //jff 3/24/98 default skill
extern boolean haswolflevels; //jff 4/18/98 wolf levels present

View File

@ -46,6 +46,8 @@ enum
input_prevweapon,
input_nextweapon,
input_mouselook,
input_weapon1,
input_weapon2,
input_weapon3,

View File

@ -2741,10 +2741,11 @@ setup_menu_t keys_settings1[] = // Key Binding screen strings
{"STRAFE" ,S_INPUT ,m_scrn,KB_X,KB_Y+9*8,{0},input_strafe},
{"AUTORUN" ,S_INPUT ,m_scrn,KB_X,KB_Y+10*8,{0},input_autorun},
{"VERTICAL MOUSE",S_INPUT ,m_scrn,KB_X,KB_Y+11*8,{0},input_novert},
{"MOUSELOOK" ,S_INPUT ,m_scrn,KB_X,KB_Y+12*8,{0},input_mouselook},
{"TURN LEFT" ,S_INPUT ,m_scrn,KB_X,KB_Y+13*8,{0},input_turnleft},
{"TURN RIGHT" ,S_INPUT ,m_scrn,KB_X,KB_Y+14*8,{0},input_turnright},
{"180 TURN" ,S_INPUT ,m_scrn,KB_X,KB_Y+15*8,{0},input_reverse},
{"TURN LEFT" ,S_INPUT ,m_scrn,KB_X,KB_Y+14*8,{0},input_turnleft},
{"TURN RIGHT" ,S_INPUT ,m_scrn,KB_X,KB_Y+15*8,{0},input_turnright},
{"180 TURN" ,S_INPUT ,m_scrn,KB_X,KB_Y+16*8,{0},input_reverse},
// Button for resetting to defaults
{0,S_RESET,m_null,X_BUTTON,Y_BUTTON},
@ -4903,6 +4904,13 @@ boolean M_Responder (event_t* ev)
// return true; // [FG] don't let toggles eat keys
}
if (M_InputActivated(input_mouselook))
{
mouselook = mouselook ? -1 : 1;
dprintf("Mouselook %s", mouselook == 1 ? "On" : "Off");
// return true; // [FG] don't let toggles eat keys
}
if (ch == key_help) // Help key
{
M_StartControlPanel ();

View File

@ -380,7 +380,7 @@ default_t defaults[] = {
{ //jff 4/3/98 allow unlimited sensitivity
"mouse_sensitivity_vert",
(config_t *) &mouseSensitivity_vert, NULL,
{0}, {0,UL}, number, ss_none, wad_no,
{10}, {0,UL}, number, ss_none, wad_no,
"adjust vertical (y) mouse sensitivity"
},
@ -433,6 +433,13 @@ default_t defaults[] = {
"1 to disable vertical mouse movement"
},
{
"mouselook",
(config_t *) &mouselook, NULL,
{0}, {0,1}, number, ss_none, wad_no,
"1 to enable mouselook"
},
{ // killough 2/21/98: default to 10
"screenblocks",
(config_t *) &screenblocks, NULL,
@ -685,6 +692,14 @@ default_t defaults[] = {
input_backward, { {input_type_key, 's'}, {input_type_key, KEYD_DOWNARROW} }
},
{
"input_mouselook",
NULL, NULL,
{0}, {UL,UL}, input, ss_keys, wad_no,
"key to toggle mouselook",
input_mouselook, { {0, 0} }
},
{ // phares 3/7/98
"input_menu_right",
NULL, NULL,

View File

@ -702,6 +702,8 @@ static void P_KillMobj(mobj_t *source, mobj_t *target)
target->flags &= ~MF_SOLID;
target->player->playerstate = PST_DEAD;
P_DropWeapon (target->player);
// [crispy] center view when dying
target->player->centering = true;
if (target->player == &players[consoleplayer] && automapactive)
if (!demoplayback) // killough 11/98: don't switch out in demos, though

View File

@ -79,7 +79,11 @@ int EV_Teleport(line_t *line, int side, mobj_t *thing)
}
if (player)
{
player->viewz = thing->z + player->viewheight;
// [crispy] center view after teleporting
player->centering = true;
}
// spawn teleport fog and emit sound at source
S_StartSound(P_SpawnMobj(oldx, oldy, oldz, MT_TFOG), sfx_telept);

View File

@ -231,6 +231,18 @@ void P_MovePlayer (player_t* player)
(mo->state == states+S_PLAY))
P_SetMobjState(mo,S_PLAY_RUN1);
}
// [crispy] apply lookdir delta
if (cmd->lookdir == TOCENTER)
{
player->centering = true;
}
else if (!menuactive && !demoplayback)
{
player->lookdir = BETWEEN(-LOOKDIRMIN * MLOOKUNIT,
LOOKDIRMAX * MLOOKUNIT,
player->lookdir + cmd->lookdir);
}
}
#define ANG5 (ANG90/18)
@ -312,6 +324,7 @@ void P_PlayerThink (player_t* player)
player->mo->oldz = player->mo->z;
player->mo->oldangle = player->mo->angle;
player->oldviewz = player->viewz;
player->oldlookdir = player->lookdir;
// killough 2/8/98, 3/21/98:
// (this code is necessary despite questions raised elsewhere in a comment)
@ -332,6 +345,24 @@ void P_PlayerThink (player_t* player)
player->mo->flags &= ~MF_JUSTATTACKED;
}
// [crispy] center view
if (player->centering)
{
if (player->lookdir > 0)
{
player->lookdir -= 8 * MLOOKUNIT;
}
else if (player->lookdir < 0)
{
player->lookdir += 8 * MLOOKUNIT;
}
if (abs(player->lookdir) < 8 * MLOOKUNIT)
{
player->lookdir = 0;
player->centering = false;
}
}
if (player->playerstate == PST_DEAD)
{
P_DeathThink (player);

View File

@ -33,6 +33,12 @@
#include "r_defs.h"
#include "r_state.h"
#define LOOKDIRMIN 110 // [crispy] -110, actually
#define LOOKDIRMAX 90
#define LOOKDIRS (LOOKDIRMIN+1+LOOKDIRMAX) // [crispy] lookdir range: -110..0..90
#define MLOOKUNIT 8
#define TOCENTER INT_MIN
// Retrieve column data for span blitting.
byte *R_GetColumn(int tex, int col);
byte *R_GetColumnMod(int tex, int col);

View File

@ -57,6 +57,7 @@ angle_t viewangle;
fixed_t viewcos, viewsin;
player_t *viewplayer;
extern lighttable_t **walllights;
fixed_t viewheightfrac; // [FG] sprite clipping optimizations
//
// precalculated math tables
@ -356,6 +357,8 @@ void R_InitLightTables (void)
boolean setsizeneeded;
int setblocks;
static int viewblocks;
void R_SetViewSize(int blocks)
{
setsizeneeded = true;
@ -368,7 +371,7 @@ void R_SetViewSize(int blocks)
void R_ExecuteSetViewSize (void)
{
int i;
int i, j;
setsizeneeded = false;
@ -408,12 +411,15 @@ void R_ExecuteSetViewSize (void)
viewheight = scaledviewheight << hires; // killough 11/98
viewwidth_nonwide = scaledviewwidth_nonwide << hires;
viewblocks = MIN(setblocks, 10) << hires;
centery = viewheight/2;
centerx = viewwidth/2;
centerxfrac = centerx<<FRACBITS;
centeryfrac = centery<<FRACBITS;
centerxfrac_nonwide = (viewwidth_nonwide/2)<<FRACBITS;
projection = centerxfrac_nonwide;
viewheightfrac = viewheight<<FRACBITS; // [FG] sprite clipping optimizations
R_InitBuffer(scaledviewwidth, scaledviewheight); // killough 11/98
@ -430,9 +436,14 @@ void R_ExecuteSetViewSize (void)
// planes
for (i=0 ; i<viewheight ; i++)
{ // killough 5/2/98: reformatted
fixed_t dy = abs(((i-viewheight/2)<<FRACBITS)+FRACUNIT/2);
yslope[i] = FixedDiv(viewwidth_nonwide*(FRACUNIT/2), dy);
for (j = 0; j < LOOKDIRS; j++)
{
// [crispy] re-generate lookup-table for yslope[] whenever "viewheight" or "hires" change
fixed_t dy = abs(((i-viewheight/2-(j-LOOKDIRMIN)*viewblocks/10)<<FRACBITS)+FRACUNIT/2);
yslopes[j][i] = FixedDiv(viewwidth_nonwide*(FRACUNIT/2), dy);
}
}
yslope = yslopes[LOOKDIRMIN];
for (i=0 ; i<viewwidth ; i++)
{
@ -537,6 +548,7 @@ angle_t R_InterpolateAngle(angle_t oangle, angle_t nangle, fixed_t scale)
void R_SetupFrame (player_t *player)
{
int i, cm;
int tempCentery, lookdir;
viewplayer = player;
// [AM] Interpolate the player camera if the feature is enabled.
@ -555,6 +567,7 @@ void R_SetupFrame (player_t *player)
viewy = player->mo->oldy + FixedMul(player->mo->y - player->mo->oldy, fractionaltic);
viewz = player->oldviewz + FixedMul(player->viewz - player->oldviewz, fractionaltic);
viewangle = R_InterpolateAngle(player->mo->oldangle, player->mo->angle, fractionaltic) + viewangleoffset;
lookdir = (player->oldlookdir + (player->lookdir - player->oldlookdir) * FIXED2DOUBLE(fractionaltic)) / MLOOKUNIT;
}
else
{
@ -562,9 +575,19 @@ void R_SetupFrame (player_t *player)
viewy = player->mo->y;
viewz = player->viewz; // [FG] moved here
viewangle = player->mo->angle + viewangleoffset;
lookdir = player->lookdir / MLOOKUNIT;
}
extralight = player->extralight;
// apply new yslope[] whenever "lookdir", "viewheight" or "hires" change
tempCentery = viewheight/2 + lookdir * viewblocks / 10;
if (centery != tempCentery)
{
centery = tempCentery;
centeryfrac = centery << FRACBITS;
yslope = yslopes[LOOKDIRMIN + lookdir];
}
viewsin = finesine[viewangle>>ANGLETOFINESHIFT];
viewcos = finecosine[viewangle>>ANGLETOFINESHIFT];

View File

@ -48,6 +48,7 @@ extern fixed_t projection;
extern int validcount;
extern int linecount;
extern int loopcount;
extern fixed_t viewheightfrac; // [FG] sprite clipping optimizations
//
// Rendering stats

View File

@ -94,7 +94,7 @@ static fixed_t cachedxstep[MAX_SCREENHEIGHT];
static fixed_t cachedystep[MAX_SCREENHEIGHT];
static fixed_t xoffs,yoffs; // killough 2/28/98: flat offsets
fixed_t yslope[MAX_SCREENHEIGHT], distscale[MAX_SCREENWIDTH];
fixed_t *yslope, yslopes[LOOKDIRS][MAX_SCREENHEIGHT], distscale[MAX_SCREENWIDTH];
//
// R_InitPlanes

View File

@ -38,7 +38,7 @@
extern int *lastopening; // [FG] 32-bit integer math
extern int floorclip[], ceilingclip[]; // [FG] 32-bit integer math
extern fixed_t yslope[], distscale[];
extern fixed_t *yslope, yslopes[LOOKDIRS][MAX_SCREENHEIGHT], distscale[];
void R_InitPlanes(void);
void R_ClearPlanes(void);

View File

@ -542,8 +542,8 @@ void R_ProjectSprite (mobj_t* thing)
gzt = interpz + spritetopoffset[lump];
// killough 4/9/98: clip things which are out of view due to height
if (interpz > viewz + FixedDiv(centeryfrac, xscale) ||
gzt < viewz - FixedDiv(centeryfrac-viewheight, xscale))
if (interpz > viewz + FixedDiv(viewheightfrac, xscale) ||
gzt < (int64_t)viewz - FixedDiv(viewheightfrac - viewheight, xscale))
return;
// killough 3/27/98: exclude things totally separated
@ -730,6 +730,9 @@ void R_DrawPSprite (pspdef_t *psp)
vis->startfrac = 0;
}
// [crispy] free look
vis->texturemid += (centery - viewheight/2) * pspriteiscale;
if (vis->x1 > x1)
vis->startfrac += vis->xiscale*(vis->x1-x1);