diff --git a/CMakeLists.txt b/CMakeLists.txt index 31597f399..23b768a70 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.0) project(SRB2 - VERSION 2.1.17 + VERSION 2.1.18 LANGUAGES C) if(${PROJECT_SOURCE_DIR} MATCHES ${PROJECT_BINARY_DIR}) diff --git a/appveyor.yml b/appveyor.yml index b0544a90b..c1f6894ef 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,4 @@ -version: 2.1.17.{branch}-{build} +version: 2.1.18.{branch}-{build} os: MinGW environment: @@ -58,26 +58,29 @@ after_build: - cmd: git rev-parse --short %APPVEYOR_REPO_COMMIT%>%TMP%/gitshort.txt - cmd: set /P GITSHORT=<%TMP%/gitshort.txt - 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 - appveyor PushArtifact %BUILD_ARCHIVE% +- cmd: copy %BUILD_ARCHIVE% %BUILDSARCHIVE% +- appveyor PushArtifact %BUILDSARCHIVE% test: off -deploy: - - provider: FTP - protocol: ftps - host: - secure: NsLJEPIBvmwCOj8Tg8RoRQ== - username: - secure: ejxi5mvk7oLYu7QtbYojajEPigMy0mokaKhuEVuDZcA= - password: - secure: Hbn6Uy3lT0YZ88yFJ3aW4w== - folder: appveyor - application: - active_mode: false - on: - branch: master - appveyor_repo_tag: true +#deploy: +# - provider: FTP +# protocol: ftps +# host: +# secure: NsLJEPIBvmwCOj8Tg8RoRQ== +# username: +# secure: ejxi5mvk7oLYu7QtbYojajEPigMy0mokaKhuEVuDZcA= +# password: +# secure: Hbn6Uy3lT0YZ88yFJ3aW4w== +# folder: appveyor +# application: +# active_mode: false +# on: +# branch: master +# appveyor_repo_tag: true on_finish: diff --git a/bin/Mingw/Debug/.gitignore b/bin/Mingw/Debug/.gitignore index e431dca5d..834f313e3 100644 --- a/bin/Mingw/Debug/.gitignore +++ b/bin/Mingw/Debug/.gitignore @@ -1,3 +1,3 @@ -/srb2sdl.exe -/srb2win.exe -/r_opengl.dll +*.exe +*.mo +r_opengl.dll diff --git a/bin/Mingw/Release/.gitignore b/bin/Mingw/Release/.gitignore index e431dca5d..834f313e3 100644 --- a/bin/Mingw/Release/.gitignore +++ b/bin/Mingw/Release/.gitignore @@ -1,3 +1,3 @@ -/srb2sdl.exe -/srb2win.exe -/r_opengl.dll +*.exe +*.mo +r_opengl.dll diff --git a/objs/.gitignore b/objs/.gitignore new file mode 100644 index 000000000..35ecd6def --- /dev/null +++ b/objs/.gitignore @@ -0,0 +1,8 @@ +#All folders +SRB2.res +depend.dep +depend.ped +*.o +#VC9 folder only +/VC9/Win32 +/VC9/x64 diff --git a/objs/DC/SDL/Debug/.gitignore b/objs/DC/SDL/Debug/.gitignore index 867fcb4e0..42c6dc2c6 100644 --- a/objs/DC/SDL/Debug/.gitignore +++ b/objs/DC/SDL/Debug/.gitignore @@ -1 +1,2 @@ -/depend.dep +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/DC/SDL/Release/.gitignore b/objs/DC/SDL/Release/.gitignore index 867fcb4e0..42c6dc2c6 100644 --- a/objs/DC/SDL/Release/.gitignore +++ b/objs/DC/SDL/Release/.gitignore @@ -1 +1,2 @@ -/depend.dep +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/Linux/SDL/Debug/.gitignore b/objs/Linux/SDL/Debug/.gitignore index 8f6d0bdcd..42c6dc2c6 100644 --- a/objs/Linux/SDL/Debug/.gitignore +++ b/objs/Linux/SDL/Debug/.gitignore @@ -1,2 +1,2 @@ -/depend.dep -/*.o +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/Linux/SDL/Release/.gitignore b/objs/Linux/SDL/Release/.gitignore index 8f6d0bdcd..42c6dc2c6 100644 --- a/objs/Linux/SDL/Release/.gitignore +++ b/objs/Linux/SDL/Release/.gitignore @@ -1,2 +1,2 @@ -/depend.dep -/*.o +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/Linux64/SDL/Debug/.gitignore b/objs/Linux64/SDL/Debug/.gitignore index 8f6d0bdcd..42c6dc2c6 100644 --- a/objs/Linux64/SDL/Debug/.gitignore +++ b/objs/Linux64/SDL/Debug/.gitignore @@ -1,2 +1,2 @@ -/depend.dep -/*.o +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/Linux64/SDL/Release/.gitignore b/objs/Linux64/SDL/Release/.gitignore index 8f6d0bdcd..42c6dc2c6 100644 --- a/objs/Linux64/SDL/Release/.gitignore +++ b/objs/Linux64/SDL/Release/.gitignore @@ -1,2 +1,2 @@ -/depend.dep -/*.o +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/Mingw/Debug/.gitignore b/objs/Mingw/Debug/.gitignore index da4b3e912..42c6dc2c6 100644 --- a/objs/Mingw/Debug/.gitignore +++ b/objs/Mingw/Debug/.gitignore @@ -1,3 +1,2 @@ -/SRB2.res -/depend.dep -/*.o +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/Mingw/Release/.gitignore b/objs/Mingw/Release/.gitignore index da4b3e912..42c6dc2c6 100644 --- a/objs/Mingw/Release/.gitignore +++ b/objs/Mingw/Release/.gitignore @@ -1,3 +1,2 @@ -/SRB2.res -/depend.dep -/*.o +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/Mingw/SDL/Debug/.gitignore b/objs/Mingw/SDL/Debug/.gitignore index da4b3e912..42c6dc2c6 100644 --- a/objs/Mingw/SDL/Debug/.gitignore +++ b/objs/Mingw/SDL/Debug/.gitignore @@ -1,3 +1,2 @@ -/SRB2.res -/depend.dep -/*.o +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/Mingw/SDL/Release/.gitignore b/objs/Mingw/SDL/Release/.gitignore index da4b3e912..42c6dc2c6 100644 --- a/objs/Mingw/SDL/Release/.gitignore +++ b/objs/Mingw/SDL/Release/.gitignore @@ -1,3 +1,2 @@ -/SRB2.res -/depend.dep -/*.o +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/Mingw64/Debug/.gitignore b/objs/Mingw64/Debug/.gitignore index da4b3e912..42c6dc2c6 100644 --- a/objs/Mingw64/Debug/.gitignore +++ b/objs/Mingw64/Debug/.gitignore @@ -1,3 +1,2 @@ -/SRB2.res -/depend.dep -/*.o +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/Mingw64/Release/.gitignore b/objs/Mingw64/Release/.gitignore index da4b3e912..42c6dc2c6 100644 --- a/objs/Mingw64/Release/.gitignore +++ b/objs/Mingw64/Release/.gitignore @@ -1,3 +1,2 @@ -/SRB2.res -/depend.dep -/*.o +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/Mingw64/SDL/Debug/.gitignore b/objs/Mingw64/SDL/Debug/.gitignore index da4b3e912..42c6dc2c6 100644 --- a/objs/Mingw64/SDL/Debug/.gitignore +++ b/objs/Mingw64/SDL/Debug/.gitignore @@ -1,3 +1,2 @@ -/SRB2.res -/depend.dep -/*.o +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/Mingw64/SDL/Release/.gitignore b/objs/Mingw64/SDL/Release/.gitignore index da4b3e912..42c6dc2c6 100644 --- a/objs/Mingw64/SDL/Release/.gitignore +++ b/objs/Mingw64/SDL/Release/.gitignore @@ -1,3 +1,2 @@ -/SRB2.res -/depend.dep -/*.o +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/PS3/SDL/Debug/.gitignore b/objs/PS3/SDL/Debug/.gitignore index 8f6d0bdcd..42c6dc2c6 100644 --- a/objs/PS3/SDL/Debug/.gitignore +++ b/objs/PS3/SDL/Debug/.gitignore @@ -1,2 +1,2 @@ -/depend.dep -/*.o +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/PS3/SDL/Release/.gitignore b/objs/PS3/SDL/Release/.gitignore index 8f6d0bdcd..42c6dc2c6 100644 --- a/objs/PS3/SDL/Release/.gitignore +++ b/objs/PS3/SDL/Release/.gitignore @@ -1,2 +1,2 @@ -/depend.dep -/*.o +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/PSP/SDL/Release/.gitignore b/objs/PSP/SDL/Release/.gitignore index 867fcb4e0..42c6dc2c6 100644 --- a/objs/PSP/SDL/Release/.gitignore +++ b/objs/PSP/SDL/Release/.gitignore @@ -1 +1,2 @@ -/depend.dep +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/SDL/Release/.gitignore b/objs/SDL/Release/.gitignore index 4a262f94f..42c6dc2c6 100644 --- a/objs/SDL/Release/.gitignore +++ b/objs/SDL/Release/.gitignore @@ -1 +1,2 @@ -/depend.ped +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/VC/.gitignore b/objs/VC/.gitignore index e69de29bb..42c6dc2c6 100644 --- a/objs/VC/.gitignore +++ b/objs/VC/.gitignore @@ -0,0 +1,2 @@ +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/VC9/.gitignore b/objs/VC9/.gitignore index 205fe45de..42c6dc2c6 100644 --- a/objs/VC9/.gitignore +++ b/objs/VC9/.gitignore @@ -1,2 +1,2 @@ -/Win32 -/x64 +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/Wii/SDL/Debug/.gitignore b/objs/Wii/SDL/Debug/.gitignore index 8f6d0bdcd..42c6dc2c6 100644 --- a/objs/Wii/SDL/Debug/.gitignore +++ b/objs/Wii/SDL/Debug/.gitignore @@ -1,2 +1,2 @@ -/depend.dep -/*.o +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/Wii/SDL/Release/.gitignore b/objs/Wii/SDL/Release/.gitignore index 8f6d0bdcd..42c6dc2c6 100644 --- a/objs/Wii/SDL/Release/.gitignore +++ b/objs/Wii/SDL/Release/.gitignore @@ -1,2 +1,2 @@ -/depend.dep -/*.o +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/WinCE/SDL/Release/.gitignore b/objs/WinCE/SDL/Release/.gitignore index 867fcb4e0..42c6dc2c6 100644 --- a/objs/WinCE/SDL/Release/.gitignore +++ b/objs/WinCE/SDL/Release/.gitignore @@ -1 +1,2 @@ -/depend.dep +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/djgppdos/Debug/.gitignore b/objs/djgppdos/Debug/.gitignore index 867fcb4e0..42c6dc2c6 100644 --- a/objs/djgppdos/Debug/.gitignore +++ b/objs/djgppdos/Debug/.gitignore @@ -1 +1,2 @@ -/depend.dep +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/djgppdos/Release/.gitignore b/objs/djgppdos/Release/.gitignore index 867fcb4e0..42c6dc2c6 100644 --- a/objs/djgppdos/Release/.gitignore +++ b/objs/djgppdos/Release/.gitignore @@ -1 +1,2 @@ -/depend.dep +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/nds/Debug/.gitignore b/objs/nds/Debug/.gitignore index 8f6d0bdcd..42c6dc2c6 100644 --- a/objs/nds/Debug/.gitignore +++ b/objs/nds/Debug/.gitignore @@ -1,2 +1,2 @@ -/depend.dep -/*.o +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/objs/nds/Release/.gitignore b/objs/nds/Release/.gitignore index 8f6d0bdcd..42c6dc2c6 100644 --- a/objs/nds/Release/.gitignore +++ b/objs/nds/Release/.gitignore @@ -1,2 +1,2 @@ -/depend.dep -/*.o +# DON'T REMOVE +# This keeps the folder from disappearing diff --git a/src/d_clisrv.c b/src/d_clisrv.c index f47f6637c..89418dde2 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2531,7 +2531,7 @@ static void Command_Ban(void) return; else 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")); WRITEUINT8(p, KICK_MSG_GO_AWAY); @@ -2539,7 +2539,8 @@ static void Command_Ban(void) } else { - Ban_Add(COM_Argv(2)); + if (server) // only the server is allowed to do this right now + Ban_Add(COM_Argv(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 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])) - { 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) @@ -3399,17 +3402,38 @@ static void HandlePacketFromAwayNode(SINT8 node) if (node != servernode) 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) { case PT_ASKINFOVIAMS: if (server && serverrunning) { - INT32 clientnode = I_NetMakeNode(netbuffer->u.msaskinfo.clientaddr); - SV_SendServerInfo(clientnode, (tic_t)LONG(netbuffer->u.msaskinfo.time)); - SV_SendPlayerInfo(clientnode); // Send extra info - Net_CloseConnection(clientnode); - // Don't close connection to MS. + 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_SendPlayerInfo(clientnode); // Send extra info + Net_CloseConnection(clientnode); + // 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; case PT_ASKINFO: @@ -3417,8 +3441,8 @@ static void HandlePacketFromAwayNode(SINT8 node) { SV_SendServerInfo(node, (tic_t)LONG(netbuffer->u.askinfo.time)); SV_SendPlayerInfo(node); // Send extra info - Net_CloseConnection(node); } + Net_CloseConnection(node); break; case PT_SERVERREFUSE: // Negative response of client join request @@ -3427,6 +3451,7 @@ static void HandlePacketFromAwayNode(SINT8 node) Net_CloseConnection(node); break; } + SERVERONLY if (cl_mode == CL_WAITJOINRESPONSE) { // Save the reason so it can be displayed after quitting the netgame @@ -3458,6 +3483,7 @@ static void HandlePacketFromAwayNode(SINT8 node) Net_CloseConnection(node); break; } + SERVERONLY /// \note how would this happen? and is it doing the right thing if it does? if (cl_mode != CL_WAITJOINRESPONSE) break; @@ -3521,13 +3547,18 @@ static void HandlePacketFromAwayNode(SINT8 node) Net_CloseConnection(node); break; } - else - Got_Filetxpak(); + SERVERONLY + Got_Filetxpak(); break; case PT_REQUESTFILE: 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; case PT_NODETIMEOUT: @@ -3550,6 +3581,7 @@ static void HandlePacketFromAwayNode(SINT8 node) break; // Ignore it } +#undef SERVERONLY } /** Handles a packet received from a node that is in game @@ -3582,6 +3614,8 @@ FILESTAMP { // -------------------------------------------- SERVER RECEIVE ---------- case PT_RESYNCHGET: + if (client) + break; SV_AcknowledgeResynchAck(netconsole, netbuffer->u.resynchgot); break; case PT_CLIENTCMD: @@ -3648,7 +3682,8 @@ FILESTAMP } // 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]], &netbuffer->u.client2pak.cmd2, 1); @@ -3707,6 +3742,27 @@ FILESTAMP tic_t tic = maketic; 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 :( // doomcom->numslots+1 "+1" since doomcom->numslots can change within this time and sent time j = software_MAXPACKETLENGTH @@ -3910,6 +3966,21 @@ FILESTAMP case PT_SERVERCFG: break; 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) Got_Filetxpak(); break; diff --git a/src/d_net.c b/src/d_net.c index 7f16c302d..50b6c8cf6 100644 --- a/src/d_net.c +++ b/src/d_net.c @@ -711,11 +711,24 @@ void Net_CloseConnection(INT32 node) #else INT32 i; boolean forceclose = (node & FORCECLOSE) != 0; + + if (node == -1) + { + DEBFILE(M_GetText("Net_CloseConnection: node -1 detected!\n")); + return; // nope, just ignore it + } + node &= ~FORCECLOSE; if (!node) 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; // try to Send ack back (two army problem) diff --git a/src/d_netcmd.c b/src/d_netcmd.c index f61c80cb2..f23549315 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1569,8 +1569,13 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese mapchangepending = 0; // spawn the server if needed // reset players if there is a new one - if (!(adminplayer == consoleplayer) && SV_SpawnServer()) - buf[0] &= ~(1<<1); + if (!(adminplayer == consoleplayer)) + { + if (SV_SpawnServer()) + buf[0] &= ~(1<<1); + if (!Playing()) // you failed to start a server somehow, so cancel the map change + return; + } // Kick bot from special stages if (botskin) @@ -2116,7 +2121,7 @@ static void Command_Teamchange_f(void) 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")); return; @@ -2213,7 +2218,7 @@ static void Command_Teamchange2_f(void) 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")); return; @@ -2967,6 +2972,7 @@ static void Command_Addfile(void) XBOXSTATIC char buf[256]; char *buf_p = buf; INT32 i; + int musiconly; // W_VerifyNMUSlumps isn't boolean if (COM_Argc() != 2) { @@ -2981,7 +2987,9 @@ static void Command_Addfile(void) if (!isprint(fn[i]) || fn[i] == ';') return; - if (!W_VerifyNMUSlumps(fn)) + musiconly = W_VerifyNMUSlumps(fn); + + if (!musiconly) { // ... But only so long as they contain nothing more then music and sprites. 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. - if (!(netgame || multiplayer) || W_VerifyNMUSlumps(fn)) + if (!(netgame || multiplayer) || musiconly) { P_AddWadFile(fn, NULL); return; @@ -3013,9 +3021,7 @@ static void Command_Addfile(void) #else FILE *fhandle; - fhandle = fopen(fn, "rb"); - - if (fhandle) + if ((fhandle = W_OpenWadFile(&fn, true)) != NULL) { tic_t t = I_GetTime(); 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); fclose(fhandle); } - else - { - CONS_Printf(M_GetText("File %s not found.\n"), fn); + else // file not found return; - } #endif WRITEMEM(buf_p, md5sum, 16); } @@ -4102,7 +4105,8 @@ static void Skin_OnChange(void) if (!Playing()) 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); return; @@ -4145,8 +4149,7 @@ static void Color_OnChange(void) if (!Playing()) return; // do whatever you want - if (!(cv_debug || devparm) && !(multiplayer || netgame) // In single player. - && (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_CONTINUING)) + if (!(cv_debug || devparm) && !(multiplayer || netgame)) // In single player. { CV_StealthSet(&cv_skin, skins[players[consoleplayer].skin].name); return; diff --git a/src/d_netfil.c b/src/d_netfil.c index bf4e59878..2c463c0b5 100644 --- a/src/d_netfil.c +++ b/src/d_netfil.c @@ -62,7 +62,8 @@ #include -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 typedef struct filetx_s @@ -303,7 +304,8 @@ boolean CL_SendRequestFile(void) } // 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]; UINT8 *p = netbuffer->u.textcmd; @@ -314,8 +316,13 @@ void Got_RequestFilePak(INT32 node) if (id == 0xFF) break; 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 @@ -480,7 +487,7 @@ static INT32 filestosend = 0; * \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 *p; // The new file request @@ -488,7 +495,7 @@ static void SV_SendFile(INT32 node, const char *filename, UINT8 fileid) char wadfilename[MAX_WADPATH]; 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 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); *q = NULL; - return; + return false; // cancel the rest of the requests } // 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); *q = NULL; - return; + return false; // cancel the rest of the requests } 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->next = NULL; // End of list filestosend++; + return true; } /** Adds a memory block to the file list for a node diff --git a/src/d_netfil.h b/src/d_netfil.h index c9085a5b0..b9b7b2f2e 100644 --- a/src/d_netfil.h +++ b/src/d_netfil.h @@ -69,7 +69,7 @@ boolean SV_SendingFile(INT32 node); boolean CL_CheckDownloadable(void); boolean CL_SendRequestFile(void); -void Got_RequestFilePak(INT32 node); +boolean Got_RequestFilePak(INT32 node); void SV_AbortSendFiles(INT32 node); void CloseNetFile(void); diff --git a/src/doomdef.h b/src/doomdef.h index 99e54c077..428972ccd 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -150,9 +150,9 @@ extern FILE *logstream; // we use comprevision and compbranch instead. #else #define VERSION 201 // Game version -#define SUBVERSION 17 // more precise version number -#define VERSIONSTRING "v2.1.17" -#define VERSIONSTRINGW L"v2.1.17" +#define SUBVERSION 18 // more precise version number +#define VERSIONSTRING "v2.1.18" +#define VERSIONSTRINGW L"v2.1.18" // Hey! If you change this, add 1 to the MODVERSION below! // Otherwise we can't force updates! #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. // 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". -#define MODVERSION 22 +#define MODVERSION 23 // ========================================================================= diff --git a/src/g_game.c b/src/g_game.c index 84db90132..7499fe7a0 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -2888,7 +2888,7 @@ static void G_DoCompleted(void) if (nextmap < NUMMAPS && !mapheaderinfo[nextmap]) P_AllocMapHeader(nextmap); - if (skipstats) + if (skipstats && !modeattacking) // Don't skip stats if we're in record attack G_AfterIntermission(); else { diff --git a/src/m_menu.c b/src/m_menu.c index d7b4d9080..45b3d7e57 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -3849,6 +3849,7 @@ static void M_ChangeLevel(INT32 choice) static void M_ConfirmSpectate(INT32 choice) { (void)choice; + // We allow switching to spectator even if team changing is not allowed M_ClearMenus(true); COM_ImmedExecute("changeteam spectator"); } @@ -3856,6 +3857,11 @@ static void M_ConfirmSpectate(INT32 choice) static void M_ConfirmEnterGame(INT32 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); COM_ImmedExecute("changeteam playing"); } diff --git a/src/m_misc.c b/src/m_misc.c index cfe73d88f..d88643ec4 100644 --- a/src/m_misc.c +++ b/src/m_misc.c @@ -585,7 +585,7 @@ static const char *Newsnapshotfile(const char *pathname, const char *ext) i += add * result; - if (add < 0 || add > 9999) + if (i < 0 || i > 9999) return NULL; } diff --git a/src/p_enemy.c b/src/p_enemy.c index a8a6bb6b4..649c78838 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -1102,7 +1102,7 @@ void A_JetJawChomp(mobj_t *actor) if (!actor->target || !(actor->target->flags & MF_SHOOTABLE) || actor->target->health <= 0 || !P_CheckSight(actor, actor->target)) { - P_SetMobjState(actor, actor->info->spawnstate); + P_SetMobjStateNF(actor, actor->info->spawnstate); return; } diff --git a/src/p_mobj.c b/src/p_mobj.c index b9412ee77..fb8648013 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6648,6 +6648,18 @@ void P_MobjThinker(mobj_t *mobj) } 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: if (mobj->threshold) { diff --git a/src/p_spec.c b/src/p_spec.c index 3d83561a9..48c0f58b3 100644 --- a/src/p_spec.c +++ b/src/p_spec.c @@ -3039,7 +3039,10 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec) case 443: // Calls a named Lua function #ifdef HAVE_BLUA - LUAh_LinedefExecute(line, mo, callsec); + if (line->text) + 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 CONS_Alert(CONS_ERROR, "The map is trying to run a Lua script, but this exe was not compiled with Lua support!\n"); #endif diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index 71ee3f794..f72a9857d 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -590,70 +590,78 @@ static BOOL I_ReadyConsole(HANDLE ci) static boolean entering_con_command = false; +static void Impl_HandleKeyboardConsoleEvent(KEY_EVENT_RECORD evt, HANDLE co) +{ + event_t event; + CONSOLE_SCREEN_BUFFER_INFO CSBI; + DWORD t; + + memset(&event,0x00,sizeof (event)); + + if (evt.bKeyDown) + { + event.type = ev_console; + entering_con_command = true; + switch (evt.wVirtualKeyCode) + { + case VK_ESCAPE: + case VK_TAB: + event.data1 = KEY_NULL; + break; + case VK_SHIFT: + event.data1 = KEY_LSHIFT; + break; + case VK_RETURN: + entering_con_command = false; + // Fall through. + default: + event.data1 = MapVirtualKey(evt.wVirtualKeyCode,2); // convert in to char + } + if (co != INVALID_HANDLE_VALUE && GetFileType(co) == FILE_TYPE_CHAR && GetConsoleMode(co, &t)) + { + if (event.data1 && event.data1 != KEY_LSHIFT && event.data1 != KEY_RSHIFT) + { +#ifdef _UNICODE + WriteConsole(co, &evt.uChar.UnicodeChar, 1, &t, NULL); +#else + WriteConsole(co, &evt.uChar.AsciiChar, 1 , &t, NULL); +#endif + } + if (evt.wVirtualKeyCode == VK_BACK + && GetConsoleScreenBufferInfo(co,&CSBI)) + { + WriteConsoleOutputCharacterA(co, " ",1, CSBI.dwCursorPosition, &t); + } + } + } + else + { + event.type = ev_keyup; + switch (evt.wVirtualKeyCode) + { + case VK_SHIFT: + event.data1 = KEY_LSHIFT; + break; + default: + break; + } + } + if (event.data1) D_PostEvent(&event); +} + void I_GetConsoleEvents(void) { - event_t ev = {0,0,0,0}; HANDLE ci = GetStdHandle(STD_INPUT_HANDLE); HANDLE co = GetStdHandle(STD_OUTPUT_HANDLE); - CONSOLE_SCREEN_BUFFER_INFO CSBI; INPUT_RECORD input; DWORD t; while (I_ReadyConsole(ci) && ReadConsoleInput(ci, &input, 1, &t) && t) { - memset(&ev,0x00,sizeof (ev)); switch (input.EventType) { case KEY_EVENT: - if (input.Event.KeyEvent.bKeyDown) - { - ev.type = ev_console; - entering_con_command = true; - switch (input.Event.KeyEvent.wVirtualKeyCode) - { - case VK_ESCAPE: - case VK_TAB: - ev.data1 = KEY_NULL; - break; - case VK_SHIFT: - ev.data1 = KEY_LSHIFT; - break; - case VK_RETURN: - entering_con_command = false; - // Fall through. - default: - ev.data1 = MapVirtualKey(input.Event.KeyEvent.wVirtualKeyCode,2); // convert in to char - } - if (co != INVALID_HANDLE_VALUE && GetFileType(co) == FILE_TYPE_CHAR && GetConsoleMode(co, &t)) - { - if (ev.data1 && ev.data1 != KEY_LSHIFT && ev.data1 != KEY_RSHIFT) - { -#ifdef _UNICODE - WriteConsole(co, &input.Event.KeyEvent.uChar.UnicodeChar, 1, &t, NULL); -#else - WriteConsole(co, &input.Event.KeyEvent.uChar.AsciiChar, 1 , &t, NULL); -#endif - } - if (input.Event.KeyEvent.wVirtualKeyCode == VK_BACK - && GetConsoleScreenBufferInfo(co,&CSBI)) - { - WriteConsoleOutputCharacterA(co, " ",1, CSBI.dwCursorPosition, &t); - } - } - } - else - { - ev.type = ev_keyup; - switch (input.Event.KeyEvent.wVirtualKeyCode) - { - case VK_SHIFT: - ev.data1 = KEY_LSHIFT; - break; - default: - break; - } - } - if (ev.data1) D_PostEvent(&ev); + Impl_HandleKeyboardConsoleEvent(input.Event.KeyEvent, co); break; case MOUSE_EVENT: case WINDOW_BUFFER_SIZE_EVENT: diff --git a/src/sdl/i_video.c b/src/sdl/i_video.c index aa572e6e0..ec9b901c9 100644 --- a/src/sdl/i_video.c +++ b/src/sdl/i_video.c @@ -181,15 +181,13 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen) wasfullscreen = SDL_TRUE; SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP); } - else if (wasfullscreen) - { - wasfullscreen = SDL_FALSE; - SDL_SetWindowFullscreen(window, 0); - SDL_SetWindowSize(window, width, height); - SDL_SetWindowPosition(window, SDL_WINDOWPOS_CENTERED_DISPLAY(1), SDL_WINDOWPOS_CENTERED_DISPLAY(1)); - } - else + else // windowed mode { + if (wasfullscreen) + { + wasfullscreen = SDL_FALSE; + SDL_SetWindowFullscreen(window, 0); + } // Reposition window only in windowed mode SDL_SetWindowSize(window, width, height); 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; - if (render_soft != rendermode) + if (rendermode != render_soft) return false; skip = !skip; @@ -931,7 +929,7 @@ void I_FinishUpdate(void) if (cv_ticrate.value) SCR_DisplayTicRate(); - if (render_soft == rendermode && screens[0]) + if (rendermode == render_soft && screens[0]) { SDL_Rect rect; @@ -958,7 +956,7 @@ void I_FinishUpdate(void) } #ifdef HWRENDER - else + else if (rendermode == render_opengl) { OglSdlFinishUpdate(cv_vidwait.value); } @@ -1188,9 +1186,9 @@ INT32 VID_SetMode(INT32 modeNum) } 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) { @@ -1209,30 +1207,20 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) int flags = 0; if (rendermode == render_none) // dedicated - { return SDL_TRUE; // Monster Iestyn -- not sure if it really matters what we return here tbh - } if (window != NULL) - { return SDL_FALSE; - } if (fullscreen) - { flags |= SDL_WINDOW_FULLSCREEN_DESKTOP; - } if (borderlesswindow) - { flags |= SDL_WINDOW_BORDERLESS; - } #ifdef HWRENDER if (rendermode == render_opengl) - { flags |= SDL_WINDOW_OPENGL; - } #endif // Create a window @@ -1261,7 +1249,13 @@ static SDL_bool Impl_CreateWindow(SDL_bool fullscreen) #endif 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) { CONS_Printf(M_GetText("Couldn't create rendering context: %s\n"), SDL_GetError()); @@ -1483,7 +1477,7 @@ void I_ShutdownGraphics(void) rendermode = render_none; if (icoSurface) SDL_FreeSurface(icoSurface); icoSurface = NULL; - if (render_soft == oldrendermode) + if (oldrendermode == render_soft) { if (vidSurface) SDL_FreeSurface(vidSurface); vidSurface = NULL; diff --git a/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj b/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj index 32ae88c02..fbf9bacb2 100644 --- a/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj +++ b/src/sdl/macosx/Srb2mac.xcodeproj/project.pbxproj @@ -1214,7 +1214,7 @@ C01FCF4B08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CURRENT_PROJECT_VERSION = 2.1.17; + CURRENT_PROJECT_VERSION = 2.1.18; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", NORMALSRB2, @@ -1226,7 +1226,7 @@ C01FCF4C08A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CURRENT_PROJECT_VERSION = 2.1.17; + CURRENT_PROJECT_VERSION = 2.1.18; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_PREPROCESSOR_DEFINITIONS = ( diff --git a/src/sdl12/macosx/Srb2mac.xcodeproj/project.pbxproj b/src/sdl12/macosx/Srb2mac.xcodeproj/project.pbxproj index 13e78f314..98a760c7b 100644 --- a/src/sdl12/macosx/Srb2mac.xcodeproj/project.pbxproj +++ b/src/sdl12/macosx/Srb2mac.xcodeproj/project.pbxproj @@ -1214,7 +1214,7 @@ C01FCF4B08A954540054247B /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CURRENT_PROJECT_VERSION = 2.1.17; + CURRENT_PROJECT_VERSION = 2.1.18; GCC_PREPROCESSOR_DEFINITIONS = ( "$(inherited)", NORMALSRB2, @@ -1226,7 +1226,7 @@ C01FCF4C08A954540054247B /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CURRENT_PROJECT_VERSION = 2.1.17; + CURRENT_PROJECT_VERSION = 2.1.18; GCC_ENABLE_FIX_AND_CONTINUE = NO; GCC_GENERATE_DEBUGGING_SYMBOLS = NO; GCC_PREPROCESSOR_DEFINITIONS = ( diff --git a/src/v_video.c b/src/v_video.c index 1fb10fb5d..64bb3214e 100644 --- a/src/v_video.c +++ b/src/v_video.c @@ -758,79 +758,80 @@ void V_DrawFill(INT32 x, INT32 y, INT32 w, INT32 h, INT32 c) { UINT8 *dest; const UINT8 *deststop; - INT32 u, v, dupx, dupy; + + if (rendermode == render_none) + return; #ifdef HWRENDER - if (rendermode != render_soft && rendermode != render_none) + if (rendermode != render_soft && !con_startup) { HWR_DrawFill(x, y, w, h, c); return; } #endif - dupx = vid.dupx; - 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 + if (!(c & V_NOSCALESTART)) { + INT32 dupx = vid.dupx, dupy = vid.dupy; + if (x == 0 && y == 0 && w == BASEVIDWIDTH && h == BASEVIDHEIGHT) { // Clear the entire screen, from dest to deststop. Yes, this really works. memset(screens[0], (UINT8)(c&255), vid.width * vid.height * vid.bpp); return; } - dest = screens[0] + y*dupy*vid.width + x*dupx; - deststop = screens[0] + vid.rowbytes * vid.height; + x *= dupx; + y *= dupy; + w *= dupx; + h *= dupy; - if (w == BASEVIDWIDTH) - w = vid.width; - else - w *= dupx; - if (h == BASEVIDHEIGHT) - h = vid.height; - else - h *= dupy; - - if (x && y && x + w < vid.width && y + h < vid.height) + // Center it if necessary + if (vid.width != BASEVIDWIDTH * dupx) { - // Center it if necessary - if (vid.width != BASEVIDWIDTH * dupx) - { - // dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx, - // so center this imaginary screen - if (c & V_SNAPTORIGHT) - dest += (vid.width - (BASEVIDWIDTH * dupx)); - else if (!(c & V_SNAPTOLEFT)) - dest += (vid.width - (BASEVIDWIDTH * dupx)) / 2; - } - if (vid.height != BASEVIDHEIGHT * dupy) - { - // same thing here - if (c & V_SNAPTOBOTTOM) - dest += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width; - else if (!(c & V_SNAPTOTOP)) - dest += (vid.height - (BASEVIDHEIGHT * dupy)) * vid.width / 2; - } + // dupx adjustments pretend that screen width is BASEVIDWIDTH * dupx, + // so center this imaginary screen + if (c & V_SNAPTORIGHT) + x += (vid.width - (BASEVIDWIDTH * dupx)); + else if (!(c & V_SNAPTOLEFT)) + x += (vid.width - (BASEVIDWIDTH * dupx)) / 2; + } + if (vid.height != BASEVIDHEIGHT * dupy) + { + // same thing here + if (c & V_SNAPTOBOTTOM) + y += (vid.height - (BASEVIDHEIGHT * dupy)); + else if (!(c & V_SNAPTOTOP)) + 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; - for (v = 0; v < h; v++, dest += vid.width) - for (u = 0; u < w; u++) - { - if (dest > deststop) - return; - dest[u] = (UINT8)c; - } + for (;(--h >= 0) && dest < deststop; dest += vid.width) + memset(dest, (UINT8)(c&255), w * vid.bpp); } // diff --git a/src/w_wad.c b/src/w_wad.c index e4cb93050..3a8285593 100644 --- a/src/w_wad.c +++ b/src/w_wad.c @@ -133,6 +133,47 @@ void W_Shutdown(void) 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 static inline void W_LoadDehackedLumps(UINT16 wadnum) { @@ -234,7 +275,6 @@ static void W_InvalidateLumpnumCache(void) memset(lumpnumcache, 0, sizeof (lumpnumcache)); } - // Allocate a wadfile, setup the lumpinfo (directory) and // lumpcache, add the wadfile to the current active wadfiles // @@ -271,33 +311,9 @@ UINT16 W_LoadWadFile(const char *filename) return INT16_MAX; } - 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) - { - CONS_Alert(CONS_ERROR, M_GetText("Can't open %s\n"), filename); - return INT16_MAX; - } - } - else - { - CONS_Alert(CONS_ERROR, M_GetText("File %s not found.\n"), filename); - return INT16_MAX; - } - } + if ((handle = W_OpenWadFile(&filename, true)) == NULL) + return INT16_MAX; // Check if wad files will overflow fileneededbuffer. Only the filename part // is send in the packet; cf. @@ -1115,21 +1131,11 @@ static int W_VerifyFile(const char *filename, lumpchecklist_t *checklist, size_t i, j; int goodfile = false; - if (!checklist) I_Error("No checklist for %s\n", filename); - strlcpy(filenamebuf, filename, MAX_WADPATH); - filename = filenamebuf; + if (!checklist) + I_Error("No checklist for %s\n", filename); // open wad file - if ((handle = fopen(filename, "rb")) == NULL) - { - nameonly(filenamebuf); // leave full path here - if (findfile(filenamebuf, NULL, true)) - { - if ((handle = fopen(filename, "rb")) == NULL) - return -1; - } - else - return -1; - } + if ((handle = W_OpenWadFile(&filename, false)) == NULL) + return -1; // detect dehacked file with the "soc" extension if (stricmp(&filename[strlen(filename) - 4], ".soc") != 0 diff --git a/src/w_wad.h b/src/w_wad.h index b03e376bf..f7ea64a56 100644 --- a/src/w_wad.h +++ b/src/w_wad.h @@ -82,6 +82,8 @@ extern wadfile_t *wadfiles[MAX_WADFILES]; 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 UINT16 W_LoadWadFile(const char *filename); #ifdef DELFILE diff --git a/src/y_inter.c b/src/y_inter.c index b2e1cdf9f..2fd37ff33 100644 --- a/src/y_inter.c +++ b/src/y_inter.c @@ -965,7 +965,8 @@ void Y_StartIntermission(void) } // 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... if(!mapheaderinfo[prevmap])