1294 /* XXX - backup _sl.buf cause it is used internally by the writer |
1294 /* XXX - backup _sl.buf cause it is used internally by the writer |
1295 * and we update it for our own purposes */ |
1295 * and we update it for our own purposes */ |
1296 static byte *tmp = NULL; |
1296 static byte *tmp = NULL; |
1297 uint32 hdr[2]; |
1297 uint32 hdr[2]; |
1298 |
1298 |
1299 if (save_thread != NULL) OTTD_SendThreadMessage(MSG_OTTD_SAVETHREAD_START); |
1299 if (arg != NULL) OTTD_SendThreadMessage(MSG_OTTD_SAVETHREAD_START); |
1300 |
1300 |
1301 tmp = _sl.buf; |
1301 tmp = _sl.buf; |
1302 |
1302 |
1303 /* XXX - Setup setjmp error handler if an error occurs anywhere deep during |
1303 /* XXX - Setup setjmp error handler if an error occurs anywhere deep during |
1304 * loading/saving execute a longjmp() and continue execution here */ |
1304 * loading/saving execute a longjmp() and continue execution here */ |
1305 if (setjmp(_sl.excpt)) { |
1305 if (setjmp(_sl.excpt)) { |
1306 AbortSaveLoad(); |
1306 AbortSaveLoad(); |
1307 _sl.buf = tmp; |
1307 _sl.buf = tmp; |
1308 _sl.excpt_uninit(); |
1308 _sl.excpt_uninit(); |
1309 |
1309 |
1310 ShowInfoF("Save game failed: %s.", _sl.excpt_msg); |
1310 fprintf(stderr, "Save game failed: %s.", _sl.excpt_msg); |
1311 OTTD_SendThreadMessage(MSG_OTTD_SAVETHREAD_ERROR); |
1311 if (arg != NULL) OTTD_SendThreadMessage(MSG_OTTD_SAVETHREAD_ERROR); |
|
1312 else SaveFileError(); |
1312 return NULL; |
1313 return NULL; |
1313 } |
1314 } |
1314 |
1315 |
1315 /* We have written our stuff to memory, now write it to file! */ |
1316 /* We have written our stuff to memory, now write it to file! */ |
1316 hdr[0] = fmt->tag; |
1317 hdr[0] = fmt->tag; |
1341 fmt->uninit_write(); |
1342 fmt->uninit_write(); |
1342 assert(_ts.count == _sl.offs_base); |
1343 assert(_ts.count == _sl.offs_base); |
1343 GetSavegameFormat("memory")->uninit_write(); // clean the memorypool |
1344 GetSavegameFormat("memory")->uninit_write(); // clean the memorypool |
1344 fclose(_sl.fh); |
1345 fclose(_sl.fh); |
1345 |
1346 |
1346 if (save_thread != NULL) OTTD_SendThreadMessage(MSG_OTTD_SAVETHREAD_DONE); |
1347 if (arg != NULL) OTTD_SendThreadMessage(MSG_OTTD_SAVETHREAD_DONE); |
1347 return NULL; |
1348 return NULL; |
1348 } |
1349 } |
1349 |
1350 |
1350 void WaitTillSaved(void) |
1351 void WaitTillSaved(void) |
1351 { |
1352 { |
1363 */ |
1364 */ |
1364 SaveOrLoadResult SaveOrLoad(const char *filename, int mode) |
1365 SaveOrLoadResult SaveOrLoad(const char *filename, int mode) |
1365 { |
1366 { |
1366 uint32 hdr[2]; |
1367 uint32 hdr[2]; |
1367 const SaveLoadFormat *fmt; |
1368 const SaveLoadFormat *fmt; |
1368 uint version; |
1369 uint version; |
1369 |
1370 |
1370 /* An instance of saving is already active, so wait until it is done */ |
1371 /* An instance of saving is already active, so don't go saving again */ |
1371 if (_ts.saveinprogress) { |
1372 if (_ts.saveinprogress && mode == SL_SAVE) { |
|
1373 // if not an autosave, but a user action, show error message |
1372 if (!_do_autosave) ShowErrorMessage(_error_message, STR_SAVE_STILL_IN_PROGRESS, 0, 0); |
1374 if (!_do_autosave) ShowErrorMessage(_error_message, STR_SAVE_STILL_IN_PROGRESS, 0, 0); |
1373 WaitTillSaved(); |
1375 return SL_OK; |
1374 // nonsense to do an autosave while we were still saving our game, so skip it |
1376 } |
1375 if (_do_autosave) return SL_OK; |
1377 WaitTillSaved(); |
1376 } else { |
1378 |
1377 WaitTillSaved(); |
1379 /* Load a TTDLX or TTDPatch game */ |
1378 } |
|
1379 |
|
1380 /* Load a TTDLX or TTDPatch game */ |
|
1381 if (mode == SL_OLD_LOAD) { |
1380 if (mode == SL_OLD_LOAD) { |
1382 InitializeGame(256, 256); // set a mapsize of 256x256 for TTDPatch games or it might get confused |
1381 InitializeGame(256, 256); // set a mapsize of 256x256 for TTDPatch games or it might get confused |
1383 if (!LoadOldSaveGame(filename)) return SL_REINIT; |
1382 if (!LoadOldSaveGame(filename)) return SL_REINIT; |
1384 AfterLoadGame(0); |
1383 AfterLoadGame(0); |
1385 return SL_OK; |
1384 return SL_OK; |
1415 |
1414 |
1416 ShowInfoF("Save game failed: %s.", _sl.excpt_msg); |
1415 ShowInfoF("Save game failed: %s.", _sl.excpt_msg); |
1417 return SL_ERROR; |
1416 return SL_ERROR; |
1418 } |
1417 } |
1419 |
1418 |
1420 /* We first initialize here to avoid: "warning: variable `version' might |
1419 /* We first initialize here to avoid: "warning: variable `version' might |
1421 * be clobbered by `longjmp' or `vfork'" */ |
1420 * be clobbered by `longjmp' or `vfork'" */ |
1422 version = 0; |
1421 version = 0; |
1423 |
1422 |
1424 /* General tactic is to first save the game to memory, then use an available writer |
1423 /* General tactic is to first save the game to memory, then use an available writer |
1425 * to write it to file, either in threaded mode if possible, or single-threaded */ |
1424 * to write it to file, either in threaded mode if possible, or single-threaded */ |
1426 if (mode == SL_SAVE) { /* SAVE game */ |
1425 if (mode == SL_SAVE) { /* SAVE game */ |
1439 SlSaveChunks(); |
1438 SlSaveChunks(); |
1440 SlWriteFill(); // flush the save buffer |
1439 SlWriteFill(); // flush the save buffer |
1441 |
1440 |
1442 /* Write to file */ |
1441 /* Write to file */ |
1443 if (_network_server || |
1442 if (_network_server || |
1444 (save_thread = OTTDCreateThread(&SaveFileToDisk, NULL)) == NULL) { |
1443 (save_thread = OTTDCreateThread(&SaveFileToDisk, (void*)"")) == NULL) { |
1445 DEBUG(misc, 1) ("cannot create savegame thread, reverting to single-threaded mode..."); |
1444 DEBUG(misc, 1) ("cannot create savegame thread, reverting to single-threaded mode..."); |
1446 SaveFileToDisk(NULL); |
1445 SaveFileToDisk(NULL); |
1447 } |
1446 } |
1448 |
1447 |
1449 } else { /* LOAD game */ |
1448 } else { /* LOAD game */ |