/**
 * \brief Shutdown game
 */
PUBLIC void Game_Shutdown( void )
{
	Com_Printf( "==== Game Shutdown ====\n" );

	Z_FreeTags( TAG_LEVEL );
	Z_FreeTags( TAG_GAME );
}
示例#2
0
void ShutdownGame(void)
{
  PF_dprintf("==== ShutdownGame ====\n");

  Z_FreeTags(TAG_LEVEL);
  Z_FreeTags(TAG_GAME);
}
示例#3
0
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;
}
示例#4
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;
}
示例#5
0
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;	
}
示例#6
0
文件: common.c 项目: chrisnew/quake2
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
}
示例#7
0
//
// 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;
}
示例#8
0
//
// 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;
}
示例#9
0
文件: z_zone.c 项目: AlexMax/winmbf
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;
}
示例#10
0
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;
}
示例#11
0
//
// 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;
}
示例#12
0
//
// 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());

}
示例#13
0
/*
==================
BotImport_FreeZoneMemory
==================
*/
void BotImport_FreeZoneMemory( void )
{
	Z_FreeTags( TAG_BOTLIB );
}
示例#14
0
//
// 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);
}
示例#15
0
/*
 * 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();
}
示例#16
0
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;
}
示例#17
0
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;
}
示例#18
0
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());

}
示例#19
0
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;
    }
}
示例#20
0
void P_Stop(void)
{
   Z_FreeTags(mainzone);
}
示例#21
0
//
// 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;
}
示例#22
0
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
}
示例#23
0
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());

}
示例#24
0
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;
}