Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
  • 21-installer-nodd
  • 2210-pre1
  • 2210-pre2
  • 2210-rc1
  • 2210-rc2
  • 2210-rc3
  • 2211-pre1
  • 2211-pre2
  • 2211-rc1
  • 2212-pre1
  • 2212-pre2
  • 2212-pre3
  • 2212-rc1
  • 2213
  • 2_2_12
  • 64-gl-log
  • COM_ImmedExecute-lua
  • DJGPP
  • accel-momentum
  • acs
  • action-args
  • alpha-fixes
  • any-resolution
  • appveyor
  • better-player-states
  • blend-locking
  • blentran
  • blua-unary-not-fix
  • boost-tickrate
  • bustablesoundz
  • cleanup-opengl
  • cleanupmusic
  • clipmidtex
  • cmake-valgrind
  • crawlacommander-sprites
  • custom-map-names
  • custom-teams
  • cutscene-cleanup
  • dd-music-bypass
  • dd-music-fix
  • delfile2
  • deprecate-lua-dedicated-server
  • dpl-2
  • dropshadows-spawning
  • dynabsp
  • emblem-drawing
  • exchndl-xp-fix
  • extra-textures
  • few-kart-lua-changes
  • ffloorclip
  • fix-167
  • fix-cvar-conflicts
  • fix-opengl-shear-roll
  • flipfuncpointers
  • fof-lightlist-fixes
  • font-FUCK
  • frictionrefactor
  • fuck-macros-1
  • gamepad-luakeydown
  • gamepad-morefixes
  • gamepad_experiments
  • gametype-refactor
  • gametype-refactor-1
  • gametype-refactor-player-spawns
  • ghost-networking
  • gif-splitting
  • gitlab-ci
  • grr-lj
  • hitboxviewer
  • hwr-texture-cache-refactor
  • hwrender2
  • improve-439
  • increase-maxconditionsets
  • increase-packet-tics
  • input-display
  • input-display-translucency
  • io
  • joystick-juggling-maz
  • keycodes-only
  • ksf-wadfiles
  • ld413-mp-fix
  • levelstruct
  • libpng-version-support
  • linedef-actions
  • lj-test
  • lol-states
  • loopedsounds
  • lower-unpegged-fix
  • lua-change-gametype
  • lua-command-netids
  • lua-debug-library
  • lua-gfx-2
  • lua-gfx-sprites
  • lua-local
  • makefile-auto-mingw-gcc
  • makefile-tinkering
  • map-components-signedness-fixes
  • master
  • menu-edits
  • mobj-dispoffset
  • SRB2_release_2.1
  • SRB2_release_2.1.1
  • SRB2_release_2.1.10
  • SRB2_release_2.1.11
  • SRB2_release_2.1.12
  • SRB2_release_2.1.14
  • SRB2_release_2.1.15
  • SRB2_release_2.1.16
  • SRB2_release_2.1.16a
  • SRB2_release_2.1.17
  • SRB2_release_2.1.18
  • SRB2_release_2.1.19
  • SRB2_release_2.1.2
  • SRB2_release_2.1.20
  • SRB2_release_2.1.21
  • SRB2_release_2.1.22
  • SRB2_release_2.1.23
  • SRB2_release_2.1.24
  • SRB2_release_2.1.25
  • SRB2_release_2.1.3
  • SRB2_release_2.1.4
  • SRB2_release_2.1.5
  • SRB2_release_2.1.6
  • SRB2_release_2.1.7
  • SRB2_release_2.1.8
  • SRB2_release_2.1.9
  • SRB2_release_2.2.0
  • SRB2_release_2.2.1
  • SRB2_release_2.2.10
  • SRB2_release_2.2.11
  • SRB2_release_2.2.12
  • SRB2_release_2.2.13
  • SRB2_release_2.2.2
  • SRB2_release_2.2.3
  • SRB2_release_2.2.4
  • SRB2_release_2.2.5
  • SRB2_release_2.2.6
  • SRB2_release_2.2.7
  • SRB2_release_2.2.8
  • SRB2_release_2.2.9
  • td-release-v1.0.0
141 results

Target

Select target project
  • STJr/SRB2
  • Sryder/SRB2
  • wolfy852/SRB2
  • Alpha2244/SRB2
  • Inuyasha/SRB2
  • yoshibot/SRB2
  • TehRealSalt/SRB2
  • PrisimaTF/SRB2
  • Hatninja/SRB2
  • SteelT/SRB2
  • james/SRB2
  • ShaderWraith/SRB2
  • SinnamonLat/SRB2
  • mazmazz_/SRB2
  • filpAM/SRB2
  • chaoloveicemdboy/SRB2
  • Whooa21/SRB2
  • Machturne/SRB2
  • Golden/SRB2
  • Tatsuru/SRB2
  • Snu/SRB2
  • Zwip-Zwap_Zapony/SRB2
  • fickleheart/SRB2
  • alphaRexJames/SRB2
  • JJK/SRB2
  • diskpoppy/SRB2
  • Hannu_Hanhi/SRB2
  • ZipperQR/SRB2
  • kays/SRB2
  • spherallic/SRB2
  • Zippy_Zolton/SRB2
  • namiishere/SRB2
  • Ors/SRB2
  • SMS_Alfredo/SRB2
  • sonic_edge/SRB2
  • lavla/SRB2
  • ashi/SRB2
  • X.organic/SRB2
  • Fafabis/SRB2
  • Meziu/SRB2
  • v-rob/SRB2
  • tertu/SRB2
  • bitten2up/SRB2
  • flarn2006/SRB2
  • Krabs/SRB2
  • clairebun/SRB2
  • Lactozilla/SRB2
  • thehackstack/SRB2
  • Spice/SRB2
  • win8linux/SRB2
  • JohnFrostFox/SRB2
  • talktoneon726/SRB2
  • Wane/SRB2
  • Lamibe/SRB2
  • spectrumuk2/srb-2
  • nerdyminer18/srb-2
  • 256nil/SRB2
  • ARJr/SRB2
  • Alam/SRB2
  • Zenya/srb-2-marathon-demos
  • Acelite/srb-2-archivedmodifications
  • MIDIMan/SRB2
  • Lach/SRB2
  • Frostiikin/bounce-tweaks
  • Jaden/SRB2
  • Tyron/SRB2
  • Astronight/SRB2
  • Mari0shi06/SRB2
  • aiire/SRB2
  • Galactice/SRB2
  • srb2-ports/srb2-dreamcast
  • sdasdas/SRB2
  • chreas/srb-2-vr
  • StarManiaKG/the-story-of-sinically-rocketing-and-botching-the-2nd
  • LoganAir/SRB2
  • NepDisk/srb-2
  • alufolie91/SRB2
  • Felicia.iso/SRB2
  • twi/SRB2
  • BarrelsOFun/SRB2
  • Speed2411/SRB2
  • Leather_Realms/SRB2
  • Ayemar/SRB2
  • Acelite/SRB2
  • VladDoc/SRB2
  • kaldrum/model-features
  • strawberryfox417/SRB2
  • Lugent/SRB2
  • Rem/SRB2
  • Refrag/SRB2
  • Henry_3230/srb-3230
  • TehPuertoRicanSpartan2/tprs-srb2
  • Leminn/srb-2-marathon-stuff
  • chromaticpipe2/SRB2
  • MiguelGustavo15/SRB2
  • Maru/srb-2-tests
  • SilicDev/SRB2
  • UnmatchedBracket/SRB2
  • HybridDog/SRB2
  • xordspar0/SRB2
  • jsjhbewfhh/SRB2
  • Fancy2209/SRB2
  • Lorsoen/SRB2
  • shindoukin/SRB2
  • GamerOfDays/SRB2
  • Craftyawesome/SRB2
  • tenshi-tensai-tennoji/SRB2
  • Scarfdudebalder/SRB2
  • luigi-budd/srb-2-fix-interplag-lockon
  • mskluesner/SRB2
  • johnpetersa19/SRB2
  • Pheazant/SRB2
  • chromaticpipe2/srb2classic
  • romoney5/SRB2
  • PAS/SRB2Classic
  • BlueStaggo/SRB2
  • Jisk/srb-2-beef-jerky
