diff --git a/misc.c b/misc.c index 9e32bd0d62..54b9c1ea5f 100644 --- a/misc.c +++ b/misc.c @@ -741,33 +741,62 @@ static void Load_MAPS(void) AllocateMap(_map_dim_x, _map_dim_y); } - -static void SaveLoad_MapByte(byte *m) +static void Load_MAPT(void) { - uint size = MapSize(), i; - byte buf[4096]; - if (_sl.save) { - SlSetLength(size); - for(;size;size -= lengthof(buf)) { - for (i = 0; i != lengthof(buf); i++) { buf[i] = *m; m += sizeof(Tile); } - SlArray(buf, lengthof(buf), SLE_UINT8); - } - } else { - for(;size;size -= lengthof(buf)) { - SlArray(buf, lengthof(buf), SLE_UINT8); - for (i = 0; i != lengthof(buf); i++) { *m = buf[i]; m += sizeof(Tile); } - } + uint size = MapSize(); + uint i; + + for (i = 0; i != size;) { + byte buf[4096]; + uint j; + + SlArray(buf, lengthof(buf), SLE_UINT8); + for (j = 0; j != lengthof(buf); j++) _m[i++].type_height = buf[j]; } } -static void SaveLoad_MAPT(void) +static void Save_MAPT(void) { - SaveLoad_MapByte(&_m[0].type_height); + uint size = MapSize(); + uint i; + + SlSetLength(size); + for (i = 0; i != size;) { + byte buf[4096]; + uint j; + + for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].type_height; + SlArray(buf, lengthof(buf), SLE_UINT8); + } } -static void SaveLoad_MAPO(void) +static void Load_MAPO(void) { - SaveLoad_MapByte(&_m[0].owner); + uint size = MapSize(); + uint i; + + for (i = 0; i != size;) { + byte buf[4096]; + uint j; + + SlArray(buf, lengthof(buf), SLE_UINT8); + for (j = 0; j != lengthof(buf); j++) _m[i++].owner = buf[j]; + } +} + +static void Save_MAPO(void) +{ + uint size = MapSize(); + uint i; + + SlSetLength(size); + for (i = 0; i != size;) { + byte buf[4096]; + uint j; + + for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].owner; + SlArray(buf, lengthof(buf), SLE_UINT8); + } } static void Load_MAP2(void) @@ -781,7 +810,7 @@ static void Load_MAP2(void) SlArray(buf, lengthof(buf), /* In those versions the m2 was 8 bits */ - _sl.version < 5 ? SLE_FILE_U8 | SLE_VAR_U16 : SLE_UINT16 + _sl_version < 5 ? SLE_FILE_U8 | SLE_VAR_U16 : SLE_UINT16 ); for (j = 0; j != lengthof(buf); j++) _m[i++].m2 = buf[j]; } @@ -802,19 +831,91 @@ static void Save_MAP2(void) } } -static void SaveLoad_MAP3(void) +static void Load_MAP3(void) { - SaveLoad_MapByte(&_m[0].m3); + uint size = MapSize(); + uint i; + + for (i = 0; i != size;) { + byte buf[4096]; + uint j; + + SlArray(buf, lengthof(buf), SLE_UINT8); + for (j = 0; j != lengthof(buf); j++) _m[i++].m3 = buf[j]; + } } -static void SaveLoad_MAP4(void) +static void Save_MAP3(void) { - SaveLoad_MapByte(&_m[0].m4); + uint size = MapSize(); + uint i; + + SlSetLength(size); + for (i = 0; i != size;) { + byte buf[4096]; + uint j; + + for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].m3; + SlArray(buf, lengthof(buf), SLE_UINT8); + } } -static void SaveLoad_MAP5(void) +static void Load_MAP4(void) { - SaveLoad_MapByte(&_m[0].m5); + uint size = MapSize(); + uint i; + + for (i = 0; i != size;) { + byte buf[4096]; + uint j; + + SlArray(buf, lengthof(buf), SLE_UINT8); + for (j = 0; j != lengthof(buf); j++) _m[i++].m4 = buf[j]; + } +} + +static void Save_MAP4(void) +{ + uint size = MapSize(); + uint i; + + SlSetLength(size); + for (i = 0; i != size;) { + byte buf[4096]; + uint j; + + for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].m4; + SlArray(buf, lengthof(buf), SLE_UINT8); + } +} + +static void Load_MAP5(void) +{ + uint size = MapSize(); + uint i; + + for (i = 0; i != size;) { + byte buf[4096]; + uint j; + + SlArray(buf, lengthof(buf), SLE_UINT8); + for (j = 0; j != lengthof(buf); j++) _m[i++].m5 = buf[j]; + } +} + +static void Save_MAP5(void) +{ + uint size = MapSize(); + uint i; + + SlSetLength(size); + for (i = 0; i != size;) { + byte buf[4096]; + uint j; + + for (j = 0; j != lengthof(buf); j++) buf[j] = _m[i++].m5; + SlArray(buf, lengthof(buf), SLE_UINT8); + } } static void Load_MAPE(void) @@ -885,12 +986,12 @@ static void Load_CHTS(void) const ChunkHandler _misc_chunk_handlers[] = { { 'MAPS', Save_MAPS, Load_MAPS, CH_RIFF }, - { 'MAPT', SaveLoad_MAPT, SaveLoad_MAPT, CH_RIFF }, - { 'MAPO', SaveLoad_MAPO, SaveLoad_MAPO, CH_RIFF }, + { 'MAPT', Save_MAPT, Load_MAPT, CH_RIFF }, + { 'MAPO', Save_MAPO, Load_MAPO, CH_RIFF }, { 'MAP2', Save_MAP2, Load_MAP2, CH_RIFF }, - { 'M3LO', SaveLoad_MAP3, SaveLoad_MAP3, CH_RIFF }, - { 'M3HI', SaveLoad_MAP4, SaveLoad_MAP4, CH_RIFF }, - { 'MAP5', SaveLoad_MAP5, SaveLoad_MAP5, CH_RIFF }, + { 'M3LO', Save_MAP3, Load_MAP3, CH_RIFF }, + { 'M3HI', Save_MAP4, Load_MAP4, CH_RIFF }, + { 'MAP5', Save_MAP5, Load_MAP5, CH_RIFF }, { 'MAPE', Save_MAPE, Load_MAPE, CH_RIFF }, { 'NAME', Save_NAME, Load_NAME, CH_ARRAY}, diff --git a/order_cmd.c b/order_cmd.c index 0b26791462..6c97dd43df 100644 --- a/order_cmd.c +++ b/order_cmd.c @@ -1120,13 +1120,13 @@ static void Save_ORDR(void) static void Load_ORDR(void) { - if (_sl.full_version <= 0x501) { + if (_sl_full_version <= 0x501) { /* Version older than 0x502 did not have a ->next pointer. Convert them (in the old days, the orderlist was 5000 items big) */ uint len = SlGetFieldLength(); uint i; - if (_sl.version < 5) { + if (_sl_version < 5) { /* Pre-version 5 had an other layout for orders (uint16 instead of uint32) */ uint16 orders[5000]; @@ -1142,7 +1142,7 @@ static void Load_ORDR(void) AssignOrder(GetOrder(i), UnpackVersion4Order(orders[i])); } - } else if (_sl.full_version <= 0x501) { + } else if (_sl_full_version <= 0x501) { uint32 orders[5000]; len /= sizeof(uint32); diff --git a/saveload.c b/saveload.c index 54f73b3e81..8cce68d442 100644 --- a/saveload.c +++ b/saveload.c @@ -34,9 +34,46 @@ enum { SAVEGAME_LOADABLE_VERSION = (SAVEGAME_MAJOR_VERSION << 8) + SAVEGAME_MINOR_VERSION }; -enum NeedLengthValues {NL_NONE = 0, NL_WANTLENGTH = 1, NL_CALCLENGTH = 2}; +byte _sl_version; /// the major savegame version identifier +uint16 _sl_full_version; /// the full version of the savegame -SaverLoader _sl; +/** The saveload struct, containing reader-writer functions, bufffer, version, etc. */ +static 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 + + 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 + + uint32 offs_base; /// the offset in number of bytes since we started writing data (eg uncompressed savegame size) + + WriterProc *write_bytes; /// savegame writer function + ReaderProc *read_bytes; /// savegame loader function + + 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 + + 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 + + /** 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 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); /// 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 +} _sl; + + +enum NeedLengthValues {NL_NONE = 0, NL_WANTLENGTH = 1, NL_CALCLENGTH = 2}; /** * Fill the input buffer by reading from the file with the given reader @@ -441,7 +478,7 @@ void SlArray(void *array, uint length, VarType conv) /* NOTICE - handle some buggy stuff, in really old versions everything was saved * as a byte-type. So detect this, and adjust array size accordingly */ - if (!_sl.save && _sl.version == 0) { + if (!_sl.save && _sl_version == 0) { if (conv == SLE_INT16 || conv == SLE_UINT16 || conv == SLE_STRINGID) { length *= 2; // int16, uint16 and StringID are 2 bytes in size conv = SLE_INT8; @@ -478,7 +515,7 @@ static size_t SlCalcObjLength(void *object, const SaveLoad *sld) if (sld->cmd < SL_WRITEBYTE) { if (HASBIT(sld->cmd, 2)) { // check if the field is used in the current savegame version - if (_sl.version < sld->version_from || _sl.version > sld->version_to) + if (_sl_version < sld->version_from || _sl_version > sld->version_to) continue; } @@ -522,7 +559,7 @@ void SlObject(void *object, const SaveLoad *sld) /* CONDITIONAL saveload types depend on the savegame version */ if (HASBIT(sld->cmd, 2)) { // check if the field is of the right version, if not, proceed to next one - if (_sl.version < sld->version_from || _sl.version > sld->version_to) + if (_sl_version < sld->version_from || _sl_version > sld->version_to) continue; } @@ -571,7 +608,7 @@ static size_t SlCalcGlobListLength(const SaveLoadGlobVarList *desc) for (; desc->address != NULL; desc++) { // Of course the global variable must exist in the sought savegame version - if (_sl.version >= desc->from_version && _sl.version <= desc->to_version) + if (_sl_version >= desc->from_version && _sl_version <= desc->to_version) length += SlCalcConvLen(NULL, desc->conv); } return length; @@ -590,7 +627,7 @@ void SlGlobList(const SaveLoadGlobVarList *desc) } for (; desc->address != NULL; desc++) { - if (_sl.version >= desc->from_version && _sl.version <= desc->to_version) + if (_sl_version >= desc->from_version && _sl_version <= desc->to_version) SlSaveLoadConv(desc->address, desc->conv); } } @@ -781,7 +818,7 @@ static uint ReadLZO(void) // Check if size is bad ((uint32*)out)[0] = size = tmp[1]; - if (_sl.version != 0) { + if (_sl_version != 0) { tmp[0] = TO_BE32(tmp[0]); size = TO_BE32(size); } @@ -1089,7 +1126,7 @@ static void *IntToReference(uint index, SLRefType rt) { /* After version 4.3 REF_VEHICLE_OLD is saved as REF_VEHICLE, * and should be loaded like that */ - if (rt == REF_VEHICLE_OLD && _sl.full_version >= ((4 << 8) | 4)) + if (rt == REF_VEHICLE_OLD && _sl_full_version >= ((4 << 8) | 4)) rt = REF_VEHICLE; /* No need to look up NULL pointers, just return immediately */ @@ -1383,7 +1420,7 @@ SaveOrLoadResult SaveOrLoad(const char *filename, int mode) return AbortSaveLoad(); } - _sl.version = SAVEGAME_MAJOR_VERSION; + _sl_version = SAVEGAME_MAJOR_VERSION; BeforeSaveGame(); SlSaveChunks(); @@ -1411,8 +1448,8 @@ SaveOrLoadResult SaveOrLoad(const char *filename, int mode) if (fmt == endof(_saveload_formats)) { DEBUG(misc, 0) ("Unknown savegame type, trying to load it as the buggy format."); rewind(_sl.fh); - _sl.version = version = 0; - _sl.full_version = 0; + _sl_version = version = 0; + _sl_full_version = 0; fmt = _saveload_formats + 1; // LZO break; } @@ -1427,8 +1464,8 @@ SaveOrLoadResult SaveOrLoad(const char *filename, int mode) return AbortSaveLoad(); } - _sl.version = (version >> 8); - _sl.full_version = version; + _sl_version = (version >> 8); + _sl_full_version = version; break; } } diff --git a/saveload.h b/saveload.h index 9f3c65d06b..f6e053be8b 100644 --- a/saveload.h +++ b/saveload.h @@ -58,46 +58,10 @@ typedef enum SLRefType { typedef uint ReferenceToIntProc(const void *obj, SLRefType rt); typedef void *IntToReferenceProc(uint index, SLRefType rt); -typedef struct SaveLoad SaveLoad; -/** 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 +extern byte _sl_version; /// the major savegame version identifier +extern uint16 _sl_full_version; /// the full version of the savegame - 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 - - uint32 offs_base; /// the offset in number of bytes since we started writing data (eg uncompressed savegame size) - - WriterProc *write_bytes; /// savegame writer function - ReaderProc *read_bytes; /// savegame loader function - - 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 - - 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 - - /** 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 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); /// 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 { INC_VEHICLE_COMMON = 0, @@ -172,14 +136,14 @@ enum SaveLoadTypes { }; /** SaveLoad type struct. Do NOT use this directly but use the SLE_ macros defined just below! */ -struct SaveLoad { +typedef 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 -}; +} SaveLoad; /* Simple variables, references (pointers) and arrays */ #define SLE_VAR(base, variable, type) {SL_VAR, type, offsetof(base, variable), 0, 0, 0} diff --git a/station_cmd.c b/station_cmd.c index d35626b1aa..3199d4d4f1 100644 --- a/station_cmd.c +++ b/station_cmd.c @@ -3139,7 +3139,7 @@ static void SaveLoad_STNS(Station *st) SlObject(&st->goods[i], _goods_desc); /* In older versions, enroute_from had 0xFF as INVALID_STATION, is now 0xFFFF */ - if (_sl.full_version < 0x700 && st->goods[i].enroute_from == 0xFF) + if (_sl_full_version < 0x700 && st->goods[i].enroute_from == 0xFF) st->goods[i].enroute_from = 0xFFFF; } } @@ -3177,7 +3177,7 @@ static void Load_STNS(void) st->trainst_h = h; } - if (_sl.full_version < 0x600) { + if (_sl_full_version < 0x600) { /* Convert old bus and truck tile to new-ones */ if (st->bus_tile_obsolete != 0) { st->bus_stops = AllocateRoadStop(); diff --git a/texteff.c b/texteff.c index 9121b29a2a..25a85e2759 100644 --- a/texteff.c +++ b/texteff.c @@ -373,7 +373,7 @@ void InitializeAnimatedTiles(void) static void SaveLoad_ANIT(void) { - if (_sl.version < 6) { + if (_sl_version < 6) { SlArray(_animated_tile_list, lengthof(_animated_tile_list), SLE_FILE_U16 | SLE_VAR_U32); } else SlArray(_animated_tile_list, lengthof(_animated_tile_list), SLE_UINT32); diff --git a/vehicle.c b/vehicle.c index fa32a79ea6..4c27eaa4de 100644 --- a/vehicle.c +++ b/vehicle.c @@ -2224,10 +2224,10 @@ static void Load_VEHS(void) SlObject(v, _veh_descs[SlReadByte()]); /* Old savegames used 'last_station_visited = 0xFF', should be 0xFFFF */ - if (_sl.version < 5 && v->last_station_visited == 0xFF) + if (_sl_version < 5 && v->last_station_visited == 0xFF) v->last_station_visited = 0xFFFF; - if (_sl.version < 5) { + if (_sl_version < 5) { /* Convert the current_order.type (which is a mix of type and flags, because in those versions, they both were 4 bits big) to type and flags */ v->current_order.flags = (v->current_order.type & 0xF0) >> 4; @@ -2236,7 +2236,7 @@ static void Load_VEHS(void) } /* Check for shared order-lists (we now use pointers for that) */ - if (_sl.full_version < 0x502) { + if (_sl_full_version < 0x502) { FOR_ALL_VEHICLES(v) { Vehicle *u;