diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 0666a7d80..5f7bb3c88 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -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]; diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 6eb7bae29..bac2fac7d 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -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); diff --git a/src/d_main.cpp b/src/d_main.cpp index 3a3dde1ac..3ada228ff 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -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) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index c1d60fa5b..7d830ae48 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -2255,7 +2255,7 @@ static void Command_View_f(void) return; } - if (demo.freecam) + if (camera[viewnum-1].freecam) return; displayplayerp = &displayplayers[viewnum-1]; diff --git a/src/d_player.h b/src/d_player.h index 5fb29aca0..02c1f32b9 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -505,8 +505,6 @@ struct player_t // See pflags_t, above. pflags_t pflags; - UINT16 postimgflags; - // playing animation. panim_t panim; diff --git a/src/doomtype.h b/src/doomtype.h index 1ebf0c27c..f74f340fe 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -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 diff --git a/src/g_demo.c b/src/g_demo.c index cd3044446..5a12d785e 100644 --- a/src/g_demo.c +++ b/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 diff --git a/src/g_game.c b/src/g_game.c index 00857faaa..4c54eb314 100644 --- a/src/g_game.c +++ b/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)) { diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index e5ace0855..4d3d96ad2 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -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; diff --git a/src/k_hud.c b/src/k_hud.c index 3602bab6c..f5693c400 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -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 { diff --git a/src/k_kart.c b/src/k_kart.c index e4dfbcfdd..0f0d30d94 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -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; diff --git a/src/m_menu.c b/src/m_menu.c index 64ae9e8d4..1c80d5318 100644 --- a/src/m_menu.c +++ b/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; diff --git a/src/p_local.h b/src/p_local.h index bfcccf4a4..25c9c94c4 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -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); diff --git a/src/p_mobj.c b/src/p_mobj.c index 14323e573..607ed9a1b 100644 --- a/src/p_mobj.c +++ b/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]); + } } } diff --git a/src/p_setup.c b/src/p_setup.c index 9f3c0d0ea..6ebeac25f 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -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) diff --git a/src/p_tick.c b/src/p_tick.c index 0fe6d8822..b19e02bee 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -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; } diff --git a/src/p_user.c b/src/p_user.c index a50396c4e..5da942c8b 100644 --- a/src/p_user.c +++ b/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<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 { diff --git a/src/r_fps.c b/src/r_fps.c index 11f1b8378..ca2547121 100644 --- a/src/r_fps.c +++ b/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; } } diff --git a/src/r_main.cpp b/src/r_main.cpp index a5050b49d..322c708b8 100644 --- a/src/r_main.cpp +++ b/src/r_main.cpp @@ -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_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 diff --git a/src/r_main.h b/src/r_main.h index 17df02059..b5c4e0968 100644 --- a/src/r_main.h +++ b/src/r_main.h @@ -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; diff --git a/src/s_sound.c b/src/s_sound.c index 3a6b606da..21369732a 100644 --- a/src/s_sound.c +++ b/src/s_sound.c @@ -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; diff --git a/src/st_stuff.c b/src/st_stuff.c index 6a3756de9..2e404b3e8 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -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) { diff --git a/src/v_video.c b/src/v_video.c index e41b10021..289d7eb70 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -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)<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)<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; diff --git a/src/v_video.h b/src/v_video.h index ad31c09cf..1a17cd84c 100644 --- a/src/v_video.h +++ b/src/v_video.h @@ -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);