Saveload: Fix SlNullPointers with upstream chunks
This commit is contained in:
@@ -184,7 +184,7 @@ void SlNullPointers()
|
|||||||
/* We don't want any savegame conversion code to run
|
/* We don't want any savegame conversion code to run
|
||||||
* during NULLing; especially those that try to get
|
* during NULLing; especially those that try to get
|
||||||
* pointers from other pools. */
|
* pointers from other pools. */
|
||||||
_sl_version = SAVEGAME_VERSION;
|
_sl_version = MAX_LOAD_SAVEGAME_VERSION;
|
||||||
|
|
||||||
for (const ChunkHandler &ch : ChunkHandlers()) {
|
for (const ChunkHandler &ch : ChunkHandlers()) {
|
||||||
DEBUG(sl, 3, "Nulling pointers for %c%c%c%c", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id);
|
DEBUG(sl, 3, "Nulling pointers for %c%c%c%c", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id);
|
||||||
@@ -2038,12 +2038,24 @@ void SlFixPointers()
|
|||||||
|
|
||||||
void SlFixPointerChunkByID(uint32_t id)
|
void SlFixPointerChunkByID(uint32_t id)
|
||||||
{
|
{
|
||||||
|
_sl.action = SLA_PTRS;
|
||||||
|
|
||||||
const ChunkHandler *ch = SlFindChunkHandler(id);
|
const ChunkHandler *ch = SlFindChunkHandler(id);
|
||||||
if (ch == nullptr) SlErrorCorrupt("Unknown chunk type");
|
if (ch == nullptr) SlErrorCorrupt("Unknown chunk type");
|
||||||
DEBUG(sl, 3, "Fixing pointers for %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
|
DEBUG(sl, 3, "Fixing pointers for %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
|
||||||
ch->FixPointers();
|
ch->FixPointers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SlNullPointerChunkByID(uint32_t id)
|
||||||
|
{
|
||||||
|
_sl.action = SLA_NULL;
|
||||||
|
|
||||||
|
const ChunkHandler *ch = SlFindChunkHandler(id);
|
||||||
|
if (ch == nullptr) SlErrorCorrupt("Unknown chunk type");
|
||||||
|
DEBUG(sl, 3, "Nulling pointers for %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id);
|
||||||
|
ch->FixPointers();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save a chunk of data (eg. vehicles, stations, etc.). Each chunk is
|
* Save a chunk of data (eg. vehicles, stations, etc.). Each chunk is
|
||||||
* prefixed by an ID identifying it, followed by data, and terminator where appropriate
|
* prefixed by an ID identifying it, followed by data, and terminator where appropriate
|
||||||
|
@@ -91,6 +91,7 @@ extern bool _sl_upstream_mode;
|
|||||||
|
|
||||||
namespace upstream_sl {
|
namespace upstream_sl {
|
||||||
void SlNullPointers();
|
void SlNullPointers();
|
||||||
|
void SlNullPointerChunkByID(uint32_t);
|
||||||
void SlLoadChunks();
|
void SlLoadChunks();
|
||||||
void SlLoadChunkByID(uint32_t id);
|
void SlLoadChunkByID(uint32_t id);
|
||||||
void SlLoadCheckChunks();
|
void SlLoadCheckChunks();
|
||||||
@@ -380,6 +381,14 @@ static void SlNullPointers()
|
|||||||
|
|
||||||
_sl.action = SLA_NULL;
|
_sl.action = SLA_NULL;
|
||||||
|
|
||||||
|
/* Do upstream chunk tests before clearing version data */
|
||||||
|
ring_buffer<uint32_t> upstream_null_chunks;
|
||||||
|
for (auto &ch : ChunkHandlers()) {
|
||||||
|
if (ch.special_proc != nullptr && ch.special_proc(ch.id, CSLSO_PRE_NULL_PTRS) == CSLSOR_UPSTREAM_NULL_PTRS) {
|
||||||
|
upstream_null_chunks.push_back(ch.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* We don't want any savegame conversion code to run
|
/* We don't want any savegame conversion code to run
|
||||||
* during NULLing; especially those that try to get
|
* during NULLing; especially those that try to get
|
||||||
* pointers from other pools. */
|
* pointers from other pools. */
|
||||||
@@ -387,9 +396,14 @@ static void SlNullPointers()
|
|||||||
SlXvSetCurrentState();
|
SlXvSetCurrentState();
|
||||||
|
|
||||||
for (auto &ch : ChunkHandlers()) {
|
for (auto &ch : ChunkHandlers()) {
|
||||||
if (ch.special_proc != nullptr) {
|
if (!upstream_null_chunks.empty() && upstream_null_chunks.front() == ch.id) {
|
||||||
if (ch.special_proc(ch.id, CSLSO_PRE_PTRS) == CSLSOR_LOAD_CHUNK_CONSUMED) continue;
|
upstream_null_chunks.pop_front();
|
||||||
|
SlExecWithSlVersion(MAX_LOAD_SAVEGAME_VERSION, [&]() {
|
||||||
|
upstream_sl::SlNullPointerChunkByID(ch.id);
|
||||||
|
});
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ch.ptrs_proc != nullptr) {
|
if (ch.ptrs_proc != nullptr) {
|
||||||
DEBUG(sl, 3, "Nulling pointers for %c%c%c%c", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id);
|
DEBUG(sl, 3, "Nulling pointers for %c%c%c%c", ch.id >> 24, ch.id >> 16, ch.id >> 8, ch.id);
|
||||||
ch.ptrs_proc();
|
ch.ptrs_proc();
|
||||||
|
@@ -90,6 +90,7 @@ enum ChunkSaveLoadSpecialOp {
|
|||||||
CSLSO_PRE_LOAD,
|
CSLSO_PRE_LOAD,
|
||||||
CSLSO_PRE_LOADCHECK,
|
CSLSO_PRE_LOADCHECK,
|
||||||
CSLSO_PRE_PTRS,
|
CSLSO_PRE_PTRS,
|
||||||
|
CSLSO_PRE_NULL_PTRS,
|
||||||
CSLSO_SHOULD_SAVE_CHUNK,
|
CSLSO_SHOULD_SAVE_CHUNK,
|
||||||
};
|
};
|
||||||
enum ChunkSaveLoadSpecialOpResult {
|
enum ChunkSaveLoadSpecialOpResult {
|
||||||
@@ -97,6 +98,7 @@ enum ChunkSaveLoadSpecialOpResult {
|
|||||||
CSLSOR_LOAD_CHUNK_CONSUMED,
|
CSLSOR_LOAD_CHUNK_CONSUMED,
|
||||||
CSLSOR_DONT_SAVE_CHUNK,
|
CSLSOR_DONT_SAVE_CHUNK,
|
||||||
CSLSOR_UPSTREAM_SAVE_CHUNK,
|
CSLSOR_UPSTREAM_SAVE_CHUNK,
|
||||||
|
CSLSOR_UPSTREAM_NULL_PTRS,
|
||||||
};
|
};
|
||||||
typedef ChunkSaveLoadSpecialOpResult ChunkSaveLoadSpecialProc(uint32_t, ChunkSaveLoadSpecialOp);
|
typedef ChunkSaveLoadSpecialOpResult ChunkSaveLoadSpecialProc(uint32_t, ChunkSaveLoadSpecialOp);
|
||||||
|
|
||||||
@@ -189,6 +191,8 @@ namespace upstream_sl {
|
|||||||
SlFixPointerChunkByID(id);
|
SlFixPointerChunkByID(id);
|
||||||
});
|
});
|
||||||
return CSLSOR_LOAD_CHUNK_CONSUMED;
|
return CSLSOR_LOAD_CHUNK_CONSUMED;
|
||||||
|
case CSLSO_PRE_NULL_PTRS:
|
||||||
|
return CSLSOR_UPSTREAM_NULL_PTRS;
|
||||||
case CSLSO_SHOULD_SAVE_CHUNK:
|
case CSLSO_SHOULD_SAVE_CHUNK:
|
||||||
return CSLSOR_UPSTREAM_SAVE_CHUNK;
|
return CSLSOR_UPSTREAM_SAVE_CHUNK;
|
||||||
default:
|
default:
|
||||||
@@ -234,6 +238,9 @@ namespace upstream_sl {
|
|||||||
SlFixPointerChunkByID(id);
|
SlFixPointerChunkByID(id);
|
||||||
});
|
});
|
||||||
return CSLSOR_LOAD_CHUNK_CONSUMED;
|
return CSLSOR_LOAD_CHUNK_CONSUMED;
|
||||||
|
case CSLSO_PRE_NULL_PTRS:
|
||||||
|
if (!F::LoadUpstream()) return CSLSOR_NONE;
|
||||||
|
return CSLSOR_UPSTREAM_NULL_PTRS;
|
||||||
case CSLSO_SHOULD_SAVE_CHUNK:
|
case CSLSO_SHOULD_SAVE_CHUNK:
|
||||||
return F::SaveUpstream() ? CSLSOR_UPSTREAM_SAVE_CHUNK : CSLSOR_NONE;
|
return F::SaveUpstream() ? CSLSOR_UPSTREAM_SAVE_CHUNK : CSLSOR_NONE;
|
||||||
default:
|
default:
|
||||||
|
Reference in New Issue
Block a user