diff --git a/src/sl/animated_tile_sl.cpp b/src/sl/animated_tile_sl.cpp index aef1f9e7b0..b0eaca342d 100644 --- a/src/sl/animated_tile_sl.cpp +++ b/src/sl/animated_tile_sl.cpp @@ -16,21 +16,59 @@ #include "../safeguards.h" +using AnimatedTilePair = std::pair; + +struct AnimatedTileStructHandler : public SaveLoadStructHandler { + NamedSaveLoadTable GetDescription() const override + { + static const NamedSaveLoad _anim_tiles_sub_desc[] = { + NSLT("tile", SLTAG(SLTAG_CUSTOM_START, SLE_VAR(AnimatedTilePair, first, SLE_UINT32))), + NSLT("speed", SLTAG(SLTAG_CUSTOM_START + 1, SLE_VAR(AnimatedTilePair, second.speed, SLE_UINT8))), + }; + return _anim_tiles_sub_desc; + } + + void Save([[maybe_unused]] void *object) const override + { + uint count = 0; + for (const auto &it : _animated_tiles) { + if (!it.second.pending_deletion) count++; + } + SlSetStructListLength(count); + for (const auto &it : _animated_tiles) { + if (it.second.pending_deletion) continue; + SlWriteUint32(it.first); + SlWriteByte(it.second.speed); + } + } + + void Load([[maybe_unused]] void *object) const override + { + auto slt = this->GetLoadDescription(); + if (slt.size() != 2 || slt[0].label_tag != SLTAG_CUSTOM_START || slt[1].label_tag != SLTAG_CUSTOM_START + 1) { + SlErrorCorrupt("Table format ANIT chunk fields not as expected"); + } + + size_t count = SlGetStructListLength(MAX_MAP_TILES); + for (size_t i = 0; i < count; i++) { + TileIndex tile = SlReadUint32(); + AnimatedTileInfo info = {}; + info.speed = SlReadByte(); + _animated_tiles[tile] = info; + } + } +}; + +static const NamedSaveLoad _anim_tiles_desc[] = { + NSLT_STRUCTLIST("animated_tiles"), +}; + /** * Save the ANIT chunk. */ static void Save_ANIT() { - 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); - } + SlSaveTableObjectChunk(_anim_tiles_desc); } /** @@ -38,6 +76,14 @@ static void Save_ANIT() */ static void Load_ANIT() { + _animated_tiles.clear(); + + if (SlIsTableChunk()) { + if (SlXvIsFeatureMissing(XSLFI_ANIMATED_TILE_EXTRA, 2)) SlErrorCorrupt("Table format ANIT chunk without XSLFI_ANIMATED_TILE_EXTRA v2"); + SlLoadTableObjectChunk(_anim_tiles_desc); + return; + } + /* Before version 80 we did NOT have a variable length animated tile table */ if (IsSavegameVersionBefore(SLV_80)) { /* In pre version 6, we has 16bit per tile, now we have 32bit per tile, convert it ;) */ @@ -51,7 +97,6 @@ static void Load_ANIT() return; } - _animated_tiles.clear(); if (SlXvIsFeaturePresent(XSLFI_ANIMATED_TILE_EXTRA)) { uint count = (uint)SlGetFieldLength() / 5; for (uint i = 0; i < count; i++) { @@ -73,7 +118,7 @@ static void Load_ANIT() * the animated tile table. */ static const ChunkHandler animated_tile_chunk_handlers[] = { - { 'ANIT', Save_ANIT, Load_ANIT, nullptr, nullptr, CH_RIFF }, + { 'ANIT', Save_ANIT, Load_ANIT, nullptr, nullptr, CH_TABLE }, }; extern const ChunkHandlerTable _animated_tile_chunk_handlers(animated_tile_chunk_handlers); diff --git a/src/sl/extended_ver_sl.cpp b/src/sl/extended_ver_sl.cpp index d38a72f663..eb960cb7cf 100644 --- a/src/sl/extended_ver_sl.cpp +++ b/src/sl/extended_ver_sl.cpp @@ -154,7 +154,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, 0, 1, "venc_chunk", nullptr, nullptr, "VENC" }, - { XSLFI_ANIMATED_TILE_EXTRA, XSCF_NULL, 1, 1, "animated_tile_extra", nullptr, nullptr, nullptr }, + { XSLFI_ANIMATED_TILE_EXTRA, XSCF_NULL, 2, 2, "animated_tile_extra", nullptr, nullptr, nullptr }, { XSLFI_NEWGRF_INFO_EXTRA, XSCF_NULL, 1, 1, "newgrf_info_extra", nullptr, nullptr, nullptr }, { XSLFI_INDUSTRY_CARGO_ADJ, XSCF_IGNORABLE_UNKNOWN, 2, 2, "industry_cargo_adj", nullptr, nullptr, nullptr }, { XSLFI_REALISTIC_TRAIN_BRAKING, XSCF_NULL, 11, 11, "realistic_train_braking", nullptr, nullptr, "VLKA" },