src/newgrf.c
branchcustombridgeheads
changeset 5648 1608018c5ff2
parent 5645 72ebd9e4cd64
--- a/src/newgrf.c	Wed Jan 03 20:00:29 2007 +0000
+++ b/src/newgrf.c	Thu Jan 11 13:16:26 2007 +0000
@@ -1412,6 +1412,34 @@
 	}
 }
 
+/* Action 0x00 (GLS_SAFETYSCAN) */
+static void SafeChangeInfo(byte *buf, int len)
+{
+	uint8 feature;
+	uint8 numprops;
+	uint8 numinfo;
+	uint8 index;
+
+	check_length(len, 6, "SafeChangeInfo");
+	buf++;
+	feature  = grf_load_byte(&buf);
+	numprops = grf_load_byte(&buf);
+	numinfo  = grf_load_byte(&buf);
+	index    = grf_load_byte(&buf);
+
+	if (feature == GSF_BRIDGE && numprops == 1) {
+		uint8 prop = grf_load_byte(&buf);
+		/* Bridge property 0x0D is redefinition of sprite layout tables, which
+		 * is considered safe. */
+		if (prop == 0x0D) return;
+	}
+
+	SETBIT(_cur_grfconfig->flags, GCF_UNSAFE);
+
+	/* Skip remainder of GRF */
+	_skip_sprites = -1;
+}
+
 #undef FOR_EACH_OBJECT
 
 /**
@@ -2451,8 +2479,8 @@
 }
 
 
-/* Action 0x08 (GLS_SAFETYSCAN) */
-static void SafeInfo(byte *buf, int len)
+/* Action 0x08 (GLS_FILESCAN) */
+static void ScanInfo(byte *buf, int len)
 {
 	uint8 version;
 	uint32 grfid;
@@ -2483,12 +2511,6 @@
 
 		if (info_len < len) _cur_grfconfig->info  = TranslateTTDPatchCodes(info);
 	}
-}
-
-/* Action 0x08 (GLS_INFOSCAN) */
-static void ScanInfo(byte *buf, int len)
-{
-	SafeInfo(buf, len);
 
 	/* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
 	_skip_sprites = -1;
@@ -2619,6 +2641,29 @@
 	grfmsg(2, "GRFComment: %s", comment);
 }
 
+/* Action 0x0D (GLS_SAFETYSCAN) */
+static void SafeParamSet(byte *buf, int len)
+{
+	uint8 target;
+
+	check_length(len, 5, "SafeParamSet");
+	buf++;
+	target = grf_load_byte(&buf);
+
+	/* Only writing GRF parameters is considered safe */
+	if (target < 0x80) return;
+
+	/* GRM could be unsafe, but as here it can only happen after other GRFs
+	 * are loaded, it should be okay. If the GRF tried to use the slots it
+	 * reserved, it would be marked unsafe anyway. GRM for (e.g. bridge)
+	 * sprites  is considered safe. */
+
+	SETBIT(_cur_grfconfig->flags, GCF_UNSAFE);
+
+	/* Skip remainder of GRF */
+	_skip_sprites = -1;
+}
+
 /* Action 0x0D */
 static void ParamSet(byte *buf, int len)
 {
@@ -2908,6 +2953,37 @@
 	}
 }
 
