Commits

GhostlyDeath  committed 41c8638

Fix crashes related to dynamic WAD loading.

  • Participants
  • Parent commits c02159e

Comments (0)

Files changed (8)

File src/d_main.c

 	{NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, 0, COREGAME_DOOM, false, NULL, 0, 0}
 };
 
-/*** LOCALS ***/
+/*** GLOBALS ***/
 
 CoreGame_t g_CoreGame = COREGAME_UNKNOWN;		// Core game mode
 const void* g_ReMooDPtr = NULL;					// Pointer to remood.wad
 const char* g_IWADMapInfoName = NULL;			// Name of IWAD MAPINFO
 uint32_t g_IWADFlags = 0;						// IWAD Flags
 
+/*** LOCALS ***/
+
+static char l_IWADSum[33];						// IWAD Sum
+
 /*** FUNCTIONS ***/
 
 /* DS_FieldNumber() -- Get field number from string */
 		return true;
 	}
 	
+	// Determine if the IWAD changed
+	for (i = 0; i <= 32; i++)
+		if (l_IWADSum[i] != BaseWAD->SimpleSumChars[i])
+		{
+			if (devparm)
+				CONL_PrintF("DS_DetectGameMode: IWAD Signature Changed.\n");
+			g_CoreGame = COREGAME_UNKNOWN;
+			break;
+		}
+	
 	// Is the stack already placed?
 	if (g_CoreGame != COREGAME_UNKNOWN)
 	{
 		return true;
 	}
 	
+	// Copy IWAD sum to sum
+	for (i = 0; i <= 32; i++)
+		l_IWADSum[i] = BaseWAD->SimpleSumChars[i];
+	
 	/* Debug */
 	if (devparm)
 		CONL_PrintF("DS_DetectGameMode: Detecting game type...\n");
 	/* Register game identifier, based on pushes */
 	if (devparm)
 		CONL_PrintF("D_LoadGameFilesEx: Registering mode detector.\n");
-	if (!WL_RegisterOCCB(DS_DetectGameMode, 1))
+	if (!WL_RegisterOCCB(DS_DetectGameMode, WLDCO_IWADDETECT))
 		I_Error("D_LoadGameFilesEx: Failed to register IWAD OCCB!");
-	if (!WL_RegisterOCCB(DS_DetectReMooDWAD, 2))
+	if (!WL_RegisterOCCB(DS_DetectReMooDWAD, WLDCO_RWADDETECT))
 		I_Error("D_LoadGameFilesEx: Failed to register ReMooD OCCB!");
 	
 	/* Clear */
 	sprnames = NULL;
 	NUMSPRITES = 0;
 	
+	/* Remove All Objects Pre-Defined */
+	if (mobjinfo)
+		Z_Free(mobjinfo);
+	mobjinfo = NULL;
+	NUMMOBJTYPES = 0;
+	
 	// Add first state, an S_NULL
 	Z_ResizeArray((void**)&states, sizeof(*states), NUMSTATES, NUMSTATES + 1);
 	states[NUMSTATES++] = &StaticSNull;
 		if (TempObject->RFamilyClass)
 			TempObject->RBaseFamily = INFO_GetTypeByName(TempObject->RFamilyClass);
 		
-		// Fix Object Speed (non-missiles do not use fractional units)
-		if (!(TempObject->flags & MF_MISSILE))
-		{
-			TempObject->speed >>= FRACBITS;
-			TempObject->RFastSpeed >>= FRACBITS;
-		}
-		
 		// Setup States
 		for (z = 0; z < NUMINFOOBJECTSTATEGROUPS; z++)
 			for (j = 0; c_ObjectLocalStates[j].Name; j++)
 // mobj is intentional. Why? So in -fast you could make certain monsters fast
 // and not others with the same type. You could have a slowdown type weapon that
 // when used with fast monsters negates the fast speed?
-#define __REMOOD_GETSPEEDMO(mo) ((((mo)->RXFlags[0] & MFREXA_ENABLEFASTSPEED) && cv_fastmonsters.value) ? (mo)->info->RFastSpeed : (mo)->info->speed)
+#define __REMOOD_GETSPEEDMO(mo) ((((((mo)->RXFlags[0] & MFREXA_ENABLEFASTSPEED) && cv_fastmonsters.value) ? (mo)->info->RFastSpeed : (mo)->info->speed)) >> (((mo)->flags & MF_MISSILE) ? 0 : 16))
 
 #endif
 

File src/p_info.c

 				CurrentInfo = NULL;
 			}
 			
