Run water flooding at constant speed at day lengths >= 4

See: #482
pull/484/head
Jonathan G Rennison 1 year ago
parent 2fcb735d7b
commit 05ec32f577

@ -827,14 +827,10 @@ CommandCost CmdClearArea(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
TileIndex _cur_tileloop_tile;
TileIndex _aux_tileloop_tile;
/**
* Gradually iterate over all tiles on the map, calling their TileLoopProcs once every 256 ticks.
*/
void RunTileLoop()
static uint32 GetTileLoopFeedback()
{
PerformanceAccumulator framerate(PFE_GL_LANDSCAPE);
/* The pseudorandom sequence of tiles is generated using a Galois linear feedback
* shift register (LFSR). This allows a deterministic pseudorandom ordering, but
* still with minimal state and fast iteration. */
@ -846,7 +842,17 @@ void RunTileLoop()
0x4004B2, 0x800B87, 0x10004F3, 0x200072D, 0x40006AE, 0x80009E3,
};
static_assert(lengthof(feedbacks) == MAX_MAP_TILES_BITS - 2 * MIN_MAP_SIZE_BITS + 1);
const uint32 feedback = feedbacks[MapLogX() + MapLogY() - 2 * MIN_MAP_SIZE_BITS];
return feedbacks[MapLogX() + MapLogY() - 2 * MIN_MAP_SIZE_BITS];
}
/**
* Gradually iterate over all tiles on the map, calling their TileLoopProcs once every 256 ticks.
*/
void RunTileLoop()
{
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);
@ -873,6 +879,30 @@ void RunTileLoop()
_cur_tileloop_tile = tile;
}
void RunAuxiliaryTileLoop()
{
/* At day lengths <= 4, flooding is handled by main tile loop */
if (_settings_game.economy.day_length_factor <= 4 || (_scaled_tick_counter % 4) != 0) return;
PerformanceAccumulator framerate(PFE_GL_LANDSCAPE);
const uint32 feedback = GetTileLoopFeedback();
uint count = 1 << (MapLogX() + MapLogY() - 8);
TileIndex tile = _aux_tileloop_tile;
while (count--) {
if (!IsNonFloodingWaterTile(tile)) {
FloodingBehaviour fb = GetFloodingBehaviour(tile);
if (fb != FLOOD_NONE) TileLoopWaterFlooding(fb, tile);
}
/* Get the next tile in sequence using a Galois LFSR. */
tile = (tile >> 1) ^ (-(int32)(tile & 1) & feedback);
}
_aux_tileloop_tile = tile;
}
void InitializeLandscape()
{
for (uint y = _settings_game.construction.freeform_edges ? 1 : 0; y < MapMaxY(); y++) {

@ -166,6 +166,7 @@ bool HasFoundationNE(TileIndex tile, Slope slope_here, uint z_here);
void DoClearSquare(TileIndex tile);
void RunTileLoop();
void RunAuxiliaryTileLoop();
void InitializeLandscape();
void GenerateLandscape(byte mode);

@ -44,6 +44,7 @@
extern TileIndex _cur_tileloop_tile;
extern TileIndex _aux_tileloop_tile;
extern void ClearAllSignalSpeedRestrictions();
extern void MakeNewgameSettingsLive();
@ -91,6 +92,7 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin
_scaled_tick_counter = 0;
_scaled_date_ticks_offset = 0;
_cur_tileloop_tile = 1;
_aux_tileloop_tile = 1;
_thd.redsq = INVALID_TILE;
_road_layout_change_counter = 0;
_loaded_local_company = COMPANY_SPECTATOR;

@ -1962,6 +1962,7 @@ void StateGameLoop()
SetWindowDirty(WC_STATUS_BAR, 0);
}
RunAuxiliaryTileLoop();
if (_tick_skip_counter < _settings_game.economy.day_length_factor) {
AnimateAnimatedTiles();
CallVehicleTicks();

@ -646,6 +646,9 @@ bool AfterLoadGame()
/* The LFSR used in RunTileLoop iteration cannot have a zeroed state, make it non-zeroed. */
if (_cur_tileloop_tile == 0) _cur_tileloop_tile = 1;
extern TileIndex _aux_tileloop_tile;
if (_aux_tileloop_tile == 0) _aux_tileloop_tile = 1;
if (IsSavegameVersionBefore(SLV_98)) GamelogOldver();
GamelogTestRevision();

@ -177,6 +177,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
{ XSLFI_NO_TREE_COUNTER, XSCF_IGNORABLE_ALL, 1, 1, "no_tree_counter", nullptr, nullptr, nullptr },
{ XSLFI_TOWN_SETTING_OVERRIDE, XSCF_NULL, 1, 1, "town_setting_override", nullptr, nullptr, nullptr },
{ XSLFI_LINKGRAPH_SPARSE_EDGES, XSCF_NULL, 1, 1, "linkgraph_sparse_edges", nullptr, nullptr, nullptr },
{ XSLFI_AUX_TILE_LOOP, XSCF_NULL, 1, 1, "aux_tile_loop", 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 },

@ -130,6 +130,7 @@ enum SlXvFeatureIndex {
XSLFI_NO_TREE_COUNTER, ///< No tree counter
XSLFI_TOWN_SETTING_OVERRIDE, ///< Town setting overrides
XSLFI_LINKGRAPH_SPARSE_EDGES, ///< Link graph edge matrix is stored in sparse format, and saved in order
XSLFI_AUX_TILE_LOOP, ///< Auxiliary tile loop
XSLFI_SCRIPT_INT64, ///< See: SLV_SCRIPT_INT64
XSLFI_U64_TICK_COUNTER, ///< See: SLV_U64_TICK_COUNTER

@ -25,6 +25,7 @@
#include "../safeguards.h"
extern TileIndex _cur_tileloop_tile;
extern TileIndex _aux_tileloop_tile;
extern uint16 _disaster_delay;
extern byte _trees_tick_ctr;
extern uint64 _aspect_cfg_hash;
@ -102,6 +103,7 @@ static const SaveLoad _date_desc[] = {
SLEG_CONDVAR_X(_road_layout_change_counter, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_ROAD_LAYOUT_CHANGE_CTR)),
SLE_CONDNULL_X(1, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_REALISTIC_TRAIN_BRAKING, 4, 6)), // _extra_aspects
SLEG_CONDVAR_X(_aspect_cfg_hash, SLE_UINT64, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_REALISTIC_TRAIN_BRAKING, 7)),
SLEG_CONDVAR_X(_aux_tileloop_tile, SLE_UINT32, SL_MIN_VERSION, SL_MAX_VERSION, SlXvFeatureTest(XSLFTO_AND, XSLFI_AUX_TILE_LOOP)),
SLE_CONDNULL(4, SLV_11, SLV_120),
};

