diff --git a/src/saveload/extended_ver_sl.cpp b/src/saveload/extended_ver_sl.cpp index 597e3cf415..0cd5885ed8 100644 --- a/src/saveload/extended_ver_sl.cpp +++ b/src/saveload/extended_ver_sl.cpp @@ -84,6 +84,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = { { XSLFI_TRAIN_FLAGS_EXTRA, XSCF_NULL, 1, 1, "train_flags_extra", NULL, NULL, NULL }, { XSLFI_TRAIN_THROUGH_LOAD, XSCF_NULL, 1, 1, "train_through_load", NULL, NULL, NULL }, { XSLFI_ORDER_EXTRA_DATA, XSCF_NULL, 1, 1, "order_extra_data", NULL, NULL, NULL }, + { XSLFI_WHOLE_MAP_CHUNK, XSCF_NULL, 1, 1, "whole_map_chunk", NULL, NULL, "WMAP" }, { XSLFI_NULL, XSCF_NULL, 0, 0, NULL, NULL, NULL, NULL },// This is the end marker }; diff --git a/src/saveload/extended_ver_sl.h b/src/saveload/extended_ver_sl.h index dc4a73e9d7..cf5afa2b5a 100644 --- a/src/saveload/extended_ver_sl.h +++ b/src/saveload/extended_ver_sl.h @@ -58,6 +58,7 @@ enum SlXvFeatureIndex { XSLFI_TRAIN_FLAGS_EXTRA, ///< Train flags field extra size XSLFI_TRAIN_THROUGH_LOAD, ///< Train through load/unload XSLFI_ORDER_EXTRA_DATA, ///< Order extra data field(s) + XSLFI_WHOLE_MAP_CHUNK, ///< Whole map chunk 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/map_sl.cpp b/src/saveload/map_sl.cpp index ee157ec17c..7edebdbae2 100644 --- a/src/saveload/map_sl.cpp +++ b/src/saveload/map_sl.cpp @@ -12,9 +12,12 @@ #include "../stdafx.h" #include "../map_func.h" #include "../core/bitmath_func.hpp" +#include "../core/endian_func.hpp" +#include "../core/endian_type.hpp" #include "../fios.h" #include "saveload.h" +#include "saveload_buffer.h" #include "../safeguards.h" @@ -63,18 +66,6 @@ static void Load_MAPT() } } -static void Save_MAPT() -{ - SmallStackSafeStackAlloc buf; - TileIndex size = MapSize(); - - SlSetLength(size); - for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].type; - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8); - } -} - static void Load_MAPH() { SmallStackSafeStackAlloc buf; @@ -86,18 +77,6 @@ static void Load_MAPH() } } -static void Save_MAPH() -{ - SmallStackSafeStackAlloc buf; - TileIndex size = MapSize(); - - SlSetLength(size); - for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].height; - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8); - } -} - static void Load_MAP1() { SmallStackSafeStackAlloc buf; @@ -109,18 +88,6 @@ static void Load_MAP1() } } -static void Save_MAP1() -{ - SmallStackSafeStackAlloc buf; - TileIndex size = MapSize(); - - SlSetLength(size); - for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m1; - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8); - } -} - static void Load_MAP2() { SmallStackSafeStackAlloc buf; @@ -135,18 +102,6 @@ static void Load_MAP2() } } -static void Save_MAP2() -{ - SmallStackSafeStackAlloc buf; - TileIndex size = MapSize(); - - SlSetLength(size * sizeof(uint16)); - for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m2; - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT16); - } -} - static void Load_MAP3() { SmallStackSafeStackAlloc buf; @@ -158,18 +113,6 @@ static void Load_MAP3() } } -static void Save_MAP3() -{ - SmallStackSafeStackAlloc buf; - TileIndex size = MapSize(); - - SlSetLength(size); - for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m3; - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8); - } -} - static void Load_MAP4() { SmallStackSafeStackAlloc buf; @@ -181,18 +124,6 @@ static void Load_MAP4() } } -static void Save_MAP4() -{ - SmallStackSafeStackAlloc buf; - TileIndex size = MapSize(); - - SlSetLength(size); - for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m4; - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8); - } -} - static void Load_MAP5() { SmallStackSafeStackAlloc buf; @@ -204,18 +135,6 @@ static void Load_MAP5() } } -static void Save_MAP5() -{ - SmallStackSafeStackAlloc buf; - TileIndex size = MapSize(); - - SlSetLength(size); - for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m5; - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8); - } -} - static void Load_MAP6() { SmallStackSafeStackAlloc buf; @@ -240,18 +159,6 @@ static void Load_MAP6() } } -static void Save_MAP6() -{ - SmallStackSafeStackAlloc buf; - TileIndex size = MapSize(); - - SlSetLength(size); - for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m6; - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8); - } -} - static void Load_MAP7() { SmallStackSafeStackAlloc buf; @@ -263,27 +170,72 @@ static void Load_MAP7() } } -static void Save_MAP7() +static void Load_WMAP() { - SmallStackSafeStackAlloc buf; - TileIndex size = MapSize(); + assert_compile(sizeof(Tile) == 8); + assert_compile(sizeof(TileExtended) == 2); + assert(_sl_xv_feature_versions[XSLFI_WHOLE_MAP_CHUNK] == 1); - SlSetLength(size); - for (TileIndex i = 0; i != size;) { - for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m7; - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8); + ReadBuffer *reader = ReadBuffer::GetCurrent(); + const TileIndex size = MapSize(); + +#if TTD_ENDIAN == TTD_LITTLE_ENDIAN && 0 + reader->CopyBytes((byte *) _m, size * 8); +#else + for (TileIndex i = 0; i != size; i++) { + reader->CheckBytes(8); + _m[i].type = reader->RawReadByte(); + _m[i].height = reader->RawReadByte(); + uint16 m2 = reader->RawReadByte(); + m2 |= ((uint16) reader->RawReadByte()) << 8; + _m[i].m2 = m2; + _m[i].m1 = reader->RawReadByte(); + _m[i].m3 = reader->RawReadByte(); + _m[i].m4 = reader->RawReadByte(); + _m[i].m5 = reader->RawReadByte(); } +#endif + reader->CopyBytes((byte *) _me, size * 2); +} + +static void Save_WMAP() +{ + assert_compile(sizeof(Tile) == 8); + assert_compile(sizeof(TileExtended) == 2); + assert(_sl_xv_feature_versions[XSLFI_WHOLE_MAP_CHUNK] == 1); + + MemoryDumper *dumper = MemoryDumper::GetCurrent(); + const TileIndex size = MapSize(); + SlSetLength(size * 10); + +#if TTD_ENDIAN == TTD_LITTLE_ENDIAN && 0 + dumper->CopyBytes((byte *) _m, size * 8); +#else + for (TileIndex i = 0; i != size; i++) { + dumper->CheckBytes(8); + dumper->RawWriteByte(_m[i].type); + dumper->RawWriteByte(_m[i].height); + dumper->RawWriteByte(GB(_m[i].m2, 0, 8)); + dumper->RawWriteByte(GB(_m[i].m2, 8, 8)); + dumper->RawWriteByte(_m[i].m1); + dumper->RawWriteByte(_m[i].m3); + dumper->RawWriteByte(_m[i].m4); + dumper->RawWriteByte(_m[i].m5); + } +#endif + dumper->CopyBytes((byte *) _me, size * 2); } extern const ChunkHandler _map_chunk_handlers[] = { { 'MAPS', Save_MAPS, Load_MAPS, NULL, Check_MAPS, CH_RIFF }, - { 'MAPT', Save_MAPT, Load_MAPT, NULL, NULL, CH_RIFF }, - { 'MAPH', Save_MAPH, Load_MAPH, NULL, NULL, CH_RIFF }, - { 'MAPO', Save_MAP1, Load_MAP1, NULL, NULL, CH_RIFF }, - { 'MAP2', Save_MAP2, Load_MAP2, NULL, NULL, CH_RIFF }, - { 'M3LO', Save_MAP3, Load_MAP3, NULL, NULL, CH_RIFF }, - { 'M3HI', Save_MAP4, Load_MAP4, NULL, NULL, CH_RIFF }, - { 'MAP5', Save_MAP5, Load_MAP5, NULL, NULL, CH_RIFF }, - { 'MAPE', Save_MAP6, Load_MAP6, NULL, NULL, CH_RIFF }, - { 'MAP7', Save_MAP7, Load_MAP7, NULL, NULL, CH_RIFF | CH_LAST }, + { 'MAPT', NULL, Load_MAPT, NULL, NULL, CH_RIFF }, + { 'MAPH', NULL, Load_MAPH, NULL, NULL, CH_RIFF }, + { 'MAPO', NULL, Load_MAP1, NULL, NULL, CH_RIFF }, + { 'MAP2', NULL, Load_MAP2, NULL, NULL, CH_RIFF }, + { 'M3LO', NULL, Load_MAP3, NULL, NULL, CH_RIFF }, + { 'M3HI', NULL, Load_MAP4, NULL, NULL, CH_RIFF }, + { 'MAP5', NULL, Load_MAP5, NULL, NULL, CH_RIFF }, + { 'MAPE', NULL, Load_MAP6, NULL, NULL, CH_RIFF }, + { 'MAP7', NULL, Load_MAP7, NULL, NULL, CH_RIFF }, + { 'WMAP', Save_WMAP, Load_WMAP, NULL, NULL, CH_RIFF | CH_LAST }, };