From c2752b31e69e6069799bcbe293d6da46583eb995 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Tue, 21 Mar 2023 18:59:11 +0000 Subject: [PATCH] Saveload: Use traditional map chunks for scenario saves --- src/saveload/extended_ver_sl.cpp | 3 + src/saveload/map_sl.cpp | 130 ++++++++++++++++++++++++++++--- 2 files changed, 121 insertions(+), 12 deletions(-) diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index cdee7d1298..947e52f23d 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -278,6 +278,9 @@ void SlXvSetCurrentState() if (MapSizeX() > 8192 || MapSizeY() > 8192) { _sl_xv_feature_versions[XSLFI_EXTRA_LARGE_MAP] = 1; } + if (IsScenarioSave()) { + _sl_xv_feature_versions[XSLFI_WHOLE_MAP_CHUNK] = 0; + } } /** diff --git a/src/saveload/map_sl.cpp b/src/saveload/map_sl.cpp index 12cafaa4cd..5017b7557e 100644 --- a/src/saveload/map_sl.cpp +++ b/src/saveload/map_sl.cpp @@ -296,19 +296,125 @@ static void Save_WMAP() #endif } +struct MAPT { + typedef uint8 FieldT; + static const FieldT &GetField(TileIndex t) { return _m[t].type; } +}; + +struct MAPH { + typedef uint8 FieldT; + static const FieldT &GetField(TileIndex t) { return _m[t].height; } +}; + +struct MAP1 { + typedef uint8 FieldT; + static const FieldT &GetField(TileIndex t) { return _m[t].m1; } +}; + +struct MAP2 { + typedef uint16 FieldT; + static const FieldT &GetField(TileIndex t) { return _m[t].m2; } +}; + +struct MAP3 { + typedef uint8 FieldT; + static const FieldT &GetField(TileIndex t) { return _m[t].m3; } +}; + +struct MAP4 { + typedef uint8 FieldT; + static const FieldT &GetField(TileIndex t) { return _m[t].m4; } +}; + +struct MAP5 { + typedef uint8 FieldT; + static const FieldT &GetField(TileIndex t) { return _m[t].m5; } +}; + +struct MAP6 { + typedef uint8 FieldT; + static const FieldT &GetField(TileIndex t) { return _me[t].m6; } +}; + +struct MAP7 { + typedef uint8 FieldT; + static const FieldT &GetField(TileIndex t) { return _me[t].m7; } +}; + +struct MAP8 { + typedef uint16 FieldT; + static const FieldT &GetField(TileIndex t) { return _me[t].m8; } +}; + +template +struct MAP_VarType {}; + +template <> +struct MAP_VarType +{ + static const VarType var_type = SLE_UINT8; +}; + +template <> +struct MAP_VarType +{ + static const VarType var_type = SLE_UINT16; +}; + +template +static void Save_MAP() +{ + assert(_sl_xv_feature_versions[XSLFI_WHOLE_MAP_CHUNK] == 0); + + std::array buf; + TileIndex size = MapSize(); + + SlSetLength(size * sizeof(typename T::FieldT)); + for (TileIndex i = 0; i != size;) { + for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = T::GetField(i++); + SlArray(buf.data(), MAP_SL_BUF_SIZE, MAP_VarType::var_type); + } +} + +static ChunkSaveLoadSpecialOpResult Special_WMAP(uint32 chunk_id, ChunkSaveLoadSpecialOp op) +{ + switch (op) { + case CSLSO_SHOULD_SAVE_CHUNK: + if (_sl_xv_feature_versions[XSLFI_WHOLE_MAP_CHUNK] == 0) return CSLSOR_DONT_SAVE_CHUNK; + break; + + default: + break; + } + return CSLSOR_NONE; +} + +static ChunkSaveLoadSpecialOpResult Special_MAP_Chunks(uint32 chunk_id, ChunkSaveLoadSpecialOp op) +{ + switch (op) { + case CSLSO_SHOULD_SAVE_CHUNK: + if (_sl_xv_feature_versions[XSLFI_WHOLE_MAP_CHUNK] != 0) return CSLSOR_DONT_SAVE_CHUNK; + break; + + default: + break; + } + return CSLSOR_NONE; +} + static const ChunkHandler map_chunk_handlers[] = { - { 'MAPS', Save_MAPS, Load_MAPS, nullptr, Check_MAPS, CH_RIFF }, - { 'MAPT', nullptr, Load_MAPT, nullptr, nullptr, CH_RIFF }, - { 'MAPH', nullptr, Load_MAPH, nullptr, Check_MAPH, CH_RIFF }, - { 'MAPO', nullptr, Load_MAP1, nullptr, nullptr, CH_RIFF }, - { 'MAP2', nullptr, Load_MAP2, nullptr, nullptr, CH_RIFF }, - { 'M3LO', nullptr, Load_MAP3, nullptr, nullptr, CH_RIFF }, - { 'M3HI', nullptr, Load_MAP4, nullptr, nullptr, CH_RIFF }, - { 'MAP5', nullptr, Load_MAP5, nullptr, nullptr, CH_RIFF }, - { 'MAPE', nullptr, Load_MAP6, nullptr, nullptr, CH_RIFF }, - { 'MAP7', nullptr, Load_MAP7, nullptr, nullptr, CH_RIFF }, - { 'MAP8', nullptr, Load_MAP8, nullptr, nullptr, CH_RIFF }, - { 'WMAP', Save_WMAP, Load_WMAP, nullptr, nullptr, CH_RIFF }, + { 'MAPS', Save_MAPS, Load_MAPS, nullptr, Check_MAPS, CH_RIFF }, + { 'MAPT', Save_MAP, Load_MAPT, nullptr, nullptr, CH_RIFF, Special_MAP_Chunks }, + { 'MAPH', Save_MAP, Load_MAPH, nullptr, Check_MAPH, CH_RIFF, Special_MAP_Chunks }, + { 'MAPO', Save_MAP, Load_MAP1, nullptr, nullptr, CH_RIFF, Special_MAP_Chunks }, + { 'MAP2', Save_MAP, Load_MAP2, nullptr, nullptr, CH_RIFF, Special_MAP_Chunks }, + { 'M3LO', Save_MAP, Load_MAP3, nullptr, nullptr, CH_RIFF, Special_MAP_Chunks }, + { 'M3HI', Save_MAP, Load_MAP4, nullptr, nullptr, CH_RIFF, Special_MAP_Chunks }, + { 'MAP5', Save_MAP, Load_MAP5, nullptr, nullptr, CH_RIFF, Special_MAP_Chunks }, + { 'MAPE', Save_MAP, Load_MAP6, nullptr, nullptr, CH_RIFF, Special_MAP_Chunks }, + { 'MAP7', Save_MAP, Load_MAP7, nullptr, nullptr, CH_RIFF, Special_MAP_Chunks }, + { 'MAP8', Save_MAP, Load_MAP8, nullptr, nullptr, CH_RIFF, Special_MAP_Chunks }, + { 'WMAP', Save_WMAP, Load_WMAP, nullptr, nullptr, CH_RIFF, Special_WMAP }, }; extern const ChunkHandlerTable _map_chunk_handlers(map_chunk_handlers);