void PyrGC::DumpSet(int i) { GCSet *set = mSets + i; // scan black list PyrObjectHdr *obj = set->mBlack.next; while (!IsMarker(obj)) { post("black %s %d %d\n", slotRawSymbol(&obj->classptr->name)->name, obj->obj_sizeclass, obj->size); obj = obj->next; } // scan white list obj = set->mWhite.next; while (obj != set->mFree) { post("white %s %d %d\n", slotRawSymbol(&obj->classptr->name)->name, obj->obj_sizeclass, obj->size); obj = obj->next; } // scan free list obj = set->mFree; while (!IsMarker(obj)) { post("free %s %d %d\n", slotRawSymbol(&obj->classptr->name)->name, obj->obj_sizeclass, obj->size); obj = obj->next; } }
void PyrGC::ClearMarks() { for (int i=0; i<kNumGCSets; ++i) { GCSet *set = mSets + i; // scan black list PyrObjectHdr *obj = set->mBlack.next; while (!IsMarker(obj)) { obj->ClearMark(); // unmark it obj = obj->next; } // scan grey list obj = mGrey.next; while (!IsMarker(obj)) { obj->ClearMark(); // unmark it obj = obj->next; } // scan white list obj = set->mWhite.next; while (obj != set->mFree) { obj->ClearMark(); // unmark it obj = obj->next; } // scan free list obj = set->mFree; while (!IsMarker(obj)) { obj->ClearMark(); // unmark it obj = obj->next; } } }
void PyrGC::DumpInfo() { int i; PyrObjectHdr *obj; int numblack, numwhite, numfree, settotal, setsiztotal; int totblack, totgrey, totwhite, totfree, totref, total, siztotal; REPORTPAUSE post("flips %d collects %d nalloc %d alloc %d grey %d\n", mFlips, mCollects, mNumAllocs, mAllocTotal, mNumGrey); totblack = 0; totgrey = 0; totwhite = 0; totfree = 0; totref = 0; total = 0; siztotal = 0; for (i=0; i<kNumGCSizeClasses; ++i) { GCSet *set = mSets + i; // scan black list numblack = 0; obj = set->mBlack.next; while (!IsMarker(obj)) { numblack++; obj = obj->next; } // scan white list numwhite = 0; obj = set->mWhite.next; while (obj != set->mFree) { numwhite++; obj = obj->next; } // scan free list numfree = 0; obj = set->mFree; while (!IsMarker(obj)) { numfree++; obj = obj->next; } settotal = numblack + numwhite + numfree; setsiztotal = settotal << (i + 3); siztotal += setsiztotal; totblack += numblack; totwhite += numwhite; totfree += numfree; total += settotal; if (settotal) { post("%2d bwf t sz: %6d %6d %6d %6d %8d\n", i, numblack, numwhite, numfree, settotal, setsiztotal); } } post("tot bwf t sz: %6d %6d %6d %6d %8d\n", totblack, totwhite, totfree, total, siztotal); }
static void W_CoalesceMarkedResource(const char *start_marker, const char *end_marker, int li_namespace) { lumpinfo_t *marked = malloc(sizeof(*marked) * numlumps); size_t i, num_marked = 0, num_unmarked = 0; int is_marked = 0, mark_end = 0; lumpinfo_t *lump = lumpinfo; for (i=numlumps; i--; lump++) if (IsMarker(start_marker, lump->name)) // start marker found { // If this is the first start marker, add start marker to marked lumps if (!num_marked) { strncpy(marked->name, start_marker, 8); marked->size = 0; // killough 3/20/98: force size to be 0 marked->li_namespace = ns_global; // killough 4/17/98 marked->wadfile = NULL; num_marked = 1; } is_marked = 1; // start marking lumps } else if (IsMarker(end_marker, lump->name)) // end marker found { mark_end = 1; // add end marker below is_marked = 0; // stop marking lumps } else if (is_marked) // if we are marking lumps, { // move lump to marked list marked[num_marked] = *lump; marked[num_marked++].li_namespace = li_namespace; // killough 4/17/98 } else lumpinfo[num_unmarked++] = *lump; // else move down THIS list // Append marked list to end of unmarked list memcpy(lumpinfo + num_unmarked, marked, num_marked * sizeof(*marked)); free(marked); // free marked list numlumps = num_unmarked + num_marked; // new total number of lumps if (mark_end) // add end marker { lumpinfo[numlumps].size = 0; // killough 3/20/98: force size to be 0 lumpinfo[numlumps].wadfile = NULL; lumpinfo[numlumps].li_namespace = ns_global; // killough 4/17/98 strncpy(lumpinfo[numlumps++].name, end_marker, 8); } }
PyrObject *PyrGC::NewFrame(size_t inNumBytes, long inFlags, long inFormat, bool inAccount) { PyrObject *obj = NULL; #if SANITYCHECK SanityCheck(); #endif // obtain size info int32 alignedSize = (inNumBytes + kAlignMask) & ~kAlignMask; // 16 byte align int32 numSlots = alignedSize / sizeof(PyrSlot); numSlots = numSlots < 1 ? 1 : numSlots; int32 sizeclass = LOG2CEIL(numSlots); sizeclass = sc_min(sizeclass, kNumGCSizeClasses-1); int32 credit = 1L << sizeclass; mAllocTotal += credit; mNumAllocs++; if (inAccount) { mNumToScan += credit; if (mNumToScan >= kScanThreshold) { Collect(); } } GCSet *gcs = mSets + sizeclass; obj = (PyrObject*)gcs->mFree; if (!IsMarker(obj)) { // from free list gcs->mFree = obj->next; } else { if (sizeclass > kMaxPoolSet) { SweepBigObjects(); int32 allocSize = sizeof(PyrObjectHdr) + (sizeof(PyrSlot) << sizeclass); obj = (PyrObject*)mPool->Alloc(allocSize); } else { int32 allocSize = sizeof(PyrObjectHdr) + (sizeof(PyrSlot) << sizeclass); obj = (PyrObject*)mNewPool.Alloc(allocSize); } if (!obj) { post("Frame alloc failed. size = %d\n", inNumBytes); MEMFAILED; } DLInsertAfter(&gcs->mWhite, obj); } obj->obj_sizeclass = sizeclass; obj->obj_format = inFormat; obj->obj_flags = inFlags; obj->size = 0; obj->classptr = class_frame; obj->gc_color = mWhiteColor; #if SANITYCHECK SanityCheck(); #endif return obj; }
PyrObject *PyrGC::NewFinalizer(ObjFuncPtr finalizeFunc, PyrObject *inObject, bool inCollect) { PyrObject *obj = NULL; #ifdef GC_SANITYCHECK SanityCheck(); #endif // obtain size info int32 sizeclass = 1; int32 credit = 1L << sizeclass; mNumToScan += credit; mAllocTotal += credit; mNumAllocs++; if (inCollect && mNumToScan >= kScanThreshold) { Collect(); } GCSet *gcs = mSets + kFinalizerSet; obj = (PyrObject*)gcs->mFree; if (!IsMarker(obj)) { // from free list gcs->mFree = obj->next; } else { if (sizeclass > kMaxPoolSet) { SweepBigObjects(); int32 allocSize = sizeof(PyrObjectHdr) + (sizeof(PyrSlot) << sizeclass); obj = (PyrObject*)mPool->Alloc(allocSize); } else { int32 allocSize = sizeof(PyrObjectHdr) + (sizeof(PyrSlot) << sizeclass); obj = (PyrObject*)mNewPool.Alloc(allocSize); } if (!obj) { post("Finalizer alloc failed.\n"); MEMFAILED; } DLInsertAfter(&gcs->mWhite, obj); } obj->obj_sizeclass = sizeclass; obj->obj_format = obj_slot; obj->obj_flags = 0; obj->size = 2; obj->classptr = class_finalizer; obj->gc_color = mWhiteColor; SetPtr(obj->slots+0, (void*)finalizeFunc); SetObject(obj->slots+1, inObject); #ifdef GC_SANITYCHECK SanityCheck(); #endif return obj; }
void PyrGC::DumpGrey() { // scan grey list PyrObjectHdr *obj = mGrey.next; while (!IsMarker(obj)) { post("grey %s %d %d\n", slotRawSymbol(&obj->classptr->name)->name, obj->obj_sizeclass, obj->size); obj = obj->next; } }
void PyrGC::SweepBigObjects() { if (!mCanSweep) return; for (int i=kMaxPoolSet+1; i<kNumGCSizeClasses; ++i) { GCSet *gcs = mSets + i; PyrObjectHdr *obj = gcs->mFree; if (!IsMarker(obj)) { // unlink chain of free objects gcs->mFree = obj->prev->next = &gcs->mBlack; gcs->mBlack.prev = obj->prev; do { PyrObjectHdr *nextobj = obj->next; void* ptr = (void*)obj; mPool->Free(ptr); obj = nextobj; } while (!IsMarker(obj)); } } mCanSweep = false; }
bool PyrGC::SanityCheck2() { int numgrey = 0; PyrObjectHdr *grey = mGrey.next; while (!IsMarker(grey)) { numgrey++; if (!IsGrey(grey)) { postfl("sc Object on grey list not grey %d %d %d\n", grey->gc_color, mGreyColor, numgrey); return false; } grey = grey->next; } //postfl("sc %d %d\n", mNumGrey, numgrey); return mNumGrey == numgrey; }
void PyrGC::RunAllFinalizers() { GCSet *gcs = &mSets[kFinalizerSet]; PyrObjectHdr *obj = gcs->mBlack.next; while (!IsMarker(obj)) { Finalize((PyrObject*)obj); obj = obj->next; } obj = gcs->mWhite.next; PyrObjectHdr *firstFreeObj = gcs->mFree; while (obj != firstFreeObj) { Finalize((PyrObject*)obj); obj = obj->next; } obj = mGrey.next; while (!IsMarker(obj)) { if (obj->classptr == class_finalizer) Finalize((PyrObject*)obj); obj = obj->next; } }
void GCSet::MajorFlip() { // move all white items to beginning of free list mFree = mWhite.next; if (!IsMarker(mBlack.next)) { // move all black items to white list mWhite.next = mBlack.next; mFree->prev = mWhite.prev; mBlack.next->prev = &mWhite; mWhite.prev->next = mFree; // black list empty mBlack.next = &mWhite; mWhite.prev = &mBlack; } }
HOT bool PyrGC::ScanOneObj() { // Find a set that has a grey object PyrObject* obj; obj = (PyrObject*)mGrey.next; if (IsMarker(obj)) { if (mNumGrey) fatalerror("grey count error\n"); return false; } /*if (!IsGrey(obj)) { postfl("Object on grey list not grey %d %d\n", obj->gc_color, mGreyColor); fatalerror("C1"); }*/ mScans++; //post("-> scan %d %d %d\n", mNumGrey, IsGrey(obj), mNumToScan); // Found a grey object // move obj from grey to black ToBlack(obj); int32 size = ScanSize(obj); //post("<- scan %d %d %d %d\n", mNumGrey, IsGrey(obj), mNumToScan, size); if (size > mNumToScan + 32) { mPartialScanObj = obj; mPartialScanSlot = 0; DoPartialScan(size); } else if (size > 0) { ScanSlots(obj->slots, size); mNumToScan -= 1L << obj->obj_sizeclass; if (mNumToScan < 0) mNumToScan = 0; } else { mNumToScan -= 1L << obj->obj_sizeclass; if (mNumToScan < 0) mNumToScan = 0; } return true; }
static int W_CoalesceMarkedResource(const char *start_marker, const char *end_marker, int li_namespace) { int result = 0; lumpinfo_t *marked = malloc(sizeof(*marked) * numlumps); size_t i, num_marked = 0, num_unmarked = 0; int is_marked = 0, mark_end = 0; lumpinfo_t *lump = lumpinfo; for (i=numlumps; i--; lump++) if (IsMarker(start_marker, lump->name)) // start marker found { // If this is the first start marker, add start marker to marked lumps if (!num_marked) { strncpy(marked->name, start_marker, 8); marked->size = 0; // killough 3/20/98: force size to be 0 marked->li_namespace = ns_global; // killough 4/17/98 marked->wadfile = NULL; num_marked = 1; } is_marked = 1; // start marking lumps } else if (IsMarker(end_marker, lump->name)) // end marker found { mark_end = 1; // add end marker below is_marked = 0; // stop marking lumps } else if (is_marked || lump->li_namespace == li_namespace) { // if we are marking lumps, // move lump to marked list // sf: check for namespace already set // sf 26/10/99: // ignore sprite lumps smaller than 8 bytes (the smallest possible) // in size -- this was used by some dmadds wads // as an 'empty' graphics resource if(li_namespace != ns_sprites || lump->size > 8) { marked[num_marked] = *lump; marked[num_marked++].li_namespace = li_namespace; // killough 4/17/98 result++; } } else lumpinfo[num_unmarked++] = *lump; // else move down THIS list // Append marked list to end of unmarked list memcpy(lumpinfo + num_unmarked, marked, num_marked * sizeof(*marked)); free(marked); // free marked list numlumps = num_unmarked + num_marked; // new total number of lumps if (mark_end) // add end marker { lumpinfo[numlumps].size = 0; // killough 3/20/98: force size to be 0 lumpinfo[numlumps].wadfile = NULL; lumpinfo[numlumps].li_namespace = ns_global; // killough 4/17/98 strncpy(lumpinfo[numlumps++].name, end_marker, 8); } return result; }
bool PyrGC::ListSanity() { bool found; if (StackDepth() < 0) { fprintf(stderr, "stack underflow %d\n", (int)StackDepth()); return false; } //postfl("PyrGC::ListSanity\n"); for (int i=0; i<kNumGCSets; ++i) { PyrObjectHdr *obj; GCSet* set = mSets + i; // check black marker obj = &set->mBlack; if (!IsMarker(obj)) { //debugf("set %d black marker color wrong %d %p\n", i, obj->gc_color, obj); fprintf(stderr, "set %d black marker color wrong %d %p\n", i, obj->gc_color, obj); setPostFile(stderr); DumpBackTrace(mVMGlobals); dumpBadObject((PyrObject*)obj); return false; } // check white marker obj = &set->mWhite; if (!IsMarker(obj)) { //debugf("set %d white marker color wrong %d %p\n", i, obj->gc_color, obj); fprintf(stderr, "set %d white marker color wrong %d %p\n", i, obj->gc_color, obj); setPostFile(stderr); DumpBackTrace(mVMGlobals); dumpBadObject((PyrObject*)obj); return false; } // check free pointer between white and black marker if (set->mFree != &set->mBlack) { obj = set->mWhite.next; found = false; while (!IsMarker(obj)) { if (obj == set->mFree) { found = true; break; } obj = obj->next; } if (!found) { //debugf("set %d free pointer not between white and black\n", i); fprintf(stderr, "set %d free pointer not between white and black\n", i); fprintf(stderr, "set->mFree %p\n", set->mFree); fprintf(stderr, "set->mWhite %p\n", &set->mWhite); fprintf(stderr, "set->mBlack %p\n", &set->mBlack); setPostFile(stderr); DumpBackTrace(mVMGlobals); dumpBadObject((PyrObject*)set->mFree); fprintf(stderr, "black %d white %d grey %d\n", mBlackColor, mWhiteColor, mGreyColor); obj = &set->mWhite; int count = 0; do { if (obj == set->mFree) fprintf(stderr, "%4d %p %3d %d FREE\n", count, obj, obj->gc_color, obj->obj_sizeclass); else if (obj == &set->mWhite) fprintf(stderr, "%4d %p %3d %d WHITE\n", count, obj, obj->gc_color, obj->obj_sizeclass); else if (obj == &set->mBlack) fprintf(stderr, "%4d %p %3d %d BLACK\n", count, obj, obj->gc_color, obj->obj_sizeclass); else fprintf(stderr, "%4d %p %3d %d\n", count, obj, obj->gc_color, obj->obj_sizeclass); obj = obj->next; count++; } while (obj != &set->mWhite); return false; } } // scan black list obj = set->mBlack.next; while (!IsMarker(obj)) { if (obj->gc_color != mBlackColor) { //debugf("set %d black list obj color wrong %d (%d, %d, %d) %p\n", // i, obj->gc_color, mBlackColor, mGreyColor, mWhiteColor, obj); fprintf(stderr, "set %d black list obj color wrong %d (%d, %d, %d) %p\n", i, obj->gc_color, mBlackColor, mGreyColor, mWhiteColor, obj); setPostFile(stderr); DumpBackTrace(mVMGlobals); dumpBadObject((PyrObject*)obj); return false; } if (GetGCSet(obj) != set) { //debugf("set %d black obj gcset wrong %d %p\n", i, obj->obj_sizeclass, obj); fprintf(stderr, "set %d black obj gcset wrong %d %p\n", i, obj->obj_sizeclass, obj); setPostFile(stderr); dumpBadObject((PyrObject*)obj); return false; } if (obj->next->prev != obj) { fprintf(stderr, "set %d black obj->next->prev != obj\n", i); setPostFile(stderr); DumpBackTrace(mVMGlobals); dumpBadObject((PyrObject*)obj); } // scan for refs to white. if (!BlackToWhiteCheck((PyrObject*)obj)) return false; obj = obj->next; } // scan white list obj = set->mWhite.next; while (obj != set->mFree) { if (obj->gc_color != mWhiteColor) { //debugf("set %d white list obj color wrong %d (%d, %d, %d) %p\n", // i, obj->gc_color, mBlackColor, mGreyColor, mWhiteColor, obj); //debugf("hmmm free %p black %p\n", set->mFree, set->black); fprintf(stderr, "set %d white list obj color wrong %d (%d, %d, %d) %p\n", i, obj->gc_color, mBlackColor, mGreyColor, mWhiteColor, obj); fprintf(stderr, "hmmm free %p black %p\n", set->mFree, &set->mBlack); setPostFile(stderr); DumpBackTrace(mVMGlobals); dumpBadObject((PyrObject*)obj); return false; } if (GetGCSet(obj) != set) { //debugf("set %d white obj gcset wrong %d %p\n", i, obj->obj_sizeclass, obj); fprintf(stderr, "set %d white obj gcset wrong %d %p\n", i, obj->obj_sizeclass, obj); setPostFile(stderr); DumpBackTrace(mVMGlobals); dumpBadObject((PyrObject*)obj); return false; } if (obj->next->prev != obj) { fprintf(stderr, "set %d white obj->next->prev != obj\n", i); setPostFile(stderr); DumpBackTrace(mVMGlobals); dumpBadObject((PyrObject*)obj); } obj = obj->next; } // mark all free list items free obj = set->mFree; while (!IsMarker(obj)) { /*if (obj->gc_color == mGreyColor) { //debugf("grey obj on free list\n"); fprintf(stderr, "grey obj on free list\n"); return false; }*/ //post("FREE\n"); //dumpObject((PyrObject*)(PyrObject*)obj); obj->gc_color = mFreeColor; if (GetGCSet(obj) != set) { //debugf("set %d free obj gcset wrong %d %p\n", i, obj->obj_sizeclass, obj); fprintf(stderr, "set %d free obj gcset wrong %d %p\n", i, obj->obj_sizeclass, obj); //dumpObject((PyrObject*)obj); return false; } if (obj->next->prev != obj) { fprintf(stderr, "set %d free obj->next->prev != obj\n", i); //dumpObject((PyrObject*)obj); } obj = obj->next; } } int numgrey = 0; PyrObjectHdr *grey = mGrey.next; while (!IsMarker(grey)) { numgrey++; if (!IsGrey(grey)) { fprintf(stderr, "sc Object on grey list not grey %d %d %d\n", grey->gc_color, mGreyColor, numgrey); fprintf(stderr, "%p <- %p -> %p grey %p process %p\n", mGrey.prev, &mGrey, mGrey.next, grey, mProcess); return false; } grey = grey->next; } if (numgrey != mNumGrey) { fprintf(stderr, "grey count off %d %d\n", numgrey, mNumGrey); DumpInfo(); fprintf(stderr, "."); return false; } return true; }
int CgptPrioritize(CgptPrioritizeParams *params) { struct drive drive; int priority; int gpt_retval; uint32_t index; uint32_t max_part; int num_root; int i,j; group_list_t *groups; if (params == NULL) return CGPT_FAILED; if (CGPT_OK != DriveOpen(params->drive_name, &drive, 0, O_RDWR)) return CGPT_FAILED; if (GPT_SUCCESS != (gpt_retval = GptSanityCheck(&drive.gpt))) { Error("GptSanityCheck() returned %d: %s\n", gpt_retval, GptError(gpt_retval)); return CGPT_FAILED; } max_part = GetNumberOfEntries(&drive); if (params->set_partition) { if (params->set_partition < 1 || params->set_partition > max_part) { Error("invalid partition number: %d (must be between 1 and %d\n", params->set_partition, max_part); goto bad; } index = params->set_partition - 1; // it must be a kernel if (!IsRoot(&drive, PRIMARY, index) && !IsMarker(&drive, PRIMARY, index)) { Error("partition %d is not a valid root\n", params->set_partition); goto bad; } } // How many kernel partitions do I have? num_root = 0; for (i = 0; i < max_part; i++) { if (IsRoot(&drive, PRIMARY, i) || IsMarker(&drive, PRIMARY, i)) num_root++; } if (num_root) { // Determine the current priority groups groups = NewGroupList(num_root); for (i = 0; i < max_part; i++) { if (!IsRoot(&drive, PRIMARY, i) && !IsMarker(&drive, PRIMARY, i)) continue; priority = GetPriority(&drive, PRIMARY, i); // Is this partition special? if (params->set_partition && (i+1 == params->set_partition)) { params->orig_priority = priority; // remember the original priority if (params->set_friends) AddToGroup(groups, priority, i); // we'll move them all later else AddToGroup(groups, 99, i); // move only this one } else { AddToGroup(groups, priority, i); // just remember } } // If we're including friends, then change the original group priority if (params->set_partition && params->set_friends) { ChangeGroup(groups, params->orig_priority, 99); } // Sorting gives the new order. Now we just need to reassign the // priorities. SortGroups(groups); // We'll never lower anything to zero, so if the last group is priority zero // we can ignore it. i = groups->num_groups; if (groups->group[i-1].priority == 0) groups->num_groups--; // Where do we start? if (params->max_priority) priority = params->max_priority; else priority = groups->num_groups > 15 ? 15 : groups->num_groups; // Figure out what the new values should be for (i=0; i<groups->num_groups; i++) { groups->group[i].priority = priority; if (priority > 1) priority--; } // Now apply the ranking to the GPT for (i=0; i<groups->num_groups; i++) for (j=0; j<groups->group[i].num_parts; j++) SetPriority(&drive, PRIMARY, groups->group[i].part[j], groups->group[i].priority); FreeGroups(groups); } // Write it all out UpdateAllEntries(&drive); return DriveClose(&drive, 1); bad: (void) DriveClose(&drive, 0); return CGPT_FAILED; }
void W_MergeLumps (const char *start, const char *end, int space) { char ustart[8], uend[8]; lumpinfo_t *newlumpinfos; unsigned newlumps, oldlumps; BOOL insideBlock; unsigned flatHack, i; strncpy(ustart, start, 8); strncpy(uend, end, 8); std::transform(ustart, ustart + sizeof(ustart), ustart, toupper); std::transform(uend, uend + sizeof(uend), uend, toupper); // Some pwads use an icky hack to get flats with regular Doom. // This tries to detect them. flatHack = 0; if (!strcmp ("F_START", ustart) && !Args.CheckParm ("-noflathack")) { int fudge = 0; unsigned start = 0; for (i = 0; i < numlumps; i++) { if (IsMarker (lumpinfo + i, ustart)) fudge++, start = i; else if (IsMarker (lumpinfo + i, uend)) fudge--, flatHack = i; } if (start > flatHack) fudge--; if (fudge >= 0) flatHack = 0; } newlumpinfos = new lumpinfo_t[numlumps]; newlumps = 0; oldlumps = 0; insideBlock = false; for (i = 0; i < numlumps; i++) { if (!insideBlock) { // Check if this is the start of a block if (IsMarker (lumpinfo + i, ustart)) { insideBlock = true; // Create start marker if we haven't already if (!newlumps) { newlumps++; strncpy (newlumpinfos[0].name, ustart, 8); newlumpinfos[0].handle = NULL; newlumpinfos[0].position = newlumpinfos[0].size = 0; newlumpinfos[0].namespc = ns_global; } } else { // Copy lumpinfo down this list lumpinfo[oldlumps++] = lumpinfo[i]; } } else { // Check if this is the end of a block if (flatHack) { if (flatHack == i) { insideBlock = false; flatHack = 0; } else { if (lumpinfo[i].size != 4096) { lumpinfo[oldlumps++] = lumpinfo[i]; } else { newlumpinfos[newlumps] = lumpinfo[i]; newlumpinfos[newlumps++].namespc = space; } } } else if (i && lumpinfo[i].handle != lumpinfo[i-1].handle) { // Blocks cannot span multiple files insideBlock = false; lumpinfo[oldlumps++] = lumpinfo[i]; } else if (IsMarker (lumpinfo + i, uend)) { // It is. We'll add the end marker once // we've processed everything. insideBlock = false; } else { newlumpinfos[newlumps] = lumpinfo[i]; newlumpinfos[newlumps++].namespc = space; } } } // Now copy the merged lumps to the end of the old list // and create the end marker entry. if (newlumps) { if (oldlumps + newlumps > numlumps) lumpinfo = (lumpinfo_t *)Realloc (lumpinfo, oldlumps + newlumps); memcpy (lumpinfo + oldlumps, newlumpinfos, sizeof(lumpinfo_t) * newlumps); numlumps = oldlumps + newlumps; strncpy (lumpinfo[numlumps].name, uend, 8); lumpinfo[numlumps].handle = NULL; lumpinfo[numlumps].position = lumpinfo[numlumps].size = 0; lumpinfo[numlumps].namespc = ns_global; numlumps++; } delete[] newlumpinfos; }
// // Merge lumps between start and end markers. // Basically from Boom too, but modified. // void W_MergeLumps(char *start, char *end) { lumpinfo_t *newlumpinfo; int oldlumps; int newlumps; int in_block = 0; int i; newlumpinfo = (lumpinfo_t *)alloca(numlumps * sizeof(lumpinfo_t)); oldlumps = newlumps = 0; for (i = 0; i < numlumps; i++) { // process lumps in global namespace if (!in_block) { // check for start of block if (IsMarker(start, lumpinfo[i].name)) { in_block = 1; if (!newlumps) { newlumps++; memset(newlumpinfo[0].name, 0, 8); strcpy(newlumpinfo[0].name, start); newlumpinfo[0].handle = -1; newlumpinfo[0].position = newlumpinfo[0].size = 0; } } // else copy it else { lumpinfo[oldlumps++] = lumpinfo[i]; } } // process lumps in sprites or flats namespace else { // check for end of block if (IsMarker(end, lumpinfo[i].name)) { in_block = 0; } else if (i && lumpinfo[i].handle != lumpinfo[i-1].handle) { in_block = 0; lumpinfo[oldlumps++] = lumpinfo[i]; } else { newlumpinfo[newlumps++] = lumpinfo[i]; } } } // now copy the merged lumps to the end of the old list if (newlumps) { if (oldlumps + newlumps > numlumps) lumpinfo = realloc(lumpinfo, (oldlumps + newlumps) * sizeof(lumpinfo_t)); memcpy(lumpinfo + oldlumps, newlumpinfo, sizeof(lumpinfo_t) * newlumps); numlumps = oldlumps + newlumps; memset(lumpinfo[numlumps].name, 0, 8); strcpy(lumpinfo[numlumps].name, end); lumpinfo[numlumps].handle = -1; lumpinfo[numlumps].position = lumpinfo[numlumps].size = 0; numlumps++; } }
void FWadFile::SetNamespace(const char *startmarker, const char *endmarker, namespace_t space, bool flathack) { bool warned = false; int numstartmarkers = 0, numendmarkers = 0; unsigned int i; TArray<Marker> markers; for(i = 0; i < NumLumps; i++) { if (IsMarker(i, startmarker)) { Marker m = {0, i }; markers.Push(m); numstartmarkers++; } else if (IsMarker(i, endmarker)) { Marker m = {1, i }; markers.Push(m); numendmarkers++; } } if (numstartmarkers == 0) { if (numendmarkers == 0) return; // no markers found Printf(TEXTCOLOR_YELLOW"WARNING: %s marker without corresponding %s found.\n", endmarker, startmarker); if (flathack) { // We have found no F_START but one or more F_END markers. // mark all lumps before the last F_END marker as potential flats. int end = markers[markers.Size()-1].index; for(int i = 0; i < end; i++) { if (Lumps[i].LumpSize == 4096) { // We can't add this to the flats namespace but // it needs to be flagged for the texture manager. DPrintf("Marking %s as potential flat\n", Lumps[i].Name); Lumps[i].Flags |= LUMPF_MAYBEFLAT; } } } return; } i = 0; while (i < markers.Size()) { int start, end; if (markers[i].markertype != 0) { Printf(TEXTCOLOR_YELLOW"WARNING: %s marker without corresponding %s found.\n", endmarker, startmarker); i++; continue; } start = i++; // skip over subsequent x_START markers while (i < markers.Size() && markers[i].markertype == 0) { Printf(TEXTCOLOR_YELLOW"WARNING: duplicate %s marker found.\n", startmarker); i++; continue; } // same for x_END markers while (i < markers.Size()-1 && (markers[i].markertype == 1 && markers[i+1].markertype == 1)) { Printf(TEXTCOLOR_YELLOW"WARNING: duplicate %s marker found.\n", endmarker); i++; continue; } // We found a starting marker but no end marker. Ignore this block. if (i >= markers.Size()) { Printf(TEXTCOLOR_YELLOW"WARNING: %s marker without corresponding %s found.\n", startmarker, endmarker); end = NumLumps; } else { end = markers[i++].index; } // we found a marked block DPrintf("Found %s block at (%d-%d)\n", startmarker, markers[start].index, end); for(int j = markers[start].index + 1; j < end; j++) { if (Lumps[j].Namespace != ns_global) { if (!warned) { Printf(TEXTCOLOR_YELLOW"WARNING: Overlapping namespaces found (lump %d)\n", j); } warned = true; } else if (space == ns_sprites && Lumps[j].LumpSize < 8) { // sf 26/10/99: // ignore sprite lumps smaller than 8 bytes (the smallest possible) // in size -- this was used by some dmadds wads // as an 'empty' graphics resource DPrintf(" Skipped empty sprite %s (lump %d)\n", Lumps[j].Name, j); } else { Lumps[j].Namespace = space; } } } }