@ -13,7 +13,6 @@ typedef struct SaveLoadGlobVarList {
byte to_version ;
} SaveLoadGlobVarList ;
typedef struct {
uint32 id ;
ChunkSaveLoadProc * save_proc ;
@ -28,62 +27,63 @@ typedef struct {
typedef void WriterProc ( uint len ) ;
typedef uint ReaderProc ( void ) ;
typedef uint ReferenceToIntProc ( void * v , uint t ) ;
typedef void * IntToReferenceProc ( uint r , uint t ) ;
typedef enum SLRefType {
REF_ORDER = 0 ,
REF_VEHICLE = 1 ,
REF_STATION = 2 ,
REF_TOWN = 3 ,
REF_VEHICLE_OLD = 4 ,
REF_ROADSTOPS = 5
} SLRefType ;
typedef uint ReferenceToIntProc ( const void * obj , SLRefType rt ) ;
typedef void * IntToReferenceProc ( uint index , SLRefType rt ) ;
typedef struct {
bool save ;
byte need_length ;
byte block_mode ;
bool error ;
byte version ;
uint16 full_version ;
typedef struct SaveLoad SaveLoad ;
int obj_len ;
int array_index , last_array_index ;
/** The saveload struct, containing reader-writer functions, bufffer, version, etc. */
typedef struct {
bool save ; /// are we doing a save or a load atm. True when saving
byte need_length ; /// ???
byte block_mode ; /// ???
bool error ; /// did an error occur or not
byte version ; /// the major savegame version identifier
uint16 full_version ; /// the full version of the savegame
uint32 offs_base ;
int obj_len ; /// the length of the current object we are busy with
int array_index , last_array_index ; /// in the case of an array, the current and last positions
WriterProc * write_bytes ;
ReaderProc * read_bytes ;
uint32 offs_base ; /// the offset in number of bytes since we started writing data (eg uncompressed savegame size)
ReferenceToIntProc * ref_to_int_proc ;
IntToReferenceProc * int_to_ref_proc ;
WriterProc * write_bytes ; /// savegame writer function
ReaderProc * read_bytes ; /// savegame loader function
const ChunkHandler * const * chs ;
const byte * const * includes ;
ReferenceToIntProc * ref_to_int_proc ; /// function to convert pointers to numbers when saving a game
IntToReferenceProc * int_to_ref_proc ; /// function to convert numbers to pointers when loading a game
byte * bufp , * bufe ;
const ChunkHandler * const * chs ; /// the chunk of data that is being processed atm (vehicles, signs, etc.)
const SaveLoad * const * includes ; /// the internal layouf of the given chunk
int tmp ;
/** When saving/loading savegames, they are always saved to a temporary memory-place
* to be flushed to file ( save ) or to final place ( load ) when full . */
byte * bufp , * bufe ; /// bufp(ointer) gives the current position in the buffer bufe(nd) gives the end of the buffer
// these 3 may be used by compressor/decompressors.
byte * buf ; // pointer and size to read/write, initialized by init
uint bufsize ;
FILE * fh ;
byte * buf ; /// pointer to temporary memory to read/write, initialized by SaveLoadFormat->initread/write
uint bufsize ; /// the size of the temporary memory *buf
FILE * fh ; /// the file from which is read or written to
void ( * excpt_uninit ) ( void ) ;
const char * excpt_msg ;
jmp_buf excpt ; // used to jump to "exception handler"
void ( * excpt_uninit ) ( void ) ; /// the function to execute on any encountered error
const char * excpt_msg ; /// the error message
jmp_buf excpt ; // / @todo used to jump to "exception handler"; really ugly
} SaverLoader ;
extern SaverLoader _sl ;
enum {
REF_ORDER = 0 ,
REF_VEHICLE = 1 ,
REF_STATION = 2 ,
REF_TOWN = 3 ,
REF_VEHICLE_OLD = 4 ,
REF_ROADSTOPS = 5
} ;
enum {
INC_VEHICLE_COMMON = 0 ,
} ;
enum {
CH_RIFF = 0 ,
CH_ARRAY = 1 ,
@ -99,9 +99,9 @@ enum {
CH_NUM_PRI_LEVELS = 4 ,
} ;
enum {
SLE_FILE_I8 = 0 ,
SLE_FILE_U8 = 1 ,
typedef enum VarTypes {
SLE_FILE_I8 = 0 ,
SLE_FILE_U8 = 1 ,
SLE_FILE_I16 = 2 ,
SLE_FILE_U16 = 3 ,
SLE_FILE_I32 = 4 ,
@ -113,63 +113,88 @@ enum {
// SLE_FILE_IVAR = 8,
// SLE_FILE_UVAR = 9,
SLE_VAR_I8 = 0 < < 4 ,
SLE_VAR_U8 = 1 < < 4 ,
SLE_VAR_I16 = 2 < < 4 ,
SLE_VAR_U16 = 3 < < 4 ,
SLE_VAR_I32 = 4 < < 4 ,
SLE_VAR_U32 = 5 < < 4 ,
SLE_VAR_I64 = 6 < < 4 ,
SLE_VAR_U64 = 7 < < 4 ,
SLE_VAR_I8 = 0 < < 4 ,
SLE_VAR_U8 = 1 < < 4 ,
SLE_VAR_I16 = 2 < < 4 ,
SLE_VAR_U16 = 3 < < 4 ,
SLE_VAR_I32 = 4 < < 4 ,
SLE_VAR_U32 = 5 < < 4 ,
SLE_VAR_I64 = 6 < < 4 ,
SLE_VAR_U64 = 7 < < 4 ,
SLE_VAR_NULL = 8 < < 4 , // useful to write zeros in savegame.
SLE_VAR_INT = SLE_VAR_I32 ,
SLE_VAR_INT = SLE_VAR_I32 ,
SLE_VAR_UINT = SLE_VAR_U32 ,
SLE_INT8 = SLE_FILE_I8 | SLE_VAR_I8 ,
SLE_UINT8 = SLE_FILE_U8 | SLE_VAR_U8 ,
SLE_INT16 = SLE_FILE_I16 | SLE_VAR_I16 ,
SLE_INT8 = SLE_FILE_I8 | SLE_VAR_I8 ,
SLE_UINT8 = SLE_FILE_U8 | SLE_VAR_U8 ,
SLE_INT16 = SLE_FILE_I16 | SLE_VAR_I16 ,
SLE_UINT16 = SLE_FILE_U16 | SLE_VAR_U16 ,
SLE_INT32 = SLE_FILE_I32 | SLE_VAR_I32 ,
SLE_INT32 = SLE_FILE_I32 | SLE_VAR_I32 ,
SLE_UINT32 = SLE_FILE_U32 | SLE_VAR_U32 ,
SLE_INT64 = SLE_FILE_I64 | SLE_VAR_I64 ,
SLE_INT64 = SLE_FILE_I64 | SLE_VAR_I64 ,
SLE_UINT64 = SLE_FILE_U64 | SLE_VAR_U64 ,
SLE_STRINGID = SLE_FILE_STRINGID | SLE_VAR_U16 ,
} VarType ;
enum SaveLoadTypes {
SL_VAR = 0 ,
SL_REF = 1 ,
SL_ARR = 2 ,
SL_CONDVAR = 0 | ( 1 < < 2 ) , // 4
SL_CONDREF = 1 | ( 1 < < 2 ) , // 5
SL_CONDARR = 2 | ( 1 < < 2 ) , // 6
// non-normal save-load types
SL_WRITEBYTE = 8 ,
SL_INCLUDE = 9 ,
SL_END = 15
} ;
# define SLE_VAR(t,i,c) 0 | (offsetof(t,i) & 0xF), offsetof(t,i) >> 4, c
# define SLE_REF(t,i,c) 0x10 | (offsetof(t,i) & 0xF), offsetof(t,i) >> 4, c
# define SLE_ARR(t,i,c,l) 0x20 | (offsetof(t,i) & 0xF), offsetof(t,i) >> 4, c, l
# define SLE_CONDVAR(t,i,c,from,to) 0x40 | (offsetof(t,i) & 0xF), offsetof(t,i) >> 4, c, from, to
# define SLE_CONDREF(t,i,c,from,to) 0x50 | (offsetof(t,i) & 0xF), offsetof(t,i) >> 4, c, from, to
# define SLE_CONDARR(t,i,c,l,from,to) 0x60 | (offsetof(t,i) & 0xF), offsetof(t,i) >> 4, c, from,to, l
# define SLE_WRITEBYTE(t,i,b,c) 0x80 | (offsetof(t,i) & 0xF), offsetof(t,i) >> 4, b, c
# define SLE_INCLUDE(t,i,c) 0x90 | (offsetof(t,i) & 0xF), offsetof(t,i) >> 4, c
# define SLE_VARX(t,c) 0x00 | ((t) & 0xF), (t) >> 4, c
# define SLE_REFX(t,c) 0x10 | ((t) & 0xF), (t) >> 4, c
# define SLE_CONDVARX(t,c,from,to) 0x40 | ((t) & 0xF), (t) >> 4, c, from, to
# define SLE_CONDREFX(t,c,from,to) 0x50 | ((t) & 0xF), (t) >> 4, c, from, to
# define SLE_WRITEBYTEX(t,b) 0x80 | ((t) & 0xF), (t) >> 4, b
# define SLE_INCLUDEX(t,c) 0x90 | ((t) & 0xF), (t) >> 4, c
# define SLE_END() 0xF0
/** SaveLoad type struct. Do NOT use this directly but use the SLE_ macros defined just below! */
struct SaveLoad {
byte cmd ; /// the action to take with the saved/loaded type, All types need different action
VarType type ; /// type of the variable to be saved, int
uint16 offset ; /// offset of this variable in the struct (max offset is 65536)
uint16 length ; /// (conditional) length of the variable (eg. arrays) (max array size is 65536 elements)
uint16 version_from ; /// save/load the variable starting from this savegame version
uint16 version_to ; /// save/load the variable until this savegame version
} ;
/* Simple variables, references (pointers) and arrays */
# define SLE_VAR(base, variable, type) {SL_VAR, type, offsetof(base, variable), 0, 0, 0}
# define SLE_REF(base, variable, type) {SL_REF, type, offsetof(base, variable), 0, 0, 0}
# define SLE_ARR(base, variable, type, length) {SL_ARR, type, offsetof(base, variable), length, 0, 0}
/* Conditional variables, references (pointers) and arrays that are only valid for certain savegame versions */
# define SLE_CONDVAR(base, variable, type, from, to) {SL_CONDVAR, type, offsetof(base, variable), 0, from, to}
# define SLE_CONDREF(base, variable, type, from, to) {SL_CONDREF, type, offsetof(base, variable), 0, from, to}
# define SLE_CONDARR(base, variable, type, length, from, to) {SL_CONDARR, type, offsetof(base, variable), length, from, to}
/* Translate values ingame to different values in the savegame and vv */
# define SLE_WRITEBYTE(base, variable, game_value, file_value) {SL_WRITEBYTE, 0, offsetof(base, variable), 0, game_value, file_value}
/* Load common code and put it into each struct (currently only for vehicles */
# define SLE_INCLUDE(base, variable, include_index) {SL_INCLUDE, 0, offsetof(base, variable), 0, include_index, 0}
/* The same as the ones at the top, only the offset is given directly; used for unions */
# define SLE_VARX(offset, type) {SL_VAR, type, offset, 0, 0, 0}
# define SLE_REFX(offset, type) {SL_REF, type, offset, 0, 0, 0}
# define SLE_CONDVARX(offset, type, from, to) {SL_CONDVAR, type, offset, 0, from, to}
# define SLE_CONDREFX(offset, type, from, to) {SL_CONDREF, type, offset, 0, from, to}
# define SLE_WRITEBYTEX(offset, something) {SL_WRITEBYTE, 0, offset, 0, something, 0}
# define SLE_INCLUDEX(offset, type) {SL_INCLUDE, type, offset, 0, 0, 0}
/* End marker */
# define SLE_END() {SL_END, 0, 0, 0, 0, 0}
void SlSetArrayIndex ( uint index ) ;
int SlIterateArray ( void ) ;
void SlArray ( void * array , uint length , uint conv ) ;
void SlObject ( void * object , const void * desc ) ;
void SlObject ( void * object , const SaveLoa d * desc ) ;
void SlAutolength ( AutolengthProc * proc , void * arg ) ;
uint SlGetFieldLength ( void ) ;
int SlReadByte ( void ) ;
void SlSetLength ( uint length ) ;
void SlWriteByte ( byte v ) ;
void SlSetLength ( size_ t length ) ;
void SlWriteByte ( byte b ) ;
void SlGlobList ( const SaveLoadGlobVarList * desc ) ;
//int GetSavegameType(char *file);
# endif /* SAVELOAD_H */