diff --git a/src/openrct2-ui/Ui.cpp b/src/openrct2-ui/Ui.cpp index 7d8fae6c3e..b5d4b23c82 100644 --- a/src/openrct2-ui/Ui.cpp +++ b/src/openrct2-ui/Ui.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include "audio/AudioContext.h" #include "Ui.h" @@ -49,9 +50,10 @@ int main(int argc, char * * argv) else { // Run OpenRCT2 with a UI context + auto env = CreatePlatformEnvironment(); auto audioContext = CreateAudioContext(); - auto uiContext = CreateUiContext(); - auto context = CreateContext(audioContext, uiContext); + auto uiContext = CreateUiContext(env); + auto context = CreateContext(env, audioContext, uiContext); context->RunOpenRCT2(argc, argv); diff --git a/src/openrct2-ui/UiContext.cpp b/src/openrct2-ui/UiContext.cpp index 4d2b980d98..d9e275b3b1 100644 --- a/src/openrct2-ui/UiContext.cpp +++ b/src/openrct2-ui/UiContext.cpp @@ -59,7 +59,8 @@ class UiContext final : public IUiContext private: constexpr static uint32 TOUCH_DOUBLE_TIMEOUT = 300; - IPlatformUiContext * const _platformUiContext; + IPlatformEnvironment * const _env; + IPlatformUiContext * const _platformUiContext; CursorRepository _cursorRepository; @@ -84,14 +85,18 @@ private: float _gestureRadius = 0; public: - UiContext() - : _platformUiContext(CreatePlatformUiContext()) + UiContext(IPlatformEnvironment * env) + : _env(env), + _platformUiContext(CreatePlatformUiContext()) { if (SDL_Init(SDL_INIT_VIDEO) < 0) { SDLException::Throw("SDL_Init(SDL_INIT_VIDEO)"); } _cursorRepository.LoadCursors(); + + // Temporary to prevent warning, will be used for keyboard shortcuts + UNUSED(_env); } ~UiContext() override @@ -690,7 +695,7 @@ private: } }; -IUiContext * OpenRCT2::Ui::CreateUiContext() +IUiContext * OpenRCT2::Ui::CreateUiContext(IPlatformEnvironment * env) { - return new UiContext(); + return new UiContext(env); } diff --git a/src/openrct2-ui/UiContext.h b/src/openrct2-ui/UiContext.h index d955df3097..4e8a706ca1 100644 --- a/src/openrct2-ui/UiContext.h +++ b/src/openrct2-ui/UiContext.h @@ -24,6 +24,7 @@ struct SDL_Window; namespace OpenRCT2 { interface IContext; + interface IPlatformEnvironment; namespace Ui { @@ -41,7 +42,7 @@ namespace OpenRCT2 virtual std::string ShowDirectoryDialog(SDL_Window * window, const std::string &title) abstract; }; - IUiContext * CreateUiContext(); + IUiContext * CreateUiContext(IPlatformEnvironment * env); IPlatformUiContext * CreatePlatformUiContext(); } } diff --git a/src/openrct2/Context.cpp b/src/openrct2/Context.cpp index 4397536bdf..2ec3bb7684 100644 --- a/src/openrct2/Context.cpp +++ b/src/openrct2/Context.cpp @@ -70,11 +70,11 @@ namespace OpenRCT2 constexpr static uint32 UPDATE_TIME_MS = 25; // Dependencies - IAudioContext * const _audioContext = nullptr; - IUiContext * const _uiContext = nullptr; + IPlatformEnvironment * const _env = nullptr; + IAudioContext * const _audioContext = nullptr; + IUiContext * const _uiContext = nullptr; // Services - IPlatformEnvironment * _env = nullptr; IObjectRepository * _objectRepository = nullptr; ITrackDesignRepository * _trackDesignRepository = nullptr; IScenarioRepository * _scenarioRepository = nullptr; @@ -93,8 +93,9 @@ namespace OpenRCT2 static Context * Instance; public: - Context(IAudioContext * audioContext, IUiContext * uiContext) - : _audioContext(audioContext), + Context(IPlatformEnvironment * env, IAudioContext * audioContext, IUiContext * uiContext) + : _env(env), + _audioContext(audioContext), _uiContext(uiContext) { Instance = this; @@ -151,13 +152,6 @@ namespace OpenRCT2 crash_init(); - // Sets up the environment OpenRCT2 is running in, e.g. directory paths - _env = SetupEnvironment(); - if (_env == nullptr) - { - return false; - } - if (!rct2_interop_setup_segment()) { log_fatal("Unable to load RCT2 data sector"); @@ -237,64 +231,6 @@ namespace OpenRCT2 } private: - IPlatformEnvironment * SetupEnvironment() - { - utf8 userPath[MAX_PATH]; - platform_resolve_openrct_data_path(); - platform_resolve_user_data_path(); - platform_get_user_directory(userPath, NULL, sizeof(userPath)); - if (!platform_ensure_directory_exists(userPath)) - { - Console::Error::WriteLine("Could not create user directory (do you have write access to your documents folder?)"); - return nullptr; - } - platform_get_exe_path(gExePath, sizeof(gExePath)); - log_verbose("Setting exe path to %s", gExePath); - - config_set_defaults(); - if (!config_open_default()) - { - if (!config_find_or_browse_install_directory()) - { - gConfigGeneral.last_run_version = String::Duplicate(OPENRCT2_VERSION); - config_save_default(); - utf8 path[MAX_PATH]; - config_get_default_path(path, sizeof(path)); - Console::Error::WriteLine("An RCT2 install directory must be specified! Please edit \"game_path\" in %s.", path); - return nullptr; - } - config_save_default(); - } - - if (!rct2_init_directories()) - { - return nullptr; - } - if (!rct2_startup_checks()) - { - return nullptr; - } - - utf8 path[260]; - std::string basePaths[4]; - basePaths[(size_t)DIRBASE::RCT1] = String::ToStd(gConfigGeneral.rct1_path); - basePaths[(size_t)DIRBASE::RCT2] = String::ToStd(gConfigGeneral.rct2_path); - platform_get_openrct_data_path(path, sizeof(path)); - basePaths[(size_t)DIRBASE::OPENRCT2] = std::string(path); - platform_get_user_directory(path, nullptr, sizeof(path)); - basePaths[(size_t)DIRBASE::USER] = std::string(path); - - IPlatformEnvironment * env = CreatePlatformEnvironment(basePaths); - - // Log base paths - log_verbose("DIRBASE::RCT1 : %s", env->GetDirectoryPath(DIRBASE::RCT1).c_str()); - log_verbose("DIRBASE::RCT2 : %s", env->GetDirectoryPath(DIRBASE::RCT2).c_str()); - log_verbose("DIRBASE::OPENRCT2: %s", env->GetDirectoryPath(DIRBASE::OPENRCT2).c_str()); - log_verbose("DIRBASE::USER : %s", env->GetDirectoryPath(DIRBASE::USER).c_str()); - - return env; - } - /** * Launches the game, after command line arguments have been parsed and processed. */ @@ -564,18 +500,20 @@ namespace OpenRCT2 class PlainContext final : public Context { - std::unique_ptr _audioContext; - std::unique_ptr _uiContext; + std::unique_ptr _env; + std::unique_ptr _audioContext; + std::unique_ptr _uiContext; public: PlainContext() - : PlainContext(CreateDummyAudioContext(), CreateDummyUiContext()) + : PlainContext(CreatePlatformEnvironment(), CreateDummyAudioContext(), CreateDummyUiContext()) { } - PlainContext(IAudioContext * audioContext, IUiContext * uiContext) - : Context(audioContext, uiContext) + PlainContext(IPlatformEnvironment * env, IAudioContext * audioContext, IUiContext * uiContext) + : Context(env, audioContext, uiContext) { + _env = std::unique_ptr(env); _audioContext = std::unique_ptr(audioContext); _uiContext = std::unique_ptr(uiContext); } @@ -588,9 +526,9 @@ namespace OpenRCT2 return new PlainContext(); } - IContext * CreateContext(Audio::IAudioContext * audioContext, IUiContext * uiContext) + IContext * CreateContext(IPlatformEnvironment * env, Audio::IAudioContext * audioContext, IUiContext * uiContext) { - return new Context(audioContext, uiContext); + return new Context(env, audioContext, uiContext); } IContext * GetContext() diff --git a/src/openrct2/Context.h b/src/openrct2/Context.h index 737732d647..62cee65864 100644 --- a/src/openrct2/Context.h +++ b/src/openrct2/Context.h @@ -59,6 +59,8 @@ enum namespace OpenRCT2 { + interface IPlatformEnvironment; + namespace Audio { interface IAudioContext; @@ -86,7 +88,7 @@ namespace OpenRCT2 }; IContext * CreateContext(); - IContext * CreateContext(Audio::IAudioContext * audioContext, Ui::IUiContext * uiContext); + IContext * CreateContext(IPlatformEnvironment * env, Audio::IAudioContext * audioContext, Ui::IUiContext * uiContext); IContext * GetContext(); } diff --git a/src/openrct2/PlatformEnvironment.cpp b/src/openrct2/PlatformEnvironment.cpp index 51920f59fa..86dd4a59b5 100644 --- a/src/openrct2/PlatformEnvironment.cpp +++ b/src/openrct2/PlatformEnvironment.cpp @@ -14,17 +14,24 @@ *****************************************************************************/ #pragma endregion +#include "config/Config.h" +#include "core/Console.hpp" #include "core/Exception.hpp" #include "core/Guard.hpp" #include "core/Path.hpp" #include "core/String.hpp" +#include "OpenRCT2.h" #include "PlatformEnvironment.h" +#include "Version.h" extern "C" { #include "platform/platform.h" + #include "rct2.h" } +using namespace OpenRCT2; + class PlatformEnvironment final : public IPlatformEnvironment { private: @@ -84,11 +91,69 @@ private: static const char * FileNames[]; }; -IPlatformEnvironment * CreatePlatformEnvironment(DIRBASE_VALUES basePaths) +IPlatformEnvironment * OpenRCT2::CreatePlatformEnvironment(DIRBASE_VALUES basePaths) { return new PlatformEnvironment(basePaths); } +IPlatformEnvironment * OpenRCT2::CreatePlatformEnvironment() +{ + utf8 userPath[MAX_PATH]; + platform_resolve_openrct_data_path(); + platform_resolve_user_data_path(); + platform_get_user_directory(userPath, NULL, sizeof(userPath)); + if (!platform_ensure_directory_exists(userPath)) + { + Console::Error::WriteLine("Could not create user directory (do you have write access to your documents folder?)"); + return nullptr; + } + platform_get_exe_path(gExePath, sizeof(gExePath)); + log_verbose("Setting exe path to %s", gExePath); + + config_set_defaults(); + if (!config_open_default()) + { + if (!config_find_or_browse_install_directory()) + { + gConfigGeneral.last_run_version = String::Duplicate(OPENRCT2_VERSION); + config_save_default(); + utf8 path[MAX_PATH]; + config_get_default_path(path, sizeof(path)); + Console::Error::WriteLine("An RCT2 install directory must be specified! Please edit \"game_path\" in %s.", path); + return nullptr; + } + config_save_default(); + } + + if (!rct2_init_directories()) + { + return nullptr; + } + if (!rct2_startup_checks()) + { + return nullptr; + } + + utf8 path[260]; + std::string basePaths[4]; + basePaths[(size_t)DIRBASE::RCT1] = String::ToStd(gConfigGeneral.rct1_path); + basePaths[(size_t)DIRBASE::RCT2] = String::ToStd(gConfigGeneral.rct2_path); + platform_get_openrct_data_path(path, sizeof(path)); + basePaths[(size_t)DIRBASE::OPENRCT2] = std::string(path); + platform_get_user_directory(path, nullptr, sizeof(path)); + basePaths[(size_t)DIRBASE::USER] = std::string(path); + + IPlatformEnvironment * env = OpenRCT2::CreatePlatformEnvironment(basePaths); + + // Log base paths + log_verbose("DIRBASE::RCT1 : %s", env->GetDirectoryPath(DIRBASE::RCT1).c_str()); + log_verbose("DIRBASE::RCT2 : %s", env->GetDirectoryPath(DIRBASE::RCT2).c_str()); + log_verbose("DIRBASE::OPENRCT2: %s", env->GetDirectoryPath(DIRBASE::OPENRCT2).c_str()); + log_verbose("DIRBASE::USER : %s", env->GetDirectoryPath(DIRBASE::USER).c_str()); + + return env; +} + const char * PlatformEnvironment::DirectoryNamesRCT2[] = { "Data", // DATA diff --git a/src/openrct2/PlatformEnvironment.h b/src/openrct2/PlatformEnvironment.h index 76a28912b6..a1aa05c308 100644 --- a/src/openrct2/PlatformEnvironment.h +++ b/src/openrct2/PlatformEnvironment.h @@ -19,58 +19,62 @@ #include #include "common.h" -enum class DIRBASE : sint32 +namespace OpenRCT2 { - RCT1, // Base directory for original RollerCoaster Tycoon 1 content. - RCT2, // Base directory for original RollerCoaster Tycoon 2 content. - OPENRCT2, // Base directory for OpenRCT2 installation. - USER, // Base directory for OpenRCT2 user content. -}; -constexpr sint32 DIRBASE_COUNT = 4; -using DIRBASE_VALUES = std::string[DIRBASE_COUNT]; + enum class DIRBASE : sint32 + { + RCT1, // Base directory for original RollerCoaster Tycoon 1 content. + RCT2, // Base directory for original RollerCoaster Tycoon 2 content. + OPENRCT2, // Base directory for OpenRCT2 installation. + USER, // Base directory for OpenRCT2 user content. + }; + constexpr sint32 DIRBASE_COUNT = 4; + using DIRBASE_VALUES = std::string[DIRBASE_COUNT]; -enum class DIRID -{ - DATA, // Contains g1.dat, music etc. - LANDSCAPE, // Contains scenario editor landscapes (SC6). - LANGUAGE, // Contains language packs. - LOG_CHAT, // Contains chat logs. - LOG_SERVER, // Contains server logs. - NETWORK_KEY, // Contains the user's public and private keys. - OBJECT, // Contains objects. - SAVE, // Contains saved games (SV6). - SCENARIO, // Contains scenarios (SC6). - SCREENSHOT, // Contains screenshots. - SEQUENCE, // Contains title sequences. - SHADER, // Contains OpenGL shaders. - THEME, // Contains interface themes. - TRACK, // Contains track designs. -}; + enum class DIRID + { + DATA, // Contains g1.dat, music etc. + LANDSCAPE, // Contains scenario editor landscapes (SC6). + LANGUAGE, // Contains language packs. + LOG_CHAT, // Contains chat logs. + LOG_SERVER, // Contains server logs. + NETWORK_KEY, // Contains the user's public and private keys. + OBJECT, // Contains objects. + SAVE, // Contains saved games (SV6). + SCENARIO, // Contains scenarios (SC6). + SCREENSHOT, // Contains screenshots. + SEQUENCE, // Contains title sequences. + SHADER, // Contains OpenGL shaders. + THEME, // Contains interface themes. + TRACK, // Contains track designs. + }; -enum class PATHID -{ - CONFIG, // Main configuration (config.ini). - CONFIG_KEYBOARD, // Keyboard shortcuts. (hotkeys.cfg) - CACHE_OBJECTS, // Object repository cache (objects.idx). - CACHE_TRACKS, // Track repository cache (tracks.idx). - NETWORK_GROUPS, // Server groups with permissions (groups.json). - NETWORK_SERVERS, // Saved servers (servers.cfg). - NETWORK_USERS, // Users and their groups (users.json). - SCORES, // Scenario scores (highscores.dat). - SCORES_LEGACY, // Scenario scores, legacy (scores.dat). - SCORES_RCT2, // Scenario scores, rct2 (\Saved Games\scores.dat). -}; + enum class PATHID + { + CONFIG, // Main configuration (config.ini). + CONFIG_KEYBOARD, // Keyboard shortcuts. (hotkeys.cfg) + CACHE_OBJECTS, // Object repository cache (objects.idx). + CACHE_TRACKS, // Track repository cache (tracks.idx). + NETWORK_GROUPS, // Server groups with permissions (groups.json). + NETWORK_SERVERS, // Saved servers (servers.cfg). + NETWORK_USERS, // Users and their groups (users.json). + SCORES, // Scenario scores (highscores.dat). + SCORES_LEGACY, // Scenario scores, legacy (scores.dat). + SCORES_RCT2, // Scenario scores, rct2 (\Saved Games\scores.dat). + }; -/** - * Interface for retrieving paths and other environment related things. - */ -interface IPlatformEnvironment -{ - virtual ~IPlatformEnvironment() = default; + /** + * Interface for retrieving paths and other environment related things. + */ + interface IPlatformEnvironment + { + virtual ~IPlatformEnvironment() = default; - virtual std::string GetDirectoryPath(DIRBASE base) const abstract; - virtual std::string GetDirectoryPath(DIRBASE base, DIRID did) const abstract; - virtual std::string GetFilePath(PATHID pathid) const abstract; -}; + virtual std::string GetDirectoryPath(DIRBASE base) const abstract; + virtual std::string GetDirectoryPath(DIRBASE base, DIRID did) const abstract; + virtual std::string GetFilePath(PATHID pathid) const abstract; + }; -IPlatformEnvironment * CreatePlatformEnvironment(DIRBASE_VALUES basePaths); + IPlatformEnvironment * CreatePlatformEnvironment(DIRBASE_VALUES basePaths); + IPlatformEnvironment * CreatePlatformEnvironment(); +} diff --git a/src/openrct2/network/network.cpp b/src/openrct2/network/network.cpp index bb98b15f3f..6f65c3c895 100644 --- a/src/openrct2/network/network.cpp +++ b/src/openrct2/network/network.cpp @@ -74,6 +74,8 @@ extern "C" { #pragma comment(lib, "Ws2_32.lib") +using namespace OpenRCT2; + Network gNetwork; enum { diff --git a/src/openrct2/network/network.h b/src/openrct2/network/network.h index 58a264d8e1..857df75997 100644 --- a/src/openrct2/network/network.h +++ b/src/openrct2/network/network.h @@ -85,15 +85,19 @@ enum { NETWORK_TICK_FLAG_CHECKSUMS = 1 << 0, }; -interface IPlatformEnvironment; -struct ObjectRepositoryItem; +struct ObjectRepositoryItem; + +namespace OpenRCT2 +{ + interface IPlatformEnvironment; +} class Network { public: Network(); ~Network(); - void SetEnvironment(IPlatformEnvironment * env); + void SetEnvironment(OpenRCT2::IPlatformEnvironment * env); bool Init(); void Close(); bool BeginClient(const char* host, uint16 port); @@ -231,7 +235,7 @@ private: std::string _chatLogFilenameFormat = "%Y%m%d-%H%M%S.txt"; std::string _serverLogPath; std::string _serverLogFilenameFormat = "-%Y%m%d-%H%M%S.txt"; - IPlatformEnvironment * _env; + OpenRCT2::IPlatformEnvironment * _env; void UpdateServer(); void UpdateClient(); diff --git a/src/openrct2/object/ObjectRepository.cpp b/src/openrct2/object/ObjectRepository.cpp index 5ba2ddb533..a8d780f98d 100644 --- a/src/openrct2/object/ObjectRepository.cpp +++ b/src/openrct2/object/ObjectRepository.cpp @@ -53,6 +53,8 @@ extern "C" #include "../util/util.h" } +using namespace OpenRCT2; + constexpr uint16 OBJECT_REPOSITORY_VERSION = 10; #pragma pack(push, 1) diff --git a/src/openrct2/object/ObjectRepository.h b/src/openrct2/object/ObjectRepository.h index 0db506d28b..0ebc14f8a5 100644 --- a/src/openrct2/object/ObjectRepository.h +++ b/src/openrct2/object/ObjectRepository.h @@ -32,9 +32,12 @@ extern "C" #endif #ifdef __cplusplus - interface IPlatformEnvironment; interface IStream; class Object; + namespace OpenRCT2 + { + interface IPlatformEnvironment; + } #else typedef struct Object Object; #endif @@ -87,7 +90,7 @@ interface IObjectRepository virtual void WritePackedObjects(IStream * stream, std::vector &objects) abstract; }; -IObjectRepository * CreateObjectRepository(IPlatformEnvironment * env); +IObjectRepository * CreateObjectRepository(OpenRCT2::IPlatformEnvironment * env); IObjectRepository * GetObjectRepository(); bool IsObjectCustom(const ObjectRepositoryItem * object); diff --git a/src/openrct2/ride/TrackDesignRepository.cpp b/src/openrct2/ride/TrackDesignRepository.cpp index 05d919cfac..444f29837c 100644 --- a/src/openrct2/ride/TrackDesignRepository.cpp +++ b/src/openrct2/ride/TrackDesignRepository.cpp @@ -36,6 +36,8 @@ extern "C" #include "track_design.h" } +using namespace OpenRCT2; + #pragma pack(push, 1) struct TrackRepositoryHeader { diff --git a/src/openrct2/ride/TrackDesignRepository.h b/src/openrct2/ride/TrackDesignRepository.h index 08b4183f54..8fa5ac0319 100644 --- a/src/openrct2/ride/TrackDesignRepository.h +++ b/src/openrct2/ride/TrackDesignRepository.h @@ -28,7 +28,10 @@ typedef struct track_design_file_ref #include -interface IPlatformEnvironment; +namespace OpenRCT2 +{ + interface IPlatformEnvironment; +} interface ITrackDesignRepository { @@ -46,7 +49,7 @@ interface ITrackDesignRepository virtual std::string Install(const std::string &path) abstract; }; -ITrackDesignRepository * CreateTrackDesignRepository(IPlatformEnvironment * env); +ITrackDesignRepository * CreateTrackDesignRepository(OpenRCT2::IPlatformEnvironment * env); ITrackDesignRepository * GetTrackDesignRepository(); #endif diff --git a/src/openrct2/scenario/ScenarioRepository.cpp b/src/openrct2/scenario/ScenarioRepository.cpp index 0954db2f2f..b0d89666e6 100644 --- a/src/openrct2/scenario/ScenarioRepository.cpp +++ b/src/openrct2/scenario/ScenarioRepository.cpp @@ -39,6 +39,8 @@ extern "C" #include "scenario.h" } +using namespace OpenRCT2; + static sint32 ScenarioCategoryCompare(sint32 categoryA, sint32 categoryB) { if (categoryA == categoryB) return 0; diff --git a/src/openrct2/scenario/ScenarioRepository.h b/src/openrct2/scenario/ScenarioRepository.h index d005b99a9c..bb790cacee 100644 --- a/src/openrct2/scenario/ScenarioRepository.h +++ b/src/openrct2/scenario/ScenarioRepository.h @@ -56,7 +56,10 @@ typedef struct scenario_index_entry #ifdef __cplusplus -interface IPlatformEnvironment; +namespace OpenRCT2 +{ + interface IPlatformEnvironment; +} interface IScenarioRepository { @@ -75,7 +78,7 @@ interface IScenarioRepository virtual bool TryRecordHighscore(const utf8 * scenarioFileName, money32 companyValue, const utf8 * name) abstract; }; -IScenarioRepository * CreateScenarioRepository(IPlatformEnvironment * env); +IScenarioRepository * CreateScenarioRepository(OpenRCT2::IPlatformEnvironment * env); IScenarioRepository * GetScenarioRepository(); #endif