Changeset - r15093:2257306d1c9a
[Not reviewed]
master
0 1 0
terkhen - 14 years ago 2010-04-26 17:40:03
terkhen@openttd.org
(svn r19729) -Fix [FS#3793]: The company value graph crashed the game when displaying companies with a huge amount of money.
1 file changed with 9 insertions and 8 deletions:
0 comments (0 inline, 0 general)
src/graph_gui.cpp
Show inline comments
 
@@ -14,24 +14,25 @@
 
#include "graph_gui.h"
 
#include "window_gui.h"
 
#include "company_base.h"
 
#include "company_gui.h"
 
#include "economy_func.h"
 
#include "cargotype.h"
 
#include "strings_func.h"
 
#include "window_func.h"
 
#include "date_func.h"
 
#include "gfx_func.h"
 
#include "sortlist_type.h"
 
#include "core/geometry_func.hpp"
 
#include "math.h"
 

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

	
 
/* Bitmasks of company and cargo indices that shouldn't be drawn. */
 
static uint _legend_excluded_companies;
 
static uint _legend_excluded_cargo;
 

	
 
/* Apparently these don't play well with enums. */
 
static const OverflowSafeInt64 INVALID_DATAPOINT(INT64_MAX); // Value used for a datapoint that shouldn't be drawn.
 
static const uint INVALID_DATAPOINT_POS = UINT_MAX;  // Used to determine if the previous point was drawn.
 

	
 
@@ -224,41 +225,41 @@ protected:
 
				if (datapoint != INVALID_DATAPOINT) {
 
					current_interval.highest = max(current_interval.highest, datapoint);
 
					current_interval.lowest  = min(current_interval.lowest, datapoint);
 
				}
 
			}
 
		}
 

	
 
		/* Prevent showing values too close to the graph limits. */
 
		current_interval.highest = (11 * current_interval.highest) / 10;
 
		current_interval.lowest =  (11 * current_interval.lowest) / 10;
 

	
 
		/* Always include zero in the shown range. */
 
		OverflowSafeInt64 abs_lower  = (current_interval.lowest > 0) ? (OverflowSafeInt64)0 : abs(current_interval.lowest);
 
		OverflowSafeInt64 abs_higher = (current_interval.highest < 0) ? (OverflowSafeInt64)0 : current_interval.highest;
 
		double abs_lower  = (current_interval.lowest > 0) ? 0 : (double)abs(current_interval.lowest);
 
		double abs_higher = (current_interval.highest < 0) ? 0 : (double)current_interval.highest;
 

	
 
		int num_pos_grids;
 
		int grid_size;
 
		int64 grid_size;
 

	
 
		if (abs_lower != 0 || abs_higher != 0) {
 
			/* The number of grids to reserve for the positive part is: */
 
			num_pos_grids = RoundDivSU(abs_higher * num_hori_lines, abs_higher + abs_lower);
 
			num_pos_grids = (int)floor(0.5 + num_hori_lines * abs_higher / (abs_higher + abs_lower));
 

	
 
			/* If there are any positive or negative values, force that they have at least one grid. */
 
			if (num_pos_grids == 0 && abs_higher != 0) num_pos_grids++;
 
			if (num_pos_grids == num_hori_lines && abs_lower != 0) num_pos_grids--;
 

	
 
			/* Get the required grid size for each side and use the maximum one. */
 
			int grid_size_higher = (abs_higher > 0) ? (int)(abs_higher + num_pos_grids - 1) / num_pos_grids : 0;
 
			int grid_size_lower = (abs_lower > 0) ? (int)(abs_lower + num_hori_lines - num_pos_grids - 1) / (num_hori_lines - num_pos_grids) : 0;
 
			int64 grid_size_higher = (abs_higher > 0) ? ((int64)abs_higher + num_pos_grids - 1) / num_pos_grids : 0;
 
			int64 grid_size_lower = (abs_lower > 0) ? ((int64)abs_lower + num_hori_lines - num_pos_grids - 1) / (num_hori_lines - num_pos_grids) : 0;
 
			grid_size = max(grid_size_higher, grid_size_lower);
 
		} else {
 
			/* If both values are zero, show an empty graph. */
 
			num_pos_grids = num_hori_lines / 2;
 
			grid_size = 1;
 
		}
 

	
 
		current_interval.highest = num_pos_grids * grid_size;
 
		current_interval.lowest = -(num_hori_lines - num_pos_grids) * grid_size;
 
		return current_interval;
 
	}
 

	
 
@@ -322,26 +323,26 @@ protected:
 

	
 
		r.left += label_width;
 

	
 
		int x_sep = (r.right - r.left) / this->num_vert_lines;
 
		int y_sep = (r.bottom - r.top) / num_hori_lines;
 

	
 
		/* Redetermine right and bottom edge of graph to fit with the integer
 
		 * separation values. */
 
		r.right = r.left + x_sep * this->num_vert_lines;
 
		r.bottom = r.top + y_sep * num_hori_lines;
 

	
 
		OverflowSafeInt64 interval_size = interval.highest + abs(interval.lowest);
 
		/* Where to draw the X axis */
 
		x_axis_offset = (r.bottom - r.top) * interval.highest / interval_size;
 
		/* Where to draw the X axis. Use floating point to avoid overflowing and results of zero. */
 
		x_axis_offset = (int)((r.bottom - r.top) * (double)interval.highest / (double)interval_size);
 

	
 
		/* Draw the vertical grid lines. */
 

	
 
		/* Don't draw the first line, as that's where the axis will be. */
 
		x = r.left + x_sep;
 

	
 
		for (int i = 0; i < this->num_vert_lines; i++) {
 
			GfxFillRect(x, r.top, x, r.bottom, grid_colour);
 
			x += x_sep;
 
		}
 

	
 
		/* Draw the horizontal grid lines. */
0 comments (0 inline, 0 general)