(svn r8180) -Backport from trunk (r8093, r8094, r8105, r8106, (r8107), r8111, r8165): 0.5
authorDarkvater
Wed, 17 Jan 2007 01:17:44 +0000
branch0.5
changeset 5416 87d5e006851b
parent 5415 a7e0e4e75be2
child 5417 a66d9847aef2
(svn r8180) -Backport from trunk (r8093, r8094, r8105, r8106, (r8107), r8111, r8165):
- Show the activated status of the GRF after pressing apply in window (r8094)
- Add the ability to load savegames without matching grf's.
*NOTE*: currently this feature is different from trunk in behaviour as it does NOT
allow you to load savegames with MISSING grfs only compatible (matching GRFID, non-
matching MD5SUM).
lang/english.txt
newgrf_config.c
newgrf_config.h
newgrf_gui.c
openttd.c
string.c
string.h
--- a/lang/english.txt	Wed Jan 17 01:02:51 2007 +0000
+++ b/lang/english.txt	Wed Jan 17 01:17:44 2007 +0000
@@ -2914,6 +2914,11 @@
 
 STR_NEWGRF_NOT_FOUND                                            :{RED}Matching file not found
 STR_NEWGRF_DISABLED                                             :{RED}Disabled
+STR_NEWGRF_COMPATIBLE_LOADED                                    :{ORANGE}Matching file not found (compatible GRF loaded)
+
+STR_NEWGRF_COMPATIBLE_LOAD_WARNING                              :{WHITE}Compatible GRF(s) loaded for missing files
+STR_NEWGRF_DISABLED_WARNING                                     :{WHITE}Missing GRF file(s) have been disabled
+STR_NEWGRF_NOT_FOUND_WARNING                                    :{WHITE}Missing GRF file(s) to be able to load game
 
 STR_CURRENCY_WINDOW                                             :{WHITE}Custom currency
 STR_CURRENCY_EXCHANGE_RATE                                      :{LTBLUE}Exchange rate: {ORANGE}{CURRENCY} = £ {COMMA}
--- a/newgrf_config.c	Wed Jan 17 01:02:51 2007 +0000
+++ b/newgrf_config.c	Wed Jan 17 01:17:44 2007 +0000
@@ -196,27 +196,46 @@
 }
 
 
