Changeset - r6935:a7744b917c21
[Not reviewed]
master
0 4 0
rubidium - 17 years ago 2007-06-17 20:09:05
rubidium@openttd.org
(svn r10188) -Codechange: make it a little easier to load a savegame from the console:
-g <absolute path>
-g <relative path from current working directory>
-g <relative path from within the savegame directory>
4 files changed with 12 insertions and 6 deletions:
0 comments (0 inline, 0 general)
src/fileio.cpp
Show inline comments
 
@@ -258,75 +258,75 @@ char *FioGetDirectory(char *buf, size_t 
 
	FOR_ALL_SEARCHPATHS(sp) {
 
		char *ret = FioAppendDirectory(buf, buflen, sp, subdir);
 
		if (FileExists(buf)) return ret;
 
	}
 

	
 
	/* Could not find the directory, fall back to a base path */
 
	ttd_strlcpy(buf, _personal_dir, buflen);
 

	
 
	return buf;
 
}
 

	
 
FILE *FioFOpenFileSp(const char *filename, const char *mode, Searchpath sp, Subdirectory subdir)
 
{
 
#if defined(WIN32) && defined(UNICODE)
 
	/* fopen is implemented as a define with ellipses for
 
	 * Unicode support (prepend an L). As we are not sending
 
	 * a string, but a variable, it 'renames' the variable,
 
	 * so make that variable to makes it compile happily */
 
	wchar_t Lmode[5];
 
	MultiByteToWideChar(CP_ACP, 0, mode, -1, Lmode, lengthof(Lmode));
 
#endif
 
	FILE *f = NULL;
 
	char buf[MAX_PATH];
 

	
 
	if (subdir == BASE_DIR) {
 
	if (subdir == NO_DIRECTORY) {
 
		ttd_strlcpy(buf, filename, lengthof(buf));
 
	} else {
 
		snprintf(buf, lengthof(buf), "%s%s%s", _searchpaths[sp], _subdirs[subdir], filename);
 
	}
 

	
 
	f = fopen(buf, mode);
 
#if !defined(WIN32)
 
	if (f == NULL) {
 
		strtolower(buf + strlen(_searchpaths[sp]) - 1);
 
		f = fopen(buf, mode);
 
	}
 
#endif
 
	return f;
 
}
 

	
 
/** Opens OpenTTD files somewhere in a personal or global directory */
 
FILE *FioFOpenFile(const char *filename, const char *mode, Subdirectory subdir)
 
{
 
	FILE *f = NULL;
 
	Searchpath sp;
 

	
 
	assert(subdir < NUM_SUBDIRS);
 
	assert(subdir < NUM_SUBDIRS || subdir == NO_DIRECTORY);
 

	
 
	FOR_ALL_SEARCHPATHS(sp) {
 
		f = FioFOpenFileSp(filename, mode, sp, subdir);
 
		if (f != NULL || subdir == 0) break;
 
		if (f != NULL || subdir == NO_DIRECTORY) break;
 
	}
 

	
 
	return f;
 
}
 

	
 
/**
 
 * Create a directory with the given name
 
 * @param name the new name of the directory
 
 */
 
void FioCreateDirectory(const char *name)
 
{
 
#if defined(WIN32) || defined(WINCE)
 
	CreateDirectory(OTTD2FS(name), NULL);
 
#elif defined(OS2) && !defined(__INNOTEK_LIBC__)
 
	mkdir(OTTD2FS(name));
 
#else
 
	mkdir(OTTD2FS(name), 0755);
 
#endif
 
}
 

	
 
/**
 
 * Appends, if necessary, the path separator character to the end of the string.
 
 * It does not add the path separator to zero-sized strings.
 
 * @param buf    string to append the separator to
src/fileio.h
Show inline comments
 
@@ -12,48 +12,49 @@ void FioSeekToFile(uint32 pos);
 
uint32 FioGetPos();
 
const char *FioGetFilename();
 
byte FioReadByte();
 
uint16 FioReadWord();
 
uint32 FioReadDword();
 
void FioCloseAll();
 
void FioOpenFile(int slot, const char *filename);
 
void FioReadBlock(void *ptr, uint size);
 
void FioSkipBytes(int n);
 
void FioCreateDirectory(const char *filename);
 

	
 
/**
 
 * The different kinds of subdirectories OpenTTD uses
 
 */
 
enum Subdirectory {
 
	BASE_DIR,      ///< Base directory for all subdirectories
 
	SAVE_DIR,      ///< Base directory for all savegames
 
	AUTOSAVE_DIR,  ///< Subdirectory of save for autosaves
 
	SCENARIO_DIR,  ///< Base directory for all scenarios
 
	HEIGHTMAP_DIR, ///< Subdirectory of scenario for heightmaps
 
	GM_DIR,        ///< Subdirectory for all music
 
	DATA_DIR,      ///< Subdirectory for all data (GRFs, sample.cat, intro game)
 
	LANG_DIR,      ///< Subdirectory for all translation files
 
	NUM_SUBDIRS,   ///< Number of subdirectories
 
	NO_DIRECTORY,  ///< A path without any base directory
 
};
 

	
 
/**
 
 * Types of searchpaths OpenTTD might use
 
 */
 
enum Searchpath {
 
	SP_PERSONAL_DIR,           ///< Search in the personal directory
 
	SP_SHARED_DIR,             ///< Search in the shared directory, like 'Shared Files' under Windows
 
	SP_WORKING_DIR,            ///< Search in the working directory
 
	SP_BINARY_DIR,             ///< Search in the directory where the binary resides
 
	SP_INSTALLATION_DIR,       ///< Search in the installation directory
 
	SP_APPLICATION_BUNDLE_DIR, ///< Search within the application bundle
 
	NUM_SEARCHPATHS
 
};
 

	
 
DECLARE_POSTFIX_INCREMENT(Searchpath);
 

	
 
/**
 
 * The searchpaths OpenTTD could search through.
 
 * At least one of the slots has to be filled with a path.
 
 * NULL paths tell that there is no such path for the
 
 * current operating system.
 
 */
 
extern const char *_searchpaths[NUM_SEARCHPATHS];
src/openttd.cpp
Show inline comments
 
@@ -839,99 +839,99 @@ void SwitchMode(int new_mode)
 
		break;
 

	
 
	case SM_NEWGAME: /* New Game --> 'Random game' */
 
#ifdef ENABLE_NETWORK
 
		if (_network_server) {
 
			snprintf(_network_game_info.map_name, lengthof(_network_game_info.map_name), "Random Map");
 
		}
 
#endif /* ENABLE_NETWORK */
 
		MakeNewGame(false);
 
		break;
 

	
 
	case SM_START_SCENARIO: /* New Game --> Choose one of the preset scenarios */
 
#ifdef ENABLE_NETWORK
 
		if (_network_server) {
 
			snprintf(_network_game_info.map_name, lengthof(_network_game_info.map_name), "%s (Loaded scenario)", _file_to_saveload.title);
 
		}
 
#endif /* ENABLE_NETWORK */
 
		StartScenario();
 
		break;
 

	
 
	case SM_LOAD: { /* Load game, Play Scenario */
 
		_opt_ptr = &_opt;
 
		ResetGRFConfig(true);
 

	
 
		if (!SafeSaveOrLoad(_file_to_saveload.name, _file_to_saveload.mode, GM_NORMAL, BASE_DIR)) {
 
		if (!SafeSaveOrLoad(_file_to_saveload.name, _file_to_saveload.mode, GM_NORMAL, NO_DIRECTORY)) {
 
			LoadIntroGame();
 
			ShowErrorMessage(INVALID_STRING_ID, STR_4009_GAME_LOAD_FAILED, 0, 0);
 
		} else {
 
			/* Update the local player for a loaded game. It is either always
 
			 * player #1 (eg 0) or in the case of a dedicated server a spectator */
 
			SetLocalPlayer(_network_dedicated ? PLAYER_SPECTATOR : PLAYER_FIRST);
 
			DoCommandP(0, 0, 0, NULL, CMD_PAUSE); // decrease pause counter (was increased from opening load dialog)
 
#ifdef ENABLE_NETWORK
 
			if (_network_server) {
 
				snprintf(_network_game_info.map_name, lengthof(_network_game_info.map_name), "%s (Loaded game)", _file_to_saveload.title);
 
			}
 
#endif /* ENABLE_NETWORK */
 
		}
 
		break;
 
	}
 

	
 
	case SM_START_HEIGHTMAP: /* Load a heightmap and start a new game from it */
 
#ifdef ENABLE_NETWORK
 
		if (_network_server) {
 
			snprintf(_network_game_info.map_name, lengthof(_network_game_info.map_name), "%s (Heightmap)", _file_to_saveload.title);
 
		}
 
#endif /* ENABLE_NETWORK */
 
		MakeNewGame(true);
 
		break;
 

	
 
	case SM_LOAD_HEIGHTMAP: /* Load heightmap from scenario editor */
 
		SetLocalPlayer(OWNER_NONE);
 

	
 
		GenerateWorld(GW_HEIGHTMAP, 1 << _patches.map_x, 1 << _patches.map_y);
 
		MarkWholeScreenDirty();
 
		break;
 

	
 
	case SM_LOAD_SCENARIO: { /* Load scenario from scenario editor */
 
		if (SafeSaveOrLoad(_file_to_saveload.name, _file_to_saveload.mode, GM_EDITOR, BASE_DIR)) {
 
		if (SafeSaveOrLoad(_file_to_saveload.name, _file_to_saveload.mode, GM_EDITOR, NO_DIRECTORY)) {
 
			_opt_ptr = &_opt;
 

	
 
			SetLocalPlayer(OWNER_NONE);
 
			_patches_newgame.starting_year = _cur_year;
 
		} else {
 
			ShowErrorMessage(INVALID_STRING_ID, STR_4009_GAME_LOAD_FAILED, 0, 0);
 
		}
 
		break;
 
	}
 

	
 
	case SM_MENU: /* Switch to game intro menu */
 
		LoadIntroGame();
 
		break;
 

	
 
	case SM_SAVE: /* Save game */
 
		if (SaveOrLoad(_file_to_saveload.name, SL_SAVE, BASE_DIR) != SL_OK) {
 
		if (SaveOrLoad(_file_to_saveload.name, SL_SAVE, NO_DIRECTORY) != SL_OK) {
 
			ShowErrorMessage(INVALID_STRING_ID, STR_4007_GAME_SAVE_FAILED, 0, 0);
 
		} else {
 
			DeleteWindowById(WC_SAVELOAD, 0);
 
		}
 
		break;
 

	
 
	case SM_GENRANDLAND: /* Generate random land within scenario editor */
 
		SetLocalPlayer(OWNER_NONE);
 
		GenerateWorld(GW_RANDOM, 1 << _patches.map_x, 1 << _patches.map_y);
 
		/* XXX: set date */
 
		MarkWholeScreenDirty();
 
		break;
 
	}
 

	
 
	if (_switch_mode_errorstr != INVALID_STRING_ID) {
 
		ShowErrorMessage(INVALID_STRING_ID, _switch_mode_errorstr, 0, 0);
 
	}
 
}
 

	
 

	
 
/* State controlling game loop.
 
 * The state must not be changed from anywhere
 
 * but here.
 
 * That check is enforced in DoCommand. */
src/saveload.cpp
Show inline comments
 
@@ -1563,48 +1563,53 @@ void WaitTillSaved()
 
 */
 
SaveOrLoadResult SaveOrLoad(const char *filename, int mode, Subdirectory sb)
 
{
 
	uint32 hdr[2];
 
	const SaveLoadFormat *fmt;
 

	
 
	/* An instance of saving is already active, so don't go saving again */
 
	if (_ts.saveinprogress && mode == SL_SAVE) {
 
		/* if not an autosave, but a user action, show error message */
 
		if (!_do_autosave) ShowErrorMessage(INVALID_STRING_ID, STR_SAVE_STILL_IN_PROGRESS, 0, 0);
 
		return SL_OK;
 
	}
 
	WaitTillSaved();
 

	
 
	/* Load a TTDLX or TTDPatch game */
 
	if (mode == SL_OLD_LOAD) {
 
		InitializeGame(IG_DATE_RESET, 256, 256); // set a mapsize of 256x256 for TTDPatch games or it might get confused
 
		if (!LoadOldSaveGame(filename)) return SL_REINIT;
 
		_sl_version = 0;
 
		AfterLoadGame();
 
		return SL_OK;
 
	}
 

	
 
	_sl.fh = (mode == SL_SAVE) ? FioFOpenFile(filename, "wb", sb) : FioFOpenFile(filename, "rb", sb);
 

	
 
	/* Make it a little easier to load savegames from the console */
 
	if (_sl.fh == NULL && mode == SL_LOAD) _sl.fh = FioFOpenFile(filename, "rb", SAVE_DIR);
 
	if (_sl.fh == NULL && mode == SL_LOAD) _sl.fh = FioFOpenFile(filename, "rb", BASE_DIR);
 

	
 
	if (_sl.fh == NULL) {
 
		DEBUG(sl, 0, "Cannot open savegame '%s' for saving/loading.", filename);
 
		return SL_ERROR;
 
	}
 

	
 
	_sl.bufe = _sl.bufp = NULL;
 
	_sl.offs_base = 0;
 
	_sl.save = (mode != 0);
 
	_sl.includes = _desc_includes;
 
	_sl.chs = _chunk_handlers;
 

	
 
	/* XXX - Setup setjmp error handler if an error occurs anywhere deep during
 
	 * loading/saving execute a longjmp() and continue execution here */
 
	if (setjmp(_sl.excpt)) {
 
		AbortSaveLoad();
 

	
 
		/* deinitialize compressor. */
 
		_sl.excpt_uninit();
 

	
 
		/* A saver/loader exception!! reinitialize all variables to prevent crash! */
 
		if (mode == SL_LOAD) {
 
			ShowInfoF("Load game failed: %s.", _sl.excpt_msg);
 
			return SL_REINIT;
 
		}
0 comments (0 inline, 0 general)