Merge branch 'master' into disable_gettext

This commit is contained in:
Alam Ed Arias 2017-05-26 18:06:57 -04:00
commit 0e0769d11a
52 changed files with 437 additions and 297 deletions

View file

@ -1,6 +1,6 @@
cmake_minimum_required(VERSION 3.0) cmake_minimum_required(VERSION 3.0)
project(SRB2 project(SRB2
VERSION 2.1.17 VERSION 2.1.18
LANGUAGES C) LANGUAGES C)
if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR}) if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR})

View file

@ -1,4 +1,4 @@
version: 2.1.17.{branch}-{build} version: 2.1.18.{branch}-{build}
os: MinGW os: MinGW
environment: environment:
@ -58,26 +58,29 @@ after_build:
- cmd: git rev-parse --short %APPVEYOR_REPO_COMMIT%>%TMP%/gitshort.txt - cmd: git rev-parse --short %APPVEYOR_REPO_COMMIT%>%TMP%/gitshort.txt
- cmd: set /P GITSHORT=<%TMP%/gitshort.txt - cmd: set /P GITSHORT=<%TMP%/gitshort.txt
- set BUILD_ARCHIVE=%APPVEYOR_REPO_BRANCH%-%GITSHORT%-%CONFIGURATION%.7z - set BUILD_ARCHIVE=%APPVEYOR_REPO_BRANCH%-%GITSHORT%-%CONFIGURATION%.7z
- set BUILDSARCHIVE=%APPVEYOR_REPO_BRANCH%-%CONFIGURATION%.7z
- cmd: 7z a %BUILD_ARCHIVE% bin\Mingw\Release -xr!.gitignore - cmd: 7z a %BUILD_ARCHIVE% bin\Mingw\Release -xr!.gitignore
- appveyor PushArtifact %BUILD_ARCHIVE% - appveyor PushArtifact %BUILD_ARCHIVE%
- cmd: copy %BUILD_ARCHIVE% %BUILDSARCHIVE%
- appveyor PushArtifact %BUILDSARCHIVE%
test: off test: off
deploy: #deploy:
- provider: FTP # - provider: FTP
protocol: ftps # protocol: ftps
host: # host:
secure: NsLJEPIBvmwCOj8Tg8RoRQ== # secure: NsLJEPIBvmwCOj8Tg8RoRQ==
username: # username:
secure: ejxi5mvk7oLYu7QtbYojajEPigMy0mokaKhuEVuDZcA= # secure: ejxi5mvk7oLYu7QtbYojajEPigMy0mokaKhuEVuDZcA=
password: # password:
secure: Hbn6Uy3lT0YZ88yFJ3aW4w== # secure: Hbn6Uy3lT0YZ88yFJ3aW4w==
folder: appveyor # folder: appveyor
application: # application:
active_mode: false # active_mode: false
on: # on:
branch: master # branch: master
appveyor_repo_tag: true # appveyor_repo_tag: true
on_finish: on_finish:

View file

@ -1,3 +1,3 @@
/srb2sdl.exe *.exe
/srb2win.exe *.mo
/r_opengl.dll r_opengl.dll

View file

@ -1,3 +1,3 @@
/srb2sdl.exe *.exe
/srb2win.exe *.mo
/r_opengl.dll r_opengl.dll

8
objs/.gitignore vendored Normal file
View file

@ -0,0 +1,8 @@
#All folders
SRB2.res
depend.dep
depend.ped
*.o
#VC9 folder only
/VC9/Win32
/VC9/x64

View file

@ -1 +1,2 @@
/depend.dep # DON'T REMOVE
# This keeps the folder from disappearing

View file

@ -1 +1,2 @@
/depend.dep # DON'T REMOVE
# This keeps the folder from disappearing

View file

