src/main_gui.cpp
changeset 6527 f584ab6d87f8
parent 6145 d34703513ed0
child 6557 8381016f71f3
child 9895 7bd07f43b0e3
equal deleted inserted replaced
6526:85cfa44803d0 6527:f584ab6d87f8
     1 /* $Id$ */
     1 /* $Id$ */
       
     2 
       
     3 /** @file main_gui.cpp */
     2 
     4 
     3 #include "stdafx.h"
     5 #include "stdafx.h"
     4 #include "openttd.h"
     6 #include "openttd.h"
     5 #include "heightmap.h"
     7 #include "heightmap.h"
     6 #include "currency.h"
     8 #include "currency.h"
    58 {
    60 {
    59 	int id = _rename_id;
    61 	int id = _rename_id;
    60 	_cmd_text = str;
    62 	_cmd_text = str;
    61 
    63 
    62 	switch (_rename_what) {
    64 	switch (_rename_what) {
    63 	case 0: /* Rename a s sign, if string is empty, delete sign */
    65 	case 0: // Rename a s sign, if string is empty, delete sign
    64 		DoCommandP(0, id, 0, NULL, CMD_RENAME_SIGN | CMD_MSG(STR_280C_CAN_T_CHANGE_SIGN_NAME));
    66 		DoCommandP(0, id, 0, NULL, CMD_RENAME_SIGN | CMD_MSG(STR_280C_CAN_T_CHANGE_SIGN_NAME));
    65 		break;
    67 		break;
    66 	case 1: /* Rename a waypoint */
    68 	case 1: // Rename a waypoint
    67 		if (*str == '\0') return;
    69 		if (*str == '\0') return;
    68 		DoCommandP(0, id, 0, NULL, CMD_RENAME_WAYPOINT | CMD_MSG(STR_CANT_CHANGE_WAYPOINT_NAME));
    70 		DoCommandP(0, id, 0, NULL, CMD_RENAME_WAYPOINT | CMD_MSG(STR_CANT_CHANGE_WAYPOINT_NAME));
    69 		break;
    71 		break;
    70 #ifdef ENABLE_NETWORK
    72 #ifdef ENABLE_NETWORK
    71 	case 3: { /* Give money, you can only give money in excess of loan */
    73 	case 3: { // Give money, you can only give money in excess of loan
    72 		const Player *p = GetPlayer(_current_player);
    74 		const Player *p = GetPlayer(_current_player);
    73 		int32 money = min(p->money64 - p->current_loan, atoi(str) / _currency->rate);
    75 		int32 money = min(p->money64 - p->current_loan, atoi(str) / _currency->rate);
    74 		char msg[20];
    76 		char msg[20];
    75 
    77 
    76 		money = clamp(money, 0, 20000000); // Clamp between 20 million and 0
    78 		money = clamp(money, 0, 20000000); // Clamp between 20 million and 0
    77 
    79 
    78 		// Give 'id' the money, and substract it from ourself
    80 		/* Give 'id' the money, and substract it from ourself */
    79 		if (!DoCommandP(0, money, id, NULL, CMD_GIVE_MONEY | CMD_MSG(STR_INSUFFICIENT_FUNDS))) break;
    81 		if (!DoCommandP(0, money, id, NULL, CMD_GIVE_MONEY | CMD_MSG(STR_INSUFFICIENT_FUNDS))) break;
    80 
    82 
    81 		// Inform the player of this action
    83 		/* Inform the player of this action */
    82 		snprintf(msg, sizeof(msg), "%d", money);
    84 		snprintf(msg, sizeof(msg), "%d", money);
    83 
    85 
    84 		if (!_network_server) {
    86 		if (!_network_server) {
    85 			SEND_COMMAND(PACKET_CLIENT_CHAT)(NETWORK_ACTION_GIVE_MONEY, DESTTYPE_TEAM, id, msg);
    87 			SEND_COMMAND(PACKET_CLIENT_CHAT)(NETWORK_ACTION_GIVE_MONEY, DESTTYPE_TEAM, id, msg);
    86 		} else {
    88 		} else {
   101  * @param w Window which called the function
   103  * @param w Window which called the function
   102  * @param widget ID of the widget (=button) that called this function
   104  * @param widget ID of the widget (=button) that called this function
   103  * @param cursor How should the cursor image change? E.g. cursor with depot image in it
   105  * @param cursor How should the cursor image change? E.g. cursor with depot image in it
   104  * @param mode Tile highlighting mode, e.g. drawing a rectangle or a dot on the ground
   106  * @param mode Tile highlighting mode, e.g. drawing a rectangle or a dot on the ground
   105  * @param placeproc Procedure which will be called when someone clicks on the map
   107  * @param placeproc Procedure which will be called when someone clicks on the map
   106 
       
   107  * @return true if the button is clicked, false if it's unclicked
   108  * @return true if the button is clicked, false if it's unclicked
   108  */
   109  */
   109 bool HandlePlacePushButton(Window *w, int widget, CursorID cursor, int mode, PlaceProc *placeproc)
   110 bool HandlePlacePushButton(Window *w, int widget, CursorID cursor, int mode, PlaceProc *placeproc)
   110 {
   111 {
   111 	if (IsWindowWidgetDisabled(w, widget)) return false;
   112 	if (IsWindowWidgetDisabled(w, widget)) return false;
   524 
   525 
   525 static void UpdatePlayerMenuHeight(Window *w)
   526 static void UpdatePlayerMenuHeight(Window *w)
   526 {
   527 {
   527 	byte num = ActivePlayerCount();
   528 	byte num = ActivePlayerCount();
   528 
   529 
   529 	// Increase one to fit in PlayerList in the menu when in network
   530 	/* Increase one to fit in PlayerList in the menu when in network */
   530 	if (_networking && WP(w,menu_d).main_button == 9) num++;
   531 	if (_networking && WP(w,menu_d).main_button == 9) num++;
   531 
   532 
   532 	if (WP(w,menu_d).item_count != num) {
   533 	if (WP(w,menu_d).item_count != num) {
   533 		WP(w,menu_d).item_count = num;
   534 		WP(w,menu_d).item_count = num;
   534 		SetWindowDirty(w);
   535 		SetWindowDirty(w);
   554 		x = 1;
   555 		x = 1;
   555 		y = 1;
   556 		y = 1;
   556 		sel = WP(w,menu_d).sel_index;
   557 		sel = WP(w,menu_d).sel_index;
   557 		chk = WP(w,menu_d).checked_items; // let this mean gray items.
   558 		chk = WP(w,menu_d).checked_items; // let this mean gray items.
   558 
   559 
   559 		// 9 = playerlist
   560 		/* 9 = playerlist */
   560 		if (_networking && WP(w,menu_d).main_button == 9) {
   561 		if (_networking && WP(w,menu_d).main_button == 9) {
   561 			if (sel == 0) {
   562 			if (sel == 0) {
   562 				GfxFillRect(x, y, x + 238, y + 9, 0);
   563 				GfxFillRect(x, y, x + 238, y + 9, 0);
   563 			}
   564 			}
   564 			DrawString(x + 19, y, STR_NETWORK_CLIENT_LIST, 0x0);
   565 			DrawString(x + 19, y, STR_NETWORK_CLIENT_LIST, 0x0);
   599 
   600 
   600 	case WE_POPUPMENU_SELECT: {
   601 	case WE_POPUPMENU_SELECT: {
   601 		int index = GetMenuItemIndex(w, e->we.popupmenu.pt.x, e->we.popupmenu.pt.y);
   602 		int index = GetMenuItemIndex(w, e->we.popupmenu.pt.x, e->we.popupmenu.pt.y);
   602 		int action_id = WP(w,menu_d).action_id;
   603 		int action_id = WP(w,menu_d).action_id;
   603 
   604 
   604 		// We have a new entry at the top of the list of menu 9 when networking
   605 		/* We have a new entry at the top of the list of menu 9 when networking
   605 		//  so keep that in count
   606 		 *  so keep that in count */
   606 		if (_networking && WP(w,menu_d).main_button == 9) {
   607 		if (_networking && WP(w,menu_d).main_button == 9) {
   607 			if (index > 0) index = GetPlayerIndexFromMenu(index - 1) + 1;
   608 			if (index > 0) index = GetPlayerIndexFromMenu(index - 1) + 1;
   608 		} else {
   609 		} else {
   609 			index = GetPlayerIndexFromMenu(index);
   610 			index = GetPlayerIndexFromMenu(index);
   610 		}
   611 		}
   626 	case WE_POPUPMENU_OVER: {
   627 	case WE_POPUPMENU_OVER: {
   627 		int index;
   628 		int index;
   628 		UpdatePlayerMenuHeight(w);
   629 		UpdatePlayerMenuHeight(w);
   629 		index = GetMenuItemIndex(w, e->we.popupmenu.pt.x, e->we.popupmenu.pt.y);
   630 		index = GetMenuItemIndex(w, e->we.popupmenu.pt.x, e->we.popupmenu.pt.y);
   630 
   631 
   631 		// We have a new entry at the top of the list of menu 9 when networking
   632 		/* We have a new entry at the top of the list of menu 9 when networking
   632 		//  so keep that in count
   633 		 * so keep that in count */
   633 		if (_networking && WP(w,menu_d).main_button == 9) {
   634 		if (_networking && WP(w,menu_d).main_button == 9) {
   634 			if (index > 0) index = GetPlayerIndexFromMenu(index - 1) + 1;
   635 			if (index > 0) index = GetPlayerIndexFromMenu(index - 1) + 1;
   635 		} else {
   636 		} else {
   636 			index = GetPlayerIndexFromMenu(index);
   637 			index = GetPlayerIndexFromMenu(index);
   637 		}
   638 		}
   971 	PopupMainToolbMenu(w, 3, STR_0292_SAVE_SCENARIO, 6, 0);
   972 	PopupMainToolbMenu(w, 3, STR_0292_SAVE_SCENARIO, 6, 0);
   972 }
   973 }
   973 
   974 
   974 static void ToolbarScenDateBackward(Window *w)
   975 static void ToolbarScenDateBackward(Window *w)
   975 {
   976 {
   976 	// don't allow too fast scrolling
   977 	/* don't allow too fast scrolling */
   977 	if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) {
   978 	if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) {
   978 		HandleButtonClick(w, 6);
   979 		HandleButtonClick(w, 6);
   979 		SetWindowDirty(w);
   980 		SetWindowDirty(w);
   980 
   981 
   981 		_patches_newgame.starting_year = clamp(_patches_newgame.starting_year - 1, MIN_YEAR, MAX_YEAR);
   982 		_patches_newgame.starting_year = clamp(_patches_newgame.starting_year - 1, MIN_YEAR, MAX_YEAR);
   984 	_left_button_clicked = false;
   985 	_left_button_clicked = false;
   985 }
   986 }
   986 
   987 
   987 static void ToolbarScenDateForward(Window *w)
   988 static void ToolbarScenDateForward(Window *w)
   988 {
   989 {
   989 	// don't allow too fast scrolling
   990 	/* don't allow too fast scrolling */
   990 	if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) {
   991 	if ((w->flags4 & WF_TIMEOUT_MASK) <= 2 << WF_TIMEOUT_SHL) {
   991 		HandleButtonClick(w, 7);
   992 		HandleButtonClick(w, 7);
   992 		SetWindowDirty(w);
   993 		SetWindowDirty(w);
   993 
   994 
   994 		_patches_newgame.starting_year = clamp(_patches_newgame.starting_year + 1, MIN_YEAR, MAX_YEAR);
   995 		_patches_newgame.starting_year = clamp(_patches_newgame.starting_year + 1, MIN_YEAR, MAX_YEAR);
  1039 			DoZoomInOutWindow(in ? ZOOM_IN : ZOOM_OUT, w);
  1040 			DoZoomInOutWindow(in ? ZOOM_IN : ZOOM_OUT, w);
  1040 		}
  1041 		}
  1041 	}
  1042 	}
  1042 }
  1043 }
  1043 
  1044 
  1044 // TODO - Incorporate into game itself to allow for ingame raising/lowering of
       
  1045 // larger chunks at the same time OR remove altogether, as we have 'level land' ?
       
  1046 /**
  1045 /**
  1047  * Raise/Lower a bigger chunk of land at the same time in the editor. When
  1046  * Raise/Lower a bigger chunk of land at the same time in the editor. When
  1048  * raising get the lowest point, when lowering the highest point, and set all
  1047  * raising get the lowest point, when lowering the highest point, and set all
  1049  * tiles in the selection to that height.
  1048  * tiles in the selection to that height.
       
  1049  * @todo : Incorporate into game itself to allow for ingame raising/lowering of
       
  1050  *         larger chunks at the same time OR remove altogether, as we have 'level land' ?
  1050  * @param tile The top-left tile where the terraforming will start
  1051  * @param tile The top-left tile where the terraforming will start
  1051  * @param mode 1 for raising, 0 for lowering land
  1052  * @param mode 1 for raising, 0 for lowering land
  1052  */
  1053  */
  1053 static void CommonRaiseLowerBigLand(TileIndex tile, int mode)
  1054 static void CommonRaiseLowerBigLand(TileIndex tile, int mode)
  1054 {
  1055 {
  1064 		DoCommandP(tile, 8, (uint32)mode, CcTerraform, CMD_TERRAFORM_LAND | CMD_AUTO | CMD_MSG(msg));
  1065 		DoCommandP(tile, 8, (uint32)mode, CcTerraform, CMD_TERRAFORM_LAND | CMD_AUTO | CMD_MSG(msg));
  1065 	} else {
  1066 	} else {
  1066 		SndPlayTileFx(SND_1F_SPLAT, tile);
  1067 		SndPlayTileFx(SND_1F_SPLAT, tile);
  1067 
  1068 
  1068 		assert(_terraform_size != 0);
  1069 		assert(_terraform_size != 0);
  1069 		// check out for map overflows
  1070 		/* check out for map overflows */
  1070 		sizex = min(MapSizeX() - TileX(tile) - 1, _terraform_size);
  1071 		sizex = min(MapSizeX() - TileX(tile) - 1, _terraform_size);
  1071 		sizey = min(MapSizeY() - TileY(tile) - 1, _terraform_size);
  1072 		sizey = min(MapSizeY() - TileY(tile) - 1, _terraform_size);
  1072 
  1073 
  1073 		if (sizex == 0 || sizey == 0) return;
  1074 		if (sizex == 0 || sizey == 0) return;
  1074 
  1075 
  1172 	{-20,  0}, {-16, -2}, {-12, -4}, { -8, -6}, { -4, -8}, {  0,-10}, {  4, -8}, {  8, -6}, { 12, -4}, { 16, -2}, { 20,  0},
  1173 	{-20,  0}, {-16, -2}, {-12, -4}, { -8, -6}, { -4, -8}, {  0,-10}, {  4, -8}, {  8, -6}, { 12, -4}, { 16, -2}, { 20,  0},
  1173 	{-24,  2}, {-20,  4}, {-16,  6}, {-12,  8}, { -8, 10}, { -4, 12}, {  0, 14}, {  4, 12}, {  8, 10}, { 12,  8}, { 16,  6}, { 20,  4}, { 24,  2},
  1174 	{-24,  2}, {-20,  4}, {-16,  6}, {-12,  8}, { -8, 10}, { -4, 12}, {  0, 14}, {  4, 12}, {  8, 10}, { 12,  8}, { 16,  6}, { 20,  4}, { 24,  2},
  1174 	{-28,  0}, {-24, -2}, {-20, -4}, {-16, -6}, {-12, -8}, { -8,-10}, { -4,-12}, {  0,-14}, {  4,-12}, {  8,-10}, { 12, -8}, { 16, -6}, { 20, -4}, { 24, -2}, { 28,  0},
  1175 	{-28,  0}, {-24, -2}, {-20, -4}, {-16, -6}, {-12, -8}, { -8,-10}, { -4,-12}, {  0,-14}, {  4,-12}, {  8,-10}, { 12, -8}, { 16, -6}, { 20, -4}, { 24, -2}, { 28,  0},
  1175 };
  1176 };
  1176 
  1177 
  1177 // TODO - Merge with terraform_gui.c (move there) after I have cooled down at its braindeadness
  1178 /**
  1178 // and changed OnButtonClick to include the widget as well in the function decleration. Post 0.4.0 - Darkvater
  1179  * @todo Merge with terraform_gui.cpp (move there) after I have cooled down at its braindeadness
       
  1180  * and changed OnButtonClick to include the widget as well in the function declaration. Post 0.4.0 - Darkvater
       
  1181  */
  1179 static void EditorTerraformClick_Dynamite(Window *w)
  1182 static void EditorTerraformClick_Dynamite(Window *w)
  1180 {
  1183 {
  1181 	HandlePlacePushButton(w, 4, ANIMCURSOR_DEMOLISH, 1, PlaceProc_DemolishArea);
  1184 	HandlePlacePushButton(w, 4, ANIMCURSOR_DEMOLISH, 1, PlaceProc_DemolishArea);
  1182 }
  1185 }
  1183 
  1186 
  1269 
  1272 
  1270 static void ScenEditLandGenWndProc(Window *w, WindowEvent *e)
  1273 static void ScenEditLandGenWndProc(Window *w, WindowEvent *e)
  1271 {
  1274 {
  1272 	switch (e->event) {
  1275 	switch (e->event) {
  1273 	case WE_CREATE:
  1276 	case WE_CREATE:
  1274 		// XXX - lighthouse button is widget 10!! Don't forget when changing
  1277 		/* XXX - lighthouse button is widget 10!! Don't forget when changing */
  1275 		w->widget[10].tooltips = (_opt.landscape == LT_DESERT) ? STR_028F_DEFINE_DESERT_AREA : STR_028D_PLACE_LIGHTHOUSE;
  1278 		w->widget[10].tooltips = (_opt.landscape == LT_DESERT) ? STR_028F_DEFINE_DESERT_AREA : STR_028D_PLACE_LIGHTHOUSE;
  1276 		break;
  1279 		break;
  1277 
  1280 
  1278 	case WE_PAINT:
  1281 	case WE_PAINT:
  1279 		DrawWindowWidgets(w);
  1282 		DrawWindowWidgets(w);
  1309 	case WE_CLICK:
  1312 	case WE_CLICK:
  1310 		switch (e->we.click.widget) {
  1313 		switch (e->we.click.widget) {
  1311 		case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11:
  1314 		case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11:
  1312 			_editor_terraform_button_proc[e->we.click.widget - 4](w);
  1315 			_editor_terraform_button_proc[e->we.click.widget - 4](w);
  1313 			break;
  1316 			break;
  1314 		case 12: case 13: { /* Increase/Decrease terraform size */
  1317 		case 12: case 13: { // Increase/Decrease terraform size
  1315 			int size = (e->we.click.widget == 12) ? 1 : -1;
  1318 			int size = (e->we.click.widget == 12) ? 1 : -1;
  1316 			HandleButtonClick(w, e->we.click.widget);
  1319 			HandleButtonClick(w, e->we.click.widget);
  1317 			size += _terraform_size;
  1320 			size += _terraform_size;
  1318 
  1321 
  1319 			if (!IS_INT_INSIDE(size, 1, 8 + 1)) return;
  1322 			if (!IS_INT_INSIDE(size, 1, 8 + 1)) return;
  1320 			_terraform_size = size;
  1323 			_terraform_size = size;
  1321 
  1324 
  1322 			SndPlayFx(SND_15_BEEP);
  1325 			SndPlayFx(SND_15_BEEP);
  1323 			SetWindowDirty(w);
  1326 			SetWindowDirty(w);
  1324 		} break;
  1327 		} break;
  1325 		case 14: /* gen random land */
  1328 		case 14: // gen random land
  1326 			HandleButtonClick(w, 14);
  1329 			HandleButtonClick(w, 14);
  1327 			ShowCreateScenario();
  1330 			ShowCreateScenario();
  1328 			break;
  1331 			break;
  1329 		case 15: /* Reset landscape */
  1332 		case 15: // Reset landscape
  1330 			ShowQuery(
  1333 			ShowQuery(
  1331 			  STR_022C_RESET_LANDSCAPE,
  1334 			  STR_022C_RESET_LANDSCAPE,
  1332 			  STR_RESET_LANDSCAPE_CONFIRMATION_TEXT,
  1335 			  STR_RESET_LANDSCAPE_CONFIRMATION_TEXT,
  1333 			  NULL,
  1336 			  NULL,
  1334 			  ResetLandscapeConfirmationCallback);
  1337 			  ResetLandscapeConfirmationCallback);
  1429 		LowerWindowWidget(w, (_scengen_town_size - 1)+ 7);
  1432 		LowerWindowWidget(w, (_scengen_town_size - 1)+ 7);
  1430 		break;
  1433 		break;
  1431 
  1434 
  1432 	case WE_CLICK:
  1435 	case WE_CLICK:
  1433 		switch (e->we.click.widget) {
  1436 		switch (e->we.click.widget) {
  1434 		case 4: /* new town */
  1437 		case 4: // new town
  1435 			HandlePlacePushButton(w, 4, SPR_CURSOR_TOWN, 1, PlaceProc_Town);
  1438 			HandlePlacePushButton(w, 4, SPR_CURSOR_TOWN, 1, PlaceProc_Town);
  1436 			break;
  1439 			break;
  1437 		case 5: {/* random town */
  1440 		case 5: {// random town
  1438 			Town *t;
  1441 			Town *t;
  1439 
  1442 
  1440 			HandleButtonClick(w, 5);
  1443 			HandleButtonClick(w, 5);
  1441 			_generating_world = true;
  1444 			_generating_world = true;
  1442 			t = CreateRandomTown(20, _scengen_town_size);
  1445 			t = CreateRandomTown(20, _scengen_town_size);
  1448 				ScrollMainWindowToTile(t->xy);
  1451 				ScrollMainWindowToTile(t->xy);
  1449 			}
  1452 			}
  1450 
  1453 
  1451 			break;
  1454 			break;
  1452 		}
  1455 		}
  1453 		case 6: {/* many random towns */
  1456 		case 6: {// many random towns
  1454 			HandleButtonClick(w, 6);
  1457 			HandleButtonClick(w, 6);
  1455 
  1458 
  1456 			_generating_world = true;
  1459 			_generating_world = true;
  1457 			if (!GenerateTowns()) ShowErrorMessage(STR_NO_SPACE_FOR_TOWN, STR_CANNOT_GENERATE_TOWN, 0, 0);
  1460 			if (!GenerateTowns()) ShowErrorMessage(STR_NO_SPACE_FOR_TOWN, STR_CANNOT_GENERATE_TOWN, 0, 0);
  1458 			_generating_world = false;
  1461 			_generating_world = false;
  1603 
  1606 
  1604 /**
  1607 /**
  1605  * Search callback function for TryBuildIndustry
  1608  * Search callback function for TryBuildIndustry
  1606  * @param tile to test
  1609  * @param tile to test
  1607  * @param data that is passed by the caller.  In this case, the type of industry been tested
  1610  * @param data that is passed by the caller.  In this case, the type of industry been tested
  1608  * @result of the operation
  1611  * @return the success (or not) of the operation
  1609  */
  1612  */
  1610 static bool SearchTileForIndustry(TileIndex tile, uint32 data)
  1613 static bool SearchTileForIndustry(TileIndex tile, uint32 data)
  1611 {
  1614 {
  1612 	return CreateNewIndustry(tile, data) != NULL;
  1615 	return CreateNewIndustry(tile, data) != NULL;
  1613 }
  1616 }
  1615 /**
  1618 /**
  1616  * Perform a 9*9 tiles circular search around a tile
  1619  * Perform a 9*9 tiles circular search around a tile
  1617  * in order to find a suitable zone to create the desired industry
  1620  * in order to find a suitable zone to create the desired industry
  1618  * @param tile to start search for
  1621  * @param tile to start search for
  1619  * @param type of the desired industry
  1622  * @param type of the desired industry
       
  1623  * @return the success (or not) of the operation
  1620  */
  1624  */
  1621 static bool TryBuildIndustry(TileIndex tile, int type)
  1625 static bool TryBuildIndustry(TileIndex tile, int type)
  1622 {
  1626 {
  1623 	return CircularTileSearch(tile, 9, SearchTileForIndustry, type);
  1627 	return CircularTileSearch(tile, 9, SearchTileForIndustry, type);
  1624 }
  1628 }
  1663 		}
  1667 		}
  1664 		break;
  1668 		break;
  1665 	case WE_PLACE_OBJ: {
  1669 	case WE_PLACE_OBJ: {
  1666 		int type;
  1670 		int type;
  1667 
  1671 
  1668 		// Show error if no town exists at all
  1672 		/* Show error if no town exists at all */
  1669 		type = _industry_type_to_place;
  1673 		type = _industry_type_to_place;
  1670 		if (!AnyTownExists()) {
  1674 		if (!AnyTownExists()) {
  1671 			SetDParam(0, GetIndustrySpec(type)->name);
  1675 			SetDParam(0, GetIndustrySpec(type)->name);
  1672 			ShowErrorMessage(STR_0286_MUST_BUILD_TOWN_FIRST, STR_0285_CAN_T_BUILD_HERE, e->we.place.pt.x, e->we.place.pt.y);
  1676 			ShowErrorMessage(STR_0286_MUST_BUILD_TOWN_FIRST, STR_0285_CAN_T_BUILD_HERE, e->we.place.pt.x, e->we.place.pt.y);
  1673 			return;
  1677 			return;
  1802 
  1806 
  1803 static void MainToolbarWndProc(Window *w, WindowEvent *e)
  1807 static void MainToolbarWndProc(Window *w, WindowEvent *e)
  1804 {
  1808 {
  1805 	switch (e->event) {
  1809 	switch (e->event) {
  1806 	case WE_PAINT:
  1810 	case WE_PAINT:
  1807 		// Draw brown-red toolbar bg.
  1811 		/* Draw brown-red toolbar bg. */
  1808 		GfxFillRect(0, 0, w->width-1, w->height-1, 0xB2);
  1812 		GfxFillRect(0, 0, w->width-1, w->height-1, 0xB2);
  1809 		GfxFillRect(0, 0, w->width-1, w->height-1, 0xB4 | (1 << PALETTE_MODIFIER_GREYOUT));
  1813 		GfxFillRect(0, 0, w->width-1, w->height-1, 0xB4 | (1 << PALETTE_MODIFIER_GREYOUT));
  1810 
  1814 
  1811 		/* If spectator, disable all construction buttons
  1815 		/* If spectator, disable all construction buttons
  1812 		 * ie : Build road, rail, ships, airports and landscaping
  1816 		 * ie : Build road, rail, ships, airports and landscaping
  2015 	switch (e->event) {
  2019 	switch (e->event) {
  2016 	case WE_PAINT:
  2020 	case WE_PAINT:
  2017 		SetWindowWidgetDisabledState(w, 6, _patches_newgame.starting_year <= MIN_YEAR);
  2021 		SetWindowWidgetDisabledState(w, 6, _patches_newgame.starting_year <= MIN_YEAR);
  2018 		SetWindowWidgetDisabledState(w, 7, _patches_newgame.starting_year >= MAX_YEAR);
  2022 		SetWindowWidgetDisabledState(w, 7, _patches_newgame.starting_year >= MAX_YEAR);
  2019 
  2023 
  2020 		// Draw brown-red toolbar bg.
  2024 		/* Draw brown-red toolbar bg. */
  2021 		GfxFillRect(0, 0, w->width-1, w->height-1, 0xB2);
  2025 		GfxFillRect(0, 0, w->width-1, w->height-1, 0xB2);
  2022 		GfxFillRect(0, 0, w->width-1, w->height-1, 0xB4 | (1 << PALETTE_MODIFIER_GREYOUT));
  2026 		GfxFillRect(0, 0, w->width-1, w->height-1, 0xB4 | (1 << PALETTE_MODIFIER_GREYOUT));
  2023 
  2027 
  2024 		DrawWindowWidgets(w);
  2028 		DrawWindowWidgets(w);
  2025 
  2029 
  2153 		DrawStringCentered(
  2157 		DrawStringCentered(
  2154 			70, 1, (_pause || _patches.status_long_date) ? STR_00AF : STR_00AE, 0
  2158 			70, 1, (_pause || _patches.status_long_date) ? STR_00AF : STR_00AE, 0
  2155 		);
  2159 		);
  2156 
  2160 
  2157 		if (p != NULL) {
  2161 		if (p != NULL) {
  2158 			// Draw player money
  2162 			/* Draw player money */
  2159 			SetDParam64(0, p->money64);
  2163 			SetDParam64(0, p->money64);
  2160 			DrawStringCentered(570, 1, p->player_money >= 0 ? STR_0004 : STR_0005, 0);
  2164 			DrawStringCentered(570, 1, p->player_money >= 0 ? STR_0004 : STR_0005, 0);
  2161 		}
  2165 		}
  2162 
  2166 
  2163 		// Draw status bar
  2167 		/* Draw status bar */
  2164 		if (w->message.msg) { // true when saving is active
  2168 		if (w->message.msg) { // true when saving is active
  2165 			DrawStringCentered(320, 1, STR_SAVING_GAME, 0);
  2169 			DrawStringCentered(320, 1, STR_SAVING_GAME, 0);
  2166 		} else if (_do_autosave) {
  2170 		} else if (_do_autosave) {
  2167 			DrawStringCentered(320, 1, STR_032F_AUTOSAVE, 0);
  2171 			DrawStringCentered(320, 1, STR_032F_AUTOSAVE, 0);
  2168 		} else if (_pause) {
  2172 		} else if (_pause) {
  2169 			DrawStringCentered(320, 1, STR_0319_PAUSED, 0);
  2173 			DrawStringCentered(320, 1, STR_0319_PAUSED, 0);
  2170 		} else if (WP(w,def_d).data_1 > -1280 && FindWindowById(WC_NEWS_WINDOW,0) == NULL && _statusbar_news_item.string_id != 0) {
  2174 		} else if (WP(w,def_d).data_1 > -1280 && FindWindowById(WC_NEWS_WINDOW,0) == NULL && _statusbar_news_item.string_id != 0) {
  2171 			// Draw the scrolling news text
  2175 			/* Draw the scrolling news text */
  2172 			if (!DrawScrollingStatusText(&_statusbar_news_item, WP(w,def_d).data_1))
  2176 			if (!DrawScrollingStatusText(&_statusbar_news_item, WP(w,def_d).data_1))
  2173 				WP(w,def_d).data_1 = -1280;
  2177 				WP(w,def_d).data_1 = -1280;
  2174 		} else {
  2178 		} else {
  2175 			if (p != NULL) {
  2179 			if (p != NULL) {
  2176 				// This is the default text
  2180 				/* This is the default text */
  2177 				SetDParam(0, p->name_1);
  2181 				SetDParam(0, p->name_1);
  2178 				SetDParam(1, p->name_2);
  2182 				SetDParam(1, p->name_2);
  2179 				DrawStringCentered(320, 1, STR_02BA, 0);
  2183 				DrawStringCentered(320, 1, STR_02BA, 0);
  2180 			}
  2184 			}
  2181 		}
  2185 		}
  2197 		break;
  2201 		break;
  2198 
  2202 
  2199 	case WE_TICK: {
  2203 	case WE_TICK: {
  2200 		if (_pause) return;
  2204 		if (_pause) return;
  2201 
  2205 
  2202 		if (WP(w, def_d).data_1 > -1280) { /* Scrolling text */
  2206 		if (WP(w, def_d).data_1 > -1280) { // Scrolling text
  2203 			WP(w, def_d).data_1 -= 2;
  2207 			WP(w, def_d).data_1 -= 2;
  2204 			InvalidateWidget(w, 1);
  2208 			InvalidateWidget(w, 1);
  2205 		}
  2209 		}
  2206 
  2210 
  2207 		if (WP(w, def_d).data_2 > 0) { /* Red blot to show there are new unread newsmessages */
  2211 		if (WP(w, def_d).data_2 > 0) { // Red blot to show there are new unread newsmessages
  2208 			WP(w, def_d).data_2 -= 2;
  2212 			WP(w, def_d).data_2 -= 2;
  2209 		} else if (WP(w, def_d).data_2 < 0) {
  2213 		} else if (WP(w, def_d).data_2 < 0) {
  2210 			WP(w, def_d).data_2 = 0;
  2214 			WP(w, def_d).data_2 = 0;
  2211 			InvalidateWidget(w, 1);
  2215 			InvalidateWidget(w, 1);
  2212 		}
  2216 		}
  2309 			case WKC_DELETE: DeleteNonVitalWindows(); break;
  2313 			case WKC_DELETE: DeleteNonVitalWindows(); break;
  2310 			case WKC_DELETE | WKC_SHIFT: DeleteAllNonVitalWindows(); break;
  2314 			case WKC_DELETE | WKC_SHIFT: DeleteAllNonVitalWindows(); break;
  2311 			case 'R' | WKC_CTRL: MarkWholeScreenDirty(); break;
  2315 			case 'R' | WKC_CTRL: MarkWholeScreenDirty(); break;
  2312 
  2316 
  2313 #if defined(_DEBUG)
  2317 #if defined(_DEBUG)
  2314 			case '0' | WKC_ALT: /* Crash the game */
  2318 			case '0' | WKC_ALT: // Crash the game
  2315 				*(byte*)0 = 0;
  2319 				*(byte*)0 = 0;
  2316 				break;
  2320 				break;
  2317 
  2321 
  2318 			case '1' | WKC_ALT: /* Gimme money */
  2322 			case '1' | WKC_ALT: // Gimme money
  2319 				/* Server can not cheat in advertise mode either! */
  2323 				/* Server can not cheat in advertise mode either! */
  2320 				if (!_networking || !_network_server || !_network_advertise)
  2324 				if (!_networking || !_network_server || !_network_advertise)
  2321 					DoCommandP(0, 10000000, 0, NULL, CMD_MONEY_CHEAT);
  2325 					DoCommandP(0, 10000000, 0, NULL, CMD_MONEY_CHEAT);
  2322 				break;
  2326 				break;
  2323 
  2327 
  2324 			case '2' | WKC_ALT: /* Update the coordinates of all station signs */
  2328 			case '2' | WKC_ALT: // Update the coordinates of all station signs
  2325 				UpdateAllStationVirtCoord();
  2329 				UpdateAllStationVirtCoord();
  2326 				break;
  2330 				break;
  2327 #endif
  2331 #endif
  2328 
  2332 
  2329 			case 'X':
  2333 			case 'X':
  2416 	height = _screen.height;
  2420 	height = _screen.height;
  2417 
  2421 
  2418 	w = AllocateWindow(0, 0, width, height, MainWindowWndProc, WC_MAIN_WINDOW, NULL);
  2422 	w = AllocateWindow(0, 0, width, height, MainWindowWndProc, WC_MAIN_WINDOW, NULL);
  2419 	AssignWindowViewport(w, 0, 0, width, height, TileXY(32, 32), 0);
  2423 	AssignWindowViewport(w, 0, 0, width, height, TileXY(32, 32), 0);
  2420 
  2424 
  2421 	// XXX: these are not done
  2425 	/* XXX: these are not done */
  2422 	switch (_game_mode) {
  2426 	switch (_game_mode) {
  2423 		default: NOT_REACHED();
  2427 		default: NOT_REACHED();
  2424 		case GM_MENU:
  2428 		case GM_MENU:
  2425 			ShowSelectGameWindow();
  2429 			ShowSelectGameWindow();
  2426 			break;
  2430 			break;