mirror of https://github.com/OpenTTD/OpenTTD
Add: allow loading heightmaps from command-line (#11870)
If you want to load a file from tar, you have to give the file inside the tar in order for it to work: <tar-file>/<dir-in-tar>/<file>.pngpull/11871/head
parent
bf3fd6526b
commit
090616b4c9
|
@ -13,7 +13,7 @@
|
||||||
.Op Fl c Ar config_file
|
.Op Fl c Ar config_file
|
||||||
.Op Fl d Op Ar level | Ar cat Ns = Ns Ar lvl Ns Op , Ns Ar ...
|
.Op Fl d Op Ar level | Ar cat Ns = Ns Ar lvl Ns Op , Ns Ar ...
|
||||||
.Op Fl D Oo Ar host Oc Ns Op : Ns Ar port
|
.Op Fl D Oo Ar host Oc Ns Op : Ns Ar port
|
||||||
.Op Fl g Op Ar savegame
|
.Op Fl g Op Ar file
|
||||||
.Op Fl G Ar seed
|
.Op Fl G Ar seed
|
||||||
.Op Fl I Ar graphicsset
|
.Op Fl I Ar graphicsset
|
||||||
.Op Fl m Ar driver
|
.Op Fl m Ar driver
|
||||||
|
@ -62,11 +62,11 @@ Start in world editor mode.
|
||||||
.It Fl f
|
.It Fl f
|
||||||
Fork into background (dedicated server only, see
|
Fork into background (dedicated server only, see
|
||||||
.Fl D ) .
|
.Fl D ) .
|
||||||
.It Fl g Op Ar savegame
|
.It Fl g Op Ar file
|
||||||
Load
|
Load
|
||||||
.Ar savegame
|
.Ar file
|
||||||
at start or start a new game if omitted.
|
(can be either a savegame, scenario, or heightmap) at start or start a new game if omitted.
|
||||||
.Ar savegame
|
.Ar file
|
||||||
must be either an absolute path or one relative to the current path or one of
|
must be either an absolute path or one relative to the current path or one of
|
||||||
the search paths.
|
the search paths.
|
||||||
.It Fl G Ar seed
|
.It Fl G Ar seed
|
||||||
|
|
|
@ -447,9 +447,6 @@ std::tuple<FiosType, std::string> FiosGetSavegameListCallback(SaveLoadOperation
|
||||||
* .SV1 Transport Tycoon Deluxe (Patch) saved game
|
* .SV1 Transport Tycoon Deluxe (Patch) saved game
|
||||||
* .SV2 Transport Tycoon Deluxe (Patch) saved 2-player game */
|
* .SV2 Transport Tycoon Deluxe (Patch) saved 2-player game */
|
||||||
|
|
||||||
/* Don't crash if we supply no extension */
|
|
||||||
if (ext.empty()) return { FIOS_TYPE_INVALID, {} };
|
|
||||||
|
|
||||||
if (StrEqualsIgnoreCase(ext, ".sav")) {
|
if (StrEqualsIgnoreCase(ext, ".sav")) {
|
||||||
return { FIOS_TYPE_FILE, GetFileTitle(file, SAVE_DIR) };
|
return { FIOS_TYPE_FILE, GetFileTitle(file, SAVE_DIR) };
|
||||||
}
|
}
|
||||||
|
@ -490,7 +487,7 @@ void FiosGetSavegameList(SaveLoadOperation fop, FileList &file_list)
|
||||||
* @see FiosGetFileList
|
* @see FiosGetFileList
|
||||||
* @see FiosGetScenarioList
|
* @see FiosGetScenarioList
|
||||||
*/
|
*/
|
||||||
static std::tuple<FiosType, std::string> FiosGetScenarioListCallback(SaveLoadOperation fop, const std::string &file, const std::string_view ext)
|
std::tuple<FiosType, std::string> FiosGetScenarioListCallback(SaveLoadOperation fop, const std::string &file, const std::string_view ext)
|
||||||
{
|
{
|
||||||
/* Show scenario files
|
/* Show scenario files
|
||||||
* .SCN OpenTTD style scenario file
|
* .SCN OpenTTD style scenario file
|
||||||
|
@ -530,7 +527,7 @@ void FiosGetScenarioList(SaveLoadOperation fop, FileList &file_list)
|
||||||
FiosGetFileList(fop, &FiosGetScenarioListCallback, subdir, file_list);
|
FiosGetFileList(fop, &FiosGetScenarioListCallback, subdir, file_list);
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::tuple<FiosType, std::string> FiosGetHeightmapListCallback(SaveLoadOperation, const std::string &file, const std::string_view ext)
|
std::tuple<FiosType, std::string> FiosGetHeightmapListCallback(SaveLoadOperation, const std::string &file, const std::string_view ext)
|
||||||
{
|
{
|
||||||
/* Show heightmap files
|
/* Show heightmap files
|
||||||
* .PNG PNG Based heightmap files
|
* .PNG PNG Based heightmap files
|
||||||
|
|
|
@ -117,6 +117,8 @@ std::string FiosMakeHeightmapName(const char *name);
|
||||||
std::string FiosMakeSavegameName(const char *name);
|
std::string FiosMakeSavegameName(const char *name);
|
||||||
|
|
||||||
std::tuple<FiosType, std::string> FiosGetSavegameListCallback(SaveLoadOperation fop, const std::string &file, const std::string_view ext);
|
std::tuple<FiosType, std::string> FiosGetSavegameListCallback(SaveLoadOperation fop, const std::string &file, const std::string_view ext);
|
||||||
|
std::tuple<FiosType, std::string> FiosGetScenarioListCallback(SaveLoadOperation fop, const std::string &file, const std::string_view ext);
|
||||||
|
std::tuple<FiosType, std::string> FiosGetHeightmapListCallback(SaveLoadOperation fop, const std::string &file, const std::string_view ext);
|
||||||
|
|
||||||
void ScanScenarios();
|
void ScanScenarios();
|
||||||
const char *FindScenario(const ContentInfo *ci, bool md5sum);
|
const char *FindScenario(const ContentInfo *ci, bool md5sum);
|
||||||
|
|
|
@ -103,8 +103,14 @@ static void _GenerateWorld()
|
||||||
/* Must start economy early because of the costs. */
|
/* Must start economy early because of the costs. */
|
||||||
StartupEconomy();
|
StartupEconomy();
|
||||||
|
|
||||||
|
bool landscape_generated = false;
|
||||||
|
|
||||||
/* Don't generate landscape items when in the scenario editor. */
|
/* Don't generate landscape items when in the scenario editor. */
|
||||||
if (_gw.mode == GWM_EMPTY) {
|
if (_gw.mode != GWM_EMPTY) {
|
||||||
|
landscape_generated = GenerateLandscape(_gw.mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!landscape_generated) {
|
||||||
SetGeneratingWorldProgress(GWP_OBJECT, 1);
|
SetGeneratingWorldProgress(GWP_OBJECT, 1);
|
||||||
|
|
||||||
/* Make sure the tiles at the north border are void tiles if needed. */
|
/* Make sure the tiles at the north border are void tiles if needed. */
|
||||||
|
@ -121,7 +127,6 @@ static void _GenerateWorld()
|
||||||
|
|
||||||
_settings_game.game_creation.snow_line_height = DEF_SNOWLINE_HEIGHT;
|
_settings_game.game_creation.snow_line_height = DEF_SNOWLINE_HEIGHT;
|
||||||
} else {
|
} else {
|
||||||
GenerateLandscape(_gw.mode);
|
|
||||||
GenerateClearTile();
|
GenerateClearTile();
|
||||||
|
|
||||||
/* Only generate towns, tree and industries in newgame mode. */
|
/* Only generate towns, tree and industries in newgame mode. */
|
||||||
|
|
|
@ -520,14 +520,14 @@ bool GetHeightmapDimensions(DetailedFileType dft, const char *filename, uint *x,
|
||||||
* @param dft Type of image file.
|
* @param dft Type of image file.
|
||||||
* @param filename of the heightmap file to be imported
|
* @param filename of the heightmap file to be imported
|
||||||
*/
|
*/
|
||||||
void LoadHeightmap(DetailedFileType dft, const char *filename)
|
bool LoadHeightmap(DetailedFileType dft, const char *filename)
|
||||||
{
|
{
|
||||||
uint x, y;
|
uint x, y;
|
||||||
byte *map = nullptr;
|
byte *map = nullptr;
|
||||||
|
|
||||||
if (!ReadHeightMap(dft, filename, &x, &y, &map)) {
|
if (!ReadHeightMap(dft, filename, &x, &y, &map)) {
|
||||||
free(map);
|
free(map);
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
GrayscaleToMapHeights(x, y, map);
|
GrayscaleToMapHeights(x, y, map);
|
||||||
|
@ -535,6 +535,8 @@ void LoadHeightmap(DetailedFileType dft, const char *filename)
|
||||||
|
|
||||||
FixSlopes();
|
FixSlopes();
|
||||||
MarkWholeScreenDirty();
|
MarkWholeScreenDirty();
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -22,7 +22,7 @@ enum HeightmapRotation {
|
||||||
};
|
};
|
||||||
|
|
||||||
bool GetHeightmapDimensions(DetailedFileType dft, const char *filename, uint *x, uint *y);
|
bool GetHeightmapDimensions(DetailedFileType dft, const char *filename, uint *x, uint *y);
|
||||||
void LoadHeightmap(DetailedFileType dft, const char *filename);
|
bool LoadHeightmap(DetailedFileType dft, const char *filename);
|
||||||
void FlatEmptyWorld(byte tile_height);
|
void FlatEmptyWorld(byte tile_height);
|
||||||
void FixSlopes();
|
void FixSlopes();
|
||||||
|
|
||||||
|
|
|
@ -1557,7 +1557,7 @@ static uint8_t CalculateDesertLine()
|
||||||
return CalculateCoverageLine(100 - _settings_game.game_creation.desert_coverage, 4);
|
return CalculateCoverageLine(100 - _settings_game.game_creation.desert_coverage, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GenerateLandscape(byte mode)
|
bool GenerateLandscape(byte mode)
|
||||||
{
|
{
|
||||||
/** Number of steps of landscape generation */
|
/** Number of steps of landscape generation */
|
||||||
enum GenLandscapeSteps {
|
enum GenLandscapeSteps {
|
||||||
|
@ -1571,7 +1571,9 @@ void GenerateLandscape(byte mode)
|
||||||
|
|
||||||
if (mode == GWM_HEIGHTMAP) {
|
if (mode == GWM_HEIGHTMAP) {
|
||||||
SetGeneratingWorldProgress(GWP_LANDSCAPE, steps + GLS_HEIGHTMAP);
|
SetGeneratingWorldProgress(GWP_LANDSCAPE, steps + GLS_HEIGHTMAP);
|
||||||
LoadHeightmap(_file_to_saveload.detail_ftype, _file_to_saveload.name.c_str());
|
if (!LoadHeightmap(_file_to_saveload.detail_ftype, _file_to_saveload.name.c_str())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
|
IncreaseGeneratingWorldProgress(GWP_LANDSCAPE);
|
||||||
} else if (_settings_game.game_creation.land_generator == LG_TERRAGENESIS) {
|
} else if (_settings_game.game_creation.land_generator == LG_TERRAGENESIS) {
|
||||||
SetGeneratingWorldProgress(GWP_LANDSCAPE, steps + GLS_TERRAGENESIS);
|
SetGeneratingWorldProgress(GWP_LANDSCAPE, steps + GLS_TERRAGENESIS);
|
||||||
|
@ -1657,6 +1659,7 @@ void GenerateLandscape(byte mode)
|
||||||
}
|
}
|
||||||
|
|
||||||
CreateRivers();
|
CreateRivers();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OnTick_Town();
|
void OnTick_Town();
|
||||||
|
|
|
@ -139,6 +139,6 @@ void DoClearSquare(TileIndex tile);
|
||||||
void RunTileLoop();
|
void RunTileLoop();
|
||||||
|
|
||||||
void InitializeLandscape();
|
void InitializeLandscape();
|
||||||
void GenerateLandscape(byte mode);
|
bool GenerateLandscape(byte mode);
|
||||||
|
|
||||||
#endif /* LANDSCAPE_H */
|
#endif /* LANDSCAPE_H */
|
||||||
|
|
|
@ -165,7 +165,7 @@ static void ShowHelp()
|
||||||
" -t year = Set starting year\n"
|
" -t year = Set starting year\n"
|
||||||
" -d [[fac=]lvl[,...]]= Debug mode\n"
|
" -d [[fac=]lvl[,...]]= Debug mode\n"
|
||||||
" -e = Start Editor\n"
|
" -e = Start Editor\n"
|
||||||
" -g [savegame] = Start new/save game immediately\n"
|
" -g [savegame|scenario|heightmap] = Start new/savegame/scenario/heightmap immediately\n"
|
||||||
" -G seed = Set random seed\n"
|
" -G seed = Set random seed\n"
|
||||||
" -n host[:port][#company]= Join network game\n"
|
" -n host[:port][#company]= Join network game\n"
|
||||||
" -p password = Password to join server\n"
|
" -p password = Password to join server\n"
|
||||||
|
@ -577,21 +577,37 @@ int openttd_main(int argc, char *argv[])
|
||||||
if (mgo.opt != nullptr) SetDebugString(mgo.opt, ShowInfoI);
|
if (mgo.opt != nullptr) SetDebugString(mgo.opt, ShowInfoI);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case 'e': _switch_mode = (_switch_mode == SM_LOAD_GAME || _switch_mode == SM_LOAD_SCENARIO ? SM_LOAD_SCENARIO : SM_EDITOR); break;
|
case 'e':
|
||||||
|
/* Allow for '-e' before or after '-g'. */
|
||||||
|
switch (_switch_mode) {
|
||||||
|
case SM_MENU: _switch_mode = SM_EDITOR; break;
|
||||||
|
case SM_LOAD_GAME: _switch_mode = SM_LOAD_SCENARIO; break;
|
||||||
|
case SM_START_HEIGHTMAP: _switch_mode = SM_LOAD_HEIGHTMAP; break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 'g':
|
case 'g':
|
||||||
if (mgo.opt != nullptr) {
|
if (mgo.opt != nullptr) {
|
||||||
_file_to_saveload.name = mgo.opt;
|
_file_to_saveload.name = 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 */
|
std::string extension = std::filesystem::path(_file_to_saveload.name).extension().string();
|
||||||
auto t = _file_to_saveload.name.find_last_of('.');
|
auto [ft, _] = FiosGetSavegameListCallback(SLO_LOAD, _file_to_saveload.name, extension);
|
||||||
if (t != std::string::npos) {
|
if (ft == FIOS_TYPE_INVALID) {
|
||||||
auto [ft, _] = FiosGetSavegameListCallback(SLO_LOAD, _file_to_saveload.name, _file_to_saveload.name.substr(t));
|
std::tie(ft, _) = FiosGetScenarioListCallback(SLO_LOAD, _file_to_saveload.name, extension);
|
||||||
if (ft != FIOS_TYPE_INVALID) _file_to_saveload.SetMode(ft);
|
}
|
||||||
|
if (ft == FIOS_TYPE_INVALID) {
|
||||||
|
std::tie(ft, _) = FiosGetHeightmapListCallback(SLO_LOAD, _file_to_saveload.name, extension);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Allow for '-e' before or after '-g'. */
|
||||||
|
switch (GetAbstractFileType(ft)) {
|
||||||
|
case FT_SAVEGAME: _switch_mode = (_switch_mode == SM_EDITOR ? SM_LOAD_SCENARIO : SM_LOAD_GAME); break;
|
||||||
|
case FT_SCENARIO: _switch_mode = (_switch_mode == SM_EDITOR ? SM_LOAD_SCENARIO : SM_LOAD_GAME); break;
|
||||||
|
case FT_HEIGHTMAP: _switch_mode = (_switch_mode == SM_EDITOR ? SM_LOAD_HEIGHTMAP : SM_START_HEIGHTMAP); break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
_file_to_saveload.SetMode(SLO_LOAD, GetAbstractFileType(ft), GetDetailedFileType(ft));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1131,6 +1147,8 @@ void SwitchToMode(SwitchMode new_mode)
|
||||||
case SM_LOAD_HEIGHTMAP: // Load heightmap from scenario editor
|
case SM_LOAD_HEIGHTMAP: // Load heightmap from scenario editor
|
||||||
SetLocalCompany(OWNER_NONE);
|
SetLocalCompany(OWNER_NONE);
|
||||||
|
|
||||||
|
_game_mode = GM_EDITOR;
|
||||||
|
|
||||||
GenerateWorld(GWM_HEIGHTMAP, 1 << _settings_game.game_creation.map_x, 1 << _settings_game.game_creation.map_y);
|
GenerateWorld(GWM_HEIGHTMAP, 1 << _settings_game.game_creation.map_x, 1 << _settings_game.game_creation.map_y);
|
||||||
GenerateSavegameId();
|
GenerateSavegameId();
|
||||||
MarkWholeScreenDirty();
|
MarkWholeScreenDirty();
|
||||||
|
|
|
@ -204,8 +204,8 @@ void VideoDriver_Dedicated::MainLoop()
|
||||||
_network_dedicated = true;
|
_network_dedicated = true;
|
||||||
_current_company = _local_company = COMPANY_SPECTATOR;
|
_current_company = _local_company = COMPANY_SPECTATOR;
|
||||||
|
|
||||||
/* If SwitchMode is SM_LOAD_GAME, it means that the user used the '-g' options */
|
/* If SwitchMode is SM_LOAD_GAME / SM_START_HEIGHTMAP, it means that the user used the '-g' options */
|
||||||
if (_switch_mode != SM_LOAD_GAME) {
|
if (_switch_mode != SM_LOAD_GAME && _switch_mode != SM_START_HEIGHTMAP) {
|
||||||
StartNewGameWithoutGUI(GENERATE_NEW_SEED);
|
StartNewGameWithoutGUI(GENERATE_NEW_SEED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue