|
@@ -19,12 +19,14 @@
|
|
|
|
|
|
#include "table/strings.h"
|
|
|
|
|
|
#include "saveload_internal.h"
|
|
|
#include "oldloader.h"
|
|
|
|
|
|
#include <exception>
|
|
|
|
|
|
static const int TTO_HEADER_SIZE = 41;
|
|
|
static const int TTD_HEADER_SIZE = 49;
|
|
|
|
|
|
uint32 _bump_assert_value;
|
|
|
|
|
|
static inline OldChunkType GetOldChunkType(OldChunkType type) {return (OldChunkType)GB(type, 0, 4);}
|
|
@@ -46,19 +48,20 @@ static inline byte CalcOldVarLen(OldChun
|
|
|
*/
|
|
|
static byte ReadByteFromFile(LoadgameState *ls)
|
|
|
{
|
|
|
/* To avoid slow reads, we read BUFFER_SIZE of bytes per time
|
|
|
and just return a byte per time */
|
|
|
if (ls->buffer_cur >= ls->buffer_count) {
|
|
|
|
|
|
/* Read some new bytes from the file */
|
|
|
int count = (int)fread(ls->buffer, 1, BUFFER_SIZE, ls->file);
|
|
|
|
|
|
/* We tried to read, but there is nothing in the file anymore.. */
|
|
|
if (count == 0) {
|
|
|
DEBUG(oldloader, 0, "Read past end of file, loading failed");
|
|
|
ls->failed = true;
|
|
|
throw std::exception();
|
|
|
}
|
|
|
|
|
|
ls->buffer_count = count;
|
|
|
ls->buffer_cur = 0;
|
|
|
}
|
|
|
|
|
@@ -116,14 +119,12 @@ bool LoadChunk(LoadgameState *ls, void *
|
|
|
}
|
|
|
|
|
|
byte *ptr = (byte*)chunk->ptr;
|
|
|
if (chunk->type & OC_DEREFERENCE_POINTER) ptr = *(byte**)ptr;
|
|
|
|
|
|
for (uint i = 0; i < chunk->amount; i++) {
|
|
|
if (ls->failed) return false;
|
|
|
|
|
|
/* Handle simple types */
|
|
|
if (GetOldChunkType(chunk->type) != 0) {
|
|
|
switch (GetOldChunkType(chunk->type)) {
|
|
|
/* Just read the byte and forget about it */
|
|
|
case OC_NULL: ReadByte(ls); break;
|
|
|
|
|
@@ -132,13 +133,13 @@ bool LoadChunk(LoadgameState *ls, void *
|
|
|
* are going to read */
|
|
|
if (!chunk->proc(ls, i)) return false;
|
|
|
break;
|
|
|
|
|
|
case OC_ASSERT:
|
|
|
DEBUG(oldloader, 4, "Assert point: 0x%X / 0x%X", ls->total_read, chunk->offset + _bump_assert_value);
|
|
|
if (ls->total_read != chunk->offset + _bump_assert_value) ls->failed = true;
|
|
|
if (ls->total_read != chunk->offset + _bump_assert_value) throw std::exception();
|
|
|
default: break;
|
|
|
}
|
|
|
} else {
|
|
|
uint64 res = 0;
|
|
|
|
|
|
/* Reading from the file: bits 16 to 23 have the FILE type */
|
|
@@ -186,13 +187,12 @@ bool LoadChunk(LoadgameState *ls, void *
|
|
|
*
|
|
|
*/
|
|
|
static void InitLoading(LoadgameState *ls)
|
|
|
{
|
|
|
ls->chunk_size = 0;
|
|
|
ls->total_read = 0;
|
|
|
ls->failed = false;
|
|
|
|
|
|
ls->decoding = false;
|
|
|
ls->decode_char = 0;
|
|
|
|
|
|
ls->buffer_cur = 0;
|
|
|
ls->buffer_count = 0;
|
|
@@ -298,13 +298,20 @@ bool LoadOldSaveGame(const char *file)
|
|
|
case SGT_TTD: proc = &LoadTTDMain; break;
|
|
|
default: break;
|
|
|
}
|
|
|
|
|
|
_savegame_type = type;
|
|
|
|
|
|
if (proc == NULL || !proc(&ls)) {
|
|
|
bool game_loaded;
|
|
|
try {
|
|
|
game_loaded = proc != NULL && proc(&ls);
|
|
|
} catch (...) {
|
|
|
game_loaded = false;
|
|
|
}
|
|
|
|
|
|
if (!game_loaded) {
|
|
|
SetSaveLoadError(STR_GAME_SAVELOAD_ERROR_DATA_INTEGRITY_CHECK_FAILED);
|
|
|
fclose(ls.file);
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
_pause_mode = 2;
|