From 2e90f7f8b975d380c3d544995ef6db9d6c8a86d8 Mon Sep 17 00:00:00 2001 From: frosch Date: Sun, 18 Apr 2010 14:56:05 +0000 Subject: (svn r19670) -Codechange: Add CeilDiv() and RoundDiv() to simplify integer divisions with rounding. --- src/aircraft_cmd.cpp | 2 +- src/autoreplace_cmd.cpp | 2 +- src/core/math_func.hpp | 22 ++++++++++++++++++++++ src/depot_gui.cpp | 4 ++-- src/economy.cpp | 2 +- src/gfx.cpp | 9 ++++----- src/industry_cmd.cpp | 4 ++-- src/map_func.h | 11 +++++------ src/pathfinder/yapf/yapf_costrail.hpp | 2 +- src/smallmap_gui.cpp | 8 ++++---- src/station_gui.cpp | 4 ++-- src/terraform_gui.cpp | 4 ++-- src/timetable_cmd.cpp | 2 +- src/toolbar_gui.cpp | 2 +- src/viewport.cpp | 2 +- 15 files changed, 50 insertions(+), 30 deletions(-) diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index 4cb96beb4..4e3a1168f 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.cpp @@ -1061,7 +1061,7 @@ static bool AircraftController(Aircraft *v) /* Only start lowering when we're sufficiently close for a 1:1 glide */ if (delta >= t) { - z -= ((z - curz) + t - 1) / t; + z -= CeilDiv(z - curz, t); } if (z < curz) z = curz; } diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index aeee94ff2..fe962cd73 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.cpp @@ -412,7 +412,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon if (old_head->type == VEH_TRAIN) { /* Store the length of the old vehicle chain, rounded up to whole tiles */ - uint16 old_total_length = (Train::From(old_head)->tcache.cached_total_length + TILE_SIZE - 1) / TILE_SIZE * TILE_SIZE; + uint16 old_total_length = CeilDiv(Train::From(old_head)->tcache.cached_total_length, TILE_SIZE) * TILE_SIZE; int num_units = 0; ///< Number of units in the chain for (Train *w = Train::From(old_head); w != NULL; w = w->GetNextUnit()) num_units++; diff --git a/src/core/math_func.hpp b/src/core/math_func.hpp index d57a3a511..8f31dd273 100644 --- a/src/core/math_func.hpp +++ b/src/core/math_func.hpp @@ -318,4 +318,26 @@ static FORCEINLINE uint ToPercent16(uint i) int LeastCommonMultiple(int a, int b); int GreatestCommonDivisor(int a, int b); +/** + * Computes ceil(a / b) for non-negative a and b. + * @param a Numerator + * @param b Denominator + * @return Quotient, rounded up + */ +static FORCEINLINE uint CeilDiv(uint a, uint b) +{ + return (a + b - 1) / b; +} + +/** + * Computes round(a / b) for non-negative a and b. + * @param a Numerator + * @param b Denominator + * @return Quotient, rounded to nearest + */ +static FORCEINLINE uint RoundDiv(uint a, uint b) +{ + return (a + b / 2) / b; +} + #endif /* MATH_FUNC_HPP */ diff --git a/src/depot_gui.cpp b/src/depot_gui.cpp index 6a5d53592..fef980725 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.cpp @@ -259,7 +259,7 @@ struct DepotWindow : Window { DrawTrainImage(u, image_left + (rtl ? 0 : x_space), image_right - (rtl ? x_space : 0), sprite_y - 1, this->sel, free_wagon ? 0 : this->hscroll.GetPosition()); /* Number of wagons relative to a standard length wagon (rounded up) */ - SetDParam(0, (u->tcache.cached_total_length + 7) / 8); + SetDParam(0, CeilDiv(u->tcache.cached_total_length, 8)); DrawString(rtl ? left + WD_FRAMERECT_LEFT : right - this->count_width, rtl ? left + this->count_width : right - WD_FRAMERECT_RIGHT, y + (this->resize.step_height - FONT_HEIGHT_SMALL) / 2, STR_TINY_BLACK_COMA, TC_FROMSTRING, SA_RIGHT); // Draw the counter break; } @@ -692,7 +692,7 @@ struct DepotWindow : Window { this->vscroll.SetCount(this->vehicle_list.Length() + this->wagon_list.Length() + 1); this->hscroll.SetCount(max_width); } else { - this->vscroll.SetCount((this->vehicle_list.Length() + this->hscroll.GetCapacity() - 1) / this->hscroll.GetCapacity()); + this->vscroll.SetCount(CeilDiv(this->vehicle_list.Length(), this->hscroll.GetCapacity())); } /* Setup disabled buttons. */ diff --git a/src/economy.cpp b/src/economy.cpp index b591d5d9b..4107852e3 100644 --- a/src/economy.cpp +++ b/src/economy.cpp @@ -1165,7 +1165,7 @@ static void LoadUnloadVehicle(Vehicle *v, int *cargo_left) byte load_amount = e->info.load_amount; /* The default loadamount for mail is 1/4 of the load amount for passengers */ - if (v->type == VEH_AIRCRAFT && !Aircraft::From(v)->IsNormalAircraft()) load_amount = (load_amount + 3) / 4; + if (v->type == VEH_AIRCRAFT && !Aircraft::From(v)->IsNormalAircraft()) load_amount = CeilDiv(load_amount, 4); if (_settings_game.order.gradual_loading && HasBit(e->info.callback_mask, CBM_VEHICLE_LOAD_AMOUNT)) { uint16 cb_load_amount = GetVehicleCallback(CBID_VEHICLE_LOAD_AMOUNT, 0, 0, v->engine_type, v); diff --git a/src/gfx.cpp b/src/gfx.cpp index c8e9229f2..4c5177f21 100644 --- a/src/gfx.cpp +++ b/src/gfx.cpp @@ -550,8 +550,7 @@ static int DrawString(int left, int right, int top, char *str, const char *last, break; case SA_CENTER: - /* The second + 1 is to round to the closest number */ - left = (initial_right + 1 + initial_left - w + 1) / 2; + left = RoundDiv(initial_right + 1 + initial_left - w, 2); /* right + 1 = left + w */ right = left + w - 1; break; @@ -824,7 +823,7 @@ int DrawStringMultiLine(int left, int right, int top, int bottom, StringID str, total_height = (num + 1) * mt; } - int y = (align == SA_CENTER) ? (bottom + top - total_height + 1) / 2 : top; + int y = (align == SA_CENTER) ? RoundDiv(bottom + top - total_height, 2) : top; const char *src = buffer; for (;;) { @@ -1324,8 +1323,8 @@ byte GetDigitWidth(FontSize size) void ScreenSizeChanged() { - _dirty_bytes_per_line = (_screen.width + DIRTY_BLOCK_WIDTH - 1) / DIRTY_BLOCK_WIDTH; - _dirty_blocks = ReallocT(_dirty_blocks, _dirty_bytes_per_line * ((_screen.height + DIRTY_BLOCK_HEIGHT - 1) / DIRTY_BLOCK_HEIGHT)); + _dirty_bytes_per_line = CeilDiv(_screen.width, DIRTY_BLOCK_WIDTH); + _dirty_blocks = ReallocT(_dirty_blocks, _dirty_bytes_per_line * CeilDiv(_screen.height, DIRTY_BLOCK_HEIGHT)); /* check the dirty rect */ if (_invalid_rect.right >= _screen.width) _invalid_rect.right = _screen.width; diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index f25ada8c3..24d279170 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -2332,8 +2332,8 @@ static void ChangeIndustryProduction(Industry *i, bool monthly) * For non-smooth economy these should always be synchronized with prod_level */ if (recalculate_multipliers) { /* Rates are rounded up, so e.g. oilrig always produces some passengers */ - i->production_rate[0] = min((indspec->production_rate[0] * i->prod_level + PRODLEVEL_DEFAULT - 1) / PRODLEVEL_DEFAULT, 0xFF); - i->production_rate[1] = min((indspec->production_rate[1] * i->prod_level + PRODLEVEL_DEFAULT - 1) / PRODLEVEL_DEFAULT, 0xFF); + i->production_rate[0] = min(CeilDiv(indspec->production_rate[0] * i->prod_level, PRODLEVEL_DEFAULT), 0xFF); + i->production_rate[1] = min(CeilDiv(indspec->production_rate[1] * i->prod_level, PRODLEVEL_DEFAULT), 0xFF); } /* Close if needed and allowed */ diff --git a/src/map_func.h b/src/map_func.h index 5acabc11d..6711677c1 100644 --- a/src/map_func.h +++ b/src/map_func.h @@ -12,6 +12,7 @@ #ifndef MAP_FUNC_H #define MAP_FUNC_H +#include "core/math_func.hpp" #include "tile_type.h" #include "map_type.h" #include "direction_func.h" @@ -126,9 +127,8 @@ static inline uint MapMaxY() static inline uint ScaleByMapSize(uint n) { /* Subtract 12 from shift in order to prevent integer overflow - * for large values of n. It's safe since the min mapsize is 64x64. - * Add (1<<4)-1 to round upwards. */ - return ((n << (MapLogX() + MapLogY() - 12)) + (1 << 4) - 1) >> 4; + * for large values of n. It's safe since the min mapsize is 64x64. */ + return CeilDiv(n << (MapLogX() + MapLogY() - 12), 1 << 4); } @@ -142,9 +142,8 @@ static inline uint ScaleByMapSize1D(uint n) { /* Normal circumference for the X+Y is 256+256 = 1<<9 * Note, not actually taking the full circumference into account, - * just half of it. - * (1<<9) - 1 is there to scale upwards. */ - return ((n << MapLogX()) + (n << MapLogY()) + (1 << 9) - 1) >> 9; + * just half of it. */ + return CeilDiv((n << MapLogX()) + (n << MapLogY()), 1 << 9); } /** diff --git a/src/pathfinder/yapf/yapf_costrail.hpp b/src/pathfinder/yapf/yapf_costrail.hpp index 6c4603c68..3badace9a 100644 --- a/src/pathfinder/yapf/yapf_costrail.hpp +++ b/src/pathfinder/yapf/yapf_costrail.hpp @@ -259,7 +259,7 @@ public: assert(v != NULL); assert(v->type == VEH_TRAIN); assert(v->tcache.cached_total_length != 0); - int missing_platform_length = (v->tcache.cached_total_length + TILE_SIZE - 1) / TILE_SIZE - platform_length; + int missing_platform_length = CeilDiv(v->tcache.cached_total_length, TILE_SIZE) - platform_length; if (missing_platform_length < 0) { /* apply penalty for longer platform than needed */ cost += Yapf().PfGetSettings().rail_longer_platform_penalty + Yapf().PfGetSettings().rail_longer_platform_per_tile_penalty * -missing_platform_length; diff --git a/src/smallmap_gui.cpp b/src/smallmap_gui.cpp index be437703c..45a5d334d 100644 --- a/src/smallmap_gui.cpp +++ b/src/smallmap_gui.cpp @@ -984,7 +984,7 @@ public: */ inline uint GetMaxLegendHeight() const { - uint num_rows = max(this->min_number_of_fixed_rows, (_smallmap_industry_count + this->min_number_of_columns - 1) / this->min_number_of_columns); + uint num_rows = max(this->min_number_of_fixed_rows, CeilDiv(_smallmap_industry_count, this->min_number_of_columns)); return WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + num_rows * FONT_HEIGHT_SMALL; } @@ -1010,7 +1010,7 @@ public: uint GetLegendHeight(uint width) const { uint num_columns = this->GetNumberColumnsLegend(width); - uint num_rows = max(this->min_number_of_fixed_rows, (_smallmap_industry_count + num_columns - 1) / num_columns); + uint num_rows = max(this->min_number_of_fixed_rows, CeilDiv(_smallmap_industry_count, num_columns)); return WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + num_rows * FONT_HEIGHT_SMALL; } @@ -1067,7 +1067,7 @@ public: case SM_WIDGET_LEGEND: { uint columns = this->GetNumberColumnsLegend(r.right - r.left + 1); - uint number_of_rows = max(this->map_type == SMT_INDUSTRY ? (_smallmap_industry_count + columns - 1) / columns : 0, this->min_number_of_fixed_rows); + uint number_of_rows = max(this->map_type == SMT_INDUSTRY ? CeilDiv(_smallmap_industry_count, columns) : 0, this->min_number_of_fixed_rows); bool rtl = _dynlang.text_dir == TD_RTL; uint y_org = r.top + WD_FRAMERECT_TOP; uint x = rtl ? r.right - this->column_width - WD_FRAMERECT_RIGHT : r.left + WD_FRAMERECT_LEFT; @@ -1195,7 +1195,7 @@ public: const NWidgetBase *wi = this->GetWidget(SM_WIDGET_LEGEND); // Label panel uint line = (pt.y - wi->pos_y - WD_FRAMERECT_TOP) / FONT_HEIGHT_SMALL; uint columns = this->GetNumberColumnsLegend(wi->current_x); - uint number_of_rows = max((_smallmap_industry_count + columns - 1) / columns, this->min_number_of_fixed_rows); + uint number_of_rows = max(CeilDiv(_smallmap_industry_count, columns), this->min_number_of_fixed_rows); if (line >= number_of_rows) break; bool rtl = _dynlang.text_dir == TD_RTL; diff --git a/src/station_gui.cpp b/src/station_gui.cpp index f672823c0..bc0e6066b 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.cpp @@ -1105,7 +1105,7 @@ struct StationViewWindow : public Window { } Rect s = {r.left + WD_FRAMERECT_LEFT, r.top + WD_FRAMERECT_TOP, r.right - WD_FRAMERECT_RIGHT, INT32_MAX}; int bottom = DrawCargoListText(cargo_mask, s, STR_STATION_VIEW_ACCEPTS_CARGO); - return (bottom - r.top - WD_FRAMERECT_TOP + FONT_HEIGHT_NORMAL - 1) / FONT_HEIGHT_NORMAL; + return CeilDiv(bottom - r.top - WD_FRAMERECT_TOP, FONT_HEIGHT_NORMAL); } /** Draw cargo ratings in the #SVW_ACCEPTLIST widget. @@ -1131,7 +1131,7 @@ struct StationViewWindow : public Window { DrawString(r.left + WD_FRAMERECT_LEFT + 6, r.right - WD_FRAMERECT_RIGHT - 6, y, STR_STATION_VIEW_CARGO_RATING); y += FONT_HEIGHT_NORMAL; } - return (y - r.top - WD_FRAMERECT_TOP + FONT_HEIGHT_NORMAL - 1) / FONT_HEIGHT_NORMAL; + return CeilDiv(y - r.top - WD_FRAMERECT_TOP, FONT_HEIGHT_NORMAL); } void HandleCargoWaitingClick(int row) diff --git a/src/terraform_gui.cpp b/src/terraform_gui.cpp index 60e505045..019dd5616 100644 --- a/src/terraform_gui.cpp +++ b/src/terraform_gui.cpp @@ -649,8 +649,8 @@ struct ScenarioEditorLandscapeGenerationWindow : Window { { if (widget != ETTW_DOTS) return; - int center_x = (r.left + r.right + 1) / 2; - int center_y = (r.top + r.bottom + 1) / 2; + int center_x = RoundDiv(r.left + r.right, 2); + int center_y = RoundDiv(r.top + r.bottom, 2); int n = _terraform_size * _terraform_size; const int8 *coords = &_multi_terraform_coords[0][0]; diff --git a/src/timetable_cmd.cpp b/src/timetable_cmd.cpp index c003acbee..9cc8ddb0c 100644 --- a/src/timetable_cmd.cpp +++ b/src/timetable_cmd.cpp @@ -279,7 +279,7 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling) /* Round the time taken up to the nearest day, as this will avoid * confusion for people who are timetabling in days, and can be * adjusted later by people who aren't. */ - time_taken = (((time_taken - 1) / DAY_TICKS) + 1) * DAY_TICKS; + time_taken = CeilDiv(time_taken, DAY_TICKS) * DAY_TICKS; ChangeTimetable(v, v->cur_order_index, time_taken, travelling); } diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index 1ac6d1705..700310c2f 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.cpp @@ -1113,7 +1113,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer { }; /* If at least BIGGEST_ARRANGEMENT fit, just spread all the buttons nicely */ - uint full_buttons = max((width + this->smallest_x - 1) / this->smallest_x, SMALLEST_ARRANGEMENT); + uint full_buttons = max(CeilDiv(width, this->smallest_x), SMALLEST_ARRANGEMENT); if (full_buttons > BIGGEST_ARRANGEMENT) { button_count = arrangable_count = lengthof(arrange_all); spacer_count = this->spacers; diff --git a/src/viewport.cpp b/src/viewport.cpp index 8347c3e8b..52488e140 100644 --- a/src/viewport.cpp +++ b/src/viewport.cpp @@ -2478,7 +2478,7 @@ static void CalcRaildirsDrawstyle(TileHighlightData *thd, int x, int y, int meth * 2 tiles have a length of 1. To bias towards the ceiling we add * one before division. It feels more natural to count 3 lengths as 2 */ if ((b & HT_DIR_MASK) != HT_DIR_X && (b & HT_DIR_MASK) != HT_DIR_Y) { - distance = (distance + 1) / 2; + distance = CeilDiv(distance, 2); } params[index++] = distance; -- cgit v1.2.3-70-g09d2