// Moves 'count' lumpinfos, starting from 'from'. Updates the lumpcache. // Offset can only be positive. // // Lumpinfo and lumpcache are assumed to have enough memory for the operation! // void W_MoveLumps(int from, int count, int offset) { int i; // Check that our information is valid. if(!offset || count <= 0 || from < 0 || from > numlumps - 1) return; // First update the lumpcache. memmove(lumpcache + from + offset, lumpcache + from, sizeof(*lumpcache) * count); for(i = from + offset; i < from + count + offset; i++) if(lumpcache[i]) Z_ChangeUser(lumpcache[i], lumpcache + i); // Update the user. // Clear the 'revealed' memory. if(offset > 0) // Revealed from the beginning. memset(lumpcache + from, 0, offset * sizeof(*lumpcache)); else // Revealed from the end. memset(lumpcache + from + count + offset, 0, -offset * sizeof(*lumpcache)); // Lumpinfo. memmove(lumpinfo + from + offset, lumpinfo + from, sizeof(lumpinfo_t) * count); }
void W_RemoveLumpsWithHandle(DFILE * handle) { int i, k, first, len; for(i = 0, first = -1; i < numlumps; i++) { if(first < 0 && lumpinfo[i].handle == handle) { // Start a region. first = i; continue; } // Does a region end? if(first >= 0) if(lumpinfo[i].handle != handle || i == numlumps - 1 || MarkerForGroup(lumpinfo[i].name, true) || MarkerForGroup(lumpinfo[i].name, false)) { if(lumpinfo[i].handle == handle && i == numlumps - 1) i++; // Also free the last one. // The length of the region. len = i - first; // Free the memory allocated for the region. for(k = first; k < i; k++) { // Con_Message("removing lump: %s (%d)\n", lumpinfo[k].name, lumpinfo[k].handle); if(lumpcache[k]) { // If the block has a user, it must be explicitly freed. /*if((unsigned int)Z_GetUser(lumpcache[k]) > 0x100) Z_Free(lumpcache[k]); else if(Z_GetTag(lumpcache[k]) < PU_LEVEL) Z_ChangeTag(lumpcache[k], PU_LEVEL); */ //Z_ChangeTag(lumpcache[k], PU_CACHE); //Z_ChangeUser(lumpcache[k], NULL); if(Z_GetTag(lumpcache[k]) < PU_LEVEL) Z_ChangeTag(lumpcache[k], PU_LEVEL); // Mark the memory pointer in use, but unowned. Z_ChangeUser(lumpcache[k], (void *) 0x2); } } // Move the data in the lump storage. W_MoveLumps(i, numlumps - i, -len); numlumps -= len; i -= len; // Make it possible to begin a new region. first = -1; } } }
// Increase the size of the lumpinfo[] array to the specified size. static void ExtendLumpInfo(int newnumlumps) { lumpinfo_t *newlumpinfo; unsigned int i; newlumpinfo = calloc(newnumlumps, sizeof(lumpinfo_t)); if (newlumpinfo == NULL) { I_Error ("Couldn't realloc lumpinfo"); } // Copy over lumpinfo_t structures from the old array. If any of // these lumps have been cached, we need to update the user // pointers to the new location. for (i = 0; i < numlumps && i < newnumlumps; ++i) { memcpy(&newlumpinfo[i], &lumpinfo[i], sizeof(lumpinfo_t)); if (newlumpinfo[i].cache != NULL) { Z_ChangeUser(newlumpinfo[i].cache, &newlumpinfo[i].cache); } // We shouldn't be generating a hash table until after all WADs have // been loaded, but just in case... if (lumpinfo[i].next != NULL) { int nextlumpnum = lumpinfo[i].next - lumpinfo; newlumpinfo[i].next = &newlumpinfo[nextlumpnum]; } } // All done. free(lumpinfo); lumpinfo = newlumpinfo; numlumps = newnumlumps; }
// Reallocates lumpinfo and lumpcache. void W_ResizeLumpStorage(int numitems) { lumpinfo = realloc(lumpinfo, sizeof(lumpinfo_t) * numitems); // Updating the cache is a bit more difficult. We need to make sure // the user pointers in the memory zone remain valid. if(numcache != numitems) { void **newcache; // This is the new cache. int i, newCacheBytes = numitems * sizeof(*newcache); // The new size of the cache (bytes). int numToMod; newcache = malloc(newCacheBytes); memset(newcache, 0, newCacheBytes); // Clear the new cache. // Copy the old cache. if(numcache < numitems) numToMod = numcache; else numToMod = numitems; memcpy(newcache, lumpcache, numToMod * sizeof(*lumpcache)); // Update the user information in the memory zone. for(i = 0; i < numToMod; i++) if(newcache[i]) Z_ChangeUser(newcache[i], newcache + i); /* // Check that the rest of the cache has been freed (the part that gets // removed, if the storage is getting smaller). for(i=numToMod; i<numcache; i++) if(lumpcache[i]) Con_Error("W_ResizeLumpStorage: Cached lump getting lost.\n"); */ // Get rid of the old cache. free(lumpcache); lumpcache = newcache; numcache = numitems; } }