Merge branch 'master' of https://git.magicalgirl.moe/STJr/SRB2Internal.git into pretty_stuff

# Conflicts:
#	src/d_main.c
#	src/st_stuff.c
This commit is contained in:
toasterbabe 2018-03-24 17:17:01 +00:00
commit 33afd94252
21 changed files with 669 additions and 383 deletions

View File

@ -79,7 +79,7 @@
# SRB2 data files # SRB2 data files
D_DIR?=../bin/Resources D_DIR?=../bin/Resources
D_FILES=$(D_DIR)/srb2.srb \ D_FILES=$(D_DIR)/srb2.pk3 \
$(D_DIR)/player.dta \ $(D_DIR)/player.dta \
$(D_DIR)/rings.wpn \ $(D_DIR)/rings.wpn \
$(D_DIR)/drill.dta \ $(D_DIR)/drill.dta \

View File

@ -11,7 +11,7 @@
#ifdef CMAKECONFIG #ifdef CMAKECONFIG
#define ASSET_HASH_SRB2_SRB "${SRB2_ASSET_srb2.srb_HASH}" #define ASSET_HASH_SRB2_PK3 "${SRB2_ASSET_srb2.pk3_HASH}"
#define ASSET_HASH_PLAYER_DTA "${SRB2_ASSET_player.dta_HASH}" #define ASSET_HASH_PLAYER_DTA "${SRB2_ASSET_player.dta_HASH}"
#define ASSET_HASH_RINGS_DTA "${SRB2_ASSET_rings.dta_HASH}" #define ASSET_HASH_RINGS_DTA "${SRB2_ASSET_rings.dta_HASH}"
#define ASSET_HASH_ZONES_DTA "${SRB2_ASSET_zones.dta_HASH}" #define ASSET_HASH_ZONES_DTA "${SRB2_ASSET_zones.dta_HASH}"
@ -31,7 +31,7 @@
/* Manually defined asset hashes for non-CMake builds /* Manually defined asset hashes for non-CMake builds
* Last updated 2015 / 05 / 03 * Last updated 2015 / 05 / 03
*/ */
#define ASSET_HASH_SRB2_SRB "c1b9577687f8a795104aef4600720ea7" #define ASSET_HASH_SRB2_PK3 "c1b9577687f8a795104aef4600720ea7"
#define ASSET_HASH_ZONES_DTA "303838c6c534d9540288360fa49cca60" #define ASSET_HASH_ZONES_DTA "303838c6c534d9540288360fa49cca60"
#define ASSET_HASH_PLAYER_DTA "cfca0f1c73023cbbd8f844f45480f799" #define ASSET_HASH_PLAYER_DTA "cfca0f1c73023cbbd8f844f45480f799"
#define ASSET_HASH_RINGS_DTA "85901ad4bf94637e5753d2ac2c03ea26" #define ASSET_HASH_RINGS_DTA "85901ad4bf94637e5753d2ac2c03ea26"

View File

@ -845,8 +845,9 @@ boolean CON_Responder(event_t *ev)
return true; return true;
} }
// don't eat the key // ...why shouldn't it eat the key? if it doesn't, it just means you
return false; // can control Sonic from the console, which is silly
return true; //return false;
} }
// command completion forward (tab) and backward (shift-tab) // command completion forward (tab) and backward (shift-tab)
@ -1045,7 +1046,7 @@ boolean CON_Responder(event_t *ev)
// enter a char into the command prompt // enter a char into the command prompt
if (key < 32 || key > 127) if (key < 32 || key > 127)
return false; return true; // even if key can't be printed, eat it anyway
// add key to cmd line here // add key to cmd line here
if (key >= 'A' && key <= 'Z' && !shiftdown) //this is only really necessary for dedicated servers if (key >= 'A' && key <= 'Z' && !shiftdown) //this is only really necessary for dedicated servers

View File

@ -4003,7 +4003,8 @@ static void HandlePacketFromPlayer(SINT8 node)
INT32 k = *txtpak++; // playernum INT32 k = *txtpak++; // playernum
const size_t txtsize = txtpak[0]+1; const size_t txtsize = txtpak[0]+1;
M_Memcpy(D_GetTextcmd(i, k), txtpak, txtsize); if (i >= gametic) // Don't copy old net commands
M_Memcpy(D_GetTextcmd(i, k), txtpak, txtsize);
txtpak += txtsize; txtpak += txtsize;
} }
} }

View File

