From df4c458c29bb158885e1785c1152153e3ef20a30 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Sat, 30 Sep 2023 12:19:05 +0100 Subject: [PATCH] Add savegame flag for station tile cache flags Update flags as necessary on load and when reloading GRFs --- src/misc.cpp | 3 +++ src/newgrf_station.cpp | 41 ++++++++++++++++++++++++++++++++++++++ src/newgrf_station.h | 2 ++ src/openttd.cpp | 2 ++ src/saveload/afterload.cpp | 23 ++++----------------- src/sl/extended_ver_sl.cpp | 21 +++++++++++++++++++ src/sl/extended_ver_sl.h | 1 + 7 files changed, 74 insertions(+), 19 deletions(-) diff --git a/src/misc.cpp b/src/misc.cpp index 31a1f0fab1..04d615a7c2 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -51,6 +51,8 @@ extern TileIndex _aux_tileloop_tile; extern void ClearAllSignalSpeedRestrictions(); extern void MakeNewgameSettingsLive(); +extern uint64 _station_tile_cache_hash; + void InitializeSound(); void InitializeMusic(); void InitializeVehicles(); @@ -137,6 +139,7 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin _game_load_time = 0; _extra_aspects = 0; _aspect_cfg_hash = 0; + _station_tile_cache_hash = 0; InitGRFGlobalVars(); _loadgame_DBGL_data.clear(); if (reset_settings) MakeNewgameSettingsLive(); diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index 09abffc604..9aac6b2959 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -24,9 +24,11 @@ #include "newgrf_animation_base.h" #include "newgrf_class_func.h" #include "newgrf_extension.h" +#include "core/checksum_func.hpp" #include "safeguards.h" +uint64 _station_tile_cache_hash = 0; template /* static */ void NewGRFClass::InsertDefaults() @@ -1089,3 +1091,42 @@ void DumpStationSpriteGroup(const StationSpec *statspec, BaseStation *st, DumpSp } } } + +void UpdateStationTileCacheFlags(bool force_update) +{ + SimpleChecksum64 checksum; + for (uint i = 0; StationClass::IsClassIDValid((StationClassID)i); i++) { + StationClass *stclass = StationClass::Get((StationClassID)i); + + checksum.Update(stclass->GetSpecCount()); + for (uint j = 0; j < stclass->GetSpecCount(); j++) { + const StationSpec *statspec = stclass->GetSpec(j); + if (statspec == nullptr) continue; + + checksum.Update(j); + checksum.Update(statspec->blocked); + checksum.Update(statspec->pylons); + checksum.Update(statspec->wires); + } + } + + if (checksum.state != _station_tile_cache_hash || force_update) { + _station_tile_cache_hash = checksum.state; + + for (TileIndex t = 0; t < MapSize(); t++) { + if (HasStationTileRail(t)) { + StationGfx gfx = GetStationGfx(t); + const StationSpec *statspec = GetStationSpec(t); + + bool blocked = statspec != nullptr && HasBit(statspec->blocked, gfx); + /* Default stations do not draw pylons under roofs (gfx >= 4) */ + bool pylons = statspec != nullptr ? HasBit(statspec->pylons, gfx) : gfx < 4; + bool wires = statspec == nullptr || !HasBit(statspec->wires, gfx); + + SetStationTileBlocked(t, blocked); + SetStationTileHavePylons(t, pylons); + SetStationTileHaveWires(t, wires); + } + } + } +} diff --git a/src/newgrf_station.h b/src/newgrf_station.h index 9f02b486a5..77b7ddfdc9 100644 --- a/src/newgrf_station.h +++ b/src/newgrf_station.h @@ -223,4 +223,6 @@ void TriggerStationAnimation(BaseStation *st, TileIndex tile, StationAnimationTr void TriggerStationRandomisation(Station *st, TileIndex tile, StationRandomTrigger trigger, CargoID cargo_type = CT_INVALID); void StationUpdateCachedTriggers(BaseStation *st); +void UpdateStationTileCacheFlags(bool force_update); + #endif /* NEWGRF_STATION_H */ diff --git a/src/openttd.cpp b/src/openttd.cpp index ad0ab8f3e9..413d89ce7d 100644 --- a/src/openttd.cpp +++ b/src/openttd.cpp @@ -129,6 +129,7 @@ extern void RebuildTownCaches(bool cargo_update_required, bool old_map_position) extern void ShowOSErrorBox(const char *buf, bool system); extern void NORETURN DoOSAbort(); extern std::string _config_file; +extern uint64 _station_tile_cache_hash; bool _save_config = false; bool _request_newgrf_scan = false; @@ -515,6 +516,7 @@ static void ShutdownGame() _game_load_time = 0; _extra_aspects = 0; _aspect_cfg_hash = 0; + _station_tile_cache_hash = 0; InitGRFGlobalVars(); _loadgame_DBGL_data.clear(); _loadgame_DBGC_data.clear(); diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index cbed5a99b7..512173aae8 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -3338,25 +3338,9 @@ bool AfterLoadGame() _settings_game.script.settings_profile = IsInsideMM(_old_diff_level, SP_BEGIN, SP_END) ? _old_diff_level : (uint)SP_MEDIUM; } - { - /* Station blocked, wires and pylon flags need to be stored in the map. This is effectively cached data, so no - * version check is necessary. This is done here as the SLV_182 check below needs the blocked status. */ - for (TileIndex t = 0; t < map_size; t++) { - if (HasStationTileRail(t)) { - StationGfx gfx = GetStationGfx(t); - const StationSpec *statspec = GetStationSpec(t); - - bool blocked = statspec != nullptr && HasBit(statspec->blocked, gfx); - /* Default stations do not draw pylons under roofs (gfx >= 4) */ - bool pylons = statspec != nullptr ? HasBit(statspec->pylons, gfx) : gfx < 4; - bool wires = statspec == nullptr || !HasBit(statspec->wires, gfx); - - SetStationTileBlocked(t, blocked); - SetStationTileHavePylons(t, pylons); - SetStationTileHaveWires(t, wires); - } - } - } + /* Station blocked, wires and pylon flags need to be stored in the map. + * This is done here as the SLV_182 check below needs the blocked status. */ + UpdateStationTileCacheFlags(SlXvIsFeatureMissing(XSLFI_STATION_TILE_CACHE_FLAGS)); if (IsSavegameVersionBefore(SLV_182)) { /* Aircraft acceleration variable was bonkers */ @@ -4409,6 +4393,7 @@ void ReloadNewGRFData() GroupStatistics::UpdateAfterLoad(); /* update station graphics */ AfterLoadStations(); + UpdateStationTileCacheFlags(false); RailType rail_type_translate_map[RAILTYPE_END]; for (RailType old_type = RAILTYPE_BEGIN; old_type != RAILTYPE_END; old_type++) { diff --git a/src/sl/extended_ver_sl.cpp b/src/sl/extended_ver_sl.cpp index c5ce5f7542..d330a6057c 100644 --- a/src/sl/extended_ver_sl.cpp +++ b/src/sl/extended_ver_sl.cpp @@ -70,6 +70,8 @@ static void loadUV(const SlxiSubChunkInfo *info, uint32 length); static uint32 saveUV(const SlxiSubChunkInfo *info, bool dry_run); static void loadLC(const SlxiSubChunkInfo *info, uint32 length); static uint32 saveLC(const SlxiSubChunkInfo *info, bool dry_run); +static void loadSTC(const SlxiSubChunkInfo *info, uint32 length); +static uint32 saveSTC(const SlxiSubChunkInfo *info, bool dry_run); const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_VERSION_LABEL, XSCF_IGNORABLE_ALL, 1, 1, "version_label", saveVL, loadVL, nullptr }, @@ -190,6 +192,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { 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_ROAD_VEH_FLAGS, XSCF_NULL, 1, 1, "road_veh_flags", nullptr, nullptr, nullptr }, + { XSLFI_STATION_TILE_CACHE_FLAGS, XSCF_IGNORABLE_ALL, 1, 1, "station_tile_cache_flags", saveSTC, loadSTC, 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 }, @@ -755,6 +758,24 @@ static uint32 saveLC(const SlxiSubChunkInfo *info, bool dry_run) return 1; } +static void loadSTC(const SlxiSubChunkInfo *info, uint32 length) +{ + extern uint64 _station_tile_cache_hash; + if (length == 8) { + _station_tile_cache_hash = SlReadUint64(); + } else { + DEBUG(sl, 1, "SLXI chunk: feature: '%s', version: %d, has data of wrong length: %u", info->name, _sl_xv_feature_versions[info->index], length); + ReadBuffer::GetCurrent()->SkipBytes(length); + } +} + +static uint32 saveSTC(const SlxiSubChunkInfo *info, bool dry_run) +{ + extern uint64 _station_tile_cache_hash; + if (!dry_run) SlWriteUint64(_station_tile_cache_hash); + return 8; +} + extern const ChunkHandler version_ext_chunk_handlers[] = { { 'SLXI', Save_SLXI, Load_SLXI, nullptr, Load_SLXI, CH_RIFF }, }; diff --git a/src/sl/extended_ver_sl.h b/src/sl/extended_ver_sl.h index 10de8f8f25..b9dc9ac7be 100644 --- a/src/sl/extended_ver_sl.h +++ b/src/sl/extended_ver_sl.h @@ -141,6 +141,7 @@ enum SlXvFeatureIndex { XSLFI_LABEL_ORDERS, ///< Label orders XSLFI_VARIABLE_TICK_RATE, ///< Variable tick rate XSLFI_ROAD_VEH_FLAGS, ///< Road vehicle flags + XSLFI_STATION_TILE_CACHE_FLAGS, ///< Station tile cache flags XSLFI_SCRIPT_INT64, ///< See: SLV_SCRIPT_INT64 XSLFI_U64_TICK_COUNTER, ///< See: SLV_U64_TICK_COUNTER