File diff r221:56c7ed3a0581 → r222:4409829eb08f
settings.c
Show inline comments
 
@@ -304,51 +304,51 @@ static bool ini_save(const char *filenam
 
	if (f == NULL) return false;
 

	
 
	for(group = ini->group; group; group = group->next) {
 
		if (group->comment) fputs(group->comment, f);
 
		fprintf(f, "[%s]\n", group->name);
 
		for(item = group->item; item; item = item->next) {
 
			if (item->comment) fputs(item->comment, f);
 
			fprintf(f, "%s = %s\n", item->name, item->value ? item->value : "");
 
		}
 
	}
 
	if (ini->comment) fputs(ini->comment, f);
 

	
 
	fclose(f);
 
	return true;
 
}
 

	
 
static void ini_free(IniFile *ini)
 
{
 
	pool_free(&ini->pool);
 
}
 

	
 
struct SettingDesc {
 
	const char *name;
 
	int flags;
 
	void *def;
 
	const void *def;
 
	void *ptr;
 
	void *b;
 
	const void *b;
 

	
 
};
 

	
 
static int lookup_oneofmany(const char *many, const char *one, int onelen)
 
{
 
	const char *s;
 
	int idx;
 

	
 
	if (onelen == -1) onelen = strlen(one);
 

	
 
	// check if it's an integer
 
	if (*one >= '0' && *one <= '9')
 
		return strtoul(one, NULL, 0);
 

	
 
	idx = 0;
 
	for(;;) {
 
		// find end of item
 
		s = many;
 
		while (*s != '|' && *s != 0) s++;
 
		if (s - many == onelen && !memcmp(one, many, onelen)) return idx;
 
		if (*s == 0) return -1;
 
		many = s + 1;
 
		idx++;
 
	}
 
@@ -472,92 +472,92 @@ static void make_oneofmany(char *buf, co
 
static void make_manyofmany(char *buf, const char *many, uint32 x)
 
{
 
	const char *start;
 
	int i = 0;
 
	bool init = true;
 

	
 
	do {
 
		start = many;
 
		while (*many != 0 && *many != '|') many++;
 
		if (x & 1) {
 
			if (!init) *buf++ = '|';
 
			init = false;
 
			if (start == many) {
 
				buf += sprintf(buf, "%d", i);
 
			} else {
 
				memcpy(buf, start, many - start);
 
				buf += many - start;
 
			}
 
		}
 
		if (*many == '|') many++;
 
	} while (++i, x>>=1);
 
	*buf = 0;
 
}
 

	
 
static void *string_to_val(const SettingDesc *desc, const char *str)
 
static const void *string_to_val(const SettingDesc *desc, const char *str)
 
{
 
	unsigned long val;
 
	char *end;
 

	
 
	switch(desc->flags & 0xF) {
 
	case SDT_INTX:
 
		val = strtol(str, &end, 0);
 
		if (*end != 0) ShowInfoF("ini: trailing characters at end of setting '%s'", desc->name);
 
		return (void*)val;
 
	case SDT_ONEOFMANY: {
 
		int r = lookup_oneofmany((char*)desc->b, str, -1);
 
		if (r != -1) return (void*)r;
 
		ShowInfoF("ini: invalid value '%s' for '%s'", str, desc->name);
 
		return 0;
 
	}
 
	case SDT_MANYOFMANY: {
 
		uint32 r = lookup_manyofmany(desc->b, str);
 
		if (r != (uint32)-1) return (void*)r;
 
		ShowInfoF("ini: invalid value '%s' for '%s'", str, desc->name);
 
		return 0;
 
	}
 
	case SDT_BOOLX:
 
		if (!strcmp(str, "true") || !strcmp(str, "on") || !strcmp(str, "1"))
 
			return (void*)true;
 
		if (!strcmp(str, "false") || !strcmp(str, "off") || !strcmp(str, "0"))
 
			return (void*)false;
 
		ShowInfoF("ini: invalid setting value '%s' for '%s'", str, desc->name);
 
		break;
 

	
 
	case SDT_STRING:
 
	case SDT_STRINGBUF:
 
	case SDT_INTLIST:
 
		return (void*)str;
 
	}
 

	
 
	return NULL;
 
}
 

	
 
static void load_setting_desc(IniFile *ini, const SettingDesc *desc, void *grpname, void *base)
 
static void load_setting_desc(IniFile *ini, const SettingDesc *desc, const void *grpname, void *base)
 
{
 
	IniGroup *group_def = ini_getgroup(ini, grpname, -1), *group;
 
	IniItem *item;
 
	void *p;
 
	const void *p;
 
	void *ptr;
 

	
 
	for (;desc->name;desc++) {
 
		// group override?
 
		const char *s = strchr(desc->name, '.');
 
		if (s) {
 
			group = ini_getgroup(ini, desc->name, s - desc->name);
 
			s++;
 
		} else {
 
			s = desc->name;
 
			group = group_def;
 
		}
 

	
 
		item = ini_getitem(group, s, false);
 
		if (!item) {
 
			p = desc->def;
 
		} else {
 
			p = string_to_val(desc, item->value);
 
		}
 

	
 
		// get ptr to array
 
		ptr = desc->ptr;
 
		if ( (uint32)ptr < 0x10000)
 
			ptr = (byte*)base + (uint32)ptr;
 
@@ -582,53 +582,54 @@ static void load_setting_desc(IniFile *i
 
				*(uint32*)ptr = (uint32)p;
 
				break;
 
			default:
 
				NOT_REACHED();
 
			}
 
			break;
 
		case SDT_STRING:
 
			if (*(char**)ptr) free(*(char**)ptr);
 
			*(char**)ptr = strdup((char*)p);
 
			break;
 
		case SDT_STRINGBUF:
 
			if (p) ttd_strlcpy((char*)ptr, p, desc->flags >> 16);
 
			break;
 
		case SDT_INTLIST: {
 
			if (!load_intlist(p, ptr, desc->flags >> 16, desc->flags >> 4 & 7))
 
				ShowInfoF("ini: error in array '%s'", desc->name);
 
			break;
 
		}
 
		default:
 
			NOT_REACHED();
 
		}
 
	}
 
}
 

	
 
static void save_setting_desc(IniFile *ini, const SettingDesc *desc, void *grpname, void *base)
 
static void save_setting_desc(IniFile *ini, const SettingDesc *desc, const void *grpname, void *base)
 
{
 
	IniGroup *group_def = NULL, *group;
 
	IniItem *item;
 
	void *p, *ptr;
 
	const void *p;
 
	void *ptr;
 
	int i = 0;
 
	char buf[512]; // setting buffer
 
	const char *s;
 

	
 
	for (;desc->name;desc++) {
 
		if (desc->flags & SDT_NOSAVE)
 
			continue;
 

	
 
		// group override?
 
		s = strchr(desc->name, '.');
 
		if (s) {
 
			group = ini_getgroup(ini, desc->name, s - desc->name);
 
			s++;
 
		} else {
 
			if (group_def == NULL)
 
				group_def = ini_getgroup(ini, grpname, -1);
 
			s = desc->name;
 
			group = group_def;
 
		}
 

	
 
		item = ini_getitem(group, s, true);
 

	
 
		// get ptr to array
 
		ptr = desc->ptr;
 
@@ -862,49 +863,49 @@ static const SettingDesc patch_settings[
 

	
 
	{"keep_all_autosave",		SDT_BOOL,		(void*)false, (void*)offsetof(Patches, keep_all_autosave),		NULL},
 

	
 
	{"extra_dynamite",			SDT_BOOL,		(void*)false, (void*)offsetof(Patches, extra_dynamite),				NULL},
 

	
 
	{"never_expire_vehicles",SDT_BOOL,	(void*)false, (void*)offsetof(Patches, never_expire_vehicles),NULL},
 
	{"extend_vehicle_life",	SDT_UINT8,	(void*)0,			(void*)offsetof(Patches, extend_vehicle_life),	NULL},
 

	
 
	{"auto_euro",						SDT_BOOL,		(void*)true,	(void*)offsetof(Patches, auto_euro),						NULL},
 

	
 
	{"serviceathelipad",		SDT_BOOL,		(void*)true,	(void*)offsetof(Patches, serviceathelipad),			NULL},
 
	{"smooth_economy",			SDT_BOOL,		(void*)false, (void*)offsetof(Patches, smooth_economy),				NULL},
 
	{"dist_local_authority",SDT_UINT8,	(void*)20,		(void*)offsetof(Patches, dist_local_authority), NULL},
 

	
 
	{"wait_oneway_signal",	SDT_UINT8,	(void*)15,		(void*)offsetof(Patches, wait_oneway_signal),		NULL},
 
	{"wait_twoway_signal",	SDT_UINT8,	(void*)41,		(void*)offsetof(Patches, wait_twoway_signal),		NULL},
 

	
 
	{"ainew_active",				SDT_BOOL,		(void*)false, (void*)offsetof(Patches, ainew_active),					NULL},
 

	
 
	{"drag_signals_density",SDT_UINT8,	(void*)4,			(void*)offsetof(Patches, drag_signals_density), NULL},
 

	
 
	{NULL,									0,					NULL,					NULL,																						NULL}
 
};
 

	
 
typedef void SettingDescProc(IniFile *ini, const SettingDesc *desc, void *grpname, void *base);
 
typedef void SettingDescProc(IniFile *ini, const SettingDesc *desc, const void *grpname, void *base);
 

	
 
static void HandleSettingDescs(IniFile *ini, SettingDescProc *proc)
 
{
 
	proc(ini, misc_settings,		"misc",			NULL);
 
	proc(ini, win32_settings,		"win32",		NULL);
 
	proc(ini, network_settings, "network",	NULL);
 
	proc(ini, music_settings,		"music",		&msf);
 
	proc(ini, gameopt_settings, "gameopt",	&_new_opt);
 
	proc(ini, patch_settings,		"patches",	&_patches);
 

	
 
	proc(ini, debug_settings,		"debug",		NULL);
 
}
 

	
 
void LoadGrfSettings(IniFile *ini)
 
{
 
	IniGroup *group = ini_getgroup(ini, "newgrf", -1);
 
	IniItem *item;
 
	int i;
 

	
 
	if (!group)
 
		return;
 

	
 
	for(i=0; i!=lengthof(_newgrf_files); i++) {
 
		char buf[3];