@ -784,7 +784,7 @@ static inline void D_CleanFile(void)
static void IdentifyVersion(void) static void IdentifyVersion(void)
{ {
char *srb2wad1, *srb2wad2; char *srb2wad;
const char *srb2waddir = NULL; const char *srb2waddir = NULL;
#if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL) #if (defined (__unix__) && !defined (MSDOS)) || defined (UNIXCOMMON) || defined (HAVE_SDL)
@ -813,31 +813,24 @@ static void IdentifyVersion(void)
srb2waddir = I_GetWadDir(); srb2waddir = I_GetWadDir();
#endif #endif
// Commercial. // Commercial.
srb2wad1 = malloc(strlen(srb2waddir)+1+8+1); srb2wad = malloc(strlen(srb2waddir)+1+8+1);
srb2wad2 = malloc(strlen(srb2waddir)+1+8+1); if (srb2wad == NULL)
if (srb2wad1 == NULL && srb2wad2 == NULL)
I_Error("No more free memory to look in %s", srb2waddir); I_Error("No more free memory to look in %s", srb2waddir);
if (srb2wad1 != NULL) else
sprintf(srb2wad1, pandf, srb2waddir, "srb2.pk3"); sprintf(srb2wad, pandf, srb2waddir, "srb2.pk3");
if (srb2wad2 != NULL)
sprintf(srb2wad2, pandf, srb2waddir, "srb2.wad");
// will be overwritten in case of -cdrom or unix/win home // will be overwritten in case of -cdrom or unix/win home
snprintf(configfile, sizeof configfile, "%s" PATHSEP CONFIGFILENAME, srb2waddir); snprintf(configfile, sizeof configfile, "%s" PATHSEP CONFIGFILENAME, srb2waddir);
configfile[sizeof configfile - 1] = '\0'; configfile[sizeof configfile - 1] = '\0';
// Load the IWAD // Load the IWAD
if (srb2wad2 != NULL && FIL_ReadFileOK(srb2wad2)) if (srb2wad != NULL && FIL_ReadFileOK(srb2wad))
D_AddFile(srb2wad2); D_AddFile(srb2wad);
else if (srb2wad1 != NULL && FIL_ReadFileOK(srb2wad1))
D_AddFile(srb2wad1);
else else
I_Error("SRB2.PK3/SRB2.WAD not found! Expected in %s, ss files: %s and %s\n", srb2waddir, srb2wad1, srb2wad2); I_Error("srb2.pk3 not found! Expected in %s, ss file: %s\n", srb2waddir, srb2wad);
if (srb2wad1) if (srb2wad)
free(srb2wad1); free(srb2wad);
if (srb2wad2)
free(srb2wad2);
// if you change the ordering of this or add/remove a file, be sure to update the md5 // if you change the ordering of this or add/remove a file, be sure to update the md5
// checking in D_SRB2Main // checking in D_SRB2Main
@ -1132,7 +1125,7 @@ void D_SRB2Main(void)
#ifndef DEVELOP // md5s last updated 12/14/14 #ifndef DEVELOP // md5s last updated 12/14/14
// Check MD5s of autoloaded files // Check MD5s of autoloaded files
//W_VerifyFileMD5(0, ASSET_HASH_SRB2_SRB); // srb2.srb/srb2.wad //W_VerifyFileMD5(0, ASSET_HASH_SRB2_PK3); // srb2.pk3
//W_VerifyFileMD5(1, ASSET_HASH_ZONES_DTA); // zones.dta //W_VerifyFileMD5(1, ASSET_HASH_ZONES_DTA); // zones.dta
//W_VerifyFileMD5(2, ASSET_HASH_PLAYER_DTA); // player.dta //W_VerifyFileMD5(2, ASSET_HASH_PLAYER_DTA); // player.dta
#ifdef USE_PATCH_DTA #ifdef USE_PATCH_DTA

View File

@ -586,7 +586,6 @@ void D_RegisterServerCommands(void)
*/ */
void D_RegisterClientCommands(void) void D_RegisterClientCommands(void)
{ {
const char *username;
INT32 i; INT32 i;
for (i = 0; i < MAXSKINCOLORS; i++) for (i = 0; i < MAXSKINCOLORS; i++)
@ -644,8 +643,6 @@ void D_RegisterClientCommands(void)
#endif #endif
// register these so it is saved to config // register these so it is saved to config
if ((username = I_GetUserName()))
cv_playername.defaultvalue = cv_defaultplayername.defaultvalue = username;
CV_RegisterVar(&cv_playername); CV_RegisterVar(&cv_playername);
CV_RegisterVar(&cv_playercolor); CV_RegisterVar(&cv_playercolor);
CV_RegisterVar(&cv_skin); // r_things.c (skin NAME) CV_RegisterVar(&cv_skin); // r_things.c (skin NAME)
@ -3071,7 +3068,7 @@ static void Command_Addfile(void)
// Add file on your client directly if it is trivial, or you aren't in a netgame. // Add file on your client directly if it is trivial, or you aren't in a netgame.
if (!(netgame || multiplayer) || musiconly) if (!(netgame || multiplayer) || musiconly)
{ {
P_AddWadFile(fn, NULL); P_AddWadFile(fn);
return; return;
} }
@ -3240,7 +3237,7 @@ static void Got_Addfilecmd(UINT8 **cp, INT32 playernum)
ncs = findfile(filename,md5sum,true); ncs = findfile(filename,md5sum,true);
if (ncs != FS_FOUND || !P_AddWadFile(filename, NULL)) if (ncs != FS_FOUND || !P_AddWadFile(filename))
{ {
Command_ExitGame_f(); Command_ExitGame_f();
if (ncs == FS_FOUND) if (ncs == FS_FOUND)

View File

@ -333,7 +333,7 @@ INT32 CL_CheckFiles(void)
// return 1; // return 1;
// the first is the iwad (the main wad file) // the first is the iwad (the main wad file)
// we don't care if it's called srb2.srb or srb2.wad. // we don't care if it's called srb2.pk3 or not.
// Never download the IWAD, just assume it's there and identical // Never download the IWAD, just assume it's there and identical
fileneeded[0].status = FS_OPEN; fileneeded[0].status = FS_OPEN;
@ -423,7 +423,7 @@ void CL_LoadServerFiles(void)
continue; // Already loaded continue; // Already loaded
else if (fileneeded[i].status == FS_FOUND) else if (fileneeded[i].status == FS_FOUND)
{ {
P_AddWadFile(fileneeded[i].filename, NULL); P_AddWadFile(fileneeded[i].filename);
G_SetGameModified(true); G_SetGameModified(true);
fileneeded[i].status = FS_OPEN; fileneeded[i].status = FS_OPEN;
} }
@ -754,6 +754,7 @@ void Got_Filetxpak(void)
static INT32 filetime = 0; static INT32 filetime = 0;
if (!(strcmp(filename, "srb2.pk3") if (!(strcmp(filename, "srb2.pk3")
&& strcmp(filename, "srb2.srb")
&& strcmp(filename, "srb2.wad") && strcmp(filename, "srb2.wad")
&& strcmp(filename, "zones.dta") && strcmp(filename, "zones.dta")
&& strcmp(filename, "player.dta") && strcmp(filename, "player.dta")

View File

@ -1823,7 +1823,6 @@ static void readframe(MYFILE *f, INT32 num)
char *word1; char *word1;
char *word2 = NULL; char *word2 = NULL;
char *tmp; char *tmp;
INT32 j;
do do
{ {
@ -1838,16 +1837,6 @@ static void readframe(MYFILE *f, INT32 num)
if (s == tmp) if (s == tmp)
continue; // Skip comment lines, but don't break. continue; // Skip comment lines, but don't break.
for (j = 0; s[j] != '\n'; j++)
{
if (s[j] == '=')
{
j += 2;
j = atoi(&s[j]);
break;
}
}
word1 = strtok(s, " "); word1 = strtok(s, " ");
if (word1) if (word1)
strupr(word1); strupr(word1);

View File

@ -581,8 +581,8 @@ void HWR_FreeTextureCache(void)
// free all hardware-converted graphics cached in the heap // free all hardware-converted graphics cached in the heap
// our gool is only the textures since user of the texture is the texture cache // our gool is only the textures since user of the texture is the texture cache
Z_FreeTags(PU_HWRCACHE, PU_HWRCACHE); Z_FreeTag(PU_HWRCACHE);
Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRCACHE_UNLOCKED); Z_FreeTag(PU_HWRCACHE_UNLOCKED);
// Alam: free the Z_Blocks before freeing it's users // Alam: free the Z_Blocks before freeing it's users
@ -629,8 +629,8 @@ void HWR_SetPalette(RGBA_t *palette)
// now flush data texture cache so 32 bit texture are recomputed // now flush data texture cache so 32 bit texture are recomputed
if (patchformat == GR_RGBA || textureformat == GR_RGBA) if (patchformat == GR_RGBA || textureformat == GR_RGBA)
{ {
Z_FreeTags(PU_HWRCACHE, PU_HWRCACHE); Z_FreeTag(PU_HWRCACHE);
Z_FreeTags(PU_HWRCACHE_UNLOCKED, PU_HWRCACHE_UNLOCKED); Z_FreeTag(PU_HWRCACHE_UNLOCKED);
} }
} }

View File

@ -176,11 +176,16 @@ static inline void LUA_LoadFile(MYFILE *f, char *name)
LUA_ClearState(); LUA_ClearState();
lua_pushinteger(gL, f->wad); lua_pushinteger(gL, f->wad);
lua_setfield(gL, LUA_REGISTRYINDEX, "WAD"); lua_setfield(gL, LUA_REGISTRYINDEX, "WAD");
lua_lumploading = true; // turn on loading flag
if (luaL_loadbuffer(gL, f->data, f->size, va("@%s",name)) || lua_pcall(gL, 0, 0, 0)) { if (luaL_loadbuffer(gL, f->data, f->size, va("@%s",name)) || lua_pcall(gL, 0, 0, 0)) {
CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1)); CONS_Alert(CONS_WARNING,"%s\n",lua_tostring(gL,-1));
lua_pop(gL,1); lua_pop(gL,1);
} }
lua_gc(gL, LUA_GCCOLLECT, 0); lua_gc(gL, LUA_GCCOLLECT, 0);
lua_lumploading = false; // turn off again
} }
// Load a script from a lump // Load a script from a lump
@ -188,24 +193,28 @@ void LUA_LoadLump(UINT16 wad, UINT16 lump)
{ {
MYFILE f; MYFILE f;
char *name; char *name;
f.wad = wad; f.wad = wad;
f.size = W_LumpLengthPwad(wad, lump); f.size = W_LumpLengthPwad(wad, lump);
f.data = Z_Malloc(f.size, PU_LUA, NULL); f.data = Z_Malloc(f.size, PU_LUA, NULL);
W_ReadLumpPwad(wad, lump, f.data); W_ReadLumpPwad(wad, lump, f.data);
f.curpos = f.data; f.curpos = f.data;
name = malloc(strlen(wadfiles[wad]->filename)+10); if (wadfiles[wad]->type == RET_LUA)
strcpy(name, wadfiles[wad]->filename); {
if (!fasticmp(&name[strlen(name) - 4], ".lua")) { name = malloc(strlen(wadfiles[wad]->filename)+1);
// If it's not a .lua file, copy the lump name in too. strcpy(name, wadfiles[wad]->filename);
name[strlen(wadfiles[wad]->filename)] = '|'; }
M_Memcpy(name+strlen(wadfiles[wad]->filename)+1, wadfiles[wad]->lumpinfo[lump].name, 8); else // If it's not a .lua file, copy the lump name in too.
name[strlen(wadfiles[wad]->filename)+9] = '\0'; {
lumpinfo_t *lump_p = &wadfiles[wad]->lumpinfo[lump];
size_t length = strlen(wadfiles[wad]->filename) + 1 + strlen(lump_p->name2); // length of file name, '|', and lump name
name = malloc(length + 1);
sprintf(name, "%s|%s", wadfiles[wad]->filename, lump_p->name2);
name[length] = '\0';
} }
lua_lumploading = true; // turn on loading flag
LUA_LoadFile(&f, name); // actually load file! LUA_LoadFile(&f, name); // actually load file!
lua_lumploading = false; // turn off again
free(name); free(name);
Z_Free(f.data); Z_Free(f.data);

View File

@ -649,13 +649,12 @@ static void M_PNGhdr(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png_
static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png_byte movie) static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png_byte movie)
{ {
#ifdef PNG_TEXT_SUPPORTED #ifdef PNG_TEXT_SUPPORTED
#define SRB2PNGTXT 11 //PNG_KEYWORD_MAX_LENGTH(79) is the max #define SRB2PNGTXT 10 //PNG_KEYWORD_MAX_LENGTH(79) is the max
png_text png_infotext[SRB2PNGTXT]; png_text png_infotext[SRB2PNGTXT];
char keytxt[SRB2PNGTXT][12] = { char keytxt[SRB2PNGTXT][12] = {
"Title", "Author", "Description", "Playername", "Mapnum", "Mapname", "Title", "Description", "Playername", "Mapnum", "Mapname",
"Location", "Interface", "Revision", "Build Date", "Build Time"}; "Location", "Interface", "Revision", "Build Date", "Build Time"};
char titletxt[] = "Sonic Robo Blast 2 " VERSIONSTRING; char titletxt[] = "Sonic Robo Blast 2 " VERSIONSTRING;
png_charp authortxt = I_GetUserName();
png_charp playertxt = cv_playername.zstring; png_charp playertxt = cv_playername.zstring;
char desctxt[] = "SRB2 Screenshot"; char desctxt[] = "SRB2 Screenshot";
char Movietxt[] = "SRB2 Movie"; char Movietxt[] = "SRB2 Movie";
@ -705,19 +704,18 @@ static void M_PNGText(png_structp png_ptr, png_infop png_info_ptr, PNG_CONST png
png_infotext[i].key = keytxt[i]; png_infotext[i].key = keytxt[i];
png_infotext[0].text = titletxt; png_infotext[0].text = titletxt;
png_infotext[1].text = authortxt;
if (movie) if (movie)
png_infotext[2].text = Movietxt; png_infotext[1].text = Movietxt;
else else
png_infotext[2].text = desctxt; png_infotext[1].text = desctxt;
png_infotext[3].text = playertxt; png_infotext[2].text = playertxt;
png_infotext[4].text = maptext; png_infotext[3].text = maptext;
png_infotext[5].text = lvlttltext; png_infotext[4].text = lvlttltext;
png_infotext[6].text = locationtxt; png_infotext[5].text = locationtxt;
png_infotext[7].text = interfacetxt; png_infotext[6].text = interfacetxt;
png_infotext[8].text = strncpy(ctrevision, comprevision, sizeof(ctrevision)-1); png_infotext[7].text = strncpy(ctrevision, comprevision, sizeof(ctrevision)-1);
png_infotext[9].text = strncpy(ctdate, compdate, sizeof(ctdate)-1); png_infotext[8].text = strncpy(ctdate, compdate, sizeof(ctdate)-1);
png_infotext[10].text = strncpy(cttime, comptime, sizeof(cttime)-1); png_infotext[9].text = strncpy(cttime, comptime, sizeof(cttime)-1);
png_set_text(png_ptr, png_info_ptr, png_infotext, SRB2PNGTXT); png_set_text(png_ptr, png_info_ptr, png_infotext, SRB2PNGTXT);
#undef SRB2PNGTXT #undef SRB2PNGTXT

View File

@ -497,16 +497,34 @@ static void P_NetArchiveWorld(void)
UINT8 *put; UINT8 *put;
// reload the map just to see difference // reload the map just to see difference
const mapsector_t *ms; mapsector_t *ms;
const mapsidedef_t *msd; mapsidedef_t *msd;
const maplinedef_t *mld; maplinedef_t *mld;
const sector_t *ss = sectors; const sector_t *ss = sectors;
UINT8 diff, diff2; UINT8 diff, diff2;
WRITEUINT32(save_p, ARCHIVEBLOCK_WORLD); WRITEUINT32(save_p, ARCHIVEBLOCK_WORLD);
put = save_p; put = save_p;
ms = W_CacheLumpNum(lastloadedmaplumpnum+ML_SECTORS, PU_CACHE); if (W_IsLumpWad(lastloadedmaplumpnum)) // welp it's a map wad in a pk3
{ // HACK: Open wad file rather quickly so we can get the data from the relevant lumps
UINT8 *wadData = W_CacheLumpNum(lastloadedmaplumpnum, PU_STATIC);
filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs);
#define retrieve_mapdata(d, f)\
d = Z_Malloc((f)->size, PU_CACHE, NULL); \
M_Memcpy(d, wadData + (f)->filepos, (f)->size)
retrieve_mapdata(ms, fileinfo + ML_SECTORS);
retrieve_mapdata(mld, fileinfo + ML_LINEDEFS);
retrieve_mapdata(msd, fileinfo + ML_SIDEDEFS);
#undef retrieve_mapdata
Z_Free(wadData); // we're done with this now
}
else // phew it's just a WAD
{
ms = W_CacheLumpNum(lastloadedmaplumpnum+ML_SECTORS, PU_CACHE);
mld = W_CacheLumpNum(lastloadedmaplumpnum+ML_LINEDEFS, PU_CACHE);
msd = W_CacheLumpNum(lastloadedmaplumpnum+ML_SIDEDEFS, PU_CACHE);
}
for (i = 0; i < numsectors; i++, ss++, ms++) for (i = 0; i < numsectors; i++, ss++, ms++)
{ {
@ -637,8 +655,6 @@ static void P_NetArchiveWorld(void)
WRITEUINT16(put, 0xffff); WRITEUINT16(put, 0xffff);
mld = W_CacheLumpNum(lastloadedmaplumpnum+ML_LINEDEFS, PU_CACHE);
msd = W_CacheLumpNum(lastloadedmaplumpnum+ML_SIDEDEFS, PU_CACHE);
// do lines // do lines
for (i = 0; i < numlines; i++, mld++, li++) for (i = 0; i < numlines; i++, mld++, li++)
{ {

View File

@ -1893,6 +1893,30 @@ static void P_CreateBlockMap(void)
} }
} }
// Split from P_LoadBlockMap for convenience
// -- Monster Iestyn 08/01/18
static void P_ReadBlockMapLump(INT16 *wadblockmaplump, size_t count)
{
size_t i;
blockmaplump = Z_Calloc(sizeof (*blockmaplump) * count, PU_LEVEL, NULL);
// killough 3/1/98: Expand wad blockmap into larger internal one,
// by treating all offsets except -1 as unsigned and zero-extending
// them. This potentially doubles the size of blockmaps allowed,
// because Doom originally considered the offsets as always signed.
blockmaplump[0] = SHORT(wadblockmaplump[0]);
blockmaplump[1] = SHORT(wadblockmaplump[1]);
blockmaplump[2] = (INT32)(SHORT(wadblockmaplump[2])) & 0xffff;
blockmaplump[3] = (INT32)(SHORT(wadblockmaplump[3])) & 0xffff;
for (i = 4; i < count; i++)
{
INT16 t = SHORT(wadblockmaplump[i]); // killough 3/1/98
blockmaplump[i] = t == -1 ? (INT32)-1 : (INT32) t & 0xffff;
}
}
// //
// P_LoadBlockMap // P_LoadBlockMap
// //
@ -1919,38 +1943,20 @@ static boolean P_LoadBlockMap(lumpnum_t lumpnum)
return false; return false;
{ {
size_t i;
INT16 *wadblockmaplump = malloc(count); //INT16 *wadblockmaplump = W_CacheLumpNum (lump, PU_LEVEL); INT16 *wadblockmaplump = malloc(count); //INT16 *wadblockmaplump = W_CacheLumpNum (lump, PU_LEVEL);
if (!wadblockmaplump)
if (wadblockmaplump) W_ReadLump(lumpnum, wadblockmaplump); return false;
else return false; W_ReadLump(lumpnum, wadblockmaplump);
count /= 2; count /= 2;
blockmaplump = Z_Calloc(sizeof (*blockmaplump) * count, PU_LEVEL, 0); P_ReadBlockMapLump(wadblockmaplump, count);
// killough 3/1/98: Expand wad blockmap into larger internal one,
// by treating all offsets except -1 as unsigned and zero-extending
// them. This potentially doubles the size of blockmaps allowed,
// because Doom originally considered the offsets as always signed.
blockmaplump[0] = SHORT(wadblockmaplump[0]);
blockmaplump[1] = SHORT(wadblockmaplump[1]);
blockmaplump[2] = (INT32)(SHORT(wadblockmaplump[2])) & 0xffff;
blockmaplump[3] = (INT32)(SHORT(wadblockmaplump[3])) & 0xffff;
for (i = 4; i < count; i++)
{
INT16 t = SHORT(wadblockmaplump[i]); // killough 3/1/98
blockmaplump[i] = t == -1 ? (INT32)-1 : (INT32) t & 0xffff;
}
free(wadblockmaplump); free(wadblockmaplump);
bmaporgx = blockmaplump[0]<<FRACBITS;
bmaporgy = blockmaplump[1]<<FRACBITS;
bmapwidth = blockmaplump[2];
bmapheight = blockmaplump[3];
} }
bmaporgx = blockmaplump[0]<<FRACBITS;
bmaporgy = blockmaplump[1]<<FRACBITS;
bmapwidth = blockmaplump[2];
bmapheight = blockmaplump[3];
// clear out mobj chains // clear out mobj chains
count = sizeof (*blocklinks)* bmapwidth*bmapheight; count = sizeof (*blocklinks)* bmapwidth*bmapheight;
blocklinks = Z_Calloc(count, PU_LEVEL, NULL); blocklinks = Z_Calloc(count, PU_LEVEL, NULL);
@ -1984,6 +1990,53 @@ static boolean P_LoadBlockMap(lumpnum_t lumpnum)
#endif #endif
} }
// This needs to be a separate function
// because making both the WAD and PK3 loading code use
// the same functions is trickier than it looks for blockmap
// -- Monster Iestyn 09/01/18
static boolean P_LoadRawBlockMap(UINT8 *data, size_t count, const char *lumpname)
{
#if 0
(void)data;
(void)count;
(void)lumpname;
return false;
#else
// Check if the lump is named "BLOCKMAP"
if (!lumpname || memcmp(lumpname, "BLOCKMAP", 8) != 0)
{
CONS_Printf("No blockmap lump found for pk3!\n");
return false;
}
if (!count || count >= 0x20000)
return false;
CONS_Printf("Reading blockmap lump for pk3...\n");
// no need to malloc anything, assume the data is uncompressed for now
count /= 2;
P_ReadBlockMapLump((INT16 *)data, count);
bmaporgx = blockmaplump[0]<<FRACBITS;
bmaporgy = blockmaplump[1]<<FRACBITS;
bmapwidth = blockmaplump[2];
bmapheight = blockmaplump[3];
// clear out mobj chains
count = sizeof (*blocklinks)* bmapwidth*bmapheight;
blocklinks = Z_Calloc(count, PU_LEVEL, NULL);
blockmap = blockmaplump+4;
#ifdef POLYOBJECTS
// haleyjd 2/22/06: setup polyobject blockmap
count = sizeof(*polyblocklinks) * bmapwidth * bmapheight;
polyblocklinks = Z_Calloc(count, PU_LEVEL, NULL);
#endif
return true;
#endif
}
// //
// P_GroupLines // P_GroupLines
// Builds sector line lists and subsector sector numbers. // Builds sector line lists and subsector sector numbers.
@ -2109,6 +2162,30 @@ static void P_LoadReject(lumpnum_t lumpnum)
rejectmatrix = W_CacheLumpNum(lumpnum, PU_LEVEL); rejectmatrix = W_CacheLumpNum(lumpnum, PU_LEVEL);
} }
// PK3 version
// -- Monster Iestyn 09/01/18
static void P_LoadRawReject(UINT8 *data, size_t count, const char *lumpname)
{
// Check if the lump is named "REJECT"
if (!lumpname || memcmp(lumpname, "REJECT\0\0", 8) != 0)
{
rejectmatrix = NULL;
CONS_Debug(DBG_SETUP, "P_LoadRawReject: No valid REJECT lump found\n");
return;
}
if (!count) // zero length, someone probably used ZDBSP
{
rejectmatrix = NULL;
CONS_Debug(DBG_SETUP, "P_LoadRawReject: REJECT lump has size 0, will not be loaded\n");
}
else
{
rejectmatrix = Z_Malloc(count, PU_LEVEL, NULL); // allocate memory for the reject matrix
M_Memcpy(rejectmatrix, data, count); // copy the data into it
}
}
#if 0 #if 0
static char *levellumps[] = static char *levellumps[] =
{ {
@ -2581,7 +2658,6 @@ boolean P_SetupLevel(boolean skipprecip)
// use gamemap to get map number. // use gamemap to get map number.
// 99% of the things already did, so. // 99% of the things already did, so.
// Map header should always be in place at this point // Map header should always be in place at this point
char *lumpfullName;
INT32 i, loadprecip = 1, ranspecialwipe = 0; INT32 i, loadprecip = 1, ranspecialwipe = 0;
INT32 loademblems = 1; INT32 loademblems = 1;
INT32 fromnetsave = 0; INT32 fromnetsave = 0;
@ -2764,14 +2840,26 @@ boolean P_SetupLevel(boolean skipprecip)
// As it is implemented right now, we're assuming an uncompressed WAD. // As it is implemented right now, we're assuming an uncompressed WAD.
// (As in, a normal PWAD, not ZWAD or anything. The lump itself can be compressed.) // (As in, a normal PWAD, not ZWAD or anything. The lump itself can be compressed.)
// We're not accounting for extra lumps and scrambled lump positions. Any additional data will cause an error. // We're not accounting for extra lumps and scrambled lump positions. Any additional data will cause an error.
lumpfullName = (wadfiles[WADFILENUM(lastloadedmaplumpnum)]->lumpinfo + LUMPNUM(lastloadedmaplumpnum))->name2; if (W_IsLumpWad(lastloadedmaplumpnum))
if (!strnicmp(lumpfullName + strlen(lumpfullName) - 4, ".wad", 4))
{ {
// Remember that we're assuming that the WAD will have a specific set of lumps in a specific order. // Remember that we're assuming that the WAD will have a specific set of lumps in a specific order.
UINT8 *wadData = W_CacheLumpNum(lastloadedmaplumpnum, PU_STATIC); UINT8 *wadData = W_CacheLumpNum(lastloadedmaplumpnum, PU_STATIC);
//filelump_t *fileinfo = wadData + ((wadinfo_t *)wadData)->infotableofs; //filelump_t *fileinfo = wadData + ((wadinfo_t *)wadData)->infotableofs;
filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs); filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs);
UINT32 numlumps = ((wadinfo_t *)wadData)->numlumps;
if (numlumps < ML_REJECT) // at least 9 lumps should be in the wad for a map to be loaded
{
I_Error("Bad WAD file for map %s!\n", maplumpname);
}
if (numlumps > ML_BLOCKMAP) // enough room for a BLOCKMAP lump at least
{
loadedbm = P_LoadRawBlockMap(
wadData + (fileinfo + ML_BLOCKMAP)->filepos,
(fileinfo + ML_BLOCKMAP)->size,
(fileinfo + ML_BLOCKMAP)->name);
}
P_LoadRawVertexes(wadData + (fileinfo + ML_VERTEXES)->filepos, (fileinfo + ML_VERTEXES)->size); P_LoadRawVertexes(wadData + (fileinfo + ML_VERTEXES)->filepos, (fileinfo + ML_VERTEXES)->size);
P_LoadRawSectors(wadData + (fileinfo + ML_SECTORS)->filepos, (fileinfo + ML_SECTORS)->size); P_LoadRawSectors(wadData + (fileinfo + ML_SECTORS)->filepos, (fileinfo + ML_SECTORS)->size);
P_LoadRawSideDefs((fileinfo + ML_SIDEDEFS)->size); P_LoadRawSideDefs((fileinfo + ML_SIDEDEFS)->size);
@ -2780,6 +2868,13 @@ boolean P_SetupLevel(boolean skipprecip)
P_LoadRawSubsectors(wadData + (fileinfo + ML_SSECTORS)->filepos, (fileinfo + ML_SSECTORS)->size); P_LoadRawSubsectors(wadData + (fileinfo + ML_SSECTORS)->filepos, (fileinfo + ML_SSECTORS)->size);
P_LoadRawNodes(wadData + (fileinfo + ML_NODES)->filepos, (fileinfo + ML_NODES)->size); P_LoadRawNodes(wadData + (fileinfo + ML_NODES)->filepos, (fileinfo + ML_NODES)->size);
P_LoadRawSegs(wadData + (fileinfo + ML_SEGS)->filepos, (fileinfo + ML_SEGS)->size); P_LoadRawSegs(wadData + (fileinfo + ML_SEGS)->filepos, (fileinfo + ML_SEGS)->size);
if (numlumps > ML_REJECT) // enough room for a REJECT lump at least
{
P_LoadRawReject(
wadData + (fileinfo + ML_REJECT)->filepos,
(fileinfo + ML_REJECT)->size,
(fileinfo + ML_REJECT)->name);
}
// Important: take care of the ordering of the next functions. // Important: take care of the ordering of the next functions.
if (!loadedbm) if (!loadedbm)
@ -3133,7 +3228,7 @@ boolean P_RunSOC(const char *socfilename)
lumpnum_t lump; lumpnum_t lump;
if (strstr(socfilename, ".soc") != NULL) if (strstr(socfilename, ".soc") != NULL)
return P_AddWadFile(socfilename, NULL); return P_AddWadFile(socfilename);
lump = W_CheckNumForName(socfilename); lump = W_CheckNumForName(socfilename);
if (lump == LUMPERROR) if (lump == LUMPERROR)
@ -3163,6 +3258,7 @@ void P_LoadSoundsRange(UINT16 wadnum, UINT16 first, UINT16 num)
CONS_Debug(DBG_SETUP, "Sound %.8s replaced\n", lumpinfo->name); CONS_Debug(DBG_SETUP, "Sound %.8s replaced\n", lumpinfo->name);
I_FreeSfx(&S_sfx[j]); I_FreeSfx(&S_sfx[j]);
break; // there shouldn't be two sounds with the same name, so stop looking
} }
} }
} }
@ -3214,13 +3310,13 @@ static lumpinfo_t* FindFolder(const char *folName, UINT16 *start, UINT16 *end, l
// Add a wadfile to the active wad files, // Add a wadfile to the active wad files,
// replace sounds, musics, patches, textures, sprites and maps // replace sounds, musics, patches, textures, sprites and maps
// //
boolean P_AddWadFile(const char *wadfilename, char **firstmapname) boolean P_AddWadFile(const char *wadfilename)
{ {
size_t i, j, sreplaces = 0, mreplaces = 0, digmreplaces = 0; size_t i, j, sreplaces = 0, mreplaces = 0, digmreplaces = 0;
UINT16 numlumps, wadnum; UINT16 numlumps, wadnum;
INT16 firstmapreplaced = 0, num;
char *name; char *name;
lumpinfo_t *lumpinfo; lumpinfo_t *lumpinfo;
boolean mapsadded = false;
boolean replacedcurrentmap = false; boolean replacedcurrentmap = false;
// Vars to help us with the position start and amount of each resource type. // Vars to help us with the position start and amount of each resource type.
@ -3290,17 +3386,21 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname)
name = lumpinfo->name; name = lumpinfo->name;
if (name[0] == 'D') if (name[0] == 'D')
{ {
if (name[1] == 'S') for (j = 1; j < NUMSFX; j++) if (name[1] == 'S')
{ {
if (S_sfx[j].name && !strnicmp(S_sfx[j].name, name + 2, 6)) for (j = 1; j < NUMSFX; j++)
{ {
// the sound will be reloaded when needed, if (S_sfx[j].name && !strnicmp(S_sfx[j].name, name + 2, 6))
// since sfx->data will be NULL {
CONS_Debug(DBG_SETUP, "Sound %.8s replaced\n", name); // the sound will be reloaded when needed,
// since sfx->data will be NULL
CONS_Debug(DBG_SETUP, "Sound %.8s replaced\n", name);
I_FreeSfx(&S_sfx[j]); I_FreeSfx(&S_sfx[j]);
sreplaces++; sreplaces++;
break; // there shouldn't be two sounds with the same name, so stop looking
}
} }
} }
else if (name[1] == '_') else if (name[1] == '_')
@ -3354,10 +3454,9 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname)
for (i = 0; i < numlumps; i++, lumpinfo++) for (i = 0; i < numlumps; i++, lumpinfo++)
{ {
name = lumpinfo->name; name = lumpinfo->name;
num = firstmapreplaced;
if (name[0] == 'M' && name[1] == 'A' && name[2] == 'P') // Ignore the headers if (name[0] == 'M' && name[1] == 'A' && name[2] == 'P') // Ignore the headers
{ {
INT16 num;
if (name[5]!='\0') if (name[5]!='\0')
continue; continue;
num = (INT16)M_MapNumber(name[3], name[4]); num = (INT16)M_MapNumber(name[3], name[4]);
@ -3367,16 +3466,10 @@ boolean P_AddWadFile(const char *wadfilename, char **firstmapname)
replacedcurrentmap = true; replacedcurrentmap = true;
CONS_Printf("%s\n", name); CONS_Printf("%s\n", name);
} mapsadded = true;
if (num && (num < firstmapreplaced || !firstmapreplaced))
{
firstmapreplaced = num;
if (firstmapname)
*firstmapname = name;
} }
} }
if (!firstmapreplaced) if (!mapsadded)
CONS_Printf(M_GetText("No maps added\n")); CONS_Printf(M_GetText("No maps added\n"));
// reload status bar (warning should have valid player!) // reload status bar (warning should have valid player!)

View File

@ -59,7 +59,7 @@ void P_ScanThings(INT16 mapnum, INT16 wadnum, INT16 lumpnum);
#endif #endif
void P_LoadThingsOnly(void); void P_LoadThingsOnly(void);
boolean P_SetupLevel(boolean skipprecip); boolean P_SetupLevel(boolean skipprecip);
boolean P_AddWadFile(const char *wadfilename, char **firstmapname); boolean P_AddWadFile(const char *wadfilename);
boolean P_RunSOC(const char *socfilename); boolean P_RunSOC(const char *socfilename);
void P_LoadSoundsRange(UINT16 wadnum, UINT16 first, UINT16 num); void P_LoadSoundsRange(UINT16 wadnum, UINT16 first, UINT16 num);
void P_LoadMusicsRange(UINT16 wadnum, UINT16 first, UINT16 num); void P_LoadMusicsRange(UINT16 wadnum, UINT16 first, UINT16 num);

View File

@ -6305,9 +6305,21 @@ void P_SpawnSpecials(INT32 fromnetsave)
case 259: // Make-Your-Own FOF! case 259: // Make-Your-Own FOF!
if (lines[i].sidenum[1] != 0xffff) if (lines[i].sidenum[1] != 0xffff)
{ {
UINT8 *data = W_CacheLumpNum(lastloadedmaplumpnum + ML_SIDEDEFS,PU_STATIC); UINT8 *data;
UINT16 b; UINT16 b;
if (W_IsLumpWad(lastloadedmaplumpnum)) // welp it's a map wad in a pk3
{ // HACK: Open wad file rather quickly so we can get the data from the sidedefs lump
UINT8 *wadData = W_CacheLumpNum(lastloadedmaplumpnum, PU_STATIC);
filelump_t *fileinfo = (filelump_t *)(wadData + ((wadinfo_t *)wadData)->infotableofs);
fileinfo += ML_SIDEDEFS; // we only need the SIDEDEFS lump
data = Z_Malloc(fileinfo->size, PU_STATIC, NULL);
M_Memcpy(data, wadData + fileinfo->filepos, fileinfo->size); // copy data
Z_Free(wadData); // we're done with this now
}
else // phew it's just a WAD
data = W_CacheLumpNum(lastloadedmaplumpnum + ML_SIDEDEFS,PU_STATIC);
for (b = 0; b < (INT16)numsides; b++) for (b = 0; b < (INT16)numsides; b++)
{ {
register mapsidedef_t *msd = (mapsidedef_t *)data + b; register mapsidedef_t *msd = (mapsidedef_t *)data + b;

View File

@ -124,7 +124,7 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
#include "macosx/mac_resources.h" #include "macosx/mac_resources.h"
#endif #endif
// Locations for searching the srb2.srb // Locations for searching the srb2.pk3
#if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON) #if defined (__unix__) || defined(__APPLE__) || defined (UNIXCOMMON)
#define DEFAULTWADLOCATION1 "/usr/local/share/games/SRB2" #define DEFAULTWADLOCATION1 "/usr/local/share/games/SRB2"
#define DEFAULTWADLOCATION2 "/usr/local/games/SRB2" #define DEFAULTWADLOCATION2 "/usr/local/games/SRB2"
@ -143,7 +143,6 @@ typedef LPVOID (WINAPI *p_MapViewOfFile) (HANDLE, DWORD, DWORD, DWORD, SIZE_T);
/** \brief WAD file to look for /** \brief WAD file to look for
*/ */
#define WADKEYWORD1 "srb2.pk3" #define WADKEYWORD1 "srb2.pk3"
#define WADKEYWORD2 "srb2.wad"
/** \brief holds wad path /** \brief holds wad path
*/ */
static char returnWadPath[256]; static char returnWadPath[256];
@ -2511,14 +2510,6 @@ static boolean isWadPathOk(const char *path)
return true; return true;
} }
sprintf(wad3path, pandf, path, WADKEYWORD2);
if (FIL_ReadFileOK(wad3path))
{
free(wad3path);
return true;
}
free(wad3path); free(wad3path);
return false; return false;
} }
@ -2536,7 +2527,7 @@ static void pathonly(char *s)
} }
} }
/** \brief search for srb2.srb in the given path /** \brief search for srb2.pk3 in the given path
\param searchDir starting path \param searchDir starting path
@ -2557,19 +2548,12 @@ static const char *searchWad(const char *searchDir)
return tempsw; return tempsw;
} }
strcpy(tempsw, WADKEYWORD2);
fstemp = filesearch(tempsw, searchDir, NULL, true, 20);
if (fstemp == FS_FOUND)
{
pathonly(tempsw);
return tempsw;
}
return NULL; return NULL;
} }
/** \brief go through all possible paths and look for srb2.srb /** \brief go through all possible paths and look for srb2.pk3
\return path to srb2.srb if any \return path to srb2.pk3 if any
*/ */
static const char *locateWad(void) static const char *locateWad(void)
{ {
@ -2698,7 +2682,7 @@ const char *I_LocateWad(void)
if (waddir) if (waddir)
{ {
// change to the directory where we found srb2.srb // change to the directory where we found srb2.pk3
#if defined (_WIN32) #if defined (_WIN32)
SetCurrentDirectoryA(waddir); SetCurrentDirectoryA(waddir);
#else #else
@ -2709,7 +2693,7 @@ const char *I_LocateWad(void)
return waddir; return waddir;
} }
#if defined(LINUX) || defined(LINUX64) #ifdef __linux__
#define MEMINFO_FILE "/proc/meminfo" #define MEMINFO_FILE "/proc/meminfo"
#define MEMTOTAL "MemTotal:" #define MEMTOTAL "MemTotal:"
#define MEMFREE "MemFree:" #define MEMFREE "MemFree:"
@ -2729,20 +2713,23 @@ UINT32 I_GetFreeMem(UINT32 *total)
}; };
if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open")) == NULL) if ((kd = kvm_open(NULL, NULL, NULL, O_RDONLY, "kvm_open")) == NULL)
{ {
*total = 0L; if (total)
*total = 0L;
return 0; return 0;
} }
if (kvm_nlist(kd, namelist) != 0) if (kvm_nlist(kd, namelist) != 0)
{ {
kvm_close (kd); kvm_close (kd);
*total = 0L; if (total)
*total = 0L;
return 0; return 0;
} }
if (kvm_read(kd, namelist[X_SUM].n_value, &sum, if (kvm_read(kd, namelist[X_SUM].n_value, &sum,
sizeof (sum)) != sizeof (sum)) sizeof (sum)) != sizeof (sum))
{ {
kvm_close(kd); kvm_close(kd);
*total = 0L; if (total)
*total = 0L;
return 0; return 0;
} }
kvm_close(kd); kvm_close(kd);
@ -2763,7 +2750,7 @@ UINT32 I_GetFreeMem(UINT32 *total)
if (total) if (total)
*total = (UINT32)info.dwTotalPhys; *total = (UINT32)info.dwTotalPhys;
return (UINT32)info.dwAvailPhys; return (UINT32)info.dwAvailPhys;
#elif defined (LINUX) || defined (LINUX64) #elif defined (__linux__)
/* Linux */ /* Linux */
char buf[1024]; char buf[1024];
char *memTag; char *memTag;
@ -2779,25 +2766,28 @@ UINT32 I_GetFreeMem(UINT32 *total)
if (n < 0) if (n < 0)
{ {
// Error // Error
*total = 0L; if (total)
*total = 0L;
return 0; return 0;
} }
buf[n] = '\0'; buf[n] = '\0';
if (NULL == (memTag = strstr(buf, MEMTOTAL))) if ((memTag = strstr(buf, MEMTOTAL)) == NULL)
{ {
// Error // Error
*total = 0L; if (total)
*total = 0L;
return 0; return 0;
} }
memTag += sizeof (MEMTOTAL); memTag += sizeof (MEMTOTAL);
totalKBytes = atoi(memTag); totalKBytes = atoi(memTag);
if (NULL == (memTag = strstr(buf, MEMFREE))) if ((memTag = strstr(buf, MEMFREE)) == NULL)
{ {
// Error // Error
*total = 0L; if (total)
*total = 0L;
return 0; return 0;
} }
@ -2812,7 +2802,7 @@ UINT32 I_GetFreeMem(UINT32 *total)
if (total) if (total)
*total = 48<<20; *total = 48<<20;
return 48<<20; return 48<<20;
#endif /* LINUX */ #endif
} }
const CPUInfoFlags *I_CPUInfo(void) const CPUInfoFlags *I_CPUInfo(void)

