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_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}
|
||||
|
|
|
@ -196,27 +196,46 @@ void ResetGRFConfig(bool defaults)
|
|||
}
|
||||
|
||||
|
||||
/* 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 @@ bool IsGoodGRFConfigList(void)
|
|||
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 @@ void ScanNewGRFFiles(void)
|
|||
}
|
||||
|
||||
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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_newgame;
|
|||
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);
|
||||
|
||||
|
|
24
newgrf_gui.c
24
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)
|
||||
{
|
||||
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 @@ static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint w, bool show
|
|||
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);
|
||||
|
||||
|
@ -77,6 +72,7 @@ static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint w, bool show
|
|||
/* 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_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 @@ static void NewGRFConfirmationCallback(bool yes_clicked)
|
|||
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 @@ static void NewGRFWndProc(Window *w, WindowEvent *e)
|
|||
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 {
|
||||
|
|
13
openttd.c
13
openttd.c
|
@ -1157,8 +1157,17 @@ bool AfterLoadGame(void)
|
|||
// 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 */
|
||||
|
|
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 */
|
||||
|
||||
|
||||
/** 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 */
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue