From a8e329ef99063866959c70a57bf6258bc94acde2 Mon Sep 17 00:00:00 2001 From: Ted John Date: Mon, 30 Jan 2017 21:32:58 +0000 Subject: [PATCH] Implement getting sc entries from SC4s --- src/openrct2/rct1/S4Importer.cpp | 42 ++++++++++++++++++++ src/openrct2/rct1/S4Importer.h | 2 + src/openrct2/scenario/ScenarioRepository.cpp | 33 ++++++++++----- 3 files changed, 66 insertions(+), 11 deletions(-) diff --git a/src/openrct2/rct1/S4Importer.cpp b/src/openrct2/rct1/S4Importer.cpp index b2e57adf64..2724a4279d 100644 --- a/src/openrct2/rct1/S4Importer.cpp +++ b/src/openrct2/rct1/S4Importer.cpp @@ -168,6 +168,48 @@ public: map_count_remaining_land_rights(); } + bool GetDetails(scenario_index_entry * dst) override + { + bool result = false; + Memory::Set(dst, 0, sizeof(scenario_index_entry)); + + source_desc desc; + if (ScenarioSources::TryGetById(_s4.scenario_slot_index, &desc)) + { + dst->category = desc.category; + dst->source_game = desc.source; + dst->source_index = desc.index; + dst->sc_id = desc.id; + + dst->objective_type = _s4.scenario_objective_type; + dst->objective_arg_1 = _s4.scenario_objective_years; + dst->objective_arg_2 = _s4.scenario_objective_currency; + dst->objective_arg_3 = _s4.scenario_objective_num_guests; + + std::string name = std::string(_s4.scenario_name, sizeof(_s4.scenario_name)); + std::string details; + rct_string_id localisedStringIds[3]; + if (language_get_localised_scenario_strings(desc.title, localisedStringIds)) + { + if (localisedStringIds[0] != STR_NONE) + { + name = String::ToStd(language_get_string(localisedStringIds[0])); + } + if (localisedStringIds[2] != STR_NONE) + { + details = String::ToStd(language_get_string(localisedStringIds[2])); + } + } + + String::Set(dst->name, sizeof(dst->name), name.c_str()); + String::Set(dst->details, sizeof(dst->details), details.c_str()); + + result = true; + } + + return result; + } + private: void Initialise() { diff --git a/src/openrct2/rct1/S4Importer.h b/src/openrct2/rct1/S4Importer.h index 84c2b9183c..64bb5df230 100644 --- a/src/openrct2/rct1/S4Importer.h +++ b/src/openrct2/rct1/S4Importer.h @@ -17,6 +17,7 @@ #pragma once #include "../common.h" +#include "../scenario/ScenarioRepository.h" /** * Interface to import RollerCoaster Tycoon 1 scenarios (*.SC4) and saved games (*.SV4). @@ -28,6 +29,7 @@ public: virtual void LoadSavedGame(const utf8 * path) abstract; virtual void LoadScenario(const utf8 * path) abstract; virtual void Import() abstract; + virtual bool GetDetails(scenario_index_entry * dst) abstract; }; IS4Importer * CreateS4Importer(); diff --git a/src/openrct2/scenario/ScenarioRepository.cpp b/src/openrct2/scenario/ScenarioRepository.cpp index 5c4a0ecb8b..d838e0387e 100644 --- a/src/openrct2/scenario/ScenarioRepository.cpp +++ b/src/openrct2/scenario/ScenarioRepository.cpp @@ -25,6 +25,7 @@ #include "../core/String.hpp" #include "../core/Util.hpp" #include "../PlatformEnvironment.h" +#include "../rct1/S4Importer.h" #include "../rct12/SawyerEncoding.h" #include "ScenarioRepository.h" #include "ScenarioSources.h" @@ -270,8 +271,8 @@ private: void AddScenario(const std::string &path, uint64 timestamp) { - rct_s6_info s6Info; - if (!GetScenarioInfo(path, &s6Info)) + scenario_index_entry entry; + if (!GetScenarioInfo(path, timestamp, &entry)) { return; } @@ -287,7 +288,7 @@ private: conflictPath = String::ToStd(existingEntry->path); // Overwrite existing entry with this one - *existingEntry = CreateNewScenarioEntry(path.c_str(), timestamp, &s6Info); + *existingEntry = entry; } else { @@ -298,7 +299,6 @@ private: } else { - scenario_index_entry entry = CreateNewScenarioEntry(path.c_str(), timestamp, &s6Info); _scenarios.push_back(entry); } } @@ -306,29 +306,40 @@ private: /** * Reads basic information from a scenario file. */ - bool GetScenarioInfo(const std::string &path, rct_s6_info * info) + bool GetScenarioInfo(const std::string &path, uint64 timestamp, scenario_index_entry * entry) { log_verbose("GetScenarioInfo(%s, ...)", path); try { - auto fs = FileStream(path, FILE_MODE_OPEN); - std::string extension = Path::GetExtension(path); if (String::Equals(extension, ".sc4", true)) { // RCT1 scenario - log_verbose("%s is an RCT1 scenario, not yet supported", path); + bool result = false; + IS4Importer * s4Importer = CreateS4Importer(); + s4Importer->LoadScenario(path.c_str()); + if (s4Importer->GetDetails(entry)) + { + String::Set(entry->path, sizeof(entry->path), path.c_str()); + entry->timestamp = timestamp; + result = true; + } + delete s4Importer; + return result; } else { // RCT2 scenario + auto fs = FileStream(path, FILE_MODE_OPEN); rct_s6_header header; if (SawyerEncoding::TryReadChunk(&header, &fs)) { if (header.type == S6_TYPE_SCENARIO) { - if (SawyerEncoding::TryReadChunk(info, &fs)) + rct_s6_info info; + if (SawyerEncoding::TryReadChunk(&info, &fs)) { + *entry = CreateNewScenarioEntry(path, timestamp, &info); return true; } else @@ -350,12 +361,12 @@ private: return false; } - scenario_index_entry CreateNewScenarioEntry(const utf8 * path, uint64 timestamp, rct_s6_info * s6Info) + scenario_index_entry CreateNewScenarioEntry(const std::string &path, uint64 timestamp, rct_s6_info * s6Info) { scenario_index_entry entry = { 0 }; // Set new entry - String::Set(entry.path, sizeof(entry.path), path); + String::Set(entry.path, sizeof(entry.path), path.c_str()); entry.timestamp = timestamp; entry.category = s6Info->category; entry.objective_type = s6Info->objective_type;