@ -1,2 +1,2 @@
/depend.dep # DON'T REMOVE
/*.o # This keeps the folder from disappearing

View file

@ -1,2 +1,2 @@
/depend.dep # DON'T REMOVE
/*.o # This keeps the folder from disappearing

View file

@ -1,2 +1,2 @@
/depend.dep # DON'T REMOVE
/*.o # This keeps the folder from disappearing

View file

@ -1,2 +1,2 @@
/depend.dep # DON'T REMOVE
/*.o # This keeps the folder from disappearing

View file

@ -1,3 +1,2 @@
/SRB2.res # DON'T REMOVE
/depend.dep # This keeps the folder from disappearing
/*.o

View file

@ -1,3 +1,2 @@
/SRB2.res # DON'T REMOVE
/depend.dep # This keeps the folder from disappearing
/*.o

View file

@ -1,3 +1,2 @@
/SRB2.res # DON'T REMOVE
/depend.dep # This keeps the folder from disappearing
/*.o

View file

@ -1,3 +1,2 @@
/SRB2.res # DON'T REMOVE
/depend.dep # This keeps the folder from disappearing
/*.o

View file

@ -1,3 +1,2 @@
/SRB2.res # DON'T REMOVE
/depend.dep # This keeps the folder from disappearing
/*.o

View file

@ -1,3 +1,2 @@
/SRB2.res # DON'T REMOVE
/depend.dep # This keeps the folder from disappearing
/*.o

View file

@ -1,3 +1,2 @@
/SRB2.res # DON'T REMOVE
/depend.dep # This keeps the folder from disappearing
/*.o

View file

@ -1,3 +1,2 @@
/SRB2.res # DON'T REMOVE
/depend.dep # This keeps the folder from disappearing
/*.o

View file

@ -1,2 +1,2 @@
/depend.dep # DON'T REMOVE
/*.o # This keeps the folder from disappearing

View file

@ -1,2 +1,2 @@
/depend.dep # DON'T REMOVE
/*.o # This keeps the folder from disappearing

View file

@ -1 +1,2 @@
/depend.dep # DON'T REMOVE
# This keeps the folder from disappearing

View file

@ -1 +1,2 @@
/depend.ped # DON'T REMOVE
# This keeps the folder from disappearing

2
objs/VC/.gitignore vendored
View file

@ -0,0 +1,2 @@
# DON'T REMOVE
# This keeps the folder from disappearing

4
objs/VC9/.gitignore vendored
View file

@ -1,2 +1,2 @@
/Win32 # DON'T REMOVE
/x64 # This keeps the folder from disappearing

View file

@ -1,2 +1,2 @@
/depend.dep # DON'T REMOVE
/*.o # This keeps the folder from disappearing

View file

@ -1,2 +1,2 @@
/depend.dep # DON'T REMOVE
/*.o # This keeps the folder from disappearing

View file

@ -1 +1,2 @@
/depend.dep # DON'T REMOVE
# This keeps the folder from disappearing

View file

@ -1 +1,2 @@
/depend.dep # DON'T REMOVE
# This keeps the folder from disappearing

View file

@ -1 +1,2 @@
/depend.dep # DON'T REMOVE
# This keeps the folder from disappearing

View file

@ -1,2 +1,2 @@
/depend.dep # DON'T REMOVE
/*.o # This keeps the folder from disappearing

View file

@ -1,2 +1,2 @@
/depend.dep # DON'T REMOVE
/*.o # This keeps the folder from disappearing

View file

@ -2531,7 +2531,7 @@ static void Command_Ban(void)
return; return;
else else
WRITEUINT8(p, pn); WRITEUINT8(p, pn);
if (I_Ban && !I_Ban(node)) if (server && I_Ban && !I_Ban(node)) // only the server is allowed to do this right now
{ {
CONS_Alert(CONS_WARNING, M_GetText("Too many bans! Geez, that's a lot of people you're excluding...\n")); CONS_Alert(CONS_WARNING, M_GetText("Too many bans! Geez, that's a lot of people you're excluding...\n"));
WRITEUINT8(p, KICK_MSG_GO_AWAY); WRITEUINT8(p, KICK_MSG_GO_AWAY);
@ -2539,6 +2539,7 @@ static void Command_Ban(void)
} }
else else
{ {
if (server) // only the server is allowed to do this right now
Ban_Add(COM_Argv(2)); Ban_Add(COM_Argv(2));
if (COM_Argc() == 2) if (COM_Argc() == 2)
@ -2696,12 +2697,14 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
// If a verified admin banned someone, the server needs to know about it. // If a verified admin banned someone, the server needs to know about it.
// If the playernum isn't zero (the server) then the server needs to record the ban. // If the playernum isn't zero (the server) then the server needs to record the ban.
if (server && playernum && msg == KICK_MSG_BANNED) if (server && playernum && (msg == KICK_MSG_BANNED || msg == KICK_MSG_CUSTOM_BAN))
{ {
if (I_Ban && !I_Ban(playernode[(INT32)pnum])) if (I_Ban && !I_Ban(playernode[(INT32)pnum]))
{
CONS_Alert(CONS_WARNING, M_GetText("Too many bans! Geez, that's a lot of people you're excluding...\n")); CONS_Alert(CONS_WARNING, M_GetText("Too many bans! Geez, that's a lot of people you're excluding...\n"));
} #ifndef NONET
else
Ban_Add(reason);
#endif
} }
switch (msg) switch (msg)
@ -3399,17 +3402,38 @@ static void HandlePacketFromAwayNode(SINT8 node)
if (node != servernode) if (node != servernode)
DEBFILE(va("Received packet from unknown host %d\n", node)); DEBFILE(va("Received packet from unknown host %d\n", node));
// macro for packets that should only be sent by the server
// if it is NOT from the server, bail out and close the connection!
#define SERVERONLY \
if (node != servernode) \
{ \
Net_CloseConnection(node); \
break; \
}
switch (netbuffer->packettype) switch (netbuffer->packettype)
{ {
case PT_ASKINFOVIAMS: case PT_ASKINFOVIAMS:
if (server && serverrunning) if (server && serverrunning)
{ {
INT32 clientnode = I_NetMakeNode(netbuffer->u.msaskinfo.clientaddr); INT32 clientnode;
if (ms_RoomId < 0) // ignore if we're not actually on the MS right now
{
Net_CloseConnection(node); // and yes, close connection
return;
}
clientnode = I_NetMakeNode(netbuffer->u.msaskinfo.clientaddr);
if (clientnode != -1)
{
SV_SendServerInfo(clientnode, (tic_t)LONG(netbuffer->u.msaskinfo.time)); SV_SendServerInfo(clientnode, (tic_t)LONG(netbuffer->u.msaskinfo.time));
SV_SendPlayerInfo(clientnode); // Send extra info SV_SendPlayerInfo(clientnode); // Send extra info
Net_CloseConnection(clientnode); Net_CloseConnection(clientnode);
// Don't close connection to MS. // Don't close connection to MS...
} }
else
Net_CloseConnection(node); // ...unless the IP address is not valid
}
else
Net_CloseConnection(node); // you're not supposed to get it, so ignore it
break; break;
case PT_ASKINFO: case PT_ASKINFO:
@ -3417,8 +3441,8 @@ static void HandlePacketFromAwayNode(SINT8 node)
{ {
SV_SendServerInfo(node, (tic_t)LONG(netbuffer->u.askinfo.time)); SV_SendServerInfo(node, (tic_t)LONG(netbuffer->u.askinfo.time));
SV_SendPlayerInfo(node); // Send extra info SV_SendPlayerInfo(node); // Send extra info
Net_CloseConnection(node);
} }
Net_CloseConnection(node);
break; break;
case PT_SERVERREFUSE: // Negative response of client join request case PT_SERVERREFUSE: // Negative response of client join request
@ -3427,6 +3451,7 @@ static void HandlePacketFromAwayNode(SINT8 node)
Net_CloseConnection(node); Net_CloseConnection(node);
break; break;
} }
SERVERONLY
if (cl_mode == CL_WAITJOINRESPONSE) if (cl_mode == CL_WAITJOINRESPONSE)
{ {
// Save the reason so it can be displayed after quitting the netgame // Save the reason so it can be displayed after quitting the netgame
@ -3458,6 +3483,7 @@ static void HandlePacketFromAwayNode(SINT8 node)
Net_CloseConnection(node); Net_CloseConnection(node);
break; break;
} }
SERVERONLY
/// \note how would this happen? and is it doing the right thing if it does? /// \note how would this happen? and is it doing the right thing if it does?
if (cl_mode != CL_WAITJOINRESPONSE) if (cl_mode != CL_WAITJOINRESPONSE)
break; break;
@ -3521,13 +3547,18 @@ static void HandlePacketFromAwayNode(SINT8 node)
Net_CloseConnection(node); Net_CloseConnection(node);
break; break;
} }
else SERVERONLY
Got_Filetxpak(); Got_Filetxpak();
break; break;
case PT_REQUESTFILE: case PT_REQUESTFILE:
if (server) if (server)
Got_RequestFilePak(node); {
if (!cv_downloading.value || !Got_RequestFilePak(node))
Net_CloseConnection(node); // close connection if one of the requested files could not be sent, or you disabled downloading anyway
}
else
Net_CloseConnection(node); // nope
break; break;
case PT_NODETIMEOUT: case PT_NODETIMEOUT:
@ -3550,6 +3581,7 @@ static void HandlePacketFromAwayNode(SINT8 node)
break; // Ignore it break; // Ignore it
} }
#undef SERVERONLY
} }
/** Handles a packet received from a node that is in game /** Handles a packet received from a node that is in game
@ -3582,6 +3614,8 @@ FILESTAMP
{ {
// -------------------------------------------- SERVER RECEIVE ---------- // -------------------------------------------- SERVER RECEIVE ----------
case PT_RESYNCHGET: case PT_RESYNCHGET:
if (client)
break;
SV_AcknowledgeResynchAck(netconsole, netbuffer->u.resynchgot); SV_AcknowledgeResynchAck(netconsole, netbuffer->u.resynchgot);
break; break;
case PT_CLIENTCMD: case PT_CLIENTCMD:
@ -3648,7 +3682,8 @@ FILESTAMP
} }
// Splitscreen cmd // Splitscreen cmd
if (netbuffer->packettype == PT_CLIENT2CMD && nodetoplayer2[node] >= 0) if ((netbuffer->packettype == PT_CLIENT2CMD || netbuffer->packettype == PT_CLIENT2MIS)
&& nodetoplayer2[node] >= 0)
G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)nodetoplayer2[node]], G_MoveTiccmd(&netcmds[maketic%BACKUPTICS][(UINT8)nodetoplayer2[node]],
&netbuffer->u.client2pak.cmd2, 1); &netbuffer->u.client2pak.cmd2, 1);
@ -3707,6 +3742,27 @@ FILESTAMP
tic_t tic = maketic; tic_t tic = maketic;
UINT8 *textcmd; UINT8 *textcmd;
// ignore if the textcmd has a reported size of zero
// this shouldn't be sent at all
if (!netbuffer->u.textcmd[0])
{
DEBFILE(va("GetPacket: Textcmd with size 0 detected! (node %u, player %d)\n",
node, netconsole));
Net_UnAcknowledgePacket(node);
break;
}
// ignore if the textcmd size var is actually larger than it should be
// BASEPACKETSIZE + 1 (for size) + textcmd[0] should == datalength
if (netbuffer->u.textcmd[0] > (size_t)doomcom->datalength-BASEPACKETSIZE-1)
{
DEBFILE(va("GetPacket: Bad Textcmd packet size! (expected %d, actual %s, node %u, player %d)\n",
netbuffer->u.textcmd[0], sizeu1((size_t)doomcom->datalength-BASEPACKETSIZE-1),
node, netconsole));
Net_UnAcknowledgePacket(node);
break;
}
// check if tic that we are making isn't too large else we cannot send it :( // check if tic that we are making isn't too large else we cannot send it :(
// doomcom->numslots+1 "+1" since doomcom->numslots can change within this time and sent time // doomcom->numslots+1 "+1" since doomcom->numslots can change within this time and sent time
j = software_MAXPACKETLENGTH j = software_MAXPACKETLENGTH
@ -3910,6 +3966,21 @@ FILESTAMP
case PT_SERVERCFG: case PT_SERVERCFG:
break; break;
case PT_FILEFRAGMENT: case PT_FILEFRAGMENT:
// Only accept PT_FILEFRAGMENT from the server.
if (node != servernode)
{
CONS_Alert(CONS_WARNING, M_GetText("%s received from non-host %d\n"), "PT_FILEFRAGMENT", node);
if (server)
{
XBOXSTATIC UINT8 buf[2];
buf[0] = (UINT8)node;
buf[1] = KICK_MSG_CON_FAIL;
SendNetXCmd(XD_KICK, &buf, 2);
}
break;
}
if (client) if (client)
Got_Filetxpak(); Got_Filetxpak();
break; break;

View file

@ -711,11 +711,24 @@ void Net_CloseConnection(INT32 node)
#else #else
INT32 i; INT32 i;
boolean forceclose = (node & FORCECLOSE) != 0; boolean forceclose = (node & FORCECLOSE) != 0;
if (node == -1)
{
DEBFILE(M_GetText("Net_CloseConnection: node -1 detected!\n"));
return; // nope, just ignore it
}
node &= ~FORCECLOSE; node &= ~FORCECLOSE;
if (!node) if (!node)
return; return;
if (node < 0 || node >= MAXNETNODES) // prevent invalid nodes from crashing the game
{
DEBFILE(va(M_GetText("Net_CloseConnection: invalid node %d detected!\n"), node));
return;
}
nodes[node].flags |= NF_CLOSE; nodes[node].flags |= NF_CLOSE;
// try to Send ack back (two army problem) // try to Send ack back (two army problem)

View file

@ -1569,8 +1569,13 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese
mapchangepending = 0; mapchangepending = 0;
// spawn the server if needed // spawn the server if needed
// reset players if there is a new one // reset players if there is a new one
if (!(adminplayer == consoleplayer) && SV_SpawnServer()) if (!(adminplayer == consoleplayer))
{
if (SV_SpawnServer())
buf[0] &= ~(1<<1); buf[0] &= ~(1<<1);
if (!Playing()) // you failed to start a server somehow, so cancel the map change
return;
}
// Kick bot from special stages // Kick bot from special stages
if (botskin) if (botskin)
@ -2116,7 +2121,7 @@ static void Command_Teamchange_f(void)
return; return;
} }
if (!cv_allowteamchange.value && !NetPacket.packet.newteam) // allow swapping to spectator even in locked teams. if (!cv_allowteamchange.value && NetPacket.packet.newteam) // allow swapping to spectator even in locked teams.
{ {
CONS_Alert(CONS_NOTICE, M_GetText("The server is not allowing team changes at the moment.\n")); CONS_Alert(CONS_NOTICE, M_GetText("The server is not allowing team changes at the moment.\n"));
return; return;
@ -2213,7 +2218,7 @@ static void Command_Teamchange2_f(void)
return; return;
} }
if (!cv_allowteamchange.value && !NetPacket.packet.newteam) // allow swapping to spectator even in locked teams. if (!cv_allowteamchange.value && NetPacket.packet.newteam) // allow swapping to spectator even in locked teams.
{ {
CONS_Alert(CONS_NOTICE, M_GetText("The server is not allowing team changes at the moment.\n")); CONS_Alert(CONS_NOTICE, M_GetText("The server is not allowing team changes at the moment.\n"));
return; return;
@ -2967,6 +2972,7 @@ static void Command_Addfile(void)
XBOXSTATIC char buf[256]; XBOXSTATIC char buf[256];
char *buf_p = buf; char *buf_p = buf;
INT32 i; INT32 i;
int musiconly; // W_VerifyNMUSlumps isn't boolean
if (COM_Argc() != 2) if (COM_Argc() != 2)
{ {
@ -2981,7 +2987,9 @@ static void Command_Addfile(void)
if (!isprint(fn[i]) || fn[i] == ';') if (!isprint(fn[i]) || fn[i] == ';')
return; return;
if (!W_VerifyNMUSlumps(fn)) musiconly = W_VerifyNMUSlumps(fn);
if (!musiconly)
{ {
// ... But only so long as they contain nothing more then music and sprites. // ... But only so long as they contain nothing more then music and sprites.
if (netgame && !(server || adminplayer == consoleplayer)) if (netgame && !(server || adminplayer == consoleplayer))
@ -2993,7 +3001,7 @@ static void Command_Addfile(void)
} }
// Add file on your client directly if it is trivial, or you aren't in a netgame. // Add file on your client directly if it is trivial, or you aren't in a netgame.
if (!(netgame || multiplayer) || W_VerifyNMUSlumps(fn)) if (!(netgame || multiplayer) || musiconly)
{ {
P_AddWadFile(fn, NULL); P_AddWadFile(fn, NULL);
return; return;
@ -3013,9 +3021,7 @@ static void Command_Addfile(void)
#else #else
FILE *fhandle; FILE *fhandle;
fhandle = fopen(fn, "rb"); if ((fhandle = W_OpenWadFile(&fn, true)) != NULL)
if (fhandle)
{ {
tic_t t = I_GetTime(); tic_t t = I_GetTime();
CONS_Debug(DBG_SETUP, "Making MD5 for %s\n",fn); CONS_Debug(DBG_SETUP, "Making MD5 for %s\n",fn);
@ -3023,11 +3029,8 @@ static void Command_Addfile(void)
CONS_Debug(DBG_SETUP, "MD5 calc for %s took %f second\n", fn, (float)(I_GetTime() - t)/TICRATE); CONS_Debug(DBG_SETUP, "MD5 calc for %s took %f second\n", fn, (float)(I_GetTime() - t)/TICRATE);
fclose(fhandle); fclose(fhandle);
} }
else else // file not found
{
CONS_Printf(M_GetText("File %s not found.\n"), fn);
return; return;
}
#endif #endif
WRITEMEM(buf_p, md5sum, 16); WRITEMEM(buf_p, md5sum, 16);
} }
@ -4102,7 +4105,8 @@ static void Skin_OnChange(void)
if (!Playing()) if (!Playing())
return; // do whatever you want return; // do whatever you want
if (!(cv_debug || devparm) && !(multiplayer || netgame)) // In single player. if (!(cv_debug || devparm) && !(multiplayer || netgame) // In single player.
&& (gamestate != GS_WAITINGPLAYERS)) // allows command line -warp x +skin y
{ {
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name); CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
return; return;
@ -4145,8 +4149,7 @@ static void Color_OnChange(void)
if (!Playing()) if (!Playing())
return; // do whatever you want return; // do whatever you want
if (!(cv_debug || devparm) && !(multiplayer || netgame) // In single player. if (!(cv_debug || devparm) && !(multiplayer || netgame)) // In single player.
&& (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_CONTINUING))
{ {
CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name); CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name);
return; return;

View file

@ -62,7 +62,8 @@
#include <errno.h> #include <errno.h>
static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid); // Prototypes
static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid);
// Sender structure // Sender structure
typedef struct filetx_s typedef struct filetx_s
@ -303,7 +304,8 @@ boolean CL_SendRequestFile(void)
} }
// get request filepak and put it on the send queue // get request filepak and put it on the send queue
void Got_RequestFilePak(INT32 node) // returns false if a requested file was not found or cannot be sent
boolean Got_RequestFilePak(INT32 node)
{ {
char wad[MAX_WADPATH+1]; char wad[MAX_WADPATH+1];
UINT8 *p = netbuffer->u.textcmd; UINT8 *p = netbuffer->u.textcmd;
@ -314,8 +316,13 @@ void Got_RequestFilePak(INT32 node)
if (id == 0xFF) if (id == 0xFF)
break; break;
READSTRINGN(p, wad, MAX_WADPATH); READSTRINGN(p, wad, MAX_WADPATH);
SV_SendFile(node, wad, id); if (!SV_SendFile(node, wad, id))
{
SV_AbortSendFiles(node);
return false; // don't read the rest of the files
} }
}
return true; // no problems with any files
} }
/** Checks if the files needed aren't already loaded or on the disk /** Checks if the files needed aren't already loaded or on the disk
@ -480,7 +487,7 @@ static INT32 filestosend = 0;
* \sa SV_SendRam * \sa SV_SendRam
* *
*/ */
static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid) static boolean SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
{ {
filetx_t **q; // A pointer to the "next" field of the last file in the list filetx_t **q; // A pointer to the "next" field of the last file in the list
filetx_t *p; // The new file request filetx_t *p; // The new file request
@ -488,7 +495,7 @@ static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
char wadfilename[MAX_WADPATH]; char wadfilename[MAX_WADPATH];
if (cv_noticedownload.value) if (cv_noticedownload.value)
CONS_Printf("Sending file \"%s\" to node %d\n", filename, node); CONS_Printf("Sending file \"%s\" to node %d (%s)\n", filename, node, I_GetNodeAddress(node));
// Find the last file in the list and set a pointer to its "next" field // Find the last file in the list and set a pointer to its "next" field
q = &transfer[node].txlist; q = &transfer[node].txlist;
@ -537,7 +544,7 @@ static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
free(p->id.filename); free(p->id.filename);
free(p); free(p);
*q = NULL; *q = NULL;
return; return false; // cancel the rest of the requests
} }
// Handle huge file requests (i.e. bigger than cv_maxsend.value KB) // Handle huge file requests (i.e. bigger than cv_maxsend.value KB)
@ -549,7 +556,7 @@ static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
free(p->id.filename); free(p->id.filename);
free(p); free(p);
*q = NULL; *q = NULL;
return; return false; // cancel the rest of the requests
} }
DEBFILE(va("Sending file %s (id=%d) to %d\n", filename, fileid, node)); DEBFILE(va("Sending file %s (id=%d) to %d\n", filename, fileid, node));
@ -557,6 +564,7 @@ static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid)
p->fileid = fileid; p->fileid = fileid;
p->next = NULL; // End of list p->next = NULL; // End of list
filestosend++; filestosend++;
return true;
} }
/** Adds a memory block to the file list for a node /** Adds a memory block to the file list for a node

View file

@ -69,7 +69,7 @@ boolean SV_SendingFile(INT32 node);
boolean CL_CheckDownloadable(void); boolean CL_CheckDownloadable(void);
boolean CL_SendRequestFile(void); boolean CL_SendRequestFile(void);
void Got_RequestFilePak(INT32 node); boolean Got_RequestFilePak(INT32 node);
void SV_AbortSendFiles(INT32 node); void SV_AbortSendFiles(INT32 node);
void CloseNetFile(void); void CloseNetFile(void);

View file

@ -150,9 +150,9 @@ extern FILE *logstream;
// we use comprevision and compbranch instead. // we use comprevision and compbranch instead.
#else #else
#define VERSION 201 // Game version #define VERSION 201 // Game version
#define SUBVERSION 17 // more precise version number #define SUBVERSION 18 // more precise version number
#define VERSIONSTRING "v2.1.17" #define VERSIONSTRING "v2.1.18"
#define VERSIONSTRINGW L"v2.1.17" #define VERSIONSTRINGW L"v2.1.18"
// Hey! If you change this, add 1 to the MODVERSION below! // Hey! If you change this, add 1 to the MODVERSION below!
// Otherwise we can't force updates! // Otherwise we can't force updates!
#endif #endif
@ -214,7 +214,7 @@ extern FILE *logstream;
// it's only for detection of the version the player is using so the MS can alert them of an update. // it's only for detection of the version the player is using so the MS can alert them of an update.
// Only set it higher, not lower, obviously. // Only set it higher, not lower, obviously.
// Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1". // Note that we use this to help keep internal testing in check; this is why v2.1.0 is not version "1".
#define MODVERSION 22 #define MODVERSION 23
// ========================================================================= // =========================================================================

View file

@ -2888,7 +2888,7 @@ static void G_DoCompleted(void)
if (nextmap < NUMMAPS && !mapheaderinfo[nextmap]) if (nextmap < NUMMAPS && !mapheaderinfo[nextmap])
P_AllocMapHeader(nextmap); P_AllocMapHeader(nextmap);
if (skipstats) if (skipstats && !modeattacking) // Don't skip stats if we're in record attack
G_AfterIntermission(); G_AfterIntermission();
else else
{ {

View file

@ -3849,6 +3849,7 @@ static void M_ChangeLevel(INT32 choice)
static void M_ConfirmSpectate(INT32 choice) static void M_ConfirmSpectate(INT32 choice)
{ {
(void)choice; (void)choice;
// We allow switching to spectator even if team changing is not allowed
M_ClearMenus(true); M_ClearMenus(true);
COM_ImmedExecute("changeteam spectator"); COM_ImmedExecute("changeteam spectator");
} }
@ -3856,6 +3857,11 @@ static void M_ConfirmSpectate(INT32 choice)
static void M_ConfirmEnterGame(INT32 choice) static void M_ConfirmEnterGame(INT32 choice)
{ {
(void)choice; (void)choice;
if (!cv_allowteamchange.value)
{
M_StartMessage(M_GetText("The server is not allowing\nteam changes at this time.\nPress a key.\n"), NULL, MM_NOTHING);
return;
}
M_ClearMenus(true); M_ClearMenus(true);
COM_ImmedExecute("changeteam playing"); COM_ImmedExecute("changeteam playing");
} }

View file

@ -585,7 +585,7 @@ static const char *Newsnapshotfile(const char *pathname, const char *ext)
i += add * result; i += add * result;
if (add < 0 || add > 9999) if (i < 0 || i > 9999)
return NULL; return NULL;
} }

View file

@ -1102,7 +1102,7 @@ void A_JetJawChomp(mobj_t *actor)
if (!actor->target || !(actor->target->flags & MF_SHOOTABLE) if (!actor->target || !(actor->target->flags & MF_SHOOTABLE)
|| actor->target->health <= 0 || !P_CheckSight(actor, actor->target)) || actor->target->health <= 0 || !P_CheckSight(actor, actor->target))
{ {
P_SetMobjState(actor, actor->info->spawnstate); P_SetMobjStateNF(actor, actor->info->spawnstate);
return; return;
} }

View file

@ -6648,6 +6648,18 @@ void P_MobjThinker(mobj_t *mobj)
} }
else switch (mobj->type) else switch (mobj->type)
{ {
case MT_FALLINGROCK:
// Despawn rocks here in case zmovement code can't do so (blame slopes)
if (!mobj->momx && !mobj->momy && !mobj->momz
&& ((mobj->eflags & MFE_VERTICALFLIP) ?
mobj->z + mobj->height >= mobj->ceilingz
: mobj->z <= mobj->floorz))
{
P_RemoveMobj(mobj);
return;
}
P_MobjCheckWater(mobj);
break;
case MT_EMERALDSPAWN: case MT_EMERALDSPAWN:
if (mobj->threshold) if (mobj->threshold)
{ {

View file

@ -3039,7 +3039,10 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
case 443: // Calls a named Lua function case 443: // Calls a named Lua function
#ifdef HAVE_BLUA #ifdef HAVE_BLUA
if (line->text)
LUAh_LinedefExecute(line, mo, callsec); LUAh_LinedefExecute(line, mo, callsec);
else
CONS_Alert(CONS_WARNING, "Linedef %s is missing the hook name of the Lua function to call! (This should be given in the front texture fields)\n", sizeu1(line-lines));
#else #else
CONS_Alert(CONS_ERROR, "The map is trying to run a Lua script, but this exe was not compiled with Lua support!\n"); CONS_Alert(CONS_ERROR, "The map is trying to run a Lua script, but this exe was not compiled with Lua support!\n");
#endif #endif

View file

@ -590,51 +590,44 @@ static BOOL I_ReadyConsole(HANDLE ci)
static boolean entering_con_command = false; static boolean entering_con_command = false;
void I_GetConsoleEvents(void) static void Impl_HandleKeyboardConsoleEvent(KEY_EVENT_RECORD evt, HANDLE co)
{ {
event_t ev = {0,0,0,0}; event_t event;
HANDLE ci = GetStdHandle(STD_INPUT_HANDLE);
HANDLE co = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO CSBI; CONSOLE_SCREEN_BUFFER_INFO CSBI;
INPUT_RECORD input;
DWORD t; DWORD t;
while (I_ReadyConsole(ci) && ReadConsoleInput(ci, &input, 1, &t) && t) memset(&event,0x00,sizeof (event));
if (evt.bKeyDown)
{ {
memset(&ev,0x00,sizeof (ev)); event.type = ev_console;
switch (input.EventType)
{
case KEY_EVENT:
if (input.Event.KeyEvent.bKeyDown)
{
ev.type = ev_console;
entering_con_command = true; entering_con_command = true;
switch (input.Event.KeyEvent.wVirtualKeyCode) switch (evt.wVirtualKeyCode)
{ {
case VK_ESCAPE: case VK_ESCAPE:
case VK_TAB: case VK_TAB:
ev.data1 = KEY_NULL; event.data1 = KEY_NULL;
break; break;
case VK_SHIFT: case VK_SHIFT:
ev.data1 = KEY_LSHIFT; event.data1 = KEY_LSHIFT;
break; break;
case VK_RETURN: case VK_RETURN:
entering_con_command = false; entering_con_command = false;
// Fall through. // Fall through.
default: default:
ev.data1 = MapVirtualKey(input.Event.KeyEvent.wVirtualKeyCode,2); // convert in to char event.data1 = MapVirtualKey(evt.wVirtualKeyCode,2); // convert in to char
} }
if (co != INVALID_HANDLE_VALUE && GetFileType(co) == FILE_TYPE_CHAR && GetConsoleMode(co, &t)) if (co != INVALID_HANDLE_VALUE && GetFileType(co) == FILE_TYPE_CHAR && GetConsoleMode(co, &t))
{ {
if (ev.data1 && ev.data1 != KEY_LSHIFT && ev.data1 != KEY_RSHIFT) if (event.data1 && event.data1 != KEY_LSHIFT && event.data1 != KEY_RSHIFT)
{ {
#ifdef _UNICODE #ifdef _UNICODE
WriteConsole(co, &input.Event.KeyEvent.uChar.UnicodeChar, 1, &t, NULL); WriteConsole(co, &evt.uChar.UnicodeChar, 1, &t, NULL);
#else #else
WriteConsole(co, &input.Event.KeyEvent.uChar.AsciiChar, 1 , &t, NULL); WriteConsole(co, &evt.uChar.AsciiChar, 1 , &t, NULL);
#endif #endif
} }
if (input.Event.KeyEvent.wVirtualKeyCode == VK_BACK if (evt.wVirtualKeyCode == VK_BACK
&& GetConsoleScreenBufferInfo(co,&CSBI)) && GetConsoleScreenBufferInfo(co,&CSBI))
{ {
WriteConsoleOutputCharacterA(co, " ",1, CSBI.dwCursorPosition, &t); WriteConsoleOutputCharacterA(co, " ",1, CSBI.dwCursorPosition, &t);
@ -643,17 +636,32 @@ void I_GetConsoleEvents(void)
} }
else else
{ {
ev.type = ev_keyup; event.type = ev_keyup;
switch (input.Event.KeyEvent.wVirtualKeyCode) switch (evt.wVirtualKeyCode)
{ {
case VK_SHIFT: case VK_SHIFT:
ev.data1 = KEY_LSHIFT; event.data1 = KEY_LSHIFT;
break; break;
default: default:
break; break;
} }
} }
if (ev.data1) D_PostEvent(&ev); if (event.data1) D_PostEvent(&event);
}
void I_GetConsoleEvents(void)
{
HANDLE ci = GetStdHandle(STD_INPUT_HANDLE);
HANDLE co = GetStdHandle(STD_OUTPUT_HANDLE);
INPUT_RECORD input;
DWORD t;
while (I_ReadyConsole(ci) && ReadConsoleInput(ci, &input, 1, &t) && t)
{
switch (input.EventType)
{
case KEY_EVENT:
Impl_HandleKeyboardConsoleEvent(input.Event.KeyEvent, co);
break; break;
case MOUSE_EVENT: case MOUSE_EVENT:
case WINDOW_BUFFER_SIZE_EVENT: case WINDOW_BUFFER_SIZE_EVENT:

View file

@ -181,15 +181,13 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen)
wasfullscreen = SDL_TRUE; wasfullscreen = SDL_TRUE;
SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP); SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
} }
else if (wasfullscreen) else // windowed mode
{
if (wasfullscreen)
{ {
wasfullscreen = SDL_FALSE; wasfullscreen = SDL_FALSE;
SDL_SetWindowFullscreen(window, 0); SDL_SetWindowFullscreen(window, 0);
SDL_SetWindowSize(window, width, height);
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED_DISPLAY(1), SDL_WINDOWPOS_CENTERED_DISPLAY(1));
} }
else
{
// Reposition window only in windowed mode // Reposition window only in windowed mode
SDL_SetWindowSize(window, width, height); SDL_SetWindowSize(window, width, height);
SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED_DISPLAY(1), SDL_WINDOWPOS_CENTERED_DISPLAY(1)); SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED_DISPLAY(1), SDL_WINDOWPOS_CENTERED_DISPLAY(1));
@ -899,7 +897,7 @@ static inline boolean I_SkipFrame(void)
{ {
static boolean skip = false; static boolean skip = false;
if (render_soft != rendermode) if (rendermode != render_soft)
return false; return false;
skip = !skip; skip = !skip;
@ -931,7 +929,7 @@ void I_FinishUpdate(void)
if (cv_ticrate.value) if (cv_ticrate.value)
SCR_DisplayTicRate(); SCR_DisplayTicRate();
if (render_soft == rendermode && screens[0]) if (rendermode == render_soft && screens[0])
{ {
SDL_Rect rect; SDL_Rect rect;
@ -958,7 +956,7 @@ void I_FinishUpdate(void)
} }
#ifdef HWRENDER #ifdef HWRENDER
else else if (rendermode == render_opengl)
{ {
OglSdlFinishUpdate(cv_vidwait.value); OglSdlFinishUpdate(cv_vidwait.value);
} }
@ -1188,9 +1186,9 @@ INT32 VID_SetMode(INT32 modeNum)
} }
Impl_SetWindowName("SRB2 "VERSIONSTRING); Impl_SetWindowName("SRB2 "VERSIONSTRING);
SDLSetMode(windowedModes[modeNum][0], windowedModes[modeNum][1], USE_FULLSCREEN); SDLSetMode(vid.width, vid.height, USE_FULLSCREEN);
if (render_soft == rendermode) if (rendermode == render_soft)
{ {
if (bufSurface) if (bufSurface)
{ {
@ -1209,30 +1207,20 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen)
int flags = 0; int flags = 0;
if (rendermode == render_none) // dedicated if (rendermode == render_none) // dedicated
{
return SDL_TRUE; // Monster Iestyn -- not sure if it really matters what we return here tbh return SDL_TRUE; // Monster Iestyn -- not sure if it really matters what we return here tbh
}
if (window != NULL) if (window != NULL)
{
return SDL_FALSE; return SDL_FALSE;
}
if (fullscreen) if (fullscreen)
{
flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
}
if (borderlesswindow) if (borderlesswindow)
{
flags |= SDL_WINDOW_BORDERLESS; flags |= SDL_WINDOW_BORDERLESS;
}
#ifdef HWRENDER #ifdef HWRENDER
if (rendermode == render_opengl) if (rendermode == render_opengl)
{
flags |= SDL_WINDOW_OPENGL; flags |= SDL_WINDOW_OPENGL;
}
#endif #endif
// Create a window // Create a window
@ -1261,7 +1249,13 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen)
#endif #endif
if (rendermode == render_soft) if (rendermode == render_soft)
{ {
renderer = SDL_CreateRenderer(window, -1, (usesdl2soft ? SDL_RENDERER_SOFTWARE : 0) | (cv_vidwait.value && !usesdl2soft ? SDL_RENDERER_PRESENTVSYNC : 0)); flags = 0; // Use this to set SDL_RENDERER_* flags now
if (usesdl2soft)
flags |= SDL_RENDERER_SOFTWARE;
else if (cv_vidwait.value)
flags |= SDL_RENDERER_PRESENTVSYNC;
renderer = SDL_CreateRenderer(window, -1, flags);
if (renderer == NULL) if (renderer == NULL)
{ {
CONS_Printf(M_GetText("Couldn't create rendering context: %s\n"), SDL_GetError()); CONS_Printf(M_GetText("Couldn't create rendering context: %s\n"), SDL_GetError());
@ -1483,7 +1477,7 @@ void I_ShutdownGraphics(void)
rendermode = render_none; rendermode = render_none;
if (icoSurface) SDL_FreeSurface(icoSurface); if (icoSurface) SDL_FreeSurface(icoSurface);
icoSurface = NULL; icoSurface = NULL;
if (render_soft == oldrendermode) if (oldrendermode == render_soft)
{ {
if (vidSurface) SDL_FreeSurface(vidSurface); if (vidSurface) SDL_FreeSurface(vidSurface);
vidSurface = NULL; vidSurface = NULL;

View file

@ -1214,7 +1214,7 @@
C01FCF4B08A954540054247B /* Debug */ = { C01FCF4B08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
CURRENT_PROJECT_VERSION = 2.1.17; CURRENT_PROJECT_VERSION = 2.1.18;
GCC_PREPROCESSOR_DEFINITIONS = ( GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)", "$(inherited)",
NORMALSRB2, NORMALSRB2,
@ -1226,7 +1226,7 @@
C01FCF4C08A954540054247B /* Release */ = { C01FCF4C08A954540054247B /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
CURRENT_PROJECT_VERSION = 2.1.17; CURRENT_PROJECT_VERSION = 2.1.18;
GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_PREPROCESSOR_DEFINITIONS = ( GCC_PREPROCESSOR_DEFINITIONS = (

View file

@ -1214,7 +1214,7 @@
C01FCF4B08A954540054247B /* Debug */ = { C01FCF4B08A954540054247B /* Debug */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
CURRENT_PROJECT_VERSION = 2.1.17; CURRENT_PROJECT_VERSION = 2.1.18;
GCC_PREPROCESSOR_DEFINITIONS = ( GCC_PREPROCESSOR_DEFINITIONS = (
"$(inherited)", "$(inherited)",
NORMALSRB2, NORMALSRB2,
@ -1226,7 +1226,7 @@
C01FCF4C08A954540054247B /* Release */ = { C01FCF4C08A954540054247B /* Release */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
buildSettings = { buildSettings = {
CURRENT_PROJECT_VERSION = 2.1.17; CURRENT_PROJECT_VERSION = 2.1.18;
GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_ENABLE_FIX_AND_CONTINUE = NO;
GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO;
GCC_PREPROCESSOR_DEFINITIONS = ( GCC_PREPROCESSOR_DEFINITIONS = (

View file

@ -758,79 +758,80 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c)
{ {
UINT8 *dest; UINT8 *dest;
const UINT8 *deststop; const UINT8 *deststop;
INT32 u, v, dupx, dupy;
if (rendermode == render_none)
return;
#ifdef HWRENDER #ifdef HWRENDER
if (rendermode != render_soft && rendermode != render_none) if (rendermode != render_soft && !con_startup)
{ {
HWR_DrawFill(x, y, w, h, c); HWR_DrawFill(x, y, w, h, c);
return; return;
} }
#endif #endif
dupx = vid.dupx; if (!(c & V_NOSCALESTART))
dupy = vid.dupy;
if (!screens[0])
return;
if (c & V_NOSCALESTART)
{
dest = screens[0] + y*vid.width + x;
deststop = screens[0] + vid.rowbytes * vid.height;
}
else
{ {
INT32 dupx = vid.dupx, dupy = vid.dupy;
if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT) if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT)
{ // Clear the entire screen, from dest to deststop. Yes, this really works. { // Clear the entire screen, from dest to deststop. Yes, this really works.
memset(screens[0], (UINT8)(c&255), vid.width * vid.height * vid.bpp); memset(screens[0], (UINT8)(c&255), vid.width * vid.height * vid.bpp);
return; return;
} }
dest = screens[0] + y*dupy*vid.width + x*dupx; x *= dupx;
deststop = screens[0] + vid.rowbytes * vid.height; y *= dupy;
if (w == BASEVIDWIDTH)
w = vid.width;
else
w *= dupx; w *= dupx;
if (h == BASEVIDHEIGHT)
h = vid.height;
else
h *= dupy; h *= dupy;
if (x && y && x + w < vid.width && y + h < vid.height)
{
// Center it if necessary // Center it if necessary
if (vid.width != BASEVIDWIDTH * dupx) if (vid.width != BASEVIDWIDTH * dupx)
{ {
// dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx, // dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx,
// so center this imaginary screen // so center this imaginary screen
if (c & V_SNAPTORIGHT) if (c & V_SNAPTORIGHT)
dest += (vid.width - (BASEVIDWIDTH * dupx)); x += (vid.width - (BASEVIDWIDTH * dupx));
else if (!(c & V_SNAPTOLEFT)) else if (!(c & V_SNAPTOLEFT))
dest += (vid.width - (BASEVIDWIDTH * dupx)) / 2; x += (vid.width - (BASEVIDWIDTH * dupx)) / 2;
} }
if (vid.height != BASEVIDHEIGHT * dupy) if (vid.height != BASEVIDHEIGHT * dupy)
{ {
// same thing here // same thing here
if (c & V_SNAPTOBOTTOM) if (c & V_SNAPTOBOTTOM)
dest += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width; y += (vid.height - (BASEVIDHEIGHT * dupy));
else if (!(c & V_SNAPTOTOP)) else if (!(c & V_SNAPTOTOP))
dest += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width / 2; y += (vid.height - (BASEVIDHEIGHT * dupy)) / 2;
} }
} }
if (x >= vid.width || y >= vid.height)
return; // off the screen
if (x < 0)
{
w += x;
x = 0;
} }
if (y < 0)
{
h += y;
y = 0;
}
if (w <= 0 || h <= 0)
return; // zero width/height wouldn't draw anything
if (x + w > vid.width)
w = vid.width - x;
if (y + h > vid.height)
h = vid.height - y;
dest = screens[0] + y*vid.width + x;
deststop = screens[0] + vid.rowbytes * vid.height;
c &= 255; c &= 255;
for (v = 0; v < h; v++, dest += vid.width) for (;(--h >= 0) && dest < deststop; dest += vid.width)
for (u = 0; u < w; u++) memset(dest, (UINT8)(c&255), w * vid.bpp);
{
if (dest > deststop)
return;
dest[u] = (UINT8)c;
}
} }
// //

View file

@ -133,6 +133,47 @@ void W_Shutdown(void)
static char filenamebuf[MAX_WADPATH]; static char filenamebuf[MAX_WADPATH];
// W_OpenWadFile
// Helper function for opening the WAD file.
// Returns the FILE * handle for the file, or NULL if not found or could not be opened
// If "useerrors" is true then print errors in the console, else just don't bother
// "filename" may be modified to have the correct path the actual file is located in, if necessary
FILE *W_OpenWadFile(const char **filename, boolean useerrors)
{
FILE *handle;
strncpy(filenamebuf, *filename, MAX_WADPATH);
filenamebuf[MAX_WADPATH - 1] = '\0';
*filename = filenamebuf;
// open wad file
if ((handle = fopen(*filename, "rb")) == NULL)
{
// If we failed to load the file with the path as specified by
// the user, strip the directories and search for the file.
nameonly(filenamebuf);
// If findfile finds the file, the full path will be returned
// in filenamebuf == *filename.
if (findfile(filenamebuf, NULL, true))
{
if ((handle = fopen(*filename, "rb")) == NULL)
{
if (useerrors)
CONS_Alert(CONS_ERROR, M_GetText("Can't open %s\n"), *filename);
return NULL;
}
}
else
{
if (useerrors)
CONS_Alert(CONS_ERROR, M_GetText("File %s not found.\n"), *filename);
return NULL;
}
}
return handle;
}
// search for all DEHACKED lump in all wads and load it // search for all DEHACKED lump in all wads and load it
static inline void W_LoadDehackedLumps(UINT16 wadnum) static inline void W_LoadDehackedLumps(UINT16 wadnum)
{ {
@ -234,7 +275,6 @@ static void W_InvalidateLumpnumCache(void)
memset(lumpnumcache, 0, sizeof (lumpnumcache)); memset(lumpnumcache, 0, sizeof (lumpnumcache));
} }
// Allocate a wadfile, setup the lumpinfo (directory) and // Allocate a wadfile, setup the lumpinfo (directory) and
// lumpcache, add the wadfile to the current active wadfiles // lumpcache, add the wadfile to the current active wadfiles
// //
@ -271,33 +311,9 @@ UINT16 W_LoadWadFile(const char *filename)
return INT16_MAX; return INT16_MAX;
} }
strncpy(filenamebuf, filename, MAX_WADPATH);
filenamebuf[MAX_WADPATH - 1] = '\0';
filename = filenamebuf;
// open wad file // open wad file
if ((handle = fopen(filename, "rb")) == NULL) if ((handle = W_OpenWadFile(&filename, true)) == NULL)
{
// If we failed to load the file with the path as specified by
// the user, strip the directories and search for the file.
nameonly(filenamebuf);
// If findfile finds the file, the full path will be returned
// in filenamebuf == filename.
if (findfile(filenamebuf, NULL, true))
{
if ((handle = fopen(filename, "rb")) == NULL)
{
CONS_Alert(CONS_ERROR, M_GetText("Can't open %s\n"), filename);
return INT16_MAX; return INT16_MAX;
}
}
else
{
CONS_Alert(CONS_ERROR, M_GetText("File %s not found.\n"), filename);
return INT16_MAX;
}
}
// Check if wad files will overflow fileneededbuffer. Only the filename part // Check if wad files will overflow fileneededbuffer. Only the filename part
// is send in the packet; cf. // is send in the packet; cf.
@ -1115,21 +1131,11 @@ static int W_VerifyFile(const char *filename, lumpchecklist_t *checklist,
size_t i, j; size_t i, j;
int goodfile = false; int goodfile = false;
if (!checklist) I_Error("No checklist for %s\n", filename); if (!checklist)
strlcpy(filenamebuf, filename, MAX_WADPATH); I_Error("No checklist for %s\n", filename);
filename = filenamebuf;
// open wad file // open wad file
if ((handle = fopen(filename, "rb")) == NULL) if ((handle = W_OpenWadFile(&filename, false)) == NULL)
{
nameonly(filenamebuf); // leave full path here
if (findfile(filenamebuf, NULL, true))
{
if ((handle = fopen(filename, "rb")) == NULL)
return -1; return -1;
}
else
return -1;
}
// detect dehacked file with the "soc" extension // detect dehacked file with the "soc" extension
if (stricmp(&filename[strlen(filename) - 4], ".soc") != 0 if (stricmp(&filename[strlen(filename) - 4], ".soc") != 0

View file

@ -82,6 +82,8 @@ extern wadfile_t *wadfiles[MAX_WADFILES];
void W_Shutdown(void); void W_Shutdown(void);
// Opens a WAD file. Returns the FILE * handle for the file, or NULL if not found or could not be opened
FILE *W_OpenWadFile(const char **filename, boolean useerrors);
// Load and add a wadfile to the active wad files, returns numbers of lumps, INT16_MAX on error // Load and add a wadfile to the active wad files, returns numbers of lumps, INT16_MAX on error
UINT16 W_LoadWadFile(const char *filename); UINT16 W_LoadWadFile(const char *filename);
#ifdef DELFILE #ifdef DELFILE

View file

@ -965,7 +965,8 @@ void Y_StartIntermission(void)
} }
// We couldn't display the intermission even if we wanted to. // We couldn't display the intermission even if we wanted to.
if (dedicated) return; // But we still need to give the players their score bonuses, dummy.
//if (dedicated) return;
// This should always exist, but just in case... // This should always exist, but just in case...
if(!mapheaderinfo[prevmap]) if(!mapheaderinfo[prevmap])