From 109ecfa0363906ada86ab6594a95f80235e46468 Mon Sep 17 00:00:00 2001 From: Ilya Shurumov Date: Tue, 17 Nov 2020 00:21:31 +0600 Subject: [PATCH] - fixed crash caused by unloaded spooled models --- src_rebuild/GAME/C/MODELS.C | 30 ++++++++++++++++++++++++------ src_rebuild/GAME/C/MODELS.H | 2 +- src_rebuild/GAME/C/SPOOL.C | 30 ++++-------------------------- 3 files changed, 29 insertions(+), 33 deletions(-) diff --git a/src_rebuild/GAME/C/MODELS.C b/src_rebuild/GAME/C/MODELS.C index 4e327bda..45f6bcfc 100644 --- a/src_rebuild/GAME/C/MODELS.C +++ b/src_rebuild/GAME/C/MODELS.C @@ -50,19 +50,33 @@ unsigned short *Low2LowerDetailTable = NULL; // End Line: 79 // [A] -void CleanSpooledModelSlots() +int staticModelSlotBitfield[48]; + +// [A] returns freed slot count +int CleanSpooledModelSlots() { int i; + int num_freed; + + num_freed = 0; // assign model pointers for (i = 0; i < MAX_MODEL_SLOTS; i++) // [A] bug fix. Init with dummyModel { - if(!(modelpointers[i]->shape_flags & 0x8000)) + // if bit does not indicate usage - reset to dummy model + if((staticModelSlotBitfield[i >> 5] & 1 << (i & 31)) == 0) { - modelpointers[i] = &dummyModel; - pLodModels[i] = &dummyModel; + if(modelpointers[i] != &dummyModel) + { + modelpointers[i] = &dummyModel; + pLodModels[i] = &dummyModel; + + num_freed++; + } } } + + return num_freed; } // [D] [T] @@ -78,6 +92,9 @@ void ProcessMDSLump(char *lump_file, int lump_size) mdsfile = (lump_file + 4); num_models_in_pack = modelAmts; + // [A] usage bits + ClearMem((char*)staticModelSlotBitfield, sizeof(staticModelSlotBitfield)); + // assign model pointers for (i = 0; i < MAX_MODEL_SLOTS; i++) // [A] bug fix. Init with dummyModel { @@ -92,9 +109,10 @@ void ProcessMDSLump(char *lump_file, int lump_size) if (size) { - model = (MODEL*)mdsfile; - model->shape_flags |= 0x8000; // [A] non-spooled flag + // add the usage bit + staticModelSlotBitfield[i >> 5] |= 1 << (i & 31); + model = (MODEL*)mdsfile; modelpointers[i] = model; } diff --git a/src_rebuild/GAME/C/MODELS.H b/src_rebuild/GAME/C/MODELS.H index e416d9a0..677fe316 100644 --- a/src_rebuild/GAME/C/MODELS.H +++ b/src_rebuild/GAME/C/MODELS.H @@ -14,7 +14,7 @@ extern unsigned short *Low2LowerDetailTable; extern int num_models_in_pack; -void CleanSpooledModelSlots(); +extern int CleanSpooledModelSlots(); extern void ProcessMDSLump(char *lump_file, int lump_size); // 0x00064CFC diff --git a/src_rebuild/GAME/C/SPOOL.C b/src_rebuild/GAME/C/SPOOL.C index e1c14d19..37958a43 100644 --- a/src_rebuild/GAME/C/SPOOL.C +++ b/src_rebuild/GAME/C/SPOOL.C @@ -1729,34 +1729,12 @@ void SetupModels(void) // [D] [T] void LoadInAreaModels(int area) { - int i; - MODEL* model; - int nmodels; - unsigned short* new_model_numbers; - int model_number; + int num_freed; - if(newmodels) - { - // clear old model ids - nmodels = *newmodels; - new_model_numbers = newmodels + 1; + // [A] invalidate previously used spooled slots + num_freed = CleanSpooledModelSlots(); - // set old model ids to dummy - for (i = 0; i < nmodels; i++) - { - model_number = new_model_numbers[i]; - - model = modelpointers[model_number]; - - if(model->shape_flags & 0x8000) - { - modelpointers[model_number] = &dummyModel; - pLodModels[model_number] = &dummyModel; - } - } - - SPOOL_INFO("freed %d model slots\n", nmodels); - } + SPOOL_INFO("freed %d model slots\n", num_freed); int length = AreaData[area].model_size; newmodels = (ushort *)(model_spool_buffer + (length-1) * 2048);