View File

@ -520,7 +520,7 @@ static void ST_drawDebugInfo(void)
if (cv_debug & DBG_MEMORY) if (cv_debug & DBG_MEMORY)
{ {
V_DrawRightAlignedString(320, height, VFLAGS, va("Heap: %7sKB", sizeu1(Z_TagsUsage(0, INT32_MAX)>>10))); V_DrawRightAlignedString(320, height, VFLAGS, va("Heap: %7sKB", sizeu1(Z_TotalUsage()>>10)));
} }
#undef VFLAGS #undef VFLAGS

View File

@ -190,6 +190,7 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum)
if (posStart != INT16_MAX) if (posStart != INT16_MAX)
{ {
posEnd = W_CheckNumForFolderEndPK3("Lua/", wadnum, posStart); posEnd = W_CheckNumForFolderEndPK3("Lua/", wadnum, posStart);
posStart++; // first "lump" will be "Lua/" folder itself, so ignore it
for (; posStart < posEnd; posStart++) for (; posStart < posEnd; posStart++)
LUA_LoadLump(wadnum, posStart); LUA_LoadLump(wadnum, posStart);
} }
@ -197,8 +198,19 @@ static inline void W_LoadDehackedLumpsPK3(UINT16 wadnum)
if (posStart != INT16_MAX) if (posStart != INT16_MAX)
{ {
posEnd = W_CheckNumForFolderEndPK3("SOCs/", wadnum, posStart); posEnd = W_CheckNumForFolderEndPK3("SOCs/", wadnum, posStart);
posStart++; // first "lump" will be "SOCs/" folder itself, so ignore it
for(; posStart < posEnd; posStart++) for(; posStart < posEnd; posStart++)
{
lumpinfo_t *lump_p = &wadfiles[wadnum]->lumpinfo[posStart];
size_t length = strlen(wadfiles[wadnum]->filename) + 1 + strlen(lump_p->name2); // length of file name, '|', and lump name
char *name = malloc(length + 1);
sprintf(name, "%s|%s", wadfiles[wadnum]->filename, lump_p->name2);
name[length] = '\0';
CONS_Printf(M_GetText("Loading SOC from %s\n"), name);
DEH_LoadDehackedLumpPwad(wadnum, posStart); DEH_LoadDehackedLumpPwad(wadnum, posStart);
free(name);
}
} }
} }
@ -222,16 +234,14 @@ static inline void W_LoadDehackedLumps(UINT16 wadnum)
for (lump = 0; lump < wadfiles[wadnum]->numlumps; lump++, lump_p++) for (lump = 0; lump < wadfiles[wadnum]->numlumps; lump++, lump_p++)
if (memcmp(lump_p->name,"SOC_",4)==0) // Check for generic SOC lump if (memcmp(lump_p->name,"SOC_",4)==0) // Check for generic SOC lump
{ // shameless copy+paste of code from LUA_LoadLump { // shameless copy+paste of code from LUA_LoadLump
char *name = malloc(strlen(wadfiles[wadnum]->filename)+10); size_t length = strlen(wadfiles[wadnum]->filename) + 1 + strlen(lump_p->name2); // length of file name, '|', and lump name
strcpy(name, wadfiles[wadnum]->filename); char *name = malloc(length + 1);
if (!fasticmp(&name[strlen(name) - 4], ".soc")) { sprintf(name, "%s|%s", wadfiles[wadnum]->filename, lump_p->name2);
// If it's not a .soc file, copy the lump name in too. name[length] = '\0';
name[strlen(wadfiles[wadnum]->filename)] = '|';
M_Memcpy(name+strlen(wadfiles[wadnum]->filename)+1, lump_p->name, 8);
name[strlen(wadfiles[wadnum]->filename)+9] = '\0';
}
CONS_Printf(M_GetText("Loading SOC from %s\n"), name); CONS_Printf(M_GetText("Loading SOC from %s\n"), name);
DEH_LoadDehackedLumpPwad(wadnum, lump); DEH_LoadDehackedLumpPwad(wadnum, lump);
free(name);
} }
else if (memcmp(lump_p->name,"MAINCFG",8)==0) // Check for MAINCFG else if (memcmp(lump_p->name,"MAINCFG",8)==0) // Check for MAINCFG
{ {
@ -319,7 +329,7 @@ UINT16 W_InitFile(const char *filename)
FILE *handle; FILE *handle;
lumpinfo_t *lumpinfo; lumpinfo_t *lumpinfo;
wadfile_t *wadfile; wadfile_t *wadfile;
enum restype type; restype_t type;
UINT16 numlumps; UINT16 numlumps;
size_t i; size_t i;
INT32 compressed = 0; INT32 compressed = 0;
@ -390,7 +400,7 @@ UINT16 W_InitFile(const char *filename)
// This code emulates a wadfile with one lump name "OBJCTCFG" // This code emulates a wadfile with one lump name "OBJCTCFG"
// at position 0 and size of the whole file. // at position 0 and size of the whole file.
// This allows soc files to be like all wads, copied by network and loaded at the console. // This allows soc files to be like all wads, copied by network and loaded at the console.
type = RET_WAD; type = RET_SOC;
numlumps = 1; numlumps = 1;
lumpinfo = Z_Calloc(sizeof (*lumpinfo), PU_STATIC, NULL); lumpinfo = Z_Calloc(sizeof (*lumpinfo), PU_STATIC, NULL);
@ -411,7 +421,7 @@ UINT16 W_InitFile(const char *filename)
// This code emulates a wadfile with one lump name "LUA_INIT" // This code emulates a wadfile with one lump name "LUA_INIT"
// at position 0 and size of the whole file. // at position 0 and size of the whole file.
// This allows soc files to be like all wads, copied by network and loaded at the console. // This allows soc files to be like all wads, copied by network and loaded at the console.
type = RET_WAD; type = RET_LUA;
numlumps = 1; numlumps = 1;
lumpinfo = Z_Calloc(sizeof (*lumpinfo), PU_STATIC, NULL); lumpinfo = Z_Calloc(sizeof (*lumpinfo), PU_STATIC, NULL);
@ -733,11 +743,24 @@ UINT16 W_InitFile(const char *filename)
numwadfiles++; // must come BEFORE W_LoadDehackedLumps, so any addfile called by COM_BufInsertText called by Lua doesn't overwrite what we just loaded numwadfiles++; // must come BEFORE W_LoadDehackedLumps, so any addfile called by COM_BufInsertText called by Lua doesn't overwrite what we just loaded
// TODO: HACK ALERT - Load Lua & SOC stuff right here. I feel like this should be out of this place, but... Let's stick with this for now. // TODO: HACK ALERT - Load Lua & SOC stuff right here. I feel like this should be out of this place, but... Let's stick with this for now.
if (wadfile->type == RET_WAD) switch (wadfile->type)
W_LoadDehackedLumps(numwadfiles - 1); {
else if (wadfile->type == RET_PK3) case RET_WAD:
W_LoadDehackedLumpsPK3(numwadfiles - 1); W_LoadDehackedLumps(numwadfiles - 1);
break;
case RET_PK3:
W_LoadDehackedLumpsPK3(numwadfiles - 1);
break;
case RET_SOC:
CONS_Printf(M_GetText("Loading SOC from %s\n"), wadfile->filename);
DEH_LoadDehackedLumpPwad(numwadfiles - 1, 0);
break;
case RET_LUA:
LUA_LoadLump(numwadfiles - 1, 0);
break;
default:
break;
}
W_InvalidateLumpnumCache(); W_InvalidateLumpnumCache();
@ -1038,6 +1061,24 @@ size_t W_LumpLength(lumpnum_t lumpnum)
return W_LumpLengthPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum)); return W_LumpLengthPwad(WADFILENUM(lumpnum),LUMPNUM(lumpnum));
} }
//
// W_IsLumpWad
// Is the lump a WAD? (presumably in a PK3)
//
boolean W_IsLumpWad(lumpnum_t lumpnum)
{
if (wadfiles[WADFILENUM(lumpnum)]->type == RET_PK3)
{
const char *lumpfullName = (wadfiles[WADFILENUM(lumpnum)]->lumpinfo + LUMPNUM(lumpnum))->name2;
if (strlen(lumpfullName) < 4)
return false; // can't possibly be a WAD can it?
return !strnicmp(lumpfullName + strlen(lumpfullName) - 4, ".wad", 4);
}
return false; // WADs should never be inside non-PK3s as far as SRB2 is concerned
}
/* report a zlib or i/o error */ /* report a zlib or i/o error */
void zerr(int ret) void zerr(int ret)
{ {
@ -1117,30 +1158,30 @@ size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, si
I_Error("wad %d, lump %d: cannot read compressed data", wad, lump); I_Error("wad %d, lump %d: cannot read compressed data", wad, lump);
retval = lzf_decompress(rawData, l->disksize, decData, l->size); retval = lzf_decompress(rawData, l->disksize, decData, l->size);
#ifndef AVOID_ERRNO #ifndef AVOID_ERRNO
if (retval == 0 && errno == E2BIG) // errno is a global var set by the lzf functions when something goes wrong. if (retval == 0) // If this was returned, check if errno was set
{ {
I_Error("wad %d, lump %d: compressed data too big (bigger than %s)", wad, lump, sizeu1(l->size)); // errno is a global var set by the lzf functions when something goes wrong.
if (errno == E2BIG)
I_Error("wad %d, lump %d: compressed data too big (bigger than %s)", wad, lump, sizeu1(l->size));
else if (errno == EINVAL)
I_Error("wad %d, lump %d: invalid compressed data", wad, lump);
} }
else if (retval == 0 && errno == EINVAL) // Otherwise, fall back on below error (if zero was actually the correct size then ???)
I_Error("wad %d, lump %d: invalid compressed data", wad, lump);
else
#endif #endif
if (retval != l->size) if (retval != l->size)
{ {
I_Error("wad %d, lump %d: decompressed to wrong number of bytes (expected %s, got %s)", wad, lump, sizeu1(l->size), sizeu2(retval)); I_Error("wad %d, lump %d: decompressed to wrong number of bytes (expected %s, got %s)", wad, lump, sizeu1(l->size), sizeu2(retval));
} }
#else
(void)wad;
(void)lump;
//I_Error("ZWAD files not supported on this platform.");
return NULL;
#endif
if (!decData) // Did we get no data at all? if (!decData) // Did we get no data at all?
return 0; return 0;
M_Memcpy(dest, decData + offset, size); M_Memcpy(dest, decData + offset, size);
Z_Free(rawData); Z_Free(rawData);
Z_Free(decData); Z_Free(decData);
return size; return size;
#else
//I_Error("ZWAD files not supported on this platform.");
return 0;
#endif
} }
case CM_DEFLATE: // Is it compressed via DEFLATE? Very common in ZIPs/PK3s, also what most doom-related editors support. case CM_DEFLATE: // Is it compressed via DEFLATE? Very common in ZIPs/PK3s, also what most doom-related editors support.
{ {

View File

@ -78,12 +78,18 @@ typedef struct
#endif #endif
// Resource type of the WAD. Yeah, I know this sounds dumb, but I'll leave it like this until I clean up the code further. // Resource type of the WAD. Yeah, I know this sounds dumb, but I'll leave it like this until I clean up the code further.
enum restype {RET_WAD, RET_PK3}; typedef enum restype
{
RET_WAD,
RET_SOC,
RET_LUA,
RET_PK3
} restype_t;
typedef struct wadfile_s typedef struct wadfile_s
{ {
char *filename; char *filename;
enum restype type; restype_t type;
lumpinfo_t *lumpinfo; lumpinfo_t *lumpinfo;
lumpcache_t *lumpcache; lumpcache_t *lumpcache;
#ifdef HWRENDER #ifdef HWRENDER
@ -133,6 +139,8 @@ UINT8 W_LumpExists(const char *name); // Lua uses this.
size_t W_LumpLengthPwad(UINT16 wad, UINT16 lump); size_t W_LumpLengthPwad(UINT16 wad, UINT16 lump);
size_t W_LumpLength(lumpnum_t lumpnum); size_t W_LumpLength(lumpnum_t lumpnum);
boolean W_IsLumpWad(lumpnum_t lumpnum); // for loading maps from WADs in PK3s
void zerr(int ret); // zlib error checking void zerr(int ret); // zlib error checking
size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, size_t offset); size_t W_ReadLumpHeaderPwad(UINT16 wad, UINT16 lump, void *dest, size_t size, size_t offset);

View File

@ -82,6 +82,59 @@ typedef struct memblock_s
struct memblock_s *next, *prev; struct memblock_s *next, *prev;
} ATTRPACK memblock_t; } ATTRPACK memblock_t;
// both the head and tail of the zone memory block list
static memblock_t head;
//
// Function prototypes
//
static void Command_Memfree_f(void);
#ifdef ZDEBUG
static void Command_Memdump_f(void);
#endif
// --------------------------
// Zone memory initialisation
// --------------------------
/** Initialises zone memory.
* Used at game startup.
*
* \sa I_GetFreeMem, Command_Memfree_f, Command_Memdump_f
*/
void Z_Init(void)
{
UINT32 total, memfree;
memset(&head, 0x00, sizeof(head));
head.next = head.prev = &head;
memfree = I_GetFreeMem(&total)>>20;
CONS_Printf("System memory: %uMB - Free: %uMB\n", total>>20, memfree);
// Note: This allocates memory. Watch out.
COM_AddCommand("memfree", Command_Memfree_f);
#ifdef ZDEBUG
COM_AddCommand("memdump", Command_Memdump_f);
#endif
}
// ----------------------
// Zone memory allocation
// ----------------------
/** Returns the corresponding memblock_t for a given memory block.
*
* \param ptr A pointer to allocated memory,
* assumed to have been allocated with Z_Malloc/Z_Calloc.
* \param func A string containing the name of the function that called this,
* to be printed if the function I_Errors
* \return A pointer to the memblock_t for the given memory.
* \sa Z_Free, Z_ReallocAlign
*/
#ifdef ZDEBUG #ifdef ZDEBUG
#define Ptr2Memblock(s, f) Ptr2Memblock2(s, f, __FILE__, __LINE__) #define Ptr2Memblock(s, f) Ptr2Memblock2(s, f, __FILE__, __LINE__)
static memblock_t *Ptr2Memblock2(void *ptr, const char* func, const char *file, INT32 line) static memblock_t *Ptr2Memblock2(void *ptr, const char* func, const char *file, INT32 line)
@ -131,32 +184,12 @@ static memblock_t *Ptr2Memblock(void *ptr, const char* func)
} }
static memblock_t head; /** Frees allocated memory.
*
static void Command_Memfree_f(void); * \param ptr A pointer to allocated memory,
#ifdef ZDEBUG * assumed to have been allocated with Z_Malloc/Z_Calloc.
static void Command_Memdump_f(void); * \sa Z_FreeTags
#endif */
void Z_Init(void)
{
UINT32 total, memfree;
memset(&head, 0x00, sizeof(head));
head.next = head.prev = &head;
memfree = I_GetFreeMem(&total)>>20;
CONS_Printf("System memory: %uMB - Free: %uMB\n", total>>20, memfree);
// Note: This allocates memory. Watch out.
COM_AddCommand("memfree", Command_Memfree_f);
#ifdef ZDEBUG
COM_AddCommand("memdump", Command_Memdump_f);
#endif
}
#ifdef ZDEBUG #ifdef ZDEBUG
void Z_Free2(void *ptr, const char *file, INT32 line) void Z_Free2(void *ptr, const char *file, INT32 line)
#else #else
@ -206,7 +239,11 @@ void Z_Free(void *ptr)
#endif #endif
} }
// malloc() that doesn't accept failure. /** malloc() that doesn't accept failure.
*
* \param size Amount of memory to be allocated, in bytes.
* \return A pointer to the allocated memory.
*/
static void *xm(size_t size) static void *xm(size_t size)
{ {
const size_t padedsize = size+sizeof (size_t); const size_t padedsize = size+sizeof (size_t);
@ -227,10 +264,18 @@ static void *xm(size_t size)
return p; return p;
} }
// Z_Malloc /** The Z_MallocAlign function.
// You can pass Z_Malloc() a NULL user if the tag is less than * Allocates a block of memory, adds it to a linked list so we can keep track of it.
// PU_PURGELEVEL. *
* \param size Amount of memory to be allocated, in bytes.
* \param tag Purge tag.
* \param user The address of a pointer to the memory to be allocated.
* When the memory is freed by Z_Free later,
* the pointer at this address will then be automatically set to NULL.
* \param alignbits The alignment of the memory to be allocated, in bits. Can be 0.
* \note You can pass Z_Malloc() a NULL user if the tag is less than PU_PURGELEVEL.
* \sa Z_CallocAlign, Z_ReallocAlign
*/
#ifdef ZDEBUG #ifdef ZDEBUG
void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits, void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits,
const char *file, INT32 line) const char *file, INT32 line)
@ -307,6 +352,19 @@ void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits)
return given; return given;
} }
/** The Z_CallocAlign function.
* Allocates a block of memory, adds it to a linked list so we can keep track of it.
* Unlike Z_MallocAlign, this also initialises the bytes to zero.
*
* \param size Amount of memory to be allocated, in bytes.
* \param tag Purge tag.
* \param user The address of a pointer to the memory to be allocated.
* When the memory is freed by Z_Free later,
* the pointer at this address will then be automatically set to NULL.
* \param alignbits The alignment of the memory to be allocated, in bits. Can be 0.
* \note You can pass Z_Calloc() a NULL user if the tag is less than PU_PURGELEVEL.
* \sa Z_MallocAlign, Z_ReallocAlign
*/
#ifdef ZDEBUG #ifdef ZDEBUG
void *Z_Calloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) void *Z_Calloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line)
#else #else
@ -323,10 +381,26 @@ void *Z_CallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits)
#endif #endif
} }
/** The Z_ReallocAlign function.
* Reallocates a block of memory with a new size.
*
* \param ptr A pointer to allocated memory,
* assumed to have been allocated with Z_Malloc/Z_Calloc.
* If NULL, this function instead acts as a wrapper for Z_CallocAlign.
* \param size New size of memory block, in bytes.
* If zero, then the memory is freed and NULL is returned.
* \param tag New purge tag.
* \param user The address of a pointer to the memory to be reallocated.
* This can be a different user to the one originally assigned to the memory block.
* \param alignbits The alignment of the memory to be allocated, in bits. Can be 0.
* \return A pointer to the reallocated memory. Can be NULL if memory was freed.
* \note You can pass Z_Realloc() a NULL user if the tag is less than PU_PURGELEVEL.
* \sa Z_MallocAlign, Z_CallocAlign
*/
#ifdef ZDEBUG #ifdef ZDEBUG
void *Z_Realloc2(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) void *Z_Realloc2(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line)
#else #else
void *Z_ReallocAlign(void *ptr, size_t size,INT32 tag, void *user, INT32 alignbits) void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits)
#endif #endif
{ {
void *rez; void *rez;
@ -393,6 +467,11 @@ void *Z_ReallocAlign(void *ptr, size_t size,INT32 tag, void *user, INT32 alignb
return rez; return rez;
} }
/** Frees all memory for a given set of tags.
*
* \param lowtag The lowest tag to consider.
* \param hightag The highest tag to consider.
*/
void Z_FreeTags(INT32 lowtag, INT32 hightag) void Z_FreeTags(INT32 lowtag, INT32 hightag)
{ {
memblock_t *block, *next; memblock_t *block, *next;
@ -407,22 +486,25 @@ void Z_FreeTags(INT32 lowtag, INT32 hightag)
} }
} }
// // -----------------
// Z_CheckMemCleanup // Utility functions
// // -----------------
// TODO: Currently blocks >= PU_PURGELEVEL are freed every
// CLEANUPCOUNT. It might be better to keep track of
// the total size of all purgable memory and free it when the
// size exceeds some value.
//
// This was in Z_Malloc, but was freeing data at
// unsafe times. Now it is only called when it is safe
// to cleanup memory.
// starting value of nextcleanup
#define CLEANUPCOUNT 2000 #define CLEANUPCOUNT 2000
// number of function calls left before next cleanup
static INT32 nextcleanup = CLEANUPCOUNT; static INT32 nextcleanup = CLEANUPCOUNT;
/** This was in Z_Malloc, but was freeing data at
* unsafe times. Now it is only called when it is safe
* to cleanup memory.
*
* \todo Currently blocks >= PU_PURGELEVEL are freed every
* CLEANUPCOUNT. It might be better to keep track of
* the total size of all purgable memory and free it when the
* size exceeds some value.
*/
void Z_CheckMemCleanup(void) void Z_CheckMemCleanup(void)
{ {
if (nextcleanup-- == 0) if (nextcleanup-- == 0)
@ -538,10 +620,21 @@ void Z_CheckHeap(INT32 i)
} }
} }
// ------------------------
// Zone memory modification
// ------------------------
/** Changes a memory block's purge tag.
*
* \param ptr A pointer to allocated memory,
* assumed to have been allocated with Z_Malloc/Z_Calloc.
* \param tag The new tag.
* \sa Z_SetUser
*/
#ifdef PARANOIA #ifdef PARANOIA
void Z_ChangeTag2(void *ptr, INT32 tag, const char *file, INT32 line) void Z_ChangeTag2(void *ptr, INT32 tag, const char *file, INT32 line)
#else #else
void Z_ChangeTag2(void *ptr, INT32 tag) void Z_ChangeTag(void *ptr, INT32 tag)
#endif #endif
{ {
memblock_t *block; memblock_t *block;
@ -583,99 +676,17 @@ void Z_ChangeTag2(void *ptr, INT32 tag)
block->tag = tag; block->tag = tag;
} }
/** Calculates memory usage for a given set of tags. /** Changes a memory block's user.
* \param lowtag The lowest tag to consider. *
* \param hightag The highest tag to consider. * \param ptr A pointer to allocated memory,
* \return Number of bytes currently allocated in the heap for the * assumed to have been allocated with Z_Malloc/Z_Calloc.
* given tags. * \param newuser The new user for the memory block.
* \sa Z_TagUsage * \sa Z_ChangeTag
*/ */
size_t Z_TagsUsage(INT32 lowtag, INT32 hightag)
{
size_t cnt = 0;
memblock_t *rover;
for (rover = head.next; rover != &head; rover = rover->next)
{
if (rover->tag < lowtag || rover->tag > hightag)
continue;
cnt += rover->size + sizeof *rover;
}
return cnt;
}
size_t Z_TagUsage(INT32 tagnum)
{
return Z_TagsUsage(tagnum, tagnum);
}
void Command_Memfree_f(void)
{
UINT32 freebytes, totalbytes;
Z_CheckHeap(-1);
CONS_Printf("\x82%s", M_GetText("Memory Info\n"));
CONS_Printf(M_GetText("Total heap used : %7s KB\n"), sizeu1(Z_TagsUsage(0, INT32_MAX)>>10));
CONS_Printf(M_GetText("Static : %7s KB\n"), sizeu1(Z_TagUsage(PU_STATIC)>>10));
CONS_Printf(M_GetText("Static (sound) : %7s KB\n"), sizeu1(Z_TagUsage(PU_SOUND)>>10));
CONS_Printf(M_GetText("Static (music) : %7s KB\n"), sizeu1(Z_TagUsage(PU_MUSIC)>>10));
CONS_Printf(M_GetText("Locked cache : %7s KB\n"), sizeu1(Z_TagUsage(PU_CACHE)>>10));
CONS_Printf(M_GetText("Level : %7s KB\n"), sizeu1(Z_TagUsage(PU_LEVEL)>>10));
CONS_Printf(M_GetText("Special thinker : %7s KB\n"), sizeu1(Z_TagUsage(PU_LEVSPEC)>>10));
CONS_Printf(M_GetText("All purgable : %7s KB\n"),
sizeu1(Z_TagsUsage(PU_PURGELEVEL, INT32_MAX)>>10));
#ifdef HWRENDER
if (rendermode != render_soft && rendermode != render_none)
{
CONS_Printf(M_GetText("Patch info headers: %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHINFO)>>10));
CONS_Printf(M_GetText("Mipmap patches : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHCOLMIPMAP)>>10));
CONS_Printf(M_GetText("HW Texture cache : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRCACHE)>>10));
CONS_Printf(M_GetText("Plane polygons : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPLANE)>>10));
CONS_Printf(M_GetText("HW Texture used : %7d KB\n"), HWR_GetTextureUsed()>>10);
}
#endif
CONS_Printf("\x82%s", M_GetText("System Memory Info\n"));
freebytes = I_GetFreeMem(&totalbytes);
CONS_Printf(M_GetText(" Total physical memory: %7u KB\n"), totalbytes>>10);
CONS_Printf(M_GetText("Available physical memory: %7u KB\n"), freebytes>>10);
}
#ifdef ZDEBUG
static void Command_Memdump_f(void)
{
memblock_t *block;
INT32 mintag = 0, maxtag = INT32_MAX;
INT32 i;
if ((i = COM_CheckParm("-min")))
mintag = atoi(COM_Argv(i + 1));
if ((i = COM_CheckParm("-max")))
maxtag = atoi(COM_Argv(i + 1));
for (block = head.next; block != &head; block = block->next)
if (block->tag >= mintag && block->tag <= maxtag)
{
char *filename = strrchr(block->ownerfile, PATHSEP[0]);
CONS_Printf("[%3d] %s (%s) bytes @ %s:%d\n", block->tag, sizeu1(block->size), sizeu2(block->realsize), filename ? filename + 1 : block->ownerfile, block->ownerline);
}
}
#endif
// Creates a copy of a string.
char *Z_StrDup(const char *s)
{
return strcpy(ZZ_Alloc(strlen(s) + 1), s);
}
#ifdef PARANOIA #ifdef PARANOIA
void Z_SetUser2(void *ptr, void **newuser, const char *file, INT32 line) void Z_SetUser2(void *ptr, void **newuser, const char *file, INT32 line)
#else #else
void Z_SetUser2(void *ptr, void **newuser) void Z_SetUser(void *ptr, void **newuser)
#endif #endif
{ {
memblock_t *block; memblock_t *block;
@ -707,3 +718,106 @@ void Z_SetUser2(void *ptr, void **newuser)
block->user = (void*)newuser; block->user = (void*)newuser;
*newuser = ptr; *newuser = ptr;
} }
// -----------------
// Zone memory usage
// -----------------
/** Calculates memory usage for a given set of tags.
*
* \param lowtag The lowest tag to consider.
* \param hightag The highest tag to consider.
* \return Number of bytes currently allocated in the heap for the
* given tags.
*/
size_t Z_TagsUsage(INT32 lowtag, INT32 hightag)
{
size_t cnt = 0;
memblock_t *rover;
for (rover = head.next; rover != &head; rover = rover->next)
{
if (rover->tag < lowtag || rover->tag > hightag)
continue;
cnt += rover->size + sizeof *rover;
}
return cnt;
}
// -----------------------
// Miscellaneous functions
// -----------------------
/** The function called by the "memfree" console command.
* Prints the memory being used by each part of the game to the console.
*/
static void Command_Memfree_f(void)
{
UINT32 freebytes, totalbytes;
Z_CheckHeap(-1);
CONS_Printf("\x82%s", M_GetText("Memory Info\n"));
CONS_Printf(M_GetText("Total heap used : %7s KB\n"), sizeu1(Z_TotalUsage()>>10));
CONS_Printf(M_GetText("Static : %7s KB\n"), sizeu1(Z_TagUsage(PU_STATIC)>>10));
CONS_Printf(M_GetText("Static (sound) : %7s KB\n"), sizeu1(Z_TagUsage(PU_SOUND)>>10));
CONS_Printf(M_GetText("Static (music) : %7s KB\n"), sizeu1(Z_TagUsage(PU_MUSIC)>>10));
CONS_Printf(M_GetText("Locked cache : %7s KB\n"), sizeu1(Z_TagUsage(PU_CACHE)>>10));
CONS_Printf(M_GetText("Level : %7s KB\n"), sizeu1(Z_TagUsage(PU_LEVEL)>>10));
CONS_Printf(M_GetText("Special thinker : %7s KB\n"), sizeu1(Z_TagUsage(PU_LEVSPEC)>>10));
CONS_Printf(M_GetText("All purgable : %7s KB\n"),
sizeu1(Z_TagsUsage(PU_PURGELEVEL, INT32_MAX)>>10));
#ifdef HWRENDER
if (rendermode != render_soft && rendermode != render_none)
{
CONS_Printf(M_GetText("Patch info headers: %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHINFO)>>10));
CONS_Printf(M_GetText("Mipmap patches : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPATCHCOLMIPMAP)>>10));
CONS_Printf(M_GetText("HW Texture cache : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRCACHE)>>10));
CONS_Printf(M_GetText("Plane polygons : %7s KB\n"), sizeu1(Z_TagUsage(PU_HWRPLANE)>>10));
CONS_Printf(M_GetText("HW Texture used : %7d KB\n"), HWR_GetTextureUsed()>>10);
}
#endif
CONS_Printf("\x82%s", M_GetText("System Memory Info\n"));
freebytes = I_GetFreeMem(&totalbytes);
CONS_Printf(M_GetText(" Total physical memory: %7u KB\n"), totalbytes>>10);
CONS_Printf(M_GetText("Available physical memory: %7u KB\n"), freebytes>>10);
}
#ifdef ZDEBUG
/** The function called by the "memdump" console command.
* Prints zone memory debugging information (i.e. tag, size, location in code allocated).
* Can be all memory allocated in game, or between a set of tags (if -min/-max args used).
* This command is available only if ZDEBUG is enabled.
*/
static void Command_Memdump_f(void)
{
memblock_t *block;
INT32 mintag = 0, maxtag = INT32_MAX;
INT32 i;
if ((i = COM_CheckParm("-min")))
mintag = atoi(COM_Argv(i + 1));
if ((i = COM_CheckParm("-max")))
maxtag = atoi(COM_Argv(i + 1));
for (block = head.next; block != &head; block = block->next)
if (block->tag >= mintag && block->tag <= maxtag)
{
char *filename = strrchr(block->ownerfile, PATHSEP[0]);
CONS_Printf("[%3d] %s (%s) bytes @ %s:%d\n", block->tag, sizeu1(block->size), sizeu2(block->realsize), filename ? filename + 1 : block->ownerfile, block->ownerline);
}
}
#endif
/** Creates a copy of a string.
*
* \param s The string to be copied.
* \return A copy of the string, allocated in zone memory.
*/
char *Z_StrDup(const char *s)
{
return strcpy(ZZ_Alloc(strlen(s) + 1), s);
}

View File

@ -30,92 +30,115 @@
//#define ZDEBUG //#define ZDEBUG
// //
// ZONE MEMORY // Purge tags
// PU - purge tags. //
// Tags < PU_LEVEL are not purged until freed explicitly. // Now they are an enum! -- Monster Iestyn 15/02/18
#define PU_STATIC 1 // static entire execution time //
#define PU_LUA 2 // static entire execution time -- used by lua so it doesn't get caught in loops forever enum
{
// Tags < PU_LEVEL are not purged until freed explicitly.
PU_STATIC = 1, // static entire execution time
PU_LUA = 2, // static entire execution time -- used by lua so it doesn't get caught in loops forever
#define PU_SOUND 11 // static while playing PU_SOUND = 11, // static while playing
#define PU_MUSIC 12 // static while playing PU_MUSIC = 12, // static while playing
#define PU_HUDGFX 13 // static until WAD added PU_HUDGFX = 13, // static until WAD added
#define PU_HWRPATCHINFO 21 // Hardware GLPatch_t struct for OpenGL texture cache PU_HWRPATCHINFO = 21, // Hardware GLPatch_t struct for OpenGL texture cache
#define PU_HWRPATCHCOLMIPMAP 22 // Hardware GLMipmap_t struct colromap variation of patch PU_HWRPATCHCOLMIPMAP = 22, // Hardware GLMipmap_t struct colormap variation of patch
#define PU_HWRCACHE 48 // static until unlocked PU_HWRCACHE = 48, // static until unlocked
#define PU_CACHE 49 // static until unlocked PU_CACHE = 49, // static until unlocked
// Tags s.t. PU_LEVEL <= tag < PU_PURGELEVEL are purged at level start // Tags s.t. PU_LEVEL <= tag < PU_PURGELEVEL are purged at level start
#define PU_LEVEL 50 // static until level exited PU_LEVEL = 50, // static until level exited
#define PU_LEVSPEC 51 // a special thinker in a level PU_LEVSPEC = 51, // a special thinker in a level
#define PU_HWRPLANE 52 PU_HWRPLANE = 52, // if ZPLANALLOC is enabled in hw_bsp.c, this is used to alloc polygons for OpenGL
// Tags >= PU_PURGELEVEL are purgable whenever needed // Tags >= PU_PURGELEVEL are purgable whenever needed
#define PU_PURGELEVEL 100 PU_PURGELEVEL = 100, // Note: this is never actually used as a tag
#define PU_CACHE_UNLOCKED 101 PU_CACHE_UNLOCKED = 101, // Note: unused
#define PU_HWRCACHE_UNLOCKED 102 // 'second-level' cache for graphics PU_HWRCACHE_UNLOCKED = 102, // 'unlocked' PU_HWRCACHE memory:
// stored in hardware format and downloaded as needed // 'second-level' cache for graphics
#define PU_HWRPATCHINFO_UNLOCKED 103 // stored in hardware format and downloaded as needed
PU_HWRPATCHINFO_UNLOCKED = 103, // 'unlocked' PU_HWRPATCHINFO memory
};
//
// Zone memory initialisation
//
void Z_Init(void); void Z_Init(void);
void Z_FreeTags(INT32 lowtag, INT32 hightag);
void Z_CheckMemCleanup(void);
void Z_CheckHeap(INT32 i);
#ifdef PARANOIA
void Z_ChangeTag2(void *ptr, INT32 tag, const char *file, INT32 line);
#else
void Z_ChangeTag2(void *ptr, INT32 tag);
#endif
#ifdef PARANOIA //
void Z_SetUser2(void *ptr, void **newuser, const char *file, INT32 line); // Zone memory allocation
#else //
void Z_SetUser2(void *ptr, void **newuser); // enable ZDEBUG to get the file + line the functions were called from
#endif // for ZZ_Alloc, see doomdef.h
//
// Z_Free and alloc with alignment
#ifdef ZDEBUG #ifdef ZDEBUG
#define Z_Free(p) Z_Free2(p, __FILE__, __LINE__) #define Z_Free(p) Z_Free2(p, __FILE__, __LINE__)
void Z_Free2(void *ptr, const char *file, INT32 line); #define Z_MallocAlign(s,t,u,a) Z_Malloc2(s, t, u, a, __FILE__, __LINE__)
#define Z_Malloc(s,t,u) Z_Malloc2(s, t, u, 0, __FILE__, __LINE__) #define Z_CallocAlign(s,t,u,a) Z_Calloc2(s, t, u, a, __FILE__, __LINE__)
#define Z_MallocAlign(s,t,u,a) Z_Malloc2(s, t, u, a, __FILE__, __LINE__)
void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(1);
#define Z_Calloc(s,t,u) Z_Calloc2(s, t, u, 0, __FILE__, __LINE__)
#define Z_CallocAlign(s,t,u,a) Z_Calloc2(s, t, u, a, __FILE__, __LINE__)
void *Z_Calloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(1);
#define Z_Realloc(p,s,t,u) Z_Realloc2(p, s, t, u, 0, __FILE__, __LINE__)
#define Z_ReallocAlign(p,s,t,u,a) Z_Realloc2(p,s, t, u, a, __FILE__, __LINE__) #define Z_ReallocAlign(p,s,t,u,a) Z_Realloc2(p,s, t, u, a, __FILE__, __LINE__)
void Z_Free2(void *ptr, const char *file, INT32 line);
void *Z_Malloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(1);
void *Z_Calloc2(size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(1);
void *Z_Realloc2(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(2); void *Z_Realloc2(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits, const char *file, INT32 line) FUNCALLOC(2);
#else #else
void Z_Free(void *ptr); void Z_Free(void *ptr);
void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALLOC(1); void *Z_MallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALLOC(1);
#define Z_Malloc(s,t,u) Z_MallocAlign(s, t, u, 0)
void *Z_CallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALLOC(1); void *Z_CallocAlign(size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALLOC(1);
#define Z_Calloc(s,t,u) Z_CallocAlign(s, t, u, 0) void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALLOC(2);
void *Z_ReallocAlign(void *ptr, size_t size, INT32 tag, void *user, INT32 alignbits) FUNCALLOC(2) ;
#define Z_Realloc(p, s,t,u) Z_ReallocAlign(p, s, t, u, 0)
#endif #endif
size_t Z_TagUsage(INT32 tagnum); // Alloc with no alignment
size_t Z_TagsUsage(INT32 lowtag, INT32 hightag); #define Z_Malloc(s,t,u) Z_MallocAlign(s, t, u, 0)
#define Z_Calloc(s,t,u) Z_CallocAlign(s, t, u, 0)
#define Z_Realloc(p,s,t,u) Z_ReallocAlign(p, s, t, u, 0)
char *Z_StrDup(const char *in); // Free all memory by tag
// these don't give line numbers for ZDEBUG currently though
// (perhaps this should be changed in future?)
#define Z_FreeTag(tagnum) Z_FreeTags(tagnum, tagnum)
void Z_FreeTags(INT32 lowtag, INT32 hightag);
// This is used to get the local FILE : LINE info from CPP //
// prior to really call the function in question. // Utility functions
//
void Z_CheckMemCleanup(void);
void Z_CheckHeap(INT32 i);
//
// Zone memory modification
//
// enable PARANOIA to get the file + line the functions were called from
// //
#ifdef PARANOIA #ifdef PARANOIA
#define Z_ChangeTag(p,t) Z_ChangeTag2(p, t, __FILE__, __LINE__) #define Z_ChangeTag(p,t) Z_ChangeTag2(p, t, __FILE__, __LINE__)
#define Z_SetUser(p,u) Z_SetUser2(p, u, __FILE__, __LINE__)
void Z_ChangeTag2(void *ptr, INT32 tag, const char *file, INT32 line);
void Z_SetUser2(void *ptr, void **newuser, const char *file, INT32 line);
#else #else
#define Z_ChangeTag(p,t) Z_ChangeTag2(p, t) void Z_ChangeTag(void *ptr, INT32 tag);
void Z_SetUser(void *ptr, void **newuser);
#endif #endif
#ifdef PARANOIA //
#define Z_SetUser(p,u) Z_SetUser2(p, u, __FILE__, __LINE__) // Zone memory usage
#else //
#define Z_SetUser(p,u) Z_SetUser2(p, u) // Note: These give the memory used in bytes,
#endif // shift down by 10 to convert to KB
//
#define Z_TagUsage(tagnum) Z_TagsUsage(tagnum, tagnum)
size_t Z_TagsUsage(INT32 lowtag, INT32 hightag);
#define Z_TotalUsage() Z_TagsUsage(0, INT32_MAX)
#define Z_Unlock(p) (void)p //
// Miscellaneous functions
//
char *Z_StrDup(const char *in);
#define Z_Unlock(p) (void)p // TODO: remove this now that NDS code has been removed
#endif #endif