Esempio n. 1
0
File: seg002.c Progetto: mfn/SDLPoP
// seg002:0000
void __pascal far do_init_shad(const byte *source,int seq_index) {
	memcpy_near(&Char, source, 7);
	seqtbl_offset_char(seq_index);
	Char.charid = charid_1_shadow;
	demo_time = 0;
	guard_skill = 3;
	guardhp_delta = guardhp_curr = guardhp_max = 4;
	saveshad();
}
Esempio n. 2
0
//
// Z_Realloc
//
// haleyjd 09/18/06: Rewritten to be an actual realloc routine. The
// various cases are as follows:
//
// 1. If the block is NULL, is in virtual memory, or we're trying to set it to
//    zero-byte size, we use Z_ReallocOld above.
// 2. If the block is smaller than the new size, we need to expand it. If the
//    next block on the zone heap is free, check to see if it together with the
//    current block is large enough. If so, merge the blocks. Now test to make
//    sure the internal fragmentation does not exceed the split limit. If it
//    does, resplit the blocks at the new boundary. If the next block wasn't
//    free, we have to call Z_ReallocOld to move the entire block elsewhere.
// 3. If the block is larger than the new size, we can shrink it, but we only
//    need to shrink it if the wasted space is larger than the split limit.
//    If so, the block is split at its new boundary. If the next block on the
//    zone heap is free, it is then necessary to merge the new free block with
//    the next block on the heap. In the event the block is not shrunk, only the
//    INSTRUMENTED data needs to be updated to reflect the new internal fragmen-
//    tation.
// 4. If the block is already the same size as "n", we don't need to do anything
//    aside from adjusting the INSTRUMENTED block data for debugging purposes.
//
void *(Z_Realloc)(void *ptr, size_t n, int tag, void **user, __string file, int line)
{
   register memblock_t __near *block, *other;
   register size_t curr_size = 0;

   // davidph 12/09/12: Handle null and size 0 right here instead of in Z_ReallocOld.
   if(n == 0) { (Z_Free)(ptr, file, line); return NULL; }

   if(!ptr)
      return (Z_Malloc)(n, tag, user, file, line);

   // get current size of block
   block = VoidToBlock(ptr);

   Z_IDCheck(IDBOOL(block->id != ZONEID),
             "Z_Realloc: Reallocated a block without ZONEID\n",
             block, file, line);

   other = block->next; // save pointer to next block
   curr_size = block->size;

   // round new size to CHUNK_SIZE
   n = (n + CHUNK_SIZE - 1) & ~(CHUNK_SIZE - 1);

   if(n > curr_size) // is new allocation size larger than current?
   {
      register size_t extra;

      // haleyjd 10/03/06: free adjacent purgable blocks
      while(other != zone && other != block &&
            (other->tag == PU_FREE || other->tag >= PU_PURGELEVEL))
      {
         if(other->tag >= PU_PURGELEVEL)
         {
            (Z_Free)(BlockToVoid(other), file, line);

            // reset pointer to next block
            other = block->next;
         }

         // use current size of block; note it may have increased if it was
         // merged with an adjacent free block

         // if we've freed enough, stop
         if(curr_size + other->size + HEADER_SIZE >= n)
            break;

         // move to next block
         other = other->next;
      }

      // reset pointer
      other = block->next;

      // check to see if it can fit if we merge with the next block
      if(other != zone && other->tag == PU_FREE &&
         curr_size + other->size + HEADER_SIZE >= n)
      {
         // merge the blocks
         if(rover == other)
            rover = block;
         (block->next = other->next)->prev = block;
         block->size += other->size + HEADER_SIZE;

#ifdef INSTRUMENTED
         // lost a block...
         inactive_memory -= HEADER_SIZE;
         // lost a free block...
         free_memory -= other->size;
         // increased active or purgable
         if(block->tag >= PU_PURGELEVEL)
            purgable_memory += other->size + HEADER_SIZE;
         else
            active_memory += other->size + HEADER_SIZE;
#endif

         // check to see if there's enough extra to warrant splitting off
         // a new free block
         extra = block->size - n;

         if(extra >= MIN_BLOCK_SPLIT + HEADER_SIZE)
         {
            register memblock_t __near *newb =
               (memblock_t __near *)((char __near *)block + HEADER_SIZE + n);

            (newb->next = block->next)->prev = newb;
            (newb->prev = block)->next = newb;
            block->size = n;
            newb->size = extra - HEADER_SIZE;
            newb->tag = PU_FREE;

            if(rover == block)
               rover = newb;

#ifdef INSTRUMENTED
            // added a block...
            inactive_memory += HEADER_SIZE;
            // added a free block...
            free_memory += newb->size;
            // decreased active or purgable
            if(block->tag >= PU_PURGELEVEL)
               purgable_memory -= newb->size + HEADER_SIZE;
            else
               active_memory -= newb->size + HEADER_SIZE;
#endif
         }

         // subtract old internal fragmentation and add new
         INSTRUMENT(inactive_memory -= block->extra);
         INSTRUMENT(inactive_memory += (block->extra = block->size - n));
      }
      else // else, do old realloc (make new, copy old, free old)
      {
         // davidph 12/10/12: This was the only place Z_ReallocOld was called.
         //   And we know that ptr != NULL and n != 0 and n > curr_size.

         register void *p = (Z_Malloc)(n, tag, user, file, line);

         memcpy_near((void __near *)p, (void __near *)ptr, curr_size);
         (Z_Free)(ptr, file, line);
         if(user) // in case Z_Free nullified same user
            *user = p;

         return p;
      }
   }
   else if(n < curr_size) // is new allocation size smaller than current?
   {
      // check to see if there's enough extra to warrant splitting off
      // a new free block
      size_t extra = curr_size - n;

      if(extra >= MIN_BLOCK_SPLIT + HEADER_SIZE)
      {
         register memblock_t __near *newb =
            (memblock_t __near *)((char __near *)block + HEADER_SIZE + n);

         (newb->next = block->next)->prev = newb;
         (newb->prev = block)->next = newb;
         block->size = n;
         newb->size = extra - HEADER_SIZE;
         newb->tag = PU_FREE;

#ifdef INSTRUMENTED
         // added a block...
         inactive_memory += HEADER_SIZE;
         // added a free block...
         free_memory += newb->size;
         // decreased purgable or active
         if(block->tag >= PU_PURGELEVEL)
            purgable_memory -= newb->size + HEADER_SIZE;
         else
            active_memory -= newb->size + HEADER_SIZE;
#endif

         // may need to merge new block with next block
         if(other && other->tag == PU_FREE && other != zone)
         {
            if(rover == other) // Move back rover if it points at next block
               rover = newb;
            (newb->next = other->next)->prev = newb;
            newb->size += other->size + HEADER_SIZE;

            // deleted a block...
            INSTRUMENT(inactive_memory -= HEADER_SIZE);
            // space between blocks is now free
            INSTRUMENT(free_memory += HEADER_SIZE);
         }
      }
      // else, leave block the same size

      // subtract old internal fragmentation and add new
      INSTRUMENT(inactive_memory -= block->extra);
      INSTRUMENT(inactive_memory += (block->extra = block->size - n));
   }
   // else new allocation size is same as current, don't change it

   // modify the block
   INSTRUMENT(block->file = file);
   INSTRUMENT(block->line = line);

   // reset ptr for consistency
   ptr = BlockToVoid(block);

   if(block->user != user)
   {
      if(block->user)           // nullify old user if any
         *(block->user) = NULL;
      block->user = user;       // set block's new user
      if(user)                  // if non-null, set user to allocation
         *user = ptr;
   }

   // let Z_ChangeTag handle changing the tag
   if(block->tag != tag)
      (Z_ChangeTag)(ptr, tag, file, line);

   Z_PrintStats();           // print memory allocation stats
   Z_LogPrintf("* Z_Realloc(ptr=%p, n=%u, tag=%d, user=%p, source=%s:%d)\n",
               ptr, n, tag, user, file, line);

   return ptr;
}