diff --git a/src/d_netcmd.c b/src/d_netcmd.c index b02d79df3..c287366ab 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -12,6 +12,7 @@ /// commands are executed through the command buffer /// like console commands, other miscellaneous commands (at the end) +#include "d_player.h" #include "doomdef.h" #include "console.h" @@ -1730,6 +1731,7 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum) enum { WP_KICKSTARTACCEL = 1<<0, WP_SHRINKME = 1<<1, + WP_FLIPCAM = 1<<2, }; void WeaponPref_Send(UINT8 ssplayer) @@ -1741,6 +1743,9 @@ void WeaponPref_Send(UINT8 ssplayer) if (cv_shrinkme[ssplayer].value) prefs |= WP_SHRINKME; + + if (cv_flipcam[ssplayer].value) + prefs |= WP_FLIPCAM; SendNetXCmdForPlayer(ssplayer, XD_WEAPONPREF, &prefs, 1); } @@ -1756,6 +1761,9 @@ void WeaponPref_Save(UINT8 **cp, INT32 playernum) if (player->pflags & PF_SHRINKME) prefs |= WP_SHRINKME; + + if (player->pflags & PF_FLIPCAM) + prefs |= WP_FLIPCAM; WRITEUINT8(*cp, prefs); } @@ -1773,6 +1781,9 @@ void WeaponPref_Parse(UINT8 **cp, INT32 playernum) if (prefs & WP_SHRINKME) player->pflags |= PF_SHRINKME; + + if (prefs & WP_FLIPCAM) + player->pflags |= PF_FLIPCAM; if (leveltime < 2) { diff --git a/src/d_player.h b/src/d_player.h index c4fb80a79..facc15be1 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -93,7 +93,7 @@ typedef enum PF_AIRFAILSAFE = 1<<22, // Whenever or not try the air boost PF_TRICKDELAY = 1<<23, // Prevent tricks until control stick is neutral - //free = 1<<24, + PF_FLIPCAM = 1<<24, //free = 1<<25, PF_HITFINISHLINE = 1<<26, // Already hit the finish line this tic diff --git a/src/doomtype.h b/src/doomtype.h index 5d14fceae..d415d2aff 100644 --- a/src/doomtype.h +++ b/src/doomtype.h @@ -351,7 +351,8 @@ typedef enum postimg_motion, postimg_flip, postimg_heat, - postimg_mirror + postimg_mirror, + postimg_mirrorflip } postimg_t; typedef UINT32 lumpnum_t; // 16 : 16 unsigned long (wad num: lump num) diff --git a/src/g_game.c b/src/g_game.c index 9ac1f5e1e..208674f2f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -344,11 +344,6 @@ INT16 prevmap, nextmap; static UINT8 *savebuffer; -static void weaponPrefChange(void); -static void weaponPrefChange2(void); -static void weaponPrefChange3(void); -static void weaponPrefChange4(void); - static CV_PossibleValue_t joyaxis_cons_t[] = {{0, "None"}, {1, "X-Axis"}, {2, "Y-Axis"}, {-1, "X-Axis-"}, {-2, "Y-Axis-"}, #if JOYAXISSET > 1 @@ -1249,22 +1244,22 @@ ticcmd_t *G_MoveTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n) return dest; } -static void weaponPrefChange(void) +void weaponPrefChange(void) { WeaponPref_Send(0); } -static void weaponPrefChange2(void) +void weaponPrefChange2(void) { WeaponPref_Send(1); } -static void weaponPrefChange3(void) +void weaponPrefChange3(void) { WeaponPref_Send(2); } -static void weaponPrefChange4(void) +void weaponPrefChange4(void) { WeaponPref_Send(3); } diff --git a/src/g_game.h b/src/g_game.h index 535f38470..af2fe94b3 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -77,6 +77,12 @@ extern consvar_t cv_resetspecialmusic; extern consvar_t cv_resume; + +void weaponPrefChange(void); +void weaponPrefChange2(void); +void weaponPrefChange3(void); +void weaponPrefChange4(void); + // mouseaiming (looking up/down with the mouse or keyboard) #define KB_LOOKSPEED (1<<25) #define MAXPLMOVE (50) diff --git a/src/hardware/hw_defs.h b/src/hardware/hw_defs.h index 1ba8164a3..692a545fb 100644 --- a/src/hardware/hw_defs.h +++ b/src/hardware/hw_defs.h @@ -119,6 +119,7 @@ typedef struct FLOAT centerx, centery; FLOAT rollx, rollz; boolean mirror; // SRB2Kart: Encore Mode + boolean mirrorflip; // Encore Mode with Flipcam } FTransform; // Transformed vector, as passed to HWR API diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 9f88bfdd9..88963049e 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -5999,6 +5999,11 @@ static void HWR_DrawSkyBackground(player_t *player) dometransform.mirror = true; else dometransform.mirror = false; + + if (*type == postimg_mirrorflip) + dometransform.mirrorflip = true; + else + dometransform.mirrorflip = false; dometransform.scalex = 1; dometransform.scaley = (float)vid.width/vid.height; @@ -6499,6 +6504,11 @@ void HWR_RenderPlayerView(void) atransform.mirror = true; else atransform.mirror = false; + + if (*type == postimg_mirrorflip) + atransform.mirrorflip = true; + else + atransform.mirrorflip = false; atransform.x = gl_viewx; // FIXED_TO_FLOAT(viewx) atransform.y = gl_viewy; // FIXED_TO_FLOAT(viewy) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index f57b8d64d..bb856ae7c 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -3035,6 +3035,8 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) used_fov = stransform->fovxangle; if (stransform->mirror) pglScalef(-stransform->scalex, stransform->scaley, -stransform->scalez); + else if (stransform->mirrorflip) + pglScalef(-stransform->scalex, -stransform->scaley, -stransform->scalez); else if (stransform->flip) pglScalef(stransform->scalex, -stransform->scaley, -stransform->scalez); else diff --git a/src/p_mobj.c b/src/p_mobj.c index 3b1501fd4..9990cf0bd 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -12,6 +12,7 @@ /// \brief Moving object handling. Spawn functions #include "doomdef.h" +#include "doomtype.h" #include "g_game.h" #include "g_input.h" #include "st_stuff.h" @@ -1028,6 +1029,27 @@ static void P_PlayerFlip(mobj_t *mo) { if (!mo->player) return; + + if (mo->player->pflags & PF_FLIPCAM) + { + UINT8 i; + + mo->player->aiming = InvAngle(mo->player->aiming); + + for (i = 0; i <= r_splitscreen; i++) + { + if (mo->player-players == displayplayers[i]) + { + localaiming[i] = mo->player->aiming; + if (camera[i].chase) { + camera[i].aiming = InvAngle(camera[i].aiming); + camera[i].z = mo->z - camera[i].z + mo->z; + if (mo->eflags & MFE_VERTICALFLIP) + camera[i].z += FixedMul(20*FRACUNIT, mo->scale); + } + } + } + } G_GhostAddFlip((INT32) (mo->player - players)); // Flip aiming to match! @@ -3447,6 +3469,7 @@ 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); postimg_t postimg = postimg_none; UINT8 i; @@ -3454,10 +3477,12 @@ void P_CalcChasePostImg(player_t *player, camera_t *thiscam) if (thiscam->subsector == NULL || thiscam->subsector->sector == NULL) return; - if (encoremode) - { + if (encoremode && !flipcam) postimg = postimg_mirror; - } + else if (!encoremode && flipcam) + postimg = postimg_flip; + else if (encoremode && flipcam) + postimg = postimg_mirrorflip; else if (player->awayviewtics && player->awayviewmobj && !P_MobjWasRemoved(player->awayviewmobj)) // Camera must obviously exist { camera_t dummycam; diff --git a/src/p_user.c b/src/p_user.c index 8e66237d4..12976ea81 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3800,8 +3800,18 @@ static void P_CalcPostImg(player_t *player) } } - if (player->mo->eflags & MFE_VERTICALFLIP) - *type = postimg_flip; + if (!encoremode) // srb2kart + { + if (player->mo->eflags & MFE_VERTICALFLIP) + *type = postimg_flip; + } + else + { + if (player->mo->eflags & MFE_VERTICALFLIP) + *type = postimg_mirrorflip; + else + *type = postimg_mirror; + } #if 1 (void)param; @@ -3816,9 +3826,6 @@ static void P_CalcPostImg(player_t *player) *param = 5; } #endif - - if (encoremode) // srb2kart - *type = postimg_mirror; } void P_DoTimeOver(player_t *player) diff --git a/src/r_main.c b/src/r_main.c index 955a9237f..d6cad900e 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -147,6 +147,10 @@ static void ChaseCam_OnChange(void); static void ChaseCam2_OnChange(void); static void ChaseCam3_OnChange(void); static void ChaseCam4_OnChange(void); +static void FlipCam_OnChange(void); +static void FlipCam2_OnChange(void); +static void FlipCam3_OnChange(void); +static void FlipCam4_OnChange(void); consvar_t cv_tailspickup = CVAR_INIT ("tailspickup", "On", CV_NETVAR|CV_NOSHOWHELP, CV_OnOff, NULL); consvar_t cv_chasecam[MAXSPLITSCREENPLAYERS] = { @@ -156,6 +160,13 @@ consvar_t cv_chasecam[MAXSPLITSCREENPLAYERS] = { CVAR_INIT ("chasecam4", "On", CV_CALL, CV_OnOff, ChaseCam4_OnChange) }; +consvar_t cv_flipcam[MAXSPLITSCREENPLAYERS] = { + CVAR_INIT ("flipcam", "Off", CV_CALL|CV_SAVE, CV_OnOff, weaponPrefChange), + CVAR_INIT ("flipcam2", "Off", CV_CALL|CV_SAVE, CV_OnOff, weaponPrefChange2), + CVAR_INIT ("flipcam3", "Off", CV_CALL|CV_SAVE, CV_OnOff, weaponPrefChange3), + CVAR_INIT ("flipcam4", "Off", CV_CALL|CV_SAVE, CV_OnOff, weaponPrefChange4) +}; + consvar_t cv_shadow = CVAR_INIT ("shadow", "On", CV_SAVE, CV_OnOff, NULL); consvar_t cv_skybox = CVAR_INIT ("skybox", "On", CV_SAVE, CV_OnOff, NULL); consvar_t cv_ffloorclip = CVAR_INIT ("ffloorclip", "On", CV_SAVE, CV_OnOff, NULL); @@ -1656,6 +1667,7 @@ void R_RegisterEngineStuff(void) { CV_RegisterVar(&cv_fov[i]); CV_RegisterVar(&cv_chasecam[i]); + CV_RegisterVar(&cv_flipcam[i]); CV_RegisterVar(&cv_cam_dist[i]); CV_RegisterVar(&cv_cam_still[i]); CV_RegisterVar(&cv_cam_height[i]); diff --git a/src/v_video.c b/src/v_video.c index b13f02eef..e8a934708 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -2790,6 +2790,19 @@ Unoptimized version for (x = xoffset, x2 = xoffset+((viewwidth*vid.bpp)-1); x < xoffset+(viewwidth*vid.bpp); x++, x2--) tmpscr[y*vid.width + x2] = srcscr[y*vid.width + x]; } + + VID_BlitLinearScreen(tmpscr+vid.width*vid.bpp*yoffset+xoffset, screens[0]+vid.width*vid.bpp*yoffset+xoffset, + viewwidth*vid.bpp, viewheight, vid.width*vid.bpp, vid.width); + } + else if (type == postimg_mirrorflip) // Flip the screen upside-down and on the x axis + { + UINT8 *tmpscr = screens[4]; + UINT8 *srcscr = screens[0]; + INT32 y, x; + + for (y = yoffset; y < yoffset + viewheight; y++) + for (x = xoffset; x < xoffset + viewwidth; x++) + tmpscr[((yoffset + viewheight - 1 - y) * vid.width) + xoffset + viewwidth - (x - xoffset) - 1] = srcscr[(y * vid.width) + x]; VID_BlitLinearScreen(tmpscr+vid.width*vid.bpp*yoffset+xoffset, screens[0]+vid.width*vid.bpp*yoffset+xoffset, viewwidth*vid.bpp, viewheight, vid.width*vid.bpp, vid.width);