Merge pull request 'Spectator freecam' (#35) from freecamspectate into blankart-dev
Reviewed-on: https://codeberg.org/NepDisk/blankart/pulls/35
This commit is contained in:
commit
889170823d
24 changed files with 372 additions and 344 deletions
|
|
@ -469,6 +469,11 @@ void D_ResetTiccmds(void)
|
|||
D_Clearticcmd(textcmds[i]->tic);
|
||||
}
|
||||
|
||||
ticcmd_t *D_LocalTiccmd(UINT8 ss)
|
||||
{
|
||||
return &localcmds[ss][0];
|
||||
}
|
||||
|
||||
void SendKick(UINT8 playernum, UINT8 msg)
|
||||
{
|
||||
UINT8 buf[2];
|
||||
|
|
|
|||
|
|
@ -512,6 +512,7 @@ extern UINT8 playerconsole[MAXPLAYERS];
|
|||
INT32 D_NumPlayers(void);
|
||||
boolean D_IsPlayerHumanAndGaming(INT32 player_number);
|
||||
void D_ResetTiccmds(void);
|
||||
ticcmd_t *D_LocalTiccmd(UINT8 ss);
|
||||
|
||||
tic_t GetLag(INT32 node);
|
||||
UINT8 GetFreeXCmdSize(UINT8 playerid);
|
||||
|
|
|
|||
|
|
@ -367,7 +367,7 @@ static void D_RenderLevel(void)
|
|||
{
|
||||
R_ApplyViewMorph(i);
|
||||
|
||||
V_DoPostProcessor(i, &players[displayplayers[i]], postimgparam[i]);
|
||||
V_DoPostProcessor(i, postimgparam[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -907,11 +907,14 @@ void D_SRB2Loop(void)
|
|||
{
|
||||
rendertimefrac = FRACUNIT;
|
||||
}
|
||||
|
||||
rendertimefrac_unpaused = g_time.timefrac;
|
||||
}
|
||||
else
|
||||
{
|
||||
renderdeltatics = realtics * FRACUNIT;
|
||||
rendertimefrac = FRACUNIT;
|
||||
rendertimefrac_unpaused = FRACUNIT;
|
||||
}
|
||||
|
||||
if ((interp || doDisplay) && !frameskip)
|
||||
|
|
|
|||
|
|
@ -2255,7 +2255,7 @@ static void Command_View_f(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (demo.freecam)
|
||||
if (camera[viewnum-1].freecam)
|
||||
return;
|
||||
|
||||
displayplayerp = &displayplayers[viewnum-1];
|
||||
|
|
|
|||
|
|
@ -505,8 +505,6 @@ struct player_t
|
|||
// See pflags_t, above.
|
||||
pflags_t pflags;
|
||||
|
||||
UINT16 postimgflags;
|
||||
|
||||
// playing animation.
|
||||
panim_t panim;
|
||||
|
||||
|
|
|
|||
|
|
@ -340,15 +340,6 @@ union FColorRGBA
|
|||
} ATTRPACK;
|
||||
typedef union FColorRGBA RGBA_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
POSTIMG_WATER = 1, // Underwater screen effect.
|
||||
POSTIMG_MOTION = 1<<1, // Unused motion blur effect.
|
||||
POSTIMG_FLIP = 1<<2, // Flipcam screen effect.
|
||||
POSTIMG_HEAT = 1<<3, // Heatwave screen effect.
|
||||
POSTIMG_MIRROR = 1<<4, // encore screen effect.
|
||||
} postimgflag_t;
|
||||
|
||||
typedef UINT32 lumpnum_t; // 16 : 16 unsigned long (wad num: lump num)
|
||||
#define LUMPERROR UINT32_MAX
|
||||
|
||||
|
|
|
|||
18
src/g_demo.c
18
src/g_demo.c
|
|
@ -1709,9 +1709,6 @@ void G_ConfirmRewind(tic_t rewindtime)
|
|||
|
||||
COM_BufInsertText("renderview on\n");
|
||||
|
||||
if (demo.freecam)
|
||||
return; // don't touch from there
|
||||
|
||||
splitscreen = oldss;
|
||||
displayplayers[0] = olddp1;
|
||||
displayplayers[1] = olddp2;
|
||||
|
|
@ -3212,6 +3209,7 @@ void G_DoPlayDemo(char *defdemoname)
|
|||
consoleplayer = 0;
|
||||
memset(playeringame,0,sizeof(playeringame));
|
||||
memset(displayplayers,0,sizeof(displayplayers));
|
||||
memset(camera,0,sizeof(camera)); // reset freecam
|
||||
|
||||
// Load players that were in-game when the map started
|
||||
p = READUINT8(demobuf.p);
|
||||
|
|
@ -3990,13 +3988,13 @@ void G_StopDemo(void)
|
|||
demo.timing = false;
|
||||
singletics = false;
|
||||
|
||||
demo.freecam = false;
|
||||
// reset democam shit too:
|
||||
democam.cam = NULL;
|
||||
democam.soundmobj = NULL;
|
||||
democam.localangle = 0;
|
||||
democam.localaiming = 0;
|
||||
democam.keyboardlook = false;
|
||||
{
|
||||
UINT8 i;
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; ++i)
|
||||
{
|
||||
camera[i].freecam = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (gamestate == GS_INTERMISSION)
|
||||
Y_EndIntermission(); // cleanup
|
||||
|
|
|
|||
29
src/g_game.c
29
src/g_game.c
|
|
@ -965,8 +965,7 @@ static void G_DoAnglePrediction(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer, p
|
|||
|
||||
void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
||||
{
|
||||
const boolean fordemocam = ssplayer == UINT8_MAX;
|
||||
const UINT8 forplayer = fordemocam ? 0 : ssplayer-1;
|
||||
const UINT8 forplayer = ssplayer-1;
|
||||
|
||||
static INT32 turnheld[MAXSPLITSCREENPLAYERS]; // for accelerative turning
|
||||
static boolean resetdown[MAXSPLITSCREENPLAYERS]; // don't cam reset every frame
|
||||
|
|
@ -976,13 +975,10 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
joystickvector2_t joystickvector;
|
||||
|
||||
// you'd BETTER not touch the player while freecamming...
|
||||
player_t *player = fordemocam ? NULL : &players[g_localplayers[forplayer]];
|
||||
camera_t *thiscam = fordemocam ? democam.cam : &camera[forplayer];
|
||||
player_t *player = &players[g_localplayers[forplayer]];
|
||||
camera_t *thiscam = &camera[forplayer];
|
||||
boolean *rd = &resetdown[forplayer];
|
||||
boolean spectating = fordemocam || player->spectator;
|
||||
|
||||
if (!fordemocam && demo.playback) return;
|
||||
|
||||
boolean spectating = player->spectator || thiscam->freecam;
|
||||
// Is there any reason this can't just be I_BaseTiccmd?
|
||||
switch (ssplayer)
|
||||
{
|
||||
|
|
@ -1003,12 +999,12 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
|
||||
// why build a ticcmd if we're paused?
|
||||
// Or, for that matter, if we're being reborn.
|
||||
if (!fordemocam && (paused || P_AutoPause() || (gamestate == GS_LEVEL && player->playerstate == PST_REBORN)))
|
||||
if (!thiscam->freecam && (paused || P_AutoPause() || (gamestate == GS_LEVEL && player->playerstate == PST_REBORN)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!fordemocam && K_PlayerUsesBotMovement(player))
|
||||
if (K_PlayerUsesBotMovement(player))
|
||||
{
|
||||
// Bot ticcmd is generated by K_BuildBotTiccmd
|
||||
return;
|
||||
|
|
@ -1099,7 +1095,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
forward += (value * MAXPLMOVE) / JOYAXISRANGE;
|
||||
}
|
||||
|
||||
if (!fordemocam && player->sneakertimer)
|
||||
if (player->sneakertimer)
|
||||
forward = MAXPLMOVE; // 50
|
||||
|
||||
value = G_PlayerInputAnalog(forplayer, gc_brake, false);
|
||||
|
|
@ -1144,7 +1140,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
cmd->buttons |= BT_CUSTOM3;
|
||||
|
||||
// Reset camera
|
||||
if (!fordemocam && G_PlayerInputDown(forplayer, gc_camreset, false))
|
||||
if (G_PlayerInputDown(forplayer, gc_camreset, false))
|
||||
{
|
||||
if (thiscam->chase && *rd == false)
|
||||
P_ResetCamera(player, thiscam);
|
||||
|
|
@ -1156,7 +1152,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
// spectator aiming shit, ahhhh...
|
||||
{
|
||||
INT32 screen_invert =
|
||||
(!fordemocam && player->mo && (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
(player->mo && (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
&& (!thiscam->chase)) //because chasecam's not inverted
|
||||
? -1 : 1; // set to -1 or 1 to multiply
|
||||
|
||||
|
|
@ -1197,7 +1193,7 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
-Making some galaxy brain autopilot Lua if you're a masochist
|
||||
-Making a Mario Kart 8 Deluxe tier baby mode that steers you away from walls and whatnot. You know what, do what you want!
|
||||
*/
|
||||
if (!fordemocam && addedtogame && gamestate == GS_LEVEL)
|
||||
if (addedtogame && gamestate == GS_LEVEL)
|
||||
{
|
||||
LUA_HookTiccmd(player, cmd, HOOK(PlayerCmd));
|
||||
|
||||
|
|
@ -1226,9 +1222,6 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer)
|
|||
else if (cmd->throwdir < -KART_FULLTURN)
|
||||
cmd->throwdir = -KART_FULLTURN;
|
||||
|
||||
if (fordemocam)
|
||||
return;
|
||||
|
||||
G_DoAnglePrediction(cmd, realtics, ssplayer, player);
|
||||
|
||||
// Reset away view if a command is given.
|
||||
|
|
@ -1588,7 +1581,7 @@ boolean G_Responder(event_t *ev)
|
|||
}
|
||||
}
|
||||
|
||||
if (gamestate == GS_LEVEL && ev->type == ev_keydown && multiplayer && demo.playback && !demo.freecam)
|
||||
if (gamestate == GS_LEVEL && ev->type == ev_keydown && multiplayer && demo.playback)
|
||||
{
|
||||
if (G_ControlBoundToKey(1, gc_viewpoint, ev->data1, false))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -5657,6 +5657,8 @@ void HWR_BuildSkyDome(void)
|
|||
|
||||
static void HWR_DrawSkyBackground(player_t *player)
|
||||
{
|
||||
UINT8 viewnum = R_GetViewNumber();
|
||||
camera_t *thiscam = &camera[viewnum];
|
||||
HWD.pfnSetBlend(PF_Translucent|PF_NoDepthTest|PF_Modulated);
|
||||
|
||||
if (cv_glskydome.value)
|
||||
|
|
@ -5672,15 +5674,15 @@ static void HWR_DrawSkyBackground(player_t *player)
|
|||
dometransform.angley = (float)((viewangle-ANGLE_270)>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES);
|
||||
|
||||
dometransform.flip = false;
|
||||
if ((player->postimgflags & POSTIMG_FLIP) && !(player->postimgflags & POSTIMG_MIRROR))
|
||||
if ((thiscam->postimgflags & POSTIMG_FLIP) && !(thiscam->postimgflags & POSTIMG_MIRROR))
|
||||
dometransform.flip = true;
|
||||
|
||||
dometransform.mirror = false;
|
||||
if ((player->postimgflags & POSTIMG_MIRROR) && !(player->postimgflags & POSTIMG_FLIP))
|
||||
if ((thiscam->postimgflags & POSTIMG_MIRROR) && !(thiscam->postimgflags & POSTIMG_FLIP))
|
||||
dometransform.mirror = true;
|
||||
|
||||
dometransform.mirrorflip = false;
|
||||
if ((player->postimgflags & POSTIMG_FLIP) && (player->postimgflags & POSTIMG_MIRROR))
|
||||
if ((thiscam->postimgflags & POSTIMG_FLIP) && (thiscam->postimgflags & POSTIMG_MIRROR))
|
||||
dometransform.mirrorflip = true;
|
||||
|
||||
dometransform.scalex = 1;
|
||||
|
|
@ -5926,6 +5928,8 @@ static void HWR_ClearClipper(void)
|
|||
// ==========================================================================
|
||||
void HWR_RenderSkyboxView(player_t *player)
|
||||
{
|
||||
UINT8 viewnum = R_GetViewNumber();
|
||||
camera_t *thiscam = &camera[viewnum];
|
||||
const float fpov = FIXED_TO_FLOAT(cv_fov[viewssnum].value+player->fovadd);
|
||||
|
||||
{
|
||||
|
|
@ -5968,15 +5972,15 @@ void HWR_RenderSkyboxView(player_t *player)
|
|||
gl_viewludcos = FIXED_TO_FLOAT(-FINESINE(gl_aimingangle>>ANGLETOFINESHIFT));
|
||||
|
||||
atransform.flip = false;
|
||||
if ((player->postimgflags & POSTIMG_FLIP) && !(player->postimgflags & POSTIMG_MIRROR))
|
||||
if ((thiscam->postimgflags & POSTIMG_FLIP) && !(thiscam->postimgflags & POSTIMG_MIRROR))
|
||||
atransform.flip = true;
|
||||
|
||||
atransform.mirror = false;
|
||||
if ((player->postimgflags & POSTIMG_MIRROR) && !(player->postimgflags & POSTIMG_FLIP))
|
||||
if ((thiscam->postimgflags & POSTIMG_MIRROR) && !(thiscam->postimgflags & POSTIMG_FLIP))
|
||||
atransform.mirror = true;
|
||||
|
||||
atransform.mirrorflip = false;
|
||||
if ((player->postimgflags & POSTIMG_FLIP) && (player->postimgflags & POSTIMG_MIRROR))
|
||||
if ((thiscam->postimgflags & POSTIMG_FLIP) && (thiscam->postimgflags & POSTIMG_MIRROR))
|
||||
atransform.mirrorflip = true;
|
||||
|
||||
atransform.x = gl_viewx; // FIXED_TO_FLOAT(viewx)
|
||||
|
|
@ -6075,6 +6079,8 @@ static void HWR_RollTransform(FTransform *tr, angle_t roll)
|
|||
void HWR_RenderPlayerView(void)
|
||||
{
|
||||
player_t * player = &players[displayplayers[viewssnum]];
|
||||
UINT8 viewnum = R_GetViewNumber();
|
||||
camera_t *thiscam = &camera[viewnum];
|
||||
|
||||
const float fpov = FIXED_TO_FLOAT(cv_fov[viewssnum].value+player->fovadd);
|
||||
|
||||
|
|
@ -6153,15 +6159,15 @@ void HWR_RenderPlayerView(void)
|
|||
gl_viewludcos = FIXED_TO_FLOAT(-FINESINE(gl_aimingangle>>ANGLETOFINESHIFT));
|
||||
|
||||
atransform.flip = false;
|
||||
if ((player->postimgflags & POSTIMG_FLIP) && !(player->postimgflags & POSTIMG_MIRROR))
|
||||
if ((thiscam->postimgflags & POSTIMG_FLIP) && !(thiscam->postimgflags & POSTIMG_MIRROR))
|
||||
atransform.flip = true;
|
||||
|
||||
atransform.mirror = false;
|
||||
if ((player->postimgflags & POSTIMG_MIRROR) && !(player->postimgflags & POSTIMG_FLIP))
|
||||
if ((thiscam->postimgflags & POSTIMG_MIRROR) && !(thiscam->postimgflags & POSTIMG_FLIP))
|
||||
atransform.mirror = true;
|
||||
|
||||
atransform.mirrorflip = false;
|
||||
if ((player->postimgflags & POSTIMG_FLIP) && (player->postimgflags & POSTIMG_MIRROR))
|
||||
if ((thiscam->postimgflags & POSTIMG_FLIP) && (thiscam->postimgflags & POSTIMG_MIRROR))
|
||||
atransform.mirrorflip = true;
|
||||
|
||||
atransform.x = gl_viewx; // FIXED_TO_FLOAT(viewx)
|
||||
|
|
@ -6562,8 +6568,12 @@ void HWR_DoPostProcessor(player_t *player)
|
|||
if (r_splitscreen) // Not supported in splitscreen - someone want to add support?
|
||||
return;
|
||||
|
||||
//UINT8 viewnum = R_GetViewNumber(); // see above
|
||||
//camera_t *thiscam = &camera[viewnum];
|
||||
camera_t *thiscam = &camera[0];
|
||||
|
||||
// Drunken vision! WooOOooo~
|
||||
if (player->postimgflags & POSTIMG_WATER || player->postimgflags & POSTIMG_HEAT)
|
||||
if (thiscam->postimgflags & POSTIMG_WATER || thiscam->postimgflags & POSTIMG_HEAT)
|
||||
{
|
||||
// 10 by 10 grid. 2 coordinates (xy)
|
||||
float v[SCREENVERTS][SCREENVERTS][2];
|
||||
|
|
@ -6575,7 +6585,7 @@ void HWR_DoPostProcessor(player_t *player)
|
|||
INT32 FREQUENCY;
|
||||
|
||||
// Modifies the wave.
|
||||
if (player->postimgflags & POSTIMG_WATER)
|
||||
if (thiscam->postimgflags & POSTIMG_WATER)
|
||||
{
|
||||
WAVELENGTH = 5;
|
||||
AMPLITUDE = 40;
|
||||
|
|
|
|||
|
|
@ -2617,7 +2617,7 @@ static boolean K_ShowPlayerNametag(player_t *p)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (demo.playback == true && demo.freecam == true)
|
||||
if (demo.playback == true && camera[R_GetViewNumber()].freecam == true)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
@ -3046,7 +3046,7 @@ static void K_drawKartNameTags(void)
|
|||
|
||||
if (result.onScreen == true)
|
||||
{
|
||||
if (!(demo.playback == true && demo.freecam == true))
|
||||
if (!(demo.playback == true && camera[cnum].freecam == true))
|
||||
{
|
||||
for (j = 0; j <= r_splitscreen; j++)
|
||||
{
|
||||
|
|
@ -4493,7 +4493,8 @@ void K_drawKartHUD(void)
|
|||
{
|
||||
boolean islonesome = false;
|
||||
boolean battlefullscreen = false;
|
||||
boolean freecam = demo.freecam; //disable some hud elements w/ freecam
|
||||
UINT8 viewnum = R_GetViewNumber();
|
||||
boolean freecam = camera[viewnum].freecam; //disable some hud elements w/ freecam
|
||||
UINT8 i;
|
||||
|
||||
// Define the X and Y for each drawn object
|
||||
|
|
@ -4568,7 +4569,7 @@ void K_drawKartHUD(void)
|
|||
islonesome = K_drawKartPositionFaces();
|
||||
}
|
||||
|
||||
if (!stplyr->spectator && !demo.freecam) // Bottom of the screen elements, don't need in spectate mode
|
||||
if (!stplyr->spectator && !freecam) // Bottom of the screen elements, don't need in spectate mode
|
||||
{
|
||||
if (demo.title) // Draw title logo instead in demo.titles
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1457,7 +1457,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
|
|||
dontforcespb = true;
|
||||
|
||||
// This makes the roulette produce the random noises.
|
||||
if ((player->itemroulette % 3) == 1 && P_IsDisplayPlayer(player) && !demo.freecam)
|
||||
if ((player->itemroulette % 3) == 1 && P_IsDisplayPlayer(player))
|
||||
{
|
||||
#define PLAYROULETTESND S_StartSound(NULL, sfx_itrol1 + ((player->itemroulette / 3) % 8))
|
||||
for (i = 0; i <= r_splitscreen; i++)
|
||||
|
|
@ -1535,7 +1535,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
|
|||
//player->itemblinkmode = 1;
|
||||
player->itemroulette = 0;
|
||||
player->roulettetype = 0;
|
||||
if (P_IsDisplayPlayer(player) && !demo.freecam)
|
||||
if (P_IsDisplayPlayer(player))
|
||||
S_StartSound(NULL, sfx_itrole);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1550,7 +1550,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
|
|||
player->itemblinkmode = 2;
|
||||
player->itemroulette = 0;
|
||||
player->roulettetype = 0;
|
||||
if (P_IsDisplayPlayer(player) && !demo.freecam)
|
||||
if (P_IsDisplayPlayer(player))
|
||||
S_StartSound(NULL, sfx_dbgsal);
|
||||
return;
|
||||
}
|
||||
|
|
@ -1712,7 +1712,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
|
|||
player->itemamount = 1;
|
||||
}
|
||||
|
||||
if (P_IsDisplayPlayer(player) && !demo.freecam)
|
||||
if (P_IsDisplayPlayer(player))
|
||||
S_StartSound(NULL, ((player->roulettetype == 1) ? sfx_itrolk : (mashed ? sfx_itrolm : sfx_itrolf)));
|
||||
|
||||
player->itemblink = TICRATE;
|
||||
|
|
|
|||
15
src/m_menu.c
15
src/m_menu.c
|
|
@ -4219,22 +4219,13 @@ void M_PlaybackToggleFreecam(INT32 choice)
|
|||
splitscreen = 0;
|
||||
R_ExecuteSetViewSize();
|
||||
|
||||
P_InitCameraCmd(); // init camera controls
|
||||
if (!demo.freecam) // toggle on
|
||||
UINT8 i;
|
||||
for (i = 0; i <= r_splitscreen; ++i)
|
||||
{
|
||||
demo.freecam = true;
|
||||
democam.cam = &camera[0]; // this is rather useful
|
||||
}
|
||||
else // toggle off
|
||||
{
|
||||
demo.freecam = false;
|
||||
// reset democam vars:
|
||||
democam.cam = NULL;
|
||||
democam.keyboardlook = false; // reset only these. localangle / aiming gets set before the cam does anything anyway
|
||||
P_ToggleDemoCamera(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void M_PlaybackQuit(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
|
|
|
|||
|
|
@ -95,6 +95,8 @@ void P_UnlinkThinker(thinker_t *thinker);
|
|||
struct camera_t
|
||||
{
|
||||
boolean chase;
|
||||
boolean freecam;
|
||||
|
||||
angle_t aiming;
|
||||
|
||||
// Things used by FS cameras.
|
||||
|
|
@ -128,25 +130,29 @@ struct camera_t
|
|||
// SRB2Kart: camera pitches on slopes
|
||||
angle_t pitch;
|
||||
|
||||
// Freecam: A button was held since entering from menu, so don't move camera
|
||||
UINT8 button_a_held;
|
||||
|
||||
boolean reset_aiming; // camera aiming needs to be reset from chase camera
|
||||
|
||||
// Interpolation data
|
||||
fixed_t old_x, old_y, old_z;
|
||||
angle_t old_angle, old_aiming;
|
||||
|
||||
// postproccess effects
|
||||
UINT8 postimgflags;
|
||||
};
|
||||
|
||||
// demo freecam or something before i commit die
|
||||
struct demofreecam_s {
|
||||
|
||||
camera_t *cam; // this is useful when the game is paused, notably
|
||||
mobj_t *soundmobj; // mobj to play sound from, used in s_sound
|
||||
|
||||
angle_t localangle; // keeps track of the cam angle for cmds
|
||||
angle_t localaiming; // ditto with aiming
|
||||
boolean turnheld; // holding turn button for gradual turn speed
|
||||
boolean keyboardlook; // keyboard look
|
||||
// post process types
|
||||
enum
|
||||
{
|
||||
POSTIMG_WATER = 1, // Underwater screen effect.
|
||||
POSTIMG_MOTION = 1<<1, // Unused motion blur effect.
|
||||
POSTIMG_FLIP = 1<<2, // Flipcam screen effect.
|
||||
POSTIMG_HEAT = 1<<3, // Heatwave screen effect.
|
||||
POSTIMG_MIRROR = 1<<4, // encore screen effect.
|
||||
};
|
||||
|
||||
extern struct demofreecam_s democam;
|
||||
|
||||
extern camera_t camera[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_cam_dist[MAXSPLITSCREENPLAYERS], cv_cam_still[MAXSPLITSCREENPLAYERS], cv_cam_height[MAXSPLITSCREENPLAYERS];
|
||||
extern consvar_t cv_cam_speed[MAXSPLITSCREENPLAYERS], cv_cam_rotate[MAXSPLITSCREENPLAYERS];
|
||||
|
|
@ -161,9 +167,10 @@ void P_AddPlayerScore(player_t *player, UINT32 amount);
|
|||
void P_ResetCamera(player_t *player, camera_t *thiscam);
|
||||
boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam);
|
||||
void P_SlideCameraMove(camera_t *thiscam);
|
||||
void P_DemoCameraMovement(camera_t *cam);
|
||||
void P_DemoCameraMovement(camera_t *cam, UINT8 num);
|
||||
void P_ToggleDemoCamera(UINT8 viewnum);
|
||||
boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcalled);
|
||||
void P_InitCameraCmd(void);
|
||||
void P_CalcChasePostImg(player_t *player, camera_t *thiscam);
|
||||
|
||||
boolean P_CanPlayerTurn(player_t *player, ticcmd_t *cmd);
|
||||
|
||||
|
|
|
|||
48
src/p_mobj.c
48
src/p_mobj.c
|
|
@ -3546,18 +3546,25 @@ void P_DestroyRobots(void)
|
|||
// the below is chasecam only, if you're curious. check out P_CalcPostImg in p_user.c for first person
|
||||
void P_CalcChasePostImg(player_t *player, camera_t *thiscam)
|
||||
{
|
||||
boolean flipcam = (player->pflags & PF_FLIPCAM && player->mo->eflags & MFE_VERTICALFLIP);
|
||||
UINT16 postimgflags = 0;
|
||||
UINT8 i;
|
||||
const boolean flipcam = (player->pflags & PF_FLIPCAM && player->mo->eflags & MFE_VERTICALFLIP);
|
||||
UINT8 postimgtype = 0;
|
||||
|
||||
// This can happen when joining
|
||||
if (thiscam->subsector == NULL || thiscam->subsector->sector == NULL)
|
||||
return;
|
||||
|
||||
if (encoremode)
|
||||
postimgflags |= POSTIMG_MIRROR;
|
||||
postimgtype |= POSTIMG_MIRROR;
|
||||
if (flipcam)
|
||||
postimgflags |= POSTIMG_FLIP;
|
||||
postimgtype |= POSTIMG_FLIP;
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl && splitscreen)
|
||||
{
|
||||
thiscam->postimgflags = postimgtype;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (player->awayviewtics && player->awayviewmobj && !P_MobjWasRemoved(player->awayviewmobj)) // Camera must obviously exist
|
||||
{
|
||||
|
|
@ -3572,26 +3579,20 @@ void P_CalcChasePostImg(player_t *player, camera_t *thiscam)
|
|||
|
||||
// Are we in water?
|
||||
if (P_CameraCheckWater(&dummycam))
|
||||
postimgflags |= POSTIMG_WATER;
|
||||
if (P_CameraCheckHeat(&dummycam))
|
||||
postimgflags |= POSTIMG_HEAT;
|
||||
postimgtype |= POSTIMG_WATER;
|
||||
else if (P_CameraCheckHeat(&dummycam))
|
||||
postimgtype |= POSTIMG_HEAT;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Are we in water?
|
||||
if (P_CameraCheckWater(thiscam))
|
||||
postimgflags |= POSTIMG_WATER;
|
||||
if (P_CameraCheckHeat(thiscam))
|
||||
postimgflags |= POSTIMG_HEAT;
|
||||
postimgtype |= POSTIMG_WATER;
|
||||
else if (P_CameraCheckHeat(thiscam))
|
||||
postimgtype |= POSTIMG_HEAT;
|
||||
}
|
||||
|
||||
for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (player != &players[displayplayers[i]])
|
||||
continue;
|
||||
|
||||
players[displayplayers[i]].postimgflags = postimgflags;
|
||||
}
|
||||
thiscam->postimgflags = postimgtype;
|
||||
}
|
||||
|
||||
// P_CameraThinker
|
||||
|
|
@ -10648,12 +10649,15 @@ void P_AfterPlayerSpawn(INT32 playernum)
|
|||
|
||||
p->drawangle = mobj->angle;
|
||||
|
||||
for (i = 0; i <= r_splitscreen; i++)
|
||||
if (p->spectator == false)
|
||||
{
|
||||
if (camera[i].chase)
|
||||
for (i = 0; i <= r_splitscreen; i++)
|
||||
{
|
||||
if (displayplayers[i] == playernum)
|
||||
P_ResetCamera(p, &camera[i]);
|
||||
if (camera[i].chase)
|
||||
{
|
||||
if (displayplayers[i] == playernum)
|
||||
P_ResetCamera(p, &camera[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8179,6 +8179,8 @@ static void P_SetupCamera(UINT8 pnum, camera_t *cam)
|
|||
cam->subsector = R_PointInSubsectorFast(cam->x, cam->y); // make sure camera has a subsector set -- Monster Iestyn (12/11/18)
|
||||
}
|
||||
}
|
||||
|
||||
cam->chase = false; // tell camera to reset its position next tic
|
||||
}
|
||||
|
||||
static void P_InitCamera(void)
|
||||
|
|
|
|||
|
|
@ -690,9 +690,8 @@ void P_Ticker(boolean run)
|
|||
timeinmap = (timeinmap-1) & ~3;
|
||||
G_PreviewRewind(leveltime);
|
||||
}
|
||||
else if (demo.freecam && democam.cam) // special case: allow freecam to MOVE during pause!
|
||||
P_DemoCameraMovement(democam.cam);
|
||||
S_SetStackAdjustmentStart();
|
||||
else
|
||||
P_RunChaseCameras(); // special case: allow freecam to MOVE during pause!
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
|||
376
src/p_user.c
376
src/p_user.c
|
|
@ -1139,6 +1139,15 @@ boolean P_IsDisplayPlayer(player_t *player)
|
|||
|
||||
for (i = 0; i <= r_splitscreen; i++) // DON'T skip P1
|
||||
{
|
||||
if (camera[i].freecam)
|
||||
{
|
||||
// Freecam still techically has a player in
|
||||
// displayplayers. But since the camera is
|
||||
// detached, it would be weird if sounds were
|
||||
// heard from that player's perspective.
|
||||
continue;
|
||||
}
|
||||
|
||||
if (player == &players[displayplayers[i]])
|
||||
return true;
|
||||
}
|
||||
|
|
@ -2068,42 +2077,6 @@ static void P_UpdateBotAngle(player_t* player)
|
|||
player->mo->angle = player->angleturn;
|
||||
}
|
||||
|
||||
//
|
||||
// P_SpectatorMovement
|
||||
//
|
||||
// Control for spectators in multiplayer
|
||||
//
|
||||
static void P_SpectatorMovement(player_t *player)
|
||||
{
|
||||
ticcmd_t *cmd = &player->cmd;
|
||||
|
||||
player->mo->angle = cmd->angle<<16;
|
||||
P_UpdatePlayerAiming(player);
|
||||
|
||||
ticruned++;
|
||||
if (!(cmd->flags & TICCMD_RECEIVED))
|
||||
ticmiss++;
|
||||
|
||||
if (cmd->buttons & BT_ACCELERATE)
|
||||
player->mo->z += 32*mapobjectscale;
|
||||
else if (cmd->buttons & BT_BRAKE)
|
||||
player->mo->z -= 32*mapobjectscale;
|
||||
|
||||
if (player->mo->z > player->mo->ceilingz - player->mo->height)
|
||||
player->mo->z = player->mo->ceilingz - player->mo->height;
|
||||
if (player->mo->z < player->mo->floorz)
|
||||
player->mo->z = player->mo->floorz;
|
||||
|
||||
player->mo->momx = player->mo->momy = player->mo->momz = 0;
|
||||
if (cmd->forwardmove != 0)
|
||||
{
|
||||
P_Thrust(player->mo, player->mo->angle, cmd->forwardmove*mapobjectscale);
|
||||
|
||||
// Quake-style flying spectators :D
|
||||
player->mo->momz += FixedMul(cmd->forwardmove*mapobjectscale, AIMINGTOSLOPE(player->aiming));
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// P_MovePlayer
|
||||
void P_MovePlayer(player_t *player)
|
||||
|
|
@ -2130,7 +2103,6 @@ void P_MovePlayer(player_t *player)
|
|||
if (player->spectator)
|
||||
{
|
||||
player->mo->eflags &= ~MFE_VERTICALFLIP; // deflip...
|
||||
P_SpectatorMovement(player);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -2671,54 +2643,85 @@ fixed_t t_cam_dist[MAXSPLITSCREENPLAYERS] = {-42,-42,-42,-42};
|
|||
fixed_t t_cam_height[MAXSPLITSCREENPLAYERS] = {-42,-42,-42,-42};
|
||||
fixed_t t_cam_rotate[MAXSPLITSCREENPLAYERS] = {-42,-42,-42,-42};
|
||||
|
||||
static ticcmd_t cameracmd;
|
||||
|
||||
struct demofreecam_s democam;
|
||||
|
||||
// called by m_menu to reinit cam input every time it's toggled
|
||||
void P_InitCameraCmd(void)
|
||||
void P_DemoCameraMovement(camera_t *cam, UINT8 num)
|
||||
{
|
||||
memset(&cameracmd, 0, sizeof(ticcmd_t)); // initialize cmd
|
||||
}
|
||||
|
||||
void P_DemoCameraMovement(camera_t *cam)
|
||||
{
|
||||
ticcmd_t *cmd = &cameracmd;;
|
||||
ticcmd_t *cmd;
|
||||
angle_t thrustangle;
|
||||
mobj_t *awayviewmobj_hack;
|
||||
player_t *lastp;
|
||||
|
||||
// update democam stuff with what we got here:
|
||||
democam.cam = cam;
|
||||
democam.localangle = cam->angle;
|
||||
democam.localaiming = cam->aiming;
|
||||
boolean moving = false;
|
||||
|
||||
// first off we need to get button input
|
||||
G_BuildTiccmd(cmd, 1, UINT8_MAX);
|
||||
cmd = D_LocalTiccmd(num);
|
||||
|
||||
if (cmd->aiming != 0)
|
||||
{
|
||||
cam->aiming += cmd->aiming << TICCMD_REDUCE;
|
||||
|
||||
cam->reset_aiming = false;
|
||||
}
|
||||
|
||||
cam->aiming += cmd->aiming << TICCMD_REDUCE;
|
||||
cam->angle += cmd->turning << TICCMD_REDUCE;
|
||||
|
||||
democam.localangle += cmd->turning << TICCMD_REDUCE;
|
||||
democam.localaiming += cmd->aiming << TICCMD_REDUCE;
|
||||
|
||||
cam->aiming = G_ClipAimingPitch((INT32 *)&cam->aiming);
|
||||
democam.localaiming = G_ClipAimingPitch((INT32 *)&democam.localaiming);
|
||||
|
||||
// camera movement:
|
||||
if (cmd->buttons & BT_ACCELERATE)
|
||||
cam->z += 32*mapobjectscale;
|
||||
else if (cmd->buttons & BT_BRAKE)
|
||||
cam->z -= 32*mapobjectscale;
|
||||
if (!cam->button_a_held)
|
||||
{
|
||||
if (cmd->buttons & BT_ACCELERATE)
|
||||
{
|
||||
cam->z += 32*mapobjectscale;
|
||||
moving = true;
|
||||
}
|
||||
else if (cmd->buttons & BT_BRAKE)
|
||||
{
|
||||
cam->z -= 32*mapobjectscale;
|
||||
moving = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!(cmd->buttons & (BT_ACCELERATE | BT_DRIFT)) && cam->button_a_held)
|
||||
{
|
||||
cam->button_a_held--;
|
||||
}
|
||||
|
||||
// if you hold item, you will lock on to displayplayer. (The last player you were ""f12-ing"")
|
||||
if (cmd->buttons & BT_ATTACK)
|
||||
if (cam->freecam && cmd->buttons & BT_ATTACK)
|
||||
{
|
||||
lastp = &players[displayplayers[0]]; // Fun fact, I was trying displayplayers[0]->mo as if it was Lua like an absolute idiot.
|
||||
cam->angle = R_PointToAngle2(cam->x, cam->y, lastp->mo->x, lastp->mo->y);
|
||||
cam->aiming = R_PointToAngle2(0, cam->z, R_PointToDist2(cam->x, cam->y, lastp->mo->x, lastp->mo->y), lastp->mo->z + lastp->mo->scale*128*P_MobjFlip(lastp->mo)); // This is still unholy. Aim a bit above their heads.
|
||||
|
||||
cam->reset_aiming = false;
|
||||
}
|
||||
|
||||
if (cmd->forwardmove != 0)
|
||||
{
|
||||
moving = true;
|
||||
}
|
||||
|
||||
// After switching to democam, the vertical angle of
|
||||
// chasecam is inherited. This is intentional because it
|
||||
// creates a smooth transition. However, moving
|
||||
// forward/back will have a slope. So, as long as democam
|
||||
// controls haven't been used to alter the vertical angle,
|
||||
// slowly reset it to flat.
|
||||
if ((cam->reset_aiming && moving) || ((cmd->buttons & BT_DRIFT) && !cam->button_a_held))
|
||||
{
|
||||
INT32 aiming = cam->aiming;
|
||||
INT32 smooth = FixedMul(ANGLE_11hh / 4, FCOS(cam->aiming));
|
||||
|
||||
if (abs(smooth) < abs(aiming))
|
||||
{
|
||||
cam->aiming -= smooth * intsign(aiming);
|
||||
}
|
||||
else
|
||||
{
|
||||
cam->aiming = 0;
|
||||
cam->reset_aiming = false; // completely smoothed out
|
||||
}
|
||||
}
|
||||
|
||||
G_FinalClipAimingPitch((INT32 *)&cam->aiming, NULL, false);
|
||||
|
||||
cam->momx = cam->momy = cam->momz = 0;
|
||||
|
||||
if (cmd->forwardmove != 0)
|
||||
|
|
@ -2727,31 +2730,43 @@ void P_DemoCameraMovement(camera_t *cam)
|
|||
|
||||
cam->x += FixedMul(cmd->forwardmove*mapobjectscale, FINECOSINE(thrustangle));
|
||||
cam->y += FixedMul(cmd->forwardmove*mapobjectscale, FINESINE(thrustangle));
|
||||
cam->z += FixedMul(cmd->forwardmove*mapobjectscale, AIMINGTOSLOPE(cam->aiming));
|
||||
|
||||
if (!cam->reset_aiming)
|
||||
{
|
||||
cam->z += FixedMul(cmd->forwardmove*mapobjectscale, AIMINGTOSLOPE(cam->aiming));
|
||||
}
|
||||
// momentums are useless here, directly add to the coordinates
|
||||
|
||||
// this.......... doesn't actually check for floors and walls and whatnot but the function to do that is a pure mess so fuck that.
|
||||
// besides freecam going inside walls sounds pretty cool on paper.
|
||||
}
|
||||
|
||||
// awayviewmobj hack; this is to prevent us from hearing sounds from the player's perspective
|
||||
|
||||
awayviewmobj_hack = P_SpawnMobj(cam->x, cam->y, cam->z, MT_THOK);
|
||||
awayviewmobj_hack->tics = 2;
|
||||
awayviewmobj_hack->renderflags |= RF_DONTDRAW;
|
||||
|
||||
democam.soundmobj = awayviewmobj_hack;
|
||||
|
||||
// update subsector to avoid crashes;
|
||||
cam->subsector = R_PointInSubsectorFast(cam->x, cam->y);
|
||||
}
|
||||
|
||||
void P_ToggleDemoCamera(UINT8 viewnum)
|
||||
{
|
||||
camera_t *cam = &camera[viewnum];
|
||||
|
||||
if (!cam->freecam) // toggle on
|
||||
{
|
||||
cam->freecam = true;
|
||||
cam->button_a_held = 2;
|
||||
cam->reset_aiming = true;
|
||||
}
|
||||
else // toggle off
|
||||
{
|
||||
cam->freecam = false;
|
||||
}
|
||||
}
|
||||
|
||||
void P_ResetCamera(player_t *player, camera_t *thiscam)
|
||||
{
|
||||
tic_t tries = 0;
|
||||
fixed_t x, y, z;
|
||||
|
||||
if (demo.freecam)
|
||||
if (thiscam->freecam)
|
||||
return; // do not reset the camera there.
|
||||
|
||||
if (!player->mo)
|
||||
|
|
@ -2812,8 +2827,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
thiscam->old_angle = thiscam->angle;
|
||||
thiscam->old_aiming = thiscam->aiming;
|
||||
|
||||
democam.soundmobj = NULL; // reset this each frame, we don't want the game crashing for stupid reasons now do we
|
||||
|
||||
// We probably shouldn't move the camera if there is no player or player mobj somehow
|
||||
if (!player || !player->mo)
|
||||
return true;
|
||||
|
|
@ -2822,12 +2835,6 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
if (thiscam->subsector == NULL || thiscam->subsector->sector == NULL)
|
||||
return true;
|
||||
|
||||
if (demo.freecam)
|
||||
{
|
||||
P_DemoCameraMovement(thiscam);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (thiscam == &camera[1]) // Camera 2
|
||||
{
|
||||
num = 1;
|
||||
|
|
@ -2845,6 +2852,17 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
|
|||
num = 0;
|
||||
}
|
||||
|
||||
if (thiscam->freecam || player->spectator)
|
||||
{
|
||||
UINT8 camnum = G_PartyPosition(g_localplayers[num]);
|
||||
P_DemoCameraMovement(thiscam, camnum);
|
||||
P_CalcChasePostImg(player, thiscam);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (paused || P_AutoPause())
|
||||
return true;
|
||||
|
||||
mo = player->mo;
|
||||
|
||||
if (player->playerstate == PST_DEAD)
|
||||
|
|
@ -3346,14 +3364,94 @@ boolean P_SpectatorJoinGame(player_t *player)
|
|||
return true; // no more player->mo, cannot continue.
|
||||
}
|
||||
|
||||
// the below is first person only, if you're curious. check out P_CalcChasePostImg in p_mobj.c for chasecam
|
||||
static void P_CalcPostImg(player_t *player)
|
||||
static boolean P_CameraCheckHeatFirstperson(player_t *player, sector_t *sector, fixed_t pviewheight)
|
||||
{
|
||||
sector_t *sector = player->mo->subsector->sector;
|
||||
INT16 typeflag = 0;
|
||||
mtag_t sectag = Tag_FGet(§or->tags);
|
||||
|
||||
if (Tag_FindLineSpecial(13, sectag))
|
||||
return true;
|
||||
|
||||
if (sector->ffloors)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
|
||||
for (rover = sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (!(rover->fofflags & FOF_EXISTS))
|
||||
continue;
|
||||
|
||||
if (pviewheight >= P_GetFFloorTopZAt(rover, player->mo->x, player->mo->y))
|
||||
continue;
|
||||
|
||||
if (pviewheight <= P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y))
|
||||
continue;
|
||||
|
||||
sectag = Tag_FGet(&rover->master->frontsector->tags);
|
||||
|
||||
if (Tag_FindLineSpecial(13, sectag))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static boolean P_CameraCheckWaterFirstperson(player_t *player, sector_t *sector, fixed_t pviewheight)
|
||||
{
|
||||
if (sector->ffloors)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
|
||||
for (rover = sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_SWIMMABLE) || rover->fofflags & FOF_BLOCKPLAYER)
|
||||
continue;
|
||||
|
||||
if (pviewheight >= P_GetFFloorTopZAt(rover, player->mo->x, player->mo->y))
|
||||
continue;
|
||||
|
||||
if (pviewheight <= P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y))
|
||||
continue;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// the below is first person only, if you're curious. check out P_CalcChasePostImg in p_mobj.c for chasecam
|
||||
static void P_CalcPostImg(player_t *player, camera_t *thiscam)
|
||||
{
|
||||
sector_t *sector = NULL;
|
||||
UINT8 postimgtype = 0;
|
||||
//INT32 *param;
|
||||
fixed_t pviewheight;
|
||||
size_t i;
|
||||
fixed_t pviewheight = 0;
|
||||
|
||||
/*for (i = 0; i <= splitscreen; i++)
|
||||
{
|
||||
if (player == &players[displayplayers[i]])
|
||||
{
|
||||
param = &postimgparam[i];
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
|
||||
if (encoremode) // srb2kart
|
||||
postimgtype |= POSTIMG_MIRROR;
|
||||
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
postimgtype |= POSTIMG_FLIP;
|
||||
|
||||
#ifdef HWRENDER
|
||||
if (rendermode == render_opengl && splitscreen)
|
||||
{
|
||||
thiscam->postimgflags = postimgtype;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
sector = player->mo->subsector->sector;
|
||||
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
pviewheight = player->mo->z + player->mo->height - player->viewheight;
|
||||
|
|
@ -3366,105 +3464,25 @@ static void P_CalcPostImg(player_t *player)
|
|||
pviewheight = player->awayviewmobj->z + 20*FRACUNIT;
|
||||
}
|
||||
|
||||
/*for (i = 0; i <= (unsigned)r_splitscreen; i++)
|
||||
{
|
||||
if (player == &players[displayplayers[i]])
|
||||
{
|
||||
param = &postimgparam[i];
|
||||
break;
|
||||
}
|
||||
}*/
|
||||
|
||||
// see if we are in heat (no, not THAT kind of heat...)
|
||||
for (i = 0; i < sector->tags.count; i++)
|
||||
{
|
||||
if (Tag_FindLineSpecial(13, sector->tags.tags[i]) != -1)
|
||||
{
|
||||
typeflag |= POSTIMG_HEAT;
|
||||
break;
|
||||
}
|
||||
else if (sector->ffloors)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
fixed_t topheight;
|
||||
fixed_t bottomheight;
|
||||
boolean gotres = false;
|
||||
|
||||
for (rover = sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
size_t j;
|
||||
|
||||
if (!(rover->fofflags & FOF_EXISTS))
|
||||
continue;
|
||||
|
||||
topheight = P_GetFFloorTopZAt (rover, player->mo->x, player->mo->y);
|
||||
bottomheight = P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y);
|
||||
|
||||
if (pviewheight >= topheight || pviewheight <= bottomheight)
|
||||
continue;
|
||||
|
||||
for (j = 0; j < rover->master->frontsector->tags.count; j++)
|
||||
{
|
||||
if (Tag_FindLineSpecial(13, rover->master->frontsector->tags.tags[j]) != -1)
|
||||
{
|
||||
typeflag |= POSTIMG_HEAT;
|
||||
gotres = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (gotres)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// see if we are in water (water trumps heat)
|
||||
if (sector->ffloors)
|
||||
{
|
||||
ffloor_t *rover;
|
||||
fixed_t topheight;
|
||||
fixed_t bottomheight;
|
||||
|
||||
for (rover = sector->ffloors; rover; rover = rover->next)
|
||||
{
|
||||
if (!(rover->fofflags & FOF_EXISTS) || !(rover->fofflags & FOF_SWIMMABLE) || rover->fofflags & FOF_BLOCKPLAYER)
|
||||
continue;
|
||||
|
||||
topheight = P_GetFFloorTopZAt (rover, player->mo->x, player->mo->y);
|
||||
bottomheight = P_GetFFloorBottomZAt(rover, player->mo->x, player->mo->y);
|
||||
|
||||
if (pviewheight >= topheight || pviewheight <= bottomheight)
|
||||
continue;
|
||||
|
||||
typeflag |= POSTIMG_WATER;
|
||||
}
|
||||
}
|
||||
|
||||
if (encoremode) // srb2kart
|
||||
typeflag |= POSTIMG_MIRROR;
|
||||
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
typeflag |= POSTIMG_FLIP;
|
||||
if (P_CameraCheckWaterFirstperson(player, sector, pviewheight))
|
||||
postimgtype |= POSTIMG_WATER;
|
||||
// see if we are in heat (no, not THAT kind of heat...)
|
||||
else if (P_CameraCheckHeatFirstperson(player, sector, pviewheight))
|
||||
postimgtype |= POSTIMG_HEAT;
|
||||
|
||||
// Motion blur
|
||||
// unused
|
||||
/*if (player->speed > (35<<FRACBITS))
|
||||
{
|
||||
typeflag |= POSTIMG_MOTION;
|
||||
postimgtype |= POSTIMG_MOTION;
|
||||
*param = (player->speed - 32)/4;
|
||||
|
||||
if (*param > 5)
|
||||
*param = 5;
|
||||
}*/
|
||||
|
||||
for (i = 0; i <= (unsigned)r_splitscreen; i++)
|
||||
{
|
||||
if (player != &players[displayplayers[i]])
|
||||
continue;
|
||||
|
||||
players[displayplayers[i]].postimgflags = typeflag;
|
||||
break;
|
||||
}
|
||||
thiscam->postimgflags = postimgtype;
|
||||
}
|
||||
|
||||
void P_DoTimeOver(player_t *player)
|
||||
|
|
@ -4247,7 +4265,7 @@ void P_PlayerAfterThink(player_t *player)
|
|||
if (!thiscam->chase) // bob view only if looking through the player's eyes
|
||||
{
|
||||
P_CalcHeight(player);
|
||||
P_CalcPostImg(player);
|
||||
P_CalcPostImg(player, thiscam);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
|||
12
src/r_fps.c
12
src/r_fps.c
|
|
@ -23,6 +23,7 @@
|
|||
#include "r_state.h"
|
||||
#include "z_zone.h"
|
||||
#include "console.h" // con_startup_loadprogress
|
||||
#include "i_time.h"
|
||||
|
||||
static CV_PossibleValue_t fpscap_cons_t[] = {
|
||||
#ifdef DEVELOP
|
||||
|
|
@ -73,6 +74,7 @@ static viewvars_t skyview_old[MAXSPLITSCREENPLAYERS];
|
|||
static viewvars_t skyview_new[MAXSPLITSCREENPLAYERS];
|
||||
|
||||
static viewvars_t *oldview = &pview_old[0];
|
||||
static tic_t last_view_update;
|
||||
static int oldview_invalid[MAXSPLITSCREENPLAYERS] = {0, 0, 0, 0};
|
||||
viewvars_t *newview = &pview_new[0];
|
||||
|
||||
|
|
@ -180,21 +182,27 @@ void R_UpdateViewInterpolation(void)
|
|||
skyview_old[i] = skyview_new[i];
|
||||
if (oldview_invalid[i] > 0) oldview_invalid[i]--;
|
||||
}
|
||||
|
||||
last_view_update = I_GetTime();
|
||||
}
|
||||
|
||||
void R_ResetViewInterpolation(UINT8 p)
|
||||
{
|
||||
// Wait an extra tic if the interpolation state hasn't
|
||||
// updated yet.
|
||||
int t = last_view_update == I_GetTime() ? 1 : 2;
|
||||
|
||||
if (p == 0)
|
||||
{
|
||||
UINT8 i;
|
||||
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||
{
|
||||
oldview_invalid[i]++;
|
||||
oldview_invalid[i] = t;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
oldview_invalid[p - 1]++;
|
||||
oldview_invalid[p - 1] = t;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ mobj_t *r_viewmobj;
|
|||
int r_splitscreen;
|
||||
|
||||
fixed_t rendertimefrac;
|
||||
fixed_t rendertimefrac_unpaused;
|
||||
fixed_t renderdeltatics;
|
||||
boolean renderisnewtic;
|
||||
|
||||
|
|
@ -913,13 +914,13 @@ void R_ApplyViewMorph(int s)
|
|||
width*vid.bpp, height, width*vid.bpp, vid.width);
|
||||
}
|
||||
|
||||
angle_t R_ViewRollAngle(const player_t *player)
|
||||
angle_t R_ViewRollAngle(const player_t *player, UINT8 viewnum)
|
||||
{
|
||||
angle_t roll = player->viewrollangle;
|
||||
|
||||
if (cv_tilting.value)
|
||||
{
|
||||
if (!player->spectator)
|
||||
if (!player->spectator && !camera[viewnum].freecam)
|
||||
{
|
||||
roll += player->tilt;
|
||||
}
|
||||
|
|
@ -1202,20 +1203,21 @@ R_SetupCommonFrame
|
|||
( player_t * player,
|
||||
subsector_t * subsector)
|
||||
{
|
||||
const UINT8 viewnum = R_GetViewNumber();
|
||||
newview->player = player;
|
||||
|
||||
newview->x += quake.x;
|
||||
newview->y += quake.y;
|
||||
newview->z += quake.z;
|
||||
|
||||
newview->roll = R_ViewRollAngle(player);
|
||||
newview->roll = R_ViewRollAngle(player, viewnum);
|
||||
|
||||
if (subsector)
|
||||
newview->sector = subsector->sector;
|
||||
else
|
||||
newview->sector = R_PointInSubsector(newview->x, newview->y)->sector;
|
||||
|
||||
R_InterpolateView(rendertimefrac);
|
||||
R_InterpolateView(rendertimefrac_unpaused);
|
||||
}
|
||||
|
||||
static void R_SetupAimingFrame(int s)
|
||||
|
|
@ -1253,8 +1255,12 @@ void R_SetupFrame(int s, boolean skybox)
|
|||
|
||||
R_SetViewContext(static_cast<viewcontext_e>(VIEWCONTEXT_PLAYER1 + s));
|
||||
|
||||
if (player->spectator) // no spectator chasecam
|
||||
chasecam = false; // force chasecam off
|
||||
if (player->spectator)
|
||||
{
|
||||
// Free flying spectator uses demo freecam. This
|
||||
// requires chasecam to be enabled.
|
||||
chasecam = true;
|
||||
}
|
||||
|
||||
if (chasecam && (thiscam && !thiscam->chase))
|
||||
{
|
||||
|
|
@ -1280,7 +1286,7 @@ void R_SetupFrame(int s, boolean skybox)
|
|||
|
||||
R_SetupCommonFrame(player, r_viewmobj->subsector);
|
||||
}
|
||||
else if (!player->spectator && chasecam)
|
||||
else if (chasecam)
|
||||
// use outside cam view
|
||||
{
|
||||
r_viewmobj = NULL;
|
||||
|
|
@ -1426,10 +1432,8 @@ boolean R_ViewpointHasChasecam(player_t *player)
|
|||
}
|
||||
}
|
||||
|
||||
if (player->playerstate == PST_DEAD || gamestate == GS_TITLESCREEN || tutorialmode)
|
||||
if (player->playerstate == PST_DEAD || gamestate == GS_TITLESCREEN || tutorialmode || player->spectator)
|
||||
chasecam = true; // force chasecam on
|
||||
else if (player->spectator) // no spectator chasecam
|
||||
chasecam = false; // force chasecam off
|
||||
|
||||
return chasecam;
|
||||
}
|
||||
|
|
@ -1448,7 +1452,7 @@ boolean R_IsViewpointThirdPerson(player_t *player, boolean skybox)
|
|||
if (player->awayviewtics || skybox)
|
||||
return chasecam;
|
||||
// use outside cam view
|
||||
else if (!player->spectator && chasecam)
|
||||
else if (chasecam)
|
||||
return true;
|
||||
|
||||
// use the player's eyes view
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ extern size_t validcount, linecount, loopcount, framecount;
|
|||
|
||||
// The fraction of a tic being drawn (for interpolation between two tics)
|
||||
extern fixed_t rendertimefrac;
|
||||
// Same as rendertimefrac but not suspended when the game is paused
|
||||
extern fixed_t rendertimefrac_unpaused;
|
||||
// Evaluated delta tics for this frame (how many tics since the last frame)
|
||||
extern fixed_t renderdeltatics;
|
||||
// The current render is a new logical tic
|
||||
|
|
@ -190,7 +192,7 @@ void R_Init(void);
|
|||
|
||||
void R_CheckViewMorph(int split);
|
||||
void R_ApplyViewMorph(int split);
|
||||
angle_t R_ViewRollAngle(const player_t *player);
|
||||
angle_t R_ViewRollAngle(const player_t *player, UINT8 viewnum);
|
||||
|
||||
// just sets setsizeneeded true
|
||||
extern boolean setsizeneeded;
|
||||
|
|
|
|||
|
|
@ -545,11 +545,6 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (i == 0 && democam.soundmobj)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (player->awayviewtics)
|
||||
{
|
||||
listenmobj[i] = player->awayviewmobj;
|
||||
|
|
@ -559,7 +554,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
|
|||
listenmobj[i] = player->mo;
|
||||
}
|
||||
|
||||
if (origin && origin == listenmobj[i])
|
||||
if (origin && origin == listenmobj[i] && !camera[i].freecam)
|
||||
{
|
||||
itsUs = true;
|
||||
}
|
||||
|
|
@ -810,11 +805,6 @@ void S_UpdateSounds(void)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (i == 0 && democam.soundmobj)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (player->awayviewtics)
|
||||
{
|
||||
listenmobj[i] = player->awayviewmobj;
|
||||
|
|
@ -883,6 +873,9 @@ void S_UpdateSounds(void)
|
|||
|
||||
for (i = r_splitscreen; i >= 0; i--)
|
||||
{
|
||||
if (camera[i].freecam)
|
||||
continue;
|
||||
|
||||
if (c->origin != listenmobj[i])
|
||||
continue;
|
||||
|
||||
|
|
|
|||
|
|
@ -726,6 +726,8 @@ void ST_preLevelTitleCardDrawer(void)
|
|||
//
|
||||
static void ST_overlayDrawer(void)
|
||||
{
|
||||
const UINT8 viewnum = R_GetViewNumber();
|
||||
|
||||
// hu_showscores = auto hide score/time/rings when tab rankings are shown
|
||||
if (!(hu_showscores && (netgame || multiplayer)))
|
||||
{
|
||||
|
|
@ -743,7 +745,7 @@ static void ST_overlayDrawer(void)
|
|||
{
|
||||
if (cv_showviewpointtext.value)
|
||||
{
|
||||
if (!demo.title && !P_IsLocalPlayer(stplyr))
|
||||
if (!demo.title && !P_IsLocalPlayer(stplyr) && !camera[viewnum].freecam)
|
||||
{
|
||||
if (!r_splitscreen)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -2840,7 +2840,7 @@ INT32 heatindex[MAXSPLITSCREENPLAYERS] = {0, 0, 0, 0};
|
|||
// Perform a particular image postprocessing function.
|
||||
//
|
||||
|
||||
void V_DoPostProcessor(INT32 view, player_t *player, INT32 param)
|
||||
void V_DoPostProcessor(INT32 view, INT32 param)
|
||||
{
|
||||
#if NUMSCREENS < 5
|
||||
// do not enable image post processing for ARM, SH and MIPS CPUs
|
||||
|
|
@ -2859,6 +2859,11 @@ void V_DoPostProcessor(INT32 view, player_t *player, INT32 param)
|
|||
if (view < 0 || view > 3 || view > r_splitscreen)
|
||||
return;
|
||||
|
||||
camera_t *thiscam = &camera[view];
|
||||
|
||||
if (!thiscam->postimgflags)
|
||||
return;
|
||||
|
||||
if ((view == 1 && r_splitscreen == 1) || view >= 2)
|
||||
yoffset = viewheight;
|
||||
else
|
||||
|
|
@ -2872,10 +2877,7 @@ void V_DoPostProcessor(INT32 view, player_t *player, INT32 param)
|
|||
UINT8 *tmpscr = screens[4];
|
||||
UINT8 *srcscr = screens[0];
|
||||
|
||||
if (!player->postimgflags)
|
||||
return;
|
||||
|
||||
if (player->postimgflags & POSTIMG_WATER)
|
||||
if (thiscam->postimgflags & POSTIMG_WATER)
|
||||
{
|
||||
INT32 y;
|
||||
// Set disStart to a range from 0 to FINEANGLE, incrementing by 128 per tic
|
||||
|
|
@ -2933,25 +2935,7 @@ void V_DoPostProcessor(INT32 view, player_t *player, INT32 param)
|
|||
tmpscr = srcscr;
|
||||
srcscr = tmp;
|
||||
}
|
||||
|
||||
/*if (player->postimgflags & POSTIMG_MOTION) // Motion Blur!
|
||||
* {
|
||||
* INT32 x, y;
|
||||
*
|
||||
* // TODO: Add a postimg_param so that we can pick the translucency level...
|
||||
* UINT8 *transme = transtables + ((param-1)<<FF_TRANSSHIFT);
|
||||
*
|
||||
* for (y = yoffset; y < yoffset+viewheight; y++)
|
||||
* {
|
||||
* for (x = xoffset; x < xoffset+viewwidth; x++)
|
||||
* {
|
||||
* tmpscr[y*vid.width + x]
|
||||
* = colormaps[*(transme + (srcscr [(y*vid.width)+x ] <<8) + (tmpscr[(y*vid.width)+x]))];
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
if (player->postimgflags & POSTIMG_HEAT) // Heat wave
|
||||
else if (thiscam->postimgflags & POSTIMG_HEAT) // Heat wave
|
||||
{
|
||||
INT32 y;
|
||||
|
||||
|
|
@ -2998,7 +2982,21 @@ void V_DoPostProcessor(INT32 view, player_t *player, INT32 param)
|
|||
srcscr = tmp;
|
||||
}
|
||||
|
||||
if ((player->postimgflags & POSTIMG_FLIP) && !(player->postimgflags & POSTIMG_MIRROR)) // Flip the screen upside-down
|
||||
/*if (thiscam->postimg & POSTIMG_MOTION) // Motion Blur!
|
||||
{
|
||||
INT32 x, y;
|
||||
|
||||
// TODO: Add a postimg_param so that we can pick the translucency level...
|
||||
UINT8 *transme = transtables + ((param-1)<<FF_TRANSSHIFT);
|
||||
|
||||
for (y = yoffset; y < yoffset+viewheight; y++)
|
||||
{
|
||||
for (x = xoffset; x < xoffset+viewwidth; x++)
|
||||
tmpscr[y*vid.width + x] = colormaps[*(transme + (srcscr [(y*vid.width)+x ] <<8) + (tmpscr[(y*vid.width)+x]))];
|
||||
}
|
||||
}*/
|
||||
|
||||
if ((thiscam->postimgflags & POSTIMG_FLIP) && !(thiscam->postimgflags & POSTIMG_MIRROR)) // Flip the screen upside-down
|
||||
{
|
||||
INT32 y, y2;
|
||||
|
||||
|
|
@ -3009,7 +3007,7 @@ void V_DoPostProcessor(INT32 view, player_t *player, INT32 param)
|
|||
tmpscr = srcscr;
|
||||
srcscr = tmp;
|
||||
}
|
||||
else if ((player->postimgflags & POSTIMG_MIRROR) && !(player->postimgflags & POSTIMG_FLIP)) // Flip the screen on the x axis
|
||||
else if ((thiscam->postimgflags & POSTIMG_MIRROR) && !(thiscam->postimgflags & POSTIMG_FLIP)) // Flip the screen on the x axis
|
||||
{
|
||||
INT32 y, x, x2;
|
||||
|
||||
|
|
@ -3021,7 +3019,7 @@ void V_DoPostProcessor(INT32 view, player_t *player, INT32 param)
|
|||
tmpscr = srcscr;
|
||||
srcscr = tmp;
|
||||
}
|
||||
else if ((player->postimgflags & POSTIMG_MIRROR) && (player->postimgflags & POSTIMG_FLIP)) // Flip the screen upside-down and on the x axis
|
||||
else if ((thiscam->postimgflags & POSTIMG_MIRROR) && (thiscam->postimgflags & POSTIMG_FLIP)) // Flip the screen upside-down and on the x axis
|
||||
{
|
||||
INT32 y, x;
|
||||
|
||||
|
|
|
|||
|
|
@ -337,7 +337,7 @@ INT32 V_ThinStringWidth(const char *string, INT32 option);
|
|||
// Find string width from tny_font chars, 0.5x scale
|
||||
INT32 V_SmallThinStringWidth(const char *string, INT32 option);
|
||||
|
||||
void V_DoPostProcessor(INT32 view, player_t *player, INT32 param);
|
||||
void V_DoPostProcessor(INT32 view, INT32 param);
|
||||
|
||||
void V_DrawPatchFill(patch_t *pat);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue