=== src/console_cmds.cpp ================================================================== --- src/console_cmds.cpp (/openttd/trunk) (revision 153) +++ src/console_cmds.cpp (/openttd/safeint) (revision 153) @@ -1251,7 +1251,7 @@ GetString(buffer, STR_00D1_DARK_BLUE + _player_colors[p->index], lastof(buffer)); IConsolePrintF(8, "#:%d(%s) Company Name: '%s' Year Founded: %d Money: %" OTTD_PRINTF64 "d Loan: %" OTTD_PRINTF64 "d Value: %" OTTD_PRINTF64 "d (T:%d, R:%d, P:%d, S:%d) %sprotected", - p->index + 1, buffer, npi->company_name, p->inaugurated_year, p->player_money, p->current_loan, CalculateCompanyValue(p), + p->index + 1, buffer, npi->company_name, p->inaugurated_year, p->player_money.tovaluetype(), p->current_loan.tovaluetype(), CalculateCompanyValue(p).tovaluetype(), /* trains */ npi->num_vehicle[0], /* lorry + bus */ npi->num_vehicle[1] + npi->num_vehicle[2], /* planes */ npi->num_vehicle[3], === src/build_vehicle_gui.cpp ================================================================== --- src/build_vehicle_gui.cpp (/openttd/trunk) (revision 153) +++ src/build_vehicle_gui.cpp (/openttd/safeint) (revision 153) @@ -210,7 +210,7 @@ Money va = rvi_a->running_cost_base * _price.running_rail[rvi_a->running_cost_class] * (rvi_a->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1); Money vb = rvi_b->running_cost_base * _price.running_rail[rvi_b->running_cost_class] * (rvi_b->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1); - int r = ClampToI32(va - vb); + int r = ClampToI32( (va - vb).tovaluetype()); return _internal_sort_order ? -r : r; } @@ -228,7 +228,7 @@ * Since it would be multipling with 2 in both numerator and denumerator, it will even themselves out and we skip checking for multiheaded. */ Money va = (rvi_a->running_cost_base * _price.running_rail[rvi_a->running_cost_class]) / max((uint16)1, rvi_a->power); Money vb = (rvi_b->running_cost_base * _price.running_rail[rvi_b->running_cost_class]) / max((uint16)1, rvi_b->power); - int r = ClampToI32(vb - va); + int r = ClampToI32( (vb - va).tovaluetype()) ; return _internal_sort_order ? -r : r; } === src/command.cpp ================================================================== --- src/command.cpp (/openttd/trunk) (revision 153) +++ src/command.cpp (/openttd/safeint) (revision 153) @@ -672,25 +672,13 @@ CommandCost CommandCost::AddCost(Money cost) { - /* Overflow protection */ - if (cost < 0 && (this->cost + cost) > this->cost) { - this->cost = INT64_MIN; - } else if (cost > 0 && (this->cost + cost) < this->cost) { - this->cost = INT64_MAX; - } else { - this->cost += cost; - } + this->cost += cost; return *this; } CommandCost CommandCost::MultiplyCost(int factor) { - /* Overflow protection */ - if (factor != 0 && (INT64_MAX / myabs(factor)) < myabs(this->cost)) { - this->cost = (this->cost < 0 == factor < 0) ? INT64_MAX : INT64_MIN; - } else { - this->cost *= factor; - } + this->cost *= factor; return *this; } === src/ai/trolly/trolly.cpp ================================================================== --- src/ai/trolly/trolly.cpp (/openttd/trunk) (revision 153) +++ src/ai/trolly/trolly.cpp (/openttd/safeint) (revision 153) @@ -957,7 +957,7 @@ // Check if we have enough money for it! if (p->ainew.new_cost > p->player_money - AI_MINIMUM_MONEY) { // Too bad.. - DEBUG(ai, 1, "Insufficient funds to build route (%d)", p->ainew.new_cost); + DEBUG(ai, 1, "Insufficient funds to build route (%d)", p->ainew.new_cost.tovaluetype()); p->ainew.state = AI_STATE_NOTHING; return; } @@ -1089,7 +1089,7 @@ } } - DEBUG(ai, 1, "Finished building path, cost: %d", p->ainew.new_cost); + DEBUG(ai, 1, "Finished building path, cost: %d", p->ainew.new_cost.tovaluetype()); p->ainew.state = AI_STATE_BUILD_DEPOT; } } === src/station_gui.cpp ================================================================== --- src/station_gui.cpp (/openttd/trunk) (revision 153) +++ src/station_gui.cpp (/openttd/safeint) (revision 153) @@ -138,7 +138,7 @@ if (!st2->goods[j].cargo.Empty()) sum2 += GetTransportedGoodsIncome(st2->goods[j].cargo.Count(), 20, 50, j); } - return (_internal_sort_order & 1) ? ClampToI32(sum2 - sum1) : ClampToI32(sum1 - sum2); + return (_internal_sort_order & 1) ? ClampToI32((sum2 - sum1).tovaluetype()) : ClampToI32((sum1 - sum2).tovaluetype()); } /** === src/strings.cpp ================================================================== --- src/strings.cpp (/openttd/trunk) (revision 153) +++ src/strings.cpp (/openttd/safeint) (revision 153) @@ -374,7 +374,7 @@ *--p = spec->separator; j = 3; } - *--p = '0' + number % 10; + *--p = '0' + (number % 10).tovaluetype(); } while ((number /= 10) != 0); buff = strecpy(buff, p, last); === src/economy.cpp ================================================================== --- src/economy.cpp (/openttd/trunk) (revision 153) +++ src/economy.cpp (/openttd/safeint) (revision 153) @@ -95,7 +95,7 @@ value.AddCost(-p->current_loan); value.AddCost(p->player_money); - return max(value.GetCost(), 1LL); + return max(value.GetCost().tovaluetype(), 1LL); } /** if update is set to true, the economy is updated with this score @@ -137,7 +137,7 @@ _score_part[owner][SCORE_VEHICLES] = num; /* Don't allow negative min_profit to show */ if (min_profit > 0) - _score_part[owner][SCORE_MIN_PROFIT] = ClampToI32(min_profit); + _score_part[owner][SCORE_MIN_PROFIT] = ClampToI32(min_profit.tovaluetype()); } /* Count stations */ @@ -165,9 +165,9 @@ } while (++pee,--numec); if (min_income > 0) - _score_part[owner][SCORE_MIN_INCOME] = ClampToI32(min_income); + _score_part[owner][SCORE_MIN_INCOME] = ClampToI32(min_income.tovaluetype()); - _score_part[owner][SCORE_MAX_INCOME] = ClampToI32(max_income); + _score_part[owner][SCORE_MAX_INCOME] = ClampToI32(max_income.tovaluetype()); } } @@ -199,13 +199,13 @@ /* Generate score for player money */ { if (p->player_money > 0) { - _score_part[owner][SCORE_MONEY] = ClampToI32(p->player_money); + _score_part[owner][SCORE_MONEY] = ClampToI32(p->player_money.tovaluetype()); } } /* Generate score for loan */ { - _score_part[owner][SCORE_LOAN] = ClampToI32(_score_info[SCORE_LOAN].needed - p->current_loan); + _score_part[owner][SCORE_LOAN] = ClampToI32( (_score_info[SCORE_LOAN].needed - p->current_loan).tovaluetype() ); } /* Now we calculate the score for each item.. */ @@ -641,11 +641,11 @@ static void AddSingleInflation(Money *value, uint16 *frac, int32 amt) { /* Is it safe to add inflation ? */ - if ((INT64_MAX / amt) < (*value + 1)) { + if ((INT64_MAX / amt) < (*value + 1).tovaluetype()) { *value = INT64_MAX / amt; *frac = 0; } else { - int64 tmp = (int64)*value * amt + *frac; + int64 tmp = (*value * amt + *frac).tovaluetype(); *frac = GB(tmp, 0, 16); *value += tmp >> 16; } @@ -678,10 +678,10 @@ Money inf = _economy.infl_amount * 54; for (uint i = 0; i != NUM_PRICES; i++) { - AddSingleInflation((Money*)&_price + i, _price_frac + i, inf); + AddSingleInflation((Money*)&_price + i, _price_frac + i, inf.tovaluetype()); } - AddSingleInflation(&_economy.max_loan_unround, &_economy.max_loan_unround_fract, inf); + AddSingleInflation(&_economy.max_loan_unround, &_economy.max_loan_unround_fract, inf.tovaluetype()); if (_economy.max_loan + 50000 <= _economy.max_loan_unround) _economy.max_loan += 50000; @@ -690,7 +690,7 @@ AddSingleInflation( (Money*)_cargo_payment_rates + i, _cargo_payment_rates_frac + i, - inf + inf.tovaluetype() ); } @@ -711,7 +711,7 @@ _current_player = p->index; SET_EXPENSES_TYPE(EXPENSES_LOAN_INT); - SubtractMoneyFromPlayer(CommandCost((Money)BIGMULUS(p->current_loan, interest, 16))); + SubtractMoneyFromPlayer(CommandCost( (Money)BIGMULUS(p->current_loan.tovaluetype(), interest, 16))); SET_EXPENSES_TYPE(EXPENSES_OTHER); SubtractMoneyFromPlayer(_price.station_value >> 2); @@ -1207,7 +1207,7 @@ if (time_factor < MIN_TIME_FACTOR) time_factor = MIN_TIME_FACTOR; - return BIGMULSS(dist * time_factor * num_pieces, _cargo_payment_rates[cargo_type], 21); + return BIGMULSS(dist * time_factor * num_pieces, _cargo_payment_rates[cargo_type].tovaluetype(), 21); } static void DeliverGoodsToIndustry(TileIndex xy, CargoID cargo_type, int num_pieces) === src/vehicle_gui.cpp ================================================================== --- src/vehicle_gui.cpp (/openttd/trunk) (revision 153) +++ src/vehicle_gui.cpp (/openttd/safeint) (revision 153) @@ -580,7 +580,7 @@ { const Vehicle* va = *(const Vehicle**)a; const Vehicle* vb = *(const Vehicle**)b; - int r = ClampToI32(va->profit_this_year - vb->profit_this_year); + int r = ClampToI32((va->profit_this_year - vb->profit_this_year).tovaluetype()); VEHICLEUNITNUMBERSORTER(r, va, vb); @@ -591,7 +591,7 @@ { const Vehicle* va = *(const Vehicle**)a; const Vehicle* vb = *(const Vehicle**)b; - int r = ClampToI32(va->profit_last_year - vb->profit_last_year); + int r = ClampToI32((va->profit_last_year - vb->profit_last_year).tovaluetype()); VEHICLEUNITNUMBERSORTER(r, va, vb); @@ -683,7 +683,7 @@ for (u = va; u != NULL; u = u->Next()) valuea += u->value; for (u = vb; u != NULL; u = u->Next()) valueb += u->value; - int r = ClampToI32(valuea - valueb); + int r = ClampToI32((valuea - valueb).tovaluetype()); VEHICLEUNITNUMBERSORTER(r, va, vb); === src/network/network_server.cpp ================================================================== --- src/network/network_server.cpp (/openttd/trunk) (revision 153) +++ src/network/network_server.cpp (/openttd/safeint) (revision 153) @@ -96,9 +96,9 @@ p->Send_string(_network_player_info[player->index].company_name); p->Send_uint32(_network_player_info[player->index].inaugurated_year); - p->Send_uint64(_network_player_info[player->index].company_value); - p->Send_uint64(_network_player_info[player->index].money); - p->Send_uint64(_network_player_info[player->index].income); + p->Send_uint64(_network_player_info[player->index].company_value.tovaluetype()); + p->Send_uint64(_network_player_info[player->index].money.tovaluetype()); + p->Send_uint64(_network_player_info[player->index].income.tovaluetype()); p->Send_uint16(_network_player_info[player->index].performance); /* Send 1 if there is a passord for the company else send 0 */ === src/network/network_udp.cpp ================================================================== --- src/network/network_udp.cpp (/openttd/trunk) (revision 153) +++ src/network/network_udp.cpp (/openttd/safeint) (revision 153) @@ -118,9 +118,9 @@ packet.Send_string(_network_player_info[player->index].company_name); packet.Send_uint32(_network_player_info[player->index].inaugurated_year); - packet.Send_uint64(_network_player_info[player->index].company_value); - packet.Send_uint64(_network_player_info[player->index].money); - packet.Send_uint64(_network_player_info[player->index].income); + packet.Send_uint64(_network_player_info[player->index].company_value.tovaluetype()); + packet.Send_uint64(_network_player_info[player->index].money.tovaluetype()); + packet.Send_uint64(_network_player_info[player->index].income.tovaluetype()); packet.Send_uint16(_network_player_info[player->index].performance); /* Send 1 if there is a passord for the company else send 0 */ === src/players.cpp ================================================================== --- src/players.cpp (/openttd/trunk) (revision 153) +++ src/players.cpp (/openttd/safeint) (revision 153) @@ -230,9 +230,9 @@ byte m = p->player_money_fraction; Money cost = cst.GetCost(); - p->player_money_fraction = m - (byte)cost; + p->player_money_fraction = m - (byte)(cost.tovaluetype()); cost >>= 8; - if (p->player_money_fraction > m) cost++; + if (p->player_money_fraction > m) cost+= 1; if (cost != 0) SubtractMoneyFromAnyPlayer(p, CommandCost(cost)); } === src/openttd.h ================================================================== --- src/openttd.h (/openttd/trunk) (revision 153) +++ src/openttd.h (/openttd/safeint) (revision 153) @@ -69,7 +69,7 @@ typedef uint16 GroupID; typedef uint16 EngineRenewID; typedef uint16 DestinationID; -typedef int64 Money; +typedef OverflowSafeInt Money; /* DestinationID must be at least as large as every these below, because it can * be any of them === src/strings.h ================================================================== --- src/strings.h (/openttd/trunk) (revision 153) +++ src/strings.h (/openttd/safeint) (revision 153) @@ -24,7 +24,11 @@ assert(n < lengthof(_decode_parameters)); _decode_parameters[n] = v; } - +template +static inline void SetDParam(uint n, OverflowSafeInt v) +{ + SetDParam(n,v.tovaluetype()); +} /* Used to bind a C string name to a dparam number. * NOTE: This has a short lifetime. You can't * use this string much later or it will be gone. */ === src/newgrf_engine.cpp ================================================================== --- src/newgrf_engine.cpp (/openttd/trunk) (revision 153) +++ src/newgrf_engine.cpp (/openttd/safeint) (revision 153) @@ -725,19 +725,19 @@ case 0x4F: return GB(v->reliability, 8, 8); case 0x50: return v->reliability_spd_dec; case 0x51: return GB(v->reliability_spd_dec, 8, 8); - case 0x52: return ClampToI32(v->profit_this_year); - case 0x53: return GB(ClampToI32(v->profit_this_year), 8, 24); - case 0x54: return GB(ClampToI32(v->profit_this_year), 16, 16); - case 0x55: return GB(ClampToI32(v->profit_this_year), 24, 8); - case 0x56: return ClampToI32(v->profit_last_year); - case 0x57: return GB(ClampToI32(v->profit_last_year), 8, 24); - case 0x58: return GB(ClampToI32(v->profit_last_year), 16, 16); - case 0x59: return GB(ClampToI32(v->profit_last_year), 24, 8); + case 0x52: return ClampToI32(v->profit_this_year.tovaluetype()); + case 0x53: return GB(ClampToI32(v->profit_this_year.tovaluetype()), 8, 24); + case 0x54: return GB(ClampToI32(v->profit_this_year.tovaluetype()), 16, 16); + case 0x55: return GB(ClampToI32(v->profit_this_year.tovaluetype()), 24, 8); + case 0x56: return ClampToI32(v->profit_last_year.tovaluetype()); + case 0x57: return GB(ClampToI32(v->profit_last_year.tovaluetype()), 8, 24); + case 0x58: return GB(ClampToI32(v->profit_last_year.tovaluetype()), 16, 16); + case 0x59: return GB(ClampToI32(v->profit_last_year.tovaluetype()), 24, 8); case 0x5A: return v->Next() == NULL ? INVALID_VEHICLE : v->Next()->index; - case 0x5C: return ClampToI32(v->value); - case 0x5D: return GB(ClampToI32(v->value), 8, 24); - case 0x5E: return GB(ClampToI32(v->value), 16, 16); - case 0x5F: return GB(ClampToI32(v->value), 24, 8); + case 0x5C: return ClampToI32(v->value.tovaluetype()); + case 0x5D: return GB(ClampToI32(v->value.tovaluetype()), 8, 24); + case 0x5E: return GB(ClampToI32(v->value.tovaluetype()), 16, 16); + case 0x5F: return GB(ClampToI32(v->value.tovaluetype()), 24, 8); case 0x60: return v->string_id; case 0x61: return GB(v->string_id, 8, 8); case 0x72: return v->cargo_subtype; === src/graph_gui.cpp ================================================================== --- src/graph_gui.cpp (/openttd/trunk) (revision 153) +++ src/graph_gui.cpp (/openttd/safeint) (revision 153) @@ -139,7 +139,7 @@ /* For now, if the graph has negative values the scaling is * symmetrical about the x axis, so take the absolute value * of each data point. */ - highest_value = max(highest_value, myabs(datapoint)); + highest_value = max(highest_value, myabs(datapoint).tovaluetype()); } } } @@ -220,7 +220,7 @@ if (datapoint != INVALID_DATAPOINT) { /* XXX: This can overflow if x_axis_offset * datapoint is * too big to fit in an int64. */ - y = gw->top + x_axis_offset - (x_axis_offset * datapoint) / highest_value; + y = gw->top + x_axis_offset - (x_axis_offset * datapoint.tovaluetype()) / highest_value; /* Draw the point. */ GfxFillRect(x - 1, y - 1, x + 1, y + 1, color); === src/misc_cmd.cpp ================================================================== --- src/misc_cmd.cpp (/openttd/trunk) (revision 153) +++ src/misc_cmd.cpp (/openttd/safeint) (revision 153) @@ -174,7 +174,7 @@ switch (p2) { default: return CMD_ERROR; // Invalid method case 0: // Pay back one step - loan = min(p->current_loan, (Money)(IsHumanPlayer(_current_player) || _patches.ainew_active) ? LOAN_INTERVAL : LOAN_INTERVAL_OLD_AI); + loan = min(p->current_loan.tovaluetype(), (IsHumanPlayer(_current_player) || _patches.ainew_active) ? LOAN_INTERVAL : LOAN_INTERVAL_OLD_AI); break; case 1: // Pay back as much as possible loan = max(min(p->current_loan, p->player_money), (Money)LOAN_INTERVAL); === src/helpers.hpp ================================================================== --- src/helpers.hpp (/openttd/trunk) (revision 153) +++ src/helpers.hpp (/openttd/safeint) (revision 153) @@ -158,4 +158,176 @@ t = (T)(t ^ ((T)1 << bit_index)); } +template +class OverflowSafeInt +{ +private: + T m_value; +public: + OverflowSafeInt():m_value(0) + { + + } + + OverflowSafeInt(const OverflowSafeInt& other) + { + this->m_value = other.m_value; + } + OverflowSafeInt(const int64 int_) + { + this->m_value = int_; + } + + OverflowSafeInt& operator=(const OverflowSafeInt& other) + { + if(this == &other) return *this; + + this->m_value = other.m_value; + return *this; + } + OverflowSafeInt& operator*=(const int64 factor) + { + + if (factor != 0 && (T_MAX / myabs(factor)) < myabs(this->m_value)) { + this->m_value = (this->m_value < 0 == factor < 0) ? T_MAX : T_MIN ; + } else { + this->m_value *= factor ; + } + return *this; + } + const OverflowSafeInt operator*(const int64 factor) const + { + OverflowSafeInt result = *this; + result *= factor; + return result; + } + + OverflowSafeInt& operator+=(const OverflowSafeInt& other) + { + if(T_MAX - myabs(other.m_value) < myabs(this->m_value) ){ + if((this->m_value < 0 == other.m_value < 0)){ + + this->m_value = (this->m_value < 0) ? T_MIN : T_MAX ; + return *this; + } + } + this->m_value += other.m_value; + return *this; + } + const OverflowSafeInt operator+(const OverflowSafeInt& other) const + { + OverflowSafeInt result = *this; + result += other; + return result; + } + + OverflowSafeInt operator-() const + { + return OverflowSafeInt(-this->m_value); + } + + OverflowSafeInt& operator-=(const OverflowSafeInt& other) + { + return *this += (-other); + } + const OverflowSafeInt operator-(const OverflowSafeInt& other) const + { + OverflowSafeInt result = *this; + result -= other; + return result; + } + OverflowSafeInt& operator/=(const int64 divisor) + { + this->m_value /= divisor; + return *this; + } + const OverflowSafeInt operator/(const int64 divisor) const + { + OverflowSafeInt result = *this; + result /= divisor; + return result; + } + OverflowSafeInt& operator%=(const int64 divisor) + { + this->m_value %= divisor; + return *this; + } + const OverflowSafeInt operator%(const int64 divisor) const + { + OverflowSafeInt result = *this; + result %= divisor; + return result; + } + OverflowSafeInt& operator<<=(const uint16 shift) + { + this->m_value <<= shift; + return *this; + } + const OverflowSafeInt operator<<(const uint16 shift) const + { + OverflowSafeInt result = *this; + result <<= shift; + return result; + } + OverflowSafeInt& operator>>=(const uint16 shift) + { + this->m_value >>= shift; + return *this; + } + const OverflowSafeInt operator>>(const uint16 shift) const + { + OverflowSafeInt result = *this; + result >>= shift; + return result; + } + + bool operator==(const OverflowSafeInt& other) const + { + return this->m_value == other.m_value; + } + bool operator!=(const OverflowSafeInt& other) const + { + return !(*this == other); + } + bool operator>(const OverflowSafeInt& other) const + { + return this->m_value > other.m_value; + } + bool operator>=(const OverflowSafeInt& other) const + { + return this->m_value > other.m_value; + } + bool operator<(const OverflowSafeInt& other) const + { + return !(*this >= other); + } + bool operator<=(const OverflowSafeInt& other) const + { + return !(*this > other); + } + T tovaluetype() const + { + return m_value; + } + +}; + +template +OverflowSafeInt operator+(int64 a, OverflowSafeInt b) +{ + return b + a; +} + +template +OverflowSafeInt operator*(int64 a, OverflowSafeInt b) +{ + return b * a; +} + +template +OverflowSafeInt operator-(int64 a, OverflowSafeInt b) +{ + return b - a; +} + #endif /* HELPERS_HPP */ === src/main_gui.cpp ================================================================== --- src/main_gui.cpp (/openttd/trunk) (revision 153) +++ src/main_gui.cpp (/openttd/safeint) (revision 153) @@ -92,7 +92,7 @@ const Player *p = GetPlayer(_current_player); Money money = min(p->player_money - p->current_loan, (Money)(atoi(str) / _currency->rate)); - uint32 money_c = clamp(ClampToI32(money), 0, 20000000); // Clamp between 20 million and 0 + uint32 money_c = clamp(ClampToI32(money.tovaluetype()), 0, 20000000); // Clamp between 20 million and 0 /* Give 'id' the money, and substract it from ourself */ DoCommandP(0, money_c, id, CcGiveMoney, CMD_GIVE_MONEY | CMD_MSG(STR_INSUFFICIENT_FUNDS));