From df2b793c0a3ee098d3b93cb3f8ed31c632dbcffd Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Mon, 11 Jan 2016 21:49:13 +0000 Subject: [PATCH 1/3] refactor console error output --- src/cmdline/CommandLine.cpp | 30 +++++++++++++------------- src/cmdline/RootCommands.cpp | 6 +++--- src/core/Console.cpp | 42 +++++++++++++++++++++++------------- src/core/Console.hpp | 13 +++++++---- 4 files changed, 54 insertions(+), 37 deletions(-) diff --git a/src/cmdline/CommandLine.cpp b/src/cmdline/CommandLine.cpp index aeca7e203e..f985a87122 100644 --- a/src/cmdline/CommandLine.cpp +++ b/src/cmdline/CommandLine.cpp @@ -350,7 +350,7 @@ namespace CommandLine } else if (!firstOption) { - Console::WriteLineError("All options must be passed at the end of the command line."); + Console::Error::WriteLine("All options must be passed at the end of the command line."); return false; } else @@ -383,8 +383,8 @@ namespace CommandLine const CommandLineOptionDefinition * option = FindOption(options, optionName); if (option == nullptr) { - Console::WriteError("Unknown option: --"); - Console::WriteLineError(optionName); + Console::Error::Write("Unknown option: --"); + Console::Error::WriteLine(optionName); return false; } @@ -399,8 +399,8 @@ namespace CommandLine const char * valueString = nullptr; if (!argEnumerator->TryPopString(&valueString)) { - Console::WriteError("Expected value for option: "); - Console::WriteLineError(optionName); + Console::Error::Write("Expected value for option: "); + Console::Error::WriteLine(optionName); return false; } @@ -414,8 +414,8 @@ namespace CommandLine { if (option->Type == CMDLINE_TYPE_SWITCH) { - Console::WriteError("Option is a switch: "); - Console::WriteLineError(optionName); + Console::Error::Write("Option is a switch: "); + Console::Error::WriteLine(optionName); return false; } else @@ -442,9 +442,9 @@ namespace CommandLine option = FindOption(options, shortOption[0]); if (option == nullptr) { - Console::WriteError("Unknown option: -"); - Console::WriteError(shortOption[0]); - Console::WriteLineError(); + Console::Error::Write("Unknown option: -"); + Console::Error::Write(shortOption[0]); + Console::Error::WriteLine(); return false; } if (option->Type == CMDLINE_TYPE_SWITCH) @@ -469,9 +469,9 @@ namespace CommandLine const char * valueString = nullptr; if (!argEnumerator->TryPopString(&valueString)) { - Console::WriteError("Expected value for option: "); - Console::WriteError(option->ShortName); - Console::WriteLineError(); + Console::Error::Write("Expected value for option: "); + Console::Error::Write(option->ShortName); + Console::Error::WriteLine(); return false; } @@ -502,8 +502,8 @@ namespace CommandLine *((utf8 * *)option->OutAddress) = String::Duplicate(valueString); return true; default: - Console::WriteError("Unknown CMDLINE_TYPE for: "); - Console::WriteLineError(option->LongName); + Console::Error::Write("Unknown CMDLINE_TYPE for: "); + Console::Error::WriteLine(option->LongName); return false; } } diff --git a/src/cmdline/RootCommands.cpp b/src/cmdline/RootCommands.cpp index 45b360f748..9c9f24b851 100644 --- a/src/cmdline/RootCommands.cpp +++ b/src/cmdline/RootCommands.cpp @@ -163,7 +163,7 @@ exitcode_t HandleCommandEdit(CommandLineArgEnumerator * enumerator) const char * parkUri; if (!enumerator->TryPopString(&parkUri)) { - Console::WriteLineError("Expected path or URL to a saved park."); + Console::Error::WriteLine("Expected path or URL to a saved park."); return EXITCODE_FAIL; } String::Set(gOpenRCT2StartupActionPath, sizeof(gOpenRCT2StartupActionPath), parkUri); @@ -197,7 +197,7 @@ exitcode_t HandleCommandHost(CommandLineArgEnumerator * enumerator) const char * parkUri; if (!enumerator->TryPopString(&parkUri)) { - Console::WriteLineError("Expected path or URL to a saved park."); + Console::Error::WriteLine("Expected path or URL to a saved park."); return EXITCODE_FAIL; } @@ -220,7 +220,7 @@ exitcode_t HandleCommandJoin(CommandLineArgEnumerator * enumerator) const char * hostname; if (!enumerator->TryPopString(&hostname)) { - Console::WriteLineError("Expected a hostname or IP address to the server to connect to."); + Console::Error::WriteLine("Expected a hostname or IP address to the server to connect to."); return EXITCODE_FAIL; } diff --git a/src/core/Console.cpp b/src/core/Console.cpp index e4cde07de9..713e651378 100644 --- a/src/core/Console.cpp +++ b/src/core/Console.cpp @@ -44,24 +44,36 @@ namespace Console puts(str); } - void WriteError(char c) + namespace Error { - fputc(c, stderr); - } + void Write(char c) + { + fputc(c, stderr); + } - void WriteError(const utf8 * str) - { - fputs(str, stderr); - } + void Write(const utf8 * str) + { + fputs(str, stderr); + } - void WriteLineError() - { - fputs(platform_get_new_line(), stderr); - } + void WriteFormat(const utf8 * format, ...) + { + va_list args; - void WriteLineError(const utf8 * str) - { - fputs(str, stderr); - WriteLineError(); + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + } + + void WriteLine() + { + fputs(platform_get_new_line(), stderr); + } + + void WriteLine(const utf8 * str) + { + fputs(str, stderr); + WriteLine(); + } } } \ No newline at end of file diff --git a/src/core/Console.hpp b/src/core/Console.hpp index b9e30309f6..36068ae204 100644 --- a/src/core/Console.hpp +++ b/src/core/Console.hpp @@ -13,8 +13,13 @@ namespace Console void WriteFormat(const utf8 * format, ...); void WriteLine(); void WriteLine(const utf8 * str); - void WriteError(char c); - void WriteError(const utf8 * str); - void WriteLineError(); - void WriteLineError(const utf8 * str); + + namespace Error + { + void Write(char c); + void Write(const utf8 * str); + void WriteFormat(const utf8 * format, ...); + void WriteLine(); + void WriteLine(const utf8 * str); + } } From 8cf53c12af5ad1c0e9d81dbf853194f78b3e9410 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Tue, 12 Jan 2016 19:08:41 +0000 Subject: [PATCH 2/3] add ability to set RCT2 path by command line --- openrct2.vcxproj | 4 +- openrct2.vcxproj.filters | 6 +++ src/cmdline/RootCommands.cpp | 94 +++++++++++++++++++++++++++++++++--- src/core/Path.cpp | 52 ++++++++++++++++++++ src/core/Path.hpp | 12 +++++ src/core/String.cpp | 12 +++++ src/core/String.hpp | 10 ++++ src/openrct2.c | 3 +- src/openrct2.h | 1 + 9 files changed, 185 insertions(+), 9 deletions(-) create mode 100644 src/core/Path.cpp create mode 100644 src/core/Path.hpp diff --git a/openrct2.vcxproj b/openrct2.vcxproj index 4a8b885800..092fca3988 100644 --- a/openrct2.vcxproj +++ b/openrct2.vcxproj @@ -30,6 +30,7 @@ + @@ -203,6 +204,7 @@ + @@ -377,4 +379,4 @@ - + \ No newline at end of file diff --git a/openrct2.vcxproj.filters b/openrct2.vcxproj.filters index fcebcbbe58..2ad680ca98 100644 --- a/openrct2.vcxproj.filters +++ b/openrct2.vcxproj.filters @@ -576,6 +576,9 @@ Source\Core + + Source\Core + @@ -875,5 +878,8 @@ Source\Core + + Source\Core + \ No newline at end of file diff --git a/src/cmdline/RootCommands.cpp b/src/cmdline/RootCommands.cpp index 9c9f24b851..5596d65b69 100644 --- a/src/cmdline/RootCommands.cpp +++ b/src/cmdline/RootCommands.cpp @@ -2,11 +2,13 @@ extern "C" { + #include "../config.h" #include "../openrct2.h" } #include "../core/Console.hpp" #include "../core/Memory.hpp" +#include "../core/Path.hpp" #include "../core/String.hpp" #include "../network/network.h" #include "CommandLine.hpp" @@ -52,6 +54,7 @@ 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 exitcode_t HandleCommandSetRCT2(CommandLineArgEnumerator * enumerator); static void PrintAbout(); static void PrintVersion(); @@ -60,13 +63,14 @@ 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 ), + DefineCommand("", "", StandardOptions, HandleNoCommand ), + DefineCommand("edit", "", StandardOptions, HandleCommandEdit ), + DefineCommand("intro", "", StandardOptions, HandleCommandIntro ), +#ifndef DISABLE_NETWORK + DefineCommand("host", "", StandardOptions, HandleCommandHost ), + DefineCommand("join", "", StandardOptions, HandleCommandJoin ), #endif + DefineCommand("set-rct2", "", StandardOptions, HandleCommandSetRCT2), // Sub-commands DefineSubCommand("screenshot", CommandLine::ScreenshotCommands), @@ -232,6 +236,84 @@ exitcode_t HandleCommandJoin(CommandLineArgEnumerator * enumerator) #endif // DISABLE_NETWORK +static exitcode_t HandleCommandSetRCT2(CommandLineArgEnumerator * enumerator) +{ + exitcode_t result = CommandLine::HandleCommandDefault(); + if (result != EXITCODE_CONTINUE) + { + return result; + } + + // Get the path that was passed + const utf8 * rawPath; + if (!enumerator->TryPopString(&rawPath)) + { + Console::Error::WriteLine("Expected a path."); + return EXITCODE_FAIL; + } + + utf8 path[MAX_PATH]; + Path::GetAbsolute(path, sizeof(path), rawPath); + + // Check if path exists + Console::WriteLine("Checking path..."); + if (!platform_directory_exists(path)) + { + Console::Error::WriteFormat("The path '%s' does not exist", path); + Console::Error::WriteLine(); + return EXITCODE_FAIL; + } + + // Check if g1.dat exists (naive but good check) + Console::WriteLine("Checking g1.dat..."); + + utf8 pathG1Check[MAX_PATH]; + String::Set(pathG1Check, sizeof(pathG1Check), path); + Path::Append(pathG1Check, sizeof(pathG1Check), "Data"); + Path::Append(pathG1Check, sizeof(pathG1Check), "g1.dat"); + if (!platform_file_exists(pathG1Check)) + { + Console::Error::WriteLine("RCT2 path not valid."); + Console::Error::WriteFormat("Unable to find %s.", pathG1Check); + Console::Error::WriteLine(); + return EXITCODE_FAIL; + } + + // Check user path that will contain the config + utf8 userPath[MAX_PATH]; + platform_resolve_user_data_path(); + platform_get_user_directory(userPath, NULL); + if (!platform_ensure_directory_exists(userPath)) { + Console::Error::WriteFormat("Unable to access or create directory '%s'.", userPath); + Console::Error::WriteLine(); + return EXITCODE_FAIL; + } + + // Update RCT2 path in config + + // TODO remove this when we get rid of config_apply_to_old_addresses + if (!openrct2_setup_rct2_segment()) { + Console::Error::WriteLine("Unable to load RCT2 data sector"); + return EXITCODE_FAIL; + } + + config_set_defaults(); + config_open_default(); + String::DiscardDuplicate(&gConfigGeneral.game_path, path); + if (config_save_default()) + { + Console::WriteFormat("Updating RCT2 path to '%s'.", path); + Console::WriteLine(); + Console::WriteLine("Updated config.ini"); + return EXITCODE_OK; + } + else + { + Console::Error::WriteLine("Unable to update config.ini"); + return EXITCODE_FAIL; + } +} + static void PrintAbout() { PrintVersion(); diff --git a/src/core/Path.cpp b/src/core/Path.cpp new file mode 100644 index 0000000000..8b4344d4da --- /dev/null +++ b/src/core/Path.cpp @@ -0,0 +1,52 @@ +extern "C" +{ + #include "../platform/platform.h" + #include "../localisation/localisation.h" + #include "../util/util.h" +} + +#include "Memory.hpp" +#include "Path.hpp" +#include "String.hpp" +#include "Util.hpp" + +namespace Path +{ + utf8 * Append(utf8 * buffer, size_t bufferSize, const utf8 * src) + { + return safe_strcat_path(buffer, src, bufferSize); + } + + utf8 * GetAbsolute(utf8 *buffer, size_t bufferSize, const utf8 * relativePath) + { +#if _WIN32 + wchar_t * relativePathW = utf8_to_widechar(relativePath); + wchar_t absolutePathW[MAX_PATH]; + DWORD length = GetFullPathNameW(relativePathW, Util::CountOf(absolutePathW), absolutePathW, NULL); + Memory::Free(relativePathW); + if (length == 0) + { + return String::Set(buffer, bufferSize, relativePath); + } + else + { + utf8 * absolutePath = widechar_to_utf8(absolutePathW); + String::Set(buffer, bufferSize, absolutePath); + Memory::Free(absolutePath); + return buffer; + } +#else + utf8 * absolutePath = realpath(relativePath, NULL); + if (absolutePath == nullptr) + { + return String::Set(buffer, bufferSize, relativePath); + } + else + { + String::Set(buffer, bufferSize, absolutePath); + Memory::Free(absolutePath); + return buffer; + } +#endif + } +} diff --git a/src/core/Path.hpp b/src/core/Path.hpp new file mode 100644 index 0000000000..cdc1bab230 --- /dev/null +++ b/src/core/Path.hpp @@ -0,0 +1,12 @@ +#pragma once + +extern "C" +{ + #include "../common.h" +} + +namespace Path +{ + utf8 * Append(utf8 * buffer, size_t bufferSize, const utf8 * src); + utf8 * GetAbsolute(utf8 *buffer, size_t bufferSize, const utf8 * relativePath); +} diff --git a/src/core/String.cpp b/src/core/String.cpp index 9c02161a35..543a892cfd 100644 --- a/src/core/String.cpp +++ b/src/core/String.cpp @@ -129,4 +129,16 @@ namespace String size_t srcSize = SizeOf(src); return Memory::DuplicateArray(src, srcSize + 1); } + + utf8 * DiscardUse(utf8 * * ptr, utf8 * replacement) + { + Memory::Free(*ptr); + *ptr = replacement; + return replacement; + } + + utf8 * DiscardDuplicate(utf8 * * ptr, utf8 * replacement) + { + return DiscardUse(ptr, String::Duplicate(replacement)); + } } diff --git a/src/core/String.hpp b/src/core/String.hpp index 98313ec1ce..b1dc24c720 100644 --- a/src/core/String.hpp +++ b/src/core/String.hpp @@ -17,4 +17,14 @@ namespace String utf8 * Format(utf8 * buffer, size_t bufferSize, const utf8 * format, ...); utf8 * AppendFormat(utf8 * buffer, size_t bufferSize, const utf8 * format, ...); utf8 * Duplicate(const utf8 * src); + + /** + * Helper method to free the string a string pointer points to and set it to a replacement string. + */ + utf8 * DiscardUse(utf8 * * ptr, utf8 * replacement); + + /** + * Helper method to free the string a string pointer points to and set it to a copy of a replacement string. + */ + utf8 * DiscardDuplicate(utf8 * * ptr, utf8 * replacement); } diff --git a/src/openrct2.c b/src/openrct2.c index 908e57f927..b54cd5a088 100644 --- a/src/openrct2.c +++ b/src/openrct2.c @@ -68,7 +68,6 @@ int _finished; static struct { sint16 x, y, z; } _spritelocations1[MAX_SPRITES], _spritelocations2[MAX_SPRITES]; static void openrct2_loop(); -static bool openrct2_setup_rct2_segment(); static void openrct2_setup_rct2_hooks(); void openrct2_write_full_version_info(utf8 *buffer, size_t bufferSize) @@ -475,7 +474,7 @@ void openrct2_reset_object_tween_locations() * Loads RCT2's data model and remaps the addresses. * @returns true if the data integrity check succeeded, otherwise false. */ -static bool openrct2_setup_rct2_segment() +bool openrct2_setup_rct2_segment() { // OpenRCT2 on Linux and OS X is wired to have the original Windows PE sections loaded // necessary. Windows does not need to do this as OpenRCT2 runs as a DLL loaded from the Windows PE. diff --git a/src/openrct2.h b/src/openrct2.h index e044e848f9..82eb77452a 100644 --- a/src/openrct2.h +++ b/src/openrct2.h @@ -54,6 +54,7 @@ void openrct2_launch(); void openrct2_dispose(); void openrct2_finish(); void openrct2_reset_object_tween_locations(); +bool openrct2_setup_rct2_segment(); int cmdline_run(const char **argv, int argc); From 02c03d225c7f3dd1e47d46db6c71b186e3ee0e21 Mon Sep 17 00:00:00 2001 From: LRFLEW Date: Tue, 12 Jan 2016 16:05:40 -0700 Subject: [PATCH 3/3] Added Path class to Xcode project --- OpenRCT2.xcodeproj/project.pbxproj | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/OpenRCT2.xcodeproj/project.pbxproj b/OpenRCT2.xcodeproj/project.pbxproj index f6e4ced2bc..59b8173a9d 100644 --- a/OpenRCT2.xcodeproj/project.pbxproj +++ b/OpenRCT2.xcodeproj/project.pbxproj @@ -22,6 +22,7 @@ D4B63B951C43028200367A37 /* Console.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D4B63B931C43028200367A37 /* Console.cpp */; }; D4B63B981C43028F00367A37 /* String.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D4B63B961C43028F00367A37 /* String.cpp */; }; D4B85B5B1C41C7F3005C568A /* cable_lift.c in Sources */ = {isa = PBXBuildFile; fileRef = D4B85B591C41C7F3005C568A /* cable_lift.c */; }; + D4D35E2C1C45BD9B00AAFCB4 /* Path.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D4D35E2A1C45BD9B00AAFCB4 /* Path.cpp */; }; D4D4DF141C34697B0048BE43 /* image_io.c in Sources */ = {isa = PBXBuildFile; fileRef = D4D4DF121C34697B0048BE43 /* image_io.c */; }; D4EC47DF1C26342F0024B507 /* addresses.c in Sources */ = {isa = PBXBuildFile; fileRef = D4EC46D61C26342F0024B507 /* addresses.c */; }; D4EC47E01C26342F0024B507 /* audio.c in Sources */ = {isa = PBXBuildFile; fileRef = D4EC46D91C26342F0024B507 /* audio.c */; }; @@ -237,6 +238,8 @@ D4B63B971C43028F00367A37 /* String.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = String.hpp; sourceTree = ""; }; D4B85B591C41C7F3005C568A /* cable_lift.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cable_lift.c; sourceTree = ""; }; D4B85B5A1C41C7F3005C568A /* cable_lift.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cable_lift.h; sourceTree = ""; }; + D4D35E2A1C45BD9B00AAFCB4 /* Path.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Path.cpp; sourceTree = ""; }; + D4D35E2B1C45BD9B00AAFCB4 /* Path.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Path.hpp; sourceTree = ""; }; D4D4DF121C34697B0048BE43 /* image_io.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = image_io.c; path = src/image_io.c; sourceTree = ""; }; D4D4DF131C34697B0048BE43 /* image_io.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = image_io.h; path = src/image_io.h; sourceTree = ""; }; D4EC46D61C26342F0024B507 /* addresses.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = addresses.c; path = src/addresses.c; sourceTree = ""; }; @@ -726,6 +729,8 @@ D4EC46E91C26342F0024B507 /* IStream.hpp */, D4EC46EA1C26342F0024B507 /* Math.hpp */, D4EC46EB1C26342F0024B507 /* Memory.hpp */, + D4D35E2A1C45BD9B00AAFCB4 /* Path.cpp */, + D4D35E2B1C45BD9B00AAFCB4 /* Path.hpp */, D4B63B961C43028F00367A37 /* String.cpp */, D4B63B971C43028F00367A37 /* String.hpp */, D4EC46EC1C26342F0024B507 /* StringBuilder.hpp */, @@ -1354,6 +1359,7 @@ D4EC484F1C26342F0024B507 /* options.c in Sources */, D4EC485C1C26342F0024B507 /* shortcut_keys.c in Sources */, D4EC481A1C26342F0024B507 /* posix.c in Sources */, + D4D35E2C1C45BD9B00AAFCB4 /* Path.cpp in Sources */, D4B63B981C43028F00367A37 /* String.cpp in Sources */, D4EC47E31C26342F0024B507 /* cmdline_sprite.c in Sources */, D4EC48611C26342F0024B507 /* text_input.c in Sources */,