src/settings_gui.cpp
branchNewGRF_ports
changeset 6871 5a9dc001e1ad
parent 6870 ca3fd1fbe311
child 6872 1c4a4a609f85
equal deleted inserted replaced
6870:ca3fd1fbe311 6871:5a9dc001e1ad
   138 	switch (e->event) {
   138 	switch (e->event) {
   139 	case WE_PAINT: {
   139 	case WE_PAINT: {
   140 		int i;
   140 		int i;
   141 		StringID str = STR_02BE_DEFAULT;
   141 		StringID str = STR_02BE_DEFAULT;
   142 
   142 
   143 		SetWindowWidgetDisabledState(w, 21, !(_vehicle_design_names & 1));
   143 		w->SetWidgetDisabledState(21, !(_vehicle_design_names & 1));
   144 		if (!IsWindowWidgetDisabled(w, 21)) str = STR_02BF_CUSTOM;
   144 		if (!w->IsWidgetDisabled(21)) str = STR_02BF_CUSTOM;
   145 		SetDParam(0, str);
   145 		SetDParam(0, str);
   146 		SetDParam(1, _currency_specs[_opt_ptr->currency].name);
   146 		SetDParam(1, _currency_specs[_opt_ptr->currency].name);
   147 		SetDParam(2, STR_UNITS_IMPERIAL + _opt_ptr->units);
   147 		SetDParam(2, STR_UNITS_IMPERIAL + _opt_ptr->units);
   148 		SetDParam(3, STR_02E9_DRIVE_ON_LEFT + _opt_ptr->road_side);
   148 		SetDParam(3, STR_02E9_DRIVE_ON_LEFT + _opt_ptr->road_side);
   149 		SetDParam(4, TownName(_opt_ptr->town_name));
   149 		SetDParam(4, TownName(_opt_ptr->town_name));
   150 		SetDParam(5, _autosave_dropdown[_opt_ptr->autosave]);
   150 		SetDParam(5, _autosave_dropdown[_opt_ptr->autosave]);
   151 		SetDParam(6, SPECSTR_LANGUAGE_START + _dynlang.curr);
   151 		SetDParam(6, SPECSTR_LANGUAGE_START + _dynlang.curr);
   152 		i = GetCurRes();
   152 		i = GetCurRes();
   153 		SetDParam(7, i == _num_resolutions ? STR_RES_OTHER : SPECSTR_RESOLUTION_START + i);
   153 		SetDParam(7, i == _num_resolutions ? STR_RES_OTHER : SPECSTR_RESOLUTION_START + i);
   154 		SetDParam(8, SPECSTR_SCREENSHOT_START + _cur_screenshot_format);
   154 		SetDParam(8, SPECSTR_SCREENSHOT_START + _cur_screenshot_format);
   155 		SetWindowWidgetLoweredState(w, 28, _fullscreen);
   155 		w->SetWidgetLoweredState(28, _fullscreen);
   156 
   156 
   157 		DrawWindowWidgets(w);
   157 		DrawWindowWidgets(w);
   158 		DrawString(20, 175, STR_OPTIONS_FULLSCREEN, 0); // fullscreen
   158 		DrawString(20, 175, STR_OPTIONS_FULLSCREEN, TC_FROMSTRING); // fullscreen
   159 	} break;
   159 	} break;
   160 
   160 
   161 	case WE_CLICK:
   161 	case WE_CLICK:
   162 		switch (e->we.click.widget) {
   162 		switch (e->we.click.widget) {
   163 		case 4: case 5: /* Setup currencies dropdown */
   163 		case 4: case 5: /* Setup currencies dropdown */
   200 			return;
   200 			return;
   201 		case 26: case 27: /* Setup resolution dropdown */
   201 		case 26: case 27: /* Setup resolution dropdown */
   202 			ShowDropDownMenu(w, BuildDynamicDropdown(SPECSTR_RESOLUTION_START, _num_resolutions), GetCurRes(), 27, 0, 0);
   202 			ShowDropDownMenu(w, BuildDynamicDropdown(SPECSTR_RESOLUTION_START, _num_resolutions), GetCurRes(), 27, 0, 0);
   203 			return;
   203 			return;
   204 		case 28: /* Click fullscreen on/off */
   204 		case 28: /* Click fullscreen on/off */
   205 			SetWindowWidgetLoweredState(w, 28, !_fullscreen);
   205 			w->SetWidgetLoweredState(28, !_fullscreen);
   206 			ToggleFullScreen(!_fullscreen); // toggle full-screen on/off
   206 			ToggleFullScreen(!_fullscreen); // toggle full-screen on/off
   207 			SetWindowDirty(w);
   207 			SetWindowDirty(w);
   208 			return;
   208 			return;
   209 		case 30: case 31: /* Setup screenshot format dropdown */
   209 		case 30: case 31: /* Setup screenshot format dropdown */
   210 			ShowDropDownMenu(w, BuildDynamicDropdown(SPECSTR_SCREENSHOT_START, _num_screenshot_formats), _cur_screenshot_format, 31, 0, 0);
   210 			ShowDropDownMenu(w, BuildDynamicDropdown(SPECSTR_SCREENSHOT_START, _num_screenshot_formats), _cur_screenshot_format, 31, 0, 0);
   397  * O: economy (0 = steady, 1 = fluctuating)
   397  * O: economy (0 = steady, 1 = fluctuating)
   398  * P: Train reversing (0 = end of line + stations, 1 = end of line)
   398  * P: Train reversing (0 = end of line + stations, 1 = end of line)
   399  * Q: disasters
   399  * Q: disasters
   400  * R: area restructuring (0 = permissive, 2 = hostile)
   400  * R: area restructuring (0 = permissive, 2 = hostile)
   401  */
   401  */
   402 static const int16 _default_game_diff[3][GAME_DIFFICULTY_NUM] = { /*
   402 static const GDType _default_game_diff[3][GAME_DIFFICULTY_NUM] = { /*
   403 	 A, B, C, D,   E, F, G, H, I, J, K, L, M, N, O, P, Q, R*/
   403 	 A, B, C, D,   E, F, G, H, I, J, K, L, M, N, O, P, Q, R*/
   404 	{2, 2, 1, 4, 300, 2, 0, 2, 0, 1, 2, 0, 1, 0, 0, 0, 0, 0}, ///< easy
   404 	{2, 2, 1, 4, 300, 2, 0, 2, 0, 1, 2, 0, 1, 0, 0, 0, 0, 0}, ///< easy
   405 	{4, 1, 1, 3, 150, 3, 1, 3, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1}, ///< medium
   405 	{4, 1, 1, 3, 150, 3, 1, 3, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1}, ///< medium
   406 	{7, 0, 0, 2, 100, 4, 1, 3, 2, 2, 0, 2, 3, 2, 1, 1, 1, 2}, ///< hard
   406 	{7, 0, 0, 2, 100, 4, 1, 3, 2, 2, 0, 2, 3, 2, 1, 1, 1, 2}, ///< hard
   407 };
   407 };
   412 	assert(mode <= 3);
   412 	assert(mode <= 3);
   413 
   413 
   414 	gm_opt->diff_level = mode;
   414 	gm_opt->diff_level = mode;
   415 	if (mode != 3) { // not custom
   415 	if (mode != 3) { // not custom
   416 		for (i = 0; i != GAME_DIFFICULTY_NUM; i++)
   416 		for (i = 0; i != GAME_DIFFICULTY_NUM; i++)
   417 			((int*)&gm_opt->diff)[i] = _default_game_diff[mode][i];
   417 			((GDType*)&gm_opt->diff)[i] = _default_game_diff[mode][i];
   418 	}
   418 	}
   419 }
   419 }
   420 
   420 
   421 /**
   421 /**
   422  * Checks the difficulty levels read from the configuration and
   422  * Checks the difficulty levels read from the configuration and
   426 {
   426 {
   427 	if (_opt_newgame.diff_level != 3) {
   427 	if (_opt_newgame.diff_level != 3) {
   428 		SetDifficultyLevel(_opt_newgame.diff_level, &_opt_newgame);
   428 		SetDifficultyLevel(_opt_newgame.diff_level, &_opt_newgame);
   429 	} else {
   429 	} else {
   430 		for (uint i = 0; i < GAME_DIFFICULTY_NUM; i++) {
   430 		for (uint i = 0; i < GAME_DIFFICULTY_NUM; i++) {
   431 			int *diff = ((int*)&_opt_newgame.diff) + i;
   431 			GDType *diff = ((GDType*)&_opt_newgame.diff) + i;
   432 			*diff = clamp(*diff, _game_setting_info[i].min, _game_setting_info[i].max);
   432 			*diff = Clamp(*diff, _game_setting_info[i].min, _game_setting_info[i].max);
   433 			*diff -= *diff % _game_setting_info[i].step;
   433 			*diff -= *diff % _game_setting_info[i].step;
   434 		}
   434 		}
   435 	}
   435 	}
   436 }
   436 }
   437 
   437 
   450 static void GameDifficultyWndProc(Window *w, WindowEvent *e)
   450 static void GameDifficultyWndProc(Window *w, WindowEvent *e)
   451 {
   451 {
   452 	switch (e->event) {
   452 	switch (e->event) {
   453 	case WE_CREATE: // Setup disabled buttons when creating window
   453 	case WE_CREATE: // Setup disabled buttons when creating window
   454 		/* disable all other difficulty buttons during gameplay except for 'custom' */
   454 		/* disable all other difficulty buttons during gameplay except for 'custom' */
   455 		SetWindowWidgetDisabledState(w,  3, _game_mode == GM_NORMAL);
   455 		w->SetWidgetDisabledState( 3, _game_mode == GM_NORMAL);
   456 		SetWindowWidgetDisabledState(w,  4, _game_mode == GM_NORMAL);
   456 		w->SetWidgetDisabledState( 4, _game_mode == GM_NORMAL);
   457 		SetWindowWidgetDisabledState(w,  5, _game_mode == GM_NORMAL);
   457 		w->SetWidgetDisabledState( 5, _game_mode == GM_NORMAL);
   458 		SetWindowWidgetDisabledState(w,  6, _game_mode == GM_NORMAL);
   458 		w->SetWidgetDisabledState( 6, _game_mode == GM_NORMAL);
   459 		SetWindowWidgetDisabledState(w,  7, _game_mode == GM_EDITOR || _networking); // highscore chart in multiplayer
   459 		w->SetWidgetDisabledState( 7, _game_mode == GM_EDITOR || _networking); // highscore chart in multiplayer
   460 		SetWindowWidgetDisabledState(w, 10, _networking && !_network_server); // Save-button in multiplayer (and if client)
   460 		w->SetWidgetDisabledState(10, _networking && !_network_server); // Save-button in multiplayer (and if client)
   461 		LowerWindowWidget(w, _opt_mod_temp.diff_level + 3);
   461 		w->LowerWidget(_opt_mod_temp.diff_level + 3);
   462 
   462 
   463 		break;
   463 		break;
   464 	case WE_PAINT: {
   464 	case WE_PAINT: {
   465 		uint32 click_a, click_b, disabled;
   465 		uint32 click_a, click_b, disabled;
   466 		int i;
   466 		int i;
   475 		 * that bit is set. If it is set, the button is disabled */
   475 		 * that bit is set. If it is set, the button is disabled */
   476 		disabled = (_game_mode == GM_NORMAL) ? DIFF_INGAME_DISABLED_BUTTONS : 0;
   476 		disabled = (_game_mode == GM_NORMAL) ? DIFF_INGAME_DISABLED_BUTTONS : 0;
   477 
   477 
   478 		y = GAMEDIFF_WND_TOP_OFFSET;
   478 		y = GAMEDIFF_WND_TOP_OFFSET;
   479 		for (i = 0; i != GAME_DIFFICULTY_NUM; i++) {
   479 		for (i = 0; i != GAME_DIFFICULTY_NUM; i++) {
   480 			DrawFrameRect( 5, y,  5 + 8, y + 8, 3, HASBIT(click_a, i) ? FR_LOWERED : FR_NONE);
   480 			DrawFrameRect( 5, y,  5 + 8, y + 8, 3, HasBit(click_a, i) ? FR_LOWERED : FR_NONE);
   481 			DrawFrameRect(15, y, 15 + 8, y + 8, 3, HASBIT(click_b, i) ? FR_LOWERED : FR_NONE);
   481 			DrawFrameRect(15, y, 15 + 8, y + 8, 3, HasBit(click_b, i) ? FR_LOWERED : FR_NONE);
   482 			if (HASBIT(disabled, i) || (_networking && !_network_server)) {
   482 			if (HasBit(disabled, i) || (_networking && !_network_server)) {
   483 				int color = (1 << PALETTE_MODIFIER_GREYOUT) | _colour_gradient[COLOUR_YELLOW][2];
   483 				int color = (1 << PALETTE_MODIFIER_GREYOUT) | _colour_gradient[COLOUR_YELLOW][2];
   484 				GfxFillRect( 6, y + 1,  6 + 8, y + 8, color);
   484 				GfxFillRect( 6, y + 1,  6 + 8, y + 8, color);
   485 				GfxFillRect(16, y + 1, 16 + 8, y + 8, color);
   485 				GfxFillRect(16, y + 1, 16 + 8, y + 8, color);
   486 			}
   486 			}
   487 
   487 
   488 			DrawStringCentered(10, y, STR_6819, 0);
   488 			DrawStringCentered(10, y, STR_6819, TC_FROMSTRING);
   489 			DrawStringCentered(20, y, STR_681A, 0);
   489 			DrawStringCentered(20, y, STR_681A, TC_FROMSTRING);
   490 
   490 
   491 
   491 
   492 			value = _game_setting_info[i].str + ((int*)&_opt_mod_temp.diff)[i];
   492 			value = _game_setting_info[i].str + ((GDType*)&_opt_mod_temp.diff)[i];
   493 			if (i == 4) value *= 1000; // XXX - handle currency option
   493 			if (i == 4) value *= 1000; // XXX - handle currency option
   494 			SetDParam(0, value);
   494 			SetDParam(0, value);
   495 			DrawString(30, y, STR_6805_MAXIMUM_NO_COMPETITORS + i, 0);
   495 			DrawString(30, y, STR_6805_MAXIMUM_NO_COMPETITORS + i, TC_FROMSTRING);
   496 
   496 
   497 			y += GAMEDIFF_WND_ROWSIZE + 2; // space items apart a bit
   497 			y += GAMEDIFF_WND_ROWSIZE + 2; // space items apart a bit
   498 		}
   498 		}
   499 	} break;
   499 	} break;
   500 
   500 
   509 			/* Don't allow clients to make any changes */
   509 			/* Don't allow clients to make any changes */
   510 			if  (_networking && !_network_server)
   510 			if  (_networking && !_network_server)
   511 				return;
   511 				return;
   512 
   512 
   513 			x = e->we.click.pt.x - 5;
   513 			x = e->we.click.pt.x - 5;
   514 			if (!IS_INT_INSIDE(x, 0, 21)) // Button area
   514 			if (!IsInsideMM(x, 0, 21)) // Button area
   515 				return;
   515 				return;
   516 
   516 
   517 			y = e->we.click.pt.y - GAMEDIFF_WND_TOP_OFFSET;
   517 			y = e->we.click.pt.y - GAMEDIFF_WND_TOP_OFFSET;
   518 			if (y < 0)
   518 			if (y < 0)
   519 				return;
   519 				return;
   524 				return;
   524 				return;
   525 
   525 
   526 			/* Clicked disabled button? */
   526 			/* Clicked disabled button? */
   527 			dis = (_game_mode == GM_NORMAL) ? DIFF_INGAME_DISABLED_BUTTONS : 0;
   527 			dis = (_game_mode == GM_NORMAL) ? DIFF_INGAME_DISABLED_BUTTONS : 0;
   528 
   528 
   529 			if (HASBIT(dis, btn))
   529 			if (HasBit(dis, btn))
   530 				return;
   530 				return;
   531 
   531 
   532 			_difficulty_timeout = 5;
   532 			_difficulty_timeout = 5;
   533 
   533 
   534 			val = ((int*)&_opt_mod_temp.diff)[btn];
   534 			val = ((GDType*)&_opt_mod_temp.diff)[btn];
   535 
   535 
   536 			info = &_game_setting_info[btn]; // get information about the difficulty setting
   536 			info = &_game_setting_info[btn]; // get information about the difficulty setting
   537 			if (x >= 10) {
   537 			if (x >= 10) {
   538 				// Increase button clicked
   538 				// Increase button clicked
   539 				val = min(val + info->step, info->max);
   539 				val = min(val + info->step, info->max);
   540 				SETBIT(_difficulty_click_b, btn);
   540 				SetBit(_difficulty_click_b, btn);
   541 			} else {
   541 			} else {
   542 				// Decrease button clicked
   542 				// Decrease button clicked
   543 				val -= info->step;
   543 				val -= info->step;
   544 				val = max(val,  info->min);
   544 				val = max(val,  info->min);
   545 				SETBIT(_difficulty_click_a, btn);
   545 				SetBit(_difficulty_click_a, btn);
   546 			}
   546 			}
   547 
   547 
   548 			// save value in temporary variable
   548 			// save value in temporary variable
   549 			((int*)&_opt_mod_temp.diff)[btn] = val;
   549 			((GDType*)&_opt_mod_temp.diff)[btn] = val;
   550 			RaiseWindowWidget(w, _opt_mod_temp.diff_level + 3);
   550 			w->RaiseWidget(_opt_mod_temp.diff_level + 3);
   551 			SetDifficultyLevel(3, &_opt_mod_temp); // set difficulty level to custom
   551 			SetDifficultyLevel(3, &_opt_mod_temp); // set difficulty level to custom
   552 			LowerWindowWidget(w, _opt_mod_temp.diff_level + 3);
   552 			w->LowerWidget(_opt_mod_temp.diff_level + 3);
   553 			SetWindowDirty(w);
   553 			SetWindowDirty(w);
   554 		} break;
   554 		} break;
   555 		case 3: case 4: case 5: case 6: /* Easy / Medium / Hard / Custom */
   555 		case 3: case 4: case 5: case 6: /* Easy / Medium / Hard / Custom */
   556 			// temporarily change difficulty level
   556 			// temporarily change difficulty level
   557 			RaiseWindowWidget(w, _opt_mod_temp.diff_level + 3);
   557 			w->RaiseWidget(_opt_mod_temp.diff_level + 3);
   558 			SetDifficultyLevel(e->we.click.widget - 3, &_opt_mod_temp);
   558 			SetDifficultyLevel(e->we.click.widget - 3, &_opt_mod_temp);
   559 			LowerWindowWidget(w, _opt_mod_temp.diff_level + 3);
   559 			w->LowerWidget(_opt_mod_temp.diff_level + 3);
   560 			SetWindowDirty(w);
   560 			SetWindowDirty(w);
   561 			break;
   561 			break;
   562 		case 7: /* Highscore Table */
   562 		case 7: /* Highscore Table */
   563 			ShowHighscoreTable(_opt_mod_temp.diff_level, -1);
   563 			ShowHighscoreTable(_opt_mod_temp.diff_level, -1);
   564 			break;
   564 			break;
   565 		case 10: { /* Save button - save changes */
   565 		case 10: { /* Save button - save changes */
   566 			int btn, val;
   566 			GDType btn, val;
   567 			for (btn = 0; btn != GAME_DIFFICULTY_NUM; btn++) {
   567 			for (btn = 0; btn != GAME_DIFFICULTY_NUM; btn++) {
   568 				val = ((int*)&_opt_mod_temp.diff)[btn];
   568 				val = ((GDType*)&_opt_mod_temp.diff)[btn];
   569 				// if setting has changed, change it
   569 				// if setting has changed, change it
   570 				if (val != ((int*)&_opt_ptr->diff)[btn])
   570 				if (val != ((GDType*)&_opt_ptr->diff)[btn])
   571 					DoCommandP(0, btn, val, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
   571 					DoCommandP(0, btn, val, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
   572 			}
   572 			}
   573 			DoCommandP(0, UINT_MAX, _opt_mod_temp.diff_level, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
   573 			DoCommandP(0, UINT_MAX, _opt_mod_temp.diff_level, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
   574 			DeleteWindow(w);
   574 			DeleteWindow(w);
   575 			// If we are in the editor, we should reload the economy.
   575 			// If we are in the editor, we should reload the economy.
   667 	"autoslope",
   667 	"autoslope",
   668 	"extra_dynamite",
   668 	"extra_dynamite",
   669 	"longbridges",
   669 	"longbridges",
   670 	"signal_side",
   670 	"signal_side",
   671 	"always_small_airport",
   671 	"always_small_airport",
       
   672 	"enable_signal_gui",
   672 	"drag_signals_density",
   673 	"drag_signals_density",
   673 	"oil_refinery_limit",
   674 	"oil_refinery_limit",
   674 	"semaphore_build_before",
   675 	"semaphore_build_before",
   675 };
   676 };
   676 
   677 
   802 					page->entries[i].index = index;
   803 					page->entries[i].index = index;
   803 				}
   804 				}
   804 			}
   805 			}
   805 			first_time = false;
   806 			first_time = false;
   806 		}
   807 		}
   807 		LowerWindowWidget(w, 4);
   808 		w->LowerWidget(4);
   808 	} break;
   809 	} break;
   809 
   810 
   810 	case WE_PAINT: {
   811 	case WE_PAINT: {
   811 		int x, y;
   812 		int x, y;
   812 		const PatchPage *page = &_patches_page[WP(w,def_d).data_1];
   813 		const PatchPage *page = &_patches_page[WP(w,def_d).data_1];
   825 			bool disabled = false;
   826 			bool disabled = false;
   826 
   827 
   827 			// We do not allow changes of some items when we are a client in a networkgame
   828 			// We do not allow changes of some items when we are a client in a networkgame
   828 			if (!(sd->save.conv & SLF_NETWORK_NO) && _networking && !_network_server) editable = false;
   829 			if (!(sd->save.conv & SLF_NETWORK_NO) && _networking && !_network_server) editable = false;
   829 			if ((sdb->flags & SGF_NETWORK_ONLY) && !_networking) editable = false;
   830 			if ((sdb->flags & SGF_NETWORK_ONLY) && !_networking) editable = false;
       
   831 			if ((sdb->flags & SGF_NO_NETWORK) && _networking) editable = false;
   830 
   832 
   831 			if (sdb->cmd == SDT_BOOLX) {
   833 			if (sdb->cmd == SDT_BOOLX) {
   832 				static const int _bool_ctabs[2][2] = {{9, 4}, {7, 6}};
   834 				static const int _bool_ctabs[2][2] = {{9, 4}, {7, 6}};
   833 				/* Draw checkbox for boolean-value either on/off */
   835 				/* Draw checkbox for boolean-value either on/off */
   834 				bool on = (*(bool*)var);
   836 				bool on = (*(bool*)var);
   855 						SetDParam(0, (sdb->flags & SGF_NOCOMMA) ? STR_CONFIG_PATCHES_INT32 : STR_7024);
   857 						SetDParam(0, (sdb->flags & SGF_NOCOMMA) ? STR_CONFIG_PATCHES_INT32 : STR_7024);
   856 					}
   858 					}
   857 					SetDParam(1, value);
   859 					SetDParam(1, value);
   858 				}
   860 				}
   859 			}
   861 			}
   860 			DrawString(30, y, (sdb->str) + disabled, 0);
   862 			DrawString(30, y, (sdb->str) + disabled, TC_FROMSTRING);
   861 			y += 11;
   863 			y += 11;
   862 		}
   864 		}
   863 		break;
   865 		break;
   864 	}
   866 	}
   865 
   867 
   884 			if (btn >= page->num) return;
   886 			if (btn >= page->num) return;
   885 
   887 
   886 			sd = page->entries[btn].setting;
   888 			sd = page->entries[btn].setting;
   887 
   889 
   888 			/* return if action is only active in network, or only settable by server */
   890 			/* return if action is only active in network, or only settable by server */
       
   891 			if (!(sd->save.conv & SLF_NETWORK_NO) && _networking && !_network_server) return;
   889 			if ((sd->desc.flags & SGF_NETWORK_ONLY) && !_networking) return;
   892 			if ((sd->desc.flags & SGF_NETWORK_ONLY) && !_networking) return;
   890 			if (!(sd->save.conv & SLF_NETWORK_NO) && _networking && !_network_server) return;
   893 			if ((sd->desc.flags & SGF_NO_NETWORK) && _networking) return;
   891 
   894 
   892 			var = GetVariableAddress(patches_ptr, &sd->save);
   895 			var = GetVariableAddress(patches_ptr, &sd->save);
   893 			value = (int32)ReadValue(var, sd->save.conv);
   896 			value = (int32)ReadValue(var, sd->save.conv);
   894 
   897 
   895 			/* clicked on the icon on the left side. Either scroller or bool on/off */
   898 			/* clicked on the icon on the left side. Either scroller or bool on/off */
   949 			}
   952 			}
   950 
   953 
   951 			break;
   954 			break;
   952 		}
   955 		}
   953 		case 4: case 5: case 6: case 7: case 8: case 9:
   956 		case 4: case 5: case 6: case 7: case 8: case 9:
   954 			RaiseWindowWidget(w, WP(w, def_d).data_1 + 4);
   957 			w->RaiseWidget(WP(w, def_d).data_1 + 4);
   955 			WP(w, def_d).data_1 = e->we.click.widget - 4;
   958 			WP(w, def_d).data_1 = e->we.click.widget - 4;
   956 			LowerWindowWidget(w, WP(w, def_d).data_1 + 4);
   959 			w->LowerWidget(WP(w, def_d).data_1 + 4);
   957 			DeleteWindowById(WC_QUERY_STRING, 0);
   960 			DeleteWindowById(WC_QUERY_STRING, 0);
   958 			SetWindowDirty(w);
   961 			SetWindowDirty(w);
   959 			break;
   962 			break;
   960 		}
   963 		}
   961 		break;
   964 		break;
  1029 {
  1032 {
  1030 	int color = (1 << PALETTE_MODIFIER_GREYOUT) | _colour_gradient[COLOUR_YELLOW][2];
  1033 	int color = (1 << PALETTE_MODIFIER_GREYOUT) | _colour_gradient[COLOUR_YELLOW][2];
  1031 
  1034 
  1032 	DrawFrameRect(x,      y + 1, x +  9, y + 9, ctab, (state == 1) ? FR_LOWERED : FR_NONE);
  1035 	DrawFrameRect(x,      y + 1, x +  9, y + 9, ctab, (state == 1) ? FR_LOWERED : FR_NONE);
  1033 	DrawFrameRect(x + 10, y + 1, x + 19, y + 9, ctab, (state == 2) ? FR_LOWERED : FR_NONE);
  1036 	DrawFrameRect(x + 10, y + 1, x + 19, y + 9, ctab, (state == 2) ? FR_LOWERED : FR_NONE);
  1034 	DrawStringCentered(x +  5, y + 1, STR_6819, 0); // [<]
  1037 	DrawStringCentered(x +  5, y + 1, STR_6819, TC_FROMSTRING); // [<]
  1035 	DrawStringCentered(x + 15, y + 1, STR_681A, 0); // [>]
  1038 	DrawStringCentered(x + 15, y + 1, STR_681A, TC_FROMSTRING); // [>]
  1036 
  1039 
  1037 	/* Grey out the buttons that aren't clickable */
  1040 	/* Grey out the buttons that aren't clickable */
  1038 	if (!clickable_left)
  1041 	if (!clickable_left)
  1039 		GfxFillRect(x +  1, y + 1, x +  1 + 8, y + 8, color);
  1042 		GfxFillRect(x +  1, y + 1, x +  1 + 8, y + 8, color);
  1040 	if (!clickable_right)
  1043 	if (!clickable_right)
  1054 
  1057 
  1055 			// exchange rate
  1058 			// exchange rate
  1056 			DrawArrowButtons(10, y, 3, GB(clk, 0, 2), true, true);
  1059 			DrawArrowButtons(10, y, 3, GB(clk, 0, 2), true, true);
  1057 			SetDParam(0, 1);
  1060 			SetDParam(0, 1);
  1058 			SetDParam(1, 1);
  1061 			SetDParam(1, 1);
  1059 			DrawString(35, y + 1, STR_CURRENCY_EXCHANGE_RATE, 0);
  1062 			DrawString(35, y + 1, STR_CURRENCY_EXCHANGE_RATE, TC_FROMSTRING);
  1060 			y += 12;
  1063 			y += 12;
  1061 
  1064 
  1062 			// separator
  1065 			// separator
  1063 			DrawFrameRect(10, y + 1, 29, y + 9, 0, GB(clk, 2, 2) ? FR_LOWERED : FR_NONE);
  1066 			DrawFrameRect(10, y + 1, 29, y + 9, 0, GB(clk, 2, 2) ? FR_LOWERED : FR_NONE);
  1064 			x = DrawString(35, y + 1, STR_CURRENCY_SEPARATOR, 0);
  1067 			x = DrawString(35, y + 1, STR_CURRENCY_SEPARATOR, TC_FROMSTRING);
  1065 			DoDrawString(_str_separator, x + 4, y + 1, 6);
  1068 			DoDrawString(_str_separator, x + 4, y + 1, TC_ORANGE);
  1066 			y += 12;
  1069 			y += 12;
  1067 
  1070 
  1068 			// prefix
  1071 			// prefix
  1069 			DrawFrameRect(10, y + 1, 29, y + 9, 0, GB(clk, 4, 2) ? FR_LOWERED : FR_NONE);
  1072 			DrawFrameRect(10, y + 1, 29, y + 9, 0, GB(clk, 4, 2) ? FR_LOWERED : FR_NONE);
  1070 			x = DrawString(35, y + 1, STR_CURRENCY_PREFIX, 0);
  1073 			x = DrawString(35, y + 1, STR_CURRENCY_PREFIX, TC_FROMSTRING);
  1071 			DoDrawString(_custom_currency.prefix, x + 4, y + 1, 6);
  1074 			DoDrawString(_custom_currency.prefix, x + 4, y + 1, TC_ORANGE);
  1072 			y += 12;
  1075 			y += 12;
  1073 
  1076 
  1074 			// suffix
  1077 			// suffix
  1075 			DrawFrameRect(10, y + 1, 29, y + 9, 0, GB(clk, 6, 2) ? FR_LOWERED : FR_NONE);
  1078 			DrawFrameRect(10, y + 1, 29, y + 9, 0, GB(clk, 6, 2) ? FR_LOWERED : FR_NONE);
  1076 			x = DrawString(35, y + 1, STR_CURRENCY_SUFFIX, 0);
  1079 			x = DrawString(35, y + 1, STR_CURRENCY_SUFFIX, TC_FROMSTRING);
  1077 			DoDrawString(_custom_currency.suffix, x + 4, y + 1, 6);
  1080 			DoDrawString(_custom_currency.suffix, x + 4, y + 1, TC_ORANGE);
  1078 			y += 12;
  1081 			y += 12;
  1079 
  1082 
  1080 			// switch to euro
  1083 			// switch to euro
  1081 			DrawArrowButtons(10, y, 3, GB(clk, 8, 2), true, true);
  1084 			DrawArrowButtons(10, y, 3, GB(clk, 8, 2), true, true);
  1082 			SetDParam(0, _custom_currency.to_euro);
  1085 			SetDParam(0, _custom_currency.to_euro);
  1083 			DrawString(35, y + 1, (_custom_currency.to_euro != CF_NOEURO) ? STR_CURRENCY_SWITCH_TO_EURO : STR_CURRENCY_SWITCH_TO_EURO_NEVER, 0);
  1086 			DrawString(35, y + 1, (_custom_currency.to_euro != CF_NOEURO) ? STR_CURRENCY_SWITCH_TO_EURO : STR_CURRENCY_SWITCH_TO_EURO_NEVER, TC_FROMSTRING);
  1084 			y += 12;
  1087 			y += 12;
  1085 
  1088 
  1086 			// Preview
  1089 			// Preview
  1087 			y += 12;
  1090 			y += 12;
  1088 			SetDParam(0, 10000);
  1091 			SetDParam(0, 10000);
  1089 			DrawString(35, y + 1, STR_CURRENCY_PREVIEW, 0);
  1092 			DrawString(35, y + 1, STR_CURRENCY_PREVIEW, TC_FROMSTRING);
  1090 			break;
  1093 			break;
  1091 		}
  1094 		}
  1092 
  1095 
  1093 		case WE_CLICK: {
  1096 		case WE_CLICK: {
  1094 			int line = (e->we.click.pt.y - 20) / 12;
  1097 			int line = (e->we.click.pt.y - 20) / 12;
  1097 			StringID str = 0;
  1100 			StringID str = 0;
  1098 			CharSetFilter afilter = CS_ALPHANUMERAL;
  1101 			CharSetFilter afilter = CS_ALPHANUMERAL;
  1099 
  1102 
  1100 			switch (line) {
  1103 			switch (line) {
  1101 				case 0: // rate
  1104 				case 0: // rate
  1102 					if (IS_INT_INSIDE(x, 10, 30)) { // clicked buttons
  1105 					if (IsInsideMM(x, 10, 30)) { // clicked buttons
  1103 						if (x < 20) {
  1106 						if (x < 20) {
  1104 							if (_custom_currency.rate > 1) _custom_currency.rate--;
  1107 							if (_custom_currency.rate > 1) _custom_currency.rate--;
  1105 							WP(w,def_d).data_1 = 1 << (line * 2 + 0);
  1108 							WP(w,def_d).data_1 = 1 << (line * 2 + 0);
  1106 						} else {
  1109 						} else {
  1107 							if (_custom_currency.rate < 5000) _custom_currency.rate++;
  1110 							if (_custom_currency.rate < 5000) _custom_currency.rate++;
  1114 						afilter = CS_NUMERAL;
  1117 						afilter = CS_NUMERAL;
  1115 					}
  1118 					}
  1116 					break;
  1119 					break;
  1117 
  1120 
  1118 				case 1: // separator
  1121 				case 1: // separator
  1119 					if (IS_INT_INSIDE(x, 10, 30)) { // clicked button
  1122 					if (IsInsideMM(x, 10, 30)) { // clicked button
  1120 						WP(w,def_d).data_1 = 1 << (line * 2 + 1);
  1123 						WP(w,def_d).data_1 = 1 << (line * 2 + 1);
  1121 					}
  1124 					}
  1122 					str = BindCString(_str_separator);
  1125 					str = BindCString(_str_separator);
  1123 					len = 1;
  1126 					len = 1;
  1124 					break;
  1127 					break;
  1125 
  1128 
  1126 				case 2: // prefix
  1129 				case 2: // prefix
  1127 					if (IS_INT_INSIDE(x, 10, 30)) { // clicked button
  1130 					if (IsInsideMM(x, 10, 30)) { // clicked button
  1128 						WP(w,def_d).data_1 = 1 << (line * 2 + 1);
  1131 						WP(w,def_d).data_1 = 1 << (line * 2 + 1);
  1129 					}
  1132 					}
  1130 					str = BindCString(_custom_currency.prefix);
  1133 					str = BindCString(_custom_currency.prefix);
  1131 					len = 12;
  1134 					len = 12;
  1132 					break;
  1135 					break;
  1133 
  1136 
  1134 				case 3: // suffix
  1137 				case 3: // suffix
  1135 					if (IS_INT_INSIDE(x, 10, 30)) { // clicked button
  1138 					if (IsInsideMM(x, 10, 30)) { // clicked button
  1136 						WP(w,def_d).data_1 = 1 << (line * 2 + 1);
  1139 						WP(w,def_d).data_1 = 1 << (line * 2 + 1);
  1137 					}
  1140 					}
  1138 					str = BindCString(_custom_currency.suffix);
  1141 					str = BindCString(_custom_currency.suffix);
  1139 					len = 12;
  1142 					len = 12;
  1140 					break;
  1143 					break;
  1141 
  1144 
  1142 				case 4: // to euro
  1145 				case 4: // to euro
  1143 					if (IS_INT_INSIDE(x, 10, 30)) { // clicked buttons
  1146 					if (IsInsideMM(x, 10, 30)) { // clicked buttons
  1144 						if (x < 20) {
  1147 						if (x < 20) {
  1145 							_custom_currency.to_euro = (_custom_currency.to_euro <= 2000) ?
  1148 							_custom_currency.to_euro = (_custom_currency.to_euro <= 2000) ?
  1146 								CF_NOEURO : _custom_currency.to_euro - 1;
  1149 								CF_NOEURO : _custom_currency.to_euro - 1;
  1147 							WP(w,def_d).data_1 = 1 << (line * 2 + 0);
  1150 							WP(w,def_d).data_1 = 1 << (line * 2 + 0);
  1148 						} else {
  1151 						} else {
  1149 							_custom_currency.to_euro =
  1152 							_custom_currency.to_euro =
  1150 								clamp(_custom_currency.to_euro + 1, 2000, MAX_YEAR);
  1153 								Clamp(_custom_currency.to_euro + 1, 2000, MAX_YEAR);
  1151 							WP(w,def_d).data_1 = 1 << (line * 2 + 1);
  1154 							WP(w,def_d).data_1 = 1 << (line * 2 + 1);
  1152 						}
  1155 						}
  1153 					} else { // enter text
  1156 					} else { // enter text
  1154 						SetDParam(0, _custom_currency.to_euro);
  1157 						SetDParam(0, _custom_currency.to_euro);
  1155 						str = STR_CONFIG_PATCHES_INT32;
  1158 						str = STR_CONFIG_PATCHES_INT32;
  1172 		case WE_ON_EDIT_TEXT: {
  1175 		case WE_ON_EDIT_TEXT: {
  1173 				const char *b = e->we.edittext.str;
  1176 				const char *b = e->we.edittext.str;
  1174 
  1177 
  1175 				switch (WP(w,def_d).data_2) {
  1178 				switch (WP(w,def_d).data_2) {
  1176 					case 0: /* Exchange rate */
  1179 					case 0: /* Exchange rate */
  1177 						_custom_currency.rate = clamp(atoi(b), 1, 5000);
  1180 						_custom_currency.rate = Clamp(atoi(b), 1, 5000);
  1178 						break;
  1181 						break;
  1179 
  1182 
  1180 					case 1: /* Thousands seperator */
  1183 					case 1: /* Thousands seperator */
  1181 						_custom_currency.separator = (b[0] == '\0') ? ' ' : b[0];
  1184 						_custom_currency.separator = (b[0] == '\0') ? ' ' : b[0];
  1182 						ttd_strlcpy(_str_separator, b, lengthof(_str_separator));
  1185 						ttd_strlcpy(_str_separator, b, lengthof(_str_separator));