Changeset - r8319:ed53804bb33f
[Not reviewed]
master
0 1 0
peter1138 - 17 years ago 2008-01-16 23:46:46
peter1138@openttd.org
(svn r11884) -Cleanup: leftover use of widget numbers instead of enum
1 file changed with 2 insertions and 2 deletions:
0 comments (0 inline, 0 general)
src/settings_gui.cpp
Show inline comments
 
/* $Id$ */
 

	
 
/** @file settings_gui.cpp */
 

	
 
#include "stdafx.h"
 
#include "openttd.h"
 
#include "currency.h"
 
#include "gui.h"
 
#include "window_gui.h"
 
#include "textbuf_gui.h"
 
#include "command_func.h"
 
#include "engine.h"
 
#include "screenshot.h"
 
#include "newgrf.h"
 
#include "network/network.h"
 
#include "town.h"
 
#include "variables.h"
 
#include "settings_internal.h"
 
#include "newgrf_townname.h"
 
#include "strings_func.h"
 
#include "functions.h"
 
#include "window_func.h"
 
#include "vehicle_base.h"
 
#include "core/alloc_func.hpp"
 
#include "string_func.h"
 
#include "gfx_func.h"
 
#include "widgets/dropdown_func.h"
 

	
 
#include "table/sprites.h"
 
#include "table/strings.h"
 

	
 
static uint32 _difficulty_click_a;
 
static uint32 _difficulty_click_b;
 
static byte _difficulty_timeout;
 

	
 
static const StringID _units_dropdown[] = {
 
	STR_UNITS_IMPERIAL,
 
	STR_UNITS_METRIC,
 
	STR_UNITS_SI,
 
	INVALID_STRING_ID
 
};
 

	
 
static const StringID _driveside_dropdown[] = {
 
	STR_02E9_DRIVE_ON_LEFT,
 
	STR_02EA_DRIVE_ON_RIGHT,
 
	INVALID_STRING_ID
 
};
 

	
 
static const StringID _autosave_dropdown[] = {
 
	STR_02F7_OFF,
 
	STR_AUTOSAVE_1_MONTH,
 
	STR_02F8_EVERY_3_MONTHS,
 
	STR_02F9_EVERY_6_MONTHS,
 
	STR_02FA_EVERY_12_MONTHS,
 
	INVALID_STRING_ID,
 
};
 

	
 
static const StringID _designnames_dropdown[] = {
 
	STR_02BE_DEFAULT,
 
	STR_02BF_CUSTOM,
 
	INVALID_STRING_ID
 
};
 

	
 
static StringID *BuildDynamicDropdown(StringID base, int num)
 
{
 
	static StringID buf[32 + 1];
 
	StringID *p = buf;
 
	while (--num>=0) *p++ = base++;
 
	*p = INVALID_STRING_ID;
 
	return buf;
 
}
 

	
 
int _nb_orig_names = SPECSTR_TOWNNAME_LAST - SPECSTR_TOWNNAME_START + 1;
 
static StringID *_town_names = NULL;
 
static StringID *_grf_names = NULL;
 
static int _nb_grf_names = 0;
 

	
 
void SortTownGeneratorNames()
 
{
 
	int n = 0;
 

	
 
	/* Get Newgrf generators' names */
 
	free(_grf_names);
 
	_grf_names = GetGRFTownNameList();
 
	_nb_grf_names = 0;
 
	for (StringID *s = _grf_names; *s != INVALID_STRING_ID; s++) _nb_grf_names++;
 

	
 
	/* Prepare the list */
 
	free(_town_names);
 
	_town_names = MallocT<StringID>(_nb_orig_names + _nb_grf_names + 1);
 

	
 
	/* Put the original strings */
 
	for (int i = 0; i < _nb_orig_names; i++) _town_names[n++] = STR_TOWNNAME_ORIGINAL_ENGLISH + i;
 

	
 
	/* Put the grf strings */
 
	for (int i = 0; i < _nb_grf_names; i++) _town_names[n++] = _grf_names[i];
 

	
 
	/* Put the terminator */
 
	_town_names[n] = INVALID_STRING_ID;
 

	
 
	/* Sort the strings */
 
	qsort(&_town_names[0], _nb_orig_names + _nb_grf_names, sizeof(StringID), &StringIDSorter);
 
}
 

	
 
