From 031daceb6cbffde005dab6e8301f66de79466305 Mon Sep 17 00:00:00 2001 From: Silent Date: Tue, 7 Jan 2025 19:12:55 +0100 Subject: [PATCH 1/2] EditorObjectSelectionWindow: Remove MAX_PATH --- .../windows/EditorObjectSelection.cpp | 127 +++++++----------- 1 file changed, 46 insertions(+), 81 deletions(-) diff --git a/src/openrct2-ui/windows/EditorObjectSelection.cpp b/src/openrct2-ui/windows/EditorObjectSelection.cpp index 3846d3e415..71312385ac 100644 --- a/src/openrct2-ui/windows/EditorObjectSelection.cpp +++ b/src/openrct2-ui/windows/EditorObjectSelection.cpp @@ -107,16 +107,6 @@ namespace OpenRCT2::Ui::Windows static constexpr uint8_t _numSourceGameItems = 8; - static uint32_t _filter_flags; - static uint16_t _filter_object_counts[EnumValue(ObjectType::count)]; - - static char _filter_string[MAX_PATH]; - - static bool isFilterActive(const uint16_t filter) - { - return (_filter_flags & filter) == filter; - } - static constexpr StringId WINDOW_TITLE = STR_OBJECT_SELECTION; static constexpr int32_t WH = 400; static constexpr int32_t WW = 600; @@ -267,6 +257,8 @@ namespace OpenRCT2::Ui::Windows int32_t _listSortType = RIDE_SORT_TYPE; bool _listSortDescending = false; std::unique_ptr _loadedObject; + u8string _filter; + uint32_t _filterFlags = FILTER_RIDES_ALL; uint8_t _selectedSubTab = 0; public: @@ -281,10 +273,8 @@ namespace OpenRCT2::Ui::Windows Sub6AB211(); ResetSelectedObjectCountAndSize(); - widgets[WIDX_FILTER_TEXT_BOX].string = _filter_string; - - _filter_flags = FILTER_RIDES_ALL | Config::Get().interface.ObjectSelectionFilterFlags; - std::fill_n(_filter_string, sizeof(_filter_string), 0x00); + _filterFlags = FILTER_RIDES_ALL | Config::Get().interface.ObjectSelectionFilterFlags; + _filter.clear(); WindowInitScrollWidgets(*this); @@ -406,13 +396,12 @@ namespace OpenRCT2::Ui::Windows auto& currentPage = ObjectSelectionPages[selected_tab]; auto& subTabDef = currentPage.subTabs[_selectedSubTab]; - _filter_flags &= ~FILTER_RIDES_ALL; - _filter_flags |= subTabDef.flagFilter; + _filterFlags &= ~FILTER_RIDES_ALL; + _filterFlags |= subTabDef.flagFilter; - Config::Get().interface.ObjectSelectionFilterFlags = _filter_flags; + Config::Get().interface.ObjectSelectionFilterFlags = _filterFlags; Config::Save(); - FilterUpdateCounts(); VisibleListRefresh(); selected_list_item = -1; @@ -436,11 +425,10 @@ namespace OpenRCT2::Ui::Windows break; } case WIDX_FILTER_TEXT_BOX: - WindowStartTextbox(*this, widgetIndex, _filter_string, sizeof(_filter_string)); + WindowStartTextbox(*this, widgetIndex, _filter, kTextInputSize); break; case WIDX_FILTER_CLEAR_BUTTON: - std::fill_n(_filter_string, sizeof(_filter_string), 0x00); - FilterUpdateCounts(); + _filter.clear(); scrolls->contentOffsetY = 0; VisibleListRefresh(); Invalidate(); @@ -535,7 +523,7 @@ namespace OpenRCT2::Ui::Windows for (int32_t i = 0; i < _numSourceGameItems; i++) { - if (_filter_flags & (1 << i)) + if (_filterFlags & (1 << i)) { Dropdown::SetChecked(i, true); } @@ -543,8 +531,8 @@ namespace OpenRCT2::Ui::Windows if (!(gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER)) { - Dropdown::SetChecked(DDIX_FILTER_SELECTED, isFilterActive(FILTER_SELECTED)); - Dropdown::SetChecked(DDIX_FILTER_NONSELECTED, isFilterActive(FILTER_NONSELECTED)); + Dropdown::SetChecked(DDIX_FILTER_SELECTED, IsFilterActive(FILTER_SELECTED)); + Dropdown::SetChecked(DDIX_FILTER_NONSELECTED, IsFilterActive(FILTER_NONSELECTED)); } break; } @@ -560,22 +548,21 @@ namespace OpenRCT2::Ui::Windows case WIDX_FILTER_DROPDOWN_BTN: if (dropdownIndex == DDIX_FILTER_SELECTED) { - _filter_flags ^= FILTER_SELECTED; - _filter_flags &= ~FILTER_NONSELECTED; + _filterFlags ^= FILTER_SELECTED; + _filterFlags &= ~FILTER_NONSELECTED; } else if (dropdownIndex == DDIX_FILTER_NONSELECTED) { - _filter_flags ^= FILTER_NONSELECTED; - _filter_flags &= ~FILTER_SELECTED; + _filterFlags ^= FILTER_NONSELECTED; + _filterFlags &= ~FILTER_SELECTED; } else { - _filter_flags ^= (1 << dropdownIndex); + _filterFlags ^= (1 << dropdownIndex); } - Config::Get().interface.ObjectSelectionFilterFlags = _filter_flags; + Config::Get().interface.ObjectSelectionFilterFlags = _filterFlags; Config::Save(); - FilterUpdateCounts(); scrolls->contentOffsetY = 0; VisibleListRefresh(); @@ -659,9 +646,8 @@ namespace OpenRCT2::Ui::Windows return; } - if (isFilterActive(FILTER_SELECTED) || isFilterActive(FILTER_NONSELECTED)) + if (IsFilterActive(FILTER_SELECTED) || IsFilterActive(FILTER_NONSELECTED)) { - FilterUpdateCounts(); VisibleListRefresh(); Invalidate(); } @@ -830,15 +816,10 @@ namespace OpenRCT2::Ui::Windows if (widgetIndex != WIDX_FILTER_TEXT_BOX) return; - std::string tempText = text.data(); - const char* c = tempText.c_str(); - - if (strcmp(_filter_string, c) == 0) + if (text == _filter) return; - String::safeUtf8Copy(_filter_string, c, sizeof(_filter_string)); - - FilterUpdateCounts(); + _filter.assign(text); scrolls->contentOffsetY = 0; @@ -893,10 +874,10 @@ namespace OpenRCT2::Ui::Windows ft.Add(currentPage.Caption); // Set filter dropdown caption - if (!isFilterActive(FILTER_SOURCES_ALL)) + if (!IsFilterActive(FILTER_SOURCES_ALL)) { // Only one source active? - uint32_t sources = _filter_flags & FILTER_SOURCES_ALL; + uint32_t sources = _filterFlags & FILTER_SOURCES_ALL; auto numSourcesActive = std::popcount(sources); if (numSourcesActive == 1) { @@ -951,6 +932,7 @@ namespace OpenRCT2::Ui::Windows widgets[WIDX_FILTER_TEXT_BOX].right = widgets[WIDX_LIST].right - 77; widgets[WIDX_FILTER_TEXT_BOX].top = (hasSubTabs ? 79 : 48); widgets[WIDX_FILTER_TEXT_BOX].bottom = (hasSubTabs ? 92 : 61); + widgets[WIDX_FILTER_TEXT_BOX].string = _filter.data(); widgets[WIDX_FILTER_CLEAR_BUTTON].left = widgets[WIDX_LIST].right - 73; widgets[WIDX_FILTER_CLEAR_BUTTON].right = widgets[WIDX_LIST].right; @@ -1157,7 +1139,7 @@ namespace OpenRCT2::Ui::Windows selected_tab = _page; _selectedSubTab = 0; - _filter_flags |= FILTER_RIDES_ALL; + _filterFlags |= FILTER_RIDES_ALL; selected_list_item = -1; scrolls[0].contentOffsetY = 0; frame_no = 0; @@ -1423,15 +1405,15 @@ namespace OpenRCT2::Ui::Windows { return true; } - if (isFilterActive(FILTER_SELECTED) == isFilterActive(FILTER_NONSELECTED)) + if (IsFilterActive(FILTER_SELECTED) == IsFilterActive(FILTER_NONSELECTED)) { return true; } - if (isFilterActive(FILTER_SELECTED) && (objectFlag & ObjectSelectionFlags::Selected)) + if (IsFilterActive(FILTER_SELECTED) && (objectFlag & ObjectSelectionFlags::Selected)) { return true; } - if (isFilterActive(FILTER_NONSELECTED) && !(objectFlag & ObjectSelectionFlags::Selected)) + if (IsFilterActive(FILTER_NONSELECTED) && !(objectFlag & ObjectSelectionFlags::Selected)) { return true; } @@ -1445,6 +1427,11 @@ namespace OpenRCT2::Ui::Windows return !(item.Flags & ObjectItemFlags::IsCompatibilityObject) || (objectFlag & ObjectSelectionFlags::Selected); } + bool IsFilterActive(const uint16_t filter) const + { + return (_filterFlags & filter) == filter; + } + static bool IsFilterInName(const ObjectRepositoryItem& item, std::string_view filter) { return String::contains(item.Name, filter, true); @@ -1481,25 +1468,24 @@ namespace OpenRCT2::Ui::Windows bool FilterString(const ObjectRepositoryItem& item) { // Nothing to search for - std::string_view filter = _filter_string; - if (filter.empty()) + if (_filter.empty()) return true; - return IsFilterInName(item, filter) || IsFilterInRideType(item, filter) || IsFilterInFilename(item, filter) - || IsFilterInAuthor(item, filter); + return IsFilterInName(item, _filter) || IsFilterInRideType(item, _filter) || IsFilterInFilename(item, _filter) + || IsFilterInAuthor(item, _filter); } bool SourcesMatch(ObjectSourceGame source) { // clang-format off - return (isFilterActive(FILTER_RCT1) && source == ObjectSourceGame::RCT1) || - (isFilterActive(FILTER_AA) && source == ObjectSourceGame::AddedAttractions) || - (isFilterActive(FILTER_LL) && source == ObjectSourceGame::LoopyLandscapes) || - (isFilterActive(FILTER_RCT2) && source == ObjectSourceGame::RCT2) || - (isFilterActive(FILTER_WW) && source == ObjectSourceGame::WackyWorlds) || - (isFilterActive(FILTER_TT) && source == ObjectSourceGame::TimeTwister) || - (isFilterActive(FILTER_OO) && source == ObjectSourceGame::OpenRCT2Official) || - (isFilterActive(FILTER_CUSTOM) && + return (IsFilterActive(FILTER_RCT1) && source == ObjectSourceGame::RCT1) || + (IsFilterActive(FILTER_AA) && source == ObjectSourceGame::AddedAttractions) || + (IsFilterActive(FILTER_LL) && source == ObjectSourceGame::LoopyLandscapes) || + (IsFilterActive(FILTER_RCT2) && source == ObjectSourceGame::RCT2) || + (IsFilterActive(FILTER_WW) && source == ObjectSourceGame::WackyWorlds) || + (IsFilterActive(FILTER_TT) && source == ObjectSourceGame::TimeTwister) || + (IsFilterActive(FILTER_OO) && source == ObjectSourceGame::OpenRCT2Official) || + (IsFilterActive(FILTER_CUSTOM) && source != ObjectSourceGame::RCT1 && source != ObjectSourceGame::AddedAttractions && source != ObjectSourceGame::LoopyLandscapes && @@ -1512,7 +1498,7 @@ namespace OpenRCT2::Ui::Windows bool FilterSource(const ObjectRepositoryItem* item) { - if (isFilterActive(FILTER_ALL)) + if (IsFilterActive(FILTER_ALL)) return true; for (auto source : item->Sources) @@ -1537,32 +1523,11 @@ namespace OpenRCT2::Ui::Windows break; } } - return (_filter_flags & (1 << (GetRideTypeDescriptor(rideType).Category + _numSourceGameItems))) != 0; + return (_filterFlags & (1 << (GetRideTypeDescriptor(rideType).Category + _numSourceGameItems))) != 0; } return true; } - void FilterUpdateCounts() - { - if (!isFilterActive(FILTER_ALL) || _filter_string[0] != '\0') - { - const auto& selectionFlags = _objectSelectionFlags; - std::fill(std::begin(_filter_object_counts), std::end(_filter_object_counts), 0); - - size_t numObjects = ObjectRepositoryGetItemsCount(); - const ObjectRepositoryItem* items = ObjectRepositoryGetItems(); - for (size_t i = 0; i < numObjects; i++) - { - const ObjectRepositoryItem* item = &items[i]; - if (FilterSource(item) && FilterString(*item) && FilterChunks(item) && FilterSelected(selectionFlags[i]) - && FilterCompatibilityObject(*item, selectionFlags[i])) - { - _filter_object_counts[EnumValue(item->Type)]++; - } - } - } - } - std::string ObjectGetDescription(const Object* object) { switch (object->GetObjectType()) From dd4f6a30361e9dd39c5dc86eb17bbd44e848758f Mon Sep 17 00:00:00 2001 From: Silent Date: Tue, 7 Jan 2025 19:44:04 +0100 Subject: [PATCH 2/2] Platform.Win32: Remove the last MAX_PATH --- src/openrct2/platform/Platform.Win32.cpp | 61 ++++++++++++------------ 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/src/openrct2/platform/Platform.Win32.cpp b/src/openrct2/platform/Platform.Win32.cpp index ed965b0ef1..fa275c8296 100644 --- a/src/openrct2/platform/Platform.Win32.cpp +++ b/src/openrct2/platform/Platform.Win32.cpp @@ -35,6 +35,7 @@ #include "Platform.h" #include + #include #include #include @@ -54,7 +55,8 @@ static constexpr wchar_t SINGLE_INSTANCE_MUTEX_NAME[] = L"RollerCoaster Tycoon 2 namespace OpenRCT2::Platform { static std::string WIN32_GetKnownFolderPath(REFKNOWNFOLDERID rfid); - static std::string WIN32_GetModuleFileNameW(HMODULE hModule); + static std::wstring WIN32_GetModuleFileNameW(HMODULE hModule); + static u8string WIN32_GetModuleFileNameUTF8(HMODULE hModule); std::string GetEnvironmentVariable(std::string_view name) { @@ -155,7 +157,7 @@ namespace OpenRCT2::Platform std::string GetCurrentExecutablePath() { - return WIN32_GetModuleFileNameW(nullptr); + return WIN32_GetModuleFileNameUTF8(nullptr); } std::string GetDocsPath() @@ -307,18 +309,25 @@ namespace OpenRCT2::Platform return path; } - static std::string WIN32_GetModuleFileNameW(HMODULE hModule) + static std::wstring WIN32_GetModuleFileNameW(HMODULE hModule) { - uint32_t wExePathCapacity = MAX_PATH; - std::unique_ptr wExePath; + uint32_t wExePathCapacity = 128; + std::wstring exePath; + uint32_t size; do { wExePathCapacity *= 2; - wExePath = std::make_unique(wExePathCapacity); - size = GetModuleFileNameW(hModule, wExePath.get(), wExePathCapacity); + exePath.resize(wExePathCapacity); + size = GetModuleFileNameW(hModule, exePath.data(), wExePathCapacity); } while (size >= wExePathCapacity); - return String::toUtf8(wExePath.get()); + exePath.resize(size); + return exePath; + } + + static u8string WIN32_GetModuleFileNameUTF8(HMODULE hModule) + { + return String::toUtf8(WIN32_GetModuleFileNameW(hModule)); } u8string StrDecompToPrecomp(u8string_view input) @@ -364,13 +373,8 @@ namespace OpenRCT2::Platform std::string_view extension, std::string_view fileTypeText, std::string_view commandText, std::string_view commandArgs, const uint32_t iconIndex) { - wchar_t exePathW[MAX_PATH]; - wchar_t dllPathW[MAX_PATH]; - - [[maybe_unused]] int32_t printResult; - - GetModuleFileNameW(nullptr, exePathW, static_cast(std::size(exePathW))); - GetModuleFileNameW(GetDLLModule(), dllPathW, static_cast(std::size(dllPathW))); + const std::wstring& exePathW = WIN32_GetModuleFileNameW(nullptr); + const std::wstring& dllPathW = WIN32_GetModuleFileNameW(GetDLLModule()); auto extensionW = String::toWideChar(extension); auto fileTypeTextW = String::toWideChar(fileTypeText); @@ -410,10 +414,8 @@ namespace OpenRCT2::Platform return false; } // [hRootKey\OpenRCT2.ext\DefaultIcon] - wchar_t szIconW[MAX_PATH]; - printResult = swprintf_s(szIconW, MAX_PATH, L"\"%s\",%d", dllPathW, iconIndex); - assert(printResult >= 0); - if (RegSetValueW(hKey, L"DefaultIcon", REG_SZ, szIconW, 0) != ERROR_SUCCESS) + const std::wstring szIconW = std::format(L"\"{}\",{}", dllPathW, iconIndex); + if (RegSetValueW(hKey, L"DefaultIcon", REG_SZ, szIconW.c_str(), 0) != ERROR_SUCCESS) { RegCloseKey(hKey); RegCloseKey(hRootKey); @@ -437,10 +439,8 @@ namespace OpenRCT2::Platform } // [hRootKey\OpenRCT2.sv6\shell\open\command] - wchar_t szCommandW[MAX_PATH]; - printResult = swprintf_s(szCommandW, MAX_PATH, L"\"%s\" %s", exePathW, commandArgsW.c_str()); - assert(printResult >= 0); - if (RegSetValueW(hKey, L"shell\\open\\command", REG_SZ, szCommandW, 0) != ERROR_SUCCESS) + const std::wstring szCommandW = std::format(L"\"{}\" {}", exePathW, commandArgsW); + if (RegSetValueW(hKey, L"shell\\open\\command", REG_SZ, szCommandW.c_str(), 0) != ERROR_SUCCESS) { RegCloseKey(hKey); RegCloseKey(hRootKey); @@ -857,23 +857,22 @@ namespace OpenRCT2::Platform if (RegSetKeyValueW(hClassKey, nullptr, L"URL Protocol", REG_SZ, "", 0) == ERROR_SUCCESS) { // [hRootKey\openrct2\shell\open\command] - wchar_t exePath[MAX_PATH]; - GetModuleFileNameW(nullptr, exePath, MAX_PATH); - - wchar_t buffer[512]; - swprintf_s(buffer, std::size(buffer), L"\"%s\" handle-uri \"%%1\"", exePath); - if (RegSetValueW(hClassKey, L"shell\\open\\command", REG_SZ, buffer, 0) == ERROR_SUCCESS) + const std::wstring& exePathW = WIN32_GetModuleFileNameW(nullptr); + const std::wstring handle_uri_string = std::format(L"\"{}\" handle-uri \"%1\"", exePathW); + if (RegSetValueW(hClassKey, L"shell\\open\\command", REG_SZ, handle_uri_string.c_str(), 0) + == ERROR_SUCCESS) { // Not compulsory, but gives the application a nicer name // [HKEY_CURRENT_USER\SOFTWARE\Classes\Local Settings\Software\Microsoft\Windows\Shell\MuiCache] HKEY hMuiCacheKey; if (RegCreateKeyW(hRootKey, MUI_CACHE, &hMuiCacheKey) == ERROR_SUCCESS) { - swprintf_s(buffer, std::size(buffer), L"%s.FriendlyAppName", exePath); + const std::wstring friendly_apl_name = std::format(L"{}.FriendlyAppName", exePathW); // mingw-w64 used to define RegSetKeyValueW's signature incorrectly // You need at least mingw-w64 5.0 including this commit: // https://sourceforge.net/p/mingw-w64/mingw-w64/ci/da9341980a4b70be3563ac09b5927539e7da21f7/ - RegSetKeyValueW(hMuiCacheKey, nullptr, buffer, REG_SZ, L"OpenRCT2", sizeof(L"OpenRCT2")); + RegSetKeyValueW( + hMuiCacheKey, nullptr, friendly_apl_name.c_str(), REG_SZ, L"OpenRCT2", sizeof(L"OpenRCT2")); } LOG_VERBOSE("URI protocol setup successful");