From 2ad446369df7eef07dae96360083dd4dc5ec909f Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Tue, 24 Nov 2020 19:02:38 +0000 Subject: [PATCH] Cache animated tile speed, use btree map for animated tiles --- src/CMakeLists.txt | 1 + src/animated_tile.cpp | 124 ++++++++++++++++++++++-------- src/animated_tile.h | 23 ++++++ src/animated_tile_func.h | 1 + src/industry_cmd.cpp | 41 ++++++++++ src/newgrf_airporttiles.cpp | 7 ++ src/newgrf_airporttiles.h | 1 + src/newgrf_animation_base.h | 6 ++ src/newgrf_house.cpp | 8 ++ src/newgrf_house.h | 1 + src/newgrf_industrytiles.cpp | 8 ++ src/newgrf_industrytiles.h | 1 + src/newgrf_object.cpp | 8 ++ src/newgrf_object.h | 1 + src/newgrf_station.cpp | 8 ++ src/newgrf_station.h | 1 + src/saveload/afterload.cpp | 17 ++-- src/saveload/animated_tile_sl.cpp | 34 ++++++-- src/saveload/extended_ver_sl.cpp | 1 + src/saveload/extended_ver_sl.h | 1 + src/saveload/oldloader_sl.cpp | 4 +- src/station_cmd.cpp | 12 +++ src/town_cmd.cpp | 8 ++ 23 files changed, 264 insertions(+), 53 deletions(-) create mode 100644 src/animated_tile.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e163db0d44..0f5f94c08e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -38,6 +38,7 @@ add_files( airport.h airport_gui.cpp animated_tile.cpp + animated_tile.h animated_tile_func.h articulated_vehicles.cpp articulated_vehicles.h diff --git a/src/animated_tile.cpp b/src/animated_tile.cpp index 8cc39a2c6f..67aba4c364 100644 --- a/src/animated_tile.cpp +++ b/src/animated_tile.cpp @@ -8,16 +8,19 @@ /** @file animated_tile.cpp Everything related to animated tiles. */ #include "stdafx.h" +#include "animated_tile.h" #include "core/alloc_func.hpp" #include "core/smallvec_type.hpp" #include "tile_cmd.h" #include "viewport_func.h" #include "framerate_type.h" +#include "date_func.h" +#include "3rdparty/cpp-btree/btree_map.h" #include "safeguards.h" /** The table/list with animated tiles. */ -std::vector _animated_tiles; +btree::btree_map _animated_tiles; /** * Removes the given tile from the animated tile table. @@ -25,14 +28,43 @@ std::vector _animated_tiles; */ void DeleteAnimatedTile(TileIndex tile) { - auto to_remove = std::find(_animated_tiles.begin(), _animated_tiles.end(), tile); - if (to_remove != _animated_tiles.end()) { - /* The order of the remaining elements must stay the same, otherwise the animation loop may miss a tile. */ - _animated_tiles.erase(to_remove); + auto to_remove = _animated_tiles.find(tile); + if (to_remove != _animated_tiles.end() && !to_remove->second.pending_deletion) { + to_remove->second.pending_deletion = true; MarkTileDirtyByTile(tile, VMDF_NOT_MAP_MODE); } } +static void UpdateAnimatedTileSpeed(TileIndex tile, AnimatedTileInfo &info) +{ + extern uint8 GetAnimatedTileSpeed_Town(TileIndex tile); + extern uint8 GetAnimatedTileSpeed_Station(TileIndex tile); + extern uint8 GetAnimatedTileSpeed_Industry(TileIndex tile); + extern uint8 GetNewObjectTileAnimationSpeed(TileIndex tile); + + switch (GetTileType(tile)) { + case MP_HOUSE: + info.speed = GetAnimatedTileSpeed_Town(tile); + break; + + case MP_STATION: + info.speed = GetAnimatedTileSpeed_Station(tile); + break; + + case MP_INDUSTRY: + info.speed = GetAnimatedTileSpeed_Industry(tile); + break; + + case MP_OBJECT: + info.speed = GetNewObjectTileAnimationSpeed(tile); + break; + + default: + info.speed = 0; + break; + } +} + /** * Add the given tile to the animated tile table (if it does not exist * on that table yet). Also increases the size of the table if necessary. @@ -41,7 +73,18 @@ void DeleteAnimatedTile(TileIndex tile) void AddAnimatedTile(TileIndex tile) { MarkTileDirtyByTile(tile, VMDF_NOT_MAP_MODE); - include(_animated_tiles, tile); + AnimatedTileInfo &info = _animated_tiles[tile]; + UpdateAnimatedTileSpeed(tile, info); + info.pending_deletion = false; +} + +int GetAnimatedTileSpeed(TileIndex tile) +{ + const auto iter = _animated_tiles.find(tile); + if (iter != _animated_tiles.end() && !iter->second.pending_deletion) { + return iter->second.speed; + } + return -1; } /** @@ -56,40 +99,53 @@ void AnimateAnimatedTiles() PerformanceAccumulator framerate(PFE_GL_LANDSCAPE); - const TileIndex *ti = _animated_tiles.data(); - while (ti < _animated_tiles.data() + _animated_tiles.size()) { - const TileIndex curr = *ti; - switch (GetTileType(curr)) { - case MP_HOUSE: - AnimateTile_Town(curr); - break; + const uint32 ticks = (uint) _scaled_tick_counter; + const uint8 max_speed = (ticks == 0) ? 32 : FindFirstBit(ticks); + + auto iter = _animated_tiles.begin(); + while (iter != _animated_tiles.end()) { + if (iter->second.pending_deletion) { + iter = _animated_tiles.erase(iter); + continue; + } + + if (iter->second.speed <= max_speed) { + const TileIndex curr = iter->first; + switch (GetTileType(curr)) { + case MP_HOUSE: + AnimateTile_Town(curr); + break; - case MP_STATION: - AnimateTile_Station(curr); - break; + case MP_STATION: + AnimateTile_Station(curr); + break; - case MP_INDUSTRY: - AnimateTile_Industry(curr); - break; + case MP_INDUSTRY: + AnimateTile_Industry(curr); + break; - case MP_OBJECT: - AnimateTile_Object(curr); - break; + case MP_OBJECT: + AnimateTile_Object(curr); + break; - default: - NOT_REACHED(); + default: + NOT_REACHED(); + } } + ++iter; + } +} - /* During the AnimateTile call, DeleteAnimatedTile could have been called, - * deleting an element we've already processed and pushing the rest one - * slot to the left. We can detect this by checking whether the index - * in the current slot has changed - if it has, an element has been deleted, - * and we should process the current slot again instead of going forward. - * NOTE: this will still break if more than one animated tile is being - * deleted during the same AnimateTile call, but no code seems to - * be doing this anyway. - */ - if (*ti == curr) ++ti; +void UpdateAllAnimatedTileSpeeds() +{ + auto iter = _animated_tiles.begin(); + while (iter != _animated_tiles.end()) { + if (iter->second.pending_deletion) { + iter = _animated_tiles.erase(iter); + continue; + } + UpdateAnimatedTileSpeed(iter->first, iter->second); + ++iter; } } diff --git a/src/animated_tile.h b/src/animated_tile.h new file mode 100644 index 0000000000..bb4b71e38a --- /dev/null +++ b/src/animated_tile.h @@ -0,0 +1,23 @@ +/* + * This file is part of OpenTTD. + * OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2. + * OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see . + */ + +/** @file animated_tile.h %Tile animation! */ + +#ifndef ANIMATED_TILE_H +#define ANIMATED_TILE_H + +#include "tile_type.h" +#include "3rdparty/cpp-btree/btree_map.h" + +struct AnimatedTileInfo { + uint8 speed = 0; + bool pending_deletion = false; +}; + +extern btree::btree_map _animated_tiles; + +#endif /* ANIMATED_TILE_H */ diff --git a/src/animated_tile_func.h b/src/animated_tile_func.h index 6a871f1bc5..0066f8a082 100644 --- a/src/animated_tile_func.h +++ b/src/animated_tile_func.h @@ -15,6 +15,7 @@ void AddAnimatedTile(TileIndex tile); void DeleteAnimatedTile(TileIndex tile); void AnimateAnimatedTiles(); +void UpdateAllAnimatedTileSpeeds(); void InitializeAnimatedTiles(); #endif /* ANIMATED_TILE_FUNC_H */ diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 379ddbc2f2..e25b7c2f37 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.cpp @@ -724,6 +724,47 @@ void AnimateTile_Industry(TileIndex tile) } } + +uint8 GetAnimatedTileSpeed_Industry(TileIndex tile) +{ + IndustryGfx gfx = GetIndustryGfx(tile); + + if (GetIndustryTileSpec(gfx)->animation.status != ANIM_STATUS_NO_ANIMATION) { + return GetNewIndustryTileAnimationSpeed(tile); + } + + switch (gfx) { + case GFX_SUGAR_MINE_SIEVE: + return 1; + + case GFX_TOFFEE_QUARY: + return 2; + + case GFX_BUBBLE_CATCHER: + return 1; + + case GFX_POWERPLANT_SPARKS: + return 2; + + case GFX_TOY_FACTORY: + return 1; + + case GFX_PLASTIC_FOUNTAIN_ANIMATED_1: case GFX_PLASTIC_FOUNTAIN_ANIMATED_2: + 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: + return 2; + + case GFX_OILWELL_ANIMATED_1: + case GFX_OILWELL_ANIMATED_2: + case GFX_OILWELL_ANIMATED_3: + return 3; + + default: + return 0; + } +} + static void CreateChimneySmoke(TileIndex tile) { uint x = TileX(tile) * TILE_SIZE; diff --git a/src/newgrf_airporttiles.cpp b/src/newgrf_airporttiles.cpp index 88231c255d..3557d8d222 100644 --- a/src/newgrf_airporttiles.cpp +++ b/src/newgrf_airporttiles.cpp @@ -312,3 +312,10 @@ void AirportAnimationTrigger(Station *st, AirpAnimationTrigger trigger, CargoID } } +uint8 GetAirportTileAnimationSpeed(TileIndex tile) +{ + const AirportTileSpec *ats = AirportTileSpec::GetByTile(tile); + if (ats == nullptr) return 0; + + return AirportTileAnimationBase::GetAnimationSpeed(ats); +} diff --git a/src/newgrf_airporttiles.h b/src/newgrf_airporttiles.h index 84b1234753..43c255c475 100644 --- a/src/newgrf_airporttiles.h +++ b/src/newgrf_airporttiles.h @@ -86,6 +86,7 @@ StationGfx GetTranslatedAirportTileID(StationGfx gfx); void AnimateAirportTile(TileIndex tile); void AirportTileAnimationTrigger(Station *st, TileIndex tile, AirpAnimationTrigger trigger, CargoID cargo_type = CT_INVALID); void AirportAnimationTrigger(Station *st, AirpAnimationTrigger trigger, CargoID cargo_type = CT_INVALID); +uint8 GetAirportTileAnimationSpeed(TileIndex tile); bool DrawNewAirportTile(TileInfo *ti, Station *st, StationGfx gfx, const AirportTileSpec *airts); #endif /* NEWGRF_AIRPORTTILES_H */ diff --git a/src/newgrf_animation_base.h b/src/newgrf_animation_base.h index ad1df6d2d7..f36cac27c0 100644 --- a/src/newgrf_animation_base.h +++ b/src/newgrf_animation_base.h @@ -133,4 +133,10 @@ struct AnimationBase { * result are not empty, it is a sound effect. */ if (GB(callback, 8, 7) != 0 && _settings_client.sound.ambient) PlayTileSound(spec->grf_prop.grffile, GB(callback, 8, 7), tile); } + + static uint8 GetAnimationSpeed(const Tspec *spec) + { + if (HasBit(spec->callback_mask, Tbase::cbm_animation_speed)) return 0; + return spec->animation.speed; + } }; diff --git a/src/newgrf_house.cpp b/src/newgrf_house.cpp index ae250060af..44e33db3e8 100644 --- a/src/newgrf_house.cpp +++ b/src/newgrf_house.cpp @@ -662,6 +662,14 @@ void AnimateNewHouseConstruction(TileIndex tile) } } +uint8 GetNewHouseTileAnimationSpeed(TileIndex tile) +{ + const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile)); + if (hs == nullptr) return 0; + + return HouseAnimationBase::GetAnimationSpeed(hs); +} + /** * Check if GRF allows a given house to be constructed (callback 17) * @param house_id house type diff --git a/src/newgrf_house.h b/src/newgrf_house.h index 090a0d71f1..d1468512cc 100644 --- a/src/newgrf_house.h +++ b/src/newgrf_house.h @@ -144,6 +144,7 @@ void DrawNewHouseTile(TileInfo *ti, HouseID house_id); void DrawNewHouseTileInGUI(int x, int y, HouseID house_id, bool ground); void AnimateNewHouseTile(TileIndex tile); void AnimateNewHouseConstruction(TileIndex tile); +uint8 GetNewHouseTileAnimationSpeed(TileIndex tile); uint16 GetHouseCallback(CallbackID callback, uint32 param1, uint32 param2, HouseID house_id, Town *town = nullptr, TileIndex tile = INVALID_TILE, bool not_yet_constructed = false, uint8 initial_random_bits = 0, CargoTypes watched_cargo_triggers = 0); diff --git a/src/newgrf_industrytiles.cpp b/src/newgrf_industrytiles.cpp index 1d2afac7bc..5b374394cf 100644 --- a/src/newgrf_industrytiles.cpp +++ b/src/newgrf_industrytiles.cpp @@ -300,6 +300,14 @@ bool StartStopIndustryTileAnimation(const Industry *ind, IndustryAnimationTrigge return ret; } +uint8 GetNewIndustryTileAnimationSpeed(TileIndex tile) +{ + const IndustryTileSpec *itspec = GetIndustryTileSpec(GetIndustryGfx(tile)); + if (itspec == nullptr) return 0; + + return IndustryAnimationBase::GetAnimationSpeed(itspec); +} + /** * Trigger random triggers for an industry tile and reseed its random bits. * @param tile Industry tile to trigger. diff --git a/src/newgrf_industrytiles.h b/src/newgrf_industrytiles.h index 3e23e2a2d4..3563227efa 100644 --- a/src/newgrf_industrytiles.h +++ b/src/newgrf_industrytiles.h @@ -64,6 +64,7 @@ CommandCost PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind void AnimateNewIndustryTile(TileIndex tile); bool StartStopIndustryTileAnimation(TileIndex tile, IndustryAnimationTrigger iat, uint32 random = Random()); bool StartStopIndustryTileAnimation(const Industry *ind, IndustryAnimationTrigger iat); +uint8 GetNewIndustryTileAnimationSpeed(TileIndex tile); /** Available industry tile triggers. */ diff --git a/src/newgrf_object.cpp b/src/newgrf_object.cpp index e1dd3d87ca..fbaa1b2c0a 100644 --- a/src/newgrf_object.cpp +++ b/src/newgrf_object.cpp @@ -530,6 +530,14 @@ void AnimateNewObjectTile(TileIndex tile) ObjectAnimationBase::AnimateTile(spec, Object::GetByTile(tile), tile, (spec->flags & OBJECT_FLAG_ANIM_RANDOM_BITS) != 0); } +uint8 GetNewObjectTileAnimationSpeed(TileIndex tile) +{ + const ObjectSpec *spec = ObjectSpec::GetByTile(tile); + if (spec == nullptr || !(spec->flags & OBJECT_FLAG_ANIMATION)) return 0; + + return ObjectAnimationBase::GetAnimationSpeed(spec); +} + /** * Trigger the update of animation on a single tile. * @param o The object that got triggered. diff --git a/src/newgrf_object.h b/src/newgrf_object.h index d048472251..68b10cc145 100644 --- a/src/newgrf_object.h +++ b/src/newgrf_object.h @@ -163,6 +163,7 @@ uint16 GetObjectCallback(CallbackID callback, uint32 param1, uint32 param2, cons void DrawNewObjectTile(TileInfo *ti, const ObjectSpec *spec); void DrawNewObjectTileInGUI(int x, int y, const ObjectSpec *spec, uint8 view); void AnimateNewObjectTile(TileIndex tile); +uint8 GetNewObjectTileAnimationSpeed(TileIndex tile); void TriggerObjectTileAnimation(Object *o, TileIndex tile, ObjectAnimationTrigger trigger, const ObjectSpec *spec); void TriggerObjectAnimation(Object *o, ObjectAnimationTrigger trigger, const ObjectSpec *spec); diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index af1031a242..6c62ed7152 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -924,6 +924,14 @@ void AnimateStationTile(TileIndex tile) StationAnimationBase::AnimateTile(ss, BaseStation::GetByTile(tile), tile, HasBit(ss->flags, SSF_CB141_RANDOM_BITS)); } +uint8 GetStationTileAnimationSpeed(TileIndex tile) +{ + const StationSpec *ss = GetStationSpec(tile); + if (ss == nullptr) return 0; + + return StationAnimationBase::GetAnimationSpeed(ss); +} + void TriggerStationAnimation(BaseStation *st, TileIndex tile, StationAnimationTrigger trigger, CargoID cargo_type) { /* List of coverage areas for each animation trigger */ diff --git a/src/newgrf_station.h b/src/newgrf_station.h index 18b46a74bf..7e7f88de71 100644 --- a/src/newgrf_station.h +++ b/src/newgrf_station.h @@ -204,6 +204,7 @@ void DeallocateSpecFromStation(BaseStation *st, byte specindex); bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID sclass, uint station); void AnimateStationTile(TileIndex tile); +uint8 GetStationTileAnimationSpeed(TileIndex tile); void TriggerStationAnimation(BaseStation *st, TileIndex tile, StationAnimationTrigger trigger, CargoID cargo_type = CT_INVALID); void TriggerStationRandomisation(Station *st, TileIndex tile, StationRandomTrigger trigger, CargoID cargo_type = CT_INVALID); void StationUpdateCachedTriggers(BaseStation *st); diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 115bf42ea0..be7d4c58ee 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.cpp @@ -63,6 +63,7 @@ #include "../bridge_signal_map.h" #include "../water.h" #include "../settings_func.h" +#include "../animated_tile.h" #include "saveload_internal.h" @@ -2461,16 +2462,9 @@ bool AfterLoadGame() /* Animated tiles would sometimes not be actually animated or * in case of old savegames duplicate. */ - extern std::vector _animated_tiles; - - for (auto tile = _animated_tiles.begin(); tile < _animated_tiles.end(); /* Nothing */) { + for (auto tile = _animated_tiles.begin(); tile != _animated_tiles.end(); /* Nothing */) { /* Remove if tile is not animated */ - bool remove = _tile_type_procs[GetTileType(*tile)]->animate_tile_proc == nullptr; - - /* and remove if duplicate */ - for (auto j = _animated_tiles.begin(); !remove && j < tile; j++) { - remove = *tile == *j; - } + bool remove = _tile_type_procs[GetTileType(tile->first)]->animate_tile_proc == nullptr; if (remove) { tile = _animated_tiles.erase(tile); @@ -3806,6 +3800,10 @@ bool AfterLoadGame() RecalculateRoadCachedOneWayStates(); } + if (SlXvIsFeatureMissing(XSLFI_ANIMATED_TILE_EXTRA)) { + UpdateAllAnimatedTileSpeeds(); + } + InitializeRoadGUI(); /* This needs to be done after conversion. */ @@ -3928,4 +3926,5 @@ void ReloadNewGRFData() CheckTrainsLengths(); AfterLoadTemplateVehiclesUpdateImage(); AfterLoadTemplateVehiclesUpdateProperties(); + UpdateAllAnimatedTileSpeeds(); } diff --git a/src/saveload/animated_tile_sl.cpp b/src/saveload/animated_tile_sl.cpp index 9f03e598d7..1f2eec34e6 100644 --- a/src/saveload/animated_tile_sl.cpp +++ b/src/saveload/animated_tile_sl.cpp @@ -8,6 +8,7 @@ /** @file animated_tile_sl.cpp Code handling saving and loading of animated tiles */ #include "../stdafx.h" +#include "../animated_tile.h" #include "../tile_type.h" #include "../core/alloc_func.hpp" #include "../core/smallvec_type.hpp" @@ -16,15 +17,21 @@ #include "../safeguards.h" -extern std::vector _animated_tiles; - /** * Save the ANIT chunk. */ static void Save_ANIT() { - SlSetLength(_animated_tiles.size() * sizeof(_animated_tiles.front())); - SlArray(_animated_tiles.data(), _animated_tiles.size(), SLE_UINT32); + uint count = 0; + for (const auto &it : _animated_tiles) { + if (!it.second.pending_deletion) count++; + } + SlSetLength(count * 5); + for (const auto &it : _animated_tiles) { + if (it.second.pending_deletion) continue; + SlWriteUint32(it.first); + SlWriteByte(it.second.speed); + } } /** @@ -40,15 +47,26 @@ static void Load_ANIT() for (int i = 0; i < 256; i++) { if (anim_list[i] == 0) break; - _animated_tiles.push_back(anim_list[i]); + _animated_tiles[anim_list[i]] = {}; } return; } - uint count = (uint)SlGetFieldLength() / sizeof(_animated_tiles.front()); _animated_tiles.clear(); - _animated_tiles.resize(_animated_tiles.size() + count); - SlArray(_animated_tiles.data(), count, SLE_UINT32); + if (SlXvIsFeaturePresent(XSLFI_ANIMATED_TILE_EXTRA)) { + uint count = (uint)SlGetFieldLength() / 5; + for (uint i = 0; i < count; i++) { + TileIndex tile = SlReadUint32(); + AnimatedTileInfo info = {}; + info.speed = SlReadByte(); + _animated_tiles[tile] = info; + } + } else { + uint count = (uint)SlGetFieldLength() / 4; + for (uint i = 0; i < count; i++) { + _animated_tiles[SlReadUint32()] = {}; + } + } } /** diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index e0cd50ce06..1009625221 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -139,6 +139,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_ONE_WAY_DT_ROAD_STOP, XSCF_NULL, 1, 1, "one_way_dt_road_stop", nullptr, nullptr, nullptr }, { XSLFI_ONE_WAY_ROAD_STATE, XSCF_NULL, 1, 1, "one_way_road_state", nullptr, nullptr, nullptr }, { XSLFI_VENC_CHUNK, XSCF_IGNORABLE_ALL, 1, 1, "venc_chunk", nullptr, nullptr, "VENC" }, + { XSLFI_ANIMATED_TILE_EXTRA, XSCF_NULL, 1, 1, "animated_tile_extra", nullptr, nullptr, nullptr }, { XSLFI_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr },// This is the end marker }; diff --git a/src/saveload/extended_ver_sl.h b/src/saveload/extended_ver_sl.h index b349ae2fe5..d04e31daf4 100644 --- a/src/saveload/extended_ver_sl.h +++ b/src/saveload/extended_ver_sl.h @@ -93,6 +93,7 @@ enum SlXvFeatureIndex { XSLFI_ONE_WAY_DT_ROAD_STOP, ///< One-way drive-through road stops XSLFI_ONE_WAY_ROAD_STATE, ///< One-way road state cache XSLFI_VENC_CHUNK, ///< VENC chunk + XSLFI_ANIMATED_TILE_EXTRA, ///< Animated tile extra info XSLFI_RIFF_HEADER_60_BIT, ///< Size field in RIFF chunk header is 60 bit XSLFI_HEIGHT_8_BIT, ///< Map tile height is 8 bit instead of 4 bit, but savegame version may be before this became true in trunk diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index a8af62f22a..ba9f0e1b50 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.cpp @@ -26,6 +26,7 @@ #include "../engine_func.h" #include "../company_base.h" #include "../disaster_vehicle.h" +#include "../animated_tile.h" #include "../core/smallvec_type.hpp" #include "saveload_internal.h" #include "oldloader.h" @@ -483,7 +484,6 @@ static inline uint RemapOrderIndex(uint x) return _savegame_type == SGT_TTO ? (x - 0x1AC4) / 2 : (x - 0x1C18) / 2; } -extern std::vector _animated_tiles; extern char *_old_name_array; static uint32 _old_town_index; @@ -643,7 +643,7 @@ static bool LoadOldAnimTileList(LoadgameState *ls, int num) /* The first zero in the loaded array indicates the end of the list. */ for (int i = 0; i < 256; i++) { if (anim_list[i] == 0) break; - _animated_tiles.push_back(anim_list[i]); + _animated_tiles[anim_list[i]] = {}; } return true; diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index 79665ba32e..ac36a9ce77 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -3553,6 +3553,18 @@ void AnimateTile_Station(TileIndex tile) } } +uint8 GetAnimatedTileSpeed_Station(TileIndex tile) +{ + if (HasStationRail(tile)) { + return GetStationTileAnimationSpeed(tile); + } + + if (IsAirport(tile)) { + AnimateAirportTile(tile); + } + return 0; +} + static bool ClickTile_Station(TileIndex tile) { diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 6b146bdf66..df0d00a95b 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.cpp @@ -432,6 +432,14 @@ static Foundation GetFoundation_Town(TileIndex tile, Slope tileh) return FlatteningFoundation(tileh); } +uint8 GetAnimatedTileSpeed_Town(TileIndex tile) +{ + if (GetHouseType(tile) >= NEW_HOUSE_OFFSET) { + return GetNewHouseTileAnimationSpeed(tile); + } + return 2; +} + /** * Animate a tile for a town * Only certain houses can be animated