Add setting for milliseconds per game tick mode
This commit is contained in:
@@ -24,8 +24,8 @@ typedef uint8 Day; ///< Type for the day of the month, note: 1 based, first d
|
||||
/**
|
||||
* 1 day is 74 ticks; _date_fract used to be uint16 and incremented by 885. On
|
||||
* an overflow the new day begun and 65535 / 885 = 74.
|
||||
* 1 tick is approximately 30 ms.
|
||||
* 1 day is thus about 2 seconds (74 * 30 = 2220) on a machine that can run OpenTTD normally
|
||||
* 1 tick is approximately 27 ms.
|
||||
* 1 day is thus about 2 seconds (74 * 27 = 1998) on a machine that can run OpenTTD normally
|
||||
*/
|
||||
static const int DAY_TICKS = 74; ///< ticks per day
|
||||
static const int DAYS_IN_YEAR = 365; ///< days per year
|
||||
|
@@ -241,4 +241,11 @@ enum CargoPaymentAlgorithm : byte {
|
||||
CPA_END, ///< Used for iterations and limit testing
|
||||
};
|
||||
|
||||
enum TickRateMode : byte {
|
||||
TRM_BEGIN = 0, ///< Used for iterations and limit testing
|
||||
TRM_TRADITIONAL = 0, ///< Traditional value (30ms)
|
||||
TRM_MODERN, ///< Modern value (27ms)
|
||||
TRM_END, ///< Used for iterations and limit testing
|
||||
};
|
||||
|
||||
#endif /* ECONOMY_TYPE_H */
|
||||
|
@@ -183,16 +183,13 @@ namespace {
|
||||
}
|
||||
};
|
||||
|
||||
/** %Game loop rate, cycles per second */
|
||||
static const double GL_RATE = 1000.0 / MILLISECONDS_PER_TICK;
|
||||
|
||||
/**
|
||||
* Storage for all performance element measurements.
|
||||
* Elements are initialized with the expected rate in recorded values per second.
|
||||
* @hideinitializer
|
||||
*/
|
||||
PerformanceData _pf_data[PFE_MAX] = {
|
||||
PerformanceData(GL_RATE), // PFE_GAMELOOP
|
||||
PerformanceData(1), // PFE_GAMELOOP
|
||||
PerformanceData(1), // PFE_ACC_GL_ECONOMY
|
||||
PerformanceData(1), // PFE_ACC_GL_TRAINS
|
||||
PerformanceData(1), // PFE_ACC_GL_ROADVEHS
|
||||
@@ -479,6 +476,7 @@ struct FramerateWindow : Window {
|
||||
|
||||
void UpdateData()
|
||||
{
|
||||
_pf_data[PFE_GAMELOOP].expected_rate = _ticks_per_second;
|
||||
double gl_rate = _pf_data[PFE_GAMELOOP].GetRate();
|
||||
bool have_script = false;
|
||||
this->rate_gameloop.SetRate(gl_rate, _pf_data[PFE_GAMELOOP].expected_rate);
|
||||
|
@@ -46,6 +46,8 @@ bool _shift_pressed; ///< Is Shift pressed?
|
||||
bool _invert_ctrl;
|
||||
bool _invert_shift;
|
||||
uint16 _game_speed = 100; ///< Current game-speed; 100 is 1x, 0 is infinite.
|
||||
uint8 _milliseconds_per_tick = 27; ///< Milliseconds per tick
|
||||
float _ticks_per_second; ///< Ticks per second
|
||||
bool _left_button_down; ///< Is left mouse button pressed?
|
||||
bool _left_button_clicked; ///< Is left mouse button clicked?
|
||||
bool _right_button_down; ///< Is right mouse button pressed?
|
||||
@@ -2439,3 +2441,9 @@ void ChangeGameSpeed(bool enable_fast_forward)
|
||||
_game_speed = 100;
|
||||
}
|
||||
}
|
||||
|
||||
void SetupTickRate()
|
||||
{
|
||||
_milliseconds_per_tick = (_settings_game.economy.tick_rate == TRM_MODERN) ? 27 : 30;
|
||||
_ticks_per_second = 1000.0f / _milliseconds_per_tick;
|
||||
}
|
||||
|
@@ -56,6 +56,8 @@ extern bool _shift_pressed; ///< Is Shift pressed?
|
||||
extern bool _invert_ctrl;
|
||||
extern bool _invert_shift;
|
||||
extern uint16 _game_speed;
|
||||
extern uint8 _milliseconds_per_tick;
|
||||
extern float _ticks_per_second;
|
||||
|
||||
extern bool _left_button_down;
|
||||
extern bool _left_button_clicked;
|
||||
@@ -79,6 +81,7 @@ void HandleShiftChanged();
|
||||
void HandleMouseEvents();
|
||||
void UpdateWindows();
|
||||
void ChangeGameSpeed(bool enable_fast_forward);
|
||||
void SetupTickRate();
|
||||
|
||||
void DrawMouseCursor();
|
||||
void ScreenSizeChanged();
|
||||
|
@@ -317,8 +317,12 @@ enum SpriteType : byte {
|
||||
ST_INVALID = 4, ///< Pseudosprite or other unusable sprite, used only internally
|
||||
};
|
||||
|
||||
/** The number of milliseconds per game tick. */
|
||||
static const uint MILLISECONDS_PER_TICK = 30;
|
||||
/**
|
||||
* The number of milliseconds per game tick.
|
||||
* The value 27 together with a day length of 74 ticks makes one day 1998 milliseconds, almost exactly 2 seconds.
|
||||
* With a 2 second day, one standard month is 1 minute, and one standard year is slightly over 12 minutes.
|
||||
*/
|
||||
#define MILLISECONDS_PER_TICK ((uint)_milliseconds_per_tick)
|
||||
|
||||
/** Information about the currently used palette. */
|
||||
struct Palette {
|
||||
|
@@ -599,6 +599,11 @@ STR_CONFIG_SETTING_CARGO_PAYMENT_ALGORITHM_HELPTEXT :The algorithm t
|
||||
STR_CONFIG_SETTING_CARGO_PAYMENT_ALGORITHM_TRADITIONAL :Traditional
|
||||
STR_CONFIG_SETTING_CARGO_PAYMENT_ALGORITHM_MODERN :Modern
|
||||
|
||||
STR_CONFIG_SETTING_TICK_RATE :Game tick rate: {STRING2}
|
||||
STR_CONFIG_SETTING_TICK_RATE_HELPTEXT :Number of milliseconds per game tick.
|
||||
STR_CONFIG_SETTING_TICK_RATE_TRADITIONAL :30 ms/tick (traditional)
|
||||
STR_CONFIG_SETTING_TICK_RATE_MODERN :27 ms/tick (modern)
|
||||
|
||||
STR_CONFIG_SETTING_TOWN_MIN_DISTANCE :Minimum distance between towns: {STRING2}
|
||||
STR_CONFIG_SETTING_TOWN_MIN_DISTANCE_HELPTEXT :Set the minimum distance in tiles between towns for map generation and random founding
|
||||
|
||||
|
@@ -568,6 +568,8 @@ void MakeNewgameSettingsLive()
|
||||
if (_settings_newgame.game_config != nullptr) {
|
||||
_settings_game.game_config = new GameConfig(_settings_newgame.game_config);
|
||||
}
|
||||
|
||||
SetupTickRate();
|
||||
}
|
||||
|
||||
void OpenBrowser(const char *url)
|
||||
@@ -2027,7 +2029,7 @@ void StateGameLoop()
|
||||
_scaled_date_ticks++; // This must update in lock-step with _tick_skip_counter, such that it always matches what SetScaledTickVariables would return.
|
||||
|
||||
if (_settings_client.gui.autosave == 6 && !(_game_mode == GM_MENU || _game_mode == GM_BOOTSTRAP) &&
|
||||
(_scaled_date_ticks % (_settings_client.gui.autosave_custom_minutes * (60000 / MILLISECONDS_PER_TICK))) == 0) {
|
||||
(_scaled_date_ticks % (_settings_client.gui.autosave_custom_minutes * (_settings_game.economy.tick_rate == TRM_MODERN ? (60000 / 27) : (60000 / 30)))) == 0) {
|
||||
_do_autosave = true;
|
||||
_check_special_modes = true;
|
||||
SetWindowDirty(WC_STATUS_BAR, 0);
|
||||
|
@@ -4191,6 +4191,10 @@ bool AfterLoadGame()
|
||||
_settings_game.economy.payment_algorithm = IsSavegameVersionBefore(SLV_MORE_CARGO_AGE) ? CPA_TRADITIONAL : CPA_MODERN;
|
||||
}
|
||||
|
||||
if (SlXvIsFeatureMissing(XSLFI_VARIABLE_TICK_RATE)) {
|
||||
_settings_game.economy.tick_rate = IsSavegameVersionUntil(SLV_MORE_CARGO_AGE) ? TRM_TRADITIONAL : TRM_MODERN;
|
||||
}
|
||||
|
||||
InitializeRoadGUI();
|
||||
|
||||
/* This needs to be done after conversion. */
|
||||
@@ -4207,6 +4211,8 @@ bool AfterLoadGame()
|
||||
|
||||
GamelogPrintDebug(1);
|
||||
|
||||
SetupTickRate();
|
||||
|
||||
InitializeWindowsAndCaches();
|
||||
/* Restore the signals */
|
||||
ResetSignalHandlers();
|
||||
|
@@ -188,6 +188,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
|
||||
{ XSLFI_MULTI_CARGO_SHIPS, XSCF_NULL, 1, 1, "multi_cargo_ships", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_REMAIN_NEXT_ORDER_STATION, XSCF_IGNORABLE_UNKNOWN, 1, 1, "remain_next_order_station", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_LABEL_ORDERS, XSCF_NULL, 2, 2, "label_orders", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_VARIABLE_TICK_RATE, XSCF_IGNORABLE_ALL, 1, 1, "variable_tick_rate", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_SCRIPT_INT64, XSCF_NULL, 1, 1, "script_int64", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_U64_TICK_COUNTER, XSCF_NULL, 1, 1, "u64_tick_counter", nullptr, nullptr, nullptr },
|
||||
{ XSLFI_LINKGRAPH_TRAVEL_TIME, XSCF_NULL, 1, 1, "linkgraph_travel_time", nullptr, nullptr, nullptr },
|
||||
|
@@ -139,6 +139,7 @@ enum SlXvFeatureIndex {
|
||||
XSLFI_MULTI_CARGO_SHIPS, ///< Multi-cargo ships
|
||||
XSLFI_REMAIN_NEXT_ORDER_STATION, ///< Remain in station if next order is for same station
|
||||
XSLFI_LABEL_ORDERS, ///< Label orders
|
||||
XSLFI_VARIABLE_TICK_RATE, ///< Variable tick rate
|
||||
|
||||
XSLFI_SCRIPT_INT64, ///< See: SLV_SCRIPT_INT64
|
||||
XSLFI_U64_TICK_COUNTER, ///< See: SLV_U64_TICK_COUNTER
|
||||
|
@@ -2295,6 +2295,7 @@ static SettingsContainer &GetSettingsTree()
|
||||
environment->Add(new SettingEntry("station.catchment_increase"));
|
||||
environment->Add(new SettingEntry("station.cargo_class_rating_wait_time"));
|
||||
environment->Add(new SettingEntry("station.station_size_rating_cargo_amount"));
|
||||
environment->Add(new SettingEntry("economy.tick_rate"));
|
||||
}
|
||||
|
||||
SettingsPage *ai = main->Add(new SettingsPage(STR_CONFIG_SETTING_AI));
|
||||
|
@@ -706,6 +706,7 @@ struct EconomySettings {
|
||||
uint16 random_road_reconstruction; ///< chance out of 1000 per tile loop for towns to start random road re-construction
|
||||
bool disable_inflation_newgrf_flag; ///< Disable NewGRF inflation flag
|
||||
CargoPaymentAlgorithm payment_algorithm; ///< Cargo payment algorithm
|
||||
TickRateMode tick_rate; ///< Tick rate mode
|
||||
};
|
||||
|
||||
struct LinkGraphSettings {
|
||||
|
@@ -3251,6 +3251,21 @@ strval = STR_CONFIG_SETTING_CARGO_PAYMENT_ALGORITHM_TRADITIONAL
|
||||
cat = SC_BASIC
|
||||
patxname = ""economy.payment_algorithm""
|
||||
|
||||
[SDT_VAR]
|
||||
var = economy.tick_rate
|
||||
type = SLE_UINT8
|
||||
flags = SF_GUI_DROPDOWN
|
||||
def = TRM_TRADITIONAL
|
||||
min = TRM_BEGIN
|
||||
max = TRM_END - 1
|
||||
interval = 1
|
||||
str = STR_CONFIG_SETTING_TICK_RATE
|
||||
strhelp = STR_CONFIG_SETTING_TICK_RATE_HELPTEXT
|
||||
strval = STR_CONFIG_SETTING_TICK_RATE_TRADITIONAL
|
||||
cat = SC_EXPERT
|
||||
post_cb = [](auto) { SetupTickRate(); }
|
||||
patxname = ""economy.tick_rate""
|
||||
|
||||
##
|
||||
[SDT_VAR]
|
||||
var = pf.wait_for_pbs_path
|
||||
|
Reference in New Issue
Block a user