Merge branch 'save_ext' into jgrpp
# Conflicts: # config.lib # src/saveload/extended_ver_sl.cpp # src/saveload/saveload.cpp
This commit is contained in:
24
config.lib
24
config.lib
@@ -1291,7 +1291,12 @@ make_compiler_cflags() {
|
||||
# remark #2259: non-pointer conversion from ... to ... may lose significant bits
|
||||
flags="$flags -wd2259"
|
||||
# Use c++0x mode so static_assert() is available
|
||||
cxxflags="$cxxflags -std=c++0x"
|
||||
cxxflags="$cxxflags -std=c++11"
|
||||
fi
|
||||
|
||||
if [ $cc_version -lt 140 ]; then
|
||||
log 1 "configure: error: ICC version is too old: `$1 -dumpversion`, minumum: 14.0"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$enable_lto" != "0" ]; then
|
||||
@@ -1311,7 +1316,7 @@ make_compiler_cflags() {
|
||||
|
||||
# -W alone doesn't enable all warnings enabled by -Wall; on the other hand,
|
||||
# -Weverything enables too many useless warnings that can't be disabled (as of 3.0)
|
||||
flags="$flags -Wall -W"
|
||||
flags="$flags -Wall -W -Wextra"
|
||||
|
||||
# warning: unused parameter '...'
|
||||
flags="$flags -Wno-unused-parameter"
|
||||
@@ -1352,6 +1357,14 @@ make_compiler_cflags() {
|
||||
flags="$flags -Wno-unused-variable"
|
||||
fi
|
||||
|
||||
if [ "$cc_version" -ge "33" ]; then
|
||||
# clang completed C++11 support in version 3.3
|
||||
flags="$flags -std=c++11"
|
||||
else
|
||||
log 1 "configure: error: clang version is too old: `$1 -v 2>&1 | head -n 1`, minumum: 3.3"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# rdynamic is used to get useful stack traces from crash reports.
|
||||
ldflags="$ldflags -rdynamic"
|
||||
else
|
||||
@@ -1408,11 +1421,9 @@ make_compiler_cflags() {
|
||||
flags="$flags -Wnon-virtual-dtor"
|
||||
fi
|
||||
|
||||
if [ $cc_version -ge 403 ] && [ $cc_version -lt 407 ]; then
|
||||
if [ $cc_version -ge 403 ] && [ $cc_version -lt 600 ]; then
|
||||
# Use gnu++0x mode so static_assert() is available.
|
||||
# Don't use c++0x, it breaks mingw (with gcc 4.4.0).
|
||||
cxxflags="$cxxflags -std=gnu++0x -DDISABLE_OVERRIDE"
|
||||
elif [ $cc_version -ge 407 ] && [ $cc_version -lt 600 ]; then
|
||||
cxxflags="$cxxflags -std=gnu++11"
|
||||
fi
|
||||
|
||||
@@ -1429,6 +1440,9 @@ make_compiler_cflags() {
|
||||
cxxflags="$cxxflags -Wno-narrowing"
|
||||
# Disable bogus 'attempt to free a non-heap object' warning
|
||||
flags="$flags -Wno-free-nonheap-object"
|
||||
else
|
||||
log 1 "configure: error: GCC version is too old: `$1 -dumpversion`, minumum: 4.7"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ $cc_version -ge 409 ]; then
|
||||
|
@@ -592,6 +592,7 @@
|
||||
<ClInclude Include="..\src\roadstop_base.h" />
|
||||
<ClInclude Include="..\src\roadveh.h" />
|
||||
<ClInclude Include="..\src\safeguards.h" />
|
||||
<ClInclude Include="..\src\scope.h" />
|
||||
<ClInclude Include="..\src\screenshot.h" />
|
||||
<ClInclude Include="..\src\sdl.h" />
|
||||
<ClInclude Include="..\src\sound\sdl_s.h" />
|
||||
|
@@ -1005,6 +1005,9 @@
|
||||
<ClInclude Include="..\src\safeguards.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\scope.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\screenshot.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
@@ -609,6 +609,7 @@
|
||||
<ClInclude Include="..\src\roadstop_base.h" />
|
||||
<ClInclude Include="..\src\roadveh.h" />
|
||||
<ClInclude Include="..\src\safeguards.h" />
|
||||
<ClInclude Include="..\src\scope.h" />
|
||||
<ClInclude Include="..\src\screenshot.h" />
|
||||
<ClInclude Include="..\src\sdl.h" />
|
||||
<ClInclude Include="..\src\sound\sdl_s.h" />
|
||||
|
@@ -1005,6 +1005,9 @@
|
||||
<ClInclude Include="..\src\safeguards.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\scope.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\src\screenshot.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
|
@@ -1642,6 +1642,10 @@
|
||||
RelativePath=".\..\src\safeguards.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\..\src\scope.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\..\src\screenshot.h"
|
||||
>
|
||||
|
@@ -1639,6 +1639,10 @@
|
||||
RelativePath=".\..\src\safeguards.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\..\src\scope.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\..\src\screenshot.h"
|
||||
>
|
||||
|
@@ -332,6 +332,7 @@ road_type.h
|
||||
roadstop_base.h
|
||||
roadveh.h
|
||||
safeguards.h
|
||||
scope.h
|
||||
screenshot.h
|
||||
sdl.h
|
||||
sound/sdl_s.h
|
||||
|
@@ -48,6 +48,38 @@
|
||||
/* scriptfile handling */
|
||||
static bool _script_running; ///< Script is running (used to abort execution when #ConReturn is encountered).
|
||||
|
||||
/** File list storage for the console, for caching the last 'ls' command. */
|
||||
class ConsoleFileList : public FileList {
|
||||
public:
|
||||
ConsoleFileList() : FileList()
|
||||
{
|
||||
this->file_list_valid = false;
|
||||
}
|
||||
|
||||
/** Declare the file storage cache as being invalid, also clears all stored files. */
|
||||
void InvalidateFileList()
|
||||
{
|
||||
this->Clear();
|
||||
this->file_list_valid = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* (Re-)validate the file storage cache. Only makes a change if the storage was invalid, or if \a force_reload.
|
||||
* @param Always reload the file storage cache.
|
||||
*/
|
||||
void ValidateFileList(bool force_reload = false)
|
||||
{
|
||||
if (force_reload || !this->file_list_valid) {
|
||||
this->BuildFileList(FT_SAVEGAME, SLO_LOAD);
|
||||
this->file_list_valid = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool file_list_valid; ///< If set, the file list is valid.
|
||||
};
|
||||
|
||||
static ConsoleFileList _console_file_list; ///< File storage cache for the console.
|
||||
|
||||
/* console command defines */
|
||||
#define DEF_CONSOLE_CMD(function) static bool function(byte argc, char *argv[])
|
||||
#define DEF_CONSOLE_HOOK(function) static ConsoleHookResult function(bool echo)
|
||||
@@ -288,7 +320,7 @@ DEF_CONSOLE_CMD(ConSave)
|
||||
char *filename = str_fmt("%s.sav", argv[1]);
|
||||
IConsolePrint(CC_DEFAULT, "Saving map...");
|
||||
|
||||
if (SaveOrLoad(filename, SL_SAVE, SAVE_DIR) != SL_OK) {
|
||||
if (SaveOrLoad(filename, SLO_SAVE, DFT_GAME_FILE, SAVE_DIR) != SL_OK) {
|
||||
IConsolePrint(CC_ERROR, "Saving map failed");
|
||||
} else {
|
||||
IConsolePrintF(CC_DEFAULT, "Map successfully saved to %s", filename);
|
||||
@@ -317,42 +349,6 @@ DEF_CONSOLE_CMD(ConSaveConfig)
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get savegame file informations.
|
||||
* @param file The savegame filename to return information about. Can be the actual name
|
||||
* or a numbered entry into the filename list.
|
||||
* @return FiosItem The information on the file.
|
||||
*/
|
||||
static const FiosItem *GetFiosItem(const char *file)
|
||||
{
|
||||
_saveload_mode = SLD_LOAD_GAME;
|
||||
BuildFileList();
|
||||
|
||||
for (const FiosItem *item = _fios_items.Begin(); item != _fios_items.End(); item++) {
|
||||
if (strcmp(file, item->name) == 0) return item;
|
||||
if (strcmp(file, item->title) == 0) return item;
|
||||
}
|
||||
|
||||
/* If no name matches, try to parse it as number */
|
||||
char *endptr;
|
||||
int i = strtol(file, &endptr, 10);
|
||||
if (file == endptr || *endptr != '\0') i = -1;
|
||||
|
||||
if (IsInsideMM(i, 0, _fios_items.Length())) return _fios_items.Get(i);
|
||||
|
||||
/* As a last effort assume it is an OpenTTD savegame and
|
||||
* that the ".sav" part was not given. */
|
||||
char long_file[MAX_PATH];
|
||||
seprintf(long_file, lastof(long_file), "%s.sav", file);
|
||||
for (const FiosItem *item = _fios_items.Begin(); item != _fios_items.End(); item++) {
|
||||
if (strcmp(long_file, item->name) == 0) return item;
|
||||
if (strcmp(long_file, item->title) == 0) return item;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
DEF_CONSOLE_CMD(ConLoad)
|
||||
{
|
||||
if (argc == 0) {
|
||||
@@ -363,24 +359,21 @@ DEF_CONSOLE_CMD(ConLoad)
|
||||
if (argc != 2) return false;
|
||||
|
||||
const char *file = argv[1];
|
||||
const FiosItem *item = GetFiosItem(file);
|
||||
_console_file_list.ValidateFileList();
|
||||
const FiosItem *item = _console_file_list.FindItem(file);
|
||||
if (item != NULL) {
|
||||
switch (item->type) {
|
||||
case FIOS_TYPE_FILE: case FIOS_TYPE_OLDFILE: {
|
||||
if (GetAbstractFileType(item->type) == FT_SAVEGAME) {
|
||||
_switch_mode = SM_LOAD_GAME;
|
||||
SetFiosType(item->type);
|
||||
|
||||
strecpy(_file_to_saveload.name, FiosBrowseTo(item), lastof(_file_to_saveload.name));
|
||||
strecpy(_file_to_saveload.title, item->title, lastof(_file_to_saveload.title));
|
||||
break;
|
||||
}
|
||||
default: IConsolePrintF(CC_ERROR, "%s: Not a savegame.", file);
|
||||
_file_to_saveload.SetMode(item->type);
|
||||
_file_to_saveload.SetName(FiosBrowseTo(item));
|
||||
_file_to_saveload.SetTitle(item->title);
|
||||
} else {
|
||||
IConsolePrintF(CC_ERROR, "%s: Not a savegame.", file);
|
||||
}
|
||||
} else {
|
||||
IConsolePrintF(CC_ERROR, "%s: No such file or directory.", file);
|
||||
}
|
||||
|
||||
FiosFreeSavegameList();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -395,7 +388,8 @@ DEF_CONSOLE_CMD(ConRemove)
|
||||
if (argc != 2) return false;
|
||||
|
||||
const char *file = argv[1];
|
||||
const FiosItem *item = GetFiosItem(file);
|
||||
_console_file_list.ValidateFileList();
|
||||
const FiosItem *item = _console_file_list.FindItem(file);
|
||||
if (item != NULL) {
|
||||
if (!FiosDelete(item->name)) {
|
||||
IConsolePrintF(CC_ERROR, "%s: Failed to delete file", file);
|
||||
@@ -404,7 +398,7 @@ DEF_CONSOLE_CMD(ConRemove)
|
||||
IConsolePrintF(CC_ERROR, "%s: No such file or directory.", file);
|
||||
}
|
||||
|
||||
FiosFreeSavegameList();
|
||||
_console_file_list.InvalidateFileList();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -417,13 +411,11 @@ DEF_CONSOLE_CMD(ConListFiles)
|
||||
return true;
|
||||
}
|
||||
|
||||
BuildFileList();
|
||||
|
||||
for (uint i = 0; i < _fios_items.Length(); i++) {
|
||||
IConsolePrintF(CC_DEFAULT, "%d) %s", i, _fios_items[i].title);
|
||||
_console_file_list.ValidateFileList(true);
|
||||
for (uint i = 0; i < _console_file_list.Length(); i++) {
|
||||
IConsolePrintF(CC_DEFAULT, "%d) %s", i, _console_file_list[i].title);
|
||||
}
|
||||
|
||||
FiosFreeSavegameList();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -438,7 +430,8 @@ DEF_CONSOLE_CMD(ConChangeDirectory)
|
||||
if (argc != 2) return false;
|
||||
|
||||
const char *file = argv[1];
|
||||
const FiosItem *item = GetFiosItem(file);
|
||||
_console_file_list.ValidateFileList(true);
|
||||
const FiosItem *item = _console_file_list.FindItem(file);
|
||||
if (item != NULL) {
|
||||
switch (item->type) {
|
||||
case FIOS_TYPE_DIR: case FIOS_TYPE_DRIVE: case FIOS_TYPE_PARENT:
|
||||
@@ -450,7 +443,7 @@ DEF_CONSOLE_CMD(ConChangeDirectory)
|
||||
IConsolePrintF(CC_ERROR, "%s: No such file or directory.", file);
|
||||
}
|
||||
|
||||
FiosFreeSavegameList();
|
||||
_console_file_list.InvalidateFileList();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -464,8 +457,8 @@ DEF_CONSOLE_CMD(ConPrintWorkingDirectory)
|
||||
}
|
||||
|
||||
/* XXX - Workaround for broken file handling */
|
||||
FiosGetSavegameList(SLD_LOAD_GAME);
|
||||
FiosFreeSavegameList();
|
||||
_console_file_list.ValidateFileList(true);
|
||||
_console_file_list.InvalidateFileList();
|
||||
|
||||
FiosGetDescText(&path, NULL);
|
||||
IConsolePrint(CC_DEFAULT, path);
|
||||
|
@@ -256,6 +256,8 @@ public:
|
||||
|
||||
/**
|
||||
* Get the number of items in the list.
|
||||
*
|
||||
* @return The number of items in the list.
|
||||
*/
|
||||
inline uint Length() const
|
||||
{
|
||||
|
@@ -414,7 +414,7 @@ bool CrashLog::WriteSavegame(char *filename, const char *filename_last) const
|
||||
seprintf(filename, filename_last, "%scrash.sav", _personal_dir);
|
||||
|
||||
/* Don't do a threaded saveload. */
|
||||
return SaveOrLoad(filename, SL_SAVE, NO_DIRECTORY, false) == SL_OK;
|
||||
return SaveOrLoad(filename, SLO_SAVE, DFT_GAME_FILE, NO_DIRECTORY, false) == SL_OK;
|
||||
} catch (...) {
|
||||
return false;
|
||||
}
|
||||
|
@@ -14,6 +14,96 @@
|
||||
|
||||
#include "core/enum_type.hpp"
|
||||
|
||||
/** The different abstract types of files that the system knows about. */
|
||||
enum AbstractFileType {
|
||||
FT_NONE, ///< nothing to do
|
||||
FT_SAVEGAME, ///< old or new savegame
|
||||
FT_SCENARIO, ///< old or new scenario
|
||||
FT_HEIGHTMAP, ///< heightmap file
|
||||
|
||||
FT_INVALID = 7, ///< Invalid or unknown file type.
|
||||
FT_NUMBITS = 3, ///< Number of bits required for storing a #AbstractFileType value.
|
||||
FT_MASK = (1 << FT_NUMBITS) - 1, ///< Bitmask for extracting an abstract file type.
|
||||
};
|
||||
|
||||
/** Kinds of files in each #AbstractFileType. */
|
||||
enum DetailedFileType {
|
||||
/* Save game and scenario files. */
|
||||
DFT_OLD_GAME_FILE, ///< Old save game or scenario file.
|
||||
DFT_GAME_FILE, ///< Save game or scenario file.
|
||||
|
||||
/* Heightmap files. */
|
||||
DFT_HEIGHTMAP_BMP, ///< BMP file.
|
||||
DFT_HEIGHTMAP_PNG, ///< PNG file.
|
||||
|
||||
/* fios 'files' */
|
||||
DFT_FIOS_DRIVE, ///< A drive (letter) entry.
|
||||
DFT_FIOS_PARENT, ///< A parent directory entry.
|
||||
DFT_FIOS_DIR, ///< A directory entry.
|
||||
DFT_FIOS_DIRECT, ///< Direct filename.
|
||||
|
||||
DFT_INVALID = 255, ///< Unknown or invalid file.
|
||||
};
|
||||
|
||||
/** Operation performed on the file. */
|
||||
enum SaveLoadOperation {
|
||||
SLO_CHECK, ///< Load file for checking and/or preview.
|
||||
SLO_LOAD, ///< File is being loaded.
|
||||
SLO_SAVE, ///< File is being saved.
|
||||
|
||||
SLO_INVALID, ///< Unknown file operation.
|
||||
};
|
||||
|
||||
/**
|
||||
* Construct an enum value for #FiosType as a combination of an abstract and a detailed file type.
|
||||
* @param abstract Abstract file type (one of #AbstractFileType).
|
||||
* @param detailed Detailed file type (one of #DetailedFileType).
|
||||
*/
|
||||
#define MAKE_FIOS_TYPE(abstract, detailed) ((abstract) | ((detailed) << FT_NUMBITS))
|
||||
|
||||
/**
|
||||
* Elements of a file system that are recognized.
|
||||
* Values are a combination of #AbstractFileType and #DetailedFileType.
|
||||
* @see GetAbstractFileType GetDetailedFileType
|
||||
*/
|
||||
enum FiosType {
|
||||
FIOS_TYPE_DRIVE = MAKE_FIOS_TYPE(FT_NONE, DFT_FIOS_DRIVE),
|
||||
FIOS_TYPE_PARENT = MAKE_FIOS_TYPE(FT_NONE, DFT_FIOS_PARENT),
|
||||
FIOS_TYPE_DIR = MAKE_FIOS_TYPE(FT_NONE, DFT_FIOS_DIR),
|
||||
FIOS_TYPE_DIRECT = MAKE_FIOS_TYPE(FT_NONE, DFT_FIOS_DIRECT),
|
||||
|
||||
FIOS_TYPE_FILE = MAKE_FIOS_TYPE(FT_SAVEGAME, DFT_GAME_FILE),
|
||||
FIOS_TYPE_OLDFILE = MAKE_FIOS_TYPE(FT_SAVEGAME, DFT_OLD_GAME_FILE),
|
||||
FIOS_TYPE_SCENARIO = MAKE_FIOS_TYPE(FT_SCENARIO, DFT_GAME_FILE),
|
||||
FIOS_TYPE_OLD_SCENARIO = MAKE_FIOS_TYPE(FT_SCENARIO, DFT_OLD_GAME_FILE),
|
||||
FIOS_TYPE_PNG = MAKE_FIOS_TYPE(FT_HEIGHTMAP, DFT_HEIGHTMAP_PNG),
|
||||
FIOS_TYPE_BMP = MAKE_FIOS_TYPE(FT_HEIGHTMAP, DFT_HEIGHTMAP_BMP),
|
||||
|
||||
FIOS_TYPE_INVALID = MAKE_FIOS_TYPE(FT_INVALID, DFT_INVALID),
|
||||
};
|
||||
|
||||
#undef MAKE_FIOS_TYPE
|
||||
|
||||
/**
|
||||
* Extract the abstract file type from a #FiosType.
|
||||
* @param fios_type Type to query.
|
||||
* @return The Abstract file type of the \a fios_type.
|
||||
*/
|
||||
inline AbstractFileType GetAbstractFileType(FiosType fios_type)
|
||||
{
|
||||
return static_cast<AbstractFileType>(fios_type & FT_MASK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract the detailed file type from a #FiosType.
|
||||
* @param fios_type Type to query.
|
||||
* @return The Detailed file type of the \a fios_type.
|
||||
*/
|
||||
inline DetailedFileType GetDetailedFileType(FiosType fios_type)
|
||||
{
|
||||
return static_cast<DetailedFileType>(fios_type >> FT_NUMBITS);
|
||||
}
|
||||
|
||||
/**
|
||||
* The different kinds of subdirectories OpenTTD uses
|
||||
*/
|
||||
|
152
src/fios.cpp
152
src/fios.cpp
@@ -29,17 +29,15 @@
|
||||
#include "safeguards.h"
|
||||
|
||||
/* Variables to display file lists */
|
||||
SmallVector<FiosItem, 32> _fios_items;
|
||||
static char *_fios_path;
|
||||
static const char *_fios_path_last;
|
||||
SmallFiosItem _file_to_saveload;
|
||||
SortingBits _savegame_sort_order = SORT_BY_DATE | SORT_DESCENDING;
|
||||
|
||||
/* OS-specific functions are taken from their respective files (win32/unix/os2 .c) */
|
||||
extern bool FiosIsRoot(const char *path);
|
||||
extern bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb);
|
||||
extern bool FiosIsHiddenFile(const struct dirent *ent);
|
||||
extern void FiosGetDrives();
|
||||
extern void FiosGetDrives(FileList &file_list);
|
||||
extern bool FiosGetDiskFreeSpace(const char *path, uint64 *tot);
|
||||
|
||||
/* get the name of an oldstyle savegame */
|
||||
@@ -65,11 +63,72 @@ int CDECL CompareFiosItems(const FiosItem *da, const FiosItem *db)
|
||||
return r;
|
||||
}
|
||||
|
||||
/** Free the list of savegames. */
|
||||
void FiosFreeSavegameList()
|
||||
FileList::~FileList()
|
||||
{
|
||||
_fios_items.Clear();
|
||||
_fios_items.Compact();
|
||||
this->Clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a file list with the given kind of files, for the stated purpose.
|
||||
* @param abstract_filetype Kind of files to collect.
|
||||
* @param fop Purpose of the collection, either #SLO_LOAD or #SLO_SAVE.
|
||||
*/
|
||||
void FileList::BuildFileList(AbstractFileType abstract_filetype, SaveLoadOperation fop)
|
||||
{
|
||||
this->Clear();
|
||||
|
||||
assert(fop == SLO_LOAD || SLO_SAVE);
|
||||
switch (abstract_filetype) {
|
||||
case FT_NONE:
|
||||
break;
|
||||
|
||||
case FT_SAVEGAME:
|
||||
FiosGetSavegameList(fop, *this);
|
||||
break;
|
||||
|
||||
case FT_SCENARIO:
|
||||
FiosGetScenarioList(fop, *this);
|
||||
break;
|
||||
|
||||
case FT_HEIGHTMAP:
|
||||
FiosGetHeightmapList(fop, *this);
|
||||
break;
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Find file information of a file by its name from the file list.
|
||||
* @param file The filename to return information about. Can be the actual name
|
||||
* or a numbered entry into the filename list.
|
||||
* @return The information on the file, or \c NULL if the file is not available.
|
||||
*/
|
||||
const FiosItem *FileList::FindItem(const char *file)
|
||||
{
|
||||
for (const FiosItem *item = this->Begin(); item != this->End(); item++) {
|
||||
if (strcmp(file, item->name) == 0) return item;
|
||||
if (strcmp(file, item->title) == 0) return item;
|
||||
}
|
||||
|
||||
/* If no name matches, try to parse it as number */
|
||||
char *endptr;
|
||||
int i = strtol(file, &endptr, 10);
|
||||
if (file == endptr || *endptr != '\0') i = -1;
|
||||
|
||||
if (IsInsideMM(i, 0, this->Length())) return this->Get(i);
|
||||
|
||||
/* As a last effort assume it is an OpenTTD savegame and
|
||||
* that the ".sav" part was not given. */
|
||||
char long_file[MAX_PATH];
|
||||
seprintf(long_file, lastof(long_file), "%s.sav", file);
|
||||
for (const FiosItem *item = this->Begin(); item != this->End(); item++) {
|
||||
if (strcmp(long_file, item->name) == 0) return item;
|
||||
if (strcmp(long_file, item->title) == 0) return item;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -215,23 +274,24 @@ bool FiosDelete(const char *name)
|
||||
return unlink(filename) == 0;
|
||||
}
|
||||
|
||||
typedef FiosType fios_getlist_callback_proc(SaveLoadDialogMode mode, const char *filename, const char *ext, char *title, const char *last);
|
||||
typedef FiosType fios_getlist_callback_proc(SaveLoadOperation fop, const char *filename, const char *ext, char *title, const char *last);
|
||||
|
||||
/**
|
||||
* Scanner to scan for a particular type of FIOS file.
|
||||
*/
|
||||
class FiosFileScanner : public FileScanner {
|
||||
SaveLoadDialogMode mode; ///< The mode we want to search for
|
||||
SaveLoadOperation fop; ///< The kind of file we are looking for.
|
||||
fios_getlist_callback_proc *callback_proc; ///< Callback to check whether the file may be added
|
||||
FileList &file_list; ///< Destination of the found files.
|
||||
public:
|
||||
/**
|
||||
* Create the scanner
|
||||
* @param mode The mode we are in. Some modes don't allow 'parent'.
|
||||
* @param fop Purpose of collecting the list.
|
||||
* @param callback_proc The function that is called where you need to do the filtering.
|
||||
* @param file_list Destination of the found files.
|
||||
*/
|
||||
FiosFileScanner(SaveLoadDialogMode mode, fios_getlist_callback_proc *callback_proc) :
|
||||
mode(mode),
|
||||
callback_proc(callback_proc)
|
||||
FiosFileScanner(SaveLoadOperation fop, fios_getlist_callback_proc *callback_proc, FileList &file_list) :
|
||||
fop(fop), callback_proc(callback_proc), file_list(file_list)
|
||||
{}
|
||||
|
||||
/* virtual */ bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename);
|
||||
@@ -251,14 +311,14 @@ bool FiosFileScanner::AddFile(const char *filename, size_t basepath_length, cons
|
||||
char fios_title[64];
|
||||
fios_title[0] = '\0'; // reset the title;
|
||||
|
||||
FiosType type = this->callback_proc(this->mode, filename, ext, fios_title, lastof(fios_title));
|
||||
FiosType type = this->callback_proc(this->fop, filename, ext, fios_title, lastof(fios_title));
|
||||
if (type == FIOS_TYPE_INVALID) return false;
|
||||
|
||||
for (const FiosItem *fios = _fios_items.Begin(); fios != _fios_items.End(); fios++) {
|
||||
for (const FiosItem *fios = file_list.Begin(); fios != file_list.End(); fios++) {
|
||||
if (strcmp(fios->name, filename) == 0) return false;
|
||||
}
|
||||
|
||||
FiosItem *fios = _fios_items.Append();
|
||||
FiosItem *fios = file_list.Append();
|
||||
#ifdef WIN32
|
||||
struct _stat sb;
|
||||
if (_tstat(OTTD2FS(filename), &sb) == 0) {
|
||||
@@ -289,11 +349,12 @@ bool FiosFileScanner::AddFile(const char *filename, size_t basepath_length, cons
|
||||
|
||||
/**
|
||||
* Fill the list of the files in a directory, according to some arbitrary rule.
|
||||
* @param mode The mode we are in. Some modes don't allow 'parent'.
|
||||
* @param fop Purpose of collecting the list.
|
||||
* @param callback_proc The function that is called where you need to do the filtering.
|
||||
* @param subdir The directory from where to start (global) searching.
|
||||
* @param file_list Destination of the found files.
|
||||
*/
|
||||
static void FiosGetFileList(SaveLoadDialogMode mode, fios_getlist_callback_proc *callback_proc, Subdirectory subdir)
|
||||
static void FiosGetFileList(SaveLoadOperation fop, fios_getlist_callback_proc *callback_proc, Subdirectory subdir, FileList &file_list)
|
||||
{
|
||||
struct stat sb;
|
||||
struct dirent *dirent;
|
||||
@@ -302,11 +363,11 @@ static void FiosGetFileList(SaveLoadDialogMode mode, fios_getlist_callback_proc
|
||||
int sort_start;
|
||||
char d_name[sizeof(fios->name)];
|
||||
|
||||
_fios_items.Clear();
|
||||
file_list.Clear();
|
||||
|
||||
/* A parent directory link exists if we are not in the root directory */
|
||||
if (!FiosIsRoot(_fios_path)) {
|
||||
fios = _fios_items.Append();
|
||||
fios = file_list.Append();
|
||||
fios->type = FIOS_TYPE_PARENT;
|
||||
fios->mtime = 0;
|
||||
strecpy(fios->name, "..", lastof(fios->name));
|
||||
@@ -322,7 +383,7 @@ static void FiosGetFileList(SaveLoadDialogMode mode, fios_getlist_callback_proc
|
||||
if (FiosIsValidFile(_fios_path, dirent, &sb) && S_ISDIR(sb.st_mode) &&
|
||||
(!FiosIsHiddenFile(dirent) || strncasecmp(d_name, PERSONAL_DIR, strlen(d_name)) == 0) &&
|
||||
strcmp(d_name, ".") != 0 && strcmp(d_name, "..") != 0) {
|
||||
fios = _fios_items.Append();
|
||||
fios = file_list.Append();
|
||||
fios->type = FIOS_TYPE_DIR;
|
||||
fios->mtime = 0;
|
||||
strecpy(fios->name, d_name, lastof(fios->name));
|
||||
@@ -337,27 +398,27 @@ static void FiosGetFileList(SaveLoadDialogMode mode, fios_getlist_callback_proc
|
||||
{
|
||||
SortingBits order = _savegame_sort_order;
|
||||
_savegame_sort_order = SORT_BY_NAME | SORT_ASCENDING;
|
||||
QSortT(_fios_items.Begin(), _fios_items.Length(), CompareFiosItems);
|
||||
QSortT(file_list.files.Begin(), file_list.files.Length(), CompareFiosItems);
|
||||
_savegame_sort_order = order;
|
||||
}
|
||||
|
||||
/* This is where to start sorting for the filenames */
|
||||
sort_start = _fios_items.Length();
|
||||
sort_start = file_list.Length();
|
||||
|
||||
/* Show files */
|
||||
FiosFileScanner scanner(mode, callback_proc);
|
||||
FiosFileScanner scanner(fop, callback_proc, file_list);
|
||||
if (subdir == NO_DIRECTORY) {
|
||||
scanner.Scan(NULL, _fios_path, false);
|
||||
} else {
|
||||
scanner.Scan(NULL, subdir, true, true);
|
||||
}
|
||||
|
||||
QSortT(_fios_items.Get(sort_start), _fios_items.Length() - sort_start, CompareFiosItems);
|
||||
QSortT(file_list.Get(sort_start), file_list.Length() - sort_start, CompareFiosItems);
|
||||
|
||||
/* Show drives */
|
||||
FiosGetDrives();
|
||||
FiosGetDrives(file_list);
|
||||
|
||||
_fios_items.Compact();
|
||||
file_list.Compact();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -386,7 +447,7 @@ static void GetFileTitle(const char *file, char *title, const char *last, Subdir
|
||||
|
||||
/**
|
||||
* Callback for FiosGetFileList. It tells if a file is a savegame or not.
|
||||
* @param mode Save/load mode.
|
||||
* @param fop Purpose of collecting the list.
|
||||
* @param file Name of the file to check.
|
||||
* @param ext A pointer to the extension identifier inside file
|
||||
* @param title Buffer if a callback wants to lookup the title of the file; NULL to skip the lookup
|
||||
@@ -395,7 +456,7 @@ static void GetFileTitle(const char *file, char *title, const char *last, Subdir
|
||||
* @see FiosGetFileList
|
||||
* @see FiosGetSavegameList
|
||||
*/
|
||||
FiosType FiosGetSavegameListCallback(SaveLoadDialogMode mode, const char *file, const char *ext, char *title, const char *last)
|
||||
FiosType FiosGetSavegameListCallback(SaveLoadOperation fop, const char *file, const char *ext, char *title, const char *last)
|
||||
{
|
||||
/* Show savegame files
|
||||
* .SAV OpenTTD saved game
|
||||
@@ -411,7 +472,7 @@ FiosType FiosGetSavegameListCallback(SaveLoadDialogMode mode, const char *file,
|
||||
return FIOS_TYPE_FILE;
|
||||
}
|
||||
|
||||
if (mode == SLD_LOAD_GAME || mode == SLD_LOAD_SCENARIO) {
|
||||
if (fop == SLO_LOAD) {
|
||||
if (strcasecmp(ext, ".ss1") == 0 || strcasecmp(ext, ".sv1") == 0 ||
|
||||
strcasecmp(ext, ".sv2") == 0) {
|
||||
if (title != NULL) GetOldSaveGameName(file, title, last);
|
||||
@@ -424,10 +485,11 @@ FiosType FiosGetSavegameListCallback(SaveLoadDialogMode mode, const char *file,
|
||||
|
||||
/**
|
||||
* Get a list of savegames.
|
||||
* @param mode Save/load mode.
|
||||
* @param fop Purpose of collecting the list.
|
||||
* @param file_list Destination of the found files.
|
||||
* @see FiosGetFileList
|
||||
*/
|
||||
void FiosGetSavegameList(SaveLoadDialogMode mode)
|
||||
void FiosGetSavegameList(SaveLoadOperation fop, FileList &file_list)
|
||||
{
|
||||
static char *fios_save_path = NULL;
|
||||
static char *fios_save_path_last = NULL;
|
||||
@@ -441,12 +503,12 @@ void FiosGetSavegameList(SaveLoadDialogMode mode)
|
||||
_fios_path = fios_save_path;
|
||||
_fios_path_last = fios_save_path_last;
|
||||
|
||||
FiosGetFileList(mode, &FiosGetSavegameListCallback, NO_DIRECTORY);
|
||||
FiosGetFileList(fop, &FiosGetSavegameListCallback, NO_DIRECTORY, file_list);
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for FiosGetFileList. It tells if a file is a scenario or not.
|
||||
* @param mode Save/load mode.
|
||||
* @param fop Purpose of collecting the list.
|
||||
* @param file Name of the file to check.
|
||||
* @param ext A pointer to the extension identifier inside file
|
||||
* @param title Buffer if a callback wants to lookup the title of the file
|
||||
@@ -455,7 +517,7 @@ void FiosGetSavegameList(SaveLoadDialogMode mode)
|
||||
* @see FiosGetFileList
|
||||
* @see FiosGetScenarioList
|
||||
*/
|
||||
static FiosType FiosGetScenarioListCallback(SaveLoadDialogMode mode, const char *file, const char *ext, char *title, const char *last)
|
||||
static FiosType FiosGetScenarioListCallback(SaveLoadOperation fop, const char *file, const char *ext, char *title, const char *last)
|
||||
{
|
||||
/* Show scenario files
|
||||
* .SCN OpenTTD style scenario file
|
||||
@@ -466,7 +528,7 @@ static FiosType FiosGetScenarioListCallback(SaveLoadDialogMode mode, const char
|
||||
return FIOS_TYPE_SCENARIO;
|
||||
}
|
||||
|
||||
if (mode == SLD_LOAD_GAME || mode == SLD_LOAD_SCENARIO) {
|
||||
if (fop == SLO_LOAD) {
|
||||
if (strcasecmp(ext, ".sv0") == 0 || strcasecmp(ext, ".ss0") == 0 ) {
|
||||
GetOldSaveGameName(file, title, last);
|
||||
return FIOS_TYPE_OLD_SCENARIO;
|
||||
@@ -478,10 +540,11 @@ static FiosType FiosGetScenarioListCallback(SaveLoadDialogMode mode, const char
|
||||
|
||||
/**
|
||||
* Get a list of scenarios.
|
||||
* @param mode Save/load mode.
|
||||
* @param fop Purpose of collecting the list.
|
||||
* @param file_list Destination of the found files.
|
||||
* @see FiosGetFileList
|
||||
*/
|
||||
void FiosGetScenarioList(SaveLoadDialogMode mode)
|
||||
void FiosGetScenarioList(SaveLoadOperation fop, FileList &file_list)
|
||||
{
|
||||
static char *fios_scn_path = NULL;
|
||||
static char *fios_scn_path_last = NULL;
|
||||
@@ -499,10 +562,11 @@ void FiosGetScenarioList(SaveLoadDialogMode mode)
|
||||
char base_path[MAX_PATH];
|
||||
FioGetDirectory(base_path, lastof(base_path), SCENARIO_DIR);
|
||||
|
||||
FiosGetFileList(mode, &FiosGetScenarioListCallback, (mode == SLD_LOAD_SCENARIO && strcmp(base_path, _fios_path) == 0) ? SCENARIO_DIR : NO_DIRECTORY);
|
||||
Subdirectory subdir = (fop == SLO_LOAD && strcmp(base_path, _fios_path) == 0) ? SCENARIO_DIR : NO_DIRECTORY;
|
||||
FiosGetFileList(fop, &FiosGetScenarioListCallback, subdir, file_list);
|
||||
}
|
||||
|
||||
static FiosType FiosGetHeightmapListCallback(SaveLoadDialogMode mode, const char *file, const char *ext, char *title, const char *last)
|
||||
static FiosType FiosGetHeightmapListCallback(SaveLoadOperation fop, const char *file, const char *ext, char *title, const char *last)
|
||||
{
|
||||
/* Show heightmap files
|
||||
* .PNG PNG Based heightmap files
|
||||
@@ -548,9 +612,10 @@ static FiosType FiosGetHeightmapListCallback(SaveLoadDialogMode mode, const char
|
||||
|
||||
/**
|
||||
* Get a list of heightmaps.
|
||||
* @param mode Save/load mode.
|
||||
* @param fop Purpose of collecting the list.
|
||||
* @param file_list Destination of the found files.
|
||||
*/
|
||||
void FiosGetHeightmapList(SaveLoadDialogMode mode)
|
||||
void FiosGetHeightmapList(SaveLoadOperation fop, FileList &file_list)
|
||||
{
|
||||
static char *fios_hmap_path = NULL;
|
||||
static char *fios_hmap_path_last = NULL;
|
||||
@@ -567,7 +632,8 @@ void FiosGetHeightmapList(SaveLoadDialogMode mode)
|
||||
char base_path[MAX_PATH];
|
||||
FioGetDirectory(base_path, lastof(base_path), HEIGHTMAP_DIR);
|
||||
|
||||
FiosGetFileList(mode, &FiosGetHeightmapListCallback, strcmp(base_path, _fios_path) == 0 ? HEIGHTMAP_DIR : NO_DIRECTORY);
|
||||
Subdirectory subdir = strcmp(base_path, _fios_path) == 0 ? HEIGHTMAP_DIR : NO_DIRECTORY;
|
||||
FiosGetFileList(fop, &FiosGetHeightmapListCallback, subdir, file_list);
|
||||
}
|
||||
|
||||
/**
|
||||
|
146
src/fios.h
146
src/fios.h
@@ -99,38 +99,6 @@ enum FileSlots {
|
||||
MAX_FILE_SLOTS_IN_NETWORK = 63
|
||||
};
|
||||
|
||||
/** Mode of the file dialogue window. */
|
||||
enum SaveLoadDialogMode {
|
||||
SLD_LOAD_GAME, ///< Load a game.
|
||||
SLD_LOAD_SCENARIO, ///< Load a scenario.
|
||||
SLD_SAVE_GAME, ///< Save a game.
|
||||
SLD_SAVE_SCENARIO, ///< Save a scenario.
|
||||
SLD_LOAD_HEIGHTMAP, ///< Load a heightmap.
|
||||
SLD_SAVE_HEIGHTMAP, ///< Save a heightmap.
|
||||
};
|
||||
|
||||
/** The different types of files that the system knows about. */
|
||||
enum FileType {
|
||||
FT_NONE, ///< nothing to do
|
||||
FT_SAVEGAME, ///< old or new savegame
|
||||
FT_SCENARIO, ///< old or new scenario
|
||||
FT_HEIGHTMAP, ///< heightmap file
|
||||
};
|
||||
|
||||
enum FiosType {
|
||||
FIOS_TYPE_DRIVE,
|
||||
FIOS_TYPE_PARENT,
|
||||
FIOS_TYPE_DIR,
|
||||
FIOS_TYPE_FILE,
|
||||
FIOS_TYPE_OLDFILE,
|
||||
FIOS_TYPE_SCENARIO,
|
||||
FIOS_TYPE_OLD_SCENARIO,
|
||||
FIOS_TYPE_DIRECT,
|
||||
FIOS_TYPE_PNG,
|
||||
FIOS_TYPE_BMP,
|
||||
FIOS_TYPE_INVALID = 255,
|
||||
};
|
||||
|
||||
/** Deals with finding savegames */
|
||||
struct FiosItem {
|
||||
FiosType type;
|
||||
@@ -139,12 +107,95 @@ struct FiosItem {
|
||||
char name[MAX_PATH];
|
||||
};
|
||||
|
||||
/** Deals with the type of the savegame, independent of extension */
|
||||
struct SmallFiosItem {
|
||||
int mode; ///< savegame/scenario type (old, new)
|
||||
FileType filetype; ///< what type of file are we dealing with
|
||||
char name[MAX_PATH]; ///< name
|
||||
char title[255]; ///< internal name of the game
|
||||
/** List of file information. */
|
||||
class FileList {
|
||||
public:
|
||||
~FileList();
|
||||
|
||||
/**
|
||||
* Construct a new entry in the file list.
|
||||
* @return Pointer to the new items to be initialized.
|
||||
*/
|
||||
inline FiosItem *Append()
|
||||
{
|
||||
return this->files.Append();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the number of files in the list.
|
||||
* @return The number of files stored in the list.
|
||||
*/
|
||||
inline uint Length() const
|
||||
{
|
||||
return this->files.Length();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a pointer to the first file information.
|
||||
* @return Address of the first file information.
|
||||
*/
|
||||
inline const FiosItem *Begin() const
|
||||
{
|
||||
return this->files.Begin();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a pointer behind the last file information.
|
||||
* @return Address behind the last file information.
|
||||
*/
|
||||
inline const FiosItem *End() const
|
||||
{
|
||||
return this->files.End();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a pointer to the indicated file information. File information must exist.
|
||||
* @return Address of the indicated existing file information.
|
||||
*/
|
||||
inline const FiosItem *Get(uint index) const
|
||||
{
|
||||
return this->files.Get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a pointer to the indicated file information. File information must exist.
|
||||
* @return Address of the indicated existing file information.
|
||||
*/
|
||||
inline FiosItem *Get(uint index)
|
||||
{
|
||||
return this->files.Get(index);
|
||||
}
|
||||
|
||||
inline const FiosItem &operator[](uint index) const
|
||||
{
|
||||
return this->files[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a reference to the indicated file information. File information must exist.
|
||||
* @return The requested file information.
|
||||
*/
|
||||
inline FiosItem &operator[](uint index)
|
||||
{
|
||||
return this->files[index];
|
||||
}
|
||||
|
||||
/** Remove all items from the list. */
|
||||
inline void Clear()
|
||||
{
|
||||
this->files.Clear();
|
||||
}
|
||||
|
||||
/** Compact the list down to the smallest block size boundary. */
|
||||
inline void Compact()
|
||||
{
|
||||
this->files.Compact();
|
||||
}
|
||||
|
||||
void BuildFileList(AbstractFileType abstract_filetype, SaveLoadOperation fop);
|
||||
const FiosItem *FindItem(const char *file);
|
||||
|
||||
SmallVector<FiosItem, 32> files; ///< The list of files.
|
||||
};
|
||||
|
||||
enum SortingBits {
|
||||
@@ -156,18 +207,14 @@ enum SortingBits {
|
||||
DECLARE_ENUM_AS_BIT_SET(SortingBits)
|
||||
|
||||
/* Variables to display file lists */
|
||||
extern SmallVector<FiosItem, 32> _fios_items;
|
||||
extern SmallFiosItem _file_to_saveload;
|
||||
extern SaveLoadDialogMode _saveload_mode;
|
||||
extern SortingBits _savegame_sort_order;
|
||||
|
||||
void ShowSaveLoadDialog(SaveLoadDialogMode mode);
|
||||
void ShowSaveLoadDialog(AbstractFileType abstract_filetype, SaveLoadOperation fop);
|
||||
|
||||
void FiosGetSavegameList(SaveLoadDialogMode mode);
|
||||
void FiosGetScenarioList(SaveLoadDialogMode mode);
|
||||
void FiosGetHeightmapList(SaveLoadDialogMode mode);
|
||||
void FiosGetSavegameList(SaveLoadOperation fop, FileList &file_list);
|
||||
void FiosGetScenarioList(SaveLoadOperation fop, FileList &file_list);
|
||||
void FiosGetHeightmapList(SaveLoadOperation fop, FileList &file_list);
|
||||
|
||||
void FiosFreeSavegameList();
|
||||
const char *FiosBrowseTo(const FiosItem *item);
|
||||
|
||||
StringID FiosGetDescText(const char **path, uint64 *total_free);
|
||||
@@ -175,13 +222,8 @@ bool FiosDelete(const char *name);
|
||||
void FiosMakeHeightmapName(char *buf, const char *name, const char *last);
|
||||
void FiosMakeSavegameName(char *buf, const char *name, const char *last);
|
||||
|
||||
FiosType FiosGetSavegameListCallback(SaveLoadDialogMode mode, const char *file, const char *ext, char *title, const char *last);
|
||||
FiosType FiosGetSavegameListCallback(SaveLoadOperation fop, const char *file, const char *ext, char *title, const char *last);
|
||||
|
||||
int CDECL CompareFiosItems(const FiosItem *a, const FiosItem *b);
|
||||
|
||||
extern const TextColour _fios_colours[];
|
||||
|
||||
void BuildFileList();
|
||||
void SetFiosType(const byte fiostype);
|
||||
|
||||
#endif /* FIOS_H */
|
||||
|
299
src/fios_gui.cpp
299
src/fios_gui.cpp
@@ -36,7 +36,6 @@
|
||||
|
||||
#include "safeguards.h"
|
||||
|
||||
SaveLoadDialogMode _saveload_mode;
|
||||
LoadCheckData _load_check_data; ///< Data loaded from save during SL_LOAD_CHECK.
|
||||
|
||||
static bool _fios_path_changed;
|
||||
@@ -187,33 +186,24 @@ static const NWidgetPart _nested_save_dialog_widgets[] = {
|
||||
EndContainer(),
|
||||
};
|
||||
|
||||
/** Colours for fios types, indexed by #FiosType. */
|
||||
const TextColour _fios_colours[] = {
|
||||
TC_LIGHT_BLUE, TC_DARK_GREEN, TC_DARK_GREEN, TC_ORANGE, TC_LIGHT_BROWN,
|
||||
TC_ORANGE, TC_LIGHT_BROWN, TC_ORANGE, TC_ORANGE, TC_YELLOW
|
||||
/** Text colours of #DetailedFileType fios entries in the window. */
|
||||
static const TextColour _fios_colours[] = {
|
||||
TC_LIGHT_BROWN, // DFT_OLD_GAME_FILE
|
||||
TC_ORANGE, // DFT_GAME_FILE
|
||||
TC_YELLOW, // DFT_HEIGHTMAP_BMP
|
||||
TC_ORANGE, // DFT_HEIGHTMAP_PNG
|
||||
TC_LIGHT_BLUE, // DFT_FIOS_DRIVE
|
||||
TC_DARK_GREEN, // DFT_FIOS_PARENT
|
||||
TC_DARK_GREEN, // DFT_FIOS_DIR
|
||||
TC_ORANGE, // DFT_FIOS_DIRECT
|
||||
};
|
||||
|
||||
void BuildFileList()
|
||||
{
|
||||
_fios_path_changed = true;
|
||||
FiosFreeSavegameList();
|
||||
|
||||
switch (_saveload_mode) {
|
||||
case SLD_LOAD_SCENARIO:
|
||||
case SLD_SAVE_SCENARIO:
|
||||
FiosGetScenarioList(_saveload_mode); break;
|
||||
case SLD_SAVE_HEIGHTMAP:
|
||||
case SLD_LOAD_HEIGHTMAP:
|
||||
FiosGetHeightmapList(_saveload_mode); break;
|
||||
|
||||
default: FiosGetSavegameList(_saveload_mode); break;
|
||||
}
|
||||
|
||||
/* Invalidate saveload window */
|
||||
InvalidateWindowData(WC_SAVELOAD, 0, 2, true);
|
||||
}
|
||||
|
||||
static void MakeSortedSaveGameList()
|
||||
/**
|
||||
* Sort the collected list save games prior to displaying it in the save/load gui.
|
||||
* @param [inout] file_list List of save game files found in the directory.
|
||||
*/
|
||||
static void SortSaveGameList(FileList &file_list)
|
||||
{
|
||||
uint sort_start = 0;
|
||||
uint sort_end = 0;
|
||||
@@ -222,7 +212,7 @@ static void MakeSortedSaveGameList()
|
||||
* Drives (A:\ (windows only) are always under the files (FIOS_TYPE_DRIVE)
|
||||
* Only sort savegames/scenarios, not directories
|
||||
*/
|
||||
for (const FiosItem *item = _fios_items.Begin(); item != _fios_items.End(); item++) {
|
||||
for (const FiosItem *item = file_list.Begin(); item != file_list.End(); item++) {
|
||||
switch (item->type) {
|
||||
case FIOS_TYPE_DIR: sort_start++; break;
|
||||
case FIOS_TYPE_PARENT: sort_start++; break;
|
||||
@@ -231,15 +221,18 @@ static void MakeSortedSaveGameList()
|
||||
}
|
||||
}
|
||||
|
||||
uint s_amount = _fios_items.Length() - sort_start - sort_end;
|
||||
QSortT(_fios_items.Get(sort_start), s_amount, CompareFiosItems);
|
||||
uint s_amount = file_list.Length() - sort_start - sort_end;
|
||||
QSortT(file_list.Get(sort_start), s_amount, CompareFiosItems);
|
||||
}
|
||||
|
||||
struct SaveLoadWindow : public Window {
|
||||
private:
|
||||
QueryString filename_editbox; ///< Filename editbox.
|
||||
AbstractFileType abstract_filetype; /// Type of file to select.
|
||||
SaveLoadOperation fop; ///< File operation to perform.
|
||||
FileList fios_items; ///< Save game list.
|
||||
FiosItem o_dir;
|
||||
const FiosItem *selected;
|
||||
const FiosItem *selected; ///< Selected game in #fios_items, or \c NULL.
|
||||
Scrollbar *vscroll;
|
||||
public:
|
||||
|
||||
@@ -250,35 +243,56 @@ public:
|
||||
this->filename_editbox.text.UpdateSize();
|
||||
}
|
||||
|
||||
SaveLoadWindow(WindowDesc *desc, SaveLoadDialogMode mode) : Window(desc), filename_editbox(64)
|
||||
SaveLoadWindow(WindowDesc *desc, AbstractFileType abstract_filetype, SaveLoadOperation fop)
|
||||
: Window(desc), filename_editbox(64), abstract_filetype(abstract_filetype), fop(fop)
|
||||
{
|
||||
static const StringID saveload_captions[] = {
|
||||
STR_SAVELOAD_LOAD_CAPTION,
|
||||
STR_SAVELOAD_LOAD_SCENARIO,
|
||||
STR_SAVELOAD_SAVE_CAPTION,
|
||||
STR_SAVELOAD_SAVE_SCENARIO,
|
||||
STR_SAVELOAD_LOAD_HEIGHTMAP,
|
||||
STR_SAVELOAD_SAVE_HEIGHTMAP,
|
||||
};
|
||||
assert((uint)mode < lengthof(saveload_captions));
|
||||
assert(this->fop == SLO_SAVE || this->fop == SLO_LOAD);
|
||||
|
||||
/* Use an array to define what will be the current file type being handled
|
||||
* by current file mode */
|
||||
switch (mode) {
|
||||
case SLD_SAVE_GAME: this->GenerateFileName(); break;
|
||||
case SLD_SAVE_HEIGHTMAP:
|
||||
case SLD_SAVE_SCENARIO: this->filename_editbox.text.Assign("UNNAMED"); break;
|
||||
default: break;
|
||||
/* For saving, construct an initial file name. */
|
||||
if (this->fop == SLO_SAVE) {
|
||||
switch (this->abstract_filetype) {
|
||||
case FT_SAVEGAME:
|
||||
this->GenerateFileName();
|
||||
break;
|
||||
|
||||
case FT_SCENARIO:
|
||||
case FT_HEIGHTMAP:
|
||||
this->filename_editbox.text.Assign("UNNAMED");
|
||||
break;
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
}
|
||||
|
||||
this->querystrings[WID_SL_SAVE_OSK_TITLE] = &this->filename_editbox;
|
||||
this->filename_editbox.ok_button = WID_SL_SAVE_GAME;
|
||||
|
||||
this->CreateNestedTree(true);
|
||||
if (mode == SLD_LOAD_GAME) this->GetWidget<NWidgetStacked>(WID_SL_CONTENT_DOWNLOAD_SEL)->SetDisplayedPlane(SZSP_HORIZONTAL);
|
||||
this->GetWidget<NWidgetCore>(WID_SL_CAPTION)->widget_data = saveload_captions[mode];
|
||||
this->vscroll = this->GetScrollbar(WID_SL_SCROLLBAR);
|
||||
if (this->fop == SLO_LOAD && this->abstract_filetype == FT_SAVEGAME) {
|
||||
this->GetWidget<NWidgetStacked>(WID_SL_CONTENT_DOWNLOAD_SEL)->SetDisplayedPlane(SZSP_HORIZONTAL);
|
||||
}
|
||||
|
||||
/* Select caption string of the window. */
|
||||
StringID caption_string;
|
||||
switch (this->abstract_filetype) {
|
||||
case FT_SAVEGAME:
|
||||
caption_string = (this->fop == SLO_SAVE) ? STR_SAVELOAD_SAVE_CAPTION : STR_SAVELOAD_LOAD_CAPTION;
|
||||
break;
|
||||
|
||||
case FT_SCENARIO:
|
||||
caption_string = (this->fop == SLO_SAVE) ? STR_SAVELOAD_SAVE_SCENARIO : STR_SAVELOAD_LOAD_SCENARIO;
|
||||
break;
|
||||
|
||||
case FT_HEIGHTMAP:
|
||||
caption_string = (this->fop == SLO_SAVE) ? STR_SAVELOAD_SAVE_HEIGHTMAP : STR_SAVELOAD_LOAD_HEIGHTMAP;
|
||||
break;
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
this->GetWidget<NWidgetCore>(WID_SL_CAPTION)->widget_data = caption_string;
|
||||
|
||||
this->vscroll = this->GetScrollbar(WID_SL_SCROLLBAR);
|
||||
this->FinishInitNested(0);
|
||||
|
||||
this->LowerWidget(WID_SL_DRIVES_DIRECTORIES_LIST);
|
||||
@@ -294,20 +308,18 @@ public:
|
||||
|
||||
ResetObjectToPlace();
|
||||
|
||||
/* Select the initial directory. */
|
||||
o_dir.type = FIOS_TYPE_DIRECT;
|
||||
switch (_saveload_mode) {
|
||||
case SLD_SAVE_GAME:
|
||||
case SLD_LOAD_GAME:
|
||||
switch (this->abstract_filetype) {
|
||||
case FT_SAVEGAME:
|
||||
FioGetDirectory(o_dir.name, lastof(o_dir.name), SAVE_DIR);
|
||||
break;
|
||||
|
||||
case SLD_SAVE_SCENARIO:
|
||||
case SLD_LOAD_SCENARIO:
|
||||
case FT_SCENARIO:
|
||||
FioGetDirectory(o_dir.name, lastof(o_dir.name), SCENARIO_DIR);
|
||||
break;
|
||||
|
||||
case SLD_SAVE_HEIGHTMAP:
|
||||
case SLD_LOAD_HEIGHTMAP:
|
||||
case FT_HEIGHTMAP:
|
||||
FioGetDirectory(o_dir.name, lastof(o_dir.name), HEIGHTMAP_DIR);
|
||||
break;
|
||||
|
||||
@@ -316,9 +328,7 @@ public:
|
||||
}
|
||||
|
||||
/* Focus the edit box by default in the save windows */
|
||||
if (_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO || _saveload_mode == SLD_SAVE_HEIGHTMAP) {
|
||||
this->SetFocusedWidget(WID_SL_SAVE_OSK_TITLE);
|
||||
}
|
||||
if (this->fop == SLO_SAVE) this->SetFocusedWidget(WID_SL_SAVE_OSK_TITLE);
|
||||
}
|
||||
|
||||
virtual ~SaveLoadWindow()
|
||||
@@ -327,7 +337,6 @@ public:
|
||||
if (!_networking && _game_mode != GM_EDITOR && _game_mode != GM_MENU) {
|
||||
DoCommandP(0, PM_PAUSED_SAVELOAD, 0, CMD_PAUSE);
|
||||
}
|
||||
FiosFreeSavegameList();
|
||||
}
|
||||
|
||||
virtual void DrawWidget(const Rect &r, int widget) const
|
||||
@@ -360,13 +369,13 @@ public:
|
||||
GfxFillRect(r.left + 1, r.top + 1, r.right, r.bottom, PC_BLACK);
|
||||
|
||||
uint y = r.top + WD_FRAMERECT_TOP;
|
||||
for (uint pos = this->vscroll->GetPosition(); pos < _fios_items.Length(); pos++) {
|
||||
const FiosItem *item = _fios_items.Get(pos);
|
||||
for (uint pos = this->vscroll->GetPosition(); pos < this->fios_items.Length(); pos++) {
|
||||
const FiosItem *item = this->fios_items.Get(pos);
|
||||
|
||||
if (item == this->selected) {
|
||||
GfxFillRect(r.left + 1, y, r.right, y + this->resize.step_height, PC_DARK_BLUE);
|
||||
}
|
||||
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, item->title, _fios_colours[item->type]);
|
||||
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, item->title, _fios_colours[GetDetailedFileType(item->type)]);
|
||||
y += this->resize.step_height;
|
||||
if (y >= this->vscroll->GetCapacity() * this->resize.step_height + r.top + WD_FRAMERECT_TOP) break;
|
||||
}
|
||||
@@ -421,7 +430,7 @@ public:
|
||||
if (y > y_max) break;
|
||||
|
||||
/* Hide current date for scenarios */
|
||||
if (_saveload_mode != SLD_LOAD_SCENARIO && _saveload_mode != SLD_SAVE_SCENARIO) {
|
||||
if (this->abstract_filetype != FT_SCENARIO) {
|
||||
/* Current date */
|
||||
SetDParam(0, _load_check_data.current_date);
|
||||
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_CURRENT_DATE);
|
||||
@@ -429,7 +438,7 @@ public:
|
||||
}
|
||||
|
||||
/* Hide the NewGRF stuff when saving. We also hide the button. */
|
||||
if (_saveload_mode == SLD_LOAD_GAME || _saveload_mode == SLD_LOAD_SCENARIO) {
|
||||
if (this->fop == SLO_LOAD && (this->abstract_filetype == FT_SAVEGAME || this->abstract_filetype == FT_SCENARIO)) {
|
||||
y += WD_PAR_VSEP_NORMAL;
|
||||
if (y > y_max) break;
|
||||
|
||||
@@ -442,7 +451,7 @@ public:
|
||||
if (y > y_max) break;
|
||||
|
||||
/* Hide the company stuff for scenarios */
|
||||
if (_saveload_mode != SLD_LOAD_SCENARIO && _saveload_mode != SLD_SAVE_SCENARIO) {
|
||||
if (this->abstract_filetype != FT_SCENARIO) {
|
||||
y += FONT_HEIGHT_NORMAL;
|
||||
if (y > y_max) break;
|
||||
|
||||
@@ -495,10 +504,10 @@ public:
|
||||
{
|
||||
if (_savegame_sort_dirty) {
|
||||
_savegame_sort_dirty = false;
|
||||
MakeSortedSaveGameList();
|
||||
SortSaveGameList(this->fios_items);
|
||||
}
|
||||
|
||||
this->vscroll->SetCount(_fios_items.Length());
|
||||
this->vscroll->SetCount(this->fios_items.Length());
|
||||
this->DrawWidgets();
|
||||
}
|
||||
|
||||
@@ -527,14 +536,14 @@ public:
|
||||
case WID_SL_LOAD_BUTTON:
|
||||
if (this->selected != NULL && !_load_check_data.HasErrors()) {
|
||||
const char *name = FiosBrowseTo(this->selected);
|
||||
SetFiosType(this->selected->type);
|
||||
_file_to_saveload.SetMode(this->selected->type);
|
||||
_file_to_saveload.SetName(name);
|
||||
_file_to_saveload.SetTitle(this->selected->title);
|
||||
|
||||
strecpy(_file_to_saveload.name, name, lastof(_file_to_saveload.name));
|
||||
strecpy(_file_to_saveload.title, this->selected->title, lastof(_file_to_saveload.title));
|
||||
|
||||
if (_saveload_mode == SLD_LOAD_HEIGHTMAP) {
|
||||
if (this->abstract_filetype == FT_HEIGHTMAP) {
|
||||
delete this;
|
||||
ShowHeightmapLoad();
|
||||
|
||||
} else if (!_load_check_data.HasNewGrfs() || _load_check_data.grf_compatibility != GLC_NOT_FOUND || _settings_client.gui.UserIsAllowedToChangeNewGRFs()) {
|
||||
_switch_mode = (_game_mode == GM_EDITOR) ? SM_LOAD_SCENARIO : SM_LOAD_GAME;
|
||||
ClearErrorMessages();
|
||||
@@ -563,7 +572,7 @@ public:
|
||||
int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SL_DRIVES_DIRECTORIES_LIST, WD_FRAMERECT_TOP);
|
||||
if (y == INT_MAX) return;
|
||||
|
||||
const FiosItem *file = _fios_items.Get(y);
|
||||
const FiosItem *file = this->fios_items.Get(y);
|
||||
|
||||
const char *name = FiosBrowseTo(file);
|
||||
if (name != NULL) {
|
||||
@@ -572,30 +581,34 @@ public:
|
||||
this->selected = file;
|
||||
_load_check_data.Clear();
|
||||
|
||||
if (file->type == FIOS_TYPE_FILE || file->type == FIOS_TYPE_SCENARIO) {
|
||||
SaveOrLoad(name, SL_LOAD_CHECK, NO_DIRECTORY, false);
|
||||
if (GetDetailedFileType(file->type) == DFT_GAME_FILE) {
|
||||
/* Other detailed file types cannot be checked before. */
|
||||
SaveOrLoad(name, SLO_CHECK, DFT_GAME_FILE, NO_DIRECTORY, false);
|
||||
}
|
||||
|
||||
this->InvalidateData(1);
|
||||
}
|
||||
if (_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO || _saveload_mode == SLD_SAVE_HEIGHTMAP) {
|
||||
if (this->fop == SLO_SAVE) {
|
||||
/* Copy clicked name to editbox */
|
||||
this->filename_editbox.text.Assign(file->title);
|
||||
this->SetWidgetDirty(WID_SL_SAVE_OSK_TITLE);
|
||||
}
|
||||
} else if (!_load_check_data.HasErrors()) {
|
||||
this->selected = file;
|
||||
if (_saveload_mode == SLD_LOAD_GAME || _saveload_mode == SLD_LOAD_SCENARIO) {
|
||||
if (this->fop == SLO_LOAD) {
|
||||
if (this->abstract_filetype == FT_SAVEGAME || this->abstract_filetype == FT_SCENARIO) {
|
||||
this->OnClick(pt, WID_SL_LOAD_BUTTON, 1);
|
||||
} else if (_saveload_mode == SLD_LOAD_HEIGHTMAP) {
|
||||
SetFiosType(file->type);
|
||||
strecpy(_file_to_saveload.name, name, lastof(_file_to_saveload.name));
|
||||
strecpy(_file_to_saveload.title, file->title, lastof(_file_to_saveload.title));
|
||||
} else {
|
||||
assert(this->abstract_filetype == FT_HEIGHTMAP);
|
||||
_file_to_saveload.SetMode(file->type);
|
||||
_file_to_saveload.SetName(name);
|
||||
_file_to_saveload.SetTitle(file->title);
|
||||
|
||||
delete this;
|
||||
ShowHeightmapLoad();
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Changed directory, need refresh. */
|
||||
this->InvalidateData();
|
||||
@@ -608,10 +621,11 @@ public:
|
||||
ShowErrorMessage(STR_NETWORK_ERROR_NOTAVAILABLE, INVALID_STRING_ID, WL_ERROR);
|
||||
} else {
|
||||
#if defined(ENABLE_NETWORK)
|
||||
switch (_saveload_mode) {
|
||||
assert(this->fop == SLO_LOAD);
|
||||
switch (this->abstract_filetype) {
|
||||
default: NOT_REACHED();
|
||||
case SLD_LOAD_SCENARIO: ShowNetworkContentListWindow(NULL, CONTENT_TYPE_SCENARIO); break;
|
||||
case SLD_LOAD_HEIGHTMAP: ShowNetworkContentListWindow(NULL, CONTENT_TYPE_HEIGHTMAP); break;
|
||||
case FT_SCENARIO: ShowNetworkContentListWindow(NULL, CONTENT_TYPE_SCENARIO); break;
|
||||
case FT_HEIGHTMAP: ShowNetworkContentListWindow(NULL, CONTENT_TYPE_HEIGHTMAP); break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -639,9 +653,8 @@ public:
|
||||
|
||||
virtual void OnTimeout()
|
||||
{
|
||||
/* This test protects against using widgets 11 and 12 which are only available
|
||||
* in those saveload modes. */
|
||||
if (!(_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO || _saveload_mode == SLD_SAVE_HEIGHTMAP)) return;
|
||||
/* Widgets WID_SL_DELETE_SELECTION and WID_SL_SAVE_GAME only exist when saving to a file. */
|
||||
if (this->fop != SLO_SAVE) return;
|
||||
|
||||
if (this->IsWidgetLowered(WID_SL_DELETE_SELECTION)) { // Delete button clicked
|
||||
if (!FiosDelete(this->filename_editbox.text.buf)) {
|
||||
@@ -649,10 +662,10 @@ public:
|
||||
} else {
|
||||
this->InvalidateData();
|
||||
/* Reset file name to current date on successful delete */
|
||||
if (_saveload_mode == SLD_SAVE_GAME) GenerateFileName();
|
||||
if (this->abstract_filetype == FT_SAVEGAME) GenerateFileName();
|
||||
}
|
||||
} else if (this->IsWidgetLowered(WID_SL_SAVE_GAME)) { // Save button clicked
|
||||
if (_saveload_mode == SLD_SAVE_GAME || _saveload_mode == SLD_SAVE_SCENARIO) {
|
||||
if (this->abstract_filetype == FT_SAVEGAME || this->abstract_filetype == FT_SCENARIO) {
|
||||
_switch_mode = SM_SAVE_GAME;
|
||||
FiosMakeSavegameName(_file_to_saveload.name, this->filename_editbox.text.buf, lastof(_file_to_saveload.name));
|
||||
} else {
|
||||
@@ -683,28 +696,40 @@ public:
|
||||
this->selected = NULL;
|
||||
_load_check_data.Clear();
|
||||
if (!gui_scope) break;
|
||||
BuildFileList();
|
||||
|
||||
_fios_path_changed = true;
|
||||
this->fios_items.BuildFileList(this->abstract_filetype, this->fop);
|
||||
this->vscroll->SetCount(this->fios_items.Length());
|
||||
this->selected = NULL;
|
||||
_load_check_data.Clear();
|
||||
/* FALL THROUGH */
|
||||
case 1:
|
||||
/* Selection changes */
|
||||
if (!gui_scope) break;
|
||||
if (_saveload_mode == SLD_LOAD_HEIGHTMAP) {
|
||||
|
||||
if (this->fop != SLO_LOAD) break;
|
||||
|
||||
switch (this->abstract_filetype) {
|
||||
case FT_HEIGHTMAP:
|
||||
this->SetWidgetDisabledState(WID_SL_LOAD_BUTTON, this->selected == NULL || _load_check_data.HasErrors());
|
||||
break;
|
||||
|
||||
case FT_SAVEGAME:
|
||||
case FT_SCENARIO: {
|
||||
bool disabled = this->selected == NULL || _load_check_data.HasErrors();
|
||||
if (!_settings_client.gui.UserIsAllowedToChangeNewGRFs()) {
|
||||
disabled |= _load_check_data.HasNewGrfs() && _load_check_data.grf_compatibility == GLC_NOT_FOUND;
|
||||
}
|
||||
if (_saveload_mode == SLD_LOAD_GAME || _saveload_mode == SLD_LOAD_SCENARIO) {
|
||||
this->SetWidgetDisabledState(WID_SL_LOAD_BUTTON,
|
||||
this->selected == NULL || _load_check_data.HasErrors() || !(!_load_check_data.HasNewGrfs() || _load_check_data.grf_compatibility != GLC_NOT_FOUND || _settings_client.gui.UserIsAllowedToChangeNewGRFs()));
|
||||
this->SetWidgetDisabledState(WID_SL_NEWGRF_INFO,
|
||||
!_load_check_data.HasNewGrfs());
|
||||
this->SetWidgetDisabledState(WID_SL_LOAD_BUTTON, disabled);
|
||||
this->SetWidgetDisabledState(WID_SL_NEWGRF_INFO, !_load_check_data.HasNewGrfs());
|
||||
this->SetWidgetDisabledState(WID_SL_MISSING_NEWGRFS,
|
||||
!_load_check_data.HasNewGrfs() || _load_check_data.grf_compatibility == GLC_ALL_GOOD);
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
/* _fios_items changed */
|
||||
this->vscroll->SetCount(_fios_items.Length());
|
||||
this->selected = NULL;
|
||||
_load_check_data.Clear();
|
||||
}
|
||||
|
||||
default:
|
||||
NOT_REACHED();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -734,70 +759,24 @@ static WindowDesc _save_dialog_desc(
|
||||
_nested_save_dialog_widgets, lengthof(_nested_save_dialog_widgets)
|
||||
);
|
||||
|
||||
/**
|
||||
* These values are used to convert the file/operations mode into a corresponding file type.
|
||||
* So each entry, as expressed by the related comment, is based on the enum
|
||||
*/
|
||||
static const FileType _file_modetotype[] = {
|
||||
FT_SAVEGAME, // used for SLD_LOAD_GAME
|
||||
FT_SCENARIO, // used for SLD_LOAD_SCENARIO
|
||||
FT_SAVEGAME, // used for SLD_SAVE_GAME
|
||||
FT_SCENARIO, // used for SLD_SAVE_SCENARIO
|
||||
FT_HEIGHTMAP, // used for SLD_LOAD_HEIGHTMAP
|
||||
FT_HEIGHTMAP, // used for SLD_SAVE_HEIGHTMAP
|
||||
};
|
||||
|
||||
/**
|
||||
* Launch save/load dialog in the given mode.
|
||||
* @param mode Save/load mode.
|
||||
* @param abstract_filetype Kind of file to handle.
|
||||
* @param fop File operation to perform (load or save).
|
||||
*/
|
||||
void ShowSaveLoadDialog(SaveLoadDialogMode mode)
|
||||
void ShowSaveLoadDialog(AbstractFileType abstract_filetype, SaveLoadOperation fop)
|
||||
{
|
||||
DeleteWindowById(WC_SAVELOAD, 0);
|
||||
|
||||
WindowDesc *sld;
|
||||
switch (mode) {
|
||||
case SLD_SAVE_GAME:
|
||||
case SLD_SAVE_SCENARIO:
|
||||
case SLD_SAVE_HEIGHTMAP:
|
||||
sld = &_save_dialog_desc; break;
|
||||
case SLD_LOAD_HEIGHTMAP:
|
||||
sld = &_load_heightmap_dialog_desc; break;
|
||||
default:
|
||||
sld = &_load_dialog_desc; break;
|
||||
if (fop == SLO_SAVE) {
|
||||
sld = &_save_dialog_desc;
|
||||
} else {
|
||||
/* Dialogue for loading a file. */
|
||||
sld = (abstract_filetype == FT_HEIGHTMAP) ? &_load_heightmap_dialog_desc : &_load_dialog_desc;
|
||||
}
|
||||
|
||||
_saveload_mode = mode;
|
||||
_file_to_saveload.filetype = _file_modetotype[mode];
|
||||
_file_to_saveload.abstract_ftype = abstract_filetype;
|
||||
|
||||
new SaveLoadWindow(sld, mode);
|
||||
}
|
||||
|
||||
void SetFiosType(const byte fiostype)
|
||||
{
|
||||
switch (fiostype) {
|
||||
case FIOS_TYPE_FILE:
|
||||
case FIOS_TYPE_SCENARIO:
|
||||
_file_to_saveload.mode = SL_LOAD;
|
||||
break;
|
||||
|
||||
case FIOS_TYPE_OLDFILE:
|
||||
case FIOS_TYPE_OLD_SCENARIO:
|
||||
_file_to_saveload.mode = SL_OLD_LOAD;
|
||||
break;
|
||||
|
||||
#ifdef WITH_PNG
|
||||
case FIOS_TYPE_PNG:
|
||||
_file_to_saveload.mode = SL_PNG;
|
||||
break;
|
||||
#endif /* WITH_PNG */
|
||||
|
||||
case FIOS_TYPE_BMP:
|
||||
_file_to_saveload.mode = SL_BMP;
|
||||
break;
|
||||
|
||||
default:
|
||||
_file_to_saveload.mode = SL_INVALID;
|
||||
break;
|
||||
}
|
||||
new SaveLoadWindow(sld, abstract_filetype, fop);
|
||||
}
|
||||
|
@@ -204,7 +204,7 @@ static void _GenerateWorld(void *)
|
||||
if (_debug_desync_level > 0) {
|
||||
char name[MAX_PATH];
|
||||
seprintf(name, lastof(name), "dmp_cmds_%08x_%08x.sav", _settings_game.game_creation.generation_seed, _date);
|
||||
SaveOrLoad(name, SL_SAVE, AUTOSAVE_DIR, false);
|
||||
SaveOrLoad(name, SLO_SAVE, DFT_GAME_FILE, AUTOSAVE_DIR, false);
|
||||
}
|
||||
} catch (...) {
|
||||
BasePersistentStorageArray::SwitchMode(PSM_LEAVE_GAMELOOP, true);
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include "town.h"
|
||||
#include "core/geometry_func.hpp"
|
||||
#include "core/random_func.hpp"
|
||||
#include "saveload/saveload.h"
|
||||
#include "progress.h"
|
||||
#include "error.h"
|
||||
|
||||
@@ -875,7 +876,7 @@ static void _ShowGenerateLandscape(GenerateLandscapeWindowMode mode)
|
||||
|
||||
if (mode == GLWM_HEIGHTMAP) {
|
||||
/* If the function returns negative, it means there was a problem loading the heightmap */
|
||||
if (!GetHeightmapDimensions(_file_to_saveload.name, &x, &y)) return;
|
||||
if (!GetHeightmapDimensions(_file_to_saveload.detail_ftype, _file_to_saveload.name, &x, &y)) return;
|
||||
}
|
||||
|
||||
WindowDesc *desc = (mode == GLWM_HEIGHTMAP) ? &_heightmap_load_desc : &_generate_landscape_desc;
|
||||
|
@@ -102,7 +102,7 @@ static void ReadHeightmapPNGImageData(byte *map, png_structp png_ptr, png_infop
|
||||
* If map == NULL only the size of the PNG is read, otherwise a map
|
||||
* with grayscale pixels is allocated and assigned to *map.
|
||||
*/
|
||||
static bool ReadHeightmapPNG(char *filename, uint *x, uint *y, byte **map)
|
||||
static bool ReadHeightmapPNG(const char *filename, uint *x, uint *y, byte **map)
|
||||
{
|
||||
FILE *fp;
|
||||
png_structp png_ptr = NULL;
|
||||
@@ -232,7 +232,7 @@ static void ReadHeightmapBMPImageData(byte *map, BmpInfo *info, BmpData *data)
|
||||
* If map == NULL only the size of the BMP is read, otherwise a map
|
||||
* with grayscale pixels is allocated and assigned to *map.
|
||||
*/
|
||||
static bool ReadHeightmapBMP(char *filename, uint *x, uint *y, byte **map)
|
||||
static bool ReadHeightmapBMP(const char *filename, uint *x, uint *y, byte **map)
|
||||
{
|
||||
FILE *f;
|
||||
BmpInfo info;
|
||||
@@ -444,45 +444,56 @@ void FixSlopes()
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the heightmap with the correct file reader
|
||||
* Reads the heightmap with the correct file reader.
|
||||
* @param dft Type of image file.
|
||||
* @param filename Name of the file to load.
|
||||
* @param [out] x Length of the image.
|
||||
* @param [out] y Height of the image.
|
||||
* @param [inout] map If not \c NULL, destination to store the loaded block of image data.
|
||||
* @return Whether loading was successful.
|
||||
*/
|
||||
static bool ReadHeightMap(char *filename, uint *x, uint *y, byte **map)
|
||||
static bool ReadHeightMap(DetailedFileType dft, const char *filename, uint *x, uint *y, byte **map)
|
||||
{
|
||||
switch (_file_to_saveload.mode) {
|
||||
default: NOT_REACHED();
|
||||
switch (dft) {
|
||||
default:
|
||||
NOT_REACHED();
|
||||
|
||||
#ifdef WITH_PNG
|
||||
case SL_PNG:
|
||||
case DFT_HEIGHTMAP_PNG:
|
||||
return ReadHeightmapPNG(filename, x, y, map);
|
||||
#endif /* WITH_PNG */
|
||||
case SL_BMP:
|
||||
|
||||
case DFT_HEIGHTMAP_BMP:
|
||||
return ReadHeightmapBMP(filename, x, y, map);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the dimensions of a heightmap.
|
||||
* @param dft Type of image file.
|
||||
* @param filename to query
|
||||
* @param x dimension x
|
||||
* @param y dimension y
|
||||
* @return Returns false if loading of the image failed.
|
||||
*/
|
||||
bool GetHeightmapDimensions(char *filename, uint *x, uint *y)
|
||||
bool GetHeightmapDimensions(DetailedFileType dft, const char *filename, uint *x, uint *y)
|
||||
{
|
||||
return ReadHeightMap(filename, x, y, NULL);
|
||||
return ReadHeightMap(dft, filename, x, y, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Load a heightmap from file and change the map in his current dimensions
|
||||
* to a landscape representing the heightmap.
|
||||
* It converts pixels to height. The brighter, the higher.
|
||||
* @param dft Type of image file.
|
||||
* @param filename of the heightmap file to be imported
|
||||
*/
|
||||
void LoadHeightmap(char *filename)
|
||||
void LoadHeightmap(DetailedFileType dft, const char *filename)
|
||||
{
|
||||
uint x, y;
|
||||
byte *map = NULL;
|
||||
|
||||
if (!ReadHeightMap(filename, &x, &y, &map)) {
|
||||
if (!ReadHeightMap(dft, filename, &x, &y, &map)) {
|
||||
free(map);
|
||||
return;
|
||||
}
|
||||
|
@@ -12,6 +12,8 @@
|
||||
#ifndef HEIGHTMAP_H
|
||||
#define HEIGHTMAP_H
|
||||
|
||||
#include "fileio_type.h"
|
||||
|
||||
/**
|
||||
* Order of these enums has to be the same as in lang/english.txt
|
||||
* Otherwise you will get inconsistent behaviour.
|
||||
@@ -21,8 +23,8 @@ enum HeightmapRotation {
|
||||
HM_CLOCKWISE, ///< Rotate the map clockwise 45 degrees
|
||||
};
|
||||
|
||||
bool GetHeightmapDimensions(char *filename, uint *x, uint *y);
|
||||
void LoadHeightmap(char *filename);
|
||||
bool GetHeightmapDimensions(DetailedFileType dft, const char *filename, uint *x, uint *y);
|
||||
void LoadHeightmap(DetailedFileType dft, const char *filename);
|
||||
void FlatEmptyWorld(byte tile_height);
|
||||
void FixSlopes();
|
||||
|
||||
|
@@ -111,9 +111,9 @@ struct SelectGameWindow : public Window {
|
||||
}
|
||||
break;
|
||||
|
||||
case WID_SGI_LOAD_GAME: ShowSaveLoadDialog(SLD_LOAD_GAME); break;
|
||||
case WID_SGI_PLAY_SCENARIO: ShowSaveLoadDialog(SLD_LOAD_SCENARIO); break;
|
||||
case WID_SGI_PLAY_HEIGHTMAP: ShowSaveLoadDialog(SLD_LOAD_HEIGHTMAP); break;
|
||||
case WID_SGI_LOAD_GAME: ShowSaveLoadDialog(FT_SAVEGAME, SLO_LOAD); break;
|
||||
case WID_SGI_PLAY_SCENARIO: ShowSaveLoadDialog(FT_SCENARIO, SLO_LOAD); break;
|
||||
case WID_SGI_PLAY_HEIGHTMAP: ShowSaveLoadDialog(FT_HEIGHTMAP,SLO_LOAD); break;
|
||||
case WID_SGI_EDIT_SCENARIO: StartScenarioEditor(); break;
|
||||
|
||||
case WID_SGI_PLAY_NETWORK:
|
||||
|
@@ -31,6 +31,7 @@
|
||||
#include "object_base.h"
|
||||
#include "company_func.h"
|
||||
#include "pathfinder/npf/aystar.h"
|
||||
#include "saveload/saveload.h"
|
||||
#include <list>
|
||||
#include <set>
|
||||
|
||||
@@ -1222,7 +1223,7 @@ void GenerateLandscape(byte mode)
|
||||
|
||||
if (mode == GWM_HEIGHTMAP) {
|
||||
SetGeneratingWorldProgress(GWP_LANDSCAPE, steps + GLS_HEIGHTMAP);
|
||||
LoadHeightmap(_file_to_saveload.name);
|
||||
LoadHeightmap(_file_to_saveload.detail_ftype, _file_to_saveload.name);
|
||||
IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
|
||||
} else if (_settings_game.game_creation.land_generator == LG_TERRAGENESIS) {
|
||||
SetGeneratingWorldProgress(GWP_LANDSCAPE, steps + GLS_TERRAGENESIS);
|
||||
|
@@ -525,7 +525,7 @@ bool ClientNetworkGameSocketHandler::IsConnected()
|
||||
* DEF_CLIENT_RECEIVE_COMMAND has parameter: Packet *p
|
||||
************/
|
||||
|
||||
extern bool SafeLoad(const char *filename, int mode, GameMode newgm, Subdirectory subdir, struct LoadFilter *lf = NULL);
|
||||
extern bool SafeLoad(const char *filename, SaveLoadOperation fop, DetailedFileType dft, GameMode newgm, Subdirectory subdir, struct LoadFilter *lf = NULL);
|
||||
|
||||
NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_FULL(Packet *p)
|
||||
{
|
||||
@@ -841,7 +841,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_DONE(Packet
|
||||
|
||||
/* The map is done downloading, load it */
|
||||
ClearErrorMessages();
|
||||
bool load_success = SafeLoad(NULL, SL_LOAD, GM_NORMAL, NO_DIRECTORY, lf);
|
||||
bool load_success = SafeLoad(NULL, SLO_LOAD, DFT_GAME_FILE, GM_NORMAL, NO_DIRECTORY, lf);
|
||||
|
||||
/* Long savegame loads shouldn't affect the lag calculation! */
|
||||
this->last_packet = _realtime_tick;
|
||||
|
@@ -1193,17 +1193,17 @@ struct NetworkStartServerWindow : public Window {
|
||||
|
||||
case WID_NSS_LOAD_GAME:
|
||||
_is_network_server = true;
|
||||
ShowSaveLoadDialog(SLD_LOAD_GAME);
|
||||
ShowSaveLoadDialog(FT_SAVEGAME, SLO_LOAD);
|
||||
break;
|
||||
|
||||
case WID_NSS_PLAY_SCENARIO:
|
||||
_is_network_server = true;
|
||||
ShowSaveLoadDialog(SLD_LOAD_SCENARIO);
|
||||
ShowSaveLoadDialog(FT_SCENARIO, SLO_LOAD);
|
||||
break;
|
||||
|
||||
case WID_NSS_PLAY_HEIGHTMAP:
|
||||
_is_network_server = true;
|
||||
ShowSaveLoadDialog(SLD_LOAD_HEIGHTMAP);
|
||||
ShowSaveLoadDialog(FT_HEIGHTMAP,SLO_LOAD);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@@ -359,7 +359,7 @@ static void LoadIntroGame(bool load_newgrfs = true)
|
||||
SetupColoursAndInitialWindow();
|
||||
|
||||
/* Load the default opening screen savegame */
|
||||
if (SaveOrLoad("opntitle.dat", SL_LOAD, BASESET_DIR) != SL_OK) {
|
||||
if (SaveOrLoad("opntitle.dat", SLO_LOAD, DFT_GAME_FILE, BASESET_DIR) != SL_OK) {
|
||||
GenerateWorld(GWM_EMPTY, 64, 64); // if failed loading, make empty world.
|
||||
WaitTillGeneratedWorld();
|
||||
SetLocalCompany(COMPANY_SPECTATOR);
|
||||
@@ -650,15 +650,16 @@ int openttd_main(int argc, char *argv[])
|
||||
case 'e': _switch_mode = (_switch_mode == SM_LOAD_GAME || _switch_mode == SM_LOAD_SCENARIO ? SM_LOAD_SCENARIO : SM_EDITOR); break;
|
||||
case 'g':
|
||||
if (mgo.opt != NULL) {
|
||||
strecpy(_file_to_saveload.name, mgo.opt, lastof(_file_to_saveload.name));
|
||||
_switch_mode = (_switch_mode == SM_EDITOR || _switch_mode == SM_LOAD_SCENARIO ? SM_LOAD_SCENARIO : SM_LOAD_GAME);
|
||||
_file_to_saveload.mode = SL_LOAD;
|
||||
_file_to_saveload.SetName(mgo.opt);
|
||||
bool is_scenario = _switch_mode == SM_EDITOR || _switch_mode == SM_LOAD_SCENARIO;
|
||||
_switch_mode = is_scenario ? SM_LOAD_SCENARIO : SM_LOAD_GAME;
|
||||
_file_to_saveload.SetMode(SLO_LOAD, is_scenario ? FT_SCENARIO : FT_SAVEGAME, DFT_GAME_FILE);
|
||||
|
||||
/* if the file doesn't exist or it is not a valid savegame, let the saveload code show an error */
|
||||
const char *t = strrchr(_file_to_saveload.name, '.');
|
||||
if (t != NULL) {
|
||||
FiosType ft = FiosGetSavegameListCallback(SLD_LOAD_GAME, _file_to_saveload.name, t, NULL, NULL);
|
||||
if (ft != FIOS_TYPE_INVALID) SetFiosType(ft);
|
||||
FiosType ft = FiosGetSavegameListCallback(SLO_LOAD, _file_to_saveload.name, t, NULL, NULL);
|
||||
if (ft != FIOS_TYPE_INVALID) _file_to_saveload.SetMode(ft);
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -679,10 +680,10 @@ int openttd_main(int argc, char *argv[])
|
||||
|
||||
char title[80];
|
||||
title[0] = '\0';
|
||||
FiosGetSavegameListCallback(SLD_LOAD_GAME, mgo.opt, strrchr(mgo.opt, '.'), title, lastof(title));
|
||||
FiosGetSavegameListCallback(SLO_LOAD, mgo.opt, strrchr(mgo.opt, '.'), title, lastof(title));
|
||||
|
||||
_load_check_data.Clear();
|
||||
SaveOrLoadResult res = SaveOrLoad(mgo.opt, SL_LOAD_CHECK, SAVE_DIR, false);
|
||||
SaveOrLoadResult res = SaveOrLoad(mgo.opt, SLO_CHECK, DFT_GAME_FILE, SAVE_DIR, false);
|
||||
if (res != SL_OK || _load_check_data.HasErrors()) {
|
||||
fprintf(stderr, "Failed to open savegame\n");
|
||||
if (_load_check_data.HasErrors()) {
|
||||
@@ -1056,14 +1057,15 @@ static void MakeNewEditorWorld()
|
||||
* @param subdir default directory to look for filename, set to 0 if not needed
|
||||
* @param lf Load filter to use, if NULL: use filename + subdir.
|
||||
*/
|
||||
bool SafeLoad(const char *filename, int mode, GameMode newgm, Subdirectory subdir, struct LoadFilter *lf = NULL)
|
||||
bool SafeLoad(const char *filename, SaveLoadOperation fop, DetailedFileType dft, GameMode newgm, Subdirectory subdir, struct LoadFilter *lf = NULL)
|
||||
{
|
||||
assert(mode == SL_LOAD || (lf == NULL && mode == SL_OLD_LOAD));
|
||||
assert(fop == SLO_LOAD);
|
||||
assert(dft == DFT_GAME_FILE || (lf == NULL && dft == DFT_OLD_GAME_FILE));
|
||||
GameMode ogm = _game_mode;
|
||||
|
||||
_game_mode = newgm;
|
||||
|
||||
switch (lf == NULL ? SaveOrLoad(filename, mode, subdir) : LoadWithFilter(lf)) {
|
||||
switch (lf == NULL ? SaveOrLoad(filename, fop, dft, subdir) : LoadWithFilter(lf)) {
|
||||
case SL_OK: return true;
|
||||
|
||||
case SL_REINIT:
|
||||
@@ -1152,11 +1154,11 @@ void SwitchToMode(SwitchMode new_mode)
|
||||
ResetGRFConfig(true);
|
||||
ResetWindowSystem();
|
||||
|
||||
if (!SafeLoad(_file_to_saveload.name, _file_to_saveload.mode, GM_NORMAL, NO_DIRECTORY)) {
|
||||
if (!SafeLoad(_file_to_saveload.name, _file_to_saveload.file_op, _file_to_saveload.detail_ftype, GM_NORMAL, NO_DIRECTORY)) {
|
||||
SetDParamStr(0, GetSaveLoadErrorString());
|
||||
ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_ERROR);
|
||||
} else {
|
||||
if (_saveload_mode == SLD_LOAD_SCENARIO) {
|
||||
if (_file_to_saveload.abstract_ftype == FT_SCENARIO) {
|
||||
/* Reset engine pool to simplify changing engine NewGRFs in scenario editor. */
|
||||
EngineOverrideManager::ResetToCurrentNewGRFConfig();
|
||||
}
|
||||
@@ -1197,7 +1199,7 @@ void SwitchToMode(SwitchMode new_mode)
|
||||
break;
|
||||
|
||||
case SM_LOAD_SCENARIO: { // Load scenario from scenario editor
|
||||
if (SafeLoad(_file_to_saveload.name, _file_to_saveload.mode, GM_EDITOR, NO_DIRECTORY)) {
|
||||
if (SafeLoad(_file_to_saveload.name, _file_to_saveload.file_op, _file_to_saveload.detail_ftype, GM_EDITOR, NO_DIRECTORY)) {
|
||||
SetLocalCompany(OWNER_NONE);
|
||||
_settings_newgame.game_creation.starting_year = _cur_year;
|
||||
/* Cancel the saveload pausing */
|
||||
@@ -1219,7 +1221,7 @@ void SwitchToMode(SwitchMode new_mode)
|
||||
|
||||
case SM_SAVE_GAME: // Save game.
|
||||
/* Make network saved games on pause compatible to singleplayer */
|
||||
if (SaveOrLoad(_file_to_saveload.name, SL_SAVE, NO_DIRECTORY) != SL_OK) {
|
||||
if (SaveOrLoad(_file_to_saveload.name, SLO_SAVE, DFT_GAME_FILE, NO_DIRECTORY) != SL_OK) {
|
||||
SetDParamStr(0, GetSaveLoadErrorString());
|
||||
ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_ERROR);
|
||||
} else {
|
||||
@@ -1514,7 +1516,7 @@ void StateGameLoop()
|
||||
/* Save the desync savegame if needed. */
|
||||
char name[MAX_PATH];
|
||||
seprintf(name, lastof(name), "dmp_cmds_%08x_%08x.sav", _settings_game.game_creation.generation_seed, _date);
|
||||
SaveOrLoad(name, SL_SAVE, AUTOSAVE_DIR, false);
|
||||
SaveOrLoad(name, SLO_SAVE, DFT_GAME_FILE, AUTOSAVE_DIR, false);
|
||||
}
|
||||
|
||||
CheckCaches(false);
|
||||
@@ -1578,7 +1580,7 @@ static void DoAutosave()
|
||||
}
|
||||
|
||||
DEBUG(sl, 2, "Autosaving to '%s'", buf);
|
||||
if (SaveOrLoad(buf, SL_SAVE, AUTOSAVE_DIR) != SL_OK) {
|
||||
if (SaveOrLoad(buf, SLO_SAVE, DFT_GAME_FILE, AUTOSAVE_DIR) != SL_OK) {
|
||||
ShowErrorMessage(STR_ERROR_AUTOSAVE_FAILED, INVALID_STRING_ID, WL_ERROR);
|
||||
}
|
||||
}
|
||||
|
@@ -45,7 +45,7 @@ bool FiosIsRoot(const char *file)
|
||||
return file[3] == '\0';
|
||||
}
|
||||
|
||||
void FiosGetDrives()
|
||||
void FiosGetDrives(FileList &file_list)
|
||||
{
|
||||
uint disk, disk2, save, total;
|
||||
|
||||
@@ -75,7 +75,7 @@ void FiosGetDrives()
|
||||
#endif
|
||||
|
||||
if (disk == disk2) {
|
||||
FiosItem *fios = _fios_items.Append();
|
||||
FiosItem *fios = file_list.Append();
|
||||
fios->type = FIOS_TYPE_DRIVE;
|
||||
fios->mtime = 0;
|
||||
#ifndef __INNOTEK_LIBC__
|
||||
|
@@ -16,6 +16,7 @@
|
||||
#include "../../core/random_func.hpp"
|
||||
#include "../../debug.h"
|
||||
#include "../../string_func.h"
|
||||
#include "../../fios.h"
|
||||
|
||||
|
||||
#include <dirent.h>
|
||||
@@ -77,7 +78,7 @@ bool FiosIsRoot(const char *path)
|
||||
#endif
|
||||
}
|
||||
|
||||
void FiosGetDrives()
|
||||
void FiosGetDrives(FileList &file_list)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
@@ -208,11 +208,11 @@ bool FiosIsRoot(const char *file)
|
||||
return file[3] == '\0'; // C:\...
|
||||
}
|
||||
|
||||
void FiosGetDrives()
|
||||
void FiosGetDrives(FileList &file_list)
|
||||
{
|
||||
#if defined(WINCE)
|
||||
/* WinCE only knows one drive: / */
|
||||
FiosItem *fios = _fios_items.Append();
|
||||
FiosItem *fios = file_list.Append();
|
||||
fios->type = FIOS_TYPE_DRIVE;
|
||||
fios->mtime = 0;
|
||||
seprintf(fios->name, lastof(fios->name), PATHSEP "");
|
||||
@@ -223,7 +223,7 @@ void FiosGetDrives()
|
||||
|
||||
GetLogicalDriveStrings(lengthof(drives), drives);
|
||||
for (s = drives; *s != '\0';) {
|
||||
FiosItem *fios = _fios_items.Append();
|
||||
FiosItem *fios = file_list.Append();
|
||||
fios->type = FIOS_TYPE_DRIVE;
|
||||
fios->mtime = 0;
|
||||
seprintf(fios->name, lastof(fios->name), "%c:", s[0] & 0xFF);
|
||||
|
@@ -250,7 +250,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;
|
||||
}
|
||||
}
|
||||
|
@@ -143,6 +143,7 @@ void SlXvSetCurrentState()
|
||||
*/
|
||||
void SlXvCheckSpecialSavegameVersions()
|
||||
{
|
||||
// Checks for special savegame versions go here
|
||||
extern uint16 _sl_version;
|
||||
|
||||
if (_sl_version == 2000) {
|
||||
|
@@ -273,6 +273,7 @@ extern const uint16 SAVEGAME_VERSION = 195; ///< Current savegame version of Ope
|
||||
const uint16 SAVEGAME_VERSION_EXT = 0x8000; ///< Savegame extension indicator mask
|
||||
|
||||
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
|
||||
@@ -2866,10 +2867,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;
|
||||
@@ -2878,7 +2879,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
|
||||
@@ -2901,25 +2902,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; %02X; %s", _date, _date_fract, _tick_skip_counter, filename);
|
||||
if (_network_server || !_settings_client.gui.threaded_saves) threaded = false;
|
||||
|
||||
@@ -2927,24 +2938,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);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2982,6 +2994,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.
|
||||
|
@@ -25,15 +25,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. */
|
||||
@@ -46,10 +49,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;
|
||||
}
|
||||
}
|
||||
|
53
src/scope.h
Normal file
53
src/scope.h
Normal file
@@ -0,0 +1,53 @@
|
||||
/* $Id$ */
|
||||
|
||||
/*
|
||||
* This file is part of OpenTTD.
|
||||
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/** @file scope.h Simple scope guard... */
|
||||
|
||||
#ifndef SCOPE_H
|
||||
#define SCOPE_H
|
||||
|
||||
template <typename T>
|
||||
class scope_exit_obj {
|
||||
T f;
|
||||
bool shouldexec;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
scope_exit_obj(T &&func)
|
||||
: f(std::move(func)), shouldexec(true) { }
|
||||
|
||||
scope_exit_obj(const scope_exit_obj ©src) = delete;
|
||||
scope_exit_obj(scope_exit_obj &&movesrc)
|
||||
: f(std::move(movesrc.f)), shouldexec(movesrc.shouldexec) {
|
||||
movesrc.shouldexec = false;
|
||||
}
|
||||
|
||||
~scope_exit_obj() {
|
||||
exec();
|
||||
}
|
||||
|
||||
void exec() {
|
||||
if (shouldexec) {
|
||||
f();
|
||||
shouldexec = false;
|
||||
}
|
||||
}
|
||||
|
||||
void cancel() {
|
||||
shouldexec = false;
|
||||
}
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
scope_exit_obj<typename std::decay<T>::type> scope_guard(T &&func) {
|
||||
return scope_exit_obj<typename std::decay<T>::type>(std::forward<T>(func));
|
||||
}
|
||||
|
||||
#endif /* SCOPE_H */
|
@@ -2340,18 +2340,6 @@ static void SaveSettings(const SettingDesc *sd, void *object)
|
||||
/** Sorted list of PATX settings, generated by MakeSettingsPatxList */
|
||||
static std::vector<const SettingDesc *> _sorted_patx_settings;
|
||||
|
||||
/**
|
||||
* Internal structure used in LoadSettingsPatx()
|
||||
* placed outside for legacy compiler compatibility
|
||||
* this makes me miss lambdas :/
|
||||
*/
|
||||
struct StringSorter {
|
||||
bool operator()(const SettingDesc *a, const SettingDesc *b)
|
||||
{
|
||||
return strcmp(a->patx_name, b->patx_name) < 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Prepare a sorted list of settings to be potentially be loaded out of the PATX chunk
|
||||
* This is to enable efficient lookup of settings by name
|
||||
@@ -2370,28 +2358,11 @@ static void MakeSettingsPatxList(const SettingDesc *sd)
|
||||
_sorted_patx_settings.push_back(desc);
|
||||
}
|
||||
|
||||
std::sort(_sorted_patx_settings.begin(), _sorted_patx_settings.end(), StringSorter());
|
||||
std::sort(_sorted_patx_settings.begin(), _sorted_patx_settings.end(), [](const SettingDesc *a, const SettingDesc *b) {
|
||||
return strcmp(a->patx_name, b->patx_name) < 0;
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal structure used in LoadSettingsPatx()
|
||||
* placed outside for legacy compiler compatibility
|
||||
* this is effectively a reference capture lambda
|
||||
*/
|
||||
struct StringSearcher {
|
||||
bool &m_exact_match;
|
||||
|
||||
StringSearcher(bool &exact_match)
|
||||
: m_exact_match(exact_match) { }
|
||||
|
||||
bool operator()(const SettingDesc *a, const char *b)
|
||||
{
|
||||
int result = strcmp(a->patx_name, b);
|
||||
if (result == 0) m_exact_match = true;
|
||||
return result < 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Internal structure used in LoadSettingsPatx() and LoadSettingsPlyx()
|
||||
*/
|
||||
@@ -2447,9 +2418,13 @@ static void LoadSettingsPatx(const SettingDesc *sd, void *object)
|
||||
// flags are not in use yet, reserve for future expansion
|
||||
if (current_setting.flags != 0) SlErrorCorruptFmt("PATX chunk: unknown setting header flags: 0x%X", current_setting.flags);
|
||||
|
||||
// now try to find corresponding setting, this would be much easier with C++11 support...
|
||||
// now try to find corresponding setting
|
||||
bool exact_match = false;
|
||||
std::vector<const SettingDesc *>::iterator iter = std::lower_bound(_sorted_patx_settings.begin(), _sorted_patx_settings.end(), current_setting.name, StringSearcher(exact_match));
|
||||
auto iter = std::lower_bound(_sorted_patx_settings.begin(), _sorted_patx_settings.end(), current_setting.name, [&](const SettingDesc *a, const char *b) {
|
||||
int result = strcmp(a->patx_name, b);
|
||||
if (result == 0) exact_match = true;
|
||||
return result < 0;
|
||||
});
|
||||
|
||||
if (exact_match) {
|
||||
assert(iter != _sorted_patx_settings.end());
|
||||
@@ -2469,15 +2444,6 @@ static void LoadSettingsPatx(const SettingDesc *sd, void *object)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal structure used in SaveSettingsPatx()
|
||||
* placed outside for legacy compiler compatibility
|
||||
*/
|
||||
struct SettingToAdd {
|
||||
const SettingDesc *setting;
|
||||
uint32 setting_length;
|
||||
};
|
||||
|
||||
/**
|
||||
* Save handler for settings which go in the PATX chunk
|
||||
* @param sd SettingDesc struct containing all information
|
||||
@@ -2488,6 +2454,10 @@ static void SaveSettingsPatx(const SettingDesc *sd, void *object)
|
||||
{
|
||||
SettingsExtSave current_setting;
|
||||
|
||||
struct SettingToAdd {
|
||||
const SettingDesc *setting;
|
||||
uint32 setting_length;
|
||||
};
|
||||
std::vector<SettingToAdd> settings_to_add;
|
||||
|
||||
size_t length = 8;
|
||||
|
13
src/stdafx.h
13
src/stdafx.h
@@ -361,21 +361,8 @@ typedef unsigned char byte;
|
||||
#define PERSONAL_DIR ""
|
||||
#endif
|
||||
|
||||
/* Compile time assertions. Prefer c++0x static_assert().
|
||||
* Older compilers cannot evaluate some expressions at compile time,
|
||||
* typically when templates are involved, try assert_tcompile() in those cases. */
|
||||
#if defined(__STDCXX_VERSION__) || defined(__GXX_EXPERIMENTAL_CXX0X__) || defined(__GXX_EXPERIMENTAL_CPP0X__) || defined(static_assert)
|
||||
/* __STDCXX_VERSION__ is c++0x feature macro, __GXX_EXPERIMENTAL_CXX0X__ is used by gcc, __GXX_EXPERIMENTAL_CPP0X__ by icc */
|
||||
#define assert_compile(expr) static_assert(expr, #expr )
|
||||
#define assert_tcompile(expr) assert_compile(expr)
|
||||
#elif defined(__OS2__)
|
||||
/* Disabled for OS/2 */
|
||||
#define assert_compile(expr)
|
||||
#define assert_tcompile(expr) assert_compile(expr)
|
||||
#else
|
||||
#define assert_compile(expr) typedef int __ct_assert__[1 - 2 * !(expr)]
|
||||
#define assert_tcompile(expr) assert(expr)
|
||||
#endif
|
||||
|
||||
/* Check if the types have the bitsizes like we are using them */
|
||||
assert_compile(sizeof(uint64) == 8);
|
||||
|
@@ -17,7 +17,7 @@
|
||||
#define NIP_END() { NULL, 0, 0, 0, 0 }
|
||||
|
||||
/* Helper for filling callback tables */
|
||||
#define NIC(cb_id, base, variable, bit) { #cb_id, cpp_offsetof(base, variable), cpp_sizeof(base, variable), bit, cb_id }
|
||||
#define NIC(cb_id, base, variable, bit) { #cb_id, (ptrdiff_t)cpp_offsetof(base, variable), cpp_sizeof(base, variable), bit, cb_id }
|
||||
#define NIC_END() { NULL, 0, 0, 0, 0 }
|
||||
|
||||
/* Helper for filling variable tables */
|
||||
|
@@ -11,6 +11,10 @@
|
||||
|
||||
#include "../core/enum_type.hpp"
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#pragma GCC diagnostic ignored "-Wunused-variable"
|
||||
#endif
|
||||
|
||||
static const char * const _name_original_english_1[] = {
|
||||
"Great ",
|
||||
"Little ",
|
||||
|
@@ -437,17 +437,17 @@ static CallBackFunction MenuClickSaveLoad(int index = 0)
|
||||
{
|
||||
if (_game_mode == GM_EDITOR) {
|
||||
switch (index) {
|
||||
case SLEME_SAVE_SCENARIO: ShowSaveLoadDialog(SLD_SAVE_SCENARIO); break;
|
||||
case SLEME_LOAD_SCENARIO: ShowSaveLoadDialog(SLD_LOAD_SCENARIO); break;
|
||||
case SLEME_SAVE_HEIGHTMAP: ShowSaveLoadDialog(SLD_SAVE_HEIGHTMAP); break;
|
||||
case SLEME_LOAD_HEIGHTMAP: ShowSaveLoadDialog(SLD_LOAD_HEIGHTMAP); break;
|
||||
case SLEME_SAVE_SCENARIO: ShowSaveLoadDialog(FT_SCENARIO, SLO_SAVE); break;
|
||||
case SLEME_LOAD_SCENARIO: ShowSaveLoadDialog(FT_SCENARIO, SLO_LOAD); break;
|
||||
case SLEME_SAVE_HEIGHTMAP: ShowSaveLoadDialog(FT_HEIGHTMAP,SLO_SAVE); break;
|
||||
case SLEME_LOAD_HEIGHTMAP: ShowSaveLoadDialog(FT_HEIGHTMAP,SLO_LOAD); break;
|
||||
case SLEME_EXIT_TOINTRO: AskExitToGameMenu(); break;
|
||||
case SLEME_EXIT_GAME: HandleExitGameRequest(); break;
|
||||
}
|
||||
} else {
|
||||
switch (index) {
|
||||
case SLNME_SAVE_GAME: ShowSaveLoadDialog(SLD_SAVE_GAME); break;
|
||||
case SLNME_LOAD_GAME: ShowSaveLoadDialog(SLD_LOAD_GAME); break;
|
||||
case SLNME_SAVE_GAME: ShowSaveLoadDialog(FT_SAVEGAME, SLO_SAVE); break;
|
||||
case SLNME_LOAD_GAME: ShowSaveLoadDialog(FT_SAVEGAME, SLO_LOAD); break;
|
||||
case SLNME_EXIT_TOINTRO: AskExitToGameMenu(); break;
|
||||
case SLNME_EXIT_GAME: HandleExitGameRequest(); break;
|
||||
}
|
||||
@@ -1726,7 +1726,7 @@ struct MainToolbarWindow : Window {
|
||||
case MTHK_FASTFORWARD: ToolbarFastForwardClick(this); break;
|
||||
case MTHK_SETTINGS: ShowGameOptions(); break;
|
||||
case MTHK_SAVEGAME: MenuClickSaveLoad(); break;
|
||||
case MTHK_LOADGAME: ShowSaveLoadDialog(SLD_LOAD_GAME); break;
|
||||
case MTHK_LOADGAME: ShowSaveLoadDialog(FT_SAVEGAME, SLO_LOAD); break;
|
||||
case MTHK_SMALLMAP: ShowSmallMap(); break;
|
||||
case MTHK_TOWNDIRECTORY: ShowTownDirectory(); break;
|
||||
case MTHK_SUBSIDIES: ShowSubsidiesList(); break;
|
||||
|
@@ -142,7 +142,7 @@ static void *_dedicated_video_mem;
|
||||
/* Whether a fork has been done. */
|
||||
bool _dedicated_forks;
|
||||
|
||||
extern bool SafeLoad(const char *filename, int mode, GameMode newgm, Subdirectory subdir, struct LoadFilter *lf = NULL);
|
||||
extern bool SafeLoad(const char *filename, SaveLoadOperation fop, DetailedFileType dft, GameMode newgm, Subdirectory subdir, struct LoadFilter *lf = NULL);
|
||||
|
||||
static FVideoDriver_Dedicated iFVideoDriver_Dedicated;
|
||||
|
||||
@@ -286,7 +286,7 @@ void VideoDriver_Dedicated::MainLoop()
|
||||
_switch_mode = SM_NONE;
|
||||
/* First we need to test if the savegame can be loaded, else we will end up playing the
|
||||
* intro game... */
|
||||
if (!SafeLoad(_file_to_saveload.name, _file_to_saveload.mode, GM_NORMAL, BASE_DIR)) {
|
||||
if (!SafeLoad(_file_to_saveload.name, _file_to_saveload.file_op, _file_to_saveload.detail_ftype, GM_NORMAL, BASE_DIR)) {
|
||||
/* Loading failed, pop out.. */
|
||||
DEBUG(net, 0, "Loading requested map failed, aborting");
|
||||
_networking = false;
|
||||
|
Reference in New Issue
Block a user