Merge branch 'master' into tracerestrict
# Conflicts: # src/rail_gui.cpp # src/saveload/saveload.cpp
This commit is contained in:
@@ -248,7 +248,7 @@ static void InitializeWindowsAndCaches()
|
||||
/* For each company, verify (while loading a scenario) that the inauguration date is the current year and set it
|
||||
* accordingly if it is not the case. No need to set it on companies that are not been used already,
|
||||
* thus the MIN_YEAR (which is really nothing more than Zero, initialized value) test */
|
||||
if (_file_to_saveload.filetype == FT_SCENARIO && c->inaugurated_year != MIN_YEAR) {
|
||||
if (_file_to_saveload.abstract_ftype == FT_SCENARIO && c->inaugurated_year != MIN_YEAR) {
|
||||
c->inaugurated_year = _cur_year;
|
||||
}
|
||||
}
|
||||
|
@@ -1165,7 +1165,7 @@ static const OldChunks vehicle_chunk[] = {
|
||||
|
||||
OCL_SVAR( OC_UINT8, Vehicle, owner ),
|
||||
OCL_SVAR( OC_TILE, Vehicle, tile ),
|
||||
OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, cur_image ),
|
||||
OCL_SVAR( OC_FILE_U16 | OC_VAR_U32, Vehicle, sprite_seq.seq[0].sprite ),
|
||||
|
||||
OCL_NULL( 8 ), ///< Vehicle sprite box, calculated automatically
|
||||
|
||||
@@ -1258,7 +1258,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num)
|
||||
if (v == NULL) continue;
|
||||
v->refit_cap = v->cargo_cap;
|
||||
|
||||
SpriteID sprite = v->cur_image;
|
||||
SpriteID sprite = v->sprite_seq.seq[0].sprite;
|
||||
/* no need to override other sprites */
|
||||
if (IsInsideMM(sprite, 1460, 1465)) {
|
||||
sprite += 580; // aircraft smoke puff
|
||||
@@ -1269,7 +1269,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num)
|
||||
} else if (IsInsideMM(sprite, 2516, 2539)) {
|
||||
sprite += 1385; // rotor or disaster-related vehicles
|
||||
}
|
||||
v->cur_image = sprite;
|
||||
v->sprite_seq.seq[0].sprite = sprite;
|
||||
|
||||
switch (v->type) {
|
||||
case VEH_TRAIN: {
|
||||
|
@@ -261,12 +261,14 @@
|
||||
* 191 26646
|
||||
* 192 26700
|
||||
* 193 26802
|
||||
* 194 26881 1.5.x
|
||||
* 2000 Trace restrict patch
|
||||
* 194 26881 1.5.x, 1.6.0
|
||||
* 195 27572 1.6.x
|
||||
* 2001 Trace restrict patch
|
||||
*/
|
||||
extern const uint16 SAVEGAME_VERSION = 2000; ///< Current savegame version of OpenTTD.
|
||||
extern const uint16 SAVEGAME_VERSION = 2001; ///< Current savegame version of OpenTTD.
|
||||
|
||||
SavegameType _savegame_type; ///< type of savegame we are loading
|
||||
FileToSaveLoad _file_to_saveload; ///< File to save or load in the openttd loop.
|
||||
|
||||
uint32 _ttdp_version; ///< version of TTDP savegame (if applicable)
|
||||
uint16 _sl_version; ///< the major savegame version identifier
|
||||
@@ -1485,6 +1487,8 @@ size_t SlCalcObjMemberLength(const void *object, const SaveLoad *sld)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef OTTD_ASSERT
|
||||
|
||||
/**
|
||||
* Check whether the variable size of the variable in the saveload configuration
|
||||
* matches with the actual variable size.
|
||||
@@ -1525,9 +1529,13 @@ static bool IsVariableSizeRight(const SaveLoad *sld)
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* OTTD_ASSERT */
|
||||
|
||||
bool SlObjectMember(void *ptr, const SaveLoad *sld)
|
||||
{
|
||||
#ifdef OTTD_ASSERT
|
||||
assert(IsVariableSizeRight(sld));
|
||||
#endif
|
||||
|
||||
VarType conv = GB(sld->conv, 0, 8);
|
||||
switch (sld->cmd) {
|
||||
@@ -2462,7 +2470,7 @@ static void SaveFileStart()
|
||||
{
|
||||
_sl.ff_state = _fast_forward;
|
||||
_fast_forward = 0;
|
||||
if (_cursor.sprite == SPR_CURSOR_MOUSE) SetMouseCursor(SPR_CURSOR_ZZZ, PAL_NONE);
|
||||
SetMouseCursorBusy(true);
|
||||
|
||||
InvalidateWindowData(WC_STATUS_BAR, 0, SBI_SAVELOAD_START);
|
||||
_sl.saveinprogress = true;
|
||||
@@ -2472,7 +2480,7 @@ static void SaveFileStart()
|
||||
static void SaveFileDone()
|
||||
{
|
||||
if (_game_mode != GM_MENU) _fast_forward = _sl.ff_state;
|
||||
if (_cursor.sprite == SPR_CURSOR_ZZZ) SetMouseCursor(SPR_CURSOR_MOUSE, PAL_NONE);
|
||||
SetMouseCursorBusy(false);
|
||||
|
||||
InvalidateWindowData(WC_STATUS_BAR, 0, SBI_SAVELOAD_FINISH);
|
||||
_sl.saveinprogress = false;
|
||||
@@ -2586,7 +2594,7 @@ static SaveOrLoadResult DoSave(SaveFilter *writer, bool threaded)
|
||||
SlSaveChunks();
|
||||
|
||||
SaveFileStart();
|
||||
if (!threaded || !ThreadObject::New(&SaveFileToDiskThread, NULL, &_save_thread)) {
|
||||
if (!threaded || !ThreadObject::New(&SaveFileToDiskThread, NULL, &_save_thread, "ottd:savegame")) {
|
||||
if (threaded) DEBUG(sl, 1, "Cannot create savegame thread, reverting to single-threaded mode...");
|
||||
|
||||
SaveOrLoadResult result = SaveFileToDisk(false);
|
||||
@@ -2779,10 +2787,10 @@ SaveOrLoadResult LoadWithFilter(LoadFilter *reader)
|
||||
* @param threaded True when threaded saving is allowed
|
||||
* @return Return the result of the action. #SL_OK, #SL_ERROR, or #SL_REINIT ("unload" the game)
|
||||
*/
|
||||
SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb, bool threaded)
|
||||
SaveOrLoadResult SaveOrLoad(const char *filename, SaveLoadOperation fop, DetailedFileType dft, Subdirectory sb, bool threaded)
|
||||
{
|
||||
/* An instance of saving is already active, so don't go saving again */
|
||||
if (_sl.saveinprogress && mode == SL_SAVE && threaded) {
|
||||
if (_sl.saveinprogress && fop == SLO_SAVE && dft == DFT_GAME_FILE && threaded) {
|
||||
/* if not an autosave, but a user action, show error message */
|
||||
if (!_do_autosave) ShowErrorMessage(STR_ERROR_SAVE_STILL_IN_PROGRESS, INVALID_STRING_ID, WL_ERROR);
|
||||
return SL_OK;
|
||||
@@ -2791,7 +2799,7 @@ SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb, boo
|
||||
|
||||
try {
|
||||
/* Load a TTDLX or TTDPatch game */
|
||||
if (mode == SL_OLD_LOAD) {
|
||||
if (fop == SLO_LOAD && dft == DFT_OLD_GAME_FILE) {
|
||||
InitializeGame(256, 256, true, true); // set a mapsize of 256x256 for TTDPatch games or it might get confused
|
||||
|
||||
/* TTD/TTO savegames have no NewGRFs, TTDP savegame have them
|
||||
@@ -2812,25 +2820,35 @@ SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb, boo
|
||||
return SL_OK;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case SL_LOAD_CHECK: _sl.action = SLA_LOAD_CHECK; break;
|
||||
case SL_LOAD: _sl.action = SLA_LOAD; break;
|
||||
case SL_SAVE: _sl.action = SLA_SAVE; break;
|
||||
assert(dft == DFT_GAME_FILE);
|
||||
switch (fop) {
|
||||
case SLO_CHECK:
|
||||
_sl.action = SLA_LOAD_CHECK;
|
||||
break;
|
||||
|
||||
case SLO_LOAD:
|
||||
_sl.action = SLA_LOAD;
|
||||
break;
|
||||
|
||||
case SLO_SAVE:
|
||||
_sl.action = SLA_SAVE;
|
||||
break;
|
||||
|
||||
default: NOT_REACHED();
|
||||
}
|
||||
|
||||
FILE *fh = (mode == SL_SAVE) ? FioFOpenFile(filename, "wb", sb) : FioFOpenFile(filename, "rb", sb);
|
||||
FILE *fh = (fop == SLO_SAVE) ? FioFOpenFile(filename, "wb", sb) : FioFOpenFile(filename, "rb", sb);
|
||||
|
||||
/* Make it a little easier to load savegames from the console */
|
||||
if (fh == NULL && mode != SL_SAVE) fh = FioFOpenFile(filename, "rb", SAVE_DIR);
|
||||
if (fh == NULL && mode != SL_SAVE) fh = FioFOpenFile(filename, "rb", BASE_DIR);
|
||||
if (fh == NULL && mode != SL_SAVE) fh = FioFOpenFile(filename, "rb", SCENARIO_DIR);
|
||||
if (fh == NULL && fop != SLO_SAVE) fh = FioFOpenFile(filename, "rb", SAVE_DIR);
|
||||
if (fh == NULL && fop != SLO_SAVE) fh = FioFOpenFile(filename, "rb", BASE_DIR);
|
||||
if (fh == NULL && fop != SLO_SAVE) fh = FioFOpenFile(filename, "rb", SCENARIO_DIR);
|
||||
|
||||
if (fh == NULL) {
|
||||
SlError(mode == SL_SAVE ? STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE : STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
|
||||
SlError(fop == SLO_SAVE ? STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE : STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE);
|
||||
}
|
||||
|
||||
if (mode == SL_SAVE) { // SAVE game
|
||||
if (fop == SLO_SAVE) { // SAVE game
|
||||
DEBUG(desync, 1, "save: %08x; %02x; %s", _date, _date_fract, filename);
|
||||
if (_network_server || !_settings_client.gui.threaded_saves) threaded = false;
|
||||
|
||||
@@ -2838,24 +2856,25 @@ SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb, boo
|
||||
}
|
||||
|
||||
/* LOAD game */
|
||||
assert(mode == SL_LOAD || mode == SL_LOAD_CHECK);
|
||||
assert(fop == SLO_LOAD || fop == SLO_CHECK);
|
||||
DEBUG(desync, 1, "load: %s", filename);
|
||||
return DoLoad(new FileReader(fh), mode == SL_LOAD_CHECK);
|
||||
return DoLoad(new FileReader(fh), fop == SLO_CHECK);
|
||||
} catch (...) {
|
||||
/* This code may be executed both for old and new save games. */
|
||||
ClearSaveLoadState();
|
||||
|
||||
/* Skip the "colour" character */
|
||||
if (mode != SL_LOAD_CHECK) DEBUG(sl, 0, "%s", GetSaveLoadErrorString() + 3);
|
||||
if (fop != SLO_CHECK) DEBUG(sl, 0, "%s", GetSaveLoadErrorString() + 3);
|
||||
|
||||
/* A saver/loader exception!! reinitialize all variables to prevent crash! */
|
||||
return (mode == SL_LOAD || mode == SL_OLD_LOAD) ? SL_REINIT : SL_ERROR;
|
||||
return (fop == SLO_LOAD) ? SL_REINIT : SL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/** Do a save when exiting the game (_settings_client.gui.autosave_on_exit) */
|
||||
void DoExitSave()
|
||||
{
|
||||
SaveOrLoad("exit.sav", SL_SAVE, AUTOSAVE_DIR);
|
||||
SaveOrLoad("exit.sav", SLO_SAVE, DFT_GAME_FILE, AUTOSAVE_DIR);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2893,6 +2912,53 @@ void GenerateDefaultSaveName(char *buf, const char *last)
|
||||
SanitizeFilename(buf);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the mode and file type of the file to save or load based on the type of file entry at the file system.
|
||||
* @param ft Type of file entry of the file system.
|
||||
*/
|
||||
void FileToSaveLoad::SetMode(FiosType ft)
|
||||
{
|
||||
this->SetMode(SLO_LOAD, GetAbstractFileType(ft), GetDetailedFileType(ft));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the mode and file type of the file to save or load.
|
||||
* @param fop File operation being performed.
|
||||
* @param aft Abstract file type.
|
||||
* @param dft Detailed file type.
|
||||
*/
|
||||
void FileToSaveLoad::SetMode(SaveLoadOperation fop, AbstractFileType aft, DetailedFileType dft)
|
||||
{
|
||||
if (aft == FT_INVALID || aft == FT_NONE) {
|
||||
this->file_op = SLO_INVALID;
|
||||
this->detail_ftype = DFT_INVALID;
|
||||
this->abstract_ftype = FT_INVALID;
|
||||
return;
|
||||
}
|
||||
|
||||
this->file_op = fop;
|
||||
this->detail_ftype = dft;
|
||||
this->abstract_ftype = aft;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the name of the file.
|
||||
* @param name Name of the file.
|
||||
*/
|
||||
void FileToSaveLoad::SetName(const char *name)
|
||||
{
|
||||
strecpy(this->name, name, lastof(this->name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the title of the file.
|
||||
* @param title Title of the file.
|
||||
*/
|
||||
void FileToSaveLoad::SetTitle(const char *title)
|
||||
{
|
||||
strecpy(this->title, title, lastof(this->title));
|
||||
}
|
||||
|
||||
#if 0
|
||||
/**
|
||||
* Function to get the type of the savegame by looking at the file header.
|
||||
|
@@ -22,15 +22,18 @@ enum SaveOrLoadResult {
|
||||
SL_REINIT = 2, ///< error that was caught in the middle of updating game state, need to clear it. (can only happen during load)
|
||||
};
|
||||
|
||||
/** Save or load mode. @see SaveOrLoad */
|
||||
enum SaveOrLoadMode {
|
||||
SL_INVALID = -1, ///< Invalid mode.
|
||||
SL_LOAD = 0, ///< Load game.
|
||||
SL_SAVE = 1, ///< Save game.
|
||||
SL_OLD_LOAD = 2, ///< Load old game.
|
||||
SL_PNG = 3, ///< Load PNG file (height map).
|
||||
SL_BMP = 4, ///< Load BMP file (height map).
|
||||
SL_LOAD_CHECK = 5, ///< Load for game preview.
|
||||
/** Deals with the type of the savegame, independent of extension */
|
||||
struct FileToSaveLoad {
|
||||
SaveLoadOperation file_op; ///< File operation to perform.
|
||||
DetailedFileType detail_ftype; ///< Concrete file type (PNG, BMP, old save, etc).
|
||||
AbstractFileType abstract_ftype; ///< Abstract type of file (scenario, heightmap, etc).
|
||||
char name[MAX_PATH]; ///< Name of the file.
|
||||
char title[255]; ///< Internal name of the game.
|
||||
|
||||
void SetMode(FiosType ft);
|
||||
void SetMode(SaveLoadOperation fop, AbstractFileType aft, DetailedFileType dft);
|
||||
void SetName(const char *name);
|
||||
void SetTitle(const char *title);
|
||||
};
|
||||
|
||||
/** Types of save games. */
|
||||
@@ -43,10 +46,12 @@ enum SavegameType {
|
||||
SGT_INVALID = 0xFF, ///< broken savegame (used internally)
|
||||
};
|
||||
|
||||
extern FileToSaveLoad _file_to_saveload;
|
||||
|
||||
void GenerateDefaultSaveName(char *buf, const char *last);
|
||||
void SetSaveLoadError(uint16 str);
|
||||
const char *GetSaveLoadErrorString();
|
||||
SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb, bool threaded = true);
|
||||
SaveOrLoadResult SaveOrLoad(const char *filename, SaveLoadOperation fop, DetailedFileType dft, Subdirectory sb, bool threaded = true);
|
||||
void WaitTillSaved();
|
||||
void ProcessAsyncSaveFinish();
|
||||
void DoExitSave();
|
||||
|
@@ -60,7 +60,7 @@ static void Load_SIGN()
|
||||
}
|
||||
|
||||
/* Signs placed in scenario editor shall now be OWNER_DEITY */
|
||||
if (IsSavegameVersionBefore(171) && si->owner == OWNER_NONE && _saveload_mode == SLD_LOAD_SCENARIO) {
|
||||
if (IsSavegameVersionBefore(171) && si->owner == OWNER_NONE && _file_to_saveload.abstract_ftype == FT_SCENARIO) {
|
||||
si->owner = OWNER_DEITY;
|
||||
}
|
||||
}
|
||||
|
@@ -436,21 +436,21 @@ void AfterLoadVehicles(bool part_of_load)
|
||||
|
||||
case VEH_TRAIN:
|
||||
case VEH_SHIP:
|
||||
v->cur_image = v->GetImage(v->direction, EIT_ON_MAP);
|
||||
v->GetImage(v->direction, EIT_ON_MAP, &v->sprite_seq);
|
||||
break;
|
||||
|
||||
case VEH_AIRCRAFT:
|
||||
if (Aircraft::From(v)->IsNormalAircraft()) {
|
||||
v->cur_image = v->GetImage(v->direction, EIT_ON_MAP);
|
||||
v->GetImage(v->direction, EIT_ON_MAP, &v->sprite_seq);
|
||||
|
||||
/* The plane's shadow will have the same image as the plane */
|
||||
/* The plane's shadow will have the same image as the plane, but no colour */
|
||||
Vehicle *shadow = v->Next();
|
||||
shadow->cur_image = v->cur_image;
|
||||
shadow->sprite_seq.CopyWithoutPalette(v->sprite_seq);
|
||||
|
||||
/* In the case of a helicopter we will update the rotor sprites */
|
||||
if (v->subtype == AIR_HELICOPTER) {
|
||||
Vehicle *rotor = shadow->Next();
|
||||
rotor->cur_image = GetRotorImage(Aircraft::From(v), EIT_ON_MAP);
|
||||
GetRotorImage(Aircraft::From(v), EIT_ON_MAP, &rotor->sprite_seq);
|
||||
}
|
||||
|
||||
UpdateAircraftCache(Aircraft::From(v), true);
|
||||
@@ -796,7 +796,7 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
|
||||
SLE_CONDVAR(Vehicle, z_pos, SLE_FILE_U8 | SLE_VAR_I32, 0, 163),
|
||||
SLE_CONDVAR(Vehicle, z_pos, SLE_INT32, 164, SL_MAX_VERSION),
|
||||
|
||||
SLE_VAR(Vehicle, cur_image, SLE_FILE_U16 | SLE_VAR_U32),
|
||||
SLE_VAR(Vehicle, sprite_seq.seq[0].sprite, SLE_FILE_U16 | SLE_VAR_U32),
|
||||
SLE_CONDNULL(5, 0, 57),
|
||||
SLE_VAR(Vehicle, progress, SLE_UINT8),
|
||||
SLE_VAR(Vehicle, vehstatus, SLE_UINT8),
|
||||
@@ -836,7 +836,7 @@ const SaveLoad *GetVehicleDescription(VehicleType vt)
|
||||
SLE_CONDVAR(Vehicle, current_order.dest, SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
|
||||
SLE_CONDVAR(Vehicle, current_order.dest, SLE_UINT16, 5, SL_MAX_VERSION),
|
||||
|
||||
SLE_VAR(Vehicle, cur_image, SLE_FILE_U16 | SLE_VAR_U32),
|
||||
SLE_VAR(Vehicle, sprite_seq.seq[0].sprite, SLE_FILE_U16 | SLE_VAR_U32),
|
||||
SLE_CONDVAR(Vehicle, age, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
|
||||
SLE_CONDVAR(Vehicle, age, SLE_INT32, 31, SL_MAX_VERSION),
|
||||
SLE_VAR(Vehicle, tick_counter, SLE_UINT8),
|
||||
|
Reference in New Issue
Block a user