Merge branch 'quads' of http://git.magicalgirl.moe/wolfs/Kart into quads

# Conflicts:
#	src/d_main.c
This commit is contained in:
Wolfy 2017-12-17 20:30:37 -06:00
commit 0305af3069
25 changed files with 588 additions and 364 deletions

View File

@ -97,7 +97,7 @@ SINT8 nodetoplayer[MAXNETNODES];
SINT8 nodetoplayer2[MAXNETNODES]; // say the numplayer for this node if any (splitscreen) 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 nodetoplayer3[MAXNETNODES]; // say the numplayer for this node if any (splitscreen3)
SINT8 nodetoplayer4[MAXNETNODES]; // say the numplayer for this node if any (splitscreen4) 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 boolean nodeingame[MAXNETNODES]; // set false as nodes leave game
static tic_t nettics[MAXNETNODES]; // what tic the client have received static tic_t nettics[MAXNETNODES]; // what tic the client have received
static tic_t supposedtics[MAXNETNODES]; // nettics prevision for smaller packet 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) UINT8 GetFreeXCmdSize(void)
{ {
// -1 for the size and another -1 for the ID. // -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? // Is playernum authorized to make this kick?
if (playernum != serverplayer && !IsPlayerAdmin(playernum) if (playernum != serverplayer && !IsPlayerAdmin(playernum)
&& !(playerpernode[playernode[playernum]] >= 2 && !(playerpernode[playernode[playernum]] >= 2
&& nodetoplayer2[playernode[playernum]] == pnum && (nodetoplayer2[playernode[playernum]] == pnum
&& nodetoplayer3[playernode[playernum]] == pnum || nodetoplayer3[playernode[playernum]] == pnum
&& nodetoplayer4[playernode[playernum]] == pnum)) || nodetoplayer4[playernode[playernum]] == pnum)))
{ {
// We received a kick command from someone who isn't the // We received a kick command from someone who isn't the
// server or admin, and who isn't in splitscreen removing // 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) if (node == mynode)
{ {
playernode[newplayernum] = 0; // for information only playernode[newplayernum] = 0; // for information only
if (splitscreenplayer == 0) if (splitscreenplayer)
{ {
consoleplayer = newplayernum; if (splitscreenplayer == 1)
displayplayer = newplayernum; {
secondarydisplayplayer = newplayernum; secondarydisplayplayer = newplayernum;
thirddisplayplayer = newplayernum; DEBFILE("spawning my brother\n");
fourthdisplayplayer = newplayernum; if (botingame)
DEBFILE("spawning me\n"); players[newplayernum].bot = 1;
// Apply player flags as soon as possible! // Same goes for player 2 when relevant
players[newplayernum].pflags &= ~(PF_FLIPCAM|PF_ANALOGMODE); players[newplayernum].pflags &= ~(PF_FLIPCAM|PF_ANALOGMODE);
if (cv_flipcam.value) if (cv_flipcam2.value)
players[newplayernum].pflags |= PF_FLIPCAM; players[newplayernum].pflags |= PF_FLIPCAM;
if (cv_analog.value) if (cv_analog2.value)
players[newplayernum].pflags |= PF_ANALOGMODE; players[newplayernum].pflags |= PF_ANALOGMODE;
} }
else else if (splitscreenplayer == 2)
{
if (splitscreenplayer == 2)
{ {
thirddisplayplayer = newplayernum; thirddisplayplayer = newplayernum;
DEBFILE("spawning my sister\n"); DEBFILE("spawning my sister\n");
@ -3152,19 +3182,21 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
if (cv_analog4.value) if (cv_analog4.value)
players[newplayernum].pflags |= PF_ANALOGMODE; players[newplayernum].pflags |= PF_ANALOGMODE;
} }
else }
{ else
secondarydisplayplayer = newplayernum; {
DEBFILE("spawning my brother\n"); consoleplayer = newplayernum;
if (botingame) displayplayer = newplayernum;
players[newplayernum].bot = 1; secondarydisplayplayer = newplayernum;
// Same goes for player 2 when relevant thirddisplayplayer = newplayernum;
players[newplayernum].pflags &= ~(PF_FLIPCAM|PF_ANALOGMODE); fourthdisplayplayer = newplayernum;
if (cv_flipcam2.value) DEBFILE("spawning me\n");
players[newplayernum].pflags |= PF_FLIPCAM; // Apply player flags as soon as possible!
if (cv_analog2.value) players[newplayernum].pflags &= ~(PF_FLIPCAM|PF_ANALOGMODE);
players[newplayernum].pflags |= PF_ANALOGMODE; if (cv_flipcam.value)
} players[newplayernum].pflags |= PF_FLIPCAM;
if (cv_analog.value)
players[newplayernum].pflags |= PF_ANALOGMODE;
} }
D_SendPlayerConfig(); D_SendPlayerConfig();
addedtogame = true; addedtogame = true;
@ -3233,7 +3265,7 @@ static boolean SV_AddWaitingPlayers(void)
nodetoplayer3[node] = newplayernum; nodetoplayer3[node] = newplayernum;
buf[1] += MAXPLAYERS*2; buf[1] += MAXPLAYERS*2;
} }
else if (playerpernode[node] < 4) else
{ {
nodetoplayer4[node] = newplayernum; nodetoplayer4[node] = newplayernum;
buf[1] += MAXPLAYERS*3; buf[1] += MAXPLAYERS*3;
@ -3752,6 +3784,7 @@ FILESTAMP
realend = ExpandTics(netbuffer->u.clientpak.resendfrom); realend = ExpandTics(netbuffer->u.clientpak.resendfrom);
if (netbuffer->packettype == PT_CLIENTMIS || netbuffer->packettype == PT_CLIENT2MIS if (netbuffer->packettype == PT_CLIENTMIS || netbuffer->packettype == PT_CLIENT2MIS
|| netbuffer->packettype == PT_CLIENT3MIS || netbuffer->packettype == PT_CLIENT4MIS
|| netbuffer->packettype == PT_NODEKEEPALIVEMIS || netbuffer->packettype == PT_NODEKEEPALIVEMIS
|| supposedtics[node] < realend) || supposedtics[node] < realend)
{ {
@ -3800,20 +3833,26 @@ FILESTAMP
if (((netbuffer->packettype == PT_CLIENT2CMD || netbuffer->packettype == PT_CLIENT2MIS) if (((netbuffer->packettype == PT_CLIENT2CMD || netbuffer->packettype == PT_CLIENT2MIS)
|| (netbuffer->packettype == PT_CLIENT3CMD || netbuffer->packettype == PT_CLIENT3MIS) || (netbuffer->packettype == PT_CLIENT3CMD || netbuffer->packettype == PT_CLIENT3MIS)
|| (netbuffer->packettype == PT_CLIENT4CMD || netbuffer->packettype == PT_CLIENT4MIS)) || (netbuffer->packettype == PT_CLIENT4CMD || netbuffer->packettype == PT_CLIENT4MIS))
&& nodetoplayer2[node] >= 0) && (nodetoplayer2[node] >= 0))
{
G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)nodetoplayer2[node]], G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)nodetoplayer2[node]],
&netbuffer->u.client2pak.cmd2, 1); &netbuffer->u.client2pak.cmd2, 1);
}
if (((netbuffer->packettype == PT_CLIENT3CMD || netbuffer->packettype == PT_CLIENT3MIS) if (((netbuffer->packettype == PT_CLIENT3CMD || netbuffer->packettype == PT_CLIENT3MIS)
|| (netbuffer->packettype == PT_CLIENT4CMD || netbuffer->packettype == PT_CLIENT4MIS)) || (netbuffer->packettype == PT_CLIENT4CMD || netbuffer->packettype == PT_CLIENT4MIS))
&& nodetoplayer3[node] >= 0) && (nodetoplayer3[node] >= 0))
{
G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)nodetoplayer3[node]], G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)nodetoplayer3[node]],
&netbuffer->u.client3pak.cmd3, 1); &netbuffer->u.client3pak.cmd3, 1);
}
if ((netbuffer->packettype == PT_CLIENT4CMD || netbuffer->packettype == PT_CLIENT4MIS) if ((netbuffer->packettype == PT_CLIENT4CMD || netbuffer->packettype == PT_CLIENT4MIS)
&& nodetoplayer4[node] >= 0) && (nodetoplayer4[node] >= 0))
{
G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)nodetoplayer4[node]], G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)nodetoplayer4[node]],
&netbuffer->u.client4pak.cmd4, 1); &netbuffer->u.client4pak.cmd4, 1);
}
// A delay before we check resynching // A delay before we check resynching
// Used on join or just after a synch fail // Used on join or just after a synch fail
@ -3948,6 +3987,7 @@ FILESTAMP
buf[1] = KICK_MSG_PLAYER_QUIT; buf[1] = KICK_MSG_PLAYER_QUIT;
SendNetXCmd(XD_KICK, &buf, 2); SendNetXCmd(XD_KICK, &buf, 2);
nodetoplayer[node] = -1; nodetoplayer[node] = -1;
if (nodetoplayer2[node] != -1 && nodetoplayer2[node] >= 0 if (nodetoplayer2[node] != -1 && nodetoplayer2[node] >= 0
&& playeringame[(UINT8)nodetoplayer2[node]]) && playeringame[(UINT8)nodetoplayer2[node]])
{ {
@ -3955,6 +3995,7 @@ FILESTAMP
SendNetXCmd(XD_KICK, &buf, 2); SendNetXCmd(XD_KICK, &buf, 2);
nodetoplayer2[node] = -1; nodetoplayer2[node] = -1;
} }
if (nodetoplayer3[node] != -1 && nodetoplayer3[node] >= 0 if (nodetoplayer3[node] != -1 && nodetoplayer3[node] >= 0
&& playeringame[(UINT8)nodetoplayer3[node]]) && playeringame[(UINT8)nodetoplayer3[node]])
{ {
@ -3962,6 +4003,7 @@ FILESTAMP
SendNetXCmd(XD_KICK, &buf, 2); SendNetXCmd(XD_KICK, &buf, 2);
nodetoplayer3[node] = -1; nodetoplayer3[node] = -1;
} }
if (nodetoplayer4[node] != -1 && nodetoplayer4[node] >= 0 if (nodetoplayer4[node] != -1 && nodetoplayer4[node] >= 0
&& playeringame[(UINT8)nodetoplayer4[node]]) && playeringame[(UINT8)nodetoplayer4[node]])
{ {
@ -4326,7 +4368,7 @@ static void CL_SendClientCmd(void)
if (gamestate == GS_WAITINGPLAYERS) if (gamestate == GS_WAITINGPLAYERS)
{ {
// Send PT_NODEKEEPALIVE packet // Send PT_NODEKEEPALIVE packet
netbuffer->packettype += 4; netbuffer->packettype += 8;
packetsize = sizeof (clientcmd_pak) - sizeof (ticcmd_t) - sizeof (INT16); packetsize = sizeof (clientcmd_pak) - sizeof (ticcmd_t) - sizeof (INT16);
HSendPacket(servernode, false, 0, packetsize); HSendPacket(servernode, false, 0, packetsize);
} }
@ -4335,23 +4377,26 @@ static void CL_SendClientCmd(void)
G_MoveTiccmd(&netbuffer->u.clientpak.cmd, &localcmds, 1); G_MoveTiccmd(&netbuffer->u.clientpak.cmd, &localcmds, 1);
netbuffer->u.clientpak.consistancy = SHORT(consistancy[gametic%BACKUPTICS]); 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; netbuffer->packettype += 2;
G_MoveTiccmd(&netbuffer->u.client4pak.cmd2, &localcmds2, 1); G_MoveTiccmd(&netbuffer->u.client2pak.cmd2, &localcmds2, 1);
G_MoveTiccmd(&netbuffer->u.client4pak.cmd3, &localcmds3, 1); packetsize = sizeof (client2cmd_pak);
G_MoveTiccmd(&netbuffer->u.client4pak.cmd4, &localcmds4, 1);
} }
else if (splitscreen3) else if (splitscreen3)
{ {
netbuffer->packettype += 4; 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.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 else
packetsize = sizeof (clientcmd_pak); packetsize = sizeof (clientcmd_pak);
@ -4380,6 +4425,26 @@ static void CL_SendClientCmd(void)
if (HSendPacket(servernode, true, 0, localtextcmd2[0]+1)) // Send can fail... if (HSendPacket(servernode, true, 0, localtextcmd2[0]+1)) // Send can fail...
localtextcmd2[0] = 0; 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); CONS_Debug(DBG_NETPLAY, "Client Misstic %d\n", maketic);
#endif #endif
// copy the old tic // 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] = netcmds[(maketic-1)%BACKUPTICS][player];
netcmds[maketic%BACKUPTICS][player].angleturn &= ~TICCMD_RECEIVED; netcmds[maketic%BACKUPTICS][player].angleturn &= ~TICCMD_RECEIVED;
} }

