mirror of
https://github.com/JGRennison/OpenTTD-patches.git
synced 2024-11-11 13:10:45 +00:00
Saveload: Remove intermediate copy in map individual chunk save/load
This commit is contained in:
parent
f739710ad3
commit
159e68c4dc
@ -54,17 +54,12 @@ static void Check_MAPS()
|
||||
_load_check_data.map_size_y = _map_dim_y;
|
||||
}
|
||||
|
||||
static const uint MAP_SL_BUF_SIZE = 4096;
|
||||
|
||||
static void Load_MAPT()
|
||||
{
|
||||
std::array<uint8_t, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
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];
|
||||
}
|
||||
TileIndex i = 0;
|
||||
ReadBuffer::GetCurrent()->ReadBytesToHandler(MapSize(), [&](uint8_t val) {
|
||||
_m[i++].type = val;
|
||||
});
|
||||
}
|
||||
|
||||
static void Check_MAPH_common()
|
||||
@ -88,128 +83,101 @@ static void Load_MAPH()
|
||||
if (SlXvIsFeaturePresent(XSLFI_CHILLPP)) {
|
||||
if (SlGetFieldLength() != 0) {
|
||||
_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;) {
|
||||
SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16);
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].height = buf[j];
|
||||
}
|
||||
TileIndex i = 0;
|
||||
ReadBuffer::GetCurrent()->ReadUint16sToHandler(MapSize(), [&](uint16_t val) {
|
||||
_m[i++].height = val;
|
||||
});
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
std::array<uint8_t, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
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];
|
||||
}
|
||||
TileIndex i = 0;
|
||||
ReadBuffer::GetCurrent()->ReadBytesToHandler(MapSize(), [&](uint8_t val) {
|
||||
_m[i++].height = val;
|
||||
});
|
||||
}
|
||||
|
||||
static void Load_MAP1()
|
||||
{
|
||||
std::array<uint8_t, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
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];
|
||||
}
|
||||
TileIndex i = 0;
|
||||
ReadBuffer::GetCurrent()->ReadBytesToHandler(MapSize(), [&](uint8_t val) {
|
||||
_m[i++].m1 = val;
|
||||
});
|
||||
}
|
||||
|
||||
static void Load_MAP2()
|
||||
{
|
||||
std::array<uint16_t, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
SlArray(buf.data(), MAP_SL_BUF_SIZE,
|
||||
/* In those versions the m2 was 8 bits */
|
||||
IsSavegameVersionBefore(SLV_5) ? SLE_FILE_U8 | SLE_VAR_U16 : SLE_UINT16
|
||||
);
|
||||
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m2 = buf[j];
|
||||
TileIndex i = 0;
|
||||
if (IsSavegameVersionBefore(SLV_5)) {
|
||||
/* In those versions the m2 was 8 bits */
|
||||
ReadBuffer::GetCurrent()->ReadBytesToHandler(MapSize(), [&](uint8_t val) {
|
||||
_m[i++].m2 = val;
|
||||
});
|
||||
} else {
|
||||
ReadBuffer::GetCurrent()->ReadUint16sToHandler(MapSize(), [&](uint16_t val) {
|
||||
_m[i++].m2 = val;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_MAP3()
|
||||
{
|
||||
std::array<uint8_t, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
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];
|
||||
}
|
||||
TileIndex i = 0;
|
||||
ReadBuffer::GetCurrent()->ReadBytesToHandler(MapSize(), [&](uint8_t val) {
|
||||
_m[i++].m3 = val;
|
||||
});
|
||||
}
|
||||
|
||||
static void Load_MAP4()
|
||||
{
|
||||
std::array<uint8_t, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
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];
|
||||
}
|
||||
TileIndex i = 0;
|
||||
ReadBuffer::GetCurrent()->ReadBytesToHandler(MapSize(), [&](uint8_t val) {
|
||||
_m[i++].m4 = val;
|
||||
});
|
||||
}
|
||||
|
||||
static void Load_MAP5()
|
||||
{
|
||||
std::array<uint8_t, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
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];
|
||||
}
|
||||
TileIndex i = 0;
|
||||
ReadBuffer::GetCurrent()->ReadBytesToHandler(MapSize(), [&](uint8_t val) {
|
||||
_m[i++].m5 = val;
|
||||
});
|
||||
}
|
||||
|
||||
static void Load_MAP6()
|
||||
{
|
||||
std::array<uint8_t, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
TileIndex i = 0;
|
||||
if (IsSavegameVersionBefore(SLV_42)) {
|
||||
for (TileIndex i = 0; i != size;) {
|
||||
/* 1024, otherwise we overflow on 64x64 maps! */
|
||||
SlArray(buf.data(), 1024, SLE_UINT8);
|
||||
for (uint j = 0; j != 1024; j++) {
|
||||
_me[i++].m6 = GB(buf[j], 0, 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);
|
||||
}
|
||||
}
|
||||
ReadBuffer::GetCurrent()->ReadBytesToHandler(size / 4, [&](uint8_t val) {
|
||||
_me[i++].m6 = GB(val, 0, 2);
|
||||
_me[i++].m6 = GB(val, 2, 2);
|
||||
_me[i++].m6 = GB(val, 4, 2);
|
||||
_me[i++].m6 = GB(val, 6, 2);
|
||||
});
|
||||
} else {
|
||||
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++].m6 = buf[j];
|
||||
}
|
||||
ReadBuffer::GetCurrent()->ReadBytesToHandler(size, [&](uint8_t val) {
|
||||
_me[i++].m6 = val;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static void Load_MAP7()
|
||||
{
|
||||
std::array<uint8_t, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
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];
|
||||
}
|
||||
TileIndex i = 0;
|
||||
ReadBuffer::GetCurrent()->ReadBytesToHandler(MapSize(), [&](uint8_t val) {
|
||||
_me[i++].m7 = val;
|
||||
});
|
||||
}
|
||||
|
||||
static void Load_MAP8()
|
||||
{
|
||||
std::array<uint16_t, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
|
||||
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];
|
||||
}
|
||||
TileIndex i = 0;
|
||||
ReadBuffer::GetCurrent()->ReadUint16sToHandler(MapSize(), [&](uint16_t val) {
|
||||
_me[i++].m8 = val;
|
||||
});
|
||||
}
|
||||
|
||||
static void Load_WMAP()
|
||||
@ -347,33 +315,25 @@ struct MAP8 {
|
||||
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>
|
||||
static void Save_MAP()
|
||||
{
|
||||
assert(_sl_xv_feature_versions[XSLFI_WHOLE_MAP_CHUNK] == 0);
|
||||
|
||||
std::array<typename T::FieldT, MAP_SL_BUF_SIZE> buf;
|
||||
TileIndex size = MapSize();
|
||||
static_assert(std::is_same_v<typename T::FieldT, uint8_t> || std::is_same_v<typename T::FieldT, uint16_t>);
|
||||
|
||||
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<typename T::FieldT>::var_type);
|
||||
|
||||
TileIndex i = 0;
|
||||
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());
|
||||
}
|
||||
|
||||
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.
|
||||
* @return The size.
|
||||
@ -274,6 +302,33 @@ struct MemoryDumper {
|
||||
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);
|
||||
size_t GetSize() const;
|
||||
void StartAutoLength();
|
||||
|
Loading…
Reference in New Issue
Block a user