117 results
Select Git revision
  • 21-installer-nodd
  • 2210-pre1
  • 2210-pre2
  • 2210-rc1
  • 2210-rc2
  • 2210-rc3
  • 2211-pre1
  • 2211-pre2
  • 2211-rc1
  • 2212-pre1
  • 2212-pre2
  • 2212-pre3
  • 2212-rc1
  • 2213
  • 2214-pre1
  • 2214-pre2
  • 2214-pre3
  • 2214-pre4
  • 2_2_12
  • 64-gl-log
  • COM_ImmedExecute-lua
  • DJGPP
  • accel-momentum
  • acs
  • action-args
  • alpha-fixes
  • any-resolution
  • appveyor
  • blend-locking
  • blentran
  • blua-unary-not-fix
  • boost-tickrate
  • bustablesoundz
  • cleanup-opengl
  • cleanupmusic
  • clipmidtex
  • cmake-valgrind
  • crawlacommander-sprites
  • custom-map-names
  • custom-teams
  • cutscene-cleanup
  • dd-music-bypass
  • dd-music-fix
  • delfile2
  • deprecate-lua-dedicated-server
  • dpl-2
  • dropshadows-spawning
  • dynabsp
  • emblem-drawing
  • exchndl-xp-fix
  • extra-textures
  • few-kart-lua-changes
  • ffloorclip
  • fix-167
  • fix-cvar-conflicts
  • fix-opengl-parameter-crash
  • fix-opengl-shear-roll
  • flipfuncpointers
  • fof-lightlist-fixes
  • font-FUCK
  • frictionrefactor
  • fuck-macros-1
  • gamepad-luakeydown
  • gamepad-morefixes
  • gamepad_experiments
  • gametype-refactor
  • gametype-refactor-1
  • gametype-refactor-player-spawns
  • ghost-networking
  • gif-splitting
  • grr-lj
  • hitboxviewer
  • hwr-texture-cache-refactor
  • hwrender2
  • improve-439
  • increase-maxconditionsets
  • increase-packet-tics
  • input-display
  • input-display-translucency
  • io
  • joystick-juggling-maz
  • just-in-case
  • keycodes-only
  • ksf-wadfiles
  • ld413-mp-fix
  • levelstruct
  • libpng-version-support
  • linedef-actions
  • lj-test
  • lol-states
  • loopedsounds
  • lower-unpegged-fix
  • lua-change-gametype
  • lua-command-netids
  • lua-gfx-2
  • lua-gfx-sprites
  • lua-local
  • makefile-auto-mingw-gcc
  • makefile-tinkering
  • map-components-signedness-fixes
  • SRB2_release_2.1
  • SRB2_release_2.1.1
  • SRB2_release_2.1.10
  • SRB2_release_2.1.11
  • SRB2_release_2.1.12
  • SRB2_release_2.1.14
  • SRB2_release_2.1.15
  • SRB2_release_2.1.16
  • SRB2_release_2.1.16a
  • SRB2_release_2.1.17
  • SRB2_release_2.1.18
  • SRB2_release_2.1.19
  • SRB2_release_2.1.2
  • SRB2_release_2.1.20
  • SRB2_release_2.1.21
  • SRB2_release_2.1.22
  • SRB2_release_2.1.23
  • SRB2_release_2.1.24
  • SRB2_release_2.1.25
  • SRB2_release_2.1.3
  • SRB2_release_2.1.4
  • SRB2_release_2.1.5
  • SRB2_release_2.1.6
  • SRB2_release_2.1.7
  • SRB2_release_2.1.8
  • SRB2_release_2.1.9
  • SRB2_release_2.2.0
  • SRB2_release_2.2.1
  • SRB2_release_2.2.10
  • SRB2_release_2.2.11
  • SRB2_release_2.2.12
  • SRB2_release_2.2.13
  • SRB2_release_2.2.15
  • SRB2_release_2.2.2
  • SRB2_release_2.2.3
  • SRB2_release_2.2.4
  • SRB2_release_2.2.5
  • SRB2_release_2.2.6
  • SRB2_release_2.2.7
  • SRB2_release_2.2.8
  • SRB2_release_2.2.9
  • td-release-v1.0.0
