diff --git a/openrct2.vcxproj b/openrct2.vcxproj
index 1b663f40b6..50deb39584 100644
--- a/openrct2.vcxproj
+++ b/openrct2.vcxproj
@@ -27,10 +27,13 @@
+
+
+
diff --git a/openrct2.vcxproj.filters b/openrct2.vcxproj.filters
index a27804dbe2..199085fcb3 100644
--- a/openrct2.vcxproj.filters
+++ b/openrct2.vcxproj.filters
@@ -567,6 +567,9 @@
+
+
+
diff --git a/openrct2.vcxproj.user b/openrct2.vcxproj.user
index 6e6c19d6fb..ccf34d4657 100644
--- a/openrct2.vcxproj.user
+++ b/openrct2.vcxproj.user
@@ -7,7 +7,7 @@
$(TargetDir)\openrct2.exe
WindowsLocalDebugger
$(TargetDir)
- --port=233
+ host "C:\Users\Ted\Documents\OpenRCT2\save\Forest Frontiers MP.sv6"
$(TargetDir)
diff --git a/src/cmdline.c b/src/cmdline.c
index 6c3e57081e..194a95b475 100644
--- a/src/cmdline.c
+++ b/src/cmdline.c
@@ -47,12 +47,6 @@ typedef int (*cmdline_action)(const char **argv, int argc);
int gExitCode = 0;
int sprite_mode;
-#ifndef DISABLE_NETWORK
-int gNetworkStart = NETWORK_MODE_NONE;
-char gNetworkStartHost[128];
-int gNetworkStartPort = NETWORK_DEFAULT_PORT;
-#endif // DISABLE_NETWORK
-
static void print_launch_information();
static void print_version();
static int cmdline_call_action(const char **argv, int argc);
diff --git a/src/cmdline.h b/src/cmdline.h
index e29bc5ea67..dd11f23549 100644
--- a/src/cmdline.h
+++ b/src/cmdline.h
@@ -28,10 +28,6 @@ extern int gExitCode;
extern int sprite_mode;
-extern int gNetworkStart;
-extern char gNetworkStartHost[128];
-extern int gNetworkStartPort;
-
int cmdline_run(const char **argv, int argc);
int cmdline_for_sprite(const char **argv, int argc);
diff --git a/src/cmdline/CommandLine.cpp b/src/cmdline/CommandLine.cpp
index fdac6a6d7a..0a368f20d7 100644
--- a/src/cmdline/CommandLine.cpp
+++ b/src/cmdline/CommandLine.cpp
@@ -93,6 +93,7 @@ namespace CommandLine
constexpr const char * HelpText = "openrct2 -ha shows help for all commands. "
"openrct2 -h will show help and details for a given command.";
+ static void PrintHelpFor(const CommandLineCommand * commands);
static void PrintOptions(const CommandLineOptionDefinition *options);
static void PrintExamples(const CommandLineExample *examples);
static utf8 * GetOptionCaption(utf8 * buffer, size_t bufferSize, const CommandLineOptionDefinition *option);
@@ -104,27 +105,61 @@ namespace CommandLine
static bool ParseLongOption(const CommandLineOptionDefinition * options, CommandLineArgEnumerator * argEnumerator, const char * argument);
static bool ParseOptionValue(const CommandLineOptionDefinition * option, const char * valueString);
- void PrintHelp()
+ void PrintHelp(bool allCommands)
+ {
+ PrintHelpFor(RootCommands);
+ PrintExamples(RootExamples);
+
+ if (allCommands)
+ {
+ const CommandLineCommand * command;
+ for (command = RootCommands; command->Name != nullptr; command++)
+ {
+ if (command->SubCommands != nullptr)
+ {
+ size_t commandNameLength = String::LengthOf(command->Name);
+ for (size_t i = 0; i < commandNameLength; i++)
+ {
+ Console::Write("-");
+ }
+ Console::WriteLine();
+ Console::WriteLine(command->Name);
+ for (size_t i = 0; i < commandNameLength; i++)
+ {
+ Console::Write("-");
+ }
+ Console::WriteLine();
+ PrintHelpFor(command->SubCommands);
+ }
+ }
+ }
+ else
+ {
+ Console::WriteLine(HelpText);
+ }
+ }
+
+ static void PrintHelpFor(const CommandLineCommand * commands)
{
const CommandLineCommand * command;
- size_t maxNameLength = 0;
- size_t maxParamsLength = 0;
+
+ // Print usage
+ const char * usageString = "usage: openrct2 ";
+ const size_t usageStringLength = String::LengthOf(usageString);
+ Console::Write(usageString);
// Get the largest command name length and parameter length
- for (command = RootCommands; command->Name != nullptr; command++)
+ size_t maxNameLength = 0;
+ size_t maxParamsLength = 0;
+ for (command = commands; command->Name != nullptr; command++)
{
maxNameLength = Math::Max(maxNameLength, String::LengthOf(command->Name));
maxParamsLength = Math::Max(maxParamsLength, String::LengthOf(command->Parameters));
}
- // Print usage / main commands
- const char * usageString = "usage: openrct2 ";
- const size_t usageStringLength = String::LengthOf(usageString);
-
- Console::Write(usageString);
- for (command = RootCommands; command->Name != nullptr; command++)
+ for (command = commands; command->Name != nullptr; command++)
{
- if (command != RootCommands)
+ if (command != commands)
{
Console::WriteSpace(usageStringLength);
}
@@ -150,10 +185,10 @@ namespace CommandLine
}
Console::WriteLine();
- PrintOptions(RootCommands->Options);
- PrintExamples(RootExamples);
-
- Console::WriteLine(HelpText);
+ if (commands->Options != nullptr)
+ {
+ PrintOptions(commands->Options);
+ }
}
static void PrintOptions(const CommandLineOptionDefinition *options)
@@ -169,7 +204,7 @@ namespace CommandLine
maxOptionLength = Math::Max(maxOptionLength, optionCaptionLength);
}
- option = RootCommands->Options;
+ option = options;
for (; option->Type != 255; option++)
{
Console::WriteSpace(4);
@@ -239,11 +274,6 @@ namespace CommandLine
return buffer;
}
- void PrintUsageFor(const char * command)
- {
-
- }
-
const CommandLineCommand * FindCommandFor(const CommandLineCommand * commands, CommandLineArgEnumerator *argEnumerator)
{
// Check if end of arguments or options have started
@@ -288,8 +318,10 @@ namespace CommandLine
static bool ParseOptions(const CommandLineOptionDefinition * options, CommandLineArgEnumerator *argEnumerator)
{
+ bool firstOption = true;
+
const char * argument;
- if (argEnumerator->TryPopString(&argument))
+ while (argEnumerator->TryPopString(&argument))
{
if (argument[0] == '-')
{
@@ -308,11 +340,16 @@ namespace CommandLine
}
}
}
- else
+ else if (!firstOption)
{
Console::WriteLineError("All options must be passed at the end of the command line.");
return false;
}
+ else
+ {
+ break;
+ }
+ firstOption = false;
}
return true;
diff --git a/src/cmdline/CommandLine.hpp b/src/cmdline/CommandLine.hpp
index 8a1c340c5b..c6f16f082b 100644
--- a/src/cmdline/CommandLine.hpp
+++ b/src/cmdline/CommandLine.hpp
@@ -83,10 +83,11 @@ constexpr char NAC = '\0';
namespace CommandLine
{
extern const CommandLineCommand RootCommands[];
+ extern const CommandLineCommand ScreenshotCommands[];
+ extern const CommandLineCommand SpriteCommands[];
+
extern const CommandLineExample RootExamples[];
- void PrintHelp();
- void PrintUsageFor(const char * command);
-
+ void PrintHelp(bool allCommands = false);
exitcode_t HandleCommandDefault();
}
diff --git a/src/cmdline/RootCommands.cpp b/src/cmdline/RootCommands.cpp
index eb6aa3351c..f5d1d2a1e1 100644
--- a/src/cmdline/RootCommands.cpp
+++ b/src/cmdline/RootCommands.cpp
@@ -1,16 +1,32 @@
+#include
+
+extern "C"
+{
+ #include "../openrct2.h"
+}
+
#include "../core/Console.hpp"
+#include "../core/Memory.hpp"
+#include "../core/String.hpp"
+#include "../network/network.h"
#include "CommandLine.hpp"
-const CommandLineCommand * ScreenshotCommandTable;
-const CommandLineCommand * SpriteCommandTable;
+#ifndef DISABLE_NETWORK
+int gNetworkStart = NETWORK_MODE_NONE;
+char gNetworkStartHost[128];
+int gNetworkStartPort = NETWORK_DEFAULT_PORT;
+#endif
static bool _help = false;
static bool _version = false;
static bool _noInstall = false;
+static bool _all = false;
static bool _about = false;
static bool _verbose = false;
static bool _headless = false;
+#ifndef DISABLE_NETWORK
static uint32 _port = 0;
+#endif
static utf8 * _userDataPath = nullptr;
static utf8 * _openrctDataPath = nullptr;
@@ -19,31 +35,42 @@ static const CommandLineOptionDefinition StandardOptions[]
{ CMDLINE_TYPE_SWITCH, &_help, 'h', "help", "show this help message and exit" },
{ CMDLINE_TYPE_SWITCH, &_version, 'v', "version", "show version information and exit" },
{ CMDLINE_TYPE_SWITCH, &_noInstall, 'n', "no-install", "do not install scenario if passed" },
- { CMDLINE_TYPE_SWITCH, &_about, NAC, "about" , "show information about " OPENRCT2_NAME },
+ { CMDLINE_TYPE_SWITCH, &_all, 'a', "all", "show help for all commands" },
+ { CMDLINE_TYPE_SWITCH, &_about, NAC, "about", "show information about " OPENRCT2_NAME },
{ CMDLINE_TYPE_SWITCH, &_verbose, NAC, "verbose", "log verbose messages" },
{ CMDLINE_TYPE_SWITCH, &_headless, NAC, "headless", "run " OPENRCT2_NAME " headless" },
+#ifndef DISABLE_NETWORK
{ CMDLINE_TYPE_INTEGER, &_port, NAC, "port", "port to use for hosting or joining a server" },
+#endif
{ CMDLINE_TYPE_STRING, &_userDataPath, NAC, "user-data-path", "path to the user data directory (containing config.ini)" },
{ CMDLINE_TYPE_STRING, &_openrctDataPath, NAC, "openrct-data-path", "path to the OpenRCT2 data directory (containing languages)" },
OptionTableEnd
};
static exitcode_t HandleNoCommand(CommandLineArgEnumerator * enumerator);
+static exitcode_t HandleCommandEdit(CommandLineArgEnumerator * enumerator);
static exitcode_t HandleCommandIntro(CommandLineArgEnumerator * enumerator);
static exitcode_t HandleCommandHost(CommandLineArgEnumerator * enumerator);
static exitcode_t HandleCommandJoin(CommandLineArgEnumerator * enumerator);
+static void PrintAbout();
+static void PrintVersion();
+static void PrintLaunchInformation();
+
const CommandLineCommand CommandLine::RootCommands[]
{
// Main commands
DefineCommand("", "", StandardOptions, HandleNoCommand ),
+ DefineCommand("edit", "", StandardOptions, HandleCommandEdit ),
DefineCommand("intro", "", StandardOptions, HandleCommandIntro),
+#ifndef DISABLE_NETWORK
DefineCommand("host", "", StandardOptions, HandleCommandHost ),
DefineCommand("join", "", StandardOptions, HandleCommandJoin ),
+#endif
// Sub-commands
- DefineSubCommand("screenshot", ScreenshotCommandTable),
- DefineSubCommand("sprite", SpriteCommandTable ),
+ DefineSubCommand("screenshot", CommandLine::ScreenshotCommands),
+ DefineSubCommand("sprite", CommandLine::SpriteCommands ),
CommandTableEnd
};
@@ -54,19 +81,57 @@ static const CommandLineExample CommandLine::RootExamples[]
{ "./SnowyPark.sc6", "install and open a scenario" },
{ "./ShuttleLoop.td6", "install a track" },
{ "http:/openrct2.website/files/SnowyPark.sv6", "download and open a saved park" },
+#ifndef DISABLE_NETWORK
{ "host ./my_park.sv6 --port 11753 --headless", "run a headless server for a saved park" },
+#endif
ExampleTableEnd
};
exitcode_t CommandLine::HandleCommandDefault()
{
- if (_help)
+ exitcode_t result = EXITCODE_CONTINUE;
+
+ if (_about)
{
- CommandLine::PrintHelp();
- return EXITCODE_OK;
+ PrintAbout();
+ result = EXITCODE_OK;
+ } else
+ {
+ if (_verbose)
+ {
+ _log_levels[DIAGNOSTIC_LEVEL_VERBOSE] = 1;
+ PrintLaunchInformation();
+ }
+
+ if (_version)
+ {
+ if (!_verbose)
+ {
+ PrintVersion();
+ }
+ result = EXITCODE_OK;
+ }
}
- return EXITCODE_CONTINUE;
+ if (_help)
+ {
+ CommandLine::PrintHelp(_all);
+ result = EXITCODE_OK;
+ }
+
+ gOpenRCT2Headless = _headless;
+
+ if (_userDataPath != NULL) {
+ String::Set(gCustomUserDataPath, sizeof(gCustomUserDataPath), _userDataPath);
+ Memory::Free(_userDataPath);
+ }
+
+ if (_openrctDataPath != NULL) {
+ String::Set(gCustomOpenrctDataPath, sizeof(gCustomOpenrctDataPath), _openrctDataPath);
+ Memory::Free(gCustomOpenrctDataPath);
+ }
+
+ return result;
}
exitcode_t HandleNoCommand(CommandLineArgEnumerator * enumerator)
@@ -77,8 +142,35 @@ exitcode_t HandleNoCommand(CommandLineArgEnumerator * enumerator)
return result;
}
- // Process URI
+ const char * parkUri;
+ if (!enumerator->TryPopString(&parkUri))
+ {
+ Console::WriteLineError("Expected path or URL to a saved park.");
+ return EXITCODE_FAIL;
+ }
+ String::Set(gOpenRCT2StartupActionPath, sizeof(gOpenRCT2StartupActionPath), parkUri);
+ gOpenRCT2StartupAction = STARTUP_ACTION_OPEN;
+ return EXITCODE_CONTINUE;
+}
+
+exitcode_t HandleCommandEdit(CommandLineArgEnumerator * enumerator)
+{
+ exitcode_t result = CommandLine::HandleCommandDefault();
+ if (result != EXITCODE_CONTINUE)
+ {
+ return result;
+ }
+
+ const char * parkUri;
+ if (!enumerator->TryPopString(&parkUri))
+ {
+ Console::WriteLineError("Expected path or URL to a saved park.");
+ return EXITCODE_FAIL;
+ }
+ String::Set(gOpenRCT2StartupActionPath, sizeof(gOpenRCT2StartupActionPath), parkUri);
+
+ gOpenRCT2StartupAction = STARTUP_ACTION_EDIT;
return EXITCODE_CONTINUE;
}
@@ -90,68 +182,106 @@ exitcode_t HandleCommandIntro(CommandLineArgEnumerator * enumerator)
return result;
}
+ gOpenRCT2StartupAction = STARTUP_ACTION_INTRO;
return EXITCODE_CONTINUE;
}
+#ifndef DISABLE_NETWORK
+
exitcode_t HandleCommandHost(CommandLineArgEnumerator * enumerator)
{
- const char * parkUri;
-
exitcode_t result = CommandLine::HandleCommandDefault();
if (result != EXITCODE_CONTINUE)
{
return result;
}
+ const char * parkUri;
if (!enumerator->TryPopString(&parkUri))
{
Console::WriteLineError("Expected path or URL to a saved park.");
- CommandLine::PrintUsageFor("host");
return EXITCODE_FAIL;
}
+ gOpenRCT2StartupAction = STARTUP_ACTION_OPEN;
+ String::Set(gOpenRCT2StartupActionPath, sizeof(gOpenRCT2StartupActionPath), parkUri);
+
+ gNetworkStart = NETWORK_MODE_SERVER;
+ gNetworkStartPort = _port;
return EXITCODE_CONTINUE;
}
exitcode_t HandleCommandJoin(CommandLineArgEnumerator * enumerator)
{
- const char * hostname;
-
exitcode_t result = CommandLine::HandleCommandDefault();
if (result != EXITCODE_CONTINUE)
{
return result;
}
+ const char * hostname;
if (!enumerator->TryPopString(&hostname))
{
Console::WriteLineError("Expected a hostname or IP address to the server to connect to.");
- CommandLine::PrintUsageFor("join");
return EXITCODE_FAIL;
}
+ gNetworkStart = NETWORK_MODE_CLIENT;
+ gNetworkStartPort = _port;
+ String::Set(gNetworkStartHost, sizeof(gNetworkStartHost), hostname);
return EXITCODE_CONTINUE;
}
-const CommandLineCommand ScreenshotCommands[]
-{
- // Main commands
- DefineCommand("", " [ ]", nullptr, nullptr),
- DefineCommand("", " giant ", nullptr, nullptr),
- CommandTableEnd
-};
+#endif // DISABLE_NETWORK
-const CommandLineOptionDefinition SpriteOptions[]
+static void PrintAbout()
{
- { CMDLINE_TYPE_STRING, nullptr, 'm', "mode", "the type of sprite conversion " },
- OptionTableEnd
-};
+ PrintVersion();
+ Console::WriteLine();
+ Console::WriteLine("OpenRCT2 is an amusement park simulation game based upon the popular game");
+ Console::WriteLine("RollerCoaster Tycoon 2, written by Chris Sawyer. It attempts to mimic the ");
+ Console::WriteLine("original game as closely as possible while extending it with new features.");
+ Console::WriteLine("OpenRCT2 is licensed under the GNU General Public License version 3.0, but");
+ Console::WriteLine("includes some 3rd party software under different licenses. See the file");
+ Console::WriteLine("\"licence.txt\" shipped with the game for details.");
+ Console::WriteLine();
+ Console::WriteLine("Website: https://openrct2.website");
+ Console::WriteLine("GitHub: https://github.com/OpenRCT2/OpenRCT2");
+ Console::WriteLine("Contributors: https://github.com/OpenRCT2/OpenRCT2/blob/develop/contributors.md");
+ Console::WriteLine();
+}
-const CommandLineCommand SpriteCommands[]
+static void PrintVersion()
{
- // Main commands
- DefineCommand("details", " [idx]", SpriteOptions, nullptr),
- DefineCommand("export", "