2009-08-21 20:21:05 +00:00
|
|
|
/*
|
|
|
|
* This file is part of OpenTTD.
|
|
|
|
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
|
|
|
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*/
|
|
|
|
|
2009-01-20 16:47:42 +00:00
|
|
|
/** @file oldloader.h Declarations of strctures and function used in loader of old savegames */
|
|
|
|
|
|
|
|
#ifndef OLDLOADER_H
|
|
|
|
#define OLDLOADER_H
|
|
|
|
|
|
|
|
#include "saveload.h"
|
2010-01-15 16:41:15 +00:00
|
|
|
#include "../tile_type.h"
|
2009-01-20 16:47:42 +00:00
|
|
|
|
2010-05-13 09:44:44 +00:00
|
|
|
static const uint BUFFER_SIZE = 4096;
|
|
|
|
static const uint OLD_MAP_SIZE = 256 * 256;
|
2009-01-20 16:47:42 +00:00
|
|
|
|
|
|
|
struct LoadgameState {
|
|
|
|
FILE *file;
|
|
|
|
|
|
|
|
uint chunk_size;
|
|
|
|
|
|
|
|
bool decoding;
|
|
|
|
byte decode_char;
|
|
|
|
|
|
|
|
uint buffer_count;
|
|
|
|
uint buffer_cur;
|
|
|
|
byte buffer[BUFFER_SIZE];
|
|
|
|
|
|
|
|
uint total_read;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* OldChunk-Type */
|
|
|
|
enum OldChunkType {
|
|
|
|
OC_SIMPLE = 0,
|
|
|
|
OC_NULL = 1,
|
|
|
|
OC_CHUNK = 2,
|
|
|
|
OC_ASSERT = 3,
|
2009-01-23 02:35:17 +00:00
|
|
|
/* 4 bits allocated (16 max) */
|
|
|
|
|
|
|
|
OC_TTD = 1 << 4, ///< chunk is valid ONLY for TTD savegames
|
2009-01-23 13:36:12 +00:00
|
|
|
OC_TTO = 1 << 5, ///< -//- TTO (default is neither of these)
|
2009-01-23 02:35:17 +00:00
|
|
|
/* 4 bits allocated */
|
2009-01-20 16:47:42 +00:00
|
|
|
|
|
|
|
OC_VAR_I8 = 1 << 8,
|
|
|
|
OC_VAR_U8 = 2 << 8,
|
|
|
|
OC_VAR_I16 = 3 << 8,
|
|
|
|
OC_VAR_U16 = 4 << 8,
|
|
|
|
OC_VAR_I32 = 5 << 8,
|
|
|
|
OC_VAR_U32 = 6 << 8,
|
|
|
|
OC_VAR_I64 = 7 << 8,
|
2009-01-25 22:50:00 +00:00
|
|
|
OC_VAR_U64 = 8 << 8,
|
2009-01-20 16:47:42 +00:00
|
|
|
/* 8 bits allocated (256 max) */
|
|
|
|
|
|
|
|
OC_FILE_I8 = 1 << 16,
|
|
|
|
OC_FILE_U8 = 2 << 16,
|
|
|
|
OC_FILE_I16 = 3 << 16,
|
|
|
|
OC_FILE_U16 = 4 << 16,
|
|
|
|
OC_FILE_I32 = 5 << 16,
|
|
|
|
OC_FILE_U32 = 6 << 16,
|
|
|
|
/* 8 bits allocated (256 max) */
|
|
|
|
|
|
|
|
OC_INT8 = OC_VAR_I8 | OC_FILE_I8,
|
|
|
|
OC_UINT8 = OC_VAR_U8 | OC_FILE_U8,
|
|
|
|
OC_INT16 = OC_VAR_I16 | OC_FILE_I16,
|
|
|
|
OC_UINT16 = OC_VAR_U16 | OC_FILE_U16,
|
|
|
|
OC_INT32 = OC_VAR_I32 | OC_FILE_I32,
|
|
|
|
OC_UINT32 = OC_VAR_U32 | OC_FILE_U32,
|
|
|
|
|
|
|
|
OC_TILE = OC_VAR_U32 | OC_FILE_U16,
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Dereference the pointer once before writing to it,
|
|
|
|
* so we do not have to use big static arrays.
|
|
|
|
*/
|
|
|
|
OC_DEREFERENCE_POINTER = 1 << 31,
|
|
|
|
|
2011-12-19 17:48:04 +00:00
|
|
|
OC_END = 0, ///< End of the whole chunk, all 32 bits set to zero
|
2009-01-20 16:47:42 +00:00
|
|
|
};
|
|
|
|
|
2010-03-23 22:25:43 +00:00
|
|
|
DECLARE_ENUM_AS_BIT_SET(OldChunkType)
|
2009-01-20 16:47:42 +00:00
|
|
|
|
|
|
|
typedef bool OldChunkProc(LoadgameState *ls, int num);
|
|
|
|
|
|
|
|
struct OldChunks {
|
|
|
|
OldChunkType type; ///< Type of field
|
|
|
|
uint32 amount; ///< Amount of fields
|
|
|
|
|
|
|
|
void *ptr; ///< Pointer where to save the data (may only be set if offset is 0)
|
2019-04-10 21:07:06 +00:00
|
|
|
uint offset; ///< Offset from basepointer (may only be set if ptr is nullptr)
|
2009-01-20 16:47:42 +00:00
|
|
|
OldChunkProc *proc; ///< Pointer to function that is called with OC_CHUNK
|
|
|
|
};
|
|
|
|
|
|
|
|
/* If it fails, check lines above.. */
|
|
|
|
assert_compile(sizeof(TileIndex) == 4);
|
|
|
|
|
|
|
|
extern uint _bump_assert_value;
|
|
|
|
byte ReadByte(LoadgameState *ls);
|
|
|
|
bool LoadChunk(LoadgameState *ls, void *base, const OldChunks *chunks);
|
|
|
|
|
2009-01-23 02:35:17 +00:00
|
|
|
bool LoadTTDMain(LoadgameState *ls);
|
|
|
|
bool LoadTTOMain(LoadgameState *ls);
|
2009-01-20 16:47:42 +00:00
|
|
|
|
|
|
|
static inline uint16 ReadUint16(LoadgameState *ls)
|
|
|
|
{
|
|
|
|
byte x = ReadByte(ls);
|
|
|
|
return x | ReadByte(ls) << 8;
|
|
|
|
}
|
|
|
|
|
|
|
|
static inline uint32 ReadUint32(LoadgameState *ls)
|
|
|
|
{
|
|
|
|
uint16 x = ReadUint16(ls);
|
|
|
|
return x | ReadUint16(ls) << 16;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Help:
|
|
|
|
* - OCL_SVAR: load 'type' to offset 'offset' in a struct of type 'base', which must also
|
|
|
|
* be given via base in LoadChunk() as real pointer
|
|
|
|
* - OCL_VAR: load 'type' to a global var
|
|
|
|
* - OCL_END: every struct must end with this
|
|
|
|
* - OCL_NULL: read 'amount' of bytes and send them to /dev/null or something
|
2010-01-01 18:45:40 +00:00
|
|
|
* - OCL_CHUNK: load another proc to load a part of the savegame, 'amount' times
|
2009-01-20 16:47:42 +00:00
|
|
|
* - OCL_ASSERT: to check if we are really at the place we expect to be.. because old savegames are too binary to be sure ;)
|
|
|
|
*/
|
2019-04-13 19:18:31 +00:00
|
|
|
#define OCL_SVAR(type, base, offset) { type, 1, nullptr, (uint)cpp_offsetof(base, offset), nullptr }
|
2019-04-10 21:07:06 +00:00
|
|
|
#define OCL_VAR(type, amount, pointer) { type, amount, pointer, 0, nullptr }
|
2019-04-13 19:18:31 +00:00
|
|
|
#define OCL_END() { OC_END, 0, nullptr, 0, nullptr }
|
|
|
|
#define OCL_CNULL(type, amount) { OC_NULL | type, amount, nullptr, 0, nullptr }
|
|
|
|
#define OCL_CCHUNK(type, amount, proc) { OC_CHUNK | type, amount, nullptr, 0, proc }
|
|
|
|
#define OCL_ASSERT(type, size) { OC_ASSERT | type, 1, nullptr, size, nullptr }
|
2009-01-23 02:35:17 +00:00
|
|
|
#define OCL_NULL(amount) OCL_CNULL((OldChunkType)0, amount)
|
|
|
|
#define OCL_CHUNK(amount, proc) OCL_CCHUNK((OldChunkType)0, amount, proc)
|
2009-01-20 16:47:42 +00:00
|
|
|
|
|
|
|
#endif /* OLDLOADER_H */
|