diff --git a/pcsx2-qt/AutoUpdaterDialog.cpp b/pcsx2-qt/AutoUpdaterDialog.cpp index 10f1ade9ad..32e7a1d7d7 100644 --- a/pcsx2-qt/AutoUpdaterDialog.cpp +++ b/pcsx2-qt/AutoUpdaterDialog.cpp @@ -57,7 +57,9 @@ #define UPDATE_PLATFORM_STR "Linux" #endif -#if _M_SSE >= 0x500 +#if MULTI_ISA_SHARED_COMPILATION +// #undef UPDATE_ADDITIONAL_TAGS +#elif _M_SSE >= 0x501 #define UPDATE_ADDITIONAL_TAGS "AVX2" #else #define UPDATE_ADDITIONAL_TAGS "SSE4" @@ -208,20 +210,26 @@ void AutoUpdaterDialog::getLatestReleaseComplete(QNetworkReply* reply) const QJsonArray platform_array(assets_object[UPDATE_PLATFORM_STR].toArray()); if (!platform_array.isEmpty()) { - // search for the correct file + QJsonObject best_asset; + int best_asset_score = 0; + + // search for usable files for (const QJsonValue& asset_value : platform_array) { const QJsonObject asset_object(asset_value.toObject()); const QJsonArray additional_tags_array(asset_object["additionalTags"].toArray()); - bool is_matching_asset = false; + bool is_symbols = false; + bool is_avx2 = false; + bool is_sse4 = false; bool is_qt_asset = false; + bool is_perfect_match = false; for (const QJsonValue& additional_tag : additional_tags_array) { const QString additional_tag_str(additional_tag.toString()); if (additional_tag_str == QStringLiteral("symbols")) { // we're not interested in symbols downloads - is_matching_asset = false; + is_symbols = true; break; } else if (additional_tag_str == QStringLiteral("Qt")) @@ -229,37 +237,57 @@ void AutoUpdaterDialog::getLatestReleaseComplete(QNetworkReply* reply) // found a qt build is_qt_asset = true; } - - // is this the right variant? + else if (additional_tag_str == QStringLiteral("SSE4")) + { + is_sse4 = true; + } + else if (additional_tag_str == QStringLiteral("AVX2")) + { + is_avx2 = true; + } +#ifdef UPDATE_ADDITIONAL_TAGS if (additional_tag_str == QStringLiteral(UPDATE_ADDITIONAL_TAGS)) { - // yep! found the right one. but keep checking in case it's symbols. - is_matching_asset = true; + // Found the same variant as what's currently running! But keep checking in case it's symbols. + is_perfect_match = true; } +#endif } - if (!is_qt_asset || !is_matching_asset) + if (!is_qt_asset || is_symbols || (!x86caps.hasAVX2 && is_avx2)) { // skip this asset continue; } - m_latest_version = data_object["version"].toString(); - m_latest_version_timestamp = QDateTime::fromString(data_object["publishedAt"].toString(), QStringLiteral("yyyy-MM-ddThh:mm:ss.zzzZ")); - m_download_url = asset_object["url"].toString(); - if (!m_latest_version.isEmpty() && !m_download_url.isEmpty()) - { - found_update_info = true; - break; - } + int score; + if (is_perfect_match) + score = 4; // #1 choice is the one matching this binary + else if (is_avx2) + score = 3; // Prefer AVX2 over SSE4 (support test was done above) + else if (is_sse4) + score = 2; // Prefer SSE4 over one with no tags at all else + score = 1; // Multi-ISA builds will have no tags, they'll only get picked because they're the only available build + + if (score > best_asset_score) { - reportError("missing version/download info"); + best_asset = std::move(asset_object); + best_asset_score = score; } } - if (!found_update_info) - reportError("matching asset not found"); + if (best_asset_score == 0) + { + reportError("no matching assets found"); + } + else + { + m_latest_version = data_object["version"].toString(); + m_latest_version_timestamp = QDateTime::fromString(data_object["publishedAt"].toString(), QStringLiteral("yyyy-MM-ddThh:mm:ss.zzzZ")); + m_download_url = best_asset["url"].toString(); + found_update_info = true; + } } else { diff --git a/pcsx2/CMakeLists.txt b/pcsx2/CMakeLists.txt index 65dccd72d8..7968980a8f 100644 --- a/pcsx2/CMakeLists.txt +++ b/pcsx2/CMakeLists.txt @@ -999,7 +999,7 @@ set(pcsx2IPUHeaders ) if(DISABLE_ADVANCE_SIMD) - target_compile_definitions(PCSX2 PRIVATE MULTI_ISA_SHARED_COMPILATION) + target_compile_definitions(PCSX2 PUBLIC MULTI_ISA_SHARED_COMPILATION) if(USE_GCC) target_link_options(PCSX2_FLAGS INTERFACE -Wno-odr) endif() diff --git a/updater/Updater.cpp b/updater/Updater.cpp index 8c20dada67..8c52356097 100644 --- a/updater/Updater.cpp +++ b/updater/Updater.cpp @@ -434,3 +434,19 @@ void Updater::RemoveUpdateZip() if (!FileSystem::DeleteFilePath(m_zip_path.c_str())) m_progress->DisplayFormattedError("Failed to remove update zip '%s'", m_zip_path.c_str()); } + +std::string Updater::FindPCSX2Exe() const +{ + for (const FileToUpdate& file : m_update_paths) + { + const std::string& name = file.destination_filename; + if (name.find(FS_OSPATH_SEPARATOR_CHARACTER) != name.npos) + continue; // Main exe is expected to be at the top level + if (!StringUtil::StartsWithNoCase(name, "pcsx2")) + continue; + if (!StringUtil::EndsWithNoCase(name, "exe")) + continue; + return name; + } + return {}; +} diff --git a/updater/Updater.h b/updater/Updater.h index fc5bf31a6c..1e2e28cfa3 100644 --- a/updater/Updater.h +++ b/updater/Updater.h @@ -42,6 +42,8 @@ public: void CleanupStagingDirectory(); void RemoveUpdateZip(); + std::string FindPCSX2Exe() const; + private: static bool RecursiveDeleteDirectory(const char* path); diff --git a/updater/Windows/WindowsUpdater.cpp b/updater/Windows/WindowsUpdater.cpp index 92df9eab29..753d3ada8d 100644 --- a/updater/Windows/WindowsUpdater.cpp +++ b/updater/Windows/WindowsUpdater.cpp @@ -453,7 +453,7 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLi const int parent_process_id = StringUtil::FromChars(StringUtil::WideStringToUTF8String(argv[1])).value_or(0); const std::string destination_directory = StringUtil::WideStringToUTF8String(argv[2]); const std::string zip_path = StringUtil::WideStringToUTF8String(argv[3]); - const std::wstring program_to_launch(argv[4]); + std::wstring program_to_launch(argv[4]); argv.reset(); if (parent_process_id <= 0 || destination_directory.empty() || zip_path.empty() || program_to_launch.empty()) @@ -493,6 +493,7 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLi return 1; } + DeleteFileW(program_to_launch.c_str()); // In case the new exe has a different name, delete the old one to prevent confusion if (!updater.CommitUpdate()) { progress.ModalError( @@ -505,6 +506,21 @@ int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLi progress.ModalInformation("Update complete."); + if (GetFileAttributesW(program_to_launch.c_str()) == INVALID_FILE_ATTRIBUTES) + { + // New executable doesn't match old, try to find the real one... + if (std::string actual_exe = updater.FindPCSX2Exe(); !actual_exe.empty()) + { + std::string full_path = destination_directory + FS_OSPATH_SEPARATOR_STR + actual_exe; + program_to_launch = StringUtil::UTF8StringToWideString(full_path); + } + else + { + progress.ModalError("Couldn't find PCSX2 in update package, please re-download a fresh version from GitHub."); + return 1; + } + } + progress.DisplayFormattedInformation("Launching '%s'...", StringUtil::WideStringToUTF8String(program_to_launch).c_str()); ShellExecuteW(nullptr, L"open", program_to_launch.c_str(), nullptr, nullptr, SW_SHOWNORMAL);