diff --git a/src/landscape.cpp b/src/landscape.cpp index 592ac130a3..cb1b9f3890 100644 --- a/src/landscape.cpp +++ b/src/landscape.cpp @@ -818,18 +818,41 @@ static uint32 GetTileLoopFeedback() return feedbacks[MapLogX() + MapLogY() - 2 * MIN_MAP_SIZE_BITS]; } +static std::vector _tile_loop_counts; + +void SetupTileLoopCounts() +{ + _tile_loop_counts.resize(_settings_game.economy.day_length_factor); + if (_settings_game.economy.day_length_factor == 0) return; + + uint64 count_per_tick_fp16 = (static_cast(1) << (MapLogX() + MapLogY() + 8)) / _settings_game.economy.day_length_factor; + uint64 accumulator = 0; + for (uint &count : _tile_loop_counts) { + accumulator += count_per_tick_fp16; + count = static_cast(accumulator >> 16); + accumulator &= 0xFFFF; + } + if (accumulator > 0) _tile_loop_counts[0]++; +} + /** * Gradually iterate over all tiles on the map, calling their TileLoopProcs once every 256 ticks. */ -void RunTileLoop() +void RunTileLoop(bool apply_day_length) { + /* We update every tile every 256 ticks, so divide the map size by 2^8 = 256 */ + uint count; + if (apply_day_length && _settings_game.economy.day_length_factor > 1) { + count = _tile_loop_counts[_tick_skip_counter]; + if (count == 0) return; + } else { + count = 1 << (MapLogX() + MapLogY() - 8); + } + PerformanceAccumulator framerate(PFE_GL_LANDSCAPE); const uint32 feedback = GetTileLoopFeedback(); - /* We update every tile every 256 ticks, so divide the map size by 2^8 = 256 */ - uint count = 1 << (MapLogX() + MapLogY() - 8); - TileIndex tile = _cur_tileloop_tile; /* The LFSR cannot have a zeroed state. */ dbg_assert(tile != 0); diff --git a/src/landscape.h b/src/landscape.h index a6f9e14e7f..5c0d8327c7 100644 --- a/src/landscape.h +++ b/src/landscape.h @@ -166,7 +166,8 @@ bool HasFoundationNW(TileIndex tile, Slope slope_here, uint z_here); bool HasFoundationNE(TileIndex tile, Slope slope_here, uint z_here); void DoClearSquare(TileIndex tile); -void RunTileLoop(); +void SetupTileLoopCounts(); +void RunTileLoop(bool apply_day_length = false); void RunAuxiliaryTileLoop(); void InitializeLandscape(); diff --git a/src/misc.cpp b/src/misc.cpp index 7d4adbcc57..2cb03e573a 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -116,6 +116,7 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin } else { SetScaledTickVariables(); } + SetupTileLoopCounts(); UpdateCachedSnowLine(); UpdateCachedSnowLineBounds(); diff --git a/src/openttd.cpp b/src/openttd.cpp index fe50e24e75..1b404ad72b 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -2050,13 +2050,14 @@ void StateGameLoop() RunAuxiliaryTileLoop(); if (_tick_skip_counter < _settings_game.economy.day_length_factor) { AnimateAnimatedTiles(); + RunTileLoop(true); CallVehicleTicks(); OnTick_Companies(false); } else { _tick_skip_counter = 0; IncreaseDate(); AnimateAnimatedTiles(); - RunTileLoop(); + RunTileLoop(true); CallVehicleTicks(); CallLandscapeTick(); OnTick_Companies(true); diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 6963266f32..f50f36a1d4 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -859,6 +859,7 @@ bool AfterLoadGame() /* Update current year * must be done before loading sprites as some newgrfs check it */ SetDate(_date, _date_fract, false); + SetupTileLoopCounts(); /* * Force the old behaviour for compatibility reasons with old savegames. As new diff --git a/src/settings.cpp b/src/settings.cpp index 6846170c93..6c023cac41 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -1743,6 +1743,8 @@ static void DayLengthChanged(int32 new_value) extern void VehicleDayLengthChanged(DateTicksScaled old_scaled_date_ticks, DateTicksScaled old_scaled_date_ticks_offset, uint8 old_day_length_factor); VehicleDayLengthChanged(old_scaled_date_ticks, old_scaled_date_ticks_offset, _pre_change_day_length_factor); + SetupTileLoopCounts(); + MarkWholeScreenDirty(); }