settings_gui.c
changeset 1500 a66721629bc0
parent 1477 9389baf2bf3c
child 1501 0fc808b4e375
equal deleted inserted replaced
1499:4d141d000000 1500:a66721629bc0
    77 	return false;
    77 	return false;
    78 }
    78 }
    79 
    79 
    80 static void GameOptionsWndProc(Window *w, WindowEvent *e)
    80 static void GameOptionsWndProc(Window *w, WindowEvent *e)
    81 {
    81 {
    82 	switch(e->event) {
    82 	switch (e->event) {
    83 	case WE_PAINT: {
    83 	case WE_PAINT: {
    84 		int i;
    84 		int i;
    85 		StringID str = STR_02BE_DEFAULT;
    85 		StringID str = STR_02BE_DEFAULT;
    86 		w->disabled_state = (_vehicle_design_names & 1) ? (++str, 0) : (1 << 21);
    86 		w->disabled_state = (_vehicle_design_names & 1) ? (++str, 0) : (1 << 21);
    87 		SetDParam(0, str);
    87 		SetDParam(0, str);
    88 		SetDParam(1, _currency_string_list[_opt_mod_ptr->currency]);
    88 		SetDParam(1, _currency_string_list[_opt_ptr->currency]);
    89 		SetDParam(2, _opt_mod_ptr->kilometers + STR_0139_IMPERIAL_MILES);
    89 		SetDParam(2, _opt_ptr->kilometers + STR_0139_IMPERIAL_MILES);
    90 		SetDParam(3, STR_02E9_DRIVE_ON_LEFT + _opt_mod_ptr->road_side);
    90 		SetDParam(3, STR_02E9_DRIVE_ON_LEFT + _opt_ptr->road_side);
    91 		SetDParam(4, STR_TOWNNAME_ORIGINAL_ENGLISH + _opt_mod_ptr->town_name);
    91 		SetDParam(4, STR_TOWNNAME_ORIGINAL_ENGLISH + _opt_ptr->town_name);
    92 		SetDParam(5, _autosave_dropdown[_opt_mod_ptr->autosave]);
    92 		SetDParam(5, _autosave_dropdown[_opt_ptr->autosave]);
    93 		SetDParam(6, SPECSTR_LANGUAGE_START + _dynlang.curr);
    93 		SetDParam(6, SPECSTR_LANGUAGE_START + _dynlang.curr);
    94 		i = GetCurRes();
    94 		i = GetCurRes();
    95 		SetDParam(7, i == _num_resolutions ? STR_RES_OTHER : SPECSTR_RESOLUTION_START + i);
    95 		SetDParam(7, i == _num_resolutions ? STR_RES_OTHER : SPECSTR_RESOLUTION_START + i);
    96 		SetDParam(8, SPECSTR_SCREENSHOT_START + _cur_screenshot_format);
    96 		SetDParam(8, SPECSTR_SCREENSHOT_START + _cur_screenshot_format);
    97 		(_fullscreen) ? SETBIT(w->click_state, 28) : CLRBIT(w->click_state, 28); // fullscreen button
    97 		(_fullscreen) ? SETBIT(w->click_state, 28) : CLRBIT(w->click_state, 28); // fullscreen button
    99 		DrawWindowWidgets(w);
    99 		DrawWindowWidgets(w);
   100 		DrawString(20, 175, STR_OPTIONS_FULLSCREEN, 0); // fullscreen
   100 		DrawString(20, 175, STR_OPTIONS_FULLSCREEN, 0); // fullscreen
   101 	}	break;
   101 	}	break;
   102 
   102 
   103 	case WE_CLICK:
   103 	case WE_CLICK:
   104 		switch(e->click.widget) {
   104 		switch (e->click.widget) {
   105 		case 5: /* Setup currencies dropdown */
   105 		case 5: /* Setup currencies dropdown */
   106 			ShowDropDownMenu(w, _currency_string_list, _opt_mod_ptr->currency, e->click.widget, _game_mode == GM_MENU ? 0 : ~GetMaskOfAllowedCurrencies(), 0);
   106 			ShowDropDownMenu(w, _currency_string_list, _opt_ptr->currency, e->click.widget, _game_mode == GM_MENU ? 0 : ~GetMaskOfAllowedCurrencies(), 0);
   107 			return;
   107 			return;
   108 		case 8: /* Setup distance unit dropdown */
   108 		case 8: /* Setup distance unit dropdown */
   109 			ShowDropDownMenu(w, _distances_dropdown, _opt_mod_ptr->kilometers, e->click.widget, 0, 0);
   109 			ShowDropDownMenu(w, _distances_dropdown, _opt_ptr->kilometers, e->click.widget, 0, 0);
   110 			return;
   110 			return;
   111 		case 11: { /* Setup road-side dropdown */
   111 		case 11: { /* Setup road-side dropdown */
   112 			int i = 0;
   112 			int i = 0;
   113 
   113 
   114 			/* You can only change the drive side if you are in the menu or ingame with
   114 			/* You can only change the drive side if you are in the menu or ingame with
   115 			 * no vehicles present. In a networking game only the server can change it */
   115 			 * no vehicles present. In a networking game only the server can change it */
   116 			if ((_game_mode != GM_MENU && RoadVehiclesAreBuilt()) || (_networking && !_network_server))
   116 			if ((_game_mode != GM_MENU && RoadVehiclesAreBuilt()) || (_networking && !_network_server))
   117 				i = (-1) ^ (1 << _opt_mod_ptr->road_side); // disable the other value
   117 				i = (-1) ^ (1 << _opt_ptr->road_side); // disable the other value
   118 
   118 
   119 			ShowDropDownMenu(w, _driveside_dropdown, _opt_mod_ptr->road_side, e->click.widget, i, 0);
   119 			ShowDropDownMenu(w, _driveside_dropdown, _opt_ptr->road_side, e->click.widget, i, 0);
   120 		} return;
   120 		} return;
   121 		case 14: { /* Setup townname dropdown */
   121 		case 14: { /* Setup townname dropdown */
   122 			int i = _opt_mod_ptr->town_name;
   122 			int i = _opt_ptr->town_name;
   123 			ShowDropDownMenu(w, BuildDynamicDropdown(STR_TOWNNAME_ORIGINAL_ENGLISH, SPECSTR_TOWNNAME_LAST - SPECSTR_TOWNNAME_START + 1), i, e->click.widget, (_game_mode == GM_MENU) ? 0 : (-1) ^ (1 << i), 0);
   123 			ShowDropDownMenu(w, BuildDynamicDropdown(STR_TOWNNAME_ORIGINAL_ENGLISH, SPECSTR_TOWNNAME_LAST - SPECSTR_TOWNNAME_START + 1), i, e->click.widget, (_game_mode == GM_MENU) ? 0 : (-1) ^ (1 << i), 0);
   124 			return;
   124 			return;
   125 		}
   125 		}
   126 		case 17: /* Setup autosave dropdown */
   126 		case 17: /* Setup autosave dropdown */
   127 			ShowDropDownMenu(w, _autosave_dropdown, _opt_mod_ptr->autosave, e->click.widget, 0, 0);
   127 			ShowDropDownMenu(w, _autosave_dropdown, _opt_ptr->autosave, e->click.widget, 0, 0);
   128 			return;
   128 			return;
   129 		case 20: /* Setup customized vehicle-names dropdown */
   129 		case 20: /* Setup customized vehicle-names dropdown */
   130 			ShowDropDownMenu(w, _designnames_dropdown, (_vehicle_design_names&1)?1:0, e->click.widget, (_vehicle_design_names&2)?0:2, 0);
   130 			ShowDropDownMenu(w, _designnames_dropdown, (_vehicle_design_names&1)?1:0, e->click.widget, (_vehicle_design_names&2)?0:2, 0);
   131 			return;
   131 			return;
   132 		case 21: /* Save customized vehicle-names to disk */
   132 		case 21: /* Save customized vehicle-names to disk */
   147 			return;
   147 			return;
   148 		}
   148 		}
   149 		break;
   149 		break;
   150 
   150 
   151 	case WE_DROPDOWN_SELECT:
   151 	case WE_DROPDOWN_SELECT:
   152 		switch(e->dropdown.button) {
   152 		switch (e->dropdown.button) {
   153 		case 20: /* Vehicle design names */
   153 		case 20: /* Vehicle design names */
   154 			if (e->dropdown.index == 0) {
   154 			if (e->dropdown.index == 0) {
   155 				DeleteCustomEngineNames();
   155 				DeleteCustomEngineNames();
   156 				MarkWholeScreenDirty();
   156 				MarkWholeScreenDirty();
   157 			} else if (!(_vehicle_design_names&1)) {
   157 			} else if (!(_vehicle_design_names & 1)) {
   158 				LoadCustomEngineNames();
   158 				LoadCustomEngineNames();
   159 				MarkWholeScreenDirty();
   159 				MarkWholeScreenDirty();
   160 			}
   160 			}
   161 			break;
   161 			break;
   162 		case 5: /* Currency */
   162 		case 5: /* Currency */
   163 			if (e->dropdown.index == 23)
   163 			if (e->dropdown.index == 23)
   164 				ShowCustCurrency();
   164 				ShowCustCurrency();
   165 			_opt_mod_ptr->currency = _opt.currency = e->dropdown.index;
   165 			_opt_ptr->currency = e->dropdown.index;
   166 			MarkWholeScreenDirty();
   166 			MarkWholeScreenDirty();
   167 			break;
   167 			break;
   168 		case 8: /* Distance units */
   168 		case 8: /* Distance units */
   169 			_opt_mod_ptr->kilometers = e->dropdown.index;
   169 			_opt_ptr->kilometers = e->dropdown.index;
   170 			MarkWholeScreenDirty();
   170 			MarkWholeScreenDirty();
   171 			break;
   171 			break;
   172 		case 11: /* Road side */
   172 		case 11: /* Road side */
   173 			if (_opt_mod_ptr->road_side != e->dropdown.index) { // only change if setting changed
   173 			if (_opt_ptr->road_side != e->dropdown.index) { // only change if setting changed
   174 				DoCommandP(0, e->dropdown.index, 0, NULL, CMD_SET_ROAD_DRIVE_SIDE | CMD_MSG(STR_EMPTY));
   174 				DoCommandP(0, e->dropdown.index, 0, NULL, CMD_SET_ROAD_DRIVE_SIDE | CMD_MSG(STR_EMPTY));
   175 				MarkWholeScreenDirty();
   175 				MarkWholeScreenDirty();
   176 			}
   176 			}
   177 			break;
   177 			break;
   178 		case 14: /* Town names */
   178 		case 14: /* Town names */
   179 			if (_game_mode == GM_MENU)
   179 			if (_game_mode == GM_MENU)
   180 				DoCommandP(0, e->dropdown.index, 0, NULL, CMD_SET_TOWN_NAME_TYPE | CMD_MSG(STR_EMPTY));
   180 				DoCommandP(0, e->dropdown.index, 0, NULL, CMD_SET_TOWN_NAME_TYPE | CMD_MSG(STR_EMPTY));
   181 			break;
   181 			break;
   182 		case 17: /* Autosave options */
   182 		case 17: /* Autosave options */
   183 			_opt_mod_ptr->autosave = e->dropdown.index;
   183 			_opt_ptr->autosave = e->dropdown.index;
   184 			SetWindowDirty(w);
   184 			SetWindowDirty(w);
   185 			break;
   185 			break;
   186 		case 24: /* Change interface language */
   186 		case 24: /* Change interface language */
   187 			ReadLanguagePack(e->dropdown.index);
   187 			ReadLanguagePack(e->dropdown.index);
   188 			MarkWholeScreenDirty();
   188 			MarkWholeScreenDirty();
   206 }
   206 }
   207 
   207 
   208 int32 CmdSetRoadDriveSide(int x, int y, uint32 flags, uint32 p1, uint32 p2)
   208 int32 CmdSetRoadDriveSide(int x, int y, uint32 flags, uint32 p1, uint32 p2)
   209 {
   209 {
   210 	if (flags & DC_EXEC) {
   210 	if (flags & DC_EXEC) {
   211 		_opt_mod_ptr->road_side = p1;
   211 		_opt_ptr->road_side = p1;
   212 		InvalidateWindow(WC_GAME_OPTIONS,0);
   212 		InvalidateWindow(WC_GAME_OPTIONS,0);
   213 	}
   213 	}
   214 	return 0;
   214 	return 0;
   215 }
   215 }
   216 
   216 
   217 int32 CmdSetTownNameType(int x, int y, uint32 flags, uint32 p1, uint32 p2)
   217 int32 CmdSetTownNameType(int x, int y, uint32 flags, uint32 p1, uint32 p2)
   218 {
   218 {
   219 	if (flags & DC_EXEC) {
   219 	if (flags & DC_EXEC) {
   220 		_opt_mod_ptr->town_name = p1;
   220 		_opt_ptr->town_name = p1;
   221 		InvalidateWindow(WC_GAME_OPTIONS,0);
   221 		InvalidateWindow(WC_GAME_OPTIONS,0);
   222 	}
   222 	}
   223 	return 0;
   223 	return 0;
   224 }
   224 }
   225 
   225 
   286 	int16 step;
   286 	int16 step;
   287 	StringID str;
   287 	StringID str;
   288 } GameSettingData;
   288 } GameSettingData;
   289 
   289 
   290 static const GameSettingData _game_setting_info[] = {
   290 static const GameSettingData _game_setting_info[] = {
   291 	{0,7,1,0},
   291 	{  0,   7,  1, STR_NULL},
   292 	{0,3,1,STR_6830_IMMEDIATE},
   292 	{  0,   3,  1, STR_6830_IMMEDIATE},
   293 	{0,2,1,STR_6816_LOW},
   293 	{  0,   2,  1, STR_6816_LOW},
   294 	{0,3,1,STR_26816_NONE},
   294 	{  0,   3,  1, STR_26816_NONE},
   295 	{100,500,50,0},
   295 	{100, 500, 50, STR_NULL},
   296 	{2,4,1,0},
   296 	{  2,   4,  1, STR_NULL},
   297 	{0,2,1,STR_6820_LOW},
   297 	{  0,   2,  1, STR_6820_LOW},
   298 	{0,4,1,STR_681B_VERY_SLOW},
   298 	{  0,   4,  1, STR_681B_VERY_SLOW},
   299 	{0,2,1,STR_6820_LOW},
   299 	{  0,   2,  1, STR_6820_LOW},
   300 	{0,2,1,STR_6823_NONE},
   300 	{  0,   2,  1, STR_6823_NONE},
   301 	{0,3,1,STR_6826_X1_5},
   301 	{  0,   3,  1, STR_6826_X1_5},
   302 	{0,2,1,STR_6820_LOW},
   302 	{  0,   2,  1, STR_6820_LOW},
   303 	{0,3,1,STR_682A_VERY_FLAT},
   303 	{  0,   3,  1, STR_682A_VERY_FLAT},
   304 	{0,3,1,STR_VERY_LOW},
   304 	{  0,   3,  1, STR_VERY_LOW},
   305 	{0,1,1,STR_682E_STEADY},
   305 	{  0,   1,  1, STR_682E_STEADY},
   306 	{0,1,1,STR_6834_AT_END_OF_LINE_AND_AT_STATIONS},
   306 	{  0,   1,  1, STR_6834_AT_END_OF_LINE_AND_AT_STATIONS},
   307 	{0,1,1,STR_6836_OFF},
   307 	{  0,   1,  1, STR_6836_OFF},
   308 	{0,2,1,STR_6839_PERMISSIVE},
   308 	{  0,   2,  1, STR_6839_PERMISSIVE},
   309 };
   309 };
   310 
   310 
   311 static inline bool GetBitAndShift(uint32 *b)
   311 static inline bool GetBitAndShift(uint32 *b)
   312 {
   312 {
   313 	uint32 x = *b;
   313 	uint32 x = *b;
   314 	*b >>= 1;
   314 	*b >>= 1;
   315 	return (x&1) != 0;
   315 	return HASBIT(x, 0);
   316 }
   316 }
   317 
   317 
   318 /*
   318 /*
   319 	A: competitors
   319 	A: competitors
   320 	B: start time in months / 3
   320 	B: start time in months / 3
   347 	int i;
   347 	int i;
   348 	assert(mode <= 3);
   348 	assert(mode <= 3);
   349 
   349 
   350 	gm_opt->diff_level = mode;
   350 	gm_opt->diff_level = mode;
   351 	if (mode != 3) { // not custom
   351 	if (mode != 3) { // not custom
   352 		for(i = 0; i != GAME_DIFFICULTY_NUM; i++)
   352 		for (i = 0; i != GAME_DIFFICULTY_NUM; i++)
   353 			((int*)&gm_opt->diff)[i] = _default_game_diff[mode][i];
   353 			((int*)&gm_opt->diff)[i] = _default_game_diff[mode][i];
   354 	}
   354 	}
   355 }
   355 }
   356 
   356 
   357 extern void StartupEconomy(void);
   357 extern void StartupEconomy(void);
   359 enum {
   359 enum {
   360 	GAMEDIFF_WND_TOP_OFFSET = 45,
   360 	GAMEDIFF_WND_TOP_OFFSET = 45,
   361 	GAMEDIFF_WND_ROWSIZE    = 9
   361 	GAMEDIFF_WND_ROWSIZE    = 9
   362 };
   362 };
   363 
   363 
       
   364 // Temporary holding place of values in the difficulty window until 'Save' is clicked
       
   365 static GameOptions _opt_mod_temp;
       
   366 // 0x383E = (1 << 13) | (1 << 12) | (1 << 11) | (1 << 5) | (1 << 4) | (1 << 3) | (1 << 2) | (1 << 1)
       
   367 #define DIFF_INGAME_DISABLED_BUTTONS 0x383E
       
   368 
   364 static void GameDifficultyWndProc(Window *w, WindowEvent *e)
   369 static void GameDifficultyWndProc(Window *w, WindowEvent *e)
   365 {
   370 {
   366 	switch(e->event) {
   371 	switch (e->event) {
   367 	case WE_PAINT: {
   372 	case WE_PAINT: {
   368 		uint32 click_a, click_b, disabled;
   373 		uint32 click_a, click_b, disabled;
   369 		int i;
   374 		int i;
   370 		int x,y,value;
   375 		int y, value;
   371 
   376 
   372 		w->click_state = (1 << 3) << _opt_mod_temp.diff_level;
   377 		w->click_state = (1 << 3) << _opt_mod_temp.diff_level; // have current difficulty button clicked
       
   378 		// disable all other difficulty buttons during gameplay except for 'custom'
   373 		w->disabled_state = (_game_mode != GM_NORMAL) ? 0 : (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
   379 		w->disabled_state = (_game_mode != GM_NORMAL) ? 0 : (1 << 3) | (1 << 4) | (1 << 5) | (1 << 6);
   374 
   380 
   375 		if (_game_mode == GM_EDITOR)
   381 		if (_game_mode == GM_EDITOR)
   376 			SETBIT(w->disabled_state, 7);
   382 			SETBIT(w->disabled_state, 7);
   377 
   383 
   384 		DrawWindowWidgets(w);
   390 		DrawWindowWidgets(w);
   385 
   391 
   386 		click_a = _difficulty_click_a;
   392 		click_a = _difficulty_click_a;
   387 		click_b = _difficulty_click_b;
   393 		click_b = _difficulty_click_b;
   388 
   394 
   389 		/* XXX - This is most likely the worst way I have ever seen
   395 		/* XXX - Disabled buttons in normal gameplay. Bitshifted for each button to see if
   390 		     to disable some buttons and to enable others.
   396 		 * that bit is set. If it is set, the button is disabled */
   391 		     What the value means, is this:
   397 		disabled = (_game_mode == GM_NORMAL) ? DIFF_INGAME_DISABLED_BUTTONS : 0;
   392 		       if bit1 is enabled, setting 1 is disabled
   398 
   393 		       then it is shifted to the left, and the story
       
   394 		       repeats....
       
   395 		   -- TrueLight */
       
   396 		disabled = _game_mode == GM_NORMAL ? 0x383E : 0;
       
   397 
       
   398 		x = 0;
       
   399 		y = GAMEDIFF_WND_TOP_OFFSET;
   399 		y = GAMEDIFF_WND_TOP_OFFSET;
   400 		for (i = 0; i != GAME_DIFFICULTY_NUM; i++) {
   400 		for (i = 0; i != GAME_DIFFICULTY_NUM; i++) {
   401 			DrawFrameRect(x+5, y, x+5+8, y+8, 3, GetBitAndShift(&click_a)?0x20:0);
   401 			DrawFrameRect( 5, y,  5 + 8, y + 8, 3, GetBitAndShift(&click_a) ? (1 << 5) : 0);
   402 			DrawFrameRect(x+15, y, x+15+8, y+8, 3, GetBitAndShift(&click_b)?0x20:0);
   402 			DrawFrameRect(15, y, 15 + 8, y + 8, 3, GetBitAndShift(&click_b) ? (1 << 5) : 0);
   403 			if (GetBitAndShift(&disabled) || (_networking && !_network_server)) {
   403 			if (GetBitAndShift(&disabled) || (_networking && !_network_server)) {
   404 				int color = 0x8000 | _color_list[3].unk2;
   404 				int color = PALETTE_MODIFIER_COLOR | _color_list[3].unk2;
   405 				GfxFillRect(x+6, y+1, x+6+8, y+8, color);
   405 				GfxFillRect( 6, y + 1,  6 + 8, y + 8, color);
   406 				GfxFillRect(x+16, y+1, x+16+8, y+8, color);
   406 				GfxFillRect(16, y + 1, 16 + 8, y + 8, color);
   407 			}
   407 			}
   408 
   408 
   409 			DrawStringCentered(x+10, y, STR_6819, 0);
   409 			DrawStringCentered(10, y, STR_6819, 0);
   410 			DrawStringCentered(x+20, y, STR_681A, 0);
   410 			DrawStringCentered(20, y, STR_681A, 0);
   411 
   411 
   412 
   412 
   413 			value = _game_setting_info[i].str + ((int*)&_opt_mod_temp.diff)[i];
   413 			value = _game_setting_info[i].str + ((int*)&_opt_mod_temp.diff)[i];
   414 			if (i == 4) value *= 1000; // handle currency option
   414 			if (i == 4) value *= 1000; // XXX - handle currency option
   415 			SetDParam(0, value);
   415 			SetDParam(0, value);
   416 			DrawString(x+30, y, STR_6805_MAXIMUM_NO_COMPETITORS + i, 0);
   416 			DrawString(30, y, STR_6805_MAXIMUM_NO_COMPETITORS + i, 0);
   417 
   417 
   418 			y += GAMEDIFF_WND_ROWSIZE + 2; // space items apart a bit
   418 			y += GAMEDIFF_WND_ROWSIZE + 2; // space items apart a bit
   419 		}
   419 		}
   420 	} break;
   420 	} break;
   421 
   421 
   422 	case WE_CLICK:
   422 	case WE_CLICK:
   423 		switch(e->click.widget) {
   423 		switch (e->click.widget) {
   424 		case 8: {
   424 		case 8: { /* Difficulty settings widget, decode click */
   425 			int x,y;
   425 			const GameSettingData *info;
       
   426 			int x, y;
   426 			uint btn, dis;
   427 			uint btn, dis;
   427 			int val;
   428 			int val;
   428 			const GameSettingData *info;
       
   429 
   429 
   430 			// Don't allow clients to make any changes
   430 			// Don't allow clients to make any changes
   431 			if  (_networking && !_network_server)
   431 			if  (_networking && !_network_server)
   432 				return;
   432 				return;
   433 
   433 
   434 			x = e->click.pt.x - 5;
   434 			x = e->click.pt.x - 5;
   435 			if (!IS_INT_INSIDE(x, 0, 21))
   435 			if (!IS_INT_INSIDE(x, 0, 21)) // Button area
   436 				return;
   436 				return;
   437 
   437 
   438 			y = e->click.pt.y - GAMEDIFF_WND_TOP_OFFSET;
   438 			y = e->click.pt.y - GAMEDIFF_WND_TOP_OFFSET;
   439 			if (y < 0)
   439 			if (y < 0)
   440 				return;
   440 				return;
   443 			btn = y / (GAMEDIFF_WND_ROWSIZE + 2);
   443 			btn = y / (GAMEDIFF_WND_ROWSIZE + 2);
   444 			if (btn >= GAME_DIFFICULTY_NUM || y % (GAMEDIFF_WND_ROWSIZE + 2) >= 9)
   444 			if (btn >= GAME_DIFFICULTY_NUM || y % (GAMEDIFF_WND_ROWSIZE + 2) >= 9)
   445 				return;
   445 				return;
   446 
   446 
   447 			// Clicked disabled button?
   447 			// Clicked disabled button?
   448 			dis = (_game_mode == GM_NORMAL) ? 0x383E : 0;
   448 			dis = (_game_mode == GM_NORMAL) ? DIFF_INGAME_DISABLED_BUTTONS : 0;
   449 
   449 
   450 			if (HASBIT(dis, btn))
   450 			if (HASBIT(dis, btn))
   451 				return;
   451 				return;
   452 
   452 
   453 			_difficulty_timeout = 5;
   453 			_difficulty_timeout = 5;
   454 
   454 
   455 			val = ((int*)&_opt_mod_temp.diff)[btn];
   455 			val = ((int*)&_opt_mod_temp.diff)[btn];
   456 
   456 
   457 			info = &_game_setting_info[btn];
   457 			info = &_game_setting_info[btn]; // get information about the difficulty setting
   458 			if (x >= 10) {
   458 			if (x >= 10) {
   459 				// Increase button clicked
   459 				// Increase button clicked
   460 				val = min(val + info->step, info->max);
   460 				val = min(val + info->step, info->max);
   461 				SETBIT(_difficulty_click_b, btn);
   461 				SETBIT(_difficulty_click_b, btn);
   462 			} else {
   462 			} else {
   467 
   467 
   468 			// save value in temporary variable
   468 			// save value in temporary variable
   469 			((int*)&_opt_mod_temp.diff)[btn] = val;
   469 			((int*)&_opt_mod_temp.diff)[btn] = val;
   470 			SetDifficultyLevel(3, &_opt_mod_temp); // set difficulty level to custom
   470 			SetDifficultyLevel(3, &_opt_mod_temp); // set difficulty level to custom
   471 			SetWindowDirty(w);
   471 			SetWindowDirty(w);
   472 			break;
   472 		}	break;
   473 		}
       
   474 		case 3: case 4: case 5: case 6: /* Easy / Medium / Hard / Custom */
   473 		case 3: case 4: case 5: case 6: /* Easy / Medium / Hard / Custom */
   475 			// temporarily change difficulty level
   474 			// temporarily change difficulty level
   476 			SetDifficultyLevel(e->click.widget - 3, &_opt_mod_temp);
   475 			SetDifficultyLevel(e->click.widget - 3, &_opt_mod_temp);
   477 			SetWindowDirty(w);
   476 			SetWindowDirty(w);
   478 			break;
   477 			break;
   482 		case 10: { /* Save button - save changes */
   481 		case 10: { /* Save button - save changes */
   483 			int btn, val;
   482 			int btn, val;
   484 			for (btn = 0; btn != GAME_DIFFICULTY_NUM; btn++) {
   483 			for (btn = 0; btn != GAME_DIFFICULTY_NUM; btn++) {
   485 				val = ((int*)&_opt_mod_temp.diff)[btn];
   484 				val = ((int*)&_opt_mod_temp.diff)[btn];
   486 				// if setting has changed, change it
   485 				// if setting has changed, change it
   487 				if (val != ((int*)&_opt_mod_ptr->diff)[btn])
   486 				if (val != ((int*)&_opt_mod_temp.diff)[btn])
   488 					DoCommandP(0, btn, val, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
   487 					DoCommandP(0, btn, val, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
   489 			}
   488 			}
   490 			DoCommandP(0, -1, _opt_mod_temp.diff_level, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
   489 			DoCommandP(0, -1, _opt_mod_temp.diff_level, NULL, CMD_CHANGE_DIFFICULTY_LEVEL);
   491 			DeleteWindow(w);
   490 			DeleteWindow(w);
   492 			// If we are in the editor, we should reload the economy.
   491 			// If we are in the editor, we should reload the economy.
   494 			//  are loaded correctly.
   493 			//  are loaded correctly.
   495 			if (_game_mode == GM_EDITOR)
   494 			if (_game_mode == GM_EDITOR)
   496 				StartupEconomy();
   495 				StartupEconomy();
   497 			break;
   496 			break;
   498 		}
   497 		}
   499 		case 11: // Cancel button - close window
   498 		case 11: /* Cancel button - close window, abandon changes */
   500 			DeleteWindow(w);
   499 			DeleteWindow(w);
   501 			break;
   500 			break;
   502 		}
   501 	} break;
   503 		break;
   502 
   504 
   503 	case WE_MOUSELOOP: /* Handle the visual 'clicking' of the buttons */
   505 	case WE_MOUSELOOP:
       
   506 		if (_difficulty_timeout != 0 && !--_difficulty_timeout) {
   504 		if (_difficulty_timeout != 0 && !--_difficulty_timeout) {
   507 			_difficulty_click_a = 0;
   505 			_difficulty_click_a = 0;
   508 			_difficulty_click_b = 0;
   506 			_difficulty_click_b = 0;
   509 			SetWindowDirty(w);
   507 			SetWindowDirty(w);
   510 		}
   508 		}
   511 		break;
   509 		break;
   512 	}
   510 	}
   513 }
   511 }
       
   512 
       
   513 #undef DIFF_INGAME_DISABLED_BUTTONS
   514 
   514 
   515 static const Widget _game_difficulty_widgets[] = {
   515 static const Widget _game_difficulty_widgets[] = {
   516 {   WWT_CLOSEBOX,   RESIZE_NONE,    10,     0,    10,     0,    13, STR_00C5,									STR_018B_CLOSE_WINDOW},
   516 {   WWT_CLOSEBOX,   RESIZE_NONE,    10,     0,    10,     0,    13, STR_00C5,									STR_018B_CLOSE_WINDOW},
   517 {    WWT_CAPTION,   RESIZE_NONE,    10,    11,   369,     0,    13, STR_6800_DIFFICULTY_LEVEL,	STR_018C_WINDOW_TITLE_DRAG_THIS},
   517 {    WWT_CAPTION,   RESIZE_NONE,    10,    11,   369,     0,    13, STR_6800_DIFFICULTY_LEVEL,	STR_018C_WINDOW_TITLE_DRAG_THIS},
   518 {      WWT_PANEL,   RESIZE_NONE,    10,     0,   369,    14,    29, 0x0,												STR_NULL},
   518 {      WWT_PANEL,   RESIZE_NONE,    10,     0,   369,    14,    29, 0x0,												STR_NULL},
   537 };
   537 };
   538 
   538 
   539 void ShowGameDifficulty(void)
   539 void ShowGameDifficulty(void)
   540 {
   540 {
   541 	DeleteWindowById(WC_GAME_OPTIONS, 0);
   541 	DeleteWindowById(WC_GAME_OPTIONS, 0);
   542 	/*	copy current settings to temporary holding place
   542 	/* Copy current settings (ingame or in intro) to temporary holding place
   543 	 *	change that when setting stuff, copy back on clicking 'OK'
   543 	 * change that when setting stuff, copy back on clicking 'OK' */
   544 	 */
   544 	memcpy(&_opt_mod_temp, _opt_ptr, sizeof(GameOptions));
   545 	memcpy(&_opt_mod_temp, _opt_mod_ptr, sizeof(GameOptions));
       
   546 	AllocateWindowDesc(&_game_difficulty_desc);
   545 	AllocateWindowDesc(&_game_difficulty_desc);
   547 }
   546 }
   548 
   547 
   549 // virtual PositionMainToolbar function, calls the right one.
   548 // virtual PositionMainToolbar function, calls the right one.
   550 static int32 v_PositionMainToolbar(int32 p1)
   549 static int32 v_PositionMainToolbar(int32 p1)