src/saveload.cpp
branchnoai
changeset 9631 8a2d1c2ceb88
parent 9629 66dde6412125
child 9641 855e32c08c9b
equal deleted inserted replaced
9630:550db5cefcc2 9631:8a2d1c2ceb88
    15  */
    15  */
    16 #include "stdafx.h"
    16 #include "stdafx.h"
    17 #include "openttd.h"
    17 #include "openttd.h"
    18 #include "debug.h"
    18 #include "debug.h"
    19 #include "functions.h"
    19 #include "functions.h"
    20 #include "hal.h"
       
    21 #include "vehicle.h"
    20 #include "vehicle.h"
    22 #include "station.h"
    21 #include "station.h"
    23 #include "thread.h"
    22 #include "thread.h"
    24 #include "town.h"
    23 #include "town.h"
    25 #include "player.h"
    24 #include "player.h"
   286 {
   285 {
   287 	_sl.need_length = NL_WANTLENGTH;
   286 	_sl.need_length = NL_WANTLENGTH;
   288 	_sl.array_index = index;
   287 	_sl.array_index = index;
   289 }
   288 }
   290 
   289 
       
   290 static uint32 _next_offs;
       
   291 
   291 /**
   292 /**
   292  * Iterate through the elements of an array and read the whole thing
   293  * Iterate through the elements of an array and read the whole thing
   293  * @return The index of the object, or -1 if we have reached the end of current block
   294  * @return The index of the object, or -1 if we have reached the end of current block
   294  */
   295  */
   295 int SlIterateArray()
   296 int SlIterateArray()
   296 {
   297 {
   297 	int index;
   298 	int index;
   298 	static uint32 next_offs;
       
   299 
   299 
   300 	/* After reading in the whole array inside the loop
   300 	/* After reading in the whole array inside the loop
   301 	 * we must have read in all the data, so we must be at end of current block. */
   301 	 * we must have read in all the data, so we must be at end of current block. */
   302 	assert(next_offs == 0 || SlGetOffs() == next_offs);
   302 	if (_next_offs != 0 && SlGetOffs() != _next_offs) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME, "Invalid chunk size");
   303 
   303 
   304 	while (true) {
   304 	while (true) {
   305 		uint length = SlReadArrayLength();
   305 		uint length = SlReadArrayLength();
   306 		if (length == 0) {
   306 		if (length == 0) {
   307 			next_offs = 0;
   307 			_next_offs = 0;
   308 			return -1;
   308 			return -1;
   309 		}
   309 		}
   310 
   310 
   311 		_sl.obj_len = --length;
   311 		_sl.obj_len = --length;
   312 		next_offs = SlGetOffs() + length;
   312 		_next_offs = SlGetOffs() + length;
   313 
   313 
   314 		switch (_sl.block_mode) {
   314 		switch (_sl.block_mode) {
   315 		case CH_SPARSE_ARRAY: index = (int)SlReadSparseIndex(); break;
   315 		case CH_SPARSE_ARRAY: index = (int)SlReadSparseIndex(); break;
   316 		case CH_ARRAY:        index = _sl.array_index++; break;
   316 		case CH_ARRAY:        index = _sl.array_index++; break;
   317 		default:
   317 		default:
   494  * @param length maximum length of the string (buffer). If -1 we don't care
   494  * @param length maximum length of the string (buffer). If -1 we don't care
   495  * about a maximum length, but take string length as it is.
   495  * about a maximum length, but take string length as it is.
   496  * @return return the net length of the string */
   496  * @return return the net length of the string */
   497 static inline size_t SlCalcNetStringLen(const char *ptr, size_t length)
   497 static inline size_t SlCalcNetStringLen(const char *ptr, size_t length)
   498 {
   498 {
       
   499 	if (ptr == NULL) return 0;
   499 	return minu(strlen(ptr), length - 1);
   500 	return minu(strlen(ptr), length - 1);
   500 }
   501 }
   501 
   502 
   502 /** Calculate the gross length of the string that it
   503 /** Calculate the gross length of the string that it
   503  * will occupy in the savegame. This includes the real length, returned
   504  * will occupy in the savegame. This includes the real length, returned
   571 				}
   572 				}
   572 				break;
   573 				break;
   573 			case SLE_VAR_STR:
   574 			case SLE_VAR_STR:
   574 			case SLE_VAR_STRQ: // Malloc'd string, free previous incarnation, and allocate
   575 			case SLE_VAR_STRQ: // Malloc'd string, free previous incarnation, and allocate
   575 				free(*(char**)ptr);
   576 				free(*(char**)ptr);
   576 				*(char**)ptr = (char*)malloc(len + 1); // terminating '\0'
   577 				if (len == 0) {
   577 				ptr = *(char**)ptr;
   578 					*(char**)ptr = NULL;
   578 				SlCopyBytes(ptr, len);
   579 				} else {
       
   580 					*(char**)ptr = (char*)malloc(len + 1); // terminating '\0'
       
   581 					ptr = *(char**)ptr;
       
   582 					SlCopyBytes(ptr, len);
       
   583 				}
   579 				break;
   584 				break;
   580 		}
   585 		}
   581 
   586 
   582 		((char*)ptr)[len] = '\0'; // properly terminate the string
   587 		((char*)ptr)[len] = '\0'; // properly terminate the string
   583 	}
   588 	}
  1597 		if (!_do_autosave) ShowErrorMessage(INVALID_STRING_ID, STR_SAVE_STILL_IN_PROGRESS, 0, 0);
  1602 		if (!_do_autosave) ShowErrorMessage(INVALID_STRING_ID, STR_SAVE_STILL_IN_PROGRESS, 0, 0);
  1598 		return SL_OK;
  1603 		return SL_OK;
  1599 	}
  1604 	}
  1600 	WaitTillSaved();
  1605 	WaitTillSaved();
  1601 
  1606 
       
  1607 	_next_offs = 0;
       
  1608 
  1602 	/* Load a TTDLX or TTDPatch game */
  1609 	/* Load a TTDLX or TTDPatch game */
  1603 	if (mode == SL_OLD_LOAD) {
  1610 	if (mode == SL_OLD_LOAD) {
  1604 		InitializeGame(IG_DATE_RESET, 256, 256); // set a mapsize of 256x256 for TTDPatch games or it might get confused
  1611 		InitializeGame(IG_DATE_RESET, 256, 256); // set a mapsize of 256x256 for TTDPatch games or it might get confused
  1605 		if (!LoadOldSaveGame(filename)) return SL_REINIT;
  1612 		if (!LoadOldSaveGame(filename)) return SL_REINIT;
  1606 		_sl_version = 0;
  1613 		_sl_version = 0;