static inline StringID TownName(int town_name)
 
{
 
	if (town_name < _nb_orig_names) return STR_TOWNNAME_ORIGINAL_ENGLISH + town_name;
 
	town_name -= _nb_orig_names;
 
	if (town_name < _nb_grf_names) return _grf_names[town_name];
 
	return STR_UNDEFINED;
 
}
 

	
 
static int GetCurRes()
 
{
 
	int i;
 

	
 
	for (i = 0; i != _num_resolutions; i++) {
 
		if (_resolutions[i][0] == _screen.width &&
 
				_resolutions[i][1] == _screen.height) {
 
			break;
 
		}
 
	}
 
	return i;
 
}
 

	
 
static inline bool RoadVehiclesAreBuilt()
 
{
 
	const Vehicle* v;
 

	
 
	FOR_ALL_VEHICLES(v) {
 
		if (v->type == VEH_ROAD) return true;
 
	}
 
	return false;
 
}
 

	
 

	
 
enum GameOptionsWidgets {
 
	GAMEOPT_CURRENCY_TXT    =  4,
 
	GAMEOPT_CURRENCY_BTN,
 
	GAMEOPT_DISTANCE_TXT    =  7,
 
	GAMEOPT_DISTANCE_BTN,
 
	GAMEOPT_ROADSIDE_TXT    = 10,
 
	GAMEOPT_ROADSIDE_BTN,
 
	GAMEOPT_TOWNNAME_TXT    = 13,
 
	GAMEOPT_TOWNNAME_BTN,
 
	GAMEOPT_AUTOSAVE_TXT    = 16,
 
	GAMEOPT_AUTOSAVE_BTN,
 
	GAMEOPT_VEHICLENAME_TXT = 19,
 
	GAMEOPT_VEHICLENAME_BTN,
 
	GAMEOPT_VEHICLENAME_SAVE,
 
	GAMEOPT_LANG_TXT        = 23,
 
	GAMEOPT_LANG_BTN,
 
	GAMEOPT_RESOLUTION_TXT  = 26,
 
	GAMEOPT_RESOLUTION_BTN,
 
	GAMEOPT_FULLSCREEN,
 
	GAMEOPT_SCREENSHOT_TXT  = 30,
 
	GAMEOPT_SCREENSHOT_BTN,
 
};
 

	
 
static void ShowCustCurrency();
 

	
 
static void GameOptionsWndProc(Window *w, WindowEvent *e)
 
