settings.c
changeset 193 0a7025304867
parent 188 30f27b5c1ee5
child 222 b88456001397
equal deleted inserted replaced
192:614bba52258d 193:0a7025304867
    48 
    48 
    49 static MemoryPool *pool_new(uint minsize)
    49 static MemoryPool *pool_new(uint minsize)
    50 {
    50 {
    51 	MemoryPool *p;
    51 	MemoryPool *p;
    52 	if (minsize < 4096 - 12) minsize = 4096 - 12;
    52 	if (minsize < 4096 - 12) minsize = 4096 - 12;
    53 	
    53 
    54 	p = malloc(sizeof(MemoryPool) - 1 + minsize);
    54 	p = malloc(sizeof(MemoryPool) - 1 + minsize);
    55 	p->pos = 0;
    55 	p->pos = 0;
    56 	p->size = minsize;
    56 	p->size = minsize;
    57 	p->next = NULL;
    57 	p->next = NULL;
    58 	return p;
    58 	return p;
    76 	// then check if there's not memory in the cur pool
    76 	// then check if there's not memory in the cur pool
    77 	} else if (p->pos + size > p->size) {
    77 	} else if (p->pos + size > p->size) {
    78 		MemoryPool *n = pool_new(size);
    78 		MemoryPool *n = pool_new(size);
    79 		*pool = n;
    79 		*pool = n;
    80 		n->next = p;
    80 		n->next = p;
    81 		p = n;		
    81 		p = n;
    82 	}
    82 	}
    83 
    83 
    84 	pos = p->pos;
    84 	pos = p->pos;
    85 	p->pos += size;
    85 	p->pos += size;
    86 	return p->mem + pos;
    86 	return p->mem + pos;
   186 	in = fopen(filename, "r");
   186 	in = fopen(filename, "r");
   187 	if (in == NULL) return ini;
   187 	if (in == NULL) return ini;
   188 
   188 
   189 	// for each line in the file
   189 	// for each line in the file
   190 	while (fgets(buffer, sizeof(buffer), in)) {
   190 	while (fgets(buffer, sizeof(buffer), in)) {
   191 		
   191 
   192 		// trim whitespace from the left side
   192 		// trim whitespace from the left side
   193 		for(s=buffer; *s == ' ' || *s == '\t'; s++);
   193 		for(s=buffer; *s == ' ' || *s == '\t'; s++);
   194 
   194 
   195 		// trim whitespace from right side.
   195 		// trim whitespace from right side.
   196 		e = s + strlen(s);
   196 		e = s + strlen(s);
   228 				comment_size = 0;
   228 				comment_size = 0;
   229 			}
   229 			}
   230 		} else if (group) {
   230 		} else if (group) {
   231 			// find end of keyname
   231 			// find end of keyname
   232 			for(t=s; *t != 0 && *t != '=' && *t != '\t' && *t != ' '; t++) {}
   232 			for(t=s; *t != 0 && *t != '=' && *t != '\t' && *t != ' '; t++) {}
   233 						
   233 
   234 			// it's an item in an existing group
   234 			// it's an item in an existing group
   235 			item = ini_item_alloc(group, s, t-s);
   235 			item = ini_item_alloc(group, s, t-s);
   236 			if (comment_size) {
   236 			if (comment_size) {
   237 				item->comment = pool_strdup(&ini->pool, comment, comment_size);
   237 				item->comment = pool_strdup(&ini->pool, comment, comment_size);
   238 				comment_size = 0;
   238 				comment_size = 0;
   283 	uint len = strlen(name);
   283 	uint len = strlen(name);
   284 
   284 
   285 	for(item = group->item; item; item = item->next)
   285 	for(item = group->item; item; item = item->next)
   286 		if (!strcmp(item->name, name))
   286 		if (!strcmp(item->name, name))
   287 			return item;
   287 			return item;
   288 	
   288 
   289 	if (!create) return NULL;
   289 	if (!create) return NULL;
   290 
   290 
   291 	// otherwise make a new one
   291 	// otherwise make a new one
   292 	item = ini_item_alloc(group, name, len);
   292 	item = ini_item_alloc(group, name, len);
   293 	return item;
   293 	return item;
   297 static bool ini_save(const char *filename, IniFile *ini)
   297 static bool ini_save(const char *filename, IniFile *ini)
   298 {
   298 {
   299 	FILE *f;
   299 	FILE *f;
   300 	IniGroup *group;
   300 	IniGroup *group;
   301 	IniItem *item;
   301 	IniItem *item;
   302 	
   302 
   303 	f = fopen(filename, "w");
   303 	f = fopen(filename, "w");
   304 	if (f == NULL) return false;
   304 	if (f == NULL) return false;
   305 
   305 
   306 	for(group = ini->group; group; group = group->next) {
   306 	for(group = ini->group; group; group = group->next) {
   307 		if (group->comment) fputs(group->comment, f);
   307 		if (group->comment) fputs(group->comment, f);
   326 	const char *name;
   326 	const char *name;
   327 	int flags;
   327 	int flags;
   328 	void *def;
   328 	void *def;
   329 	void *ptr;
   329 	void *ptr;
   330 	void *b;
   330 	void *b;
   331 	
   331 
   332 };
   332 };
   333 
   333 
   334 static int lookup_oneofmany(const char *many, const char *one, int onelen)
   334 static int lookup_oneofmany(const char *many, const char *one, int onelen)
   335 {
   335 {
   336 	const char *s;
   336 	const char *s;
   339 	if (onelen == -1) onelen = strlen(one);
   339 	if (onelen == -1) onelen = strlen(one);
   340 
   340 
   341 	// check if it's an integer
   341 	// check if it's an integer
   342 	if (*one >= '0' && *one <= '9')
   342 	if (*one >= '0' && *one <= '9')
   343 		return strtoul(one, NULL, 0);
   343 		return strtoul(one, NULL, 0);
   344 		
   344 
   345 	idx = 0;
   345 	idx = 0;
   346 	for(;;) {
   346 	for(;;) {
   347 		// find end of item
   347 		// find end of item
   348 		s = many;
   348 		s = many;
   349 		while (*s != '|' && *s != 0) s++;
   349 		while (*s != '|' && *s != 0) s++;
   398 
   398 
   399 static bool load_intlist(const char *str, void *array, int nelems, int type)
   399 static bool load_intlist(const char *str, void *array, int nelems, int type)
   400 {
   400 {
   401 	int items[64];
   401 	int items[64];
   402 	int i,nitems;
   402 	int i,nitems;
   403 	
   403 
   404 	if (str == NULL) {
   404 	if (str == NULL) {
   405 		memset(items, 0, sizeof(items));
   405 		memset(items, 0, sizeof(items));
   406 		nitems = nelems;
   406 		nitems = nelems;
   407 	} else {
   407 	} else {
   408 		nitems = parse_intlist(str, items, lengthof(items));
   408 		nitems = parse_intlist(str, items, lengthof(items));
   520 			return (void*)true;
   520 			return (void*)true;
   521 		if (!strcmp(str, "false") || !strcmp(str, "off") || !strcmp(str, "0"))
   521 		if (!strcmp(str, "false") || !strcmp(str, "off") || !strcmp(str, "0"))
   522 			return (void*)false;
   522 			return (void*)false;
   523 		ShowInfoF("ini: invalid setting value '%s' for '%s'", str, desc->name);
   523 		ShowInfoF("ini: invalid setting value '%s' for '%s'", str, desc->name);
   524 		break;
   524 		break;
   525 	
   525 
   526 	case SDT_STRING:
   526 	case SDT_STRING:
   527 	case SDT_STRINGBUF:
   527 	case SDT_STRINGBUF:
   528 	case SDT_INTLIST:
   528 	case SDT_INTLIST:
   529 		return (void*)str;
   529 		return (void*)str;
   530 	}
   530 	}
   547 			s++;
   547 			s++;
   548 		} else {
   548 		} else {
   549 			s = desc->name;
   549 			s = desc->name;
   550 			group = group_def;
   550 			group = group_def;
   551 		}
   551 		}
   552 		
   552 
   553 		item = ini_getitem(group, s, false);
   553 		item = ini_getitem(group, s, false);
   554 		if (!item) {
   554 		if (!item) {
   555 			p = desc->def;
   555 			p = desc->def;
   556 		} else {
   556 		} else {
   557 			p = string_to_val(desc, item->value);
   557 			p = string_to_val(desc, item->value);
   558 		}
   558 		}
   559 		
   559 
   560 		// get ptr to array
   560 		// get ptr to array
   561 		ptr = desc->ptr;
   561 		ptr = desc->ptr;
   562 		if ( (uint32)ptr < 0x10000)
   562 		if ( (uint32)ptr < 0x10000)
   563 			ptr = (byte*)base + (uint32)ptr;
   563 			ptr = (byte*)base + (uint32)ptr;
   564 
   564 
   598 			break;
   598 			break;
   599 		}
   599 		}
   600 		default:
   600 		default:
   601 			NOT_REACHED();
   601 			NOT_REACHED();
   602 		}
   602 		}
   603 	}	
   603 	}
   604 }
   604 }
   605 
   605 
   606 static void save_setting_desc(IniFile *ini, const SettingDesc *desc, void *grpname, void *base)
   606 static void save_setting_desc(IniFile *ini, const SettingDesc *desc, void *grpname, void *base)
   607 {
   607 {
   608 	IniGroup *group_def = NULL, *group;
   608 	IniGroup *group_def = NULL, *group;
   613 	const char *s;
   613 	const char *s;
   614 
   614 
   615 	for (;desc->name;desc++) {
   615 	for (;desc->name;desc++) {
   616 		if (desc->flags & SDT_NOSAVE)
   616 		if (desc->flags & SDT_NOSAVE)
   617 			continue;
   617 			continue;
   618 		
   618 
   619 		// group override?
   619 		// group override?
   620 		s = strchr(desc->name, '.');
   620 		s = strchr(desc->name, '.');
   621 		if (s) {
   621 		if (s) {
   622 			group = ini_getgroup(ini, desc->name, s - desc->name);
   622 			group = ini_getgroup(ini, desc->name, s - desc->name);
   623 			s++;
   623 			s++;
   625 			if (group_def == NULL)
   625 			if (group_def == NULL)
   626 				group_def = ini_getgroup(ini, grpname, -1);
   626 				group_def = ini_getgroup(ini, grpname, -1);
   627 			s = desc->name;
   627 			s = desc->name;
   628 			group = group_def;
   628 			group = group_def;
   629 		}
   629 		}
   630 		
   630 
   631 		item = ini_getitem(group, s, true);
   631 		item = ini_getitem(group, s, true);
   632 
   632 
   633 		// get ptr to array
   633 		// get ptr to array
   634 		ptr = desc->ptr;
   634 		ptr = desc->ptr;
   635 		if ( (uint32)ptr < 0x10000)
   635 		if ( (uint32)ptr < 0x10000)
   636 			ptr = (byte*)base + (uint32)ptr;
   636 			ptr = (byte*)base + (uint32)ptr;
   637 		
   637 
   638 		if (item->value != NULL) {
   638 		if (item->value != NULL) {
   639 			// check if the value is the same as the old value	
   639 			// check if the value is the same as the old value
   640 			p = string_to_val(desc, item->value);
   640 			p = string_to_val(desc, item->value);
   641 
   641 
   642 			switch(desc->flags & 0xF) {
   642 			switch(desc->flags & 0xF) {
   643 			case SDT_INTX:
   643 			case SDT_INTX:
   644 			case SDT_ONEOFMANY:
   644 			case SDT_ONEOFMANY:
   656 						continue;
   656 						continue;
   657 					break;
   657 					break;
   658 				case SDT_INT32 >> 4:
   658 				case SDT_INT32 >> 4:
   659 				case SDT_UINT32 >> 4:
   659 				case SDT_UINT32 >> 4:
   660 					if (*(uint32*)ptr == (uint32)p)
   660 					if (*(uint32*)ptr == (uint32)p)
   661 						continue;	
   661 						continue;
   662 					break;
   662 					break;
   663 				default:
   663 				default:
   664 					NOT_REACHED();
   664 					NOT_REACHED();
   665 				}
   665 				}
   666 				break;
   666 				break;
   715 			make_intlist(buf, ptr, desc->flags >> 16, desc->flags >> 4 & 7);
   715 			make_intlist(buf, ptr, desc->flags >> 16, desc->flags >> 4 & 7);
   716 			break;
   716 			break;
   717 		}
   717 		}
   718 		// the value is different, that means we have to write it to the ini
   718 		// the value is different, that means we have to write it to the ini
   719 		item->value = pool_strdup(&ini->pool, buf, strlen(buf));
   719 		item->value = pool_strdup(&ini->pool, buf, strlen(buf));
   720 	}	
   720 	}
   721 }
   721 }
   722 
   722 
   723 //***************************
   723 //***************************
   724 // TTD specific INI stuff
   724 // TTD specific INI stuff
   725 //***************************
   725 //***************************
   824 	{"new_depot_finding",		SDT_BOOL,		(void*)false, (void*)offsetof(Patches, new_depot_finding),		NULL},
   824 	{"new_depot_finding",		SDT_BOOL,		(void*)false, (void*)offsetof(Patches, new_depot_finding),		NULL},
   825 
   825 
   826 	{"nonuniform_stations",	SDT_BOOL,		(void*)false, (void*)offsetof(Patches, nonuniform_stations),	NULL},
   826 	{"nonuniform_stations",	SDT_BOOL,		(void*)false, (void*)offsetof(Patches, nonuniform_stations),	NULL},
   827 	{"always_small_airport",SDT_BOOL,		(void*)false, (void*)offsetof(Patches, always_small_airport),	NULL},
   827 	{"always_small_airport",SDT_BOOL,		(void*)false, (void*)offsetof(Patches, always_small_airport),	NULL},
   828 	{"realistic_acceleration",SDT_BOOL, (void*)false, (void*)offsetof(Patches, realistic_acceleration),	NULL},
   828 	{"realistic_acceleration",SDT_BOOL, (void*)false, (void*)offsetof(Patches, realistic_acceleration),	NULL},
   829 	
   829 
   830 	{"toolbar_pos",					SDT_UINT8,	(void*)0,			(void*)offsetof(Patches, toolbar_pos),					NULL},
   830 	{"toolbar_pos",					SDT_UINT8,	(void*)0,			(void*)offsetof(Patches, toolbar_pos),					NULL},
   831 
   831 
   832 	{"max_trains",					SDT_UINT8,	(void*)80,		(void*)offsetof(Patches, max_trains),						NULL},
   832 	{"max_trains",					SDT_UINT8,	(void*)80,		(void*)offsetof(Patches, max_trains),						NULL},
   833 	{"max_roadveh",					SDT_UINT8,	(void*)80,		(void*)offsetof(Patches, max_roadveh),					NULL},
   833 	{"max_roadveh",					SDT_UINT8,	(void*)80,		(void*)offsetof(Patches, max_roadveh),					NULL},
   834 	{"max_aircraft",				SDT_UINT8,	(void*)40,		(void*)offsetof(Patches, max_aircraft),					NULL},
   834 	{"max_aircraft",				SDT_UINT8,	(void*)40,		(void*)offsetof(Patches, max_aircraft),					NULL},
   846 
   846 
   847 	{"new_pathfinding",			SDT_BOOL,		(void*)false, (void*)offsetof(Patches, new_pathfinding),			NULL},
   847 	{"new_pathfinding",			SDT_BOOL,		(void*)false, (void*)offsetof(Patches, new_pathfinding),			NULL},
   848 	{"pf_maxlength",				SDT_UINT16, (void*)512,		(void*)offsetof(Patches, pf_maxlength),					NULL},
   848 	{"pf_maxlength",				SDT_UINT16, (void*)512,		(void*)offsetof(Patches, pf_maxlength),					NULL},
   849 	{"pf_maxdepth",					SDT_UINT8,	(void*)16,		(void*)offsetof(Patches, pf_maxdepth),					NULL},
   849 	{"pf_maxdepth",					SDT_UINT8,	(void*)16,		(void*)offsetof(Patches, pf_maxdepth),					NULL},
   850 
   850 
   851 	
   851 
   852 	{"ai_disable_veh_train",SDT_BOOL,		(void*)false, (void*)offsetof(Patches, ai_disable_veh_train),	NULL},
   852 	{"ai_disable_veh_train",SDT_BOOL,		(void*)false, (void*)offsetof(Patches, ai_disable_veh_train),	NULL},
   853 	{"ai_disable_veh_roadveh",SDT_BOOL,	(void*)false, (void*)offsetof(Patches, ai_disable_veh_roadveh),	NULL},
   853 	{"ai_disable_veh_roadveh",SDT_BOOL,	(void*)false, (void*)offsetof(Patches, ai_disable_veh_roadveh),	NULL},
   854 	{"ai_disable_veh_aircraft",SDT_BOOL,(void*)false, (void*)offsetof(Patches, ai_disable_veh_aircraft),NULL},
   854 	{"ai_disable_veh_aircraft",SDT_BOOL,(void*)false, (void*)offsetof(Patches, ai_disable_veh_aircraft),NULL},
   855 	{"ai_disable_veh_ship",	SDT_BOOL,		(void*)false, (void*)offsetof(Patches, ai_disable_veh_ship),	NULL},
   855 	{"ai_disable_veh_ship",	SDT_BOOL,		(void*)false, (void*)offsetof(Patches, ai_disable_veh_ship),	NULL},
   856 	{"starting_date",				SDT_UINT32, (void*)1950,	(void*)offsetof(Patches, starting_date),				NULL},
   856 	{"starting_date",				SDT_UINT32, (void*)1950,	(void*)offsetof(Patches, starting_date),				NULL},
   873 	{"smooth_economy",			SDT_BOOL,		(void*)false, (void*)offsetof(Patches, smooth_economy),				NULL},
   873 	{"smooth_economy",			SDT_BOOL,		(void*)false, (void*)offsetof(Patches, smooth_economy),				NULL},
   874 	{"dist_local_authority",SDT_UINT8,	(void*)20,		(void*)offsetof(Patches, dist_local_authority), NULL},
   874 	{"dist_local_authority",SDT_UINT8,	(void*)20,		(void*)offsetof(Patches, dist_local_authority), NULL},
   875 
   875 
   876 	{"wait_oneway_signal",	SDT_UINT8,	(void*)15,		(void*)offsetof(Patches, wait_oneway_signal),		NULL},
   876 	{"wait_oneway_signal",	SDT_UINT8,	(void*)15,		(void*)offsetof(Patches, wait_oneway_signal),		NULL},
   877 	{"wait_twoway_signal",	SDT_UINT8,	(void*)41,		(void*)offsetof(Patches, wait_twoway_signal),		NULL},
   877 	{"wait_twoway_signal",	SDT_UINT8,	(void*)41,		(void*)offsetof(Patches, wait_twoway_signal),		NULL},
   878 	
   878 
   879 	{"ainew_active",				SDT_BOOL,		(void*)false, (void*)offsetof(Patches, ainew_active),					NULL},
   879 	{"ainew_active",				SDT_BOOL,		(void*)false, (void*)offsetof(Patches, ainew_active),					NULL},
   880 
   880 
   881 	{"drag_signals_density",SDT_UINT8,	(void*)4,			(void*)offsetof(Patches, drag_signals_density), NULL},
   881 	{"drag_signals_density",SDT_UINT8,	(void*)4,			(void*)offsetof(Patches, drag_signals_density), NULL},
   882 
   882 
   883 	{NULL,									0,					NULL,					NULL,																						NULL}
   883 	{NULL,									0,					NULL,					NULL,																						NULL}