mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-08 01:10:28 +00:00
(svn r7490) -Feature: Load a list of NewGRFs from the config (in the [newgrf-static] section) that should always be loaded. These will also be active during the intro screen, and in multiplayer games. Only "network-safe" NewGRFs are permitted, such as fonts and sprite replacement sets.
This commit is contained in:
parent
208b466181
commit
be3e653db3
65
newgrf.c
65
newgrf.c
@ -2471,8 +2471,8 @@ static void SkipIf(byte *buf, int len)
|
||||
}
|
||||
|
||||
|
||||
/* Action 0x08 (GLS_FILESCAN) */
|
||||
static void ScanInfo(byte *buf, int len)
|
||||
/* Action 0x08 (GLS_SAFETYSCAN) */
|
||||
static void SafeInfo(byte *buf, int len)
|
||||
{
|
||||
uint8 version;
|
||||
uint32 grfid;
|
||||
@ -2487,6 +2487,9 @@ static void ScanInfo(byte *buf, int len)
|
||||
|
||||
_cur_grfconfig->grfid = grfid;
|
||||
|
||||
/* GRF IDs starting with 0xFF are reserved for internal TTDPatch use */
|
||||
if (GB(grfid, 24, 8) == 0xFF) SETBIT(_cur_grfconfig->flags, GCF_SYSTEM);
|
||||
|
||||
len -= 6;
|
||||
name = (const char*)buf;
|
||||
name_len = ttd_strnlen(name, len);
|
||||
@ -2502,7 +2505,14 @@ static void ScanInfo(byte *buf, int len)
|
||||
_cur_grfconfig->info = TranslateTTDPatchCodes(info);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Action 0x08 (GLS_INFOSCAN) */
|
||||
static void ScanInfo(byte *buf, int len)
|
||||
{
|
||||
SafeInfo(buf, len);
|
||||
|
||||
/* GLS_INFOSCAN only looks for the action 8, so we can skip the rest of the file */
|
||||
_skip_sprites = -1;
|
||||
}
|
||||
|
||||
@ -3177,6 +3187,17 @@ static void GRFDataBlock(byte *buf, int len)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Used during safety scan on unsafe actions */
|
||||
static void GRFUnsafe(byte *buf, int len)
|
||||
{
|
||||
SETBIT(_cur_grfconfig->flags, GCF_UNSAFE);
|
||||
|
||||
/* Skip remainder of GRF if GRF ID is set */
|
||||
if (_cur_grfconfig->grfid != 0) _skip_sprites = -1;
|
||||
}
|
||||
|
||||
|
||||
static void InitializeGRFSpecial(void)
|
||||
{
|
||||
_ttdpatch_flags[0] = ((_patches.always_small_airport ? 1 : 0) << 0x0C) // keepsmallairport
|
||||
@ -3517,25 +3538,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, 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, },
|
||||
/* 0x00 */ { NULL, GRFUnsafe, NULL, NULL, FeatureChangeInfo, },
|
||||
/* 0x01 */ { NULL, GRFUnsafe, NULL, NULL, NewSpriteSet, },
|
||||
/* 0x02 */ { NULL, GRFUnsafe, NULL, NULL, NewSpriteGroup, },
|
||||
/* 0x03 */ { NULL, GRFUnsafe, NULL, NULL, FeatureMapSpriteGroup, },
|
||||
/* 0x04 */ { NULL, NULL, NULL, NULL, FeatureNewName, },
|
||||
/* 0x05 */ { NULL, NULL, NULL, NULL, GraphicsNew, },
|
||||
/* 0x06 */ { NULL, NULL, NULL, CfgApply, CfgApply, },
|
||||
/* 0x07 */ { NULL, NULL, NULL, NULL, SkipIf, },
|
||||
/* 0x08 */ { ScanInfo, SafeInfo, NULL, GRFInfo, GRFInfo, },
|
||||
/* 0x09 */ { NULL, NULL, NULL, SkipIf, SkipIf, },
|
||||
/* 0x0A */ { NULL, NULL, NULL, NULL, SpriteReplace, },
|
||||
/* 0x0B */ { NULL, NULL, NULL, GRFError, GRFError, },
|
||||
/* 0x0C */ { NULL, NULL, NULL, GRFComment, GRFComment, },
|
||||
/* 0x0D */ { NULL, GRFUnsafe, NULL, ParamSet, ParamSet, },
|
||||
/* 0x0E */ { NULL, GRFUnsafe, NULL, GRFInhibit, GRFInhibit, },
|
||||
/* 0x0F */ { NULL, NULL, NULL, NULL, NULL, },
|
||||
/* 0x10 */ { NULL, NULL, DefineGotoLabel, NULL, NULL, },
|
||||
/* 0x11 */ { NULL, GRFUnsafe, NULL, NULL, GRFSound, },
|
||||
/* 0x12 */ { NULL, NULL, NULL, NULL, LoadFontGlyph, },
|
||||
};
|
||||
|
||||
byte* buf;
|
||||
@ -3591,7 +3612,7 @@ void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage)
|
||||
* 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_FILESCAN && stage != GLS_LABELSCAN) {
|
||||
if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) {
|
||||
_cur_grffile = GetFileByFilename(filename);
|
||||
if (_cur_grffile == NULL) error("File ``%s'' lost in cache.\n", filename);
|
||||
if (stage == GLS_ACTIVATION && !HASBIT(config->flags, GCF_ACTIVATED)) return;
|
||||
|
1
newgrf.h
1
newgrf.h
@ -8,6 +8,7 @@
|
||||
|
||||
typedef enum GrfLoadingStage {
|
||||
GLS_FILESCAN,
|
||||
GLS_SAFETYSCAN,
|
||||
GLS_LABELSCAN,
|
||||
GLS_INIT,
|
||||
GLS_ACTIVATION,
|
||||
|
@ -28,6 +28,7 @@
|
||||
GRFConfig *_all_grfs;
|
||||
GRFConfig *_grfconfig;
|
||||
GRFConfig *_grfconfig_newgame;
|
||||
GRFConfig *_grfconfig_static;
|
||||
|
||||
|
||||
/* Calculate the MD5 Sum for a GRF */
|
||||
@ -58,7 +59,7 @@ static bool CalcGRFMD5Sum(GRFConfig *config)
|
||||
|
||||
|
||||
/* Find the GRFID and calculate the md5sum */
|
||||
bool FillGRFDetails(GRFConfig *config)
|
||||
bool FillGRFDetails(GRFConfig *config, bool is_static)
|
||||
{
|
||||
if (!FioCheckFileExists(config->filename)) {
|
||||
SETBIT(config->flags, GCF_NOT_FOUND);
|
||||
@ -68,7 +69,10 @@ bool FillGRFDetails(GRFConfig *config)
|
||||
/* 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);
|
||||
LoadNewGRFFile(config, 62, is_static ? GLS_SAFETYSCAN : GLS_FILESCAN);
|
||||
|
||||
/* GCF_UNSAFE is set if GLS_SAFETYSCAN finds unsafe actions */
|
||||
if (HASBIT(config->flags, GCF_UNSAFE)) return false;
|
||||
|
||||
/* Skip if the grfid is 0 (not read) or 0xFFFFFFFF (ttdp system grf) */
|
||||
if (config->grfid == 0 || config->grfid == 0xFFFFFFFF) return false;
|
||||
@ -77,22 +81,28 @@ bool FillGRFDetails(GRFConfig *config)
|
||||
}
|
||||
|
||||
|
||||
void ClearGRFConfig(GRFConfig *config)
|
||||
{
|
||||
free(config->filename);
|
||||
free(config->name);
|
||||
free(config->info);
|
||||
free(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);
|
||||
ClearGRFConfig(c);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Copy a GRF Config list */
|
||||
static void CopyGRFConfigList(GRFConfig **dst, GRFConfig *src)
|
||||
static GRFConfig **CopyGRFConfigList(GRFConfig **dst, GRFConfig *src)
|
||||
{
|
||||
GRFConfig *c;
|
||||
|
||||
@ -106,15 +116,21 @@ static void CopyGRFConfigList(GRFConfig **dst, GRFConfig *src)
|
||||
*dst = c;
|
||||
dst = &c->next;
|
||||
}
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
/* Reset the current GRF Config to either blank or newgame settings */
|
||||
void ResetGRFConfig(bool defaults)
|
||||
{
|
||||
GRFConfig **c = &_grfconfig;
|
||||
|
||||
ClearGRFConfigList(_grfconfig);
|
||||
_grfconfig = NULL;
|
||||
if (defaults) CopyGRFConfigList(&_grfconfig, _grfconfig_newgame);
|
||||
|
||||
if (defaults) c = CopyGRFConfigList(c, _grfconfig_newgame);
|
||||
CopyGRFConfigList(c, _grfconfig_static);
|
||||
}
|
||||
|
||||
|
||||
@ -138,7 +154,7 @@ bool IsGoodGRFConfigList(void)
|
||||
|
||||
res = false;
|
||||
} else {
|
||||
DEBUG(grf, 1) ("[GRF] Loading GRF %X from %s", BSWAP32(c->grfid), f->filename);
|
||||
DEBUG(grf, 1) ("[GRF] Loading GRF %08X from %s", BSWAP32(c->grfid), f->filename);
|
||||
c->filename = strdup(f->filename);
|
||||
c->name = strdup(f->name);
|
||||
c->info = strdup(f->info);
|
||||
@ -186,7 +202,7 @@ static uint ScanPath(const char *path)
|
||||
c = calloc(1, sizeof(*c));
|
||||
c->filename = strdup(file);
|
||||
|
||||
if (FillGRFDetails(c)) {
|
||||
if (FillGRFDetails(c, false)) {
|
||||
if (_all_grfs == NULL) {
|
||||
_all_grfs = c;
|
||||
} else {
|
||||
@ -294,6 +310,7 @@ static void Save_NGRF(void)
|
||||
int index = 0;
|
||||
|
||||
for (c = _grfconfig; c != NULL; c = c->next) {
|
||||
if (HASBIT(c->flags, GCF_STATIC)) continue;
|
||||
SlSetArrayIndex(index++);
|
||||
SlObject(c, _grfconfig_desc);
|
||||
}
|
||||
@ -314,6 +331,9 @@ static void Load_NGRF(void)
|
||||
last = &c->next;
|
||||
}
|
||||
|
||||
/* Append static NewGRF configuration */
|
||||
CopyGRFConfigList(last, _grfconfig_static);
|
||||
|
||||
ClearGRFConfigList(_grfconfig);
|
||||
_grfconfig = first;
|
||||
}
|
||||
|
@ -8,6 +8,9 @@ enum {
|
||||
GCF_DISABLED,
|
||||
GCF_NOT_FOUND,
|
||||
GCF_ACTIVATED,
|
||||
GCF_SYSTEM,
|
||||
GCF_UNSAFE,
|
||||
GCF_STATIC,
|
||||
};
|
||||
|
||||
typedef struct GRFConfig {
|
||||
@ -33,13 +36,17 @@ extern GRFConfig *_grfconfig;
|
||||
/* First item in list of default GRF set up */
|
||||
extern GRFConfig *_grfconfig_newgame;
|
||||
|
||||
/* First item in list of static GRF set up */
|
||||
extern GRFConfig *_grfconfig_static;
|
||||
|
||||
void ScanNewGRFFiles(void);
|
||||
const GRFConfig *FindGRFConfig(uint32 grfid, uint8 *md5sum);
|
||||
const GRFConfig *GetGRFConfig(uint32 grfid);
|
||||
void ClearGRFConfig(GRFConfig *config);
|
||||
void ClearGRFConfigList(GRFConfig *config);
|
||||
void ResetGRFConfig(bool defaults);
|
||||
bool IsGoodGRFConfigList(void);
|
||||
bool FillGRFDetails(GRFConfig *config);
|
||||
bool FillGRFDetails(GRFConfig *config, bool is_static);
|
||||
char *GRFBuildParamList(char *dst, const GRFConfig *c, const char *last);
|
||||
|
||||
/* In newgrf_gui.c */
|
||||
|
@ -274,6 +274,8 @@ static void NewGRFWndProc(Window *w, WindowEvent *e)
|
||||
/* Pick a colour */
|
||||
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;
|
||||
} else if (HASBIT(c->flags, GCF_ACTIVATED)) {
|
||||
pal = PALETTE_TO_GREEN;
|
||||
} else {
|
||||
|
77
settings.c
77
settings.c
@ -1495,41 +1495,62 @@ static const SettingDesc _currency_settings[] = {
|
||||
#undef NO
|
||||
#undef CR
|
||||
|
||||
static const char *GRFProcessParams(const IniItem *item, uint index)
|
||||
|
||||
/* Load a GRF configuration from the given group name */
|
||||
static GRFConfig *GRFLoadConfig(IniFile *ini, const char *grpname, bool is_static)
|
||||
{
|
||||
GRFConfig *c;
|
||||
IniGroup *group = ini_getgroup(ini, grpname, -1);
|
||||
IniItem *item;
|
||||
GRFConfig *first = NULL;
|
||||
GRFConfig **curr = &first;
|
||||
|
||||
/* Saving newgrf stuff to configuration, not done since it is kept the same */
|
||||
if (item == NULL) return NULL;
|
||||
if (group == NULL) return NULL;
|
||||
|
||||
/* Loading newgrf stuff from configuration file */
|
||||
c = calloc(1, sizeof(*c));
|
||||
c->filename = strdup(item->name);
|
||||
if (!FillGRFDetails(c)) {
|
||||
ShowInfoF("ini: ignoring invalid NewGRF '%s'", c->filename);
|
||||
return NULL;
|
||||
}
|
||||
for (item = group->item; item != NULL; item = item->next) {
|
||||
GRFConfig *c = calloc(1, sizeof(*c));
|
||||
c->filename = strdup(item->name);
|
||||
|
||||
if (*item->value != '\0') {
|
||||
c->num_params = parse_intlist(item->value, (int*)c->param, lengthof(c->param));
|
||||
if (c->num_params == (byte)-1) {
|
||||
ShowInfoF("ini: error in array '%s'", item->name);
|
||||
c->num_params = 0;
|
||||
/* Parse parameters */
|
||||
if (*item->value != '\0') {
|
||||
c->num_params = parse_intlist(item->value, (int*)c->param, lengthof(c->param));
|
||||
if (c->num_params == (byte)-1) {
|
||||
ShowInfoF("ini: error in array '%s'", item->name);
|
||||
c->num_params = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check if item is valid */
|
||||
if (!FillGRFDetails(c, is_static)) {
|
||||
const char *msg;
|
||||
|
||||
if (HASBIT(c->flags, GCF_NOT_FOUND)) {
|
||||
msg = "not found";
|
||||
} else if (HASBIT(c->flags, GCF_UNSAFE)) {
|
||||
msg = "unsafe for static use";
|
||||
} else if (HASBIT(c->flags, GCF_SYSTEM)) {
|
||||
msg = "system NewGRF";
|
||||
} else {
|
||||
msg = "unknown";
|
||||
}
|
||||
|
||||
ShowInfoF("ini: ignoring invalid NewGRF '%s': %s", item->name, msg);
|
||||
ClearGRFConfig(c);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Mark file as static to avoid saving in savegame. */
|
||||
if (is_static) SETBIT(c->flags, GCF_STATIC);
|
||||
|
||||
/* Add item to list */
|
||||
*curr = c;
|
||||
curr = &c->next;
|
||||
}
|
||||
|
||||
if (_grfconfig_newgame == NULL) {
|
||||
_grfconfig_newgame = c;
|
||||
} else {
|
||||
GRFConfig *c2;
|
||||
/* Attach the label to the end of the list */
|
||||
for (c2 = _grfconfig_newgame; c2->next != NULL; c2 = c2->next);
|
||||
c2->next = c;
|
||||
}
|
||||
|
||||
return c->filename;
|
||||
return first;
|
||||
}
|
||||
|
||||
|
||||
/* Save a GRF configuration to the given group name */
|
||||
static void GRFSaveConfig(IniFile *ini, const char *grpname, const GRFConfig *list)
|
||||
{
|
||||
IniGroup *group = ini_getgroup(ini, grpname, -1);
|
||||
@ -1575,7 +1596,8 @@ void LoadFromConfig(void)
|
||||
{
|
||||
IniFile *ini = ini_load(_config_file);
|
||||
HandleSettingDescs(ini, ini_load_settings, ini_load_setting_list);
|
||||
ini_load_setting_list(ini, "newgrf", NULL, 0, GRFProcessParams);
|
||||
_grfconfig_newgame = GRFLoadConfig(ini, "newgrf", false);
|
||||
_grfconfig_static = GRFLoadConfig(ini, "newgrf-static", true);
|
||||
ini_free(ini);
|
||||
}
|
||||
|
||||
@ -1585,6 +1607,7 @@ void SaveToConfig(void)
|
||||
IniFile *ini = ini_load(_config_file);
|
||||
HandleSettingDescs(ini, ini_save_settings, ini_save_setting_list);
|
||||
GRFSaveConfig(ini, "newgrf", _grfconfig_newgame);
|
||||
GRFSaveConfig(ini, "newgrf-static", _grfconfig_static);
|
||||
ini_save(_config_file, ini);
|
||||
ini_free(ini);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user