View File

@ -70,8 +70,8 @@ typedef enum
PT_TEXTCMD, // Extra text commands from the client. PT_TEXTCMD, // Extra text commands from the client.
PT_TEXTCMD2, // Splitscreen text commands. PT_TEXTCMD2, // Splitscreen text commands.
PT_TEXTCMD3, PT_TEXTCMD3, // 3P
PT_TEXTCMD4, PT_TEXTCMD4, // 4P
PT_CLIENTJOIN, // Client wants to join; used in start game. PT_CLIENTJOIN, // Client wants to join; used in start game.
PT_NODETIMEOUT, // Packet sent to self if the connection times out. PT_NODETIMEOUT, // Packet sent to self if the connection times out.
PT_RESYNCHING, // Packet sent to resync players. 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 RegisterNetXCmd(netxcmd_t id, void (*cmd_f)(UINT8 **p, INT32 playernum));
void SendNetXCmd(netxcmd_t id, const void *param, size_t nparam); 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 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. // Create any new ticcmds and broadcast to other players.
void NetUpdate(void); void NetUpdate(void);

View File

@ -412,7 +412,6 @@ static void D_Display(void)
{ {
if (splitscreen3 || splitscreen4) if (splitscreen3 || splitscreen4)
viewwindowx = vid.width / 2; viewwindowx = vid.width / 2;
viewwindowy = vid.height / 2; viewwindowy = vid.height / 2;
M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0])); M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0]));
@ -425,48 +424,50 @@ static void D_Display(void)
} }
} }
// render the third screen
if ((splitscreen3 || splitscreen4) && players[thirddisplayplayer].mo) if ((splitscreen3 || splitscreen4) && players[thirddisplayplayer].mo)
{ {
#ifdef HWRENDER #ifdef HWRENDER
if (rendermode != render_soft) if (rendermode != render_soft)
HWR_RenderPlayerView(2, &players[thirddisplayplayer]); HWR_RenderPlayerView(2, &players[thirddisplayplayer]);
else //else
#endif #endif
if (rendermode != render_none) /*if (rendermode != render_none)
{ {
viewwindowx = vid.width / 2; viewwindowx = vid.width / 2;
viewwindowy = vid.height / 2; viewwindowy = vid.height / 2;
M_Memcpy(ylookup2, ylookup3, viewheight*sizeof (ylookup[0])); M_Memcpy(ylookup, ylookup2, viewheight*sizeof (ylookup[0]));
topleft = screens[0] + viewwindowy*vid.width + viewwindowx; topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
R_RenderPlayerView(&players[thirddisplayplayer]); R_RenderPlayerView(&players[thirddisplayplayer]);
viewwindowy = 0; viewwindowy = 0;
M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0])); M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0]));
} }*/
} }
// render the fourth screen
if (splitscreen4 && players[fourthdisplayplayer].mo) if (splitscreen4 && players[fourthdisplayplayer].mo)
{ {
#ifdef HWRENDER #ifdef HWRENDER
if (rendermode != render_soft) if (rendermode != render_soft)
HWR_RenderPlayerView(3, &players[fourthdisplayplayer]); HWR_RenderPlayerView(3, &players[fourthdisplayplayer]);
else //else
#endif #endif
if (rendermode != render_none) /*if (rendermode != render_none)
{ {
viewwindowx = vid.width / 2; viewwindowx = vid.width / 2;
viewwindowy = vid.height / 2; viewwindowy = vid.height / 2;
M_Memcpy(ylookup3, ylookup4, viewheight*sizeof (ylookup[0])); M_Memcpy(ylookup3, ylookup4, viewheight*sizeof (ylookup[0]));
topleft = screens[0] + viewwindowy*vid.width + viewwindowx; topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
R_RenderPlayerView(&players[fourthdisplayplayer]); R_RenderPlayerView(&players[fourthdisplayplayer]);
viewwindowy = 0; viewwindowy = 0;
M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0])); M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0]));
} }*/
} }
// Image postprocessing effect // Image postprocessing effect

View File

@ -818,6 +818,10 @@ static const char *packettypename[NUMPACKETTYPE] =
"CLIENTMIS", "CLIENTMIS",
"CLIENT2CMD", "CLIENT2CMD",
"CLIENT2MIS", "CLIENT2MIS",
"CLIENT3CMD",
"CLIENT3MIS",
"CLIENT4CMD",
"CLIENT4MIS",
"NODEKEEPALIVE", "NODEKEEPALIVE",
"NODEKEEPALIVEMIS", "NODEKEEPALIVEMIS",
"SERVERTICS", "SERVERTICS",
@ -837,6 +841,8 @@ static const char *packettypename[NUMPACKETTYPE] =
"FILEFRAGMENT", "FILEFRAGMENT",
"TEXTCMD", "TEXTCMD",
"TEXTCMD2", "TEXTCMD2",
"TEXTCMD3",
"TEXTCMD4",
"CLIENTJOIN", "CLIENTJOIN",
"NODETIMEOUT", "NODETIMEOUT",
"RESYNCHING", "RESYNCHING",

View File

@ -21,7 +21,7 @@
// Max computers in a game // Max computers in a game
#define MAXNETNODES 16 #define MAXNETNODES 16
#define BROADCASTADDR MAXNETNODES #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) #define STATLENGTH (TICRATE*2)

View File