-			// Setup level title?
-			if (!CurrentInfo->Title)
+			// Setup Defaults
+			if (CurrentInfo)
 			{
-				// Set as MAPINFO level
-				CurrentInfo->SetBits[0] = PLIBL_MAPINFO;
+				// Setup level title?
+				if (!CurrentInfo->Title)
+				{
+					// Set as MAPINFO level
+					CurrentInfo->SetBits[0] = PLIBL_MAPINFO;
 				
-				// Ignore any whitespace
-				for (; *p && (*p == ' ' || *p == '\t'); p++)
-					;
+					// Ignore any whitespace
+					for (; *p && (*p == ' ' || *p == '\t'); p++)
+						;
 				
-				// Ignore any quotes
-				if (*p == '\"')
-				{
-					// Null the quote away
-					*(p++) = '\0';
+					// Ignore any quotes
+					if (*p == '\"')
+					{
+						// Null the quote away
+						*(p++) = '\0';
 				
-					// Find the next quote, null that then die
-					for (q = p; *q; q++)
-						if (*q == '\"')
-						{
-							*q = '\0';
-							break;
-						}
+						// Find the next quote, null that then die
+						for (q = p; *q; q++)
+							if (*q == '\"')
+							{
+								*q = '\0';
+								break;
+							}
+					}
+				
+					// Place level name here
+					CurrentInfo->Title = Z_StrDup(p, PU_WLDKRMOD, NULL);
 				}
-				
-				// Place level name here
-				CurrentInfo->Title = Z_StrDup(p, PU_WLDKRMOD, NULL);
 			}
 			
 			// Copy default settings?
 	if (devparm)
 		CONL_PrintF("PS_WLInfoOCCB: Building composite...\n");
 	
+	/* Clear level info composite */
+	if (l_CompInfos)
+	{
+		// Clear subs
+		for (i = 0; i < l_NumCompInfos; i++)
+			if (l_CompInfos[i])
+				if (l_CompInfos[i]->IsComposite)
+				{
+					// Clear out strings
+					// Copy fields over (all but authors)
+					for (Field = 0; !c_PMIFields[Field].IsEnd; Field++)
+					{
+						// Get source
+						vP = (void*)(((uintptr_t)l_CompInfos[i]) + c_PMIFields[Field].Offset);
+					
+						// Which type now?
+						switch (c_PMIFields[Field].Type)
+						{
+								// Copy String
+							case PPMFIFT_STRING:
+								if (*((char**)vP))
+									Z_Free(*((char**)vP));
+								break;
+								
+								// Nothing to be freed
+							default:
+								break;
+						}
+					}
+					
+					// Clear self away
+					Z_Free(l_CompInfos[i]);
+				}
+		
+		// Clear master
+		Z_Free(l_CompInfos);
+	}
+	l_CompInfos = NULL;
+	l_NumCompInfos = 0;
+	
 	/* First, The IWAD must get their MAPINFOs loaded from remood.wad */
 	// IWAD is always first
 	Rover = WL_IterateVWAD(NULL, true);
 		Holder->IWADParsed = true;
 	}
 	
-	/* Clear level info composite */
-	if (l_CompInfos)
-	{
-		// Clear subs
-		for (i = 0; i < l_NumCompInfos; i++)
-			if (l_CompInfos[i])
-				if (l_CompInfos[i]->IsComposite)
-				{
-					// Clear out strings
-					
-					// Clear self away
-					Z_Free(l_CompInfos[i]);
-				}
-		
-		// Clear master
-		Z_Free(l_CompInfos);
-	}
-	l_CompInfos = NULL;
-	l_NumCompInfos = 0;
-	
 	/* Now merge all the level information into a composite form */
 	for (Rover = WL_IterateVWAD(NULL, true); Rover; Rover = WL_IterateVWAD(Rover, true))
 	{

File src/r_data.c

 		Z_HashDeleteTable(l_TextureHashes);
 	l_TextureHashes = NULL;
 	
+	// Delete sprites
+	if (g_ExSprites)
+		Z_Free(g_ExSprites);
+	if (sprites)
+		Z_Free(sprites);
+	g_ExSprites = NULL;
+	g_NumExSprites = 0;
+	sprites = NULL;
+	numsprites = 0;
+	
 	/* Go through WAD files in reverse order */
 	// Why reverse? So later textures take precedence, when a texture is to be
 	// slapped onto the pointer list, see if a texture of the same name already

File src/v_video.c

 	/* Load colormaps */
 	V_InitializeColormaps();
 	
+	/* Clear all defined image info */
+	
 	return true;
 }
 
 		WL_PushWAD(NewWAD);
 		
 		// Push remaining WADs
-		for (i = i - 1; i >= 0; i--)
+		for (i = i - 2; i >= 0; i--)
 			WL_PushWAD(WArray[i]);
 		
 		// Unlock OCCB (Done with changes)
 /* WL_DataOCCBOrder_t -- Orders for data handling (OCCBs) */
 typedef enum WL_DataOCCBOrder_e
 {
+	WLDCO_IWADDETECT = 1,			// IWAD Detection
+	WLDCO_RWADDETECT = 2,			// ReMooD.WAD Detection
 	WLDCO_RMOD = 30,				// ReMooD Map Object Data
 	WLDCO_VFONTS = 75,				// Fonts
 	WLDCO_TEXTURES = 75,			// Textures