From 66a9a6bdd42c16e7b338683a82da0ceda3f56e8a Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 17 Dec 2017 14:17:07 -0500 Subject: [PATCH 1/4] Fixed local sync fail, among a bunch of other splitscreen check fixes in other files I don't know how many of the changes in d_clisrv were really necessary, I was just franticly trying to figure out the source of the local sync fail --- src/d_clisrv.c | 173 ++++++++++++++++++++++++++++++++++--------------- src/d_clisrv.h | 6 +- src/d_main.c | 4 +- src/d_net.c | 6 ++ src/d_net.h | 2 +- src/d_netcmd.c | 20 ++++-- src/g_game.c | 4 +- src/hu_stuff.c | 2 +- src/p_mobj.c | 9 ++- src/p_setup.c | 34 +++++++++- src/p_spec.c | 6 +- src/p_user.c | 13 ++-- src/r_main.c | 4 +- src/r_state.h | 2 +- src/st_stuff.c | 28 ++++---- src/v_video.c | 2 +- 16 files changed, 218 insertions(+), 97 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 9e519d61..4b47d4a5 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -97,7 +97,7 @@ SINT8 nodetoplayer[MAXNETNODES]; SINT8 nodetoplayer2[MAXNETNODES]; // say the numplayer for this node if any (splitscreen) SINT8 nodetoplayer3[MAXNETNODES]; // say the numplayer for this node if any (splitscreen3) SINT8 nodetoplayer4[MAXNETNODES]; // say the numplayer for this node if any (splitscreen4) -UINT8 playerpernode[MAXNETNODES]; // used specialy for scplitscreen +UINT8 playerpernode[MAXNETNODES]; // used specialy for splitscreen boolean nodeingame[MAXNETNODES]; // set false as nodes leave game static tic_t nettics[MAXNETNODES]; // what tic the client have received static tic_t supposedtics[MAXNETNODES]; // nettics prevision for smaller packet @@ -269,6 +269,38 @@ void SendNetXCmd2(netxcmd_t id, const void *param, size_t nparam) } } +void SendNetXCmd3(netxcmd_t id, const void *param, size_t nparam) +{ + if (localtextcmd3[0]+2+nparam > MAXTEXTCMD) + { + I_Error("No more place in the buffer for netcmd %d\n",id); + return; + } + localtextcmd3[0]++; + localtextcmd3[localtextcmd3[0]] = (UINT8)id; + if (param && nparam) + { + M_Memcpy(&localtextcmd3[localtextcmd3[0]+1], param, nparam); + localtextcmd3[0] = (UINT8)(localtextcmd3[0] + (UINT8)nparam); + } +} + +void SendNetXCmd4(netxcmd_t id, const void *param, size_t nparam) +{ + if (localtextcmd4[0]+2+nparam > MAXTEXTCMD) + { + I_Error("No more place in the buffer for netcmd %d\n",id); + return; + } + localtextcmd4[0]++; + localtextcmd4[localtextcmd4[0]] = (UINT8)id; + if (param && nparam) + { + M_Memcpy(&localtextcmd4[localtextcmd4[0]+1], param, nparam); + localtextcmd4[0] = (UINT8)(localtextcmd4[0] + (UINT8)nparam); + } +} + UINT8 GetFreeXCmdSize(void) { // -1 for the size and another -1 for the ID. @@ -2708,9 +2740,9 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum) // Is playernum authorized to make this kick? if (playernum != serverplayer && !IsPlayerAdmin(playernum) && !(playerpernode[playernode[playernum]] >= 2 - && nodetoplayer2[playernode[playernum]] == pnum - && nodetoplayer3[playernode[playernum]] == pnum - && nodetoplayer4[playernode[playernum]] == pnum)) + && (nodetoplayer2[playernode[playernum]] == pnum + || nodetoplayer3[playernode[playernum]] == pnum + || nodetoplayer4[playernode[playernum]] == pnum))) { // We received a kick command from someone who isn't the // server or admin, and who isn't in splitscreen removing @@ -3115,24 +3147,22 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) if (node == mynode) { playernode[newplayernum] = 0; // for information only - if (splitscreenplayer == 0) + if (splitscreenplayer) { - consoleplayer = newplayernum; - displayplayer = newplayernum; - secondarydisplayplayer = newplayernum; - thirddisplayplayer = newplayernum; - fourthdisplayplayer = newplayernum; - DEBFILE("spawning me\n"); - // Apply player flags as soon as possible! - players[newplayernum].pflags &= ~(PF_FLIPCAM|PF_ANALOGMODE); - if (cv_flipcam.value) - players[newplayernum].pflags |= PF_FLIPCAM; - if (cv_analog.value) - players[newplayernum].pflags |= PF_ANALOGMODE; - } - else - { - if (splitscreenplayer == 2) + if (splitscreenplayer == 1) + { + secondarydisplayplayer = newplayernum; + DEBFILE("spawning my brother\n"); + if (botingame) + players[newplayernum].bot = 1; + // Same goes for player 2 when relevant + players[newplayernum].pflags &= ~(PF_FLIPCAM|PF_ANALOGMODE); + if (cv_flipcam2.value) + players[newplayernum].pflags |= PF_FLIPCAM; + if (cv_analog2.value) + players[newplayernum].pflags |= PF_ANALOGMODE; + } + else if (splitscreenplayer == 2) { thirddisplayplayer = newplayernum; DEBFILE("spawning my sister\n"); @@ -3152,19 +3182,21 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum) if (cv_analog4.value) players[newplayernum].pflags |= PF_ANALOGMODE; } - else - { - secondarydisplayplayer = newplayernum; - DEBFILE("spawning my brother\n"); - if (botingame) - players[newplayernum].bot = 1; - // Same goes for player 2 when relevant - players[newplayernum].pflags &= ~(PF_FLIPCAM|PF_ANALOGMODE); - if (cv_flipcam2.value) - players[newplayernum].pflags |= PF_FLIPCAM; - if (cv_analog2.value) - players[newplayernum].pflags |= PF_ANALOGMODE; - } + } + else + { + consoleplayer = newplayernum; + displayplayer = newplayernum; + secondarydisplayplayer = newplayernum; + thirddisplayplayer = newplayernum; + fourthdisplayplayer = newplayernum; + DEBFILE("spawning me\n"); + // Apply player flags as soon as possible! + players[newplayernum].pflags &= ~(PF_FLIPCAM|PF_ANALOGMODE); + if (cv_flipcam.value) + players[newplayernum].pflags |= PF_FLIPCAM; + if (cv_analog.value) + players[newplayernum].pflags |= PF_ANALOGMODE; } D_SendPlayerConfig(); addedtogame = true; @@ -3233,7 +3265,7 @@ static boolean SV_AddWaitingPlayers(void) nodetoplayer3[node] = newplayernum; buf[1] += MAXPLAYERS*2; } - else if (playerpernode[node] < 4) + else { nodetoplayer4[node] = newplayernum; buf[1] += MAXPLAYERS*3; @@ -3752,6 +3784,7 @@ FILESTAMP realend = ExpandTics(netbuffer->u.clientpak.resendfrom); if (netbuffer->packettype == PT_CLIENTMIS || netbuffer->packettype == PT_CLIENT2MIS + || netbuffer->packettype == PT_CLIENT3MIS || netbuffer->packettype == PT_CLIENT4MIS || netbuffer->packettype == PT_NODEKEEPALIVEMIS || supposedtics[node] < realend) { @@ -3800,20 +3833,26 @@ FILESTAMP if (((netbuffer->packettype == PT_CLIENT2CMD || netbuffer->packettype == PT_CLIENT2MIS) || (netbuffer->packettype == PT_CLIENT3CMD || netbuffer->packettype == PT_CLIENT3MIS) || (netbuffer->packettype == PT_CLIENT4CMD || netbuffer->packettype == PT_CLIENT4MIS)) - && nodetoplayer2[node] >= 0) + && (nodetoplayer2[node] >= 0)) + { G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)nodetoplayer2[node]], &netbuffer->u.client2pak.cmd2, 1); - + } + if (((netbuffer->packettype == PT_CLIENT3CMD || netbuffer->packettype == PT_CLIENT3MIS) || (netbuffer->packettype == PT_CLIENT4CMD || netbuffer->packettype == PT_CLIENT4MIS)) - && nodetoplayer3[node] >= 0) + && (nodetoplayer3[node] >= 0)) + { G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)nodetoplayer3[node]], &netbuffer->u.client3pak.cmd3, 1); + } if ((netbuffer->packettype == PT_CLIENT4CMD || netbuffer->packettype == PT_CLIENT4MIS) - && nodetoplayer4[node] >= 0) + && (nodetoplayer4[node] >= 0)) + { G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)nodetoplayer4[node]], &netbuffer->u.client4pak.cmd4, 1); + } // A delay before we check resynching // Used on join or just after a synch fail @@ -3948,6 +3987,7 @@ FILESTAMP buf[1] = KICK_MSG_PLAYER_QUIT; SendNetXCmd(XD_KICK, &buf, 2); nodetoplayer[node] = -1; + if (nodetoplayer2[node] != -1 && nodetoplayer2[node] >= 0 && playeringame[(UINT8)nodetoplayer2[node]]) { @@ -3955,6 +3995,7 @@ FILESTAMP SendNetXCmd(XD_KICK, &buf, 2); nodetoplayer2[node] = -1; } + if (nodetoplayer3[node] != -1 && nodetoplayer3[node] >= 0 && playeringame[(UINT8)nodetoplayer3[node]]) { @@ -3962,6 +4003,7 @@ FILESTAMP SendNetXCmd(XD_KICK, &buf, 2); nodetoplayer3[node] = -1; } + if (nodetoplayer4[node] != -1 && nodetoplayer4[node] >= 0 && playeringame[(UINT8)nodetoplayer4[node]]) { @@ -4326,7 +4368,7 @@ static void CL_SendClientCmd(void) if (gamestate == GS_WAITINGPLAYERS) { // Send PT_NODEKEEPALIVE packet - netbuffer->packettype += 4; + netbuffer->packettype += 8; packetsize = sizeof (clientcmd_pak) - sizeof (ticcmd_t) - sizeof (INT16); HSendPacket(servernode, false, 0, packetsize); } @@ -4335,23 +4377,26 @@ static void CL_SendClientCmd(void) G_MoveTiccmd(&netbuffer->u.clientpak.cmd, &localcmds, 1); netbuffer->u.clientpak.consistancy = SHORT(consistancy[gametic%BACKUPTICS]); - if (splitscreen4) + if (splitscreen || botingame) // Send a special packet with 2 cmd for splitscreen { - netbuffer->packettype += 6; - G_MoveTiccmd(&netbuffer->u.client4pak.cmd2, &localcmds2, 1); - G_MoveTiccmd(&netbuffer->u.client4pak.cmd3, &localcmds3, 1); - G_MoveTiccmd(&netbuffer->u.client4pak.cmd4, &localcmds4, 1); + netbuffer->packettype += 2; + G_MoveTiccmd(&netbuffer->u.client2pak.cmd2, &localcmds2, 1); + packetsize = sizeof (client2cmd_pak); } else if (splitscreen3) { netbuffer->packettype += 4; - G_MoveTiccmd(&netbuffer->u.client3pak.cmd2, &localcmds2, 1); - G_MoveTiccmd(&netbuffer->u.client3pak.cmd3, &localcmds3, 1); - } - else if (splitscreen || botingame) // Send a special packet with 2 cmd for splitscreen - { - netbuffer->packettype += 2; G_MoveTiccmd(&netbuffer->u.client2pak.cmd2, &localcmds2, 1); + G_MoveTiccmd(&netbuffer->u.client3pak.cmd3, &localcmds3, 1); + packetsize = sizeof (client3cmd_pak); + } + else if (splitscreen4) + { + netbuffer->packettype += 6; + G_MoveTiccmd(&netbuffer->u.client2pak.cmd2, &localcmds2, 1); + G_MoveTiccmd(&netbuffer->u.client3pak.cmd3, &localcmds3, 1); + G_MoveTiccmd(&netbuffer->u.client4pak.cmd4, &localcmds4, 1); + packetsize = sizeof (client4cmd_pak); } else packetsize = sizeof (clientcmd_pak); @@ -4380,6 +4425,26 @@ static void CL_SendClientCmd(void) if (HSendPacket(servernode, true, 0, localtextcmd2[0]+1)) // Send can fail... localtextcmd2[0] = 0; } + + // Send extra data if needed for player 3 (splitscreen3) + if (localtextcmd3[0]) + { + netbuffer->packettype = PT_TEXTCMD3; + M_Memcpy(netbuffer->u.textcmd, localtextcmd3, localtextcmd3[0]+1); + // All extra data have been sent + if (HSendPacket(servernode, true, 0, localtextcmd3[0]+1)) // Send can fail... + localtextcmd3[0] = 0; + } + + // Send extra data if needed for player 4 (splitscreen4) + if (localtextcmd4[0]) + { + netbuffer->packettype = PT_TEXTCMD4; + M_Memcpy(netbuffer->u.textcmd, localtextcmd4, localtextcmd4[0]+1); + // All extra data have been sent + if (HSendPacket(servernode, true, 0, localtextcmd4[0]+1)) // Send can fail... + localtextcmd4[0] = 0; + } } } @@ -4558,8 +4623,12 @@ static void SV_Maketic(void) CONS_Debug(DBG_NETPLAY, "Client Misstic %d\n", maketic); #endif // copy the old tic - for (i = 0; i < playerpernode[j]; i++, player = nodetoplayer2[j]) + for (i = 0; i < playerpernode[j]; i++) { + if (i == 0) player = nodetoplayer[j]; + else if (i == 1) player = nodetoplayer2[j]; + else if (i == 2) player = nodetoplayer3[j]; + else if (i == 3) player = nodetoplayer4[j]; netcmds[maketic%BACKUPTICS][player] = netcmds[(maketic-1)%BACKUPTICS][player]; netcmds[maketic%BACKUPTICS][player].angleturn &= ~TICCMD_RECEIVED; } diff --git a/src/d_clisrv.h b/src/d_clisrv.h index 702e5d60..bc902ac5 100644 --- a/src/d_clisrv.h +++ b/src/d_clisrv.h @@ -70,8 +70,8 @@ typedef enum PT_TEXTCMD, // Extra text commands from the client. PT_TEXTCMD2, // Splitscreen text commands. - PT_TEXTCMD3, - PT_TEXTCMD4, + PT_TEXTCMD3, // 3P + PT_TEXTCMD4, // 4P PT_CLIENTJOIN, // Client wants to join; used in start game. PT_NODETIMEOUT, // Packet sent to self if the connection times out. PT_RESYNCHING, // Packet sent to resync players. @@ -506,6 +506,8 @@ void D_ClientServerInit(void); void RegisterNetXCmd(netxcmd_t id, void (*cmd_f)(UINT8 **p, INT32 playernum)); void SendNetXCmd(netxcmd_t id, const void *param, size_t nparam); void SendNetXCmd2(netxcmd_t id, const void *param, size_t nparam); // splitsreen player +void SendNetXCmd3(netxcmd_t id, const void *param, size_t nparam); // splitsreen3 player +void SendNetXCmd4(netxcmd_t id, const void *param, size_t nparam); // splitsreen4 player // Create any new ticcmds and broadcast to other players. void NetUpdate(void); diff --git a/src/d_main.c b/src/d_main.c index 367bd012..6e469aad 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -401,7 +401,7 @@ static void D_Display(void) } // render the second screen - if (splitscreen && players[secondarydisplayplayer].mo) + if ((splitscreen || splitscreen3 || splitscreen4) && players[secondarydisplayplayer].mo) { #ifdef HWRENDER if (rendermode != render_soft) @@ -410,6 +410,8 @@ static void D_Display(void) #endif if (rendermode != render_none) { + if (splitscreen3 || splitscreen4) + viewwindowx = vid.width / 2; viewwindowy = vid.height / 2; M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0])); diff --git a/src/d_net.c b/src/d_net.c index 5c3f644d..5437af56 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -818,6 +818,10 @@ static const char *packettypename[NUMPACKETTYPE] = "CLIENTMIS", "CLIENT2CMD", "CLIENT2MIS", + "CLIENT3CMD", + "CLIENT3MIS", + "CLIENT4CMD", + "CLIENT4MIS", "NODEKEEPALIVE", "NODEKEEPALIVEMIS", "SERVERTICS", @@ -837,6 +841,8 @@ static const char *packettypename[NUMPACKETTYPE] = "FILEFRAGMENT", "TEXTCMD", "TEXTCMD2", + "TEXTCMD3", + "TEXTCMD4", "CLIENTJOIN", "NODETIMEOUT", "RESYNCHING", diff --git a/src/d_net.h b/src/d_net.h index cb70b6df..45fd8683 100644 --- a/src/d_net.h +++ b/src/d_net.h @@ -21,7 +21,7 @@ // Max computers in a game #define MAXNETNODES 16 #define BROADCASTADDR MAXNETNODES -#define MAXSPLITSCREENPLAYERS 2 // Max number of players on a single computer +#define MAXSPLITSCREENPLAYERS 4 // Max number of players on a single computer #define STATLENGTH (TICRATE*2) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index 6a454f46..2c2e2218 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -178,8 +178,8 @@ static void Command_Archivetest_f(void); void SendWeaponPref(void); void SendWeaponPref2(void); -//void SendWeaponPref3(void); -//void SendWeaponPref4(void); +void SendWeaponPref3(void); +void SendWeaponPref4(void); static CV_PossibleValue_t usemouse_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Force"}, {0, NULL}}; #if (defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON) @@ -772,16 +772,28 @@ void D_RegisterClientCommands(void) // g_input.c CV_RegisterVar(&cv_sideaxis); CV_RegisterVar(&cv_sideaxis2); + CV_RegisterVar(&cv_sideaxis3); + CV_RegisterVar(&cv_sideaxis4); CV_RegisterVar(&cv_turnaxis); CV_RegisterVar(&cv_turnaxis2); + CV_RegisterVar(&cv_turnaxis3); + CV_RegisterVar(&cv_turnaxis4); CV_RegisterVar(&cv_moveaxis); CV_RegisterVar(&cv_moveaxis2); + CV_RegisterVar(&cv_moveaxis3); + CV_RegisterVar(&cv_moveaxis4); CV_RegisterVar(&cv_lookaxis); CV_RegisterVar(&cv_lookaxis2); + CV_RegisterVar(&cv_lookaxis3); + CV_RegisterVar(&cv_lookaxis4); CV_RegisterVar(&cv_fireaxis); CV_RegisterVar(&cv_fireaxis2); + CV_RegisterVar(&cv_fireaxis3); + CV_RegisterVar(&cv_fireaxis4); CV_RegisterVar(&cv_firenaxis); CV_RegisterVar(&cv_firenaxis2); + CV_RegisterVar(&cv_firenaxis3); + CV_RegisterVar(&cv_firenaxis4); // WARNING: the order is important when initialising mouse2 // we need the mouse2port @@ -1689,7 +1701,7 @@ void SendWeaponPref3(void) buf[0] |= 1; if (players[thirddisplayplayer].pflags & PF_ANALOGMODE) buf[0] |= 2; - //SendNetXCmd3(XD_WEAPONPREF, buf, 1); + SendNetXCmd3(XD_WEAPONPREF, buf, 1); } void SendWeaponPref4(void) @@ -1701,7 +1713,7 @@ void SendWeaponPref4(void) buf[0] |= 1; if (players[fourthdisplayplayer].pflags & PF_ANALOGMODE) buf[0] |= 2; - //SendNetXCmd4(XD_WEAPONPREF, buf, 1); + SendNetXCmd4(XD_WEAPONPREF, buf, 1); } static void Got_WeaponPref(UINT8 **cp,INT32 playernum) diff --git a/src/g_game.c b/src/g_game.c index 65f80109..7e4a4f4b 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2109,8 +2109,6 @@ void G_Ticker(boolean run) if (playeringame[i]) { - G_CopyTiccmd(cmd, &netcmds[buf][i], 1); - // SRB2kart // Save the dir the player is holding // to allow items to be thrown forward or backward. @@ -2120,6 +2118,8 @@ void G_Ticker(boolean run) players[i].kartstuff[k_throwdir] = -1; else players[i].kartstuff[k_throwdir] = 0; + + G_CopyTiccmd(cmd, &netcmds[buf][i], 1); } } diff --git a/src/hu_stuff.c b/src/hu_stuff.c index e46080e0..69e2a9dd 100644 --- a/src/hu_stuff.c +++ b/src/hu_stuff.c @@ -1802,7 +1802,7 @@ static void HU_DrawRankings(void) HU_DrawDualTabRankings(32, 32, tab, scorelines, whiteplayer); // draw spectators in a ticker across the bottom - if ((!splitscreen || !splitscreen3 || !splitscreen4) && G_GametypeHasSpectators()) + if (!(splitscreen || splitscreen3 || splitscreen4) && G_GametypeHasSpectators()) HU_DrawSpectatorTicker(); } diff --git a/src/p_mobj.c b/src/p_mobj.c index 8de54718..62bb3746 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6136,7 +6136,7 @@ void P_RunOverlays(void) if (!mo->target) continue; - if (!splitscreen /*&& rendermode != render_soft*/) + if (!(splitscreen || splitscreen3 || splitscreen4) /*&& rendermode != render_soft*/) { angle_t viewingangle; @@ -6779,8 +6779,7 @@ void P_MobjThinker(mobj_t *mobj) fixed_t scale = mobj->target->scale; mobj->color = mobj->target->color; - if ((splitscreen || !netgame) - || gametype == GT_RACE + if (!netgame || gametype == GT_RACE || mobj->target->player == &players[displayplayer] || mobj->target->player->kartstuff[k_balloon] <= 0 || (mobj->target->player->mo->flags2 & MF2_DONTDRAW)) @@ -8096,7 +8095,7 @@ void P_MobjThinker(mobj_t *mobj) CONS_Printf(M_GetText("The %c%s%c has returned to base.\n"), 0x85, M_GetText("Red flag"), 0x80); // Assumedly in splitscreen players will be on opposing teams - if (players[consoleplayer].ctfteam == 1 || splitscreen) + if (players[consoleplayer].ctfteam == 1 || (splitscreen || splitscreen3 || splitscreen4)) S_StartSound(NULL, sfx_hoop1); redflag = flagmo; @@ -8107,7 +8106,7 @@ void P_MobjThinker(mobj_t *mobj) CONS_Printf(M_GetText("The %c%s%c has returned to base.\n"), 0x84, M_GetText("Blue flag"), 0x80); // Assumedly in splitscreen players will be on opposing teams - if (players[consoleplayer].ctfteam == 2 || splitscreen) + if (players[consoleplayer].ctfteam == 2 || (splitscreen || splitscreen3 || splitscreen4)) S_StartSound(NULL, sfx_hoop1); blueflag = flagmo; diff --git a/src/p_setup.c b/src/p_setup.c index 6086a346..1c57fd56 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2354,10 +2354,20 @@ static void P_ForceCharacter(const char *forcecharskin) if (netgame) { char skincmd[33]; - if (splitscreen) + if (splitscreen || splitscreen3 || splitscreen4) { sprintf(skincmd, "skin2 %s\n", forcecharskin); CV_Set(&cv_skin2, forcecharskin); + if (splitscreen3 || splitscreen4) + { + sprintf(skincmd, "skin3 %s\n", forcecharskin); + CV_Set(&cv_skin3, forcecharskin); + if (splitscreen4) + { + sprintf(skincmd, "skin4 %s\n", forcecharskin); + CV_Set(&cv_skin4, forcecharskin); + } + } } sprintf(skincmd, "skin %s\n", forcecharskin); @@ -2920,10 +2930,20 @@ boolean P_SetupLevel(boolean skipprecip) if (!cv_cam2_rotate.changed) CV_Set(&cv_cam2_rotate, cv_cam2_rotate.defaultvalue); + if (!cv_cam3_rotate.changed) + CV_Set(&cv_cam3_rotate, cv_cam3_rotate.defaultvalue); + + if (!cv_cam4_rotate.changed) + CV_Set(&cv_cam4_rotate, cv_cam4_rotate.defaultvalue); + if (!cv_analog.changed) CV_SetValue(&cv_analog, 0); if (!cv_analog2.changed) CV_SetValue(&cv_analog2, 0); + if (!cv_analog3.changed) + CV_SetValue(&cv_analog3, 0); + if (!cv_analog4.changed) + CV_SetValue(&cv_analog4, 0); #ifdef HWRENDER if (rendermode != render_soft && rendermode != render_none) @@ -2936,13 +2956,21 @@ boolean P_SetupLevel(boolean skipprecip) if (cv_useranalog.value) CV_SetValue(&cv_analog, true); - if (splitscreen && cv_useranalog2.value) + if ((splitscreen || splitscreen3 || splitscreen4) && cv_useranalog2.value) CV_SetValue(&cv_analog2, true); else if (botingame) CV_SetValue(&cv_analog2, true); + if ((splitscreen3 || splitscreen4) && cv_useranalog3.value) + CV_SetValue(&cv_analog3, true); + + if (splitscreen4 && cv_useranalog4.value) + CV_SetValue(&cv_analog4, true); + if (twodlevel) { + CV_SetValue(&cv_analog4, false); + CV_SetValue(&cv_analog3, false); CV_SetValue(&cv_analog2, false); CV_SetValue(&cv_analog, false); } @@ -2998,7 +3026,7 @@ boolean P_SetupLevel(boolean skipprecip) savedata.lives = 0; } - skyVisible = skyVisible1 = skyVisible2 = true; // assume the skybox is visible on level load. + skyVisible = skyVisible1 = skyVisible2 = skyVisible3 = skyVisible4 = true; // assume the skybox is visible on level load. if (loadprecip) // uglier hack { // to make a newly loaded level start on the second frame. INT32 buf = gametic % BACKUPTICS; diff --git a/src/p_spec.c b/src/p_spec.c index 693cf2b7..feb87b2c 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3898,7 +3898,7 @@ DoneSection2: HU_SetCEchoDuration(5); HU_DoCEcho(va(M_GetText("%s\\captured the blue flag.\\\\\\\\"), player_names[player-players])); - if (splitscreen || players[consoleplayer].ctfteam == 1) + if ((splitscreen || splitscreen3 || splitscreen4) || players[consoleplayer].ctfteam == 1) S_StartSound(NULL, sfx_flgcap); else if (players[consoleplayer].ctfteam == 2) S_StartSound(NULL, sfx_lose); @@ -3931,7 +3931,7 @@ DoneSection2: HU_SetCEchoDuration(5); HU_DoCEcho(va(M_GetText("%s\\captured the red flag.\\\\\\\\"), player_names[player-players])); - if (splitscreen || players[consoleplayer].ctfteam == 2) + if ((splitscreen || splitscreen3 || splitscreen4) || players[consoleplayer].ctfteam == 2) S_StartSound(NULL, sfx_flgcap); else if (players[consoleplayer].ctfteam == 1) S_StartSound(NULL, sfx_lose); @@ -4189,7 +4189,7 @@ DoneSection2: if (P_IsLocalPlayer(player)) { // SRB2kart 200117 - if (!splitscreen) + if (!(splitscreen || splitscreen3 || splitscreen4)) { if (player->kartstuff[k_position] == 1) S_ChangeMusicInternal("karwin", true); diff --git a/src/p_user.c b/src/p_user.c index 67a89360..f8649a10 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -1663,7 +1663,7 @@ void P_DoPlayerExit(player_t *player) if (P_IsLocalPlayer(player) && cv_inttime.value > 0) { - if (!splitscreen) + if (!(splitscreen || splitscreen3 || splitscreen4)) { if (player->kartstuff[k_position] == 1) S_ChangeMusicInternal("karwin", true); @@ -2388,7 +2388,7 @@ static void P_DoPlayerHeadSigns(player_t *player) { // Spawn a got-flag message over the head of the player that // has it (but not on your own screen if you have the flag). - if (splitscreen || player != &players[consoleplayer]) + if ((splitscreen || splitscreen3 || splitscreen4) || player != &players[consoleplayer]) { if (player->gotflag & GF_REDFLAG) { @@ -8840,7 +8840,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall } // Make player translucent if camera is too close (only in single player). - /*if (!(multiplayer || netgame) && !splitscreen) + /*if (!(multiplayer || netgame) && !(splitscreen || splitscreen3 || splitscreen4)) { fixed_t vx = 0, vy = 0; if (player->awayviewtics) { @@ -9377,7 +9377,7 @@ void P_PlayerThink(player_t *player) player->realtime = 0; } - if ((netgame || splitscreen) && player->spectator && cmd->buttons & BT_ATTACK && !player->powers[pw_flashing]) + if ((netgame || (splitscreen || splitscreen3 || splitscreen4)) && player->spectator && cmd->buttons & BT_ATTACK && !player->powers[pw_flashing]) { if (P_SpectatorJoinGame(player)) return; // player->mo was removed. @@ -9619,7 +9619,10 @@ void P_PlayerThink(player_t *player) if (!(player->pflags & PF_NIGHTSMODE)) { // SRB2kart - fixes boo not flashing when it should. Mega doesn't flash either. Flashing is local. - if ((player == &players[displayplayer] || (splitscreen && player == &players[secondarydisplayplayer])) + if ((player == &players[displayplayer] + || ((splitscreen || splitscreen3 || splitscreen4) && player == &players[secondarydisplayplayer]) + || ((splitscreen3 || splitscreen4) && player == &players[thirddisplayplayer]) + || (splitscreen4 && player == &players[fourthdisplayplayer])) && player->kartstuff[k_bootimer] == 0 && player->kartstuff[k_growshrinktimer] <= 0 && (player->kartstuff[k_comebacktimer] == 0 || (gametype == GT_RACE || player->kartstuff[k_balloon] > 0))) { diff --git a/src/r_main.c b/src/r_main.c index 1c9e8744..a4840692 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -195,12 +195,12 @@ void SplitScreen_OnChange(void) CL_AddSplitscreenPlayer(); else CL_RemoveSplitscreenPlayer(secondarydisplayplayer); - + if (splitscreen3 || splitscreen4) CL_AddSplitscreenPlayer(); else CL_RemoveSplitscreenPlayer(thirddisplayplayer); - + if (splitscreen4) CL_AddSplitscreenPlayer(); else diff --git a/src/r_state.h b/src/r_state.h index 49d0457b..8436413b 100644 --- a/src/r_state.h +++ b/src/r_state.h @@ -85,7 +85,7 @@ extern side_t *sides; extern fixed_t viewx, viewy, viewz; extern angle_t viewangle, aimingangle; extern boolean viewsky, skyVisible; -extern boolean skyVisible1, skyVisible2; // saved values of skyVisible for P1 and P2, for splitscreen +extern boolean skyVisible1, skyVisible2, skyVisible3, skyVisible4; // saved values of skyVisible for P1 and P2, for splitscreen extern sector_t *viewsector; extern player_t *viewplayer; extern UINT8 portalrender; diff --git a/src/st_stuff.c b/src/st_stuff.c index cd774f30..c3aee555 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -229,7 +229,7 @@ void ST_doPaletteStuff(void) if (rendermode != render_none) { V_SetPaletteLump(GetPalette()); // Reset the palette - if (!splitscreen) + if (!(splitscreen || splitscreen3 || splitscreen4)) V_SetPalette(palette); } } @@ -445,7 +445,7 @@ static INT32 SCY(INT32 y) // do not scale to resolution for hardware accelerated // because these modes always scale by default y = SCZ(y); // scale to resolution - if (splitscreen) + if (splitscreen || splitscreen3 || splitscreen4) { y >>= 1; if (stplyr != &players[displayplayer]) @@ -459,7 +459,7 @@ static INT32 STRINGY(INT32 y) //31/10/99: fixed by Hurdler so it _works_ also in hardware mode // do not scale to resolution for hardware accelerated // because these modes always scale by default - if (splitscreen) + if (splitscreen || splitscreen3 || splitscreen4) { y >>= 1; if (stplyr != &players[displayplayer]) @@ -472,7 +472,7 @@ static INT32 STRINGY(INT32 y) static INT32 SPLITFLAGS(INT32 f) { // Pass this V_SNAPTO(TOP|BOTTOM) and it'll trim them to account for splitscreen! -Red - if (splitscreen) + if (splitscreen || splitscreen3 || splitscreen4) { if (stplyr != &players[displayplayer]) f &= ~V_SNAPTOTOP; @@ -496,7 +496,7 @@ static INT32 SCR(INT32 r) // do not scale to resolution for hardware accelerated // because these modes always scale by default y = FixedMul(r*FRACUNIT, vid.fdupy); // scale to resolution - if (splitscreen) + if (splitscreen || splitscreen3 || splitscreen4) { y >>= 1; if (stplyr != &players[displayplayer]) @@ -668,7 +668,7 @@ static void ST_drawTime(void) ST_DrawPatchFromHudWS(HUD_TIMECOLON, sbocolon); // Colon ST_DrawPadNumFromHudWS(HUD_SECONDS, seconds, 2); // Seconds - if (!splitscreen && (cv_timetic.value == 2 || modeattacking)) // there's not enough room for tics in splitscreen, don't even bother trying! + if (!(splitscreen || splitscreen3 || splitscreen4) && (cv_timetic.value == 2 || modeattacking)) // there's not enough room for tics in splitscreen, don't even bother trying! { ST_DrawPatchFromHud(HUD_TIMETICCOLON, sboperiod); // Period ST_DrawPadNumFromHud(HUD_TICS, tictrn, 2); // Tics @@ -700,7 +700,7 @@ static inline void ST_drawRings(void) /* static void ST_drawLives(void) // SRB2kart - unused. { - const INT32 v_splitflag = (splitscreen && stplyr == &players[displayplayer] ? V_SPLITSCREEN : 0); + const INT32 v_splitflag = ((splitscreen || splitscreen3 || splitscreen4) && stplyr == &players[displayplayer] ? V_SPLITSCREEN : 0); if (!stplyr->skincolor) return; // Just joined a server, skin isn't loaded yet! @@ -838,7 +838,7 @@ static void ST_drawFirstPersonHUD(void) if (p) { - if (splitscreen) + if (splitscreen || splitscreen3 || splitscreen4) V_DrawSmallScaledPatch(312, STRINGY(24), V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, p); else V_DrawScaledPatch(304, 24, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, p); @@ -848,7 +848,7 @@ static void ST_drawFirstPersonHUD(void) invulntime = player->powers[pw_flashing] ? 1 : player->powers[pw_invulnerability]; if (invulntime > 3*TICRATE || (invulntime && leveltime & 1)) { - if (splitscreen) + if (splitscreen || splitscreen3 || splitscreen4) V_DrawSmallScaledPatch(312, STRINGY(24) + 14, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, invincibility); else V_DrawScaledPatch(304, 24 + 28, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, invincibility); @@ -856,7 +856,7 @@ static void ST_drawFirstPersonHUD(void) if (player->powers[pw_sneakers] > 3*TICRATE || (player->powers[pw_sneakers] && leveltime & 1)) { - if (splitscreen) + if (splitscreen || splitscreen3 || splitscreen4) V_DrawSmallScaledPatch(312, STRINGY(24) + 28, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, sneakers); else V_DrawScaledPatch(304, 24 + 56, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, sneakers); @@ -1620,11 +1620,11 @@ static void ST_drawCTFHUD(void) // SRB2kart - unused. static inline void ST_drawTeamName(void) { if (stplyr->ctfteam == 1) - V_DrawString(256, (splitscreen) ? STRINGY(184) : STRINGY(192), V_HUDTRANSHALF, "RED TEAM"); + V_DrawString(256, (splitscreen || splitscreen3 || splitscreen4) ? STRINGY(184) : STRINGY(192), V_HUDTRANSHALF, "RED TEAM"); else if (stplyr->ctfteam == 2) - V_DrawString(248, (splitscreen) ? STRINGY(184) : STRINGY(192), V_HUDTRANSHALF, "BLUE TEAM"); + V_DrawString(248, (splitscreen || splitscreen3 || splitscreen4) ? STRINGY(184) : STRINGY(192), V_HUDTRANSHALF, "BLUE TEAM"); else - V_DrawString(244, (splitscreen) ? STRINGY(184) : STRINGY(192), V_HUDTRANSHALF, "SPECTATOR"); + V_DrawString(244, (splitscreen || splitscreen3 || splitscreen4) ? STRINGY(184) : STRINGY(192), V_HUDTRANSHALF, "SPECTATOR"); } /* @@ -1914,7 +1914,7 @@ static void ST_overlayDrawer(void) ) ST_drawLevelTitle(); - if (!hu_showscores && !splitscreen && netgame && displayplayer == consoleplayer) + if (!hu_showscores && !(splitscreen || splitscreen3 || splitscreen4) && netgame && displayplayer == consoleplayer) { if (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1) V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), 0, M_GetText("Press F12 to watch another player.")); diff --git a/src/v_video.c b/src/v_video.c index bda2f5e8..a5d5f86b 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -1977,7 +1977,7 @@ void V_DoPostProcessor(INT32 view, postimg_t type, INT32 param) return; #endif - if (view < 0 || view >= 2 || (view == 1 && !splitscreen)) + if (view < 0 || view >= 2 || (view == 1 && !(splitscreen || splitscreen3 || splitscreen4))) return; if (splitscreen) From 1f958091df3077e2214108e588981e5ab5405d2c Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 17 Dec 2017 16:33:21 -0500 Subject: [PATCH 2/4] OpenGL rendering --- src/d_main.c | 52 ++++++++++++ src/hardware/hw_draw.c | 2 +- src/hardware/hw_light.c | 2 +- src/hardware/hw_main.c | 134 +++++++++++++++++++++---------- src/hardware/hw_main.h | 4 +- src/hardware/r_opengl/r_opengl.c | 7 +- src/p_setup.c | 2 +- src/p_tick.c | 4 +- 8 files changed, 155 insertions(+), 52 deletions(-) diff --git a/src/d_main.c b/src/d_main.c index 6e469aad..035e4f4d 100644 --- a/src/d_main.c +++ b/src/d_main.c @@ -424,11 +424,63 @@ static void D_Display(void) } } + // render the third screen + if ((splitscreen3 || splitscreen4) && players[thirddisplayplayer].mo) + { +#ifdef HWRENDER + if (rendermode != render_soft) + HWR_RenderPlayerView(2, &players[thirddisplayplayer]); + //else +#endif + /*if (rendermode != render_none) + { + if (splitscreen3 || splitscreen4) + viewwindowx = vid.width / 2; + viewwindowy = vid.height / 2; + M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0])); + + topleft = screens[0] + viewwindowy*vid.width + viewwindowx; + + R_RenderPlayerView(&players[secondarydisplayplayer]); + + viewwindowy = 0; + M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0])); + }*/ + } + + // render the fourth screen + if (splitscreen4 && players[fourthdisplayplayer].mo) + { +#ifdef HWRENDER + if (rendermode != render_soft) + HWR_RenderPlayerView(3, &players[fourthdisplayplayer]); + //else +#endif + /*if (rendermode != render_none) + { + if (splitscreen3 || splitscreen4) + viewwindowx = vid.width / 2; + viewwindowy = vid.height / 2; + M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0])); + + topleft = screens[0] + viewwindowy*vid.width + viewwindowx; + + R_RenderPlayerView(&players[secondarydisplayplayer]); + + viewwindowy = 0; + M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0])); + }*/ + } + // Image postprocessing effect if (postimgtype) V_DoPostProcessor(0, postimgtype, postimgparam); if (postimgtype2) V_DoPostProcessor(1, postimgtype2, postimgparam2); + if (postimgtype3) + V_DoPostProcessor(2, postimgtype3, postimgparam3); + if (postimgtype4) + V_DoPostProcessor(3, postimgtype4, postimgparam4); } if (lastdraw) diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index f23753ee..6c8b3dbf 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -512,7 +512,7 @@ void HWR_DrawViewBorder(INT32 clearlines) baseviewwidth = FixedInt(FixedDiv(FLOAT_TO_FIXED(gr_viewwidth), vid.fdupx)); //(cv_viewsize.value * BASEVIDWIDTH/10)&~7; baseviewheight = FixedInt(FixedDiv(FLOAT_TO_FIXED(gr_viewheight), vid.fdupy)); top = FixedInt(FixedDiv(FLOAT_TO_FIXED(gr_baseviewwindowy), vid.fdupy)); - side = FixedInt(FixedDiv(FLOAT_TO_FIXED(gr_viewwindowx), vid.fdupx)); + side = FixedInt(FixedDiv(FLOAT_TO_FIXED(gr_baseviewwindowx), vid.fdupx)); // top HWR_DrawFlatFill(0, 0, diff --git a/src/hardware/hw_light.c b/src/hardware/hw_light.c index fe4be9be..eeb5afbd 100644 --- a/src/hardware/hw_light.c +++ b/src/hardware/hw_light.c @@ -45,7 +45,7 @@ #define LIGHTMAPFLAGS (PF_Modulated|PF_Additive|PF_Clip) #ifdef ALAM_LIGHTING -static dynlights_t view_dynlights[2]; // 2 players in splitscreen mode +static dynlights_t view_dynlights[4]; // 4 players for splitscreen modes static dynlights_t *dynlights = &view_dynlights[0]; #endif diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 3797e94b..e3eb1a7e 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -328,14 +328,18 @@ static angle_t gr_xtoviewangle[MAXVIDWIDTH+1]; // base values set at SetViewSize static float gr_basecentery; +static float gr_basecenterx; float gr_baseviewwindowy, gr_basewindowcentery; +float gr_baseviewwindowx, gr_basewindowcenterx; float gr_viewwidth, gr_viewheight; // viewport clipping boundaries (screen coords) -float gr_viewwindowx; -static float gr_centerx, gr_centery; -static float gr_viewwindowy; // top left corner of view window +static float gr_centerx; +static float gr_viewwindowx; static float gr_windowcenterx; // center of view window, for projection + +static float gr_centery; +static float gr_viewwindowy; // top left corner of view window static float gr_windowcentery; static float gr_pspritexscale, gr_pspriteyscale; @@ -4055,15 +4059,15 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float t angle_t shadowdir; // Set direction - if ((splitscreen || splitscreen3 || splitscreen4) && stplyr != &players[displayplayer]) + if ((splitscreen || splitscreen3 || splitscreen4) && stplyr == &players[secondarydisplayplayer]) { shadowdir = localangle2 + FixedAngle(cv_cam2_rotate.value); - if ((splitscreen3 || splitscreen4) && stplyr != &players[displayplayer]) + if ((splitscreen3 || splitscreen4) && stplyr == &players[thirddisplayplayer]) { shadowdir = localangle3 + FixedAngle(cv_cam3_rotate.value); - if (splitscreen4 && stplyr != &players[displayplayer]) + if (splitscreen4 && stplyr == &players[fourthdisplayplayer]) shadowdir = localangle4 + FixedAngle(cv_cam4_rotate.value); } } @@ -5512,26 +5516,22 @@ void HWR_SetViewSize(void) gr_viewwidth = (float)vid.width; gr_viewheight = (float)vid.height; - if (splitscreen) + if (splitscreen || splitscreen3 || splitscreen4) gr_viewheight /= 2; - gr_centerx = gr_viewwidth / 2; - gr_basecentery = gr_viewheight / 2; //note: this is (gr_centerx * gr_viewheight / gr_viewwidth) + if (splitscreen3 || splitscreen4) + gr_viewwidth /= 2; - gr_viewwindowx = (vid.width - gr_viewwidth) / 2; - gr_windowcenterx = (float)(vid.width / 2); - if (gr_viewwidth == vid.width) - { - gr_baseviewwindowy = 0; - gr_basewindowcentery = gr_viewheight / 2; // window top left corner at 0,0 - } - else - { - gr_baseviewwindowy = (vid.height-gr_viewheight) / 2; - gr_basewindowcentery = (float)(vid.height / 2); - } + gr_basecenterx = gr_viewwidth / 2; + gr_basecentery = gr_viewheight / 2; - gr_pspritexscale = gr_viewwidth / BASEVIDWIDTH; + gr_baseviewwindowy = 0; + gr_basewindowcentery = (float)(gr_viewheight / 2); + + gr_baseviewwindowx = 0; + gr_basewindowcenterx = (float)(gr_viewwidth / 2); + + gr_pspritexscale = ((vid.width*gr_pspriteyscale*BASEVIDHEIGHT)/BASEVIDWIDTH)/vid.height; gr_pspriteyscale = ((vid.height*gr_pspritexscale*BASEVIDWIDTH)/BASEVIDHEIGHT)/vid.width; } @@ -5574,19 +5574,23 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) dup_viewangle = viewangle; // set window position + gr_centerx = gr_basecenterx; + gr_viewwindowx = gr_baseviewwindowx; + gr_windowcenterx = gr_basewindowcenterx; gr_centery = gr_basecentery; gr_viewwindowy = gr_baseviewwindowy; gr_windowcentery = gr_basewindowcentery; - if ((splitscreen || splitscreen3) && (viewnumber == 1 || viewnumber == 2)) + + if ((splitscreen && viewnumber == 1) || ((splitscreen3 || splitscreen4) && viewnumber >= 2)) { - gr_viewwindowy += (vid.height/2); - gr_windowcentery += (vid.height/2); + gr_viewwindowy += gr_viewheight; + gr_windowcentery += gr_viewheight; } - if (splitscreen4 && (viewnumber == 2 || viewnumber == 3)) + if ((splitscreen3 || splitscreen4) && (viewnumber == 1 || viewnumber == 3)) { - gr_viewwindowy += (vid.height/2); - gr_windowcentery += (vid.height/2); + gr_viewwindowx += gr_viewwidth; + gr_windowcenterx += gr_viewwidth; } // check for new console commands. @@ -5619,7 +5623,15 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) atransform.scalez = 1; atransform.fovxangle = fpov; // Tails atransform.fovyangle = fpov; // Tails - atransform.splitscreen = splitscreen; + + if (splitscreen4) + atransform.splitscreen = 3; + else if (splitscreen3) + atransform.splitscreen = 2; + else if (splitscreen) + atransform.splitscreen = 1; + else + atransform.splitscreen = 0; // Transform for sprites stransform.anglex = 0.0f; @@ -5638,7 +5650,15 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player) stransform.scalez = 1; stransform.fovxangle = 90.0f; stransform.fovyangle = 90.0f; - stransform.splitscreen = splitscreen; + + if (splitscreen4) + stransform.splitscreen = 3; + else if (splitscreen3) + stransform.splitscreen = 2; + else if (splitscreen) + stransform.splitscreen = 1; + else + stransform.splitscreen = 0; gr_fovlud = (float)(1.0l/tan((double)(fpov*M_PIl/360l))); @@ -5661,7 +5681,7 @@ if (0) #endif //Hurdler: it doesn't work in splitscreen mode - drawsky = splitscreen || splitscreen3 || splitscreen4; + drawsky = (splitscreen || splitscreen3 || splitscreen4); HWR_ClearSprites(); @@ -5818,19 +5838,23 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) dup_viewangle = viewangle; // set window position + gr_centerx = gr_basecenterx; + gr_viewwindowx = gr_baseviewwindowx; + gr_windowcenterx = gr_basewindowcenterx; gr_centery = gr_basecentery; gr_viewwindowy = gr_baseviewwindowy; gr_windowcentery = gr_basewindowcentery; - if ((splitscreen || splitscreen3) && (viewnumber == 1 || viewnumber == 2)) + + if ((splitscreen && viewnumber == 1) || ((splitscreen3 || splitscreen4) && viewnumber >= 2)) { - gr_viewwindowy += (vid.height/2); - gr_windowcentery += (vid.height/2); + gr_viewwindowy += gr_viewheight; + gr_windowcentery += gr_viewheight; } - if (splitscreen4 && (viewnumber == 2 || viewnumber == 3)) + if ((splitscreen3 || splitscreen4) && (viewnumber == 1 || viewnumber == 3)) { - gr_viewwindowy += (vid.height/2); - gr_windowcentery += (vid.height/2); + gr_viewwindowx += gr_viewwidth; + gr_windowcenterx += gr_viewwidth; } // check for new console commands. @@ -5863,7 +5887,15 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) atransform.scalez = 1; atransform.fovxangle = fpov; // Tails atransform.fovyangle = fpov; // Tails - atransform.splitscreen = splitscreen; + + if (splitscreen4) + atransform.splitscreen = 3; + else if (splitscreen3) + atransform.splitscreen = 2; + else if (splitscreen) + atransform.splitscreen = 1; + else + atransform.splitscreen = 0; // Transform for sprites stransform.anglex = 0.0f; @@ -5882,7 +5914,15 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player) stransform.scalez = 1; stransform.fovxangle = 90.0f; stransform.fovyangle = 90.0f; - stransform.splitscreen = splitscreen; + + if (splitscreen4) + stransform.splitscreen = 3; + else if (splitscreen3) + stransform.splitscreen = 2; + else if (splitscreen) + stransform.splitscreen = 1; + else + stransform.splitscreen = 0; gr_fovlud = (float)(1.0l/tan((double)(fpov*M_PIl/360l))); @@ -5905,7 +5945,7 @@ if (0) #endif //Hurdler: it doesn't work in splitscreen mode - drawsky = splitscreen; + drawsky = (splitscreen || splitscreen3 || splitscreen4); HWR_ClearSprites(); @@ -5925,8 +5965,12 @@ if (0) // Make a viewangle int so we can render things based on mouselook if (player == &players[consoleplayer]) viewangle = localaiming; - else if (splitscreen && player == &players[secondarydisplayplayer]) + else if ((splitscreen || splitscreen3 || splitscreen4) && player == &players[secondarydisplayplayer]) viewangle = localaiming2; + else if ((splitscreen3 || splitscreen4) && player == &players[thirddisplayplayer]) + viewangle = localaiming3; + else if (splitscreen4 && player == &players[fourthdisplayplayer]) + viewangle = localaiming4; // Handle stuff when you are looking farther up or down. if ((aimingangle || cv_grfov.value+player->fovadd > 90*FRACUNIT)) @@ -6413,7 +6457,11 @@ void HWR_DoPostProcessor(player_t *player) { postimg_t *type; - if (splitscreen && player == &players[secondarydisplayplayer]) + if (splitscreen4 && player == &players[fourthdisplayplayer]) + type = &postimgtype4; + else if ((splitscreen3 || splitscreen4) && player == &players[thirddisplayplayer]) + type = &postimgtype3; + else if ((splitscreen || splitscreen3 || splitscreen4) && player == &players[secondarydisplayplayer]) type = &postimgtype2; else type = &postimgtype; @@ -6447,7 +6495,7 @@ void HWR_DoPostProcessor(player_t *player) if(gamestate != GS_INTERMISSION) HWD.pfnMakeScreenTexture(); - if (splitscreen) // Not supported in splitscreen - someone want to add support? + if (splitscreen || splitscreen3 || splitscreen4) // Not supported in splitscreen - someone want to add support? return; #ifdef SHUFFLE diff --git a/src/hardware/hw_main.h b/src/hardware/hw_main.h index b0a14d3b..fce17062 100644 --- a/src/hardware/hw_main.h +++ b/src/hardware/hw_main.h @@ -96,9 +96,9 @@ extern consvar_t cv_voodoocompatibility; extern consvar_t cv_grfovchange; extern consvar_t cv_grsolvetjoin; -extern float gr_viewwidth, gr_viewheight, gr_baseviewwindowy; +extern float gr_viewwidth, gr_viewheight, gr_baseviewwindowx, gr_baseviewwindowy; -extern float gr_viewwindowx, gr_basewindowcentery; +extern float gr_basewindowcenterx, gr_basewindowcentery; // BP: big hack for a test in lighting ref : 1249753487AB extern fixed_t *hwbbox; diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index e6ff83e8..8be35e4a 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2024,8 +2024,11 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) pglMatrixMode(GL_PROJECTION); pglLoadIdentity(); - special_splitscreen = (stransform->splitscreen && stransform->fovxangle == 90.0f); - if (special_splitscreen) + if (stransform->splitscreen == 1 && stransform->fovxangle == 90.0f); + special_splitscreen = stransform->splitscreen; + if (special_splitscreen > 1) + GLPerspective(53.13l, ASPECT_RATIO); + else if (special_splitscreen == 1) GLPerspective(53.13l, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5) else GLPerspective(stransform->fovxangle, ASPECT_RATIO); diff --git a/src/p_setup.c b/src/p_setup.c index 1c57fd56..e18c24c1 100644 --- a/src/p_setup.c +++ b/src/p_setup.c @@ -2593,7 +2593,7 @@ boolean P_SetupLevel(boolean skipprecip) P_LevelInitStuff(); - postimgtype = postimgtype2 = postimg_none; + postimgtype = postimgtype2 = postimgtype3 = postimgtype4 = postimg_none; if (mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0' && atoi(mapheaderinfo[gamemap-1]->forcecharacter) != 255) diff --git a/src/p_tick.c b/src/p_tick.c index 7ea98435..658e5325 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -591,7 +591,7 @@ void P_Ticker(boolean run) if (paused || P_AutoPause()) return; - postimgtype = postimgtype2 = postimg_none; + postimgtype = postimgtype2 = postimgtype3 = postimgtype4 = postimg_none; P_MapStart(); @@ -711,7 +711,7 @@ void P_PreTicker(INT32 frames) INT32 i,framecnt; ticcmd_t temptic; - postimgtype = postimgtype2 = postimg_none; + postimgtype = postimgtype2 = postimgtype3 = postimgtype4 = postimg_none; for (framecnt = 0; framecnt < frames; ++framecnt) { From 654e5e482bee7c81c73ff63413931d8e01ca9a61 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 17 Dec 2017 17:01:19 -0500 Subject: [PATCH 3/4] Mess with camera distance stuff Also fixed a bug where I made all of the screens in 3p/4p mode in OpenGL too zoomed in --- src/hardware/r_opengl/r_opengl.c | 6 ++---- src/p_user.c | 12 +++++++++--- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 8be35e4a..385b1fce 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -2026,9 +2026,7 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) pglLoadIdentity(); if (stransform->splitscreen == 1 && stransform->fovxangle == 90.0f); special_splitscreen = stransform->splitscreen; - if (special_splitscreen > 1) - GLPerspective(53.13l, ASPECT_RATIO); - else if (special_splitscreen == 1) + if (special_splitscreen == 1) GLPerspective(53.13l, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5) else GLPerspective(stransform->fovxangle, ASPECT_RATIO); @@ -2043,7 +2041,7 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform) pglMatrixMode(GL_PROJECTION); pglLoadIdentity(); - if (special_splitscreen) + if (special_splitscreen == 1) GLPerspective(53.13l, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5) else //Hurdler: is "fov" correct? diff --git a/src/p_user.c b/src/p_user.c index f8649a10..926be4cc 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8506,18 +8506,24 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall { dist = camdist; - if (splitscreen || splitscreen3 || splitscreen4) // x1.5 dist for splitscreen + // in splitscreen, mess with the camera distances to make it feel proportional to how it feels normally + if (splitscreen) // widescreen splits should get farther distance { dist = FixedMul(dist, 3*FRACUNIT/2); height = FixedMul(height, 3*FRACUNIT/2); } + else if (splitscreen3 || splitscreen4) // small screen splits should get a shorter distance (yes, oddly enough that feels better) + { + dist = FixedMul(dist, 7*FRACUNIT/8); + height = FixedMul(height, 7*FRACUNIT/8); + } // x1.2 dist for analog - if (P_AnalogMove(player)) + /*if (P_AnalogMove(player)) { dist = FixedMul(dist, 6*FRACUNIT/5); height = FixedMul(height, 6*FRACUNIT/5); - } + }*/ if (player->climbing || player->exiting || player->playerstate == PST_DEAD || (player->pflags & (PF_MACESPIN|PF_ITEMHANG|PF_ROPEHANG))) dist <<= 1; From d2425329cab3cfc412668ec00484c5b948759d85 Mon Sep 17 00:00:00 2001 From: TehRealSalt Date: Sun, 17 Dec 2017 20:42:17 -0500 Subject: [PATCH 4/4] HUD --- src/dehacked.c | 2 +- src/hardware/hw_draw.c | 5 +- src/k_kart.c | 393 +++++++++++++++++++++++------------------ src/p_user.c | 6 +- src/v_video.c | 11 +- src/v_video.h | 28 +-- 6 files changed, 253 insertions(+), 192 deletions(-) diff --git a/src/dehacked.c b/src/dehacked.c index e93ab35a..7aed816e 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -7854,7 +7854,6 @@ struct { {"V_90TRANS",V_90TRANS}, {"V_HUDTRANSHALF",V_HUDTRANSHALF}, {"V_HUDTRANS",V_HUDTRANS}, - {"V_HUDTRANSDOUBLE",V_HUDTRANSDOUBLE}, {"V_AUTOFADEOUT",V_AUTOFADEOUT}, {"V_RETURN8",V_RETURN8}, {"V_OFFSET",V_OFFSET}, @@ -7868,6 +7867,7 @@ struct { {"V_WRAPY",V_WRAPY}, {"V_NOSCALESTART",V_NOSCALESTART}, {"V_SPLITSCREEN",V_SPLITSCREEN}, + {"V_HORZSCREEN",V_HORZSCREEN}, {"V_PARAMMASK",V_PARAMMASK}, {"V_SCALEPATCHMASK",V_SCALEPATCHMASK}, diff --git a/src/hardware/hw_draw.c b/src/hardware/hw_draw.c index 6c8b3dbf..108482a5 100644 --- a/src/hardware/hw_draw.c +++ b/src/hardware/hw_draw.c @@ -180,7 +180,10 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale, sdupx = sdupy = 2.0f; if (option & V_SPLITSCREEN) - sdupy /= 2.0f; + cy += FIXED_TO_FLOAT((BASEVIDHEIGHT/2)<>= 1; - if (stplyr != &players[displayplayer]) - y += BASEVIDHEIGHT / 2; - } - return y; -} - -/*static INT32 SCX(INT32 x) -{ - return FixedInt(FixedMul(x<kartstuff[k_itemclose]) { @@ -4221,11 +4205,8 @@ static void K_drawKartItemClose(void) default: break; } - if (splitscreen) - flags = 0; - if (localpatch != kp_nodraw) - V_DrawScaledPatch(ITEM_X, STRINGY(ITEM_Y), flags, localpatch); + V_DrawScaledPatch(ITEM_X, ITEM_Y, V_SNAPTORIGHT|V_SNAPTOTOP|splitflags, localpatch); } static void K_drawKartItemRoulette(void) @@ -4233,12 +4214,21 @@ static void K_drawKartItemRoulette(void) // ITEM_X = BASEVIDWIDTH-50; // 270 // ITEM_Y = 24; // 24 - INT32 flags = V_SNAPTORIGHT|V_SNAPTOTOP; - // Why write V_DrawScaledPatch calls over and over when they're all the same? // Set to 'no item' just in case. patch_t *localpatch = kp_nodraw; + INT32 splitflags = 0; + if (splitscreen && stplyr == &players[secondarydisplayplayer]) + splitflags |= V_SPLITSCREEN; + else if (splitscreen3 || splitscreen4) + { + if (stplyr == &players[thirddisplayplayer] || stplyr == &players[fourthdisplayplayer]) + splitflags |= V_SPLITSCREEN; + if (stplyr == &players[secondarydisplayplayer] || stplyr == &players[fourthdisplayplayer]) + splitflags |= V_HORZSCREEN; + } + /*if () switch(stplyr->kartstuff[k_itemroulette] % 53) { @@ -4290,9 +4280,7 @@ static void K_drawKartItemRoulette(void) default: break; } - if (splitscreen) - flags = 0; - V_DrawScaledPatch(ITEM_X, STRINGY(ITEM_Y), flags, localpatch); + V_DrawScaledPatch(ITEM_X, ITEM_Y, V_SNAPTORIGHT|V_SNAPTOTOP|splitflags, localpatch); } static void K_drawKartRetroItem(void) @@ -4300,12 +4288,21 @@ static void K_drawKartRetroItem(void) // ITEM_X = BASEVIDWIDTH-50; // 270 // ITEM_Y = 24; // 24 - INT32 flags = V_SNAPTORIGHT|V_SNAPTOTOP; - // Why write V_DrawScaledPatch calls over and over when they're all the same? // Set to 'no item' just in case. patch_t *localpatch = kp_nodraw; + INT32 splitflags = 0; + if (splitscreen && stplyr == &players[secondarydisplayplayer]) + splitflags |= V_SPLITSCREEN; + else if (splitscreen3 || splitscreen4) + { + if (stplyr == &players[thirddisplayplayer] || stplyr == &players[fourthdisplayplayer]) + splitflags |= V_SPLITSCREEN; + if (stplyr == &players[secondarydisplayplayer] || stplyr == &players[fourthdisplayplayer]) + splitflags |= V_HORZSCREEN; + } + // I'm doing this a little weird and drawing mostly in reverse order // The only actual reason is to make triple/double/single mushrooms line up this way in the code below // This shouldn't have any actual baring over how it functions @@ -4339,9 +4336,7 @@ static void K_drawKartRetroItem(void) else if (stplyr->kartstuff[k_boo] == 1) localpatch = kp_boo; else if (stplyr->kartstuff[k_magnet] == 1) localpatch = kp_magnet; - if (splitscreen) - flags = 0; - V_DrawScaledPatch(ITEM_X, STRINGY(ITEM_Y), flags, localpatch); + V_DrawScaledPatch(ITEM_X, ITEM_Y, V_SNAPTORIGHT|V_SNAPTOTOP|splitflags, localpatch); } /* @@ -4385,7 +4380,7 @@ static void K_drawKartNeoItem(void) else if (stplyr->kartstuff[k_boo] & 8) localpatch = kp_skghost; else if (stplyr->kartstuff[k_magnet] & 8) localpatch = kp_electroshield; - V_DrawScaledPatch(ITEM_X, STRINGY(ITEM_Y), V_SNAPTORIGHT|V_TRANSLUCENT, localpatch); + V_DrawScaledPatch(ITEM_X, ITEM_Y, V_SNAPTORIGHT|V_TRANSLUCENT, localpatch); } */ @@ -4439,7 +4434,7 @@ static void K_DrawKartTripleItem(void) } if (localpatch != kp_nodraw) - V_DrawScaledPatch(TRIP_X, STRINGY(TRIP_Y), V_SNAPTOBOTTOM, localpatch); + V_DrawScaledPatch(TRIP_X, TRIP_Y, V_SNAPTOBOTTOM, localpatch); } */ @@ -4449,12 +4444,19 @@ static void K_drawKartTimestamp(void) // TIME_Y = 6; // 6 INT32 TIME_XB; - INT32 flags = V_SNAPTORIGHT|V_SNAPTOTOP; - - if (splitscreen) - flags = 0; - V_DrawScaledPatch(TIME_X, STRINGY(TIME_Y), flags, kp_timestickerwide); + INT32 splitflags = 0; + if (splitscreen && stplyr == &players[secondarydisplayplayer]) + splitflags |= V_SPLITSCREEN; + else if (splitscreen3 || splitscreen4) + { + if (stplyr == &players[thirddisplayplayer] || stplyr == &players[fourthdisplayplayer]) + splitflags |= V_SPLITSCREEN; + if (stplyr == &players[secondarydisplayplayer] || stplyr == &players[fourthdisplayplayer]) + splitflags |= V_HORZSCREEN; + } + + V_DrawScaledPatch(TIME_X, TIME_Y, V_SNAPTOTOP|V_SNAPTORIGHT|splitflags, kp_timestickerwide); TIME_XB = TIME_X+33; @@ -4463,44 +4465,44 @@ static void K_drawKartTimestamp(void) // zero minute if (stplyr->realtime/(60*TICRATE) < 10) { - V_DrawKartString(TIME_XB, STRINGY(TIME_Y+3), flags, va("0")); + V_DrawKartString(TIME_XB, TIME_Y+3, V_SNAPTOTOP|V_SNAPTORIGHT|splitflags, va("0")); // minutes time 0 __ __ - V_DrawKartString(TIME_XB+12, STRINGY(TIME_Y+3), flags, va("%d", stplyr->realtime/(60*TICRATE))); + V_DrawKartString(TIME_XB+12, TIME_Y+3, V_SNAPTOTOP|V_SNAPTORIGHT|splitflags, va("%d", stplyr->realtime/(60*TICRATE))); } // minutes time 0 __ __ else - V_DrawKartString(TIME_XB, STRINGY(TIME_Y+3), flags, va("%d", stplyr->realtime/(60*TICRATE))); + V_DrawKartString(TIME_XB, TIME_Y+3, V_SNAPTOTOP|V_SNAPTORIGHT|splitflags, va("%d", stplyr->realtime/(60*TICRATE))); // apostrophe location _'__ __ - V_DrawKartString(TIME_XB+24, STRINGY(TIME_Y+3), flags, va("'")); + V_DrawKartString(TIME_XB+24, TIME_Y+3, V_SNAPTOTOP|V_SNAPTORIGHT|splitflags, va("'")); // zero second _ 0_ __ if ((stplyr->realtime/TICRATE % 60) < 10) { - V_DrawKartString(TIME_XB+36, STRINGY(TIME_Y+3), flags, va("0")); + V_DrawKartString(TIME_XB+36, TIME_Y+3, V_SNAPTOTOP|V_SNAPTORIGHT|splitflags, va("0")); // seconds time _ _0 __ - V_DrawKartString(TIME_XB+48, STRINGY(TIME_Y+3), flags, va("%d", stplyr->realtime/TICRATE % 60)); + V_DrawKartString(TIME_XB+48, TIME_Y+3, V_SNAPTOTOP|V_SNAPTORIGHT|splitflags, va("%d", stplyr->realtime/TICRATE % 60)); } // zero second _ 00 __ else - V_DrawKartString(TIME_XB+36, STRINGY(TIME_Y+3), flags, va("%d", stplyr->realtime/TICRATE % 60)); + V_DrawKartString(TIME_XB+36, TIME_Y+3, V_SNAPTOTOP|V_SNAPTORIGHT|splitflags, va("%d", stplyr->realtime/TICRATE % 60)); // quotation mark location _ __"__ - V_DrawKartString(TIME_XB+60, STRINGY(TIME_Y+3), flags, va("\"")); + V_DrawKartString(TIME_XB+60, TIME_Y+3, V_SNAPTOTOP|V_SNAPTORIGHT|splitflags, va("\"")); // zero tick _ __ 0_ if (G_TicsToCentiseconds(stplyr->realtime) < 10) { - V_DrawKartString(TIME_XB+72, STRINGY(TIME_Y+3), flags, va("0")); + V_DrawKartString(TIME_XB+72, TIME_Y+3, V_SNAPTOTOP|V_SNAPTORIGHT|splitflags, va("0")); // tics _ __ _0 - V_DrawKartString(TIME_XB+84, STRINGY(TIME_Y+3), flags, va("%d", G_TicsToCentiseconds(stplyr->realtime))); + V_DrawKartString(TIME_XB+84, TIME_Y+3, V_SNAPTOTOP|V_SNAPTORIGHT|splitflags, va("%d", G_TicsToCentiseconds(stplyr->realtime))); } // zero tick _ __ 00 if (G_TicsToCentiseconds(stplyr->realtime) >= 10) - V_DrawKartString(TIME_XB+72, STRINGY(TIME_Y+3), flags, va("%d", G_TicsToCentiseconds(stplyr->realtime))); + V_DrawKartString(TIME_XB+72, TIME_Y+3, V_SNAPTOTOP|V_SNAPTORIGHT|splitflags, va("%d", G_TicsToCentiseconds(stplyr->realtime))); } else - V_DrawKartString(TIME_XB, STRINGY(TIME_Y+3), flags, va("99'59\"99")); + V_DrawKartString(TIME_XB, TIME_Y+3, V_SNAPTORIGHT|V_SNAPTOTOP|splitflags, va("99'59\"99")); } static void K_DrawKartPositionNum(INT32 num) @@ -4510,16 +4512,23 @@ static void K_DrawKartPositionNum(INT32 num) INT32 X = POSI_X+43; // +43 to offset where it's being drawn if there are more than one INT32 W = SHORT(kp_positionnum[0][0]->width); - INT32 flags = V_TRANSLUCENT|V_SNAPTORIGHT|V_SNAPTOBOTTOM; patch_t *localpatch = kp_positionnum[0][0]; - if (splitscreen) - flags = V_TRANSLUCENT; + INT32 splitflags = 0; + if (splitscreen && stplyr == &players[secondarydisplayplayer]) + splitflags |= V_SPLITSCREEN; + else if (splitscreen3 || splitscreen4) + { + if (stplyr == &players[thirddisplayplayer] || stplyr == &players[fourthdisplayplayer]) + splitflags |= V_SPLITSCREEN; + if (stplyr == &players[secondarydisplayplayer] || stplyr == &players[fourthdisplayplayer]) + splitflags |= V_HORZSCREEN; + } // Special case for 0 if (!num) { - V_DrawTranslucentPatch(X-W, STRINGY(POSI_Y), flags, kp_positionnum[0][0]); + V_DrawTranslucentPatch(X-W, POSI_Y, V_TRANSLUCENT|V_SNAPTORIGHT|V_SNAPTOBOTTOM|splitflags, kp_positionnum[0][0]); return; } @@ -4592,7 +4601,7 @@ static void K_DrawKartPositionNum(INT32 num) else localpatch = kp_positionnum[num % 10][0]; - V_DrawTranslucentPatch(X, STRINGY(POSI_Y), flags, localpatch); + V_DrawTranslucentPatch(X, POSI_Y, V_TRANSLUCENT|V_SNAPTORIGHT|V_SNAPTOBOTTOM|splitflags, localpatch); num /= 10; } } @@ -4654,24 +4663,24 @@ static void K_drawKartPositionFaces(void) colormap = colormaps; if (rankplayer[i] != myplayer) { - V_DrawSmallTranslucentPatch(FACE_X, STRINGY(Y), V_SNAPTOLEFT, faceprefix[players[rankplayer[i]].skin]); + V_DrawSmallTranslucentPatch(FACE_X, Y, V_SNAPTOLEFT, faceprefix[players[rankplayer[i]].skin]); if (gametype == GT_MATCH && players[rankplayer[i]].kartstuff[k_balloon] > 0) { for (j = 0; j < players[rankplayer[i]].kartstuff[k_balloon]; j++) { - V_DrawSmallTranslucentPatch(balloonx, STRINGY(Y+10), V_SNAPTOLEFT, kp_rankballoon); + V_DrawSmallTranslucentPatch(balloonx, Y+10, V_SNAPTOLEFT, kp_rankballoon); balloonx += 3; } } } else { - V_DrawSmallScaledPatch(FACE_X, STRINGY(Y), V_SNAPTOLEFT, faceprefix[players[rankplayer[i]].skin]); + V_DrawSmallScaledPatch(FACE_X, Y, V_SNAPTOLEFT, faceprefix[players[rankplayer[i]].skin]); if (gametype == GT_MATCH && players[rankplayer[i]].kartstuff[k_balloon] > 0) { for (j = 0; j < players[rankplayer[i]].kartstuff[k_balloon]; j++) { - V_DrawSmallScaledPatch(balloonx, STRINGY(Y+10), V_SNAPTOLEFT, kp_rankballoon); + V_DrawSmallScaledPatch(balloonx, Y+10, V_SNAPTOLEFT, kp_rankballoon); balloonx += 3; } } @@ -4682,24 +4691,24 @@ static void K_drawKartPositionFaces(void) colormap = R_GetTranslationColormap(players[rankplayer[i]].skin, players[rankplayer[i]].mo->color, GTC_CACHE); if (rankplayer[i] != myplayer) { - V_DrawSmallTranslucentMappedPatch(FACE_X, STRINGY(Y), V_SNAPTOLEFT, faceprefix[players[rankplayer[i]].skin], colormap); + V_DrawSmallTranslucentMappedPatch(FACE_X, Y, V_SNAPTOLEFT, faceprefix[players[rankplayer[i]].skin], colormap); if (gametype == GT_MATCH && players[rankplayer[i]].kartstuff[k_balloon] > 0) { for (j = 0; j < players[rankplayer[i]].kartstuff[k_balloon]; j++) { - V_DrawSmallTranslucentMappedPatch(balloonx, STRINGY(Y+10), V_SNAPTOLEFT, kp_rankballoon, colormap); + V_DrawSmallTranslucentMappedPatch(balloonx, Y+10, V_SNAPTOLEFT, kp_rankballoon, colormap); balloonx += 3; } } } else { - V_DrawSmallMappedPatch(FACE_X, STRINGY(Y), V_SNAPTOLEFT, faceprefix[players[rankplayer[i]].skin], colormap); + V_DrawSmallMappedPatch(FACE_X, Y, V_SNAPTOLEFT, faceprefix[players[rankplayer[i]].skin], colormap); if (gametype == GT_MATCH && players[rankplayer[i]].kartstuff[k_balloon] > 0) { for (j = 0; j < players[rankplayer[i]].kartstuff[k_balloon]; j++) { - V_DrawSmallMappedPatch(balloonx, STRINGY(Y+10), V_SNAPTOLEFT, kp_rankballoon, colormap); + V_DrawSmallMappedPatch(balloonx, Y+10, V_SNAPTOLEFT, kp_rankballoon, colormap); balloonx += 3; } } @@ -4719,16 +4728,16 @@ static void K_drawKartPositionFaces(void) if (rankplayer[i] != myplayer) { if (gametype == GT_MATCH && players[rankplayer[i]].kartstuff[k_balloon] <= 0) - V_DrawSmallTranslucentPatch(FACE_X-2, STRINGY(Y), V_SNAPTOLEFT, kp_ranknoballoons); + V_DrawSmallTranslucentPatch(FACE_X-2, Y, V_SNAPTOLEFT, kp_ranknoballoons); else - V_DrawSmallTranslucentPatch(FACE_X, STRINGY(Y), V_SNAPTOLEFT, localpatch); + V_DrawSmallTranslucentPatch(FACE_X, Y, V_SNAPTOLEFT, localpatch); } else { if (gametype == GT_MATCH && players[rankplayer[i]].kartstuff[k_balloon] <= 0) - V_DrawSmallScaledPatch(FACE_X-2, STRINGY(Y), V_SNAPTOLEFT, kp_ranknoballoons); + V_DrawSmallScaledPatch(FACE_X-2, Y, V_SNAPTOLEFT, kp_ranknoballoons); else - V_DrawSmallScaledPatch(FACE_X, STRINGY(Y), V_SNAPTOLEFT, localpatch); + V_DrawSmallScaledPatch(FACE_X, Y, V_SNAPTOLEFT, localpatch); } Y += 18; @@ -4737,67 +4746,91 @@ static void K_drawKartPositionFaces(void) static void K_drawKartLaps(void) { - INT32 flags = V_SNAPTOLEFT|V_SNAPTOBOTTOM; - if (splitscreen) - flags = 0; + INT32 splitflags = 0; + if (splitscreen && stplyr == &players[secondarydisplayplayer]) + splitflags |= V_SPLITSCREEN; + else if (splitscreen3 || splitscreen4) + { + if (stplyr == &players[thirddisplayplayer] || stplyr == &players[fourthdisplayplayer]) + splitflags |= V_SPLITSCREEN; + if (stplyr == &players[secondarydisplayplayer] || stplyr == &players[fourthdisplayplayer]) + splitflags |= V_HORZSCREEN; + } - V_DrawScaledPatch(LAPS_X, STRINGY(LAPS_Y), flags, kp_lapsticker); + V_DrawScaledPatch(LAPS_X, LAPS_Y, V_SNAPTOLEFT|V_SNAPTOBOTTOM|splitflags, kp_lapsticker); if (stplyr->exiting) - V_DrawKartString(LAPS_X+33, STRINGY(LAPS_Y+3), flags, "FIN"); + V_DrawKartString(LAPS_X+33, LAPS_Y+3, V_SNAPTOLEFT|V_SNAPTOBOTTOM|splitflags, "FIN"); else - V_DrawKartString(LAPS_X+33, STRINGY(LAPS_Y+3), flags, va("%d/%d", stplyr->laps+1, cv_numlaps.value)); + V_DrawKartString(LAPS_X+33, LAPS_Y+3, V_SNAPTOLEFT|V_SNAPTOBOTTOM|splitflags, va("%d/%d", stplyr->laps+1, cv_numlaps.value)); } static void K_drawKartSpeedometer(void) { fixed_t convSpeed; - INT32 flags = V_SNAPTOLEFT|V_SNAPTOBOTTOM; - if (splitscreen) - flags = 0; + + INT32 splitflags = 0; + if (splitscreen && stplyr == &players[secondarydisplayplayer]) + splitflags |= V_SPLITSCREEN; + else if (splitscreen3 || splitscreen4) + { + if (stplyr == &players[thirddisplayplayer] || stplyr == &players[fourthdisplayplayer]) + splitflags |= V_SPLITSCREEN; + if (stplyr == &players[secondarydisplayplayer] || stplyr == &players[fourthdisplayplayer]) + splitflags |= V_HORZSCREEN; + } + if (cv_speedometer.value == 1) { convSpeed = FixedMul(stplyr->speed, 142371)/FRACUNIT; // 2.172409058 - V_DrawKartString(SPDM_X, STRINGY(SPDM_Y), flags, va("%3d km/h", convSpeed)); + V_DrawKartString(SPDM_X, SPDM_Y, V_SNAPTOLEFT|V_SNAPTOBOTTOM|splitflags, va("%3d km/h", convSpeed)); } else if (cv_speedometer.value == 2) { convSpeed = FixedMul(stplyr->speed, 88465)/FRACUNIT; // 1.349868774 - V_DrawKartString(SPDM_X, STRINGY(SPDM_Y), flags, va("%3d mph", convSpeed)); + V_DrawKartString(SPDM_X, SPDM_Y, V_SNAPTOLEFT|V_SNAPTOBOTTOM|splitflags, va("%3d mph", convSpeed)); } else if (cv_speedometer.value == 3) { convSpeed = stplyr->speed/FRACUNIT; - V_DrawKartString(SPDM_X, STRINGY(SPDM_Y), flags, va("%3d fu/s", convSpeed)); + V_DrawKartString(SPDM_X, SPDM_Y, V_SNAPTOLEFT|V_SNAPTOBOTTOM|splitflags, va("%3d fu/s", convSpeed)); } } static void K_drawKartBalloonsOrKarma(void) { UINT8 *colormap = R_GetTranslationColormap(-1, stplyr->skincolor, 0); - INT32 flags = V_SNAPTOLEFT|V_SNAPTOBOTTOM; - if (splitscreen) - flags = 0; + + INT32 splitflags = 0; + if (splitscreen && stplyr == &players[secondarydisplayplayer]) + splitflags |= V_SPLITSCREEN; + else if (splitscreen3 || splitscreen4) + { + if (stplyr == &players[thirddisplayplayer] || stplyr == &players[fourthdisplayplayer]) + splitflags |= V_SPLITSCREEN; + if (stplyr == &players[secondarydisplayplayer] || stplyr == &players[fourthdisplayplayer]) + splitflags |= V_HORZSCREEN; + } if (stplyr->kartstuff[k_balloon] <= 0) { - V_DrawScaledPatch(LAPS_X, STRINGY(LAPS_Y), flags, kp_karmasticker); - V_DrawKartString(LAPS_X+58, STRINGY(LAPS_Y+3), flags, va("%d", stplyr->kartstuff[k_comebackpoints])); - V_DrawKartString(LAPS_X+85, STRINGY(LAPS_Y+3), flags, va("3")); + V_DrawMappedPatch(LAPS_X, LAPS_Y, V_SNAPTOLEFT|V_SNAPTOBOTTOM|splitflags, kp_karmasticker, colormap); + V_DrawKartString(LAPS_X+58, LAPS_Y+3, V_SNAPTOLEFT|V_SNAPTOBOTTOM|splitflags, va("%d", stplyr->kartstuff[k_comebackpoints])); + V_DrawKartString(LAPS_X+85, LAPS_Y+3, V_SNAPTOLEFT|V_SNAPTOBOTTOM|splitflags, va("3")); } else { if (cv_kartballoons.value > 9) { - V_DrawMappedPatch(LAPS_X, STRINGY(LAPS_Y), flags, kp_balloonstickerwide, colormap); - V_DrawKartString(LAPS_X+46, STRINGY(LAPS_Y+3), flags, va("%2d", stplyr->kartstuff[k_balloon])); - V_DrawKartString(LAPS_X+83, STRINGY(LAPS_Y+3), flags, va("%2d", cv_kartballoons.value)); + V_DrawMappedPatch(LAPS_X, LAPS_Y, V_SNAPTOLEFT|V_SNAPTOBOTTOM|splitflags, kp_balloonstickerwide, colormap); + V_DrawKartString(LAPS_X+46, LAPS_Y+3, V_SNAPTOLEFT|V_SNAPTOBOTTOM|splitflags, va("%2d", stplyr->kartstuff[k_balloon])); + V_DrawKartString(LAPS_X+83, LAPS_Y+3, V_SNAPTOLEFT|V_SNAPTOBOTTOM|splitflags, va("%2d", cv_kartballoons.value)); } else { - V_DrawMappedPatch(LAPS_X, STRINGY(LAPS_Y), flags, kp_balloonsticker, colormap); - V_DrawKartString(LAPS_X+46, STRINGY(LAPS_Y+3), flags, va("%d", stplyr->kartstuff[k_balloon])); - V_DrawKartString(LAPS_X+73, STRINGY(LAPS_Y+3), flags, va("%d", cv_kartballoons.value)); + V_DrawMappedPatch(LAPS_X, LAPS_Y, V_SNAPTOLEFT|V_SNAPTOBOTTOM|splitflags, kp_balloonsticker, colormap); + V_DrawKartString(LAPS_X+46, LAPS_Y+3, V_SNAPTOLEFT|V_SNAPTOBOTTOM|splitflags, va("%d", stplyr->kartstuff[k_balloon])); + V_DrawKartString(LAPS_X+73, LAPS_Y+3, V_SNAPTOLEFT|V_SNAPTOBOTTOM|splitflags, va("%d", cv_kartballoons.value)); } } } @@ -4831,6 +4864,17 @@ static void K_drawKartPlayerCheck(void) INT32 x; patch_t *localpatch; + INT32 splitflags = 0; + if (splitscreen && stplyr == &players[secondarydisplayplayer]) + splitflags |= V_SPLITSCREEN; + else if (splitscreen3 || splitscreen4) + { + if (stplyr == &players[thirddisplayplayer] || stplyr == &players[fourthdisplayplayer]) + splitflags |= V_SPLITSCREEN; + if (stplyr == &players[secondarydisplayplayer] || stplyr == &players[fourthdisplayplayer]) + splitflags |= V_HORZSCREEN; + } + if (!(stplyr->mo)) return; @@ -4872,7 +4916,7 @@ static void K_drawKartPlayerCheck(void) x = 306; colormap = R_GetTranslationColormap(-1, players[i].mo->color, 0); - V_DrawMappedPatch(x, STRINGY(CHEK_Y), V_SNAPTOBOTTOM, localpatch, colormap); + V_DrawMappedPatch(x, CHEK_Y, V_SNAPTOBOTTOM|splitflags, localpatch, colormap); } } } @@ -4881,9 +4925,10 @@ static void K_drawBattleFullscreen(void) { INT32 y = -64+(stplyr->kartstuff[k_cardanimation]); // card animation goes from 0 to 164, 164 is the middle of the screen - if (splitscreen) + if (splitscreen || splitscreen3 || splitscreen4) { - if (stplyr != &players[displayplayer]) + if ((splitscreen && stplyr == &players[secondarydisplayplayer]) + || ((splitscreen3 || splitscreen4) && (stplyr == &players[thirddisplayplayer] || stplyr == &players[fourthdisplayplayer]))) y = 232-(stplyr->kartstuff[k_cardanimation]/2); else y = -32+(stplyr->kartstuff[k_cardanimation]/2); @@ -4926,8 +4971,8 @@ static void K_drawBattleFullscreen(void) else V_DrawScaledPatch(BASEVIDWIDTH/2, y, 0, kp_battlewait); - V_DrawScaledPatch(BASEVIDWIDTH/2, STRINGY((BASEVIDHEIGHT/2) + 66), 0, kp_timeoutsticker); - V_DrawKartString(x, STRINGY((BASEVIDHEIGHT/2) + 66), 0, va("%d", stplyr->kartstuff[k_comebacktimer]/TICRATE)); + V_DrawScaledPatch(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2) + 66, 0, kp_timeoutsticker); + V_DrawKartString(x, (BASEVIDHEIGHT/2) + 66, 0, va("%d", stplyr->kartstuff[k_comebacktimer]/TICRATE)); } } @@ -4963,7 +5008,7 @@ static void K_drawStartLakitu(void) else adjustY = 200; - V_DrawSmallScaledPatch(LAKI_X, STRINGY(LAKI_Y + adjustY), V_SNAPTOTOP, localpatch); + V_DrawSmallScaledPatch(LAKI_X, LAKI_Y + adjustY, V_SNAPTOTOP, localpatch); } static void K_drawLapLakitu(void) @@ -5033,7 +5078,7 @@ static void K_drawLapLakitu(void) adjustY = 200; } - V_DrawSmallScaledPatch(LAKI_X+14+(swoopTimer/4), STRINGY(LAKI_Y + adjustY), V_SNAPTOTOP, localpatch); + V_DrawSmallScaledPatch(LAKI_X+14+(swoopTimer/4), LAKI_Y + adjustY, V_SNAPTOTOP, localpatch); } void K_drawKartHUD(void) @@ -5043,7 +5088,12 @@ void K_drawKartHUD(void) K_initKartHUD(); // Draw full screen stuff that turns off the rest of the HUD - if ((gametype != GT_RACE) && (stplyr->exiting || (stplyr->kartstuff[k_balloon] <= 0 && stplyr->kartstuff[k_comebacktimer] && cv_kartcomeback.value && stplyr->playerstate == PST_LIVE))) + if ((gametype != GT_RACE) + && (stplyr->exiting + || (stplyr->kartstuff[k_balloon] <= 0 + && stplyr->kartstuff[k_comebacktimer] + && cv_kartcomeback.value + && stplyr->playerstate == PST_LIVE))) { K_drawBattleFullscreen(); return; @@ -5052,19 +5102,19 @@ void K_drawKartHUD(void) // Draw Lakitu // This is done first so that regardless of HUD layers, // he'll appear to be in the 'real world' - if (!splitscreen) + if (!(splitscreen || splitscreen3 || splitscreen4)) { if (leveltime < 178) K_drawStartLakitu(); if (stplyr->kartstuff[k_lapanimation]) K_drawLapLakitu(); - - // Draw the CHECK indicator before the other items too, so it's overlapped by everything else - if (cv_kartcheck.value) - K_drawKartPlayerCheck(); } + // Draw the CHECK indicator before the other items too, so it's overlapped by everything else + if (cv_kartcheck.value) + K_drawKartPlayerCheck(); + // If the item window is closing, draw it closing! if (stplyr->kartstuff[k_itemclose]) K_drawKartItemClose(); @@ -5079,16 +5129,23 @@ void K_drawKartHUD(void) K_drawKartRetroItem(); //K_DrawKartTripleItem(); - - // Draw the timestamp - K_drawKartTimestamp(); - if (!(splitscreen || modeattacking)) + // If not splitscreen, draw... + if (!(splitscreen3 || splitscreen4)) // Tiny screen, don't clutter it too much + { + // Draw the timestamp + K_drawKartTimestamp(); + } + + if (!(splitscreen || splitscreen3 || splitscreen4) && !modeattacking) // Unnecessary stuff { - // If not splitscreen, draw... // The little triple-item icons at the bottom // The top-four faces on the left K_drawKartPositionFaces(); + + // Draw the speedometer + // TODO: Make a better speedometer. + K_drawKartSpeedometer(); } if (gametype == GT_RACE) // Race-only elements @@ -5096,10 +5153,6 @@ void K_drawKartHUD(void) // Draw the numerical position K_DrawKartPositionNum(stplyr->kartstuff[k_position]); - // Draw the speedometer - // TODO: Make a better speedometer. - K_drawKartSpeedometer(); - // Draw the lap counter K_drawKartLaps(); } diff --git a/src/p_user.c b/src/p_user.c index 926be4cc..c5036433 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -8506,13 +8506,13 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall { dist = camdist; - // in splitscreen, mess with the camera distances to make it feel proportional to how it feels normally - if (splitscreen) // widescreen splits should get farther distance + // in splitscreen modes, mess with the camera distances to make it feel proportional to how it feels normally + if (splitscreen) // widescreen splits should get x1.5 distance { dist = FixedMul(dist, 3*FRACUNIT/2); height = FixedMul(height, 3*FRACUNIT/2); } - else if (splitscreen3 || splitscreen4) // small screen splits should get a shorter distance (yes, oddly enough that feels better) + else if (splitscreen3 || splitscreen4) // smallscreen splits should get 7/8 distance (shorter feels better, oddly enough) { dist = FixedMul(dist, 7*FRACUNIT/8); height = FixedMul(height, 7*FRACUNIT/8); diff --git a/src/v_video.c b/src/v_video.c index a5d5f86b..8dbffcd2 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -425,7 +425,10 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t } if (scrn & V_SPLITSCREEN) - y>>=1; + y += (BASEVIDHEIGHT/2)<