# HG changeset patch
# User Darkvater
# Date 1168996664 0
# Node ID 87d5e006851bc8227a242fe1cc75aa9793b4501b
# Parent a7e0e4e75be2bc77f4e89b6b960694ab3d6fdd3d
(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).
diff -r a7e0e4e75be2 -r 87d5e006851b lang/english.txt
--- 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}
diff -r a7e0e4e75be2 -r 87d5e006851b newgrf_config.c
--- 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:
+ *
+ * - GCF_ACTIVATED: No problems occured, all GRF files were found and loaded
+ *
- 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
+ *
- GCF_NOT_FOUND: For one or more GRF's no match was found at all
+ *
*/
+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;
}
}
diff -r a7e0e4e75be2 -r 87d5e006851b newgrf_config.h
--- 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);
diff -r a7e0e4e75be2 -r 87d5e006851b newgrf_gui.c
--- 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 {
diff -r a7e0e4e75be2 -r 87d5e006851b openttd.c
--- 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 */
diff -r a7e0e4e75be2 -r 87d5e006851b string.c
--- 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 */
diff -r a7e0e4e75be2 -r 87d5e006851b string.h
--- 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;