Index: src/console_cmds.cpp =================================================================== --- src/console_cmds.cpp (revision 25725) +++ src/console_cmds.cpp (working copy) @@ -315,13 +315,16 @@ /** * Get savegame file informations. - * @param file The savegame filename to return information about. Can be the actual name + * @param file The filename to return information about. Can be the actual name * or a numbered entry into the filename list. + * @param mode The mode to use for building the filelist to find the item in. + * SLD_LOAD_GAME for save games, SLD_LOAD_SCENARIO for scenarios. + * SLD_LOAD_GAME_SCENARIO for both. * @return FiosItem The information on the file. */ -static const FiosItem *GetFiosItem(const char *file) +static const FiosItem *GetFiosItem(const char *file, SaveLoadDialogMode mode) { - _saveload_mode = SLD_LOAD_GAME; + _saveload_mode = mode; BuildFileList(); for (const FiosItem *item = _fios_items.Begin(); item != _fios_items.End(); item++) { @@ -336,19 +339,28 @@ if (IsInsideMM(i, 0, _fios_items.Length())) return _fios_items.Get(i); - /* As a last effort assume it is an OpenTTD savegame and + /* As a next-to-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); + char long_file_sav[MAX_PATH]; + seprintf(long_file_sav, lastof(long_file_sav), "%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; + if (strcmp(long_file_sav, item->name) == 0) return item; + if (strcmp(long_file_sav, item->title) == 0) return item; } + /* Finally assume it is an OpenTTD scenario and + * that the ".scn" part was not given. */ + char long_file_scn[MAX_PATH]; + seprintf(long_file_scn, lastof(long_file_scn), "%s.scn", file); + for (const FiosItem *item = _fios_items.Begin(); item != _fios_items.End(); item++) { + if (strcmp(long_file_scn, item->name) == 0) return item; + if (strcmp(long_file_scn, item->title) == 0) return item; + } + return NULL; } - +/* Load a saved game to play. */ DEF_CONSOLE_CMD(ConLoad) { if (argc == 0) { @@ -359,10 +371,10 @@ if (argc != 2) return false; const char *file = argv[1]; - const FiosItem *item = GetFiosItem(file); + const FiosItem *item = GetFiosItem(file, SLD_LOAD_GAME_SCENARIO); if (item != NULL) { switch (item->type) { - case FIOS_TYPE_FILE: case FIOS_TYPE_OLDFILE: { + case FIOS_TYPE_FILE: case FIOS_TYPE_OLDFILE: case FIOS_TYPE_SCENARIO: case FIOS_TYPE_OLD_SCENARIO: { _switch_mode = SM_LOAD_GAME; SetFiosType(item->type); @@ -370,7 +382,7 @@ strecpy(_file_to_saveload.title, item->title, lastof(_file_to_saveload.title)); break; } - default: IConsolePrintF(CC_ERROR, "%s: Not a savegame.", file); + default: IConsolePrintF(CC_ERROR, "%s: Not a savegame or scenario.", file); } } else { IConsolePrintF(CC_ERROR, "%s: No such file or directory.", file); @@ -380,11 +392,43 @@ return true; } +/* Load a scenario into the scenario editor to edit. */ +DEF_CONSOLE_CMD(ConEditScn) +{ + if (argc == 0) { + IConsoleHelp("Edit a scenario in the scenario editor by name or index. Usage: 'edit_scn '"); + return true; + } + if (argc != 2) return false; + + const char *file = argv[1]; + const FiosItem *item = GetFiosItem(file, SLD_LOAD_GAME_SCENARIO); + if (item != NULL) { + switch (item->type) { + case FIOS_TYPE_SCENARIO: case FIOS_TYPE_OLD_SCENARIO: { + _switch_mode = SM_LOAD_SCENARIO; + 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 scenario.", file); + } + } else { + IConsolePrintF(CC_ERROR, "%s: No such file or directory.", file); + } + + FiosFreeSavegameList(); + return true; +} + +/* Removed a scenario. */ DEF_CONSOLE_CMD(ConRemove) { if (argc == 0) { - IConsoleHelp("Remove a savegame by name or index. Usage: 'rm '"); + IConsoleHelp("Remove a savegame or scenario by name or index. Usage: 'rm '"); return true; } @@ -391,10 +435,16 @@ if (argc != 2) return false; const char *file = argv[1]; - const FiosItem *item = GetFiosItem(file); + const FiosItem *item = GetFiosItem(file, SLD_LOAD_GAME_SCENARIO); if (item != NULL) { - if (!FiosDelete(item->name)) { - IConsolePrintF(CC_ERROR, "%s: Failed to delete file", file); + switch (item->type) { + case FIOS_TYPE_FILE: case FIOS_TYPE_OLDFILE: case FIOS_TYPE_SCENARIO: case FIOS_TYPE_OLD_SCENARIO: { + if (!FiosDelete(item->name)) { + IConsolePrintF(CC_ERROR, "%s: Failed to delete file", file); + } + break; + } + default: IConsolePrintF(CC_ERROR, "%s: Not a savegame or scenario.", file); } } else { IConsolePrintF(CC_ERROR, "%s: No such file or directory.", file); @@ -404,8 +454,7 @@ return true; } - -/* List all the files in the current dir via console */ +/* List all the save game and scenario files in the current dir via console */ DEF_CONSOLE_CMD(ConListFiles) { if (argc == 0) { @@ -413,6 +462,7 @@ return true; } + _saveload_mode = SLD_LOAD_GAME_SCENARIO; BuildFileList(); for (uint i = 0; i < _fios_items.Length(); i++) { @@ -420,6 +470,7 @@ } FiosFreeSavegameList(); + return true; } @@ -434,7 +485,7 @@ if (argc != 2) return false; const char *file = argv[1]; - const FiosItem *item = GetFiosItem(file); + const FiosItem *item = GetFiosItem(file, SLD_LOAD_GAME); if (item != NULL) { switch (item->type) { case FIOS_TYPE_DIR: case FIOS_TYPE_DRIVE: case FIOS_TYPE_PARENT: @@ -1910,6 +1961,7 @@ IConsoleCmdRegister("scrollto", ConScrollToTile); IConsoleCmdRegister("alias", ConAlias); IConsoleCmdRegister("load", ConLoad); + IConsoleCmdRegister("edit_scn", ConEditScn); IConsoleCmdRegister("rm", ConRemove); IConsoleCmdRegister("save", ConSave); IConsoleCmdRegister("saveconfig", ConSaveConfig); Index: src/fios.cpp =================================================================== --- src/fios.cpp (revision 25725) +++ src/fios.cpp (working copy) @@ -344,10 +344,17 @@ /* Show files */ FiosFileScanner scanner(mode, callback_proc); - if (subdir == NO_DIRECTORY) { + + /* If we're looking for both saves and scenarios, we have two directories to search. */ + if(mode == SLD_LOAD_GAME_SCENARIO) { scanner.Scan(NULL, _fios_path, false); + scanner.Scan(NULL, subdir, true, true); } else { - scanner.Scan(NULL, subdir, true, true); + 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); @@ -490,6 +497,75 @@ FiosGetFileList(mode, &FiosGetScenarioListCallback, (mode == SLD_LOAD_SCENARIO && strcmp(base_path, _fios_path) == 0) ? SCENARIO_DIR : NO_DIRECTORY); } +/** + * Callback for FiosGetSaveScenarioFileList. It tells if a file is a scenario, save game or neither. + * @param mode Save/load mode. + * @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 + * @param last Last available byte in buffer (to prevent buffer overflows) + * @return a FIOS_TYPE_* type of the found file, FIOS_TYPE_INVALID if not a scenario + * @see FiosGetFileList + * @see FiosGetScenarioList + */ +static FiosType FiosGetSaveScenarioListCallback(SaveLoadDialogMode mode, const char *file, const char *ext, char *title, const char *last) +{ + /* Show scenario files + * .SCN OpenTTD style scenario file + * .SV0 Transport Tycoon Deluxe (Patch) scenario + * .SS0 Transport Tycoon Deluxe preset scenario */ + if (strcasecmp(ext, ".scn") == 0) { + GetFileTitle(file, title, last, SCENARIO_DIR); + return FIOS_TYPE_SCENARIO; + } + + if (mode == SLD_LOAD_GAME || mode == SLD_LOAD_SCENARIO || mode == SLD_LOAD_GAME_SCENARIO) { + if (strcasecmp(ext, ".sv0") == 0 || strcasecmp(ext, ".ss0") == 0 ) { + GetOldSaveGameName(file, title, last); + return FIOS_TYPE_OLD_SCENARIO; + } + } + + /* Show savegame files + * .SAV OpenTTD saved game + * .SS1 Transport Tycoon Deluxe preset game + * .SV1 Transport Tycoon Deluxe (Patch) saved game + * .SV2 Transport Tycoon Deluxe (Patch) saved 2-player game */ + if (strcasecmp(ext, ".sav") == 0) { + GetFileTitle(file, title, last, SAVE_DIR); + return FIOS_TYPE_FILE; + } + + if (mode == SLD_LOAD_GAME || mode == SLD_LOAD_SCENARIO || mode == SLD_LOAD_GAME_SCENARIO) { + if (strcasecmp(ext, ".ss1") == 0 || strcasecmp(ext, ".sv1") == 0 || + strcasecmp(ext, ".sv2") == 0) { + if (title != NULL) GetOldSaveGameName(file, title, last); + return FIOS_TYPE_OLDFILE; + } + } + + return FIOS_TYPE_INVALID; +} + +/** + * Get a list of save games and scenarios. + * @param mode Save/load mode. + * @see FiosGetFileList + */ +void FiosGetSaveScenarioList(SaveLoadDialogMode mode) +{ + static char *fios_save_path = NULL; + + if (fios_save_path == NULL) { + fios_save_path = MallocT(MAX_PATH); + FioGetDirectory(fios_save_path, MAX_PATH, SAVE_DIR); + } + + _fios_path = fios_save_path; + + FiosGetFileList(mode, &FiosGetSaveScenarioListCallback, SCENARIO_DIR); +} + static FiosType FiosGetHeightmapListCallback(SaveLoadDialogMode mode, const char *file, const char *ext, char *title, const char *last) { /* Show heightmap files Index: src/fios.h =================================================================== --- src/fios.h (revision 25725) +++ src/fios.h (working copy) @@ -104,6 +104,7 @@ SLD_SAVE_SCENARIO, ///< Save a scenario. SLD_LOAD_HEIGHTMAP, ///< Load a heightmap. SLD_SAVE_HEIGHTMAP, ///< Save a heightmap. + SLD_LOAD_GAME_SCENARIO, ///< Load a game or scenario. }; /** The different types of files that the system knows about. */ @@ -162,6 +163,7 @@ void FiosGetSavegameList(SaveLoadDialogMode mode); void FiosGetScenarioList(SaveLoadDialogMode mode); +void FiosGetSaveScenarioList(SaveLoadDialogMode mode); void FiosGetHeightmapList(SaveLoadDialogMode mode); void FiosFreeSavegameList(); Index: src/fios_gui.cpp =================================================================== --- src/fios_gui.cpp (revision 25725) +++ src/fios_gui.cpp (working copy) @@ -201,6 +201,8 @@ case SLD_SAVE_HEIGHTMAP: case SLD_LOAD_HEIGHTMAP: FiosGetHeightmapList(_saveload_mode); break; + case SLD_LOAD_GAME_SCENARIO: + FiosGetSaveScenarioList(_saveload_mode); break; default: FiosGetSavegameList(_saveload_mode); break; }