/** * \brief Shutdown game */ PUBLIC void Game_Shutdown( void ) { Com_Printf( "==== Game Shutdown ====\n" ); Z_FreeTags( TAG_LEVEL ); Z_FreeTags( TAG_GAME ); }
void ShutdownGame(void) { PF_dprintf("==== ShutdownGame ====\n"); Z_FreeTags(TAG_LEVEL); Z_FreeTags(TAG_GAME); }
void Z_Shutdown(void) { int numVolumes = 0; size_t totalMemory = 0; // Get rid of possible zone-allocated memory in the garbage. Garbage_RecycleAllWithDestructor(Z_Free); // Destroy all the memory volumes. while (volumeRoot) { memvolume_t *vol = volumeRoot; volumeRoot = vol->next; // Calculate stats. numVolumes++; totalMemory += vol->size; #ifdef LIBDENG_FAKE_MEMORY_ZONE Z_FreeTags(0, DDMAXINT); #endif M_Free(vol->zone); M_Free(vol); } App_Log(DE2_LOG_NOTE, "Z_Shutdown: Used %i volumes, total %u bytes.", numVolumes, totalMemory); Sys_DestroyMutex(zoneMutex); zoneMutex = 0; }
// // Z_Malloc // // You can pass a NULL user if the tag is < PU_PURGELEVEL. // void *(Z_Malloc)(size_t size, int tag, void **user, const char *file, int line) { memblock_t *block; byte *ret; DEBUG_CHECKHEAP(); Z_IDCheckNB(IDBOOL(tag >= PU_PURGELEVEL && !user), "Z_Malloc: an owner is required for purgable blocks", file, line); if(!size) return user ? *user = NULL : NULL; // malloc(0) returns NULL if(!(block = (memblock_t *)(malloc(size + header_size)))) { if(blockbytag[PU_CACHE]) { Z_FreeTags(PU_CACHE, PU_CACHE); block = (memblock_t *)(malloc(size + header_size)); } } if(!block) { I_FatalError(I_ERR_KILL, "Z_Malloc: Failure trying to allocate %u bytes\n" "Source: %s:%d\n", (unsigned int)size, file, line); } block->size = size; if((block->next = blockbytag[tag])) block->next->prev = &block->next; blockbytag[tag] = block; block->prev = &blockbytag[tag]; INSTRUMENT(memorybytag[tag] += block->size); INSTRUMENT(block->file = file); INSTRUMENT(block->line = line); IDCHECK(block->id = ZONEID); // signature required in block header block->tag = tag; // tag block->user = user; // user ret = ((byte *) block + header_size); if(user) // if there is a user *user = ret; // set user to point to new block // scramble memory -- weed out any bugs SCRAMBLER(ret, size); Z_LogPrintf("* %p = Z_Malloc(size=%lu, tag=%d, user=%p, source=%s:%d)\n", ret, size, tag, user, file, line); return ret; }
void WI_unloadData(void) { Z_FreeTags( PU_LEVEL_SHARED, PU_LEVEL_SHARED ); // HACK ALERT - reset these to help stability? they are used for consistency checking for (int i=0 ; i<MAXPLAYERS ; i++) { if (::g->playeringame[i]) { ::g->players[i].mo = NULL; } } ::g->bg = NULL; }
void Z_FreeTagsGame (int tag) { if (tag == TAG_GAME) tag = TAG_DLL_GAME; else if(tag == TAG_LEVEL) tag = TAG_DLL_LEVEL; else tag = tag + TAG_MAX_TAGS; #ifndef NDEBUG _Z_FreeTags(tag, "Game DLL", 2); #else Z_FreeTags(tag); #endif }
// // Z_Malloc // You can pass a NULL user if the tag is < PU_PURGELEVEL. // // cph - the algorithm here was a very simple first-fit round-robin // one - just keep looping around, freeing everything we can until // we get a large enough space // // This has been changed now; we still do the round-robin first-fit, // but we only free the blocks we actually end up using; we don't // free all the stuff we just pass on the way. // void *Z_Malloc(size_t size, int tag, void **user) { memblock_t *block = NULL; if (!size) return (user ? (*user = NULL) : NULL); // malloc(0) returns NULL size = (size + CHUNK_SIZE - 1) & ~(CHUNK_SIZE - 1); // round to chunk size while (!(block = malloc(size + headersize))) { if (!blockbytag[PU_CACHE]) I_Error("Z_Malloc: Failure trying to allocate %lu bytes", (unsigned long)size); Z_FreeTags(PU_CACHE, PU_CACHE); } if (!blockbytag[tag]) { blockbytag[tag] = block; block->next = block->prev = block; } else { blockbytag[tag]->prev->next = block; block->prev = blockbytag[tag]->prev; block->next = blockbytag[tag]; blockbytag[tag]->prev = block; } block->size = size; block->tag = tag; // tag block->user = user; // user block = (memblock_t *)((char *)block + headersize); if (user) // if there is a user *user = block; // set user to point to new block return block; }
// // Z_Malloc // You can pass a NULL user if the tag is < PU_PURGELEVEL. // void *Z_Malloc(int size, int tag, void **user) { memblock_t *block; byte *ret; if(tag >= PU_PURGELEVEL && !user) I_Error("Z_Malloc: an owner is required for purgable blocks"); if(!size) size = 32; // vanilla compat if(!(block = (memblock_t *)(malloc(size + header_size)))) { if(blockbytag[PU_CACHE]) { Z_FreeTags(PU_CACHE, PU_CACHE); block = (memblock_t *)(malloc(size + header_size)); } } if(!block) I_Error("Z_Malloc: failed on allocation of %u bytes", (unsigned int)size); block->size = size; if((block->next = blockbytag[tag])) block->next->prev = &block->next; blockbytag[tag] = block; block->prev = &blockbytag[tag]; block->id = ZONEID; block->tag = tag; block->user = user; ret = ((byte *)block + header_size); if(user) *user = ret; return ret; }
void* (Z_Malloc)(size_t size, int tag, void** user, const char* file, int line) { register memblock_t* block; memblock_t* start; #ifdef INSTRUMENTED size_t size_orig = size; #ifdef CHECKHEAP Z_CheckHeap(); #endif file_history[malloc_history][history_index[malloc_history]] = file; line_history[malloc_history][history_index[malloc_history]++] = line; history_index[malloc_history] &= ZONE_HISTORY - 1; #endif #ifdef ZONEIDCHECK if (tag >= PU_PURGELEVEL && !user) I_Error("Z_Malloc: an owner is required for purgable blocks\n" "Source: %s:%d", file, line); #endif if (!size) return user ? *user = NULL : NULL; // malloc(0) returns NULL size = (size + CHUNK_SIZE - 1) & ~(CHUNK_SIZE - 1); // round to chunk size block = rover; if (block->prev->tag == PU_FREE) block = block->prev; start = block; // haleyjd 06/17/08: import from EE: // the first if() inside the loop below contains cph's memory // purging efficiency fix do { // Free purgable blocks; replacement is roughly FIFO if (block->tag >= PU_PURGELEVEL) { start = block->prev; Z_Free((char*) block + HEADER_SIZE); /* cph - If start->next == block, we did not merge with the previous * If !=, we did, so we continue from start. * Important: we've reset start! */ if (start->next == block) start = start->next; else block = start; } if (block->tag == PU_FREE && block->size >= size) // First-fit { size_t extra = block->size - size; if (extra >= MIN_BLOCK_SPLIT + HEADER_SIZE) { memblock_t* newb = (memblock_t*)((char*) block + HEADER_SIZE + size); (newb->next = block->next)->prev = newb; (newb->prev = block)->next = newb; // Split up block block->size = size; newb->size = extra - HEADER_SIZE; newb->tag = PU_FREE; newb->vm = 0; #ifdef INSTRUMENTED inactive_memory += HEADER_SIZE; free_memory -= HEADER_SIZE; #endif } rover = block->next; // set roving pointer for next search #ifdef INSTRUMENTED inactive_memory += block->extra = block->size - size_orig; if (tag >= PU_PURGELEVEL) purgable_memory += size_orig; else active_memory += size_orig; free_memory -= block->size; #endif allocated: #ifdef INSTRUMENTED block->file = file; block->line = line; #endif #ifdef ZONEIDCHECK block->id = ZONEID; // signature required in block header #endif block->tag = tag; // tag block->user = user; // user block = (memblock_t*)((char*) block + HEADER_SIZE); if (user) // if there is a user *user = block; // set user to point to new block #ifdef INSTRUMENTED Z_PrintStats(); // print memory allocation stats // scramble memory -- weed out any bugs memset(block, gametic & 0xff, size); #endif return block; } } while ((block = block->next) != start); // detect cycles as failure // We've run out of physical memory, or so we think. // Although less efficient, we'll just use ordinary malloc. // This will squeeze the remaining juice out of this machine // and start cutting into virtual memory if it has it. while (!(block = (malloc)(size + HEADER_SIZE))) { if (!blockbytag[PU_CACHE]) I_Error("Z_Malloc: Failure trying to allocate %lu bytes" "\nSource: %s:%d", (unsigned long) size, file, line); Z_FreeTags(PU_CACHE, PU_CACHE); } if ((block->next = blockbytag[tag])) block->next->prev = (memblock_t*) &block->next; blockbytag[tag] = block; block->prev = (memblock_t*) &blockbytag[tag]; block->vm = 1; // haleyjd: cph's virtual memory error fix #ifdef INSTRUMENTED virtual_memory += size + HEADER_SIZE; // haleyjd 06/17/08: Import from EE: // Big problem: extra wasn't being initialized for vm // blocks. This caused the memset used to randomize freed memory when // INSTRUMENTED is defined to stomp all over the C heap. block->extra = 0; #endif /* cph - the next line was lost in the #ifdef above, and also added an * extra HEADER_SIZE to block->size, which was incorrect */ block->size = size; goto allocated; }
void P_SetupLevel(int map, skill_t skill) { int i; static char lumpname[16]; int lumpnum; mobj_t *mobj; extern int cy; M_ClearRandom(); P_LoadingPlaque(); D_printf("P_SetupLevel(%i,%i)\n", map, skill); totalkills = totalitems = totalsecret = 0; for(i = 0; i < MAXPLAYERS; i++) players[i].killcount = players[i].secretcount = players[i].itemcount = 0; Z_CheckHeap(mainzone); Z_CheckHeap(refzone); Z_FreeTags(mainzone); P_InitThinkers(); // // look for a regular (development) map first // lumpname[0] = 'M'; lumpname[1] = 'A'; lumpname[2] = 'P'; lumpname[3] = '0' + map / 10; lumpname[4] = '0' + map % 10; lumpname[5] = 0; lumpnum = W_GetNumForName(lumpname); // note: most of this ordering is important P_LoadBlockMap(lumpnum+ML_BLOCKMAP); P_LoadVertexes(lumpnum+ML_VERTEXES); P_LoadSectors(lumpnum+ML_SECTORS); P_LoadSideDefs(lumpnum+ML_SIDEDEFS); P_LoadLineDefs(lumpnum+ML_LINEDEFS); P_LoadSubsectors(lumpnum+ML_SSECTORS); P_LoadNodes(lumpnum+ML_NODES); P_LoadSegs(lumpnum+ML_SEGS); rejectmatrix = W_CacheLumpNum(lumpnum + ML_REJECT, PU_LEVEL); P_GroupLines(); deathmatch_p = deathmatchstarts; P_LoadThings(lumpnum + ML_THINGS); // // if deathmatch, randomly spawn the active players // if(netgame == gt_deathmatch) { for(i = 0; i < MAXPLAYERS; i++) { if(playeringame[i]) { // must give a player spot before deathmatchspawn mobj = P_SpawnMobj(deathmatchstarts[0].x << 16 ,deathmatchstarts[0].y << 16, 0, MT_PLAYER); players[i].mo = mobj; G_DeathMatchSpawnPlayer(i); P_RemoveMobj(mobj); } } } // set up world state P_SpawnSpecials(); ST_InitEveryLevel(); cy = 4; iquehead = iquetail = 0; gamepaused = false; }
// // Z_Realloc // // haleyjd 20140816: [SVE] Necessary to remove static limits // void *Z_Realloc(void *ptr, int size, int tag, void **user) { void *p; memblock_t *block, *newblock, *origblock; size_t origsize; // if not allocated at all, defer to Z_Malloc if(!ptr) return Z_Calloc(1, size, tag, user); // also defer for a 0 byte request if(size == 0) { Z_Free(ptr); return Z_Calloc(1, size, tag, user); } block = origblock = (memblock_t *)((byte *)ptr - header_size); if(block->id != ZONEID) I_Error("Z_Realloc: reallocated a block without ZONEID"); origsize = block->size; // nullify current user, if any if(block->user) *(block->user) = NULL; // detach from list before reallocation if((*block->prev = block->next)) block->next->prev = block->prev; block->next = NULL; block->prev = NULL; if(!(newblock = (memblock_t *)(realloc(block, size + header_size)))) { if(blockbytag[PU_CACHE]) { Z_FreeTags(PU_CACHE, PU_CACHE); newblock = (memblock_t *)(realloc(block, size + header_size)); } } if(!(block = newblock)) { if(origblock->size >= size) { // restore original alloc if shrinking realloc fails block = origblock; size = block->size; } else I_Error("Z_Realloc: failed on allocation of %u bytes", (unsigned int)size); } block->size = size; block->tag = tag; if(size > origsize) memset((byte *)block + header_size + origsize, 0, size - origsize); p = (byte *)block + header_size; // set new user, if any block->user = user; if(user) *user = p; // reattach to list at possibly new address, new tag if((block->next = blockbytag[tag])) block->next->prev = &block->next; blockbytag[tag] = block; block->prev = &blockbytag[tag]; return p; }
// // P_SetupLevel // void P_SetupLevel ( int episode, int map, int playermask, skill_t skill) { int i; char lumpname[9]; int lumpnum; totalkills = totalitems = totalsecret = wminfo.maxfrags = 0; wminfo.partime = 180; for (i=0 ; i<MAXPLAYERS ; i++) { players[i].killcount = players[i].secretcount = players[i].itemcount = 0; } // Initial height of PointOfView // will be set by player think. players[consoleplayer].viewz = 1; // Make sure all sounds are stopped before Z_FreeTags. S_Start (); #if 0 // UNUSED if (debugfile) { Z_FreeTags (PU_LEVEL, MAXINT); Z_FileDumpHeap (debugfile); } else #endif Z_FreeTags (PU_LEVEL, PU_PURGELEVEL-1); // UNUSED W_Profile (); P_InitThinkers (); // if working with a devlopment map, reload it W_Reload (); // find map name if ( gamemode == commercial) { if (map<10) sprintf (lumpname,"map0%i", map); else sprintf (lumpname,"map%i", map); } else { lumpname[0] = 'E'; lumpname[1] = '0' + episode; lumpname[2] = 'M'; lumpname[3] = '0' + map; lumpname[4] = 0; } lumpnum = W_GetNumForName (lumpname); leveltime = 0; // note: most of this ordering is important P_LoadBlockMap (lumpnum+ML_BLOCKMAP); P_LoadVertexes (lumpnum+ML_VERTEXES); P_LoadSectors (lumpnum+ML_SECTORS); P_LoadSideDefs (lumpnum+ML_SIDEDEFS); P_LoadLineDefs (lumpnum+ML_LINEDEFS); P_LoadSubsectors (lumpnum+ML_SSECTORS); P_LoadNodes (lumpnum+ML_NODES); P_LoadSegs (lumpnum+ML_SEGS); rejectmatrix = W_CacheLumpNum (lumpnum+ML_REJECT,PU_LEVEL); P_GroupLines (); bodyqueslot = 0; deathmatch_p = deathmatchstarts; P_LoadThings (lumpnum+ML_THINGS); // if deathmatch, randomly spawn the active players if (deathmatch) { for (i=0 ; i<MAXPLAYERS ; i++) if (playeringame[i]) { players[i].mo = NULL; G_DeathMatchSpawnPlayer (i); } } // clear special respawning que iquehead = iquetail = 0; // set up world state P_SpawnSpecials (); // build subsector connect matrix // UNUSED P_ConnectSubsectors (); // preload graphics if (precache) R_PrecacheLevel (); //printf ("free memory: 0x%x\n", Z_FreeMemory()); }
/* ================== BotImport_FreeZoneMemory ================== */ void BotImport_FreeZoneMemory( void ) { Z_FreeTags( TAG_BOTLIB ); }
// // R_FreeData // // Called when adding a new wad file. Frees all data loaded through R_Init. // R_Init must then be immediately called again. // void R_FreeData(void) { // haleyjd: let's harness the power of the zone heap and make this simple. Z_FreeTags(PU_RENDERER, PU_RENDERER); }
/* * Creates a server's entity / program execution context by * parsing textual entity definitions out of an ent file. */ void SpawnEntities(const char *mapname, char *entities, const char *spawnpoint) { edict_t *ent; int inhibit; const char *com_token; int i; float skill_level; if (!mapname || !entities || !spawnpoint) { return; } skill_level = floor(skill->value); if (skill_level < 0) { skill_level = 0; } if (skill_level > 3) { skill_level = 3; } if (skill->value != skill_level) { Cvar_ForceSet("skill", va("%f", skill_level)); } SaveClientData(); Z_FreeTags(TAG_LEVEL); memset(&level, 0, sizeof(level)); memset(g_edicts, 0, game.maxentities * sizeof(g_edicts[0])); Q_strlcpy(level.mapname, mapname, sizeof(level.mapname)); Q_strlcpy(game.spawnpoint, spawnpoint, sizeof(game.spawnpoint)); /* set client fields on player ents */ for (i = 0; i < game.maxclients; i++) { g_edicts[i + 1].client = game.clients + i; } ent = NULL; inhibit = 0; /* parse ents */ while (1) { /* parse the opening brace */ com_token = COM_Parse(&entities); if (!entities) { break; } if (com_token[0] != '{') { PF_error("ED_LoadFromFile: found %s when expecting {", com_token); } if (!ent) { ent = g_edicts; } else { ent = G_Spawn(); } entities = ED_ParseEdict(entities, ent); /* remove things (except the world) from different skill levels or deathmatch */ if (ent != g_edicts) { if (deathmatch->value) { if (ent->spawnflags & SPAWNFLAG_NOT_DEATHMATCH) { G_FreeEdict(ent); inhibit++; continue; } } else { if (((skill->value == 0) && (ent->spawnflags & SPAWNFLAG_NOT_EASY)) || ((skill->value == 1) && (ent->spawnflags & SPAWNFLAG_NOT_MEDIUM)) || (((skill->value == 2) || (skill->value == 3)) && (ent->spawnflags & SPAWNFLAG_NOT_HARD))) { G_FreeEdict(ent); inhibit++; continue; } } ent->spawnflags &= ~(SPAWNFLAG_NOT_EASY | SPAWNFLAG_NOT_MEDIUM | SPAWNFLAG_NOT_HARD | SPAWNFLAG_NOT_COOP | SPAWNFLAG_NOT_DEATHMATCH); } ED_CallSpawn(ent); } PF_dprintf("%i entities inhibited.\n", inhibit); G_FindTeams(); PlayerTrail_Init(); }
void *(Z_Malloc)(size_t size, int tag, void **user, const char *file, int line) { register memblock_t *block; memblock_t *start; #ifdef INSTRUMENTED size_t size_orig = size; #ifdef CHECKHEAP Z_CheckHeap(); #endif file_history[malloc_history][history_index[malloc_history]] = file; line_history[malloc_history][history_index[malloc_history]++] = line; history_index[malloc_history] &= ZONE_HISTORY-1; #endif #ifdef ZONEIDCHECK if (tag >= PU_PURGELEVEL && !user) I_Error ("Z_Malloc: an owner is required for purgable blocks\n" "Source: %s:%d", file, line); #endif if (!size) return user ? *user = NULL : NULL; // malloc(0) returns NULL size = (size+CHUNK_SIZE-1) & ~(CHUNK_SIZE-1); // round to chunk size block = rover; if (block->prev->tag == PU_FREE) block = block->prev; start = block; do { if (block->tag >= PU_PURGELEVEL) // Free purgable blocks { // replacement is roughly FIFO start = block->prev; Z_Free((char *) block + HEADER_SIZE); block = start = start->next; // Important: resets start } if (block->tag == PU_FREE && block->size >= size) // First-fit { size_t extra = block->size - size; if (extra >= MIN_BLOCK_SPLIT + HEADER_SIZE) { memblock_t *newb = (memblock_t *)((char *) block + HEADER_SIZE + size); (newb->next = block->next)->prev = newb; (newb->prev = block)->next = newb; // Split up block block->size = size; newb->size = extra - HEADER_SIZE; newb->tag = PU_FREE; newb->vm = 0; #ifdef INSTRUMENTED inactive_memory += HEADER_SIZE; free_memory -= HEADER_SIZE; #endif } rover = block->next; // set roving pointer for next search #ifdef INSTRUMENTED inactive_memory += block->extra = block->size - size_orig; if (tag >= PU_PURGELEVEL) purgable_memory += size_orig; else active_memory += size_orig; free_memory -= block->size; #endif allocated: #ifdef INSTRUMENTED block->file = file; block->line = line; #endif #ifdef ZONEIDCHECK block->id = ZONEID; // signature required in block header #endif block->tag = tag; // tag block->user = user; // user block = (memblock_t *)((char *) block + HEADER_SIZE); if (user) // if there is a user *user = block; // set user to point to new block #ifdef INSTRUMENTED Z_PrintStats(); // print memory allocation stats // scramble memory -- weed out any bugs memset(block, gametic & 0xff, size); #endif return block; } } while ((block = block->next) != start); // detect cycles as failure // We've run out of physical memory, or so we think. // Although less efficient, we'll just use ordinary malloc. // This will squeeze the remaining juice out of this machine // and start cutting into virtual memory if it has it. while (!(block = (malloc)(size + HEADER_SIZE))) { if (!blockbytag[PU_CACHE]) I_Error ("Z_Malloc: Failure trying to allocate %lu bytes" "\nSource: %s:%d",(unsigned long) size, file, line); Z_FreeTags(PU_CACHE,PU_CACHE); } if ((block->next = blockbytag[tag])) block->next->prev = (memblock_t *) &block->next; blockbytag[tag] = block; block->prev = (memblock_t *) &blockbytag[tag]; block->vm = 1; #ifdef INSTRUMENTED virtual_memory += #endif block->size = size + HEADER_SIZE; // CPhipps - this was lost in the #ifdef above goto allocated; }
void *Z_Malloc(size_t size, int tag, void **user) { memblock_t *block = NULL; if (!size) return user ? *user = NULL : NULL; // malloc(0) returns NULL size = (size+CHUNK_SIZE-1) & ~(CHUNK_SIZE-1); // round to chunk size if (memory_size > 0 && ((free_memory + memory_size) < (int)(size + HEADER_SIZE))) { memblock_t *end_block; block = blockbytag[PU_CACHE]; if (block) { end_block = block->prev; while (1) { memblock_t *next = block->next; (Z_Free)((uint8_t*) block + HEADER_SIZE); if (((free_memory + memory_size) >= (int)(size + HEADER_SIZE)) || (block == end_block)) break; block = next; // Advance to next block } } block = NULL; } while (!(block = (malloc)(size + HEADER_SIZE))) { if (!blockbytag[PU_CACHE]) I_Error ("Z_Malloc: Failure trying to allocate %lu bytes" ,(unsigned long) size ); Z_FreeTags(PU_CACHE,PU_CACHE); } if (!blockbytag[tag]) { blockbytag[tag] = block; block->next = block->prev = block; } else { blockbytag[tag]->prev->next = block; block->prev = blockbytag[tag]->prev; block->next = blockbytag[tag]; blockbytag[tag]->prev = block; } block->size = size; free_memory -= block->size; block->tag = tag; // tag block->user = user; // user block = (memblock_t *)((uint8_t*) block + HEADER_SIZE); if (user) // if there is a user *user = block; // set user to point to new block return block; }
void P_SetupLevel(int episode, int map, int playermask, skill_t skill) { int i; int parm; char lumpname[9]; char auxName[128]; int lumpnum; mobj_t *mobj; for(i = 0; i < MAXPLAYERS; i++) { players[i].killcount = players[i].secretcount = players[i].itemcount = 0; } players[consoleplayer].viewz = 1; // will be set by player think #ifdef __WATCOMC__ if(i_CDMusic == false) { S_StartSongName("chess", true); // Waiting-for-level-load song } #endif Z_FreeTags(PU_LEVEL, PU_PURGELEVEL-1); P_InitThinkers(); leveltime = 0; if(DevMaps) { sprintf(auxName, "%sMAP%02d.WAD", DevMapsDir, map); W_OpenAuxiliary(auxName); } sprintf(lumpname, "MAP%02d", map); lumpnum = W_GetNumForName(lumpname); // // Begin processing map lumps // Note: most of this ordering is important // P_LoadBlockMap(lumpnum+ML_BLOCKMAP); P_LoadVertexes(lumpnum+ML_VERTEXES); P_LoadSectors(lumpnum+ML_SECTORS); P_LoadSideDefs(lumpnum+ML_SIDEDEFS); P_LoadLineDefs(lumpnum+ML_LINEDEFS); P_LoadSubsectors(lumpnum+ML_SSECTORS); P_LoadNodes(lumpnum+ML_NODES); P_LoadSegs(lumpnum+ML_SEGS); rejectmatrix = W_CacheLumpNum(lumpnum+ML_REJECT, PU_LEVEL); P_GroupLines(); bodyqueslot = 0; po_NumPolyobjs = 0; deathmatch_p = deathmatchstarts; P_LoadThings(lumpnum+ML_THINGS); PO_Init(lumpnum+ML_THINGS); // Initialize the polyobjs P_LoadACScripts(lumpnum+ML_BEHAVIOR); // ACS object code // // End of map lump processing // if(DevMaps) { // Close the auxiliary file, but don't free its loaded lumps. // The next call to W_OpenAuxiliary() will do a full shutdown // of the current auxiliary WAD (free lumps and info lists). W_CloseAuxiliaryFile(); W_UsePrimary(); } // If deathmatch, randomly spawn the active players TimerGame = 0; if(deathmatch) { for (i=0 ; i<MAXPLAYERS ; i++) { if (playeringame[i]) { // must give a player spot before deathmatchspawn mobj = P_SpawnMobj (playerstarts[0][i].x<<16, playerstarts[0][i].y<<16,0, MT_PLAYER_FIGHTER); players[i].mo = mobj; G_DeathMatchSpawnPlayer (i); P_RemoveMobj (mobj); } } parm = M_CheckParm("-timer"); if(parm && parm < myargc-1) { TimerGame = atoi(myargv[parm+1])*35*60; } } // set up world state P_SpawnSpecials (); // build subsector connect matrix // P_ConnectSubsectors (); // Load colormap and set the fullbright flag i = P_GetMapFadeTable(gamemap); W_ReadLump(i, colormaps); if(i == W_GetNumForName("COLORMAP")) { LevelUseFullBright = true; } else { // Probably fog ... don't use fullbright sprites LevelUseFullBright = false; } // preload graphics if (precache) R_PrecacheLevel (); // Check if the level is a lightning level P_InitLightning(); S_StopAllSound(); SN_StopAllSequences(); S_StartSong(gamemap, true); //printf ("free memory: 0x%x\n", Z_FreeMemory()); }
void P_Stop(void) { int i = 0; int action = gameaction; // // [d64] stop plasma buzz // S_StopSound(NULL, sfx_electric); for(i = 0; i < MAXPLAYERS; i++) { // take away cards and stuff if(playeringame[i]) { G_PlayerFinishLevel(i); } } // [kex] reset damage indicators if(p_damageindicator.value) { ST_ClearDamageMarkers(); } // free level tags Z_FreeTags(PU_LEVEL, PU_PURGELEVEL-1); if(automapactive) { AM_Stop(); } // music continues on exit if defined if(!P_GetMapInfo(gamemap)->contmusexit) { S_StopMusic(); } // end iwad demo playback here if(demoplayback && iwadDemo) { demoplayback = false; iwadDemo = false; } // do wipe/melt effect if(gameaction != ga_loadgame) { if(r_wipe.value) { if(gameaction != ga_warpquick) { WIPE_MeltScreen(); } else { S_StopMusic(); WIPE_FadeScreen(8); } } else { if(gameaction == ga_warpquick) { S_StopMusic(); } } } S_ResetSound(); // action is warpquick only because the user // cancelled demo playback... // boot the user back to the title screen if(gameaction == ga_warpquick && demoplayback) { gameaction = ga_title; demoplayback = false; } else { gameaction = action; } }
void P_Stop(void) { Z_FreeTags(mainzone); }
// // Z_Realloc // // For the native heap, this can easily behave as a real realloc, and not // just an ignorant copy-and-free. // void *(Z_Realloc)(void *ptr, size_t n, int tag, void **user, const char *file, int line) { void *p; memblock_t *block, *newblock, *origblock; // if not allocated at all, defer to Z_Malloc if(!ptr) return (Z_Malloc)(n, tag, user, file, line); // size == 0 is a special case that cannot be handled below if(n == 0) { (Z_Free)(ptr, file, line); return NULL; } DEBUG_CHECKHEAP(); block = origblock = (memblock_t *)((byte *)ptr - header_size); Z_IDCheck(IDBOOL(block->id != ZONEID), "Z_Realloc: Reallocated a block without ZONEID\n", block, file, line); // haleyjd: realloc cannot change the tag of a permanent block if(block->tag == PU_PERMANENT) tag = PU_PERMANENT; // nullify current user, if any if(block->user) *(block->user) = NULL; // detach from list before reallocation if((*block->prev = block->next)) block->next->prev = block->prev; block->next = NULL; block->prev = NULL; INSTRUMENT(memorybytag[block->tag] -= block->size); if(!(newblock = (memblock_t *)(realloc(block, n + header_size)))) { // haleyjd 07/09/10: Note that unlinking the block above makes this safe // even if the current block is PU_CACHE; Z_FreeTags won't find it. if(blockbytag[PU_CACHE]) { Z_FreeTags(PU_CACHE, PU_CACHE); newblock = (memblock_t *)(realloc(block, n + header_size)); } } if(!(block = newblock)) { if(origblock->size >= n) { block = origblock; // restore original block if size was equal or smaller n = block->size; // keep same size in this event } else { I_FatalError(I_ERR_KILL, "Z_Realloc: Failure trying to allocate %u bytes\n" "Source: %s:%d\n", (unsigned int)n, file, line); } } block->size = n; block->tag = tag; p = (byte *)block + header_size; // set new user, if any block->user = user; if(user) *user = p; // reattach to list at possibly new address, new tag if((block->next = blockbytag[tag])) block->next->prev = &block->next; blockbytag[tag] = block; block->prev = &blockbytag[tag]; INSTRUMENT(memorybytag[tag] += block->size); INSTRUMENT(block->file = file); INSTRUMENT(block->line = line); Z_LogPrintf("* %p = Z_Realloc(ptr=%p, n=%lu, tag=%d, user=%p, source=%s:%d)\n", p, ptr, n, tag, user, file, line); return p; }
void *(Z_Malloc)(size_t size, int tag, void **user #ifdef INSTRUMENTED , const char *file, int line #endif ) { memblock_t *block = NULL; #ifdef INSTRUMENTED #ifdef CHECKHEAP Z_CheckHeap(); #endif file_history[malloc_history][history_index[malloc_history]] = file; line_history[malloc_history][history_index[malloc_history]++] = line; history_index[malloc_history] &= ZONE_HISTORY-1; #endif #ifdef ZONEIDCHECK if (tag >= PU_PURGELEVEL && !user) I_Error ("Z_Malloc: An owner is required for purgable blocks" #ifdef INSTRUMENTED "Source: %s:%d", file, line #endif ); #endif if (!size) return user ? *user = NULL : NULL; // malloc(0) returns NULL size = (size+CHUNK_SIZE-1) & ~(CHUNK_SIZE-1); // round to chunk size if (memory_size > 0 && ((free_memory + memory_size) < (int)(size + HEADER_SIZE))) { memblock_t *end_block; block = blockbytag[PU_CACHE]; if (block) { end_block = block->prev; while (1) { memblock_t *next = block->next; #ifdef INSTRUMENTED (Z_Free)((char *) block + HEADER_SIZE, file, line); #else (Z_Free)((char *) block + HEADER_SIZE); #endif if (((free_memory + memory_size) >= (int)(size + HEADER_SIZE)) || (block == end_block)) break; block = next; // Advance to next block } } block = NULL; } #ifdef HAVE_LIBDMALLOC while (!(block = dmalloc_malloc(file,line,size + HEADER_SIZE,DMALLOC_FUNC_MALLOC,0,0))) { #else while (!(block = (malloc)(size + HEADER_SIZE))) { #endif if (!blockbytag[PU_CACHE]) I_Error ("Z_Malloc: Failure trying to allocate %lu bytes" #ifdef INSTRUMENTED "\nSource: %s:%d" #endif ,(unsigned long) size #ifdef INSTRUMENTED , file, line #endif ); Z_FreeTags(PU_CACHE,PU_CACHE); } if (!blockbytag[tag]) { blockbytag[tag] = block; block->next = block->prev = block; } else { blockbytag[tag]->prev->next = block; block->prev = blockbytag[tag]->prev; block->next = blockbytag[tag]; blockbytag[tag]->prev = block; } block->size = size; #ifdef INSTRUMENTED if (tag >= PU_PURGELEVEL) purgable_memory += block->size; else active_memory += block->size; #endif free_memory -= block->size; #ifdef INSTRUMENTED block->file = file; block->line = line; #endif #ifdef ZONEIDCHECK block->id = ZONEID; // signature required in block header #endif block->tag = tag; // tag block->user = user; // user block = (memblock_t *)((char *) block + HEADER_SIZE); if (user) // if there is a user *user = block; // set user to point to new block #ifdef INSTRUMENTED Z_DrawStats(); // print memory allocation stats // scramble memory -- weed out any bugs memset(block, gametic & 0xff, size); #endif return block; } void (Z_Free)(void *p #ifdef INSTRUMENTED , const char *file, int line #endif ) { memblock_t *block = (memblock_t *)((char *) p - HEADER_SIZE); #ifdef INSTRUMENTED #ifdef CHECKHEAP Z_CheckHeap(); #endif file_history[free_history][history_index[free_history]] = file; line_history[free_history][history_index[free_history]++] = line; history_index[free_history] &= ZONE_HISTORY-1; #endif if (!p) return; #ifdef ZONEIDCHECK if (block->id != ZONEID) I_Error("Z_Free: freed a pointer without ZONEID" #ifdef INSTRUMENTED "\nSource: %s:%d" "\nSource of malloc: %s:%d" , file, line, block->file, block->line #endif ); block->id = 0; // Nullify id so another free fails #endif if (block->user) // Nullify user if one exists *block->user = NULL; if (block == block->next) blockbytag[block->tag] = NULL; else if (blockbytag[block->tag] == block) blockbytag[block->tag] = block->next; block->prev->next = block->next; block->next->prev = block->prev; free_memory += block->size; #ifdef INSTRUMENTED if (block->tag >= PU_PURGELEVEL) purgable_memory -= block->size; else active_memory -= block->size; /* scramble memory -- weed out any bugs */ memset(block, gametic & 0xff, block->size + HEADER_SIZE); #endif #ifdef HAVE_LIBDMALLOC dmalloc_free(file,line,block,DMALLOC_FUNC_MALLOC); #else (free)(block); #endif #ifdef INSTRUMENTED Z_DrawStats(); // print memory allocation stats #endif }
void P_SetupLevel(int episode, int map, int playermask, skill_t skill) { int i; int parm; char lumpname[9]; int lumpnum; mobj_t *mobj; for (i = 0; i < MAXPLAYERS; i++) { players[i].killcount = players[i].secretcount = players[i].itemcount = 0; } players[consoleplayer].viewz = 1; // will be set by player think // Waiting-for-level-load song; not played if playing music from CD // (the seek time will be so long it will just make loading take // longer) if (!cdmusic) { S_StartSongName("chess", true); } Z_FreeTags(PU_LEVEL, PU_PURGELEVEL - 1); P_InitThinkers(); leveltime = 0; sprintf(lumpname, "MAP%02d", map); lumpnum = W_GetNumForName(lumpname); // // Begin processing map lumps // Note: most of this ordering is important // P_LoadBlockMap(lumpnum + ML_BLOCKMAP); P_LoadVertexes(lumpnum + ML_VERTEXES); P_LoadSectors(lumpnum + ML_SECTORS); P_LoadSideDefs(lumpnum + ML_SIDEDEFS); P_LoadLineDefs(lumpnum + ML_LINEDEFS); P_LoadSubsectors(lumpnum + ML_SSECTORS); P_LoadNodes(lumpnum + ML_NODES); P_LoadSegs(lumpnum + ML_SEGS); rejectmatrix = W_CacheLumpNum(lumpnum + ML_REJECT, PU_LEVEL); P_GroupLines(); bodyqueslot = 0; po_NumPolyobjs = 0; deathmatch_p = deathmatchstarts; P_LoadThings(lumpnum + ML_THINGS); PO_Init(lumpnum + ML_THINGS); // Initialize the polyobjs P_LoadACScripts(lumpnum + ML_BEHAVIOR); // ACS object code // // End of map lump processing // // If deathmatch, randomly spawn the active players TimerGame = 0; if (deathmatch) { for (i = 0; i < MAXPLAYERS; i++) { if (playeringame[i]) { // must give a player spot before deathmatchspawn mobj = P_SpawnMobj(playerstarts[0][i].x << 16, playerstarts[0][i].y << 16, 0, MT_PLAYER_FIGHTER); players[i].mo = mobj; G_DeathMatchSpawnPlayer(i); P_RemoveMobj(mobj); } } //! // @arg <n> // @category net // @vanilla // // For multiplayer games: exit each level after n minutes. // parm = M_CheckParmWithArgs("-timer", 1); if (parm) { TimerGame = atoi(myargv[parm + 1]) * 35 * 60; } } // set up world state P_SpawnSpecials(); // build subsector connect matrix // P_ConnectSubsectors (); // Load colormap and set the fullbright flag i = P_GetMapFadeTable(gamemap); W_ReadLump(i, colormaps); if (i == W_GetNumForName("COLORMAP")) { LevelUseFullBright = true; } else { // Probably fog ... don't use fullbright sprites LevelUseFullBright = false; } // preload graphics if (precache) R_PrecacheLevel(); // Check if the level is a lightning level P_InitLightning(); S_StopAllSound(); SN_StopAllSequences(); S_StartSong(gamemap, true); //printf ("free memory: 0x%x\n", Z_FreeMemory()); }
void P_SetupLevel (int map, skill_t skill) { int i; static char lumpname[16]; int lumpnum; mobj_t *mobj; extern int cy; M_ClearRandom (); P_LoadingPlaque (); D_printf ("P_SetupLevel(%i,%i)\n",map,skill); totalkills = totalitems = totalsecret = 0; for (i=0 ; i<MAXPLAYERS ; i++) { players[i].killcount = players[i].secretcount = players[i].itemcount = 0; } Z_CheckHeap (mainzone); #ifndef MARS Z_CheckHeap (refzone); #endif Z_FreeTags (mainzone); /*PrintHex (1,1,Z_FreeMemory (mainzone)); */ P_InitThinkers (); /* */ /* look for a regular (development) map first */ /* */ lumpname[0] = 'M'; lumpname[1] = 'A'; lumpname[2] = 'P'; lumpname[3] = '0' + map/10; lumpname[4] = '0' + map%10; lumpname[5] = 0; lumpnum = W_GetNumForName (lumpname); /* note: most of this ordering is important */ P_LoadBlockMap (lumpnum+ML_BLOCKMAP); P_LoadVertexes (lumpnum+ML_VERTEXES); P_LoadSectors (lumpnum+ML_SECTORS); P_LoadSideDefs (lumpnum+ML_SIDEDEFS); P_LoadLineDefs (lumpnum+ML_LINEDEFS); P_LoadSubsectors (lumpnum+ML_SSECTORS); P_LoadNodes (lumpnum+ML_NODES); P_LoadSegs (lumpnum+ML_SEGS); #ifdef MARS rejectmatrix = (byte *)(wadfileptr+BIGLONG(lumpinfo[lumpnum+ML_REJECT].filepos)); #else rejectmatrix = W_CacheLumpNum (lumpnum+ML_REJECT,PU_LEVEL); #endif P_GroupLines (); deathmatch_p = deathmatchstarts; P_LoadThings (lumpnum+ML_THINGS); /* */ /* if deathmatch, randomly spawn the active players */ /* */ if (netgame == gt_deathmatch) { for (i=0 ; i<MAXPLAYERS ; i++) if (playeringame[i]) { /* must give a player spot before deathmatchspawn */ mobj = P_SpawnMobj (deathmatchstarts[0].x<<16 ,deathmatchstarts[0].y<<16,0, MT_PLAYER); players[i].mo = mobj; G_DeathMatchSpawnPlayer (i); P_RemoveMobj (mobj); } } /* set up world state */ P_SpawnSpecials (); ST_InitEveryLevel (); /*printf ("free memory: 0x%x\n", Z_FreeMemory(mainzone)); */ cy = 4; #ifdef JAGUAR { extern byte *debugscreen; D_memset (debugscreen,0,32*224); } #endif iquehead = iquetail = 0; gamepaused = false; }