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); |
947 } |
949 } |
948 |
950 |
949 /* If there are no active players, don't display anything else. */ |
951 /* If there are no active players, don't display anything else. */ |
950 if (_performance_rating_detail_player == INVALID_PLAYER) break; |
952 if (_performance_rating_detail_player == INVALID_PLAYER) break; |
951 |
953 |
952 // Paint the player icons |
954 /* Paint the player icons */ |
953 for (PlayerID i = PLAYER_FIRST; i < MAX_PLAYERS; i++) { |
955 for (PlayerID i = PLAYER_FIRST; i < MAX_PLAYERS; i++) { |
954 if (!GetPlayer(i)->is_active) { |
956 if (!GetPlayer(i)->is_active) { |
955 // Check if we have the player as an active player |
957 /* Check if we have the player as an active player */ |
956 if (!IsWindowWidgetDisabled(w, i + 13)) { |
958 if (!IsWindowWidgetDisabled(w, i + 13)) { |
957 // Bah, player gone :( |
959 /* Bah, player gone :( */ |
958 DisableWindowWidget(w, i + 13); |
960 DisableWindowWidget(w, i + 13); |
959 |
961 |
960 // We need a repaint |
962 /* We need a repaint */ |
961 SetWindowDirty(w); |
963 SetWindowDirty(w); |
962 } |
964 } |
963 continue; |
965 continue; |
964 } |
966 } |
965 |
967 |
966 // Check if we have the player marked as inactive |
968 /* Check if we have the player marked as inactive */ |
967 if (IsWindowWidgetDisabled(w, i + 13)) { |
969 if (IsWindowWidgetDisabled(w, i + 13)) { |
968 // New player! Yippie :p |
970 /* New player! Yippie :p */ |
969 EnableWindowWidget(w, i + 13); |
971 EnableWindowWidget(w, i + 13); |
970 // We need a repaint |
972 /* We need a repaint */ |
971 SetWindowDirty(w); |
973 SetWindowDirty(w); |
972 } |
974 } |
973 |
975 |
974 x = (i == _performance_rating_detail_player) ? 1 : 0; |
976 x = (i == _performance_rating_detail_player) ? 1 : 0; |
975 DrawPlayerIcon(i, i * 37 + 13 + x, 16 + x); |
977 DrawPlayerIcon(i, i * 37 + 13 + x, 16 + x); |
976 } |
978 } |
977 |
979 |
978 // The colors used to show how the progress is going |
980 /* The colors used to show how the progress is going */ |
979 color_done = _colour_gradient[COLOUR_GREEN][4]; |
981 color_done = _colour_gradient[COLOUR_GREEN][4]; |
980 color_notdone = _colour_gradient[COLOUR_RED][4]; |
982 color_notdone = _colour_gradient[COLOUR_RED][4]; |
981 |
983 |
982 // Draw all the score parts |
984 /* Draw all the score parts */ |
983 for (ScoreID i = SCORE_BEGIN; i < SCORE_END; i++) { |
985 for (ScoreID i = SCORE_BEGIN; i < SCORE_END; i++) { |
984 int val = _score_part[_performance_rating_detail_player][i]; |
986 int val = _score_part[_performance_rating_detail_player][i]; |
985 int needed = _score_info[i].needed; |
987 int needed = _score_info[i].needed; |
986 int score = _score_info[i].score; |
988 int score = _score_info[i].score; |
987 |
989 |
988 y += 20; |
990 y += 20; |
989 // SCORE_TOTAL has his own rulez ;) |
991 /* SCORE_TOTAL has his own rulez ;) */ |
990 if (i == SCORE_TOTAL) { |
992 if (i == SCORE_TOTAL) { |
991 needed = total_score; |
993 needed = total_score; |
992 score = SCORE_MAX; |
994 score = SCORE_MAX; |
993 } else { |
995 } else { |
994 total_score += score; |
996 total_score += score; |
995 } |
997 } |
996 |
998 |
997 DrawString(7, y, STR_PERFORMANCE_DETAIL_VEHICLES + i, 0); |
999 DrawString(7, y, STR_PERFORMANCE_DETAIL_VEHICLES + i, 0); |
998 |
1000 |
999 // Draw the score |
1001 /* Draw the score */ |
1000 SetDParam(0, score); |
1002 SetDParam(0, score); |
1001 DrawStringRightAligned(107, y, SET_PERFORMANCE_DETAIL_INT, 0); |
1003 DrawStringRightAligned(107, y, SET_PERFORMANCE_DETAIL_INT, 0); |
1002 |
1004 |
1003 // Calculate the %-bar |
1005 /* Calculate the %-bar */ |
1004 if (val > needed) { |
1006 if (val > needed) { |
1005 x = 50; |
1007 x = 50; |
1006 } else if (val == 0) { |
1008 } else if (val == 0) { |
1007 x = 0; |
1009 x = 0; |
1008 } else { |
1010 } else { |
1009 x = val * 50 / needed; |
1011 x = val * 50 / needed; |
1010 } |
1012 } |
1011 |
1013 |
1012 // SCORE_LOAN is inversed |
1014 /* SCORE_LOAN is inversed */ |
1013 if (val < 0 && i == SCORE_LOAN) x = 0; |
1015 if (val < 0 && i == SCORE_LOAN) x = 0; |
1014 |
1016 |
1015 // Draw the bar |
1017 /* Draw the bar */ |
1016 if (x != 0) GfxFillRect(112, y - 2, 112 + x, y + 10, color_done); |
1018 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); |
1019 if (x != 50) GfxFillRect(112 + x, y - 2, 112 + 50, y + 10, color_notdone); |
1018 |
1020 |
1019 // Calculate the % |
1021 /* Calculate the % */ |
1020 x = (val <= needed) ? val * 100 / needed : 100; |
1022 x = (val <= needed) ? val * 100 / needed : 100; |
1021 |
1023 |
1022 // SCORE_LOAN is inversed |
1024 /* SCORE_LOAN is inversed */ |
1023 if (val < 0 && i == SCORE_LOAN) x = 0; |
1025 if (val < 0 && i == SCORE_LOAN) x = 0; |
1024 |
1026 |
1025 // Draw it |
1027 /* Draw it */ |
1026 SetDParam(0, x); |
1028 SetDParam(0, x); |
1027 DrawStringCentered(137, y, STR_PERFORMANCE_DETAIL_PERCENT, 0); |
1029 DrawStringCentered(137, y, STR_PERFORMANCE_DETAIL_PERCENT, 0); |
1028 |
1030 |
1029 // SCORE_LOAN is inversed |
1031 /* SCORE_LOAN is inversed */ |
1030 if (i == SCORE_LOAN) val = needed - val; |
1032 if (i == SCORE_LOAN) val = needed - val; |
1031 |
1033 |
1032 // Draw the amount we have against what is needed |
1034 /* Draw the amount we have against what is needed |
1033 // For some of them it is in currency format |
1035 * For some of them it is in currency format */ |
1034 SetDParam(0, val); |
1036 SetDParam(0, val); |
1035 SetDParam(1, needed); |
1037 SetDParam(1, needed); |
1036 switch (i) { |
1038 switch (i) { |
1037 case SCORE_MIN_PROFIT: |
1039 case SCORE_MIN_PROFIT: |
1038 case SCORE_MIN_INCOME: |
1040 case SCORE_MIN_INCOME: |