diff --git a/src/openrct2-ui/windows/ScenarioSelect.cpp b/src/openrct2-ui/windows/ScenarioSelect.cpp index de308cfc2f..2c9c552169 100644 --- a/src/openrct2-ui/windows/ScenarioSelect.cpp +++ b/src/openrct2-ui/windows/ScenarioSelect.cpp @@ -26,6 +26,9 @@ #include #include #include +#include +#include +#include #include #include #include @@ -190,45 +193,77 @@ namespace OpenRCT2::Ui::Windows auto& bgWorker = GetContext()->GetBackgroundWorker(); auto& path = _highlightedScenario->Path; + auto& name = _highlightedScenario->InternalName; - _previewLoadJob = bgWorker.addJob( - [path]() { - try - { - auto fs = FileStream(path, FileMode::open); + ClassifiedFileInfo info; + if (!TryClassifyFile(path, &info)) + return; - ClassifiedFileInfo info; - if (!TryClassifyFile(&fs, &info)) - return ParkPreview{}; - - if (info.Type == FileType::park) + if (info.Type == FileType::park) + { + _previewLoadJob = bgWorker.addJob( + [path, name]() { + try { + auto fs = FileStream(path, FileMode::open); auto& objectRepository = GetContext()->GetObjectRepository(); auto parkImporter = ParkImporter::CreateParkFile(objectRepository); parkImporter->LoadFromStream(&fs, false, true, path.c_str()); return parkImporter->GetParkPreview(); } - else + catch (const std::exception& e) { + LOG_ERROR("Could not get preview for \"%s\" due to %s", path.c_str(), e.what()); return ParkPreview{}; } - } - catch (const std::exception& e) - { - LOG_ERROR("Could not get preview for \"%s\" due to %s", path.c_str(), e.what()); - return ParkPreview{}; - } - }, - [](const ParkPreview preview) { - auto* windowMgr = GetWindowManager(); - auto* wnd = windowMgr->FindByClass(WindowClass::ScenarioSelect); - if (wnd == nullptr) - { + }, + [](const ParkPreview preview) { + auto* windowMgr = GetWindowManager(); + auto* wnd = windowMgr->FindByClass(WindowClass::ScenarioSelect); + if (wnd == nullptr) + { + return; + } + auto* scenarioSelectWnd = static_cast(wnd); + scenarioSelectWnd->UpdateParkPreview(preview); + }); + } + else if (info.Type == FileType::scenario) + { + SourceDescriptor source{}; + if (!ScenarioSources::TryGetByName(name, &source)) + return; + + auto& objManager = GetContext()->GetObjectManager(); + + // Unload current scenario meta object if it's not the one we need + auto* loadedObject = objManager.GetLoadedObject(ObjectType::scenarioMeta, 0); + if (loadedObject != nullptr && loadedObject->GetIdentifier() != source.textObjectId) + { + objManager.UnloadObjects({ loadedObject->GetDescriptor() }); + loadedObject = nullptr; + } + + // Load the relevant scenario meta file if it hasn't been loaded yet + if (loadedObject == nullptr) + { + loadedObject = objManager.LoadObject(source.textObjectId); + if (loadedObject == nullptr) return; - } - auto* scenarioSelectWnd = static_cast(wnd); - scenarioSelectWnd->UpdateParkPreview(preview); - }); + } + + auto* scenarioMetaObj = reinterpret_cast(loadedObject); + + ParkPreview preview{}; + preview.images.push_back(scenarioMetaObj->GetMiniMapImage()); + preview.images.push_back(scenarioMetaObj->GetPreviewImage()); + + _preview = preview; + } + else + { + return; + } } void UpdateParkPreview(const ParkPreview& preview) diff --git a/src/openrct2/object/ScenarioMetaObject.cpp b/src/openrct2/object/ScenarioMetaObject.cpp index 20f5075ab6..816ed18614 100644 --- a/src/openrct2/object/ScenarioMetaObject.cpp +++ b/src/openrct2/object/ScenarioMetaObject.cpp @@ -51,12 +51,36 @@ std::string ScenarioMetaObject::GetScenarioDetails() return GetStringTable().GetString(ObjectStringID::SCENARIO_DETAILS); } -ImageIndex ScenarioMetaObject::GetMiniMapImageIndex() const +PreviewImage ScenarioMetaObject::GetMiniMapImage() const { - return _imageOffsetId; + PreviewImage preview{}; + preview.type = PreviewImageType::miniMap; + + auto* g1 = GfxGetG1Element(_imageOffsetId); + if (g1 == nullptr) + return preview; + + preview.width = g1->width; + preview.height = g1->height; + + std::copy_n(g1->offset, g1->width * g1->height, preview.pixels); + + return preview; } -ImageIndex ScenarioMetaObject::GetPreviewImageIndex() const +PreviewImage ScenarioMetaObject::GetPreviewImage() const { - return _imageOffsetId + 1; + PreviewImage preview{}; + preview.type = PreviewImageType::screenshot; + + auto* g1 = GfxGetG1Element(_imageOffsetId + 1); + if (g1 == nullptr) + return preview; + + preview.width = g1->width; + preview.height = g1->height; + + std::copy_n(g1->offset, g1->width * g1->height, preview.pixels); + + return preview; } diff --git a/src/openrct2/object/ScenarioMetaObject.h b/src/openrct2/object/ScenarioMetaObject.h index fbea3b41d9..8a568703b4 100644 --- a/src/openrct2/object/ScenarioMetaObject.h +++ b/src/openrct2/object/ScenarioMetaObject.h @@ -10,6 +10,7 @@ #pragma once #include "../core/IStream.hpp" +#include "../park/ParkPreview.h" #include "Object.h" #include @@ -30,6 +31,6 @@ public: std::string GetParkName(); std::string GetScenarioDetails(); - ImageIndex GetMiniMapImageIndex() const; - ImageIndex GetPreviewImageIndex() const; + OpenRCT2::PreviewImage GetMiniMapImage() const; + OpenRCT2::PreviewImage GetPreviewImage() const; };