-/* Check if all GRFs in the GRF Config can be loaded */
-bool IsGoodGRFConfigList(void)
+/** Check if all GRFs in the GRF config from a savegame can be loaded.
+ * @return will return any of the following 3 values:<br>
+ * <ul>
+ * <li> GCF_ACTIVATED: No problems occured, all GRF files were found and loaded
+ * <li> GCF_COMPATIBLE: For one or more GRF's no exact match was found, but a
+ *     compatible GRF with the same grfid was found and used instead
+ * <li> GCF_NOT_FOUND: For one or more GRF's no match was found at all
+ * </ul> */
+GCF_Flags IsGoodGRFConfigList(void)
 {
-	bool res = true;
+	GCF_Flags res = GCF_ACTIVATED;
 	GRFConfig *c;
 
 	for (c = _grfconfig; c != NULL; c = c->next) {
 		const GRFConfig *f = FindGRFConfig(c->grfid, c->md5sum);
 		if (f == NULL) {
-			char buf[512], *p = buf;
-			uint i;
+			char buf[256];
 
-			p += snprintf(p, lastof(buf) - p, "Couldn't find NewGRF %08X (%s) checksum ", BSWAP32(c->grfid), c->filename);
-			for (i = 0; i < lengthof(c->md5sum); i++) {
-				p += snprintf(p, lastof(buf) - p, "%02X", c->md5sum[i]);
+			/* If we have not found the exactly matching GRF try to find one with the
+			 * same grfid, as it most likely is compatible */
+			f = FindGRFConfig(c->grfid, NULL);
+			if (f != NULL) {
+				md5sumToString(buf, lastof(buf), c->md5sum);
+				DEBUG(grf, 1) ("[GRF] NewGRF %08X (%s) not found; checksum %s. Compatibility mode on", BSWAP32(c->grfid), c->filename, buf);
+				SETBIT(c->flags, GCF_COMPATIBLE);
+
+				/* Non-found has precedence over compatibility load */
+				if (res != GCF_NOT_FOUND) res = GCF_COMPATIBLE;
+				goto compatible_grf;
 			}
-			ShowInfo(buf);
 
-			res = false;
+			/* No compatible grf was found, mark it as disabled */
+			md5sumToString(buf, lastof(buf), c->md5sum);
+			DEBUG(grf, 0) ("[GRF] NewGRF %08X (%s) not found; checksum %s", BSWAP32(c->grfid), c->filename, buf);
+
+			SETBIT(c->flags, GCF_NOT_FOUND);
+			res = GCF_NOT_FOUND;
 		} else {
-			DEBUG(grf, 1) ("[GRF] Loading GRF %08X from %s", BSWAP32(c->grfid), f->filename);
+compatible_grf:
+			DEBUG(grf, 1) ("[GRF] Loading GRF %08X from %s", BSWAP32(f->grfid), f->filename);
 			/* The filename could be the filename as in the savegame. As we need
 			 * to load the GRF here, we need the correct filename, so overwrite that
 			 * in any case and set the name and info when it is not set already.
@@ -225,6 +244,7 @@
 			if (!HASBIT(c->flags, GCF_COPY)) {
 				free(c->filename);
 				c->filename = strdup(f->filename);
+				memcpy(c->md5sum, f->md5sum, sizeof(c->md5sum));
 				if (c->name == NULL) c->name = strdup(f->name);
 				if (c->info == NULL) c->info = strdup(f->info);
 			}
@@ -317,15 +337,14 @@
 }
 
 
-/* Find a NewGRF in the scanned list */
-const GRFConfig *FindGRFConfig(uint32 grfid, uint8 *md5sum)
+/* Find a NewGRF in the scanned list, if md5sum is NULL, we don't care about it*/
+const GRFConfig *FindGRFConfig(uint32 grfid, const uint8 *md5sum)
 {
-	GRFConfig *c;
-	static const uint8 blanksum[sizeof(c->md5sum)] = { 0 };
-
+	const GRFConfig *c;
 	for (c = _all_grfs; c != NULL; c = c->next) {
 		if (c->grfid == grfid) {
-			if (memcmp(blanksum, c->md5sum, sizeof(c->md5sum)) == 0) CalcGRFMD5Sum(c);
+			if (md5sum == NULL) return c;
+
 			if (memcmp(md5sum, c->md5sum, sizeof(c->md5sum)) == 0) return c;
 		}
 	}
--- a/newgrf_config.h	Wed Jan 17 01:02:51 2007 +0000
+++ b/newgrf_config.h	Wed Jan 17 01:17:44 2007 +0000
@@ -4,15 +4,16 @@
 #define NEWGRF_CONFIG_H
 
 /* GRF config bit flags */
-enum {
-	GCF_DISABLED,
-	GCF_NOT_FOUND,
-	GCF_ACTIVATED,
-	GCF_SYSTEM,
-	GCF_UNSAFE,
-	GCF_STATIC,
+typedef enum {
+	GCF_DISABLED,  ///< GRF file is disabled
+	GCF_NOT_FOUND, ///< GRF file was not found in the local cache
+	GCF_ACTIVATED, ///< GRF file is active
+	GCF_SYSTEM,    ///< GRF file is an openttd-internal system grf
+	GCF_UNSAFE,    ///< GRF file is unsafe for static usage
+	GCF_STATIC,    ///< GRF file is used statically (can be used in any MP game)
+	GCF_COMPATIBLE,///< GRF file does not exactly match the requested GRF (different MD5SUM), but grfid matches)
 	GCF_COPY,      ///< The data is copied from a grf in _all_grfs
-};
+} GCF_Flags;
 
 typedef struct GRFConfig {
 	char *filename;
@@ -41,14 +42,14 @@
 extern GRFConfig *_grfconfig_static;
 
 void ScanNewGRFFiles(void);
-const GRFConfig *FindGRFConfig(uint32 grfid, uint8 *md5sum);
+const GRFConfig *FindGRFConfig(uint32 grfid, const uint8 *md5sum);
 GRFConfig *GetGRFConfig(uint32 grfid);
 GRFConfig **CopyGRFConfigList(GRFConfig **dst, const GRFConfig *src);
 void AppendStaticGRFConfigs(GRFConfig **dst);
 void ClearGRFConfig(GRFConfig **config);
 void ClearGRFConfigList(GRFConfig **config);
 void ResetGRFConfig(bool defaults);
-bool IsGoodGRFConfigList(void);
+GCF_Flags IsGoodGRFConfigList(void);
 bool FillGRFDetails(GRFConfig *config, bool is_static);
 char *GRFBuildParamList(char *dst, const GRFConfig *c, const char *last);
 
--- a/newgrf_gui.c	Wed Jan 17 01:02:51 2007 +0000
+++ b/newgrf_gui.c	Wed Jan 17 01:17:44 2007 +0000
@@ -40,9 +40,7 @@
 
 static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint w, bool show_params)
 {
-	char buff[512];
-	char *s;
-	uint i;
+	char buff[256];
 
 	/* Draw filename or not if it is not known (GRF sent over internet) */
 	if (c->filename != NULL) {
@@ -56,10 +54,7 @@
 	y += DrawStringMultiLine(x, y, STR_NEWGRF_GRF_ID, w);
 
 	/* Prepare and draw MD5 sum */
-	s = buff;
-	for (i = 0; i < lengthof(c->md5sum); i++) {
-		s += snprintf(s, lastof(buff) - s, "%02X", c->md5sum[i]);
-	}
+	md5sumToString(buff, lastof(buff), c->md5sum);
 	SetDParamStr(0, buff);
 	y += DrawStringMultiLine(x, y, STR_NEWGRF_MD5SUM, w);
 
@@ -75,8 +70,9 @@
 	}
 
 	/* Show flags */
-	if (HASBIT(c->flags, GCF_NOT_FOUND)) y += DrawStringMultiLine(x, y, STR_NEWGRF_NOT_FOUND, w);
-	if (HASBIT(c->flags, GCF_DISABLED))  y += DrawStringMultiLine(x, y, STR_NEWGRF_DISABLED, w);
+	if (HASBIT(c->flags, GCF_NOT_FOUND))  y += DrawStringMultiLine(x, y, STR_NEWGRF_NOT_FOUND, w);
+	if (HASBIT(c->flags, GCF_DISABLED))   y += DrawStringMultiLine(x, y, STR_NEWGRF_DISABLED, w);
+	if (HASBIT(c->flags, GCF_COMPATIBLE)) y += DrawStringMultiLine(x, y, STR_NEWGRF_COMPATIBLE_LOADED, w);
 
 	/* Draw GRF info if it exists */
 	if (c->info != NULL && strlen(c->info) != 0) {
@@ -283,9 +279,19 @@
 	if (yes_clicked) {
 		Window *w = FindWindowById(WC_GAME_OPTIONS, 0);
 		newgrf_d *nd = &WP(w, newgrf_d);
+		GRFConfig *c;
+		int i = 0;
 
 		CopyGRFConfigList(nd->orig_list, *nd->list);
 		ReloadNewGRFData();
+
+		/* Show new, updated list */
+		for (c = *nd->list; c != NULL && c != nd->sel; c = c->next, i++);
+		CopyGRFConfigList(nd->list, *nd->orig_list);
+		for (c = *nd->list; c != NULL && i > 0; c = c->next, i--);
+		nd->sel = c;
+
+		SetWindowDirty(w);
 	}
 }
 
@@ -312,7 +318,9 @@
 					if (HASBIT(c->flags, GCF_NOT_FOUND) || HASBIT(c->flags, GCF_DISABLED)) {
 						pal = PALETTE_TO_RED;
 					} else if (HASBIT(c->flags, GCF_STATIC)) {
-						pal = PALETTE_TO_YELLOW;
+						pal = PALETTE_TO_GREY;
+					} else if (HASBIT(c->flags, GCF_COMPATIBLE)) {
+						pal = PALETTE_TO_ORANGE;
 					} else if (HASBIT(c->flags, GCF_ACTIVATED)) {
 						pal = PALETTE_TO_GREEN;
 					} else {
--- a/openttd.c	Wed Jan 17 01:02:51 2007 +0000
+++ b/openttd.c	Wed Jan 17 01:17:44 2007 +0000
@@ -1157,8 +1157,17 @@
 	// convert road side to my format.
 	if (_opt.road_side) _opt.road_side = 1;
 
-	/* Check all NewGRFs are present */
-	if (!IsGoodGRFConfigList()) return false;
+	{
+		/* Check if all NewGRFs are present, we are very strict in MP mode */
+		GCF_Flags gcf_res = IsGoodGRFConfigList();
+		if (_networking && gcf_res != GCF_ACTIVATED) return false;
+
+		switch (gcf_res) {
+			case GCF_COMPATIBLE: _switch_mode_errorstr = STR_NEWGRF_COMPATIBLE_LOAD_WARNING; break;
+			case GCF_NOT_FOUND: return false; /*_switch_mode_errorstr = STR_NEWGRF_DISABLED_WARNING; break; */
+			default: break;
+		}
+	}
 
 	/* Update current year
 	 * must be done before loading sprites as some newgrfs check it */
--- a/string.c	Wed Jan 17 01:02:51 2007 +0000
+++ b/string.c	Wed Jan 17 01:17:44 2007 +0000
@@ -177,6 +177,25 @@
 #endif /* WIN32 */
 
 
+/** Convert the md5sum to a hexadecimal string representation
+ * @param buf buffer to put the md5sum into
+ * @param last last character of buffer (usually lastof(buf))
+ * @param md5sum the md5sum itself
+ * @return a pointer to the next character after the md5sum */
+char *md5sumToString(char *buf, const char *last, const uint8 md5sum[16])
+{
+	uint i;
+	char *p = buf;
+
+	for (i = 0; i < 16; i++) {
+		p += snprintf(p, last + 1 - p, "%02X", md5sum[i]);
+		if (p >= last) break;
+	}
+
+	return p;
+}
+
+
 /* UTF-8 handling routines */
 
 
--- a/string.h	Wed Jan 17 01:02:51 2007 +0000
+++ b/string.h	Wed Jan 17 01:17:44 2007 +0000
@@ -55,6 +55,8 @@
 	return t - str;
 }
 
+/** Convert the md5sum number to a 'hexadecimal' string, return next pos in buffer */
+char *md5sumToString(char *buf, const char *last, const uint8 md5sum[16]);
 
 typedef uint32 WChar;