mirror of https://github.com/OpenTTD/OpenTTD
(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
parent
40245ce496
commit
ac3b1883ed
|
@ -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}
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
28
newgrf_gui.c
28
newgrf_gui.c
|
@ -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 {
|
||||||
|
|
13
openttd.c
13
openttd.c
|
@ -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 */
|
||||||
|
|
19
string.c
19
string.c
|
@ -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 */
|
||||||
|
|
||||||
|
|
||||||
|
|
2
string.h
2
string.h
|
@ -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;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue