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,7 +339,7 @@ if (IsInsideMM(i, 0, _fios_items.Length())) return _fios_items.Get(i); - /* As a last effort assume it is an OpenTTD savegame and + /* Check if 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); @@ -345,10 +348,20 @@ if (strcmp(long_file, item->title) == 0) return item; } + memset(long_file, 0, sizeof long_file); + + /* Check if it is an OpenTTD scenario and + * that the ".scn" part was not given. */ + seprintf(long_file, lastof(long_file), "%s.scn", 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; } - +/* Load a saved game to play. */ DEF_CONSOLE_CMD(ConLoad) { if (argc == 0) { @@ -359,10 +372,13 @@ 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 +386,8 @@ 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 +397,45 @@ 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 +442,20 @@ 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 +465,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 +473,7 @@ return true; } + _saveload_mode = SLD_LOAD_GAME_SCENARIO; BuildFileList(); for (uint i = 0; i < _fios_items.Length(); i++) { @@ -420,6 +481,7 @@ } FiosFreeSavegameList(); + return true; } @@ -434,7 +496,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 +1972,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); @@ -386,10 +393,10 @@ * Callback for FiosGetFileList. It tells if a file is a savegame or not. * @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; NULL to skip the lookup - * @param last Last available byte in buffer (to prevent buffer overflows); not used when title == NULL - * @return a FIOS_TYPE_* type of the found file, FIOS_TYPE_INVALID if not a savegame + * @param ext The extension identifier inside file. + * @param [out] title Buffer if a callback wants to lookup the title of the file; NULL to skip the lookup. + * @param last Last available byte in buffer; not used when title == NULL. + * @return a FIOS_TYPE_* type of the found file, #FIOS_TYPE_INVALID if not a savegame. * @see FiosGetFileList * @see FiosGetSavegameList */ @@ -439,10 +446,10 @@ * Callback for FiosGetFileList. It tells if a file is a scenario or not. * @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 + * @param ext The extension identifier inside file. + * @param [out] title Buffer if a callback wants to lookup the title of the file; NULL to skip the lookup. + * @param last Last available byte in buffer + * @return a FIOS_TYPE_* type of the found file, #FIOS_TYPE_INVALID if not a scenario. * @see FiosGetFileList * @see FiosGetScenarioList */ @@ -490,6 +497,74 @@ FiosGetFileList(mode, &FiosGetScenarioListCallback, (mode == SLD_LOAD_SCENARIO && strcmp(base_path, _fios_path) == 0) ? SCENARIO_DIR : NO_DIRECTORY); } +/** + * Callback for FiosGetFileList. 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 The extension identifier inside file. + * @param [out] title Buffer if a callback wants to lookup the title of the file; NULL to skip the lookup. + * @param last Last available byte in buffer + * @return a FIOS_TYPE_* type of the found file, #FIOS_TYPE_INVALID if not a scenario. + * @see FiosGetFileList + * @see FiosGetSaveScenarioList + */ +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) @@ -98,12 +98,13 @@ /** 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. + 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. + 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) @@ -198,11 +198,16 @@ 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; + case SLD_LOAD_GAME_SCENARIO: + FiosGetSaveScenarioList(_saveload_mode); break; + + default: + FiosGetSavegameList(_saveload_mode); break; } /* Invalidate saveload window */