Saveload: Remove intermediate copy in map individual chunk save/load
This commit is contained in:
@@ -54,17 +54,12 @@ static void Check_MAPS()
|
|||||||
_load_check_data.map_size_y = _map_dim_y;
|
_load_check_data.map_size_y = _map_dim_y;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const uint MAP_SL_BUF_SIZE = 4096;
|
|
||||||
|
|
||||||
static void Load_MAPT()
|
static void Load_MAPT()
|
||||||
{
|
{
|
||||||
std::array<uint8_t, MAP_SL_BUF_SIZE> buf;
|
TileIndex i = 0;
|
||||||
TileIndex size = MapSize();
|
ReadBuffer::GetCurrent()->ReadBytesToHandler(MapSize(), [&](uint8_t val) {
|
||||||
|
_m[i++].type = val;
|
||||||
for (TileIndex i = 0; i != size;) {
|
});
|
||||||
SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
|
|
||||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].type = buf[j];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Check_MAPH_common()
|
static void Check_MAPH_common()
|
||||||
@@ -88,128 +83,101 @@ static void Load_MAPH()
|
|||||||
if (SlXvIsFeaturePresent(XSLFI_CHILLPP)) {
|
if (SlXvIsFeaturePresent(XSLFI_CHILLPP)) {
|
||||||
if (SlGetFieldLength() != 0) {
|
if (SlGetFieldLength() != 0) {
|
||||||
_sl_xv_feature_versions[XSLFI_HEIGHT_8_BIT] = 2;
|
_sl_xv_feature_versions[XSLFI_HEIGHT_8_BIT] = 2;
|
||||||
std::array<uint16_t, MAP_SL_BUF_SIZE> buf;
|
|
||||||
TileIndex size = MapSize();
|
|
||||||
|
|
||||||
for (TileIndex i = 0; i != size;) {
|
TileIndex i = 0;
|
||||||
SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16);
|
ReadBuffer::GetCurrent()->ReadUint16sToHandler(MapSize(), [&](uint16_t val) {
|
||||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].height = buf[j];
|
_m[i++].height = val;
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::array<uint8_t, MAP_SL_BUF_SIZE> buf;
|
TileIndex i = 0;
|
||||||
TileIndex size = MapSize();
|
ReadBuffer::GetCurrent()->ReadBytesToHandler(MapSize(), [&](uint8_t val) {
|
||||||
|
_m[i++].height = val;
|
||||||
for (TileIndex i = 0; i != size;) {
|
});
|
||||||
SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
|
|
||||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].height = buf[j];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Load_MAP1()
|
static void Load_MAP1()
|
||||||
{
|
{
|
||||||
std::array<uint8_t, MAP_SL_BUF_SIZE> buf;
|
TileIndex i = 0;
|
||||||
TileIndex size = MapSize();
|
ReadBuffer::GetCurrent()->ReadBytesToHandler(MapSize(), [&](uint8_t val) {
|
||||||
|
_m[i++].m1 = val;
|
||||||
for (TileIndex i = 0; i != size;) {
|
});
|
||||||
SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
|
|
||||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m1 = buf[j];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Load_MAP2()
|
static void Load_MAP2()
|
||||||
{
|
{
|
||||||
std::array<uint16_t, MAP_SL_BUF_SIZE> buf;
|
TileIndex i = 0;
|
||||||
TileIndex size = MapSize();
|
if (IsSavegameVersionBefore(SLV_5)) {
|
||||||
|
|
||||||
for (TileIndex i = 0; i != size;) {
|
|
||||||
SlArray(buf.data(), MAP_SL_BUF_SIZE,
|
|
||||||
/* In those versions the m2 was 8 bits */
|
/* In those versions the m2 was 8 bits */
|
||||||
IsSavegameVersionBefore(SLV_5) ? SLE_FILE_U8 | SLE_VAR_U16 : SLE_UINT16
|
ReadBuffer::GetCurrent()->ReadBytesToHandler(MapSize(), [&](uint8_t val) {
|
||||||
);
|
_m[i++].m2 = val;
|
||||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m2 = buf[j];
|
});
|
||||||
|
} else {
|
||||||
|
ReadBuffer::GetCurrent()->ReadUint16sToHandler(MapSize(), [&](uint16_t val) {
|
||||||
|
_m[i++].m2 = val;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Load_MAP3()
|
static void Load_MAP3()
|
||||||
{
|
{
|
||||||
std::array<uint8_t, MAP_SL_BUF_SIZE> buf;
|
TileIndex i = 0;
|
||||||
TileIndex size = MapSize();
|
ReadBuffer::GetCurrent()->ReadBytesToHandler(MapSize(), [&](uint8_t val) {
|
||||||
|
_m[i++].m3 = val;
|
||||||
for (TileIndex i = 0; i != size;) {
|
});
|
||||||
SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
|
|
||||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m3 = buf[j];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Load_MAP4()
|
static void Load_MAP4()
|
||||||
{
|
{
|
||||||
std::array<uint8_t, MAP_SL_BUF_SIZE> buf;
|
TileIndex i = 0;
|
||||||
TileIndex size = MapSize();
|
ReadBuffer::GetCurrent()->ReadBytesToHandler(MapSize(), [&](uint8_t val) {
|
||||||
|
_m[i++].m4 = val;
|
||||||
for (TileIndex i = 0; i != size;) {
|
});
|
||||||
SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
|
|
||||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m4 = buf[j];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Load_MAP5()
|
static void Load_MAP5()
|
||||||
{
|
{
|
||||||
std::array<uint8_t, MAP_SL_BUF_SIZE> buf;
|
TileIndex i = 0;
|
||||||
TileIndex size = MapSize();
|
ReadBuffer::GetCurrent()->ReadBytesToHandler(MapSize(), [&](uint8_t val) {
|
||||||
|
_m[i++].m5 = val;
|
||||||
for (TileIndex i = 0; i != size;) {
|
});
|
||||||
SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
|
|
||||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m5 = buf[j];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Load_MAP6()
|
static void Load_MAP6()
|
||||||
{
|
{
|
||||||
std::array<uint8_t, MAP_SL_BUF_SIZE> buf;
|
|
||||||
TileIndex size = MapSize();
|
TileIndex size = MapSize();
|
||||||
|
|
||||||
|
TileIndex i = 0;
|
||||||
if (IsSavegameVersionBefore(SLV_42)) {
|
if (IsSavegameVersionBefore(SLV_42)) {
|
||||||
for (TileIndex i = 0; i != size;) {
|
ReadBuffer::GetCurrent()->ReadBytesToHandler(size / 4, [&](uint8_t val) {
|
||||||
/* 1024, otherwise we overflow on 64x64 maps! */
|
_me[i++].m6 = GB(val, 0, 2);
|
||||||
SlArray(buf.data(), 1024, SLE_UINT8);
|
_me[i++].m6 = GB(val, 2, 2);
|
||||||
for (uint j = 0; j != 1024; j++) {
|
_me[i++].m6 = GB(val, 4, 2);
|
||||||
_me[i++].m6 = GB(buf[j], 0, 2);
|
_me[i++].m6 = GB(val, 6, 2);
|
||||||
_me[i++].m6 = GB(buf[j], 2, 2);
|
});
|
||||||
_me[i++].m6 = GB(buf[j], 4, 2);
|
|
||||||
_me[i++].m6 = GB(buf[j], 6, 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
for (TileIndex i = 0; i != size;) {
|
ReadBuffer::GetCurrent()->ReadBytesToHandler(size, [&](uint8_t val) {
|
||||||
SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
|
_me[i++].m6 = val;
|
||||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m6 = buf[j];
|
});
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Load_MAP7()
|
static void Load_MAP7()
|
||||||
{
|
{
|
||||||
std::array<uint8_t, MAP_SL_BUF_SIZE> buf;
|
TileIndex i = 0;
|
||||||
TileIndex size = MapSize();
|
ReadBuffer::GetCurrent()->ReadBytesToHandler(MapSize(), [&](uint8_t val) {
|
||||||
|
_me[i++].m7 = val;
|
||||||
for (TileIndex i = 0; i != size;) {
|
});
|
||||||
SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8);
|
|
||||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m7 = buf[j];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Load_MAP8()
|
static void Load_MAP8()
|
||||||
{
|
{
|
||||||
std::array<uint16_t, MAP_SL_BUF_SIZE> buf;
|
TileIndex i = 0;
|
||||||
TileIndex size = MapSize();
|
ReadBuffer::GetCurrent()->ReadUint16sToHandler(MapSize(), [&](uint16_t val) {
|
||||||
|
_me[i++].m8 = val;
|
||||||
for (TileIndex i = 0; i != size;) {
|
});
|
||||||
SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16);
|
|
||||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m8 = buf[j];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Load_WMAP()
|
static void Load_WMAP()
|
||||||
@@ -347,33 +315,25 @@ struct MAP8 {
|
|||||||
static const FieldT &GetField(TileIndex t) { return _me[t].m8; }
|
static const FieldT &GetField(TileIndex t) { return _me[t].m8; }
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
|
||||||
struct MAP_VarType {};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct MAP_VarType<uint8_t>
|
|
||||||
{
|
|
||||||
static const VarType var_type = SLE_UINT8;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <>
|
|
||||||
struct MAP_VarType<uint16_t>
|
|
||||||
{
|
|
||||||
static const VarType var_type = SLE_UINT16;
|
|
||||||
};
|
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
static void Save_MAP()
|
static void Save_MAP()
|
||||||
{
|
{
|
||||||
assert(_sl_xv_feature_versions[XSLFI_WHOLE_MAP_CHUNK] == 0);
|
assert(_sl_xv_feature_versions[XSLFI_WHOLE_MAP_CHUNK] == 0);
|
||||||
|
|
||||||
std::array<typename T::FieldT, MAP_SL_BUF_SIZE> buf;
|
static_assert(std::is_same_v<typename T::FieldT, uint8_t> || std::is_same_v<typename T::FieldT, uint16_t>);
|
||||||
TileIndex size = MapSize();
|
|
||||||
|
|
||||||
|
TileIndex size = MapSize();
|
||||||
SlSetLength(size * sizeof(typename T::FieldT));
|
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++);
|
TileIndex i = 0;
|
||||||
SlArray(buf.data(), MAP_SL_BUF_SIZE, MAP_VarType<typename T::FieldT>::var_type);
|
if constexpr (std::is_same_v<typename T::FieldT, uint8_t>) {
|
||||||
|
MemoryDumper::GetCurrent()->WriteBytesFromHandler(size, [&]() -> uint8_t {
|
||||||
|
return T::GetField(i++);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
MemoryDumper::GetCurrent()->WriteUint16sFromHandler(size, [&]() -> uint16_t {
|
||||||
|
return T::GetField(i++);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -139,6 +139,34 @@ struct ReadBuffer {
|
|||||||
this->CopyBytes(buffer.data(), buffer.size());
|
this->CopyBytes(buffer.data(), buffer.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
inline void ReadBytesToHandler(size_t length, F handler)
|
||||||
|
{
|
||||||
|
while (length) {
|
||||||
|
if (unlikely(this->bufp == this->bufe)) {
|
||||||
|
this->AcquireBytes();
|
||||||
|
}
|
||||||
|
size_t to_copy = std::min<size_t>(this->bufe - this->bufp, length);
|
||||||
|
for (size_t i = 0; i < to_copy; i++) {
|
||||||
|
handler(this->RawReadByte());
|
||||||
|
}
|
||||||
|
length -= to_copy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
inline void ReadUint16sToHandler(size_t length, F handler)
|
||||||
|
{
|
||||||
|
while (length) {
|
||||||
|
this->CheckBytes(2);
|
||||||
|
size_t to_copy = std::min<size_t>((this->bufe - this->bufp) / 2, length);
|
||||||
|
for (size_t i = 0; i < to_copy; i++) {
|
||||||
|
handler(this->RawReadUint16());
|
||||||
|
}
|
||||||
|
length -= to_copy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the size of the memory dump made so far.
|
* Get the size of the memory dump made so far.
|
||||||
* @return The size.
|
* @return The size.
|
||||||
@@ -274,6 +302,33 @@ struct MemoryDumper {
|
|||||||
this->buf += 8;
|
this->buf += 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
inline void WriteBytesFromHandler(size_t length, F handler)
|
||||||
|
{
|
||||||
|
while (length) {
|
||||||
|
this->CheckBytes(1);
|
||||||
|
size_t to_copy = std::min<size_t>(this->bufe - this->buf, length);
|
||||||
|
for (size_t i = 0; i < to_copy; i++) {
|
||||||
|
this->RawWriteByte(handler());
|
||||||
|
}
|
||||||
|
length -= to_copy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename F>
|
||||||
|
inline void WriteUint16sFromHandler(size_t length, F handler)
|
||||||
|
{
|
||||||
|
while (length) {
|
||||||
|
this->CheckBytes(2);
|
||||||
|
size_t to_copy = std::min<size_t>((this->bufe - this->buf) / 2, length);
|
||||||
|
for (size_t i = 0; i < to_copy; i++) {
|
||||||
|
this->RawWriteUint16(handler());
|
||||||
|
}
|
||||||
|
length -= to_copy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void Flush(SaveFilter &writer);
|
void Flush(SaveFilter &writer);
|
||||||
size_t GetSize() const;
|
size_t GetSize() const;
|
||||||
void StartAutoLength();
|
void StartAutoLength();
|
||||||
|
Reference in New Issue
Block a user