{
 
	switch (e->event) {
 
		case WE_PAINT: {
 
			int i;
 
			StringID str = STR_02BE_DEFAULT;
 

	
 
			w->SetWidgetDisabledState(21, !(_vehicle_design_names & 1));
 
			if (!w->IsWidgetDisabled(21)) str = STR_02BF_CUSTOM;
 
			w->SetWidgetDisabledState(GAMEOPT_VEHICLENAME_SAVE, !(_vehicle_design_names & 1));
 
			if (!w->IsWidgetDisabled(GAMEOPT_VEHICLENAME_SAVE)) str = STR_02BF_CUSTOM;
 
			SetDParam(0, str);
 
			SetDParam(1, _currency_specs[_opt_ptr->currency].name);
 
			SetDParam(2, STR_UNITS_IMPERIAL + _opt_ptr->units);
 
			SetDParam(3, STR_02E9_DRIVE_ON_LEFT + _opt_ptr->road_side);
 
			SetDParam(4, TownName(_opt_ptr->town_name));
 
			SetDParam(5, _autosave_dropdown[_opt_ptr->autosave]);
 
			SetDParam(6, SPECSTR_LANGUAGE_START + _dynlang.curr);
 
			i = GetCurRes();
 
			SetDParam(7, i == _num_resolutions ? STR_RES_OTHER : SPECSTR_RESOLUTION_START + i);
 
			SetDParam(8, SPECSTR_SCREENSHOT_START + _cur_screenshot_format);
 
			w->SetWidgetLoweredState(GAMEOPT_FULLSCREEN, _fullscreen);
 

	
 
			DrawWindowWidgets(w);
 
			DrawString(20, 175, STR_OPTIONS_FULLSCREEN, TC_FROMSTRING); // fullscreen
 
		} break;
 

	
 
		case WE_CLICK:
 
			switch (e->we.click.widget) {
 
				case GAMEOPT_CURRENCY_TXT: case GAMEOPT_CURRENCY_BTN: /* Setup currencies dropdown */
 
					ShowDropDownMenu(w, BuildCurrencyDropdown(), _opt_ptr->currency, GAMEOPT_CURRENCY_BTN, _game_mode == GM_MENU ? 0 : ~GetMaskOfAllowedCurrencies(), 0);
 
					break;
 

	
 
				case GAMEOPT_DISTANCE_TXT: case GAMEOPT_DISTANCE_BTN: /* Setup distance unit dropdown */
 
					ShowDropDownMenu(w, _units_dropdown, _opt_ptr->units, GAMEOPT_DISTANCE_BTN, 0, 0);
 
					break;
 

	
 
				case GAMEOPT_ROADSIDE_TXT: case GAMEOPT_ROADSIDE_BTN: { /* Setup road-side dropdown */
 
					int i = 0;
 

	
 
					/* You can only change the drive side if you are in the menu or ingame with
 
					 * no vehicles present. In a networking game only the server can change it */
 
					if ((_game_mode != GM_MENU && RoadVehiclesAreBuilt()) || (_networking && !_network_server))
 
						i = (-1) ^ (1 << _opt_ptr->road_side); // disable the other value
 

	
 
					ShowDropDownMenu(w, _driveside_dropdown, _opt_ptr->road_side, GAMEOPT_ROADSIDE_BTN, i, 0);
 
				} break;
 

	
 
				case GAMEOPT_TOWNNAME_TXT: case GAMEOPT_TOWNNAME_BTN: { /* Setup townname dropdown */
 
					uint sel = 0;
 
					for (uint i = 0; _town_names[i] != INVALID_STRING_ID; i++) {
 
						if (_town_names[i] == TownName(_opt_ptr->town_name)) {
 
							sel = i;
 
							break;
 
						}
 
					}
 
					ShowDropDownMenu(w, _town_names, sel, GAMEOPT_TOWNNAME_BTN, (_game_mode == GM_MENU) ? 0 : (-1) ^ (1 << sel), 0);
 
				} break;
 

	
 
				case GAMEOPT_AUTOSAVE_TXT: case GAMEOPT_AUTOSAVE_BTN: /* Setup autosave dropdown */
 
					ShowDropDownMenu(w, _autosave_dropdown, _opt_ptr->autosave, GAMEOPT_AUTOSAVE_BTN, 0, 0);
 
					break;
 

	
 
				case GAMEOPT_VEHICLENAME_TXT: case GAMEOPT_VEHICLENAME_BTN: /* Setup customized vehicle-names dropdown */
 
					ShowDropDownMenu(w, _designnames_dropdown, (_vehicle_design_names & 1) ? 1 : 0, GAMEOPT_VEHICLENAME_BTN, (_vehicle_design_names & 2) ? 0 : 2, 0);
 
					break;
 

	
 
				case GAMEOPT_VEHICLENAME_SAVE: /* Save customized vehicle-names to disk */
 
					break;  // not implemented
 

	
 
				case GAMEOPT_LANG_TXT: case GAMEOPT_LANG_BTN: /* Setup interface language dropdown */
 
					ShowDropDownMenu(w, _dynlang.dropdown, _dynlang.curr, GAMEOPT_LANG_BTN, 0, 0);
 
					break;
 

	
 
				case GAMEOPT_RESOLUTION_TXT: case GAMEOPT_RESOLUTION_BTN: /* Setup resolution dropdown */
 
					ShowDropDownMenu(w, BuildDynamicDropdown(SPECSTR_RESOLUTION_START, _num_resolutions), GetCurRes(), GAMEOPT_RESOLUTION_BTN, 0, 0);
 
					break;
 

	
 
				case GAMEOPT_FULLSCREEN: /* Click fullscreen on/off */
 
					/* try to toggle full-screen on/off */
 
					if (!ToggleFullScreen(!_fullscreen)) {
 
						ShowErrorMessage(INVALID_STRING_ID, STR_FULLSCREEN_FAILED, 0, 0);
 
					}
 
					w->SetWidgetLoweredState(GAMEOPT_FULLSCREEN, _fullscreen);
 
					SetWindowDirty(w);
 
					break;
 

	
 
				case GAMEOPT_SCREENSHOT_TXT: case GAMEOPT_SCREENSHOT_BTN: /* Setup screenshot format dropdown */
 
					ShowDropDownMenu(w, BuildDynamicDropdown(SPECSTR_SCREENSHOT_START, _num_screenshot_formats), _cur_screenshot_format, GAMEOPT_SCREENSHOT_BTN, 0, 0);
 
					break;
 
			}
 
			break;
 

	
 
		case WE_DROPDOWN_SELECT:
 
			switch (e->we.dropdown.button) {
 
				case GAMEOPT_VEHICLENAME_BTN: /* Vehicle design names */
 
					if (e->we.dropdown.index == 0) {
 
						DeleteCustomEngineNames();
 
						MarkWholeScreenDirty();
 
					} else if (!(_vehicle_design_names & 1)) {
 
						LoadCustomEngineNames();
 
						MarkWholeScreenDirty();
 
					}
 
					break;
 

	
 
				case GAMEOPT_CURRENCY_BTN: /* Currency */
 
					if (e->we.dropdown.index == CUSTOM_CURRENCY_ID) ShowCustCurrency();
 
					_opt_ptr->currency = e->we.dropdown.index;
 
					MarkWholeScreenDirty();
 
					break;
 

	
 
				case GAMEOPT_DISTANCE_BTN: /* Measuring units */
 
					_opt_ptr->units = e->we.dropdown.index;
 
					MarkWholeScreenDirty();
 
					break;
 

	
 
				case GAMEOPT_ROADSIDE_BTN: /* Road side */
 
					if (_opt_ptr->road_side != e->we.dropdown.index) { // only change if setting changed
 
						DoCommandP(0, e->we.dropdown.index, 0, NULL, CMD_SET_ROAD_DRIVE_SIDE | CMD_MSG(STR_00B4_CAN_T_DO_THIS));
 
						MarkWholeScreenDirty();
 
					}
 
					break;
 

	
 
				case GAMEOPT_TOWNNAME_BTN: /* Town names */
 
					if (_game_mode == GM_MENU) {
 
						for (uint i = 0; _town_names[i] != INVALID_STRING_ID; i++) {
 
							if (_town_names[e->we.dropdown.index] == TownName(i)) {
 
								_opt_ptr->town_name = i;
 
								break;
 
							}
 
						}
 
						InvalidateWindow(WC_GAME_OPTIONS, 0);
 
					}
 
					break;
 

	
 
				case GAMEOPT_AUTOSAVE_BTN: /* Autosave options */
 
					_opt.autosave = _opt_newgame.autosave = e->we.dropdown.index;
 
					SetWindowDirty(w);
 
					break;
 

	
 
				case GAMEOPT_LANG_BTN: /* Change interface language */
 
					ReadLanguagePack(e->we.dropdown.index);
 
					CheckForMissingGlyphsInLoadedLanguagePack();
 
					UpdateAllStationVirtCoord();
 
					MarkWholeScreenDirty();
 
					break;
 

	
 
				case GAMEOPT_RESOLUTION_BTN: /* Change resolution */
 
					if (e->we.dropdown.index < _num_resolutions && ChangeResInGame(_resolutions[e->we.dropdown.index][0],_resolutions[e->we.dropdown.index][1]))
 
						SetWindowDirty(w);
 
					break;
 

	
 
				case GAMEOPT_SCREENSHOT_BTN: /* Change screenshot format */
 
					SetScreenshotFormat(e->we.dropdown.index);
 
					SetWindowDirty(w);
 
					break;
 
			}
 
			break;
 

	
 
		case WE_DESTROY:
 
			DeleteWindowById(WC_CUSTOM_CURRENCY, 0);
 
			break;
 
	}
 

	
 
}
 

	
 
