2 * This file is part of OpenTTD.
3 * 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.
4 * 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.
5 * 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/>.
8 /** @file oldloader.h Declarations of strctures and function used in loader of old savegames */
14 #include "../tile_type.h"
16 static const uint BUFFER_SIZE
= 4096;
17 static const uint OLD_MAP_SIZE
= 256;
19 struct LoadgameState
{
20 std::optional
<FileHandle
> file
;
29 uint8_t buffer
[BUFFER_SIZE
];
40 /* 4 bits allocated (16 max) */
42 OC_TTD
= 1 << 4, ///< chunk is valid ONLY for TTD savegames
43 OC_TTO
= 1 << 5, ///< -//- TTO (default is neither of these)
44 /* 4 bits allocated */
54 /* 8 bits allocated (256 max) */
58 OC_FILE_I16
= 3 << 16,
59 OC_FILE_U16
= 4 << 16,
60 OC_FILE_I32
= 5 << 16,
61 OC_FILE_U32
= 6 << 16,
62 /* 8 bits allocated (256 max) */
64 OC_INT8
= OC_VAR_I8
| OC_FILE_I8
,
65 OC_UINT8
= OC_VAR_U8
| OC_FILE_U8
,
66 OC_INT16
= OC_VAR_I16
| OC_FILE_I16
,
67 OC_UINT16
= OC_VAR_U16
| OC_FILE_U16
,
68 OC_INT32
= OC_VAR_I32
| OC_FILE_I32
,
69 OC_UINT32
= OC_VAR_U32
| OC_FILE_U32
,
71 OC_TILE
= OC_VAR_U32
| OC_FILE_U16
,
74 * Dereference the pointer once before writing to it,
75 * so we do not have to use big static arrays.
77 OC_DEREFERENCE_POINTER
= 1 << 31,
79 OC_END
= 0, ///< End of the whole chunk, all 32 bits set to zero
82 DECLARE_ENUM_AS_BIT_SET(OldChunkType
)
84 typedef bool OldChunkProc(LoadgameState
*ls
, int num
);
85 typedef void *OffsetProc(void *base
);
88 OldChunkType type
; ///< Type of field
89 uint32_t amount
; ///< Amount of fields
91 void *ptr
; ///< Pointer where to save the data (takes precedence over #offset)
92 OffsetProc
*offset
; ///< Pointer to function that returns the actual memory address of a member (ignored if #ptr is not nullptr)
93 OldChunkProc
*proc
; ///< Pointer to function that is called with OC_CHUNK
96 extern uint _bump_assert_value
;
97 uint8_t ReadByte(LoadgameState
*ls
);
98 bool LoadChunk(LoadgameState
*ls
, void *base
, const OldChunks
*chunks
);
100 bool LoadTTDMain(LoadgameState
*ls
);
101 bool LoadTTOMain(LoadgameState
*ls
);
103 inline uint16_t ReadUint16(LoadgameState
*ls
)
105 uint8_t x
= ReadByte(ls
);
106 return x
| ReadByte(ls
) << 8;
109 inline uint32_t ReadUint32(LoadgameState
*ls
)
111 uint16_t x
= ReadUint16(ls
);
112 return x
| ReadUint16(ls
) << 16;
116 * - OCL_SVAR: load 'type' to offset 'offset' in a struct of type 'base', which must also
117 * be given via base in LoadChunk() as real pointer
118 * - OCL_VAR: load 'type' to a global var
119 * - OCL_END: every struct must end with this
120 * - OCL_NULL: read 'amount' of bytes and send them to /dev/null or something
121 * - OCL_CHUNK: load another proc to load a part of the savegame, 'amount' times
122 * - OCL_ASSERT: to check if we are really at the place we expect to be.. because old savegames are too binary to be sure ;)
124 #define OCL_SVAR(type, base, offset) { type, 1, nullptr, [] (void *b) -> void * { return std::addressof(static_cast<base *>(b)->offset); }, nullptr }
125 #define OCL_VAR(type, amount, pointer) { type, amount, pointer, nullptr, nullptr }
126 #define OCL_END() { OC_END, 0, nullptr, nullptr, nullptr }
127 #define OCL_CNULL(type, amount) { OC_NULL | type, amount, nullptr, nullptr, nullptr }
128 #define OCL_CCHUNK(type, amount, proc) { OC_CHUNK | type, amount, nullptr, nullptr, proc }
129 #define OCL_ASSERT(type, size) { OC_ASSERT | type, 1, (void *)(size_t)size, nullptr, nullptr }
130 #define OCL_NULL(amount) OCL_CNULL((OldChunkType)0, amount)
131 #define OCL_CHUNK(amount, proc) OCL_CCHUNK((OldChunkType)0, amount, proc)
133 #endif /* OLDLOADER_H */