@ -178,8 +178,8 @@ static void Command_Archivetest_f(void);
void SendWeaponPref(void); void SendWeaponPref(void);
void SendWeaponPref2(void); void SendWeaponPref2(void);
//void SendWeaponPref3(void); void SendWeaponPref3(void);
//void SendWeaponPref4(void); void SendWeaponPref4(void);
static CV_PossibleValue_t usemouse_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Force"}, {0, NULL}}; static CV_PossibleValue_t usemouse_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "Force"}, {0, NULL}};
#if (defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON) #if (defined (__unix__) && !defined (MSDOS)) || defined(__APPLE__) || defined (UNIXCOMMON)
@ -1705,7 +1705,7 @@ void SendWeaponPref3(void)
buf[0] |= 1; buf[0] |= 1;
if (players[thirddisplayplayer].pflags & PF_ANALOGMODE) if (players[thirddisplayplayer].pflags & PF_ANALOGMODE)
buf[0] |= 2; buf[0] |= 2;
//SendNetXCmd3(XD_WEAPONPREF, buf, 1); SendNetXCmd3(XD_WEAPONPREF, buf, 1);
} }
void SendWeaponPref4(void) void SendWeaponPref4(void)
@ -1717,7 +1717,7 @@ void SendWeaponPref4(void)
buf[0] |= 1; buf[0] |= 1;
if (players[fourthdisplayplayer].pflags & PF_ANALOGMODE) if (players[fourthdisplayplayer].pflags & PF_ANALOGMODE)
buf[0] |= 2; buf[0] |= 2;
//SendNetXCmd4(XD_WEAPONPREF, buf, 1); SendNetXCmd4(XD_WEAPONPREF, buf, 1);
} }
static void Got_WeaponPref(UINT8 **cp,INT32 playernum) static void Got_WeaponPref(UINT8 **cp,INT32 playernum)

View File

@ -7854,7 +7854,6 @@ struct {
{"V_90TRANS",V_90TRANS}, {"V_90TRANS",V_90TRANS},
{"V_HUDTRANSHALF",V_HUDTRANSHALF}, {"V_HUDTRANSHALF",V_HUDTRANSHALF},
{"V_HUDTRANS",V_HUDTRANS}, {"V_HUDTRANS",V_HUDTRANS},
{"V_HUDTRANSDOUBLE",V_HUDTRANSDOUBLE},
{"V_AUTOFADEOUT",V_AUTOFADEOUT}, {"V_AUTOFADEOUT",V_AUTOFADEOUT},
{"V_RETURN8",V_RETURN8}, {"V_RETURN8",V_RETURN8},
{"V_OFFSET",V_OFFSET}, {"V_OFFSET",V_OFFSET},
@ -7868,6 +7867,7 @@ struct {
{"V_WRAPY",V_WRAPY}, {"V_WRAPY",V_WRAPY},
{"V_NOSCALESTART",V_NOSCALESTART}, {"V_NOSCALESTART",V_NOSCALESTART},
{"V_SPLITSCREEN",V_SPLITSCREEN}, {"V_SPLITSCREEN",V_SPLITSCREEN},
{"V_HORZSCREEN",V_HORZSCREEN},
{"V_PARAMMASK",V_PARAMMASK}, {"V_PARAMMASK",V_PARAMMASK},
{"V_SCALEPATCHMASK",V_SCALEPATCHMASK}, {"V_SCALEPATCHMASK",V_SCALEPATCHMASK},

View File

@ -2109,8 +2109,6 @@ void G_Ticker(boolean run)
if (playeringame[i]) if (playeringame[i])
{ {
G_CopyTiccmd(cmd, &netcmds[buf][i], 1);
// SRB2kart // SRB2kart
// Save the dir the player is holding // Save the dir the player is holding
// to allow items to be thrown forward or backward. // to allow items to be thrown forward or backward.
@ -2120,6 +2118,8 @@ void G_Ticker(boolean run)
players[i].kartstuff[k_throwdir] = -1; players[i].kartstuff[k_throwdir] = -1;
else else
players[i].kartstuff[k_throwdir] = 0; players[i].kartstuff[k_throwdir] = 0;
G_CopyTiccmd(cmd, &netcmds[buf][i], 1);
} }
} }

View File

