--- 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, },