+/* Action 0x0E (GLS_SAFETYSCAN) */
+static void SafeGRFInhibit(byte *buf, int len)
+{
+	/* <0E> <num> <grfids...>
+	 *
+	 * B num           Number of GRFIDs that follow
+	 * D grfids        GRFIDs of the files to deactivate */
+
+	byte num;
+	int i;
+
+	check_length(len, 1, "GRFInhibit");
+	buf++, len--;
+	num = grf_load_byte(&buf); len--;
+	check_length(len, 4 * num, "GRFInhibit");
+
+	for (i = 0; i < num; i++) {
+		uint32 grfid = grf_load_dword(&buf);
+
+		/* GRF is unsafe it if tries to deactivate other GRFs */
+		if (grfid != _cur_grfconfig->grfid) {
+			SETBIT(_cur_grfconfig->flags, GCF_UNSAFE);
+
+			/* Skip remainder of GRF */
+			_skip_sprites = -1;
+
+			return;
+		}
+	}
+}
+
 /* Action 0x0E */
 static void GRFInhibit(byte *buf, int len)
 {
@@ -3169,8 +3245,8 @@
 {
 	SETBIT(_cur_grfconfig->flags, GCF_UNSAFE);
 
-	/* Skip remainder of GRF if GRF ID is set */
-	if (_cur_grfconfig->grfid != 0) _skip_sprites = -1;
+	/* Skip remainder of GRF */
+	_skip_sprites = -1;
 }
 
 
@@ -3192,7 +3268,7 @@
 	                   |        ((_patches.mammoth_trains ? 1 : 0) << 0x08)  // mammothtrains
 	                   |                                        (1 << 0x09)  // trainrefit
 	                   |                                        (0 << 0x0B)  // subsidiaries
-	                   |       ((_patches.gradual_loading ? 1 : 0) << 0x1C)  // gradualloading
+	                   |       ((_patches.gradual_loading ? 1 : 0) << 0x0C)  // gradualloading
 	                   |                                        (1 << 0x12)  // unifiedmaglevmode - set bit 0 mode. Not revelant to OTTD
 	                   |                                        (1 << 0x13)  // unifiedmaglevmode - set bit 1 mode
 	                   |                                        (1 << 0x14)  // bridgespeedlimits
@@ -3514,7 +3590,7 @@
 	 * is not in memory and scanning the file every time would be too expensive.
 	 * In other stages we skip action 0x10 since it's already dealt with. */
 	static const SpecialSpriteHandler handlers[][GLS_END] = {
-		/* 0x00 */ { NULL,     GRFUnsafe, NULL,            NULL,       FeatureChangeInfo, },
+		/* 0x00 */ { NULL,     SafeChangeInfo, NULL,       NULL,       FeatureChangeInfo, },
 		/* 0x01 */ { NULL,     GRFUnsafe, NULL,            NULL,       NewSpriteSet, },
 		/* 0x02 */ { NULL,     GRFUnsafe, NULL,            NULL,       NewSpriteGroup, },
 		/* 0x03 */ { NULL,     GRFUnsafe, NULL,            NULL,       FeatureMapSpriteGroup, },
@@ -3522,13 +3598,13 @@
 		/* 0x05 */ { NULL,     NULL,      NULL,            NULL,       GraphicsNew, },
 		/* 0x06 */ { NULL,     NULL,      NULL,            CfgApply,   CfgApply, },
 		/* 0x07 */ { NULL,     NULL,      NULL,            NULL,       SkipIf, },
-		/* 0x08 */ { ScanInfo, SafeInfo,  NULL,            GRFInfo,    GRFInfo, },
+		/* 0x08 */ { ScanInfo, NULL,      NULL,            GRFInfo,    GRFInfo, },
 		/* 0x09 */ { NULL,     NULL,      NULL,            SkipIf,     SkipIf, },
 		/* 0x0A */ { NULL,     NULL,      NULL,            NULL,       SpriteReplace, },
 		/* 0x0B */ { NULL,     NULL,      NULL,            GRFError,   GRFError, },
 		/* 0x0C */ { NULL,     NULL,      NULL,            GRFComment, GRFComment, },
-		/* 0x0D */ { NULL,     GRFUnsafe, NULL,            ParamSet,   ParamSet, },
-		/* 0x0E */ { NULL,     GRFUnsafe, NULL,            GRFInhibit, GRFInhibit, },
+		/* 0x0D */ { NULL,     SafeParamSet, NULL,         ParamSet,   ParamSet, },
+		/* 0x0E */ { NULL,     SafeGRFInhibit, NULL,       GRFInhibit, GRFInhibit, },
 		/* 0x0F */ { NULL,     NULL,      NULL,            NULL,       NULL, },
 		/* 0x10 */ { NULL,     NULL,      DefineGotoLabel, NULL,       NULL, },
 		/* 0x11 */ { NULL,     GRFUnsafe, NULL,            NULL,       GRFSound, },