@ -180,7 +180,10 @@ void HWR_DrawFixedPatch(GLPatch_t *gpatch, fixed_t x, fixed_t y, fixed_t pscale,
sdupx = sdupy = 2.0f; sdupx = sdupy = 2.0f;
if (option & V_SPLITSCREEN) if (option & V_SPLITSCREEN)
sdupy /= 2.0f; cy += FIXED_TO_FLOAT((BASEVIDHEIGHT/2)<<FRACBITS);
if (option & V_HORZSCREEN)
cx += FIXED_TO_FLOAT((BASEVIDWIDTH/2)<<FRACBITS);
if (option & V_FLIP) // Need to flip both this and sow if (option & V_FLIP) // Need to flip both this and sow
{ {
@ -512,7 +515,7 @@ void HWR_DrawViewBorder(INT32 clearlines)
baseviewwidth = FixedInt(FixedDiv(FLOAT_TO_FIXED(gr_viewwidth), vid.fdupx)); //(cv_viewsize.value * BASEVIDWIDTH/10)&~7; 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)); baseviewheight = FixedInt(FixedDiv(FLOAT_TO_FIXED(gr_viewheight), vid.fdupy));
top = FixedInt(FixedDiv(FLOAT_TO_FIXED(gr_baseviewwindowy), 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 // top
HWR_DrawFlatFill(0, 0, HWR_DrawFlatFill(0, 0,

View File

@ -45,7 +45,7 @@
#define LIGHTMAPFLAGS (PF_Modulated|PF_Additive|PF_Clip) #define LIGHTMAPFLAGS (PF_Modulated|PF_Additive|PF_Clip)
#ifdef ALAM_LIGHTING #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]; static dynlights_t *dynlights = &view_dynlights[0];
#endif #endif

View File

@ -328,14 +328,18 @@ static angle_t gr_xtoviewangle[MAXVIDWIDTH+1];
// base values set at SetViewSize // base values set at SetViewSize
static float gr_basecentery; static float gr_basecentery;
static float gr_basecenterx;
float gr_baseviewwindowy, gr_basewindowcentery; float gr_baseviewwindowy, gr_basewindowcentery;
float gr_baseviewwindowx, gr_basewindowcenterx;
float gr_viewwidth, gr_viewheight; // viewport clipping boundaries (screen coords) float gr_viewwidth, gr_viewheight; // viewport clipping boundaries (screen coords)
float gr_viewwindowx;
static float gr_centerx, gr_centery; static float gr_centerx;
static float gr_viewwindowy; // top left corner of view window static float gr_viewwindowx;
static float gr_windowcenterx; // center of view window, for projection 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_windowcentery;
static float gr_pspritexscale, gr_pspriteyscale; 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; angle_t shadowdir;
// Set direction // Set direction
if ((splitscreen || splitscreen3 || splitscreen4) && stplyr != &players[displayplayer]) if ((splitscreen || splitscreen3 || splitscreen4) && stplyr == &players[secondarydisplayplayer])
{ {
shadowdir = localangle2 + FixedAngle(cv_cam2_rotate.value); 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); shadowdir = localangle3 + FixedAngle(cv_cam3_rotate.value);
if (splitscreen4 && stplyr != &players[displayplayer]) if (splitscreen4 && stplyr == &players[fourthdisplayplayer])
shadowdir = localangle4 + FixedAngle(cv_cam4_rotate.value); shadowdir = localangle4 + FixedAngle(cv_cam4_rotate.value);
} }
} }
@ -5512,26 +5516,22 @@ void HWR_SetViewSize(void)
gr_viewwidth = (float)vid.width; gr_viewwidth = (float)vid.width;
gr_viewheight = (float)vid.height; gr_viewheight = (float)vid.height;
if (splitscreen) if (splitscreen || splitscreen3 || splitscreen4)
gr_viewheight /= 2; gr_viewheight /= 2;
gr_centerx = gr_viewwidth / 2; if (splitscreen3 || splitscreen4)
gr_basecentery = gr_viewheight / 2; //note: this is (gr_centerx * gr_viewheight / gr_viewwidth) gr_viewwidth /= 2;
gr_viewwindowx = (vid.width - gr_viewwidth) / 2; gr_basecenterx = gr_viewwidth / 2;
gr_windowcenterx = (float)(vid.width / 2); gr_basecentery = gr_viewheight / 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_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; 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; dup_viewangle = viewangle;
// set window position // set window position
gr_centerx = gr_basecenterx;
gr_viewwindowx = gr_baseviewwindowx;
gr_windowcenterx = gr_basewindowcenterx;
gr_centery = gr_basecentery; gr_centery = gr_basecentery;
gr_viewwindowy = gr_baseviewwindowy; gr_viewwindowy = gr_baseviewwindowy;
gr_windowcentery = gr_basewindowcentery; 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_viewwindowy += gr_viewheight;
gr_windowcentery += (vid.height/2); gr_windowcentery += gr_viewheight;
} }
if (splitscreen4 && (viewnumber == 2 || viewnumber == 3)) if ((splitscreen3 || splitscreen4) && (viewnumber == 1 || viewnumber == 3))
{ {
gr_viewwindowy += (vid.height/2); gr_viewwindowx += gr_viewwidth;
gr_windowcentery += (vid.height/2); gr_windowcenterx += gr_viewwidth;
} }
// check for new console commands. // check for new console commands.
@ -5619,7 +5623,15 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
atransform.scalez = 1; atransform.scalez = 1;
atransform.fovxangle = fpov; // Tails atransform.fovxangle = fpov; // Tails
atransform.fovyangle = 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 // Transform for sprites
stransform.anglex = 0.0f; stransform.anglex = 0.0f;
@ -5638,7 +5650,15 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
stransform.scalez = 1; stransform.scalez = 1;
stransform.fovxangle = 90.0f; stransform.fovxangle = 90.0f;
stransform.fovyangle = 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))); gr_fovlud = (float)(1.0l/tan((double)(fpov*M_PIl/360l)));
@ -5661,7 +5681,7 @@ if (0)
#endif #endif
//Hurdler: it doesn't work in splitscreen mode //Hurdler: it doesn't work in splitscreen mode
drawsky = splitscreen || splitscreen3 || splitscreen4; drawsky = (splitscreen || splitscreen3 || splitscreen4);
HWR_ClearSprites(); HWR_ClearSprites();
@ -5818,19 +5838,23 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
dup_viewangle = viewangle; dup_viewangle = viewangle;
// set window position // set window position
gr_centerx = gr_basecenterx;
gr_viewwindowx = gr_baseviewwindowx;
gr_windowcenterx = gr_basewindowcenterx;
gr_centery = gr_basecentery; gr_centery = gr_basecentery;
gr_viewwindowy = gr_baseviewwindowy; gr_viewwindowy = gr_baseviewwindowy;
gr_windowcentery = gr_basewindowcentery; 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_viewwindowy += gr_viewheight;
gr_windowcentery += (vid.height/2); gr_windowcentery += gr_viewheight;
} }
if (splitscreen4 && (viewnumber == 2 || viewnumber == 3)) if ((splitscreen3 || splitscreen4) && (viewnumber == 1 || viewnumber == 3))
{ {
gr_viewwindowy += (vid.height/2); gr_viewwindowx += gr_viewwidth;
gr_windowcentery += (vid.height/2); gr_windowcenterx += gr_viewwidth;
} }
// check for new console commands. // check for new console commands.
@ -5863,7 +5887,15 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
atransform.scalez = 1; atransform.scalez = 1;
atransform.fovxangle = fpov; // Tails atransform.fovxangle = fpov; // Tails
atransform.fovyangle = 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 // Transform for sprites
stransform.anglex = 0.0f; stransform.anglex = 0.0f;
@ -5882,7 +5914,15 @@ void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
stransform.scalez = 1; stransform.scalez = 1;
stransform.fovxangle = 90.0f; stransform.fovxangle = 90.0f;
stransform.fovyangle = 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))); gr_fovlud = (float)(1.0l/tan((double)(fpov*M_PIl/360l)));
@ -5905,7 +5945,7 @@ if (0)
#endif #endif
//Hurdler: it doesn't work in splitscreen mode //Hurdler: it doesn't work in splitscreen mode
drawsky = splitscreen; drawsky = (splitscreen || splitscreen3 || splitscreen4);
HWR_ClearSprites(); HWR_ClearSprites();
@ -5925,8 +5965,12 @@ if (0)
// Make a viewangle int so we can render things based on mouselook // Make a viewangle int so we can render things based on mouselook
if (player == &players[consoleplayer]) if (player == &players[consoleplayer])
viewangle = localaiming; viewangle = localaiming;
else if (splitscreen && player == &players[secondarydisplayplayer]) else if ((splitscreen || splitscreen3 || splitscreen4) && player == &players[secondarydisplayplayer])
viewangle = localaiming2; 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. // Handle stuff when you are looking farther up or down.
if ((aimingangle || cv_grfov.value+player->fovadd > 90*FRACUNIT)) if ((aimingangle || cv_grfov.value+player->fovadd > 90*FRACUNIT))
@ -6413,7 +6457,11 @@ void HWR_DoPostProcessor(player_t *player)
{ {
postimg_t *type; 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; type = &postimgtype2;
else else
type = &postimgtype; type = &postimgtype;
@ -6447,7 +6495,7 @@ void HWR_DoPostProcessor(player_t *player)
if(gamestate != GS_INTERMISSION) if(gamestate != GS_INTERMISSION)
HWD.pfnMakeScreenTexture(); 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; return;
#ifdef SHUFFLE #ifdef SHUFFLE

View File

@ -96,9 +96,9 @@ extern consvar_t cv_voodoocompatibility;
extern consvar_t cv_grfovchange; extern consvar_t cv_grfovchange;
extern consvar_t cv_grsolvetjoin; 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 // BP: big hack for a test in lighting ref : 1249753487AB
extern fixed_t *hwbbox; extern fixed_t *hwbbox;

View File

@ -2024,8 +2024,9 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
pglMatrixMode(GL_PROJECTION); pglMatrixMode(GL_PROJECTION);
pglLoadIdentity(); pglLoadIdentity();
special_splitscreen = (stransform->splitscreen && stransform->fovxangle == 90.0f); if (stransform->splitscreen == 1 && stransform->fovxangle == 90.0f);
if (special_splitscreen) special_splitscreen = stransform->splitscreen;
if (special_splitscreen == 1)
GLPerspective(53.13l, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5) GLPerspective(53.13l, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5)
else else
GLPerspective(stransform->fovxangle, ASPECT_RATIO); GLPerspective(stransform->fovxangle, ASPECT_RATIO);
@ -2040,7 +2041,7 @@ EXPORT void HWRAPI(SetTransform) (FTransform *stransform)
pglMatrixMode(GL_PROJECTION); pglMatrixMode(GL_PROJECTION);
pglLoadIdentity(); pglLoadIdentity();
if (special_splitscreen) if (special_splitscreen == 1)
GLPerspective(53.13l, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5) GLPerspective(53.13l, 2*ASPECT_RATIO); // 53.13 = 2*atan(0.5)
else else
//Hurdler: is "fov" correct? //Hurdler: is "fov" correct?

View File

@ -1802,7 +1802,7 @@ static void HU_DrawRankings(void)
HU_DrawDualTabRankings(32, 32, tab, scorelines, whiteplayer); HU_DrawDualTabRankings(32, 32, tab, scorelines, whiteplayer);
// draw spectators in a ticker across the bottom // draw spectators in a ticker across the bottom
if ((!splitscreen || !splitscreen3 || !splitscreen4) && G_GametypeHasSpectators()) if (!(splitscreen || splitscreen3 || splitscreen4) && G_GametypeHasSpectators())
HU_DrawSpectatorTicker(); HU_DrawSpectatorTicker();
} }

View File

