summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpeter1138 <peter1138@openttd.org>2006-12-04 08:30:04 +0000
committerpeter1138 <peter1138@openttd.org>2006-12-04 08:30:04 +0000
commit3b6d2ed064b790e9296f13656d742bbd67f3adf9 (patch)
treefb2a8cf881b385cb52b110880f86128061ea020c
parent0c5d6c94d69580bf114054ef95e63090a2337a12 (diff)
downloadopenttd-3b6d2ed064b790e9296f13656d742bbd67f3adf9.tar.xz
(svn r7348) -Feature: Initial support for saving NewGRF settings with savegames. Back up your savegames...
-rw-r--r--Makefile1
-rw-r--r--genworld_gui.c2
-rw-r--r--newgrf.c82
-rw-r--r--newgrf.h12
-rw-r--r--newgrf_config.c294
-rw-r--r--newgrf_config.h43
-rw-r--r--newgrf_text.c2
-rw-r--r--newgrf_text.h1
-rw-r--r--openttd.c10
-rw-r--r--openttd.vcproj6
-rw-r--r--openttd_vs80.vcproj8
-rw-r--r--saveload.c4
-rw-r--r--settings.c8
13 files changed, 433 insertions, 40 deletions
diff --git a/Makefile b/Makefile
index 85ce7a4bf..debabfffc 100644
--- a/Makefile
+++ b/Makefile
@@ -733,6 +733,7 @@ SRCS += network_server.c
SRCS += network_udp.c
SRCS += newgrf.c
SRCS += newgrf_cargo.c
+SRCS += newgrf_config.c
SRCS += newgrf_engine.c
SRCS += newgrf_sound.c
SRCS += newgrf_spritegroup.c
diff --git a/genworld_gui.c b/genworld_gui.c
index 571dec4f9..7b597bd57 100644
--- a/genworld_gui.c
+++ b/genworld_gui.c
@@ -22,6 +22,7 @@
#include "network.h"
#include "thread.h"
#include "date.h"
+#include "newgrf_config.h"
enum {
START_DATE_QUERY,
@@ -164,6 +165,7 @@ static void StartGeneratingLandscape(glwp_modes mode)
UpdatePatches();
_opt_ptr = &_opt;
*_opt_ptr = _opt_newgame;
+ ResetGRFConfig(true);
SndPlayFx(SND_15_BEEP);
switch (mode) {
diff --git a/newgrf.c b/newgrf.c
index d4a6d78f1..4b1005c18 100644
--- a/newgrf.c
+++ b/newgrf.c
@@ -27,6 +27,7 @@
#include "date.h"
#include "currency.h"
#include "sound.h"
+#include "newgrf_config.h"
#include "newgrf_sound.h"
#include "newgrf_spritegroup.h"
@@ -47,11 +48,12 @@ SpriteID _coast_base;
static GRFFile *_cur_grffile;
GRFFile *_first_grffile;
-GRFConfig *_first_grfconfig;
static SpriteID _cur_spriteid;
static GrfLoadingStage _cur_stage;
static uint32 _nfo_line;
+static GRFConfig *_cur_grfconfig;
+
/* Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E */
static byte _misc_grf_features = 0;
@@ -2450,6 +2452,27 @@ static void SkipIf(byte *buf, int len)
}
}
+/* Action 0x08 (GLS_FILESCAN) */
+static void ScanInfo(byte *buf, int len)
+{
+ uint8 version;
+ uint32 grfid;
+ const char *name;
+ const char *info;
+
+ check_length(len, 8, "Info"); buf++;
+ version = grf_load_byte(&buf);
+ grfid = grf_load_dword(&buf);
+ name = (const char*)buf;
+ info = name + strlen(name) + 1;
+
+ _cur_grfconfig->grfid = grfid;
+ _cur_grfconfig->name = TranslateTTDPatchCodes(name);
+ _cur_grfconfig->info = TranslateTTDPatchCodes(info);
+
+ _skip_sprites = -1;
+}
+
/* Action 0x08 */
static void GRFInfo(byte *buf, int len)
{
@@ -3460,25 +3483,25 @@ static void DecodeSpecialSprite(uint num, GrfLoadingStage stage)
* is not in memory and scanning the file every time would be too expensive.
* In other stages we skip action 0x10 since it's already dealt with. */
static const SpecialSpriteHandler handlers[][GLS_END] = {
- /* 0x00 */ { NULL, NULL, FeatureChangeInfo, },
- /* 0x01 */ { NULL, NULL, NewSpriteSet, },
- /* 0x02 */ { NULL, NULL, NewSpriteGroup, },
- /* 0x03 */ { NULL, NULL, FeatureMapSpriteGroup, },
- /* 0x04 */ { NULL, NULL, FeatureNewName, },
- /* 0x05 */ { NULL, NULL, GraphicsNew, },
- /* 0x06 */ { NULL, CfgApply, CfgApply, },
- /* 0x07 */ { NULL, NULL, SkipIf, },
- /* 0x08 */ { NULL, GRFInfo, GRFInfo, },
- /* 0x09 */ { NULL, SkipIf, SkipIf, },
- /* 0x0A */ { NULL, NULL, SpriteReplace, },
- /* 0x0B */ { NULL, GRFError, GRFError, },
- /* 0x0C */ { NULL, GRFComment, GRFComment, },
- /* 0x0D */ { NULL, ParamSet, ParamSet, },
- /* 0x0E */ { NULL, GRFInhibit, GRFInhibit, },
- /* 0x0F */ { NULL, NULL, NULL, },
- /* 0x10 */ { DefineGotoLabel, NULL, NULL, },
- /* 0x11 */ { NULL, NULL, GRFSound, },
- /* 0x12 */ { NULL, NULL, LoadFontGlyph, },
+ /* 0x00 */ { NULL, NULL, NULL, FeatureChangeInfo, },
+ /* 0x01 */ { NULL, NULL, NULL, NewSpriteSet, },
+ /* 0x02 */ { NULL, NULL, NULL, NewSpriteGroup, },
+ /* 0x03 */ { NULL, NULL, NULL, FeatureMapSpriteGroup, },
+ /* 0x04 */ { NULL, NULL, NULL, FeatureNewName, },
+ /* 0x05 */ { NULL, NULL, NULL, GraphicsNew, },
+ /* 0x06 */ { NULL, NULL, CfgApply, CfgApply, },
+ /* 0x07 */ { NULL, NULL, NULL, SkipIf, },
+ /* 0x08 */ { ScanInfo, NULL, GRFInfo, GRFInfo, },
+ /* 0x09 */ { NULL, NULL, SkipIf, SkipIf, },
+ /* 0x0A */ { NULL, NULL, NULL, SpriteReplace, },
+ /* 0x0B */ { NULL, NULL, GRFError, GRFError, },
+ /* 0x0C */ { NULL, NULL, GRFComment, GRFComment, },
+ /* 0x0D */ { NULL, NULL, ParamSet, ParamSet, },
+ /* 0x0E */ { NULL, NULL, GRFInhibit, GRFInhibit, },
+ /* 0x0F */ { NULL, NULL, NULL, NULL, },
+ /* 0x10 */ { NULL, DefineGotoLabel, NULL, NULL, },
+ /* 0x11 */ { NULL, NULL, NULL, GRFSound, },
+ /* 0x12 */ { NULL, NULL, NULL, LoadFontGlyph, },
};
byte* buf;
@@ -3520,8 +3543,9 @@ static void DecodeSpecialSprite(uint num, GrfLoadingStage stage)
}
-static void LoadNewGRFFile(const char *filename, uint file_index, GrfLoadingStage stage)
+void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage)
{
+ const char *filename = config->filename;
uint16 num;
/* A .grf file is activated only if it was active when the game was
@@ -3533,15 +3557,17 @@ static void LoadNewGRFFile(const char *filename, uint file_index, GrfLoadingStag
* During activation, only actions 0, 1, 2, 3, 4, 5, 7, 8, 9, 0A and 0B are
* carried out. All others are ignored, because they only need to be
* processed once at initialization. */
- if (stage != GLS_LABELSCAN) {
+ if (stage != GLS_FILESCAN && stage != GLS_LABELSCAN) {
_cur_grffile = GetFileByFilename(filename);
if (_cur_grffile == NULL) error("File ``%s'' lost in cache.\n", filename);
- if (stage > 1 && !(_cur_grffile->flags & 0x0001)) return;
+ if (stage == GLS_ACTIVATION && !(_cur_grffile->flags & 0x0001)) return;
}
FioOpenFile(file_index, filename);
_file_index = file_index; // XXX
+ _cur_grfconfig = config;
+
DEBUG(grf, 7) ("Reading NewGRF-file '%s'", filename);
/* Skip the first sprite; we don't care about how many sprites this
@@ -3550,7 +3576,8 @@ static void LoadNewGRFFile(const char *filename, uint file_index, GrfLoadingStag
if (FioReadWord() == 4 && FioReadByte() == 0xFF) {
FioReadDword();
} else {
- error("Custom .grf has invalid format.");
+ DEBUG(grf, 7) ("Custom .grf has invalid format.");
+ return;
}
_skip_sprites = 0; // XXX
@@ -3616,14 +3643,16 @@ void LoadNewGRF(uint load_index, uint file_index)
_cur_stage = stage;
_cur_spriteid = load_index;
- for (c = _first_grfconfig; c != NULL; c = c->next) {
+ for (c = _grfconfig; c != NULL; c = c->next) {
+ if (HASBIT(c->flags, GCF_DISABLED) || HASBIT(c->flags, GCF_NOT_FOUND)) continue;
+
if (!FioCheckFileExists(c->filename)) {
// TODO: usrerror()
error("NewGRF file missing: %s", c->filename);
}
if (stage == GLS_LABELSCAN) InitNewGRFFile(c, _cur_spriteid);
- LoadNewGRFFile(c->filename, slot++, stage);
+ LoadNewGRFFile(c, slot++, stage);
if (stage == GLS_ACTIVATION) ClearTemporaryNewGRFData();
DEBUG(spritecache, 2) ("Currently %i sprites are loaded", load_index);
}
@@ -3632,3 +3661,4 @@ void LoadNewGRF(uint load_index, uint file_index)
// Pre-calculate all refit masks after loading GRF files
CalculateRefitMasks();
}
+
diff --git a/newgrf.h b/newgrf.h
index a4dcecccf..ac4102207 100644
--- a/newgrf.h
+++ b/newgrf.h
@@ -4,8 +4,10 @@
#define NEWGRF_H
#include "station.h"
+#include "newgrf_config.h"
typedef enum GrfLoadingStage {
+ GLS_FILESCAN,
GLS_LABELSCAN,
GLS_INIT,
GLS_ACTIVATION,
@@ -58,19 +60,11 @@ typedef struct GRFFile {
extern GRFFile *_first_grffile;
-typedef struct GRFConfig {
- const char *filename;
- uint32 param[0x80];
- byte num_params;
-
- struct GRFConfig *next;
-} GRFConfig;
-
-extern GRFConfig *_first_grfconfig;
extern SpriteID _signal_base;
extern SpriteID _coast_base;
extern bool _have_2cc;
+void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage);
void LoadNewGRF(uint load_index, uint file_index);
#endif /* NEWGRF_H */
diff --git a/newgrf_config.c b/newgrf_config.c
new file mode 100644
index 000000000..8c07c8af6
--- /dev/null
+++ b/newgrf_config.c
@@ -0,0 +1,294 @@
+/* $Id$ */
+
+#include "stdafx.h"
+#include "openttd.h"
+#include "functions.h"
+#include "macros.h"
+#include "debug.h"
+#include "variables.h"
+#include "saveload.h"
+#include "md5.h"
+#include "newgrf.h"
+#include "newgrf_config.h"
+
+#include "fileio.h"
+#include "fios.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+
+#ifdef WIN32
+# include <io.h>
+#else
+# include <unistd.h>
+# include <dirent.h>
+#endif /* WIN32 */
+
+
+GRFConfig *_all_grfs;
+GRFConfig *_grfconfig;
+GRFConfig *_grfconfig_newgame;
+
+
+/* Calculate the MD5 Sum for a GRF */
+static bool CalcGRFMD5Sum(GRFConfig *config)
+{
+ FILE *f;
+ char filename[MAX_PATH];
+ md5_state_t md5state;
+ md5_byte_t buffer[1024];
+ size_t len;
+
+ /* open the file */
+ snprintf(filename, lengthof(filename), "%s%s", _path.data_dir, config->filename);
+ f = fopen(filename, "rb");
+ if (f == NULL) return false;
+
+ /* calculate md5sum */
+ md5_init(&md5state);
+ while ((len = fread(buffer, 1, sizeof(buffer), f)) != 0) {
+ md5_append(&md5state, buffer, len);
+ }
+ md5_finish(&md5state, config->md5sum);
+
+ fclose(f);
+
+ return true;
+}
+
+
+/* Find the GRFID and calculate the md5sum */
+bool FillGRFDetails(GRFConfig *config)
+{
+ if (!FioCheckFileExists(config->filename)) {
+ SETBIT(config->flags, GCF_NOT_FOUND);
+ return false;
+ }
+
+ /* Find and load the Action 8 information */
+ /* 62 is the last file slot before sample.cat.
+ * Should perhaps be some "don't care" value */
+ LoadNewGRFFile(config, 62, GLS_FILESCAN);
+
+ /* Skip if the grfid is 0 (not read) or 0xFFFFFFFF (ttdp system grf) */
+ if (config->grfid == 0 || config->grfid == 0xFFFFFFFF) return false;
+
+ return CalcGRFMD5Sum(config);
+}
+
+
+/* Clear a GRF Config list */
+void ClearGRFConfigList(GRFConfig *config)
+{
+ GRFConfig *c, *next;
+ for (c = config; c != NULL; c = next) {
+ next = c->next;
+ free(c->filename);
+ free(c->name);
+ free(c->info);
+ free(c);
+ }
+}
+
+
+/* Copy a GRF Config list */
+static void CopyGRFConfigList(GRFConfig **dst, GRFConfig *src)
+{
+ GRFConfig *c;
+
+ for (; src != NULL; src = src->next) {
+ c = calloc(1, sizeof(*c));
+ *c = *src;
+ c->filename = strdup(src->filename);
+ if (src->name != NULL) c->name = strdup(src->name);
+ if (src->info != NULL) c->info = strdup(src->info);
+
+ *dst = c;
+ dst = &c->next;
+ }
+}
+
+
+/* Reset the current GRF Config to either blank or newgame settings */
+void ResetGRFConfig(bool defaults)
+{
+ ClearGRFConfigList(_grfconfig);
+ _grfconfig = NULL;
+ if (defaults) CopyGRFConfigList(&_grfconfig, _grfconfig_newgame);
+}
+
+
+/* Check if all GRFs in the GRF Config can be loaded */
+bool IsGoodGRFConfigList(void)
+{
+ bool res = true;
+ 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;
+
+ 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]);
+ }
+ ShowInfo(buf);
+
+ res = false;
+ } else {
+ DEBUG(grf, 1) ("[GRF] Loading GRF %X from %s", BSWAP32(c->grfid), f->filename);
+ c->filename = strdup(f->filename);
+ c->name = strdup(f->name);
+ c->info = strdup(f->info);
+ }
+ }
+
+ return res;
+}
+
+
+extern bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb);
+
+/* Scan a path for NewGRFs */
+static uint ScanPath(const char *path)
+{
+ uint num = 0;
+ struct stat sb;
+ struct dirent *dirent;
+ DIR *dir;
+ GRFConfig *c;
+
+ if ((dir = opendir(path)) == NULL) return 0;
+
+ while ((dirent = readdir(dir)) != NULL) {
+ const char *d_name = FS2OTTD(dirent->d_name);
+ char filename[MAX_PATH];
+
+ if (!FiosIsValidFile(path, dirent, &sb)) continue;
+
+ snprintf(filename, lengthof(filename), "%s" PATHSEP "%s", path, d_name);
+
+ if (sb.st_mode & S_IFDIR) {
+ /* Directory */
+ if (strcmp(d_name, ".") == 0 || strcmp(d_name, "..") == 0) continue;
+ num += ScanPath(filename);
+ } else if (sb.st_mode & S_IFREG) {
+ /* File */
+ char *ext = strrchr(filename, '.');
+ char *file = strchr(filename, PATHSEPCHAR) + 1; // Crop base path
+
+ /* If no extension or extension isn't .grf, skip the file */
+ if (ext == NULL) continue;
+ if (strcasecmp(ext, ".grf") != 0) continue;
+
+ c = calloc(1, sizeof(*c));
+ c->filename = strdup(file);
+
+ if (FillGRFDetails(c)) {
+ if (_all_grfs == NULL) {
+ _all_grfs = c;
+ } else {
+ /* Insert file into list at a position determined by its
+ * name, so the list is sorted as we go along */
+ GRFConfig **pd, *d;
+ for (pd = &_all_grfs; (d = *pd) != NULL; pd = &d->next) {
+ if (strcasecmp(c->name, d->name) <= 0) break;
+ }
+ c->next = d;
+ *pd = c;
+ }
+
+ num++;
+ } else {
+ /* File couldn't be opened, or is either not a NewGRF or is a
+ * 'system' NewGRF, so forget about it. */
+ free(c->filename);
+ free(c->name);
+ free(c->info);
+ free(c);
+ }
+ }
+ }
+
+ closedir(dir);
+
+ return num;
+}
+
+
+/* Scan for all NewGRFs */
+void ScanNewGRFFiles(void)
+{
+ uint num;
+
+ ClearGRFConfigList(_all_grfs);
+ _all_grfs = NULL;
+
+ DEBUG(grf, 1) ("[GRF] Scanning for NewGRFs");
+ num = ScanPath(_path.data_dir);
+ DEBUG(grf, 1) ("[GRF] Scan complete, found %d files", num);
+}
+
+
+/* Find a NewGRF in the scanned list */
+const GRFConfig *FindGRFConfig(uint32 grfid, uint8 *md5sum)
+{
+ GRFConfig *c;
+ static const uint8 blanksum[sizeof(c->md5sum)] = { 0 };
+
+ 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 (memcmp(md5sum, c->md5sum, sizeof(c->md5sum)) == 0) return c;
+ }
+ }
+
+ return NULL;
+}
+
+
+static const SaveLoad _grfconfig_desc[] = {
+ SLE_STR(GRFConfig, filename, SLE_STR, 0x40),
+ SLE_VAR(GRFConfig, grfid, SLE_UINT32),
+ SLE_ARR(GRFConfig, md5sum, SLE_UINT8, 16),
+ SLE_ARR(GRFConfig, param, SLE_UINT32, 0x80),
+ SLE_VAR(GRFConfig, num_params, SLE_UINT8),
+ SLE_END()
+};
+
+
+static void Save_NGRF(void)
+{
+ GRFConfig *c;
+ int index = 0;
+
+ for (c = _grfconfig; c != NULL; c = c->next) {
+ SlSetArrayIndex(index++);
+ SlObject(c, _grfconfig_desc);
+ }
+}
+
+
+static void Load_NGRF(void)
+{
+ GRFConfig *first = NULL;
+ GRFConfig **last = &first;
+
+ while (SlIterateArray() != -1) {
+ GRFConfig *c = calloc(1, sizeof(*c));
+ SlObject(c, _grfconfig_desc);
+
+ /* Append our configuration to the list */
+ *last = c;
+ last = &c->next;
+ }
+
+ ClearGRFConfigList(_grfconfig);
+ _grfconfig = first;
+}
+
+const ChunkHandler _newgrf_chunk_handlers[] = {
+ { 'NGRF', Save_NGRF, Load_NGRF, CH_ARRAY | CH_LAST }
+};
+
diff --git a/newgrf_config.h b/newgrf_config.h
new file mode 100644
index 000000000..2d9bdfd0b
--- /dev/null
+++ b/newgrf_config.h
@@ -0,0 +1,43 @@
+/* $Id$ */
+
+#ifndef NEWGRF_CONFIG_H
+#define NEWGRF_CONFIG_H
+
+/* GRF config bit flags */
+enum {
+ GCF_DISABLED,
+ GCF_NOT_FOUND,
+ GCF_ACTIVATED,
+};
+
+typedef struct GRFConfig {
+ char *filename;
+ char *name;
+ char *info;
+ uint32 grfid;
+
+ uint8 flags;
+ uint8 md5sum[16];
+ uint32 param[0x80];
+ uint8 num_params;
+
+ struct GRFConfig *next;
+} GRFConfig;
+
+/* First item in list of all scanned NewGRFs */
+extern GRFConfig *_all_grfs;
+
+/* First item in list of current GRF set up */
+extern GRFConfig *_grfconfig;
+
+/* First item in list of default GRF set up */
+extern GRFConfig *_grfconfig_newgame;
+
+void ScanNewGRFFiles(void);
+const GRFConfig *FindGRFConfig(uint32 grfid, uint8 *md5sum);
+void ClearGRFConfigList(GRFConfig *config);
+void ResetGRFConfig(bool defaults);
+bool IsGoodGRFConfigList(void);
+bool FillGRFDetails(GRFConfig *config);
+
+#endif /* NEWGRF_CONFIG_H */
diff --git a/newgrf_text.c b/newgrf_text.c
index e8d606d78..bcb462878 100644
--- a/newgrf_text.c
+++ b/newgrf_text.c
@@ -154,7 +154,7 @@ static GRFTextEntry _grf_text[(1 << TABSIZE) * 3];
static byte _currentLangID = GRFLX_ENGLISH; //by default, english is used.
-static char *TranslateTTDPatchCodes(const char *str)
+char *TranslateTTDPatchCodes(const char *str)
{
char *tmp = malloc(strlen(str) * 10 + 1); /* Allocate space to allow for expansion */
char *d = tmp;
diff --git a/newgrf_text.h b/newgrf_text.h
index 62dc3c473..b9850a54e 100644
--- a/newgrf_text.h
+++ b/newgrf_text.h
@@ -11,5 +11,6 @@ StringID GetGRFStringID(uint32 grfid, uint16 stringid);
char *GetGRFString(char *buff, uint16 stringid, const char* last);
void CleanUpStrings(void);
void SetCurrentGrfLangID(const char *iso_name);
+char *TranslateTTDPatchCodes(const char *str);
#endif /* NEWGRF_TEXT_H */
diff --git a/openttd.c b/openttd.c
index 7d30e3ac3..01e0fd8c6 100644
--- a/openttd.c
+++ b/openttd.c
@@ -53,6 +53,7 @@
#include "date.h"
#include "clear_map.h"
#include "fontcache.h"
+#include "newgrf_config.h"
#include <stdarg.h>
@@ -281,6 +282,7 @@ static void LoadIntroGame(void)
_game_mode = GM_MENU;
CLRBITS(_display_opt, DO_TRANS_BUILDINGS); // don't make buildings transparent in intro
_opt_ptr = &_opt_newgame;
+ ResetGRFConfig(false);
// Setup main window
ResetWindowSystem();
@@ -451,7 +453,10 @@ int ttd_main(int argc, char *argv[])
NetworkStartUp(); // initialize network-core
+ ScanNewGRFFiles();
+
_opt_ptr = &_opt_newgame;
+ ResetGRFConfig(false);
/* XXX - ugly hack, if diff_level is 9, it means we got no setting from the config file */
if (_opt_newgame.diff_level == 9) SetDifficultyLevel(0, &_opt_newgame);
@@ -754,6 +759,7 @@ void SwitchMode(int new_mode)
case SM_LOAD: { /* Load game, Play Scenario */
_opt_ptr = &_opt;
+ ResetGRFConfig(true);
if (!SafeSaveOrLoad(_file_to_saveload.name, _file_to_saveload.mode, GM_NORMAL)) {
LoadIntroGame();
@@ -793,6 +799,7 @@ void SwitchMode(int new_mode)
Player *p;
_opt_ptr = &_opt;
+ ResetGRFConfig(true);
_local_player = OWNER_NONE;
_generating_world = true;
@@ -1149,6 +1156,9 @@ 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;
+
// Load the sprites
GfxLoadSprites();
LoadStringWidthTable();
diff --git a/openttd.vcproj b/openttd.vcproj
index 93251b6a1..094f52d2d 100644
--- a/openttd.vcproj
+++ b/openttd.vcproj
@@ -316,6 +316,9 @@
RelativePath=".\newgrf_cargo.c">
</File>
<File
+ RelativePath=".\newgrf_config.c">
+ </File>
+ <File
RelativePath=".\newgrf_engine.c">
</File>
<File
@@ -572,6 +575,9 @@
RelativePath=".\newgrf_cargo.h">
</File>
<File
+ RelativePath=".\newgrf_config.h">
+ </File>
+ <File
RelativePath=".\newgrf_engine.h">
</File>
<File
diff --git a/openttd_vs80.vcproj b/openttd_vs80.vcproj
index 93ee72635..5370011fa 100644
--- a/openttd_vs80.vcproj
+++ b/openttd_vs80.vcproj
@@ -669,6 +669,10 @@
>
</File>
<File
+ RelativePath=".\newgrf_config.c"
+ >
+ </File>
+ <File
RelativePath=".\newgrf_engine.c"
>
</File>
@@ -1060,6 +1064,10 @@
>
</File>
<File
+ RelativePath=".\newgrf_config.h"
+ >
+ </File>
+ <File
RelativePath=".\newgrf_engine.h"
>
</File>
diff --git a/saveload.c b/saveload.c
index 3a5a7889d..0c51c81a5 100644
--- a/saveload.c
+++ b/saveload.c
@@ -30,7 +30,7 @@
#include "variables.h"
#include <setjmp.h>
-const uint16 SAVEGAME_VERSION = 40;
+const uint16 SAVEGAME_VERSION = 41;
uint16 _sl_version; /// the major savegame version identifier
byte _sl_minor_version; /// the minor savegame version, DO NOT USE!
@@ -1200,6 +1200,7 @@ extern const ChunkHandler _station_chunk_handlers[];
extern const ChunkHandler _industry_chunk_handlers[];
extern const ChunkHandler _economy_chunk_handlers[];
extern const ChunkHandler _animated_tile_chunk_handlers[];
+extern const ChunkHandler _newgrf_chunk_handlers[];
static const ChunkHandler * const _chunk_handlers[] = {
_misc_chunk_handlers,
@@ -1216,6 +1217,7 @@ static const ChunkHandler * const _chunk_handlers[] = {
_station_chunk_handlers,
_player_chunk_handlers,
_animated_tile_chunk_handlers,
+ _newgrf_chunk_handlers,
NULL,
};
diff --git a/settings.c b/settings.c
index 8fc10ef9c..39fa1e03c 100644
--- a/settings.c
+++ b/settings.c
@@ -36,6 +36,7 @@
#include "npf.h"
#include "yapf/yapf.h"
#include "newgrf.h"
+#include "newgrf_config.h"
#include "genworld.h"
#include "date.h"
#include "rail.h"
@@ -1504,6 +1505,7 @@ const char *GRFProcessParams(const IniItem *item, uint index)
/* Loading newgrf stuff from configuration file */
c = calloc(1, sizeof(*c));
c->filename = strdup(item->name);
+ FillGRFDetails(c);
if (*item->value != '\0') {
c->num_params = parse_intlist(item->value, (int*)c->param, lengthof(c->param));
@@ -1513,12 +1515,12 @@ const char *GRFProcessParams(const IniItem *item, uint index)
}
}
- if (_first_grfconfig == NULL) {
- _first_grfconfig = c;
+ if (_grfconfig_newgame == NULL) {
+ _grfconfig_newgame = c;
} else {
GRFConfig *c2;
/* Attach the label to the end of the list */
- for (c2 = _first_grfconfig; c2->next != NULL; c2 = c2->next);
+ for (c2 = _grfconfig_newgame; c2->next != NULL; c2 = c2->next);
c2->next = c;
}