142 results
Show changes
......@@ -109,6 +109,10 @@ const char * M_Ftrim (double);
// Returns true if the string is empty.
boolean M_IsStringEmpty(const char *s);
const char *M_GetFilenameFromPath(const char *path);
const char *M_GetExtensionFromFilename(const char *filename);
const char *M_CheckFilenameExtension(const char *filename, const char *ext);
// Converts a string containing a whole number into an int. Returns false if the conversion failed.
boolean M_StringToNumber(const char *input, int *out);
......@@ -121,6 +125,11 @@ FUNCMATH UINT8 M_CountBits(UINT32 num, UINT8 size);
// Rounds off floating numbers and checks for 0 - 255 bounds
int M_RoundUp(double number);
// Hashes some message using FNV-1a
UINT32 FNV1a_Hash(const char *message, size_t size);
UINT32 FNV1a_HashString(const char *message);
UINT32 FNV1a_HashLowercaseString(const char *message);
#include "w_wad.h"
extern char configfile[MAX_WADPATH];
......
......@@ -1742,7 +1742,7 @@ void D_MapChange(INT32 mapnum, INT32 newgametype, boolean pultmode, boolean rese
{
UINT8 flags = 0;
const char *mapname = G_BuildMapName(mapnum);
I_Assert(W_CheckNumForName(mapname) != LUMPERROR);
I_Assert(G_MapFileExists(mapname) == true);
buf_p = buf;
if (pultmode)
flags |= 1;
......@@ -2044,8 +2044,8 @@ static void Command_Map_f(void)
static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
{
char mapname[MAX_WADPATH+1];
UINT8 flags;
INT32 resetplayer = 1, lastgametype;
UINT8 flags, newgametype;
INT32 resetplayer = 1, lastgametype = gametype;
UINT8 skipprecutscene, FLS;
INT16 mapnumber;
......@@ -2061,6 +2061,12 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
chmappending--;
flags = READUINT8(*cp);
newgametype = READUINT8(*cp);
READSTRINGN(*cp, mapname, MAX_WADPATH);
mapnumber = G_GetMapNumber(mapname);
if (!mapnumber) // Not valid???
return;
ultimatemode = ((flags & 1) != 0);
if (netgame || multiplayer)
......@@ -2068,13 +2074,8 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
resetplayer = ((flags & (1<<1)) == 0);
lastgametype = gametype;
gametype = READUINT8(*cp);
if (gametype < 0 || gametype >= gametypecount)
gametype = lastgametype;
else
G_SetGametype(gametype);
if (newgametype < gametypecount)
G_SetGametype(newgametype);
if (gametype != lastgametype)
D_GameTypeChanged(lastgametype); // emulate consvar_t behavior for gametype
......@@ -2083,8 +2084,6 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
FLS = ((flags & (1<<3)) != 0);
READSTRINGN(*cp, mapname, MAX_WADPATH);
if (netgame)
P_SetRandSeed(READUINT32(*cp));
......@@ -2104,7 +2103,6 @@ static void Got_Mapcmd(UINT8 **cp, INT32 playernum)
players[0].skincolor = skins[players[0].skin]->prefcolor;
}
mapnumber = M_MapNumber(mapname[3], mapname[4]);
LUA_HookInt(mapnumber, HOOK(MapChange));
G_InitNew(ultimatemode, mapname, resetplayer, skipprecutscene, FLS);
......
......@@ -26,7 +26,7 @@ packet versions.
If you change the struct or the meaning of a field
therein, increment this number.
*/
#define PACKETVERSION 5
#define PACKETVERSION 6
// Network play related stuff.
// There is a data struct that stores network
......@@ -226,7 +226,7 @@ typedef struct
tic_t time;
tic_t leveltime;
char servername[MAXSERVERNAME];
char mapname[8];
char mapname[24];
char maptitle[33];
unsigned char mapmd5[16];
UINT8 actnum;
......
......@@ -121,8 +121,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
netbuffer->u.serverinfo.flags = (dedicated ? SV_DEDICATED : 0);
strncpy(netbuffer->u.serverinfo.servername, cv_servername.string,
sizeof(netbuffer->u.serverinfo.servername)-1);
strncpy(netbuffer->u.serverinfo.mapname, G_BuildMapName(gamemap), 7);
strlcpy(netbuffer->u.serverinfo.mapname, G_BuildMapName(gamemap), sizeof netbuffer->u.serverinfo.mapname);
M_Memcpy(netbuffer->u.serverinfo.mapmd5, mapmd5, 16);
memset(netbuffer->u.serverinfo.maptitle, 0, sizeof netbuffer->u.serverinfo.maptitle);
......@@ -142,7 +141,6 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
read++;
}
*writ = '\0';
//strncpy(netbuffer->u.serverinfo.maptitle, (char *)mapheaderinfo[gamemap-1]->lvlttl, 33);
}
else
strncpy(netbuffer->u.serverinfo.maptitle, "UNKNOWN", 32);
......
......@@ -3789,11 +3789,10 @@ static void P_DoBossVictory(mobj_t *mo)
// Touching the egg trap button calls P_DoPlayerExit, which calls P_RestoreMusic.
// So just park ourselves in the mapmus variables.
// But don't change the mapmus variables if they were modified from their level header values (e.g., TUNES).
boolean changed = strnicmp(mapheaderinfo[gamemap-1]->musname, S_MusicName(), 7);
if (!strnicmp(mapheaderinfo[gamemap-1]->musname, mapmusname, 7))
boolean changed = strnicmp(mapheaderinfo[gamemap-1]->musname, S_MusicName(), MAX_MUSIC_NAME);
if (!strnicmp(mapheaderinfo[gamemap-1]->musname, mapmusname, MAX_MUSIC_NAME))
{
strncpy(mapmusname, mapheaderinfo[gamemap-1]->muspostbossname, 7);
mapmusname[6] = 0;
strlcpy(mapmusname, mapheaderinfo[gamemap-1]->muspostbossname, MAX_MUSIC_NAME+1);
mapmusflags = (mapheaderinfo[gamemap-1]->muspostbosstrack & MUSIC_TRACKMASK) | MUSIC_RELOADRESET;
mapmusposition = mapheaderinfo[gamemap-1]->muspostbosspos;
}
......
......@@ -258,7 +258,7 @@ typedef enum
typedef struct
{
char musname[7];
char musname[MAX_MUSIC_NAME+1];
boolean looping;
} jingle_t;
......
......@@ -4415,24 +4415,59 @@ static void P_NetUnArchiveSpecials(void)
// =======================================================================
// Misc
// =======================================================================
static inline void P_ArchiveMisc(INT16 mapnum)
static void P_ArchiveMisc(INT16 mapnum)
{
//lastmapsaved = mapnum;
lastmaploaded = mapnum;
if (gamecomplete)
mapnum |= 8192;
#ifdef NEWMAPSAVES
if (mapnum >= NUMBASEMAPS)
{
WRITEINT16(save_p, NEWMAPSAVES);
WRITESTRINGN(save_p, G_BuildMapName(mapnum), MAX_MAP_NAME_SIZE);
UINT8 flags = 0;
if (gamecomplete)
flags |= SAVE_GAME_COMPLETE_BIT;
WRITEUINT8(save_p, flags);
}
else
#endif
{
if (gamecomplete)
mapnum |= 8192;
WRITEINT16(save_p, mapnum);
}
WRITEINT16(save_p, mapnum);
WRITEUINT16(save_p, emeralds+357);
WRITESTRINGN(save_p, timeattackfolder, sizeof(timeattackfolder));
}
static inline void P_UnArchiveSPGame(INT16 mapoverride)
static void P_UnArchiveSPGame(INT16 mapoverride)
{
char testname[sizeof(timeattackfolder)];
gamemap = READINT16(save_p);
INT16 mapnum = READINT16(save_p);
#ifdef NEWMAPSAVES
if (mapnum == NEWMAPSAVES)
{
char mapname[MAX_MAP_NAME_SIZE+1];
READSTRINGN(save_p, mapname, MAX_MAP_NAME_SIZE);
READUINT8(save_p); // flags
mapnum = G_GetMapNumber(mapname);
if (mapnum == 0)
{
// If not valid, just load MAP01 instead.
mapnum = 1;
}
}
#endif
gamemap = mapnum;
if (mapoverride != 0)
{
......@@ -4447,7 +4482,6 @@ static inline void P_UnArchiveSPGame(INT16 mapoverride)
if(!mapheaderinfo[gamemap-1])
P_AllocMapHeader(gamemap-1);
//lastmapsaved = gamemap;
lastmaploaded = gamemap;
tokenlist = 0;
......@@ -4672,7 +4706,7 @@ static inline void P_NetArchiveEmblems(void)
WRITEUINT32(save_p, data->totalplaytime);
// TODO put another cipher on these things? meh, I don't care...
for (i = 0; i < NUMMAPS; i++)
for (i = 0; i < numgamemaps; i++)
WRITEUINT8(save_p, (data->mapvisited[i] & MV_MAX));
// To save space, use one bit per collected/achieved/unlocked flag
......@@ -4714,7 +4748,7 @@ static inline void P_NetArchiveEmblems(void)
WRITEUINT32(save_p, data->timesBeatenUltimate);
// Main records
for (i = 0; i < NUMMAPS; i++)
for (i = 0; i < numgamemaps; i++)
{
if (data->mainrecords[i])
{
......@@ -4731,7 +4765,7 @@ static inline void P_NetArchiveEmblems(void)
}
// NiGHTS records
for (i = 0; i < NUMMAPS; i++)
for (i = 0; i < numgamemaps; i++)
{
if (!data->nightsrecords[i] || !data->nightsrecords[i]->nummares)
{
......@@ -4807,7 +4841,7 @@ static inline void P_NetUnArchiveEmblems(void)
data->totalplaytime = READUINT32(save_p);
// TODO put another cipher on these things? meh, I don't care...
for (i = 0; i < NUMMAPS; i++)
for (i = 0; i < numgamemaps; i++)
if ((data->mapvisited[i] = READUINT8(save_p)) > MV_MAX)
I_Error("Bad $$$.sav dearchiving Emblems (invalid visit flags)");
......@@ -4846,7 +4880,7 @@ static inline void P_NetUnArchiveEmblems(void)
data->timesBeatenUltimate = READUINT32(save_p);
// Main records
for (i = 0; i < NUMMAPS; ++i)
for (i = 0; i < numgamemaps; ++i)
{
recscore = READUINT32(save_p);
rectime = (tic_t)READUINT32(save_p);
......@@ -4865,7 +4899,7 @@ static inline void P_NetUnArchiveEmblems(void)
}
// Nights records
for (i = 0; i < NUMMAPS; ++i)
for (i = 0; i < numgamemaps; ++i)
{
if ((recmares = READUINT8(save_p)) == 0)
continue;
......
......@@ -18,7 +18,11 @@
#pragma interface
#endif
#define NEWSKINSAVES (INT16_MAX) // TODO: 2.3: Delete (Purely for backwards compatibility)
#define SAVE_GAME_COMPLETE_BIT 0x01
// TODO: 2.3: Delete both of these (purely for backwards compatibility)
#define NEWSKINSAVES (INT16_MAX)
#define NEWMAPSAVES (INT16_MAX)
// Persistent storage/archiving.
// These are the load / save game routines.
......
......@@ -363,8 +363,7 @@ static void P_ClearSingleMapHeaderInfo(INT16 i)
mapheaderinfo[num]->ssspheres = 1;
mapheaderinfo[num]->gravity = FRACUNIT/2;
mapheaderinfo[num]->keywords[0] = '\0';
snprintf(mapheaderinfo[num]->musname, 7, "%sM", G_BuildMapName(i));
mapheaderinfo[num]->musname[6] = 0;
snprintf(mapheaderinfo[num]->musname, MAX_MUSIC_NAME+1, "%s", G_GetDefaultMapMusic(i));
mapheaderinfo[num]->mustrack = 0;
mapheaderinfo[num]->muspos = 0;
mapheaderinfo[num]->musinterfadeout = 0;
......@@ -766,69 +765,6 @@ void P_SwitchSpheresBonusMode(boolean bonustime)
}
}
#ifdef SCANTHINGS
void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum)
{
size_t i, n;
UINT8 *data, *datastart;
UINT16 type, maprings;
INT16 tol;
UINT32 flags;
tol = mapheaderinfo[mapnum-1]->typeoflevel;
if (!(tol & TOL_SP))
return;
flags = mapheaderinfo[mapnum-1]->levelflags;
n = W_LumpLengthPwad(wadnum, lumpnum) / (5 * sizeof (INT16));
//CONS_Printf("%u map things found!\n", n);
maprings = 0;
data = datastart = W_CacheLumpNumPwad(wadnum, lumpnum, PU_STATIC);
for (i = 0; i < n; i++)
{
data += 3 * sizeof (INT16); // skip x y position, angle
type = READUINT16(data) & 4095;
data += sizeof (INT16); // skip options
switch (type)
{
case 300: // MT_RING
case 1800: // MT_COIN
case 308: // red team ring
case 309: // blue team ring
maprings++;
break;
case 400: // MT_SUPERRINGBOX
case 414: // red ring box
case 415: // blue ring box
case 603: // 10 diagonal rings
maprings += 10;
break;
case 600: // 5 vertical rings
case 601: // 5 vertical rings
case 602: // 5 diagonal rings
maprings += 5;
break;
case 604: // 8 circle rings
case 609: // 16 circle rings & wings
maprings += 8;
break;
case 605: // 16 circle rings
maprings += 16;
break;
case 608: // 8 circle rings & wings
maprings += 4;
break;
}
}
Z_Free(datastart);
if (maprings)
CONS_Printf("%s has %u rings\n", G_BuildMapName(mapnum), maprings);
}
#endif
static void P_SpawnEmeraldHunt(void)
{
INT32 emer[3], num[MAXHUNTEMERALDS], i, amount, randomkey;
......@@ -7104,9 +7040,9 @@ static void P_MakeMapMD5(virtres_t *virt, void *dest)
M_Memcpy(dest, &resmd5, 16);
}
static boolean P_LoadMapFromFile(void)
static boolean P_LoadMapFromFile(lumpnum_t lumpnum)
{
virtres_t *virt = vres_GetMap(lastloadedmaplumpnum);
virtres_t *virt = vres_GetMap(lumpnum);
virtlump_t *textmap = vres_Find(virt, "TEXTMAP");
size_t i;
udmf = textmap != NULL;
......@@ -7172,9 +7108,6 @@ void P_SetupLevelSky(INT32 skynum, boolean global)
R_SetupSkyDraw();
}
static const char *maplumpname;
lumpnum_t lastloadedmaplumpnum; // for comparative savegame
//
// P_LevelInitStuff
//
......@@ -7385,14 +7318,15 @@ static void P_ResetSpawnpoints(void)
static void P_LoadRecordGhosts(void)
{
const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1;
const char *mapname = G_BuildMapName(gamemap);
const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen(mapname)+1;
char *gpath = malloc(glen);
INT32 i;
if (!gpath)
return;
sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap));
sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, mapname);
// Best Score ghost
if (cv_ghost_bestscore.value)
......@@ -7455,14 +7389,15 @@ static void P_LoadRecordGhosts(void)
static void P_LoadNightsGhosts(void)
{
const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen("MAPXX")+1;
const char *mapname = G_BuildMapName(gamemap);
const size_t glen = strlen(srb2home)+1+strlen("replay")+1+strlen(timeattackfolder)+1+strlen(mapname)+1;
char *gpath = malloc(glen);
INT32 i;
if (!gpath)
return;
sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, G_BuildMapName(gamemap));
sprintf(gpath,"%s"PATHSEP"replay"PATHSEP"%s"PATHSEP"%s", srb2home, timeattackfolder, mapname);
// Best Score ghost
if (cv_ghost_bestscore.value)
......@@ -7636,7 +7571,7 @@ static void P_RunSpecialStageWipe(void)
// Fade music! Time it to S3KAF: 0.25 seconds is snappy.
if (RESETMUSIC ||
strnicmp(S_MusicName(),
(mapmusflags & MUSIC_RELOADRESET) ? mapheaderinfo[gamemap - 1]->musname : mapmusname, 7))
(mapmusflags & MUSIC_RELOADRESET) ? mapheaderinfo[gamemap - 1]->musname : mapmusname, MAX_MUSIC_NAME))
S_FadeOutStopMusic(MUSICRATE/4); //FixedMul(FixedDiv(F_GetWipeLength(wipedefs[wipe_speclevel_towhite])*NEWTICRATERATIO, NEWTICRATE), MUSICRATE)
F_WipeStartScreen();
......@@ -7809,7 +7744,9 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
// 99% of the things already did, so.
// Map header should always be in place at this point
INT32 i, ranspecialwipe = 0;
sector_t *ss;
lumpnum_t maplumpnum;
const char *maplumpname;
levelloading = true;
// This is needed. Don't touch.
......@@ -7904,7 +7841,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
// But don't halt the music! S_Start will take care of that. This dodges a MIDI crash bug.
if (!(reloadinggamestate || titlemapinaction) && (RESETMUSIC ||
strnicmp(S_MusicName(),
(mapmusflags & MUSIC_RELOADRESET) ? mapheaderinfo[gamemap-1]->musname : mapmusname, 7)))
(mapmusflags & MUSIC_RELOADRESET) ? mapheaderinfo[gamemap-1]->musname : mapmusname, MAX_MUSIC_NAME)))
{
S_FadeMusic(0, FixedMul(
FixedDiv((F_GetWipeLength(wipedefs[wipe_level_toblack])-2)*NEWTICRATERATIO, NEWTICRATE), MUSICRATE));
......@@ -7950,7 +7887,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
LUA_InvalidateLevel();
for (ss = sectors; sectors+numsectors != ss; ss++)
for (sector_t *ss = sectors; sectors+numsectors != ss; ss++)
{
Z_Free(ss->attached);
Z_Free(ss->attachedsolid);
......@@ -7981,9 +7918,9 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
// internal game map
maplumpname = G_BuildMapName(gamemap);
lastloadedmaplumpnum = W_CheckNumForMap(maplumpname);
if (lastloadedmaplumpnum == LUMPERROR)
I_Error("Map %s not found.\n", maplumpname);
maplumpnum = G_GetMapLumpnum(maplumpname);
if (maplumpnum == LUMPERROR)
I_Error("Map %s not found\n", maplumpname);
R_ReInitColormaps(mapheaderinfo[gamemap-1]->palette);
CON_SetupBackColormap();
......@@ -7999,7 +7936,7 @@ boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate)
P_InitSlopes();
if (!P_LoadMapFromFile())
if (!P_LoadMapFromFile(maplumpnum))
return false;
if (!demoplayback)
......@@ -8225,6 +8162,142 @@ static lumpinfo_t* FindFolder(const char *folName, UINT16 *start, UINT16 *end, l
return lumpinfo;
}
static int P_AddMap(const char *name, UINT32 lumpnum)
{
// Check filename length
size_t name_len = strlen(name);
if (name_len > MAX_MAP_NAME_SIZE)
{
CONS_Alert(CONS_WARNING, "Map name's length of %s exceeds maximum of %d -- skipping\n", sizeu1(name_len), MAX_MAP_NAME_SIZE);
return 0;
}
if (!G_IsValidMapName(name))
{
CONS_Alert(CONS_WARNING, "Map name %s is invalid -- skipping\n", name);
return 0;
}
INT16 num = G_AddMap(name, lumpnum);
if (num == 0)
{
CONS_Alert(CONS_ERROR, "Too many maps loaded!\n");
return -1;
}
//If you replaced the map you're on, end the level when done.
if (gamestate == GS_LEVEL && num == gamemap)
replacedcurrentmap = true;
return 1;
}
void P_LoadMapsFromFile(UINT16 wadnum, boolean added_ingame)
{
boolean mapsadded = false;
lumpinfo_t *lumpinfo = NULL;
UINT16 numlumps = 0;
const char *name;
if (W_FileHasFolders(wadfiles[wadnum]))
{
UINT32 *list = NULL;
UINT16 capacity = 0;
W_GetFolderLumpsPwad("Maps/", wadnum, &list, &capacity, &numlumps);
for (UINT16 i = 0; i < numlumps; i++)
{
UINT32 lumpnum = list[i];
lumpinfo = wadfiles[wadnum]->lumpinfo + LUMPNUM(lumpnum);
name = W_GetFilenameFromFullname(lumpinfo->fullname); // Full lump name, with its extension
// Extension must be .wad
if (!M_CheckFilenameExtension(name, "wad"))
continue;
// Get the name without the extension
name = lumpinfo->longname;
int status = P_AddMap(name, lumpnum);
if (status == 1)
{
if (added_ingame)
CONS_Printf("%s\n", name);
mapsadded = true;
}
else if (status < 0)
break;
}
Z_Free(list);
}
else
{
lumpinfo = wadfiles[wadnum]->lumpinfo;
numlumps = wadfiles[wadnum]->numlumps;
for (size_t i = 0; i < numlumps; i++, lumpinfo++)
{
name = lumpinfo->name;
if (name[0] == 'M' && name[1] == 'A' && name[2] == 'P' && name[5] == '\0')
{
int status = P_AddMap(name, (wadnum << 16) + i);
if (status == 1)
{
if (added_ingame)
CONS_Printf("%s\n", name);
mapsadded = true;
}
else if (status < 0)
break;
}
}
// Now do markers
UINT16 start = W_CheckNumForMarkerStartPwad("LV_START", wadnum, 0);
UINT16 end = W_CheckNumForNamePwad("LV_END", wadnum, start);
lumpinfo = wadfiles[wadnum]->lumpinfo + start;
for (UINT16 l = start; l < end; l++, lumpinfo++)
{
name = lumpinfo->name;
// Ignore any of these lump names
if (stricmp(name, "THINGS") == 0
|| stricmp(name, "LINEDEFS") == 0
|| stricmp(name, "SIDEDEFS") == 0
|| stricmp(name, "VERTEXES") == 0
|| stricmp(name, "SEGS") == 0
|| stricmp(name, "SSECTORS") == 0
|| stricmp(name, "NODES") == 0
|| stricmp(name, "SECTORS") == 0
|| stricmp(name, "REJECT") == 0
|| stricmp(name, "BLOCKMAP") == 0
|| stricmp(name, "BEHAVIOR") == 0)
continue;
int status = P_AddMap(name, (wadnum << 16) + l);
if (status == 1)
{
if (added_ingame)
CONS_Printf("%s\n", name);
mapsadded = true;
}
else if (status < 0)
break;
}
}
if (!mapsadded && added_ingame)
CONS_Printf(M_GetText("No maps added\n"));
}
//
// Add a wadfile to the active wad files,
// replace sounds, musics, patches, textures, sprites and maps
......@@ -8238,8 +8311,6 @@ static boolean P_LoadAddon(UINT16 numlumps)
lumpinfo_t *lumpinfo;
//boolean texturechange = false; ///\todo Useless; broken when back-frontporting PK3 changes?
boolean mapsadded = false;
boolean replacedcurrentmap = false;
// Vars to help us with the position start and amount of each resource type.
// Useful for PK3s since they use folders.
......@@ -8381,32 +8452,7 @@ static boolean P_LoadAddon(UINT16 numlumps)
//
S_LoadMusicDefs(wadnum);
//
// search for maps
//
lumpinfo = wadfiles[wadnum]->lumpinfo;
for (i = 0; i < numlumps; i++, lumpinfo++)
{
name = lumpinfo->name;
if (name[0] == 'M' && name[1] == 'A' && name[2] == 'P') // Ignore the headers
{
INT16 num;
if (name[5]!='\0')
continue;
num = (INT16)M_MapNumber(name[3], name[4]);
//If you replaced the map you're on, end the level when done.
if (num == gamemap)
replacedcurrentmap = true;
CONS_Printf("%s\n", name);
mapsadded = true;
}
}
if (!mapsadded)
CONS_Printf(M_GetText("No maps added\n"));
R_LoadSpriteInfoLumps(wadnum, numlumps);
R_LoadSpriteInfoLumps(wadnum);
#ifdef HWRENDER
HWR_ReloadModels();
......@@ -8420,11 +8466,16 @@ static boolean P_LoadAddon(UINT16 numlumps)
if (modifiedgame && (cursaveslot > 0))
cursaveslot = 0;
if (replacedcurrentmap && gamestate == GS_LEVEL && (netgame || multiplayer))
if (replacedcurrentmap)
{
CONS_Printf(M_GetText("Current map %d replaced by added file, ending the level to ensure consistency.\n"), gamemap);
if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
replacedcurrentmap = false;
if (gamestate == GS_LEVEL && (netgame || multiplayer))
{
CONS_Printf(M_GetText("Current map %s replaced by added file, ending the level to ensure consistency.\n"), G_BuildMapName(gamemap));
if (server)
SendNetXCmd(XD_EXITLEVEL, NULL, 0);
}
}
return true;
......
......@@ -58,9 +58,6 @@ extern size_t nummapthings;
extern mapthing_t *mapthings;
void P_SetupLevelSky(INT32 skynum, boolean global);
#ifdef SCANTHINGS
void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum);
#endif
void P_RespawnThings(void);
boolean P_LoadLevel(boolean fromnetsave, boolean reloadinggamestate);
#ifdef HWRENDER
......@@ -71,6 +68,7 @@ boolean P_AddFolder(const char *folderpath);
boolean P_RunSOC(const char *socfilename);
void P_LoadSoundsRange(UINT16 wadnum, UINT16 first, UINT16 num);
void P_LoadMusicsRange(UINT16 wadnum, UINT16 first, UINT16 num);
void P_LoadMapsFromFile(UINT16 wadnum, boolean added_ingame);
void P_WriteThings(const char *filepath);
size_t P_PrecacheLevelFlats(void);
void P_AllocMapHeader(INT16 i);
......
......@@ -2457,7 +2457,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
// console player only unless TMM_ALLPLAYERS is set
if ((line->args[0] & TMM_ALLPLAYERS) || (mo && mo->player && P_IsLocalPlayer(mo->player)) || titlemapinaction)
{
boolean musicsame = (!line->stringargs[0] || !line->stringargs[0][0] || !strnicmp(line->stringargs[0], S_MusicName(), 7));
boolean musicsame = (!line->stringargs[0] || !line->stringargs[0][0] || !strnicmp(line->stringargs[0], S_MusicName(), MAX_MUSIC_NAME));
UINT16 tracknum = (UINT16)max(line->args[6], 0);
INT32 position = (INT32)max(line->args[1], 0);
UINT32 prefadems = (UINT32)max(line->args[2], 0);
......@@ -2500,8 +2500,7 @@ static void P_ProcessLineSpecial(line_t *line, mobj_t *mo, sector_t *callsec)
strcpy(mapmusname, "");
else
{
strncpy(mapmusname, line->stringargs[0], 7);
mapmusname[6] = 0;
strlcpy(mapmusname, line->stringargs[0], MAX_MUSIC_NAME+1);
}
mapmusflags = tracknum & MUSIC_TRACKMASK;
......
......@@ -1591,13 +1591,8 @@ void P_PlayJingle(player_t *player, jingletype_t jingletype)
UINT16 musflags = 0;
boolean looping = jingleinfo[jingletype].looping;
char newmusic[7];
strncpy(newmusic, musname, 7);
#ifdef HAVE_LUA_MUSICPLUS
if(LUAh_MusicJingle(jingletype, newmusic, &musflags, &looping))
return;
#endif
newmusic[6] = 0;
char newmusic[MAX_MUSIC_NAME];
strlcpy(newmusic, musname, MAX_MUSIC_NAME);
P_PlayJingleMusic(player, newmusic, musflags, looping, jingletype);
}
......
......@@ -1753,13 +1753,13 @@ void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum)
//
// Load and read every SPRTINFO lump from the specified file.
//
void R_LoadSpriteInfoLumps(UINT16 wadnum, UINT16 numlumps)
void R_LoadSpriteInfoLumps(UINT16 wadnum)
{
lumpinfo_t *lumpinfo = wadfiles[wadnum]->lumpinfo;
UINT16 i;
char *name;
for (i = 0; i < numlumps; i++, lumpinfo++)
for (i = 0; i < wadfiles[wadnum]->numlumps; i++, lumpinfo++)
{
name = lumpinfo->name;
// Load SPRTINFO and SPR_ lumps as SpriteInfo
......
......@@ -123,7 +123,7 @@ boolean Picture_PNGDimensions(UINT8 *png, INT32 *width, INT32 *height, INT16 *to
// SpriteInfo
extern spriteinfo_t spriteinfo[NUMSPRITES];
void R_LoadSpriteInfoLumps(UINT16 wadnum, UINT16 numlumps);
void R_LoadSpriteInfoLumps(UINT16 wadnum);
void R_ParseSPRTINFOLump(UINT16 wadNum, UINT16 lumpNum);
#endif // __R_PICFORMATS__
......@@ -774,7 +774,7 @@ void R_InitSprites(void)
{
R_AddSkins((UINT16)i, true);
R_PatchSkins((UINT16)i, true);
R_LoadSpriteInfoLumps(i, wadfiles[i]->numlumps);
R_LoadSpriteInfoLumps(i);
}
ST_ReloadSkinFaceGraphics();
......
......@@ -1352,12 +1352,12 @@ void S_InitSfxChannels(INT32 sfxVolume)
/// Music
/// ------------------------
static char music_name[7]; // up to 6-character name
static char music_name[MAX_MUSIC_NAME+1];
static void *music_data;
static UINT16 music_flags;
static boolean music_looping;
static char queue_name[7];
static char queue_name[MAX_MUSIC_NAME+1];
static UINT16 queue_flags;
static boolean queue_looping;
static UINT32 queue_position;
......@@ -1568,9 +1568,8 @@ ReadMusicDefFields (UINT16 wadnum, int line, boolean fields, char *stoken,
} else if (!stricmp(stoken, "soundtestpage")) {
def->soundtestpage = (UINT8)i;
} else if (!stricmp(stoken, "soundtestcond")) {
// Convert to map number
if (textline[0] >= 'A' && textline[0] <= 'Z' && textline[2] == '\0')
i = M_MapNumber(textline[0], textline[1]);
if (!i)
i = G_GetMapNumber(textline);
def->soundtestcond = (INT16)i;
} else if (!stricmp(stoken, "stoppingtime")) {
double stoppingtime = atof(textline)*TICRATE;
......@@ -1778,8 +1777,8 @@ const char *S_MusicName(void)
boolean S_MusicExists(const char *mname, boolean checkMIDI, boolean checkDigi)
{
return (
(checkDigi ? W_CheckNumForName(va("O_%s", mname)) != LUMPERROR : false)
|| (checkMIDI ? W_CheckNumForName(va("D_%s", mname)) != LUMPERROR : false)
(checkDigi ? W_CheckNumForLongName(va("O_%s", mname)) != LUMPERROR : false)
|| (checkMIDI ? W_CheckNumForLongName(va("D_%s", mname)) != LUMPERROR : false)
);
}
......@@ -1826,7 +1825,7 @@ UINT32 S_GetMusicPosition(void)
/// In this section: mazmazz doesn't know how to do dynamic arrays or struct pointers!
/// ------------------------
char music_stack_nextmusname[7];
char music_stack_nextmusname[MAX_MUSIC_NAME+1];
boolean music_stack_noposition = false;
UINT32 music_stack_fadeout = 0;
UINT32 music_stack_fadein = 0;
......@@ -1910,7 +1909,7 @@ static void S_AddMusicStackEntry(const char *mname, UINT16 mflags, boolean loopi
if (!music_stacks)
{
music_stacks = Z_Calloc(sizeof (*mst), PU_MUSIC, NULL);
strncpy(music_stacks->musname, (status == JT_MASTER ? mname : (S_CheckQueue() ? queue_name : mapmusname)), sizeof(music_stacks->musname)-1);
strlcpy(music_stacks->musname, (status == JT_MASTER ? mname : (S_CheckQueue() ? queue_name : mapmusname)), sizeof(music_stacks->musname));
music_stacks->musflags = (status == JT_MASTER ? mflags : (S_CheckQueue() ? queue_flags : mapmusflags));
music_stacks->looping = (status == JT_MASTER ? looping : (S_CheckQueue() ? queue_looping : true));
music_stacks->position = (status == JT_MASTER ? position : (S_CheckQueue() ? queue_position : S_GetMusicPosition()));
......@@ -1928,8 +1927,7 @@ static void S_AddMusicStackEntry(const char *mname, UINT16 mflags, boolean loopi
// create our new entry
new_mst = Z_Calloc(sizeof (*new_mst), PU_MUSIC, NULL);
strncpy(new_mst->musname, mname, 7);
new_mst->musname[6] = 0;
strlcpy(new_mst->musname, mname, sizeof(new_mst->musname));
new_mst->musflags = mflags;
new_mst->looping = looping;
new_mst->position = position;
......@@ -2033,13 +2031,13 @@ boolean S_RecallMusic(UINT16 status, boolean fromfirst)
if (result)
{
*entry = *result;
memcpy(entry->musname, result->musname, sizeof(entry->musname));
strlcpy(entry->musname, result->musname, sizeof(entry->musname));
}
// no result, just grab mapmusname
if (!result || !entry->musname[0] || ((status == JT_MASTER || (music_stacks ? !music_stacks->status : false)) && !entry->status))
{
strncpy(entry->musname, mapmusname, 7);
strlcpy(entry->musname, mapmusname, MAX_MUSIC_NAME+1);
entry->musflags = mapmusflags;
entry->looping = true;
entry->position = mapmusposition;
......@@ -2051,10 +2049,10 @@ boolean S_RecallMusic(UINT16 status, boolean fromfirst)
if (entry->status == JT_MASTER)
{
mapmuschanged = strnicmp(entry->musname, mapmusname, 7);
mapmuschanged = strnicmp(entry->musname, mapmusname, MAX_MUSIC_NAME);
if (mapmuschanged)
{
strncpy(entry->musname, mapmusname, 7);
strlcpy(entry->musname, mapmusname, MAX_MUSIC_NAME+1);
entry->musflags = mapmusflags;
entry->looping = true;
entry->position = mapmusposition;
......@@ -2071,7 +2069,7 @@ boolean S_RecallMusic(UINT16 status, boolean fromfirst)
return false;
}
if (strncmp(entry->musname, S_MusicName(), 7) || // don't restart music if we're already playing it
if (strncmp(entry->musname, S_MusicName(), MAX_MUSIC_NAME) || // don't restart music if we're already playing it
(midipref != currentmidi && S_PrefAvailable(midipref, entry->musname))) // but do if the user's preference has changed
{
if (music_stack_fadeout)
......@@ -2122,9 +2120,9 @@ static lumpnum_t S_GetMusicLumpNum(const char *mname)
boolean midipref = cv_musicpref.value;
if (S_PrefAvailable(midipref, mname))
return W_GetNumForName(va(midipref ? "d_%s":"o_%s", mname));
return W_GetNumForLongName(va(midipref ? "D_%s":"O_%s", mname));
else if (S_PrefAvailable(!midipref, mname))
return W_GetNumForName(va(midipref ? "o_%s":"d_%s", mname));
return W_GetNumForLongName(va(midipref ? "O_%s":"D_%s", mname));
else
return LUMPERROR;
}
......@@ -2141,18 +2139,16 @@ static boolean S_LoadMusic(const char *mname)
if (mlumpnum == LUMPERROR)
{
CONS_Alert(CONS_ERROR, "Music %.6s could not be loaded: lump not found!\n", mname);
CONS_Alert(CONS_ERROR, "Music %s could not be loaded: lump not found!\n", mname);
return false;
}
// load & register it
mdata = W_CacheLumpNum(mlumpnum, PU_MUSIC);
if (I_LoadSong(mdata, W_LumpLength(mlumpnum)))
{
strncpy(music_name, mname, 7);
music_name[6] = 0;
strlcpy(music_name, mname, MAX_MUSIC_NAME+1);
music_data = mdata;
return true;
}
......@@ -2213,7 +2209,7 @@ static boolean S_PlayMusic(boolean looping, UINT32 fadeinms)
static void S_QueueMusic(const char *mmusic, UINT16 mflags, boolean looping, UINT32 position, UINT32 fadeinms)
{
strncpy(queue_name, mmusic, 7);
strlcpy(queue_name, mmusic, MAX_MUSIC_NAME+1);
queue_flags = mflags;
queue_looping = looping;
queue_position = position;
......@@ -2238,7 +2234,7 @@ static void S_ChangeMusicToQueue(void)
void S_ChangeMusicEx(const char *mmusic, UINT16 mflags, boolean looping, UINT32 position, UINT32 prefadems, UINT32 fadeinms)
{
char newmusic[7];
char newmusic[MAX_MUSIC_NAME+1];
struct MusicChange hook_param = {
newmusic,
......@@ -2255,8 +2251,7 @@ void S_ChangeMusicEx(const char *mmusic, UINT16 mflags, boolean looping, UINT32
if (S_MusicDisabled())
return;
strncpy(newmusic, mmusic, sizeof(newmusic)-1);
newmusic[6] = 0;
strlcpy(newmusic, mmusic, sizeof(newmusic));
if (LUA_HookMusicChange(music_name, &hook_param))
return;
......@@ -2278,7 +2273,7 @@ void S_ChangeMusicEx(const char *mmusic, UINT16 mflags, boolean looping, UINT32
I_FadeSong(0, prefadems, S_ChangeMusicToQueue);
return;
}
else if (strnicmp(music_name, newmusic, 6) || (mflags & MUSIC_FORCERESET) ||
else if (strnicmp(music_name, newmusic, MAX_MUSIC_NAME) || (mflags & MUSIC_FORCERESET) ||
(midipref != currentmidi && S_PrefAvailable(midipref, newmusic)))
{
CONS_Debug(DBG_DETAILED, "Now playing song %s\n", newmusic);
......@@ -2303,7 +2298,7 @@ void S_ChangeMusicEx(const char *mmusic, UINT16 mflags, boolean looping, UINT32
{
I_SetSongPosition(position);
I_FadeSong(100, fadeinms, NULL);
}
}
else // reset volume to 100 with same music
{
I_StopFadingSong();
......@@ -2433,8 +2428,7 @@ void S_StartEx(boolean reset)
{
if (mapmusflags & MUSIC_RELOADRESET)
{
strncpy(mapmusname, mapheaderinfo[gamemap-1]->musname, 7);
mapmusname[6] = 0;
strlcpy(mapmusname, mapheaderinfo[gamemap-1]->musname, MAX_MUSIC_NAME+1);
mapmusflags = (mapheaderinfo[gamemap-1]->mustrack & MUSIC_TRACKMASK);
mapmusposition = mapheaderinfo[gamemap-1]->muspos;
}
......@@ -2487,14 +2481,13 @@ static void Command_Tunes_f(void)
track = mapheaderinfo[gamemap-1]->mustrack;
}
if (strlen(tunearg) > 6) // This is automatic -- just show the error just in case
CONS_Alert(CONS_NOTICE, M_GetText("Music name too long - truncated to six characters.\n"));
if (strlen(tunearg) > MAX_MUSIC_NAME) // This is automatic -- just show the error just in case
CONS_Alert(CONS_NOTICE, M_GetText("Music name too long - truncated to %d characters.\n"), MAX_MUSIC_NAME);
if (argc > 2)
track = (UINT16)atoi(COM_Argv(2))-1;
strncpy(mapmusname, tunearg, 7);
mapmusname[6] = 0;
strlcpy(mapmusname, tunearg, sizeof(mapmusname));
if (argc > 4)
position = (UINT32)atoi(COM_Argv(4));
......
......@@ -182,7 +182,7 @@ boolean S_SpeedMusic(float speed);
// Music definitions
typedef struct musicdef_s
{
char name[7];
char name[MAX_MUSIC_NAME+1];
char title[32];
char alttitle[64];
char authors[256];
......@@ -238,7 +238,7 @@ UINT32 S_GetMusicPosition(void);
typedef struct musicstack_s
{
char musname[7+1];
char musname[MAX_MUSIC_NAME+1];
UINT16 musflags;
boolean looping;
UINT32 position;
......@@ -251,7 +251,7 @@ typedef struct musicstack_s
struct musicstack_s *next;
} musicstack_t;
extern char music_stack_nextmusname[7];
extern char music_stack_nextmusname[MAX_MUSIC_NAME+1];
extern boolean music_stack_noposition;
extern UINT32 music_stack_fadeout;
extern UINT32 music_stack_fadein;
......
......@@ -65,9 +65,6 @@
#include "i_video.h" // rendermode
#include "md5.h"
#include "lua_script.h"
#ifdef SCANTHINGS
#include "p_setup.h" // P_ScanThings
#endif
#include "m_misc.h" // M_MapNumber
#include "g_game.h" // G_SetGameModified
......@@ -280,22 +277,6 @@ static void W_LoadDehackedLumps(UINT16 wadnum, boolean mainfile)
DEH_LoadDehackedLumpPwad(wadnum, lump, mainfile);
}
}
#ifdef SCANTHINGS
// Scan maps for emblems 'n shit
{
lumpinfo_t *lump_p = wadfiles[wadnum]->lumpinfo;
for (lump = 0; lump < wadfiles[wadnum]->numlumps; lump++, lump_p++)
{
const char *name = lump_p->name;
if (name[0] == 'M' && name[1] == 'A' && name[2] == 'P' && name[5]=='\0')
{
INT16 mapnum = (INT16)M_MapNumber(name[3], name[4]);
P_ScanThings(mapnum, wadnum, lump + ML_THINGS);
}
}
}
#endif
}
/** Compute MD5 message digest for bytes read from STREAM of this filname.
......@@ -339,6 +320,11 @@ static void W_InvalidateLumpnumCache(void)
memset(lumpnumcache, 0, sizeof (lumpnumcache));
}
UINT32 W_HashLumpName(const char *name)
{
return FNV1a_HashLowercaseString(name);
}
/** Detect a file type.
* \todo Actually detect the wad/pkzip headers and whatnot, instead of just checking the extensions.
*/
......@@ -363,18 +349,23 @@ static lumpinfo_t* ResGetLumpsStandalone (FILE* handle, UINT16* numlumps, const
fseek(handle, 0, SEEK_END);
lumpinfo->size = ftell(handle);
fseek(handle, 0, SEEK_SET);
strcpy(lumpinfo->name, lumpname);
lumpinfo->hash = quickncasehash(lumpname, 8);
strlcpy(lumpinfo->name, lumpname, sizeof(lumpinfo->name));
lumpinfo->namelength = strlen(lumpinfo->name);
lumpinfo->hash.name = W_HashLumpName(lumpname);
// Allocate the lump's long name.
lumpinfo->longname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
lumpinfo->longname = Z_Malloc((lumpinfo->namelength + 1) * sizeof(char), PU_STATIC, NULL);
strcpy(lumpinfo->longname, lumpname);
lumpinfo->longname[8] = '\0';
lumpinfo->longname[lumpinfo->namelength] = '\0';
lumpinfo->longnamelength = lumpinfo->namelength;
lumpinfo->hash.longname = lumpinfo->hash.name;
// Allocate the lump's full name.
lumpinfo->fullname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
lumpinfo->fullname = Z_Malloc((lumpinfo->namelength + 1) * sizeof(char), PU_STATIC, NULL);
strcpy(lumpinfo->fullname, lumpname);
lumpinfo->fullname[8] = '\0';
lumpinfo->fullname[lumpinfo->namelength] = '\0';
lumpinfo->fullnamelength = lumpinfo->namelength;
lumpinfo->hash.fullname = lumpinfo->hash.name;
*numlumps = 1;
return lumpinfo;
......@@ -463,17 +454,22 @@ static lumpinfo_t* ResGetLumpsWad (FILE* handle, UINT16* nlmp, const char* filen
lump_p->compression = CM_NOCOMPRESSION;
memset(lump_p->name, 0x00, 9);
strncpy(lump_p->name, fileinfo->name, 8);
lump_p->hash = quickncasehash(lump_p->name, 8);
lump_p->namelength = strlen(lump_p->name);
lump_p->hash.name = W_HashLumpName(lump_p->name);
// Allocate the lump's long name.
lump_p->longname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
strncpy(lump_p->longname, fileinfo->name, 8);
lump_p->longname[8] = '\0';
lump_p->longnamelength = lump_p->namelength;
lump_p->hash.longname = lump_p->hash.name;
// Allocate the lump's full name.
lump_p->fullname = Z_Malloc(9 * sizeof(char), PU_STATIC, NULL);
strncpy(lump_p->fullname, fileinfo->name, 8);
lump_p->fullname[8] = '\0';
lump_p->fullnamelength = lump_p->namelength;
lump_p->hash.fullname = lump_p->hash.name;
}
free(fileinfov);
*nlmp = numlumps;
......@@ -639,13 +635,18 @@ static lumpinfo_t* ResGetLumpsZip (FILE* handle, UINT16* nlmp)
memset(lump_p->name, '\0', 9); // Making sure they're initialized to 0. Is it necessary?
strncpy(lump_p->name, trimname, min(8, dotpos - trimname));
lump_p->hash = quickncasehash(lump_p->name, 8);
lump_p->namelength = strlen(lump_p->name);
lump_p->hash.name = W_HashLumpName(lump_p->name);
lump_p->longname = Z_Calloc(dotpos - trimname + 1, PU_STATIC, NULL);
strlcpy(lump_p->longname, trimname, dotpos - trimname + 1);
lump_p->longnamelength = strlen(lump_p->longname);
lump_p->hash.longname = W_HashLumpName(lump_p->longname);
lump_p->fullname = Z_Calloc(zentry.namelen + 1, PU_STATIC, NULL);
strncpy(lump_p->fullname, fullname, zentry.namelen);
lump_p->fullnamelength = zentry.namelen;
lump_p->hash.fullname = W_HashLumpName(lump_p->fullname);
switch(zentry.compression)
{
......@@ -988,6 +989,9 @@ UINT16 W_InitFile(const char *filename, boolean mainfile, boolean startup)
// Read shaders from file
W_ReadFileShaders(wadfile);
// Load maps from file
P_LoadMapsFromFile(numwadfiles - 1, !startup);
// The below hack makes me load this here.
W_LoadTrnslateLumps(numwadfiles - 1);
......@@ -1169,6 +1173,7 @@ UINT16 W_InitFolder(const char *path, boolean mainfile, boolean startup)
numwadfiles++;
W_ReadFileShaders(wadfile);
P_LoadMapsFromFile(numwadfiles - 1, !startup);
W_LoadTrnslateLumps(numwadfiles - 1);
W_LoadDehackedLumpsPK3(numwadfiles - 1, mainfile);
W_InvalidateLumpnumCache();
......@@ -1246,13 +1251,15 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
UINT16 i;
static char uname[8 + 1];
UINT32 hash;
size_t namelen;
if (!TestValidLump(wad,0))
return INT16_MAX;
strlcpy(uname, name, sizeof uname);
strupr(uname);
hash = quickncasehash(uname, 8);
namelen = strlen(uname);
hash = W_HashLumpName(uname);
//
// scan forward
......@@ -1263,7 +1270,9 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
{
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
if (lump_p->hash == hash && !strncmp(lump_p->name, uname, sizeof(uname) - 1))
if (lump_p->namelength == namelen
&& lump_p->hash.name == hash
&& !strncmp(lump_p->name, uname, sizeof(uname) - 1))
return i;
}
......@@ -1280,13 +1289,12 @@ UINT16 W_CheckNumForNamePwad(const char *name, UINT16 wad, UINT16 startlump)
UINT16 W_CheckNumForLongNamePwad(const char *name, UINT16 wad, UINT16 startlump)
{
UINT16 i;
static char uname[256 + 1];
if (!TestValidLump(wad,0))
return INT16_MAX;
strlcpy(uname, name, sizeof uname);
strupr(uname);
size_t namelen = strlen(name);
UINT32 hash = W_HashLumpName(name);
//
// scan forward
......@@ -1297,7 +1305,9 @@ UINT16 W_CheckNumForLongNamePwad(const char *name, UINT16 wad, UINT16 startlump)
{
lumpinfo_t *lump_p = wadfiles[wad]->lumpinfo + startlump;
for (i = startlump; i < wadfiles[wad]->numlumps; i++, lump_p++)
if (!strcmp(lump_p->longname, uname))
if (lump_p->longnamelength == namelen
&& lump_p->hash.name == hash
&& !stricmp(lump_p->longname, name))
return i;
}
......@@ -1350,6 +1360,14 @@ UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump)
return i;
}
const char *W_GetFilenameFromFullname(const char *path)
{
const char *slash = strrchr(path, '/');
if (slash)
return slash + 1;
return path;
}
char *W_GetLumpFolderPathPK3(UINT16 wad, UINT16 lump)
{
const char *fullname = wadfiles[wad]->lumpinfo[lump].fullname;
......@@ -1609,49 +1627,6 @@ lumpnum_t W_CheckNumForLongName(const char *name)
}
}
// Look for valid map data through all added files in descendant order.
// Get a map marker for WADs, and a standalone WAD file lump inside PK3s.
// TODO: Make it search through cache first, maybe...?
lumpnum_t W_CheckNumForMap(const char *name)
{
UINT32 hash = quickncasehash(name, 8);
UINT16 lumpNum, end;
UINT32 i;
lumpinfo_t *p;
for (i = numwadfiles - 1; i < numwadfiles; i--)
{
if (wadfiles[i]->type == RET_WAD)
{
for (lumpNum = 0; lumpNum < wadfiles[i]->numlumps; lumpNum++)
{
p = wadfiles[i]->lumpinfo + lumpNum;
if (p->hash == hash && !strncmp(name, p->name, 8))
return (i<<16) + lumpNum;
}
}
else if (W_FileHasFolders(wadfiles[i]))
{
lumpNum = W_CheckNumForFolderStartPK3("maps/", i, 0);
if (lumpNum != INT16_MAX)
end = W_CheckNumForFolderEndPK3("maps/", i, lumpNum);
else
continue;
// Now look for the specified map.
for (; lumpNum < end; lumpNum++)
{
p = wadfiles[i]->lumpinfo + lumpNum;
if (p->hash == hash && !strnicmp(name, p->name, 8))
{
const char *extension = strrchr(p->fullname, '.');
if (!(extension && stricmp(extension, ".wad")))
return (i<<16) + lumpNum;
}
}
}
}
return LUMPERROR;
}
//
// W_GetNumForName
//
......@@ -1700,11 +1675,13 @@ static UINT16 W_CheckNumForPatchNamePwad(const char *name, UINT16 wad, boolean l
if (!TestValidLump(wad,0))
return INT16_MAX;
if (!longname)
if (longname)
hash = W_HashLumpName(name);
else
{
strlcpy(uname, name, sizeof uname);
strupr(uname);
hash = quickncasehash(uname, 8);
hash = W_HashLumpName(uname);
}
// SRB2 doesn't have a specific namespace for graphics, which means someone can do weird things
......@@ -1730,23 +1707,45 @@ static UINT16 W_CheckNumForPatchNamePwad(const char *name, UINT16 wad, boolean l
if (start == INT16_MAX)
start = wadfiles[wad]->numlumps;
for (i = 0; i < start; i++, lump_p++)
if (longname)
{
if ((!longname && lump_p->hash == hash && !strncmp(lump_p->name, uname, sizeof(uname) - 1))
|| (longname && stricmp(lump_p->longname, name) == 0))
return i;
}
size_t namelen = strlen(name);
if (end != INT16_MAX && start < end)
{
lump_p = wadfiles[wad]->lumpinfo + end;
for (i = 0; i < start; i++, lump_p++)
{
if (lump_p->longnamelength == namelen && lump_p->hash.longname == hash && stricmp(lump_p->longname, name) == 0)
return i;
}
for (i = end; i < wadfiles[wad]->numlumps; i++, lump_p++)
if (end != INT16_MAX && start < end)
{
if ((!longname && lump_p->hash == hash && !strncmp(lump_p->name, uname, sizeof(uname) - 1))
|| (longname && stricmp(lump_p->longname, name) == 0))
lump_p = wadfiles[wad]->lumpinfo + end;
for (i = end; i < wadfiles[wad]->numlumps; i++, lump_p++)
{
if (lump_p->longnamelength == namelen && lump_p->hash.longname == hash && stricmp(lump_p->longname, name) == 0)
return i;
}
}
}
else
{
for (i = 0; i < start; i++, lump_p++)
{
if (lump_p->hash.name == hash && strncmp(lump_p->name, uname, sizeof(uname) - 1) == 0)
return i;
}
if (end != INT16_MAX && start < end)
{
lump_p = wadfiles[wad]->lumpinfo + end;
for (i = end; i < wadfiles[wad]->numlumps; i++, lump_p++)
{
if (lump_p->hash.name == hash && strncmp(lump_p->name, uname, sizeof(uname) - 1) == 0)
return i;
}
}
}
// not found.
......
......@@ -66,13 +66,25 @@ typedef struct
{
unsigned long position; // filelump_t filepos
unsigned long disksize; // filelump_t size
char name[9]; // filelump_t name[] e.g. "LongEntr"
UINT32 hash;
char *longname; // e.g. "LongEntryName"
char *fullname; // e.g. "Folder/Subfolder/LongEntryName.extension"
char *diskpath; // path to the file e.g. "/usr/games/srb2/Addon/Folder/Subfolder/LongEntryName.extension"
// NOTE: This is NULL if the WAD type != RET_FOLDER
size_t namelength; // length of name
size_t longnamelength; // length of longname
size_t fullnamelength; // length of fullname
size_t size; // real (uncompressed) size
compmethod compression; // lump compression method
struct {
UINT32 name; // hash of name
UINT32 longname; // hash of longname
UINT32 fullname; // hash of fullname
} hash;
} lumpinfo_t;
// =========================================================================
......@@ -168,6 +180,8 @@ void W_InitMultipleFiles(addfilelist_t *list);
INT32 W_IsPathToFolderValid(const char *path);
char *W_GetFullFolderPath(const char *path);
UINT32 W_HashLumpName(const char *name);
const char *W_CheckNameForNumPwad(UINT16 wad, UINT16 lump);
const char *W_CheckNameForNum(lumpnum_t lumpnum);
......@@ -183,12 +197,13 @@ UINT16 W_CheckNumForFolderEndPK3(const char *name, UINT16 wad, UINT16 startlump)
char *W_GetLumpFolderPathPK3(UINT16 wad, UINT16 lump);
char *W_GetLumpFolderNamePK3(UINT16 wad, UINT16 lump);
const char *W_GetFilenameFromFullname(const char *path);
void W_GetFolderLumpsPwad(const char *name, UINT16 wad, UINT32 **list, UINT16 *list_capacity, UINT16 *numlumps);
void W_GetFolderLumps(const char *name, UINT32 **list, UINT16 *list_capacity, UINT16 *numlumps);
UINT32 W_CountFolderLumpsPwad(const char *name, UINT16 wad);
UINT32 W_CountFolderLumps(const char *name);
lumpnum_t W_CheckNumForMap(const char *name);
lumpnum_t W_CheckNumForName(const char *name);
lumpnum_t W_CheckNumForLongName(const char *name);
lumpnum_t W_GetNumForName(const char *name); // like W_CheckNumForName but I_Error on LUMPERROR
......