diff --git a/src/PlatformEnvironment.cpp b/src/PlatformEnvironment.cpp index d2d0ed6248..0b3425c846 100644 --- a/src/PlatformEnvironment.cpp +++ b/src/PlatformEnvironment.cpp @@ -65,8 +65,12 @@ public: std::string GetFilePath(PATHID pathid) const override { - const utf8 * basePath = _basePath[(size_t)DIRBASE::USER].c_str(); const utf8 * fileName = FileNames[(size_t)pathid]; + const utf8 * basePath = _basePath[(size_t)DIRBASE::USER].c_str(); + if (pathid == PATHID::SCORES_RCT2) + { + basePath = _basePath[(size_t)DIRBASE::RCT2].c_str(); + } utf8 path[260]; String::Set(path, sizeof(path), basePath); @@ -138,4 +142,6 @@ const char * PlatformEnvironment::FileNames[] = "servers.cfg", // NETWORK_SERVERS "users.json", // NETWORK_USERS "highscores.dat", // SCORES + "scores.dat", // SCORES (LEGACY) + "Saved Games" PATH_SEPARATOR "scores.dat", // SCORES (RCT2) }; diff --git a/src/PlatformEnvironment.h b/src/PlatformEnvironment.h index 771dc0ebfd..b4afdc1380 100644 --- a/src/PlatformEnvironment.h +++ b/src/PlatformEnvironment.h @@ -55,6 +55,8 @@ enum class PATHID 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). }; /** diff --git a/src/ScenarioRepository.cpp b/src/ScenarioRepository.cpp index 39de3c989d..7ec4250e31 100644 --- a/src/ScenarioRepository.cpp +++ b/src/ScenarioRepository.cpp @@ -23,6 +23,7 @@ #include "core/Math.hpp" #include "core/Path.hpp" #include "core/String.hpp" +#include "PlatformEnvironment.h" #include "ScenarioRepository.h" #include "ScenarioSources.h" @@ -120,10 +121,16 @@ class ScenarioRepository final : public IScenarioRepository private: static constexpr uint32 HighscoreFileVersion = 1; + IPlatformEnvironment * _env; std::vector _scenarios; std::vector _highscores; public: + ScenarioRepository(IPlatformEnvironment * env) + { + _env = env; + } + virtual ~ScenarioRepository() { ClearHighscores(); @@ -131,17 +138,13 @@ public: void Scan() override { - utf8 directory[MAX_PATH]; - _scenarios.clear(); // Scan RCT2 directory - GetRCT2Directory(directory, sizeof(directory)); - Scan(directory); - - // Scan user directory - GetUserDirectory(directory, sizeof(directory)); - Scan(directory); + std::string rct2dir = _env->GetDirectoryPath(DIRBASE::RCT2, DIRID::SCENARIO); + std::string openrct2dir = _env->GetDirectoryPath(DIRBASE::OPENRCT2, DIRID::SCENARIO); + Scan(rct2dir); + Scan(openrct2dir); Sort(); LoadScores(); @@ -241,10 +244,10 @@ private: return (scenario_index_entry *)repo->GetByPath(path); } - void Scan(const utf8 * directory) + void Scan(const std::string &directory) { utf8 pattern[MAX_PATH]; - String::Set(pattern, sizeof(pattern), directory); + String::Set(pattern, sizeof(pattern), directory.c_str()); Path::Append(pattern, sizeof(pattern), "*.sc6"); IFileScanner * scanner = Path::ScanDirectory(pattern, true); @@ -362,16 +365,15 @@ private: void LoadScores() { - utf8 scoresPath[MAX_PATH]; - GetScoresPath(scoresPath, sizeof(scoresPath)); - if (!platform_file_exists(scoresPath)) + std::string path = _env->GetFilePath(PATHID::SCORES); + if (!platform_file_exists(path.c_str())) { return; } try { - auto fs = FileStream(scoresPath, FILE_MODE_OPEN); + auto fs = FileStream(path, FILE_MODE_OPEN); uint32 fileVersion = fs.ReadValue(); if (fileVersion != 1) { @@ -403,18 +405,15 @@ private: */ void LoadLegacyScores() { - utf8 scoresPath[MAX_PATH]; - - GetLegacyScoresPath(scoresPath, sizeof(scoresPath)); - LoadLegacyScores(scoresPath); - - GetRCT2ScoresPath(scoresPath, sizeof(scoresPath)); - LoadLegacyScores(scoresPath); + std::string rct2Path = _env->GetFilePath(PATHID::SCORES_RCT2); + std::string legacyPath = _env->GetFilePath(PATHID::SCORES_LEGACY); + LoadLegacyScores(legacyPath); + LoadLegacyScores(rct2Path); } - void LoadLegacyScores(const utf8 * path) + void LoadLegacyScores(const std::string &path) { - if (!platform_file_exists(path)) + if (!platform_file_exists(path.c_str())) { return; } @@ -512,12 +511,10 @@ private: void SaveHighscores() { - utf8 scoresPath[MAX_PATH]; - GetScoresPath(scoresPath, sizeof(scoresPath)); - + std::string path = _env->GetFilePath(PATHID::SCORES); try { - auto fs = FileStream(scoresPath, FILE_MODE_WRITE); + auto fs = FileStream(path, FILE_MODE_WRITE); fs.WriteValue(HighscoreFileVersion); fs.WriteValue((uint32)_highscores.size()); for (size_t i = 0; i < _highscores.size(); i++) @@ -531,7 +528,7 @@ private: } catch (Exception ex) { - Console::Error::WriteLine("Unable to save highscores to '%s'", scoresPath); + Console::Error::WriteLine("Unable to save highscores to '%s'", path); } } @@ -541,38 +538,25 @@ private: Path::Append(buffer, bufferSize, "Scenarios"); return buffer; } - - static utf8 * GetUserDirectory(utf8 * buffer, size_t bufferSize) - { - platform_get_user_directory(buffer, "scenario", bufferSize); - return buffer; - } - - static void GetScoresPath(utf8 * buffer, size_t bufferSize) - { - platform_get_user_directory(buffer, nullptr, bufferSize); - Path::Append(buffer, bufferSize, "highscores.dat"); - } - - static void GetLegacyScoresPath(utf8 * buffer, size_t bufferSize) - { - platform_get_user_directory(buffer, nullptr, bufferSize); - Path::Append(buffer, bufferSize, "scores.dat"); - } - - static void GetRCT2ScoresPath(utf8 * buffer, size_t bufferSize) - { - String::Set(buffer, bufferSize, get_file_path(PATH_ID_SCORES)); - } }; static std::unique_ptr _scenarioRepository; +IScenarioRepository * CreateScenarioRepository(IPlatformEnvironment * env) +{ + _scenarioRepository = std::unique_ptr(new ScenarioRepository(env)); + return _scenarioRepository.get(); +} + IScenarioRepository * GetScenarioRepository() { if (_scenarioRepository == nullptr) { - _scenarioRepository = std::unique_ptr(new ScenarioRepository()); + // TODO There should only be one platform environment which needs to be global. + // However it should be not be used here. Instead the object repository should be + // constructed in some initialisation method where it passes this dependency. + IPlatformEnvironment * env = CreatePlatformEnvironment(); + CreateScenarioRepository(env); } return _scenarioRepository.get(); } diff --git a/src/ScenarioRepository.h b/src/ScenarioRepository.h index 6a653bd44e..166d05e886 100644 --- a/src/ScenarioRepository.h +++ b/src/ScenarioRepository.h @@ -56,6 +56,8 @@ typedef struct scenario_index_entry #ifdef __cplusplus +interface IPlatformEnvironment; + interface IScenarioRepository { virtual ~IScenarioRepository() = default; @@ -73,6 +75,7 @@ interface IScenarioRepository virtual bool TryRecordHighscore(const utf8 * scenarioFileName, money32 companyValue, const utf8 * name) abstract; }; +IScenarioRepository * CreateScenarioRepository(IPlatformEnvironment * env); IScenarioRepository * GetScenarioRepository(); #endif