src/graph_gui.cpp
branchcpp_gui
changeset 6285 187e3ef04cc9
parent 6268 4b5241e5dd10
child 6298 c30fe89622df
equal deleted inserted replaced
6284:45d0233e7d79 6285:187e3ef04cc9
     1 /* $Id$ */
     1 /* $Id$ */
       
     2 
       
     3 /** @file graph_gui.cpp */
     2 
     4 
     3 #include "stdafx.h"
     5 #include "stdafx.h"
     4 #include "openttd.h"
     6 #include "openttd.h"
     5 #include "table/strings.h"
     7 #include "table/strings.h"
     6 #include "table/sprites.h"
     8 #include "table/sprites.h"
    26 enum {
    28 enum {
    27 	GRAPH_MAX_DATASETS = 16,
    29 	GRAPH_MAX_DATASETS = 16,
    28 	GRAPH_AXIS_LABEL_COLOUR = 16,
    30 	GRAPH_AXIS_LABEL_COLOUR = 16,
    29 	GRAPH_AXIS_LINE_COLOUR  = 215,
    31 	GRAPH_AXIS_LINE_COLOUR  = 215,
    30 
    32 
    31 	GRAPH_X_POSITION_BEGINNING  = 44,  // Start the graph 44 pixels from gw->left
    33 	GRAPH_X_POSITION_BEGINNING  = 44,  ///< Start the graph 44 pixels from gw->left
    32 	GRAPH_X_POSITION_SEPARATION = 22,  // There are 22 pixels between each X value
    34 	GRAPH_X_POSITION_SEPARATION = 22,  ///< There are 22 pixels between each X value
    33 
    35 
    34 	/* How many horizontal lines to draw. 9 is convenient as that means the
    36 	GRAPH_NUM_LINES_Y = 9, ///< How many horizontal lines to draw.
    35 	 * distance between them is the height of the graph / 8, which is the same
    37 	/* 9 is convenient as that means the distance between them is the height of the graph / 8,
       
    38 	 * which is the same
    36 	 * as height >> 3. */
    39 	 * as height >> 3. */
    37 	GRAPH_NUM_LINES_Y = 9,
       
    38 };
    40 };
    39 
    41 
    40 /* Apparently these don't play well with enums. */
    42 /* Apparently these don't play well with enums. */
    41 static const int64 INVALID_DATAPOINT     = INT64_MAX; // Value used for a datapoint that shouldn't be drawn.
    43 static const int64 INVALID_DATAPOINT     = INT64_MAX; // Value used for a datapoint that shouldn't be drawn.
    42 static const uint  INVALID_DATAPOINT_POS = UINT_MAX;  // Used to determine if the previous point was drawn.
    44 static const uint  INVALID_DATAPOINT_POS = UINT_MAX;  // Used to determine if the previous point was drawn.
    43 
    45 
    44 typedef struct GraphDrawer {
    46 typedef struct GraphDrawer {
    45 	uint excluded_data; // bitmask of the datasets that shouldn't be displayed.
    47 	uint excluded_data; ///< bitmask of the datasets that shouldn't be displayed.
    46 	byte num_dataset;
    48 	byte num_dataset;
    47 	byte num_on_x_axis;
    49 	byte num_on_x_axis;
    48 	bool has_negative_values;
    50 	bool has_negative_values;
    49 	byte num_vert_lines;
    51 	byte num_vert_lines;
    50 
    52 
    56 	/* These values are used if the graph is being plotted against values
    58 	/* These values are used if the graph is being plotted against values
    57 	 * rather than the dates specified by month and year. */
    59 	 * rather than the dates specified by month and year. */
    58 	uint16 x_values_start;
    60 	uint16 x_values_start;
    59 	uint16 x_values_increment;
    61 	uint16 x_values_increment;
    60 
    62 
    61 	int left, top;  // Where to start drawing the graph, in pixels.
    63 	int left, top;  ///< Where to start drawing the graph, in pixels.
    62 	uint height;    // The height of the graph in pixels.
    64 	uint height;    ///< The height of the graph in pixels.
    63 	StringID format_str_y_axis;
    65 	StringID format_str_y_axis;
    64 	byte colors[GRAPH_MAX_DATASETS];
    66 	byte colors[GRAPH_MAX_DATASETS];
    65 	int64 cost[GRAPH_MAX_DATASETS][24]; // last 2 years
    67 	int64 cost[GRAPH_MAX_DATASETS][24]; ///< last 2 years
    66 } GraphDrawer;
    68 } GraphDrawer;
    67 
    69 
    68 static void DrawGraph(const GraphDrawer *gw)
    70 static void DrawGraph(const GraphDrawer *gw)
    69 {
    71 {
    70 	uint x, y;            // Reused whenever x and y coordinates are needed.
    72 	uint x, y;            ///< Reused whenever x and y coordinates are needed.
    71 	int64 highest_value;  // Highest value to be drawn.
    73 	int64 highest_value;  ///< Highest value to be drawn.
    72 	int x_axis_offset;    // Distance from the top of the graph to the x axis.
    74 	int x_axis_offset;    ///< Distance from the top of the graph to the x axis.
    73 
    75 
    74 	/* the colors and cost array of GraphDrawer must accomodate
    76 	/* the colors and cost array of GraphDrawer must accomodate
    75 	 * both values for cargo and players. So if any are higher, quit */
    77 	 * both values for cargo and players. So if any are higher, quit */
    76 	assert(GRAPH_MAX_DATASETS >= (int)NUM_CARGO && GRAPH_MAX_DATASETS >= (int)MAX_PLAYERS);
    78 	assert(GRAPH_MAX_DATASETS >= (int)NUM_CARGO && GRAPH_MAX_DATASETS >= (int)MAX_PLAYERS);
    77 	assert(gw->num_vert_lines > 0);
    79 	assert(gw->num_vert_lines > 0);
   242 /* GRAPH LEGEND */
   244 /* GRAPH LEGEND */
   243 /****************/
   245 /****************/
   244 
   246 
   245 static void GraphLegendWndProc(BaseWindow *w, WindowEvent *e)
   247 static void GraphLegendWndProc(BaseWindow *w, WindowEvent *e)
   246 {
   248 {
   247 	const Player* p;
       
   248 
       
   249 	switch (e->event) {
   249 	switch (e->event) {
   250 	case WE_CREATE: {
   250 		case WE_CREATE: {
   251 		uint i;
   251 			for (uint i = 3; i < w->widget_count; i++) {
   252 		for (i = 3; i < w->widget_count; i++) {
   252 				if (!HASBIT(_legend_excluded_players, i - 3)) w->LowerWidget(i);
   253 			if (!HASBIT(_legend_excluded_players, i - 3)) w->LowerWidget(i);
   253 			}
   254 		}
   254 			break;
   255 		break;
   255 		}
   256 	}
   256 
   257 
   257 		case WE_PAINT: {
   258 	case WE_PAINT:
   258 			const Player *p;
   259 		FOR_ALL_PLAYERS(p) {
   259 
   260 			if (!p->is_active) {
   260 			FOR_ALL_PLAYERS(p) {
       
   261 				if (p->is_active) continue;
       
   262 
   261 				SETBIT(_legend_excluded_players, p->index);
   263 				SETBIT(_legend_excluded_players, p->index);
   262 				w->RaiseWidget(p->index + 3);
   264 				w->RaiseWidget(p->index + 3);
   263 			}
   265 			}
   264 		}
   266 
   265 		w->DrawWidgets();
   267 			w->DrawWidgets();
   266 
   268 
   267 		FOR_ALL_PLAYERS(p) {
   269 			FOR_ALL_PLAYERS(p) {
   268 			if (!p->is_active) continue;
   270 				if (!p->is_active) continue;
   269 
   271 
   270 			DrawPlayerIcon(p->index, 4, 18+p->index*12);
   272 				DrawPlayerIcon(p->index, 4, 18+p->index*12);
   271 
   273 
   272 			SetDParam(0, p->name_1);
   274 				SetDParam(0, p->name_1);
   273 			SetDParam(1, p->name_2);
   275 				SetDParam(1, p->name_2);
   274 			SetDParam(2, GetPlayerNameString(p->index, 3));
   276 				SetDParam(2, GetPlayerNameString(p->index, 3));
   275 			DrawString(21, 17 + p->index * 12, STR_7021, HASBIT(_legend_excluded_players, p->index) ? 0x10 : 0xC);
   277 				DrawString(21, 17 + p->index * 12, STR_7021, HASBIT(_legend_excluded_players, p->index) ? 0x10 : 0xC);
   276 		}
   278 			}
   277 		break;
   279 			break;
   278 
   280 		}
   279 	case WE_CLICK:
   281 
   280 		if (IS_INT_INSIDE(e->we.click.widget, 3, 11)) {
   282 		case WE_CLICK:
       
   283 			if (!IS_INT_INSIDE(e->we.click.widget, 3, 11)) return;
       
   284 
   281 			TOGGLEBIT(_legend_excluded_players, e->we.click.widget - 3);
   285 			TOGGLEBIT(_legend_excluded_players, e->we.click.widget - 3);
   282 			w->ToggleWidgetLoweredState(e->we.click.widget);
   286 			w->ToggleWidgetLoweredState(e->we.click.widget);
   283 			w->SetDirty();
   287 			w->SetDirty();
   284 			InvalidateWindow(WC_INCOME_GRAPH, 0);
   288 			InvalidateWindow(WC_INCOME_GRAPH, 0);
   285 			InvalidateWindow(WC_OPERATING_PROFIT, 0);
   289 			InvalidateWindow(WC_OPERATING_PROFIT, 0);
   286 			InvalidateWindow(WC_DELIVERED_CARGO, 0);
   290 			InvalidateWindow(WC_DELIVERED_CARGO, 0);
   287 			InvalidateWindow(WC_PERFORMANCE_HISTORY, 0);
   291 			InvalidateWindow(WC_PERFORMANCE_HISTORY, 0);
   288 			InvalidateWindow(WC_COMPANY_VALUE, 0);
   292 			InvalidateWindow(WC_COMPANY_VALUE, 0);
   289 		}
   293 			break;
   290 		break;
       
   291 	}
   294 	}
   292 }
   295 }
   293 
   296 
   294 static const OldWidget _graph_legend_widgets[] = {
   297 static const OldWidget _graph_legend_widgets[] = {
   295 {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,                       STR_018B_CLOSE_WINDOW},
   298 {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,                       STR_018B_CLOSE_WINDOW},
   328 	const Player* p;
   331 	const Player* p;
   329 	uint excluded_players = _legend_excluded_players;
   332 	uint excluded_players = _legend_excluded_players;
   330 	byte nums;
   333 	byte nums;
   331 	int mo,yr;
   334 	int mo,yr;
   332 
   335 
   333 	// Exclude the players which aren't valid
   336 	/* Exclude the players which aren't valid */
   334 	FOR_ALL_PLAYERS(p) {
   337 	FOR_ALL_PLAYERS(p) {
   335 		if (!p->is_active) SETBIT(excluded_players, p->index);
   338 		if (!p->is_active) SETBIT(excluded_players, p->index);
   336 	}
   339 	}
   337 	gd->excluded_data = excluded_players;
   340 	gd->excluded_data = excluded_players;
   338 	gd->num_vert_lines = 24;
   341 	gd->num_vert_lines = 24;
   339 
   342 
   340 	nums = 0;
   343 	nums = 0;
   341 	FOR_ALL_PLAYERS(p) {
   344 	FOR_ALL_PLAYERS(p) {
   342 		if (p->is_active) nums = max(nums,p->num_valid_stat_ent);
   345 		if (p->is_active) nums = max(nums, p->num_valid_stat_ent);
   343 	}
   346 	}
   344 	gd->num_on_x_axis = min(nums,24);
   347 	gd->num_on_x_axis = min(nums, 24);
   345 
   348 
   346 	mo = (_cur_month/3-nums)*3;
   349 	mo = (_cur_month / 3 - nums) * 3;
   347 	yr = _cur_year;
   350 	yr = _cur_year;
   348 	while (mo < 0) {
   351 	while (mo < 0) {
   349 		yr--;
   352 		yr--;
   350 		mo += 12;
   353 		mo += 12;
   351 	}
   354 	}
   355 }
   358 }
   356 
   359 
   357 static void OperatingProfitWndProc(BaseWindow *w, WindowEvent *e)
   360 static void OperatingProfitWndProc(BaseWindow *w, WindowEvent *e)
   358 {
   361 {
   359 	switch (e->event) {
   362 	switch (e->event) {
   360 	case WE_PAINT: {
   363 		case WE_PAINT: {
   361 		GraphDrawer gd;
   364 			GraphDrawer gd;
   362 		const Player* p;
   365 			const Player* p;
   363 		int i,j;
   366 
   364 		int numd;
   367 			w->DrawWidgets();
   365 
   368 
   366 		w->DrawWidgets();
   369 			gd.left = 2;
   367 
   370 			gd.top = 18;
   368 		gd.left = 2;
   371 			gd.height = 136;
   369 		gd.top = 18;
   372 			gd.has_negative_values = true;
   370 		gd.height = 136;
   373 			gd.format_str_y_axis = STR_CURRCOMPACT;
   371 		gd.has_negative_values = true;
   374 
   372 		gd.format_str_y_axis = STR_CURRCOMPACT;
   375 			SetupGraphDrawerForPlayers(&gd);
   373 
   376 
   374 		SetupGraphDrawerForPlayers(&gd);
   377 			int numd = 0;
   375 
   378 			FOR_ALL_PLAYERS(p) {
   376 		numd = 0;
   379 				if (p->is_active) {
   377 		FOR_ALL_PLAYERS(p) {
   380 					gd.colors[numd] = _colour_gradient[p->player_color][6];
   378 			if (p->is_active) {
   381 					for (int j = gd.num_on_x_axis, i = 0; --j >= 0;) {
   379 				gd.colors[numd] = _colour_gradient[p->player_color][6];
   382 						gd.cost[numd][i] = (j >= p->num_valid_stat_ent) ? INVALID_DATAPOINT : (p->old_economy[j].income + p->old_economy[j].expenses);
   380 				for (j = gd.num_on_x_axis, i = 0; --j >= 0;) {
   383 						i++;
   381 					gd.cost[numd][i] = (j >= p->num_valid_stat_ent) ? INVALID_DATAPOINT : (p->old_economy[j].income + p->old_economy[j].expenses);
   384 					}
   382 					i++;
   385 				}
   383 				}
   386 				numd++;
   384 			}
   387 			}
   385 			numd++;
   388 
   386 		}
   389 			gd.num_dataset = numd;
   387 
   390 
   388 		gd.num_dataset = numd;
   391 			DrawGraph(&gd);
   389 
   392 			break;
   390 		DrawGraph(&gd);
   393 		}
   391 	}	break;
   394 
   392 	case WE_CLICK:
   395 		case WE_CLICK:
   393 		if (e->we.click.widget == 2) /* Clicked on Legend */
   396 			/* Clicked on legend? */
   394 			ShowGraphLegend();
   397 			if (e->we.click.widget == 2) ShowGraphLegend();
   395 		break;
   398 			break;
   396 	}
   399 	}
   397 }
   400 }
   398 
   401 
   399 static const OldWidget _operating_profit_widgets[] = {
   402 static const OldWidget _operating_profit_widgets[] = {
   400 {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,                        STR_018B_CLOSE_WINDOW},
   403 {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,                        STR_018B_CLOSE_WINDOW},
   426 /****************/
   429 /****************/
   427 
   430 
   428 static void IncomeGraphWndProc(BaseWindow *w, WindowEvent *e)
   431 static void IncomeGraphWndProc(BaseWindow *w, WindowEvent *e)
   429 {
   432 {
   430 	switch (e->event) {
   433 	switch (e->event) {
   431 	case WE_PAINT: {
   434 		case WE_PAINT: {
   432 		GraphDrawer gd;
   435 			GraphDrawer gd;
   433 		const Player* p;
   436 			const Player* p;
   434 		int i,j;
   437 
   435 		int numd;
   438 			w->DrawWidgets();
   436 
   439 
   437 		w->DrawWidgets();
   440 			gd.left = 2;
   438 
   441 			gd.top = 18;
   439 		gd.left = 2;
   442 			gd.height = 104;
   440 		gd.top = 18;
   443 			gd.has_negative_values = false;
   441 		gd.height = 104;
   444 			gd.format_str_y_axis = STR_CURRCOMPACT;
   442 		gd.has_negative_values = false;
   445 			SetupGraphDrawerForPlayers(&gd);
   443 		gd.format_str_y_axis = STR_CURRCOMPACT;
   446 
   444 		SetupGraphDrawerForPlayers(&gd);
   447 			int numd = 0;
   445 
   448 			FOR_ALL_PLAYERS(p) {
   446 		numd = 0;
   449 				if (p->is_active) {
   447 		FOR_ALL_PLAYERS(p) {
   450 					gd.colors[numd] = _colour_gradient[p->player_color][6];
   448 			if (p->is_active) {
   451 					for (int j = gd.num_on_x_axis, i = 0; --j >= 0;) {
   449 				gd.colors[numd] = _colour_gradient[p->player_color][6];
   452 						gd.cost[numd][i] = (j >= p->num_valid_stat_ent) ? INVALID_DATAPOINT : p->old_economy[j].income;
   450 				for (j = gd.num_on_x_axis, i = 0; --j >= 0;) {
   453 						i++;
   451 					gd.cost[numd][i] = (j >= p->num_valid_stat_ent) ? INVALID_DATAPOINT : p->old_economy[j].income;
   454 					}
   452 					i++;
   455 				}
   453 				}
   456 				numd++;
   454 			}
   457 			}
   455 			numd++;
   458 
   456 		}
   459 			gd.num_dataset = numd;
   457 
   460 
   458 		gd.num_dataset = numd;
   461 			DrawGraph(&gd);
   459 
   462 			break;
   460 		DrawGraph(&gd);
   463 		}
   461 		break;
   464 
   462 	}
   465 		case WE_CLICK:
   463 
   466 			if (e->we.click.widget == 2) ShowGraphLegend();
   464 	case WE_CLICK:
   467 			break;
   465 		if (e->we.click.widget == 2)
       
   466 			ShowGraphLegend();
       
   467 		break;
       
   468 	}
   468 	}
   469 }
   469 }
   470 
   470 
   471 static const OldWidget _income_graph_widgets[] = {
   471 static const OldWidget _income_graph_widgets[] = {
   472 {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,              STR_018B_CLOSE_WINDOW},
   472 {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,              STR_018B_CLOSE_WINDOW},
   496 /*******************/
   496 /*******************/
   497 
   497 
   498 static void DeliveredCargoGraphWndProc(BaseWindow *w, WindowEvent *e)
   498 static void DeliveredCargoGraphWndProc(BaseWindow *w, WindowEvent *e)
   499 {
   499 {
   500 	switch (e->event) {
   500 	switch (e->event) {
   501 	case WE_PAINT: {
   501 		case WE_PAINT: {
   502 		GraphDrawer gd;
   502 			GraphDrawer gd;
   503 		const Player* p;
   503 			const Player* p;
   504 		int i,j;
   504 
   505 		int numd;
   505 			w->DrawWidgets();
   506 
   506 
   507 		w->DrawWidgets();
   507 			gd.left = 2;
   508 
   508 			gd.top = 18;
   509 		gd.left = 2;
   509 			gd.height = 104;
   510 		gd.top = 18;
   510 			gd.has_negative_values = false;
   511 		gd.height = 104;
   511 			gd.format_str_y_axis = STR_7024;
   512 		gd.has_negative_values = false;
   512 			SetupGraphDrawerForPlayers(&gd);
   513 		gd.format_str_y_axis = STR_7024;
   513 
   514 		SetupGraphDrawerForPlayers(&gd);
   514 			int numd = 0;
   515 
   515 			FOR_ALL_PLAYERS(p) {
   516 		numd = 0;
   516 				if (p->is_active) {
   517 		FOR_ALL_PLAYERS(p) {
   517 					gd.colors[numd] = _colour_gradient[p->player_color][6];
   518 			if (p->is_active) {
   518 					for (int j = gd.num_on_x_axis, i = 0; --j >= 0;) {
   519 				gd.colors[numd] = _colour_gradient[p->player_color][6];
   519 						gd.cost[numd][i] = (j >= p->num_valid_stat_ent) ? INVALID_DATAPOINT : p->old_economy[j].delivered_cargo;
   520 				for (j = gd.num_on_x_axis, i = 0; --j >= 0;) {
   520 						i++;
   521 					gd.cost[numd][i] = (j >= p->num_valid_stat_ent) ? INVALID_DATAPOINT : p->old_economy[j].delivered_cargo;
   521 					}
   522 					i++;
   522 				}
   523 				}
   523 				numd++;
   524 			}
   524 			}
   525 			numd++;
   525 
   526 		}
   526 			gd.num_dataset = numd;
   527 
   527 
   528 		gd.num_dataset = numd;
   528 			DrawGraph(&gd);
   529 
   529 			break;
   530 		DrawGraph(&gd);
   530 		}
   531 		break;
   531 
   532 	}
   532 		case WE_CLICK:
   533 
   533 			if (e->we.click.widget == 2) ShowGraphLegend();
   534 	case WE_CLICK:
   534 			break;
   535 		if (e->we.click.widget == 2)
       
   536 			ShowGraphLegend();
       
   537 		break;
       
   538 	}
   535 	}
   539 }
   536 }
   540 
   537 
   541 static const OldWidget _delivered_cargo_graph_widgets[] = {
   538 static const OldWidget _delivered_cargo_graph_widgets[] = {
   542 {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,                          STR_018B_CLOSE_WINDOW},
   539 {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,                          STR_018B_CLOSE_WINDOW},
   566 /***********************/
   563 /***********************/
   567 
   564 
   568 static void PerformanceHistoryWndProc(BaseWindow *w, WindowEvent *e)
   565 static void PerformanceHistoryWndProc(BaseWindow *w, WindowEvent *e)
   569 {
   566 {
   570 	switch (e->event) {
   567 	switch (e->event) {
   571 	case WE_PAINT: {
   568 		case WE_PAINT: {
   572 		GraphDrawer gd;
   569 			GraphDrawer gd;
   573 		const Player* p;
   570 			const Player* p;
   574 		int i,j;
   571 
   575 		int numd;
   572 			w->DrawWidgets();
   576 
   573 
   577 		w->DrawWidgets();
   574 			gd.left = 2;
   578 
   575 			gd.top = 18;
   579 		gd.left = 2;
   576 			gd.height = 200;
   580 		gd.top = 18;
   577 			gd.has_negative_values = false;
   581 		gd.height = 200;
   578 			gd.format_str_y_axis = STR_7024;
   582 		gd.has_negative_values = false;
   579 			SetupGraphDrawerForPlayers(&gd);
   583 		gd.format_str_y_axis = STR_7024;
   580 
   584 		SetupGraphDrawerForPlayers(&gd);
   581 			int numd = 0;
   585 
   582 			FOR_ALL_PLAYERS(p) {
   586 		numd = 0;
   583 				if (p->is_active) {
   587 		FOR_ALL_PLAYERS(p) {
   584 					gd.colors[numd] = _colour_gradient[p->player_color][6];
   588 			if (p->is_active) {
   585 					for (int j = gd.num_on_x_axis, i = 0; --j >= 0;) {
   589 				gd.colors[numd] = _colour_gradient[p->player_color][6];
   586 						gd.cost[numd][i] = (j >= p->num_valid_stat_ent) ? INVALID_DATAPOINT : p->old_economy[j].performance_history;
   590 				for (j = gd.num_on_x_axis, i = 0; --j >= 0;) {
   587 						i++;
   591 					gd.cost[numd][i] = (j >= p->num_valid_stat_ent) ? INVALID_DATAPOINT : p->old_economy[j].performance_history;
   588 					}
   592 					i++;
   589 				}
   593 				}
   590 				numd++;
   594 			}
   591 			}
   595 			numd++;
   592 
   596 		}
   593 			gd.num_dataset = numd;
   597 
   594 
   598 		gd.num_dataset = numd;
   595 			DrawGraph(&gd);
   599 
   596 			break;
   600 		DrawGraph(&gd);
   597 		}
   601 		break;
   598 
   602 	}
   599 		case WE_CLICK:
   603 
   600 			if (e->we.click.widget == 2) ShowGraphLegend();
   604 	case WE_CLICK:
   601 			if (e->we.click.widget == 3) ShowPerformanceRatingDetail();
   605 		if (e->we.click.widget == 2)
   602 			break;
   606 			ShowGraphLegend();
       
   607 		if (e->we.click.widget == 3)
       
   608 			ShowPerformanceRatingDetail();
       
   609 		break;
       
   610 	}
   603 	}
   611 }
   604 }
   612 
   605 
   613 static const OldWidget _performance_history_widgets[] = {
   606 static const OldWidget _performance_history_widgets[] = {
   614 {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,                             STR_018B_CLOSE_WINDOW},
   607 {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,                             STR_018B_CLOSE_WINDOW},
   639 /*****************/
   632 /*****************/
   640 
   633 
   641 static void CompanyValueGraphWndProc(BaseWindow *w, WindowEvent *e)
   634 static void CompanyValueGraphWndProc(BaseWindow *w, WindowEvent *e)
   642 {
   635 {
   643 	switch (e->event) {
   636 	switch (e->event) {
   644 	case WE_PAINT: {
   637 		case WE_PAINT: {
   645 		GraphDrawer gd;
   638 			GraphDrawer gd;
   646 		const Player* p;
   639 			const Player* p;
   647 		int i,j;
   640 
   648 		int numd;
   641 			w->DrawWidgets();
   649 
   642 
   650 		w->DrawWidgets();
   643 			gd.left = 2;
   651 
   644 			gd.top = 18;
   652 		gd.left = 2;
   645 			gd.height = 200;
   653 		gd.top = 18;
   646 			gd.has_negative_values = false;
   654 		gd.height = 200;
   647 			gd.format_str_y_axis = STR_CURRCOMPACT;
   655 		gd.has_negative_values = false;
   648 			SetupGraphDrawerForPlayers(&gd);
   656 		gd.format_str_y_axis = STR_CURRCOMPACT;
   649 
   657 		SetupGraphDrawerForPlayers(&gd);
   650 			int numd = 0;
   658 
   651 			FOR_ALL_PLAYERS(p) {
   659 		numd = 0;
   652 				if (p->is_active) {
   660 		FOR_ALL_PLAYERS(p) {
   653 					gd.colors[numd] = _colour_gradient[p->player_color][6];
   661 			if (p->is_active) {
   654 					for (int j = gd.num_on_x_axis, i = 0; --j >= 0;) {
   662 				gd.colors[numd] = _colour_gradient[p->player_color][6];
   655 						gd.cost[numd][i] = (j >= p->num_valid_stat_ent) ? INVALID_DATAPOINT : p->old_economy[j].company_value;
   663 				for (j = gd.num_on_x_axis, i = 0; --j >= 0;) {
   656 						i++;
   664 					gd.cost[numd][i] = (j >= p->num_valid_stat_ent) ? INVALID_DATAPOINT : p->old_economy[j].company_value;
   657 					}
   665 					i++;
   658 				}
   666 				}
   659 				numd++;
   667 			}
   660 			}
   668 			numd++;
   661 
   669 		}
   662 			gd.num_dataset = numd;
   670 
   663 
   671 		gd.num_dataset = numd;
   664 			DrawGraph(&gd);
   672 
   665 			break;
   673 		DrawGraph(&gd);
   666 		}
   674 		break;
   667 
   675 	}
   668 		case WE_CLICK:
   676 
   669 			if (e->we.click.widget == 2) ShowGraphLegend();
   677 	case WE_CLICK:
   670 			break;
   678 		if (e->we.click.widget == 2)
       
   679 			ShowGraphLegend();
       
   680 		break;
       
   681 	}
   671 	}
   682 }
   672 }
   683 
   673 
   684 static const OldWidget _company_value_graph_widgets[] = {
   674 static const OldWidget _company_value_graph_widgets[] = {
   685 {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,                STR_018B_CLOSE_WINDOW},
   675 {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,                STR_018B_CLOSE_WINDOW},
   709 /*****************/
   699 /*****************/
   710 
   700 
   711 static void CargoPaymentRatesWndProc(BaseWindow *w, WindowEvent *e)
   701 static void CargoPaymentRatesWndProc(BaseWindow *w, WindowEvent *e)
   712 {
   702 {
   713 	switch (e->event) {
   703 	switch (e->event) {
   714 	case WE_CREATE: {
   704 		case WE_PAINT: {
   715 		uint i;
   705 			GraphDrawer gd;
   716 		for (i = 3; i < w->widget_count; i++) {
   706 
   717 			if (!HASBIT(_legend_excluded_cargo, i - 3)) w->LowerWidget(i);
   707 			w->DrawWidgets();
   718 		}
   708 
   719 		break;
   709 			int x = 495;
   720 	}
   710 			int y = 24;
   721 
   711 
   722 	case WE_PAINT: {
   712 			gd.excluded_data = _legend_excluded_cargo;
   723 		int j, x, y;
   713 			gd.left = 2;
   724 		CargoID i;
   714 			gd.top = 24;
   725 		GraphDrawer gd;
   715 			gd.height = w->Height() - 38;
   726 
   716 			gd.has_negative_values = false;
   727 		w->DrawWidgets();
   717 			gd.format_str_y_axis = STR_CURRCOMPACT;
   728 
   718 			gd.num_on_x_axis = 20;
   729 		x = 495;
   719 			gd.num_vert_lines = 20;
   730 		y = 24;
   720 			gd.month = 0xFF;
   731 
   721 			gd.x_values_start     = 10;
   732 		gd.excluded_data = _legend_excluded_cargo;
   722 			gd.x_values_increment = 10;
   733 		gd.left = 2;
   723 
   734 		gd.top = 24;
   724 			uint i = 0;
   735 		gd.height = 104;
   725 			for (CargoID c = 0; c != NUM_CARGO; c++) {
   736 		gd.has_negative_values = false;
   726 				const CargoSpec *cs = GetCargo(c);
   737 		gd.format_str_y_axis = STR_CURRCOMPACT;
   727 				if (!cs->IsValid()) continue;
   738 		gd.num_dataset = NUM_CARGO;
   728 
   739 		gd.num_on_x_axis = 20;
   729 				/* Only draw labels for widgets that exist. If the widget doesn't
   740 		gd.num_vert_lines = 20;
   730 				 * exist then the local player has used the climate cheat or
   741 		gd.month = 0xFF;
   731 				 * changed the NewGRF configuration with this window open. */
   742 		gd.x_values_start     = 10;
   732 				if (i + 3 < w->widget_count) {
   743 		gd.x_values_increment = 10;
   733 					/* Since the buttons have no text, no images,
   744 
   734 					 * both the text and the colored box have to be manually painted.
   745 		for (i = 0; i != NUM_CARGO; i++) {
   735 					 * clk_dif will move one pixel down and one pixel to the right
   746 			/* Since the buttons have no text, no images,
   736 					 * when the button is clicked */
   747 			 * both the text and the colored box have to be manually painted.
   737 					byte clk_dif = w->IsWidgetLowered(i + 3) ? 1 : 0;
   748 			 * clk_dif will move one pixel down and one pixel to the right
   738 
   749 			 * when the button is clicked */
   739 					GfxFillRect(x + clk_dif, y + clk_dif, x + 8 + clk_dif, y + 5 + clk_dif, 0);
   750 			byte clk_dif = w->IsWidgetLowered(i + 3) ? 1 : 0;
   740 					GfxFillRect(x + 1 + clk_dif, y + 1 + clk_dif, x + 7 + clk_dif, y + 4 + clk_dif, cs->legend_colour);
   751 			const CargoSpec *cs = GetCargo(i);
   741 					SetDParam(0, cs->name);
   752 
   742 					DrawString(x + 14 + clk_dif, y + clk_dif, STR_7065, 0);
   753 			GfxFillRect(x + clk_dif, y + clk_dif, x + 8 + clk_dif, y + 5 + clk_dif, 0);
   743 					y += 8;
   754 			GfxFillRect(x + 1 + clk_dif, y + 1 + clk_dif, x + 7 + clk_dif, y + 4 + clk_dif, cs->legend_colour);
   744 				}
   755 			SetDParam(0, cs->name != 0 ? cs->name : (StringID)STR_EMPTY);
   745 
   756 			DrawString(x + 14 + clk_dif, y + clk_dif, STR_7065, 0);
   746 				gd.colors[i] = cs->legend_colour;
   757 			y += 8;
   747 				for (uint j = 0; j != 20; j++) {
   758 			gd.colors[i] = cs->legend_colour;
   748 					gd.cost[i][j] = GetTransportedGoodsIncome(10, 20, j * 6 + 6, c);
   759 			for (j = 0; j != 20; j++) {
   749 				}
   760 				gd.cost[i][j] = GetTransportedGoodsIncome(10, 20, j * 6 + 6, i);
   750 
   761 			}
   751 				i++;
   762 		}
   752 			}
   763 
   753 			gd.num_dataset = i;
   764 		DrawGraph(&gd);
   754 
   765 
   755 			DrawGraph(&gd);
   766 		DrawString(2 + 46, 24 + gd.height + 7, STR_7062_DAYS_IN_TRANSIT, 0);
   756 
   767 		DrawString(2 + 84, 24 - 9, STR_7063_PAYMENT_FOR_DELIVERING, 0);
   757 			DrawString(2 + 46, 24 + gd.height + 7, STR_7062_DAYS_IN_TRANSIT, 0);
   768 	} break;
   758 			DrawString(2 + 84, 24 - 9, STR_7063_PAYMENT_FOR_DELIVERING, 0);
   769 
   759 			break;
   770 	case WE_CLICK: {
   760 		}
   771 		switch (e->we.click.widget) {
   761 
   772 		case 3: case 4: case 5: case 6:
   762 		case WE_CLICK:
   773 		case 7: case 8: case 9: case 10:
   763 			if (e->we.click.widget >= 3) {
   774 		case 11: case 12: case 13: case 14:
   764 				TOGGLEBIT(_legend_excluded_cargo, e->we.click.widget - 3);
   775 			TOGGLEBIT(_legend_excluded_cargo, e->we.click.widget - 3);
   765 				w->ToggleWidgetLoweredState(e->we.click.widget);
   776 			w->ToggleWidgetLoweredState(e->we.click.widget);
   766 				w->SetDirty();
   777 			w->SetDirty();
   767 			}
   778 			break;
   768 			break;
   779 		}
       
   780 	} break;
       
   781 	}
   769 	}
   782 }
   770 }
   783 
   771 
   784 static const OldWidget _cargo_payment_rates_widgets[] = {
   772 static const OldWidget _cargo_payment_rates_widgets[] = {
   785 {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,                     STR_018B_CLOSE_WINDOW},
   773 {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,                     STR_018B_CLOSE_WINDOW},
   786 {    WWT_CAPTION,   RESIZE_NONE,    14,    11,   567,     0,    13, STR_7061_CARGO_PAYMENT_RATES, STR_018C_WINDOW_TITLE_DRAG_THIS},
   774 {    WWT_CAPTION,   RESIZE_NONE,    14,    11,   567,     0,    13, STR_7061_CARGO_PAYMENT_RATES, STR_018C_WINDOW_TITLE_DRAG_THIS},
   787 {      WWT_PANEL,   RESIZE_NONE,    14,     0,   567,    14,   141, 0x0,                          STR_NULL},
   775 {      WWT_PANEL, RESIZE_BOTTOM,    14,     0,   567,    14,    45, 0x0,                          STR_NULL},
   788 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    24,    31, 0x0,                          STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   789 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    32,    39, 0x0,                          STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   790 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    40,    47, 0x0,                          STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   791 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    48,    55, 0x0,                          STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   792 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    56,    63, 0x0,                          STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   793 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    64,    71, 0x0,                          STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   794 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    72,    79, 0x0,                          STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   795 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    80,    87, 0x0,                          STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   796 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    88,    95, 0x0,                          STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   797 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,    96,   103, 0x0,                          STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   798 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,   104,   111, 0x0,                          STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   799 {      WWT_PANEL,   RESIZE_NONE,    12,   493,   562,   112,   119, 0x0,                          STR_7064_TOGGLE_GRAPH_FOR_CARGO},
       
   800 {   WIDGETS_END},
   776 {   WIDGETS_END},
   801 };
   777 };
   802 
   778 
   803 static const WindowDesc _cargo_payment_rates_desc = {
   779 static const WindowDesc _cargo_payment_rates_desc = {
   804 	WDP_AUTO, WDP_AUTO, 568, 142,
   780 	WDP_AUTO, WDP_AUTO, 568, 46,
   805 	WC_PAYMENT_RATES, WC_NONE,
   781 	WC_PAYMENT_RATES, WC_NONE,
   806 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
   782 	WDF_STD_TOOLTIPS | WDF_STD_BTN | WDF_DEF_WIDGET,
   807 	_cargo_payment_rates_widgets,
   783 	_cargo_payment_rates_widgets,
   808 	CargoPaymentRatesWndProc
   784 	CargoPaymentRatesWndProc
   809 };
   785 };
   810 
   786 
   811 
   787 
   812 void ShowCargoPaymentRates(void)
   788 void ShowCargoPaymentRates(void)
   813 {
   789 {
   814 	BaseWindow::AllocateFront(&_cargo_payment_rates_desc, 0);
   790 	BaseWindow *w = BaseWindow::AllocateFront(&_cargo_payment_rates_desc, 0);
       
   791 	if (w == NULL) return;
       
   792 
       
   793 	/* Count the number of active cargo types */
       
   794 	uint num_active = 0;
       
   795 	for (CargoID c = 0; c != NUM_CARGO; c++) {
       
   796 		if (GetCargo(c)->IsValid()) num_active++;
       
   797 	}
       
   798 
       
   799 	/* Resize the window to fit the cargo types */
       
   800 	w->Resize(0, num_active * 8);
       
   801 
       
   802 	/* Add widgets for each cargo type */
       
   803 	w->widget_count = 3 + num_active;
       
   804 	w->widget = ReallocT(w->widget, w->widget_count);
       
   805 
       
   806 	/* Set the properties of each widget */
       
   807 	for (uint i = 0; i != num_active; i++) {
       
   808 		OldWidget *wi = &w->widget[3 + i];
       
   809 		wi->type     = WWT_PANEL;
       
   810 		wi->m_display_flags = RESIZE_NONE;
       
   811 		wi->color    = 12;
       
   812 		wi->left     = 493;
       
   813 		wi->right    = 562;
       
   814 		wi->top      = 24 + i * 8;
       
   815 		wi->bottom   = wi->top + 7;
       
   816 		wi->data     = 0;
       
   817 		wi->tooltips = STR_7064_TOGGLE_GRAPH_FOR_CARGO;
       
   818 
       
   819 		if (!HASBIT(_legend_excluded_cargo, i)) w->LowerWidget(i + 3);
       
   820 	}
       
   821 
       
   822 	w->SetDirty();
   815 }
   823 }
   816 
   824 
   817 /************************/
   825 /************************/
   818 /* COMPANY LEAGUE TABLE */
   826 /* COMPANY LEAGUE TABLE */
   819 /************************/
   827 /************************/
   854 {
   862 {
   855 	switch (e->event) {
   863 	switch (e->event) {
   856 		case WE_PAINT: {
   864 		case WE_PAINT: {
   857 			const Player* plist[MAX_PLAYERS];
   865 			const Player* plist[MAX_PLAYERS];
   858 			const Player* p;
   866 			const Player* p;
   859 			uint pl_num;
       
   860 			uint i;
       
   861 
   867 
   862 			w->DrawWidgets();
   868 			w->DrawWidgets();
   863 
   869 
   864 			pl_num = 0;
   870 			uint pl_num = 0;
   865 			FOR_ALL_PLAYERS(p) if (p->is_active) plist[pl_num++] = p;
   871 			FOR_ALL_PLAYERS(p) if (p->is_active) plist[pl_num++] = p;
   866 
   872 
   867 			qsort((void*)plist, pl_num, sizeof(*plist), PerfHistComp);
   873 			qsort((void*)plist, pl_num, sizeof(*plist), PerfHistComp);
   868 
   874 
   869 			for (i = 0; i != pl_num; i++) {
   875 			for (uint i = 0; i != pl_num; i++) {
   870 				p = plist[i];
   876 				p = plist[i];
   871 				SetDParam(0, i + STR_01AC_1ST);
   877 				SetDParam(0, i + STR_01AC_1ST);
   872 				SetDParam(1, p->name_1);
   878 				SetDParam(1, p->name_1);
   873 				SetDParam(2, p->name_2);
   879 				SetDParam(2, p->name_2);
   874 				SetDParam(3, GetPlayerNameString(p->index, 4));
   880 				SetDParam(3, GetPlayerNameString(p->index, 4));
   918 			byte x;
   924 			byte x;
   919 			uint16 y = 14;
   925 			uint16 y = 14;
   920 			int total_score = 0;
   926 			int total_score = 0;
   921 			int color_done, color_notdone;
   927 			int color_done, color_notdone;
   922 
   928 
   923 			// Draw standard stuff
   929 			/* Draw standard stuff */
   924 			w->DrawWidgets();
   930 			w->DrawWidgets();
   925 
   931 
   926 			/* Check if the currently selected player is still active. */
   932 			/* Check if the currently selected player is still active. */
   927 			if (_performance_rating_detail_player == INVALID_PLAYER || !GetPlayer(_performance_rating_detail_player)->is_active) {
   933 			if (_performance_rating_detail_player == INVALID_PLAYER || !GetPlayer(_performance_rating_detail_player)->is_active) {
   928 				if (_performance_rating_detail_player != INVALID_PLAYER) {
   934 				if (_performance_rating_detail_player != INVALID_PLAYER) {
   947 			}
   953 			}
   948 
   954 
   949 			/* If there are no active players, don't display anything else. */
   955 			/* If there are no active players, don't display anything else. */
   950 			if (_performance_rating_detail_player == INVALID_PLAYER) break;
   956 			if (_performance_rating_detail_player == INVALID_PLAYER) break;
   951 
   957 
   952 			// Paint the player icons
   958 			/* Paint the player icons */
   953 			for (PlayerID i = PLAYER_FIRST; i < MAX_PLAYERS; i++) {
   959 			for (PlayerID i = PLAYER_FIRST; i < MAX_PLAYERS; i++) {
   954 				if (!GetPlayer(i)->is_active) {
   960 				if (!GetPlayer(i)->is_active) {
   955 					// Check if we have the player as an active player
   961 					/* Check if we have the player as an active player */
   956 					if (!w->IsWidgetDisabled(i + 13)) {
   962 					if (!w->IsWidgetDisabled(i + 13)) {
   957 						// Bah, player gone :(
   963 						/* Bah, player gone :( */
   958 						w->DisableWidget(i + 13);
   964 						w->DisableWidget(i + 13);
   959 
   965 
   960 						// We need a repaint
   966 						/* We need a repaint */
   961 						w->SetDirty();
   967 						w->SetDirty();
   962 					}
   968 					}
   963 					continue;
   969 					continue;
   964 				}
   970 				}
   965 
   971 
   966 				// Check if we have the player marked as inactive
   972 				/* Check if we have the player marked as inactive */
   967 				if (w->IsWidgetDisabled(i + 13)) {
   973 				if (w->IsWidgetDisabled(i + 13)) {
   968 					// New player! Yippie :p
   974 					/* New player! Yippie :p */
   969 					w->EnableWidget(i + 13);
   975 					w->EnableWidget(i + 13);
   970 					// We need a repaint
   976 					/* We need a repaint */
   971 					w->SetDirty();
   977 					w->SetDirty();
   972 				}
   978 				}
   973 
   979 
   974 				x = (i == _performance_rating_detail_player) ? 1 : 0;
   980 				x = (i == _performance_rating_detail_player) ? 1 : 0;
   975 				DrawPlayerIcon(i, i * 37 + 13 + x, 16 + x);
   981 				DrawPlayerIcon(i, i * 37 + 13 + x, 16 + x);
   976 			}
   982 			}
   977 
   983 
   978 			// The colors used to show how the progress is going
   984 			/* The colors used to show how the progress is going */
   979 			color_done = _colour_gradient[COLOUR_GREEN][4];
   985 			color_done = _colour_gradient[COLOUR_GREEN][4];
   980 			color_notdone = _colour_gradient[COLOUR_RED][4];
   986 			color_notdone = _colour_gradient[COLOUR_RED][4];
   981 
   987 
   982 			// Draw all the score parts
   988 			/* Draw all the score parts */
   983 			for (ScoreID i = SCORE_BEGIN; i < SCORE_END; i++) {
   989 			for (ScoreID i = SCORE_BEGIN; i < SCORE_END; i++) {
   984 				int val    = _score_part[_performance_rating_detail_player][i];
   990 				int val    = _score_part[_performance_rating_detail_player][i];
   985 				int needed = _score_info[i].needed;
   991 				int needed = _score_info[i].needed;
   986 				int score  = _score_info[i].score;
   992 				int score  = _score_info[i].score;
   987 
   993 
   988 				y += 20;
   994 				y += 20;
   989 				// SCORE_TOTAL has his own rulez ;)
   995 				/* SCORE_TOTAL has his own rulez ;) */
   990 				if (i == SCORE_TOTAL) {
   996 				if (i == SCORE_TOTAL) {
   991 					needed = total_score;
   997 					needed = total_score;
   992 					score = SCORE_MAX;
   998 					score = SCORE_MAX;
   993 				} else {
   999 				} else {
   994 					total_score += score;
  1000 					total_score += score;
   995 				}
  1001 				}
   996 
  1002 
   997 				DrawString(7, y, STR_PERFORMANCE_DETAIL_VEHICLES + i, 0);
  1003 				DrawString(7, y, STR_PERFORMANCE_DETAIL_VEHICLES + i, 0);
   998 
  1004 
   999 				// Draw the score
  1005 				/* Draw the score */
  1000 				SetDParam(0, score);
  1006 				SetDParam(0, score);
  1001 				DrawStringRightAligned(107, y, SET_PERFORMANCE_DETAIL_INT, 0);
  1007 				DrawStringRightAligned(107, y, SET_PERFORMANCE_DETAIL_INT, 0);
  1002 
  1008 
  1003 				// Calculate the %-bar
  1009 				/* Calculate the %-bar */
  1004 				if (val > needed) {
  1010 				if (val > needed) {
  1005 					x = 50;
  1011 					x = 50;
  1006 				} else if (val == 0) {
  1012 				} else if (val == 0) {
  1007 					x = 0;
  1013 					x = 0;
  1008 				} else {
  1014 				} else {
  1009 					x = val * 50 / needed;
  1015 					x = val * 50 / needed;
  1010 				}
  1016 				}
  1011 
  1017 
  1012 				// SCORE_LOAN is inversed
  1018 				/* SCORE_LOAN is inversed */
  1013 				if (val < 0 && i == SCORE_LOAN) x = 0;
  1019 				if (val < 0 && i == SCORE_LOAN) x = 0;
  1014 
  1020 
  1015 				// Draw the bar
  1021 				/* Draw the bar */
  1016 				if (x !=  0) GfxFillRect(112,     y - 2, 112 + x,  y + 10, color_done);
  1022 				if (x !=  0) GfxFillRect(112,     y - 2, 112 + x,  y + 10, color_done);
  1017 				if (x != 50) GfxFillRect(112 + x, y - 2, 112 + 50, y + 10, color_notdone);
  1023 				if (x != 50) GfxFillRect(112 + x, y - 2, 112 + 50, y + 10, color_notdone);
  1018 
  1024 
  1019 				// Calculate the %
  1025 				/* Calculate the % */
  1020 				x = (val <= needed) ? val * 100 / needed : 100;
  1026 				x = (val <= needed) ? val * 100 / needed : 100;
  1021 
  1027 
  1022 				// SCORE_LOAN is inversed
  1028 				/* SCORE_LOAN is inversed */
  1023 				if (val < 0 && i == SCORE_LOAN) x = 0;
  1029 				if (val < 0 && i == SCORE_LOAN) x = 0;
  1024 
  1030 
  1025 				// Draw it
  1031 				/* Draw it */
  1026 				SetDParam(0, x);
  1032 				SetDParam(0, x);
  1027 				DrawStringCentered(137, y, STR_PERFORMANCE_DETAIL_PERCENT, 0);
  1033 				DrawStringCentered(137, y, STR_PERFORMANCE_DETAIL_PERCENT, 0);
  1028 
  1034 
  1029 				// SCORE_LOAN is inversed
  1035 				/* SCORE_LOAN is inversed */
  1030 				if (i == SCORE_LOAN) val = needed - val;
  1036 				if (i == SCORE_LOAN) val = needed - val;
  1031 
  1037 
  1032 				// Draw the amount we have against what is needed
  1038 				/* Draw the amount we have against what is needed
  1033 				//  For some of them it is in currency format
  1039 				 * For some of them it is in currency format */
  1034 				SetDParam(0, val);
  1040 				SetDParam(0, val);
  1035 				SetDParam(1, needed);
  1041 				SetDParam(1, needed);
  1036 				switch (i) {
  1042 				switch (i) {
  1037 					case SCORE_MIN_PROFIT:
  1043 					case SCORE_MIN_PROFIT:
  1038 					case SCORE_MIN_INCOME:
  1044 					case SCORE_MIN_INCOME:
  1048 
  1054 
  1049 			break;
  1055 			break;
  1050 		}
  1056 		}
  1051 
  1057 
  1052 		case WE_CLICK:
  1058 		case WE_CLICK:
  1053 			// Check which button is clicked
  1059 			/* Check which button is clicked */
  1054 			if (IS_INT_INSIDE(e->we.click.widget, 13, 21)) {
  1060 			if (IS_INT_INSIDE(e->we.click.widget, 13, 21)) {
  1055 				// Is it no on disable?
  1061 				/* Is it no on disable? */
  1056 				if (!w->IsWidgetDisabled(e->we.click.widget)) {
  1062 				if (!w->IsWidgetDisabled(e->we.click.widget)) {
  1057 					w->RaiseWidget(_performance_rating_detail_player + 13);
  1063 					w->RaiseWidget(_performance_rating_detail_player + 13);
  1058 					_performance_rating_detail_player = (PlayerID)(e->we.click.widget - 13);
  1064 					_performance_rating_detail_player = (PlayerID)(e->we.click.widget - 13);
  1059 					w->LowerWidget(_performance_rating_detail_player + 13);
  1065 					w->LowerWidget(_performance_rating_detail_player + 13);
  1060 					w->SetDirty();
  1066 					w->SetDirty();
  1061 				}
  1067 				}
  1062 			}
  1068 			}
  1063 			break;
  1069 			break;
  1064 
  1070 
  1065 		case WE_CREATE: {
  1071 		case WE_CREATE: {
  1066 			PlayerID i;
       
  1067 			Player *p2;
  1072 			Player *p2;
  1068 
  1073 
  1069 			/* Disable the players who are not active */
  1074 			/* Disable the players who are not active */
  1070 			for (i = PLAYER_FIRST; i < MAX_PLAYERS; i++) {
  1075 			for (PlayerID i = PLAYER_FIRST; i < MAX_PLAYERS; i++) {
  1071 				w->SetWidgetDisabledState(i + 13, !GetPlayer(i)->is_active);
  1076 				w->SetWidgetDisabledState(i + 13, !GetPlayer(i)->is_active);
  1072 			}
  1077 			}
  1073 			/* Update all player stats with the current data
  1078 			/* Update all player stats with the current data
  1074 			 * (this is because _score_info is not saved to a savegame) */
  1079 			 * (this is because _score_info is not saved to a savegame) */
  1075 			FOR_ALL_PLAYERS(p2) {
  1080 			FOR_ALL_PLAYERS(p2) {
  1083 			w->SetDirty();
  1088 			w->SetDirty();
  1084 
  1089 
  1085 			break;
  1090 			break;
  1086 		}
  1091 		}
  1087 
  1092 
  1088 		case WE_TICK: {
  1093 		case WE_TICK:
  1089 			// Update the player score every 5 days
  1094 			/* Update the player score every 5 days */
  1090 			if (--w->custom[0] == 0) {
  1095 			if (--w->custom[0] == 0) {
  1091 				w->custom[0] = DAY_TICKS;
  1096 				w->custom[0] = DAY_TICKS;
  1092 				if (--w->custom[1] == 0) {
  1097 				if (--w->custom[1] == 0) {
  1093 					Player *p2;
  1098 					Player *p2;
  1094 
  1099 
  1095 					w->custom[1] = 5;
  1100 					w->custom[1] = 5;
  1096 					FOR_ALL_PLAYERS(p2) {
  1101 					FOR_ALL_PLAYERS(p2) {
  1097 						// Skip if player is not active
  1102 						/* Skip if player is not active */
  1098 						if (p2->is_active) UpdateCompanyRatingAndValue(p2, false);
  1103 						if (p2->is_active) UpdateCompanyRatingAndValue(p2, false);
  1099 					}
  1104 					}
  1100 					w->SetDirty();
  1105 					w->SetDirty();
  1101 				}
  1106 				}
  1102 			}
  1107 			}
  1103 
  1108 
  1104 			break;
  1109 			break;
  1105 		}
       
  1106 	}
  1110 	}
  1107 }
  1111 }
  1108 
  1112 
  1109 static const OldWidget _performance_rating_detail_widgets[] = {
  1113 static const OldWidget _performance_rating_detail_widgets[] = {
  1110 {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,               STR_018B_CLOSE_WINDOW},
  1114 {   WWT_CLOSEBOX,   RESIZE_NONE,    14,     0,    10,     0,    13, STR_00C5,               STR_018B_CLOSE_WINDOW},