saveload.c
changeset 2380 392bba57462d
parent 2337 d8b9e722672d
child 2382 a66af7211f95
equal deleted inserted replaced
2379:3ef366cf3493 2380:392bba57462d
  1253 }
  1253 }
  1254 
  1254 
  1255 /** Update the gui accordingly when starting saving
  1255 /** Update the gui accordingly when starting saving
  1256  * and set locks on saveload. Also turn off fast-forward cause with that
  1256  * and set locks on saveload. Also turn off fast-forward cause with that
  1257  * saving takes Aaaaages */
  1257  * saving takes Aaaaages */
  1258 static inline void SaveFileStart(void)
  1258 void SaveFileStart(void)
  1259 {
  1259 {
  1260 	_ts.ff_state = _fast_forward;
  1260 	_ts.ff_state = _fast_forward;
  1261 	_fast_forward = false;
  1261 	_fast_forward = false;
  1262 	if (_cursor.sprite == SPR_CURSOR_MOUSE) SetMouseCursor(SPR_CURSOR_ZZZ);
  1262 	if (_cursor.sprite == SPR_CURSOR_MOUSE) SetMouseCursor(SPR_CURSOR_ZZZ);
  1263 
  1263 
  1265 	_ts.saveinprogress = true;
  1265 	_ts.saveinprogress = true;
  1266 }
  1266 }
  1267 
  1267 
  1268 /** Update the gui accordingly when saving is done and release locks
  1268 /** Update the gui accordingly when saving is done and release locks
  1269  * on saveload */
  1269  * on saveload */
  1270 static inline void SaveFileDone(void)
  1270 void SaveFileDone(void)
  1271 {
  1271 {
  1272 	_fast_forward = _ts.ff_state;
  1272 	_fast_forward = _ts.ff_state;
  1273 	if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE);
  1273 	if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE);
  1274 
  1274 
  1275 	SendWindowMessage(WC_STATUS_BAR, 0, false, 0, 0);
  1275 	SendWindowMessage(WC_STATUS_BAR, 0, false, 0, 0);
  1276 	_ts.saveinprogress = false;
  1276 	_ts.saveinprogress = false;
  1277 }
  1277 }
  1278 
  1278 
       
  1279 /** Show a gui message when saving has failed */
       
  1280 void SaveFileError(void)
       
  1281 {
       
  1282 	ShowErrorMessage(STR_4007_GAME_SAVE_FAILED, STR_NULL, 0, 0);
       
  1283 	SaveFileDone();
       
  1284 }
       
  1285 
  1279 /** We have written the whole game into memory, _save_pool, now find
  1286 /** We have written the whole game into memory, _save_pool, now find
  1280  * and appropiate compressor and start writing to file.
  1287  * and appropiate compressor and start writing to file.
  1281  */
  1288  */
  1282 static void* SaveFileToDisk(void* arg)
  1289 static void* SaveFileToDisk(void *arg)
  1283 {
  1290 {
  1284 	const SaveLoadFormat *fmt = GetSavegameFormat(_savegame_format);
  1291 	const SaveLoadFormat *fmt = GetSavegameFormat(_savegame_format);
  1285 	/* XXX - backup _sl.buf cause it is used internally by the writer
  1292 	/* XXX - backup _sl.buf cause it is used internally by the writer
  1286 	 * and we update it for our own purposes */
  1293 	 * and we update it for our own purposes */
  1287 	static byte *tmp = NULL;
  1294 	static byte *tmp = NULL;
  1288 	uint32 hdr[2];
  1295 	uint32 hdr[2];
       
  1296 
       
  1297 	OTTD_SendThreadMessage(MSG_OTTD_SAVETHREAD_START);
  1289 
  1298 
  1290 	tmp = _sl.buf;
  1299 	tmp = _sl.buf;
  1291 
  1300 
  1292 	/* XXX - Setup setjmp error handler if an error occurs anywhere deep during
  1301 	/* XXX - Setup setjmp error handler if an error occurs anywhere deep during
  1293 	 * loading/saving execute a longjmp() and continue execution here */
  1302 	 * loading/saving execute a longjmp() and continue execution here */
  1295 		AbortSaveLoad();
  1304 		AbortSaveLoad();
  1296 		_sl.buf = tmp;
  1305 		_sl.buf = tmp;
  1297 		_sl.excpt_uninit();
  1306 		_sl.excpt_uninit();
  1298 
  1307 
  1299 		ShowInfoF("Save game failed: %s.", _sl.excpt_msg);
  1308 		ShowInfoF("Save game failed: %s.", _sl.excpt_msg);
  1300 		ShowErrorMessage(STR_4007_GAME_SAVE_FAILED, STR_NULL, 0, 0);
  1309 		OTTD_SendThreadMessage(MSG_OTTD_SAVETHREAD_ERROR);
  1301 
       
  1302 		SaveFileDone();
       
  1303 		return NULL;
  1310 		return NULL;
  1304 	}
  1311 	}
  1305 
  1312 
  1306 	/* We have written our stuff to memory, now write it to file! */
  1313 	/* We have written our stuff to memory, now write it to file! */
  1307 	hdr[0] = fmt->tag;
  1314 	hdr[0] = fmt->tag;
  1332 	fmt->uninit_write();
  1339 	fmt->uninit_write();
  1333 	assert(_ts.count == _sl.offs_base);
  1340 	assert(_ts.count == _sl.offs_base);
  1334 	GetSavegameFormat("memory")->uninit_write(); // clean the memorypool
  1341 	GetSavegameFormat("memory")->uninit_write(); // clean the memorypool
  1335 	fclose(_sl.fh);
  1342 	fclose(_sl.fh);
  1336 
  1343 
  1337 	SaveFileDone();
  1344 	OTTD_SendThreadMessage(MSG_OTTD_SAVETHREAD_DONE);
  1338 	return NULL;
  1345 	return NULL;
  1339 }
  1346 }
  1340 
  1347 
  1341 
  1348 
  1342 static Thread* save_thread;
  1349 static Thread* save_thread;
  1403 
  1410 
  1404 		/* A saver/loader exception!! reinitialize all variables to prevent crash! */
  1411 		/* A saver/loader exception!! reinitialize all variables to prevent crash! */
  1405 		if (mode == SL_LOAD) {
  1412 		if (mode == SL_LOAD) {
  1406 			ShowInfoF("Load game failed: %s.", _sl.excpt_msg);
  1413 			ShowInfoF("Load game failed: %s.", _sl.excpt_msg);
  1407 			return SL_REINIT;
  1414 			return SL_REINIT;
  1408 		} else {
  1415 		}
  1409 			ShowInfoF("Save game failed: %s.", _sl.excpt_msg);
  1416 		
  1410 			return SL_ERROR;
  1417 		ShowInfoF("Save game failed: %s.", _sl.excpt_msg);
  1411 		}
  1418 		return SL_ERROR;
  1412 	}
  1419 	}
  1413 
  1420 
  1414   /* We first initialize here to avoid: "warning: variable `version' might
  1421   /* We first initialize here to avoid: "warning: variable `version' might
  1415    * be clobbered by `longjmp' or `vfork'" */
  1422    * be clobbered by `longjmp' or `vfork'" */
  1416 	version = 0;
  1423 	version = 0;
  1432 		BeforeSaveGame();
  1439 		BeforeSaveGame();
  1433 		SlSaveChunks();
  1440 		SlSaveChunks();
  1434 		SlWriteFill(); // flush the save buffer
  1441 		SlWriteFill(); // flush the save buffer
  1435 
  1442 
  1436 		/* Write to file */
  1443 		/* Write to file */
  1437 		SaveFileStart();
       
  1438 		if (_network_server ||
  1444 		if (_network_server ||
  1439 				(save_thread = OTTDCreateThread(&SaveFileToDisk, NULL)) == NULL) {
  1445 				(save_thread = OTTDCreateThread(&SaveFileToDisk, NULL)) == NULL) {
  1440 			DEBUG(misc, 1) ("cannot create savegame thread, reverting to single-threaded mode...");
  1446 			DEBUG(misc, 1) ("cannot create savegame thread, reverting to single-threaded mode...");
  1441 			SaveFileToDisk(NULL);
  1447 			SaveFileToDisk(NULL);
  1442 		}
  1448 		}