@@ -827,14 +827,10 @@ CommandCost CmdClearArea(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32
|
|||||||
|
|
||||||
|
|
||||||
TileIndex _cur_tileloop_tile;
|
TileIndex _cur_tileloop_tile;
|
||||||
|
TileIndex _aux_tileloop_tile;
|
||||||
|
|
||||||
/**
|
static uint32 GetTileLoopFeedback()
|
||||||
* Gradually iterate over all tiles on the map, calling their TileLoopProcs once every 256 ticks.
|
|
||||||
*/
|
|
||||||
void RunTileLoop()
|
|
||||||
{
|
{
|
||||||
PerformanceAccumulator framerate(PFE_GL_LANDSCAPE);
|
|
||||||
|
|
||||||
/* The pseudorandom sequence of tiles is generated using a Galois linear feedback
|
/* The pseudorandom sequence of tiles is generated using a Galois linear feedback
|
||||||
* shift register (LFSR). This allows a deterministic pseudorandom ordering, but
|
* shift register (LFSR). This allows a deterministic pseudorandom ordering, but
|
||||||
* still with minimal state and fast iteration. */
|
* still with minimal state and fast iteration. */
|
||||||
@@ -846,7 +842,17 @@ void RunTileLoop()
|
|||||||
0x4004B2, 0x800B87, 0x10004F3, 0x200072D, 0x40006AE, 0x80009E3,
|
0x4004B2, 0x800B87, 0x10004F3, 0x200072D, 0x40006AE, 0x80009E3,
|
||||||
};
|
};
|
||||||
static_assert(lengthof(feedbacks) == MAX_MAP_TILES_BITS - 2 * MIN_MAP_SIZE_BITS + 1);
|
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 */
|
/* We update every tile every 256 ticks, so divide the map size by 2^8 = 256 */
|
||||||
uint count = 1 << (MapLogX() + MapLogY() - 8);
|
uint count = 1 << (MapLogX() + MapLogY() - 8);
|
||||||
@@ -873,6 +879,30 @@ void RunTileLoop()
|
|||||||
_cur_tileloop_tile = tile;
|
_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()
|
void InitializeLandscape()
|
||||||
{
|
{
|
||||||
for (uint y = _settings_game.construction.freeform_edges ? 1 : 0; y < MapMaxY(); y++) {
|
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 DoClearSquare(TileIndex tile);
|
||||||
void RunTileLoop();
|
void RunTileLoop();
|
||||||
|
void RunAuxiliaryTileLoop();
|
||||||
|
|
||||||
void InitializeLandscape();
|
void InitializeLandscape();
|
||||||
void GenerateLandscape(byte mode);
|
void GenerateLandscape(byte mode);
|
||||||
|
@@ -44,6 +44,7 @@
|
|||||||
|
|
||||||
|
|
||||||
extern TileIndex _cur_tileloop_tile;
|
extern TileIndex _cur_tileloop_tile;
|
||||||
|
extern TileIndex _aux_tileloop_tile;
|
||||||
extern void ClearAllSignalSpeedRestrictions();
|
extern void ClearAllSignalSpeedRestrictions();
|
||||||
extern void MakeNewgameSettingsLive();
|
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_tick_counter = 0;
|
||||||
_scaled_date_ticks_offset = 0;
|
_scaled_date_ticks_offset = 0;
|
||||||
_cur_tileloop_tile = 1;
|
_cur_tileloop_tile = 1;
|
||||||
|
_aux_tileloop_tile = 1;
|
||||||
_thd.redsq = INVALID_TILE;
|
_thd.redsq = INVALID_TILE;
|
||||||
_road_layout_change_counter = 0;
|
_road_layout_change_counter = 0;
|
||||||
_loaded_local_company = COMPANY_SPECTATOR;
|
_loaded_local_company = COMPANY_SPECTATOR;
|
||||||
|
@@ -1962,6 +1962,7 @@ void StateGameLoop()
|
|||||||
SetWindowDirty(WC_STATUS_BAR, 0);
|
SetWindowDirty(WC_STATUS_BAR, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
RunAuxiliaryTileLoop();
|
||||||
if (_tick_skip_counter < _settings_game.economy.day_length_factor) {
|
if (_tick_skip_counter < _settings_game.economy.day_length_factor) {
|
||||||
AnimateAnimatedTiles();
|
AnimateAnimatedTiles();
|
||||||
CallVehicleTicks();
|
CallVehicleTicks();
|
||||||
|
@@ -646,6 +646,9 @@ bool AfterLoadGame()
|
|||||||
/* The LFSR used in RunTileLoop iteration cannot have a zeroed state, make it non-zeroed. */
|
/* The LFSR used in RunTileLoop iteration cannot have a zeroed state, make it non-zeroed. */
|
||||||
if (_cur_tileloop_tile == 0) _cur_tileloop_tile = 1;
|
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();
|
if (IsSavegameVersionBefore(SLV_98)) GamelogOldver();
|
||||||
|
|
||||||
GamelogTestRevision();
|
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_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_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_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_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_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 },
|
{ 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_NO_TREE_COUNTER, ///< No tree counter
|
||||||
XSLFI_TOWN_SETTING_OVERRIDE, ///< Town setting overrides
|
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_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_SCRIPT_INT64, ///< See: SLV_SCRIPT_INT64
|
||||||
XSLFI_U64_TICK_COUNTER, ///< See: SLV_U64_TICK_COUNTER
|
XSLFI_U64_TICK_COUNTER, ///< See: SLV_U64_TICK_COUNTER
|
||||||
|
@@ -25,6 +25,7 @@
|
|||||||
#include "../safeguards.h"
|
#include "../safeguards.h"
|
||||||
|
|
||||||
extern TileIndex _cur_tileloop_tile;
|
extern TileIndex _cur_tileloop_tile;
|
||||||
|
extern TileIndex _aux_tileloop_tile;
|
||||||
extern uint16 _disaster_delay;
|
extern uint16 _disaster_delay;
|
||||||
extern byte _trees_tick_ctr;
|
extern byte _trees_tick_ctr;
|
||||||
extern uint64 _aspect_cfg_hash;
|
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)),
|
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
|
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(_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),
|
SLE_CONDNULL(4, SLV_11, SLV_120),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -24,6 +24,7 @@
|
|||||||
#include "../../safeguards.h"
|
#include "../../safeguards.h"
|
||||||
|
|
||||||
extern TileIndex _cur_tileloop_tile;
|
extern TileIndex _cur_tileloop_tile;
|
||||||
|
extern TileIndex _aux_tileloop_tile;
|
||||||
extern uint16 _disaster_delay;
|
extern uint16 _disaster_delay;
|
||||||
extern byte _trees_tick_ctr;
|
extern byte _trees_tick_ctr;
|
||||||
|
|
||||||
|
@@ -27,6 +27,7 @@ FloodingBehaviour GetFloodingBehaviour(TileIndex tile);
|
|||||||
void ClearNeighbourNonFloodingStates(TileIndex tile);
|
void ClearNeighbourNonFloodingStates(TileIndex tile);
|
||||||
|
|
||||||
void TileLoop_Water(TileIndex tile);
|
void TileLoop_Water(TileIndex tile);
|
||||||
|
void TileLoopWaterFlooding(FloodingBehaviour flooding_behaviour, TileIndex tile);
|
||||||
bool FloodHalftile(TileIndex t);
|
bool FloodHalftile(TileIndex t);
|
||||||
void DoFloodTile(TileIndex target);
|
void DoFloodTile(TileIndex target);
|
||||||
|
|
||||||
|
@@ -1324,9 +1324,17 @@ void TileLoop_Water(TileIndex tile)
|
|||||||
{
|
{
|
||||||
if (IsTileType(tile, MP_WATER)) AmbientSoundEffect(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;
|
if (IsNonFloodingWaterTile(tile)) return;
|
||||||
|
|
||||||
switch (GetFloodingBehaviour(tile)) {
|
TileLoopWaterFlooding(GetFloodingBehaviour(tile), tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
void TileLoopWaterFlooding(FloodingBehaviour flooding_behaviour, TileIndex tile)
|
||||||
|
{
|
||||||
|
switch (flooding_behaviour) {
|
||||||
case FLOOD_ACTIVE: {
|
case FLOOD_ACTIVE: {
|
||||||
int non_water_neighbours = 0;
|
int non_water_neighbours = 0;
|
||||||
for (Direction dir = DIR_BEGIN; dir < DIR_END; dir++) {
|
for (Direction dir = DIR_BEGIN; dir < DIR_END; dir++) {
|
||||||
|
Reference in New Issue
Block a user