@ -24,6 +24,7 @@
#include "../../safeguards.h"
extern TileIndex _cur_tileloop_tile;
extern TileIndex _aux_tileloop_tile;
extern uint16 _disaster_delay;
extern byte _trees_tick_ctr;

@ -27,6 +27,7 @@ FloodingBehaviour GetFloodingBehaviour(TileIndex tile);
void ClearNeighbourNonFloodingStates(TileIndex tile);
void TileLoop_Water(TileIndex tile);
void TileLoopWaterFlooding(FloodingBehaviour flooding_behaviour, TileIndex tile);
bool FloodHalftile(TileIndex t);
void DoFloodTile(TileIndex target);

@ -1324,9 +1324,17 @@ void TileLoop_Water(TileIndex tile)
{
if (IsTileType(tile, MP_WATER)) AmbientSoundEffect(tile);
/* At day lengths > 4, handle flooding in auxiliary tile loop */
if (_settings_game.economy.day_length_factor > 4) return;
if (IsNonFloodingWaterTile(tile)) return;
switch (GetFloodingBehaviour(tile)) {
TileLoopWaterFlooding(GetFloodingBehaviour(tile), tile);
}
void TileLoopWaterFlooding(FloodingBehaviour flooding_behaviour, TileIndex tile)
{
switch (flooding_behaviour) {
case FLOOD_ACTIVE: {
int non_water_neighbours = 0;
for (Direction dir = DIR_BEGIN; dir < DIR_END; dir++) {

Loading…
Cancel
Save