mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-06 14:27:16 +00:00
(svn r4527) - Feature [NewGRF]: Add support for specifying parameters to GRF files. Usage: "mygrf = 1". You can pass up to 128 parameters, each one seperated by a comma or a space-character. Big thanks to peter1138 for the inspiration and examples.
This commit is contained in:
parent
28213ea9dc
commit
e3280971b1
25
newgrf.c
25
newgrf.c
@ -41,6 +41,7 @@ extern int _traininfo_vehicle_pitch;
|
||||
|
||||
static GRFFile *_cur_grffile;
|
||||
GRFFile *_first_grffile;
|
||||
GRFConfig *_first_grfconfig;
|
||||
static int _cur_spriteid;
|
||||
static int _cur_stage;
|
||||
static uint32 _nfo_line;
|
||||
@ -2492,11 +2493,11 @@ static void ClearTemporaryNewGRFData(void)
|
||||
_cur_grffile->spritegroups_count = 0;
|
||||
}
|
||||
|
||||
static void InitNewGRFFile(const char* filename, int sprite_offset)
|
||||
static void InitNewGRFFile(const GRFConfig *config, int sprite_offset)
|
||||
{
|
||||
GRFFile *newfile;
|
||||
|
||||
newfile = GetFileByFilename(filename);
|
||||
newfile = GetFileByFilename(config->filename);
|
||||
if (newfile != NULL) {
|
||||
/* We already loaded it once. */
|
||||
newfile->sprite_offset = sprite_offset;
|
||||
@ -2508,9 +2509,14 @@ static void InitNewGRFFile(const char* filename, int sprite_offset)
|
||||
|
||||
if (newfile == NULL) error ("Out of memory");
|
||||
|
||||
newfile->filename = strdup(filename);
|
||||
newfile->filename = strdup(config->filename);
|
||||
newfile->sprite_offset = sprite_offset;
|
||||
|
||||
/* Copy the initial parameter list */
|
||||
assert(lengthof(newfile->param) == lengthof(config->param) && lengthof(config->param) == 0x80);
|
||||
newfile->param_end = config->num_params;
|
||||
memcpy(newfile->param, config->param, 0x80 * sizeof(newfile->param[0]));
|
||||
|
||||
if (_first_grffile == NULL) {
|
||||
_cur_grffile = newfile;
|
||||
_first_grffile = newfile;
|
||||
@ -2707,17 +2713,18 @@ void LoadNewGRF(uint load_index, uint file_index)
|
||||
_custom_sprites_base = load_index;
|
||||
for (stage = 0; stage <= 2; stage++) {
|
||||
uint slot = file_index;
|
||||
uint j;
|
||||
GRFConfig *c;
|
||||
|
||||
_cur_stage = stage;
|
||||
_cur_spriteid = load_index;
|
||||
for (j = 0; j != lengthof(_newgrf_files) && _newgrf_files[j] != NULL; j++) {
|
||||
if (!FiosCheckFileExists(_newgrf_files[j])) {
|
||||
for (c = _first_grfconfig; c != NULL; c = c->next) {
|
||||
if (!FiosCheckFileExists(c->filename)) {
|
||||
// TODO: usrerror()
|
||||
error("NewGRF file missing: %s", _newgrf_files[j]);
|
||||
error("NewGRF file missing: %s", c->filename);
|
||||
}
|
||||
if (stage == 0) InitNewGRFFile(_newgrf_files[j], _cur_spriteid);
|
||||
LoadNewGRFFile(_newgrf_files[j], slot++, stage);
|
||||
|
||||
if (stage == 0) InitNewGRFFile(c, _cur_spriteid);
|
||||
LoadNewGRFFile(c->filename, slot++, stage);
|
||||
if (stage == 2) ClearTemporaryNewGRFData();
|
||||
DEBUG(spritecache, 2) ("Currently %i sprites are loaded", load_index);
|
||||
}
|
||||
|
16
newgrf.h
16
newgrf.h
@ -13,14 +13,13 @@ typedef struct GRFLabel {
|
||||
struct GRFLabel *next;
|
||||
} GRFLabel;
|
||||
|
||||
typedef struct GRFFile GRFFile;
|
||||
struct GRFFile {
|
||||
typedef struct GRFFile {
|
||||
char *filename;
|
||||
uint32 grfid;
|
||||
uint16 flags;
|
||||
uint16 sprite_offset;
|
||||
SpriteID first_spriteset; ///< Holds the first spriteset's sprite offset.
|
||||
GRFFile *next;
|
||||
struct GRFFile *next;
|
||||
|
||||
/* A sprite group contains all sprites of a given vehicle (or multiple
|
||||
* vehicles) when carrying given cargo. It consists of several sprite
|
||||
@ -48,10 +47,19 @@ struct GRFFile {
|
||||
uint param_end; /// one more than the highest set parameter
|
||||
|
||||
GRFLabel *label; ///< Pointer to the first label. This is a linked list, not an array.
|
||||
};
|
||||
} 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;
|
||||
|
||||
void LoadNewGRF(uint load_index, uint file_index);
|
||||
|
||||
|
73
settings.c
73
settings.c
@ -34,6 +34,7 @@
|
||||
#include "console.h"
|
||||
#include "saveload.h"
|
||||
#include "npf.h"
|
||||
#include "newgrf.h"
|
||||
|
||||
/** The patch values that are used for new games and/or modified in config file */
|
||||
Patches _patches_newgame;
|
||||
@ -43,6 +44,10 @@ typedef struct IniItem IniItem;
|
||||
typedef struct IniGroup IniGroup;
|
||||
typedef struct SettingsMemoryPool SettingsMemoryPool;
|
||||
|
||||
typedef const char *SettingListCallbackProc(const IniItem *item, uint index);
|
||||
typedef void SettingDescProc(IniFile *ini, const SettingDesc *desc, const char *grpname, void *object);
|
||||
typedef void SettingDescProcList(IniFile *ini, const char *grpname, char **list, uint len, SettingListCallbackProc proc);
|
||||
|
||||
static void pool_init(SettingsMemoryPool **pool);
|
||||
static void *pool_alloc(SettingsMemoryPool **pool, uint size);
|
||||
static void *pool_strdup(SettingsMemoryPool **pool, const char *mem, uint size);
|
||||
@ -817,20 +822,25 @@ static void ini_save_settings(IniFile *ini, const SettingDesc *sd, const char *g
|
||||
* file that will be parsed
|
||||
* @param list pointer to an string(pointer) array that will store the parsed
|
||||
* entries of the given section
|
||||
* @param len the maximum number of items available for the above list */
|
||||
static void ini_load_setting_list(IniFile *ini, const char *grpname, char **list, uint len)
|
||||
* @param len the maximum number of items available for the above list
|
||||
* @param proc callback function that can override how the values are stored
|
||||
* inside the list */
|
||||
static void ini_load_setting_list(IniFile *ini, const char *grpname, char **list, uint len, SettingListCallbackProc proc)
|
||||
{
|
||||
IniGroup *group = ini_getgroup(ini, grpname, -1);
|
||||
IniItem *item;
|
||||
uint i;
|
||||
const char *entry;
|
||||
uint i, j;
|
||||
|
||||
if (group == NULL) return;
|
||||
|
||||
item = group->item;
|
||||
for (i = 0; i != len; i++) {
|
||||
if (item == NULL) break;
|
||||
list[i] = strdup(item->name);
|
||||
item = item->next;
|
||||
for (i = j = 0, item = group->item; item != NULL; item = item->next) {
|
||||
entry = (proc != NULL) ? proc(item, i++) : item->name;
|
||||
|
||||
if (entry == NULL || list == NULL) continue;
|
||||
|
||||
if (j == len) break;
|
||||
list[j++] = strdup(entry);
|
||||
}
|
||||
}
|
||||
|
||||
@ -843,26 +853,30 @@ static void ini_load_setting_list(IniFile *ini, const char *grpname, char **list
|
||||
* source to be saved into the relevant ini section
|
||||
* @param len the maximum number of items available for the above list
|
||||
* @param proc callback function that can will provide the source data if defined */
|
||||
static void ini_save_setting_list(IniFile *ini, const char *grpname, char **list, uint len)
|
||||
static void ini_save_setting_list(IniFile *ini, const char *grpname, char **list, uint len, SettingListCallbackProc proc)
|
||||
{
|
||||
IniGroup *group = ini_getgroup(ini, grpname, -1);
|
||||
IniItem *item = NULL;
|
||||
const char *entry;
|
||||
uint i;
|
||||
bool first = true;
|
||||
|
||||
if (proc == NULL && list == NULL) return;
|
||||
if (group == NULL) return;
|
||||
group->item = NULL;
|
||||
|
||||
for (i = 0; i != len; i++) {
|
||||
if (list[i] == NULL || list[i][0] == '\0') continue;
|
||||
entry = (proc != NULL) ? proc(NULL, i) : list[i];
|
||||
|
||||
if (entry == NULL || *entry == '\0') continue;
|
||||
|
||||
if (first) { // add first item to the head of the group
|
||||
item = ini_item_alloc(group, list[i], strlen(list[i]));
|
||||
item = ini_item_alloc(group, entry, strlen(entry));
|
||||
item->value = item->name;
|
||||
group->item = item;
|
||||
first = false;
|
||||
} else { // all other items are attached to the previous one
|
||||
item->next = ini_item_alloc(group, list[i], strlen(list[i]));
|
||||
item->next = ini_item_alloc(group, entry, strlen(entry));
|
||||
item = item->next;
|
||||
item->value = item->name;
|
||||
}
|
||||
@ -1385,8 +1399,33 @@ static const SettingDesc _currency_settings[] = {
|
||||
#undef NO
|
||||
#undef CR
|
||||
|
||||
typedef void SettingDescProc(IniFile *ini, const SettingDesc *desc, const char *grpname, void *object);
|
||||
typedef void SettingDescProcList(IniFile *ini, const char *grpname, char **list, uint len);
|
||||
const char *GRFProcessParams(const IniItem *item, uint index)
|
||||
{
|
||||
GRFConfig *c;
|
||||
|
||||
/* Saving newgrf stuff to configuration, not done since it is kept the same */
|
||||
if (item == NULL) return NULL;
|
||||
|
||||
/* Loading newgrf stuff from configuration file */
|
||||
c = calloc(1, sizeof(*c));
|
||||
c->filename = strdup(item->name);
|
||||
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;
|
||||
}
|
||||
|
||||
if (_first_grfconfig == NULL) {
|
||||
_first_grfconfig = c;
|
||||
} else {
|
||||
GRFConfig *c2;
|
||||
/* Attach the label to the end of the list */
|
||||
for (c2 = _first_grfconfig; c2->next != NULL; c2 = c2->next);
|
||||
c2->next = c;
|
||||
}
|
||||
|
||||
return c->filename;
|
||||
}
|
||||
|
||||
/* Common handler for saving/loading variables to the configuration file */
|
||||
static void HandleSettingDescs(IniFile *ini, SettingDescProc *proc, SettingDescProcList *proc_list)
|
||||
@ -1403,8 +1442,8 @@ static void HandleSettingDescs(IniFile *ini, SettingDescProc *proc, SettingDescP
|
||||
|
||||
#ifdef ENABLE_NETWORK
|
||||
proc(ini, (const SettingDesc*)_network_settings, "network", NULL);
|
||||
proc_list(ini, "servers", _network_host_list, lengthof(_network_host_list));
|
||||
proc_list(ini, "bans", _network_ban_list, lengthof(_network_ban_list));
|
||||
proc_list(ini, "servers", _network_host_list, lengthof(_network_host_list), NULL);
|
||||
proc_list(ini, "bans", _network_ban_list, lengthof(_network_ban_list), NULL);
|
||||
#endif /* ENABLE_NETWORK */
|
||||
}
|
||||
|
||||
@ -1413,7 +1452,7 @@ void LoadFromConfig(void)
|
||||
{
|
||||
IniFile *ini = ini_load(_config_file);
|
||||
HandleSettingDescs(ini, ini_load_settings, ini_load_setting_list);
|
||||
ini_load_setting_list(ini, "newgrf", _newgrf_files, lengthof(_newgrf_files));
|
||||
ini_load_setting_list(ini, "newgrf", NULL, 0, GRFProcessParams);
|
||||
ini_free(ini);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user