diff --git a/src/date.cpp b/src/date.cpp index 0caef64b2a..b8b736382a 100644 --- a/src/date.cpp +++ b/src/date.cpp @@ -30,6 +30,8 @@ Date _date; ///< Current date in days (day counter) DateFract _date_fract; ///< Fractional part of the day. uint16 _tick_counter; ///< Ever incrementing (and sometimes wrapping) tick counter for setting off various events uint8 _tick_skip_counter; ///< Counter for ticks, when only vehicles are moving and nothing else happens +uint32 _scaled_tick_counter; ///< Tick counter in daylength-scaled ticks +DateTicksScaled _scaled_date_ticks; ///< Date as ticks in daylength-scaled ticks /** * Set the date. @@ -47,6 +49,13 @@ void SetDate(Date date, DateFract fract) ConvertDateToYMD(date, &ymd); _cur_year = ymd.year; _cur_month = ymd.month; + SetScaledTickVariables(); +} + +void SetScaledTickVariables() +{ + _scaled_date_ticks = ((((DateTicksScaled)_date * DAY_TICKS) + _date_fract) * _settings_game.economy.day_length_factor) + _tick_skip_counter; + _scaled_tick_counter = (((uint32)_tick_counter) * _settings_game.economy.day_length_factor) + _tick_skip_counter; } #define M(a, b) ((a << 5) | b) diff --git a/src/date_func.h b/src/date_func.h index bf12ba2ec6..3825938c1f 100644 --- a/src/date_func.h +++ b/src/date_func.h @@ -20,10 +20,13 @@ extern Date _date; extern DateFract _date_fract; extern uint16 _tick_counter; extern uint8 _tick_skip_counter; +extern uint32 _scaled_tick_counter; +extern DateTicksScaled _scaled_date_ticks; void SetDate(Date date, DateFract fract); void ConvertDateToYMD(Date date, YearMonthDay *ymd); Date ConvertYMDToDate(Year year, Month month, Day day); +void SetScaledTickVariables(); #define YMD_TO_DATE(ymd) (ConvertYMDToDate(ymd.year, ymd.month, ymd.day)) diff --git a/src/date_type.h b/src/date_type.h index 6879f55411..e69457070f 100644 --- a/src/date_type.h +++ b/src/date_type.h @@ -33,9 +33,6 @@ static const int DAY_TICKS = 74; ///< ticks per day static const int DAYS_IN_YEAR = 365; ///< days per year static const int DAYS_IN_LEAP_YEAR = 366; ///< sometimes, you need one day more... -#define CURRENT_SCALED_TICKS (((((DateTicksScaled)_date * DAY_TICKS) + _date_fract) * _settings_game.economy.day_length_factor) + _tick_skip_counter) -#define SCALED_TICK_COUNTER ((((uint32)_tick_counter) * _settings_game.economy.day_length_factor) + _tick_skip_counter) - #define DATE_UNIT_SIZE (_settings_client.gui.time_in_minutes ? _settings_client.gui.ticks_per_minute : (DAY_TICKS * _settings_game.economy.day_length_factor)) static const int STATION_RATING_TICKS = 185; ///< cycle duration for updating station rating @@ -115,7 +112,7 @@ static const Year MAX_YEAR = 5000000; #define MINUTES_DATE(day, hour, minute) ((day * 1440) + (hour * 60) + minute) /** Get the current date in minutes */ -#define CURRENT_MINUTE (CURRENT_SCALED_TICKS / _settings_client.gui.ticks_per_minute) +#define CURRENT_MINUTE (_scaled_date_ticks / _settings_client.gui.ticks_per_minute) /** * Data structure to convert between Date and triplet (year, month, and day). diff --git a/src/departures_gui.cpp b/src/departures_gui.cpp index 94891d7681..7a796b6bf9 100644 --- a/src/departures_gui.cpp +++ b/src/departures_gui.cpp @@ -566,7 +566,7 @@ void DeparturesWindow::DrawDeparturesListItems(const Rect &r) const uint departure = 0; uint arrival = 0; - DateTicksScaled now_date = CURRENT_SCALED_TICKS; + DateTicksScaled now_date = _scaled_date_ticks; DateTicksScaled max_date = now_date + (_settings_client.gui.max_departure_time * DAY_TICKS * _settings_game.economy.day_length_factor); /* Draw each departure. */ diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 6225710bfb..856d80fe97 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -540,7 +540,7 @@ static void AnimateTile_Industry(TileIndex tile) switch (gfx) { case GFX_SUGAR_MINE_SIEVE: - if ((SCALED_TICK_COUNTER & 1) == 0) { + if ((_scaled_tick_counter & 1) == 0) { byte m = GetAnimationFrame(tile) + 1; if (_settings_client.sound.ambient) { @@ -561,7 +561,7 @@ static void AnimateTile_Industry(TileIndex tile) break; case GFX_TOFFEE_QUARY: - if ((SCALED_TICK_COUNTER & 3) == 0) { + if ((_scaled_tick_counter & 3) == 0) { byte m = GetAnimationFrame(tile); if (_industry_anim_offs_toffee[m] == 0xFF && _settings_client.sound.ambient) { @@ -579,7 +579,7 @@ static void AnimateTile_Industry(TileIndex tile) break; case GFX_BUBBLE_CATCHER: - if ((SCALED_TICK_COUNTER & 1) == 0) { + if ((_scaled_tick_counter & 1) == 0) { byte m = GetAnimationFrame(tile); if (++m >= 40) { @@ -594,7 +594,7 @@ static void AnimateTile_Industry(TileIndex tile) /* Sparks on a coal plant */ case GFX_POWERPLANT_SPARKS: - if ((SCALED_TICK_COUNTER & 3) == 0) { + if ((_scaled_tick_counter & 3) == 0) { byte m = GetAnimationFrame(tile); if (m == 6) { SetAnimationFrame(tile, 0); @@ -607,7 +607,7 @@ static void AnimateTile_Industry(TileIndex tile) break; case GFX_TOY_FACTORY: - if ((SCALED_TICK_COUNTER & 1) == 0) { + if ((_scaled_tick_counter & 1) == 0) { byte m = GetAnimationFrame(tile) + 1; switch (m) { @@ -635,7 +635,7 @@ static void AnimateTile_Industry(TileIndex tile) case GFX_PLASTIC_FOUNTAIN_ANIMATED_3: case GFX_PLASTIC_FOUNTAIN_ANIMATED_4: case GFX_PLASTIC_FOUNTAIN_ANIMATED_5: case GFX_PLASTIC_FOUNTAIN_ANIMATED_6: case GFX_PLASTIC_FOUNTAIN_ANIMATED_7: case GFX_PLASTIC_FOUNTAIN_ANIMATED_8: - if ((SCALED_TICK_COUNTER & 3) == 0) { + if ((_scaled_tick_counter & 3) == 0) { IndustryGfx gfx = GetIndustryGfx(tile); gfx = (gfx < 155) ? gfx + 1 : 148; @@ -647,7 +647,7 @@ static void AnimateTile_Industry(TileIndex tile) case GFX_OILWELL_ANIMATED_1: case GFX_OILWELL_ANIMATED_2: case GFX_OILWELL_ANIMATED_3: - if ((SCALED_TICK_COUNTER & 7) == 0) { + if ((_scaled_tick_counter & 7) == 0) { bool b = Chance16(1, 7); IndustryGfx gfx = GetIndustryGfx(tile); @@ -667,7 +667,7 @@ static void AnimateTile_Industry(TileIndex tile) case GFX_COAL_MINE_TOWER_ANIMATED: case GFX_COPPER_MINE_TOWER_ANIMATED: case GFX_GOLD_MINE_TOWER_ANIMATED: { - int state = SCALED_TICK_COUNTER & 0x7FF; + int state = _scaled_tick_counter & 0x7FF; if ((state -= 0x400) < 0) return; @@ -827,7 +827,7 @@ static void TileLoop_Industry(TileIndex tile) case GFX_COAL_MINE_TOWER_NOT_ANIMATED: case GFX_COPPER_MINE_TOWER_NOT_ANIMATED: case GFX_GOLD_MINE_TOWER_NOT_ANIMATED: - if (!(SCALED_TICK_COUNTER & 0x400) && Chance16(1, 2)) { + if (!(_scaled_tick_counter & 0x400) && Chance16(1, 2)) { switch (gfx) { case GFX_COAL_MINE_TOWER_NOT_ANIMATED: gfx = GFX_COAL_MINE_TOWER_ANIMATED; break; case GFX_COPPER_MINE_TOWER_NOT_ANIMATED: gfx = GFX_COPPER_MINE_TOWER_ANIMATED; break; @@ -850,7 +850,7 @@ static void TileLoop_Industry(TileIndex tile) case GFX_COAL_MINE_TOWER_ANIMATED: case GFX_COPPER_MINE_TOWER_ANIMATED: case GFX_GOLD_MINE_TOWER_ANIMATED: - if (!(SCALED_TICK_COUNTER & 0x400)) { + if (!(_scaled_tick_counter & 0x400)) { switch (gfx) { case GFX_COAL_MINE_TOWER_ANIMATED: gfx = GFX_COAL_MINE_TOWER_NOT_ANIMATED; break; case GFX_COPPER_MINE_TOWER_ANIMATED: gfx = GFX_COPPER_MINE_TOWER_NOT_ANIMATED; break; diff --git a/src/misc.cpp b/src/misc.cpp index 1e7c05c6be..31cdfb470b 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -75,6 +75,8 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin if (reset_date) { SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1), 0); InitializeOldNames(); + } else { + SetScaledTickVariables(); } LinkGraphSchedule::Clear(); diff --git a/src/newgrf.cpp b/src/newgrf.cpp index b7d629dd42..ce1c6ff079 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -9226,6 +9226,7 @@ void LoadNewGRF(uint load_index, uint file_index) Year year = _cur_year; DateFract date_fract = _date_fract; uint16 tick_counter = _tick_counter; + uint8 tick_skip_counter = _tick_skip_counter; byte display_opt = _display_opt; if (_networking) { @@ -9233,7 +9234,9 @@ void LoadNewGRF(uint load_index, uint file_index) _date = ConvertYMDToDate(_cur_year, 0, 1); _date_fract = 0; _tick_counter = 0; + _tick_skip_counter = 0; _display_opt = 0; + SetScaledTickVariables(); } InitializeGRFSpecial(); @@ -9316,7 +9319,9 @@ void LoadNewGRF(uint load_index, uint file_index) _date = date; _date_fract = date_fract; _tick_counter = tick_counter; + _tick_skip_counter = tick_skip_counter; _display_opt = display_opt; + SetScaledTickVariables(); } /** diff --git a/src/newgrf_animation_base.h b/src/newgrf_animation_base.h index d706145da7..dbe2c53eb4 100644 --- a/src/newgrf_animation_base.h +++ b/src/newgrf_animation_base.h @@ -56,7 +56,7 @@ struct AnimationBase { * increasing this value by one doubles the wait. 0 is the minimum value * allowed for animation_speed, which corresponds to 30ms, and 16 is the * maximum, corresponding to around 33 minutes. */ - if (SCALED_TICK_COUNTER % (1 << animation_speed) != 0) return; + if (_scaled_tick_counter % (1 << animation_speed) != 0) return; uint8 frame = GetAnimationFrame(tile); uint8 num_frames = spec->animation.frames; diff --git a/src/openttd.cpp b/src/openttd.cpp index 4458450fb9..bfd9cd59fa 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -1262,7 +1262,7 @@ void CheckCaches(bool force_check) * always to aid testing of caches. */ if (_debug_desync_level < 1) return; - if (_debug_desync_level == 1 && CURRENT_SCALED_TICKS % 500 != 0) return; + if (_debug_desync_level == 1 && _scaled_date_ticks % 500 != 0) return; } /* Check the town caches. */ @@ -1527,13 +1527,15 @@ void StateGameLoop() BasePersistentStorageArray::SwitchMode(PSM_ENTER_GAMELOOP); _tick_skip_counter++; + _scaled_tick_counter++; // This must update in lock-step with _tick_skip_counter, such that it always matches what SetScaledTickVariables would return. + _scaled_date_ticks++; // " if (_tick_skip_counter < _settings_game.economy.day_length_factor) { AnimateAnimatedTiles(); CallVehicleTicks(); } else { _tick_skip_counter = 0; - AnimateAnimatedTiles(); IncreaseDate(); + AnimateAnimatedTiles(); RunTileLoop(); CallVehicleTicks(); CallLandscapeTick(); diff --git a/src/saveload/misc_sl.cpp b/src/saveload/misc_sl.cpp index e25a8f78ba..c4dc223100 100644 --- a/src/saveload/misc_sl.cpp +++ b/src/saveload/misc_sl.cpp @@ -127,6 +127,7 @@ static const SaveLoadGlobVarList _date_check_desc[] = { static void SaveLoad_DATE() { SlGlobList(_date_desc); + SetScaledTickVariables(); } static void Check_DATE() diff --git a/src/settings.cpp b/src/settings.cpp index bbc3cd5ade..03af43b952 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1376,6 +1376,12 @@ static bool ImprovedBreakdownsSettingChanged(int32 p1) return true; } +static bool DayLengthChanged(int32 p1) +{ + SetScaledTickVariables(); + return true; +} + #ifdef ENABLE_NETWORK static bool UpdateClientName(int32 p1) diff --git a/src/statusbar_gui.cpp b/src/statusbar_gui.cpp index 3e90fb156a..55bcac49aa 100644 --- a/src/statusbar_gui.cpp +++ b/src/statusbar_gui.cpp @@ -139,7 +139,7 @@ struct StatusBarWindow : Window { switch (widget) { case WID_S_LEFT: /* Draw the date */ - SetDParam(0, CURRENT_SCALED_TICKS); + SetDParam(0, _scaled_date_ticks); DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_WHITE_DATE_WALLCLOCK_LONG, TC_FROMSTRING, SA_HOR_CENTER); break; diff --git a/src/table/settings.ini b/src/table/settings.ini index eddc211545..dc011a20f1 100644 --- a/src/table/settings.ini +++ b/src/table/settings.ini @@ -43,6 +43,7 @@ static bool InvalidateCompanyWindow(int32 p1); static bool ZoomMinMaxChanged(int32 p1); static bool MaxVehiclesChanged(int32 p1); static bool ImprovedBreakdownsSettingChanged(int32 p1); +static bool DayLengthChanged(int32 p1); #ifdef ENABLE_NETWORK static bool UpdateClientName(int32 p1); @@ -1438,6 +1439,7 @@ max = 125 str = STR_CONFIG_SETTING_DAY_LENGTH_FACTOR strhelp = STR_CONFIG_SETTING_DAY_LENGTH_FACTOR_HELPTEXT strval = STR_JUST_COMMA +proc = DayLengthChanged cat = SC_BASIC extver = SlXvFeatureTest(XSLFTO_AND, XSLFI_VARIABLE_DAY_LENGTH) patxname = ""variable_day_length.economy.day_length_factor"" diff --git a/src/timetable_cmd.cpp b/src/timetable_cmd.cpp index 980f14181e..dbacb7c678 100644 --- a/src/timetable_cmd.cpp +++ b/src/timetable_cmd.cpp @@ -332,7 +332,7 @@ CommandCost CmdSetTimetableStart(TileIndex tile, DoCommandFlag flags, uint32 p1, if (timetable_all && !v->orders.list->IsCompleteTimetable()) return CMD_ERROR; - const DateTicksScaled now = CURRENT_SCALED_TICKS; + const DateTicksScaled now = _scaled_date_ticks; DateTicksScaled start_date_scaled = (_settings_game.economy.day_length_factor * (((DateTicks)_date * DAY_TICKS) + _date_fract + (DateTicks)(int32)p2)) + sub_ticks; if (flags & DC_EXEC) { @@ -698,7 +698,7 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling) just_started = !HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED); if (v->timetable_start != 0) { - v->lateness_counter = CURRENT_SCALED_TICKS - ((_settings_game.economy.day_length_factor * v->timetable_start) + v->timetable_start_subticks); + v->lateness_counter = _scaled_date_ticks - ((_settings_game.economy.day_length_factor * v->timetable_start) + v->timetable_start_subticks); v->timetable_start = 0; v->timetable_start_subticks = 0; } diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index dd6fe3355c..aa5204bb3e 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.cpp @@ -491,10 +491,10 @@ struct TimetableWindow : Window { if (arr_dep[i / 2].arrival != INVALID_TICKS) { DrawString(abbr_left, abbr_right, y, STR_TIMETABLE_ARRIVAL_ABBREVIATION, i == selected ? TC_WHITE : TC_BLACK); if (this->show_expected && i / 2 == earlyID) { - SetDParam(0, CURRENT_SCALED_TICKS + arr_dep[i / 2].arrival); + SetDParam(0, _scaled_date_ticks + arr_dep[i / 2].arrival); DrawString(time_left, time_right, y, STR_JUST_DATE_WALLCLOCK_TINY, TC_GREEN); } else { - SetDParam(0, CURRENT_SCALED_TICKS + arr_dep[i / 2].arrival + offset); + SetDParam(0, _scaled_date_ticks + arr_dep[i / 2].arrival + offset); DrawString(time_left, time_right, y, STR_JUST_DATE_WALLCLOCK_TINY, show_late ? TC_RED : i == selected ? TC_WHITE : TC_BLACK); } @@ -502,7 +502,7 @@ struct TimetableWindow : Window { } else { if (arr_dep[i / 2].departure != INVALID_TICKS) { DrawString(abbr_left, abbr_right, y, STR_TIMETABLE_DEPARTURE_ABBREVIATION, i == selected ? TC_WHITE : TC_BLACK); - SetDParam(0, CURRENT_SCALED_TICKS + arr_dep[i/2].departure + offset); + SetDParam(0, _scaled_date_ticks + arr_dep[i/2].departure + offset); DrawString(time_left, time_right, y, STR_JUST_DATE_WALLCLOCK_TINY, show_late ? TC_RED : i == selected ? TC_WHITE : TC_BLACK); } @@ -576,7 +576,7 @@ struct TimetableWindow : Window { if (_settings_client.gui.time_in_minutes && _settings_client.gui.timetable_start_text_entry) { this->set_start_date_all = v->orders.list->IsCompleteTimetable() && _ctrl_pressed; StringID str = STR_JUST_INT; - uint64 time = CURRENT_SCALED_TICKS; + uint64 time = _scaled_date_ticks; time /= _settings_client.gui.ticks_per_minute; time += _settings_client.gui.clock_offset; time %= (24 * 60); @@ -585,7 +585,7 @@ struct TimetableWindow : Window { ShowQueryString(str, STR_TIMETABLE_STARTING_DATE, 31, this, CS_NUMERAL, QSF_ACCEPT_UNCHANGED); } else { ShowSetDateWindow(this, v->index | (v->orders.list->IsCompleteTimetable() && _ctrl_pressed ? 1U << 20 : 0), - CURRENT_SCALED_TICKS, _cur_year, _cur_year + 15, ChangeTimetableStartCallback); + _scaled_date_ticks, _cur_year, _cur_year + 15, ChangeTimetableStartCallback); } break; diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 3aebd300ef..683f59efdd 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -399,7 +399,7 @@ static void AnimateTile_Town(TileIndex tile) return; } - if (SCALED_TICK_COUNTER & 3) return; + if (_scaled_tick_counter & 3) return; /* If the house is not one with a lift anymore, then stop this animating. * Not exactly sure when this happens, but probably when a house changes.