Merge branch 'v1' into no-limits

This commit is contained in:
TehRealSalt 2019-05-06 21:55:33 -04:00
commit 47484c5b6b
102 changed files with 9089 additions and 4892 deletions

View File

@ -401,7 +401,11 @@ if(${SRB2_CONFIG_HWRENDER})
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_light.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2load.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md3load.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_model.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_trick.c
${CMAKE_CURRENT_SOURCE_DIR}/hardware/u_list.c
)
set (SRB2_HWRENDER_HEADERS
@ -415,6 +419,10 @@ if(${SRB2_CONFIG_HWRENDER})
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_light.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_main.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md2load.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_md3load.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/hw_model.h
${CMAKE_CURRENT_SOURCE_DIR}/hardware/u_list.h
)
set(SRB2_R_OPENGL_SOURCES

View File

@ -282,7 +282,8 @@ ifndef DC
endif
OPTS+=-DHWRENDER
OBJS+=$(OBJDIR)/hw_bsp.o $(OBJDIR)/hw_draw.o $(OBJDIR)/hw_light.o \
$(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o $(OBJDIR)/hw_trick.o
$(OBJDIR)/hw_main.o $(OBJDIR)/hw_clip.o $(OBJDIR)/hw_md2.o $(OBJDIR)/hw_cache.o $(OBJDIR)/hw_trick.o \
$(OBJDIR)/hw_md2load.o $(OBJDIR)/hw_md3load.o $(OBJDIR)/hw_model.o $(OBJDIR)/u_list.o
endif
ifdef NOHS
@ -741,16 +742,18 @@ ifdef MINGW
$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \
d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \
hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \
am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
$(CC) $(CFLAGS) $(WFLAGS) -c $< -o $@
else
$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \
d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \
hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \
am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
$(CC) $(CFLAGS) $(WFLAGS) -I/usr/X11R6/include -c $< -o $@
endif
@ -902,24 +905,27 @@ ifndef NOHW
$(OBJDIR)/r_opengl.o: hardware/r_opengl/r_opengl.c hardware/r_opengl/r_opengl.h \
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \
d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \
hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \
am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
$(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@
$(OBJDIR)/ogl_win.o: hardware/r_opengl/ogl_win.c hardware/r_opengl/r_opengl.h \
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \
d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \
hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \
am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
$(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@
$(OBJDIR)/r_minigl.o: hardware/r_minigl/r_minigl.c hardware/r_opengl/r_opengl.h \
doomdef.h doomtype.h g_state.h m_swap.h hardware/hw_drv.h screen.h \
command.h hardware/hw_data.h hardware/hw_glide.h hardware/hw_defs.h \
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h am_map.h \
d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
hardware/hw_md2.h hardware/hw_glob.h hardware/hw_main.h hardware/hw_clip.h \
hardware/hw_md2load.h hardware/hw_md3load.h hardware/hw_model.h hardware/u_list.h \
am_map.h d_event.h d_player.h p_pspr.h m_fixed.h tables.h info.h d_think.h \
p_mobj.h doomdata.h d_ticcmd.h r_defs.h hardware/hw_dll.h
$(CC) $(CFLAGS) $(WFLAGS) -D_WINDOWS -mwindows -c $< -o $@
endif

View File

@ -271,12 +271,6 @@ void B_RespawnBot(INT32 playernum)
player->powers[pw_nocontrol] = sonic->player->powers[pw_nocontrol];
P_TeleportMove(tails, x, y, z);
if (player->charability == CA_FLY)
{
P_SetPlayerMobjState(tails, S_KART_STND1); // SRB2kart - was S_PLAY_ABL1
tails->player->powers[pw_tailsfly] = (UINT16)-1;
}
else
P_SetPlayerMobjState(tails, S_KART_STND1); // SRB2kart - was S_PLAY_FALL1
P_SetScale(tails, sonic->scale);
tails->destscale = sonic->destscale;

View File

@ -50,6 +50,7 @@ static void COM_Exec_f(void);
static void COM_Wait_f(void);
static void COM_Help_f(void);
static void COM_Toggle_f(void);
static void COM_Add_f(void);
static void CV_EnforceExecVersion(void);
static boolean CV_FilterVarByVersion(consvar_t *v, const char *valstr);
@ -291,6 +292,7 @@ void COM_Init(void)
COM_AddCommand("wait", COM_Wait_f);
COM_AddCommand("help", COM_Help_f);
COM_AddCommand("toggle", COM_Toggle_f);
COM_AddCommand("add", COM_Add_f);
RegisterNetXCmd(XD_NETVAR, Got_NetVar);
}
@ -537,10 +539,41 @@ static void COM_ExecuteString(char *ptext)
{
CONS_Alert(CONS_WARNING, M_GetText("Alias recursion cycle detected!\n"));
recursion = 0;
return;
}
else
{
char buf[1024];
char *write = buf, *read = a->value, *seek = read;
while ((seek = strchr(seek, '$')) != NULL)
{
memcpy(write, read, seek-read);
write += seek-read;
seek++;
if (*seek >= '1' && *seek <= '9')
{
if (com_argc > (size_t)(*seek - '0'))
{
memcpy(write, com_argv[*seek - '0'], strlen(com_argv[*seek - '0']));
write += strlen(com_argv[*seek - '0']);
}
seek++;
}
else
{
*write = '$';
write++;
}
read = seek;
}
WRITESTRING(write, read);
recursion++;
COM_BufInsertText(a->value);
COM_BufInsertText(buf);
}
return;
}
}
@ -563,8 +596,6 @@ static void COM_ExecuteString(char *ptext)
static void COM_Alias_f(void)
{
cmdalias_t *a;
char cmd[1024];
size_t i, c;
if (COM_Argc() < 3)
{
@ -577,19 +608,9 @@ static void COM_Alias_f(void)
com_alias = a;
a->name = Z_StrDup(COM_Argv(1));
// copy the rest of the command line
cmd[0] = 0; // start out with a null string
c = COM_Argc();
for (i = 2; i < c; i++)
{
strcat(cmd, COM_Argv(i));
if (i != c)
strcat(cmd, " ");
}
strcat(cmd, "\n");
a->value = Z_StrDup(cmd);
// Just use arg 2 if it's the only other argument, in case the alias is wrapped in quotes (backward compat, or multiple commands in one string).
// Otherwise pull the whole string and seek to the end of the alias name. The strctr is in case the alias is quoted.
a->value = Z_StrDup(COM_Argc() == 3 ? COM_Argv(2) : (strchr(COM_Args() + strlen(a->name), ' ') + 1));
}
/** Prints a line of text to the console.
@ -855,6 +876,27 @@ static void COM_Toggle_f(void)
CV_AddValue(cvar, +1);
}
/** Command variant of CV_AddValue
*/
static void COM_Add_f(void)
{
consvar_t *cvar;
if (COM_Argc() != 3)
{
CONS_Printf(M_GetText("Add <cvar_name> <value>: Add to the value of a cvar. Negative values work too!\n"));
return;
}
cvar = CV_FindVar(COM_Argv(1));
if (!cvar)
{
CONS_Alert(CONS_NOTICE, M_GetText("%s is not a cvar\n"), COM_Argv(1));
return;
}
CV_AddValue(cvar, atoi(COM_Argv(2)));
}
// =========================================================================
// VARIABLE SIZE BUFFERS
// =========================================================================
@ -1356,7 +1398,7 @@ static void Got_NetVar(UINT8 **p, INT32 playernum)
Setvalue(cvar, svalue, stealth);
}
void CV_SaveNetVars(UINT8 **p)
void CV_SaveNetVars(UINT8 **p, boolean isdemorecording)
{
consvar_t *cvar;
UINT8 *count_p = *p;
@ -1366,10 +1408,32 @@ void CV_SaveNetVars(UINT8 **p)
// the client will reset all netvars to default before loading
WRITEUINT16(*p, 0x0000);
for (cvar = consvar_vars; cvar; cvar = cvar->next)
if ((cvar->flags & CV_NETVAR) && !CV_IsSetToDefault(cvar))
if (((cvar->flags & CV_NETVAR) && !CV_IsSetToDefault(cvar)) || (isdemorecording && cvar->netid == cv_numlaps.netid))
{
WRITEUINT16(*p, cvar->netid);
// UGLY HACK: Save proper lap count in net replays
if (isdemorecording && cvar->netid == cv_numlaps.netid)
{
if (cv_basenumlaps.value &&
(!(mapheaderinfo[gamemap - 1]->levelflags & LF_SECTIONRACE)
|| (mapheaderinfo[gamemap - 1]->numlaps > cv_basenumlaps.value))
)
{
WRITESTRING(*p, cv_basenumlaps.string);
}
else
{
char buf[9];
sprintf(buf, "%d", mapheaderinfo[gamemap - 1]->numlaps);
WRITESTRING(*p, buf);
}
}
else
{
WRITESTRING(*p, cvar->string);
}
WRITEUINT8(*p, false);
++count;
}

View File

@ -161,7 +161,7 @@ void CV_AddValue(consvar_t *var, INT32 increment);
void CV_SaveVariables(FILE *f);
// load/save gamesate (load and save option and for network join in game)
void CV_SaveNetVars(UINT8 **p);
void CV_SaveNetVars(UINT8 **p, boolean isdemorecording);
void CV_LoadNetVars(UINT8 **p);
// reset cheat netvars after cheats is deactivated

View File

@ -92,12 +92,10 @@ tic_t jointimeout = (3*TICRATE);
static boolean sendingsavegame[MAXNETNODES]; // Are we sending the savegame?
static tic_t freezetimeout[MAXNETNODES]; // Until when can this node freeze the server before getting a timeout?
#ifdef NEWPING
UINT16 pingmeasurecount = 1;
UINT32 realpingtable[MAXPLAYERS]; //the base table of ping where an average will be sent to everyone.
UINT32 playerpingtable[MAXPLAYERS]; //table of player latency values.
tic_t servermaxping = 800; // server's max ping. Defaults to 800
#endif
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 (splitscreen == 2)
@ -141,6 +139,7 @@ static UINT8 localtextcmd3[MAXTEXTCMD]; // splitscreen == 2
static UINT8 localtextcmd4[MAXTEXTCMD]; // splitscreen == 3
static tic_t neededtic;
SINT8 servernode = 0; // the number of the server node
char connectedservername[MAXSERVERNAME];
/// \brief do we accept new players?
/// \todo WORK!
boolean acceptnewnode = true;
@ -168,7 +167,7 @@ ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS];
static textcmdtic_t *textcmds[TEXTCMD_HASH_SIZE] = {NULL};
consvar_t cv_showjoinaddress = {"showjoinaddress", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_showjoinaddress = {"showjoinaddress", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t playbackspeed_cons_t[] = {{1, "MIN"}, {10, "MAX"}, {0, NULL}};
consvar_t cv_playbackspeed = {"playbackspeed", "1", 0, playbackspeed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -586,21 +585,7 @@ static inline void resynch_write_player(resynch_pak *rsp, const size_t i)
rsp->kartspeed = (UINT8)players[i].kartspeed;
rsp->kartweight = (UINT8)players[i].kartweight;
//
rsp->normalspeed = (fixed_t)LONG(players[i].normalspeed);
rsp->runspeed = (fixed_t)LONG(players[i].runspeed);
rsp->thrustfactor = players[i].thrustfactor;
rsp->accelstart = players[i].accelstart;
rsp->acceleration = players[i].acceleration;
rsp->charability = players[i].charability;
rsp->charability2 = players[i].charability2;
rsp->charflags = (UINT32)LONG(players[i].charflags);
rsp->thokitem = (UINT32)LONG(players[i].thokitem); //mobjtype_t
rsp->spinitem = (UINT32)LONG(players[i].spinitem); //mobjtype_t
rsp->revitem = (UINT32)LONG(players[i].revitem); //mobjtype_t
rsp->actionspd = (fixed_t)LONG(players[i].actionspd);
rsp->mindash = (fixed_t)LONG(players[i].mindash);
rsp->maxdash = (fixed_t)LONG(players[i].maxdash);
rsp->jumpfactor = (fixed_t)LONG(players[i].jumpfactor);
rsp->speed = (fixed_t)LONG(players[i].speed);
rsp->jumping = players[i].jumping;
@ -723,21 +708,7 @@ static void resynch_read_player(resynch_pak *rsp)
players[i].kartspeed = (UINT8)rsp->kartspeed;
players[i].kartweight = (UINT8)rsp->kartweight;
players[i].normalspeed = (fixed_t)LONG(rsp->normalspeed);
players[i].runspeed = (fixed_t)LONG(rsp->runspeed);
players[i].thrustfactor = rsp->thrustfactor;
players[i].accelstart = rsp->accelstart;
players[i].acceleration = rsp->acceleration;
players[i].charability = rsp->charability;
players[i].charability2 = rsp->charability2;
players[i].charflags = (UINT32)LONG(rsp->charflags);
players[i].thokitem = (UINT32)LONG(rsp->thokitem); //mobjtype_t
players[i].spinitem = (UINT32)LONG(rsp->spinitem); //mobjtype_t
players[i].revitem = (UINT32)LONG(rsp->revitem); //mobjtype_t
players[i].actionspd = (fixed_t)LONG(rsp->actionspd);
players[i].mindash = (fixed_t)LONG(rsp->mindash);
players[i].maxdash = (fixed_t)LONG(rsp->maxdash);
players[i].jumpfactor = (fixed_t)LONG(rsp->jumpfactor);
players[i].speed = (fixed_t)LONG(rsp->speed);
players[i].jumping = rsp->jumping;
@ -1465,33 +1436,13 @@ static void SV_SendPlayerInfo(INT32 node)
continue;
}
netbuffer->u.playerinfo[i].node = (UINT8)playernode[i];
netbuffer->u.playerinfo[i].node = i;
strncpy(netbuffer->u.playerinfo[i].name, (const char *)&player_names[i], MAXPLAYERNAME+1);
netbuffer->u.playerinfo[i].name[MAXPLAYERNAME] = '\0';
//fetch IP address
{
const char *claddress;
UINT32 numericaddress[4];
//No, don't do that, you fuckface.
memset(netbuffer->u.playerinfo[i].address, 0, 4);
if (playernode[i] == 0)
{
//127.0.0.1
netbuffer->u.playerinfo[i].address[0] = 127;
netbuffer->u.playerinfo[i].address[3] = 1;
}
else if (playernode[i] > 0 && I_GetNodeAddress && (claddress = I_GetNodeAddress(playernode[i])) != NULL)
{
if (sscanf(claddress, "%d.%d.%d.%d", &numericaddress[0], &numericaddress[1], &numericaddress[2], &numericaddress[3]) < 4)
goto badaddress;
netbuffer->u.playerinfo[i].address[0] = (UINT8)numericaddress[0];
netbuffer->u.playerinfo[i].address[1] = (UINT8)numericaddress[1];
netbuffer->u.playerinfo[i].address[2] = (UINT8)numericaddress[2];
netbuffer->u.playerinfo[i].address[3] = (UINT8)numericaddress[3];
}
}
badaddress:
if (G_GametypeHasTeams())
{
@ -1576,7 +1527,7 @@ static boolean SV_SendServerConfig(INT32 node)
op = p = netbuffer->u.servercfg.varlengthinputs;
CV_SavePlayerNames(&p);
CV_SaveNetVars(&p);
CV_SaveNetVars(&p, false);
{
const size_t len = sizeof (serverconfig_pak) + (size_t)(p - op);
@ -1755,8 +1706,8 @@ static void CL_LoadReceivedSavegame(void)
}
paused = false;
demoplayback = false;
titledemo = false;
demo.playback = false;
demo.title = false;
automapactive = false;
// load a base level
@ -2360,6 +2311,9 @@ static void CL_ConnectToServer(boolean viams)
{
INT32 j;
const char *gametypestr = NULL;
strncpy(connectedservername, serverlist[i].info.servername, MAXSERVERNAME);
CONS_Printf(M_GetText("Connecting to: %s\n"), serverlist[i].info.servername);
for (j = 0; gametype_cons_t[j].strvalue; j++)
{
@ -2405,7 +2359,7 @@ static void CL_ConnectToServer(boolean viams)
#endif
DEBFILE(va("Synchronisation Finished\n"));
displayplayer = consoleplayer;
displayplayers[0] = consoleplayer;
}
#ifndef NONET
@ -2577,7 +2531,7 @@ static void Command_connect(void)
return;
}
if (Playing() || titledemo)
if (Playing() || demo.title)
{
CONS_Printf(M_GetText("You cannot connect while in a game. End this game first.\n"));
return;
@ -2669,14 +2623,16 @@ void CL_ClearPlayer(INT32 playernum)
//
// Removes a player from the current game
//
static void CL_RemovePlayer(INT32 playernum, INT32 reason)
void CL_RemovePlayer(INT32 playernum, INT32 reason)
{
// Sanity check: exceptional cases (i.e. c-fails) can cause multiple
// kick commands to be issued for the same player.
if (!playeringame[playernum])
return;
if (server && !demoplayback)
demo_extradata[playernum] |= DXD_PLAYSTATE;
if (server && !demo.playback)
{
INT32 node = playernode[playernum];
//playerpernode[node] = 0; // It'd be better to remove them all at once, but ghosting happened, so continue to let CL_RemovePlayer do it one-by-one
@ -2751,8 +2707,8 @@ static void CL_RemovePlayer(INT32 playernum, INT32 reason)
RemoveAdminPlayer(playernum); // don't stay admin after you're gone
}
if (playernum == displayplayer)
displayplayer = consoleplayer; // don't look through someone's view who isn't there
if (playernum == displayplayers[0] && !demo.playback)
displayplayers[0] = consoleplayer; // don't look through someone's view who isn't there
#ifdef HAVE_BLUA
LUA_InvalidatePlayer(&players[playernum]);
@ -2772,7 +2728,7 @@ void CL_Reset(void)
G_StopMetalRecording();
if (metalplayback)
G_StopMetalDemo();
if (demorecording)
if (demo.recording)
G_CheckDemoStatus();
// reset client/server code
@ -3134,12 +3090,10 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
HU_AddChatText(va("\x82*%s has been kicked (Go away)", player_names[pnum]), false);
kickreason = KR_KICK;
break;
#ifdef NEWPING
case KICK_MSG_PING_HIGH:
HU_AddChatText(va("\x82*%s left the game (Broke ping limit)", player_names[pnum]), false);
kickreason = KR_PINGLIMIT;
break;
#endif
case KICK_MSG_CON_FAIL:
HU_AddChatText(va("\x82*%s left the game (Synch Failure)", player_names[pnum]), false);
kickreason = KR_SYNCH;
@ -3212,10 +3166,8 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
D_StartTitle();
if (msg == KICK_MSG_CON_FAIL)
M_StartMessage(M_GetText("Server closed connection\n(Synch failure)\nPress ESC\n"), NULL, MM_NOTHING);
#ifdef NEWPING
else if (msg == KICK_MSG_PING_HIGH)
M_StartMessage(M_GetText("Server closed connection\n(Broke ping limit)\nPress ESC\n"), NULL, MM_NOTHING);
#endif
else if (msg == KICK_MSG_BANNED)
M_StartMessage(M_GetText("You have been banned by the server\n\nPress ESC\n"), NULL, MM_NOTHING);
else if (msg == KICK_MSG_CUSTOM_KICK)
@ -3259,15 +3211,15 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
static CV_PossibleValue_t netticbuffer_cons_t[] = {{0, "MIN"}, {3, "MAX"}, {0, NULL}};
consvar_t cv_netticbuffer = {"netticbuffer", "1", CV_SAVE, netticbuffer_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_allownewplayer = {"allowjoin", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL };
consvar_t cv_allownewplayer = {"allowjoin", "On", CV_SAVE|CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL };
#ifdef VANILLAJOINNEXTROUND
consvar_t cv_joinnextround = {"joinnextround", "Off", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; /// \todo not done
consvar_t cv_joinnextround = {"joinnextround", "Off", CV_SAVE|CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL}; /// \todo not done
#endif
static CV_PossibleValue_t maxplayers_cons_t[] = {{2, "MIN"}, {MAXPLAYERS, "MAX"}, {0, NULL}};
consvar_t cv_maxplayers = {"maxplayers", "8", CV_SAVE, maxplayers_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static CV_PossibleValue_t resynchattempts_cons_t[] = {{0, "MIN"}, {20, "MAX"}, {0, NULL}};
consvar_t cv_resynchattempts = {"resynchattempts", "5", CV_SAVE, resynchattempts_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL };
consvar_t cv_blamecfail = {"blamecfail", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL };
consvar_t cv_blamecfail = {"blamecfail", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL };
// max file size to send to a player (in kilobytes)
static CV_PossibleValue_t maxsend_cons_t[] = {{0, "MIN"}, {51200, "MAX"}, {0, NULL}};
@ -3310,12 +3262,6 @@ void D_ClientServerInit(void)
RegisterNetXCmd(XD_ADDPLAYER, Got_AddPlayer);
RegisterNetXCmd(XD_REMOVEPLAYER, Got_RemovePlayer);
#ifndef NONET
CV_RegisterVar(&cv_allownewplayer);
#ifdef VANILLAJOINNEXTROUND
CV_RegisterVar(&cv_joinnextround);
#endif
CV_RegisterVar(&cv_showjoinaddress);
CV_RegisterVar(&cv_blamecfail);
#ifdef DUMPCONSISTENCY
CV_RegisterVar(&cv_dumpconsistency);
#endif
@ -3482,6 +3428,7 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
{
INT16 node, newplayernum;
UINT8 splitscreenplayer = 0;
UINT8 i;
if (playernum != serverplayer && !IsPlayerAdmin(playernum))
{
@ -3515,34 +3462,19 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
if (node == mynode)
{
playernode[newplayernum] = 0; // for information only
if (splitscreenplayer)
{
if (splitscreenplayer == 1)
{
secondarydisplayplayer = newplayernum;
DEBFILE("spawning my brother\n");
if (botingame)
displayplayers[splitscreenplayer] = newplayernum;
DEBFILE(va("spawning one of my sister number %d\n", splitscreenplayer));
if (splitscreenplayer == 1 && botingame)
players[newplayernum].bot = 1;
// Same goes for player 2 when relevant
}
else if (splitscreenplayer == 2)
{
thirddisplayplayer = newplayernum;
DEBFILE("spawning my sister\n");
}
else if (splitscreenplayer == 3)
{
fourthdisplayplayer = newplayernum;
DEBFILE("spawning my trusty pet dog\n");
}
}
else
{
consoleplayer = newplayernum;
displayplayer = newplayernum;
secondarydisplayplayer = newplayernum;
thirddisplayplayer = newplayernum;
fourthdisplayplayer = newplayernum;
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
displayplayers[i] = newplayernum;
DEBFILE("spawning me\n");
}
D_SendPlayerConfig();
@ -3691,7 +3623,7 @@ boolean Playing(void)
boolean SV_SpawnServer(void)
{
if (demoplayback)
if (demo.playback)
G_StopDemo(); // reset engine parameter
if (metalplayback)
G_StopMetalDemo();
@ -4703,7 +4635,6 @@ FILESTAMP
resynch_local_inprogress = true;
CL_AcknowledgeResynch(&netbuffer->u.resynchpak);
break;
#ifdef NEWPING
case PT_PING:
// Only accept PT_PING from the server.
if (node != servernode)
@ -4733,7 +4664,6 @@ FILESTAMP
}
break;
#endif
case PT_SERVERCFG:
break;
case PT_FILEFRAGMENT:
@ -5312,9 +5242,9 @@ void TryRunTics(tic_t realtics)
NetUpdate();
if (demoplayback)
if (demo.playback)
{
neededtic = gametic + (realtics * cv_playbackspeed.value);
neededtic = gametic + realtics * (gamestate == GS_LEVEL ? cv_playbackspeed.value : 1);
// start a game after a demo
maketic += realtics;
firstticstosend = maketic;
@ -5371,7 +5301,6 @@ void TryRunTics(tic_t realtics)
}
}
#ifdef NEWPING
/* Ping Update except better:
We call this once per second and check for people's pings. If their ping happens to be too high, we increment some timer and kick them out.
@ -5455,11 +5384,9 @@ static inline void PingUpdate(void)
pingmeasurecount = 1; //Reset count
}
#endif
static tic_t gametime = 0;
#ifdef NEWPING
static void UpdatePingTable(void)
{
INT32 i;
@ -5474,7 +5401,6 @@ static void UpdatePingTable(void)
pingmeasurecount++;
}
}
#endif
// Handle timeouts to prevent definitive freezes from happenning
static void HandleNodeTimeouts(void)
@ -5499,9 +5425,7 @@ void NetKeepAlive(void)
if (realtics <= 0) // nothing new to update
return;
#ifdef NEWPING
UpdatePingTable();
#endif
if (server)
CL_SendClientKeepAlive();
@ -5548,9 +5472,7 @@ void NetUpdate(void)
gametime = nowtime;
#ifdef NEWPING
UpdatePingTable();
#endif
if (client)
maketic = neededtic;
@ -5575,7 +5497,7 @@ FILESTAMP
}
else
{
if (!demoplayback)
if (!demo.playback)
{
INT32 counts;

View File

@ -96,9 +96,8 @@ typedef enum
PT_TELLFILESNEEDED, // Client, to server: "what other files do I need starting from this number?"
PT_MOREFILESNEEDED, // Server, to client: "you need these (+ more on top of those)"
#ifdef NEWPING
PT_PING, // Packet sent to tell clients the other client's latency to server.
#endif
NUMPACKETTYPE
} packettype_t;
@ -227,21 +226,7 @@ typedef struct
UINT8 kartspeed;
UINT8 kartweight;
//
fixed_t normalspeed;
fixed_t runspeed;
UINT8 thrustfactor;
UINT8 accelstart;
UINT8 acceleration;
UINT8 charability;
UINT8 charability2;
UINT32 charflags;
UINT32 thokitem; // mobjtype_t
UINT32 spinitem; // mobjtype_t
UINT32 revitem; // mobjtype_t
fixed_t actionspd;
fixed_t mindash;
fixed_t maxdash;
fixed_t jumpfactor;
fixed_t speed;
UINT8 jumping;
@ -487,9 +472,7 @@ typedef struct
plrconfig playerconfig[MAXPLAYERS]; // (up to) 528 bytes(?)
INT32 filesneedednum; // 4 bytes
filesneededconfig_pak filesneededcfg; // ??? bytes
#ifdef NEWPING
UINT32 pingtable[MAXPLAYERS+1]; // 68 bytes
#endif
} u; // This is needed to pack diff packet types data together
} ATTRPACK doomdata_t;
@ -523,9 +506,7 @@ extern consvar_t cv_playbackspeed;
#define KICK_MSG_PLAYER_QUIT 3
#define KICK_MSG_TIMEOUT 4
#define KICK_MSG_BANNED 5
#ifdef NEWPING
#define KICK_MSG_PING_HIGH 6
#endif
#define KICK_MSG_CUSTOM_KICK 7
#define KICK_MSG_CUSTOM_BAN 8
@ -546,16 +527,15 @@ extern boolean dedicated; // For dedicated server
extern UINT16 software_MAXPACKETLENGTH;
extern boolean acceptnewnode;
extern SINT8 servernode;
extern char connectedservername[MAXSERVERNAME];
void Command_Ping_f(void);
extern tic_t connectiontimeout;
extern tic_t jointimeout;
#ifdef NEWPING
extern UINT16 pingmeasurecount;
extern UINT32 realpingtable[MAXPLAYERS];
extern UINT32 playerpingtable[MAXPLAYERS];
extern tic_t servermaxping;
#endif
extern consvar_t
#ifdef VANILLAJOINNEXTROUND
@ -587,6 +567,7 @@ void CL_AddSplitscreenPlayer(void);
void CL_RemoveSplitscreenPlayer(UINT8 p);
void CL_Reset(void);
void CL_ClearPlayer(INT32 playernum);
void CL_RemovePlayer(INT32 playernum, INT32 reason);
void CL_UpdateServerList(boolean internetsearch, INT32 room);
boolean CL_Responder(event_t *ev);
// Is there a game running

View File

@ -118,14 +118,8 @@ boolean devparm = false; // started game with -devparm
boolean singletics = false; // timedemo
boolean lastdraw = false;
postimg_t postimgtype = postimg_none;
INT32 postimgparam;
postimg_t postimgtype2 = postimg_none;
INT32 postimgparam2;
postimg_t postimgtype3 = postimg_none;
INT32 postimgparam3;
postimg_t postimgtype4 = postimg_none;
INT32 postimgparam4;
postimg_t postimgtype[MAXSPLITSCREENPLAYERS];
INT32 postimgparam[MAXSPLITSCREENPLAYERS];
// These variables are only true if
// whether the respective sound system is disabled
@ -248,6 +242,12 @@ void D_ProcessEvents(void)
continue;
}
if (demo.savemode == DSM_TITLEENTRY)
{
if (G_DemoTitleResponder(ev))
continue;
}
// Menu input
if (M_Responder(ev))
continue; // menu ate the event
@ -274,6 +274,7 @@ static void D_Display(void)
boolean forcerefresh = false;
static boolean wipe = false;
INT32 wipedefindex = 0;
UINT8 i;
if (dedicated)
return;
@ -422,32 +423,33 @@ static void D_Display(void)
// draw the view directly
if (cv_renderview.value && !automapactive)
{
if (players[displayplayer].mo || players[displayplayer].playerstate == PST_DEAD)
for (i = 0; i <= splitscreen; i++)
{
if (players[displayplayers[i]].mo || players[displayplayers[i]].playerstate == PST_DEAD)
{
if (i == 0) // Initialize for P1
{
viewwindowy = 0;
viewwindowx = 0;
topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
objectsdrawn = 0;
#ifdef HWRENDER
if (rendermode != render_soft)
HWR_RenderPlayerView(0, &players[displayplayer]);
else
#endif
if (rendermode != render_none)
R_RenderPlayerView(&players[displayplayer]);
}
// render the second screen
if (splitscreen && players[secondarydisplayplayer].mo)
{
viewssnum = i;
#ifdef HWRENDER
if (rendermode != render_soft)
HWR_RenderPlayerView(1, &players[secondarydisplayplayer]);
HWR_RenderPlayerView(i, &players[displayplayers[i]]);
else
#endif
if (rendermode != render_none)
{
if (i > 0) // Splitscreen-specific
{
switch (i)
{
case 1:
if (splitscreen > 1)
{
viewwindowx = viewwidth;
@ -458,73 +460,40 @@ static void D_Display(void)
viewwindowx = 0;
viewwindowy = viewheight;
}
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 third screen
if (splitscreen > 1 && players[thirddisplayplayer].mo)
{
#ifdef HWRENDER
if (rendermode != render_soft)
HWR_RenderPlayerView(2, &players[thirddisplayplayer]);
else
#endif
if (rendermode != render_none)
{
break;
case 2:
viewwindowx = 0;
viewwindowy = viewheight;
M_Memcpy(ylookup, ylookup3, viewheight*sizeof (ylookup[0]));
topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
R_RenderPlayerView(&players[thirddisplayplayer]);
viewwindowy = 0;
M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0]));
}
}
if (splitscreen > 2 && players[fourthdisplayplayer].mo) // render the fourth screen
{
#ifdef HWRENDER
if (rendermode != render_soft)
HWR_RenderPlayerView(3, &players[fourthdisplayplayer]);
else
#endif
if (rendermode != render_none)
{
break;
case 3:
viewwindowx = viewwidth;
viewwindowy = viewheight;
M_Memcpy(ylookup, ylookup4, viewheight*sizeof (ylookup[0]));
default:
break;
}
topleft = screens[0] + viewwindowy*vid.width + viewwindowx;
}
R_RenderPlayerView(&players[fourthdisplayplayer]);
R_RenderPlayerView(&players[displayplayers[i]]);
viewwindowy = 0;
if (i > 0)
M_Memcpy(ylookup, ylookup1, viewheight*sizeof (ylookup[0]));
}
}
}
if (rendermode == render_soft)
{
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);
for (i = 0; i <= splitscreen; i++)
{
if (postimgtype[i])
V_DoPostProcessor(i, postimgtype[i], postimgparam[i]);
}
}
}
@ -550,7 +519,7 @@ static void D_Display(void)
wipegamestate = gamestate;
// draw pause pic
if (paused && cv_showhud.value)
if (paused && cv_showhud.value && !demo.playback)
{
INT32 py;
patch_t *patch;
@ -562,6 +531,12 @@ static void D_Display(void)
V_DrawScaledPatch(viewwindowx + (BASEVIDWIDTH - SHORT(patch->width))/2, py, 0, patch);
}
if (demo.rewinding)
V_DrawFadeScreen(TC_RAINBOW, (leveltime & 0x20) ? SKINCOLOR_PASTEL : SKINCOLOR_MOONSLAM);
if (cv_vhseffect.value && (paused || (demo.playback && cv_playbackspeed.value > 1)))
V_DrawVhsEffect(demo.rewinding);
// vid size change is now finished if it was on...
vid.recalc = 0;
@ -619,6 +594,9 @@ static void D_Display(void)
V_DrawRightAlignedString(BASEVIDWIDTH, BASEVIDHEIGHT-ST_HEIGHT-10, V_YELLOWMAP, s);
}
if (cv_shittyscreen.value)
V_DrawVhsEffect(cv_shittyscreen.value == 2);
I_FinishUpdate(); // page flip or blit buffer
}
}
@ -636,9 +614,6 @@ void D_SRB2Loop(void)
if (dedicated)
server = true;
if (M_CheckParm("-voodoo")) // 256x256 Texture Limiter
COM_BufAddText("gr_voodoocompatibility on\n");
// Pushing of + parameters is now done back in D_SRB2Main, not here.
CONS_Printf("I_StartupKeyboard()...\n");
@ -735,7 +710,7 @@ void D_SRB2Loop(void)
M_DoScreenShot();
}
// consoleplayer -> displayplayer (hear sounds from viewpoint)
// consoleplayer -> displayplayers (hear sounds from viewpoint)
S_UpdateSounds(); // move positional sounds
// check for media change, loop music..
@ -814,7 +789,8 @@ void D_StartTitle(void)
maptol = 0;
gameaction = ga_nothing;
displayplayer = consoleplayer = 0;
memset(displayplayers, 0, sizeof(displayplayers));
consoleplayer = 0;
//demosequence = -1;
gametype = GT_RACE; // SRB2kart
paused = false;
@ -1388,6 +1364,16 @@ void D_SRB2Main(void)
midi_disabled = true;
#endif
}
if (M_CheckParm("-noaudio")) // combines -nosound and -nomusic
{
sound_disabled = true;
digital_disabled = true;
#ifndef NO_MIDI
midi_disabled = true;
#endif
}
else
{
if (M_CheckParm("-nosound"))
sound_disabled = true;
if (M_CheckParm("-nomusic")) // combines -nomidimusic and -nodigmusic
@ -1406,6 +1392,7 @@ void D_SRB2Main(void)
if (M_CheckParm("-nodigmusic"))
digital_disabled = true; // WARNING: DOS version initmusic in I_StartupSound
}
}
if (!( sound_disabled && digital_disabled
#ifndef NO_MIDI
&& midi_disabled
@ -1500,7 +1487,7 @@ void D_SRB2Main(void)
if (M_CheckParm("-playdemo"))
{
singledemo = true; // quit after one demo
demo.quitafterplaying = true; // quit after one demo
G_DeferedPlayDemo(tmp);
}
else
@ -1527,6 +1514,8 @@ void D_SRB2Main(void)
// as having been modified for the first game.
M_PushSpecialParameters(); // push all "+" parameter at the command buffer
strncpy(connectedservername, cv_servername.string, MAXSERVERNAME);
if (M_CheckParm("-gametype") && M_IsNextParm())
{
// from Command_Map_f

View File

@ -185,22 +185,10 @@ typedef struct
UINT8 nextacknum;
UINT8 flags;
#ifndef NEWPING
// jacobson tcp timeout evaluation algorithm (Karn variation)
fixed_t ping;
fixed_t varping;
INT32 timeout; // computed with ping and varping
#endif
} node_t;
static node_t nodes[MAXNETNODES];
#ifndef NEWPING
#define PINGDEFAULT ((200*TICRATE*FRACUNIT)/1000)
#define VARPINGDEFAULT ((50*TICRATE*FRACUNIT)/1000)
#define TIMEOUT(p,v) (p+4*v+FRACUNIT/2)>>FRACBITS;
#else
#define NODETIMEOUT 14 //What the above boiled down to...
#endif
#define NODETIMEOUT 14
#ifndef NONET
// return <0 if a < b (mod 256)
@ -320,19 +308,7 @@ static UINT8 GetAcktosend(INT32 node)
static void RemoveAck(INT32 i)
{
INT32 node = ackpak[i].destinationnode;
#ifndef NEWPING
fixed_t trueping = (I_GetTime() - ackpak[i].senttime)<<FRACBITS;
if (ackpak[i].resentnum)
{
// +FRACUNIT/2 for round
nodes[node].ping = (nodes[node].ping*7 + trueping)/8;
nodes[node].varping = (nodes[node].varping*7 + abs(nodes[node].ping-trueping))/8;
nodes[node].timeout = TIMEOUT(nodes[node].ping,nodes[node].varping);
}
DEBFILE(va("Remove ack %d trueping %d ping %f var %f timeout %d\n",ackpak[i].acknum,trueping>>FRACBITS,(double)FIXED_TO_FLOAT(nodes[node].ping),(double)FIXED_TO_FLOAT(nodes[node].varping),nodes[node].timeout));
#else
DEBFILE(va("Remove ack %d\n",ackpak[i].acknum));
#endif
ackpak[i].acknum = 0;
if (nodes[node].flags & NF_CLOSE)
Net_CloseConnection(node);
@ -519,11 +495,7 @@ void Net_AckTicker(void)
{
const INT32 nodei = ackpak[i].destinationnode;
node_t *node = &nodes[nodei];
#ifdef NEWPING
if (ackpak[i].acknum && ackpak[i].senttime + NODETIMEOUT < I_GetTime())
#else
if (ackpak[i].acknum && ackpak[i].senttime + node->timeout < I_GetTime())
#endif
{
if (ackpak[i].resentnum > 10 && (node->flags & NF_CLOSE))
{
@ -534,13 +506,8 @@ void Net_AckTicker(void)
ackpak[i].acknum = 0;
continue;
}
#ifdef NEWPING
DEBFILE(va("Resend ack %d, %u<%d at %u\n", ackpak[i].acknum, ackpak[i].senttime,
NODETIMEOUT, I_GetTime()));
#else
DEBFILE(va("Resend ack %d, %u<%d at %u\n", ackpak[i].acknum, ackpak[i].senttime,
node->timeout, I_GetTime()));
#endif
M_Memcpy(netbuffer, ackpak[i].pak.raw, ackpak[i].length);
ackpak[i].senttime = I_GetTime();
ackpak[i].resentnum++;
@ -658,11 +625,6 @@ void Net_WaitAllAckReceived(UINT32 timeout)
static void InitNode(node_t *node)
{
node->acktosend_head = node->acktosend_tail = 0;
#ifndef NEWPING
node->ping = PINGDEFAULT;
node->varping = VARPINGDEFAULT;
node->timeout = TIMEOUT(node->ping, node->varping);
#endif
node->firstacktosend = 0;
node->nextacknum = 1;
node->remotefirstack = 0;
@ -854,9 +816,7 @@ static const char *packettypename[NUMPACKETTYPE] =
"CLIENTJOIN",
"NODETIMEOUT",
"RESYNCHING",
#ifdef NEWPING
"PING"
#endif
};
static void DebugPrintpacket(const char *header)
@ -1410,30 +1370,73 @@ boolean D_CheckNetGame(void)
return ret;
}
struct pingcell
{
INT32 num;
INT32 ms;
};
static int pingcellcmp(const void *va, const void *vb)
{
const struct pingcell *a, *b;
a = va;
b = vb;
return ( a->ms - b->ms );
}
/*
New ping command formatted nicely to present ping in
ascending order. And with equally spaced columns.
The caller's ping is presented at the bottom too, for
convenience.
*/
void Command_Ping_f(void)
{
#ifndef NEWPING
if(server)
{
#endif
struct pingcell pingv[MAXPLAYERS];
INT32 pingc;
int name_width = 0;
int ms_width = 0;
int n;
INT32 i;
for (i = 0; i < MAXPLAYERS;i++)
pingc = 0;
for (i = 1; i < MAXPLAYERS; ++i)
if (playeringame[i])
{
#ifndef NEWPING
const INT32 node = playernode[i];
if (playeringame[i] && node != 0)
CONS_Printf(M_GetText("%.2d : %s\n %d tics, %d ms.\n"), i, player_names[i],
GetLag(node), G_TicsToMilliseconds(GetLag(node)));
#else
if (playeringame[i] && i != 0)
CONS_Printf(M_GetText("%.2d : %s\n %d ms\n"), i, player_names[i], playerpingtable[i]);
#endif
n = strlen(player_names[i]);
if (n > name_width)
name_width = n;
n = playerpingtable[i];
if (n > ms_width)
ms_width = n;
pingv[pingc].num = i;
pingv[pingc].ms = playerpingtable[i];
pingc++;
}
#ifndef NEWPING
if (ms_width < 10) ms_width = 1;
else if (ms_width < 100) ms_width = 2;
else ms_width = 3;
qsort(pingv, pingc, sizeof (struct pingcell), &pingcellcmp);
for (i = 0; i < pingc; ++i)
{
CONS_Printf("%02d : %-*s %*d ms\n",
pingv[i].num,
name_width, player_names[pingv[i].num],
ms_width, pingv[i].ms);
}
if (!server && playeringame[consoleplayer])
{
CONS_Printf("\nYour ping is %d ms\n", playerpingtable[consoleplayer]);
}
else
CONS_Printf(M_GetText("Only the server can use this.\n"));
#endif
}
void D_CloseConnection(void)

View File

@ -21,7 +21,6 @@
// Max computers in a game
#define MAXNETNODES (MAXPLAYERS+4)
#define BROADCASTADDR MAXNETNODES
#define MAXSPLITSCREENPLAYERS 4 // Max number of players on a single computer
#define NETSPLITSCREEN // Kart's splitscreen netgame feature
#define STATLENGTH (TICRATE*2)

View File

@ -129,6 +129,9 @@ static void Command_StopMovie_f(void);
static void Command_Map_f(void);
static void Command_ResetCamera_f(void);
static void Command_View_f (void);
static void Command_SetViews_f(void);
static void Command_Addfile(void);
static void Command_ListWADS_f(void);
#ifdef DELFILE
@ -423,7 +426,7 @@ consvar_t cv_numlaps = {"numlaps", "3", CV_NETVAR|CV_CALL|CV_NOINIT, numlaps_con
static CV_PossibleValue_t basenumlaps_cons_t[] = {{1, "MIN"}, {50, "MAX"}, {0, "Map default"}, {0, NULL}};
consvar_t cv_basenumlaps = {"basenumlaps", "Map default", CV_NETVAR|CV_CALL|CV_CHEAT, basenumlaps_cons_t, BaseNumLaps_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_forceskin = {"forceskin", "-1", CV_NETVAR|CV_CALL|CV_CHEAT, NULL, ForceSkin_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_forceskin = {"forceskin", "Off", CV_NETVAR|CV_CALL|CV_CHEAT, Forceskin_cons_t, ForceSkin_OnChange, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_downloading = {"downloading", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_allowexitlevel = {"allowexitlevel", "No", CV_NETVAR, CV_YesNo, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -434,7 +437,6 @@ static CV_PossibleValue_t nettimeout_cons_t[] = {{TICRATE/7, "MIN"}, {60*TICRATE
consvar_t cv_nettimeout = {"nettimeout", "105", CV_CALL|CV_SAVE, nettimeout_cons_t, NetTimeout_OnChange, 0, NULL, NULL, 0, 0, NULL};
//static CV_PossibleValue_t jointimeout_cons_t[] = {{5*TICRATE, "MIN"}, {60*TICRATE, "MAX"}, {0, NULL}};
consvar_t cv_jointimeout = {"jointimeout", "105", CV_CALL|CV_SAVE, nettimeout_cons_t, JoinTimeout_OnChange, 0, NULL, NULL, 0, 0, NULL};
#ifdef NEWPING
static CV_PossibleValue_t maxping_cons_t[] = {{0, "MIN"}, {1000, "MAX"}, {0, NULL}};
consvar_t cv_maxping = {"maxping", "800", CV_SAVE, maxping_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -445,7 +447,6 @@ consvar_t cv_pingtimeout = {"pingtimeout", "10", CV_SAVE, pingtimeout_cons_t, NU
static CV_PossibleValue_t showping_cons_t[] = {{0, "Off"}, {1, "Always"}, {2, "Warning"}, {0, NULL}};
consvar_t cv_showping = {"showping", "Always", CV_SAVE, showping_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
#endif
// Intermission time Tails 04-19-2002
static CV_PossibleValue_t inttime_cons_t[] = {{0, "MIN"}, {3600, "MAX"}, {0, NULL}};
consvar_t cv_inttime = {"inttime", "20", CV_NETVAR, inttime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -514,6 +515,17 @@ const char *netxcmdnames[MAXNETXCMD - 1] =
*/
void D_RegisterServerCommands(void)
{
int i;
Forceskin_cons_t[0].value = -1;
Forceskin_cons_t[0].strvalue = "Off";
// Set the values to 0/NULl, it will be overwritten later when a skin is assigned to the slot.
for (i = 1; i < MAXSKINS; i++)
{
Forceskin_cons_t[i].value = 0;
Forceskin_cons_t[i].strvalue = NULL;
}
RegisterNetXCmd(XD_NAMEANDCOLOR, Got_NameAndColor);
RegisterNetXCmd(XD_WEAPONPREF, Got_WeaponPref);
RegisterNetXCmd(XD_MAP, Got_Mapcmd);
@ -667,6 +679,14 @@ void D_RegisterServerCommands(void)
CV_RegisterVar(&cv_maxsend);
CV_RegisterVar(&cv_noticedownload);
CV_RegisterVar(&cv_downloadspeed);
#ifndef NONET
CV_RegisterVar(&cv_allownewplayer);
#ifdef VANILLAJOINNEXTROUND
CV_RegisterVar(&cv_joinnextround);
#endif
CV_RegisterVar(&cv_showjoinaddress);
CV_RegisterVar(&cv_blamecfail);
#endif
COM_AddCommand("ping", Command_Ping_f);
CV_RegisterVar(&cv_nettimeout);
@ -674,11 +694,9 @@ void D_RegisterServerCommands(void)
CV_RegisterVar(&cv_skipmapcheck);
CV_RegisterVar(&cv_sleep);
#ifdef NEWPING
CV_RegisterVar(&cv_maxping);
CV_RegisterVar(&cv_pingtimeout);
CV_RegisterVar(&cv_showping);
#endif
#ifdef SEENAMES
CV_RegisterVar(&cv_allowseenames);
@ -726,6 +744,13 @@ void D_RegisterClientCommands(void)
COM_AddCommand("resetcamera", Command_ResetCamera_f);
COM_AddCommand("view", Command_View_f);
COM_AddCommand("view2", Command_View_f);
COM_AddCommand("view3", Command_View_f);
COM_AddCommand("view4", Command_View_f);
COM_AddCommand("setviews", Command_SetViews_f);
COM_AddCommand("setcontrol", Command_Setcontrol_f);
COM_AddCommand("setcontrol2", Command_Setcontrol2_f);
COM_AddCommand("setcontrol3", Command_Setcontrol3_f);
@ -800,6 +825,9 @@ void D_RegisterClientCommands(void)
COM_AddCommand("displayplayer", Command_Displayplayer_f);
CV_RegisterVar(&cv_recordmultiplayerdemos);
CV_RegisterVar(&cv_netdemosyncquality);
// FIXME: not to be here.. but needs be done for config loading
CV_RegisterVar(&cv_usegamma);
@ -853,6 +881,10 @@ void D_RegisterClientCommands(void)
CV_RegisterVar(&cv_driftaxis2);
CV_RegisterVar(&cv_driftaxis3);
CV_RegisterVar(&cv_driftaxis4);
CV_RegisterVar(&cv_deadzone);
CV_RegisterVar(&cv_deadzone2);
CV_RegisterVar(&cv_deadzone3);
CV_RegisterVar(&cv_deadzone4);
// filesrch.c
CV_RegisterVar(&cv_addons_option);
@ -919,6 +951,8 @@ void D_RegisterClientCommands(void)
// screen.c
CV_RegisterVar(&cv_fullscreen);
CV_RegisterVar(&cv_renderview);
CV_RegisterVar(&cv_vhseffect);
CV_RegisterVar(&cv_shittyscreen);
CV_RegisterVar(&cv_scr_depth);
CV_RegisterVar(&cv_scr_width);
CV_RegisterVar(&cv_scr_height);
@ -1130,11 +1164,11 @@ static void CleanupPlayerName(INT32 playernum, const char *newname)
// spaces may have been removed
if (playernum == consoleplayer)
CV_StealthSet(&cv_playername, tmpname);
else if (playernum == secondarydisplayplayer || (!netgame && playernum == 1))
else if (playernum == displayplayers[1] || (!netgame && playernum == 1))
CV_StealthSet(&cv_playername2, tmpname);
else if (playernum == thirddisplayplayer || (!netgame && playernum == 2))
else if (playernum == displayplayers[2] || (!netgame && playernum == 2))
CV_StealthSet(&cv_playername3, tmpname);
else if (playernum == fourthdisplayplayer || (!netgame && playernum == 3))
else if (playernum == displayplayers[3] || (!netgame && playernum == 3))
CV_StealthSet(&cv_playername4, tmpname);
else I_Assert(((void)"CleanupPlayerName used on non-local player", 0));
@ -1166,6 +1200,7 @@ static void SetPlayerName(INT32 playernum, char *newname)
HU_AddChatText(va("\x82*%s renamed to %s", player_names[playernum], newname), false);
strcpy(player_names[playernum], newname);
demo_extradata[playernum] |= DXD_NAME;
}
}
else
@ -1241,11 +1276,11 @@ static void ForceAllSkins(INT32 forcedskin)
{
if (i == consoleplayer)
CV_StealthSet(&cv_skin, skins[forcedskin].name);
else if (i == secondarydisplayplayer)
else if (i == displayplayers[1])
CV_StealthSet(&cv_skin2, skins[forcedskin].name);
else if (i == thirddisplayplayer)
else if (i == displayplayers[2])
CV_StealthSet(&cv_skin3, skins[forcedskin].name);
else if (i == fourthdisplayplayer)
else if (i == displayplayers[3])
CV_StealthSet(&cv_skin4, skins[forcedskin].name);
}
}
@ -1380,8 +1415,8 @@ static void SendNameAndColor2(void)
if (splitscreen < 1 && !botingame)
return; // can happen if skin2/color2/name2 changed
if (secondarydisplayplayer != consoleplayer)
secondplaya = secondarydisplayplayer;
if (displayplayers[1] != consoleplayer)
secondplaya = displayplayers[1];
else if (!netgame) // HACK
secondplaya = 1;
@ -1430,7 +1465,7 @@ static void SendNameAndColor2(void)
CleanupPlayerName(secondplaya, cv_playername2.zstring);
strcpy(player_names[secondplaya], cv_playername2.zstring);
// don't use secondarydisplayplayer: the second player must be 1
// don't use displayplayers[1]: the second player must be 1
players[secondplaya].skincolor = cv_playercolor2.value;
if (players[secondplaya].mo)
players[secondplaya].mo->color = players[secondplaya].skincolor;
@ -1469,14 +1504,14 @@ static void SendNameAndColor2(void)
snac2pending++;
// Don't change name if muted
if (cv_mute.value && !(server || IsPlayerAdmin(secondarydisplayplayer)))
CV_StealthSet(&cv_playername2, player_names[secondarydisplayplayer]);
if (cv_mute.value && !(server || IsPlayerAdmin(displayplayers[1])))
CV_StealthSet(&cv_playername2, player_names[displayplayers[1]]);
else // Cleanup name if changing it
CleanupPlayerName(secondarydisplayplayer, cv_playername2.zstring);
CleanupPlayerName(displayplayers[1], cv_playername2.zstring);
// Don't change skin if the server doesn't want you to.
if (!CanChangeSkin(secondarydisplayplayer))
CV_StealthSet(&cv_skin2, skins[players[secondarydisplayplayer].skin].name);
if (!CanChangeSkin(displayplayers[1]))
CV_StealthSet(&cv_skin2, skins[players[displayplayers[1]].skin].name);
// check if player has the skin loaded (cv_skin2 may have
// the name of a skin that was available in the previous game)
@ -1503,8 +1538,8 @@ static void SendNameAndColor3(void)
if (splitscreen < 2)
return; // can happen if skin3/color3/name3 changed
if (thirddisplayplayer != consoleplayer)
thirdplaya = thirddisplayplayer;
if (displayplayers[2] != consoleplayer)
thirdplaya = displayplayers[2];
else if (!netgame) // HACK
thirdplaya = 2;
@ -1545,7 +1580,7 @@ static void SendNameAndColor3(void)
CleanupPlayerName(thirdplaya, cv_playername3.zstring);
strcpy(player_names[thirdplaya], cv_playername3.zstring);
// don't use thirddisplayplayer: the third player must be 2
// don't use displayplayers[2]: the third player must be 2
players[thirdplaya].skincolor = cv_playercolor3.value;
if (players[thirdplaya].mo)
players[thirdplaya].mo->color = players[thirdplaya].skincolor;
@ -1584,14 +1619,14 @@ static void SendNameAndColor3(void)
snac3pending++;
// Don't change name if muted
if (cv_mute.value && !(server || IsPlayerAdmin(thirddisplayplayer)))
CV_StealthSet(&cv_playername3, player_names[thirddisplayplayer]);
if (cv_mute.value && !(server || IsPlayerAdmin(displayplayers[2])))
CV_StealthSet(&cv_playername3, player_names[displayplayers[2]]);
else // Cleanup name if changing it
CleanupPlayerName(thirddisplayplayer, cv_playername3.zstring);
CleanupPlayerName(displayplayers[2], cv_playername3.zstring);
// Don't change skin if the server doesn't want you to.
if (!CanChangeSkin(thirddisplayplayer))
CV_StealthSet(&cv_skin3, skins[players[thirddisplayplayer].skin].name);
if (!CanChangeSkin(displayplayers[2]))
CV_StealthSet(&cv_skin3, skins[players[displayplayers[2]].skin].name);
// check if player has the skin loaded (cv_skin3 may have
// the name of a skin that was available in the previous game)
@ -1618,8 +1653,8 @@ static void SendNameAndColor4(void)
if (splitscreen < 3)
return; // can happen if skin4/color4/name4 changed
if (fourthdisplayplayer != consoleplayer)
fourthplaya = fourthdisplayplayer;
if (displayplayers[3] != consoleplayer)
fourthplaya = displayplayers[3];
else if (!netgame) // HACK
fourthplaya = 3;
@ -1668,7 +1703,7 @@ static void SendNameAndColor4(void)
CleanupPlayerName(fourthplaya, cv_playername4.zstring);
strcpy(player_names[fourthplaya], cv_playername4.zstring);
// don't use fourthdisplayplayer: the second player must be 4
// don't use displayplayers[3]: the second player must be 4
players[fourthplaya].skincolor = cv_playercolor4.value;
if (players[fourthplaya].mo)
players[fourthplaya].mo->color = players[fourthplaya].skincolor;
@ -1707,14 +1742,14 @@ static void SendNameAndColor4(void)
snac4pending++;
// Don't change name if muted
if (cv_mute.value && !(server || IsPlayerAdmin(fourthdisplayplayer)))
CV_StealthSet(&cv_playername4, player_names[fourthdisplayplayer]);
if (cv_mute.value && !(server || IsPlayerAdmin(displayplayers[3])))
CV_StealthSet(&cv_playername4, player_names[displayplayers[3]]);
else // Cleanup name if changing it
CleanupPlayerName(fourthdisplayplayer, cv_playername4.zstring);
CleanupPlayerName(displayplayers[3], cv_playername4.zstring);
// Don't change skin if the server doesn't want you to.
if (!CanChangeSkin(fourthdisplayplayer))
CV_StealthSet(&cv_skin4, skins[players[fourthdisplayplayer].skin].name);
if (!CanChangeSkin(displayplayers[3]))
CV_StealthSet(&cv_skin4, skins[players[displayplayers[3]].skin].name);
// check if player has the skin loaded (cv_skin4 may have
// the name of a skin that was available in the previous game)
@ -1744,12 +1779,12 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
#endif
if (playernum == consoleplayer)
snacpending--;
else if (playernum == secondarydisplayplayer)
snacpending--; // TODO: make snacpending an array instead of 4 separate vars?
else if (playernum == displayplayers[1])
snac2pending--;
else if (playernum == thirddisplayplayer)
else if (playernum == displayplayers[2])
snac3pending--;
else if (playernum == fourthdisplayplayer)
else if (playernum == displayplayers[3])
snac4pending--;
#ifdef PARANOIA
@ -1769,10 +1804,11 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
p->skincolor = color % MAXSKINCOLORS;
if (p->mo)
p->mo->color = (UINT8)p->skincolor;
demo_extradata[playernum] |= DXD_COLOR;
// normal player colors
if (server && (p != &players[consoleplayer] && p != &players[secondarydisplayplayer]
&& p != &players[thirddisplayplayer] && p != &players[fourthdisplayplayer]))
if (server && (p != &players[consoleplayer] && p != &players[displayplayers[1]]
&& p != &players[displayplayers[2]] && p != &players[displayplayers[3]]))
{
boolean kick = false;
@ -1809,11 +1845,11 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
if (playernum == consoleplayer)
CV_StealthSet(&cv_skin, skins[forcedskin].name);
else if (playernum == secondarydisplayplayer)
else if (playernum == displayplayers[1])
CV_StealthSet(&cv_skin2, skins[forcedskin].name);
else if (playernum == thirddisplayplayer)
else if (playernum == displayplayers[2])
CV_StealthSet(&cv_skin3, skins[forcedskin].name);
else if (playernum == fourthdisplayplayer)
else if (playernum == displayplayers[3])
CV_StealthSet(&cv_skin4, skins[forcedskin].name);
}
else
@ -1900,7 +1936,198 @@ void D_SendPlayerConfig(void)
// Only works for displayplayer, sorry!
static void Command_ResetCamera_f(void)
{
P_ResetCamera(&players[displayplayer], &camera);
P_ResetCamera(&players[displayplayers[0]], &camera[0]);
}
/* Consider replacing nametonum with this */
static INT32 LookupPlayer(const char *s)
{
INT32 playernum;
if (*s == '0')/* clever way to bypass atoi */
return 0;
if (( playernum = atoi(s) ))
{
playernum = max(min(playernum, MAXPLAYERS-1), 0);/* not out of range */
return playernum;
}
for (playernum = 0; playernum < MAXPLAYERS; ++playernum)
{
/* Match name case-insensitively: fully, or partially the start. */
if (playeringame[playernum])
if (strnicmp(player_names[playernum], s, strlen(s)) == 0)
{
return playernum;
}
}
return -1;
}
static INT32 FindPlayerByPlace(INT32 place)
{
INT32 playernum;
for (playernum = 0; playernum < MAXPLAYERS; ++playernum)
if (playeringame[playernum])
{
if (players[playernum].kartstuff[k_position] == place)
{
return playernum;
}
}
return -1;
}
//
// GetViewablePlayerPlaceRange
// Return in first and last, that player available to view, sorted by placement
// in the race.
//
static void GetViewablePlayerPlaceRange(INT32 *first, INT32 *last)
{
INT32 i;
INT32 place;
(*first) = MAXPLAYERS;
(*last) = 0;
for (i = 0; i < MAXPLAYERS; ++i)
if (G_CouldView(i))
{
place = players[i].kartstuff[k_position];
if (place < (*first))
(*first) = place;
if (place > (*last))
(*last) = place;
}
}
#define PRINTVIEWPOINT( pre,suf ) \
CONS_Printf(pre"viewing \x84(%d) \x83%s\x80"suf".\n",\
(*displayplayerp), player_names[(*displayplayerp)]);
static void Command_View_f(void)
{
INT32 *displayplayerp;
INT32 olddisplayplayer;
int viewnum;
const char *playerparam;
INT32 placenum;
INT32 playernum;
INT32 firstplace, lastplace;
char c;
/* easy peasy */
c = COM_Argv(0)[strlen(COM_Argv(0))-1];/* may be digit */
switch (c)
{
case '2': viewnum = 2; break;
case '3': viewnum = 3; break;
case '4': viewnum = 4; break;
default: viewnum = 1;
}
if (viewnum > 1 && !( multiplayer && demo.playback ))
{
CONS_Alert(CONS_NOTICE,
"You must be viewing a multiplayer replay to use this.\n");
return;
}
displayplayerp = &displayplayers[viewnum];
if (COM_Argc() > 1)/* switch to player */
{
playerparam = COM_Argv(1);
if (playerparam[0] == '#')/* search by placement */
{
placenum = atoi(&playerparam[1]);
playernum = FindPlayerByPlace(placenum);
if (playernum == -1 || !G_CouldView(playernum))
{
GetViewablePlayerPlaceRange(&firstplace, &lastplace);
if (playernum == -1)
{
CONS_Alert(CONS_WARNING, "There is no player in that place! ");
}
else
{
CONS_Alert(CONS_WARNING,
"That player cannot be viewed currently! "
"The first player that you can view is \x82#%d\x80; ",
firstplace);
}
CONS_Printf("Last place is \x82#%d\x80.\n", lastplace);
return;
}
}
else
{
if (( playernum = LookupPlayer(COM_Argv(1)) ) == -1)
{
CONS_Alert(CONS_WARNING, "There is no player by that name!\n");
return;
}
if (!playeringame[playernum])
{
CONS_Alert(CONS_WARNING, "There is no player using that slot!\n");
return;
}
}
olddisplayplayer = (*displayplayerp);
G_ResetView(viewnum, playernum, false);
/* The player we wanted was corrected to who it already was. */
if ((*displayplayerp) == olddisplayplayer)
return;
if ((*displayplayerp) != playernum)/* differ parameter */
{
/* skipped some */
CONS_Alert(CONS_NOTICE, "That player cannot be viewed currently.\n");
PRINTVIEWPOINT ("Now "," instead")
}
else
PRINTVIEWPOINT ("Now ",)
}
else/* print current view */
{
if (splitscreen < viewnum-1)/* We can't see those guys! */
return;
PRINTVIEWPOINT ("Currently ",)
}
}
#undef PRINTVIEWPOINT
static void Command_SetViews_f(void)
{
UINT8 splits;
UINT8 newsplits;
if (!( demo.playback && multiplayer ))
{
CONS_Alert(CONS_NOTICE,
"You must be viewing a multiplayer replay to use this.\n");
return;
}
if (COM_Argc() != 2)
{
CONS_Printf("setviews <views>: set the number of split screens\n");
return;
}
splits = splitscreen+1;
newsplits = atoi(COM_Argv(1));
newsplits = min(max(newsplits, 1), 4);
if (newsplits > splits)
G_AdjustView(newsplits, 0, true);
else
{
splitscreen = newsplits-1;
R_ExecuteSetViewSize();
}
}
// ========================================================================
@ -1913,9 +2140,14 @@ static void Command_Playdemo_f(void)
{
char name[256];
if (COM_Argc() != 2)
if (COM_Argc() < 2)
{
CONS_Printf(M_GetText("playdemo <demoname>: playback a demo\n"));
CONS_Printf("playdemo <demoname> [-addfiles / -force]:\n");
CONS_Printf(M_GetText(
"Play back a demo file. The full path from your Kart directory must be given.\n\n"
"* With \"-addfiles\", any required files are added from a list contained within the demo file.\n"
"* With \"-force\", the demo is played even if the necessary files have not been added.\n"));
return;
}
@ -1926,7 +2158,7 @@ static void Command_Playdemo_f(void)
}
// disconnect from server here?
if (demoplayback)
if (demo.playback)
G_StopDemo();
if (metalplayback)
G_StopMetalDemo();
@ -1937,6 +2169,9 @@ static void Command_Playdemo_f(void)
CONS_Printf(M_GetText("Playing back demo '%s'.\n"), name);
demo.loadfiles = strcmp(COM_Argv(2), "-addfiles") == 0;
demo.ignorefiles = strcmp(COM_Argv(2), "-force") == 0;
// Internal if no extension, external if one exists
// If external, convert the file name to a path in SRB2's home directory
if (FIL_CheckExtension(name))
@ -1962,7 +2197,7 @@ static void Command_Timedemo_f(void)
}
// disconnect from server here?
if (demoplayback)
if (demo.playback)
G_StopDemo();
if (metalplayback)
G_StopMetalDemo();
@ -2086,7 +2321,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pencoremode, boolean r
{
//CL_AddSplitscreenPlayer();
botingame = true;
secondarydisplayplayer = 1;
displayplayers[1] = 1;
playeringame[1] = true;
players[1].bot = 1;
SendNameAndColor2();
@ -2138,12 +2373,8 @@ void D_ModifyClientVote(SINT8 voted, UINT8 splitplayer)
char *p = buf;
UINT8 player = consoleplayer;
if (splitplayer == 1)
player = secondarydisplayplayer;
else if (splitplayer == 2)
player = thirddisplayplayer;
else if (splitplayer == 3)
player = fourthdisplayplayer;
if (splitplayer > 0)
player = displayplayers[splitplayer];
WRITESINT8(p, voted);
WRITEUINT8(p, player);
@ -2204,12 +2435,14 @@ static void Command_Map_f(void)
const char *mapname;
size_t i;
INT32 j, newmapnum;
boolean newresetplayers;
boolean newresetplayers, newencoremode;
INT32 newgametype = gametype;
// max length of command: map map03 -gametype coop -noresetplayers -force
// 1 2 3 4 5 6
// max length of command: map map03 -gametype race -noresetplayers -force -encore
// 1 2 3 4 5 6 7
// = 8 arg max
// i don't know whether this is intrinsic to the system or just someone being weird but
// "noresetplayers" is pretty useless for kart if it turns out this is too close to the limit
if (COM_Argc() < 2 || COM_Argc() > 8)
{
CONS_Printf(M_GetText("map <mapname> [-gametype <type> [-force]: warp to map\n"));
@ -2292,6 +2525,21 @@ static void Command_Map_f(void)
}
}
// new encoremode value
// use cvar by default
newencoremode = (boolean)cv_kartencore.value;
if (COM_CheckParm("-encore"))
{
if (!M_SecretUnlocked(SECRET_ENCORE) && !newencoremode)
{
CONS_Alert(CONS_NOTICE, M_GetText("You haven't unlocked Encore Mode yet!\n"));
return;
}
newencoremode = !newencoremode;
}
if (!(i = COM_CheckParm("-force")) && newgametype == gametype) // SRB2Kart
newresetplayers = false; // if not forcing and gametypes is the same
@ -2322,7 +2570,7 @@ static void Command_Map_f(void)
}
fromlevelselect = false;
D_MapChange(newmapnum, newgametype, (boolean)cv_kartencore.value, newresetplayers, 0, false, false);
D_MapChange(newmapnum, newgametype, newencoremode, newresetplayers, 0, false, false);
}
/** Receives a map command and changes the map.
@ -2396,7 +2644,7 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
CON_ToggleOff();
CON_ClearHUD();
if (demoplayback && !timingdemo)
if (demo.playback && !demo.timing)
precache = false;
if (resetplayer)
@ -2413,17 +2661,19 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
LUAh_MapChange(mapnumber);
#endif*/
demo.savemode = (cv_recordmultiplayerdemos.value == 2) ? DSM_WILLAUTOSAVE : DSM_NOTSAVING;
demo.savebutton = 0;
G_InitNew(pencoremode, mapname, resetplayer, skipprecutscene);
if (demoplayback && !timingdemo)
if (demo.playback && !demo.timing)
precache = true;
if (timingdemo)
if (demo.timing)
G_DoneLevelLoad();
if (metalrecording)
G_BeginMetal();
if (demorecording) // Okay, level loaded, character spawned and skinned,
if (demo.recording) // Okay, level loaded, character spawned and skinned,
G_BeginRecording(); // I AM NOW READY TO RECORD.
demo_start = true;
demo.deferstart = true;
}
static void Command_Pause(void)
@ -2473,13 +2723,13 @@ static void Got_Pause(UINT8 **cp, INT32 playernum)
return;
}
if (modeattacking)
if (modeattacking && !demo.playback)
return;
paused = READUINT8(*cp);
dedicatedpause = READUINT8(*cp);
if (!demoplayback)
if (!demo.playback)
{
if (netgame)
{
@ -2566,6 +2816,7 @@ static void Got_Respawn(UINT8 **cp, INT32 playernum)
if (players[respawnplayer].mo)
P_DamageMobj(players[respawnplayer].mo, NULL, NULL, 10000);
demo_extradata[playernum] |= DXD_RESPAWN;
}
/** Deals with an ::XD_RANDOMSEED message in a netgame.
@ -2787,11 +3038,11 @@ static void Command_Teamchange2_f(void)
return;
}
if (players[secondarydisplayplayer].spectator)
error = !(NetPacket.packet.newteam || (players[secondarydisplayplayer].pflags & PF_WANTSTOJOIN));
if (players[displayplayers[1]].spectator)
error = !(NetPacket.packet.newteam || (players[displayplayers[1]].pflags & PF_WANTSTOJOIN));
else if (G_GametypeHasTeams())
error = (NetPacket.packet.newteam == (unsigned)players[secondarydisplayplayer].ctfteam);
else if (G_GametypeHasSpectators() && !players[secondarydisplayplayer].spectator)
error = (NetPacket.packet.newteam == (unsigned)players[displayplayers[1]].ctfteam);
else if (G_GametypeHasSpectators() && !players[displayplayers[1]].spectator)
error = (NetPacket.packet.newteam == 3);
#ifdef PARANOIA
else
@ -2878,11 +3129,11 @@ static void Command_Teamchange3_f(void)
return;
}
if (players[thirddisplayplayer].spectator)
error = !(NetPacket.packet.newteam || (players[thirddisplayplayer].pflags & PF_WANTSTOJOIN));
if (players[displayplayers[2]].spectator)
error = !(NetPacket.packet.newteam || (players[displayplayers[2]].pflags & PF_WANTSTOJOIN));
else if (G_GametypeHasTeams())
error = (NetPacket.packet.newteam == (unsigned)players[thirddisplayplayer].ctfteam);
else if (G_GametypeHasSpectators() && !players[thirddisplayplayer].spectator)
error = (NetPacket.packet.newteam == (unsigned)players[displayplayers[2]].ctfteam);
else if (G_GametypeHasSpectators() && !players[displayplayers[2]].spectator)
error = (NetPacket.packet.newteam == 3);
#ifdef PARANOIA
else
@ -2969,11 +3220,11 @@ static void Command_Teamchange4_f(void)
return;
}
if (players[fourthdisplayplayer].spectator)
error = !(NetPacket.packet.newteam || (players[fourthdisplayplayer].pflags & PF_WANTSTOJOIN));
if (players[displayplayers[3]].spectator)
error = !(NetPacket.packet.newteam || (players[displayplayers[3]].pflags & PF_WANTSTOJOIN));
else if (G_GametypeHasTeams())
error = (NetPacket.packet.newteam == (unsigned)players[fourthdisplayplayer].ctfteam);
else if (G_GametypeHasSpectators() && !players[fourthdisplayplayer].spectator)
error = (NetPacket.packet.newteam == (unsigned)players[displayplayers[3]].ctfteam);
else if (G_GametypeHasSpectators() && !players[displayplayers[3]].spectator)
error = (NetPacket.packet.newteam == 3);
#ifdef PARANOIA
else
@ -3370,8 +3621,8 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
HU_AddChatText(va("\x82*%s became a spectator.", player_names[playernum]), false); // "entered the game" text was moved to P_SpectatorJoinGame
//reset view if you are changed, or viewing someone who was changed.
if (playernum == consoleplayer || displayplayer == playernum)
displayplayer = consoleplayer;
if (playernum == consoleplayer || displayplayers[0] == playernum)
displayplayers[0] = consoleplayer;
if (G_GametypeHasTeams())
{
@ -3379,11 +3630,11 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
{
if (playernum == consoleplayer) //CTF and Team Match colors.
CV_SetValue(&cv_playercolor, NetPacket.packet.newteam + 5);
else if (playernum == secondarydisplayplayer)
else if (playernum == displayplayers[1])
CV_SetValue(&cv_playercolor2, NetPacket.packet.newteam + 5);
else if (playernum == thirddisplayplayer)
else if (playernum == displayplayers[2])
CV_SetValue(&cv_playercolor3, NetPacket.packet.newteam + 5);
else if (playernum == fourthdisplayplayer)
else if (playernum == displayplayers[3])
CV_SetValue(&cv_playercolor4, NetPacket.packet.newteam + 5);
}
}
@ -3391,6 +3642,8 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
if (gamestate != GS_LEVEL)
return;
demo_extradata[playernum] |= DXD_PLAYSTATE;
// Clear player score and rings if a spectator.
if (players[playernum].spectator)
{
@ -4440,7 +4693,7 @@ static void PointLimit_OnChange(void)
static void NumLaps_OnChange(void)
{
if (!G_RaceGametype() || (modeattacking || demoplayback))
if (!G_RaceGametype() || (modeattacking || demo.playback))
return;
if (server && Playing()
@ -4880,7 +5133,7 @@ static void Command_ExitLevel_f(void)
CONS_Printf(M_GetText("This only works in a netgame.\n"));
else if (!(server || (IsPlayerAdmin(consoleplayer))))
CONS_Printf(M_GetText("Only the server or a remote admin can use this.\n"));
else if (gamestate != GS_LEVEL || demoplayback)
else if (gamestate != GS_LEVEL || demo.playback)
CONS_Printf(M_GetText("You must be in a level to use this.\n"));
else
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
@ -4978,13 +5231,13 @@ static void Got_PickVotecmd(UINT8 **cp, INT32 playernum)
Y_SetupVoteFinish(pick, level);
}
/** Prints the number of the displayplayer.
/** Prints the number of displayplayers[0].
*
* \todo Possibly remove this; it was useful for debugging at one point.
*/
static void Command_Displayplayer_f(void)
{
CONS_Printf(M_GetText("Displayplayer is %d\n"), displayplayer);
CONS_Printf(M_GetText("Displayplayer is %d\n"), displayplayers[0]);
}
/** Quits a game and returns to the title screen.
@ -5143,27 +5396,11 @@ static void Command_Archivetest_f(void)
/** Makes a change to ::cv_forceskin take effect immediately.
*
* \todo Move the enforcement code out of SendNameAndColor() so this hack
* isn't needed.
* \sa Command_SetForcedSkin_f, cv_forceskin, forcedskin
* \author Graue <graue@oceanbase.org>
*/
static void ForceSkin_OnChange(void)
{
if ((server || IsPlayerAdmin(consoleplayer)) && (cv_forceskin.value < -1 || cv_forceskin.value >= numskins))
{
if (cv_forceskin.value == -2)
CV_SetValue(&cv_forceskin, numskins-1);
else
{
// hack because I can't restrict this and still allow added skins to be used with forceskin.
if (!menuactive)
CONS_Printf(M_GetText("Valid skin numbers are 0 to %d (-1 disables)\n"), numskins - 1);
CV_SetValue(&cv_forceskin, -1);
}
return;
}
// NOT in SP, silly!
if (!(netgame || multiplayer))
return;
@ -5172,7 +5409,7 @@ static void ForceSkin_OnChange(void)
CONS_Printf("The server has lifted the forced skin restrictions.\n");
else
{
CONS_Printf("The server is restricting all players to skin \"%s\".\n",skins[cv_forceskin.value].name);
CONS_Printf("The server is restricting all players to skin \"%s\".\n",cv_forceskin.string);
ForceAllSkins(cv_forceskin.value);
}
}
@ -5195,7 +5432,7 @@ static void Name2_OnChange(void)
if (cv_mute.value) //Secondary player can't be admin.
{
CONS_Alert(CONS_NOTICE, M_GetText("You may not change your name when chat is muted.\n"));
CV_StealthSet(&cv_playername2, player_names[secondarydisplayplayer]);
CV_StealthSet(&cv_playername2, player_names[displayplayers[1]]);
}
else
SendNameAndColor2();
@ -5206,7 +5443,7 @@ static void Name3_OnChange(void)
if (cv_mute.value) //Third player can't be admin.
{
CONS_Alert(CONS_NOTICE, M_GetText("You may not change your name when chat is muted.\n"));
CV_StealthSet(&cv_playername3, player_names[thirddisplayplayer]);
CV_StealthSet(&cv_playername3, player_names[displayplayers[2]]);
}
else
SendNameAndColor3();
@ -5217,7 +5454,7 @@ static void Name4_OnChange(void)
if (cv_mute.value) //Secondary player can't be admin.
{
CONS_Alert(CONS_NOTICE, M_GetText("You may not change your name when chat is muted.\n"));
CV_StealthSet(&cv_playername4, player_names[fourthdisplayplayer]);
CV_StealthSet(&cv_playername4, player_names[displayplayers[3]]);
}
else
SendNameAndColor4();
@ -5258,12 +5495,12 @@ static void Skin2_OnChange(void)
if (!Playing() || !splitscreen)
return; // do whatever you want
if (CanChangeSkin(secondarydisplayplayer) && !P_PlayerMoving(secondarydisplayplayer))
if (CanChangeSkin(displayplayers[1]) && !P_PlayerMoving(displayplayers[1]))
SendNameAndColor2();
else
{
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
CV_StealthSet(&cv_skin2, skins[players[secondarydisplayplayer].skin].name);
CV_StealthSet(&cv_skin2, skins[players[displayplayers[1]].skin].name);
}
}
@ -5272,12 +5509,12 @@ static void Skin3_OnChange(void)
if (!Playing() || splitscreen < 2)
return; // do whatever you want
if (CanChangeSkin(thirddisplayplayer) && !P_PlayerMoving(thirddisplayplayer))
if (CanChangeSkin(displayplayers[2]) && !P_PlayerMoving(displayplayers[2]))
SendNameAndColor3();
else
{
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
CV_StealthSet(&cv_skin3, skins[players[thirddisplayplayer].skin].name);
CV_StealthSet(&cv_skin3, skins[players[displayplayers[2]].skin].name);
}
}
@ -5286,12 +5523,12 @@ static void Skin4_OnChange(void)
if (!Playing() || splitscreen < 3)
return; // do whatever you want
if (CanChangeSkin(fourthdisplayplayer) && !P_PlayerMoving(fourthdisplayplayer))
if (CanChangeSkin(displayplayers[3]) && !P_PlayerMoving(displayplayers[3]))
SendNameAndColor4();
else
{
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
CV_StealthSet(&cv_skin4, skins[players[fourthdisplayplayer].skin].name);
CV_StealthSet(&cv_skin4, skins[players[displayplayers[3]].skin].name);
}
}
@ -5332,7 +5569,7 @@ static void Color2_OnChange(void)
if (!Playing() || !splitscreen)
return; // do whatever you want
if (!P_PlayerMoving(secondarydisplayplayer))
if (!P_PlayerMoving(displayplayers[1]))
{
// Color change menu scrolling fix is no longer necessary
SendNameAndColor2();
@ -5340,7 +5577,7 @@ static void Color2_OnChange(void)
else
{
CV_StealthSetValue(&cv_playercolor2,
players[secondarydisplayplayer].skincolor);
players[displayplayers[1]].skincolor);
}
}
@ -5349,7 +5586,7 @@ static void Color3_OnChange(void)
if (!Playing() || splitscreen < 2)
return; // do whatever you want
if (!P_PlayerMoving(thirddisplayplayer))
if (!P_PlayerMoving(displayplayers[2]))
{
// Color change menu scrolling fix is no longer necessary
SendNameAndColor3();
@ -5357,7 +5594,7 @@ static void Color3_OnChange(void)
else
{
CV_StealthSetValue(&cv_playercolor3,
players[thirddisplayplayer].skincolor);
players[displayplayers[2]].skincolor);
}
}
@ -5366,7 +5603,7 @@ static void Color4_OnChange(void)
if (!Playing() || splitscreen < 3)
return; // do whatever you want
if (!P_PlayerMoving(fourthdisplayplayer))
if (!P_PlayerMoving(displayplayers[3]))
{
// Color change menu scrolling fix is no longer necessary
SendNameAndColor4();
@ -5374,7 +5611,7 @@ static void Color4_OnChange(void)
else
{
CV_StealthSetValue(&cv_playercolor4,
players[fourthdisplayplayer].skincolor);
players[displayplayers[3]].skincolor);
}
}

View File

@ -143,11 +143,9 @@ extern consvar_t cv_ringslinger, cv_soundtest;
extern consvar_t cv_specialrings, cv_powerstones, cv_matchboxes, cv_competitionboxes;
#ifdef NEWPING
extern consvar_t cv_maxping;
extern consvar_t cv_pingtimeout;
extern consvar_t cv_showping;
#endif
extern consvar_t cv_skipmapcheck;

View File

@ -35,33 +35,6 @@ typedef enum
SF_HIRES = 1, // Draw the sprite 2x as small?
} skinflags_t;
//Primary and secondary skin abilities
typedef enum
{
CA_NONE=0,
CA_THOK,
CA_FLY,
CA_GLIDEANDCLIMB,
CA_HOMINGTHOK,
CA_SWIM,
CA_DOUBLEJUMP,
CA_FLOAT,
CA_SLOWFALL,
CA_TELEKINESIS,
CA_FALLSWITCH,
CA_JUMPBOOST,
CA_AIRDRILL,
CA_JUMPTHOK
} charability_t;
//Secondary skin abilities
typedef enum
{
CA2_NONE=0,
CA2_SPINDASH,
CA2_MULTIABILITY
} charability2_t;
//
// Player states.
//
@ -442,29 +415,8 @@ typedef struct player_s
UINT8 kartweight; // Kart weight stat between 1 and 9
//
fixed_t normalspeed; // Normal ground
fixed_t runspeed; // Speed you break into the run animation
UINT8 thrustfactor; // Thrust = thrustfactor * acceleration
UINT8 accelstart; // Starting acceleration if speed = 0.
UINT8 acceleration; // Acceleration
// See charability_t and charability2_t for more information.
UINT8 charability; // Ability definition
UINT8 charability2; // Secondary ability definition
UINT32 charflags; // Extra abilities/settings for skins (combinable stuff)
// See SF_ flags
mobjtype_t thokitem; // Object # to spawn for the thok
mobjtype_t spinitem; // Object # to spawn for spindash/spinning
mobjtype_t revitem; // Object # to spawn for spindash/spinning
fixed_t actionspd; // Speed of thok/glide/fly
fixed_t mindash; // Minimum spindash speed
fixed_t maxdash; // Maximum spindash speed
fixed_t jumpfactor; // How high can the player jump?
SINT8 lives;
SINT8 continues; // continues that player has acquired

View File

@ -2142,11 +2142,12 @@ static boolean GoodDataFileName(const char *s)
p = s + strlen(s) - strlen(tail);
if (p <= s) return false; // too short
if (!fasticmp(p, tail)) return false; // doesn't end in .dat
#ifdef DELFILE
if (fasticmp(s, "gamedata.dat") && !disableundo) return false;
#else
if (fasticmp(s, "gamedata.dat")) return false;
#endif
if (fasticmp(s, "gamedata.dat")) return false; // Vanilla SRB2 gamedata
if (fasticmp(s, "main.dat")) return false; // Vanilla SRB2 time attack replay folder
if (fasticmp(s, "kartdata.dat")) return false; // SRB2Kart gamedata
if (fasticmp(s, "kart.dat")) return false; // SRB2Kart time attack replay folder
if (fasticmp(s, "online.dat")) return false; // SRB2Kart online replay folder
return true;
}
@ -8142,22 +8143,28 @@ static const char *COLOR_ENUMS[] = { // Rejigged for Kart.
"GREY", // SKINCOLOR_GREY
"NICKEL", // SKINCOLOR_NICKEL
"BLACK", // SKINCOLOR_BLACK
"SKUNK", // SKINCOLOR_SKUNK
"FAIRY", // SKINCOLOR_FAIRY
"POPCORN", // SKINCOLOR_POPCORN
"ARTICHOKE", // SKINCOLOR_ARTICHOKE
"PIGEON", // SKINCOLOR_PIGEON
"SEPIA", // SKINCOLOR_SEPIA
"BEIGE", // SKINCOLOR_BEIGE
"WALNUT", // SKINCOLOR_WALNUT
"BROWN", // SKINCOLOR_BROWN
"LEATHER", // SKINCOLOR_LEATHER
"SALMON", // SKINCOLOR_SALMON
"PINK", // SKINCOLOR_PINK
"ROSE", // SKINCOLOR_ROSE
"BRICK", // SKINCOLOR_BRICK
"CINNAMON", // SKINCOLOR_CINNAMON
"RUBY", // SKINCOLOR_RUBY
"RASPBERRY", // SKINCOLOR_RASPBERRY
"CHERRY", // SKINCOLOR_CHERRY
"RED", // SKINCOLOR_RED
"CRIMSON", // SKINCOLOR_CRIMSON
"MAROON", // SKINCOLOR_MAROON
"LEMONADE", // SKINCOLOR_LEMONADE
"FLAME", // SKINCOLOR_FLAME
"SCARLET", // SKINCOLOR_SCARLET
"KETCHUP", // SKINCOLOR_KETCHUP
@ -8176,8 +8183,10 @@ static const char *COLOR_ENUMS[] = { // Rejigged for Kart.
"ROYAL", // SKINCOLOR_ROYAL
"BRONZE", // SKINCOLOR_BRONZE
"COPPER", // SKINCOLOR_COPPER
"QUARRY", // SKINCOLOR_QUARRY
"YELLOW", // SKINCOLOR_YELLOW
"MUSTARD", // SKINCOLOR_MUSTARD
"CROCODILE", // SKINCOLOR_CROCODILE
"OLIVE", // SKINCOLOR_OLIVE
"VOMIT", // SKINCOLOR_VOMIT
"GARDEN", // SKINCOLOR_GARDEN
@ -8197,6 +8206,7 @@ static const char *COLOR_ENUMS[] = { // Rejigged for Kart.
"PLAGUE", // SKINCOLOR_PLAGUE
"ALGAE", // SKINCOLOR_ALGAE
"CARIBBEAN", // SKINCOLOR_CARIBBEAN
"AZURE", // SKINCOLOR_AZURE
"AQUA", // SKINCOLOR_AQUA
"TEAL", // SKINCOLOR_TEAL
"CYAN", // SKINCOLOR_CYAN
@ -8206,7 +8216,9 @@ static const char *COLOR_ENUMS[] = { // Rejigged for Kart.
"PLATINUM", // SKINCOLOR_PLATINUM
"SLATE", // SKINCOLOR_SLATE
"STEEL", // SKINCOLOR_STEEL
"THUNDER", // SKINCOLOR_THUNDER
"RUST", // SKINCOLOR_RUST
"WRISTWATCH", // SKINCOLOR_WRISTWATCH
"JET", // SKINCOLOR_JET
"SAPPHIRE", // SKINCOLOR_SAPPHIRE
"PERIWINKLE", // SKINCOLOR_PERIWINKLE
@ -8227,10 +8239,6 @@ static const char *COLOR_ENUMS[] = { // Rejigged for Kart.
"POMEGRANATE", // SKINCOLOR_POMEGRANATE
"LILAC", // SKINCOLOR_LILAC
// Special super colors
// Super Sonic Yellow
"SUPER1", // SKINCOLOR_SUPER1
@ -8642,27 +8650,6 @@ struct {
// Character flags (skinflags_t)
{"SF_HIRES",SF_HIRES},
// Character abilities!
// Primary
{"CA_NONE",CA_NONE}, // now slot 0!
{"CA_THOK",CA_THOK},
{"CA_FLY",CA_FLY},
{"CA_GLIDEANDCLIMB",CA_GLIDEANDCLIMB},
{"CA_HOMINGTHOK",CA_HOMINGTHOK},
{"CA_DOUBLEJUMP",CA_DOUBLEJUMP},
{"CA_FLOAT",CA_FLOAT},
{"CA_SLOWFALL",CA_SLOWFALL},
{"CA_SWIM",CA_SWIM},
{"CA_TELEKINESIS",CA_TELEKINESIS},
{"CA_FALLSWITCH",CA_FALLSWITCH},
{"CA_JUMPBOOST",CA_JUMPBOOST},
{"CA_AIRDRILL",CA_AIRDRILL},
{"CA_JUMPTHOK",CA_JUMPTHOK},
// Secondary
{"CA2_NONE",CA2_NONE}, // now slot 0!
{"CA2_SPINDASH",CA2_SPINDASH},
{"CA2_MULTIABILITY",CA2_MULTIABILITY},
// Sound flags
{"SF_TOTALLYSINGLE",SF_TOTALLYSINGLE},
{"SF_NOMULTIPLESOUND",SF_NOMULTIPLESOUND},
@ -9799,7 +9786,7 @@ static inline int lib_getenum(lua_State *L)
// DYNAMIC variables too!!
// Try not to add anything that would break netgames or timeattack replays here.
// You know, like consoleplayer, displayplayer, secondarydisplayplayer, or gametime.
// You know, like consoleplayer, displayplayers, or gametime.
if (fastcmp(word,"gamemap")) {
lua_pushinteger(L, gamemap);
return 1;
@ -9873,7 +9860,7 @@ static inline int lib_getenum(lua_State *L)
lua_pushinteger(L, mapmusflags);
return 1;
} else if (fastcmp(word,"server")) {
if ((!multiplayer || !netgame) && !playeringame[serverplayer])
if ((!multiplayer || !(netgame || demo.playback)) && !playeringame[serverplayer])
return 0;
LUA_PushUserdata(L, &players[serverplayer], META_PLAYER);
return 1;
@ -9925,6 +9912,9 @@ static inline int lib_getenum(lua_State *L)
} else if (fastcmp(word,"mapobjectscale")) {
lua_pushinteger(L, mapobjectscale);
return 1;
} else if (fastcmp(word,"numlaps")) {
lua_pushinteger(L, cv_numlaps.value);
return 1;
}
return 0;
}

View File

@ -157,6 +157,9 @@ extern FILE *logstream;
// Otherwise we can't force updates!
#endif
// Maintain compatibility with 1.0.x record attack replays?
#define DEMO_COMPAT_100
// Does this version require an added patch file?
// Comment or uncomment this as necessary.
//#define USE_PATCH_DTA
@ -256,22 +259,28 @@ typedef enum
SKINCOLOR_GREY,
SKINCOLOR_NICKEL,
SKINCOLOR_BLACK,
SKINCOLOR_SKUNK,
SKINCOLOR_FAIRY,
SKINCOLOR_POPCORN,
SKINCOLOR_ARTICHOKE,
SKINCOLOR_PIGEON,
SKINCOLOR_SEPIA,
SKINCOLOR_BEIGE,
SKINCOLOR_WALNUT,
SKINCOLOR_BROWN,
SKINCOLOR_LEATHER,
SKINCOLOR_SALMON,
SKINCOLOR_PINK,
SKINCOLOR_ROSE,
SKINCOLOR_BRICK,
SKINCOLOR_CINNAMON,
SKINCOLOR_RUBY,
SKINCOLOR_RASPBERRY,
SKINCOLOR_CHERRY,
SKINCOLOR_RED,
SKINCOLOR_CRIMSON,
SKINCOLOR_MAROON,
SKINCOLOR_LEMONADE,
SKINCOLOR_FLAME,
SKINCOLOR_SCARLET,
SKINCOLOR_KETCHUP,
@ -290,8 +299,10 @@ typedef enum
SKINCOLOR_ROYAL,
SKINCOLOR_BRONZE,
SKINCOLOR_COPPER,
SKINCOLOR_QUARRY,
SKINCOLOR_YELLOW,
SKINCOLOR_MUSTARD,
SKINCOLOR_CROCODILE,
SKINCOLOR_OLIVE,
SKINCOLOR_VOMIT,
SKINCOLOR_GARDEN,
@ -311,6 +322,7 @@ typedef enum
SKINCOLOR_PLAGUE,
SKINCOLOR_ALGAE,
SKINCOLOR_CARIBBEAN,
SKINCOLOR_AZURE,
SKINCOLOR_AQUA,
SKINCOLOR_TEAL,
SKINCOLOR_CYAN,
@ -320,7 +332,9 @@ typedef enum
SKINCOLOR_PLATINUM,
SKINCOLOR_SLATE,
SKINCOLOR_STEEL,
SKINCOLOR_THUNDER,
SKINCOLOR_RUST,
SKINCOLOR_WRISTWATCH,
SKINCOLOR_JET,
SKINCOLOR_SAPPHIRE, // sweet mother, i cannot weave - slender aphrodite has overcome me with longing for a girl
SKINCOLOR_PERIWINKLE,
@ -601,9 +615,6 @@ extern const char *compdate, *comptime, *comprevision, *compbranch;
/// Polyobject fake flat code
#define POLYOBJECTS_PLANES
/// Improved way of dealing with ping values and a ping limit.
#define NEWPING
/// See name of player in your crosshair
#define SEENAMES

View File

@ -77,7 +77,10 @@ extern boolean addedtogame; // true after the server has added you
extern boolean multiplayer;
extern INT16 gametype;
#define MAXSPLITSCREENPLAYERS 4 // Max number of players on a single computer
extern UINT8 splitscreen;
extern boolean circuitmap; // Does this level have 'circuit mode'?
extern boolean fromlevelselect;
extern boolean forceresetplayers, deferencoremode;
@ -106,14 +109,8 @@ extern UINT8 window_notinfocus; // are we in focus? (backend independant -- hand
extern boolean nodrawers;
extern boolean noblit;
extern boolean lastdraw;
extern postimg_t postimgtype;
extern INT32 postimgparam;
extern postimg_t postimgtype2;
extern INT32 postimgparam2;
extern postimg_t postimgtype3;
extern INT32 postimgparam3;
extern postimg_t postimgtype4;
extern INT32 postimgparam4;
extern postimg_t postimgtype[MAXSPLITSCREENPLAYERS];
extern INT32 postimgparam[MAXSPLITSCREENPLAYERS];
extern INT32 viewwindowx, viewwindowy;
extern INT32 viewwidth, scaledviewwidth;
@ -122,10 +119,7 @@ extern boolean gamedataloaded;
// Player taking events, and displaying.
extern INT32 consoleplayer;
extern INT32 displayplayer;
extern INT32 secondarydisplayplayer; // for splitscreen
extern INT32 thirddisplayplayer;
extern INT32 fourthdisplayplayer;
extern INT32 displayplayers[MAXSPLITSCREENPLAYERS];
// Maps of special importance
extern INT16 spstage_start;
@ -543,9 +537,7 @@ extern consvar_t cv_forceskin; // force clients to use the server's skin
extern consvar_t cv_downloading; // allow clients to downloading WADs.
extern consvar_t cv_nettimeout; // SRB2Kart: Advanced server options menu
extern consvar_t cv_jointimeout;
#ifdef NEWPING
extern consvar_t cv_maxping;
#endif
extern ticcmd_t netcmds[BACKUPTICS][MAXPLAYERS];
extern INT32 serverplayer;
extern INT32 adminplayers[MAXPLAYERS];

View File

@ -366,16 +366,18 @@ size_t strlcpy(char *dst, const char *src, size_t siz);
/* Miscellaneous types that don't fit anywhere else (Can this be changed?) */
union FColorRGBA
typedef struct
{
UINT32 rgba;
struct
{
UINT8 red;
UINT8 green;
UINT8 blue;
UINT8 alpha;
} s;
} byteColor_t;
union FColorRGBA
{
UINT32 rgba;
byteColor_t s;
} ATTRPACK;
typedef union FColorRGBA RGBA_t;

View File

@ -584,6 +584,7 @@ void F_StartCredits(void)
S_StopMusic();
S_ChangeMusicInternal("credit", false);
S_ShowMusicCredit();
finalecount = 0;
animtimer = 0;
@ -927,9 +928,9 @@ void F_StartTitleScreen(void)
// IWAD dependent stuff.
// music is started in the ticker
if (!fromtitledemo) // SRB2Kart: Don't reset music if the right track is already playing
if (!demo.fromtitle) // SRB2Kart: Don't reset music if the right track is already playing
S_StopMusic();
fromtitledemo = false;
demo.fromtitle = false;
animtimer = 0;
@ -1042,11 +1043,29 @@ void F_TitleScreenTicker(boolean run)
// is it time?
if (!(--demoIdleLeft))
{
//static boolean use_netreplay = false;
char dname[9];
lumpnum_t l;
const char *mapname;
UINT8 numstaff;
//@TODO uncomment this when this goes into vanilla
/*if ((use_netreplay = !use_netreplay))*/
{
numstaff = 1;
while ((l = W_CheckNumForName(va("TDEMO%03u", numstaff))) != LUMPERROR)
numstaff++;
numstaff--;
if (numstaff)
{
numstaff = M_RandomKey(numstaff)+1;
snprintf(dname, 9, "TDEMO%03u", numstaff);
goto loadreplay;
}
}
// prevent console spam if failed
demoIdleLeft = demoIdleTime;
@ -1097,7 +1116,10 @@ void F_TitleScreenTicker(boolean run)
return;
}*/
titledemo = fromtitledemo = true;
loadreplay:
demo.title = demo.fromtitle = true;
demo.ignorefiles = true;
demo.loadfiles = false;
G_DoPlayDemo(dname);
}
}

View File

@ -366,9 +366,10 @@ void searchfilemenu(char *tempname)
return;
}
boolean preparefilemenu(boolean samedepth)
boolean preparefilemenu(boolean samedepth, boolean replayhut)
{
(void)samedepth;
(void)replayhut;
return false;
}
@ -435,9 +436,10 @@ void searchfilemenu(char *tempname)
return;
}
boolean preparefilemenu(boolean samedepth)
boolean preparefilemenu(boolean samedepth, boolean replayhut)
{
(void)samedepth;
(void)replayhut;
return false;
}
@ -708,7 +710,7 @@ void searchfilemenu(char *tempname)
}
}
boolean preparefilemenu(boolean samedepth)
boolean preparefilemenu(boolean samedepth, boolean replayhut)
{
DIR *dirhandle;
struct dirent *dent;
@ -756,10 +758,14 @@ boolean preparefilemenu(boolean samedepth)
else // is a file or directory
{
if (!S_ISDIR(fsstat.st_mode)) // file
{
if (!cv_addons_showall.value)
{
size_t len = strlen(dent->d_name)+1;
if (replayhut)
{
if (strcasecmp(".lmp", dent->d_name+len-5)) continue; // Not a replay
}
else if (!cv_addons_showall.value)
{
UINT8 ext;
for (ext = 0; ext < NUM_EXT_TABLE; ext++)
if (!strcasecmp(exttable[ext]+1, dent->d_name+len-(exttable[ext][0]))) break; // extension comparison
@ -827,6 +833,14 @@ boolean preparefilemenu(boolean samedepth)
if (!S_ISDIR(fsstat.st_mode)) // file
{
if (!((numfolders+pos) < sizecoredirmenu)) continue; // crash prevention
if (replayhut)
{
if (strcasecmp(".lmp", dent->d_name+len-5)) continue; // Not a replay
ext = EXT_TXT; // This isn't used anywhere but better safe than sorry for messing with this...
}
else
{
for (; ext < NUM_EXT_TABLE; ext++)
if (!strcasecmp(exttable[ext]+1, dent->d_name+len-(exttable[ext][0]))) break; // extension comparison
if (ext == NUM_EXT_TABLE && !cv_addons_showall.value) continue; // not an addfile-able (or exec-able) file
@ -860,6 +874,7 @@ boolean preparefilemenu(boolean samedepth)
if (!strcmp(dent->d_name, configfile))
ext |= EXT_LOADED;
}
folder = 0;
}
@ -879,6 +894,8 @@ boolean preparefilemenu(boolean samedepth)
strcpy(temp+len, PATHSEP);
coredirmenu[folderpos++] = temp;
}
else if (replayhut) // Reverse-alphabetical on just the files; acts as a fake "most recent first" with the current filename format
coredirmenu[sizecoredirmenu - 1 - pos++] = temp;
else
coredirmenu[numfolders + pos++] = temp;
}

View File

@ -91,6 +91,6 @@ typedef enum
void closefilemenu(boolean validsize);
void searchfilemenu(char *tempname);
boolean preparefilemenu(boolean samedepth);
boolean preparefilemenu(boolean samedepth, boolean replayhut);
#endif // __FILESRCH_H__

File diff suppressed because it is too large Load Diff

View File

@ -36,11 +36,61 @@ extern boolean playeringame[MAXPLAYERS];
// ======================================
// demoplaying back and demo recording
extern boolean demoplayback, titledemo, fromtitledemo, demorecording, timingdemo;
extern consvar_t cv_recordmultiplayerdemos, cv_netdemosyncquality;
// Publicly-accessible demo vars
struct demovars_s {
char titlename[65];
boolean recording, playback, timing;
UINT16 version; // Current file format of the demo being played
boolean title; // Title Screen demo can be cancelled by any key
boolean rewinding; // Rewind in progress
boolean loadfiles, ignorefiles; // Demo file loading options
boolean fromtitle; // SRB2Kart: Don't stop the music
boolean inreplayhut; // Go back to replayhut after demos
boolean quitafterplaying; // quit after playing a demo from cmdline
boolean deferstart; // don't start playing demo right away
tic_t savebutton; // Used to determine when the local player can choose to save the replay while the race is still going
enum {
DSM_NOTSAVING,
DSM_WILLAUTOSAVE,
DSM_TITLEENTRY,
DSM_WILLSAVE,
DSM_SAVED
} savemode;
};
extern struct demovars_s demo;
typedef enum {
MD_NOTLOADED,
MD_LOADED,
MD_SUBDIR,
MD_OUTDATED,
MD_INVALID
} menudemotype_e;
typedef struct menudemo_s {
char filepath[256];
menudemotype_e type;
char title[65]; // Null-terminated for string prints
UINT16 map;
UINT8 addonstatus; // What do we need to do addon-wise to play this demo?
UINT8 gametype;
UINT8 kartspeed; // Add OR DF_ENCORE for encore mode, idk
UINT8 numlaps;
struct {
UINT8 ranking;
char name[17];
UINT8 skin, color;
UINT32 timeorscore;
} standings[MAXPLAYERS];
} menudemo_t;
// Quit after playing a demo from cmdline.
extern boolean singledemo;
extern boolean demo_start;
extern mobj_t *metalplayback;
@ -62,10 +112,10 @@ extern consvar_t cv_invertmouse/*, cv_alwaysfreelook, cv_chasefreelook, cv_mouse
extern consvar_t cv_invertmouse2/*, cv_alwaysfreelook2, cv_chasefreelook2, cv_mousemove2*/;
extern consvar_t cv_useranalog, cv_useranalog2, cv_useranalog3, cv_useranalog4;
extern consvar_t cv_analog, cv_analog2, cv_analog3, cv_analog4;
extern consvar_t cv_turnaxis,cv_moveaxis,cv_brakeaxis,cv_aimaxis,cv_lookaxis,cv_fireaxis,cv_driftaxis;
extern consvar_t cv_turnaxis2,cv_moveaxis2,cv_brakeaxis2,cv_aimaxis2,cv_lookaxis2,cv_fireaxis2,cv_driftaxis2;
extern consvar_t cv_turnaxis3,cv_moveaxis3,cv_brakeaxis3,cv_aimaxis3,cv_lookaxis3,cv_fireaxis3,cv_driftaxis3;
extern consvar_t cv_turnaxis4,cv_moveaxis4,cv_brakeaxis4,cv_aimaxis4,cv_lookaxis4,cv_fireaxis4,cv_driftaxis4;
extern consvar_t cv_turnaxis,cv_moveaxis,cv_brakeaxis,cv_aimaxis,cv_lookaxis,cv_fireaxis,cv_driftaxis,cv_deadzone;
extern consvar_t cv_turnaxis2,cv_moveaxis2,cv_brakeaxis2,cv_aimaxis2,cv_lookaxis2,cv_fireaxis2,cv_driftaxis2,cv_deadzone2;
extern consvar_t cv_turnaxis3,cv_moveaxis3,cv_brakeaxis3,cv_aimaxis3,cv_lookaxis3,cv_fireaxis3,cv_driftaxis3,cv_deadzone3;
extern consvar_t cv_turnaxis4,cv_moveaxis4,cv_brakeaxis4,cv_aimaxis4,cv_lookaxis4,cv_fireaxis4,cv_driftaxis4,cv_deadzone4;
extern consvar_t cv_ghost_besttime, cv_ghost_bestlap, cv_ghost_last, cv_ghost_guest, cv_ghost_staff;
typedef enum
@ -102,9 +152,9 @@ INT16 G_SoftwareClipAimingPitch(INT32 *aiming);
boolean InputDown(INT32 gc, UINT8 p);
INT32 JoyAxis(axis_input_e axissel, UINT8 p);
extern angle_t localangle, localangle2, localangle3, localangle4;
extern INT32 localaiming, localaiming2, localaiming3, localaiming4; // should be an angle_t but signed
extern boolean camspin, camspin2, camspin3, camspin4; // SRB2Kart
extern angle_t localangle[MAXSPLITSCREENPLAYERS];
extern INT32 localaiming[MAXSPLITSCREENPLAYERS]; // should be an angle_t but signed
extern boolean camspin[MAXSPLITSCREENPLAYERS]; // SRB2Kart
//
// GAME
@ -128,6 +178,7 @@ void G_DeferedInitNew(boolean pencoremode, const char *mapname, INT32 pickedchar
UINT8 ssplayers, boolean FLS);
void G_DoLoadLevel(boolean resetplayer);
void G_LoadDemoInfo(menudemo_t *pdemo);
void G_DeferedPlayDemo(const char *demo);
// Can be called by the startup code or M_Responder, calls P_SetupLevel.
@ -144,6 +195,7 @@ void G_BeginRecording(void);
void G_BeginMetal(void);
// Only called by shutdown code.
void G_WriteStanding(UINT8 ranking, char *name, INT32 skinnum, UINT8 color, UINT32 val);
void G_SetDemoTime(UINT32 ptime, UINT32 plap);
UINT8 G_CmpDemoTime(char *oldname, char *newname);
@ -155,19 +207,41 @@ typedef enum
GHC_INVINCIBLE
} ghostcolor_t;
extern UINT8 demo_extradata[MAXPLAYERS];
extern UINT8 demo_writerng;
#define DXD_RESPAWN 0x01 // "respawn" command in console
#define DXD_SKIN 0x02 // skin changed
#define DXD_NAME 0x04 // name changed
#define DXD_COLOR 0x08 // color changed
#define DXD_PLAYSTATE 0x10 // state changed between playing, spectating, or not in-game
#define DXD_PST_PLAYING 0x01
#define DXD_PST_SPECTATING 0x02
#define DXD_PST_LEFT 0x03
// Record/playback tics
void G_ReadDemoExtraData(void);
void G_WriteDemoExtraData(void);
void G_ReadDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum);
void G_GhostAddThok(void);
void G_GhostAddSpin(void);
void G_GhostAddRev(void);
void G_GhostAddColor(ghostcolor_t color);
void G_GhostAddFlip(void);
void G_GhostAddScale(fixed_t scale);
void G_GhostAddHit(mobj_t *victim);
void G_WriteGhostTic(mobj_t *ghost);
void G_ConsGhostTic(void);
void G_GhostAddThok(INT32 playernum);
void G_GhostAddSpin(INT32 playernum);
void G_GhostAddRev(INT32 playernum);
void G_GhostAddColor(INT32 playernum, ghostcolor_t color);
void G_GhostAddFlip(INT32 playernum);
void G_GhostAddScale(INT32 playernum, fixed_t scale);
void G_GhostAddHit(INT32 playernum, mobj_t *victim);
void G_WriteAllGhostTics(void);
void G_WriteGhostTic(mobj_t *ghost, INT32 playernum);
void G_ConsAllGhostTics(void);
void G_ConsGhostTic(INT32 playernum);
void G_GhostTicker(void);
void G_InitDemoRewind(void);
void G_StoreRewindInfo(void);
void G_PreviewRewind(tic_t previewtime);
void G_ConfirmRewind(tic_t rewindtime);
void G_ReadMetalTic(mobj_t *metal);
void G_WriteMetalTic(mobj_t *metal);
void G_SaveMetal(UINT8 **buffer);
@ -184,6 +258,13 @@ typedef struct demoghost {
} demoghost;
extern demoghost *ghosts;
// G_CheckDemoExtraFiles: checks if our loaded WAD list matches the demo's.
#define DFILE_ERROR_NOTLOADED 0x01 // Files are not loaded, but can be without a restart.
#define DFILE_ERROR_OUTOFORDER 0x02 // Files are loaded, but out of order.
#define DFILE_ERROR_INCOMPLETEOUTOFORDER 0x03 // Some files are loaded out of order, but others are not.
#define DFILE_ERROR_CANNOTLOAD 0x04 // Files are missing and cannot be loaded.
#define DFILE_ERROR_EXTRAFILES 0x05 // Extra files outside of the replay's file list are loaded.
void G_DoPlayDemo(char *defdemoname);
void G_TimeDemo(const char *name);
void G_AddGhost(char *defdemoname);
@ -194,6 +275,8 @@ void G_StopMetalDemo(void);
ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(void);
void G_StopDemo(void);
boolean G_CheckDemoStatus(void);
void G_SaveDemo(void);
boolean G_DemoTitleResponder(event_t *ev);
boolean G_IsSpecialStage(INT32 mapnum);
boolean G_GametypeUsesLives(void);
@ -214,6 +297,16 @@ void G_EndGame(void); // moved from y_inter.c/h and renamed
void G_Ticker(boolean run);
boolean G_Responder(event_t *ev);
boolean G_CouldView(INT32 playernum);
boolean G_CanView(INT32 playernum, UINT8 viewnum, boolean onlyactive);
INT32 G_FindView(INT32 startview, UINT8 viewnum, boolean onlyactive, boolean reverse);
INT32 G_CountPlayersPotentiallyViewable(boolean active);
void G_ResetViews(void);
void G_ResetView(UINT8 viewnum, INT32 playernum, boolean onlyactive);
void G_AdjustView(UINT8 viewnum, INT32 offset, boolean onlyactive);
void G_AddPlayer(INT32 playernum);
void G_SetExitGameFlag(void);

View File

@ -1239,6 +1239,8 @@ void G_ClearAllControlKeys(void)
{
G_ClearControlKeys(gamecontrol, i);
G_ClearControlKeys(gamecontrolbis, i);
G_ClearControlKeys(gamecontrol3, i);
G_ClearControlKeys(gamecontrol4, i);
}
}

View File

@ -296,7 +296,7 @@ static void HW3S_FillSourceParameters
data->max_distance = MAX_DISTANCE;
data->min_distance = MIN_DISTANCE;
if (origin && origin != players[displayplayer].mo)
if (origin && origin != players[displayplayers[0]].mo)
{
data->head_relative = false;
@ -356,10 +356,10 @@ INT32 HW3S_I_StartSound(const void *origin_p, source3D_data_t *source_parm, chan
source3D_data_t source3d_data;
INT32 s_num = 0;
source_t *source = NULL;
mobj_t *listenmobj = players[displayplayer].mo;
mobj_t *listenmobj = players[displayplayers[0]].mo; // TODO: Kart 4P does not support sounds properly here
mobj_t *listenmobj2 = NULL;
if (splitscreen) listenmobj2 = players[secondarydisplayplayer].mo;
if (splitscreen) listenmobj2 = players[displayplayers[1]].mo;
if (sound_disabled)
return -1;
@ -876,12 +876,12 @@ static void HW3S_Update3DSource(source_t *src)
void HW3S_UpdateSources(void)
{
mobj_t *listener = players[displayplayer].mo;
mobj_t *listener = players[displayplayers[0]].mo;
mobj_t *listener2 = NULL;
source_t *src;
INT32 audible, snum, volume, sep, pitch;
if (splitscreen) listener2 = players[secondarydisplayplayer].mo;
if (splitscreen) listener2 = players[displayplayers[1]].mo;
HW3S_UpdateListener2(listener2);
HW3S_UpdateListener(listener);

View File

@ -241,43 +241,6 @@ static void HWR_ResizeBlock(INT32 originalwidth, INT32 originalheight,
if (blockheight < 1)
I_Error("3D GenerateTexture : too small");
}
else if (cv_voodoocompatibility.value)
{
if (originalwidth > 256 || originalheight > 256)
{
blockwidth = 256;
while (originalwidth < blockwidth)
blockwidth >>= 1;
if (blockwidth < 1)
I_Error("3D GenerateTexture : too small");
blockheight = 256;
while (originalheight < blockheight)
blockheight >>= 1;
if (blockheight < 1)
I_Error("3D GenerateTexture : too small");
}
else
{
//size up to nearest power of 2
blockwidth = 1;
while (blockwidth < originalwidth)
blockwidth <<= 1;
// scale down the original graphics to fit in 256
if (blockwidth > 256)
blockwidth = 256;
//I_Error("3D GenerateTexture : too big");
//size up to nearest power of 2
blockheight = 1;
while (blockheight < originalheight)
blockheight <<= 1;
// scale down the original graphics to fit in 256
if (blockheight > 256)
blockheight = 255;
//I_Error("3D GenerateTexture : too big");
}
}
else
{
//size up to nearest power of 2
@ -508,18 +471,6 @@ void HWR_MakePatch (const patch_t *patch, GLPatch_t *grPatch, GLMipmap_t *grMipm
newwidth = blockwidth;
newheight = blockheight;
}
else if (cv_voodoocompatibility.value) // Only scales down textures that exceed 256x256.
{
// no rounddown, do not size up patches, so they don't look 'scaled'
newwidth = min(grPatch->width, blockwidth);
newheight = min(grPatch->height, blockheight);
if (newwidth > 256 || newheight > 256)
{
newwidth = blockwidth;
newheight = blockheight;
}
}
else
{
// no rounddown, do not size up patches, so they don't look 'scaled'
@ -935,18 +886,6 @@ GLPatch_t *HWR_GetPic(lumpnum_t lumpnum)
newwidth = blockwidth;
newheight = blockheight;
}
else if (cv_voodoocompatibility.value) // Only scales down textures that exceed 256x256.
{
// no rounddown, do not size up patches, so they don't look 'scaled'
newwidth = min(SHORT(pic->width),blockwidth);
newheight = min(SHORT(pic->height),blockheight);
if (newwidth > 256 || newheight > 256)
{
newwidth = blockwidth;
newheight = blockheight;
}
}
else
{
// no rounddown, do not size up patches, so they don't look 'scaled'

View File

@ -78,8 +78,8 @@
#include "r_opengl/r_opengl.h"
#ifdef HAVE_SPHEREFRUSTRUM
static GLdouble viewMatrix[16];
static GLdouble projMatrix[16];
static GLfloat viewMatrix[16];
static GLfloat projMatrix[16];
float frustum[6][4];
#endif
@ -381,8 +381,8 @@ void gld_FrustrumSetup(void)
float t;
float clip[16];
pglGetDoublev(GL_PROJECTION_MATRIX, projMatrix);
pglGetDoublev(GL_MODELVIEW_MATRIX, viewMatrix);
pglGeFloatv(GL_PROJECTION_MATRIX, projMatrix);
pglGetFloatv(GL_MODELVIEW_MATRIX, viewMatrix);
clip[0] = CALCMATRIX(0, 0, 1, 4, 2, 8, 3, 12);
clip[1] = CALCMATRIX(0, 1, 1, 5, 2, 9, 3, 13);

View File

@ -101,15 +101,29 @@ typedef struct
//Hurdler: Transform (coords + angles)
//BP: transform order : scale(rotation_x(rotation_y(translation(v))))
// Kart features
#define USE_FTRANSFORM_ANGLEZ
#define USE_FTRANSFORM_MIRROR
// Vanilla features
//#define USE_MODEL_NEXTFRAME
typedef struct
{
FLOAT x,y,z; // position
#ifdef USE_FTRANSFORM_ANGLEZ
FLOAT anglex,angley,anglez; // aimingangle / viewangle
#else
FLOAT anglex,angley; // aimingangle / viewangle
#endif
FLOAT scalex,scaley,scalez;
FLOAT fovxangle, fovyangle;
UINT8 splitscreen;
boolean flip; // screenflip
#ifdef USE_FTRANSFORM_MIRROR
boolean mirror; // SRB2Kart: Encore Mode
#endif
} FTransform;
// Transformed vector, as passed to HWR API
@ -152,7 +166,7 @@ enum EPolyFlags
// When set, pass the color constant into the FSurfaceInfo -> FlatColor
PF_NoTexture = 0x00002000, // Use the small white texture
PF_Corona = 0x00004000, // Tell the rendrer we are drawing a corona
PF_MD2 = 0x00008000, // Tell the rendrer we are drawing an MD2
PF_Unused = 0x00008000, // Unused
PF_RemoveYWrap = 0x00010000, // Force clamp texture on Y
PF_ForceWrapX = 0x00020000, // Force repeat texture on X
PF_ForceWrapY = 0x00040000, // Force repeat texture on Y
@ -210,8 +224,6 @@ enum hwdsetspecialstate
HWD_SET_FOG_COLOR,
HWD_SET_FOG_DENSITY,
HWD_SET_FOV,
HWD_SET_POLYGON_SMOOTH,
HWD_SET_PALETTECOLOR,
HWD_SET_TEXTUREFILTERMODE,
HWD_SET_TEXTUREANISOTROPICMODE,
HWD_NUMSTATE

View File

@ -58,20 +58,18 @@ EXPORT void HWRAPI(ClearMipMapCache) (void);
EXPORT void HWRAPI(SetSpecialState) (hwdspecialstate_t IdState, INT32 Value);
//Hurdler: added for new development
EXPORT void HWRAPI(DrawMD2) (INT32 *gl_cmd_buffer, md2_frame_t *frame, FTransform *pos, float scale);
EXPORT void HWRAPI(DrawMD2i) (INT32 *gl_cmd_buffer, md2_frame_t *frame, INT32 duration, INT32 tics, md2_frame_t *nextframe, FTransform *pos, float scale, UINT8 flipped, UINT8 *color);
EXPORT void HWRAPI(DrawModel) (model_t *model, INT32 frameIndex, INT32 duration, INT32 tics, INT32 nextFrameIndex, FTransform *pos, float scale, UINT8 flipped, UINT8 *color);
EXPORT void HWRAPI(CreateModelVBOs) (model_t *model);
EXPORT void HWRAPI(SetTransform) (FTransform *ptransform);
EXPORT INT32 HWRAPI(GetTextureUsed) (void);
EXPORT INT32 HWRAPI(GetRenderVersion) (void);
#ifdef SHUFFLE
#define SCREENVERTS 10
EXPORT void HWRAPI(PostImgRedraw) (float points[SCREENVERTS][SCREENVERTS][2]);
#endif
EXPORT void HWRAPI(FlushScreenTextures) (void);
EXPORT void HWRAPI(StartScreenWipe) (void);
EXPORT void HWRAPI(EndScreenWipe) (void);
EXPORT void HWRAPI(DoScreenWipe) (float alpha);
EXPORT void HWRAPI(DoScreenWipe) (void);
EXPORT void HWRAPI(DrawIntermissionBG) (void);
EXPORT void HWRAPI(MakeScreenTexture) (void);
EXPORT void HWRAPI(MakeScreenFinalTexture) (void);
@ -96,8 +94,8 @@ struct hwdriver_s
GClipRect pfnGClipRect;
ClearMipMapCache pfnClearMipMapCache;
SetSpecialState pfnSetSpecialState;//Hurdler: added for backward compatibility
DrawMD2 pfnDrawMD2;
DrawMD2i pfnDrawMD2i;
DrawModel pfnDrawModel;
CreateModelVBOs pfnCreateModelVBOs;
SetTransform pfnSetTransform;
GetTextureUsed pfnGetTextureUsed;
GetRenderVersion pfnGetRenderVersion;
@ -107,9 +105,7 @@ struct hwdriver_s
#ifndef HAVE_SDL
Shutdown pfnShutdown;
#endif
#ifdef SHUFFLE
PostImgRedraw pfnPostImgRedraw;
#endif
FlushScreenTextures pfnFlushScreenTextures;
StartScreenWipe pfnStartScreenWipe;
EndScreenWipe pfnEndScreenWipe;

View File

@ -63,7 +63,7 @@ struct hwdriver_s hwdriver;
// ==========================================================================
static void HWR_AddSprites(sector_t *sec, UINT8 ssplayer);
static void HWR_AddSprites(sector_t *sec);
static void HWR_ProjectSprite(mobj_t *thing);
#ifdef HWPRECIP
static void HWR_ProjectPrecipitationSprite(precipmobj_t *thing);
@ -3389,7 +3389,7 @@ static void HWR_AddPolyObjectPlanes(void)
// : Draw one or more line segments.
// Notes : Sets gr_cursectorlight to the light of the parent sector, to modulate wall textures
// -----------------+
static void HWR_Subsector(size_t num, UINT8 ssplayer)
static void HWR_Subsector(size_t num)
{
INT16 count;
seg_t *line;
@ -3754,7 +3754,7 @@ static void HWR_Subsector(size_t num, UINT8 ssplayer)
{
// draw sprites first, coz they are clipped to the solidsegs of
// subsectors more 'in front'
HWR_AddSprites(gr_frontsector, ssplayer);
HWR_AddSprites(gr_frontsector);
//Hurdler: at this point validcount must be the same, but is not because
// gr_frontsector doesn't point anymore to sub->sector due to
@ -3806,7 +3806,7 @@ static boolean HWR_CheckHackBBox(fixed_t *bb)
// BP: big hack for a test in lighning ref : 1249753487AB
fixed_t *hwbbox;
static void HWR_RenderBSPNode(INT32 bspnum, UINT8 ssplayer)
static void HWR_RenderBSPNode(INT32 bspnum)
{
/*//GZDoom code
if(bspnum == -1)
@ -3846,12 +3846,12 @@ static void HWR_RenderBSPNode(INT32 bspnum, UINT8 ssplayer)
if (bspnum == -1)
{
//*(gr_drawsubsector_p++) = 0;
HWR_Subsector(0, ssplayer);
HWR_Subsector(0);
}
else
{
//*(gr_drawsubsector_p++) = bspnum&(~NF_SUBSECTOR);
HWR_Subsector(bspnum&(~NF_SUBSECTOR), ssplayer);
HWR_Subsector(bspnum&(~NF_SUBSECTOR));
}
return;
}
@ -3863,14 +3863,14 @@ static void HWR_RenderBSPNode(INT32 bspnum, UINT8 ssplayer)
hwbbox = bsp->bbox[side];
// Recursively divide front space.
HWR_RenderBSPNode(bsp->children[side], ssplayer);
HWR_RenderBSPNode(bsp->children[side]);
// Possibly divide back space.
if (HWR_CheckBBox(bsp->bbox[side^1]))
{
// BP: big hack for a test in lighning ref : 1249753487AB
hwbbox = bsp->bbox[side^1];
HWR_RenderBSPNode(bsp->children[side^1], ssplayer);
HWR_RenderBSPNode(bsp->children[side^1]);
}
}
@ -4097,14 +4097,14 @@ static void HWR_DrawSpriteShadow(gr_vissprite_t *spr, GLPatch_t *gpatch, float t
angle_t shadowdir;
// Set direction
if (splitscreen && stplyr == &players[secondarydisplayplayer])
shadowdir = localangle2 + FixedAngle(cv_cam2_rotate.value);
else if (splitscreen > 1 && stplyr == &players[thirddisplayplayer])
shadowdir = localangle3 + FixedAngle(cv_cam3_rotate.value);
else if (splitscreen > 2 && stplyr == &players[fourthdisplayplayer])
shadowdir = localangle4 + FixedAngle(cv_cam4_rotate.value);
if (splitscreen && stplyr == &players[displayplayers[1]])
shadowdir = localangle[1] + FixedAngle(cv_cam2_rotate.value);
else if (splitscreen > 1 && stplyr == &players[displayplayers[2]])
shadowdir = localangle[2] + FixedAngle(cv_cam3_rotate.value);
else if (splitscreen > 2 && stplyr == &players[displayplayers[3]])
shadowdir = localangle[3] + FixedAngle(cv_cam4_rotate.value);
else
shadowdir = localangle + FixedAngle(cv_cam_rotate.value);
shadowdir = localangle[0] + FixedAngle(cv_cam_rotate.value);
// Find floorheight
floorheight = HWR_OpaqueFloorAtPos(
@ -5261,14 +5261,14 @@ static void HWR_DrawSprites(void)
if (spr->mobj && spr->mobj->skin && spr->mobj->sprite == SPR_PLAY)
{
// 8/1/19: Only don't display player models if no default SPR_PLAY is found.
if (!cv_grmd2.value || ((md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) && (md2_models[SPR_PLAY].notfound || md2_models[SPR_PLAY].scale < 0.0f)))
if (!cv_grmdls.value || ((md2_playermodels[(skin_t*)spr->mobj->skin-skins].notfound || md2_playermodels[(skin_t*)spr->mobj->skin-skins].scale < 0.0f) && ((!cv_grfallbackplayermodel.value) || md2_models[SPR_PLAY].notfound || md2_models[SPR_PLAY].scale < 0.0f)))
HWR_DrawSprite(spr);
else
HWR_DrawMD2(spr);
}
else
{
if (!cv_grmd2.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f)
if (!cv_grmdls.value || md2_models[spr->mobj->sprite].notfound || md2_models[spr->mobj->sprite].scale < 0.0f)
HWR_DrawSprite(spr);
else
HWR_DrawMD2(spr);
@ -5283,7 +5283,7 @@ static void HWR_DrawSprites(void)
// During BSP traversal, this adds sprites by sector.
// --------------------------------------------------------------------------
static UINT8 sectorlight;
static void HWR_AddSprites(sector_t *sec, UINT8 ssplayer)
static void HWR_AddSprites(sector_t *sec)
{
mobj_t *thing;
#ifdef HWPRECIP
@ -5316,19 +5316,19 @@ static void HWR_AddSprites(sector_t *sec, UINT8 ssplayer)
if (splitscreen)
{
if (thing->eflags & MFE_DRAWONLYFORP1)
if (ssplayer != 1)
if (viewssnum != 0)
continue;
if (thing->eflags & MFE_DRAWONLYFORP2)
if (ssplayer != 2)
if (viewssnum != 1)
continue;
if (thing->eflags & MFE_DRAWONLYFORP3 && splitscreen > 1)
if (ssplayer != 3)
if (viewssnum != 2)
continue;
if (thing->eflags & MFE_DRAWONLYFORP4 && splitscreen > 2)
if (ssplayer != 4)
if (viewssnum != 3)
continue;
}
@ -5351,19 +5351,19 @@ static void HWR_AddSprites(sector_t *sec, UINT8 ssplayer)
if (splitscreen)
{
if (thing->eflags & MFE_DRAWONLYFORP1)
if (ssplayer != 1)
if (viewssnum != 0)
continue;
if (thing->eflags & MFE_DRAWONLYFORP2)
if (ssplayer != 2)
if (viewssnum != 1)
continue;
if (thing->eflags & MFE_DRAWONLYFORP3 && splitscreen > 1)
if (ssplayer != 3)
if (viewssnum != 2)
continue;
if (thing->eflags & MFE_DRAWONLYFORP4 && splitscreen > 2)
if (ssplayer != 4)
if (viewssnum != 3)
continue;
}
@ -5435,7 +5435,7 @@ static void HWR_ProjectSprite(mobj_t *thing)
tz = (tr_x * gr_viewcos) + (tr_y * gr_viewsin);
// thing is behind view plane?
if (tz < ZCLIP_PLANE && !papersprite && (!cv_grmd2.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear
if (tz < ZCLIP_PLANE && !papersprite && (!cv_grmdls.value || md2_models[thing->sprite].notfound == true)) //Yellow: Only MD2's dont disappear
return;
// The above can stay as it works for cutting sprites that are too close
@ -5906,33 +5906,8 @@ void HWR_RenderSkyboxView(INT32 viewnumber, player_t *player)
{
const float fpov = FIXED_TO_FLOAT(cv_fov.value+player->fovadd);
postimg_t *type;
UINT8 ssplayer = 0;
if (splitscreen)
{
if (player == &players[secondarydisplayplayer])
{
type = &postimgtype2;
ssplayer = 2;
}
else if (splitscreen > 1 && player == &players[thirddisplayplayer])
{
type = &postimgtype3;
ssplayer = 3;
}
else if (splitscreen > 2 && player == &players[fourthdisplayplayer])
{
type = &postimgtype4;
ssplayer = 4;
}
else
{
type = &postimgtype;
ssplayer = 1;
}
}
else
type = &postimgtype;
type = &postimgtype[viewnumber];
{
// do we really need to save player (is it not the same)?
@ -6056,36 +6031,36 @@ if (0)
validcount++;
HWR_RenderBSPNode((INT32)numnodes-1, ssplayer);
HWR_RenderBSPNode((INT32)numnodes-1);
#ifndef NEWCLIP
// Make a viewangle int so we can render things based on mouselook
if (player == &players[consoleplayer])
viewangle = localaiming;
else if (splitscreen && player == &players[secondarydisplayplayer])
viewangle = localaiming2;
else if (splitscreen > 1 && player == &players[thirddisplayplayer])
viewangle = localaiming3;
else if (splitscreen > 2 && player == &players[fourthdisplayplayer])
viewangle = localaiming4;
viewangle = localaiming[0];
else if (splitscreen && player == &players[displayplayers[1]])
viewangle = localaiming[1];
else if (splitscreen > 1 && player == &players[displayplayers[2]])
viewangle = localaiming[2];
else if (splitscreen > 2 && player == &players[displayplayers[3]])
viewangle = localaiming[3];
// Handle stuff when you are looking farther up or down.
if ((aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT))
{
dup_viewangle += ANGLE_90;
HWR_ClearClipSegs();
HWR_RenderBSPNode((INT32)numnodes-1, ssplayer); //left
HWR_RenderBSPNode((INT32)numnodes-1); //left
dup_viewangle += ANGLE_90;
if (((INT32)aimingangle > ANGLE_45 || (INT32)aimingangle<-ANGLE_45))
{
HWR_ClearClipSegs();
HWR_RenderBSPNode((INT32)numnodes-1, ssplayer); //back
HWR_RenderBSPNode((INT32)numnodes-1); //back
}
dup_viewangle += ANGLE_90;
HWR_ClearClipSegs();
HWR_RenderBSPNode((INT32)numnodes-1, ssplayer); //right
HWR_RenderBSPNode((INT32)numnodes-1); //right
dup_viewangle += ANGLE_90;
}
@ -6149,38 +6124,13 @@ if (0)
void HWR_RenderPlayerView(INT32 viewnumber, player_t *player)
{
const float fpov = FIXED_TO_FLOAT(cv_fov.value+player->fovadd);
postimg_t *type;
UINT8 ssplayer = 0;
postimg_t *type = &postimgtype[viewnumber];
const boolean skybox = (skyboxmo[0] && cv_skybox.value); // True if there's a skybox object and skyboxes are on
FRGBAFloat ClearColor;
if (splitscreen)
{
if (player == &players[secondarydisplayplayer])
{
type = &postimgtype2;
ssplayer = 2;
}
else if (splitscreen > 1 && player == &players[thirddisplayplayer])
{
type = &postimgtype3;
ssplayer = 3;
}
else if (splitscreen > 2 && player == &players[fourthdisplayplayer])
{
type = &postimgtype4;
ssplayer = 4;
}
else
{
type = &postimgtype;
ssplayer = 1;
}
}
else
type = &postimgtype;
type = &postimgtype[viewnumber];
ClearColor.red = 0.0f;
ClearColor.green = 0.0f;
@ -6315,36 +6265,36 @@ if (0)
validcount++;
HWR_RenderBSPNode((INT32)numnodes-1, ssplayer);
HWR_RenderBSPNode((INT32)numnodes-1);
#ifndef NEWCLIP
// Make a viewangle int so we can render things based on mouselook
if (player == &players[consoleplayer])
viewangle = localaiming;
else if (splitscreen && player == &players[secondarydisplayplayer])
viewangle = localaiming2;
else if (splitscreen > 1 && player == &players[thirddisplayplayer])
viewangle = localaiming3;
else if (splitscreen > 2 && player == &players[fourthdisplayplayer])
viewangle = localaiming4;
viewangle = localaiming[0];
else if (splitscreen && player == &players[displayplayers[1]])
viewangle = localaiming[1];
else if (splitscreen > 1 && player == &players[displayplayers[2]])
viewangle = localaiming[2];
else if (splitscreen > 2 && player == &players[displayplayers[3]])
viewangle = localaiming[3];
// Handle stuff when you are looking farther up or down.
if ((aimingangle || cv_fov.value+player->fovadd > 90*FRACUNIT))
{
dup_viewangle += ANGLE_90;
HWR_ClearClipSegs();
HWR_RenderBSPNode((INT32)numnodes-1, ssplayer); //left
HWR_RenderBSPNode((INT32)numnodes-1); //left
dup_viewangle += ANGLE_90;
if (((INT32)aimingangle > ANGLE_45 || (INT32)aimingangle<-ANGLE_45))
{
HWR_ClearClipSegs();
HWR_RenderBSPNode((INT32)numnodes-1, ssplayer); //back
HWR_RenderBSPNode((INT32)numnodes-1); //back
}
dup_viewangle += ANGLE_90;
HWR_ClearClipSegs();
HWR_RenderBSPNode((INT32)numnodes-1, ssplayer); //right
HWR_RenderBSPNode((INT32)numnodes-1); //right
dup_viewangle += ANGLE_90;
}
@ -6795,11 +6745,6 @@ static void HWR_RenderWall(wallVert3D *wallVerts, FSurfaceInfo *pSurf, FBITFIE
#endif
}
void HWR_SetPaletteColor(INT32 palcolor)
{
HWD.pfnSetSpecialState(HWD_SET_PALETTECOLOR, palcolor);
}
INT32 HWR_GetTextureUsed(void)
{
return HWD.pfnGetTextureUsed();
@ -6807,16 +6752,17 @@ INT32 HWR_GetTextureUsed(void)
void HWR_DoPostProcessor(player_t *player)
{
postimg_t *type;
postimg_t *type = &postimgtype[0];
UINT8 i;
if (splitscreen > 2 && player == &players[fourthdisplayplayer])
type = &postimgtype4;
else if (splitscreen > 1 && player == &players[thirddisplayplayer])
type = &postimgtype3;
else if (splitscreen && player == &players[secondarydisplayplayer])
type = &postimgtype2;
else
type = &postimgtype;
for (i = splitscreen; i > 0; i--)
{
if (player == &players[displayplayers[i]])
{
type = &postimgtype[i];
break;
}
}
// Armageddon Blast Flash!
// Could this even be considered postprocessor?
@ -6850,7 +6796,6 @@ void HWR_DoPostProcessor(player_t *player)
if (splitscreen) // Not supported in splitscreen - someone want to add support?
return;
#ifdef SHUFFLE
// Drunken vision! WooOOooo~
if (*type == postimg_water || *type == postimg_heat)
{
@ -6893,7 +6838,6 @@ void HWR_DoPostProcessor(player_t *player)
HWD.pfnMakeScreenTexture();
}
// Flipping of the screen isn't done here anymore
#endif // SHUFFLE
}
void HWR_StartScreenWipe(void)
@ -6940,7 +6884,7 @@ void HWR_DoWipe(UINT8 wipenum, UINT8 scrnnum)
HWR_GetFadeMask(lumpnum);
HWD.pfnDoScreenWipe(HWRWipeCounter); // Still send in wipecounter since old stuff might not support multitexturing
HWD.pfnDoScreenWipe();
HWRWipeCounter += 0.05f; // increase opacity of end screen

View File

@ -58,7 +58,6 @@ void HWR_AddCommands(void);
void HWR_CorrectSWTricks(void);
void transform(float *cx, float *cy, float *cz);
FBITFIELD HWR_TranstableToAlpha(INT32 transtablenum, FSurfaceInfo *pSurf);
void HWR_SetPaletteColor(INT32 palcolor);
INT32 HWR_GetTextureUsed(void);
void HWR_DoPostProcessor(player_t *player);
void HWR_StartScreenWipe(void);
@ -80,7 +79,8 @@ extern consvar_t cv_grstaticlighting;
extern consvar_t cv_grcoronas;
extern consvar_t cv_grcoronasize;
#endif
extern consvar_t cv_grmd2;
extern consvar_t cv_grmdls;
extern consvar_t cv_grfallbackplayermodel;
extern consvar_t cv_grfog;
extern consvar_t cv_grfogcolor;
extern consvar_t cv_grfogdensity;
@ -91,7 +91,6 @@ extern consvar_t cv_grgammablue;
extern consvar_t cv_grfiltermode;
extern consvar_t cv_granisotropicmode;
extern consvar_t cv_grcorrecttricks;
extern consvar_t cv_voodoocompatibility;
extern consvar_t cv_grfovchange;
extern consvar_t cv_grsolvetjoin;

View File

@ -43,6 +43,7 @@
#include "../r_draw.h"
#include "../p_tick.h"
#include "../k_kart.h" // colortranslations
#include "hw_model.h"
#include "hw_main.h"
#include "../v_video.h"
@ -75,172 +76,6 @@
#include "errno.h"
#endif
#define NUMVERTEXNORMALS 162
float avertexnormals[NUMVERTEXNORMALS][3] = {
{-0.525731f, 0.000000f, 0.850651f},
{-0.442863f, 0.238856f, 0.864188f},
{-0.295242f, 0.000000f, 0.955423f},
{-0.309017f, 0.500000f, 0.809017f},
{-0.162460f, 0.262866f, 0.951056f},
{0.000000f, 0.000000f, 1.000000f},
{0.000000f, 0.850651f, 0.525731f},
{-0.147621f, 0.716567f, 0.681718f},
{0.147621f, 0.716567f, 0.681718f},
{0.000000f, 0.525731f, 0.850651f},
{0.309017f, 0.500000f, 0.809017f},
{0.525731f, 0.000000f, 0.850651f},
{0.295242f, 0.000000f, 0.955423f},
{0.442863f, 0.238856f, 0.864188f},
{0.162460f, 0.262866f, 0.951056f},
{-0.681718f, 0.147621f, 0.716567f},
{-0.809017f, 0.309017f, 0.500000f},
{-0.587785f, 0.425325f, 0.688191f},
{-0.850651f, 0.525731f, 0.000000f},
{-0.864188f, 0.442863f, 0.238856f},
{-0.716567f, 0.681718f, 0.147621f},
{-0.688191f, 0.587785f, 0.425325f},
{-0.500000f, 0.809017f, 0.309017f},
{-0.238856f, 0.864188f, 0.442863f},
{-0.425325f, 0.688191f, 0.587785f},
{-0.716567f, 0.681718f, -0.147621f},
{-0.500000f, 0.809017f, -0.309017f},
{-0.525731f, 0.850651f, 0.000000f},
{0.000000f, 0.850651f, -0.525731f},
{-0.238856f, 0.864188f, -0.442863f},
{0.000000f, 0.955423f, -0.295242f},
{-0.262866f, 0.951056f, -0.162460f},
{0.000000f, 1.000000f, 0.000000f},
{0.000000f, 0.955423f, 0.295242f},
{-0.262866f, 0.951056f, 0.162460f},
{0.238856f, 0.864188f, 0.442863f},
{0.262866f, 0.951056f, 0.162460f},
{0.500000f, 0.809017f, 0.309017f},
{0.238856f, 0.864188f, -0.442863f},
{0.262866f, 0.951056f, -0.162460f},
{0.500000f, 0.809017f, -0.309017f},
{0.850651f, 0.525731f, 0.000000f},
{0.716567f, 0.681718f, 0.147621f},
{0.716567f, 0.681718f, -0.147621f},
{0.525731f, 0.850651f, 0.000000f},
{0.425325f, 0.688191f, 0.587785f},
{0.864188f, 0.442863f, 0.238856f},
{0.688191f, 0.587785f, 0.425325f},
{0.809017f, 0.309017f, 0.500000f},
{0.681718f, 0.147621f, 0.716567f},
{0.587785f, 0.425325f, 0.688191f},
{0.955423f, 0.295242f, 0.000000f},
{1.000000f, 0.000000f, 0.000000f},
{0.951056f, 0.162460f, 0.262866f},
{0.850651f, -0.525731f, 0.000000f},
{0.955423f, -0.295242f, 0.000000f},
{0.864188f, -0.442863f, 0.238856f},
{0.951056f, -0.162460f, 0.262866f},
{0.809017f, -0.309017f, 0.500000f},
{0.681718f, -0.147621f, 0.716567f},
{0.850651f, 0.000000f, 0.525731f},
{0.864188f, 0.442863f, -0.238856f},
{0.809017f, 0.309017f, -0.500000f},
{0.951056f, 0.162460f, -0.262866f},
{0.525731f, 0.000000f, -0.850651f},
{0.681718f, 0.147621f, -0.716567f},
{0.681718f, -0.147621f, -0.716567f},
{0.850651f, 0.000000f, -0.525731f},
{0.809017f, -0.309017f, -0.500000f},
{0.864188f, -0.442863f, -0.238856f},
{0.951056f, -0.162460f, -0.262866f},
{0.147621f, 0.716567f, -0.681718f},
{0.309017f, 0.500000f, -0.809017f},
{0.425325f, 0.688191f, -0.587785f},
{0.442863f, 0.238856f, -0.864188f},
{0.587785f, 0.425325f, -0.688191f},
{0.688191f, 0.587785f, -0.425325f},
{-0.147621f, 0.716567f, -0.681718f},
{-0.309017f, 0.500000f, -0.809017f},
{0.000000f, 0.525731f, -0.850651f},
{-0.525731f, 0.000000f, -0.850651f},
{-0.442863f, 0.238856f, -0.864188f},
{-0.295242f, 0.000000f, -0.955423f},
{-0.162460f, 0.262866f, -0.951056f},
{0.000000f, 0.000000f, -1.000000f},
{0.295242f, 0.000000f, -0.955423f},
{0.162460f, 0.262866f, -0.951056f},
{-0.442863f, -0.238856f, -0.864188f},
{-0.309017f, -0.500000f, -0.809017f},
{-0.162460f, -0.262866f, -0.951056f},
{0.000000f, -0.850651f, -0.525731f},
{-0.147621f, -0.716567f, -0.681718f},
{0.147621f, -0.716567f, -0.681718f},
{0.000000f, -0.525731f, -0.850651f},
{0.309017f, -0.500000f, -0.809017f},
{0.442863f, -0.238856f, -0.864188f},
{0.162460f, -0.262866f, -0.951056f},
{0.238856f, -0.864188f, -0.442863f},
{0.500000f, -0.809017f, -0.309017f},
{0.425325f, -0.688191f, -0.587785f},
{0.716567f, -0.681718f, -0.147621f},
{0.688191f, -0.587785f, -0.425325f},
{0.587785f, -0.425325f, -0.688191f},
{0.000000f, -0.955423f, -0.295242f},
{0.000000f, -1.000000f, 0.000000f},
{0.262866f, -0.951056f, -0.162460f},
{0.000000f, -0.850651f, 0.525731f},
{0.000000f, -0.955423f, 0.295242f},
{0.238856f, -0.864188f, 0.442863f},
{0.262866f, -0.951056f, 0.162460f},
{0.500000f, -0.809017f, 0.309017f},
{0.716567f, -0.681718f, 0.147621f},
{0.525731f, -0.850651f, 0.000000f},
{-0.238856f, -0.864188f, -0.442863f},
{-0.500000f, -0.809017f, -0.309017f},
{-0.262866f, -0.951056f, -0.162460f},
{-0.850651f, -0.525731f, 0.000000f},
{-0.716567f, -0.681718f, -0.147621f},
{-0.716567f, -0.681718f, 0.147621f},
{-0.525731f, -0.850651f, 0.000000f},
{-0.500000f, -0.809017f, 0.309017f},
{-0.238856f, -0.864188f, 0.442863f},
{-0.262866f, -0.951056f, 0.162460f},
{-0.864188f, -0.442863f, 0.238856f},
{-0.809017f, -0.309017f, 0.500000f},
{-0.688191f, -0.587785f, 0.425325f},
{-0.681718f, -0.147621f, 0.716567f},
{-0.442863f, -0.238856f, 0.864188f},
{-0.587785f, -0.425325f, 0.688191f},
{-0.309017f, -0.500000f, 0.809017f},
{-0.147621f, -0.716567f, 0.681718f},
{-0.425325f, -0.688191f, 0.587785f},
{-0.162460f, -0.262866f, 0.951056f},
{0.442863f, -0.238856f, 0.864188f},
{0.162460f, -0.262866f, 0.951056f},
{0.309017f, -0.500000f, 0.809017f},
{0.147621f, -0.716567f, 0.681718f},
{0.000000f, -0.525731f, 0.850651f},
{0.425325f, -0.688191f, 0.587785f},
{0.587785f, -0.425325f, 0.688191f},
{0.688191f, -0.587785f, 0.425325f},
{-0.955423f, 0.295242f, 0.000000f},
{-0.951056f, 0.162460f, 0.262866f},
{-1.000000f, 0.000000f, 0.000000f},
{-0.850651f, 0.000000f, 0.525731f},
{-0.955423f, -0.295242f, 0.000000f},
{-0.951056f, -0.162460f, 0.262866f},
{-0.864188f, 0.442863f, -0.238856f},
{-0.951056f, 0.162460f, -0.262866f},
{-0.809017f, 0.309017f, -0.500000f},
{-0.864188f, -0.442863f, -0.238856f},
{-0.951056f, -0.162460f, -0.262866f},
{-0.809017f, -0.309017f, -0.500000f},
{-0.681718f, 0.147621f, -0.716567f},
{-0.681718f, -0.147621f, -0.716567f},
{-0.850651f, 0.000000f, -0.525731f},
{-0.688191f, 0.587785f, -0.425325f},
{-0.587785f, 0.425325f, -0.688191f},
{-0.425325f, 0.688191f, -0.587785f},
{-0.425325f, -0.688191f, -0.587785f},
{-0.587785f, -0.425325f, -0.688191f},
{-0.688191f, -0.587785f, -0.425325f},
};
md2_t md2_models[NUMSPRITES];
md2_t md2_playermodels[MAXSKINS];
@ -248,198 +83,29 @@ md2_t md2_playermodels[MAXSKINS];
/*
* free model
*/
static void md2_freeModel (md2_model_t *model)
#if 0
static void md2_freeModel (model_t *model)
{
if (model)
{
if (model->skins)
free(model->skins);
if (model->texCoords)
free(model->texCoords);
if (model->triangles)
free(model->triangles);
if (model->frames)
{
size_t i;
for (i = 0; i < model->header.numFrames; i++)
{
if (model->frames[i].vertices)
free(model->frames[i].vertices);
}
free(model->frames);
}
if (model->glCommandBuffer)
free(model->glCommandBuffer);
free(model);
}
UnloadModel(model);
}
#endif
//
// load model
//
// Hurdler: the current path is the Legacy.exe path
static md2_model_t *md2_readModel(const char *filename)
static model_t *md2_readModel(const char *filename)
{
FILE *file;
md2_model_t *model;
UINT8 buffer[MD2_MAX_FRAMESIZE];
size_t i;
model = calloc(1, sizeof (*model));
if (model == NULL)
return 0;
//Filename checking fixed ~Monster Iestyn and Golden
file = fopen(va("%s"PATHSEP"%s", srb2home, filename), "rb");
if (!file)
{
file = fopen(va("%s"PATHSEP"%s", srb2path, filename), "rb");
if (!file)
{
free(model);
return 0;
}
}
// initialize model and read header
if (fread(&model->header, sizeof (model->header), 1, file) != 1
|| model->header.magic != MD2_IDENT
|| model->header.version != MD2_VERSION)
{
fclose(file);
free(model);
return 0;
}
model->header.numSkins = 1;
#define MD2LIMITCHECK(field, max, msgname) \
if (field > max) \
{ \
CONS_Alert(CONS_ERROR, "md2_readModel: %s has too many " msgname " (# found: %d, maximum: %d)\n", filename, field, max); \
md2_freeModel (model); \
fclose(file); \
return 0; \
}
// Uncomment if these are actually needed
// MD2LIMITCHECK(model->header.numSkins, MD2_MAX_SKINS, "skins")
// MD2LIMITCHECK(model->header.numTexCoords, MD2_MAX_TEXCOORDS, "texture coordinates")
MD2LIMITCHECK(model->header.numTriangles, MD2_MAX_TRIANGLES, "triangles")
MD2LIMITCHECK(model->header.numFrames, MD2_MAX_FRAMES, "frames")
MD2LIMITCHECK(model->header.numVertices, MD2_MAX_VERTICES, "vertices")
#undef MD2LIMITCHECK
// read skins
fseek(file, model->header.offsetSkins, SEEK_SET);
if (model->header.numSkins > 0)
{
model->skins = calloc(sizeof (md2_skin_t), model->header.numSkins);
if (!model->skins || model->header.numSkins !=
fread(model->skins, sizeof (md2_skin_t), model->header.numSkins, file))
{
md2_freeModel (model);
fclose(file);
return 0;
}
}
// read texture coordinates
fseek(file, model->header.offsetTexCoords, SEEK_SET);
if (model->header.numTexCoords > 0)
{
model->texCoords = calloc(sizeof (md2_textureCoordinate_t), model->header.numTexCoords);
if (!model->texCoords || model->header.numTexCoords !=
fread(model->texCoords, sizeof (md2_textureCoordinate_t), model->header.numTexCoords, file))
{
md2_freeModel (model);
fclose(file);
return 0;
}
}
// read triangles
fseek(file, model->header.offsetTriangles, SEEK_SET);
if (model->header.numTriangles > 0)
{
model->triangles = calloc(sizeof (md2_triangle_t), model->header.numTriangles);
if (!model->triangles || model->header.numTriangles !=
fread(model->triangles, sizeof (md2_triangle_t), model->header.numTriangles, file))
{
md2_freeModel (model);
fclose(file);
return 0;
}
}
// read alias frames
fseek(file, model->header.offsetFrames, SEEK_SET);
if (model->header.numFrames > 0)
{
model->frames = calloc(sizeof (md2_frame_t), model->header.numFrames);
if (!model->frames)
{
md2_freeModel (model);
fclose(file);
return 0;
}
for (i = 0; i < model->header.numFrames; i++)
{
md2_alias_frame_t *frame = (md2_alias_frame_t *)(void *)buffer;
size_t j;
model->frames[i].vertices = calloc(sizeof (md2_triangleVertex_t), model->header.numVertices);
if (!model->frames[i].vertices || model->header.frameSize !=
fread(frame, 1, model->header.frameSize, file))
{
md2_freeModel (model);
fclose(file);
return 0;
}
strcpy(model->frames[i].name, frame->name);
for (j = 0; j < model->header.numVertices; j++)
{
model->frames[i].vertices[j].vertex[0] = (float) ((INT32) frame->alias_vertices[j].vertex[0]) * frame->scale[0] + frame->translate[0];
model->frames[i].vertices[j].vertex[2] = -1* ((float) ((INT32) frame->alias_vertices[j].vertex[1]) * frame->scale[1] + frame->translate[1]);
model->frames[i].vertices[j].vertex[1] = (float) ((INT32) frame->alias_vertices[j].vertex[2]) * frame->scale[2] + frame->translate[2];
model->frames[i].vertices[j].normal[0] = avertexnormals[frame->alias_vertices[j].lightNormalIndex][0];
model->frames[i].vertices[j].normal[1] = avertexnormals[frame->alias_vertices[j].lightNormalIndex][1];
model->frames[i].vertices[j].normal[2] = avertexnormals[frame->alias_vertices[j].lightNormalIndex][2];
}
}
}
// read gl commands
fseek(file, model->header.offsetGlCommands, SEEK_SET);
if (model->header.numGlCommands)
{
model->glCommandBuffer = calloc(sizeof (INT32), model->header.numGlCommands);
if (!model->glCommandBuffer || model->header.numGlCommands !=
fread(model->glCommandBuffer, sizeof (INT32), model->header.numGlCommands, file))
{
md2_freeModel (model);
fclose(file);
return 0;
}
}
fclose(file);
return model;
if (FIL_FileExists(va("%s"PATHSEP"%s", srb2home, filename)))
return LoadModel(va("%s"PATHSEP"%s", srb2home, filename), PU_STATIC);
else if (FIL_FileExists(va("%s"PATHSEP"%s", srb2path, filename)))
return LoadModel(va("%s"PATHSEP"%s", srb2path, filename), PU_STATIC);
return NULL;
}
static inline void md2_printModelInfo (md2_model_t *model)
static inline void md2_printModelInfo (model_t *model)
{
#if 0
INT32 i;
@ -498,13 +164,13 @@ static GrTextureFormat_t PNG_Load(const char *filename, int *w, int *h, GLPatch_
#endif
volatile png_FILE_p png_FILE;
//Filename checking fixed ~Monster Iestyn and Golden
char *pngfilename = va("%s"PATHSEP"md2"PATHSEP"%s", srb2home, filename);
char *pngfilename = va("%s"PATHSEP"mdls"PATHSEP"%s", srb2home, filename);
FIL_ForceExtension(pngfilename, ".png");
png_FILE = fopen(pngfilename, "rb");
if (!png_FILE)
{
pngfilename = va("%s"PATHSEP"md2"PATHSEP"%s", srb2path, filename);
pngfilename = va("%s"PATHSEP"mdls"PATHSEP"%s", srb2path, filename);
FIL_ForceExtension(pngfilename, ".png");
png_FILE = fopen(pngfilename, "rb");
//CONS_Debug(DBG_RENDER, "M_SavePNG: Error on opening %s for loading\n", filename);
@ -631,13 +297,13 @@ static GrTextureFormat_t PCX_Load(const char *filename, int *w, int *h,
INT32 ch, rep;
FILE *file;
//Filename checking fixed ~Monster Iestyn and Golden
char *pcxfilename = va("%s"PATHSEP"md2"PATHSEP"%s", srb2home, filename);
char *pcxfilename = va("%s"PATHSEP"mdls"PATHSEP"%s", srb2home, filename);
FIL_ForceExtension(pcxfilename, ".pcx");
file = fopen(pcxfilename, "rb");
if (!file)
{
pcxfilename = va("%s"PATHSEP"md2"PATHSEP"%s", srb2path, filename);
pcxfilename = va("%s"PATHSEP"mdls"PATHSEP"%s", srb2path, filename);
FIL_ForceExtension(pcxfilename, ".pcx");
file = fopen(pcxfilename, "rb");
if (!file)
@ -826,16 +492,16 @@ void HWR_InitMD2(void)
md2_models[i].error = false;
}
// read the md2.dat file
// read the mdls.dat file
//Filename checking fixed ~Monster Iestyn and Golden
f = fopen(va("%s"PATHSEP"%s", srb2home, "kmd2.dat"), "rt");
f = fopen(va("%s"PATHSEP"%s", srb2home, "mdls.dat"), "rt");
if (!f)
{
f = fopen(va("%s"PATHSEP"%s", srb2path, "kmd2.dat"), "rt");
f = fopen(va("%s"PATHSEP"%s", srb2path, "mdls.dat"), "rt");
if (!f)
{
CONS_Printf("%s %s\n", M_GetText("Error while loading kmd2.dat:"), strerror(errno));
CONS_Printf("%s %s\n", M_GetText("Error while loading mdls.dat:"), strerror(errno));
nomd2s = true;
return;
}
@ -844,7 +510,7 @@ void HWR_InitMD2(void)
{
/*if (stricmp(name, "PLAY") == 0)
{
CONS_Printf("MD2 for sprite PLAY detected in kmd2.dat, use a player skin instead!\n");
CONS_Printf("MD2 for sprite PLAY detected in mdls.dat, use a player skin instead!\n");
continue;
}*/
// 8/1/19: Allow PLAY to load for default MD2.
@ -879,7 +545,7 @@ void HWR_InitMD2(void)
}
}
// no sprite/player skin name found?!?
CONS_Printf("Unknown sprite/player skin %s detected in kmd2.dat\n", name);
CONS_Printf("Unknown sprite/player skin %s detected in mdls.dat\n", name);
md2found:
// move on to next line...
continue;
@ -898,16 +564,16 @@ void HWR_AddPlayerMD2(int skin) // For MD2's that were added after startup
CONS_Printf("AddPlayerMD2()...\n");
// read the md2.dat file
// read the mdls.dat file
//Filename checking fixed ~Monster Iestyn and Golden
f = fopen(va("%s"PATHSEP"%s", srb2home, "kmd2.dat"), "rt");
f = fopen(va("%s"PATHSEP"%s", srb2home, "mdls.dat"), "rt");
if (!f)
{
f = fopen(va("%s"PATHSEP"%s", srb2path, "kmd2.dat"), "rt");
f = fopen(va("%s"PATHSEP"%s", srb2path, "mdls.dat"), "rt");
if (!f)
{
CONS_Printf("%s %s\n", M_GetText("Error while loading kmd2.dat:"), strerror(errno));
CONS_Printf("%s %s\n", M_GetText("Error while loading mdls.dat:"), strerror(errno));
nomd2s = true;
return;
}
@ -937,7 +603,7 @@ playermd2found:
void HWR_AddSpriteMD2(size_t spritenum) // For MD2s that were added after startup
{
FILE *f;
// name[18] is used to check for names in the kmd2.dat file that match with sprites or player skins
// name[18] is used to check for names in the mdls.dat file that match with sprites or player skins
// sprite names are always 4 characters long, and names is for player skins can be up to 19 characters long
char name[18], filename[32];
float scale, offset;
@ -950,20 +616,20 @@ void HWR_AddSpriteMD2(size_t spritenum) // For MD2s that were added after startu
// Read the md2.dat file
//Filename checking fixed ~Monster Iestyn and Golden
f = fopen(va("%s"PATHSEP"%s", srb2home, "kmd2.dat"), "rt");
f = fopen(va("%s"PATHSEP"%s", srb2home, "mdls.dat"), "rt");
if (!f)
{
f = fopen(va("%s"PATHSEP"%s", srb2path, "kmd2.dat"), "rt");
f = fopen(va("%s"PATHSEP"%s", srb2path, "mdls.dat"), "rt");
if (!f)
{
CONS_Printf("%s %s\n", M_GetText("Error while loading kmd2.dat:"), strerror(errno));
CONS_Printf("%s %s\n", M_GetText("Error while loading mdls.dat:"), strerror(errno));
nomd2s = true;
return;
}
}
// Check for any MD2s that match the names of player skins!
// Check for any MD2s that match the names of sprite names!
while (fscanf(f, "%19s %31s %f %f", name, filename, &scale, &offset) == 4)
{
if (stricmp(name, sprnames[spritenum]) == 0)
@ -1195,12 +861,13 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
FSurfaceInfo Surf;
char filename[64];
INT32 frame;
INT32 frame = 0;
INT32 nextFrame = -1;
FTransform p;
md2_t *md2;
UINT8 color[4];
if (!cv_grmd2.value)
if (!cv_grmdls.value)
return;
if (spr->precip)
@ -1248,10 +915,9 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
// Look at HWR_ProjectSprite for more
{
GLPatch_t *gpatch;
INT32 *buff;
INT32 durs = spr->mobj->state->tics;
INT32 tics = spr->mobj->tics;
md2_frame_t *curr, *next = NULL;
//mdlframe_t *next = NULL;
const UINT8 flip = (UINT8)((spr->mobj->eflags & MFE_VERTICALFLIP) == MFE_VERTICALFLIP);
spritedef_t *sprdef;
spriteframe_t *sprframe;
@ -1285,13 +951,14 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
return; // we already failed loading this before :(
if (!md2->model)
{
CONS_Debug(DBG_RENDER, "Loading MD2... (%s, %s)", sprnames[spr->mobj->sprite], md2->filename);
sprintf(filename, "md2/%s", md2->filename);
CONS_Debug(DBG_RENDER, "Loading model... (%s, %s)", sprnames[spr->mobj->sprite], md2->filename);
sprintf(filename, "mdls/%s", md2->filename);
md2->model = md2_readModel(filename);
if (md2->model)
{
md2_printModelInfo(md2->model);
HWD.pfnCreateModelVBOs(md2->model);
}
else
{
@ -1364,27 +1031,27 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
}
//FIXME: this is not yet correct
frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->header.numFrames;
buff = md2->model->glCommandBuffer;
curr = &md2->model->frames[frame];
#if 0
if (cv_grmd2.value == 1 && tics <= durs)
frame = (spr->mobj->frame & FF_FRAMEMASK) % md2->model->meshes[0].numFrames;
#ifdef USE_MODEL_NEXTFRAME
if (cv_grmdls.value == 1 && tics <= durs)
{
// frames are handled differently for states with FF_ANIMATE, so get the next frame differently for the interpolation
if (spr->mobj->frame & FF_ANIMATE)
{
UINT32 nextframe = (spr->mobj->frame & FF_FRAMEMASK) + 1;
if (nextframe >= (UINT32)spr->mobj->state->var1)
nextframe = (spr->mobj->state->frame & FF_FRAMEMASK);
nextframe %= md2->model->header.numFrames;
next = &md2->model->frames[nextframe];
nextFrame = (spr->mobj->frame & FF_FRAMEMASK) + 1;
if (nextFrame >= spr->mobj->state->var1)
nextFrame = (spr->mobj->state->frame & FF_FRAMEMASK);
nextFrame %= md2->model->meshes[0].numFrames;
//next = &md2->model->meshes[0].frames[nextFrame];
}
else
{
if (spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite != SPR_NULL)
if (spr->mobj->state->nextstate != S_NULL && states[spr->mobj->state->nextstate].sprite != SPR_NULL
&& !(spr->mobj->player && (spr->mobj->state->nextstate == S_PLAY_TAP1 || spr->mobj->state->nextstate == S_PLAY_TAP2) && spr->mobj->state == &states[S_PLAY_STND]))
{
const UINT32 nextframe = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->header.numFrames;
next = &md2->model->frames[nextframe];
nextFrame = (states[spr->mobj->state->nextstate].frame & FF_FRAMEMASK) % md2->model->meshes[0].numFrames;
//next = &md2->model->meshes[0].frames[nextFrame];
}
}
}
@ -1421,6 +1088,8 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
p.angley = FIXED_TO_FLOAT(anglef);
}
p.anglex = 0.0f;
#ifdef USE_FTRANSFORM_ANGLEZ
// Slope rotation from Kart
p.anglez = 0.0f;
if (spr->mobj->standingslope)
{
@ -1432,7 +1101,7 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
tempangle = -AngleFixed(R_PointToAngle2(0, 0, tempz, tempy));
p.anglex = FIXED_TO_FLOAT(tempangle);
}
#endif
color[0] = Surf.FlatColor.s.red;
color[1] = Surf.FlatColor.s.green;
@ -1443,9 +1112,11 @@ void HWR_DrawMD2(gr_vissprite_t *spr)
finalscale *= FIXED_TO_FLOAT(spr->mobj->scale);
p.flip = atransform.flip;
p.mirror = atransform.mirror;
#ifdef USE_FTRANSFORM_MIRROR
p.mirror = atransform.mirror; // from Kart
#endif
HWD.pfnDrawMD2i(buff, curr, durs, tics, next, &p, finalscale, flip, color);
HWD.pfnDrawModel(md2->model, frame, durs, tics, nextFrame, &p, finalscale, flip, color);
}
}

View File

@ -22,97 +22,7 @@
#define _HW_MD2_H_
#include "hw_glob.h"
// magic number "IDP2" or 844121161
#define MD2_IDENT (INT32)(('2' << 24) + ('P' << 16) + ('D' << 8) + 'I')
// model version
#define MD2_VERSION 8
#define MD2_MAX_TRIANGLES 16384
#define MD2_MAX_VERTICES 4096
#define MD2_MAX_TEXCOORDS 4096
#define MD2_MAX_FRAMES 512
#define MD2_MAX_SKINS 32
#define MD2_MAX_FRAMESIZE (MD2_MAX_VERTICES * 4 + 128)
#if defined(_MSC_VER)
#pragma pack(1)
#endif
typedef struct
{
UINT32 magic;
UINT32 version;
UINT32 skinWidth;
UINT32 skinHeight;
UINT32 frameSize;
UINT32 numSkins;
UINT32 numVertices;
UINT32 numTexCoords;
UINT32 numTriangles;
UINT32 numGlCommands;
UINT32 numFrames;
UINT32 offsetSkins;
UINT32 offsetTexCoords;
UINT32 offsetTriangles;
UINT32 offsetFrames;
UINT32 offsetGlCommands;
UINT32 offsetEnd;
} ATTRPACK md2_header_t; //NOTE: each of md2_header's members are 4 unsigned bytes
typedef struct
{
UINT8 vertex[3];
UINT8 lightNormalIndex;
} ATTRPACK md2_alias_triangleVertex_t;
typedef struct
{
float vertex[3];
float normal[3];
} ATTRPACK md2_triangleVertex_t;
typedef struct
{
INT16 vertexIndices[3];
INT16 textureIndices[3];
} ATTRPACK md2_triangle_t;
typedef struct
{
INT16 s, t;
} ATTRPACK md2_textureCoordinate_t;
typedef struct
{
float scale[3];
float translate[3];
char name[16];
md2_alias_triangleVertex_t alias_vertices[1];
} ATTRPACK md2_alias_frame_t;
typedef struct
{
char name[16];
md2_triangleVertex_t *vertices;
} ATTRPACK md2_frame_t;
typedef char md2_skin_t[64];
typedef struct
{
float s, t;
INT32 vertexIndex;
} ATTRPACK md2_glCommandVertex_t;
typedef struct
{
md2_header_t header;
md2_skin_t *skins;
md2_textureCoordinate_t *texCoords;
md2_triangle_t *triangles;
md2_frame_t *frames;
INT32 *glCommandBuffer;
} ATTRPACK md2_model_t;
#include "hw_model.h"
#if defined(_MSC_VER)
#pragma pack()
@ -123,7 +33,7 @@ typedef struct
char filename[32];
float scale;
float offset;
md2_model_t *model;
model_t *model;
void *grpatch;
void *blendgrpatch;
boolean notfound;

564
src/hardware/hw_md2load.c Normal file
View File

@ -0,0 +1,564 @@
/*
From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com )
An experimental work-in-progress.
Donated to Sonic Team Junior and adapted to work with
Sonic Robo Blast 2. The license of this code matches whatever
the licensing is for Sonic Robo Blast 2.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "../doomdef.h"
#include "hw_md2load.h"
#include "hw_model.h"
#include "../z_zone.h"
#define NUMVERTEXNORMALS 162
// Quake 2 normals are indexed. Use avertexnormals[normalindex][x/y/z] and
// you'll have your normals.
float avertexnormals[NUMVERTEXNORMALS][3] = {
{-0.525731f, 0.000000f, 0.850651f},
{-0.442863f, 0.238856f, 0.864188f},
{-0.295242f, 0.000000f, 0.955423f},
{-0.309017f, 0.500000f, 0.809017f},
{-0.162460f, 0.262866f, 0.951056f},
{0.000000f, 0.000000f, 1.000000f},
{0.000000f, 0.850651f, 0.525731f},
{-0.147621f, 0.716567f, 0.681718f},
{0.147621f, 0.716567f, 0.681718f},
{0.000000f, 0.525731f, 0.850651f},
{0.309017f, 0.500000f, 0.809017f},
{0.525731f, 0.000000f, 0.850651f},
{0.295242f, 0.000000f, 0.955423f},
{0.442863f, 0.238856f, 0.864188f},
{0.162460f, 0.262866f, 0.951056f},
{-0.681718f, 0.147621f, 0.716567f},
{-0.809017f, 0.309017f, 0.500000f},
{-0.587785f, 0.425325f, 0.688191f},
{-0.850651f, 0.525731f, 0.000000f},
{-0.864188f, 0.442863f, 0.238856f},
{-0.716567f, 0.681718f, 0.147621f},
{-0.688191f, 0.587785f, 0.425325f},
{-0.500000f, 0.809017f, 0.309017f},
{-0.238856f, 0.864188f, 0.442863f},
{-0.425325f, 0.688191f, 0.587785f},
{-0.716567f, 0.681718f, -0.147621f},
{-0.500000f, 0.809017f, -0.309017f},
{-0.525731f, 0.850651f, 0.000000f},
{0.000000f, 0.850651f, -0.525731f},
{-0.238856f, 0.864188f, -0.442863f},
{0.000000f, 0.955423f, -0.295242f},
{-0.262866f, 0.951056f, -0.162460f},
{0.000000f, 1.000000f, 0.000000f},
{0.000000f, 0.955423f, 0.295242f},
{-0.262866f, 0.951056f, 0.162460f},
{0.238856f, 0.864188f, 0.442863f},
{0.262866f, 0.951056f, 0.162460f},
{0.500000f, 0.809017f, 0.309017f},
{0.238856f, 0.864188f, -0.442863f},
{0.262866f, 0.951056f, -0.162460f},
{0.500000f, 0.809017f, -0.309017f},
{0.850651f, 0.525731f, 0.000000f},
{0.716567f, 0.681718f, 0.147621f},
{0.716567f, 0.681718f, -0.147621f},
{0.525731f, 0.850651f, 0.000000f},
{0.425325f, 0.688191f, 0.587785f},
{0.864188f, 0.442863f, 0.238856f},
{0.688191f, 0.587785f, 0.425325f},
{0.809017f, 0.309017f, 0.500000f},
{0.681718f, 0.147621f, 0.716567f},
{0.587785f, 0.425325f, 0.688191f},
{0.955423f, 0.295242f, 0.000000f},
{1.000000f, 0.000000f, 0.000000f},
{0.951056f, 0.162460f, 0.262866f},
{0.850651f, -0.525731f, 0.000000f},
{0.955423f, -0.295242f, 0.000000f},
{0.864188f, -0.442863f, 0.238856f},
{0.951056f, -0.162460f, 0.262866f},
{0.809017f, -0.309017f, 0.500000f},
{0.681718f, -0.147621f, 0.716567f},
{0.850651f, 0.000000f, 0.525731f},
{0.864188f, 0.442863f, -0.238856f},
{0.809017f, 0.309017f, -0.500000f},
{0.951056f, 0.162460f, -0.262866f},
{0.525731f, 0.000000f, -0.850651f},
{0.681718f, 0.147621f, -0.716567f},
{0.681718f, -0.147621f, -0.716567f},
{0.850651f, 0.000000f, -0.525731f},
{0.809017f, -0.309017f, -0.500000f},
{0.864188f, -0.442863f, -0.238856f},
{0.951056f, -0.162460f, -0.262866f},
{0.147621f, 0.716567f, -0.681718f},
{0.309017f, 0.500000f, -0.809017f},
{0.425325f, 0.688191f, -0.587785f},
{0.442863f, 0.238856f, -0.864188f},
{0.587785f, 0.425325f, -0.688191f},
{0.688191f, 0.587785f, -0.425325f},
{-0.147621f, 0.716567f, -0.681718f},
{-0.309017f, 0.500000f, -0.809017f},
{0.000000f, 0.525731f, -0.850651f},
{-0.525731f, 0.000000f, -0.850651f},
{-0.442863f, 0.238856f, -0.864188f},
{-0.295242f, 0.000000f, -0.955423f},
{-0.162460f, 0.262866f, -0.951056f},
{0.000000f, 0.000000f, -1.000000f},
{0.295242f, 0.000000f, -0.955423f},
{0.162460f, 0.262866f, -0.951056f},
{-0.442863f, -0.238856f, -0.864188f},
{-0.309017f, -0.500000f, -0.809017f},
{-0.162460f, -0.262866f, -0.951056f},
{0.000000f, -0.850651f, -0.525731f},
{-0.147621f, -0.716567f, -0.681718f},
{0.147621f, -0.716567f, -0.681718f},
{0.000000f, -0.525731f, -0.850651f},
{0.309017f, -0.500000f, -0.809017f},
{0.442863f, -0.238856f, -0.864188f},
{0.162460f, -0.262866f, -0.951056f},
{0.238856f, -0.864188f, -0.442863f},
{0.500000f, -0.809017f, -0.309017f},
{0.425325f, -0.688191f, -0.587785f},
{0.716567f, -0.681718f, -0.147621f},
{0.688191f, -0.587785f, -0.425325f},
{0.587785f, -0.425325f, -0.688191f},
{0.000000f, -0.955423f, -0.295242f},
{0.000000f, -1.000000f, 0.000000f},
{0.262866f, -0.951056f, -0.162460f},
{0.000000f, -0.850651f, 0.525731f},
{0.000000f, -0.955423f, 0.295242f},
{0.238856f, -0.864188f, 0.442863f},
{0.262866f, -0.951056f, 0.162460f},
{0.500000f, -0.809017f, 0.309017f},
{0.716567f, -0.681718f, 0.147621f},
{0.525731f, -0.850651f, 0.000000f},
{-0.238856f, -0.864188f, -0.442863f},
{-0.500000f, -0.809017f, -0.309017f},
{-0.262866f, -0.951056f, -0.162460f},
{-0.850651f, -0.525731f, 0.000000f},
{-0.716567f, -0.681718f, -0.147621f},
{-0.716567f, -0.681718f, 0.147621f},
{-0.525731f, -0.850651f, 0.000000f},
{-0.500000f, -0.809017f, 0.309017f},
{-0.238856f, -0.864188f, 0.442863f},
{-0.262866f, -0.951056f, 0.162460f},
{-0.864188f, -0.442863f, 0.238856f},
{-0.809017f, -0.309017f, 0.500000f},
{-0.688191f, -0.587785f, 0.425325f},
{-0.681718f, -0.147621f, 0.716567f},
{-0.442863f, -0.238856f, 0.864188f},
{-0.587785f, -0.425325f, 0.688191f},
{-0.309017f, -0.500000f, 0.809017f},
{-0.147621f, -0.716567f, 0.681718f},
{-0.425325f, -0.688191f, 0.587785f},
{-0.162460f, -0.262866f, 0.951056f},
{0.442863f, -0.238856f, 0.864188f},
{0.162460f, -0.262866f, 0.951056f},
{0.309017f, -0.500000f, 0.809017f},
{0.147621f, -0.716567f, 0.681718f},
{0.000000f, -0.525731f, 0.850651f},
{0.425325f, -0.688191f, 0.587785f},
{0.587785f, -0.425325f, 0.688191f},
{0.688191f, -0.587785f, 0.425325f},
{-0.955423f, 0.295242f, 0.000000f},
{-0.951056f, 0.162460f, 0.262866f},
{-1.000000f, 0.000000f, 0.000000f},
{-0.850651f, 0.000000f, 0.525731f},
{-0.955423f, -0.295242f, 0.000000f},
{-0.951056f, -0.162460f, 0.262866f},
{-0.864188f, 0.442863f, -0.238856f},
{-0.951056f, 0.162460f, -0.262866f},
{-0.809017f, 0.309017f, -0.500000f},
{-0.864188f, -0.442863f, -0.238856f},
{-0.951056f, -0.162460f, -0.262866f},
{-0.809017f, -0.309017f, -0.500000f},
{-0.681718f, 0.147621f, -0.716567f},
{-0.681718f, -0.147621f, -0.716567f},
{-0.850651f, 0.000000f, -0.525731f},
{-0.688191f, 0.587785f, -0.425325f},
{-0.587785f, 0.425325f, -0.688191f},
{-0.425325f, 0.688191f, -0.587785f},
{-0.425325f, -0.688191f, -0.587785f},
{-0.587785f, -0.425325f, -0.688191f},
{-0.688191f, -0.587785f, -0.425325f},
};
typedef struct
{
int ident; // A "magic number" that's used to identify the .md2 file
int version; // The version of the file, always 8
int skinwidth; // Width of the skin(s) in pixels
int skinheight; // Height of the skin(s) in pixels
int framesize; // Size of each frame in bytes
int numSkins; // Number of skins with the model
int numXYZ; // Number of vertices in each frame
int numST; // Number of texture coordinates in each frame.
int numTris; // Number of triangles in each frame
int numGLcmds; // Number of dwords (4 bytes) in the gl command list.
int numFrames; // Number of frames
int offsetSkins; // Offset, in bytes from the start of the file, to the list of skin names.
int offsetST; // Offset, in bytes from the start of the file, to the list of texture coordinates
int offsetTris; // Offset, in bytes from the start of the file, to the list of triangles
int offsetFrames; // Offset, in bytes from the start of the file, to the list of frames
int offsetGLcmds; // Offset, in bytes from the start of the file, to the list of gl commands
int offsetEnd; // Offset, in bytes from the start of the file, to the end of the file (filesize)
} md2header_t;
typedef struct
{
unsigned short meshIndex[3]; // indices into the array of vertices in each frames
unsigned short stIndex[3]; // indices into the array of texture coordinates
} md2triangle_t;
typedef struct
{
short s;
short t;
} md2texcoord_t;
typedef struct
{
unsigned char v[3]; // Scaled vertices. You'll need to multiply them with scale[x] to make them normal.
unsigned char lightNormalIndex; // Index to the array of normals
} md2vertex_t;
typedef struct
{
float scale[3]; // Used by the v member in the md2framePoint structure
float translate[3]; // Used by the v member in the md2framePoint structure
char name[16]; // Name of the frame
} md2frame_t;
// Load the model
model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat)
{
FILE *f;
model_t *retModel = NULL;
md2header_t *header;
size_t fileLen;
int i, j;
size_t namelen;
char *texturefilename;
const char *texPos;
char *buffer;
const float WUNITS = 1.0f;
float dataScale = WUNITS;
md2triangle_t *tris;
md2texcoord_t *texcoords;
md2frame_t *frames;
int t;
// MD2 currently does not work with tinyframes, so force useFloat = true
//
// <SSNTails>
// the UV coordinates in MD2 are not compatible with glDrawElements like MD3 is. So they need to be loaded as full float.
//
// MD2 is intended to be draw in triangle strips and fans
// not very compatible with a modern GL implementation, either
// so the idea would be to full float expand it, and put it in a vertex buffer object
// I'm sure there's a way to convert the UVs to 'tinyframes', but maybe that's a job for someone else.
// You'd have to decompress the model, then recompress, reindexing the triangles and weeding out duplicate coordinates
// I already have the decompression work done
useFloat = true;
f = fopen(fileName, "rb");
if (!f)
return NULL;
retModel = (model_t*)Z_Calloc(sizeof(model_t), ztag, 0);
//size_t fileLen;
//int i, j;
//size_t namelen;
//char *texturefilename;
texPos = strchr(fileName, '/');
if (texPos)
{
texPos++;
namelen = strlen(texPos) + 1;
texturefilename = (char*)Z_Malloc(namelen, PU_CACHE, 0);
strcpy(texturefilename, texPos);
}
else
{
namelen = strlen(fileName) + 1;
texturefilename = (char*)Z_Malloc(namelen, PU_CACHE, 0);
strcpy(texturefilename, fileName);
}
texturefilename[namelen - 2] = 'z';
texturefilename[namelen - 3] = 'u';
texturefilename[namelen - 4] = 'b';
// find length of file
fseek(f, 0, SEEK_END);
fileLen = ftell(f);
fseek(f, 0, SEEK_SET);
// read in file
buffer = malloc(fileLen);
if (fread(buffer, fileLen, 1, f)) { } // squash ignored fread error
fclose(f);
// get pointer to file header
header = (md2header_t*)buffer;
retModel->numMeshes = 1; // MD2 only has one mesh
retModel->meshes = (mesh_t*)Z_Calloc(sizeof(mesh_t) * retModel->numMeshes, ztag, 0);
retModel->meshes[0].numFrames = header->numFrames;
// const float WUNITS = 1.0f;
// float dataScale = WUNITS;
// Tris and ST are simple structures that can be straight-copied
tris = (md2triangle_t*)&buffer[header->offsetTris];
texcoords = (md2texcoord_t*)&buffer[header->offsetST];
frames = (md2frame_t*)&buffer[header->offsetFrames];
// Read in textures
retModel->numMaterials = header->numSkins;
if (retModel->numMaterials <= 0) // Always at least one skin, duh
retModel->numMaterials = 1;
retModel->materials = (material_t*)Z_Calloc(sizeof(material_t)*retModel->numMaterials, ztag, 0);
// int t;
for (t = 0; t < retModel->numMaterials; t++)
{
retModel->materials[t].ambient[0] = 0.8f;
retModel->materials[t].ambient[1] = 0.8f;
retModel->materials[t].ambient[2] = 0.8f;
retModel->materials[t].ambient[3] = 1.0f;
retModel->materials[t].diffuse[0] = 0.8f;
retModel->materials[t].diffuse[1] = 0.8f;
retModel->materials[t].diffuse[2] = 0.8f;
retModel->materials[t].diffuse[3] = 1.0f;
retModel->materials[t].emissive[0] = 0.0f;
retModel->materials[t].emissive[1] = 0.0f;
retModel->materials[t].emissive[2] = 0.0f;
retModel->materials[t].emissive[3] = 1.0f;
retModel->materials[t].specular[0] = 0.0f;
retModel->materials[t].specular[1] = 0.0f;
retModel->materials[t].specular[2] = 0.0f;
retModel->materials[t].specular[3] = 1.0f;
retModel->materials[t].shininess = 0.0f;
retModel->materials[t].spheremap = false;
/* retModel->materials[t].texture = Texture::ReadTexture((char*)texturefilename, ZT_TEXTURE);
if (!systemSucks)
{
// Check for a normal map...??
char openfilename[1024];
char normalMapName[1024];
strcpy(normalMapName, texturefilename);
size_t len = strlen(normalMapName);
char *ptr = &normalMapName[len];
ptr--; // z
ptr--; // u
ptr--; // b
ptr--; // .
*ptr++ = '_';
*ptr++ = 'n';
*ptr++ = '.';
*ptr++ = 'b';
*ptr++ = 'u';
*ptr++ = 'z';
*ptr++ = '\0';
sprintf(openfilename, "%s/%s", "textures", normalMapName);
// Convert backslashes to forward slashes
for (int k = 0; k < 1024; k++)
{
if (openfilename[k] == '\0')
break;
if (openfilename[k] == '\\')
openfilename[k] = '/';
}
Resource::resource_t *res = Resource::Open(openfilename);
if (res)
{
Resource::Close(res);
retModel->materials[t].lightmap = Texture::ReadTexture(normalMapName, ZT_TEXTURE);
}
}*/
}
retModel->meshes[0].numTriangles = header->numTris;
if (!useFloat) // Decompress to MD3 'tinyframe' space
{
char *ptr;
md2triangle_t *trisPtr;
unsigned short *indexptr;
float *uvptr;
dataScale = 0.015624f; // 1 / 64.0f
retModel->meshes[0].tinyframes = (tinyframe_t*)Z_Calloc(sizeof(tinyframe_t)*header->numFrames, ztag, 0);
retModel->meshes[0].numVertices = header->numXYZ;
retModel->meshes[0].uvs = (float*)Z_Malloc(sizeof(float) * 2 * retModel->meshes[0].numVertices, ztag, 0);
ptr = (char*)frames;
for (i = 0; i < header->numFrames; i++, ptr += header->framesize)
{
short *vertptr;
char *normptr;
// char *tanptr;
md2vertex_t *vertex;
md2frame_t *framePtr = (md2frame_t*)ptr;
retModel->meshes[0].tinyframes[i].vertices = (short*)Z_Malloc(sizeof(short) * 3 * header->numXYZ, ztag, 0);
retModel->meshes[0].tinyframes[i].normals = (char*)Z_Malloc(sizeof(char) * 3 * header->numXYZ, ztag, 0);
// if (retModel->materials[0].lightmap)
// retModel->meshes[0].tinyframes[i].tangents = (char*)malloc(sizeof(char));//(char*)Z_Malloc(sizeof(char)*3*header->numVerts, ztag);
retModel->meshes[0].indices = (unsigned short*)Z_Malloc(sizeof(unsigned short) * 3 * header->numTris, ztag, 0);
vertptr = retModel->meshes[0].tinyframes[i].vertices;
normptr = retModel->meshes[0].tinyframes[i].normals;
// tanptr = retModel->meshes[0].tinyframes[i].tangents;
retModel->meshes[0].tinyframes[i].material = &retModel->materials[0];
framePtr++; // Advance to vertex list
vertex = (md2vertex_t*)framePtr;
framePtr--;
for (j = 0; j < header->numXYZ; j++, vertex++)
{
*vertptr = (short)(((vertex->v[0] * framePtr->scale[0]) + framePtr->translate[0]) / dataScale);
vertptr++;
*vertptr = (short)(((vertex->v[2] * framePtr->scale[2]) + framePtr->translate[2]) / dataScale);
vertptr++;
*vertptr = -1.0f * (short)(((vertex->v[1] * framePtr->scale[1]) + framePtr->translate[1]) / dataScale);
vertptr++;
// Normal
*normptr++ = (char)(avertexnormals[vertex->lightNormalIndex][0] * 127);
*normptr++ = (char)(avertexnormals[vertex->lightNormalIndex][2] * 127);
*normptr++ = (char)(avertexnormals[vertex->lightNormalIndex][1] * 127);
}
}
// This doesn't need to be done every frame!
trisPtr = tris;
indexptr = retModel->meshes[0].indices;
uvptr = (float*)retModel->meshes[0].uvs;
for (j = 0; j < header->numTris; j++, trisPtr++)
{
*indexptr = trisPtr->meshIndex[0];
indexptr++;
*indexptr = trisPtr->meshIndex[1];
indexptr++;
*indexptr = trisPtr->meshIndex[2];
indexptr++;
uvptr[trisPtr->meshIndex[0] * 2] = texcoords[trisPtr->stIndex[0]].s / (float)header->skinwidth;
uvptr[trisPtr->meshIndex[0] * 2 + 1] = (texcoords[trisPtr->stIndex[0]].t / (float)header->skinheight);
uvptr[trisPtr->meshIndex[1] * 2] = texcoords[trisPtr->stIndex[1]].s / (float)header->skinwidth;
uvptr[trisPtr->meshIndex[1] * 2 + 1] = (texcoords[trisPtr->stIndex[1]].t / (float)header->skinheight);
uvptr[trisPtr->meshIndex[2] * 2] = texcoords[trisPtr->stIndex[2]].s / (float)header->skinwidth;
uvptr[trisPtr->meshIndex[2] * 2 + 1] = (texcoords[trisPtr->stIndex[2]].t / (float)header->skinheight);
}
}
else // Full float loading method
{
md2triangle_t *trisPtr;
float *uvptr;
char *ptr;
retModel->meshes[0].numVertices = header->numTris * 3;
retModel->meshes[0].frames = (mdlframe_t*)Z_Calloc(sizeof(mdlframe_t)*header->numFrames, ztag, 0);
retModel->meshes[0].uvs = (float*)Z_Malloc(sizeof(float) * 2 * retModel->meshes[0].numVertices, ztag, 0);
trisPtr = tris;
uvptr = retModel->meshes[0].uvs;
for (i = 0; i < retModel->meshes[0].numTriangles; i++, trisPtr++)
{
*uvptr++ = texcoords[trisPtr->stIndex[0]].s / (float)header->skinwidth;
*uvptr++ = (texcoords[trisPtr->stIndex[0]].t / (float)header->skinheight);
*uvptr++ = texcoords[trisPtr->stIndex[1]].s / (float)header->skinwidth;
*uvptr++ = (texcoords[trisPtr->stIndex[1]].t / (float)header->skinheight);
*uvptr++ = texcoords[trisPtr->stIndex[2]].s / (float)header->skinwidth;
*uvptr++ = (texcoords[trisPtr->stIndex[2]].t / (float)header->skinheight);
}
ptr = (char*)frames;
for (i = 0; i < header->numFrames; i++, ptr += header->framesize)
{
float *vertptr, *normptr;
md2vertex_t *vertex;
md2frame_t *framePtr = (md2frame_t*)ptr;
retModel->meshes[0].frames[i].normals = (float*)Z_Malloc(sizeof(float) * 3 * header->numTris * 3, ztag, 0);
retModel->meshes[0].frames[i].vertices = (float*)Z_Malloc(sizeof(float) * 3 * header->numTris * 3, ztag, 0);
// if (retModel->materials[0].lightmap)
// retModel->meshes[0].frames[i].tangents = (float*)malloc(sizeof(float));//(float*)Z_Malloc(sizeof(float)*3*header->numTris*3, ztag);
//float *vertptr, *normptr;
normptr = (float*)retModel->meshes[0].frames[i].normals;
vertptr = (float*)retModel->meshes[0].frames[i].vertices;
trisPtr = tris;
retModel->meshes[0].frames[i].material = &retModel->materials[0];
framePtr++; // Advance to vertex list
vertex = (md2vertex_t*)framePtr;
framePtr--;
for (j = 0; j < header->numTris; j++, trisPtr++)
{
*vertptr = ((vertex[trisPtr->meshIndex[0]].v[0] * framePtr->scale[0]) + framePtr->translate[0]) * WUNITS;
vertptr++;
*vertptr = ((vertex[trisPtr->meshIndex[0]].v[2] * framePtr->scale[2]) + framePtr->translate[2]) * WUNITS;
vertptr++;
*vertptr = -1.0f * ((vertex[trisPtr->meshIndex[0]].v[1] * framePtr->scale[1]) + framePtr->translate[1]) * WUNITS;
vertptr++;
*vertptr = ((vertex[trisPtr->meshIndex[1]].v[0] * framePtr->scale[0]) + framePtr->translate[0]) * WUNITS;
vertptr++;
*vertptr = ((vertex[trisPtr->meshIndex[1]].v[2] * framePtr->scale[2]) + framePtr->translate[2]) * WUNITS;
vertptr++;
*vertptr = -1.0f * ((vertex[trisPtr->meshIndex[1]].v[1] * framePtr->scale[1]) + framePtr->translate[1]) * WUNITS;
vertptr++;
*vertptr = ((vertex[trisPtr->meshIndex[2]].v[0] * framePtr->scale[0]) + framePtr->translate[0]) * WUNITS;
vertptr++;
*vertptr = ((vertex[trisPtr->meshIndex[2]].v[2] * framePtr->scale[2]) + framePtr->translate[2]) * WUNITS;
vertptr++;
*vertptr = -1.0f * ((vertex[trisPtr->meshIndex[2]].v[1] * framePtr->scale[1]) + framePtr->translate[1]) * WUNITS;
vertptr++;
*normptr++ = avertexnormals[vertex[trisPtr->meshIndex[0]].lightNormalIndex][0];
*normptr++ = avertexnormals[vertex[trisPtr->meshIndex[0]].lightNormalIndex][2];
*normptr++ = avertexnormals[vertex[trisPtr->meshIndex[0]].lightNormalIndex][1];
*normptr++ = avertexnormals[vertex[trisPtr->meshIndex[1]].lightNormalIndex][0];
*normptr++ = avertexnormals[vertex[trisPtr->meshIndex[1]].lightNormalIndex][2];
*normptr++ = avertexnormals[vertex[trisPtr->meshIndex[1]].lightNormalIndex][1];
*normptr++ = avertexnormals[vertex[trisPtr->meshIndex[2]].lightNormalIndex][0];
*normptr++ = avertexnormals[vertex[trisPtr->meshIndex[2]].lightNormalIndex][2];
*normptr++ = avertexnormals[vertex[trisPtr->meshIndex[2]].lightNormalIndex][1];
}
}
}
free(buffer);
return retModel;
}

19
src/hardware/hw_md2load.h Normal file
View File

@ -0,0 +1,19 @@
/*
From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com )
An experimental work-in-progress.
Donated to Sonic Team Junior and adapted to work with
Sonic Robo Blast 2. The license of this code matches whatever
the licensing is for Sonic Robo Blast 2.
*/
#ifndef _HW_MD2LOAD_H_
#define _HW_MD2LOAD_H_
#include "hw_model.h"
#include "../doomtype.h"
// Load the Model
model_t *MD2_LoadModel(const char *fileName, int ztag, boolean useFloat);
#endif

510
src/hardware/hw_md3load.c Normal file
View File

@ -0,0 +1,510 @@
/*
From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com )
An experimental work-in-progress.
Donated to Sonic Team Junior and adapted to work with
Sonic Robo Blast 2. The license of this code matches whatever
the licensing is for Sonic Robo Blast 2.
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "../doomdef.h"
#include "hw_md3load.h"
#include "hw_model.h"
#include "../z_zone.h"
typedef struct
{
int ident; // A "magic number" that's used to identify the .md3 file
int version; // The version of the file, always 15
char name[64];
int flags;
int numFrames; // Number of frames
int numTags;
int numSurfaces;
int numSkins; // Number of skins with the model
int offsetFrames;
int offsetTags;
int offsetSurfaces;
int offsetEnd; // Offset, in bytes from the start of the file, to the end of the file (filesize)
} md3modelHeader;
typedef struct
{
float minBounds[3]; // First corner of the bounding box
float maxBounds[3]; // Second corner of the bounding box
float localOrigin[3]; // Local origin, usually (0, 0, 0)
float radius; // Radius of bounding sphere
char name[16]; // Name of frame
} md3Frame;
typedef struct
{
char name[64]; // Name of tag
float origin[3]; // Coordinates of tag
float axis[9]; // Orientation of tag object
} md3Tag;
typedef struct
{
int ident;
char name[64]; // Name of this surface
int flags;
int numFrames; // # of keyframes
int numShaders; // # of shaders
int numVerts; // # of vertices
int numTriangles; // # of triangles
int offsetTriangles; // Relative offset from start of this struct to where the list of Triangles start
int offsetShaders; // Relative offset from start of this struct to where the list of Shaders start
int offsetST; // Relative offset from start of this struct to where the list of tex coords start
int offsetXYZNormal; // Relative offset from start of this struct to where the list of vertices start
int offsetEnd; // Relative offset from start of this struct to where this surface ends
} md3Surface;
typedef struct
{
char name[64]; // Name of this shader
int shaderIndex; // Shader index number
} md3Shader;
typedef struct
{
int index[3]; // List of offset values into the list of Vertex objects that constitute the corners of the Triangle object.
} md3Triangle;
typedef struct
{
float st[2];
} md3TexCoord;
typedef struct
{
short x, y, z, n;
} md3Vertex;
static float latlnglookup[256][256][3];
static void GetNormalFromLatLong(short latlng, float *out)
{
float *lookup = latlnglookup[(unsigned char)(latlng >> 8)][(unsigned char)(latlng & 255)];
out[0] = *lookup++;
out[1] = *lookup++;
out[2] = *lookup++;
}
#if 0
static void NormalToLatLng(float *n, short *out)
{
// Special cases
if (0.0f == n[0] && 0.0f == n[1])
{
if (n[2] > 0.0f)
*out = 0;
else
*out = 128;
}
else
{
char x, y;
x = (char)(57.2957795f * (atan2(n[1], n[0])) * (255.0f / 360.0f));
y = (char)(57.2957795f * (acos(n[2])) * (255.0f / 360.0f));
*out = (x << 8) + y;
}
}
#endif
static inline void LatLngToNormal(short n, float *out)
{
const float PI = (3.1415926535897932384626433832795f);
float lat = (float)(n >> 8);
float lng = (float)(n & 255);
lat *= PI / 128.0f;
lng *= PI / 128.0f;
out[0] = cosf(lat) * sinf(lng);
out[1] = sinf(lat) * sinf(lng);
out[2] = cosf(lng);
}
static void LatLngInit(void)
{
int i, j;
for (i = 0; i < 256; i++)
{
for (j = 0; j < 256; j++)
LatLngToNormal((short)((i << 8) + j), latlnglookup[i][j]);
}
}
static boolean latlnginit = false;
model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat)
{
const float WUNITS = 1.0f;
model_t *retModel = NULL;
md3modelHeader *mdh;
long fileLen;
long fileReadLen;
char *buffer;
int surfEnd;
int i, t;
int matCount;
FILE *f;
if (!latlnginit)
{
LatLngInit();
latlnginit = true;
}
f = fopen(fileName, "rb");
if (!f)
return NULL;
retModel = (model_t*)Z_Calloc(sizeof(model_t), ztag, 0);
// find length of file
fseek(f, 0, SEEK_END);
fileLen = ftell(f);
fseek(f, 0, SEEK_SET);
// read in file
buffer = malloc(fileLen);
fileReadLen = fread(buffer, fileLen, 1, f);
fclose(f);
(void)fileReadLen; // intentionally ignore return value, per buildbot
// get pointer to file header
mdh = (md3modelHeader*)buffer;
retModel->numMeshes = mdh->numSurfaces;
retModel->numMaterials = 0;
surfEnd = 0;
for (i = 0; i < mdh->numSurfaces; i++)
{
md3Surface *mdS = (md3Surface*)&buffer[mdh->offsetSurfaces];
surfEnd += mdS->offsetEnd;
retModel->numMaterials += mdS->numShaders;
}
// Initialize materials
if (retModel->numMaterials <= 0) // Always at least one skin, duh
retModel->numMaterials = 1;
retModel->materials = (material_t*)Z_Calloc(sizeof(material_t)*retModel->numMaterials, ztag, 0);
for (t = 0; t < retModel->numMaterials; t++)
{
retModel->materials[t].ambient[0] = 0.3686f;
retModel->materials[t].ambient[1] = 0.3684f;
retModel->materials[t].ambient[2] = 0.3684f;
retModel->materials[t].ambient[3] = 1.0f;
retModel->materials[t].diffuse[0] = 0.8863f;
retModel->materials[t].diffuse[1] = 0.8850f;
retModel->materials[t].diffuse[2] = 0.8850f;
retModel->materials[t].diffuse[3] = 1.0f;
retModel->materials[t].emissive[0] = 0.0f;
retModel->materials[t].emissive[1] = 0.0f;
retModel->materials[t].emissive[2] = 0.0f;
retModel->materials[t].emissive[3] = 1.0f;
retModel->materials[t].specular[0] = 0.4902f;
retModel->materials[t].specular[1] = 0.4887f;
retModel->materials[t].specular[2] = 0.4887f;
retModel->materials[t].specular[3] = 1.0f;
retModel->materials[t].shininess = 25.0f;
retModel->materials[t].spheremap = false;
}
retModel->meshes = (mesh_t*)Z_Calloc(sizeof(mesh_t)*retModel->numMeshes, ztag, 0);
matCount = 0;
for (i = 0, surfEnd = 0; i < mdh->numSurfaces; i++)
{
int j;
md3Shader *mdShader;
md3Surface *mdS = (md3Surface*)&buffer[mdh->offsetSurfaces + surfEnd];
surfEnd += mdS->offsetEnd;
mdShader = (md3Shader*)((char*)mdS + mdS->offsetShaders);
for (j = 0; j < mdS->numShaders; j++, matCount++)
{
size_t len = strlen(mdShader[j].name);
mdShader[j].name[len-1] = 'z';
mdShader[j].name[len-2] = 'u';
mdShader[j].name[len-3] = 'b';
// Load material
/* retModel->materials[matCount].texture = Texture::ReadTexture(mdShader[j].name, ZT_TEXTURE);
if (!systemSucks)
{
// Check for a normal map...??
char openfilename[1024];
char normalMapName[1024];
strcpy(normalMapName, mdShader[j].name);
len = strlen(normalMapName);
char *ptr = &normalMapName[len];
ptr--; // z
ptr--; // u
ptr--; // b
ptr--; // .
*ptr++ = '_';
*ptr++ = 'n';
*ptr++ = '.';
*ptr++ = 'b';
*ptr++ = 'u';
*ptr++ = 'z';
*ptr++ = '\0';
sprintf(openfilename, "%s/%s", "textures", normalMapName);
// Convert backslashes to forward slashes
for (int k = 0; k < 1024; k++)
{
if (openfilename[k] == '\0')
break;
if (openfilename[k] == '\\')
openfilename[k] = '/';
}
Resource::resource_t *res = Resource::Open(openfilename);
if (res)
{
Resource::Close(res);
retModel->materials[matCount].lightmap = Texture::ReadTexture(normalMapName, ZT_TEXTURE);
}
}*/
}
retModel->meshes[i].numFrames = mdS->numFrames;
retModel->meshes[i].numTriangles = mdS->numTriangles;
if (!useFloat) // 'tinyframe' mode with indices
{
float tempNormal[3];
float *uvptr;
md3TexCoord *mdST;
unsigned short *indexptr;
md3Triangle *mdT;
retModel->meshes[i].tinyframes = (tinyframe_t*)Z_Calloc(sizeof(tinyframe_t)*mdS->numFrames, ztag, 0);
retModel->meshes[i].numVertices = mdS->numVerts;
retModel->meshes[i].uvs = (float*)Z_Malloc(sizeof(float)*2*mdS->numVerts, ztag, 0);
for (j = 0; j < mdS->numFrames; j++)
{
short *vertptr;
char *normptr;
// char *tanptr;
int k;
md3Vertex *mdV = (md3Vertex*)((char*)mdS + mdS->offsetXYZNormal + (mdS->numVerts*j*sizeof(md3Vertex)));
retModel->meshes[i].tinyframes[j].vertices = (short*)Z_Malloc(sizeof(short)*3*mdS->numVerts, ztag, 0);
retModel->meshes[i].tinyframes[j].normals = (char*)Z_Malloc(sizeof(char)*3*mdS->numVerts, ztag, 0);
// if (retModel->materials[0].lightmap)
// retModel->meshes[i].tinyframes[j].tangents = (char*)malloc(sizeof(char));//(char*)Z_Malloc(sizeof(char)*3*mdS->numVerts, ztag);
retModel->meshes[i].indices = (unsigned short*)Z_Malloc(sizeof(unsigned short) * 3 * mdS->numTriangles, ztag, 0);
vertptr = retModel->meshes[i].tinyframes[j].vertices;
normptr = retModel->meshes[i].tinyframes[j].normals;
// tanptr = retModel->meshes[i].tinyframes[j].tangents;
retModel->meshes[i].tinyframes[j].material = &retModel->materials[i];
for (k = 0; k < mdS->numVerts; k++)
{
// Vertex
*vertptr = mdV[k].x;
vertptr++;
*vertptr = mdV[k].z;
vertptr++;
*vertptr = 1.0f - mdV[k].y;
vertptr++;
// Normal
GetNormalFromLatLong(mdV[k].n, tempNormal);
*normptr = (char)(tempNormal[0] * 127);
normptr++;
*normptr = (char)(tempNormal[2] * 127);
normptr++;
*normptr = (char)(tempNormal[1] * 127);
normptr++;
}
}
uvptr = (float*)retModel->meshes[i].uvs;
mdST = (md3TexCoord*)((char*)mdS + mdS->offsetST);
for (j = 0; j < mdS->numVerts; j++)
{
*uvptr = mdST[j].st[0];
uvptr++;
*uvptr = mdST[j].st[1];
uvptr++;
}
indexptr = retModel->meshes[i].indices;
mdT = (md3Triangle*)((char*)mdS + mdS->offsetTriangles);
for (j = 0; j < mdS->numTriangles; j++, mdT++)
{
// Indices
*indexptr = (unsigned short)mdT->index[0];
indexptr++;
*indexptr = (unsigned short)mdT->index[1];
indexptr++;
*indexptr = (unsigned short)mdT->index[2];
indexptr++;
}
}
else // Traditional full-float loading method
{
float dataScale = 0.015624f * WUNITS;
float tempNormal[3];
md3TexCoord *mdST;
md3Triangle *mdT;
float *uvptr;
int k;
retModel->meshes[i].numVertices = mdS->numTriangles * 3;//mdS->numVerts;
retModel->meshes[i].frames = (mdlframe_t*)Z_Calloc(sizeof(mdlframe_t)*mdS->numFrames, ztag, 0);
retModel->meshes[i].uvs = (float*)Z_Malloc(sizeof(float)*2*mdS->numTriangles*3, ztag, 0);
for (j = 0; j < mdS->numFrames; j++)
{
float *vertptr;
float *normptr;
md3Vertex *mdV = (md3Vertex*)((char*)mdS + mdS->offsetXYZNormal + (mdS->numVerts*j*sizeof(md3Vertex)));
retModel->meshes[i].frames[j].vertices = (float*)Z_Malloc(sizeof(float)*3*mdS->numTriangles*3, ztag, 0);
retModel->meshes[i].frames[j].normals = (float*)Z_Malloc(sizeof(float)*3*mdS->numTriangles*3, ztag, 0);
// if (retModel->materials[i].lightmap)
// retModel->meshes[i].frames[j].tangents = (float*)malloc(sizeof(float));//(float*)Z_Malloc(sizeof(float)*3*mdS->numTriangles*3, ztag);
vertptr = retModel->meshes[i].frames[j].vertices;
normptr = retModel->meshes[i].frames[j].normals;
retModel->meshes[i].frames[j].material = &retModel->materials[i];
mdT = (md3Triangle*)((char*)mdS + mdS->offsetTriangles);
for (k = 0; k < mdS->numTriangles; k++)
{
// Vertex 1
*vertptr = mdV[mdT->index[0]].x * dataScale;
vertptr++;
*vertptr = mdV[mdT->index[0]].z * dataScale;
vertptr++;
*vertptr = 1.0f - mdV[mdT->index[0]].y * dataScale;
vertptr++;
GetNormalFromLatLong(mdV[mdT->index[0]].n, tempNormal);
*normptr = tempNormal[0];
normptr++;
*normptr = tempNormal[2];
normptr++;
*normptr = tempNormal[1];
normptr++;
// Vertex 2
*vertptr = mdV[mdT->index[1]].x * dataScale;
vertptr++;
*vertptr = mdV[mdT->index[1]].z * dataScale;
vertptr++;
*vertptr = 1.0f - mdV[mdT->index[1]].y * dataScale;
vertptr++;
GetNormalFromLatLong(mdV[mdT->index[1]].n, tempNormal);
*normptr = tempNormal[0];
normptr++;
*normptr = tempNormal[2];
normptr++;
*normptr = tempNormal[1];
normptr++;
// Vertex 3
*vertptr = mdV[mdT->index[2]].x * dataScale;
vertptr++;
*vertptr = mdV[mdT->index[2]].z * dataScale;
vertptr++;
*vertptr = 1.0f - mdV[mdT->index[2]].y * dataScale;
vertptr++;
GetNormalFromLatLong(mdV[mdT->index[2]].n, tempNormal);
*normptr = tempNormal[0];
normptr++;
*normptr = tempNormal[2];
normptr++;
*normptr = tempNormal[1];
normptr++;
mdT++; // Advance to next triangle
}
}
mdST = (md3TexCoord*)((char*)mdS + mdS->offsetST);
uvptr = (float*)retModel->meshes[i].uvs;
mdT = (md3Triangle*)((char*)mdS + mdS->offsetTriangles);
for (k = 0; k < mdS->numTriangles; k++)
{
*uvptr = mdST[mdT->index[0]].st[0];
uvptr++;
*uvptr = mdST[mdT->index[0]].st[1];
uvptr++;
*uvptr = mdST[mdT->index[1]].st[0];
uvptr++;
*uvptr = mdST[mdT->index[1]].st[1];
uvptr++;
*uvptr = mdST[mdT->index[2]].st[0];
uvptr++;
*uvptr = mdST[mdT->index[2]].st[1];
uvptr++;
mdT++; // Advance to next triangle
}
}
}
/*
// Tags?
retModel->numTags = mdh->numTags;
retModel->maxNumFrames = mdh->numFrames;
retModel->tags = (tag_t*)Z_Calloc(sizeof(tag_t) * retModel->numTags * mdh->numFrames, ztag);
md3Tag *mdTag = (md3Tag*)&buffer[mdh->offsetTags];
tag_t *curTag = retModel->tags;
for (i = 0; i < mdh->numFrames; i++)
{
int j;
for (j = 0; j < retModel->numTags; j++, mdTag++)
{
strcpys(curTag->name, mdTag->name, sizeof(curTag->name) / sizeof(char));
curTag->transform.m[0][0] = mdTag->axis[0];
curTag->transform.m[0][1] = mdTag->axis[1];
curTag->transform.m[0][2] = mdTag->axis[2];
curTag->transform.m[1][0] = mdTag->axis[3];
curTag->transform.m[1][1] = mdTag->axis[4];
curTag->transform.m[1][2] = mdTag->axis[5];
curTag->transform.m[2][0] = mdTag->axis[6];
curTag->transform.m[2][1] = mdTag->axis[7];
curTag->transform.m[2][2] = mdTag->axis[8];
curTag->transform.m[3][0] = mdTag->origin[0] * WUNITS;
curTag->transform.m[3][1] = mdTag->origin[1] * WUNITS;
curTag->transform.m[3][2] = mdTag->origin[2] * WUNITS;
curTag->transform.m[3][3] = 1.0f;
Matrix::Rotate(&curTag->transform, 90.0f, &Vector::Xaxis);
curTag++;
}
}*/
free(buffer);
return retModel;
}

19
src/hardware/hw_md3load.h Normal file
View File

@ -0,0 +1,19 @@
/*
From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com )
An experimental work-in-progress.
Donated to Sonic Team Junior and adapted to work with
Sonic Robo Blast 2. The license of this code matches whatever
the licensing is for Sonic Robo Blast 2.
*/
#ifndef _HW_MD3LOAD_H_
#define _HW_MD3LOAD_H_
#include "hw_model.h"
#include "../doomtype.h"
// Load the Model
model_t *MD3_LoadModel(const char *fileName, int ztag, boolean useFloat);
#endif

593
src/hardware/hw_model.c Normal file
View File

@ -0,0 +1,593 @@
/*
From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com )
An experimental work-in-progress.
Donated to Sonic Team Junior and adapted to work with
Sonic Robo Blast 2. The license of this code matches whatever
the licensing is for Sonic Robo Blast 2.
*/
#include "../z_zone.h"
#include "../doomdef.h"
#include "hw_model.h"
#include "hw_md2load.h"
#include "hw_md3load.h"
#include "u_list.h"
#include <string.h>
static float PI = (3.1415926535897932384626433832795f);
static float U_Deg2Rad(float deg)
{
return deg * ((float)PI / 180.0f);
}
vector_t vectorXaxis = { 1.0f, 0.0f, 0.0f };
vector_t vectorYaxis = { 0.0f, 1.0f, 0.0f };
vector_t vectorZaxis = { 0.0f, 0.0f, 1.0f };
void VectorRotate(vector_t *rotVec, const vector_t *axisVec, float angle)
{
float ux, uy, uz, vx, vy, vz, wx, wy, wz, sa, ca;
angle = U_Deg2Rad(angle);
// Rotate the point (x,y,z) around the vector (u,v,w)
ux = axisVec->x * rotVec->x;
uy = axisVec->x * rotVec->y;
uz = axisVec->x * rotVec->z;
vx = axisVec->y * rotVec->x;
vy = axisVec->y * rotVec->y;
vz = axisVec->y * rotVec->z;
wx = axisVec->z * rotVec->x;
wy = axisVec->z * rotVec->y;
wz = axisVec->z * rotVec->z;
sa = sinf(angle);
ca = cosf(angle);
rotVec->x = axisVec->x*(ux + vy + wz) + (rotVec->x*(axisVec->y*axisVec->y + axisVec->z*axisVec->z) - axisVec->x*(vy + wz))*ca + (-wy + vz)*sa;
rotVec->y = axisVec->y*(ux + vy + wz) + (rotVec->y*(axisVec->x*axisVec->x + axisVec->z*axisVec->z) - axisVec->y*(ux + wz))*ca + (wx - uz)*sa;
rotVec->z = axisVec->z*(ux + vy + wz) + (rotVec->z*(axisVec->x*axisVec->x + axisVec->y*axisVec->y) - axisVec->z*(ux + vy))*ca + (-vx + uy)*sa;
}
void UnloadModel(model_t *model)
{
// Wouldn't it be great if C just had destructors?
int i;
for (i = 0; i < model->numMeshes; i++)
{
mesh_t *mesh = &model->meshes[i];
if (mesh->frames)
{
int j;
for (j = 0; j < mesh->numFrames; j++)
{
if (mesh->frames[j].normals)
Z_Free(mesh->frames[j].normals);
if (mesh->frames[j].tangents)
Z_Free(mesh->frames[j].tangents);
if (mesh->frames[j].vertices)
Z_Free(mesh->frames[j].vertices);
if (mesh->frames[j].colors)
Z_Free(mesh->frames[j].colors);
}
Z_Free(mesh->frames);
}
else if (mesh->tinyframes)
{
int j;
for (j = 0; j < mesh->numFrames; j++)
{
if (mesh->tinyframes[j].normals)
Z_Free(mesh->tinyframes[j].normals);
if (mesh->tinyframes[j].tangents)
Z_Free(mesh->tinyframes[j].tangents);
if (mesh->tinyframes[j].vertices)
Z_Free(mesh->tinyframes[j].vertices);
}
if (mesh->indices)
Z_Free(mesh->indices);
Z_Free(mesh->tinyframes);
}
if (mesh->uvs)
Z_Free(mesh->uvs);
if (mesh->lightuvs)
Z_Free(mesh->lightuvs);
}
if (model->meshes)
Z_Free(model->meshes);
if (model->tags)
Z_Free(model->tags);
if (model->materials)
Z_Free(model->materials);
DeleteVBOs(model);
Z_Free(model);
}
tag_t *GetTagByName(model_t *model, char *name, int frame)
{
if (frame < model->maxNumFrames)
{
tag_t *iterator = &model->tags[frame * model->numTags];
int i;
for (i = 0; i < model->numTags; i++)
{
if (!stricmp(iterator[i].name, name))
return &iterator[i];
}
}
return NULL;
}
//
// LoadModel
//
// Load a model and
// convert it to the
// internal format.
//
model_t *LoadModel(const char *filename, int ztag)
{
model_t *model;
// What type of file?
const char *extension = NULL;
int i;
for (i = (int)strlen(filename)-1; i >= 0; i--)
{
if (filename[i] != '.')
continue;
extension = &filename[i];
break;
}
if (!extension)
{
CONS_Printf("Model %s is lacking a file extension, unable to determine type!\n", filename);
return NULL;
}
if (!strcmp(extension, ".md3"))
{
if (!(model = MD3_LoadModel(filename, ztag, false)))
return NULL;
}
else if (!strcmp(extension, ".md3s")) // MD3 that will be converted in memory to use full floats
{
if (!(model = MD3_LoadModel(filename, ztag, true)))
return NULL;
}
else if (!strcmp(extension, ".md2"))
{
if (!(model = MD2_LoadModel(filename, ztag, false)))
return NULL;
}
else if (!strcmp(extension, ".md2s"))
{
if (!(model = MD2_LoadModel(filename, ztag, true)))
return NULL;
}
else
{
CONS_Printf("Unknown model format: %s\n", extension);
return NULL;
}
model->mdlFilename = (char*)Z_Malloc(strlen(filename)+1, ztag, 0);
strcpy(model->mdlFilename, filename);
Optimize(model);
GeneratePolygonNormals(model, ztag);
// Default material properties
for (i = 0 ; i < model->numMaterials; i++)
{
material_t *material = &model->materials[i];
material->ambient[0] = 0.7686f;
material->ambient[1] = 0.7686f;
material->ambient[2] = 0.7686f;
material->ambient[3] = 1.0f;
material->diffuse[0] = 0.5863f;
material->diffuse[1] = 0.5863f;
material->diffuse[2] = 0.5863f;
material->diffuse[3] = 1.0f;
material->specular[0] = 0.4902f;
material->specular[1] = 0.4902f;
material->specular[2] = 0.4902f;
material->specular[3] = 1.0f;
material->shininess = 25.0f;
}
return model;
}
//
// GenerateVertexNormals
//
// Creates a new normal for a vertex using the average of all of the polygons it belongs to.
//
void GenerateVertexNormals(model_t *model)
{
int i;
for (i = 0; i < model->numMeshes; i++)
{
int j;
mesh_t *mesh = &model->meshes[i];
if (!mesh->frames)
continue;
for (j = 0; j < mesh->numFrames; j++)
{
mdlframe_t *frame = &mesh->frames[j];
int memTag = PU_STATIC;
float *newNormals = (float*)Z_Malloc(sizeof(float)*3*mesh->numTriangles*3, memTag, 0);
int k;
float *vertPtr = frame->vertices;
float *oldNormals;
M_Memcpy(newNormals, frame->normals, sizeof(float)*3*mesh->numTriangles*3);
/* if (!systemSucks)
{
memTag = Z_GetTag(frame->tangents);
float *newTangents = (float*)Z_Malloc(sizeof(float)*3*mesh->numTriangles*3, memTag);
M_Memcpy(newTangents, frame->tangents, sizeof(float)*3*mesh->numTriangles*3);
}*/
for (k = 0; k < mesh->numVertices; k++)
{
float x, y, z;
int vCount = 0;
vector_t normal;
int l;
float *testPtr = frame->vertices;
x = *vertPtr++;
y = *vertPtr++;
z = *vertPtr++;
normal.x = normal.y = normal.z = 0;
for (l = 0; l < mesh->numVertices; l++)
{
float testX, testY, testZ;
testX = *testPtr++;
testY = *testPtr++;
testZ = *testPtr++;
if (fabsf(x - testX) > FLT_EPSILON
|| fabsf(y - testY) > FLT_EPSILON
|| fabsf(z - testZ) > FLT_EPSILON)
continue;
// Found a vertex match! Add it...
normal.x += frame->normals[3 * l + 0];
normal.y += frame->normals[3 * l + 1];
normal.z += frame->normals[3 * l + 2];
vCount++;
}
if (vCount > 1)
{
// Vector::Normalize(&normal);
newNormals[3 * k + 0] = (float)normal.x;
newNormals[3 * k + 1] = (float)normal.y;
newNormals[3 * k + 2] = (float)normal.z;
/* if (!systemSucks)
{
Vector::vector_t tangent;
Vector::Tangent(&normal, &tangent);
newTangents[3 * k + 0] = tangent.x;
newTangents[3 * k + 1] = tangent.y;
newTangents[3 * k + 2] = tangent.z;
}*/
}
}
oldNormals = frame->normals;
frame->normals = newNormals;
Z_Free(oldNormals);
/* if (!systemSucks)
{
float *oldTangents = frame->tangents;
frame->tangents = newTangents;
Z_Free(oldTangents);
}*/
}
}
}
typedef struct materiallist_s
{
struct materiallist_s *next;
struct materiallist_s *prev;
material_t *material;
} materiallist_t;
static boolean AddMaterialToList(materiallist_t **head, material_t *material)
{
materiallist_t *node, *newMatNode;
for (node = *head; node; node = node->next)
{
if (node->material == material)
return false;
}
// Didn't find it, so add to the list
newMatNode = (materiallist_t*)Z_Malloc(sizeof(materiallist_t), PU_CACHE, 0);
newMatNode->material = material;
ListAdd(newMatNode, (listitem_t**)head);
return true;
}
//
// Optimize
//
// Groups triangles from meshes in the model
// Only works for models with 1 frame
//
void Optimize(model_t *model)
{
int numMeshes = 0;
int i;
materiallist_t *matListHead = NULL;
int memTag;
mesh_t *newMeshes;
materiallist_t *node;
if (model->numMeshes <= 1)
return; // No need
for (i = 0; i < model->numMeshes; i++)
{
mesh_t *curMesh = &model->meshes[i];
if (curMesh->numFrames > 1)
return; // Can't optimize models with > 1 frame
if (!curMesh->frames)
return; // Don't optimize tinyframe models (no need)
// We are condensing to 1 mesh per material, so
// the # of materials we use will be the new
// # of meshes
if (AddMaterialToList(&matListHead, curMesh->frames[0].material))
numMeshes++;
}
memTag = PU_STATIC;
newMeshes = (mesh_t*)Z_Calloc(sizeof(mesh_t) * numMeshes, memTag, 0);
i = 0;
for (node = matListHead; node; node = node->next)
{
material_t *curMat = node->material;
mesh_t *newMesh = &newMeshes[i];
mdlframe_t *curFrame;
int uvCount;
int vertCount;
int colorCount;
// Find all triangles with this material and count them
int numTriangles = 0;
int j;
for (j = 0; j < model->numMeshes; j++)
{
mesh_t *curMesh = &model->meshes[j];
if (curMesh->frames[0].material == curMat)
numTriangles += curMesh->numTriangles;
}
newMesh->numFrames = 1;
newMesh->numTriangles = numTriangles;
newMesh->numVertices = numTriangles * 3;
newMesh->uvs = (float*)Z_Malloc(sizeof(float)*2*numTriangles*3, memTag, 0);
// if (node->material->lightmap)
// newMesh->lightuvs = (float*)Z_Malloc(sizeof(float)*2*numTriangles*3, memTag, 0);
newMesh->frames = (mdlframe_t*)Z_Calloc(sizeof(mdlframe_t), memTag, 0);
curFrame = &newMesh->frames[0];
curFrame->material = curMat;
curFrame->normals = (float*)Z_Malloc(sizeof(float)*3*numTriangles*3, memTag, 0);
// if (!systemSucks)
// curFrame->tangents = (float*)Z_Malloc(sizeof(float)*3*numTriangles*3, memTag, 0);
curFrame->vertices = (float*)Z_Malloc(sizeof(float)*3*numTriangles*3, memTag, 0);
curFrame->colors = (char*)Z_Malloc(sizeof(char)*4*numTriangles*3, memTag, 0);
// Now traverse the meshes of the model, adding in
// vertices/normals/uvs that match the current material
uvCount = 0;
vertCount = 0;
colorCount = 0;
for (j = 0; j < model->numMeshes; j++)
{
mesh_t *curMesh = &model->meshes[j];
if (curMesh->frames[0].material == curMat)
{
float *dest;
float *src;
char *destByte;
char *srcByte;
M_Memcpy(&newMesh->uvs[uvCount],
curMesh->uvs,
sizeof(float)*2*curMesh->numTriangles*3);
/* if (node->material->lightmap)
{
M_Memcpy(&newMesh->lightuvs[uvCount],
curMesh->lightuvs,
sizeof(float)*2*curMesh->numTriangles*3);
}*/
uvCount += 2*curMesh->numTriangles*3;
dest = (float*)newMesh->frames[0].vertices;
src = (float*)curMesh->frames[0].vertices;
M_Memcpy(&dest[vertCount],
src,
sizeof(float)*3*curMesh->numTriangles*3);
dest = (float*)newMesh->frames[0].normals;
src = (float*)curMesh->frames[0].normals;
M_Memcpy(&dest[vertCount],
src,
sizeof(float)*3*curMesh->numTriangles*3);
/* if (!systemSucks)
{
dest = (float*)newMesh->frames[0].tangents;
src = (float*)curMesh->frames[0].tangents;
M_Memcpy(&dest[vertCount],
src,
sizeof(float)*3*curMesh->numTriangles*3);
}*/
vertCount += 3 * curMesh->numTriangles * 3;
destByte = (char*)newMesh->frames[0].colors;
srcByte = (char*)curMesh->frames[0].colors;
if (srcByte)
{
M_Memcpy(&destByte[colorCount],
srcByte,
sizeof(char)*4*curMesh->numTriangles*3);
}
else
{
memset(&destByte[colorCount],
255,
sizeof(char)*4*curMesh->numTriangles*3);
}
colorCount += 4 * curMesh->numTriangles * 3;
}
}
i++;
}
CONS_Printf("Model::Optimize(): Model reduced from %d to %d meshes.\n", model->numMeshes, numMeshes);
model->meshes = newMeshes;
model->numMeshes = numMeshes;
}
void GeneratePolygonNormals(model_t *model, int ztag)
{
int i;
for (i = 0; i < model->numMeshes; i++)
{
int j;
mesh_t *mesh = &model->meshes[i];
if (!mesh->frames)
continue;
for (j = 0; j < mesh->numFrames; j++)
{
int k;
mdlframe_t *frame = &mesh->frames[j];
const float *vertices = frame->vertices;
vector_t *polyNormals;
frame->polyNormals = (vector_t*)Z_Malloc(sizeof(vector_t) * mesh->numTriangles, ztag, 0);
polyNormals = frame->polyNormals;
for (k = 0; k < mesh->numTriangles; k++)
{
// Vector::Normal(vertices, polyNormals);
vertices += 3 * 3;
polyNormals++;
}
}
}
}
//
// Reload
//
// Reload VBOs
//
#if 0
static void Reload(void)
{
/* model_t *node;
for (node = modelHead; node; node = node->next)
{
int i;
for (i = 0; i < node->numMeshes; i++)
{
mesh_t *mesh = &node->meshes[i];
if (mesh->frames)
{
int j;
for (j = 0; j < mesh->numFrames; j++)
CreateVBO(mesh, &mesh->frames[j]);
}
else if (mesh->tinyframes)
{
int j;
for (j = 0; j < mesh->numFrames; j++)
CreateVBO(mesh, &mesh->tinyframes[j]);
}
}
}*/
}
#endif
void DeleteVBOs(model_t *model)
{
(void)model;
/* for (int i = 0; i < model->numMeshes; i++)
{
mesh_t *mesh = &model->meshes[i];
if (mesh->frames)
{
for (int j = 0; j < mesh->numFrames; j++)
{
mdlframe_t *frame = &mesh->frames[j];
if (!frame->vboID)
continue;
bglDeleteBuffers(1, &frame->vboID);
frame->vboID = 0;
}
}
else if (mesh->tinyframes)
{
for (int j = 0; j < mesh->numFrames; j++)
{
tinyframe_t *frame = &mesh->tinyframes[j];
if (!frame->vboID)
continue;
bglDeleteBuffers(1, &frame->vboID);
frame->vboID = 0;
}
}
}*/
}

104
src/hardware/hw_model.h Normal file
View File

@ -0,0 +1,104 @@
/*
From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com )
An experimental work-in-progress.
Donated to Sonic Team Junior and adapted to work with
Sonic Robo Blast 2. The license of this code matches whatever
the licensing is for Sonic Robo Blast 2.
*/
#ifndef _HW_MODEL_H_
#define _HW_MODEL_H_
#include "../doomtype.h"
typedef struct
{
float x, y, z;
} vector_t;
extern vector_t vectorXaxis;
extern vector_t vectorYaxis;
extern vector_t vectorZaxis;
void VectorRotate(vector_t *rotVec, const vector_t *axisVec, float angle);
typedef struct
{
float ambient[4], diffuse[4], specular[4], emissive[4];
float shininess;
boolean spheremap;
// Texture::texture_t *texture;
// Texture::texture_t *lightmap;
} material_t;
typedef struct
{
material_t *material; // Pointer to the allocated 'materials' list in model_t
float *vertices;
float *normals;
float *tangents;
char *colors;
unsigned int vboID;
vector_t *polyNormals;
} mdlframe_t;
typedef struct
{
material_t *material;
short *vertices;
char *normals;
char *tangents;
unsigned int vboID;
} tinyframe_t;
// Equivalent to MD3's many 'surfaces'
typedef struct mesh_s
{
int numVertices;
int numTriangles;
float *uvs;
float *lightuvs;
int numFrames;
mdlframe_t *frames;
tinyframe_t *tinyframes;
unsigned short *indices;
} mesh_t;
typedef struct tag_s
{
char name[64];
// matrix_t transform;
} tag_t;
typedef struct model_s
{
int maxNumFrames;
int numMaterials;
material_t *materials;
int numMeshes;
mesh_t *meshes;
int numTags;
tag_t *tags;
char *mdlFilename;
boolean unloaded;
} model_t;
extern int numModels;
extern model_t *modelHead;
tag_t *GetTagByName(model_t *model, char *name, int frame);
model_t *LoadModel(const char *filename, int ztag);
void UnloadModel(model_t *model);
void Optimize(model_t *model);
void GenerateVertexNormals(model_t *model);
void GeneratePolygonNormals(model_t *model, int ztag);
void CreateVBOTiny(mesh_t *mesh, tinyframe_t *frame);
void CreateVBO(mesh_t *mesh, mdlframe_t *frame);
void DeleteVBOs(model_t *model);
#endif

View File

@ -347,13 +347,6 @@ static INT32 WINAPI SetRes(viddef_t *lvid, vmode_t *pcurrentmode)
if (strstr(renderer, "810")) oglflags |= GLF_NOZBUFREAD;
DBG_Printf("oglflags : 0x%X\n", oglflags);
#ifdef USE_PALETTED_TEXTURE
if (isExtAvailable("GL_EXT_paletted_texture",gl_extensions))
glColorTableEXT = GetGLFunc("glColorTableEXT");
else
glColorTableEXT = NULL;
#endif
#ifdef USE_WGL_SWAP
if (isExtAvailable("WGL_EXT_swap_control",gl_extensions))
wglSwapIntervalEXT = GetGLFunc("wglSwapIntervalEXT");
@ -582,19 +575,8 @@ EXPORT void HWRAPI(SetPalette) (RGBA_t *pal, RGBA_t *gamma)
myPaletteData[i].s.blue = (UINT8)MIN((pal[i].s.blue*gamma->s.blue)/127, 255);
myPaletteData[i].s.alpha = pal[i].s.alpha;
}
#ifdef USE_PALETTED_TEXTURE
if (glColorTableEXT)
{
for (i = 0; i < 256; i++)
{
palette_tex[3*i+0] = pal[i].s.red;
palette_tex[3*i+1] = pal[i].s.green;
palette_tex[3*i+2] = pal[i].s.blue;
}
glColorTableEXT(GL_TEXTURE_2D, GL_RGB8, 256, GL_RGB, GL_UNSIGNED_BYTE, palette_tex);
}
#endif
// on a chang<6E> de palette, il faut recharger toutes les textures
// on a palette change, you have to reload all of the textures
Flush();
}

File diff suppressed because it is too large Load Diff

View File

@ -37,13 +37,11 @@
#include <GL/gl.h>
#include <GL/glu.h>
#ifndef MINI_GL_COMPATIBILITY
#ifdef STATIC_OPENGL // Because of the 1.3 functions, you'll need GLext to compile it if static
#define GL_GLEXT_PROTOTYPES
#include <GL/glext.h>
#endif
#endif
#endif
#define _CREATE_DLL_ // necessary for Unix AND Windows
#include "../../doomdef.h"
@ -73,7 +71,6 @@ extern FILE *gllogstream;
#endif
#ifndef DRIVER_STRING
// #define USE_PALETTED_TEXTURE
#define DRIVER_STRING "HWRAPI Init(): SRB2Kart OpenGL renderer" // Tails
#endif
@ -91,10 +88,6 @@ int SetupPixelFormat(INT32 WantColorBits, INT32 WantStencilBits, INT32 WantDepth
void SetModelView(GLint w, GLint h);
void SetStates(void);
FUNCMATH float byteasfloat(UINT8 fbyte);
#ifdef USE_PALETTED_TEXTURE
extern PFNGLCOLORTABLEEXTPROC glColorTableEXT;
extern GLubyte palette_tex[256*3];
#endif
#ifndef GL_EXT_texture_filter_anisotropic
#define GL_TEXTURE_MAX_ANISOTROPY_EXT 0x84FE
@ -120,6 +113,10 @@ typedef void (APIENTRY * PFNglGetIntegerv) (GLenum pname, GLint *params);
extern PFNglGetIntegerv pglGetIntegerv;
typedef const GLubyte* (APIENTRY * PFNglGetString) (GLenum name);
extern PFNglGetString pglGetString;
#if 0
typedef void (APIENTRY * PFNglEnableClientState) (GLenum cap); // redefined in r_opengl.c
static PFNglEnableClientState pglEnableClientState;
#endif
#endif
// ==========================================================================

View File

@ -0,0 +1,52 @@
/*
From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com )
An experimental work-in-progress.
Donated to Sonic Team Junior and adapted to work with
Sonic Robo Blast 2. The license of this code matches whatever
the licensing is for Sonic Robo Blast 2.
*/
#ifndef _R_VBO_H_
#define _R_VBO_H_
typedef struct
{
float x, y, z; // Vertex
float nx, ny, nz; // Normal
float s0, t0; // Texcoord0
} vbo32_t;
typedef struct
{
float x, y, z; // Vertex
float s0, t0; // Texcoord0
unsigned char r, g, b, a; // Color
float pad[2]; // Pad
} vbo2d32_t;
typedef struct
{
float x, y; // Vertex
float s0, t0; // Texcoord0
} vbofont_t;
typedef struct
{
short x, y, z; // Vertex
char nx, ny, nz; // Normal
char tanx, tany, tanz; // Tangent
float s0, t0; // Texcoord0
} vbotiny_t;
typedef struct
{
float x, y, z; // Vertex
float nx, ny, nz; // Normal
float s0, t0; // Texcoord0
float s1, t1; // Texcoord1
float s2, t2; // Texcoord2
float tan0, tan1, tan2; // Tangent
unsigned char r, g, b, a; // Color
} vbo64_t;
#endif

230
src/hardware/u_list.c Normal file
View File

@ -0,0 +1,230 @@
/*
From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com )
An experimental work-in-progress.
Donated to Sonic Team Junior and adapted to work with
Sonic Robo Blast 2. The license of this code matches whatever
the licensing is for Sonic Robo Blast 2.
*/
#include "u_list.h"
#include "../z_zone.h"
// Utility for managing
// structures in a linked
// list.
//
// Struct must have "next" and "prev" pointers
// as its first two variables.
//
//
// ListAdd
//
// Adds an item to the list
//
void ListAdd(void *pItem, listitem_t **itemHead)
{
listitem_t *item = (listitem_t*)pItem;
if (*itemHead == NULL)
{
*itemHead = item;
(*itemHead)->prev = (*itemHead)->next = NULL;
}
else
{
listitem_t *tail;
tail = *itemHead;
while (tail->next != NULL)
tail = tail->next;
tail->next = item;
tail->next->prev = tail;
item->next = NULL;
}
}
//
// ListAddFront
//
// Adds an item to the front of the list
// (This is much faster)
//
void ListAddFront(void *pItem, listitem_t **itemHead)
{
listitem_t *item = (listitem_t*)pItem;
if (*itemHead == NULL)
{
*itemHead = item;
(*itemHead)->prev = (*itemHead)->next = NULL;
}
else
{
(*itemHead)->prev = item;
item->next = (*itemHead);
item->prev = NULL;
*itemHead = item;
}
}
//
// ListAddBefore
//
// Adds an item before the item specified in the list
//
void ListAddBefore(void *pItem, void *pSpot, listitem_t **itemHead)
{
listitem_t *item = (listitem_t*)pItem;
listitem_t *spot = (listitem_t*)pSpot;
listitem_t *prev = spot->prev;
if (!prev)
ListAddFront(pItem, itemHead);
else
{
item->next = spot;
spot->prev = item;
item->prev = prev;
prev->next = item;
}
}
//
// ListAddAfter
//
// Adds an item after the item specified in the list
//
void ListAddAfter(void *pItem, void *pSpot, listitem_t **itemHead)
{
listitem_t *item = (listitem_t*)pItem;
listitem_t *spot = (listitem_t*)pSpot;
listitem_t *next = spot->next;
if (!next)
ListAdd(pItem, itemHead);
else
{
item->prev = spot;
spot->next = item;
item->next = next;
next->prev = item;
}
}
//
// ListRemove
//
// Take an item out of the list and free its memory.
//
void ListRemove(void *pItem, listitem_t **itemHead)
{
listitem_t *item = (listitem_t*)pItem;
if (item == *itemHead) // Start of list
{
*itemHead = item->next;
if (*itemHead)
(*itemHead)->prev = NULL;
}
else if (item->next == NULL) // end of list
{
item->prev->next = NULL;
}
else // Somewhere in between
{
item->prev->next = item->next;
item->next->prev = item->prev;
}
Z_Free (item);
}
//
// ListRemoveAll
//
// Removes all items from the list, freeing their memory.
//
void ListRemoveAll(listitem_t **itemHead)
{
listitem_t *item;
listitem_t *next;
for (item = *itemHead; item; item = next)
{
next = item->next;
ListRemove(item, itemHead);
}
}
//
// ListRemoveNoFree
//
// Take an item out of the list, but don't free its memory.
//
void ListRemoveNoFree(void *pItem, listitem_t **itemHead)
{
listitem_t *item = (listitem_t*)pItem;
if (item == *itemHead) // Start of list
{
*itemHead = item->next;
if (*itemHead)
(*itemHead)->prev = NULL;
}
else if (item->next == NULL) // end of list
{
item->prev->next = NULL;
}
else // Somewhere in between
{
item->prev->next = item->next;
item->next->prev = item->prev;
}
}
//
// ListGetCount
//
// Counts the # of items in a list
// Should not be used in performance-minded code
//
unsigned int ListGetCount(void *itemHead)
{
listitem_t *item = (listitem_t*)itemHead;
unsigned int count = 0;
for (; item; item = item->next)
count++;
return count;
}
//
// ListGetByIndex
//
// Gets an item in the list by its index
// Should not be used in performance-minded code
//
listitem_t *ListGetByIndex(void *itemHead, unsigned int index)
{
listitem_t *head = (listitem_t*)itemHead;
unsigned int count = 0;
listitem_t *node;
for (node = head; node; node = node->next)
{
if (count == index)
return node;
count++;
}
return NULL;
}

29
src/hardware/u_list.h Normal file
View File

@ -0,0 +1,29 @@
/*
From the 'Wizard2' engine by Spaddlewit Inc. ( http://www.spaddlewit.com )
An experimental work-in-progress.
Donated to Sonic Team Junior and adapted to work with
Sonic Robo Blast 2. The license of this code matches whatever
the licensing is for Sonic Robo Blast 2.
*/
#ifndef _U_LIST_H_
#define _U_LIST_H_
typedef struct listitem_s
{
struct listitem_s *next;
struct listitem_s *prev;
} listitem_t;
void ListAdd(void *pItem, listitem_t **itemHead);
void ListAddFront(void *pItem, listitem_t **itemHead);
void ListAddBefore(void *pItem, void *pSpot, listitem_t **itemHead);
void ListAddAfter(void *pItem, void *pSpot, listitem_t **itemHead);
void ListRemove(void *pItem, listitem_t **itemHead);
void ListRemoveAll(listitem_t **itemHead);
void ListRemoveNoFree(void *pItem, listitem_t **itemHead);
unsigned int ListGetCount(void *itemHead);
listitem_t *ListGetByIndex(void *itemHead, unsigned int index);
#endif

View File

@ -39,7 +39,7 @@
#include "am_map.h"
#include "d_main.h"
#include "p_local.h" // camera, camera2, camera3, camera4
#include "p_local.h" // camera[]
#include "p_tick.h"
#ifdef HWRENDER
@ -793,14 +793,17 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
case SKINCOLOR_GREY:
case SKINCOLOR_NICKEL:
case SKINCOLOR_BLACK:
case SKINCOLOR_SKUNK:
case SKINCOLOR_JET:
cstart = "\x86"; // V_GRAYMAP
break;
case SKINCOLOR_SEPIA:
case SKINCOLOR_BEIGE:
case SKINCOLOR_WALNUT:
case SKINCOLOR_BROWN:
case SKINCOLOR_LEATHER:
case SKINCOLOR_RUST:
case SKINCOLOR_WRISTWATCH:
cstart = "\x8e"; // V_BROWNMAP
break;
case SKINCOLOR_FAIRY:
@ -808,10 +811,12 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
case SKINCOLOR_PINK:
case SKINCOLOR_ROSE:
case SKINCOLOR_BRICK:
case SKINCOLOR_LEMONADE:
case SKINCOLOR_BUBBLEGUM:
case SKINCOLOR_LILAC:
cstart = "\x8d"; // V_PINKMAP
break;
case SKINCOLOR_CINNAMON:
case SKINCOLOR_RUBY:
case SKINCOLOR_RASPBERRY:
case SKINCOLOR_CHERRY:
@ -842,14 +847,18 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
case SKINCOLOR_ROYAL:
case SKINCOLOR_BRONZE:
case SKINCOLOR_COPPER:
case SKINCOLOR_THUNDER:
cstart = "\x8A"; // V_GOLDMAP
break;
case SKINCOLOR_POPCORN:
case SKINCOLOR_QUARRY:
case SKINCOLOR_YELLOW:
case SKINCOLOR_MUSTARD:
case SKINCOLOR_CROCODILE:
case SKINCOLOR_OLIVE:
cstart = "\x82"; // V_YELLOWMAP
break;
case SKINCOLOR_ARTICHOKE:
case SKINCOLOR_VOMIT:
case SKINCOLOR_GARDEN:
case SKINCOLOR_TEA:
@ -872,6 +881,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
cstart = "\x83"; // V_GREENMAP
break;
case SKINCOLOR_CARIBBEAN:
case SKINCOLOR_AZURE:
case SKINCOLOR_AQUA:
case SKINCOLOR_TEAL:
case SKINCOLOR_CYAN:
@ -881,6 +891,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
case SKINCOLOR_SAPPHIRE:
cstart = "\x88"; // V_SKYMAP
break;
case SKINCOLOR_PIGEON:
case SKINCOLOR_PLATINUM:
case SKINCOLOR_STEEL:
cstart = "\x8c"; // V_STEELMAP
@ -1987,7 +1998,7 @@ static void HU_DrawChat_Old(void)
if (!i)
return;
if ((netgame || multiplayer) && players[displayplayer].spectator)
if ((netgame || multiplayer) && players[displayplayers[0]].spectator)
return;
#ifdef HWRENDER
@ -2014,7 +2025,7 @@ static inline void HU_DrawCrosshair2(void)
if (!i)
return;
if ((netgame || multiplayer) && players[secondarydisplayplayer].spectator)
if ((netgame || multiplayer) && players[displayplayers[1]].spectator)
return;
#ifdef HWRENDER
@ -2061,7 +2072,7 @@ static inline void HU_DrawCrosshair3(void)
if (!i)
return;
if ((netgame || multiplayer) && players[thirddisplayplayer].spectator)
if ((netgame || multiplayer) && players[displayplayers[2]].spectator)
return;
#ifdef HWRENDER
@ -2098,7 +2109,7 @@ static inline void HU_DrawCrosshair4(void)
if (!i)
return;
if ((netgame || multiplayer) && players[fourthdisplayplayer].spectator)
if ((netgame || multiplayer) && players[displayplayers[3]].spectator)
return;
#ifdef HWRENDER
@ -2199,8 +2210,16 @@ UINT32 hu_demolap;
static void HU_DrawDemoInfo(void)
{
if (!multiplayer)/* netreplay */
{
V_DrawCenteredString((BASEVIDWIDTH/2), BASEVIDHEIGHT-40, 0, M_GetText("Replay:"));
V_DrawCenteredString((BASEVIDWIDTH/2), BASEVIDHEIGHT-32, V_ALLOWLOWERCASE, player_names[0]);
}
else
{
V_DrawRightAlignedThinString(BASEVIDWIDTH-2, BASEVIDHEIGHT-10, V_ALLOWLOWERCASE, demo.titlename);
}
if (modeattacking)
{
V_DrawRightAlignedString((BASEVIDWIDTH/2)-4, BASEVIDHEIGHT-24, V_YELLOWMAP|V_MONOSPACE, "BEST TIME:");
@ -2227,7 +2246,7 @@ static void HU_DrawDemoInfo(void)
//
// Song credits
//
static void HU_DrawSongCredits(void)
void HU_DrawSongCredits(void)
{
char *str;
INT32 len, destx;
@ -2318,10 +2337,7 @@ void HU_Drawer(void)
if (cechotimer)
HU_DrawCEcho();
if (demoplayback && hu_showscores)
HU_DrawDemoInfo();
if (!Playing()
if (!( Playing() || demo.playback )
|| gamestate == GS_INTERMISSION || gamestate == GS_CUTSCENE
|| gamestate == GS_CREDITS || gamestate == GS_EVALUATION
|| gamestate == GS_GAMEEND
@ -2341,24 +2357,28 @@ void HU_Drawer(void)
LUAh_ScoresHUD();
#endif
}
if (demo.playback)
{
HU_DrawDemoInfo();
}
}
if (gamestate != GS_LEVEL)
return;
// draw the crosshair, not when viewing demos nor with chasecam
/*if (!automapactive && !demoplayback)
/*if (!automapactive && !demo.playback)
{
if (cv_crosshair.value && !camera.chase && !players[displayplayer].spectator)
if (cv_crosshair.value && !camera[0].chase && !players[displayplayers[0]].spectator)
HU_DrawCrosshair();
if (cv_crosshair2.value && !camera2.chase && !players[secondarydisplayplayer].spectator)
if (cv_crosshair2.value && !camera[1].chase && !players[displayplayers[1]].spectator)
HU_DrawCrosshair2();
if (cv_crosshair3.value && !camera3.chase && !players[thirddisplayplayer].spectator)
if (cv_crosshair3.value && !camera[2].chase && !players[displayplayers[2]].spectator)
HU_DrawCrosshair3();
if (cv_crosshair4.value && !camera4.chase && !players[fourthdisplayplayer].spectator)
if (cv_crosshair4.value && !camera[3].chase && !players[displayplayers[3]].spectator)
HU_DrawCrosshair4();
}*/
@ -3000,7 +3020,7 @@ static void HU_DrawRankings(void)
// When you play, you quickly see your score because your name is displayed in white.
// When playing back a demo, you quickly see who's the view.
if (!splitscreen)
whiteplayer = demoplayback ? displayplayer : consoleplayer;
whiteplayer = demo.playback ? displayplayers[0] : consoleplayer;
scorelines = 0;
memset(completed, 0, sizeof (completed));

View File

@ -109,6 +109,7 @@ void HU_Start(void);
boolean HU_Responder(event_t *ev);
void HU_Ticker(void);
void HU_DrawSongCredits(void);
void HU_Drawer(void);
char HU_dequeueChatChar(void);
void HU_Erase(void);

View File

@ -813,6 +813,8 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
#endif
#endif
mysockaddr_t straddr;
struct sockaddr_in sin;
socklen_t len = sizeof(sin);
if (s == (SOCKET_TYPE)ERRSOCKET)
return (SOCKET_TYPE)ERRSOCKET;
@ -906,12 +908,16 @@ static SOCKET_TYPE UDP_Bind(int family, struct sockaddr *addr, socklen_t addrlen
CONS_Printf(M_GetText("Network system buffer set to: %dKb\n"), opt>>10);
}
if (getsockname(s, (struct sockaddr *)&sin, &len) == -1)
CONS_Alert(CONS_WARNING, M_GetText("Failed to get port number\n"));
else
current_port = (UINT16)ntohs(sin.sin_port);
return s;
}
static boolean UDP_Socket(void)
{
const char *sock_port = NULL;
size_t s;
struct my_addrinfo *ai, *runp, hints;
int gaie;
@ -933,20 +939,11 @@ static boolean UDP_Socket(void)
hints.ai_socktype = SOCK_DGRAM;
hints.ai_protocol = IPPROTO_UDP;
if (M_CheckParm("-clientport"))
{
if (!M_IsNextParm())
I_Error("syntax: -clientport <portnum>");
sock_port = M_GetNextParm();
}
else
sock_port = port_name;
if (M_CheckParm("-bindaddr"))
{
while (M_IsNextParm())
{
gaie = I_getaddrinfo(M_GetNextParm(), sock_port, &hints, &ai);
gaie = I_getaddrinfo(M_GetNextParm(), port_name, &hints, &ai);
if (gaie == 0)
{
runp = ai;
@ -967,7 +964,7 @@ static boolean UDP_Socket(void)
}
else
{
gaie = I_getaddrinfo("0.0.0.0", sock_port, &hints, &ai);
gaie = I_getaddrinfo("0.0.0.0", port_name, &hints, &ai);
if (gaie == 0)
{
runp = ai;
@ -982,8 +979,8 @@ static boolean UDP_Socket(void)
#ifdef HAVE_MINIUPNPC
if (UPNP_support)
{
I_UPnP_rem(sock_port, "UDP");
I_UPnP_add(NULL, sock_port, "UDP");
I_UPnP_rem(port_name, "UDP");
I_UPnP_add(NULL, port_name, "UDP");
}
#endif
}
@ -1000,7 +997,7 @@ static boolean UDP_Socket(void)
{
while (M_IsNextParm())
{
gaie = I_getaddrinfo(M_GetNextParm(), sock_port, &hints, &ai);
gaie = I_getaddrinfo(M_GetNextParm(), port_name, &hints, &ai);
if (gaie == 0)
{
runp = ai;
@ -1021,7 +1018,7 @@ static boolean UDP_Socket(void)
}
else
{
gaie = I_getaddrinfo("::", sock_port, &hints, &ai);
gaie = I_getaddrinfo("::", port_name, &hints, &ai);
if (gaie == 0)
{
runp = ai;
@ -1478,14 +1475,15 @@ boolean I_InitTcpNetwork(void)
if (!I_InitTcpDriver())
return false;
if (M_CheckParm("-udpport"))
if (M_CheckParm("-port"))
// Combined -udpport and -clientport into -port
// As it was really redundant having two seperate parms that does the same thing
{
if (M_IsNextParm())
strcpy(port_name, M_GetNextParm());
else
strcpy(port_name, "0");
}
current_port = (UINT16)atoi(port_name);
// parse network game options,
if (M_CheckParm("-server") || dedicated)

View File

@ -49,22 +49,28 @@ const char *KartColor_Names[MAXSKINCOLORS] =
"Grey", // SKINCOLOR_GREY
"Nickel", // SKINCOLOR_NICKEL
"Black", // SKINCOLOR_BLACK
"Skunk", // SKINCOLOR_SKUNK
"Fairy", // SKINCOLOR_FAIRY
"Popcorn", // SKINCOLOR_POPCORN
"Artichoke", // SKINCOLOR_ARTICHOKE
"Pigeon", // SKINCOLOR_PIGEON
"Sepia", // SKINCOLOR_SEPIA
"Beige", // SKINCOLOR_BEIGE
"Walnut", // SKINCOLOR_WALNUT
"Brown", // SKINCOLOR_BROWN
"Leather", // SKINCOLOR_LEATHER
"Salmon", // SKINCOLOR_SALMON
"Pink", // SKINCOLOR_PINK
"Rose", // SKINCOLOR_ROSE
"Brick", // SKINCOLOR_BRICK
"Cinnamon", // SKINCOLOR_CINNAMON
"Ruby", // SKINCOLOR_RUBY
"Raspberry", // SKINCOLOR_RASPBERRY
"Cherry", // SKINCOLOR_CHERRY
"Red", // SKINCOLOR_RED
"Crimson", // SKINCOLOR_CRIMSON
"Maroon", // SKINCOLOR_MAROON
"Lemonade", // SKINCOLOR_LEMONADE
"Flame", // SKINCOLOR_FLAME
"Scarlet", // SKINCOLOR_SCARLET
"Ketchup", // SKINCOLOR_KETCHUP
@ -83,8 +89,10 @@ const char *KartColor_Names[MAXSKINCOLORS] =
"Royal", // SKINCOLOR_ROYAL
"Bronze", // SKINCOLOR_BRONZE
"Copper", // SKINCOLOR_COPPER
"Quarry", // SKINCOLOR_QUARRY
"Yellow", // SKINCOLOR_YELLOW
"Mustard", // SKINCOLOR_MUSTARD
"Crocodile", // SKINCOLOR_CROCODILE
"Olive", // SKINCOLOR_OLIVE
"Vomit", // SKINCOLOR_VOMIT
"Garden", // SKINCOLOR_GARDEN
@ -104,6 +112,7 @@ const char *KartColor_Names[MAXSKINCOLORS] =
"Plague", // SKINCOLOR_PLAGUE
"Algae", // SKINCOLOR_ALGAE
"Caribbean", // SKINCOLOR_CARIBBEAN
"Azure", // SKINCOLOR_AZURE
"Aqua", // SKINCOLOR_AQUA
"Teal", // SKINCOLOR_TEAL
"Cyan", // SKINCOLOR_CYAN
@ -113,7 +122,9 @@ const char *KartColor_Names[MAXSKINCOLORS] =
"Platinum", // SKINCOLOR_PLATINUM
"Slate", // SKINCOLOR_SLATE
"Steel", // SKINCOLOR_STEEL
"Thunder", // SKINCOLOR_THUNDER
"Rust", // SKINCOLOR_RUST
"Wristwatch", // SKINCOLOR_WRISTWATCH
"Jet", // SKINCOLOR_JET
"Sapphire", // SKINCOLOR_SAPPHIRE
"Periwinkle", // SKINCOLOR_PERIWINKLE
@ -144,22 +155,28 @@ const UINT8 KartColor_Opposite[MAXSKINCOLORS*2] =
SKINCOLOR_GREY,8, // SKINCOLOR_GREY
SKINCOLOR_SILVER,8, // SKINCOLOR_NICKEL
SKINCOLOR_WHITE,8, // SKINCOLOR_BLACK
SKINCOLOR_CAMOUFLAGE,8, // SKINCOLOR_FAIRY
SKINCOLOR_BUBBLEGUM,8, // SKINCOLOR_POPCORN
SKINCOLOR_SKUNK,8, // SKINCOLOR_SKUNK
SKINCOLOR_ARTICHOKE,12, // SKINCOLOR_FAIRY
SKINCOLOR_PIGEON,12, // SKINCOLOR_POPCORN
SKINCOLOR_FAIRY,12, // SKINCOLOR_ARTICHOKE
SKINCOLOR_POPCORN,12, // SKINCOLOR_PIGEON
SKINCOLOR_LEATHER,6, // SKINCOLOR_SEPIA
SKINCOLOR_BROWN,2, // SKINCOLOR_BEIGE
SKINCOLOR_CAMOUFLAGE,8, // SKINCOLOR_WALNUT
SKINCOLOR_BEIGE,8, // SKINCOLOR_BROWN
SKINCOLOR_SEPIA,8, // SKINCOLOR_LEATHER
SKINCOLOR_TEA,8, // SKINCOLOR_SALMON
SKINCOLOR_PISTACHIO,8, // SKINCOLOR_PINK
SKINCOLOR_MOSS,8, // SKINCOLOR_ROSE
SKINCOLOR_RUST,8, // SKINCOLOR_BRICK
SKINCOLOR_WRISTWATCH,6, // SKINCOLOR_CINNAMON
SKINCOLOR_SAPPHIRE,8, // SKINCOLOR_RUBY
SKINCOLOR_MINT,8, // SKINCOLOR_RASPBERRY
SKINCOLOR_HANDHELD,10, // SKINCOLOR_CHERRY
SKINCOLOR_GREEN,6, // SKINCOLOR_RED
SKINCOLOR_PINETREE,6, // SKINCOLOR_CRIMSON
SKINCOLOR_TOXIC,8, // SKINCOLOR_MAROON
SKINCOLOR_THUNDER,8, // SKINCOLOR_LEMONADE
SKINCOLOR_CARIBBEAN,10, // SKINCOLOR_FLAME
SKINCOLOR_ALGAE,10, // SKINCOLOR_SCARLET
SKINCOLOR_MUSTARD,10, // SKINCOLOR_KETCHUP
@ -178,8 +195,10 @@ const UINT8 KartColor_Opposite[MAXSKINCOLORS*2] =
SKINCOLOR_PLATINUM,6, // SKINCOLOR_ROYAL
SKINCOLOR_STEEL,8, // SKINCOLOR_BRONZE
SKINCOLOR_CREAM,6, // SKINCOLOR_COPPER
SKINCOLOR_AZURE,8, // SKINCOLOR_QUARRY
SKINCOLOR_AQUA,8, // SKINCOLOR_YELLOW
SKINCOLOR_KETCHUP,8, // SKINCOLOR_MUSTARD
SKINCOLOR_BUBBLEGUM,8, // SKINCOLOR_CROCODILE
SKINCOLOR_TEAL,8, // SKINCOLOR_OLIVE
SKINCOLOR_ROBOHOOD,8, // SKINCOLOR_VOMIT
SKINCOLOR_LAVENDER,6, // SKINCOLOR_GARDEN
@ -188,7 +207,7 @@ const UINT8 KartColor_Opposite[MAXSKINCOLORS*2] =
SKINCOLOR_SALMON,8, // SKINCOLOR_TEA
SKINCOLOR_PINK,6, // SKINCOLOR_PISTACHIO
SKINCOLOR_ROSE,8, // SKINCOLOR_MOSS
SKINCOLOR_FAIRY,10, // SKINCOLOR_CAMOUFLAGE
SKINCOLOR_WALNUT,8, // SKINCOLOR_CAMOUFLAGE
SKINCOLOR_VOMIT,8, // SKINCOLOR_ROBOHOOD
SKINCOLOR_RASPBERRY,8, // SKINCOLOR_MINT
SKINCOLOR_RED,8, // SKINCOLOR_GREEN
@ -199,6 +218,7 @@ const UINT8 KartColor_Opposite[MAXSKINCOLORS*2] =
SKINCOLOR_NOVA,8, // SKINCOLOR_PLAGUE
SKINCOLOR_SCARLET,10, // SKINCOLOR_ALGAE
SKINCOLOR_FLAME,8, // SKINCOLOR_CARIBBEAN
SKINCOLOR_QUARRY,8, // SKINCOLOR_AZURE
SKINCOLOR_YELLOW,8, // SKINCOLOR_AQUA
SKINCOLOR_OLIVE,8, // SKINCOLOR_TEAL
SKINCOLOR_PEACH,8, // SKINCOLOR_CYAN
@ -208,7 +228,9 @@ const UINT8 KartColor_Opposite[MAXSKINCOLORS*2] =
SKINCOLOR_ROYAL,8, // SKINCOLOR_PLATINUM
SKINCOLOR_GOLD,10, // SKINCOLOR_SLATE
SKINCOLOR_BRONZE,10, // SKINCOLOR_STEEL
SKINCOLOR_LEMONADE,8, // SKINCOLOR_THUNDER
SKINCOLOR_BRICK,10, // SKINCOLOR_RUST
SKINCOLOR_CINNAMON,8, // SKINCOLOR_WRISTWATCH
SKINCOLOR_BURGUNDY,8, // SKINCOLOR_JET
SKINCOLOR_RUBY,6, // SKINCOLOR_SAPPHIRE
SKINCOLOR_CREAMSICLE,8, // SKINCOLOR_PERIWINKLE
@ -219,7 +241,7 @@ const UINT8 KartColor_Opposite[MAXSKINCOLORS*2] =
SKINCOLOR_SUNSET,10, // SKINCOLOR_MOONSLAM
SKINCOLOR_MAUVE,10, // SKINCOLOR_ULTRAVIOLET
SKINCOLOR_DAWN,6, // SKINCOLOR_DUSK
SKINCOLOR_POPCORN,12, // SKINCOLOR_BUBBLEGUM
SKINCOLOR_CROCODILE,8, // SKINCOLOR_BUBBLEGUM
SKINCOLOR_EMERALD,8, // SKINCOLOR_PURPLE
SKINCOLOR_PASTEL,11, // SKINCOLOR_FUCHSIA
SKINCOLOR_MAROON,8, // SKINCOLOR_TOXIC
@ -237,27 +259,33 @@ UINT8 colortranslations[MAXTRANSLATIONS][16] = {
{ 1, 3, 5, 7, 9, 11, 13, 15, 17, 19, 21, 23, 25, 27, 29, 31}, // SKINCOLOR_GREY
{ 3, 5, 8, 11, 15, 17, 19, 21, 23, 24, 25, 26, 27, 29, 30, 31}, // SKINCOLOR_NICKEL
{ 4, 7, 11, 15, 20, 22, 24, 27, 28, 28, 28, 29, 29, 30, 30, 31}, // SKINCOLOR_BLACK
{120, 120, 0, 2, 4, 10, 16, 22, 23, 24, 25, 26, 27, 28, 29, 31}, // SKINCOLOR_SKUNK
{120, 120, 121, 121, 122, 123, 10, 14, 16, 18, 20, 22, 24, 26, 28, 31}, // SKINCOLOR_FAIRY
{120, 96, 97, 98, 99, 71, 32, 11, 13, 16, 18, 21, 23, 26, 28, 31}, // SKINCOLOR_POPCORN
{ 97, 176, 177, 162, 163, 179, 12, 14, 16, 18, 20, 22, 24, 26, 28, 31}, // SKINCOLOR_ARTICHOKE
{ 0, 208, 209, 211, 226, 202, 14, 15, 17, 19, 21, 23, 25, 27, 29, 31}, // SKINCOLOR_PIGEON
{ 0, 1, 3, 5, 7, 9, 34, 36, 38, 40, 42, 44, 60, 61, 62, 63}, // SKINCOLOR_SEPIA
{120, 65, 67, 69, 32, 34, 36, 38, 40, 42, 44, 45, 46, 47, 62, 63}, // SKINCOLOR_BEIGE
{ 3, 6, 32, 33, 35, 37, 51, 52, 54, 55, 57, 58, 60, 61, 63, 30}, // SKINCOLOR_WALNUT
{ 67, 70, 73, 76, 48, 49, 51, 53, 54, 56, 58, 59, 61, 63, 29, 30}, // SKINCOLOR_BROWN
{ 72, 76, 48, 51, 53, 55, 57, 59, 61, 63, 28, 28, 29, 29, 30, 31}, // SKINCOLOR_LEATHER
{120, 120, 120, 121, 121, 122, 123, 124, 126, 127, 129, 131, 133, 135, 137, 139}, // SKINCOLOR_SALMON
{120, 121, 121, 122, 144, 145, 146, 147, 148, 149, 150, 151, 134, 136, 138, 140}, // SKINCOLOR_PINK
{144, 145, 146, 147, 148, 149, 150, 151, 134, 135, 136, 137, 138, 139, 140, 141}, // SKINCOLOR_ROSE
{ 64, 67, 70, 73, 146, 147, 148, 150, 118, 118, 119, 119, 156, 159, 141, 143}, // SKINCOLOR_BRICK
{ 68, 75, 48, 50, 52, 94, 152, 136, 137, 138, 139, 140, 141, 142, 143, 31}, // SKINCOLOR_CINNAMON
{120, 121, 144, 145, 147, 149, 132, 133, 134, 136, 198, 198, 199, 255, 30, 31}, // SKINCOLOR_RUBY
{120, 121, 122, 123, 124, 125, 126, 127, 128, 130, 131, 134, 136, 137, 139, 140}, // SKINCOLOR_RASPBERRY
{120, 65, 67, 69, 71, 124, 125, 127, 132, 133, 135, 136, 138, 139, 140, 141}, // SKINCOLOR_CHERRY
{122, 123, 124, 126, 129, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142}, // SKINCOLOR_RED
{123, 125, 128, 131, 133, 135, 136, 138, 140, 140, 141, 141, 142, 142, 143, 31}, // SKINCOLOR_CRIMSON
{123, 124, 126, 128, 132, 135, 137, 27, 28, 28, 28, 29, 29, 30, 30, 31}, // SKINCOLOR_MAROON
{120, 96, 97, 98, 99, 65, 122, 144, 123, 124, 147, 149, 151, 153, 156, 159}, // SKINCOLOR_LEMONADE
{120, 97, 112, 113, 113, 85, 87, 126, 149, 150, 151, 252, 253, 254, 255, 29}, // SKINCOLOR_FLAME
{ 99, 113, 113, 84, 85, 87, 126, 128, 130, 196, 197, 198, 199, 240, 243, 246}, // SKINCOLOR_SCARLET
{103, 113, 113, 84, 85, 88, 127, 130, 131, 133, 134, 136, 138, 139, 141, 143}, // SKINCOLOR_KETCHUP
{120, 121, 122, 123, 124, 147, 147, 148, 90, 91, 92, 93, 94, 95, 152, 154}, // SKINCOLOR_DAWN
{ 98, 112, 113, 84, 85, 87, 89, 149, 150, 251, 252, 206, 238, 240, 243, 246}, // SKINCOLOR_SUNSET
{120, 121, 122, 123, 124, 147, 148, 91, 93, 95, 152, 154, 156, 159, 141, 143}, // SKINCOLOR_DAWN
{ 98, 112, 113, 84, 85, 87, 89, 149, 150, 251, 251, 205, 206, 207, 29, 31}, // SKINCOLOR_SUNSET
{120, 120, 80, 80, 81, 82, 83, 83, 84, 85, 86, 88, 89, 91, 93, 95}, // SKINCOLOR_CREAMSICLE
{ 80, 81, 82, 83, 84, 85, 86, 88, 89, 91, 94, 95, 154, 156, 158, 159}, // SKINCOLOR_ORANGE
{ 82, 83, 84, 85, 87, 89, 90, 92, 94, 152, 153, 155, 157, 159, 141, 142}, // SKINCOLOR_PUMPKIN
@ -266,17 +294,19 @@ UINT8 colortranslations[MAXTRANSLATIONS][16] = {
{ 98, 98, 112, 112, 113, 113, 84, 85, 87, 89, 91, 93, 95, 153, 156, 159}, // SKINCOLOR_TANGERINE
{120, 80, 66, 70, 72, 76, 148, 149, 150, 151, 153, 154, 156, 61, 62, 63}, // SKINCOLOR_PEACH
{ 64, 66, 68, 70, 72, 74, 76, 78, 48, 50, 52, 54, 56, 58, 60, 62}, // SKINCOLOR_CARAMEL
{120, 120, 96, 96, 97, 82, 84, 77, 50, 54, 57, 59, 61, 63, 29, 31}, // SKINCOLOR_CREAM
{112, 112, 112, 113, 113, 114, 114, 115, 115, 116, 116, 117, 117, 118, 118, 119}, // SKINCOLOR_GOLD
{120, 96, 96, 97, 98, 82, 84, 77, 50, 54, 57, 59, 61, 63, 29, 31}, // SKINCOLOR_CREAM
{ 96, 97, 98, 112, 113, 114, 115, 116, 117, 151, 118, 119, 157, 159, 140, 143}, // SKINCOLOR_GOLD
{ 97, 112, 113, 113, 114, 78, 53, 252, 252, 253, 253, 254, 255, 29, 30, 31}, // SKINCOLOR_ROYAL
{112, 113, 114, 115, 116, 117, 118, 119, 156, 157, 158, 159, 141, 141, 142, 143}, // SKINCOLOR_BRONZE
{120, 99, 113, 114, 116, 117, 119, 61, 63, 28, 28, 29, 29, 30, 30, 31}, // SKINCOLOR_COPPER
{ 96, 97, 98, 99, 104, 105, 106, 107, 117, 152, 154, 156, 159, 141, 142, 143}, // SKINCOLOR_QUARRY
{ 96, 97, 98, 100, 101, 102, 104, 113, 114, 115, 116, 117, 118, 119, 156, 159}, // SKINCOLOR_YELLOW
{ 96, 98, 99, 112, 113, 114, 114, 106, 106, 107, 107, 108, 108, 109, 110, 111}, // SKINCOLOR_MUSTARD
{105, 105, 105, 106, 106, 107, 107, 108, 108, 109, 109, 110, 110, 111, 111, 31}, // SKINCOLOR_OLIVE
{121, 144, 145, 72, 73, 84, 114, 115, 107, 108, 109, 183, 223, 207, 30, 246}, // SKINCOLOR_VOMIT
{120, 96, 97, 98, 176, 113, 114, 106, 115, 107, 108, 109, 110, 174, 175, 31}, // SKINCOLOR_CROCODILE
{ 98, 101, 104, 105, 106, 115, 107, 108, 182, 109, 183, 110, 174, 111, 30, 31}, // SKINCOLOR_OLIVE
{ 0, 121, 122, 144, 71, 84, 114, 115, 107, 108, 109, 183, 223, 207, 30, 246}, // SKINCOLOR_VOMIT
{ 98, 99, 112, 101, 113, 114, 106, 179, 180, 180, 181, 182, 183, 173, 174, 175}, // SKINCOLOR_GARDEN
{ 96, 97, 99, 100, 102, 104, 160, 162, 164, 166, 168, 171, 223, 223, 207, 31}, // SKINCOLOR_LIME
{120, 96, 97, 98, 99, 176, 177, 163, 164, 166, 168, 170, 223, 207, 243, 31}, // SKINCOLOR_LIME
{ 98, 104, 105, 105, 106, 167, 168, 169, 170, 171, 172, 173, 174, 175, 30, 31}, // SKINCOLOR_HANDHELD
{120, 120, 176, 176, 176, 177, 177, 178, 178, 179, 179, 180, 180, 181, 182, 183}, // SKINCOLOR_TEA
{120, 120, 176, 176, 177, 177, 178, 179, 165, 166, 167, 168, 169, 170, 171, 172}, // SKINCOLOR_PISTACHIO
@ -289,9 +319,10 @@ UINT8 colortranslations[MAXTRANSLATIONS][16] = {
{160, 184, 184, 185, 185, 186, 186, 187, 187, 188, 188, 189, 189, 190, 191, 175}, // SKINCOLOR_EMERALD
{160, 184, 185, 186, 187, 188, 189, 190, 191, 191, 29, 29, 30, 30, 31, 31}, // SKINCOLOR_SWAMP
{120, 120, 80, 80, 81, 177, 162, 164, 228, 228, 204, 204, 205, 205, 206, 207}, // SKINCOLOR_DREAM
{176, 160, 184, 185, 186, 187, 188, 230, 230, 206, 206, 207, 28, 29, 30, 31}, // SKINCOLOR_PLAGUE
{ 97, 176, 160, 184, 185, 186, 187, 229, 229, 205, 206, 207, 28, 29, 30, 31}, // SKINCOLOR_PLAGUE
{208, 209, 210, 211, 213, 220, 216, 167, 168, 188, 188, 189, 190, 191, 30, 31}, // SKINCOLOR_ALGAE
{120, 176, 177, 160, 185, 220, 216, 217, 221, 230, 206, 206, 254, 255, 29, 31}, // SKINCOLOR_CARIBBEAN
{120, 176, 177, 160, 185, 220, 216, 217, 229, 229, 204, 205, 206, 254, 255, 31}, // SKINCOLOR_CARIBBEAN
{120, 96, 97, 98, 177, 220, 216, 217, 218, 204, 252, 253, 254, 255, 30, 31}, // SKINCOLOR_AZURE
{120, 208, 208, 210, 212, 214, 220, 220, 220, 221, 221, 222, 222, 223, 223, 191}, // SKINCOLOR_AQUA
{210, 213, 220, 220, 220, 216, 216, 221, 221, 221, 222, 222, 223, 223, 191, 31}, // SKINCOLOR_TEAL
{120, 120, 208, 208, 209, 210, 211, 212, 213, 215, 216, 217, 218, 219, 222, 223}, // SKINCOLOR_CYAN
@ -301,7 +332,9 @@ UINT8 colortranslations[MAXTRANSLATIONS][16] = {
{120, 0, 0, 200, 200, 201, 11, 14, 17, 218, 222, 223, 238, 240, 243, 246}, // SKINCOLOR_PLATINUM
{120, 120, 200, 200, 200, 201, 201, 201, 202, 202, 202, 203, 204, 205, 206, 207}, // SKINCOLOR_SLATE
{120, 200, 200, 201, 201, 202, 202, 203, 203, 204, 204, 205, 205, 206, 207, 31}, // SKINCOLOR_STEEL
{ 96, 97, 98, 112, 113, 114, 11, 203, 204, 205, 205, 237, 239, 241, 243, 246}, // SKINCOLOR_THUNDER
{ 64, 66, 68, 70, 32, 34, 36, 203, 204, 205, 24, 25, 26, 28, 29, 31}, // SKINCOLOR_RUST
{ 81, 72, 76, 48, 51, 55, 252, 205, 205, 206, 240, 241, 242, 243, 244, 246}, // SKINCOLOR_WRISTWATCH
{225, 226, 227, 228, 229, 205, 205, 206, 207, 207, 28, 28, 29, 29, 30, 31}, // SKINCOLOR_JET
{208, 209, 211, 213, 215, 217, 229, 230, 232, 234, 236, 238, 240, 242, 244, 246}, // SKINCOLOR_SAPPHIRE
{120, 120, 224, 225, 226, 202, 227, 228, 229, 230, 231, 233, 235, 237, 239, 241}, // SKINCOLOR_PERIWINKLE
@ -318,9 +351,10 @@ UINT8 colortranslations[MAXTRANSLATIONS][16] = {
{120, 120, 176, 176, 177, 6, 8, 10, 249, 250, 196, 197, 198, 199, 143, 31}, // SKINCOLOR_TOXIC
{ 96, 97, 98, 112, 113, 73, 146, 248, 249, 251, 205, 205, 206, 207, 29, 31}, // SKINCOLOR_MAUVE
{121, 145, 192, 248, 249, 250, 251, 252, 252, 253, 253, 254, 254, 255, 30, 31}, // SKINCOLOR_LAVENDER
{144, 248, 249, 250, 251, 252, 253, 254, 255, 255, 29, 29, 30, 30, 31, 31}, // SKINCOLOR_BYZANTIUM
{201, 248, 249, 250, 251, 252, 253, 254, 255, 255, 29, 29, 30, 30, 31, 31}, // SKINCOLOR_BYZANTIUM
{144, 145, 146, 147, 148, 149, 150, 251, 251, 252, 252, 253, 254, 255, 29, 30}, // SKINCOLOR_POMEGRANATE
{120, 120, 120, 121, 121, 122, 122, 123, 192, 248, 249, 250, 251, 252, 253, 254}, // SKINCOLOR_LILAC
{120, 120, 120, 120, 120, 120, 120, 120, 120, 120, 96, 100, 104, 113, 116, 119}, // SKINCOLOR_SUPER1
{120, 120, 120, 120, 120, 120, 120, 120, 96, 98, 101, 104, 113, 115, 117, 119}, // SKINCOLOR_SUPER2
{120, 120, 120, 120, 120, 120, 96, 98, 100, 102, 104, 113, 114, 116, 117, 119}, // SKINCOLOR_SUPER3
@ -1028,34 +1062,14 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
}
// This makes the roulette produce the random noises.
if ((player->kartstuff[k_itemroulette] % 3) == 1 && P_IsLocalPlayer(player))
if ((player->kartstuff[k_itemroulette] % 3) == 1 && P_IsDisplayPlayer(player))
{
#define PLAYROULETTESND S_StartSound(NULL, sfx_itrol1 + ((player->kartstuff[k_itemroulette] / 3) % 8));
if (splitscreen)
#define PLAYROULETTESND S_StartSound(NULL, sfx_itrol1 + ((player->kartstuff[k_itemroulette] / 3) % 8))
for (i = 0; i <= splitscreen; i++)
{
if (players[displayplayer].kartstuff[k_itemroulette])
{
if (player == &players[displayplayer])
if (player == &players[displayplayers[i]] && players[displayplayers[i]].kartstuff[k_itemroulette])
PLAYROULETTESND;
}
else if (players[secondarydisplayplayer].kartstuff[k_itemroulette])
{
if (player == &players[secondarydisplayplayer])
PLAYROULETTESND;
}
else if (players[thirddisplayplayer].kartstuff[k_itemroulette] && splitscreen > 1)
{
if (player == &players[thirddisplayplayer])
PLAYROULETTESND;
}
else if (players[fourthdisplayplayer].kartstuff[k_itemroulette] && splitscreen > 2)
{
if (player == &players[fourthdisplayplayer])
PLAYROULETTESND;
}
}
else
PLAYROULETTESND;
#undef PLAYROULETTESND
}
@ -1082,7 +1096,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
//player->kartstuff[k_itemblinkmode] = 1;
player->kartstuff[k_itemroulette] = 0;
player->kartstuff[k_roulettetype] = 0;
if (P_IsLocalPlayer(player))
if (P_IsDisplayPlayer(player))
S_StartSound(NULL, sfx_itrole);
return;
}
@ -1095,7 +1109,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
player->kartstuff[k_itemblinkmode] = 2;
player->kartstuff[k_itemroulette] = 0;
player->kartstuff[k_roulettetype] = 0;
if (P_IsLocalPlayer(player))
if (P_IsDisplayPlayer(player))
S_StartSound(NULL, sfx_dbgsal);
return;
}
@ -1127,7 +1141,7 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
player->kartstuff[k_itemamount] = 1;
}
if (P_IsLocalPlayer(player))
if (P_IsDisplayPlayer(player))
S_StartSound(NULL, ((player->kartstuff[k_roulettetype] == 1) ? sfx_itrolk : (mashed ? sfx_itrolm : sfx_itrolf)));
player->kartstuff[k_itemblink] = TICRATE;
@ -1568,7 +1582,7 @@ void K_RespawnChecker(player_t *player)
if (!P_IsObjectOnGround(player->mo) && !mapreset)
{
player->powers[pw_flashing] = 2;
player->powers[pw_flashing] = K_GetKartFlashing(player);
// Sal: The old behavior was stupid and prone to accidental usage.
// Let's rip off Mania instead, and turn this into a Drop Dash!
@ -1634,7 +1648,7 @@ void K_KartMoveAnimation(player_t *player)
P_SetPlayerMobjState(player->mo, S_KART_DRIFT1_R);
}
// Run frames - S_KART_RUN1 S_KART_RUN1_L S_KART_RUN1_R
else if (player->speed > FixedMul(player->runspeed, player->mo->scale))
else if (player->speed > (20*player->mo->scale))
{
if (cmd->driftturn < 0 && !(player->mo->state >= &states[S_KART_RUN1_R] && player->mo->state <= &states[S_KART_RUN2_R]))
P_SetPlayerMobjState(player->mo, S_KART_RUN1_R);
@ -1644,7 +1658,7 @@ void K_KartMoveAnimation(player_t *player)
P_SetPlayerMobjState(player->mo, S_KART_RUN1);
}
// Walk frames - S_KART_WALK1 S_KART_WALK1_L S_KART_WALK1_R
else if (player->speed <= FixedMul(player->runspeed, player->mo->scale))
else if (player->speed <= (20*player->mo->scale))
{
if (cmd->driftturn < 0 && !(player->mo->state >= &states[S_KART_WALK1_R] && player->mo->state <= &states[S_KART_WALK2_R]))
P_SetPlayerMobjState(player->mo, S_KART_WALK1_R);
@ -2124,11 +2138,13 @@ void K_SpinPlayer(player_t *player, mobj_t *source, INT32 type, mobj_t *inflicto
static void K_RemoveGrowShrink(player_t *player)
{
player->kartstuff[k_growshrinktimer] = 0;
player->kartstuff[k_growcancel] = 0;
if (player->mo && !P_MobjWasRemoved(player->mo))
{
if (player->kartstuff[k_growshrinktimer] > 0) // Play Shrink noise
S_StartSound(player->mo, sfx_kc59);
else if (player->kartstuff[k_growshrinktimer] < 0) // Play Grow noise
S_StartSound(player->mo, sfx_kc5a);
if (player->kartstuff[k_invincibilitytimer] == 0)
player->mo->color = player->skincolor;
@ -2138,6 +2154,9 @@ static void K_RemoveGrowShrink(player_t *player)
player->mo->destscale = (6*player->mo->destscale)/8;
}
player->kartstuff[k_growshrinktimer] = 0;
player->kartstuff[k_growcancel] = -1;
P_RestoreMusic(player);
}
@ -3526,7 +3545,6 @@ void K_DoSneaker(player_t *player, INT32 type)
{
player->pflags |= PF_ATTACKDOWN;
K_PlayBoostTaunt(player->mo);
player->powers[pw_flashing] = 0; // Stop flashing after boosting
}
}
@ -3545,8 +3563,13 @@ static void K_DoShrink(player_t *user)
continue;
if (players[i].kartstuff[k_position] < user->kartstuff[k_position])
{
//P_FlashPal(&players[i], PAL_NUKE, 10);
// Grow should get taken away.
if (players[i].kartstuff[k_growshrinktimer] > 0)
K_RemoveGrowShrink(&players[i]);
// Don't hit while invulnerable!
if (!players[i].kartstuff[k_invincibilitytimer]
else if (!players[i].kartstuff[k_invincibilitytimer]
&& players[i].kartstuff[k_growshrinktimer] <= 0
&& !players[i].kartstuff[k_hyudorotimer])
{
@ -3560,17 +3583,11 @@ static void K_DoShrink(player_t *user)
players[i].mo->destscale = (6*mapobjectscale)/8;
if (cv_kartdebugshrink.value && !modeattacking && !players[i].bot)
players[i].mo->destscale = (6*players[i].mo->destscale)/8;
}
}
// Grow should get taken away.
if (players[i].kartstuff[k_growshrinktimer] > 0)
K_RemoveGrowShrink(&players[i]);
//P_FlashPal(&players[i], PAL_NUKE, 10);
S_StartSound(players[i].mo, sfx_kc59);
}
}
}
}
}
@ -4332,10 +4349,7 @@ static void K_UpdateEngineSounds(player_t *player, ticcmd_t *cmd)
if (!playeringame[i] || !players[i].mo || players[i].spectator || players[i].exiting)
continue;
if ((i == displayplayer)
|| (i == secondarydisplayplayer && splitscreen)
|| (i == thirddisplayplayer && splitscreen > 1)
|| (i == fourthdisplayplayer && splitscreen > 2))
if (P_IsDisplayPlayer(&players[i]))
{
volumedampen += FRACUNIT; // We already know what this is gonna be, let's not waste our time.
continue;
@ -5032,6 +5046,7 @@ static void K_KartDrift(player_t *player, boolean onground)
if ((!player->kartstuff[k_sneakertimer])
|| (!player->cmd.driftturn)
|| (!player->kartstuff[k_aizdriftstrat])
|| (player->cmd.driftturn > 0) != (player->kartstuff[k_aizdriftstrat] > 0))
{
if (!player->kartstuff[k_drift])
@ -5306,6 +5321,8 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
}
// Grow Canceling
else if (player->kartstuff[k_growshrinktimer] > 0)
{
if (player->kartstuff[k_growcancel] >= 0)
{
if (cmd->buttons & BT_ATTACK)
{
@ -5316,6 +5333,14 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
else
player->kartstuff[k_growcancel] = 0;
}
else
{
if ((cmd->buttons & BT_ATTACK) || (player->pflags & PF_ATTACKDOWN))
player->kartstuff[k_growcancel] = -1;
else
player->kartstuff[k_growcancel] = 0;
}
}
else if (player->kartstuff[k_itemamount] <= 0)
{
player->kartstuff[k_itemamount] = player->kartstuff[k_itemheld] = 0;
@ -5569,6 +5594,10 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
case KITEM_GROW:
if (ATTACK_IS_DOWN && !HOLDING_ITEM && NO_HYUDORO
&& player->kartstuff[k_growshrinktimer] <= 0) // Grow holds the item box hostage
{
if (player->kartstuff[k_growshrinktimer] < 0) // If you're shrunk, then "grow" will just make you normal again.
K_RemoveGrowShrink(player);
else
{
K_PlayPowerGloatSound(player->mo);
player->mo->scalespeed = mapobjectscale/TICRATE;
@ -5580,6 +5609,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (!P_IsLocalPlayer(player))
S_StartSound(player->mo, (cv_kartinvinsfx.value ? sfx_alarmg : sfx_kgrow));
S_StartSound(player->mo, sfx_kc5a);
}
player->kartstuff[k_itemamount]--;
}
break;
@ -5674,7 +5704,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
player->kartstuff[k_curshield] = 0;
if (player->kartstuff[k_growshrinktimer] <= 0)
player->kartstuff[k_growcancel] = 0;
player->kartstuff[k_growcancel] = -1;
if (player->kartstuff[k_itemtype] == KITEM_SPB
|| player->kartstuff[k_itemtype] == KITEM_SHRINK
@ -5692,13 +5722,13 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
if (player->kartstuff[k_hyudorotimer] >= (1*TICRATE/2) && player->kartstuff[k_hyudorotimer] <= hyudorotime-(1*TICRATE/2))
{
if (player == &players[secondarydisplayplayer])
if (player == &players[displayplayers[1]])
player->mo->eflags |= MFE_DRAWONLYFORP2;
else if (player == &players[thirddisplayplayer] && splitscreen > 1)
else if (player == &players[displayplayers[2]] && splitscreen > 1)
player->mo->eflags |= MFE_DRAWONLYFORP3;
else if (player == &players[fourthdisplayplayer] && splitscreen > 2)
else if (player == &players[displayplayers[3]] && splitscreen > 2)
player->mo->eflags |= MFE_DRAWONLYFORP4;
else if (player == &players[consoleplayer])
else if (player == &players[displayplayers[0]])
player->mo->eflags |= MFE_DRAWONLYFORP1;
else
player->mo->flags2 |= MF2_DONTDRAW;
@ -5708,8 +5738,8 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
}
else
{
if (player == &players[displayplayer]
|| (player != &players[displayplayer] && (player->kartstuff[k_hyudorotimer] < (1*TICRATE/2) || player->kartstuff[k_hyudorotimer] > hyudorotime-(1*TICRATE/2))))
if (P_IsDisplayPlayer(player)
|| (!P_IsDisplayPlayer(player) && (player->kartstuff[k_hyudorotimer] < (1*TICRATE/2) || player->kartstuff[k_hyudorotimer] > hyudorotime-(1*TICRATE/2))))
{
if (leveltime & 1)
player->mo->flags2 |= MF2_DONTDRAW;
@ -5809,7 +5839,7 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
}
// Play the starting countdown sounds
if (player == &players[displayplayer]) // Don't play louder in splitscreen
if (player == &players[displayplayers[0]]) // Don't play louder in splitscreen
{
if ((leveltime == starttime-(3*TICRATE)) || (leveltime == starttime-(2*TICRATE)) || (leveltime == starttime-TICRATE))
S_StartSound(NULL, sfx_s3ka7);
@ -6694,17 +6724,17 @@ INT32 K_calcSplitFlags(INT32 snapflags)
if (splitscreen == 0)
return snapflags;
if (stplyr != &players[displayplayer])
if (stplyr != &players[displayplayers[0]])
{
if (splitscreen == 1 && stplyr == &players[secondarydisplayplayer])
if (splitscreen == 1 && stplyr == &players[displayplayers[1]])
{
splitflags |= V_SPLITSCREEN;
}
else if (splitscreen > 1)
{
if (stplyr == &players[thirddisplayplayer] || stplyr == &players[fourthdisplayplayer])
if (stplyr == &players[displayplayers[2]] || (splitscreen == 3 && stplyr == &players[displayplayers[3]]))
splitflags |= V_SPLITSCREEN;
if (stplyr == &players[secondarydisplayplayer] || stplyr == &players[fourthdisplayplayer])
if (stplyr == &players[displayplayers[1]] || (splitscreen == 3 && stplyr == &players[displayplayers[3]]))
splitflags |= V_HORZSCREEN;
}
}
@ -6859,7 +6889,7 @@ static void K_drawKartItem(void)
}
else if (stplyr->kartstuff[k_growshrinktimer] > 0)
{
if (stplyr->kartstuff[k_growcancel])
if (stplyr->kartstuff[k_growcancel] > 0)
{
itembar = stplyr->kartstuff[k_growcancel];
maxl = 26;
@ -6974,17 +7004,17 @@ static void K_drawKartItem(void)
}
else // now we're having a fun game.
{
if (stplyr == &players[displayplayer] || stplyr == &players[thirddisplayplayer]) // If we are P1 or P3...
if (stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]]) // If we are P1 or P3...
{
fx = ITEM_X;
fy = ITEM_Y;
fflags = V_SNAPTOLEFT|((stplyr == &players[thirddisplayplayer]) ? V_SPLITSCREEN : V_SNAPTOTOP); // flip P3 to the bottom.
fflags = V_SNAPTOLEFT|((stplyr == &players[displayplayers[2]]) ? V_SPLITSCREEN : V_SNAPTOTOP); // flip P3 to the bottom.
}
else // else, that means we're P2 or P4.
{
fx = ITEM2_X;
fy = ITEM2_Y;
fflags = V_SNAPTORIGHT|((stplyr == &players[fourthdisplayplayer]) ? V_SPLITSCREEN : V_SNAPTOTOP); // flip P4 to the bottom
fflags = V_SNAPTORIGHT|((stplyr == &players[displayplayers[3]]) ? V_SPLITSCREEN : V_SNAPTOTOP); // flip P4 to the bottom
flipamount = true;
}
}
@ -7116,7 +7146,7 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT16 emblemmap, UI
else if ((drawtime/TICRATE) & 1)
V_DrawKartString(TX, TY+3, splitflags, va("99'59\"99"));
if (emblemmap && (modeattacking || (mode == 1)) && !demoplayback) // emblem time!
if (emblemmap && (modeattacking || (mode == 1)) && !demo.playback) // emblem time!
{
INT32 workx = TX + 96, worky = TY+18;
SINT8 curemb = 0;
@ -7227,7 +7257,7 @@ static void K_DrawKartPositionNum(INT32 num)
else if (splitscreen == 1) // for this splitscreen, we'll use case by case because it's a bit different.
{
fx = POSI_X;
if (stplyr == &players[displayplayer]) // for player 1: display this at the top right, above the minimap.
if (stplyr == &players[displayplayers[0]]) // for player 1: display this at the top right, above the minimap.
{
fy = 30;
fflags = V_SNAPTOTOP|V_SNAPTORIGHT;
@ -7242,11 +7272,11 @@ static void K_DrawKartPositionNum(INT32 num)
}
else
{
if (stplyr == &players[displayplayer] || stplyr == &players[thirddisplayplayer]) // If we are P1 or P3...
if (stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]]) // If we are P1 or P3...
{
fx = POSI_X;
fy = POSI_Y;
fflags = V_SNAPTOLEFT|((stplyr == &players[thirddisplayplayer]) ? V_SPLITSCREEN|V_SNAPTOBOTTOM : 0); // flip P3 to the bottom.
fflags = V_SNAPTOLEFT|((stplyr == &players[displayplayers[2]]) ? V_SPLITSCREEN|V_SNAPTOBOTTOM : 0); // flip P3 to the bottom.
flipdraw = true;
if (num && num >= 10)
fx += W; // this seems dumb, but we need to do this in order for positions above 10 going off screen.
@ -7255,7 +7285,7 @@ static void K_DrawKartPositionNum(INT32 num)
{
fx = POSI2_X;
fy = POSI2_Y;
fflags = V_SNAPTORIGHT|((stplyr == &players[fourthdisplayplayer]) ? V_SPLITSCREEN|V_SNAPTOBOTTOM : 0); // flip P4 to the bottom
fflags = V_SNAPTORIGHT|((stplyr == &players[displayplayers[3]]) ? V_SPLITSCREEN|V_SNAPTOBOTTOM : 0); // flip P4 to the bottom
}
}
@ -7581,17 +7611,17 @@ static void K_drawKartLaps(void)
}
else
{
if (stplyr == &players[displayplayer] || stplyr == &players[thirddisplayplayer]) // If we are P1 or P3...
if (stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]]) // If we are P1 or P3...
{
fx = LAPS_X;
fy = LAPS_Y;
fflags = V_SNAPTOLEFT|((stplyr == &players[thirddisplayplayer]) ? V_SPLITSCREEN|V_SNAPTOBOTTOM : 0); // flip P3 to the bottom.
fflags = V_SNAPTOLEFT|((stplyr == &players[displayplayers[2]]) ? V_SPLITSCREEN|V_SNAPTOBOTTOM : 0); // flip P3 to the bottom.
}
else // else, that means we're P2 or P4.
{
fx = LAPS2_X;
fy = LAPS2_Y;
fflags = V_SNAPTORIGHT|((stplyr == &players[fourthdisplayplayer]) ? V_SPLITSCREEN|V_SNAPTOBOTTOM : 0); // flip P4 to the bottom
fflags = V_SNAPTORIGHT|((stplyr == &players[displayplayers[3]]) ? V_SPLITSCREEN|V_SNAPTOBOTTOM : 0); // flip P4 to the bottom
flipstring = true; // make the string right aligned and other shit
}
}
@ -7663,17 +7693,17 @@ static void K_drawKartBumpersOrKarma(void)
// we will reuse lap coords here since it's essentially the same shit.
if (stplyr == &players[displayplayer] || stplyr == &players[thirddisplayplayer]) // If we are P1 or P3...
if (stplyr == &players[displayplayers[0]] || stplyr == &players[displayplayers[2]]) // If we are P1 or P3...
{
fx = LAPS_X;
fy = LAPS_Y;
fflags = V_SNAPTOLEFT|((stplyr == &players[thirddisplayplayer]) ? V_SPLITSCREEN|V_SNAPTOBOTTOM : 0); // flip P3 to the bottom.
fflags = V_SNAPTOLEFT|((stplyr == &players[displayplayers[2]]) ? V_SPLITSCREEN|V_SNAPTOBOTTOM : 0); // flip P3 to the bottom.
}
else // else, that means we're P2 or P4.
{
fx = LAPS2_X;
fy = LAPS2_Y;
fflags = V_SNAPTORIGHT|((stplyr == &players[fourthdisplayplayer]) ? V_SPLITSCREEN|V_SNAPTOBOTTOM : 0); // flip P4 to the bottom
fflags = V_SNAPTORIGHT|((stplyr == &players[displayplayers[3]]) ? V_SPLITSCREEN|V_SNAPTOBOTTOM : 0); // flip P4 to the bottom
flipstring = true;
}
@ -7750,7 +7780,7 @@ static void K_drawKartWanted(void)
UINT8 *colormap = NULL;
INT32 basex = 0, basey = 0;
if (stplyr != &players[displayplayer])
if (stplyr != &players[displayplayers[0]])
return;
for (i = 0; i < 4; i++)
@ -7830,7 +7860,7 @@ static void K_drawKartPlayerCheck(void)
if (stplyr->awayviewtics)
return;
if (camspin)
if (camspin[0])
return;
for (i = 0; i < MAXPLAYERS; i++)
@ -7976,7 +8006,7 @@ static void K_drawKartMinimap(void)
if (gamestate != GS_LEVEL)
return;
if (stplyr != &players[displayplayer])
if (stplyr != &players[displayplayers[0]])
return;
lumpnum = W_CheckNumForName(va("%sR", G_BuildMapName(gamemap)));
@ -8050,7 +8080,7 @@ static void K_drawKartMinimap(void)
if (!players[i].mo || players[i].spectator)
continue;
if (i != displayplayer || splitscreen)
if (i != displayplayers[0] || splitscreen)
{
if (G_BattleGametype() && players[i].kartstuff[k_bumper] <= 0)
continue;
@ -8064,7 +8094,7 @@ static void K_drawKartMinimap(void)
}
}
if (i == displayplayer || i == secondarydisplayplayer || i == thirddisplayplayer || i == fourthdisplayplayer)
if (P_IsDisplayPlayer(&players[i]))
{
// Draw display players on top of everything else
localplayers[numlocalplayers] = i;
@ -8134,7 +8164,7 @@ static void K_drawKartFinish(void)
xval = (SHORT(kp_racefinish[pnum]->width)<<FRACBITS);
x = ((TICRATE - stplyr->kartstuff[k_cardanimation])*(xval > x ? xval : x))/TICRATE;
if (splitscreen && stplyr == &players[secondarydisplayplayer])
if (splitscreen && stplyr == &players[displayplayers[1]])
x = -x;
V_DrawFixedPatch(x + (STCD_X<<FRACBITS) - (xval>>1),
@ -8153,9 +8183,9 @@ static void K_drawBattleFullscreen(void)
if (splitscreen)
{
if ((splitscreen == 1 && stplyr == &players[secondarydisplayplayer])
|| (splitscreen > 1 && (stplyr == &players[thirddisplayplayer]
|| (stplyr == &players[fourthdisplayplayer] && splitscreen > 2))))
if ((splitscreen == 1 && stplyr == &players[displayplayers[1]])
|| (splitscreen > 1 && (stplyr == &players[displayplayers[2]]
|| (stplyr == &players[displayplayers[3]] && splitscreen > 2))))
{
y = 232-(stplyr->kartstuff[k_cardanimation]/2);
splitflags = V_SNAPTOBOTTOM;
@ -8167,8 +8197,8 @@ static void K_drawBattleFullscreen(void)
{
scale /= 2;
if (stplyr == &players[secondarydisplayplayer]
|| (stplyr == &players[fourthdisplayplayer] && splitscreen > 2))
if (stplyr == &players[displayplayers[1]]
|| (stplyr == &players[displayplayers[3]] && splitscreen > 2))
x = 3*BASEVIDWIDTH/4;
else
x = BASEVIDWIDTH/4;
@ -8177,7 +8207,7 @@ static void K_drawBattleFullscreen(void)
{
if (stplyr->exiting)
{
if (stplyr == &players[secondarydisplayplayer])
if (stplyr == &players[displayplayers[1]])
x = BASEVIDWIDTH-96;
else
x = 96;
@ -8189,7 +8219,7 @@ static void K_drawBattleFullscreen(void)
if (stplyr->exiting)
{
if (stplyr == &players[displayplayer])
if (stplyr == &players[displayplayers[0]])
V_DrawFadeScreen(0xFF00, 16);
if (stplyr->exiting < 6*TICRATE && !stplyr->spectator)
{
@ -8219,9 +8249,9 @@ static void K_drawBattleFullscreen(void)
{
if (splitscreen > 1)
ty = (BASEVIDHEIGHT/4)+33;
if ((splitscreen == 1 && stplyr == &players[secondarydisplayplayer])
|| (stplyr == &players[thirddisplayplayer] && splitscreen > 1)
|| (stplyr == &players[fourthdisplayplayer] && splitscreen > 2))
if ((splitscreen == 1 && stplyr == &players[displayplayers[1]])
|| (stplyr == &players[displayplayers[2]] && splitscreen > 1)
|| (stplyr == &players[displayplayers[3]] && splitscreen > 2))
ty += (BASEVIDHEIGHT/2);
}
else
@ -8248,7 +8278,7 @@ static void K_drawBattleFullscreen(void)
// check to see if there's anyone else at all
for (i = 0; i < MAXPLAYERS; i++)
{
if (i == displayplayer)
if (i == displayplayers[0])
continue;
if (playeringame[i] && !stplyr->spectator)
return;
@ -8274,11 +8304,11 @@ static void K_drawKartFirstPerson(void)
if (stplyr->spectator || !stplyr->mo || (stplyr->mo->flags2 & MF2_DONTDRAW))
return;
if (stplyr == &players[secondarydisplayplayer] && splitscreen)
if (stplyr == &players[displayplayers[1]] && splitscreen)
{ pn = pnum[1]; tn = turn[1]; dr = drift[1]; }
else if (stplyr == &players[thirddisplayplayer] && splitscreen > 1)
else if (stplyr == &players[displayplayers[2]] && splitscreen > 1)
{ pn = pnum[2]; tn = turn[2]; dr = drift[2]; }
else if (stplyr == &players[fourthdisplayplayer] && splitscreen > 2)
else if (stplyr == &players[displayplayers[3]] && splitscreen > 2)
{ pn = pnum[3]; tn = turn[3]; dr = drift[3]; }
else
{ pn = pnum[0]; tn = turn[0]; dr = drift[0]; }
@ -8291,7 +8321,7 @@ static void K_drawKartFirstPerson(void)
}
{
if (stplyr->speed < FixedMul(stplyr->runspeed, stplyr->mo->scale) && (leveltime & 1) && !splitscreen)
if (stplyr->speed < (20*stplyr->mo->scale) && (leveltime & 1) && !splitscreen)
y++;
// the following isn't EXPLICITLY right, it just gets the result we want, but i'm too lazy to look up the right way to do it
if (stplyr->mo->flags2 & MF2_SHADOW)
@ -8403,11 +8433,11 @@ static void K_drawKartFirstPerson(void)
V_DrawFixedPatch(x, y, scale, splitflags, kp_fpview[target], colmap);
if (stplyr == &players[secondarydisplayplayer] && splitscreen)
if (stplyr == &players[displayplayers[1]] && splitscreen)
{ pnum[1] = pn; turn[1] = tn; drift[1] = dr; }
else if (stplyr == &players[thirddisplayplayer] && splitscreen > 1)
else if (stplyr == &players[displayplayers[2]] && splitscreen > 1)
{ pnum[2] = pn; turn[2] = tn; drift[2] = dr; }
else if (stplyr == &players[fourthdisplayplayer] && splitscreen > 2)
else if (stplyr == &players[displayplayers[3]] && splitscreen > 2)
{ pnum[3] = pn; turn[3] = tn; drift[3] = dr; }
else
{ pnum[0] = pn; turn[0] = tn; drift[0] = dr; }
@ -8429,19 +8459,12 @@ static void K_drawInput(void)
if (timeinmap < 113)
{
INT32 count = ((INT32)(timeinmap) - 105);
offs = (titledemo ? 128 : 64);
offs = 64;
while (count-- > 0)
offs >>= 1;
x += offs;
}
if (titledemo)
{
V_DrawTinyScaledPatch(x-54, 128, splitflags, W_CachePatchName("TTKBANNR", PU_CACHE));
V_DrawTinyScaledPatch(x-54, 128+25, splitflags, W_CachePatchName("TTKART", PU_CACHE));
return;
}
#define BUTTW 8
#define BUTTH 11
@ -8635,7 +8658,7 @@ static void K_drawDistributionDebugger(void)
boolean dontforcespb = false;
boolean spbrush = false;
if (stplyr != &players[displayplayer]) // only for p1
if (stplyr != &players[displayplayers[0]]) // only for p1
return;
// The only code duplication from the Kart, just to avoid the actual item function from calculating pingame twice
@ -8699,7 +8722,7 @@ static void K_drawDistributionDebugger(void)
static void K_drawCheckpointDebugger(void)
{
if (stplyr != &players[displayplayer]) // only for p1
if (stplyr != &players[displayplayers[0]]) // only for p1
return;
if (stplyr->starpostnum >= (numstarposts - (numstarposts/2)))
@ -8713,20 +8736,21 @@ void K_drawKartHUD(void)
{
boolean isfreeplay = false;
boolean battlefullscreen = false;
UINT8 i;
// Define the X and Y for each drawn object
// This is handled by console/menu values
K_initKartHUD();
// Draw that fun first person HUD! Drawn ASAP so it looks more "real".
if ((stplyr == &players[displayplayer] && !camera.chase)
|| ((splitscreen && stplyr == &players[secondarydisplayplayer]) && !camera2.chase)
|| ((splitscreen > 1 && stplyr == &players[thirddisplayplayer]) && !camera3.chase)
|| ((splitscreen > 2 && stplyr == &players[fourthdisplayplayer]) && !camera4.chase))
for (i = 0; i <= splitscreen; i++)
{
if (stplyr == &players[displayplayers[i]] && !camera[i].chase)
K_drawKartFirstPerson();
}
// Draw full screen stuff that turns off the rest of the HUD
if (mapreset && stplyr == &players[displayplayer])
if (mapreset && stplyr == &players[displayplayers[0]])
{
K_drawChallengerScreen();
return;
@ -8739,10 +8763,10 @@ void K_drawKartHUD(void)
&& comeback
&& stplyr->playerstate == PST_LIVE)));
if (!battlefullscreen || splitscreen)
if (!demo.title && (!battlefullscreen || splitscreen))
{
// Draw the CHECK indicator before the other items, so it's overlapped by everything else
if (cv_kartcheck.value && !splitscreen && !players[displayplayer].exiting)
if (cv_kartcheck.value && !splitscreen && !players[displayplayers[0]].exiting)
K_drawKartPlayerCheck();
// Draw WANTED status
@ -8754,7 +8778,7 @@ void K_drawKartHUD(void)
K_drawKartWanted();
}
if (cv_kartminimap.value && !titledemo)
if (cv_kartminimap.value)
{
#ifdef HAVE_BLUA
if (LUA_HudEnabled(hud_minimap))
@ -8776,7 +8800,7 @@ void K_drawKartHUD(void)
K_drawKartItem();
// If not splitscreen, draw...
if (!splitscreen && !titledemo)
if (!splitscreen && !demo.title)
{
// Draw the timestamp
#ifdef HAVE_BLUA
@ -8796,9 +8820,29 @@ void K_drawKartHUD(void)
if (!stplyr->spectator) // Bottom of the screen elements, don't need in spectate mode
{
if (G_RaceGametype()) // Race-only elements
if (demo.title) // Draw title logo instead in demo.titles
{
if (!titledemo)
INT32 x = BASEVIDWIDTH - 32, y = 128, offs;
if (splitscreen == 3)
{
x = BASEVIDWIDTH/2 + 10;
y = BASEVIDHEIGHT/2 - 30;
}
if (timeinmap < 113)
{
INT32 count = ((INT32)(timeinmap) - 104);
offs = 256;
while (count-- > 0)
offs >>= 1;
x += offs;
}
V_DrawTinyScaledPatch(x-54, y, 0, W_CachePatchName("TTKBANNR", PU_CACHE));
V_DrawTinyScaledPatch(x-54, y+25, 0, W_CachePatchName("TTKART", PU_CACHE));
}
else if (G_RaceGametype()) // Race-only elements
{
// Draw the lap counter
#ifdef HAVE_BLUA
@ -8815,7 +8859,6 @@ void K_drawKartHUD(void)
#endif
K_drawKartSpeedometer();
}
}
if (isfreeplay)
;
@ -8827,7 +8870,7 @@ void K_drawKartHUD(void)
#endif
K_DrawKartPositionNum(stplyr->kartstuff[k_position]);
}
else //if (!(demoplayback && hu_showscores))
else //if (!(demo.playback && hu_showscores))
{
// Draw the input UI
#ifdef HAVE_BLUA

View File

@ -163,6 +163,7 @@ static int lib_pRandomFixed(lua_State *L)
{
NOHUD
lua_pushfixed(L, P_RandomFixed());
demo_writerng = 2;
return 1;
}
@ -170,6 +171,7 @@ static int lib_pRandomByte(lua_State *L)
{
NOHUD
lua_pushinteger(L, P_RandomByte());
demo_writerng = 2;
return 1;
}
@ -181,6 +183,7 @@ static int lib_pRandomKey(lua_State *L)
if (a > 65536)
LUA_UsageWarning(L, "P_RandomKey: range > 65536 is undefined behavior");
lua_pushinteger(L, P_RandomKey(a));
demo_writerng = 2;
return 1;
}
@ -198,6 +201,7 @@ static int lib_pRandomRange(lua_State *L)
if ((b-a+1) > 65536)
LUA_UsageWarning(L, "P_RandomRange: range > 65536 is undefined behavior");
lua_pushinteger(L, P_RandomRange(a, b));
demo_writerng = 2;
return 1;
}
@ -207,6 +211,7 @@ static int lib_pRandom(lua_State *L)
NOHUD
LUA_Deprecated(L, "P_Random", "P_RandomByte");
lua_pushinteger(L, P_RandomByte());
demo_writerng = 2;
return 1;
}
@ -214,6 +219,7 @@ static int lib_pSignedRandom(lua_State *L)
{
NOHUD
lua_pushinteger(L, P_SignedRandom());
demo_writerng = 2;
return 1;
}
@ -222,6 +228,7 @@ static int lib_pRandomChance(lua_State *L)
fixed_t p = luaL_checkfixed(L, 1);
NOHUD
lua_pushboolean(L, P_RandomChance(p));
demo_writerng = 2;
return 1;
}
@ -946,40 +953,6 @@ static int lib_pHomingAttack(lua_State *L)
return 1;
}*/
static int lib_pDoJump(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
boolean soundandstate = (boolean)lua_opttrueboolean(L, 2);
NOHUD
if (!player)
return LUA_ErrInvalid(L, "player_t");
P_DoJump(player, soundandstate);
return 0;
}
static int lib_pSpawnThokMobj(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
NOHUD
if (!player)
return LUA_ErrInvalid(L, "player_t");
P_SpawnThokMobj(player);
return 0;
}
static int lib_pSpawnSpinMobj(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
mobjtype_t type = luaL_checkinteger(L, 2);
NOHUD
if (!player)
return LUA_ErrInvalid(L, "player_t");
if (type >= NUMMOBJTYPES)
return luaL_error(L, "mobj type %d out of range (0 - %d)", type, NUMMOBJTYPES-1);
P_SpawnSpinMobj(player, type);
return 0;
}
static int lib_pTelekinesis(lua_State *L)
{
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
@ -2645,9 +2618,6 @@ static luaL_Reg lib[] = {
{"P_NukeEnemies",lib_pNukeEnemies},
{"P_HomingAttack",lib_pHomingAttack},
//{"P_SuperReady",lib_pSuperReady},
{"P_DoJump",lib_pDoJump},
{"P_SpawnThokMobj",lib_pSpawnThokMobj},
{"P_SpawnSpinMobj",lib_pSpawnSpinMobj},
{"P_Telekinesis",lib_pTelekinesis},
// p_map

View File

@ -118,14 +118,14 @@ void COM_Lua_f(void)
flags = (UINT8)lua_tointeger(gL, -1);
lua_pop(gL, 1); // pop flags
if (flags & 2) // flag 2: splitscreen player command.
if (flags & 2) // flag 2: splitscreen player command. TODO: support 4P
{
if (!splitscreen)
{
lua_pop(gL, 1); // pop command info table
return; // can't execute splitscreen command without player 2!
}
playernum = secondarydisplayplayer;
playernum = displayplayers[1];
}
if (netgame)

View File

@ -51,6 +51,7 @@ enum hook {
hook_PlayerExplode, //SRB2KART
hook_PlayerSquish, //SRB2KART
hook_PlayerCmd, //SRB2KART
hook_IntermissionThinker, //SRB2KART
hook_MAX // last hook
};
@ -99,4 +100,6 @@ boolean LUAh_PlayerSquish(player_t *player, mobj_t *inflictor, mobj_t *source);
boolean LUAh_PlayerCmd(player_t *player, ticcmd_t *cmd); // Allows to write to player cmd before the game does anything with them.
void LUAh_IntermissionThinker(void); // Hook for Y_Ticker
#endif

View File

@ -62,6 +62,7 @@ const char *const hookNames[hook_MAX+1] = {
"PlayerExplode",
"PlayerSquish",
"PlayerCmd",
"IntermissionThinker",
NULL
};
@ -420,6 +421,28 @@ void LUAh_ThinkFrame(void)
}
}
// Hook for Y_Ticker
void LUAh_IntermissionThinker(void)
{
hook_p hookp;
if (!gL || !(hooksAvailable[hook_IntermissionThinker/8] & (1<<(hook_IntermissionThinker%8))))
return;
for (hookp = roothook; hookp; hookp = hookp->next)
if (hookp->type == hook_IntermissionThinker)
{
lua_pushfstring(gL, FMT_HOOKID, hookp->id);
lua_gettable(gL, LUA_REGISTRYINDEX);
if (lua_pcall(gL, 0, 0, 0)) {
if (!hookp->error || cv_debug & DBG_LUA)
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL, -1));
lua_pop(gL, 1);
hookp->error = true;
}
}
}
// Hook for mobj collisions
UINT8 LUAh_MobjCollideHook(mobj_t *thing1, mobj_t *thing2, enum hook which)
{

View File

@ -797,24 +797,24 @@ void LUAh_GameHUD(player_t *stplayr)
lua_remove(gL, -3); // pop HUD
LUA_PushUserdata(gL, stplayr, META_PLAYER);
if (splitscreen > 2 && stplayr == &players[fourthdisplayplayer])
if (splitscreen > 2 && stplayr == &players[displayplayers[3]])
{
LUA_PushUserdata(gL, &camera4, META_CAMERA);
LUA_PushUserdata(gL, &camera[3], META_CAMERA);
camnum = 4;
}
else if (splitscreen > 1 && stplayr == &players[thirddisplayplayer])
else if (splitscreen > 1 && stplayr == &players[displayplayers[2]])
{
LUA_PushUserdata(gL, &camera3, META_CAMERA);
LUA_PushUserdata(gL, &camera[2], META_CAMERA);
camnum = 3;
}
else if (splitscreen && stplayr == &players[secondarydisplayplayer])
else if (splitscreen && stplayr == &players[displayplayers[1]])
{
LUA_PushUserdata(gL, &camera2, META_CAMERA);
LUA_PushUserdata(gL, &camera[1], META_CAMERA);
camnum = 2;
}
else
{
LUA_PushUserdata(gL, &camera, META_CAMERA);
LUA_PushUserdata(gL, &camera[0], META_CAMERA);
camnum = 1;
}

View File

@ -421,13 +421,13 @@ static int mobj_set(lua_State *L)
case mobj_angle:
mo->angle = luaL_checkangle(L, 3);
if (mo->player == &players[consoleplayer])
localangle = mo->angle;
else if (mo->player == &players[secondarydisplayplayer])
localangle2 = mo->angle;
else if (mo->player == &players[thirddisplayplayer])
localangle3 = mo->angle;
else if (mo->player == &players[fourthdisplayplayer])
localangle4 = mo->angle;
localangle[0] = mo->angle;
else if (mo->player == &players[displayplayers[1]])
localangle[1] = mo->angle;
else if (mo->player == &players[displayplayers[2]])
localangle[2] = mo->angle;
else if (mo->player == &players[displayplayers[3]])
localangle[3] = mo->angle;
break;
case mobj_sprite:
mo->sprite = luaL_checkinteger(L, 3);

View File

@ -155,36 +155,8 @@ static int player_get(lua_State *L)
else if (fastcmp(field,"kartweight"))
lua_pushinteger(L, plr->kartweight);
//
else if (fastcmp(field,"normalspeed"))
lua_pushfixed(L, plr->normalspeed);
else if (fastcmp(field,"runspeed"))
lua_pushfixed(L, plr->runspeed);
else if (fastcmp(field,"thrustfactor"))
lua_pushinteger(L, plr->thrustfactor);
else if (fastcmp(field,"accelstart"))
lua_pushinteger(L, plr->accelstart);
else if (fastcmp(field,"acceleration"))
lua_pushinteger(L, plr->acceleration);
else if (fastcmp(field,"charability"))
lua_pushinteger(L, plr->charability);
else if (fastcmp(field,"charability2"))
lua_pushinteger(L, plr->charability2);
else if (fastcmp(field,"charflags"))
lua_pushinteger(L, plr->charflags);
else if (fastcmp(field,"thokitem"))
lua_pushinteger(L, plr->thokitem);
else if (fastcmp(field,"spinitem"))
lua_pushinteger(L, plr->spinitem);
else if (fastcmp(field,"revitem"))
lua_pushinteger(L, plr->revitem);
else if (fastcmp(field,"actionspd"))
lua_pushfixed(L, plr->actionspd);
else if (fastcmp(field,"mindash"))
lua_pushfixed(L, plr->mindash);
else if (fastcmp(field,"maxdash"))
lua_pushfixed(L, plr->maxdash);
else if (fastcmp(field,"jumpfactor"))
lua_pushfixed(L, plr->jumpfactor);
else if (fastcmp(field,"lives"))
lua_pushinteger(L, plr->lives);
else if (fastcmp(field,"continues"))
@ -382,13 +354,13 @@ static int player_set(lua_State *L)
else if (fastcmp(field,"aiming")) {
plr->aiming = luaL_checkangle(L, 3);
if (plr == &players[consoleplayer])
localaiming = plr->aiming;
else if (plr == &players[secondarydisplayplayer])
localaiming2 = plr->aiming;
else if (plr == &players[thirddisplayplayer])
localaiming3 = plr->aiming;
else if (plr == &players[fourthdisplayplayer])
localaiming4 = plr->aiming;
localaiming[0] = plr->aiming;
else if (plr == &players[displayplayers[1]])
localaiming[1] = plr->aiming;
else if (plr == &players[displayplayers[2]])
localaiming[2] = plr->aiming;
else if (plr == &players[displayplayers[3]])
localaiming[3] = plr->aiming;
}
else if (fastcmp(field,"health"))
plr->health = (INT32)luaL_checkinteger(L, 3);
@ -431,36 +403,8 @@ static int player_set(lua_State *L)
else if (fastcmp(field,"kartweight"))
plr->kartweight = (UINT8)luaL_checkinteger(L, 3);
//
else if (fastcmp(field,"normalspeed"))
plr->normalspeed = luaL_checkfixed(L, 3);
else if (fastcmp(field,"runspeed"))
plr->runspeed = luaL_checkfixed(L, 3);
else if (fastcmp(field,"thrustfactor"))
plr->thrustfactor = (UINT8)luaL_checkinteger(L, 3);
else if (fastcmp(field,"accelstart"))
plr->accelstart = (UINT8)luaL_checkinteger(L, 3);
else if (fastcmp(field,"acceleration"))
plr->acceleration = (UINT8)luaL_checkinteger(L, 3);
else if (fastcmp(field,"charability"))
plr->charability = (UINT8)luaL_checkinteger(L, 3);
else if (fastcmp(field,"charability2"))
plr->charability2 = (UINT8)luaL_checkinteger(L, 3);
else if (fastcmp(field,"charflags"))
plr->charflags = (UINT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"thokitem"))
plr->thokitem = luaL_checkinteger(L, 3);
else if (fastcmp(field,"spinitem"))
plr->spinitem = luaL_checkinteger(L, 3);
else if (fastcmp(field,"revitem"))
plr->revitem = luaL_checkinteger(L, 3);
else if (fastcmp(field,"actionspd"))
plr->actionspd = (INT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"mindash"))
plr->mindash = (INT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"maxdash"))
plr->maxdash = (INT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"jumpfactor"))
plr->jumpfactor = (INT32)luaL_checkinteger(L, 3);
else if (fastcmp(field,"lives"))
plr->lives = (SINT8)luaL_checkinteger(L, 3);
else if (fastcmp(field,"continues"))

View File

@ -273,7 +273,7 @@ boolean cht_Responder(event_t *ev)
#define REQUIRE_OBJECTPLACE if (!objectplacing)\
{ CONS_Printf(M_GetText("OBJECTPLACE must be enabled.\n")); return; }
#define REQUIRE_INLEVEL if (gamestate != GS_LEVEL || demoplayback)\
#define REQUIRE_INLEVEL if (gamestate != GS_LEVEL || demo.playback)\
{ CONS_Printf(M_GetText("You must be in a level to use this.\n")); return; }
#define REQUIRE_SINGLEPLAYER if (netgame || multiplayer)\

View File

@ -56,7 +56,7 @@ fixed_t FixedDiv2(fixed_t a, fixed_t b)
if (b == 0)
I_Error("FixedDiv: divide by zero");
ret = (((INT64)a * FRACUNIT) ) / b;
ret = (((INT64)a * FRACUNIT)) / b;
if ((ret > INT32_MAX) || (ret < INT32_MIN))
I_Error("FixedDiv: divide by zero");
@ -117,7 +117,7 @@ fixed_t FixedHypot(fixed_t x, fixed_t y)
yx = FixedDiv(y, x); // (x/y)
}
yx2 = FixedMul(yx, yx); // (x/y)^2
yx1 = FixedSqrt(1*FRACUNIT + yx2); // (1 + (x/y)^2)^1/2
yx1 = FixedSqrt(1 * FRACUNIT + yx2); // (1 + (x/y)^2)^1/2
return FixedMul(ax, yx1); // |x|*((1 + (x/y)^2)^1/2)
}
@ -191,8 +191,8 @@ vector2_t *FV2_Divide(vector2_t *a_i, fixed_t a_c)
// Vector Complex Math
vector2_t *FV2_Midpoint(const vector2_t *a_1, const vector2_t *a_2, vector2_t *a_o)
{
a_o->x = FixedDiv(a_2->x - a_1->x, 2*FRACUNIT);
a_o->y = FixedDiv(a_2->y - a_1->y, 2*FRACUNIT);
a_o->x = FixedDiv(a_2->x - a_1->x, 2 * FRACUNIT);
a_o->y = FixedDiv(a_2->y - a_1->y, 2 * FRACUNIT);
a_o->x = a_1->x + a_o->x;
a_o->y = a_1->y + a_o->y;
return a_o;
@ -200,16 +200,16 @@ vector2_t *FV2_Midpoint(const vector2_t *a_1, const vector2_t *a_2, vector2_t *a
fixed_t FV2_Distance(const vector2_t *p1, const vector2_t *p2)
{
fixed_t xs = FixedMul(p2->x-p1->x,p2->x-p1->x);
fixed_t ys = FixedMul(p2->y-p1->y,p2->y-p1->y);
return FixedSqrt(xs+ys);
fixed_t xs = FixedMul(p2->x - p1->x, p2->x - p1->x);
fixed_t ys = FixedMul(p2->y - p1->y, p2->y - p1->y);
return FixedSqrt(xs + ys);
}
fixed_t FV2_Magnitude(const vector2_t *a_normal)
{
fixed_t xs = FixedMul(a_normal->x,a_normal->x);
fixed_t ys = FixedMul(a_normal->y,a_normal->y);
return FixedSqrt(xs+ys);
fixed_t xs = FixedMul(a_normal->x, a_normal->x);
fixed_t ys = FixedMul(a_normal->y, a_normal->y);
return FixedSqrt(xs + ys);
}
// Also returns the magnitude
@ -240,7 +240,7 @@ vector2_t *FV2_Negate(vector2_t *a_1)
boolean FV2_Equal(const vector2_t *a_1, const vector2_t *a_2)
{
fixed_t Epsilon = FRACUNIT/FRACUNIT;
fixed_t Epsilon = FRACUNIT / FRACUNIT;
if ((abs(a_2->x - a_1->x) > Epsilon) ||
(abs(a_2->y - a_1->y) > Epsilon))
@ -261,7 +261,7 @@ fixed_t FV2_Dot(const vector2_t *a_1, const vector2_t *a_2)
//
// Given two points, create a vector between them.
//
vector2_t *FV2_Point2Vec (const vector2_t *point1, const vector2_t *point2, vector2_t *a_o)
vector2_t *FV2_Point2Vec(const vector2_t *point1, const vector2_t *point2, vector2_t *a_o)
{
a_o->x = point1->x - point2->x;
a_o->y = point1->y - point2->y;
@ -344,9 +344,9 @@ vector3_t *FV3_Divide(vector3_t *a_i, fixed_t a_c)
// Vector Complex Math
vector3_t *FV3_Midpoint(const vector3_t *a_1, const vector3_t *a_2, vector3_t *a_o)
{
a_o->x = FixedDiv(a_2->x - a_1->x, 2*FRACUNIT);
a_o->y = FixedDiv(a_2->y - a_1->y, 2*FRACUNIT);
a_o->z = FixedDiv(a_2->z - a_1->z, 2*FRACUNIT);
a_o->x = FixedDiv(a_2->x - a_1->x, 2 * FRACUNIT);
a_o->y = FixedDiv(a_2->y - a_1->y, 2 * FRACUNIT);
a_o->z = FixedDiv(a_2->z - a_1->z, 2 * FRACUNIT);
a_o->x = a_1->x + a_o->x;
a_o->y = a_1->y + a_o->y;
a_o->z = a_1->z + a_o->z;
@ -355,18 +355,18 @@ vector3_t *FV3_Midpoint(const vector3_t *a_1, const vector3_t *a_2, vector3_t *a
fixed_t FV3_Distance(const vector3_t *p1, const vector3_t *p2)
{
fixed_t xs = FixedMul(p2->x-p1->x,p2->x-p1->x);
fixed_t ys = FixedMul(p2->y-p1->y,p2->y-p1->y);
fixed_t zs = FixedMul(p2->z-p1->z,p2->z-p1->z);
return FixedSqrt(xs+ys+zs);
fixed_t xs = FixedMul(p2->x - p1->x, p2->x - p1->x);
fixed_t ys = FixedMul(p2->y - p1->y, p2->y - p1->y);
fixed_t zs = FixedMul(p2->z - p1->z, p2->z - p1->z);
return FixedSqrt(xs + ys + zs);
}
fixed_t FV3_Magnitude(const vector3_t *a_normal)
{
fixed_t xs = FixedMul(a_normal->x,a_normal->x);
fixed_t ys = FixedMul(a_normal->y,a_normal->y);
fixed_t zs = FixedMul(a_normal->z,a_normal->z);
return FixedSqrt(xs+ys+zs);
fixed_t xs = FixedMul(a_normal->x, a_normal->x);
fixed_t ys = FixedMul(a_normal->y, a_normal->y);
fixed_t zs = FixedMul(a_normal->z, a_normal->z);
return FixedSqrt(xs + ys + zs);
}
// Also returns the magnitude
@ -399,7 +399,7 @@ vector3_t *FV3_Negate(vector3_t *a_1)
boolean FV3_Equal(const vector3_t *a_1, const vector3_t *a_2)
{
fixed_t Epsilon = FRACUNIT/FRACUNIT;
fixed_t Epsilon = FRACUNIT / FRACUNIT;
if ((abs(a_2->x - a_1->x) > Epsilon) ||
(abs(a_2->y - a_1->y) > Epsilon) ||
@ -458,6 +458,20 @@ vector3_t *FV3_ClosestPointOnLine(const vector3_t *Line, const vector3_t *p, vec
return FV3_AddEx(&Line[0], &V, out);
}
//
// ClosestPointOnVector
//
// Similar to ClosestPointOnLine, but uses a vector instead of two points.
//
void FV3_ClosestPointOnVector(const vector3_t *dir, const vector3_t *p, vector3_t *out)
{
fixed_t t = FV3_Dot(dir, p);
// Return the point on the line closest
FV3_MulEx(dir, t, out);
return;
}
//
// ClosestPointOnTriangle
//
@ -465,7 +479,7 @@ vector3_t *FV3_ClosestPointOnLine(const vector3_t *Line, const vector3_t *p, vec
// the closest point on the edge of
// the triangle is returned.
//
void FV3_ClosestPointOnTriangle (const vector3_t *tri, const vector3_t *point, vector3_t *result)
void FV3_ClosestPointOnTriangle(const vector3_t *tri, const vector3_t *point, vector3_t *result)
{
UINT8 i;
fixed_t dist, closestdist;
@ -506,7 +520,7 @@ void FV3_ClosestPointOnTriangle (const vector3_t *tri, const vector3_t *point, v
//
// Given two points, create a vector between them.
//
vector3_t *FV3_Point2Vec (const vector3_t *point1, const vector3_t *point2, vector3_t *a_o)
vector3_t *FV3_Point2Vec(const vector3_t *point1, const vector3_t *point2, vector3_t *a_o)
{
a_o->x = point1->x - point2->x;
a_o->y = point1->y - point2->y;
@ -519,7 +533,7 @@ vector3_t *FV3_Point2Vec (const vector3_t *point1, const vector3_t *point2, vect
//
// Calculates the normal of a polygon.
//
void FV3_Normal (const vector3_t *a_triangle, vector3_t *a_normal)
fixed_t FV3_Normal(const vector3_t *a_triangle, vector3_t *a_normal)
{
vector3_t a_1;
vector3_t a_2;
@ -529,7 +543,28 @@ void FV3_Normal (const vector3_t *a_triangle, vector3_t *a_normal)
FV3_Cross(&a_1, &a_2, a_normal);
FV3_NormalizeEx(a_normal, a_normal);
return FV3_NormalizeEx(a_normal, a_normal);
}
//
// Strength
//
// Measures the 'strength' of a vector in a particular direction.
//
fixed_t FV3_Strength(const vector3_t *a_1, const vector3_t *dir)
{
vector3_t normal;
fixed_t dist = FV3_NormalizeEx(a_1, &normal);
fixed_t dot = FV3_Dot(&normal, dir);
FV3_ClosestPointOnVector(dir, a_1, &normal);
dist = FV3_Magnitude(&normal);
if (dot < 0) // Not facing same direction, so negate result.
dist = -dist;
return dist;
}
//
@ -575,8 +610,8 @@ boolean FV3_IntersectedPlane(const vector3_t *a_triangle, const vector3_t *a_lin
fixed_t FV3_PlaneIntersection(const vector3_t *pOrigin, const vector3_t *pNormal, const vector3_t *rOrigin, const vector3_t *rVector)
{
fixed_t d = -(FV3_Dot(pNormal, pOrigin));
fixed_t number = FV3_Dot(pNormal,rOrigin) + d;
fixed_t denom = FV3_Dot(pNormal,rVector);
fixed_t number = FV3_Dot(pNormal, rOrigin) + d;
fixed_t denom = FV3_Dot(pNormal, rVector);
return -FixedDiv(number, denom);
}
@ -597,11 +632,11 @@ fixed_t FV3_IntersectRaySphere(const vector3_t *rO, const vector3_t *rV, const v
c = FV3_Magnitude(&Q);
v = FV3_Dot(&Q, rV);
d = FixedMul(sR, sR) - (FixedMul(c,c) - FixedMul(v,v));
d = FixedMul(sR, sR) - (FixedMul(c, c) - FixedMul(v, v));
// If there was no intersection, return -1
if (d < 0*FRACUNIT)
return (-1*FRACUNIT);
if (d < 0 * FRACUNIT)
return (-1 * FRACUNIT);
// Return the distance to the [first] intersecting point
return (v - FixedSqrt(d));
@ -629,7 +664,7 @@ vector3_t *FV3_IntersectionPoint(const vector3_t *vNormal, const vector3_t *vLin
// Here I just chose a arbitrary point as the point to find that distance. You notice we negate that
// distance. We negate the distance because we want to eventually go BACKWARDS from our point to the plane.
// By doing this is will basically bring us back to the plane to find our intersection point.
Numerator = - (FixedMul(vNormal->x, vLine[0].x) + // Use the plane equation with the normal and the line
Numerator = -(FixedMul(vNormal->x, vLine[0].x) + // Use the plane equation with the normal and the line
FixedMul(vNormal->y, vLine[0].y) +
FixedMul(vNormal->z, vLine[0].z) + distance);
@ -643,7 +678,7 @@ vector3_t *FV3_IntersectionPoint(const vector3_t *vNormal, const vector3_t *vLin
// on the plane (the normal is perpendicular to the line - (Normal.Vector = 0)).
// In this case, we should just return any point on the line.
if( Denominator == 0*FRACUNIT) // Check so we don't divide by zero
if (Denominator == 0 * FRACUNIT) // Check so we don't divide by zero
{
ReturnVec->x = vLine[0].x;
ReturnVec->y = vLine[0].y;
@ -686,8 +721,8 @@ vector3_t *FV3_IntersectionPoint(const vector3_t *vNormal, const vector3_t *vLin
//
UINT8 FV3_PointOnLineSide(const vector3_t *point, const vector3_t *line)
{
fixed_t s1 = FixedMul((point->y - line[0].y),(line[1].x - line[0].x));
fixed_t s2 = FixedMul((point->x - line[0].x),(line[1].y - line[0].y));
fixed_t s1 = FixedMul((point->y - line[0].y), (line[1].x - line[0].x));
fixed_t s2 = FixedMul((point->x - line[0].x), (line[1].y - line[0].y));
return (UINT8)(s1 - s2 < 0);
}
@ -752,7 +787,7 @@ void FM_CreateObjectMatrix(matrix_t *matrix, fixed_t x, fixed_t y, fixed_t z, fi
matrix->m[0] = upcross.x;
matrix->m[1] = upcross.y;
matrix->m[2] = upcross.z;
matrix->m[3] = 0*FRACUNIT;
matrix->m[3] = 0 * FRACUNIT;
matrix->m[4] = upx;
matrix->m[5] = upy;
@ -764,9 +799,9 @@ void FM_CreateObjectMatrix(matrix_t *matrix, fixed_t x, fixed_t y, fixed_t z, fi
matrix->m[10] = anglez;
matrix->m[11] = 0;
matrix->m[12] = x - FixedMul(upx,radius);
matrix->m[13] = y - FixedMul(upy,radius);
matrix->m[14] = z - FixedMul(upz,radius);
matrix->m[12] = x - FixedMul(upx, radius);
matrix->m[13] = y - FixedMul(upy, radius);
matrix->m[14] = z - FixedMul(upz, radius);
matrix->m[15] = FRACUNIT;
}
@ -778,19 +813,19 @@ void FM_CreateObjectMatrix(matrix_t *matrix, fixed_t x, fixed_t y, fixed_t z, fi
void FM_MultMatrixVec3(const matrix_t *matrix, const vector3_t *vec, vector3_t *out)
{
#define M(row,col) matrix->m[col * 4 + row]
out->x = FixedMul(vec->x,M(0, 0))
+ FixedMul(vec->y,M(0, 1))
+ FixedMul(vec->z,M(0, 2))
out->x = FixedMul(vec->x, M(0, 0))
+ FixedMul(vec->y, M(0, 1))
+ FixedMul(vec->z, M(0, 2))
+ M(0, 3);
out->y = FixedMul(vec->x,M(1, 0))
+ FixedMul(vec->y,M(1, 1))
+ FixedMul(vec->z,M(1, 2))
out->y = FixedMul(vec->x, M(1, 0))
+ FixedMul(vec->y, M(1, 1))
+ FixedMul(vec->z, M(1, 2))
+ M(1, 3);
out->z = FixedMul(vec->x,M(2, 0))
+ FixedMul(vec->y,M(2, 1))
+ FixedMul(vec->z,M(2, 2))
out->z = FixedMul(vec->x, M(2, 0))
+ FixedMul(vec->y, M(2, 1))
+ FixedMul(vec->z, M(2, 2))
+ M(2, 3);
#undef M
}
@ -811,7 +846,7 @@ void FM_MultMatrix(matrix_t *dest, const matrix_t *multme)
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
R(i, j) = FixedMul(D(i, 0),M(0, j)) + FixedMul(D(i, 1),M(1, j)) + FixedMul(D(i, 2),M(2, j)) + FixedMul(D(i, 3),M(3, j));
R(i, j) = FixedMul(D(i, 0), M(0, j)) + FixedMul(D(i, 1), M(1, j)) + FixedMul(D(i, 2), M(2, j)) + FixedMul(D(i, 3), M(3, j));
}
M_Memcpy(dest, &result, sizeof(matrix_t));
@ -869,8 +904,8 @@ void FM_Scale(matrix_t *dest, fixed_t x, fixed_t y, fixed_t z)
static inline void M_print(INT64 a)
{
const fixed_t w = (a>>FRACBITS);
fixed_t f = a%FRACUNIT;
const fixed_t w = (a >> FRACBITS);
fixed_t f = a % FRACUNIT;
fixed_t d = FRACUNIT;
if (f == 0)
@ -878,7 +913,7 @@ static inline void M_print(INT64 a)
printf("%d", (fixed_t)w);
return;
}
else while (f != 1 && f/2 == f>>1)
else while (f != 1 && f / 2 == f >> 1)
{
d /= 2;
f /= 2;
@ -892,7 +927,7 @@ static inline void M_print(INT64 a)
FUNCMATH FUNCINLINE static inline fixed_t FixedMulC(fixed_t a, fixed_t b)
{
return (fixed_t)((((INT64)a * b) ) / FRACUNIT);
return (fixed_t)((((INT64)a * b)) / FRACUNIT);
}
FUNCMATH FUNCINLINE static inline fixed_t FixedDivC2(fixed_t a, fixed_t b)
@ -902,7 +937,7 @@ FUNCMATH FUNCINLINE static inline fixed_t FixedDivC2(fixed_t a, fixed_t b)
if (b == 0)
I_Error("FixedDiv: divide by zero");
ret = (((INT64)a * FRACUNIT) ) / b;
ret = (((INT64)a * FRACUNIT)) / b;
if ((ret > INT32_MAX) || (ret < INT32_MIN))
I_Error("FixedDiv: divide by zero");
@ -911,7 +946,7 @@ FUNCMATH FUNCINLINE static inline fixed_t FixedDivC2(fixed_t a, fixed_t b)
FUNCMATH FUNCINLINE static inline fixed_t FixedDivC(fixed_t a, fixed_t b)
{
if ((abs(a) >> (FRACBITS-2)) >= abs(b))
if ((abs(a) >> (FRACBITS - 2)) >= abs(b))
return (a^b) < 0 ? INT32_MIN : INT32_MAX;
return FixedDivC2(a, b);
@ -982,7 +1017,7 @@ int main(int argc, char** argv)
{
c = FixedSqrt(a);
d = FixedSqrtC(a);
b = abs(c-d);
b = abs(c - d);
if (b > 1)
{
printf("sqrt(");

View File

@ -394,9 +394,11 @@ boolean FV3_Equal(const vector3_t *a_1, const vector3_t *a_2);
fixed_t FV3_Dot(const vector3_t *a_1, const vector3_t *a_2);
vector3_t *FV3_Cross(const vector3_t *a_1, const vector3_t *a_2, vector3_t *a_o);
vector3_t *FV3_ClosestPointOnLine(const vector3_t *Line, const vector3_t *p, vector3_t *out);
void FV3_ClosestPointOnVector(const vector3_t *dir, const vector3_t *p, vector3_t *out);
void FV3_ClosestPointOnTriangle(const vector3_t *tri, const vector3_t *point, vector3_t *result);
vector3_t *FV3_Point2Vec(const vector3_t *point1, const vector3_t *point2, vector3_t *a_o);
void FV3_Normal(const vector3_t *a_triangle, vector3_t *a_normal);
fixed_t FV3_Normal(const vector3_t *a_triangle, vector3_t *a_normal);
fixed_t FV3_Strength(const vector3_t *a_1, const vector3_t *dir);
fixed_t FV3_PlaneDistance(const vector3_t *a_normal, const vector3_t *a_point);
boolean FV3_IntersectedPlane(const vector3_t *a_triangle, const vector3_t *a_line, vector3_t *a_normal, fixed_t *originDistance);
fixed_t FV3_PlaneIntersection(const vector3_t *pOrigin, const vector3_t *pNormal, const vector3_t *rOrigin, const vector3_t *rVector);

File diff suppressed because it is too large Load Diff

View File

@ -235,6 +235,9 @@ void Screenshot_option_Onchange(void);
// Addons menu updating
void Addons_option_Onchange(void);
void M_ReplayHut(INT32 choice);
void M_SetPlaybackMenuPointer(void);
INT32 HU_GetHighlightColor(void);
// These defines make it a little easier to make menus

View File

@ -743,12 +743,12 @@ static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png
else
snprintf(lvlttltext, 48, "Unknown");
if (gamestate == GS_LEVEL && &players[displayplayer] && players[displayplayer].mo)
if (gamestate == GS_LEVEL && &players[displayplayers[0]] && players[displayplayers[0]].mo)
snprintf(locationtxt, 40, "X:%d Y:%d Z:%d A:%d",
players[displayplayer].mo->x>>FRACBITS,
players[displayplayer].mo->y>>FRACBITS,
players[displayplayer].mo->z>>FRACBITS,
FixedInt(AngleFixed(players[displayplayer].mo->angle)));
players[displayplayers[0]].mo->x>>FRACBITS,
players[displayplayers[0]].mo->y>>FRACBITS,
players[displayplayers[0]].mo->z>>FRACBITS,
FixedInt(AngleFixed(players[displayplayers[0]].mo->angle)));
else
snprintf(locationtxt, 40, "Unknown");

View File

@ -661,11 +661,19 @@ FUNCMATH static const char *int2str(INT32 n)
#ifndef NONET
static INT32 ConnectionFailed(void)
{
time(&MSLastPing);
con_state = MSCS_FAILED;
CONS_Alert(CONS_ERROR, M_GetText("Connection to Master Server failed\n"));
CloseConnection();
return MS_CONNECT_ERROR;
}
static INT32 ConnectionFailedwerrno(int no)
{
CONS_Alert(CONS_ERROR, M_GetText("Master Server socket error: %s\n"),
strerror(no));
return ConnectionFailed();
}
#endif
/** Tries to register the local game server on the master server.
@ -682,44 +690,43 @@ static INT32 AddToMasterServer(boolean firstadd)
msg_server_t *info = (msg_server_t *)msg.buffer;
INT32 room = -1;
fd_set tset;
time_t timestamp = time(NULL);
UINT32 signature, tmp;
const char *insname;
if (socket_fd == (SOCKET_TYPE)ERRSOCKET)/* Woah, our socket was closed! */
{
if (MS_Connect(GetMasterServerIP(), GetMasterServerPort(), 0))
return ConnectionFailedwerrno(errno);
}
M_Memcpy(&tset, &wset, sizeof (tset));
res = select(255, NULL, &tset, NULL, &select_timeout);
if (res != ERRSOCKET && !res)
if (res == ERRSOCKET)
return ConnectionFailedwerrno(errno);
if (res == 0)/* nothing selected */
{
if (retry++ > 30) // an about 30 second timeout
/*
Timeout next call because SendPingToMasterServer
(our calling function) already calls this once
every two minutes.
*/
if (retry++ == 1)
{
retry = 0;
CONS_Alert(CONS_ERROR, M_GetText("Master Server timed out\n"));
MSLastPing = timestamp;
return ConnectionFailed();
}
return MS_CONNECT_ERROR;
}
retry = 0;
if (res == ERRSOCKET)
{
if (MS_Connect(GetMasterServerIP(), GetMasterServerPort(), 0))
{
CONS_Alert(CONS_ERROR, M_GetText("Master Server socket error #%u: %s\n"), errno, strerror(errno));
MSLastPing = timestamp;
return ConnectionFailed();
}
}
// so, the socket is writable, but what does that mean, that the connection is
// ok, or bad... let see that!
j = (socklen_t)sizeof (i);
getsockopt(socket_fd, SOL_SOCKET, SO_ERROR, (char *)&i, &j);
if (getsockopt(socket_fd, SOL_SOCKET, SO_ERROR, (char *)&i, &j) == ERRSOCKET)
return ConnectionFailedwerrno(errno);
if (i) // it was bad
{
CONS_Alert(CONS_ERROR, M_GetText("Master Server socket error #%u: %s\n"), errno, strerror(errno));
MSLastPing = timestamp;
return ConnectionFailed();
}
return ConnectionFailedwerrno(i);
#ifdef PARANOIA
if (ms_RoomId <= 0)
@ -752,15 +759,12 @@ static INT32 AddToMasterServer(boolean firstadd)
msg.length = (UINT32)sizeof (msg_server_t);
msg.room = 0;
if (MS_Write(&msg) < 0)
{
MSLastPing = timestamp;
return ConnectionFailed();
}
if(con_state != MSCS_REGISTERED)
CONS_Printf(M_GetText("Master Server update successful.\n"));
MSLastPing = timestamp;
time(&MSLastPing);
con_state = MSCS_REGISTERED;
CloseConnection();
#endif

View File

@ -3079,7 +3079,7 @@ void A_Invincibility(mobj_t *actor)
{
S_StopMusic();
if (mariomode)
G_GhostAddColor(GHC_INVINCIBLE);
G_GhostAddColor((INT32) (player - players), GHC_INVINCIBLE);
S_ChangeMusicInternal((mariomode) ? "minvnc" : "invinc", false);
}
}
@ -4174,12 +4174,12 @@ void A_OverlayThink(mobj_t *actor)
{
angle_t viewingangle;
if (players[displayplayer].awayviewtics)
viewingangle = R_PointToAngle2(actor->target->x, actor->target->y, players[displayplayer].awayviewmobj->x, players[displayplayer].awayviewmobj->y);
else if (!camera.chase && players[displayplayer].mo)
viewingangle = R_PointToAngle2(actor->target->x, actor->target->y, players[displayplayer].mo->x, players[displayplayer].mo->y);
if (players[displayplayers[0]].awayviewtics)
viewingangle = R_PointToAngle2(actor->target->x, actor->target->y, players[displayplayers[0]].awayviewmobj->x, players[displayplayers[0]].awayviewmobj->y);
else if (!camera[0].chase && players[displayplayers[0]].mo)
viewingangle = R_PointToAngle2(actor->target->x, actor->target->y, players[displayplayers[0]].mo->x, players[displayplayers[0]].mo->y);
else
viewingangle = R_PointToAngle2(actor->target->x, actor->target->y, camera.x, camera.y);
viewingangle = R_PointToAngle2(actor->target->x, actor->target->y, camera[0].x, camera[0].y);
destx = actor->target->x + P_ReturnThrustX(actor->target, viewingangle, FixedMul(FRACUNIT, actor->scale));
desty = actor->target->y + P_ReturnThrustY(actor->target, viewingangle, FixedMul(FRACUNIT, actor->scale));
@ -4781,8 +4781,8 @@ void A_DetonChase(mobj_t *actor)
actor->reactiontime = -42;
exact = actor->movedir>>ANGLETOFINESHIFT;
xyspeed = FixedMul(FixedMul(actor->tracer->player->normalspeed,3*FRACUNIT/4), FINECOSINE(exact));
actor->momz = FixedMul(FixedMul(actor->tracer->player->normalspeed,3*FRACUNIT/4), FINESINE(exact));
xyspeed = FixedMul(FixedMul(K_GetKartSpeed(actor->tracer->player, false),3*FRACUNIT/4), FINECOSINE(exact));
actor->momz = FixedMul(FixedMul(K_GetKartSpeed(actor->tracer->player, false),3*FRACUNIT/4), FINESINE(exact));
exact = actor->angle>>ANGLETOFINESHIFT;
actor->momx = FixedMul(xyspeed, FINECOSINE(exact));
@ -8434,6 +8434,9 @@ void A_SPBChase(mobj_t *actor)
wspeed = (3*defspeed)/2;
if (wspeed < 20*actor->tracer->scale)
wspeed = 20*actor->tracer->scale;
if (actor->tracer->player->pflags & PF_SLIDING)
wspeed = actor->tracer->player->speed/2;
// ^^^^ current section: These are annoying, and grand metropolis in particular needs this.
hang = R_PointToAngle2(actor->x, actor->y, actor->tracer->x, actor->tracer->y);
vang = R_PointToAngle2(0, actor->z, dist, actor->tracer->z);

View File

@ -2536,9 +2536,9 @@ void T_CameraScanner(elevator_t *elevator)
lastleveltime = leveltime;
}
if (players[displayplayer].mo)
if (players[displayplayers[0]].mo)
{
if (players[displayplayer].mo->subsector->sector == elevator->actionsector)
if (players[displayplayers[0]].mo->subsector->sector == elevator->actionsector)
{
if (t_cam_dist == -42)
t_cam_dist = cv_cam_dist.value;
@ -2564,9 +2564,9 @@ void T_CameraScanner(elevator_t *elevator)
}
}
if (splitscreen && players[secondarydisplayplayer].mo)
if (splitscreen && players[displayplayers[1]].mo)
{
if (players[secondarydisplayplayer].mo->subsector->sector == elevator->actionsector)
if (players[displayplayers[1]].mo->subsector->sector == elevator->actionsector)
{
if (t_cam2_rotate == -42)
t_cam2_dist = cv_cam2_dist.value;
@ -2592,9 +2592,9 @@ void T_CameraScanner(elevator_t *elevator)
}
}
if (splitscreen > 1 && players[thirddisplayplayer].mo)
if (splitscreen > 1 && players[displayplayers[2]].mo)
{
if (players[thirddisplayplayer].mo->subsector->sector == elevator->actionsector)
if (players[displayplayers[2]].mo->subsector->sector == elevator->actionsector)
{
if (t_cam3_rotate == -42)
t_cam3_dist = cv_cam3_dist.value;
@ -2620,9 +2620,9 @@ void T_CameraScanner(elevator_t *elevator)
}
}
if (splitscreen > 2 && players[fourthdisplayplayer].mo)
if (splitscreen > 2 && players[displayplayers[3]].mo)
{
if (players[fourthdisplayplayer].mo->subsector->sector == elevator->actionsector)
if (players[displayplayers[3]].mo->subsector->sector == elevator->actionsector)
{
if (t_cam4_rotate == -42)
t_cam4_dist = cv_cam4_dist.value;

View File

@ -62,11 +62,11 @@ void P_ForceConstant(const BasicFF_t *FFInfo)
ConstantQuake.Magnitude = FFInfo->Magnitude;
if (FFInfo->player == &players[consoleplayer])
I_Tactile(ConstantForce, &ConstantQuake);
else if (splitscreen && FFInfo->player == &players[secondarydisplayplayer])
else if (splitscreen && FFInfo->player == &players[displayplayers[1]])
I_Tactile2(ConstantForce, &ConstantQuake);
else if (splitscreen > 1 && FFInfo->player == &players[thirddisplayplayer])
else if (splitscreen > 1 && FFInfo->player == &players[displayplayers[2]])
I_Tactile3(ConstantForce, &ConstantQuake);
else if (splitscreen > 2 && FFInfo->player == &players[fourthdisplayplayer])
else if (splitscreen > 2 && FFInfo->player == &players[displayplayers[3]])
I_Tactile4(ConstantForce, &ConstantQuake);
}
void P_RampConstant(const BasicFF_t *FFInfo, INT32 Start, INT32 End)
@ -83,11 +83,11 @@ void P_RampConstant(const BasicFF_t *FFInfo, INT32 Start, INT32 End)
RampQuake.End = End;
if (FFInfo->player == &players[consoleplayer])
I_Tactile(ConstantForce, &RampQuake);
else if (splitscreen && FFInfo->player == &players[secondarydisplayplayer])
else if (splitscreen && FFInfo->player == &players[displayplayers[1]])
I_Tactile2(ConstantForce, &RampQuake);
else if (splitscreen > 1 && FFInfo->player == &players[thirddisplayplayer])
else if (splitscreen > 1 && FFInfo->player == &players[displayplayers[2]])
I_Tactile3(ConstantForce, &RampQuake);
else if (splitscreen > 2 && FFInfo->player == &players[fourthdisplayplayer])
else if (splitscreen > 2 && FFInfo->player == &players[displayplayers[3]])
I_Tactile4(ConstantForce, &RampQuake);
}
@ -218,7 +218,7 @@ void P_DoNightsScore(player_t *player)
dummymo->fuse = 3*TICRATE;
// What?! NO, don't use the camera! Scale up instead!
//P_InstaThrust(dummymo, R_PointToAngle2(dummymo->x, dummymo->y, camera.x, camera.y), 3*FRACUNIT);
//P_InstaThrust(dummymo, R_PointToAngle2(dummymo->x, dummymo->y, camera[0].x, camera[0].y), 3*FRACUNIT);
dummymo->scalespeed = FRACUNIT/25;
dummymo->destscale = 2*FRACUNIT;
}
@ -851,7 +851,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
// Secret emblem thingy
case MT_EMBLEM:
{
if (demoplayback || player->bot)
if (demo.playback || player->bot)
return;
emblemlocations[special->health-1].collected = true;
@ -1180,13 +1180,13 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
toucher->angle = special->angle;
if (player == &players[consoleplayer])
localangle = toucher->angle;
else if (player == &players[secondarydisplayplayer])
localangle2 = toucher->angle;
else if (player == &players[thirddisplayplayer])
localangle3 = toucher->angle;
else if (player == &players[fourthdisplayplayer])
localangle4 = toucher->angle;
localangle[0] = toucher->angle;
else if (player == &players[displayplayers[1]])
localangle[1] = toucher->angle;
else if (player == &players[displayplayers[2]])
localangle[2] = toucher->angle;
else if (player == &players[displayplayers[3]])
localangle[3] = toucher->angle;
P_ResetPlayer(player);
@ -1209,7 +1209,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
}
// CECHO showing you what this item is
if (player == &players[displayplayer] || G_IsSpecialStage(gamemap))
if (player == &players[displayplayers[0]] || G_IsSpecialStage(gamemap))
{
HU_SetCEchoFlags(V_AUTOFADEOUT);
HU_SetCEchoDuration(4);
@ -1231,7 +1231,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
}
// CECHO showing you what this item is
if (player == &players[displayplayer] || G_IsSpecialStage(gamemap))
if (player == &players[displayplayers[0]] || G_IsSpecialStage(gamemap))
{
HU_SetCEchoFlags(V_AUTOFADEOUT);
HU_SetCEchoDuration(4);
@ -1263,7 +1263,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
}
// CECHO showing you what this item is
if (player == &players[displayplayer] || G_IsSpecialStage(gamemap))
if (player == &players[displayplayers[0]] || G_IsSpecialStage(gamemap))
{
HU_SetCEchoFlags(V_AUTOFADEOUT);
HU_SetCEchoDuration(4);
@ -1293,7 +1293,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
}
// CECHO showing you what this item is
if (player == &players[displayplayer] || G_IsSpecialStage(gamemap))
if (player == &players[displayplayers[0]] || G_IsSpecialStage(gamemap))
{
HU_SetCEchoFlags(V_AUTOFADEOUT);
HU_SetCEchoDuration(4);
@ -1321,7 +1321,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
}
// CECHO showing you what this item is
if (player == &players[displayplayer] || G_IsSpecialStage(gamemap))
if (player == &players[displayplayers[0]] || G_IsSpecialStage(gamemap))
{
HU_SetCEchoFlags(V_AUTOFADEOUT);
HU_SetCEchoDuration(4);
@ -1433,7 +1433,7 @@ void P_TouchSpecialThing(mobj_t *special, mobj_t *toucher, boolean heightcheck)
return;
player->powers[pw_shield] |= SH_FIREFLOWER;
toucher->color = SKINCOLOR_WHITE;
G_GhostAddColor(GHC_FIREFLOWER);
G_GhostAddColor(player - players, GHC_FIREFLOWER);
break;
// *************** //
@ -2324,17 +2324,17 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source)
AM_Stop();
//added : 22-02-98: recenter view for next life...
localaiming = 0;
localaiming[0] = 0;
}
if (target->player == &players[secondarydisplayplayer])
if (target->player == &players[displayplayers[1]])
{
// added : 22-02-98: recenter view for next life...
localaiming2 = 0;
localaiming[1] = 0;
}
if (target->player == &players[thirddisplayplayer])
localaiming3 = 0;
if (target->player == &players[fourthdisplayplayer])
localaiming4 = 0;
if (target->player == &players[displayplayers[2]])
localaiming[2] = 0;
if (target->player == &players[displayplayers[3]])
localaiming[3] = 0;
//tag deaths handled differently in suicide cases. Don't count spectators!
/*if (G_TagGametype()
@ -2978,7 +2978,7 @@ void P_RemoveShield(player_t *player)
if (!player->powers[pw_super])
{
player->mo->color = player->skincolor;
G_GhostAddColor(GHC_NORMAL);
G_GhostAddColor((INT32) (player - players), GHC_NORMAL);
}
}
else if ((player->powers[pw_shield] & SH_NOSTACK) == SH_BOMB) // Give them what's coming to them!
@ -3409,7 +3409,7 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da
target->health -= damage;
if (source && source->player && target)
G_GhostAddHit(target);
G_GhostAddHit((INT32) (source->player - players), target);
if (target->health <= 0)
{

View File

@ -22,6 +22,7 @@
#include "p_tick.h"
#include "r_defs.h"
#include "p_maputl.h"
#include "doomstat.h" // MAXSPLITSCREENPLAYERS
#define FLOATSPEED (FRACUNIT*4)
@ -108,7 +109,7 @@ typedef struct camera_s
fixed_t pan;
} camera_t;
extern camera_t camera, camera2, camera3, camera4;
extern camera_t camera[MAXSPLITSCREENPLAYERS];
extern consvar_t cv_cam_dist, cv_cam_still, cv_cam_height;
extern consvar_t cv_cam_speed, cv_cam_rotate, cv_cam_rotspeed;
@ -137,6 +138,7 @@ boolean P_PlayerInPain(player_t *player);
void P_DoPlayerPain(player_t *player, mobj_t *source, mobj_t *inflictor);
void P_ResetPlayer(player_t *player);
boolean P_IsLocalPlayer(player_t *player);
boolean P_IsDisplayPlayer(player_t *player);
boolean P_SpectatorJoinGame(player_t *player);
boolean P_IsObjectInGoop(mobj_t *mo);
@ -178,7 +180,6 @@ boolean P_LookForEnemies(player_t *player);
void P_NukeEnemies(mobj_t *inflictor, mobj_t *source, fixed_t radius);
void P_HomingAttack(mobj_t *source, mobj_t *enemy); /// \todo doesn't belong in p_user
//boolean P_SuperReady(player_t *player);
void P_DoJump(player_t *player, boolean soundandstate);
boolean P_AnalogMove(player_t *player);
/*boolean P_TransferToNextMare(player_t *player);
UINT8 P_FindLowestMare(void);*/
@ -187,8 +188,6 @@ UINT8 P_FindHighestLap(void);
void P_FindEmerald(void);
//void P_TransferToAxis(player_t *player, INT32 axisnum);
boolean P_PlayerMoving(INT32 pnum);
void P_SpawnThokMobj(player_t *player);
void P_SpawnSpinMobj(player_t *player, mobjtype_t type);
void P_Telekinesis(player_t *player, fixed_t thrust, fixed_t range);
void P_PlayLivesJingle(player_t *player);

View File

@ -212,16 +212,16 @@ boolean P_DoSpring(mobj_t *spring, mobj_t *object)
{
object->angle = spring->angle;
if (!demoplayback || P_AnalogMove(object->player))
if (!demo.playback || P_AnalogMove(object->player))
{
if (object->player == &players[consoleplayer])
localangle = spring->angle;
else if (object->player == &players[secondarydisplayplayer])
localangle2 = spring->angle;
else if (object->player == &players[thirddisplayplayer])
localangle3 = spring->angle;
else if (object->player == &players[fourthdisplayplayer])
localangle4 = spring->angle;
localangle[0] = spring->angle;
else if (object->player == &players[displayplayers[1]])
localangle[1] = spring->angle;
else if (object->player == &players[displayplayers[2]])
localangle[2] = spring->angle;
else if (object->player == &players[displayplayers[3]])
localangle[3] = spring->angle;
}
}
@ -1264,16 +1264,16 @@ static boolean PIT_CheckThing(mobj_t *thing)
thing->angle = tmthing->angle;
if (!demoplayback || P_AnalogMove(thing->player))
if (!demo.playback || P_AnalogMove(thing->player))
{
if (thing->player == &players[consoleplayer])
localangle = thing->angle;
else if (thing->player == &players[secondarydisplayplayer])
localangle2 = thing->angle;
else if (thing->player == &players[thirddisplayplayer])
localangle3 = thing->angle;
else if (thing->player == &players[fourthdisplayplayer])
localangle4 = thing->angle;
localangle[0] = thing->angle;
else if (thing->player == &players[displayplayers[1]])
localangle[1] = thing->angle;
else if (thing->player == &players[displayplayers[2]])
localangle[2] = thing->angle;
else if (thing->player == &players[displayplayers[3]])
localangle[3] = thing->angle;
}
return true;
@ -1580,12 +1580,12 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (G_BattleGametype())
{
if (thing->player->kartstuff[k_sneakertimer] && !(tmthing->player->kartstuff[k_sneakertimer]))
if (thing->player->kartstuff[k_sneakertimer] && !(tmthing->player->kartstuff[k_sneakertimer]) && !(thing->player->powers[pw_flashing])) // Don't steal bumpers while intangible
{
K_StealBumper(thing->player, tmthing->player, false);
K_SpinPlayer(tmthing->player, thing, 0, tmthing, false);
}
else if (tmthing->player->kartstuff[k_sneakertimer] && !(thing->player->kartstuff[k_sneakertimer]))
else if (tmthing->player->kartstuff[k_sneakertimer] && !(thing->player->kartstuff[k_sneakertimer]) && !(tmthing->player->powers[pw_flashing]))
{
K_StealBumper(tmthing->player, thing->player, false);
K_SpinPlayer(thing->player, tmthing, 0, thing, false);
@ -2504,34 +2504,38 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
subsector_t *s = R_PointInSubsector(x, y);
boolean retval = true;
boolean itsatwodlevel = false;
UINT8 i;
floatok = false;
if (twodlevel
|| (thiscam == &camera && players[displayplayer].mo && (players[displayplayer].mo->flags2 & MF2_TWOD))
|| (thiscam == &camera2 && players[secondarydisplayplayer].mo && (players[secondarydisplayplayer].mo->flags2 & MF2_TWOD))
|| (thiscam == &camera3 && players[thirddisplayplayer].mo && (players[thirddisplayplayer].mo->flags2 & MF2_TWOD))
|| (thiscam == &camera4 && players[fourthdisplayplayer].mo && (players[fourthdisplayplayer].mo->flags2 & MF2_TWOD)))
if (twodlevel)
itsatwodlevel = true;
else
{
for (i = 0; i <= splitscreen; i++)
{
if (thiscam == &camera[i] && players[displayplayers[i]].mo
&& (players[displayplayers[i]].mo->flags2 & MF2_TWOD))
{
itsatwodlevel = true;
break;
}
}
}
if (!itsatwodlevel && players[displayplayer].mo)
if (!itsatwodlevel && players[displayplayers[0]].mo)
{
fixed_t tryx = thiscam->x;
fixed_t tryy = thiscam->y;
for (i = 0; i <= splitscreen; i++)
{
#ifndef NOCLIPCAM
if ((thiscam == &camera && (players[displayplayer].pflags & PF_NOCLIP))
|| (thiscam == &camera2 && (players[secondarydisplayplayer].pflags & PF_NOCLIP))
|| (thiscam == &camera3 && (players[thirddisplayplayer].pflags & PF_NOCLIP))
|| (thiscam == &camera4 && (players[fourthdisplayplayer].pflags & PF_NOCLIP))
|| (leveltime < introtime))
if ((thiscam == &camera[i] && (players[displayplayers[i]].pflags & PF_NOCLIP)) || (leveltime < introtime)) // Noclipping player camera noclips too!!
#else
if ((thiscam == &camera && !(players[displayplayer].pflags & PF_TIMEOVER))
|| (thiscam == &camera2 && !(players[secondarydisplayplayer].pflags & PF_TIMEOVER))
|| (thiscam == &camera3 && !(players[thirddisplayplayer].pflags & PF_TIMEOVER))
|| (thiscam == &camera4 && !(players[fourthdisplayplayer].pflags & PF_TIMEOVER)))
if (thiscam == &camera[i] && !(players[displayplayers[i]].pflags & PF_TIMEOVER)) // Time Over should not clip through walls
#endif
{ // Noclipping player camera noclips too!!
{
floatok = true;
thiscam->floorz = thiscam->z;
thiscam->ceilingz = thiscam->z + thiscam->height;
@ -2540,6 +2544,7 @@ boolean P_TryCameraMove(fixed_t x, fixed_t y, camera_t *thiscam)
thiscam->subsector = s;
return true;
}
}
do {
if (x-tryx > MAXRADIUS)

View File

@ -339,9 +339,9 @@ void P_CameraLineOpening(line_t *linedef)
frontceiling = sectors[front->camsec].ceilingheight;
#ifdef ESLOPE
if (sectors[front->camsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
frontfloor = P_GetZAt(sectors[front->camsec].f_slope, camera.x, camera.y);
frontfloor = P_GetZAt(sectors[front->camsec].f_slope, camera[0].x, camera[0].y);
if (sectors[front->camsec].c_slope)
frontceiling = P_GetZAt(sectors[front->camsec].c_slope, camera.x, camera.y);
frontceiling = P_GetZAt(sectors[front->camsec].c_slope, camera[0].x, camera[0].y);
#endif
}
@ -351,9 +351,9 @@ void P_CameraLineOpening(line_t *linedef)
frontceiling = sectors[front->heightsec].ceilingheight;
#ifdef ESLOPE
if (sectors[front->heightsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
frontfloor = P_GetZAt(sectors[front->heightsec].f_slope, camera.x, camera.y);
frontfloor = P_GetZAt(sectors[front->heightsec].f_slope, camera[0].x, camera[0].y);
if (sectors[front->heightsec].c_slope)
frontceiling = P_GetZAt(sectors[front->heightsec].c_slope, camera.x, camera.y);
frontceiling = P_GetZAt(sectors[front->heightsec].c_slope, camera[0].x, camera[0].y);
#endif
}
else
@ -367,9 +367,9 @@ void P_CameraLineOpening(line_t *linedef)
backceiling = sectors[back->camsec].ceilingheight;
#ifdef ESLOPE
if (sectors[back->camsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
frontfloor = P_GetZAt(sectors[back->camsec].f_slope, camera.x, camera.y);
frontfloor = P_GetZAt(sectors[back->camsec].f_slope, camera[0].x, camera[0].y);
if (sectors[back->camsec].c_slope)
frontceiling = P_GetZAt(sectors[back->camsec].c_slope, camera.x, camera.y);
frontceiling = P_GetZAt(sectors[back->camsec].c_slope, camera[0].x, camera[0].y);
#endif
}
else if (back->heightsec >= 0)
@ -378,9 +378,9 @@ void P_CameraLineOpening(line_t *linedef)
backceiling = sectors[back->heightsec].ceilingheight;
#ifdef ESLOPE
if (sectors[back->heightsec].f_slope) // SRB2CBTODO: ESLOPE (sectors[front->heightsec].f_slope)
frontfloor = P_GetZAt(sectors[back->heightsec].f_slope, camera.x, camera.y);
frontfloor = P_GetZAt(sectors[back->heightsec].f_slope, camera[0].x, camera[0].y);
if (sectors[back->heightsec].c_slope)
frontceiling = P_GetZAt(sectors[back->heightsec].c_slope, camera.x, camera.y);
frontceiling = P_GetZAt(sectors[back->heightsec].c_slope, camera[0].x, camera[0].y);
#endif
}
else

View File

@ -1125,7 +1125,7 @@ static void P_PlayerFlip(mobj_t *mo)
if (!mo->player)
return;
G_GhostAddFlip();
G_GhostAddFlip((INT32) (mo->player - players));
// Flip aiming to match!
if (mo->player->pflags & PF_NIGHTSMODE) // NiGHTS doesn't use flipcam
@ -1135,46 +1135,22 @@ static void P_PlayerFlip(mobj_t *mo)
}
else if (mo->player->pflags & PF_FLIPCAM)
{
UINT8 i;
mo->player->aiming = InvAngle(mo->player->aiming);
if (mo->player-players == displayplayer)
for (i = 0; i <= splitscreen; i++)
{
localaiming = mo->player->aiming;
if (camera.chase) {
camera.aiming = InvAngle(camera.aiming);
camera.z = mo->z - camera.z + mo->z;
if (mo->eflags & MFE_VERTICALFLIP)
camera.z += FixedMul(20*FRACUNIT, mo->scale);
}
}
else if (mo->player-players == secondarydisplayplayer)
if (mo->player-players == displayplayers[i])
{
localaiming2 = mo->player->aiming;
if (camera2.chase) {
camera2.aiming = InvAngle(camera2.aiming);
camera2.z = mo->z - camera2.z + mo->z;
localaiming[i] = mo->player->aiming;
if (camera[i].chase) {
camera[i].aiming = InvAngle(camera[i].aiming);
camera[i].z = mo->z - camera[i].z + mo->z;
if (mo->eflags & MFE_VERTICALFLIP)
camera2.z += FixedMul(20*FRACUNIT, mo->scale);
camera[i].z += FixedMul(20*FRACUNIT, mo->scale);
}
}
else if (mo->player-players == thirddisplayplayer)
{
localaiming3 = mo->player->aiming;
if (camera3.chase) {
camera3.aiming = InvAngle(camera3.aiming);
camera3.z = mo->z - camera3.z + mo->z;
if (mo->eflags & MFE_VERTICALFLIP)
camera3.z += FixedMul(20*FRACUNIT, mo->scale);
}
}
else if (mo->player-players == fourthdisplayplayer)
{
localaiming4 = mo->player->aiming;
if (camera4.chase) {
camera4.aiming = InvAngle(camera4.aiming);
camera4.z = mo->z - camera4.z + mo->z;
if (mo->eflags & MFE_VERTICALFLIP)
camera4.z += FixedMul(20*FRACUNIT, mo->scale);
}
}
}
}
@ -1932,7 +1908,7 @@ void P_XYMovement(mobj_t *mo)
if (mo->type == MT_ORBINAUT || mo->type == MT_JAWZ_DUD || mo->type == MT_JAWZ || mo->type == MT_BALLHOG) //(mo->type == MT_JAWZ && !mo->tracer))
return;
if (mo->player && (mo->player->kartstuff[k_spinouttimer] && !mo->player->kartstuff[k_wipeoutslow]) && mo->player->speed <= mo->player->normalspeed/2)
if (mo->player && (mo->player->kartstuff[k_spinouttimer] && !mo->player->kartstuff[k_wipeoutslow]) && mo->player->speed <= K_GetKartSpeed(mo->player, false)/2)
return;
//}
@ -3546,17 +3522,26 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
{
boolean itsatwodlevel = false;
postimg_t postimg = postimg_none;
UINT8 i;
// This can happen when joining
if (thiscam->subsector == NULL || thiscam->subsector->sector == NULL)
return true;
if (twodlevel
|| (thiscam == &camera && players[displayplayer].mo && (players[displayplayer].mo->flags2 & MF2_TWOD))
|| (thiscam == &camera2 && players[secondarydisplayplayer].mo && (players[secondarydisplayplayer].mo->flags2 & MF2_TWOD))
|| (thiscam == &camera3 && players[thirddisplayplayer].mo && (players[thirddisplayplayer].mo->flags2 & MF2_TWOD))
|| (thiscam == &camera4 && players[fourthdisplayplayer].mo && (players[fourthdisplayplayer].mo->flags2 & MF2_TWOD)))
if (twodlevel)
itsatwodlevel = true;
else
{
for (i = 0; i <= splitscreen; i++)
{
if (thiscam == &camera[i] && players[displayplayers[i]].mo
&& (players[displayplayers[i]].mo->flags2 & MF2_TWOD))
{
itsatwodlevel = true;
break;
}
}
}
if (encoremode)
postimg = postimg_mirror;
@ -3588,14 +3573,11 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
if (postimg != postimg_none)
{
if (splitscreen && player == &players[secondarydisplayplayer])
postimgtype2 = postimg;
else if (splitscreen > 1 && player == &players[thirddisplayplayer])
postimgtype3 = postimg;
else if (splitscreen > 2 && player == &players[fourthdisplayplayer])
postimgtype4 = postimg;
else
postimgtype = postimg;
for (i = 0; i <= splitscreen; i++)
{
if (player == &players[displayplayers[i]])
postimgtype[i] = postimg;
}
}
if (thiscam->momx || thiscam->momy)
@ -3641,11 +3623,11 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
fixed_t cam_height = cv_cam_height.value;
thiscam->z = thiscam->floorz;
if (player == &players[secondarydisplayplayer])
if (player == &players[displayplayers[1]])
cam_height = cv_cam2_height.value;
if (player == &players[thirddisplayplayer])
if (player == &players[displayplayers[2]])
cam_height = cv_cam3_height.value;
if (player == &players[fourthdisplayplayer])
if (player == &players[displayplayers[3]])
cam_height = cv_cam4_height.value;
if (thiscam->z > player->mo->z + player->mo->height + FixedMul(cam_height*FRACUNIT + 16*FRACUNIT, player->mo->scale))
{
@ -5897,7 +5879,7 @@ void P_SetScale(mobj_t *mobj, fixed_t newscale)
if (player)
{
G_GhostAddScale(newscale);
G_GhostAddScale((INT32) (player - players), newscale);
player->viewheight = FixedMul(FixedDiv(player->viewheight, oldscale), newscale); // Nonono don't calculate viewheight elsewhere, this is the best place for it!
player->dashspeed = FixedMul(FixedDiv(player->dashspeed, oldscale), newscale); // Prevents the player from having to re-charge up spindash if the player grew in size
}
@ -6101,12 +6083,12 @@ void P_RunOverlays(void)
{
angle_t viewingangle;
if (players[displayplayer].awayviewtics)
viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, players[displayplayer].awayviewmobj->x, players[displayplayer].awayviewmobj->y);
else if (!camera.chase && players[displayplayer].mo)
viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, players[displayplayer].mo->x, players[displayplayer].mo->y);
if (players[displayplayers[0]].awayviewtics)
viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, players[displayplayers[0]].awayviewmobj->x, players[displayplayers[0]].awayviewmobj->y);
else if (!camera[0].chase && players[displayplayers[0]].mo)
viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, players[displayplayers[0]].mo->x, players[displayplayers[0]].mo->y);
else
viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, camera.x, camera.y);
viewingangle = R_PointToAngle2(mo->target->x, mo->target->y, camera[0].x, camera[0].y);
if (!(mo->state->frame & FF_ANIMATE) && mo->state->var1)
viewingangle += ANGLE_180;
@ -6680,7 +6662,7 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->target && mobj->target->health
&& mobj->target->player && !mobj->target->player->spectator
&& mobj->target->player->health && mobj->target->player->playerstate != PST_DEAD
/*&& players[displayplayer].mo && !players[displayplayer].spectator*/)
/*&& players[displayplayers[0]].mo && !players[displayplayers[0]].spectator*/)
{
fixed_t scale = 3*mobj->target->scale;
mobj->color = mobj->target->color;
@ -6688,7 +6670,7 @@ void P_MobjThinker(mobj_t *mobj)
if ((G_RaceGametype() || mobj->target->player->kartstuff[k_bumper] <= 0)
#if 1 // Set to 0 to test without needing to host
|| ((mobj->target->player == &players[displayplayer]) || P_IsLocalPlayer(mobj->target->player))
|| ((mobj->target->player == &players[displayplayers[0]]) || P_IsLocalPlayer(mobj->target->player))
#endif
)
mobj->flags2 |= MF2_DONTDRAW;
@ -6699,10 +6681,10 @@ void P_MobjThinker(mobj_t *mobj)
mobj->angle = R_PointToAngle(mobj->x, mobj->y) + ANGLE_90; // literally only happened because i wanted to ^L^R the SPR_ITEM's
if (!splitscreen && players[displayplayer].mo)
if (!splitscreen && players[displayplayers[0]].mo)
{
scale = mobj->target->scale + FixedMul(FixedDiv(abs(P_AproxDistance(players[displayplayer].mo->x-mobj->target->x,
players[displayplayer].mo->y-mobj->target->y)), RING_DIST), mobj->target->scale);
scale = mobj->target->scale + FixedMul(FixedDiv(abs(P_AproxDistance(players[displayplayers[0]].mo->x-mobj->target->x,
players[displayplayers[0]].mo->y-mobj->target->y)), RING_DIST), mobj->target->scale);
if (scale > 16*mobj->target->scale)
scale = 16*mobj->target->scale;
}
@ -6887,7 +6869,7 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->target && mobj->target->health && mobj->tracer
&& mobj->target->player && !mobj->target->player->spectator
&& mobj->target->player->health && mobj->target->player->playerstate != PST_DEAD
&& players[displayplayer].mo && !players[displayplayer].spectator)
&& players[displayplayers[0]].mo && !players[displayplayers[0]].spectator)
{
fixed_t scale = 3*mobj->target->scale;
@ -6909,8 +6891,8 @@ void P_MobjThinker(mobj_t *mobj)
if (!splitscreen)
{
scale = mobj->target->scale + FixedMul(FixedDiv(abs(P_AproxDistance(players[displayplayer].mo->x-mobj->target->x,
players[displayplayer].mo->y-mobj->target->y)), RING_DIST), mobj->target->scale);
scale = mobj->target->scale + FixedMul(FixedDiv(abs(P_AproxDistance(players[displayplayers[0]].mo->x-mobj->target->x,
players[displayplayers[0]].mo->y-mobj->target->y)), RING_DIST), mobj->target->scale);
if (scale > 16*mobj->target->scale)
scale = 16*mobj->target->scale;
}
@ -8296,12 +8278,12 @@ void P_MobjThinker(mobj_t *mobj)
angle_t viewingangle;
statenum_t curstate = ((mobj->tics == 1) ? (mobj->state->nextstate) : ((statenum_t)(mobj->state-states)));
if (players[displayplayer].awayviewtics)
viewingangle = R_PointToAngle2(mobj->target->x, mobj->target->y, players[displayplayer].awayviewmobj->x, players[displayplayer].awayviewmobj->y);
else if (!camera.chase && players[displayplayer].mo)
viewingangle = R_PointToAngle2(mobj->target->x, mobj->target->y, players[displayplayer].mo->x, players[displayplayer].mo->y);
if (players[displayplayers[0]].awayviewtics)
viewingangle = R_PointToAngle2(mobj->target->x, mobj->target->y, players[displayplayers[0]].awayviewmobj->x, players[displayplayers[0]].awayviewmobj->y);
else if (!camera[0].chase && players[displayplayers[0]].mo)
viewingangle = R_PointToAngle2(mobj->target->x, mobj->target->y, players[displayplayers[0]].mo->x, players[displayplayers[0]].mo->y);
else
viewingangle = R_PointToAngle2(mobj->target->x, mobj->target->y, camera.x, camera.y);
viewingangle = R_PointToAngle2(mobj->target->x, mobj->target->y, camera[0].x, camera[0].y);
if (curstate > S_THUNDERSHIELD15)
viewingangle += ANGLE_180;
@ -10562,13 +10544,13 @@ void P_PrecipitationEffects(void)
// Local effects from here on out!
// If we're not in game fully yet, we don't worry about them.
if (!playeringame[displayplayer] || !players[displayplayer].mo)
if (!playeringame[displayplayers[0]] || !players[displayplayers[0]].mo)
return;
if (sound_disabled)
return; // Sound off? D'aw, no fun.
if (players[displayplayer].mo->subsector->sector->ceilingpic == skyflatnum)
if (players[displayplayers[0]].mo->subsector->sector->ceilingpic == skyflatnum)
volume = 255; // Sky above? We get it full blast.
else
{
@ -10576,17 +10558,17 @@ void P_PrecipitationEffects(void)
fixed_t closedist, newdist;
// Essentially check in a 1024 unit radius of the player for an outdoor area.
yl = players[displayplayer].mo->y - 1024*FRACUNIT;
yh = players[displayplayer].mo->y + 1024*FRACUNIT;
xl = players[displayplayer].mo->x - 1024*FRACUNIT;
xh = players[displayplayer].mo->x + 1024*FRACUNIT;
yl = players[displayplayers[0]].mo->y - 1024*FRACUNIT;
yh = players[displayplayers[0]].mo->y + 1024*FRACUNIT;
xl = players[displayplayers[0]].mo->x - 1024*FRACUNIT;
xh = players[displayplayers[0]].mo->x + 1024*FRACUNIT;
closedist = 2048*FRACUNIT;
for (y = yl; y <= yh; y += FRACUNIT*64)
for (x = xl; x <= xh; x += FRACUNIT*64)
{
if (R_PointInSubsector(x, y)->sector->ceilingpic == skyflatnum) // Found the outdoors!
{
newdist = S_CalculateSoundDistance(players[displayplayer].mo->x, players[displayplayer].mo->y, 0, x, y, 0);
newdist = S_CalculateSoundDistance(players[displayplayers[0]].mo->x, players[displayplayers[0]].mo->y, 0, x, y, 0);
if (newdist < closedist)
closedist = newdist;
}
@ -10601,7 +10583,7 @@ void P_PrecipitationEffects(void)
volume = 255;
if (sounds_rain && (!leveltime || leveltime % 80 == 1))
S_StartSoundAtVolume(players[displayplayer].mo, sfx_rainin, volume);
S_StartSoundAtVolume(players[displayplayers[0]].mo, sfx_rainin, volume);
if (!sounds_thunder)
return;
@ -10609,7 +10591,7 @@ void P_PrecipitationEffects(void)
if (effects_lightning && lightningStrike && volume)
{
// Large, close thunder sounds to go with our lightning.
S_StartSoundAtVolume(players[displayplayer].mo, sfx_litng1 + M_RandomKey(4), volume);
S_StartSoundAtVolume(players[displayplayers[0]].mo, sfx_litng1 + M_RandomKey(4), volume);
}
else if (thunderchance < 20)
{
@ -10617,7 +10599,7 @@ void P_PrecipitationEffects(void)
if (volume < 80)
volume = 80;
S_StartSoundAtVolume(players[displayplayer].mo, sfx_athun1 + M_RandomKey(2), volume);
S_StartSoundAtVolume(players[displayplayers[0]].mo, sfx_athun1 + M_RandomKey(2), volume);
}
}
@ -10789,7 +10771,8 @@ void P_SpawnPlayer(INT32 playernum)
}
// spawn as spectator determination
if (!G_GametypeHasSpectators())
if (multiplayer && demo.playback); // Don't mess with spectator values since the demo setup handles them already.
else if (!G_GametypeHasSpectators())
p->spectator = false;
else if (netgame && p->jointime <= 1 && pcount)
{
@ -10923,15 +10906,21 @@ void P_AfterPlayerSpawn(INT32 playernum)
{
player_t *p = &players[playernum];
mobj_t *mobj = p->mo;
UINT8 i;
if (playernum == consoleplayer)
localangle = mobj->angle;
else if (playernum == secondarydisplayplayer)
localangle2 = mobj->angle;
else if (playernum == thirddisplayplayer)
localangle3 = mobj->angle;
else if (playernum == fourthdisplayplayer)
localangle4 = mobj->angle;
localangle[0] = mobj->angle;
else if (splitscreen)
{
for (i = 1; i <= splitscreen; i++)
{
if (playernum == displayplayers[i])
{
localangle[i] = mobj->angle;
break;
}
}
}
p->viewheight = 32<<FRACBITS;
@ -10953,25 +10942,13 @@ void P_AfterPlayerSpawn(INT32 playernum)
SV_SpawnPlayer(playernum, mobj->x, mobj->y, mobj->angle);
if (camera.chase)
for (i = 0; i <= splitscreen; i++)
{
if (displayplayer == playernum)
P_ResetCamera(p, &camera);
if (camera[i].chase)
{
if (displayplayers[i] == playernum)
P_ResetCamera(p, &camera[i]);
}
if (camera2.chase && splitscreen)
{
if (secondarydisplayplayer == playernum)
P_ResetCamera(p, &camera2);
}
if (camera3.chase && splitscreen > 1)
{
if (thirddisplayplayer == playernum)
P_ResetCamera(p, &camera3);
}
if (camera4.chase && splitscreen > 2)
{
if (fourthdisplayplayer == playernum)
P_ResetCamera(p, &camera4);
}
if (CheckForReverseGravity)

View File

@ -1336,13 +1336,13 @@ static void Polyobj_rotateThings(polyobj_t *po, vertex_t origin, angle_t delta,
if (turnthings == 2 || (turnthings == 1 && !mo->player)) {
mo->angle += delta;
if (mo->player == &players[consoleplayer])
localangle = mo->angle;
else if (mo->player == &players[secondarydisplayplayer])
localangle2 = mo->angle;
else if (mo->player == &players[thirddisplayplayer])
localangle3 = mo->angle;
else if (mo->player == &players[fourthdisplayplayer])
localangle4 = mo->angle;
localangle[0] += delta;
else if (mo->player == &players[displayplayers[1]])
localangle[1] += delta;
else if (mo->player == &players[displayplayers[2]])
localangle[2] += delta;
else if (mo->player == &players[displayplayers[3]])
localangle[3] += delta;
}
}
}

View File

@ -265,25 +265,11 @@ static void P_NetArchivePlayers(void)
if (flags & AWAYVIEW)
WRITEUINT32(save_p, players[i].awayviewmobj->mobjnum);
WRITEUINT8(save_p, players[i].charability);
WRITEUINT8(save_p, players[i].charability2);
WRITEUINT32(save_p, players[i].charflags);
WRITEUINT32(save_p, (UINT32)players[i].thokitem);
WRITEUINT32(save_p, (UINT32)players[i].spinitem);
WRITEUINT32(save_p, (UINT32)players[i].revitem);
WRITEFIXED(save_p, players[i].actionspd);
WRITEFIXED(save_p, players[i].mindash);
WRITEFIXED(save_p, players[i].maxdash);
// SRB2kart
WRITEUINT8(save_p, players[i].kartspeed);
WRITEUINT8(save_p, players[i].kartweight);
//
WRITEFIXED(save_p, players[i].normalspeed);
WRITEFIXED(save_p, players[i].runspeed);
WRITEUINT8(save_p, players[i].thrustfactor);
WRITEUINT8(save_p, players[i].accelstart);
WRITEUINT8(save_p, players[i].acceleration);
WRITEFIXED(save_p, players[i].jumpfactor);
for (j = 0; j < MAXPREDICTTICS; j++)
{
@ -447,25 +433,11 @@ static void P_NetUnArchivePlayers(void)
players[i].viewheight = 32<<FRACBITS;
//SetPlayerSkinByNum(i, players[i].skin);
players[i].charability = READUINT8(save_p);
players[i].charability2 = READUINT8(save_p);
players[i].charflags = READUINT32(save_p);
players[i].thokitem = (mobjtype_t)READUINT32(save_p);
players[i].spinitem = (mobjtype_t)READUINT32(save_p);
players[i].revitem = (mobjtype_t)READUINT32(save_p);
players[i].actionspd = READFIXED(save_p);
players[i].mindash = READFIXED(save_p);
players[i].maxdash = READFIXED(save_p);
// SRB2kart
players[i].kartspeed = READUINT8(save_p);
players[i].kartweight = READUINT8(save_p);
//
players[i].normalspeed = READFIXED(save_p);
players[i].runspeed = READFIXED(save_p);
players[i].thrustfactor = READUINT8(save_p);
players[i].accelstart = READUINT8(save_p);
players[i].acceleration = READUINT8(save_p);
players[i].jumpfactor = READFIXED(save_p);
for (j = 0; j < MAXPREDICTTICS; j++)
{
@ -2106,13 +2078,13 @@ static void LoadMobjThinker(actionf_p1 thinker)
mobj->player->mo = mobj;
// added for angle prediction
if (consoleplayer == i)
localangle = mobj->angle;
if (secondarydisplayplayer == i)
localangle2 = mobj->angle;
if (thirddisplayplayer == i)
localangle3 = mobj->angle;
if (fourthdisplayplayer == i)
localangle4 = mobj->angle;
localangle[0] = mobj->angle;
if (displayplayers[1] == i)
localangle[1] = mobj->angle;
if (displayplayers[2] == i)
localangle[2] = mobj->angle;
if (displayplayers[3] == i)
localangle[3] = mobj->angle;
}
if (diff & MD_MOVEDIR)
mobj->movedir = READANGLE(save_p);
@ -3451,7 +3423,7 @@ void P_SaveNetGame(void)
mobj_t *mobj;
INT32 i = 1; // don't start from 0, it'd be confused with a blank pointer otherwise
CV_SaveNetVars(&save_p);
CV_SaveNetVars(&save_p, false);
P_NetArchiveMisc();
// Assign the mobjnumber for pointer tracking

View File

@ -65,6 +65,10 @@
#include "lua_script.h"
#include "lua_hook.h"
#if !defined (UNDER_CE)
#include <time.h>
#endif
#if defined (_WIN32) || defined (_WIN32_WCE)
#include <malloc.h>
#include <math.h>
@ -2265,7 +2269,7 @@ static void P_LevelInitStuff(void)
leveltime = 0;
localaiming = localaiming2 = localaiming3 = localaiming4 = 0;
memset(localaiming, 0, sizeof(localaiming));
// map object scale
mapobjectscale = mapheaderinfo[gamemap-1]->mobj_scale;
@ -2532,29 +2536,29 @@ static void P_ForceCharacter(const char *forcecharskin)
{
if (splitscreen)
{
SetPlayerSkin(secondarydisplayplayer, forcecharskin);
if ((unsigned)cv_playercolor2.value != skins[players[secondarydisplayplayer].skin].prefcolor && !modeattacking)
SetPlayerSkin(displayplayers[1], forcecharskin);
if ((unsigned)cv_playercolor2.value != skins[players[displayplayers[1]].skin].prefcolor && !modeattacking)
{
CV_StealthSetValue(&cv_playercolor2, skins[players[secondarydisplayplayer].skin].prefcolor);
players[secondarydisplayplayer].skincolor = skins[players[secondarydisplayplayer].skin].prefcolor;
CV_StealthSetValue(&cv_playercolor2, skins[players[displayplayers[1]].skin].prefcolor);
players[displayplayers[1]].skincolor = skins[players[displayplayers[1]].skin].prefcolor;
}
if (splitscreen > 1)
{
SetPlayerSkin(thirddisplayplayer, forcecharskin);
if ((unsigned)cv_playercolor3.value != skins[players[thirddisplayplayer].skin].prefcolor && !modeattacking)
SetPlayerSkin(displayplayers[2], forcecharskin);
if ((unsigned)cv_playercolor3.value != skins[players[displayplayers[2]].skin].prefcolor && !modeattacking)
{
CV_StealthSetValue(&cv_playercolor3, skins[players[thirddisplayplayer].skin].prefcolor);
players[thirddisplayplayer].skincolor = skins[players[thirddisplayplayer].skin].prefcolor;
CV_StealthSetValue(&cv_playercolor3, skins[players[displayplayers[2]].skin].prefcolor);
players[displayplayers[2]].skincolor = skins[players[displayplayers[2]].skin].prefcolor;
}
if (splitscreen > 2)
{
SetPlayerSkin(fourthdisplayplayer, forcecharskin);
if ((unsigned)cv_playercolor4.value != skins[players[fourthdisplayplayer].skin].prefcolor && !modeattacking)
SetPlayerSkin(displayplayers[3], forcecharskin);
if ((unsigned)cv_playercolor4.value != skins[players[displayplayers[3]].skin].prefcolor && !modeattacking)
{
CV_StealthSetValue(&cv_playercolor4, skins[players[fourthdisplayplayer].skin].prefcolor);
players[fourthdisplayplayer].skincolor = skins[players[fourthdisplayplayer].skin].prefcolor;
CV_StealthSetValue(&cv_playercolor4, skins[players[displayplayers[3]].skin].prefcolor);
players[displayplayers[3]].skincolor = skins[players[displayplayers[3]].skin].prefcolor;
}
}
}
@ -2725,7 +2729,7 @@ static boolean P_CanSave(void)
if ((cursaveslot < 0) // Playing without saving
|| (modifiedgame && !savemoddata) // Game is modified
|| (netgame || multiplayer) // Not in single-player
|| (demoplayback || demorecording || metalrecording) // Currently in demo
|| (demo.playback || demo.recording || metalrecording) // Currently in demo
|| (players[consoleplayer].lives <= 0) // Completely dead
|| (modeattacking || ultimatemode || G_IsSpecialStage(gamemap))) // Specialized instances
return false;
@ -2789,7 +2793,8 @@ boolean P_SetupLevel(boolean skipprecip)
P_LevelInitStuff();
postimgtype = postimgtype2 = postimgtype3 = postimgtype4 = postimg_none;
for (i = 0; i <= splitscreen; i++)
postimgtype[i] = postimg_none;
if (mapheaderinfo[gamemap-1]->forcecharacter[0] != '\0'
&& atoi(mapheaderinfo[gamemap-1]->forcecharacter) != 255)
@ -2825,7 +2830,7 @@ boolean P_SetupLevel(boolean skipprecip)
// Encore mode fade to pink to white
// This is handled BEFORE sounds are stopped.
if (rendermode != render_none && encoremode && !prevencoremode)
if (rendermode != render_none && encoremode && !prevencoremode && !demo.rewinding)
{
tic_t locstarttime, endtime, nowtime;
@ -2877,7 +2882,7 @@ boolean P_SetupLevel(boolean skipprecip)
// Let's fade to white here
// But only if we didn't do the encore startup wipe
if (rendermode != render_none && !ranspecialwipe)
if (rendermode != render_none && !ranspecialwipe && !demo.rewinding)
{
F_WipeStartScreen();
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, levelfadecol);
@ -3109,9 +3114,9 @@ boolean P_SetupLevel(boolean skipprecip)
}
}
if (modeattacking == ATTACKING_RECORD && !demoplayback)
if (modeattacking == ATTACKING_RECORD && !demo.playback)
P_LoadRecordGhosts();
/*else if (modeattacking == ATTACKING_NIGHTS && !demoplayback)
/*else if (modeattacking == ATTACKING_NIGHTS && !demo.playback)
P_LoadNightsGhosts();*/
if (G_TagGametype())
@ -3159,25 +3164,25 @@ boolean P_SetupLevel(boolean skipprecip)
? cv_basenumlaps.value
: mapheaderinfo[gamemap - 1]->numlaps);
// Start recording replay in multiplayer with a temp filename
//@TODO I'd like to fix dedis crashing when recording replays for the future too...
if (!demo.playback && multiplayer && !dedicated) {
static char buf[256];
sprintf(buf, "replay"PATHSEP"online"PATHSEP"%d-%s", (int) (time(NULL)), G_BuildMapName(gamemap));
I_mkdir(va("%s"PATHSEP"replay", srb2home), 0755);
I_mkdir(va("%s"PATHSEP"replay"PATHSEP"online", srb2home), 0755);
G_RecordDemo(buf);
}
// ===========
// landing point for netgames.
netgameskip:
if (!dedicated)
{
P_SetupCamera(displayplayer, &camera);
if (splitscreen)
{
P_SetupCamera(secondarydisplayplayer, &camera2);
if (splitscreen > 1)
{
P_SetupCamera(thirddisplayplayer, &camera3);
if (splitscreen > 2)
{
P_SetupCamera(fourthdisplayplayer, &camera4);
}
}
}
for (i = 0; i <= splitscreen; i++)
P_SetupCamera(displayplayers[i], &camera[i]);
// Salt: CV_ClearChangedFlags() messes with your settings :(
/*if (!cv_cam_height.changed)
@ -3218,7 +3223,7 @@ boolean P_SetupLevel(boolean skipprecip)
/*if (rendermode != render_none)
CV_Set(&cv_fov, cv_fov.defaultvalue);*/
displayplayer = consoleplayer; // Start with your OWN view, please!
displayplayers[0] = consoleplayer; // Start with your OWN view, please!
}
/*if (cv_useranalog.value)
@ -3297,7 +3302,10 @@ boolean P_SetupLevel(boolean skipprecip)
savedata.lives = 0;
}
skyVisible = skyVisible1 = skyVisible2 = skyVisible3 = skyVisible4 = true; // assume the skybox is visible on level load.
// assume the skybox is visible on level load.
skyVisible = true;
memset(skyVisiblePerPlayer, true, sizeof(skyVisiblePerPlayer));
if (loadprecip) // uglier hack
{ // to make a newly loaded level start on the second frame.
INT32 buf = gametic % BACKUPTICS;

View File

@ -2243,7 +2243,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
I_Assert(!mo || !P_MobjWasRemoved(mo)); // If mo is there, mo must be valid!
if (mo && mo->player && botingame)
bot = players[secondarydisplayplayer].mo;
bot = players[displayplayers[1]].mo;
// note: only commands with linedef types >= 400 && < 500 can be used
switch (line->special)
@ -2381,35 +2381,21 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
if (mo->player)
{
UINT8 i;
if (bot) // This might put poor Tails in a wall if he's too far behind! D: But okay, whatever! >:3
P_TeleportMove(bot, bot->x + x, bot->y + y, bot->z + z);
if (splitscreen > 2 && mo->player == &players[fourthdisplayplayer] && camera4.chase)
for (i = 0; i <= splitscreen; i++)
{
camera4.x += x;
camera4.y += y;
camera4.z += z;
camera4.subsector = R_PointInSubsector(camera4.x, camera4.y);
if (mo->player == &players[displayplayers[i]] && camera[i].chase)
{
camera[i].x += x;
camera[i].y += y;
camera[i].z += z;
camera[i].subsector = R_PointInSubsector(camera[i].x, camera[i].y);
break;
}
else if (splitscreen > 1 && mo->player == &players[thirddisplayplayer] && camera3.chase)
{
camera3.x += x;
camera3.y += y;
camera3.z += z;
camera3.subsector = R_PointInSubsector(camera3.x, camera3.y);
}
else if (splitscreen && mo->player == &players[secondarydisplayplayer] && camera2.chase)
{
camera2.x += x;
camera2.y += y;
camera2.z += z;
camera2.subsector = R_PointInSubsector(camera2.x, camera2.y);
}
else if (camera.chase && mo->player == &players[displayplayer])
{
camera.x += x;
camera.y += y;
camera.z += z;
camera.subsector = R_PointInSubsector(camera.x, camera.y);
}
}
}
@ -2515,8 +2501,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
if (line->flags & ML_NOCLIMB)
{
// play the sound from nowhere, but only if display player triggered it
if (mo && mo->player && (mo->player == &players[displayplayer] || mo->player == &players[secondarydisplayplayer]
|| mo->player == &players[thirddisplayplayer] || mo->player == &players[fourthdisplayplayer]))
if (mo && mo->player && P_IsDisplayPlayer(mo->player))
S_StartSound(NULL, sfxnum);
}
else if (line->flags & ML_EFFECT4)
@ -3834,16 +3819,16 @@ DoneSection2:
if (player->mo->scale > mapobjectscale)
linespeed = FixedMul(linespeed, mapobjectscale + (player->mo->scale - mapobjectscale));
if (!demoplayback || P_AnalogMove(player))
if (!demo.playback || P_AnalogMove(player))
{
if (player == &players[consoleplayer])
localangle = player->mo->angle;
else if (player == &players[secondarydisplayplayer])
localangle2 = player->mo->angle;
else if (player == &players[thirddisplayplayer])
localangle3 = player->mo->angle;
else if (player == &players[fourthdisplayplayer])
localangle4 = player->mo->angle;
localangle[0] = player->mo->angle;
else if (player == &players[displayplayers[1]])
localangle[1] = player->mo->angle;
else if (player == &players[displayplayers[2]])
localangle[2] = player->mo->angle;
else if (player == &players[displayplayers[3]])
localangle[3] = player->mo->angle;
}
if (!(lines[i].flags & ML_EFFECT4))
@ -7841,44 +7826,44 @@ void T_Pusher(pusher_t *p)
thing->player->pflags |= PF_SLIDING;
thing->angle = R_PointToAngle2 (0, 0, xspeed<<(FRACBITS-PUSH_FACTOR), yspeed<<(FRACBITS-PUSH_FACTOR));
if (!demoplayback || P_AnalogMove(thing->player))
if (!demo.playback || P_AnalogMove(thing->player))
{
if (thing->player == &players[consoleplayer])
{
if (thing->angle - localangle > ANGLE_180)
localangle -= (localangle - thing->angle) / 8;
if (thing->angle - localangle[0] > ANGLE_180)
localangle[0] -= (localangle[0] - thing->angle) / 8;
else
localangle += (thing->angle - localangle) / 8;
localangle[0] += (thing->angle - localangle[0]) / 8;
}
else if (thing->player == &players[secondarydisplayplayer])
else if (thing->player == &players[displayplayers[1]])
{
if (thing->angle - localangle2 > ANGLE_180)
localangle2 -= (localangle2 - thing->angle) / 8;
if (thing->angle - localangle[1] > ANGLE_180)
localangle[1] -= (localangle[1] - thing->angle) / 8;
else
localangle2 += (thing->angle - localangle2) / 8;
localangle[1] += (thing->angle - localangle[1]) / 8;
}
else if (thing->player == &players[thirddisplayplayer])
else if (thing->player == &players[displayplayers[2]])
{
if (thing->angle - localangle3 > ANGLE_180)
localangle3 -= (localangle3 - thing->angle) / 8;
if (thing->angle - localangle[2] > ANGLE_180)
localangle[2] -= (localangle[2] - thing->angle) / 8;
else
localangle3 += (thing->angle - localangle3) / 8;
localangle[2] += (thing->angle - localangle[2]) / 8;
}
else if (thing->player == &players[fourthdisplayplayer])
else if (thing->player == &players[displayplayers[3]])
{
if (thing->angle - localangle4 > ANGLE_180)
localangle4 -= (localangle4 - thing->angle) / 8;
if (thing->angle - localangle[3] > ANGLE_180)
localangle[3] -= (localangle[3] - thing->angle) / 8;
else
localangle4 += (thing->angle - localangle4) / 8;
localangle[3] += (thing->angle - localangle[3]) / 8;
}
/*if (thing->player == &players[consoleplayer])
localangle = thing->angle;
else if (thing->player == &players[secondarydisplayplayer])
localangle2 = thing->angle;
else if (thing->player == &players[thirddisplayplayer])
localangle3 = thing->angle;
else if (thing->player == &players[fourthdisplayplayer])
localangle4 = thing->angle;*/
localangle[0] = thing->angle;
else if (thing->player == &players[displayplayers[1]])
localangle[1] = thing->angle;
else if (thing->player == &players[displayplayers[2]])
localangle[2] = thing->angle;
else if (thing->player == &players[displayplayers[3]])
localangle[3] = thing->angle;*/
}
}

View File

@ -36,6 +36,7 @@ void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
INT32 flags2)
{
const INT32 takeflags2 = MF2_TWOD|MF2_OBJECTFLIP;
UINT8 i;
// the move is ok,
// so link the thing into its new position
@ -64,23 +65,25 @@ void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
// absolute angle position
if (thing == players[consoleplayer].mo)
localangle = angle;
if (thing == players[secondarydisplayplayer].mo)
localangle2 = angle;
if (thing == players[thirddisplayplayer].mo)
localangle3 = angle;
if (thing == players[fourthdisplayplayer].mo)
localangle4 = angle;
localangle[0] = angle;
else if (splitscreen)
{
for (i = 1; i <= splitscreen; i++)
{
if (thing == players[displayplayers[i]].mo)
{
localangle[i] = angle;
break;
}
}
}
// move chasecam at new player location
if (splitscreen > 2 && camera4.chase && thing->player == &players[fourthdisplayplayer])
P_ResetCamera(thing->player, &camera4);
else if (splitscreen > 1 && camera3.chase && thing->player == &players[thirddisplayplayer])
P_ResetCamera(thing->player, &camera3);
else if (splitscreen && camera2.chase && thing->player == &players[secondarydisplayplayer])
P_ResetCamera(thing->player, &camera2);
else if (camera.chase && thing->player == &players[displayplayer])
P_ResetCamera(thing->player, &camera);
for (i = 0; i <= splitscreen; i++)
{
if (thing->player == &players[displayplayers[i]] && camera[i].chase)
P_ResetCamera(thing->player, &camera[i]);
}
// don't run in place after a teleport
thing->player->cmomx = thing->player->cmomy = 0;
@ -123,6 +126,8 @@ void P_MixUp(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle,
*/
boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle, boolean flash, boolean dontstopmove)
{
UINT8 i;
if (!P_TeleportMove(thing, x, y, z))
return false;
@ -144,24 +149,26 @@ boolean P_Teleport(mobj_t *thing, fixed_t x, fixed_t y, fixed_t z, angle_t angle
thing->reactiontime = TICRATE/2; // don't move for about half a second
// absolute angle position
if (thing->player == &players[consoleplayer])
localangle = angle;
if (thing->player == &players[secondarydisplayplayer])
localangle2 = angle;
if (thing->player == &players[thirddisplayplayer])
localangle3 = angle;
if (thing->player == &players[fourthdisplayplayer])
localangle4 = angle;
if (thing == players[consoleplayer].mo)
localangle[0] = angle;
else if (splitscreen)
{
for (i = 1; i <= splitscreen; i++)
{
if (thing == players[displayplayers[i]].mo)
{
localangle[i] = angle;
break;
}
}
}
// move chasecam at new player location
if (splitscreen > 2 && camera4.chase && thing->player == &players[fourthdisplayplayer])
P_ResetCamera(thing->player, &camera4);
else if (splitscreen > 1 && camera3.chase && thing->player == &players[thirddisplayplayer])
P_ResetCamera(thing->player, &camera3);
else if (splitscreen && camera2.chase && thing->player == &players[secondarydisplayplayer])
P_ResetCamera(thing->player, &camera2);
else if (camera.chase && thing->player == &players[displayplayer])
P_ResetCamera(thing->player, &camera);
for (i = 0; i <= splitscreen; i++)
{
if (thing->player == &players[displayplayers[i]] && camera[i].chase)
P_ResetCamera(thing->player, &camera[i]);
}
// don't run in place after a teleport
if (!dontstopmove)

View File

@ -13,6 +13,7 @@
#include "doomstat.h"
#include "g_game.h"
#include "g_input.h"
#include "p_local.h"
#include "z_zone.h"
#include "s_sound.h"
@ -582,7 +583,7 @@ void P_Ticker(boolean run)
{
P_MapStart();
OP_ObjectplaceMovement(&players[0]);
P_MoveChaseCamera(&players[0], &camera, false);
P_MoveChaseCamera(&players[0], &camera[0], false);
P_MapEnd();
return;
}
@ -590,18 +591,60 @@ void P_Ticker(boolean run)
// Check for pause or menu up in single player
if (paused || P_AutoPause())
return;
{
if (demo.rewinding && leveltime > 0)
{
leveltime = (leveltime-1) & ~3;
G_PreviewRewind(leveltime);
}
postimgtype = postimgtype2 = postimgtype3 = postimgtype4 = postimg_none;
return;
}
for (i = 0; i <= splitscreen; i++)
postimgtype[i] = postimg_none;
P_MapStart();
if (run)
{
if (demorecording)
G_WriteDemoTiccmd(&players[consoleplayer].cmd, 0);
if (demoplayback)
if (demo.recording)
{
G_WriteDemoExtraData();
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i])
G_WriteDemoTiccmd(&players[i].cmd, i);
}
if (demo.playback)
{
#ifdef DEMO_COMPAT_100
if (demo.version == 0x0001)
{
G_ReadDemoTiccmd(&players[consoleplayer].cmd, 0);
}
else
{
#endif
G_ReadDemoExtraData();
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i])
{
//@TODO all this throwdir stuff shouldn't be here! But it's added to maintain 1.0.4 compat for now...
// Remove for 1.1!
if (players[i].cmd.buttons & BT_FORWARD)
players[i].kartstuff[k_throwdir] = 1;
else if (players[i].cmd.buttons & BT_BACKWARD)
players[i].kartstuff[k_throwdir] = -1;
else
players[i].kartstuff[k_throwdir] = 0;
G_ReadDemoTiccmd(&players[i].cmd, i);
}
#ifdef DEMO_COMPAT_100
}
#endif
}
for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i] && players[i].mo && !P_MobjWasRemoved(players[i].mo))
@ -609,7 +652,7 @@ void P_Ticker(boolean run)
}
// Keep track of how long they've been playing!
if (!demoplayback) // Don't increment if a demo is playing.
if (!demo.playback) // Don't increment if a demo is playing.
totalplaytime++;
/*if (!useNightsSS && G_IsSpecialStage(gamemap))
@ -705,10 +748,25 @@ void P_Ticker(boolean run)
G_ReadMetalTic(metalplayback);
if (metalrecording)
G_WriteMetalTic(players[consoleplayer].mo);
if (demorecording)
G_WriteGhostTic(players[consoleplayer].mo);
if (demoplayback) // Use Ghost data for consistency checks.
G_ConsGhostTic();
if (demo.recording)
{
G_WriteAllGhostTics();
if (cv_recordmultiplayerdemos.value && (demo.savemode == DSM_NOTSAVING || demo.savemode == DSM_WILLAUTOSAVE))
if (demo.savebutton && demo.savebutton + 3*TICRATE < leveltime && InputDown(gc_lookback, 1))
demo.savemode = DSM_TITLEENTRY;
}
else if (demo.playback) // Use Ghost data for consistency checks.
{
#ifdef DEMO_COMPAT_100
if (demo.version == 0x0001)
G_ConsGhostTic(0);
else
#endif
G_ConsAllGhostTics();
}
if (modeattacking)
G_GhostTicker();
@ -719,17 +777,17 @@ void P_Ticker(boolean run)
}
// Always move the camera.
if (camera.chase)
P_MoveChaseCamera(&players[displayplayer], &camera, false);
if (splitscreen && camera2.chase)
P_MoveChaseCamera(&players[secondarydisplayplayer], &camera2, false);
if (splitscreen > 1 && camera3.chase)
P_MoveChaseCamera(&players[thirddisplayplayer], &camera3, false);
if (splitscreen > 2 && camera4.chase)
P_MoveChaseCamera(&players[fourthdisplayplayer], &camera4, false);
for (i = 0; i <= splitscreen; i++)
{
if (camera[i].chase)
P_MoveChaseCamera(&players[displayplayers[i]], &camera[i], false);
}
P_MapEnd();
if (demo.playback)
G_StoreRewindInfo();
// Z_CheckMemCleanup();
}
@ -739,7 +797,8 @@ void P_PreTicker(INT32 frames)
INT32 i,framecnt;
ticcmd_t temptic;
postimgtype = postimgtype2 = postimgtype3 = postimgtype4 = postimg_none;
for (i = 0; i <= splitscreen; i++)
postimgtype[i] = postimg_none;
for (framecnt = 0; framecnt < frames; ++framecnt)
{

File diff suppressed because it is too large Load Diff

View File

@ -252,20 +252,23 @@ sector_t *R_FakeFlat(sector_t *sec, sector_t *tempsec, INT32 *floorlightlevel,
mobj_t *viewmobj = viewplayer->mo;
INT32 heightsec;
boolean underwater;
UINT8 i;
if (splitscreen > 2 && viewplayer == &players[fourthdisplayplayer] && camera4.chase)
heightsec = R_PointInSubsector(camera4.x, camera4.y)->sector->heightsec;
else if (splitscreen > 1 && viewplayer == &players[thirddisplayplayer] && camera3.chase)
heightsec = R_PointInSubsector(camera3.x, camera3.y)->sector->heightsec;
else if (splitscreen && viewplayer == &players[secondarydisplayplayer] && camera2.chase)
heightsec = R_PointInSubsector(camera2.x, camera2.y)->sector->heightsec;
else if (camera.chase && viewplayer == &players[displayplayer])
heightsec = R_PointInSubsector(camera.x, camera.y)->sector->heightsec;
else if (viewmobj)
for (i = 0; i <= splitscreen; i++)
{
if (viewplayer == &players[displayplayers[i]] && camera[i].chase)
{
heightsec = R_PointInSubsector(camera[i].x, camera[i].y)->sector->heightsec;
break;
}
}
if (i > splitscreen && viewmobj)
heightsec = R_PointInSubsector(viewmobj->x, viewmobj->y)->sector->heightsec;
else
return sec;
underwater = heightsec != -1 && viewz <= sectors[heightsec].floorheight;
underwater = (heightsec != -1 && viewz <= sectors[heightsec].floorheight);
// Replace sector being drawn, with a copy to be hacked
*tempsec = *sec;
@ -827,7 +830,7 @@ static void R_AddPolyObjects(subsector_t *sub)
drawseg_t *firstseg;
static void R_Subsector(size_t num, UINT8 viewnumber)
static void R_Subsector(size_t num)
{
INT32 count, floorlightlevel, ceilinglightlevel, light;
seg_t *line;
@ -1149,7 +1152,7 @@ static void R_Subsector(size_t num, UINT8 viewnumber)
// Either you must pass the fake sector and handle validcount here, on the
// real sector, or you must account for the lighting in some other way,
// like passing it as an argument.
R_AddSprites(sub->sector, (floorlightlevel+ceilinglightlevel)/2, viewnumber);
R_AddSprites(sub->sector, (floorlightlevel+ceilinglightlevel)/2);
firstseg = NULL;
@ -1355,7 +1358,7 @@ INT32 R_GetPlaneLight(sector_t *sector, fixed_t planeheight, boolean underside)
//
// killough 5/2/98: reformatted, removed tail recursion
void R_RenderBSPNode(INT32 bspnum, UINT8 viewnumber)
void R_RenderBSPNode(INT32 bspnum)
{
node_t *bsp;
INT32 side;
@ -1366,7 +1369,7 @@ void R_RenderBSPNode(INT32 bspnum, UINT8 viewnumber)
// Decide which side the view point is on.
side = R_PointOnSide(viewx, viewy, bsp);
// Recursively divide front space.
R_RenderBSPNode(bsp->children[side], viewnumber);
R_RenderBSPNode(bsp->children[side]);
// Possibly divide back space.
@ -1384,5 +1387,5 @@ void R_RenderBSPNode(INT32 bspnum, UINT8 viewnumber)
portalcullsector = NULL;
}
R_Subsector(bspnum == -1 ? 0 : bspnum & ~NF_SUBSECTOR, viewnumber);
R_Subsector(bspnum == -1 ? 0 : bspnum & ~NF_SUBSECTOR);
}

View File

@ -37,7 +37,7 @@ extern INT32 doorclosed;
void R_ClearClipSegs(void);
void R_PortalClearClipSegs(INT32 start, INT32 end);
void R_ClearDrawSegs(void);
void R_RenderBSPNode(INT32 bspnum, UINT8 viewnumber);
void R_RenderBSPNode(INT32 bspnum);
void R_AddPortal(INT32 line1, INT32 line2, INT32 x1, INT32 x2);
#ifdef POLYOBJECTS

View File

@ -1600,7 +1600,7 @@ void R_PrecacheLevel(void)
thinker_t *th;
spriteframe_t *sf;
if (demoplayback)
if (demo.playback)
return;
// do not flush the memory, Z_Malloc twice with same user will cause error in Z_CheckHeap()

View File

@ -30,6 +30,7 @@
#include "p_spec.h" // skyboxmo
#include "z_zone.h"
#include "m_random.h" // quake camera shake
#include "doomstat.h" // MAXSPLITSCREENPLAYERS
#ifdef HWRENDER
#include "hardware/hw_main.h"
@ -65,9 +66,10 @@ size_t loopcount;
fixed_t viewx, viewy, viewz;
angle_t viewangle, aimingangle;
UINT8 viewssnum;
fixed_t viewcos, viewsin;
boolean viewsky, skyVisible;
boolean skyVisible1, skyVisible2, skyVisible3, skyVisible4; // saved values of skyVisible for P1/P2/P3/P4, for splitscreen
boolean skyVisiblePerPlayer[MAXSPLITSCREENPLAYERS]; // saved values of skyVisible for each splitscreen player
sector_t *viewsector;
player_t *viewplayer;
@ -193,19 +195,12 @@ void SplitScreen_OnChange(void)
// recompute screen size
R_ExecuteSetViewSize();
if (!demoplayback && !botingame)
if (!demo.playback && !botingame)
{
for (i = 1; i < 3; i++)
for (i = 1; i < MAXSPLITSCREENPLAYERS; i++)
{
if (i > splitscreen)
{
if (i == 1)
CL_RemoveSplitscreenPlayer(secondarydisplayplayer);
else if (i == 2)
CL_RemoveSplitscreenPlayer(thirddisplayplayer);
else if (i == 3)
CL_RemoveSplitscreenPlayer(fourthdisplayplayer);
}
CL_RemoveSplitscreenPlayer(displayplayers[i]);
else
CL_AddSplitscreenPlayer();
}
@ -215,22 +210,28 @@ void SplitScreen_OnChange(void)
}
else
{
secondarydisplayplayer = consoleplayer;
thirddisplayplayer = consoleplayer;
fourthdisplayplayer = consoleplayer;
for (i = 1; i < MAXSPLITSCREENPLAYERS; i++)
displayplayers[i] = consoleplayer;
for (i = 0; i < MAXPLAYERS; i++)
{
if (playeringame[i] && i != consoleplayer)
{
if (secondarydisplayplayer == consoleplayer)
secondarydisplayplayer = i;
else if (thirddisplayplayer == consoleplayer)
thirddisplayplayer = i;
else if (fourthdisplayplayer == consoleplayer)
fourthdisplayplayer = i;
else
UINT8 j;
for (j = 1; j < MAXSPLITSCREENPLAYERS; j++)
{
if (displayplayers[j] == consoleplayer)
{
displayplayers[j] = i;
break;
}
}
if (j == MAXSPLITSCREENPLAYERS)
break;
}
}
}
}
static void Fov_OnChange(void)
{
@ -844,16 +845,20 @@ static void R_SetupFreelook(void)
void R_SkyboxFrame(player_t *player)
{
camera_t *thiscam;
camera_t *thiscam = &camera[0];
UINT8 i;
if (splitscreen > 2 && player == &players[fourthdisplayplayer])
thiscam = &camera4;
else if (splitscreen > 1 && player == &players[thirddisplayplayer])
thiscam = &camera3;
else if (splitscreen && player == &players[secondarydisplayplayer])
thiscam = &camera2;
else
thiscam = &camera;
if (splitscreen)
{
for (i = 1; i <= splitscreen; i++)
{
if (player == &players[displayplayers[i]])
{
thiscam = &camera[i];
break;
}
}
}
// cut-away view stuff
viewsky = true;
@ -879,27 +884,24 @@ void R_SkyboxFrame(player_t *player)
{
aimingangle = player->aiming;
viewangle = player->mo->angle;
if (/*!demoplayback && */player->playerstate != PST_DEAD)
if (/*!demo.playback && */player->playerstate != PST_DEAD)
{
if (player == &players[consoleplayer])
{
viewangle = localangle; // WARNING: camera uses this
aimingangle = localaiming;
viewangle = localangle[0]; // WARNING: camera uses this
aimingangle = localaiming[0];
}
else if (player == &players[secondarydisplayplayer])
else if (splitscreen)
{
viewangle = localangle2;
aimingangle = localaiming2;
for (i = 1; i <= splitscreen; i++)
{
if (player == &players[displayplayers[i]])
{
viewangle = localangle[i];
aimingangle = localaiming[i];
break;
}
else if (player == &players[thirddisplayplayer])
{
viewangle = localangle3;
aimingangle = localaiming3;
}
else if (player == &players[fourthdisplayplayer])
{
viewangle = localangle4;
aimingangle = localaiming4;
}
}
}
@ -1078,24 +1080,24 @@ void R_SetupFrame(player_t *player, boolean skybox)
camera_t *thiscam;
boolean chasecam = false;
if (splitscreen > 2 && player == &players[fourthdisplayplayer])
if (splitscreen > 2 && player == &players[displayplayers[3]])
{
thiscam = &camera4;
thiscam = &camera[3];
chasecam = (cv_chasecam4.value != 0);
}
else if (splitscreen > 1 && player == &players[thirddisplayplayer])
else if (splitscreen > 1 && player == &players[displayplayers[2]])
{
thiscam = &camera3;
thiscam = &camera[2];
chasecam = (cv_chasecam3.value != 0);
}
else if (splitscreen && player == &players[secondarydisplayplayer])
else if (splitscreen && player == &players[displayplayers[1]])
{
thiscam = &camera2;
thiscam = &camera[1];
chasecam = (cv_chasecam2.value != 0);
}
else
{
thiscam = &camera;
thiscam = &camera[0];
chasecam = (cv_chasecam.value != 0);
}
@ -1141,27 +1143,25 @@ void R_SetupFrame(player_t *player, boolean skybox)
aimingangle = player->aiming;
viewangle = viewmobj->angle;
if (/*!demoplayback && */player->playerstate != PST_DEAD)
if (/*!demo.playback && */player->playerstate != PST_DEAD)
{
if (player == &players[consoleplayer])
{
viewangle = localangle; // WARNING: camera uses this
aimingangle = localaiming;
viewangle = localangle[0]; // WARNING: camera uses this
aimingangle = localaiming[0];
}
else if (player == &players[secondarydisplayplayer])
else if (splitscreen)
{
viewangle = localangle2;
aimingangle = localaiming2;
UINT8 i;
for (i = 1; i <= splitscreen; i++)
{
if (player == &players[displayplayers[i]])
{
viewangle = localangle[i];
aimingangle = localaiming[i];
break;
}
else if (player == &players[thirddisplayplayer])
{
viewangle = localangle3;
aimingangle = localaiming3;
}
else if (player == &players[fourthdisplayplayer])
{
viewangle = localangle4;
aimingangle = localaiming4;
}
}
}
@ -1323,19 +1323,10 @@ void R_RenderPlayerView(player_t *player)
{
portal_pair *portal;
const boolean skybox = (skyboxmo[0] && cv_skybox.value);
UINT8 viewnumber;
if (player == &players[secondarydisplayplayer] && splitscreen)
viewnumber = 1;
else if (player == &players[thirddisplayplayer] && splitscreen > 1)
viewnumber = 2;
else if (player == &players[fourthdisplayplayer] && splitscreen > 2)
viewnumber = 3;
else
viewnumber = 0;
UINT8 i;
// if this is display player 1
if (cv_homremoval.value && player == &players[displayplayer])
if (cv_homremoval.value && player == &players[displayplayers[0]])
{
if (cv_homremoval.value == 1)
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 31); // No HOM effect!
@ -1343,7 +1334,7 @@ void R_RenderPlayerView(player_t *player)
V_DrawFill(0, 0, BASEVIDWIDTH, BASEVIDHEIGHT, 128+(timeinmap&15));
}
// Draw over the fourth screen so you don't have to stare at a HOM :V
else if (splitscreen == 2 && player == &players[thirddisplayplayer])
else if (splitscreen == 2 && player == &players[displayplayers[2]])
#if 1
{
// V_DrawPatchFill, but for the fourth screen only
@ -1362,14 +1353,14 @@ void R_RenderPlayerView(player_t *player)
#endif
// load previous saved value of skyVisible for the player
if (splitscreen > 2 && player == &players[fourthdisplayplayer])
skyVisible = skyVisible4;
else if (splitscreen > 1 && player == &players[thirddisplayplayer])
skyVisible = skyVisible3;
else if (splitscreen && player == &players[secondarydisplayplayer])
skyVisible = skyVisible2;
else
skyVisible = skyVisible1;
for (i = 0; i <= splitscreen; i++)
{
if (player == &players[displayplayers[i]])
{
skyVisible = skyVisiblePerPlayer[i];
break;
}
}
portalrender = 0;
portal_base = portal_cap = NULL;
@ -1386,7 +1377,7 @@ void R_RenderPlayerView(player_t *player)
R_ClearVisibleFloorSplats();
#endif
R_RenderBSPNode((INT32)numnodes - 1, viewnumber);
R_RenderBSPNode((INT32)numnodes - 1);
R_ClipSprites();
R_DrawPlanes();
#ifdef FLOORSPLATS
@ -1419,7 +1410,7 @@ void R_RenderPlayerView(player_t *player)
mytotal = 0;
ProfZeroTimer();
#endif
R_RenderBSPNode((INT32)numnodes - 1, viewnumber);
R_RenderBSPNode((INT32)numnodes - 1);
R_ClipSprites();
#ifdef TIMING
RDMSR(0x10, &mycount);
@ -1444,7 +1435,7 @@ void R_RenderPlayerView(player_t *player)
validcount++;
R_RenderBSPNode((INT32)numnodes - 1, viewnumber);
R_RenderBSPNode((INT32)numnodes - 1);
R_ClipSprites();
//R_DrawPlanes();
//R_DrawMasked();
@ -1470,16 +1461,16 @@ void R_RenderPlayerView(player_t *player)
// Check for new console commands.
NetUpdate();
// save value to skyVisible1 or skyVisible2
// save value to skyVisiblePerPlayer
// this is so that P1 can't affect whether P2 can see a skybox or not, or vice versa
if (splitscreen > 2 && player == &players[fourthdisplayplayer])
skyVisible4 = skyVisible;
else if (splitscreen > 1 && player == &players[thirddisplayplayer])
skyVisible3 = skyVisible;
else if (splitscreen && player == &players[secondarydisplayplayer])
skyVisible2 = skyVisible;
else
skyVisible1 = skyVisible;
for (i = 0; i <= splitscreen; i++)
{
if (player == &players[displayplayers[i]])
{
skyVisiblePerPlayer[i] = skyVisible;
break;
}
}
}
// =========================================================================
@ -1561,7 +1552,6 @@ void R_RegisterEngineStuff(void)
CV_RegisterVar(&cv_grgammared);
CV_RegisterVar(&cv_grfovchange);
CV_RegisterVar(&cv_grfog);
CV_RegisterVar(&cv_voodoocompatibility);
CV_RegisterVar(&cv_grfogcolor);
CV_RegisterVar(&cv_grsoftwarefog);
#ifdef ALAM_LIGHTING
@ -1570,7 +1560,8 @@ void R_RegisterEngineStuff(void)
CV_RegisterVar(&cv_grcoronas);
CV_RegisterVar(&cv_grcoronasize);
#endif
CV_RegisterVar(&cv_grmd2);
CV_RegisterVar(&cv_grmdls);
CV_RegisterVar(&cv_grfallbackplayermodel);
#endif
#ifdef HWRENDER

View File

@ -883,12 +883,12 @@ void R_DrawSinglePlane(visplane_t *pl)
if (bottom > vid.height)
bottom = vid.height;
if (splitscreen > 2 && viewplayer == &players[fourthdisplayplayer]) // Only copy the part of the screen we need
if (splitscreen > 2 && viewplayer == &players[displayplayers[3]]) // Only copy the part of the screen we need
scr = (screens[0] + (top+(viewheight))*vid.width + viewwidth);
else if ((splitscreen == 1 && viewplayer == &players[secondarydisplayplayer])
|| (splitscreen > 1 && viewplayer == &players[thirddisplayplayer]))
else if ((splitscreen == 1 && viewplayer == &players[displayplayers[1]])
|| (splitscreen > 1 && viewplayer == &players[displayplayers[2]]))
scr = (screens[0] + (top+(viewheight))*vid.width);
else if (splitscreen > 1 && viewplayer == &players[secondarydisplayplayer])
else if (splitscreen > 1 && viewplayer == &players[displayplayers[1]])
scr = (screens[0] + ((top)*vid.width) + viewwidth);
else
scr = (screens[0] + ((top)*vid.width));

View File

@ -17,6 +17,7 @@
// Need data structure definitions.
#include "d_player.h"
#include "r_data.h"
#include "doomstat.h" // MAXSPLITSCREENPLAYERS
#ifdef __GNUG__
#pragma interface
@ -88,8 +89,9 @@ extern side_t *sides;
//
extern fixed_t viewx, viewy, viewz;
extern angle_t viewangle, aimingangle;
extern UINT8 viewssnum; // splitscreen view number
extern boolean viewsky, skyVisible;
extern boolean skyVisible1, skyVisible2, skyVisible3, skyVisible4; // saved values of skyVisible for P1 and P2, for splitscreen
extern boolean skyVisiblePerPlayer[MAXSPLITSCREENPLAYERS]; // saved values of skyVisible of each splitscreen player
extern sector_t *viewsector;
extern player_t *viewplayer;
extern UINT8 portalrender;

View File

@ -40,6 +40,8 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
//int vsnprintf(char *str, size_t n, const char *fmt, va_list ap);
#endif
CV_PossibleValue_t Forceskin_cons_t[MAXSKINS+2];
static void R_InitSkins(void);
#define MINZ (FRACUNIT*4)
@ -925,6 +927,13 @@ static void R_DrawVisSprite(vissprite_t *vis)
if (vis->x2 >= vid.width)
vis->x2 = vid.width-1;
#if 1
// Something is occasionally setting 1px-wide sprites whose frac is exactly the width of the sprite, causing crashes due to
// accessing invalid column info. Until the cause is found, let's try to correct those manually...
while (frac + vis->xiscale*(vis->x2-vis->x1) > SHORT(patch->width)<<FRACBITS && vis->x2 >= vis->x1)
vis->x2--;
#endif
for (dc_x = vis->x1; dc_x <= vis->x2; dc_x++, frac += vis->xiscale)
{
if (vis->scalestep) // currently papersprites only
@ -1695,7 +1704,7 @@ static void R_ProjectPrecipitationSprite(precipmobj_t *thing)
// R_AddSprites
// During BSP traversal, this adds sprites by sector.
//
void R_AddSprites(sector_t *sec, INT32 lightlevel, UINT8 viewnumber)
void R_AddSprites(sector_t *sec, INT32 lightlevel)
{
mobj_t *thing;
precipmobj_t *precipthing; // Tails 08-25-2002
@ -1741,19 +1750,19 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel, UINT8 viewnumber)
if (splitscreen)
{
if (thing->eflags & MFE_DRAWONLYFORP1)
if (viewnumber != 0)
if (viewssnum != 0)
continue;
if (thing->eflags & MFE_DRAWONLYFORP2)
if (viewnumber != 1)
if (viewssnum != 1)
continue;
if (thing->eflags & MFE_DRAWONLYFORP3 && splitscreen > 1)
if (viewnumber != 2)
if (viewssnum != 2)
continue;
if (thing->eflags & MFE_DRAWONLYFORP4 && splitscreen > 2)
if (viewnumber != 3)
if (viewssnum != 3)
continue;
}
@ -1776,19 +1785,19 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel, UINT8 viewnumber)
if (splitscreen)
{
if (thing->eflags & MFE_DRAWONLYFORP1)
if (viewnumber != 0)
if (viewssnum != 0)
continue;
if (thing->eflags & MFE_DRAWONLYFORP2)
if (viewnumber != 1)
if (viewssnum != 1)
continue;
if (thing->eflags & MFE_DRAWONLYFORP3 && splitscreen > 1)
if (viewnumber != 2)
if (viewssnum != 2)
continue;
if (thing->eflags & MFE_DRAWONLYFORP4 && splitscreen > 2)
if (viewnumber != 3)
if (viewssnum != 3)
continue;
}
@ -1796,7 +1805,7 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel, UINT8 viewnumber)
}
}
// Someone seriously wants infinite draw distance for precipitation?
// no, no infinite draw distance for precipitation. this option at zero is supposed to turn it off
if ((limit_dist = (fixed_t)cv_drawdist_precip.value << FRACBITS))
{
for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext)
@ -1812,13 +1821,6 @@ void R_AddSprites(sector_t *sec, INT32 lightlevel, UINT8 viewnumber)
R_ProjectPrecipitationSprite(precipthing);
}
}
else
{
// Draw everything in sector, no checks
for (precipthing = sec->preciplist; precipthing; precipthing = precipthing->snext)
if (!(precipthing->precipflags & PCF_INVISIBLE))
R_ProjectPrecipitationSprite(precipthing);
}
}
//
@ -2588,6 +2590,10 @@ void R_InitSkins(void)
skin->spritedef.spriteframes = sprites[SPR_PLAY].spriteframes;
ST_LoadFaceGraphics(skin->facerank, skin->facewant, skin->facemmap, 0);
// Set values for Sonic skin
Forceskin_cons_t[1].value = 0;
Forceskin_cons_t[1].strvalue = skin->name;
//MD2 for sonic doesn't want to load in Linux.
#ifdef HWRENDER
if (rendermode == render_opengl)
@ -2653,15 +2659,15 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
player->kartspeed = skin->kartspeed;
player->kartweight = skin->kartweight;
/*if (!(cv_debug || devparm) && !(netgame || multiplayer || demoplayback || modeattacking))
/*if (!(cv_debug || devparm) && !(netgame || multiplayer || demo.playback || modeattacking))
{
if (playernum == consoleplayer)
CV_StealthSetValue(&cv_playercolor, skin->prefcolor);
else if (playernum == secondarydisplayplayer)
else if (playernum == displayplayers[1])
CV_StealthSetValue(&cv_playercolor2, skin->prefcolor);
else if (playernum == thirddisplayplayer)
else if (playernum == displayplayers[2])
CV_StealthSetValue(&cv_playercolor3, skin->prefcolor);
else if (playernum == fourthdisplayplayer)
else if (playernum == displayplayers[3])
CV_StealthSetValue(&cv_playercolor4, skin->prefcolor);
player->skincolor = skin->prefcolor;
if (player->mo)
@ -2670,6 +2676,9 @@ void SetPlayerSkinByNum(INT32 playernum, INT32 skinnum)
if (player->mo)
P_SetScale(player->mo, player->mo->scale);
demo_extradata[playernum] |= DXD_SKIN;
return;
}
@ -2971,6 +2980,10 @@ next_token:
skin_cons_t[numskins].strvalue = skin->name;
#endif
// Update the forceskin possiblevalues
Forceskin_cons_t[numskins+1].value = numskins;
Forceskin_cons_t[numskins+1].strvalue = skins[numskins].name;
// add face graphics
ST_LoadFaceGraphics(skin->facerank, skin->facewant, skin->facemmap, numskins);

View File

@ -55,7 +55,7 @@ void R_DelSpriteDefs(UINT16 wadnum);
#endif
//SoM: 6/5/2000: Light sprites correctly!
void R_AddSprites(sector_t *sec, INT32 lightlevel, UINT8 viewnumber);
void R_AddSprites(sector_t *sec, INT32 lightlevel);
void R_InitSprites(void);
void R_ClearSprites(void);
void R_ClipSprites(void);
@ -97,6 +97,8 @@ typedef struct
sfxenum_t soundsid[NUMSKINSOUNDS]; // sound # in S_sfx table
} skin_t;
extern CV_PossibleValue_t Forceskin_cons_t[];
// -----------
// NOT SKINS STUFF !
// -----------

View File

@ -438,7 +438,7 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
listener_t listener3 = {0,0,0,0};
listener_t listener4 = {0,0,0,0};
mobj_t *listenmobj = players[displayplayer].mo;
mobj_t *listenmobj = players[displayplayers[0]].mo;
mobj_t *listenmobj2 = NULL;
mobj_t *listenmobj3 = NULL;
mobj_t *listenmobj4 = NULL;
@ -450,26 +450,26 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
if (sfx_id == sfx_None)
return;
if (players[displayplayer].awayviewtics)
listenmobj = players[displayplayer].awayviewmobj;
if (players[displayplayers[0]].awayviewtics)
listenmobj = players[displayplayers[0]].awayviewmobj;
if (splitscreen)
{
listenmobj2 = players[secondarydisplayplayer].mo;
if (players[secondarydisplayplayer].awayviewtics)
listenmobj2 = players[secondarydisplayplayer].awayviewmobj;
listenmobj2 = players[displayplayers[1]].mo;
if (players[displayplayers[1]].awayviewtics)
listenmobj2 = players[displayplayers[1]].awayviewmobj;
if (splitscreen > 1)
{
listenmobj3 = players[thirddisplayplayer].mo;
if (players[thirddisplayplayer].awayviewtics)
listenmobj3 = players[thirddisplayplayer].awayviewmobj;
listenmobj3 = players[displayplayers[2]].mo;
if (players[displayplayers[2]].awayviewtics)
listenmobj3 = players[displayplayers[2]].awayviewmobj;
if (splitscreen > 2)
{
listenmobj4 = players[fourthdisplayplayer].mo;
if (players[fourthdisplayplayer].awayviewtics)
listenmobj4 = players[fourthdisplayplayer].awayviewmobj;
listenmobj4 = players[displayplayers[3]].mo;
if (players[displayplayers[3]].awayviewtics)
listenmobj4 = players[displayplayers[3]].awayviewmobj;
}
}
}
@ -482,12 +482,12 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
};
#endif
if (camera.chase && !players[displayplayer].awayviewtics)
if (camera[0].chase && !players[displayplayers[0]].awayviewtics)
{
listener.x = camera.x;
listener.y = camera.y;
listener.z = camera.z;
listener.angle = camera.angle;
listener.x = camera[0].x;
listener.y = camera[0].y;
listener.z = camera[0].z;
listener.angle = camera[0].angle;
}
else if (listenmobj)
{
@ -501,12 +501,12 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
if (listenmobj2)
{
if (camera2.chase && !players[secondarydisplayplayer].awayviewtics)
if (camera[1].chase && !players[displayplayers[1]].awayviewtics)
{
listener2.x = camera2.x;
listener2.y = camera2.y;
listener2.z = camera2.z;
listener2.angle = camera2.angle;
listener2.x = camera[1].x;
listener2.y = camera[1].y;
listener2.z = camera[1].z;
listener2.angle = camera[1].angle;
}
else
{
@ -519,12 +519,12 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
if (listenmobj3)
{
if (camera3.chase && !players[thirddisplayplayer].awayviewtics)
if (camera[2].chase && !players[displayplayers[2]].awayviewtics)
{
listener3.x = camera3.x;
listener3.y = camera3.y;
listener3.z = camera3.z;
listener3.angle = camera3.angle;
listener3.x = camera[2].x;
listener3.y = camera[2].y;
listener3.z = camera[2].z;
listener3.angle = camera[2].angle;
}
else
{
@ -537,12 +537,12 @@ void S_StartSoundAtVolume(const void *origin_p, sfxenum_t sfx_id, INT32 volume)
if (listenmobj4)
{
if (camera4.chase && !players[fourthdisplayplayer].awayviewtics)
if (camera[3].chase && !players[displayplayers[3]].awayviewtics)
{
listener4.x = camera4.x;
listener4.y = camera4.y;
listener4.z = camera4.z;
listener4.angle = camera4.angle;
listener4.x = camera[3].x;
listener4.y = camera[3].y;
listener4.z = camera[3].z;
listener4.angle = camera[3].angle;
}
else
{
@ -899,7 +899,7 @@ void S_UpdateSounds(void)
listener_t listener3;
listener_t listener4;
mobj_t *listenmobj = players[displayplayer].mo;
mobj_t *listenmobj = players[displayplayers[0]].mo;
mobj_t *listenmobj2 = NULL;
mobj_t *listenmobj3 = NULL;
mobj_t *listenmobj4 = NULL;
@ -935,36 +935,36 @@ void S_UpdateSounds(void)
if (dedicated || sound_disabled)
return;
if (players[displayplayer].awayviewtics)
listenmobj = players[displayplayer].awayviewmobj;
if (players[displayplayers[0]].awayviewtics)
listenmobj = players[displayplayers[0]].awayviewmobj;
if (splitscreen)
{
listenmobj2 = players[secondarydisplayplayer].mo;
if (players[secondarydisplayplayer].awayviewtics)
listenmobj2 = players[secondarydisplayplayer].awayviewmobj;
listenmobj2 = players[displayplayers[1]].mo;
if (players[displayplayers[1]].awayviewtics)
listenmobj2 = players[displayplayers[1]].awayviewmobj;
if (splitscreen > 1)
{
listenmobj3 = players[thirddisplayplayer].mo;
if (players[thirddisplayplayer].awayviewtics)
listenmobj3 = players[thirddisplayplayer].awayviewmobj;
listenmobj3 = players[displayplayers[2]].mo;
if (players[displayplayers[2]].awayviewtics)
listenmobj3 = players[displayplayers[2]].awayviewmobj;
if (splitscreen > 2)
{
listenmobj4 = players[fourthdisplayplayer].mo;
if (players[fourthdisplayplayer].awayviewtics)
listenmobj4 = players[fourthdisplayplayer].awayviewmobj;
listenmobj4 = players[displayplayers[3]].mo;
if (players[displayplayers[3]].awayviewtics)
listenmobj4 = players[displayplayers[3]].awayviewmobj;
}
}
}
if (camera.chase && !players[displayplayer].awayviewtics)
if (camera[0].chase && !players[displayplayers[0]].awayviewtics)
{
listener.x = camera.x;
listener.y = camera.y;
listener.z = camera.z;
listener.angle = camera.angle;
listener.x = camera[0].x;
listener.y = camera[0].y;
listener.z = camera[0].z;
listener.angle = camera[0].angle;
}
else if (listenmobj)
{
@ -989,12 +989,12 @@ void S_UpdateSounds(void)
if (listenmobj2)
{
if (camera2.chase && !players[secondarydisplayplayer].awayviewtics)
if (camera[1].chase && !players[displayplayers[1]].awayviewtics)
{
listener2.x = camera2.x;
listener2.y = camera2.y;
listener2.z = camera2.z;
listener2.angle = camera2.angle;
listener2.x = camera[1].x;
listener2.y = camera[1].y;
listener2.z = camera[1].z;
listener2.angle = camera[1].angle;
}
else
{
@ -1007,12 +1007,12 @@ void S_UpdateSounds(void)
if (listenmobj3)
{
if (camera3.chase && !players[thirddisplayplayer].awayviewtics)
if (camera[2].chase && !players[displayplayers[2]].awayviewtics)
{
listener3.x = camera3.x;
listener3.y = camera3.y;
listener3.z = camera3.z;
listener3.angle = camera3.angle;
listener3.x = camera[2].x;
listener3.y = camera[2].y;
listener3.z = camera[2].z;
listener3.angle = camera[2].angle;
}
else
{
@ -1025,12 +1025,12 @@ void S_UpdateSounds(void)
if (listenmobj4)
{
if (camera4.chase && !players[fourthdisplayplayer].awayviewtics)
if (camera[3].chase && !players[displayplayers[3]].awayviewtics)
{
listener4.x = camera4.x;
listener4.y = camera4.y;
listener4.z = camera4.z;
listener4.angle = camera4.angle;
listener4.x = camera[3].x;
listener4.y = camera[3].y;
listener4.z = camera[3].z;
listener4.angle = camera[3].angle;
}
else
{
@ -1060,9 +1060,9 @@ void S_UpdateSounds(void)
// check non-local sounds for distance clipping
// or modify their params
if (c->origin && ((c->origin != players[consoleplayer].mo)
|| (splitscreen && c->origin != players[secondarydisplayplayer].mo)
|| (splitscreen > 1 && c->origin != players[thirddisplayplayer].mo)
|| (splitscreen > 2 && c->origin != players[fourthdisplayplayer].mo)))
|| (splitscreen && c->origin != players[displayplayers[1]].mo)
|| (splitscreen > 1 && c->origin != players[displayplayers[2]].mo)
|| (splitscreen > 2 && c->origin != players[displayplayers[3]].mo)))
{
// Whomever is closer gets the sound, but only in splitscreen.
if (splitscreen)
@ -1071,13 +1071,10 @@ void S_UpdateSounds(void)
fixed_t recdist = -1;
INT32 i, p = -1;
for (i = 0; i < 4; i++)
for (i = 0; i <= splitscreen; i++)
{
fixed_t thisdist = -1;
if (i > splitscreen)
break;
if (i == 0 && listenmobj)
thisdist = P_AproxDistance(listener.x-soundmobj->x, listener.y-soundmobj->y);
else if (i == 1 && listenmobj2)
@ -1250,33 +1247,33 @@ INT32 S_AdjustSoundParams(const mobj_t *listener, const mobj_t *source, INT32 *v
if (!listener)
return false;
if (listener == players[displayplayer].mo && camera.chase)
if (listener == players[displayplayers[0]].mo && camera[0].chase)
{
listensource.x = camera.x;
listensource.y = camera.y;
listensource.z = camera.z;
listensource.angle = camera.angle;
listensource.x = camera[0].x;
listensource.y = camera[0].y;
listensource.z = camera[0].z;
listensource.angle = camera[0].angle;
}
else if (splitscreen && listener == players[secondarydisplayplayer].mo && camera2.chase)
else if (splitscreen && listener == players[displayplayers[1]].mo && camera[1].chase)
{
listensource.x = camera2.x;
listensource.y = camera2.y;
listensource.z = camera2.z;
listensource.angle = camera2.angle;
listensource.x = camera[1].x;
listensource.y = camera[1].y;
listensource.z = camera[1].z;
listensource.angle = camera[1].angle;
}
else if (splitscreen > 1 && listener == players[thirddisplayplayer].mo && camera3.chase)
else if (splitscreen > 1 && listener == players[displayplayers[2]].mo && camera[2].chase)
{
listensource.x = camera3.x;
listensource.y = camera3.y;
listensource.z = camera3.z;
listensource.angle = camera3.angle;
listensource.x = camera[2].x;
listensource.y = camera[2].y;
listensource.z = camera[2].z;
listensource.angle = camera[2].angle;
}
else if (splitscreen > 2 && listener == players[fourthdisplayplayer].mo && camera4.chase)
else if (splitscreen > 2 && listener == players[displayplayers[3]].mo && camera[3].chase)
{
listensource.x = camera4.x;
listensource.y = camera4.y;
listensource.z = camera4.z;
listensource.angle = camera4.angle;
listensource.x = camera[3].x;
listensource.y = camera[3].y;
listensource.z = camera[3].z;
listensource.angle = camera[3].angle;
}
else
{
@ -1733,7 +1730,7 @@ void S_ShowMusicCredit(void)
{
musicdef_t *def = musicdefstart;
if (!cv_songcredits.value)
if (!cv_songcredits.value || demo.rewinding)
return;
if (!def) // No definitions
@ -1920,7 +1917,8 @@ void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping)
#endif
if (S_MusicDisabled()
|| titledemo) // SRB2Kart: Demos don't interrupt title screen music
|| demo.rewinding // Don't mess with music while rewinding!
|| demo.title) // SRB2Kart: Demos don't interrupt title screen music
return;
// No Music (empty string)
@ -1955,7 +1953,8 @@ void S_ChangeMusic(const char *mmusic, UINT16 mflags, boolean looping)
void S_StopMusic(void)
{
if (!I_SongPlaying()
|| titledemo) // SRB2Kart: Demos don't interrupt title screen music
|| demo.rewinding // Don't mess with music while rewinding!
|| demo.title) // SRB2Kart: Demos don't interrupt title screen music
return;
if (I_SongPaused())
@ -2182,7 +2181,7 @@ static void Command_RestartAudio_f(void)
void GameSounds_OnChange(void)
{
if (M_CheckParm("-nosound"))
if (M_CheckParm("-nosound") || M_CheckParm("-noaudio"))
return;
if (sound_disabled)
@ -2196,7 +2195,7 @@ void GameSounds_OnChange(void)
void GameDigiMusic_OnChange(void)
{
if (M_CheckParm("-nomusic"))
if (M_CheckParm("-nomusic") || M_CheckParm("-noaudio"))
return;
else if (M_CheckParm("-nodigmusic"))
return;
@ -2239,7 +2238,7 @@ void GameDigiMusic_OnChange(void)
#ifndef NO_MIDI
void GameMIDIMusic_OnChange(void)
{
if (M_CheckParm("-nomusic"))
if (M_CheckParm("-nomusic") || M_CheckParm("-noaudio"))
return;
else if (M_CheckParm("-nomidimusic"))
return;

View File

@ -59,6 +59,8 @@ INT32 setmodeneeded; //video mode change needed if > 0 (the mode number to set +
static CV_PossibleValue_t scr_depth_cons_t[] = {{8, "8 bits"}, {16, "16 bits"}, {24, "24 bits"}, {32, "32 bits"}, {0, NULL}};
static CV_PossibleValue_t shittyscreen_cons_t[] = {{0, "Okay"}, {1, "Shitty"}, {2, "Extra Shitty"}, {0, NULL}};
//added : 03-02-98: default screen mode, as loaded/saved in config
#ifdef WII
consvar_t cv_scr_width = {"scr_width", "640", CV_SAVE, CV_Unsigned, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -70,6 +72,8 @@ consvar_t cv_scr_height = {"scr_height", "800", CV_SAVE, CV_Unsigned, NULL, 0, N
consvar_t cv_scr_depth = {"scr_depth", "16 bits", CV_SAVE, scr_depth_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
#endif
consvar_t cv_renderview = {"renderview", "On", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_vhseffect = {"vhspause", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_shittyscreen = {"televisionsignal", "Okay", CV_NOSHOWHELP, shittyscreen_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
static void SCR_ChangeFullscreen (void);

View File

@ -158,7 +158,7 @@ extern INT32 setmodeneeded; // mode number to set if needed, or 0
extern INT32 scr_bpp;
extern UINT8 *scr_borderpatch; // patch used to fill the view borders
extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_fullscreen;
extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_fullscreen, cv_vhseffect, cv_shittyscreen;
// wait for page flipping to end or not
extern consvar_t cv_vidwait;

View File

@ -227,6 +227,10 @@
<ClInclude Include="..\hardware\hw_light.h" />
<ClInclude Include="..\hardware\hw_main.h" />
<ClInclude Include="..\hardware\hw_md2.h" />
<ClInclude Include="..\hardware\hw_md2load.h" />
<ClInclude Include="..\hardware\hw_md3load.h" />
<ClInclude Include="..\hardware\hw_model.h" />
<ClInclude Include="..\hardware\u_list.h" />
<ClInclude Include="..\hu_stuff.h" />
<ClInclude Include="..\info.h" />
<ClInclude Include="..\i_addrinfo.h" />
@ -366,8 +370,12 @@
<ClCompile Include="..\hardware\hw_light.c" />
<ClCompile Include="..\hardware\hw_main.c" />
<ClCompile Include="..\hardware\hw_md2.c" />
<ClCompile Include="..\hardware\hw_md2load.c" />
<ClCompile Include="..\hardware\hw_md3load.c" />
<ClCompile Include="..\hardware\hw_model.c" />
<ClCompile Include="..\hardware\hw_trick.c" />
<ClCompile Include="..\hardware\r_opengl\r_opengl.c" />
<ClCompile Include="..\hardware\u_list.c" />
<ClCompile Include="..\hu_stuff.c" />
<ClCompile Include="..\info.c" />
<ClCompile Include="..\i_addrinfo.c">

View File

@ -246,6 +246,18 @@
<ClInclude Include="..\hardware\hw_md2.h">
<Filter>Hw_Hardware</Filter>
</ClInclude>
<ClInclude Include="..\hardware\hw_md2load.h">
<Filter>Hw_Hardware</Filter>
</ClInclude>
<ClInclude Include="..\hardware\hw_md3load.h">
<Filter>Hw_Hardware</Filter>
</ClInclude>
<ClInclude Include="..\hardware\hw_model.h">
<Filter>Hw_Hardware</Filter>
</ClInclude>
<ClInclude Include="..\hardware\u_list.h">
<Filter>Hw_Hardware</Filter>
</ClInclude>
<ClInclude Include="..\byteptr.h">
<Filter>I_Interface</Filter>
</ClInclude>
@ -627,9 +639,21 @@
<ClCompile Include="..\hardware\hw_md2.c">
<Filter>Hw_Hardware</Filter>
</ClCompile>
<ClCompile Include="..\hardware\hw_md2load.c">
<Filter>Hw_Hardware</Filter>
</ClCompile>
<ClCompile Include="..\hardware\hw_md3load.c">
<Filter>Hw_Hardware</Filter>
</ClCompile>
<ClCompile Include="..\hardware\hw_model.c">
<Filter>Hw_Hardware</Filter>
</ClCompile>
<ClCompile Include="..\hardware\hw_trick.c">
<Filter>Hw_Hardware</Filter>
</ClCompile>
<ClCompile Include="..\hardware\u_list.c">
<Filter>Hw_Hardware</Filter>
</ClCompile>
<ClCompile Include="..\filesrch.c">
<Filter>I_Interface</Filter>
</ClCompile>

View File

@ -87,13 +87,11 @@ void *hwSym(const char *funcName,void *handle)
GETFUNC(ClearMipMapCache);
GETFUNC(SetSpecialState);
GETFUNC(GetTextureUsed);
GETFUNC(DrawMD2);
GETFUNC(DrawMD2i);
GETFUNC(DrawModel);
GETFUNC(CreateModelVBOs);
GETFUNC(SetTransform);
GETFUNC(GetRenderVersion);
#ifdef SHUFFLE
GETFUNC(PostImgRedraw);
#endif //SHUFFLE
GETFUNC(FlushScreenTextures);
GETFUNC(StartScreenWipe);
GETFUNC(EndScreenWipe);

View File

@ -3061,7 +3061,7 @@ void I_Quit(void)
//added:16-02-98: when recording a demo, should exit using 'q' key,
// but sometimes we forget and use 'F10'.. so save here too.
if (demorecording)
if (demo.recording)
G_CheckDemoStatus();
if (metalrecording)
G_StopMetalRecording();
@ -3179,7 +3179,7 @@ void I_Error(const char *error, ...)
G_SaveGameData(false); // Tails 12-08-2002
// Shutdown. Here might be other errors.
if (demorecording)
if (demo.recording)
G_CheckDemoStatus();
if (metalrecording)
G_StopMetalRecording();

View File

@ -359,6 +359,14 @@ static INT32 Impl_SDL_Scancode_To_Keycode(SDL_Scancode code)
return 0;
}
static void SDLdoGrabMouse(void)
{
SDL_ShowCursor(SDL_DISABLE);
SDL_SetWindowGrab(window, SDL_TRUE);
if (SDL_SetRelativeMouseMode(SDL_TRUE) == 0) // already warps mouse if successful
wrapmouseok = SDL_TRUE; // TODO: is wrapmouseok or HalfWarpMouse needed anymore?
}
static void SDLdoUngrabMouse(void)
{
SDL_ShowCursor(SDL_ENABLE);
@ -629,6 +637,9 @@ static void Impl_HandleWindowEvent(SDL_WindowEvent evt)
//else firsttimeonmouse = SDL_FALSE;
capslock = !!( SDL_GetModState() & KMOD_CAPS );// in case CL changes
if (USE_MOUSEINPUT)
SDLdoGrabMouse();
}
else if (!mousefocus && !kbfocus)
{
@ -708,9 +719,7 @@ static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt)
// -- Monster Iestyn
if (SDL_GetMouseFocus() == window && SDL_GetKeyboardFocus() == window)
{
SDL_SetWindowGrab(window, SDL_TRUE);
if (SDL_SetRelativeMouseMode(SDL_TRUE) == 0) // already warps mouse if successful
wrapmouseok = SDL_TRUE; // TODO: is wrapmouseok or HalfWarpMouse needed anymore?
SDLdoGrabMouse();
}
}
}
@ -1277,7 +1286,7 @@ void I_StartupMouse(void)
else
firsttimeonmouse = SDL_FALSE;
if (cv_usemouse.value)
return;
SDLdoGrabMouse();
else
SDLdoUngrabMouse();
}
@ -1845,13 +1854,11 @@ void I_StartupGraphics(void)
HWD.pfnSetSpecialState = hwSym("SetSpecialState",NULL);
HWD.pfnSetPalette = hwSym("SetPalette",NULL);
HWD.pfnGetTextureUsed = hwSym("GetTextureUsed",NULL);
HWD.pfnDrawMD2 = hwSym("DrawMD2",NULL);
HWD.pfnDrawMD2i = hwSym("DrawMD2i",NULL);
HWD.pfnDrawModel = hwSym("DrawModel",NULL);
HWD.pfnCreateModelVBOs = hwSym("CreateModelVBOs",NULL);
HWD.pfnSetTransform = hwSym("SetTransform",NULL);
HWD.pfnGetRenderVersion = hwSym("GetRenderVersion",NULL);
#ifdef SHUFFLE
HWD.pfnPostImgRedraw = hwSym("PostImgRedraw",NULL);
#endif
HWD.pfnFlushScreenTextures=hwSym("FlushScreenTextures",NULL);
HWD.pfnStartScreenWipe = hwSym("StartScreenWipe",NULL);
HWD.pfnEndScreenWipe = hwSym("EndScreenWipe",NULL);

View File

@ -755,6 +755,36 @@
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\hardware\hw_md2load.c">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\hardware\hw_md3load.c">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\hardware\hw_model.c">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\hardware\hw_trick.c">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
@ -765,6 +795,16 @@
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\hardware\u_list.c">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Release|x64'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<ClCompile Include="..\i_tcp.c">
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<PreprocessorDefinitions Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">%(PreprocessorDefinitions)</PreprocessorDefinitions>
@ -1340,7 +1380,11 @@
<ClInclude Include="..\hardware\hw_light.h" />
<ClInclude Include="..\hardware\hw_main.h" />
<ClInclude Include="..\hardware\hw_md2.h" />
<ClInclude Include="..\hardware\hw_md2load.h" />
<ClInclude Include="..\hardware\hw_md3load.h" />
<ClInclude Include="..\hardware\hw_model.h" />
<ClInclude Include="..\hardware\hws_data.h" />
<ClInclude Include="..\hardware\u_list.h" />
<ClInclude Include="..\byteptr.h" />
<ClInclude Include="..\i_joy.h" />
<ClInclude Include="..\i_net.h" />

View File

@ -372,7 +372,7 @@ static inline void ST_InitData(void)
// 'link' the statusbar display to a player, which could be
// another player than consoleplayer, for example, when you
// change the view in a multiplayer demo with F12.
stplyr = &players[displayplayer];
stplyr = &players[displayplayers[0]];
st_palette = -1;
}
@ -442,7 +442,7 @@ static INT32 SCY(INT32 y)
if (splitscreen)
{
y >>= 1;
if (stplyr != &players[displayplayer])
if (stplyr != &players[displayplayers[0]])
y += vid.height / 2;
}
return y;
@ -458,7 +458,7 @@ static INT32 STRINGY(INT32 y)
if (splitscreen)
{
y >>= 1;
if (stplyr != &players[displayplayer])
if (stplyr != &players[displayplayers[0]])
y += BASEVIDHEIGHT / 2;
}
return y;
@ -471,7 +471,7 @@ static INT32 SPLITFLAGS(INT32 f)
// Pass this V_SNAPTO(TOP|BOTTOM) and it'll trim them to account for splitscreen! -Red
if (splitscreen)
{
if (stplyr != &players[displayplayer])
if (stplyr != &players[displayplayers[0]])
f &= ~V_SNAPTOTOP;
else
f &= ~V_SNAPTOBOTTOM;
@ -498,7 +498,7 @@ static INT32 SCR(INT32 r)
if (splitscreen)
{
y >>= 1;
if (stplyr != &players[displayplayer])
if (stplyr != &players[displayplayers[0]])
y += vid.height / 2;
}
return FixedInt(FixedDiv(y, vid.fdupy));
@ -573,17 +573,17 @@ static void ST_drawDebugInfo(void)
if (cv_debug & DBG_DETAILED)
{
V_DrawRightAlignedString(320, height - 104, V_MONOSPACE, va("SHIELD: %5x", stplyr->powers[pw_shield]));
//V_DrawRightAlignedString(320, height - 104, V_MONOSPACE, va("SHIELD: %5x", stplyr->powers[pw_shield]));
V_DrawRightAlignedString(320, height - 96, V_MONOSPACE, va("SCALE: %5d%%", (stplyr->mo->scale*100)/FRACUNIT));
V_DrawRightAlignedString(320, height - 88, V_MONOSPACE, va("DASH: %3d/%3d", stplyr->dashspeed>>FRACBITS, FixedMul(stplyr->maxdash,stplyr->mo->scale)>>FRACBITS));
V_DrawRightAlignedString(320, height - 80, V_MONOSPACE, va("AIR: %4d, %3d", stplyr->powers[pw_underwater], stplyr->powers[pw_spacetime]));
//V_DrawRightAlignedString(320, height - 88, V_MONOSPACE, va("DASH: %3d/%3d", stplyr->dashspeed>>FRACBITS, FixedMul(stplyr->maxdash,stplyr->mo->scale)>>FRACBITS));
//V_DrawRightAlignedString(320, height - 80, V_MONOSPACE, va("AIR: %4d, %3d", stplyr->powers[pw_underwater], stplyr->powers[pw_spacetime]));
// Flags
V_DrawRightAlignedString(304-64, height - 72, V_MONOSPACE, "Flags:");
V_DrawString(304-60, height - 72, (stplyr->jumping) ? V_GREENMAP : V_REDMAP, "JM");
V_DrawString(304-40, height - 72, (stplyr->pflags & PF_JUMPED) ? V_GREENMAP : V_REDMAP, "JD");
V_DrawString(304-20, height - 72, (stplyr->pflags & PF_SPINNING) ? V_GREENMAP : V_REDMAP, "SP");
V_DrawString(304, height - 72, (stplyr->pflags & PF_STARTDASH) ? V_GREENMAP : V_REDMAP, "ST");
//V_DrawRightAlignedString(304-64, height - 72, V_MONOSPACE, "Flags:");
//V_DrawString(304-60, height - 72, (stplyr->jumping) ? V_GREENMAP : V_REDMAP, "JM");
//V_DrawString(304-40, height - 72, (stplyr->pflags & PF_JUMPED) ? V_GREENMAP : V_REDMAP, "JD");
//V_DrawString(304-20, height - 72, (stplyr->pflags & PF_SPINNING) ? V_GREENMAP : V_REDMAP, "SP");
//V_DrawString(304, height - 72, (stplyr->pflags & PF_STARTDASH) ? V_GREENMAP : V_REDMAP, "ST");
V_DrawRightAlignedString(320, height - 64, V_MONOSPACE, va("CEILZ: %6d", stplyr->mo->ceilingz>>FRACBITS));
V_DrawRightAlignedString(320, height - 56, V_MONOSPACE, va("FLOORZ: %6d", stplyr->mo->floorz>>FRACBITS));
@ -701,7 +701,7 @@ static inline void ST_drawRings(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 && stplyr == &players[displayplayers[0]] ? V_SPLITSCREEN : 0);
if (!stplyr->skincolor)
return; // Just joined a server, skin isn't loaded yet!
@ -1019,7 +1019,7 @@ static void ST_drawNiGHTSHUD(void) // SRB2kart - unused.
if (G_IsSpecialStage(gamemap))
{ // Since special stages share score, time, rings, etc.
// disable splitscreen mode for its HUD.
if (stplyr != &players[displayplayer])
if (stplyr != &players[displayplayers[0]])
return;
nosshack = splitscreen;
splitscreen = 0;
@ -1124,7 +1124,7 @@ static void ST_drawNiGHTSHUD(void) // SRB2kart - unused.
V_DrawScaledPatch(locx, STRINGY(locy)-3, V_HUDTRANS, drillbar);
for (dfill = 0; dfill < stplyr->drillmeter/20 && dfill < 96; ++dfill)
V_DrawScaledPatch(locx + 2 + dfill, STRINGY(locy + 3), V_HUDTRANS, drillfill[fillpatch]);
stplyr = &players[secondarydisplayplayer];
stplyr = &players[displayplayers[1]];
if (stplyr->pflags & PF_DRILLING)
fillpatch = (stplyr->drillmeter & 1) + 1;
else
@ -1132,7 +1132,7 @@ static void ST_drawNiGHTSHUD(void) // SRB2kart - unused.
V_DrawScaledPatch(locx, STRINGY(locy-3), V_SNAPTOBOTTOM|V_HUDTRANS, drillbar);
for (dfill = 0; dfill < stplyr->drillmeter/20 && dfill < 96; ++dfill)
V_DrawScaledPatch(locx + 2 + dfill, STRINGY(locy + 3), V_SNAPTOBOTTOM|V_HUDTRANS, drillfill[fillpatch]);
stplyr = &players[displayplayer];
stplyr = &players[displayplayers[0]];
splitscreen = 0;
}
else
@ -1881,7 +1881,7 @@ static void ST_overlayDrawer(void)
ST_drawTeamName();
// Special Stage HUD
if (!useNightsSS && G_IsSpecialStage(gamemap) && stplyr == &players[displayplayer])
if (!useNightsSS && G_IsSpecialStage(gamemap) && stplyr == &players[displayplayers[0]])
ST_drawSpecialStageHUD();
// Emerald Hunt Indicators
@ -1894,6 +1894,8 @@ static void ST_overlayDrawer(void)
V_DrawScaledPatch(hudinfo[HUD_GRAVBOOTSICO].x, STRINGY(hudinfo[HUD_GRAVBOOTSICO].y), V_SNAPTORIGHT, gravboots);
*/
if (!(multiplayer && demo.playback))
{
if(!P_IsLocalPlayer(stplyr))
{
/*char name[MAXPLAYERNAME+1];
@ -1904,12 +1906,34 @@ static void ST_overlayDrawer(void)
V_DrawCenteredString((BASEVIDWIDTH/2), BASEVIDHEIGHT-40, 0, M_GetText("Viewpoint:"));
V_DrawCenteredString((BASEVIDWIDTH/2), BASEVIDHEIGHT-32, V_ALLOWLOWERCASE, player_names[stplyr-players]);
}
}
else if (!demo.title)
{
if (!splitscreen)
{
V_DrawCenteredString((BASEVIDWIDTH/2), BASEVIDHEIGHT-40, V_HUDTRANSHALF, M_GetText("Viewpoint:"));
V_DrawCenteredString((BASEVIDWIDTH/2), BASEVIDHEIGHT-32, V_HUDTRANSHALF|V_ALLOWLOWERCASE, player_names[stplyr-players]);
}
else if (splitscreen == 1)
{
char name[MAXPLAYERNAME+12];
INT32 y = (stplyr == &players[displayplayers[0]]) ? 4 : BASEVIDHEIGHT/2-12;
sprintf(name, "VIEWPOINT: %s", player_names[stplyr-players]);
V_DrawRightAlignedThinString(BASEVIDWIDTH-40, y, V_HUDTRANSHALF|V_ALLOWLOWERCASE|K_calcSplitFlags(V_SNAPTOTOP|V_SNAPTOBOTTOM|V_SNAPTORIGHT), name);
}
else if (splitscreen)
{
V_DrawCenteredThinString((vid.width/vid.dupx)/4, BASEVIDHEIGHT/2 - 12, V_HUDTRANSHALF|V_ALLOWLOWERCASE|K_calcSplitFlags(V_SNAPTOBOTTOM|V_SNAPTOLEFT), player_names[stplyr-players]);
}
}
// This is where we draw all the fun cheese if you have the chasecam off!
/*if ((stplyr == &players[displayplayer] && !camera.chase)
|| ((splitscreen && stplyr == &players[secondarydisplayplayer]) && !camera2.chase)
|| ((splitscreen > 1 && stplyr == &players[thirddisplayplayer]) && !camera3.chase)
|| ((splitscreen > 2 && stplyr == &players[fourthdisplayplayer]) && !camera4.chase))
/*if ((stplyr == &players[displayplayers[0]] && !camera[0].chase)
|| ((splitscreen && stplyr == &players[displayplayers[1]]) && !camera[1].chase)
|| ((splitscreen > 1 && stplyr == &players[displayplayers[2]]) && !camera[2].chase)
|| ((splitscreen > 2 && stplyr == &players[displayplayers[3]]) && !camera[3].chase))
{
ST_drawFirstPersonHUD();
}*/
@ -1990,9 +2014,65 @@ static void ST_overlayDrawer(void)
}
}
// Replay manual-save stuff
if (demo.recording && multiplayer && demo.savebutton && demo.savebutton + 3*TICRATE < leveltime)
{
switch (demo.savemode)
{
case DSM_NOTSAVING:
V_DrawRightAlignedThinString(BASEVIDWIDTH - 2, 2, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|(G_BattleGametype() ? V_REDMAP : V_SKYMAP), "Look Backward: Save replay");
break;
case DSM_WILLAUTOSAVE:
V_DrawRightAlignedThinString(BASEVIDWIDTH - 2, 2, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|(G_BattleGametype() ? V_REDMAP : V_SKYMAP), "Replay will be saved. (Look Backward: Change title)");
break;
case DSM_WILLSAVE:
V_DrawRightAlignedThinString(BASEVIDWIDTH - 2, 2, V_HUDTRANS|V_SNAPTOTOP|V_SNAPTORIGHT|V_ALLOWLOWERCASE|(G_BattleGametype() ? V_REDMAP : V_SKYMAP), "Replay will be saved.");
break;
case DSM_TITLEENTRY:
ST_DrawDemoTitleEntry();
break;
default: // Don't render anything
break;
}
}
ST_drawDebugInfo();
}
void ST_DrawDemoTitleEntry(void)
{
static UINT8 skullAnimCounter = 0;
char *nametodraw;
skullAnimCounter++;
skullAnimCounter %= 8;
nametodraw = demo.titlename;
while (V_StringWidth(nametodraw, 0) > MAXSTRINGLENGTH*8 - 8)
nametodraw++;
#define x (BASEVIDWIDTH/2 - 139)
#define y (BASEVIDHEIGHT/2)
M_DrawTextBox(x, y + 4, MAXSTRINGLENGTH, 1);
V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, nametodraw);
if (skullAnimCounter < 4)
V_DrawCharacter(x + 8 + V_StringWidth(nametodraw, 0), y + 12,
'_' | 0x80, false);
M_DrawTextBox(x + 30, y - 24, 26, 1);
V_DrawString(x + 38, y - 16, V_ALLOWLOWERCASE, "Enter the name of the replay.");
M_DrawTextBox(x + 50, y + 20, 20, 1);
V_DrawThinString(x + 58, y + 28, V_ALLOWLOWERCASE, "Escape - Cancel");
V_DrawRightAlignedThinString(x + 220, y + 28, V_ALLOWLOWERCASE, "Enter - Confirm");
#undef x
#undef y
}
// MayonakaStatic: draw Midnight Channel's TV-like borders
static void ST_MayonakaStatic(void)
{
@ -2006,8 +2086,10 @@ static void ST_MayonakaStatic(void)
void ST_Drawer(void)
{
UINT8 i;
#ifdef SEENAMES
if (cv_seenames.value && cv_allowseenames.value && displayplayer == consoleplayer && seenplayer && seenplayer->mo && !mapreset)
if (cv_seenames.value && cv_allowseenames.value && displayplayers[0] == consoleplayer && seenplayer && seenplayer->mo && !mapreset)
{
if (cv_seenames.value == 1)
V_DrawCenteredString(BASEVIDWIDTH/2, BASEVIDHEIGHT/2 + 15, V_HUDTRANSHALF, player_names[seenplayer-players]);
@ -2041,26 +2123,12 @@ void ST_Drawer(void)
if (st_overlay)
{
// No deadview!
stplyr = &players[displayplayer];
ST_overlayDrawer();
if (splitscreen)
for (i = 0; i <= splitscreen; i++)
{
stplyr = &players[secondarydisplayplayer];
ST_overlayDrawer();
if (splitscreen > 1)
{
stplyr = &players[thirddisplayplayer];
ST_overlayDrawer();
if (splitscreen > 2)
{
stplyr = &players[fourthdisplayplayer];
stplyr = &players[displayplayers[i]];
ST_overlayDrawer();
}
}
}
// draw Midnight Channel's overlay ontop
if (mapheaderinfo[gamemap-1]->typeoflevel & TOL_TV) // Very specific Midnight Channel stuff.
ST_MayonakaStatic();

View File

@ -26,6 +26,9 @@
// Called by main loop.
void ST_Ticker(void);
// Called when naming a replay.
void ST_DrawDemoTitleEntry(void);
// Called by main loop.
void ST_Drawer(void);

View File

@ -60,7 +60,6 @@ static void CV_Gammaxxx_ONChange(void);
static CV_PossibleValue_t grgamma_cons_t[] = {{1, "MIN"}, {255, "MAX"}, {0, NULL}};
static CV_PossibleValue_t grsoftwarefog_cons_t[] = {{0, "Off"}, {1, "On"}, {2, "LightPlanes"}, {0, NULL}};
consvar_t cv_voodoocompatibility = {"gr_voodoocompatibility", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grfovchange = {"gr_fovchange", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grfog = {"gr_fog", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grfogcolor = {"gr_fogcolor", "AAAAAA", CV_SAVE, NULL, NULL, 0, NULL, NULL, 0, 0, NULL};
@ -80,7 +79,8 @@ consvar_t cv_grcoronasize = {"gr_coronasize", "1", CV_SAVE| CV_FLOAT, 0, NULL, 0
//static CV_PossibleValue_t CV_MD2[] = {{0, "Off"}, {1, "On"}, {2, "Old"}, {0, NULL}};
// console variables in development
consvar_t cv_grmd2 = {"gr_md2", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grmdls = {"gr_mdls", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_grfallbackplayermodel = {"gr_fallbackplayermodel", "Off", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
#endif
const UINT8 gammatable[5][256] =
@ -1214,6 +1214,66 @@ void V_DrawPatchFill(patch_t *pat)
}
}
void V_DrawVhsEffect(boolean rewind)
{
static fixed_t upbary = 100, downbary = 150;
UINT8 *buf = screens[0], *tmp = screens[4];
UINT16 y;
UINT32 x, pos = 0;
UINT8 *normalmapstart = ((UINT8 *)transtables + (8<<FF_TRANSSHIFT|(19<<8)));
#ifdef HQ_VHS
UINT8 *tmapstart = ((UINT8 *)transtables + (6<<FF_TRANSSHIFT));
#endif
UINT8 *thismapstart;
SINT8 offs;
UINT8 barsize = vid.dupy<<5;
UINT8 updistort = vid.dupx<<(rewind ? 5 : 3);
UINT8 downdistort = updistort>>1;
if (rewind)
V_DrawVhsEffect(false); // experimentation
upbary -= vid.dupy * (rewind ? 3 : 1.8f);
downbary += vid.dupy * (rewind ? 2 : 1);
if (upbary < -barsize) upbary = vid.height;
if (downbary > vid.height) downbary = -barsize;
for (y = 0; y < vid.height; y+=2)
{
thismapstart = normalmapstart;
offs = 0;
if (y >= upbary && y < upbary+barsize)
{
thismapstart -= (2<<FF_TRANSSHIFT) - (5<<8);
offs += updistort * 2.0f * min(y-upbary, upbary+barsize-y) / barsize;
}
if (y >= downbary && y < downbary+barsize)
{
thismapstart -= (2<<FF_TRANSSHIFT) - (5<<8);
offs -= downdistort * 2.0f * min(y-downbary, downbary+barsize-y) / barsize;
}
offs += M_RandomKey(vid.dupx<<1);
// lazy way to avoid crashes
if (y == 0 && offs < 0) offs = 0;
else if (y >= vid.height-2 && offs > 0) offs = 0;
for (x = pos+vid.rowbytes*2; pos < x; pos++)
{
tmp[pos] = thismapstart[buf[pos+offs]];
#ifdef HQ_VHS
tmp[pos] = tmapstart[buf[pos]<<8 | tmp[pos]];
#endif
}
}
memcpy(buf, tmp, vid.rowbytes*vid.height);
}
//
// Fade all the screen buffer, so that the menu is more readable,
// especially now that we use the small hufont in the menus...
@ -1234,7 +1294,10 @@ void V_DrawFadeScreen(UINT16 color, UINT8 strength)
#endif
{
const UINT8 *fadetable = ((color & 0xFF00) // Color is not palette index?
const UINT8 *fadetable =
(color > 0xFFF0) // Grab a specific colormap palette?
? R_GetTranslationColormap(color | 0xFFFF0000, strength, GTC_CACHE)
: ((color & 0xFF00) // Color is not palette index?
? ((UINT8 *)colormaps + strength*256) // Do COLORMAP fade.
: ((UINT8 *)transtables + ((9-strength)<<FF_TRANSSHIFT) + color*256)); // Else, do TRANSMAP** fade.
const UINT8 *deststop = screens[0] + vid.rowbytes * vid.height;
@ -1460,9 +1523,12 @@ void V_DrawString(INT32 x, INT32 y, INT32 option, const char *string)
{
dupx = dupy = 1;
scrwidth = vid.width/vid.dupx;
if (!(option & V_SNAPTOLEFT))
{
left = (scrwidth - BASEVIDWIDTH)/2;
scrwidth -= left;
}
}
charflags = (option & V_CHARCOLORMASK);
colormap = V_GetStringColormap(charflags);
@ -1870,6 +1936,12 @@ void V_DrawThinString(INT32 x, INT32 y, INT32 option, const char *string)
}
}
void V_DrawCenteredThinString(INT32 x, INT32 y, INT32 option, const char *string)
{
x -= V_ThinStringWidth(string, option)/2;
V_DrawThinString(x, y, option, string);
}
void V_DrawRightAlignedThinString(INT32 x, INT32 y, INT32 option, const char *string)
{
x -= V_ThinStringWidth(string, option);

View File

@ -153,6 +153,9 @@ void V_DrawDiag(INT32 x, INT32 y, INT32 wh, INT32 c);
// fill a box with a flat as a pattern
void V_DrawFlatFill(INT32 x, INT32 y, INT32 w, INT32 h, lumpnum_t flatnum);
// draw wobbly VHS pause stuff
void V_DrawVhsEffect(boolean rewind);
// fade down the screen buffer before drawing the menu over
void V_DrawFadeScreen(UINT16 color, UINT8 strength);
@ -182,6 +185,7 @@ void V_DrawRightAlignedSmallString(INT32 x, INT32 y, INT32 option, const char *s
// draw a string using the tny_font
void V_DrawThinString(INT32 x, INT32 y, INT32 option, const char *string);
void V_DrawCenteredThinString(INT32 x, INT32 y, INT32 option, const char *string);
void V_DrawRightAlignedThinString(INT32 x, INT32 y, INT32 option, const char *string);
void V_DrawStringAtFixed(fixed_t x, fixed_t y, INT32 option, const char *string);

View File

@ -230,7 +230,11 @@
<ClCompile Include="..\hardware\hw_light.c" />
<ClCompile Include="..\hardware\hw_main.c" />
<ClCompile Include="..\hardware\hw_md2.c" />
<ClCompile Include="..\hardware\hw_md2load.c" />
<ClCompile Include="..\hardware\hw_md3load.c" />
<ClCompile Include="..\hardware\hw_model.c" />
<ClCompile Include="..\hardware\hw_trick.c" />
<ClCompile Include="..\hardware\u_list.c" />
<ClCompile Include="..\hu_stuff.c" />
<ClCompile Include="..\info.c" />
<ClCompile Include="..\i_addrinfo.c">
@ -394,6 +398,10 @@
<ClInclude Include="..\hardware\hw_light.h" />
<ClInclude Include="..\hardware\hw_main.h" />
<ClInclude Include="..\hardware\hw_md2.h" />
<ClInclude Include="..\hardware\hw_md2load.h" />
<ClInclude Include="..\hardware\hw_md3load.h" />
<ClInclude Include="..\hardware\hw_model.h" />
<ClInclude Include="..\hardware\u_list.h" />
<ClInclude Include="..\hu_stuff.h" />
<ClInclude Include="..\info.h" />
<ClInclude Include="..\i_addrinfo.h" />

View File

@ -453,6 +453,10 @@
<ClCompile Include="..\string.c">
<Filter>M_Misc</Filter>
</ClCompile>
<ClCompile Include="..\hardware\hw_md2load.c" />
<ClCompile Include="..\hardware\hw_md3load.c" />
<ClCompile Include="..\hardware\hw_model.c" />
<ClCompile Include="..\hardware\u_list.c" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="afxres.h">
@ -506,6 +510,15 @@
<ClInclude Include="..\hardware\hw_md2.h">
<Filter>Hw_Hardware</Filter>
</ClInclude>
<ClInclude Include="..\hardware\hw_md2load.h">
<Filter>Hw_Hardware</Filter>
</ClInclude>
<ClInclude Include="..\hardware\hw_md3load.h">
<Filter>Hw_Hardware</Filter>
</ClInclude>
<ClInclude Include="..\hardware\hw_model.h">
<Filter>Hw_Hardware</Filter>
</ClInclude>
<ClInclude Include="..\hardware\hw3dsdrv.h">
<Filter>Hw_Hardware</Filter>
</ClInclude>
@ -515,6 +528,9 @@
<ClInclude Include="..\hardware\hws_data.h">
<Filter>Hw_Hardware</Filter>
</ClInclude>
<ClInclude Include="..\hardware\u_list.h">
<Filter>Hw_Hardware</Filter>
</ClInclude>
<ClInclude Include="..\blua\lapi.h">
<Filter>BLUA</Filter>
</ClInclude>

View File

@ -109,8 +109,7 @@ static loadfunc_t hwdFuncTable[] = {
{"GClipRect@20", &hwdriver.pfnGClipRect},
{"ClearMipMapCache@0", &hwdriver.pfnClearMipMapCache},
{"SetSpecialState@8", &hwdriver.pfnSetSpecialState},
{"DrawMD2@16", &hwdriver.pfnDrawMD2},
{"DrawMD2i@36", &hwdriver.pfnDrawMD2i},
{"DrawModel@16", &hwdriver.pfnDrawModel},
{"SetTransform@4", &hwdriver.pfnSetTransform},
{"GetTextureUsed@0", &hwdriver.pfnGetTextureUsed},
{"GetRenderVersion@0", &hwdriver.pfnGetRenderVersion},
@ -140,8 +139,7 @@ static loadfunc_t hwdFuncTable[] = {
{"GClipRect", &hwdriver.pfnGClipRect},
{"ClearMipMapCache", &hwdriver.pfnClearMipMapCache},
{"SetSpecialState", &hwdriver.pfnSetSpecialState},
{"DrawMD2", &hwdriver.pfnDrawMD2},
{"DrawMD2i", &hwdriver.pfnDrawMD2i},
{"DrawModel", &hwdriver.pfnDrawModel},
{"SetTransform", &hwdriver.pfnSetTransform},
{"GetTextureUsed", &hwdriver.pfnGetTextureUsed},
{"GetRenderVersion", &hwdriver.pfnGetRenderVersion},

Some files were not shown because too many files have changed in this diff Show More