settings_gui.c
changeset 3247 4e70e64adbb8
parent 3206 7635c2101f2e
child 3342 0de5e6997611
equal deleted inserted replaced
3246:70e9683e2d1f 3247:4e70e64adbb8
   553 	 * change that when setting stuff, copy back on clicking 'OK' */
   553 	 * change that when setting stuff, copy back on clicking 'OK' */
   554 	memcpy(&_opt_mod_temp, _opt_ptr, sizeof(GameOptions));
   554 	memcpy(&_opt_mod_temp, _opt_ptr, sizeof(GameOptions));
   555 	AllocateWindowDesc(&_game_difficulty_desc);
   555 	AllocateWindowDesc(&_game_difficulty_desc);
   556 }
   556 }
   557 
   557 
   558 typedef uint PatchEntry;
   558 static const char *_patches_ui[] = {
   559 
   559 	"vehicle_speed",
   560 static const PatchEntry _patches_ui[] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12};
   560 	"status_long_date",
   561 static const PatchEntry _patches_construction[] = {13, 14, 15, 16, 17, 18};
   561 	"show_finances",
   562 static const PatchEntry _patches_stations[] = {43, 44, 45, 46, 47, 48, 49, 50, 51};
   562 	"autoscroll",
   563 static const PatchEntry _patches_economy[] = {52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62};
   563 	"reverse_scroll",
   564 static const PatchEntry _patches_ai[] = {63, 64, 65, 66, 67, 68};
   564 	"errmsg_duration",
   565 static const PatchEntry _patches_vehicles[] = {
   565 	"toolbar_pos",
   566 	19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
   566 	"window_snap_radius",
   567 	31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42,
   567 	"invisible_trees",
   568 };
   568 	"population_in_label",
       
   569 	"map_x",
       
   570 	"map_y",
       
   571 	"link_terraform_toolbar",
       
   572 };
       
   573 
       
   574 static const char *_patches_construction[] = {
       
   575 	"build_on_slopes",
       
   576 	"extra_dynamite",
       
   577 	"longbridges",
       
   578 	"signal_side",
       
   579 	"always_small_airport",
       
   580 	"drag_signals_density",
       
   581 };
       
   582 
       
   583 static const char *_patches_stations[] = {
       
   584 	"join_stations",
       
   585 	"full_load_any",
       
   586 	"improved_load",
       
   587 	"selectgoods",
       
   588 	"new_nonstop",
       
   589 	"nonuniform_stations",
       
   590 	"station_spread",
       
   591 	"serviceathelipad",
       
   592 	"modified_catchment",
       
   593 };
       
   594 
       
   595 static const char *_patches_economy[] = {
       
   596 	"inflation",
       
   597 	"build_rawmaterial_ind",
       
   598 	"multiple_industry_per_town",
       
   599 	"same_industry_close",
       
   600 	"bribe",
       
   601 	"snow_line_height",
       
   602 	"colored_news_date",
       
   603 	"starting_date",
       
   604 	"ending_date",
       
   605 	"smooth_economy",
       
   606 	"allow_shares",
       
   607 };
       
   608 
       
   609 static const char *_patches_ai[] = {
       
   610 	"ainew_active",
       
   611 	"ai_in_multiplayer",
       
   612 	"ai_disable_veh_train",
       
   613 	"ai_disable_veh_roadveh",
       
   614 	"ai_disable_veh_aircraft",
       
   615 	"ai_disable_veh_ship",
       
   616 };
       
   617 
       
   618 static const char *_patches_vehicles[] = {
       
   619 	"realistic_acceleration",
       
   620 	"forbid_90_deg",
       
   621 	"mammoth_trains",
       
   622 	"gotodepot",
       
   623 	"roadveh_queue",
       
   624 	"new_pathfinding_all",
       
   625 	"train_income_warn",
       
   626 	"order_review_system",
       
   627 	"never_expire_vehicles",
       
   628 	"lost_train_days",
       
   629 	"autorenew",
       
   630 	"autorenew_months",
       
   631 	"autorenew_money",
       
   632 	"max_trains",
       
   633 	"max_roadveh",
       
   634 	"max_aircraft",
       
   635 	"max_ships",
       
   636 	"servint_ispercent",
       
   637 	"servint_trains",
       
   638 	"servint_roadveh",
       
   639 	"servint_ships",
       
   640 	"servint_aircraft",
       
   641 	"no_servicing_if_no_breakdowns",
       
   642 	"wagon_speed_limits",
       
   643 };
       
   644 
       
   645 typedef struct PatchEntry {
       
   646 	const SettingDesc *setting;
       
   647 	uint index;
       
   648 } PatchEntry;
   569 
   649 
   570 typedef struct PatchPage {
   650 typedef struct PatchPage {
   571 	const PatchEntry *entries;
   651 	const char **names;
       
   652 	PatchEntry *entries;
   572 	byte num;
   653 	byte num;
   573 } PatchPage;
   654 } PatchPage;
   574 
   655 
   575 static const PatchPage _patches_page[] = {
   656 /* PatchPage holds the categories, the number of elements in each category
   576 	{_patches_ui,           lengthof(_patches_ui)},
   657  * and (in NULL) a dynamic array of settings based on the string-representations
   577 	{_patches_construction, lengthof(_patches_construction)},
   658  * of the settings. This way there is no worry about indeces, and such */
   578 	{_patches_vehicles,     lengthof(_patches_vehicles)},
   659 static PatchPage _patches_page[] = {
   579 	{_patches_stations,     lengthof(_patches_stations)},
   660 	{_patches_ui,           NULL, lengthof(_patches_ui)},
   580 	{_patches_economy,      lengthof(_patches_economy)},
   661 	{_patches_construction, NULL, lengthof(_patches_construction)},
   581 	{_patches_ai,           lengthof(_patches_ai)},
   662 	{_patches_vehicles,     NULL, lengthof(_patches_vehicles)},
       
   663 	{_patches_stations,     NULL, lengthof(_patches_stations)},
       
   664 	{_patches_economy,      NULL, lengthof(_patches_economy)},
       
   665 	{_patches_ai,           NULL, lengthof(_patches_ai)},
   582 };
   666 };
   583 
   667 
   584 /** The main patches window. Shows a number of categories on top and
   668 /** The main patches window. Shows a number of categories on top and
   585  * a selection of patches in that category.
   669  * a selection of patches in that category.
   586  * Uses WP(w, def_d) macro - data_1, data_2, data_3 */
   670  * Uses WP(w, def_d) macro - data_1, data_2, data_3 */
   589 	static Patches *patches_ptr;
   673 	static Patches *patches_ptr;
   590 
   674 
   591 	switch (e->event) {
   675 	switch (e->event) {
   592 	case WE_CREATE: {
   676 	case WE_CREATE: {
   593 		extern Patches _patches_newgame;
   677 		extern Patches _patches_newgame;
       
   678 		static bool first_time = true;
       
   679 
   594 		patches_ptr = (_game_mode == GM_MENU) ? &_patches_newgame : &_patches;
   680 		patches_ptr = (_game_mode == GM_MENU) ? &_patches_newgame : &_patches;
       
   681 
       
   682 		/* Build up the dynamic settings-array only once per OpenTTD session */
       
   683 		if (first_time) {
       
   684 			PatchPage *page;
       
   685 			for (page = &_patches_page[0]; page != endof(_patches_page); page++) {
       
   686 				uint i;
       
   687 
       
   688 				page->entries = malloc(page->num * sizeof(*page->entries));
       
   689 				for (i = 0; i != page->num; i++) {
       
   690 					uint index;
       
   691 					const SettingDesc *sd = GetPatchFromName(page->names[i], &index);
       
   692 					assert(sd != NULL);
       
   693 
       
   694 					page->entries[i].setting = sd;
       
   695 					page->entries[i].index = index;
       
   696 				}
       
   697 			}
       
   698 			first_time = false;
       
   699 		}
   595 	} break;
   700 	} break;
   596 
   701 
   597 	case WE_PAINT: {
   702 	case WE_PAINT: {
   598 		int x, y;
   703 		int x, y;
   599 		const PatchEntry *pe;
       
   600 		const PatchPage *page = &_patches_page[WP(w,def_d).data_1];
   704 		const PatchPage *page = &_patches_page[WP(w,def_d).data_1];
   601 		uint i;
   705 		uint i;
   602 
   706 
   603 		/* Set up selected category */
   707 		/* Set up selected category */
   604 		w->click_state = 1 << (WP(w, def_d).data_1 + 4);
   708 		w->click_state = 1 << (WP(w, def_d).data_1 + 4);
   605 		DrawWindowWidgets(w);
   709 		DrawWindowWidgets(w);
   606 
   710 
   607 		x = 5;
   711 		x = 5;
   608 		y = 47;
   712 		y = 47;
   609 		for (i = 0, pe = page->entries; i != page->num; i++, pe++) {
   713 		for (i = 0; i != page->num; i++) {
   610 			const SettingDesc *sd = GetSettingDescription(*pe);
   714 			const SettingDesc *sd = page->entries[i].setting;
   611 			const SettingDescBase *sdb = &sd->desc;
   715 			const SettingDescBase *sdb = &sd->desc;
   612 			const void *var = ini_get_variable(&sd->save, patches_ptr);
   716 			const void *var = ini_get_variable(&sd->save, patches_ptr);
   613 			bool editable = true;
   717 			bool editable = true;
   614 			bool disabled = false;
   718 			bool disabled = false;
   615 
   719 
   670 
   774 
   671 			btn = y / 11;
   775 			btn = y / 11;
   672 			if (y % 11 > 9) return;
   776 			if (y % 11 > 9) return;
   673 			if (btn >= page->num) return;
   777 			if (btn >= page->num) return;
   674 
   778 
   675 			sd = GetSettingDescription(page->entries[btn]);
   779 			sd = page->entries[btn].setting;
   676 
   780 
   677 			/* return if action is only active in network, or only settable by server */
   781 			/* return if action is only active in network, or only settable by server */
   678 			if ((sd->desc.flags & SGF_NETWORK_ONLY) && !_networking) return;
   782 			if ((sd->desc.flags & SGF_NETWORK_ONLY) && !_networking) return;
   679 			if (!(sd->save.conv & SLF_NETWORK_NO) && _networking && !_network_server) return;
   783 			if (!(sd->save.conv & SLF_NETWORK_NO) && _networking && !_network_server) return;
   680 
   784 
   718 				} break;
   822 				} break;
   719 				default: NOT_REACHED();
   823 				default: NOT_REACHED();
   720 				}
   824 				}
   721 
   825 
   722 				if (value != oldvalue) {
   826 				if (value != oldvalue) {
   723 					SetPatchValue(page->entries[btn], patches_ptr, value);
   827 					SetPatchValue(page->entries[btn].index, patches_ptr, value);
   724 					SetWindowDirty(w);
   828 					SetWindowDirty(w);
   725 					if (sdb->proc != NULL) sdb->proc((int32)ReadValue(var, sd->save.conv));
   829 					if (sdb->proc != NULL) sdb->proc((int32)ReadValue(var, sd->save.conv));
   726 				}
   830 				}
   727 			} else {
   831 			} else {
   728 				/* only open editbox for types that its sensible for */
   832 				/* only open editbox for types that its sensible for */
   751 		SetWindowDirty(w);
   855 		SetWindowDirty(w);
   752 		break;
   856 		break;
   753 
   857 
   754 	case WE_ON_EDIT_TEXT: {
   858 	case WE_ON_EDIT_TEXT: {
   755 		if (e->edittext.str != NULL) {
   859 		if (e->edittext.str != NULL) {
   756 			const uint index = _patches_page[WP(w,def_d).data_1].entries[WP(w,def_d).data_3];
   860 			const PatchEntry *pe = &_patches_page[WP(w,def_d).data_1].entries[WP(w,def_d).data_3];
   757 			const SettingDesc *sd = GetSettingDescription(index);
   861 			const SettingDesc *sd = pe->setting;
   758 			void *var = ini_get_variable(&sd->save, patches_ptr);
   862 			void *var = ini_get_variable(&sd->save, patches_ptr);
   759 			int32 value = atoi(e->edittext.str);
   863 			int32 value = atoi(e->edittext.str);
   760 
   864 
   761 			/* Save the correct currency-translated value */
   865 			/* Save the correct currency-translated value */
   762 			if (sd->desc.flags & SGF_CURRENCY) value /= _currency->rate;
   866 			if (sd->desc.flags & SGF_CURRENCY) value /= _currency->rate;
   763 
   867 
   764 			SetPatchValue(index, patches_ptr, value);
   868 			SetPatchValue(pe->index, patches_ptr, value);
   765 			SetWindowDirty(w);
   869 			SetWindowDirty(w);
   766 
   870 
   767 			if (sd->desc.proc != NULL) sd->desc.proc((int32)ReadValue(var, sd->save.conv));
   871 			if (sd->desc.proc != NULL) sd->desc.proc((int32)ReadValue(var, sd->save.conv));
   768 		}
   872 		}
   769 		break;
   873 		break;