diff --git a/src/openrct2-ui/windows/Options.cpp b/src/openrct2-ui/windows/Options.cpp index 7960e6605a..5ca8942e7e 100644 --- a/src/openrct2-ui/windows/Options.cpp +++ b/src/openrct2-ui/windows/Options.cpp @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -45,7 +46,9 @@ #include #include +using namespace OpenRCT2; using namespace OpenRCT2::Audio; + namespace OpenRCT2::Ui::Windows { // clang-format off diff --git a/src/openrct2/config/Config.cpp b/src/openrct2/config/Config.cpp index 07a9aae467..fb259a60b6 100644 --- a/src/openrct2/config/Config.cpp +++ b/src/openrct2/config/Config.cpp @@ -26,7 +26,7 @@ #include "../network/network.h" #include "../paint/VirtualFloor.h" #include "../platform/Platform.h" -#include "../rct1/Limits.h" +#include "../rct1/Csg.h" #include "../scenario/Scenario.h" #include "../ui/UiContext.h" #include "../util/Util.h" @@ -944,78 +944,3 @@ bool ConfigFindOrBrowseInstallDirectory() return true; } - -std::string FindCsg1datAtLocation(u8string_view path) -{ - auto checkPath1 = Path::Combine(path, u8"Data", u8"CSG1.DAT"); - auto checkPath2 = Path::Combine(path, u8"Data", u8"CSG1.1"); - - // Since Linux is case sensitive (and macOS sometimes too), make sure we handle case properly. - std::string path1result = Path::ResolveCasing(checkPath1); - if (!path1result.empty()) - { - return path1result; - } - - std::string path2result = Path::ResolveCasing(checkPath2); - return path2result; -} - -bool Csg1datPresentAtLocation(u8string_view path) -{ - auto location = FindCsg1datAtLocation(path); - return !location.empty(); -} - -u8string FindCsg1idatAtLocation(u8string_view path) -{ - auto result1 = Path::ResolveCasing(Path::Combine(path, u8"Data", u8"CSG1I.DAT")); - if (!result1.empty()) - { - return result1; - } - auto result2 = Path::ResolveCasing(Path::Combine(path, u8"RCTdeluxe_install", u8"Data", u8"CSG1I.DAT")); - return result2; -} - -bool Csg1idatPresentAtLocation(u8string_view path) -{ - std::string location = FindCsg1idatAtLocation(path); - return !location.empty(); -} - -bool RCT1DataPresentAtLocation(u8string_view path) -{ - return Csg1datPresentAtLocation(path) && Csg1idatPresentAtLocation(path) && CsgAtLocationIsUsable(path); -} - -bool CsgIsUsable(const Gx& csg) -{ - return csg.header.total_size == RCT1::Limits::LL_CSG1_DAT_FileSize - && csg.header.num_entries == RCT1::Limits::Num_LL_CSG_Entries; -} - -bool CsgAtLocationIsUsable(u8string_view path) -{ - auto csg1HeaderPath = FindCsg1idatAtLocation(path); - if (csg1HeaderPath.empty()) - { - return false; - } - - auto csg1DataPath = FindCsg1datAtLocation(path); - if (csg1DataPath.empty()) - { - return false; - } - - auto fileHeader = FileStream(csg1HeaderPath, FILE_MODE_OPEN); - auto fileData = FileStream(csg1DataPath, FILE_MODE_OPEN); - size_t fileHeaderSize = fileHeader.GetLength(); - size_t fileDataSize = fileData.GetLength(); - - Gx csg = {}; - csg.header.num_entries = static_cast(fileHeaderSize / sizeof(RCTG1Element)); - csg.header.total_size = static_cast(fileDataSize); - return CsgIsUsable(csg); -} diff --git a/src/openrct2/config/Config.h b/src/openrct2/config/Config.h index 8206ed3602..6bcd921e76 100644 --- a/src/openrct2/config/Config.h +++ b/src/openrct2/config/Config.h @@ -14,9 +14,6 @@ #include "ConfigTypes.h" #include -#include - -struct Gx; struct GeneralConfiguration { @@ -229,11 +226,3 @@ u8string ConfigGetDefaultPath(); void ConfigSetDefaults(); bool ConfigSaveDefault(); bool ConfigFindOrBrowseInstallDirectory(); - -bool RCT1DataPresentAtLocation(u8string_view path); -std::string FindCsg1datAtLocation(u8string_view path); -bool Csg1datPresentAtLocation(u8string_view path); -std::string FindCsg1idatAtLocation(u8string_view path); -bool Csg1idatPresentAtLocation(u8string_view path); -bool CsgIsUsable(const Gx& csg); -bool CsgAtLocationIsUsable(u8string_view path); diff --git a/src/openrct2/drawing/Drawing.Sprite.cpp b/src/openrct2/drawing/Drawing.Sprite.cpp index b1eaee7d9f..0c0e2e2713 100644 --- a/src/openrct2/drawing/Drawing.Sprite.cpp +++ b/src/openrct2/drawing/Drawing.Sprite.cpp @@ -17,6 +17,7 @@ #include "../core/MemoryStream.h" #include "../core/Path.hpp" #include "../platform/Platform.h" +#include "../rct1/Csg.h" #include "../sprites.h" #include "../ui/UiContext.h" #include "../util/Util.h" diff --git a/src/openrct2/libopenrct2.vcxproj b/src/openrct2/libopenrct2.vcxproj index 3ab6981da5..83c72c269a 100644 --- a/src/openrct2/libopenrct2.vcxproj +++ b/src/openrct2/libopenrct2.vcxproj @@ -387,6 +387,7 @@ + @@ -896,6 +897,7 @@ + diff --git a/src/openrct2/rct1/Csg.cpp b/src/openrct2/rct1/Csg.cpp new file mode 100644 index 0000000000..db404f20c3 --- /dev/null +++ b/src/openrct2/rct1/Csg.cpp @@ -0,0 +1,92 @@ +/***************************************************************************** + * Copyright (c) 2014-2024 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#include "Csg.h" + +#include "../core/FileStream.h" +#include "../core/Path.hpp" +#include "../drawing/Drawing.h" +#include "../rct1/Limits.h" + +using namespace OpenRCT2; + +std::string FindCsg1datAtLocation(u8string_view path) +{ + auto checkPath1 = Path::Combine(path, u8"Data", u8"CSG1.DAT"); + auto checkPath2 = Path::Combine(path, u8"Data", u8"CSG1.1"); + + // Since Linux is case sensitive (and macOS sometimes too), make sure we handle case properly. + std::string path1result = Path::ResolveCasing(checkPath1); + if (!path1result.empty()) + { + return path1result; + } + + std::string path2result = Path::ResolveCasing(checkPath2); + return path2result; +} + +bool Csg1datPresentAtLocation(u8string_view path) +{ + auto location = FindCsg1datAtLocation(path); + return !location.empty(); +} + +u8string FindCsg1idatAtLocation(u8string_view path) +{ + auto result1 = Path::ResolveCasing(Path::Combine(path, u8"Data", u8"CSG1I.DAT")); + if (!result1.empty()) + { + return result1; + } + auto result2 = Path::ResolveCasing(Path::Combine(path, u8"RCTdeluxe_install", u8"Data", u8"CSG1I.DAT")); + return result2; +} + +bool Csg1idatPresentAtLocation(u8string_view path) +{ + std::string location = FindCsg1idatAtLocation(path); + return !location.empty(); +} + +bool RCT1DataPresentAtLocation(u8string_view path) +{ + return Csg1datPresentAtLocation(path) && Csg1idatPresentAtLocation(path) && CsgAtLocationIsUsable(path); +} + +bool CsgIsUsable(const Gx& csg) +{ + return csg.header.total_size == RCT1::Limits::LL_CSG1_DAT_FileSize + && csg.header.num_entries == RCT1::Limits::Num_LL_CSG_Entries; +} + +bool CsgAtLocationIsUsable(u8string_view path) +{ + auto csg1HeaderPath = FindCsg1idatAtLocation(path); + if (csg1HeaderPath.empty()) + { + return false; + } + + auto csg1DataPath = FindCsg1datAtLocation(path); + if (csg1DataPath.empty()) + { + return false; + } + + auto fileHeader = FileStream(csg1HeaderPath, FILE_MODE_OPEN); + auto fileData = FileStream(csg1DataPath, FILE_MODE_OPEN); + size_t fileHeaderSize = fileHeader.GetLength(); + size_t fileDataSize = fileData.GetLength(); + + Gx csg = {}; + csg.header.num_entries = static_cast(fileHeaderSize / sizeof(RCTG1Element)); + csg.header.total_size = static_cast(fileDataSize); + return CsgIsUsable(csg); +} diff --git a/src/openrct2/rct1/Csg.h b/src/openrct2/rct1/Csg.h new file mode 100644 index 0000000000..5f43c47900 --- /dev/null +++ b/src/openrct2/rct1/Csg.h @@ -0,0 +1,24 @@ +/***************************************************************************** + * Copyright (c) 2014-2024 OpenRCT2 developers + * + * For a complete list of all authors, please refer to contributors.md + * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2 + * + * OpenRCT2 is licensed under the GNU General Public License version 3. + *****************************************************************************/ + +#pragma once + +#include "../core/String.hpp" + +#include + +struct Gx; + +bool RCT1DataPresentAtLocation(u8string_view path); +std::string FindCsg1datAtLocation(u8string_view path); +bool Csg1datPresentAtLocation(u8string_view path); +std::string FindCsg1idatAtLocation(u8string_view path); +bool Csg1idatPresentAtLocation(u8string_view path); +bool CsgIsUsable(const Gx& csg); +bool CsgAtLocationIsUsable(u8string_view path);