1
0
Fork 0

(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).
release/0.5
Darkvater 2007-01-17 01:17:44 +00:00
parent 40245ce496
commit ac3b1883ed
7 changed files with 102 additions and 39 deletions

View File

@ -2914,6 +2914,11 @@ STR_NEWGRF_DUPLICATE_GRFID :{WHITE}Cannot a
STR_NEWGRF_NOT_FOUND :{RED}Matching file not found STR_NEWGRF_NOT_FOUND :{RED}Matching file not found
STR_NEWGRF_DISABLED :{RED}Disabled 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_WINDOW :{WHITE}Custom currency
STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Exchange rate: {ORANGE}{CURRENCY} = £ {COMMA} STR_CURRENCY_EXCHANGE_RATE :{LTBLUE}Exchange rate: {ORANGE}{CURRENCY} = £ {COMMA}

View File

@ -196,27 +196,46 @@ void ResetGRFConfig(bool defaults)
} }
/* Check if all GRFs in the GRF Config can be loaded */ /** Check if all GRFs in the GRF config from a savegame can be loaded.
bool IsGoodGRFConfigList(void) * @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; GRFConfig *c;
for (c = _grfconfig; c != NULL; c = c->next) { for (c = _grfconfig; c != NULL; c = c->next) {
const GRFConfig *f = FindGRFConfig(c->grfid, c->md5sum); const GRFConfig *f = FindGRFConfig(c->grfid, c->md5sum);
if (f == NULL) { if (f == NULL) {
char buf[512], *p = buf; char buf[256];
uint i;
p += snprintf(p, lastof(buf) - p, "Couldn't find NewGRF %08X (%s) checksum ", BSWAP32(c->grfid), c->filename); /* If we have not found the exactly matching GRF try to find one with the
for (i = 0; i < lengthof(c->md5sum); i++) { * same grfid, as it most likely is compatible */
p += snprintf(p, lastof(buf) - p, "%02X", c->md5sum[i]); 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 { } 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 /* 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 * 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. * in any case and set the name and info when it is not set already.
@ -225,6 +244,7 @@ bool IsGoodGRFConfigList(void)
if (!HASBIT(c->flags, GCF_COPY)) { if (!HASBIT(c->flags, GCF_COPY)) {
free(c->filename); free(c->filename);
c->filename = strdup(f->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->name == NULL) c->name = strdup(f->name);
if (c->info == NULL) c->info = strdup(f->info); if (c->info == NULL) c->info = strdup(f->info);
} }
@ -317,15 +337,14 @@ void ScanNewGRFFiles(void)
} }
/* Find a NewGRF in the scanned list */ /* Find a NewGRF in the scanned list, if md5sum is NULL, we don't care about it*/
const GRFConfig *FindGRFConfig(uint32 grfid, uint8 *md5sum) const GRFConfig *FindGRFConfig(uint32 grfid, const uint8 *md5sum)
{ {
GRFConfig *c; const GRFConfig *c;
static const uint8 blanksum[sizeof(c->md5sum)] = { 0 };
for (c = _all_grfs; c != NULL; c = c->next) { for (c = _all_grfs; c != NULL; c = c->next) {
if (c->grfid == grfid) { 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; if (memcmp(md5sum, c->md5sum, sizeof(c->md5sum)) == 0) return c;
} }
} }

View File

@ -4,15 +4,16 @@
#define NEWGRF_CONFIG_H #define NEWGRF_CONFIG_H
/* GRF config bit flags */ /* GRF config bit flags */
enum { typedef enum {
GCF_DISABLED, GCF_DISABLED, ///< GRF file is disabled
GCF_NOT_FOUND, GCF_NOT_FOUND, ///< GRF file was not found in the local cache
GCF_ACTIVATED, GCF_ACTIVATED, ///< GRF file is active
GCF_SYSTEM, GCF_SYSTEM, ///< GRF file is an openttd-internal system grf
GCF_UNSAFE, GCF_UNSAFE, ///< GRF file is unsafe for static usage
GCF_STATIC, 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_COPY, ///< The data is copied from a grf in _all_grfs
}; } GCF_Flags;
typedef struct GRFConfig { typedef struct GRFConfig {
char *filename; char *filename;
@ -41,14 +42,14 @@ extern GRFConfig *_grfconfig_newgame;
extern GRFConfig *_grfconfig_static; extern GRFConfig *_grfconfig_static;
void ScanNewGRFFiles(void); void ScanNewGRFFiles(void);
const GRFConfig *FindGRFConfig(uint32 grfid, uint8 *md5sum); const GRFConfig *FindGRFConfig(uint32 grfid, const uint8 *md5sum);
GRFConfig *GetGRFConfig(uint32 grfid); GRFConfig *GetGRFConfig(uint32 grfid);
GRFConfig **CopyGRFConfigList(GRFConfig **dst, const GRFConfig *src); GRFConfig **CopyGRFConfigList(GRFConfig **dst, const GRFConfig *src);
void AppendStaticGRFConfigs(GRFConfig **dst); void AppendStaticGRFConfigs(GRFConfig **dst);
void ClearGRFConfig(GRFConfig **config); void ClearGRFConfig(GRFConfig **config);
void ClearGRFConfigList(GRFConfig **config); void ClearGRFConfigList(GRFConfig **config);
void ResetGRFConfig(bool defaults); void ResetGRFConfig(bool defaults);
bool IsGoodGRFConfigList(void); GCF_Flags IsGoodGRFConfigList(void);
bool FillGRFDetails(GRFConfig *config, bool is_static); bool FillGRFDetails(GRFConfig *config, bool is_static);
char *GRFBuildParamList(char *dst, const GRFConfig *c, const char *last); char *GRFBuildParamList(char *dst, const GRFConfig *c, const char *last);

View File

@ -40,9 +40,7 @@ static int parse_intlist(const char *p, int *items, int maxitems)
static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint w, bool show_params) static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint w, bool show_params)
{ {
char buff[512]; char buff[256];
char *s;
uint i;
/* Draw filename or not if it is not known (GRF sent over internet) */ /* Draw filename or not if it is not known (GRF sent over internet) */
if (c->filename != NULL) { if (c->filename != NULL) {
@ -56,10 +54,7 @@ static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint w, bool show
y += DrawStringMultiLine(x, y, STR_NEWGRF_GRF_ID, w); y += DrawStringMultiLine(x, y, STR_NEWGRF_GRF_ID, w);
/* Prepare and draw MD5 sum */ /* Prepare and draw MD5 sum */
s = buff; md5sumToString(buff, lastof(buff), c->md5sum);
for (i = 0; i < lengthof(c->md5sum); i++) {
s += snprintf(s, lastof(buff) - s, "%02X", c->md5sum[i]);
}
SetDParamStr(0, buff); SetDParamStr(0, buff);
y += DrawStringMultiLine(x, y, STR_NEWGRF_MD5SUM, w); y += DrawStringMultiLine(x, y, STR_NEWGRF_MD5SUM, w);
@ -75,8 +70,9 @@ static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint w, bool show
} }
/* Show flags */ /* Show flags */
if (HASBIT(c->flags, GCF_NOT_FOUND)) y += DrawStringMultiLine(x, y, STR_NEWGRF_NOT_FOUND, 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_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 */ /* Draw GRF info if it exists */
if (c->info != NULL && strlen(c->info) != 0) { if (c->info != NULL && strlen(c->info) != 0) {
@ -283,9 +279,19 @@ static void NewGRFConfirmationCallback(bool yes_clicked)
if (yes_clicked) { if (yes_clicked) {
Window *w = FindWindowById(WC_GAME_OPTIONS, 0); Window *w = FindWindowById(WC_GAME_OPTIONS, 0);
newgrf_d *nd = &WP(w, newgrf_d); newgrf_d *nd = &WP(w, newgrf_d);
GRFConfig *c;
int i = 0;
CopyGRFConfigList(nd->orig_list, *nd->list); CopyGRFConfigList(nd->orig_list, *nd->list);
ReloadNewGRFData(); 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 @@ static void NewGRFWndProc(Window *w, WindowEvent *e)
if (HASBIT(c->flags, GCF_NOT_FOUND) || HASBIT(c->flags, GCF_DISABLED)) { if (HASBIT(c->flags, GCF_NOT_FOUND) || HASBIT(c->flags, GCF_DISABLED)) {
pal = PALETTE_TO_RED; pal = PALETTE_TO_RED;
} else if (HASBIT(c->flags, GCF_STATIC)) { } 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)) { } else if (HASBIT(c->flags, GCF_ACTIVATED)) {
pal = PALETTE_TO_GREEN; pal = PALETTE_TO_GREEN;
} else { } else {

View File

@ -1157,8 +1157,17 @@ bool AfterLoadGame(void)
// convert road side to my format. // convert road side to my format.
if (_opt.road_side) _opt.road_side = 1; 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 /* Update current year
* must be done before loading sprites as some newgrfs check it */ * must be done before loading sprites as some newgrfs check it */

View File

@ -177,6 +177,25 @@ int CDECL vsnprintf(char *str, size_t size, const char *format, va_list ap)
#endif /* WIN32 */ #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 */ /* UTF-8 handling routines */

View File

@ -55,6 +55,8 @@ static inline int ttd_strnlen(const char *str, int maxlen)
return t - str; 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; typedef uint32 WChar;