@ -4060,23 +4060,6 @@ void K_LoadKartHUDGraphics(void)
//} //}
static INT32 STRINGY(INT32 y)
{
// Copied from st_stuff.c
if (splitscreen || splitscreen3)
{
y >>= 1;
if (stplyr != &players[displayplayer])
y += BASEVIDHEIGHT / 2;
}
return y;
}
/*static INT32 SCX(INT32 x)
{
return FixedInt(FixedMul(x<<FRACBITS, vid.fdupx));
}*/
INT32 ITEM_X, ITEM_Y; // Item Window INT32 ITEM_X, ITEM_Y; // Item Window
INT32 TRIP_X, TRIP_Y; // Triple Item Icon INT32 TRIP_X, TRIP_Y; // Triple Item Icon
INT32 TIME_X, TIME_Y; // Time Sticker INT32 TIME_X, TIME_Y; // Time Sticker
@ -4124,65 +4107,57 @@ static void K_initKartHUD(void)
*/ */
if (!splitscreen) // Local Single-Player // Single Screen (defaults)
// Item Window
ITEM_X = BASEVIDWIDTH - 52; // 268
ITEM_Y = 34; // 34
// Triple Item Object
TRIP_X = 143; // 143
TRIP_Y = BASEVIDHEIGHT- 34; // 166
// Level Timer
TIME_X = BASEVIDWIDTH -148; // 172
TIME_Y = 9; // 9
// Level Laps
LAPS_X = 9; // 9
LAPS_Y = BASEVIDHEIGHT- 29; // 171
// Speedometer
SPDM_X = 9; // 9
SPDM_Y = BASEVIDHEIGHT- 45; // 155
// Position Number
POSI_X = BASEVIDWIDTH - 52; // 268
POSI_Y = BASEVIDHEIGHT- 62; // 138
// Top-Four Faces
FACE_X = 9; // 9
FACE_Y = 92; // 92
// Lakitu
LAKI_X = 136; // 138
LAKI_Y = 58 - 200; // 58
// CHECK graphic
CHEK_Y = BASEVIDHEIGHT; // 200
if (splitscreen || splitscreen3 || splitscreen4) // Splitscreen
{ {
switch (cv_karthud.value) // Item Window ITEM_X = 9;
ITEM_Y = 24;
TIME_Y = 4;
LAPS_Y = (BASEVIDHEIGHT/2)-24;
POSI_Y = (BASEVIDHEIGHT/2)-56;
if (splitscreen3 || splitscreen4) // 3P/4P Small Splitscreen
{ {
default: ITEM_X = 4;
// Item Window ITEM_Y = 4;
ITEM_X = BASEVIDWIDTH - 52; // 268
ITEM_Y = 34; // 34 LAPS_X = 2;
// Triple Item Object LAPS_Y = (BASEVIDHEIGHT/2)-22;
TRIP_X = 143; // 143
TRIP_Y = BASEVIDHEIGHT- 34; // 166 POSI_X = (BASEVIDWIDTH/2) -46;
// Level Timer POSI_Y = (BASEVIDHEIGHT/2)-56;
TIME_X = BASEVIDWIDTH -148; // 172
TIME_Y = 9; // 9
// Level Laps
LAPS_X = 9; // 9
LAPS_Y = BASEVIDHEIGHT- 29; // 171
// Speedometer
SPDM_X = 9; // 9
SPDM_Y = BASEVIDHEIGHT- 45; // 155
// Position Number
POSI_X = BASEVIDWIDTH - 52; // 268
POSI_Y = BASEVIDHEIGHT- 62; // 138
// Top-Four Faces
FACE_X = 9; // 9
FACE_Y = 92; // 92
// Lakitu
LAKI_X = 136; // 138
LAKI_Y = 58 - 200; // 58
// CHECK graphic
CHEK_Y = BASEVIDHEIGHT; // 200
break;
} }
} }
else // Local Multi-Player
{
ITEM_X = 9; // 9
ITEM_Y = 48; // 48
TRIP_X = 143; // 143
TRIP_Y = BASEVIDHEIGHT- 34; // 166
TIME_X = BASEVIDWIDTH -148; // 172 / Sticker is 196 (Base - 124) - Inside the boundry by 8px
TIME_Y = 6; // 6 / Sticker is +2
LAPS_X = 9; // 9
LAPS_Y = BASEVIDHEIGHT- 48; // 152
SPDM_X = 9; // 9
SPDM_Y = BASEVIDHEIGHT- 80; // 120
POSI_X = BASEVIDWIDTH - 52; // 268
POSI_Y = BASEVIDHEIGHT-122; // 108
FACE_X = 15; // 15
FACE_Y = 72; // 72
CHEK_Y = BASEVIDHEIGHT; // 200
}
// To correct the weird render location // To correct the weird render location
/*POSI_X = SCX(POSI_X); /*POSI_X = SCX(POSI_X);
@ -4194,12 +4169,21 @@ static void K_drawKartItemClose(void)
// ITEM_X = BASEVIDWIDTH-50; // 270 // ITEM_X = BASEVIDWIDTH-50; // 270
// ITEM_Y = 24; // 24 // ITEM_Y = 24; // 24
INT32 flags = V_SNAPTORIGHT|V_SNAPTOTOP;
// Why write V_DrawScaledPatch calls over and over when they're all the same? // Why write V_DrawScaledPatch calls over and over when they're all the same?
// Set to 'no draw' just in case. // Set to 'no draw' just in case.
patch_t *localpatch = kp_nodraw; 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 () /*if ()
switch (stplyr->kartstuff[k_itemclose]) switch (stplyr->kartstuff[k_itemclose])
{ {
@ -4221,11 +4205,8 @@ static void K_drawKartItemClose(void)
default: break; default: break;
} }
if (splitscreen)
flags = 0;
if (localpatch != kp_nodraw) 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) static void K_drawKartItemRoulette(void)
@ -4233,12 +4214,21 @@ static void K_drawKartItemRoulette(void)
// ITEM_X = BASEVIDWIDTH-50; // 270 // ITEM_X = BASEVIDWIDTH-50; // 270
// ITEM_Y = 24; // 24 // ITEM_Y = 24; // 24
INT32 flags = V_SNAPTORIGHT|V_SNAPTOTOP;
// Why write V_DrawScaledPatch calls over and over when they're all the same? // Why write V_DrawScaledPatch calls over and over when they're all the same?
// Set to 'no item' just in case. // Set to 'no item' just in case.
patch_t *localpatch = kp_nodraw; 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 () /*if ()
switch(stplyr->kartstuff[k_itemroulette] % 53) switch(stplyr->kartstuff[k_itemroulette] % 53)
{ {
@ -4290,9 +4280,7 @@ static void K_drawKartItemRoulette(void)
default: break; default: break;
} }
if (splitscreen) V_DrawScaledPatch(ITEM_X, ITEM_Y, V_SNAPTORIGHT|V_SNAPTOTOP|splitflags, localpatch);
flags = 0;
V_DrawScaledPatch(ITEM_X, STRINGY(ITEM_Y), flags, localpatch);
} }
static void K_drawKartRetroItem(void) static void K_drawKartRetroItem(void)
@ -4300,12 +4288,21 @@ static void K_drawKartRetroItem(void)
// ITEM_X = BASEVIDWIDTH-50; // 270 // ITEM_X = BASEVIDWIDTH-50; // 270
// ITEM_Y = 24; // 24 // ITEM_Y = 24; // 24
INT32 flags = V_SNAPTORIGHT|V_SNAPTOTOP;
// Why write V_DrawScaledPatch calls over and over when they're all the same? // Why write V_DrawScaledPatch calls over and over when they're all the same?
// Set to 'no item' just in case. // Set to 'no item' just in case.
patch_t *localpatch = kp_nodraw; 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 // 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 // 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 // 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_boo] == 1) localpatch = kp_boo;
else if (stplyr->kartstuff[k_magnet] == 1) localpatch = kp_magnet; else if (stplyr->kartstuff[k_magnet] == 1) localpatch = kp_magnet;
if (splitscreen) V_DrawScaledPatch(ITEM_X, ITEM_Y, V_SNAPTORIGHT|V_SNAPTOTOP|splitflags, localpatch);
flags = 0;
V_DrawScaledPatch(ITEM_X, STRINGY(ITEM_Y), flags, 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_boo] & 8) localpatch = kp_skghost;
else if (stplyr->kartstuff[k_magnet] & 8) localpatch = kp_electroshield; 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) 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 // TIME_Y = 6; // 6
INT32 TIME_XB; 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; TIME_XB = TIME_X+33;
@ -4463,44 +4465,44 @@ static void K_drawKartTimestamp(void)
// zero minute // zero minute
if (stplyr->realtime/(60*TICRATE) < 10) 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 __ __ // 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 __ __ // minutes time 0 __ __
else 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 _'__ __ // 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_ __ // zero second _ 0_ __
if ((stplyr->realtime/TICRATE % 60) < 10) 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 __ // 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 __ // zero second _ 00 __
else 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 _ __"__ // 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_ // zero tick _ __ 0_
if (G_TicsToCentiseconds(stplyr->realtime) < 10) 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 // 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 // zero tick _ __ 00
if (G_TicsToCentiseconds(stplyr->realtime) >= 10) 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 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) 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 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 W = SHORT(kp_positionnum[0][0]->width);
INT32 flags = V_TRANSLUCENT|V_SNAPTORIGHT|V_SNAPTOBOTTOM;
patch_t *localpatch = kp_positionnum[0][0]; patch_t *localpatch = kp_positionnum[0][0];
if (splitscreen) INT32 splitflags = 0;
flags = V_TRANSLUCENT; 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 // Special case for 0
if (!num) 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; return;
} }
@ -4592,7 +4601,7 @@ static void K_DrawKartPositionNum(INT32 num)
else else
localpatch = kp_positionnum[num % 10][0]; 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; num /= 10;
} }
} }
@ -4654,24 +4663,24 @@ static void K_drawKartPositionFaces(void)
colormap = colormaps; colormap = colormaps;
if (rankplayer[i] != myplayer) 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) if (gametype == GT_MATCH && players[rankplayer[i]].kartstuff[k_balloon] > 0)
{ {
for (j = 0; j < players[rankplayer[i]].kartstuff[k_balloon]; j++) 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; balloonx += 3;
} }
} }
} }
else 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) if (gametype == GT_MATCH && players[rankplayer[i]].kartstuff[k_balloon] > 0)
{ {
for (j = 0; j < players[rankplayer[i]].kartstuff[k_balloon]; j++) 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; 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); colormap = R_GetTranslationColormap(players[rankplayer[i]].skin, players[rankplayer[i]].mo->color, GTC_CACHE);
if (rankplayer[i] != myplayer) 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) if (gametype == GT_MATCH && players[rankplayer[i]].kartstuff[k_balloon] > 0)
{ {
for (j = 0; j < players[rankplayer[i]].kartstuff[k_balloon]; j++) 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; balloonx += 3;
} }
} }
} }
else 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) if (gametype == GT_MATCH && players[rankplayer[i]].kartstuff[k_balloon] > 0)
{ {
for (j = 0; j < players[rankplayer[i]].kartstuff[k_balloon]; j++) 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; balloonx += 3;
} }
} }
@ -4719,16 +4728,16 @@ static void K_drawKartPositionFaces(void)
if (rankplayer[i] != myplayer) if (rankplayer[i] != myplayer)
{ {
if (gametype == GT_MATCH && players[rankplayer[i]].kartstuff[k_balloon] <= 0) 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 else
V_DrawSmallTranslucentPatch(FACE_X, STRINGY(Y), V_SNAPTOLEFT, localpatch); V_DrawSmallTranslucentPatch(FACE_X, Y, V_SNAPTOLEFT, localpatch);
} }
else else
{ {
if (gametype == GT_MATCH && players[rankplayer[i]].kartstuff[k_balloon] <= 0) 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 else
V_DrawSmallScaledPatch(FACE_X, STRINGY(Y), V_SNAPTOLEFT, localpatch); V_DrawSmallScaledPatch(FACE_X, Y, V_SNAPTOLEFT, localpatch);
} }
Y += 18; Y += 18;
@ -4737,67 +4746,91 @@ static void K_drawKartPositionFaces(void)
static void K_drawKartLaps(void) static void K_drawKartLaps(void)
{ {
INT32 flags = V_SNAPTOLEFT|V_SNAPTOBOTTOM; INT32 splitflags = 0;
if (splitscreen) if (splitscreen && stplyr == &players[secondarydisplayplayer])
flags = 0; 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) 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 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) static void K_drawKartSpeedometer(void)
{ {
fixed_t convSpeed; fixed_t convSpeed;
INT32 flags = V_SNAPTOLEFT|V_SNAPTOBOTTOM;
if (splitscreen) INT32 splitflags = 0;
flags = 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) if (cv_speedometer.value == 1)
{ {
convSpeed = FixedMul(stplyr->speed, 142371)/FRACUNIT; // 2.172409058 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) else if (cv_speedometer.value == 2)
{ {
convSpeed = FixedMul(stplyr->speed, 88465)/FRACUNIT; // 1.349868774 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) else if (cv_speedometer.value == 3)
{ {
convSpeed = stplyr->speed/FRACUNIT; 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) static void K_drawKartBalloonsOrKarma(void)
{ {
UINT8 *colormap = R_GetTranslationColormap(-1, stplyr->skincolor, 0); UINT8 *colormap = R_GetTranslationColormap(-1, stplyr->skincolor, 0);
INT32 flags = V_SNAPTOLEFT|V_SNAPTOBOTTOM;
if (splitscreen) INT32 splitflags = 0;
flags = 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) if (stplyr->kartstuff[k_balloon] <= 0)
{ {
V_DrawScaledPatch(LAPS_X, STRINGY(LAPS_Y), flags, kp_karmasticker); V_DrawMappedPatch(LAPS_X, LAPS_Y, V_SNAPTOLEFT|V_SNAPTOBOTTOM|splitflags, kp_karmasticker, colormap);
V_DrawKartString(LAPS_X+58, STRINGY(LAPS_Y+3), flags, va("%d", stplyr->kartstuff[k_comebackpoints])); V_DrawKartString(LAPS_X+58, LAPS_Y+3, V_SNAPTOLEFT|V_SNAPTOBOTTOM|splitflags, va("%d", stplyr->kartstuff[k_comebackpoints]));
V_DrawKartString(LAPS_X+85, STRINGY(LAPS_Y+3), flags, va("3")); V_DrawKartString(LAPS_X+85, LAPS_Y+3, V_SNAPTOLEFT|V_SNAPTOBOTTOM|splitflags, va("3"));
} }
else else
{ {
if (cv_kartballoons.value > 9) if (cv_kartballoons.value > 9)
{ {
V_DrawMappedPatch(LAPS_X, STRINGY(LAPS_Y), flags, kp_balloonstickerwide, colormap); V_DrawMappedPatch(LAPS_X, LAPS_Y, V_SNAPTOLEFT|V_SNAPTOBOTTOM|splitflags, kp_balloonstickerwide, colormap);
V_DrawKartString(LAPS_X+46, STRINGY(LAPS_Y+3), flags, va("%2d", stplyr->kartstuff[k_balloon])); V_DrawKartString(LAPS_X+46, LAPS_Y+3, V_SNAPTOLEFT|V_SNAPTOBOTTOM|splitflags, va("%2d", stplyr->kartstuff[k_balloon]));
V_DrawKartString(LAPS_X+83, STRINGY(LAPS_Y+3), flags, va("%2d", cv_kartballoons.value)); V_DrawKartString(LAPS_X+83, LAPS_Y+3, V_SNAPTOLEFT|V_SNAPTOBOTTOM|splitflags, va("%2d", cv_kartballoons.value));
} }
else else
{ {
V_DrawMappedPatch(LAPS_X, STRINGY(LAPS_Y), flags, kp_balloonsticker, colormap); V_DrawMappedPatch(LAPS_X, LAPS_Y, V_SNAPTOLEFT|V_SNAPTOBOTTOM|splitflags, kp_balloonsticker, colormap);
V_DrawKartString(LAPS_X+46, STRINGY(LAPS_Y+3), flags, va("%d", stplyr->kartstuff[k_balloon])); V_DrawKartString(LAPS_X+46, LAPS_Y+3, V_SNAPTOLEFT|V_SNAPTOBOTTOM|splitflags, va("%d", stplyr->kartstuff[k_balloon]));
V_DrawKartString(LAPS_X+73, STRINGY(LAPS_Y+3), flags, va("%d", cv_kartballoons.value)); 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; INT32 x;
patch_t *localpatch; 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)) if (!(stplyr->mo))
return; return;
@ -4872,7 +4916,7 @@ static void K_drawKartPlayerCheck(void)
x = 306; x = 306;
colormap = R_GetTranslationColormap(-1, players[i].mo->color, 0); 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 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); y = 232-(stplyr->kartstuff[k_cardanimation]/2);
else else
y = -32+(stplyr->kartstuff[k_cardanimation]/2); y = -32+(stplyr->kartstuff[k_cardanimation]/2);
@ -4926,8 +4971,8 @@ static void K_drawBattleFullscreen(void)
else else
V_DrawScaledPatch(BASEVIDWIDTH/2, y, 0, kp_battlewait); V_DrawScaledPatch(BASEVIDWIDTH/2, y, 0, kp_battlewait);
V_DrawScaledPatch(BASEVIDWIDTH/2, STRINGY((BASEVIDHEIGHT/2) + 66), 0, kp_timeoutsticker); V_DrawScaledPatch(BASEVIDWIDTH/2, (BASEVIDHEIGHT/2) + 66, 0, kp_timeoutsticker);
V_DrawKartString(x, STRINGY((BASEVIDHEIGHT/2) + 66), 0, va("%d", stplyr->kartstuff[k_comebacktimer]/TICRATE)); V_DrawKartString(x, (BASEVIDHEIGHT/2) + 66, 0, va("%d", stplyr->kartstuff[k_comebacktimer]/TICRATE));
} }
} }
@ -4963,7 +5008,7 @@ static void K_drawStartLakitu(void)
else else
adjustY = 200; 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) static void K_drawLapLakitu(void)
@ -5033,7 +5078,7 @@ static void K_drawLapLakitu(void)
adjustY = 200; 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) void K_drawKartHUD(void)
@ -5043,7 +5088,12 @@ void K_drawKartHUD(void)
K_initKartHUD(); K_initKartHUD();
// Draw full screen stuff that turns off the rest of the HUD // 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(); K_drawBattleFullscreen();
return; return;
@ -5052,19 +5102,19 @@ void K_drawKartHUD(void)
// Draw Lakitu // Draw Lakitu
// This is done first so that regardless of HUD layers, // This is done first so that regardless of HUD layers,
// he'll appear to be in the 'real world' // he'll appear to be in the 'real world'
if (!splitscreen) if (!(splitscreen || splitscreen3 || splitscreen4))
{ {
if (leveltime < 178) if (leveltime < 178)
K_drawStartLakitu(); K_drawStartLakitu();
if (stplyr->kartstuff[k_lapanimation]) if (stplyr->kartstuff[k_lapanimation])
K_drawLapLakitu(); 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 the item window is closing, draw it closing!
if (stplyr->kartstuff[k_itemclose]) if (stplyr->kartstuff[k_itemclose])
K_drawKartItemClose(); K_drawKartItemClose();
@ -5079,16 +5129,23 @@ void K_drawKartHUD(void)
K_drawKartRetroItem(); K_drawKartRetroItem();
//K_DrawKartTripleItem(); //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 little triple-item icons at the bottom
// The top-four faces on the left // The top-four faces on the left
K_drawKartPositionFaces(); K_drawKartPositionFaces();
// Draw the speedometer
// TODO: Make a better speedometer.
K_drawKartSpeedometer();
} }
if (gametype == GT_RACE) // Race-only elements if (gametype == GT_RACE) // Race-only elements
@ -5096,10 +5153,6 @@ void K_drawKartHUD(void)
// Draw the numerical position // Draw the numerical position
K_DrawKartPositionNum(stplyr->kartstuff[k_position]); K_DrawKartPositionNum(stplyr->kartstuff[k_position]);
// Draw the speedometer
// TODO: Make a better speedometer.
K_drawKartSpeedometer();
// Draw the lap counter // Draw the lap counter
K_drawKartLaps(); K_drawKartLaps();
} }

View File

@ -6136,7 +6136,7 @@ void P_RunOverlays(void)
if (!mo->target) if (!mo->target)
continue; continue;
if (!splitscreen /*&& rendermode != render_soft*/) if (!(splitscreen || splitscreen3 || splitscreen4) /*&& rendermode != render_soft*/)
{ {
angle_t viewingangle; angle_t viewingangle;
@ -6779,8 +6779,7 @@ void P_MobjThinker(mobj_t *mobj)
fixed_t scale = mobj->target->scale; fixed_t scale = mobj->target->scale;
mobj->color = mobj->target->color; mobj->color = mobj->target->color;
if ((splitscreen || !netgame) if (!netgame || gametype == GT_RACE
|| gametype == GT_RACE
|| mobj->target->player == &players[displayplayer] || mobj->target->player == &players[displayplayer]
|| mobj->target->player->kartstuff[k_balloon] <= 0 || mobj->target->player->kartstuff[k_balloon] <= 0
|| (mobj->target->player->mo->flags2 & MF2_DONTDRAW)) || (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); 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 // 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); S_StartSound(NULL, sfx_hoop1);
redflag = flagmo; 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); 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 // 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); S_StartSound(NULL, sfx_hoop1);
blueflag = flagmo; blueflag = flagmo;

View File

@ -2354,10 +2354,20 @@ static void P_ForceCharacter(const char *forcecharskin)
if (netgame) if (netgame)
{ {
char skincmd[33]; char skincmd[33];
if (splitscreen) if (splitscreen || splitscreen3 || splitscreen4)
{ {
sprintf(skincmd, "skin2 %s\n", forcecharskin); sprintf(skincmd, "skin2 %s\n", forcecharskin);
CV_Set(&cv_skin2, 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); sprintf(skincmd, "skin %s\n", forcecharskin);
@ -2583,7 +2593,7 @@ boolean P_SetupLevel(boolean skipprecip)
P_LevelInitStuff(); P_LevelInitStuff();
postimgtype = postimgtype2 = postimg_none; postimgtype = postimgtype2 = postimgtype3 = postimgtype4 = postimg_none;
if (mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0' if (mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0'
&& atoi(mapheaderinfo[gamemap-1]->forcecharacter) != 255) && atoi(mapheaderinfo[gamemap-1]->forcecharacter) != 255)
@ -2920,10 +2930,20 @@ boolean P_SetupLevel(boolean skipprecip)
if (!cv_cam2_rotate.changed) if (!cv_cam2_rotate.changed)
CV_Set(&cv_cam2_rotate, cv_cam2_rotate.defaultvalue); 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) if (!cv_analog.changed)
CV_SetValue(&cv_analog, 0); CV_SetValue(&cv_analog, 0);
if (!cv_analog2.changed) if (!cv_analog2.changed)
CV_SetValue(&cv_analog2, 0); 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 #ifdef HWRENDER
if (rendermode != render_soft && rendermode != render_none) if (rendermode != render_soft && rendermode != render_none)
@ -2936,13 +2956,21 @@ boolean P_SetupLevel(boolean skipprecip)
if (cv_useranalog.value) if (cv_useranalog.value)
CV_SetValue(&cv_analog, true); CV_SetValue(&cv_analog, true);
if (splitscreen && cv_useranalog2.value) if ((splitscreen || splitscreen3 || splitscreen4) && cv_useranalog2.value)
CV_SetValue(&cv_analog2, true); CV_SetValue(&cv_analog2, true);
else if (botingame) else if (botingame)
CV_SetValue(&cv_analog2, true); 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) if (twodlevel)
{ {
CV_SetValue(&cv_analog4, false);
CV_SetValue(&cv_analog3, false);
CV_SetValue(&cv_analog2, false); CV_SetValue(&cv_analog2, false);
CV_SetValue(&cv_analog, false); CV_SetValue(&cv_analog, false);
} }
@ -2998,7 +3026,7 @@ boolean P_SetupLevel(boolean skipprecip)
savedata.lives = 0; 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 if (loadprecip) // uglier hack
{ // to make a newly loaded level start on the second frame. { // to make a newly loaded level start on the second frame.
INT32 buf = gametic % BACKUPTICS; INT32 buf = gametic % BACKUPTICS;

View File

@ -3898,7 +3898,7 @@ DoneSection2:
HU_SetCEchoDuration(5); HU_SetCEchoDuration(5);
HU_DoCEcho(va(M_GetText("%s\\captured the blue flag.\\\\\\\\"), player_names[player-players])); 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); S_StartSound(NULL, sfx_flgcap);
else if (players[consoleplayer].ctfteam == 2) else if (players[consoleplayer].ctfteam == 2)
S_StartSound(NULL, sfx_lose); S_StartSound(NULL, sfx_lose);
@ -3931,7 +3931,7 @@ DoneSection2:
HU_SetCEchoDuration(5); HU_SetCEchoDuration(5);
HU_DoCEcho(va(M_GetText("%s\\captured the red flag.\\\\\\\\"), player_names[player-players])); 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); S_StartSound(NULL, sfx_flgcap);
else if (players[consoleplayer].ctfteam == 1) else if (players[consoleplayer].ctfteam == 1)
S_StartSound(NULL, sfx_lose); S_StartSound(NULL, sfx_lose);
@ -4189,7 +4189,7 @@ DoneSection2:
if (P_IsLocalPlayer(player)) if (P_IsLocalPlayer(player))
{ {
// SRB2kart 200117 // SRB2kart 200117
if (!splitscreen) if (!(splitscreen || splitscreen3 || splitscreen4))
{ {
if (player->kartstuff[k_position] == 1) if (player->kartstuff[k_position] == 1)
S_ChangeMusicInternal("karwin", true); S_ChangeMusicInternal("karwin", true);

View File

@ -591,7 +591,7 @@ void P_Ticker(boolean run)
if (paused || P_AutoPause()) if (paused || P_AutoPause())
return; return;
postimgtype = postimgtype2 = postimg_none; postimgtype = postimgtype2 = postimgtype3 = postimgtype4 = postimg_none;
P_MapStart(); P_MapStart();
@ -711,7 +711,7 @@ void P_PreTicker(INT32 frames)
INT32 i,framecnt; INT32 i,framecnt;
ticcmd_t temptic; ticcmd_t temptic;
postimgtype = postimgtype2 = postimg_none; postimgtype = postimgtype2 = postimgtype3 = postimgtype4 = postimg_none;
for (framecnt = 0; framecnt < frames; ++framecnt) for (framecnt = 0; framecnt < frames; ++framecnt)
{ {

View File

@ -1663,7 +1663,7 @@ void P_DoPlayerExit(player_t *player)
if (P_IsLocalPlayer(player) && cv_inttime.value > 0) if (P_IsLocalPlayer(player) && cv_inttime.value > 0)
{ {
if (!splitscreen) if (!(splitscreen || splitscreen3 || splitscreen4))
{ {
if (player->kartstuff[k_position] == 1) if (player->kartstuff[k_position] == 1)
S_ChangeMusicInternal("karwin", true); 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 // 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). // 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) if (player->gotflag & GF_REDFLAG)
{ {
@ -8530,18 +8530,24 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
{ {
dist = camdist; dist = camdist;
if (splitscreen || splitscreen3 || splitscreen4) // x1.5 dist for splitscreen // 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); dist = FixedMul(dist, 3*FRACUNIT/2);
height = FixedMul(height, 3*FRACUNIT/2); height = FixedMul(height, 3*FRACUNIT/2);
} }
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);
}
// x1.2 dist for analog // x1.2 dist for analog
if (P_AnalogMove(player)) /*if (P_AnalogMove(player))
{ {
dist = FixedMul(dist, 6*FRACUNIT/5); dist = FixedMul(dist, 6*FRACUNIT/5);
height = FixedMul(height, 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))) if (player->climbing || player->exiting || player->playerstate == PST_DEAD || (player->pflags & (PF_MACESPIN|PF_ITEMHANG|PF_ROPEHANG)))
dist <<= 1; dist <<= 1;
@ -8864,7 +8870,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall
} }
// Make player translucent if camera is too close (only in single player). // 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; fixed_t vx = 0, vy = 0;
if (player->awayviewtics) { if (player->awayviewtics) {
@ -9401,7 +9407,7 @@ void P_PlayerThink(player_t *player)
player->realtime = 0; 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)) if (P_SpectatorJoinGame(player))
return; // player->mo was removed. return; // player->mo was removed.
@ -9643,7 +9649,10 @@ void P_PlayerThink(player_t *player)
if (!(player->pflags & PF_NIGHTSMODE)) if (!(player->pflags & PF_NIGHTSMODE))
{ {
// SRB2kart - fixes boo not flashing when it should. Mega doesn't flash either. Flashing is local. // 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_bootimer] == 0 && player->kartstuff[k_growshrinktimer] <= 0
&& (player->kartstuff[k_comebacktimer] == 0 || (gametype == GT_RACE || player->kartstuff[k_balloon] > 0))) && (player->kartstuff[k_comebacktimer] == 0 || (gametype == GT_RACE || player->kartstuff[k_balloon] > 0)))
{ {

View File

@ -195,12 +195,12 @@ void SplitScreen_OnChange(void)
CL_AddSplitscreenPlayer(); CL_AddSplitscreenPlayer();
else else
CL_RemoveSplitscreenPlayer(secondarydisplayplayer); CL_RemoveSplitscreenPlayer(secondarydisplayplayer);
if (splitscreen3 || splitscreen4) if (splitscreen3 || splitscreen4)
CL_AddSplitscreenPlayer(); CL_AddSplitscreenPlayer();
else else
CL_RemoveSplitscreenPlayer(thirddisplayplayer); CL_RemoveSplitscreenPlayer(thirddisplayplayer);
if (splitscreen4) if (splitscreen4)
CL_AddSplitscreenPlayer(); CL_AddSplitscreenPlayer();
else else

View File

@ -85,7 +85,7 @@ extern side_t *sides;
extern fixed_t viewx, viewy, viewz; extern fixed_t viewx, viewy, viewz;
extern angle_t viewangle, aimingangle; extern angle_t viewangle, aimingangle;
extern boolean viewsky, skyVisible; 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 sector_t *viewsector;
extern player_t *viewplayer; extern player_t *viewplayer;
extern UINT8 portalrender; extern UINT8 portalrender;

View File

@ -229,7 +229,7 @@ void ST_doPaletteStuff(void)
if (rendermode != render_none) if (rendermode != render_none)
{ {
V_SetPaletteLump(GetPalette()); // Reset the palette V_SetPaletteLump(GetPalette()); // Reset the palette
if (!splitscreen) if (!(splitscreen || splitscreen3 || splitscreen4))
V_SetPalette(palette); V_SetPalette(palette);
} }
} }
@ -445,7 +445,7 @@ static INT32 SCY(INT32 y)
// do not scale to resolution for hardware accelerated // do not scale to resolution for hardware accelerated
// because these modes always scale by default // because these modes always scale by default
y = SCZ(y); // scale to resolution y = SCZ(y); // scale to resolution
if (splitscreen) if (splitscreen || splitscreen3 || splitscreen4)
{ {
y >>= 1; y >>= 1;
if (stplyr != &players[displayplayer]) 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 //31/10/99: fixed by Hurdler so it _works_ also in hardware mode
// do not scale to resolution for hardware accelerated // do not scale to resolution for hardware accelerated
// because these modes always scale by default // because these modes always scale by default
if (splitscreen) if (splitscreen || splitscreen3 || splitscreen4)
{ {
y >>= 1; y >>= 1;
if (stplyr != &players[displayplayer]) if (stplyr != &players[displayplayer])
@ -472,7 +472,7 @@ static INT32 STRINGY(INT32 y)
static INT32 SPLITFLAGS(INT32 f) static INT32 SPLITFLAGS(INT32 f)
{ {
// Pass this V_SNAPTO(TOP|BOTTOM) and it'll trim them to account for splitscreen! -Red // 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]) if (stplyr != &players[displayplayer])
f &= ~V_SNAPTOTOP; f &= ~V_SNAPTOTOP;
@ -496,7 +496,7 @@ static INT32 SCR(INT32 r)
// do not scale to resolution for hardware accelerated // do not scale to resolution for hardware accelerated
// because these modes always scale by default // because these modes always scale by default
y = FixedMul(r*FRACUNIT, vid.fdupy); // scale to resolution y = FixedMul(r*FRACUNIT, vid.fdupy); // scale to resolution
if (splitscreen) if (splitscreen || splitscreen3 || splitscreen4)
{ {
y >>= 1; y >>= 1;
if (stplyr != &players[displayplayer]) if (stplyr != &players[displayplayer])
@ -668,7 +668,7 @@ static void ST_drawTime(void)
ST_DrawPatchFromHudWS(HUD_TIMECOLON, sbocolon); // Colon ST_DrawPatchFromHudWS(HUD_TIMECOLON, sbocolon); // Colon
ST_DrawPadNumFromHudWS(HUD_SECONDS, seconds, 2); // Seconds 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_DrawPatchFromHud(HUD_TIMETICCOLON, sboperiod); // Period
ST_DrawPadNumFromHud(HUD_TICS, tictrn, 2); // Tics ST_DrawPadNumFromHud(HUD_TICS, tictrn, 2); // Tics
@ -700,7 +700,7 @@ static inline void ST_drawRings(void)
/* /*
static void ST_drawLives(void) // SRB2kart - unused. 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) if (!stplyr->skincolor)
return; // Just joined a server, skin isn't loaded yet! return; // Just joined a server, skin isn't loaded yet!
@ -838,7 +838,7 @@ static void ST_drawFirstPersonHUD(void)
if (p) if (p)
{ {
if (splitscreen) if (splitscreen || splitscreen3 || splitscreen4)
V_DrawSmallScaledPatch(312, STRINGY(24), V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, p); V_DrawSmallScaledPatch(312, STRINGY(24), V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, p);
else else
V_DrawScaledPatch(304, 24, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, p); 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]; invulntime = player->powers[pw_flashing] ? 1 : player->powers[pw_invulnerability];
if (invulntime > 3*TICRATE || (invulntime && leveltime & 1)) 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); V_DrawSmallScaledPatch(312, STRINGY(24) + 14, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, invincibility);
else else
V_DrawScaledPatch(304, 24 + 28, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, invincibility); 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 (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); V_DrawSmallScaledPatch(312, STRINGY(24) + 28, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, sneakers);
else else
V_DrawScaledPatch(304, 24 + 56, V_SNAPTORIGHT|V_SNAPTOTOP|V_HUDTRANS, sneakers); 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) static inline void ST_drawTeamName(void)
{ {
if (stplyr->ctfteam == 1) 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) 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 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(); 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) if (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1)
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), 0, M_GetText("Press F12 to watch another player.")); V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), 0, M_GetText("Press F12 to watch another player."));

View File

@ -425,7 +425,10 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
} }
if (scrn & V_SPLITSCREEN) if (scrn & V_SPLITSCREEN)
y>>=1; y += (BASEVIDHEIGHT/2)<<FRACBITS;
if (scrn & V_HORZSCREEN)
x += (BASEVIDWIDTH/2)<<FRACBITS;
desttop = screens[scrn&V_PARAMMASK]; desttop = screens[scrn&V_PARAMMASK];
@ -455,7 +458,9 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
{ {
// dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx, // dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx,
// so center this imaginary screen // so center this imaginary screen
if (scrn & V_SNAPTORIGHT) if ((scrn & (V_HORZSCREEN|V_SNAPTORIGHT)) == (V_HORZSCREEN|V_SNAPTORIGHT))
desttop += (vid.width/2 - (BASEVIDWIDTH/2 * dupx));
else if (scrn & V_SNAPTORIGHT)
desttop += (vid.width - (BASEVIDWIDTH * dupx)); desttop += (vid.width - (BASEVIDWIDTH * dupx));
else if (!(scrn & V_SNAPTOLEFT)) else if (!(scrn & V_SNAPTOLEFT))
desttop += (vid.width - (BASEVIDWIDTH * dupx)) / 2; desttop += (vid.width - (BASEVIDWIDTH * dupx)) / 2;
@ -463,7 +468,7 @@ void V_DrawFixedPatch(fixed_t x, fixed_t y, fixed_t pscale, INT32 scrn, patch_t
if (vid.height != BASEVIDHEIGHT * dupy) if (vid.height != BASEVIDHEIGHT * dupy)
{ {
// same thing here // same thing here
if ((scrn & (V_SPLITSCREEN|V_SNAPTOBOTTOM)) == (V_SPLITSCREEN|V_SNAPTOBOTTOM)) if ((scrn & (V_SPLITSCREEN|V_SNAPTOTOP)) == (V_SPLITSCREEN|V_SNAPTOTOP))
desttop += (vid.height/2 - (BASEVIDHEIGHT/2 * dupy)) * vid.width; desttop += (vid.height/2 - (BASEVIDHEIGHT/2 * dupy)) * vid.width;
else if (scrn & V_SNAPTOBOTTOM) else if (scrn & V_SNAPTOBOTTOM)
desttop += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width; desttop += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width;
@ -1977,7 +1982,7 @@ void V_DoPostProcessor(INT32 view, postimg_t type, INT32 param)
return; return;
#endif #endif
if (view < 0 || view >= 2 || (view == 1 && !splitscreen)) if (view < 0 || view >= 2 || (view == 1 && !(splitscreen || splitscreen3 || splitscreen4)))
return; return;
if (splitscreen) if (splitscreen)

View File

@ -92,24 +92,24 @@ extern RGBA_t *pLocalPalette;
#define V_90TRANS 0x00090000 #define V_90TRANS 0x00090000
#define V_HUDTRANSHALF 0x000D0000 #define V_HUDTRANSHALF 0x000D0000
#define V_HUDTRANS 0x000E0000 // draw the hud translucent #define V_HUDTRANS 0x000E0000 // draw the hud translucent
#define V_HUDTRANSDOUBLE 0x000F0000
#define V_AUTOFADEOUT 0x00100000 // used by CECHOs, automatic fade out when almost over #define V_AUTOFADEOUT 0x000F0000 // used by CECHOs, automatic fade out when almost over
#define V_RETURN8 0x00200000 // 8 pixel return instead of 12 #define V_RETURN8 0x00100000 // 8 pixel return instead of 12
#define V_OFFSET 0x00400000 // account for offsets in patches #define V_OFFSET 0x00200000 // account for offsets in patches
#define V_ALLOWLOWERCASE 0x00800000 // (strings only) allow fonts that have lowercase letters to use them #define V_ALLOWLOWERCASE 0x00400000 // (strings only) allow fonts that have lowercase letters to use them
#define V_FLIP 0x00800000 // (patches only) Horizontal flip #define V_FLIP 0x00400000 // (patches only) Horizontal flip
#define V_SNAPTOTOP 0x01000000 // for centering #define V_SNAPTOTOP 0x00800000 // for centering
#define V_SNAPTOBOTTOM 0x02000000 // for centering #define V_SNAPTOBOTTOM 0x01000000 // for centering
#define V_SNAPTOLEFT 0x04000000 // for centering #define V_SNAPTOLEFT 0x02000000 // for centering
#define V_SNAPTORIGHT 0x08000000 // for centering #define V_SNAPTORIGHT 0x04000000 // for centering
#define V_WRAPX 0x10000000 // Don't clamp texture on X (for HW mode) #define V_WRAPX 0x08000000 // Don't clamp texture on X (for HW mode)
#define V_WRAPY 0x20000000 // Don't clamp texture on Y (for HW mode) #define V_WRAPY 0x10000000 // Don't clamp texture on Y (for HW mode)
#define V_NOSCALESTART 0x40000000 // don't scale x, y, start coords #define V_NOSCALESTART 0x20000000 // don't scale x, y, start coords
#define V_SPLITSCREEN 0x80000000 #define V_SPLITSCREEN 0x40000000
#define V_HORZSCREEN 0x80000000
// defines for old functions // defines for old functions
#define V_DrawPatch(x,y,s,p) V_DrawFixedPatch((x)<<FRACBITS, (y)<<FRACBITS, FRACUNIT, s|V_NOSCALESTART|V_NOSCALEPATCH, p, NULL) #define V_DrawPatch(x,y,s,p) V_DrawFixedPatch((x)<<FRACBITS, (y)<<FRACBITS, FRACUNIT, s|V_NOSCALESTART|V_NOSCALEPATCH, p, NULL)