/** Change the side of the road vehicles drive on (server only).
 
 * @param tile unused
 
 * @param flags operation to perform
 
 * @param p1 the side of the road; 0 = left side and 1 = right side
 
 * @param p2 unused
 
 */
 
CommandCost CmdSetRoadDriveSide(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 
{
 
	/* Check boundaries and you can only change this if NO vehicles have been built yet,
 
	 * except in the intro-menu where of course it's always possible to do so. */
 
	if (p1 > 1 || (_game_mode != GM_MENU && RoadVehiclesAreBuilt())) return CMD_ERROR;
 

	
 
	if (flags & DC_EXEC) {
 
		_opt_ptr->road_side = p1;
 
		InvalidateWindow(WC_GAME_OPTIONS,0);
 
	}
 
	return CommandCost();
 
}
 

	
 
static const Widget _game_options_widgets[] = {
 
{   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,                          STR_018B_CLOSE_WINDOW},
 
{    WWT_CAPTION,   RESIZE_NONE,    14,    11,   369,     0,    13, STR_00B1_GAME_OPTIONS,             STR_018C_WINDOW_TITLE_DRAG_THIS},
 
{      WWT_PANEL,   RESIZE_NONE,    14,     0,   369,    14,   238, 0x0,                               STR_NULL},
 
{      WWT_FRAME,   RESIZE_NONE,    14,    10,   179,    20,    55, STR_02E0_CURRENCY_UNITS,           STR_NULL},
 
{      WWT_INSET,   RESIZE_NONE,    14,    20,   169,    34,    45, STR_02E1,                          STR_02E2_CURRENCY_UNITS_SELECTION},
 
{    WWT_TEXTBTN,   RESIZE_NONE,    14,   158,   168,    35,    44, STR_0225,                          STR_02E2_CURRENCY_UNITS_SELECTION},
 
{      WWT_FRAME,   RESIZE_NONE,    14,   190,   359,    20,    55, STR_MEASURING_UNITS,               STR_NULL},
 
{      WWT_INSET,   RESIZE_NONE,    14,   200,   349,    34,    45, STR_02E4,                          STR_MEASURING_UNITS_SELECTION},
 
{    WWT_TEXTBTN,   RESIZE_NONE,    14,   338,   348,    35,    44, STR_0225,                          STR_MEASURING_UNITS_SELECTION},
 
{      WWT_FRAME,   RESIZE_NONE,    14,    10,   179,    62,    97, STR_02E6_ROAD_VEHICLES,            STR_NULL},
 
{      WWT_INSET,   RESIZE_NONE,    14,    20,   169,    76,    87, STR_02E7,                          STR_02E8_SELECT_SIDE_OF_ROAD_FOR},
 
{    WWT_TEXTBTN,   RESIZE_NONE,    14,   158,   168,    77,    86, STR_0225,                          STR_02E8_SELECT_SIDE_OF_ROAD_FOR},
 
{      WWT_FRAME,   RESIZE_NONE,    14,   190,   359,    62,    97, STR_02EB_TOWN_NAMES,               STR_NULL},
 
{      WWT_INSET,   RESIZE_NONE,    14,   200,   349,    76,    87, STR_02EC,                          STR_02ED_SELECT_STYLE_OF_TOWN_NAMES},
 
{    WWT_TEXTBTN,   RESIZE_NONE,    14,   338,   348,    77,    86, STR_0225,                          STR_02ED_SELECT_STYLE_OF_TOWN_NAMES},
 
{      WWT_FRAME,   RESIZE_NONE,    14,    10,   179,   104,   139, STR_02F4_AUTOSAVE,                 STR_NULL},
 
{      WWT_INSET,   RESIZE_NONE,    14,    20,   169,   118,   129, STR_02F5,                          STR_02F6_SELECT_INTERVAL_BETWEEN},
 
{    WWT_TEXTBTN,   RESIZE_NONE,    14,   158,   168,   119,   128, STR_0225,                          STR_02F6_SELECT_INTERVAL_BETWEEN},
 

	
 
{      WWT_FRAME,   RESIZE_NONE,    14,    10,   359,   194,   228, STR_02BC_VEHICLE_DESIGN_NAMES,     STR_NULL},
 
{      WWT_INSET,   RESIZE_NONE,    14,    20,   119,   207,   218, STR_02BD,                          STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION},
 
{    WWT_TEXTBTN,   RESIZE_NONE,    14,   108,   118,   208,   217, STR_0225,                          STR_02C1_VEHICLE_DESIGN_NAMES_SELECTION},
 
{    WWT_TEXTBTN,   RESIZE_NONE,    14,   130,   349,   207,   218, STR_02C0_SAVE_CUSTOM_NAMES,        STR_02C2_SAVE_CUSTOMIZED_VEHICLE},
 

	
 
{      WWT_FRAME,   RESIZE_NONE,    14,   190,   359,   104,   139, STR_OPTIONS_LANG,                  STR_NULL},
 
{      WWT_INSET,   RESIZE_NONE,    14,   200,   349,   118,   129, STR_OPTIONS_LANG_CBO,              STR_OPTIONS_LANG_TIP},
 
{    WWT_TEXTBTN,   RESIZE_NONE,    14,   338,   348,   119,   128, STR_0225,                          STR_OPTIONS_LANG_TIP},
 

	
 
{      WWT_FRAME,   RESIZE_NONE,    14,    10,   179,   146,   190, STR_OPTIONS_RES,                   STR_NULL},
 
{      WWT_INSET,   RESIZE_NONE,    14,    20,   169,   160,   171, STR_OPTIONS_RES_CBO,               STR_OPTIONS_RES_TIP},
 
{    WWT_TEXTBTN,   RESIZE_NONE,    14,   158,   168,   161,   170, STR_0225,                          STR_OPTIONS_RES_TIP},
 
{    WWT_TEXTBTN,   RESIZE_NONE,    14,   149,   169,   176,   184, STR_EMPTY,                         STR_OPTIONS_FULLSCREEN_TIP},
 

	
 
{      WWT_FRAME,   RESIZE_NONE,    14,   190,   359,   146,   190, STR_OPTIONS_SCREENSHOT_FORMAT,     STR_NULL},
 
{      WWT_INSET,   RESIZE_NONE,    14,   200,   349,   160,   171, STR_OPTIONS_SCREENSHOT_FORMAT_CBO, STR_OPTIONS_SCREENSHOT_FORMAT_TIP},
 
{    WWT_TEXTBTN,   RESIZE_NONE,    14,   338,   348,   161,   170, STR_0225,                          STR_OPTIONS_SCREENSHOT_FORMAT_TIP},
 

	
 
{   WIDGETS_END},
 
};
 

	
 
static const WindowDesc _game_options_desc = {
 
	WDP_CENTER, WDP_CENTER, 370, 239, 370, 239,
 
	WC_GAME_OPTIONS, WC_NONE,
 
	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET | WDF_UNCLICK_BUTTONS,
 
	_game_options_widgets,
 
	GameOptionsWndProc
 
};
 

	
 

	
 
void ShowGameOptions()
 
{
 
	DeleteWindowById(WC_GAME_OPTIONS, 0);
 
	AllocateWindowDesc(&_game_options_desc);
 
}
 

	
 
struct GameSettingData {
 
	int16 min;
 
	int16 max;
 
	int16 step;
 
	StringID str;
 
};
 

	
 
static const GameSettingData _game_setting_info[] = {
 
	{  0,   7,  1, STR_NULL},
 
	{  0,   3,  1, STR_6830_IMMEDIATE},
 
	{  0,   3,  1, STR_NUM_VERY_LOW},
 
	{  0,   4,  1, STR_26816_NONE},
 
	{100, 500, 50, STR_NULL},
 
	{  2,   4,  1, STR_NULL},
 
	{  0,   2,  1, STR_6820_LOW},
 
	{  0,   4,  1, STR_681B_VERY_SLOW},
 
	{  0,   2,  1, STR_6820_LOW},
 
	{  0,   2,  1, STR_6823_NONE},
 
	{  0,   3,  1, STR_6826_X1_5},
 
	{  0,   2,  1, STR_6820_LOW},
 
	{  0,   3,  1, STR_682A_VERY_FLAT},
 
	{  0,   3,  1, STR_VERY_LOW},
 
	{  0,   1,  1, STR_682E_STEADY},
 
	{  0,   1,  1, STR_6834_AT_END_OF_LINE_AND_AT_STATIONS},
 
	{  0,   1,  1, STR_6836_OFF},
 
	{  0,   2,  1, STR_6839_PERMISSIVE},
 
};
 

	
 
/*
 
 * A: competitors
 
 * B: start time in months / 3
 
 * C: town count (2 = high, 0 = very low)
 
 * D: industry count (4 = high, 0 = none)
 
 * E: inital loan / 1000 (in GBP)
 
 * F: interest rate
 
 * G: running costs (0 = low, 2 = high)
 
 * H: construction speed of competitors (0 = very slow, 4 = very fast)
 
 * I: intelligence (0-2)
 
 * J: breakdowns (0 = off, 2 = normal)
 
 * K: subsidy multiplier (0 = 1.5, 3 = 4.0)
 
 * L: construction cost (0-2)
 
 * M: terrain type (0 = very flat, 3 = mountainous)
 
 * N: amount of water (0 = very low, 3 = high)
 
 * O: economy (0 = steady, 1 = fluctuating)
 
 * P: Train reversing (0 = end of line + stations, 1 = end of line)
 
 * Q: disasters
 
 * R: area restructuring (0 = permissive, 2 = hostile)
 
 */
 
static const GDType _default_game_diff[3][GAME_DIFFICULTY_NUM] = { /*
 
	 A, B, C, D,   E, F, G, H, I, J, K, L, M, N, O, P, Q, R*/
 
	{2, 2, 1, 4, 300, 2, 0, 2, 0, 1, 2, 0, 1, 0, 0, 0, 0, 0}, ///< easy
 
	{4, 1, 1, 3, 150, 3, 1, 3, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1}, ///< medium
 
	{7, 0, 0, 2, 100, 4, 1, 3, 2, 2, 0, 2, 3, 2, 1, 1, 1, 2}, ///< hard
 
};
 

	
 
void SetDifficultyLevel(int mode, GameOptions *gm_opt)
 
{
 
	int i;
 
	assert(mode <= 3);
 

	
 
	gm_opt->diff_level = mode;
 
	if (mode != 3) { // not custom
 
		for (i = 0; i != GAME_DIFFICULTY_NUM; i++)
 
			((GDType*)&gm_opt->diff)[i] = _default_game_diff[mode][i];
 
	}
 
}
 

	
 
/**
 
 * Checks the difficulty levels read from the configuration and
 
 * forces them to be correct when invalid.
 
 */
 
void CheckDifficultyLevels()
 
{
 
	if (_opt_newgame.diff_level != 3) {
 
		SetDifficultyLevel(_opt_newgame.diff_level, &_opt_newgame);
 
	} else {
 
		for (uint i = 0; i < GAME_DIFFICULTY_NUM; i++) {
 
			GDType *diff = ((GDType*)&_opt_newgame.diff) + i;
 
			*diff = Clamp(*diff, _game_setting_info[i].min, _game_setting_info[i].max);
 
			*diff -= *diff % _game_setting_info[i].step;
 
		}
 
	}
 
}
 

	
 
extern void StartupEconomy();
 

	
 
enum {
 
	GAMEDIFF_WND_TOP_OFFSET = 45,
 
	GAMEDIFF_WND_ROWSIZE    = 9
 
};
 

	
 
/* Temporary holding place of values in the difficulty window until 'Save' is clicked */
 
static GameOptions _opt_mod_temp;
 
// 0x383E = (1 << 13) | (1 << 12) | (1 << 11) | (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1)
 
#define DIFF_INGAME_DISABLED_BUTTONS 0x383E
 

	
 
/* Names of the game difficulty settings window */
 
enum GameDifficultyWidgets {
 
	GDW_CLOSEBOX = 0,
 
	GDW_CAPTION,
 
	GDW_UPPER_BG,
 
	GDW_LVL_EASY,
 
	GDW_LVL_MEDIUM,
 
	GDW_LVL_HARD,
 
	GDW_LVL_CUSTOM,
 
	GDW_HIGHSCORE,
 
	GDW_SETTING_BG,
 
	GDW_LOWER_BG,
 
	GDW_ACCEPT,
 
	GDW_CANCEL,
 
};
 

	
 
static void GameDifficultyWndProc(Window *w, WindowEvent *e)
 
{
 
	switch (e->event) {
 
		case WE_CREATE:
 
			/* Hide the closebox to make sure that the user aborts or confirms his changes */
 
			w->HideWidget(GDW_CLOSEBOX);
 
			w->widget[GDW_CAPTION].left = 0;
 
			/* Setup disabled buttons when creating window
 
			 * disable all other difficulty buttons during gameplay except for 'custom' */
 
			w->SetWidgetsDisabledState(_game_mode == GM_NORMAL,
 
				GDW_LVL_EASY,
 
				GDW_LVL_MEDIUM,
 
				GDW_LVL_HARD,
 
				GDW_LVL_CUSTOM,
 
				WIDGET_LIST_END);
 
			w->SetWidgetDisabledState(GDW_HIGHSCORE, _game_mode == GM_EDITOR || _networking); // highscore chart in multiplayer
 
			w->SetWidgetDisabledState(GDW_ACCEPT, _networking && !_network_server); // Save-button in multiplayer (and if client)
 
			w->LowerWidget(GDW_LVL_EASY + _opt_mod_temp.diff_level);
 
			break;
 

	
 
		case WE_PAINT: {
 
			DrawWindowWidgets(w);
 

	
 
			/* XXX - Disabled buttons in normal gameplay or during muliplayer as non server.
 
			 *       Bitshifted for each button to see if that bit is set. If it is set, the
 
			 *       button is disabled */
 
			uint32 disabled = 0;
 
			if (_networking && !_network_server) {
 
				disabled = MAX_UVALUE(uint32); // Disable all
 
			} else if (_game_mode == GM_NORMAL) {
 
				disabled = DIFF_INGAME_DISABLED_BUTTONS;
 
			}
 

	
 
			int value;
 
			int y = GAMEDIFF_WND_TOP_OFFSET;
 
			for (uint i = 0; i != GAME_DIFFICULTY_NUM; i++) {
 
				const GameSettingData *gsd = &_game_setting_info[i];
 
				value = ((GDType*)&_opt_mod_temp.diff)[i];
 

	
 
				DrawArrowButtons(5, y, 3,
 
						!!HasBit(_difficulty_click_a, i) | !!HasBit(_difficulty_click_b, i) << 1,
 
						!(HasBit(disabled, i) || gsd->min == value),
0 comments (0 inline, 0 general)