diff --git a/.ci/windows/install-msvc.ps1 b/.ci/windows/install-msvc.ps1 index 788b2848ad..d1dcb33ada 100755 --- a/.ci/windows/install-msvc.ps1 +++ b/.ci/windows/install-msvc.ps1 @@ -1,60 +1,60 @@ -# SPDX-FileCopyrightText: 2025 Eden Emulator Project -# SPDX-License-Identifier: GPL-3.0-or-later - -$ErrorActionPreference = "Stop" - -# Check if running as administrator -if (-not ([bool](net session 2>$null))) { - Write-Host "This script must be run with administrator privileges!" - Exit 1 -} - -$VSVer = "17" -$ExeFile = "vs_community.exe" -$Uri = "https://aka.ms/vs/$VSVer/release/$ExeFile" -$Destination = "./$ExeFile" - -Write-Host "Downloading Visual Studio Build Tools from $Uri" -$WebClient = New-Object System.Net.WebClient -$WebClient.DownloadFile($Uri, $Destination) -Write-Host "Finished downloading $ExeFile" - -$Arguments = @( - "--quiet", # Suppress installer UI - "--wait", # Wait for installation to complete - "--norestart", # Prevent automatic restart - "--force", # Force installation even if components are already installed - "--add Microsoft.VisualStudio.Workload.NativeDesktop", # Desktop development with C++ - "--add Microsoft.VisualStudio.Component.VC.Tools.x86.x64", # Core C++ compiler/tools for x86/x64 - "--add Microsoft.VisualStudio.Component.Windows11SDK.26100",# Windows 11 SDK (26100) - "--add Microsoft.VisualStudio.Component.Windows10SDK.19041",# Windows 10 SDK (19041) - "--add Microsoft.VisualStudio.Component.VC.Llvm.Clang", # LLVM Clang compiler - "--add Microsoft.VisualStudio.Component.VC.Llvm.ClangToolset", # LLVM Clang integration toolset - "--add Microsoft.VisualStudio.Component.Windows11SDK.22621",# Windows 11 SDK (22621) - "--add Microsoft.VisualStudio.Component.VC.CMake.Project", # CMake project support - "--add Microsoft.VisualStudio.ComponentGroup.VC.Tools.142.x86.x64", # VC++ 14.2 toolset - "--add Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Llvm.Clang" # LLVM Clang for native desktop -) - -Write-Host "Installing Visual Studio Build Tools" -$InstallProcess = Start-Process -FilePath $Destination -NoNewWindow -PassThru -ArgumentList $Arguments - -# Spinner while installing -$Spinner = "|/-\" -$i = 0 -while (-not $InstallProcess.HasExited) { - Write-Host -NoNewline ("`rInstalling... " + $Spinner[$i % $Spinner.Length]) - Start-Sleep -Milliseconds 250 - $i++ -} - -# Clear spinner line -Write-Host "`rSetup completed! " - -$ExitCode = $InstallProcess.ExitCode -if ($ExitCode -ne 0) { - Write-Host "Error installing Visual Studio Build Tools (Error: $ExitCode)" - Exit $ExitCode -} - -Write-Host "Finished installing Visual Studio Build Tools" +# SPDX-FileCopyrightText: 2025 Eden Emulator Project +# SPDX-License-Identifier: GPL-3.0-or-later + +$ErrorActionPreference = "Stop" + +# Check if running as administrator +if (-not ([bool](net session 2>$null))) { + Write-Host "This script must be run with administrator privileges!" + Exit 1 +} + +$VSVer = "17" +$ExeFile = "vs_community.exe" +$Uri = "https://aka.ms/vs/$VSVer/release/$ExeFile" +$Destination = "./$ExeFile" + +Write-Host "Downloading Visual Studio Build Tools from $Uri" +$WebClient = New-Object System.Net.WebClient +$WebClient.DownloadFile($Uri, $Destination) +Write-Host "Finished downloading $ExeFile" + +$Arguments = @( + "--quiet", # Suppress installer UI + "--wait", # Wait for installation to complete + "--norestart", # Prevent automatic restart + "--force", # Force installation even if components are already installed + "--add Microsoft.VisualStudio.Workload.NativeDesktop", # Desktop development with C++ + "--add Microsoft.VisualStudio.Component.VC.Tools.x86.x64", # Core C++ compiler/tools for x86/x64 + "--add Microsoft.VisualStudio.Component.Windows11SDK.26100",# Windows 11 SDK (26100) + "--add Microsoft.VisualStudio.Component.Windows10SDK.19041",# Windows 10 SDK (19041) + "--add Microsoft.VisualStudio.Component.VC.Llvm.Clang", # LLVM Clang compiler + "--add Microsoft.VisualStudio.Component.VC.Llvm.ClangToolset", # LLVM Clang integration toolset + "--add Microsoft.VisualStudio.Component.Windows11SDK.22621",# Windows 11 SDK (22621) + "--add Microsoft.VisualStudio.Component.VC.CMake.Project", # CMake project support + "--add Microsoft.VisualStudio.ComponentGroup.VC.Tools.142.x86.x64", # VC++ 14.2 toolset + "--add Microsoft.VisualStudio.ComponentGroup.NativeDesktop.Llvm.Clang" # LLVM Clang for native desktop +) + +Write-Host "Installing Visual Studio Build Tools" +$InstallProcess = Start-Process -FilePath $Destination -NoNewWindow -PassThru -ArgumentList $Arguments + +# Spinner while installing +$Spinner = "|/-\" +$i = 0 +while (-not $InstallProcess.HasExited) { + Write-Host -NoNewline ("`rInstalling... " + $Spinner[$i % $Spinner.Length]) + Start-Sleep -Milliseconds 250 + $i++ +} + +# Clear spinner line +Write-Host "`rSetup completed! " + +$ExitCode = $InstallProcess.ExitCode +if ($ExitCode -ne 0) { + Write-Host "Error installing Visual Studio Build Tools (Error: $ExitCode)" + Exit $ExitCode +} + +Write-Host "Finished installing Visual Studio Build Tools" diff --git a/.patch/httplib/0001-mingw.patch b/.patch/httplib/0001-mingw.patch new file mode 100644 index 0000000000..fa3e53a88c --- /dev/null +++ b/.patch/httplib/0001-mingw.patch @@ -0,0 +1,52 @@ +From e1a946ffb79022d38351a0623f819a5419965c3e Mon Sep 17 00:00:00 2001 +From: crueter +Date: Fri, 24 Oct 2025 23:41:09 -0700 +Subject: [PATCH] [build] Fix MinGW missing GetAddrInfoExCancel definition + +MinGW does not define GetAddrInfoExCancel in its wstcpi whatever header, +so to get around this we can just load it with GetProcAddress et al. + +Signed-off-by: crueter +--- + httplib.h | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/httplib.h b/httplib.h +index e15ba44..90a76dc 100644 +--- a/httplib.h ++++ b/httplib.h +@@ -203,11 +203,13 @@ + #error Sorry, Visual Studio versions prior to 2015 are not supported + #endif + +-#pragma comment(lib, "ws2_32.lib") +- + using ssize_t = __int64; + #endif // _MSC_VER + ++#if defined(_MSC_VER) || defined(__MINGW32__) ++#pragma comment(lib, "ws2_32.lib") ++#endif ++ + #ifndef S_ISREG + #define S_ISREG(m) (((m) & S_IFREG) == S_IFREG) + #endif // S_ISREG +@@ -3557,7 +3559,15 @@ inline int getaddrinfo_with_timeout(const char *node, const char *service, + auto wait_result = + ::WaitForSingleObject(event, static_cast(timeout_sec * 1000)); + if (wait_result == WAIT_TIMEOUT) { ++#ifdef __MINGW32__ ++ typedef INT (WSAAPI *PFN_GETADDRINFOEXCANCEL)(HANDLE *CancelHandle); ++ auto wsdll = LoadLibraryW((wchar_t*) "ws2_32.lib"); ++ PFN_GETADDRINFOEXCANCEL GetAddrInfoExCancel = (PFN_GETADDRINFOEXCANCEL) GetProcAddress(wsdll, "GetAddrInfoExCancel"); ++ ++ if (cancel_handle) { GetAddrInfoExCancel(&cancel_handle); } ++#else + if (cancel_handle) { ::GetAddrInfoExCancel(&cancel_handle); } ++#endif + ::CloseHandle(event); + return EAI_AGAIN; + } +-- +2.51.0 + diff --git a/CMakeModules/MSVCCache.cmake b/CMakeModules/MSVCCache.cmake index ba0d22d9ee..a4770862fe 100644 --- a/CMakeModules/MSVCCache.cmake +++ b/CMakeModules/MSVCCache.cmake @@ -1,15 +1,15 @@ -# SPDX-FileCopyrightText: 2022 yuzu Emulator Project -# SPDX-License-Identifier: GPL-3.0-or-later - -# buildcache wrapper -OPTION(USE_CCACHE "Use buildcache for compilation" OFF) -IF(USE_CCACHE) - FIND_PROGRAM(CCACHE buildcache) - IF (CCACHE) - MESSAGE(STATUS "Using buildcache found in PATH") - SET_PROPERTY(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE}) - SET_PROPERTY(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE}) - ELSE(CCACHE) - MESSAGE(WARNING "USE_CCACHE enabled, but no buildcache executable found") - ENDIF(CCACHE) -ENDIF(USE_CCACHE) +# SPDX-FileCopyrightText: 2022 yuzu Emulator Project +# SPDX-License-Identifier: GPL-3.0-or-later + +# buildcache wrapper +OPTION(USE_CCACHE "Use buildcache for compilation" OFF) +IF(USE_CCACHE) + FIND_PROGRAM(CCACHE buildcache) + IF (CCACHE) + MESSAGE(STATUS "Using buildcache found in PATH") + SET_PROPERTY(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ${CCACHE}) + SET_PROPERTY(GLOBAL PROPERTY RULE_LAUNCH_LINK ${CCACHE}) + ELSE(CCACHE) + MESSAGE(WARNING "USE_CCACHE enabled, but no buildcache executable found") + ENDIF(CCACHE) +ENDIF(USE_CCACHE) diff --git a/externals/cpmfile.json b/externals/cpmfile.json index 6056a5be24..73cdf3e305 100644 --- a/externals/cpmfile.json +++ b/externals/cpmfile.json @@ -30,7 +30,10 @@ "tag": "v%VERSION%", "hash": "b364500f76e2ecb0fe21b032d831272e3f1dfeea71af74e325f8fc4ce9dcdb3c941b97a5b422bdeafb9facd058597b90f8bfc284fb9afe3c33fefa15dd5a010b", "git_version": "0.26.0", - "find_args": "MODULE GLOBAL" + "find_args": "MODULE GLOBAL", + "patches": [ + "0001-mingw.patch" + ] }, "cpp-jwt": { "version": "1.4", diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt index 96046af916..42c93b0a5f 100644 --- a/src/core/CMakeLists.txt +++ b/src/core/CMakeLists.txt @@ -1201,7 +1201,7 @@ endif() target_link_libraries(core PRIVATE fmt::fmt nlohmann_json::nlohmann_json RenderDoc::API MbedTLS::mbedcrypto MbedTLS::mbedtls) if (MINGW) - target_link_libraries(core PRIVATE ${MSWSOCK_LIBRARY}) + target_link_libraries(core PRIVATE ws2_32 mswsock wlanapi) endif() if (ENABLE_WEB_SERVICE) diff --git a/src/core/hle/service/mm/mm_u.cpp b/src/core/hle/service/mm/mm_u.cpp index 8fa2341ffb..da9fbc98fc 100644 --- a/src/core/hle/service/mm/mm_u.cpp +++ b/src/core/hle/service/mm/mm_u.cpp @@ -7,43 +7,43 @@ #include "core/hle/service/server_manager.h" #include "core/hle/service/sm/sm.h" -#include - +#include + namespace Service::MM { -enum class Module : u32 { - CPU = 0, - GPU = 1, - EMC = 2, - SYS_BUS = 3, - M_SELECT = 4, - NVDEC = 5, - NVENC = 6, - NVJPG = 7, - TEST = 8 -}; - -class Session { -public: - Session(Module module_, u32 request_id_, bool is_auto_clear_event_) { - this->module = module_; - this->request_id = request_id_; - this->is_auto_clear_event = is_auto_clear_event_; - this->min = 0; - this->max = -1; - }; - -public: - Module module; - u32 request_id, min; - s32 max; - bool is_auto_clear_event; - - void SetAndWait(u32 min_, s32 max_) { - this->min = min_; - this->max = max_; - } -}; - +enum class Module : u32 { + CPU = 0, + GPU = 1, + EMC = 2, + SYS_BUS = 3, + M_SELECT = 4, + NVDEC = 5, + NVENC = 6, + NVJPG = 7, + TEST = 8 +}; + +class Session { +public: + Session(Module module_, u32 request_id_, bool is_auto_clear_event_) { + this->module = module_; + this->request_id = request_id_; + this->is_auto_clear_event = is_auto_clear_event_; + this->min = 0; + this->max = -1; + }; + +public: + Module module; + u32 request_id, min; + s32 max; + bool is_auto_clear_event; + + void SetAndWait(u32 min_, s32 max_) { + this->min = min_; + this->max = max_; + } +}; + class MM_U final : public ServiceFramework { public: explicit MM_U(Core::System& system_) : ServiceFramework{system_, "mm:u"} { @@ -65,53 +65,53 @@ public: private: void InitializeOld(HLERequestContext& ctx) { - LOG_DEBUG(Service_MM, "(STUBBED) called"); - - IPC::RequestParser rp{ctx}; - const auto module = rp.PopEnum(); - rp.Pop(); - const auto event_clear_mode = rp.Pop(); - - const bool is_auto_clear_event = event_clear_mode == 1; - - sessions.push_back({module, request_id++, is_auto_clear_event}); - + LOG_DEBUG(Service_MM, "(STUBBED) called"); + + IPC::RequestParser rp{ctx}; + const auto module = rp.PopEnum(); + rp.Pop(); + const auto event_clear_mode = rp.Pop(); + + const bool is_auto_clear_event = event_clear_mode == 1; + + sessions.push_back({module, request_id++, is_auto_clear_event}); + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void FinalizeOld(HLERequestContext& ctx) { - LOG_DEBUG(Service_MM, "(STUBBED) called"); - - IPC::RequestParser rp{ctx}; - const auto module = rp.PopEnum(); - - for (auto it = sessions.begin(); it != sessions.end(); ++it) { - if (it->module == module) { - sessions.erase(it); - break; - } - } + LOG_DEBUG(Service_MM, "(STUBBED) called"); + + IPC::RequestParser rp{ctx}; + const auto module = rp.PopEnum(); + + for (auto it = sessions.begin(); it != sessions.end(); ++it) { + if (it->module == module) { + sessions.erase(it); + break; + } + } IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void SetAndWaitOld(HLERequestContext& ctx) { - LOG_DEBUG(Service_MM, "(STUBBED) called"); - + LOG_DEBUG(Service_MM, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; - const auto module = rp.PopEnum(); - const auto min = rp.Pop(); - const auto max = rp.Pop(); - - for (auto& session : sessions) { - if (session.module == module) { - session.SetAndWait(min, max); - break; - } - } - + const auto module = rp.PopEnum(); + const auto min = rp.Pop(); + const auto max = rp.Pop(); + + for (auto& session : sessions) { + if (session.module == module) { + session.SetAndWait(min, max); + break; + } + } + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } @@ -119,72 +119,72 @@ private: void GetOld(HLERequestContext& ctx) { LOG_DEBUG(Service_MM, "(STUBBED) called"); - IPC::RequestParser rp{ctx}; - const auto module = rp.PopEnum(); - - for (const auto& session : sessions) { - if (session.module == module) { - IPC::ResponseBuilder rb{ctx, 2}; - rb.Push(ResultSuccess); - rb.Push(session.min); - return; - } - } - + IPC::RequestParser rp{ctx}; + const auto module = rp.PopEnum(); + + for (const auto& session : sessions) { + if (session.module == module) { + IPC::ResponseBuilder rb{ctx, 2}; + rb.Push(ResultSuccess); + rb.Push(session.min); + return; + } + } + IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); - rb.Push(0); + rb.Push(0); } void Initialize(HLERequestContext& ctx) { - LOG_DEBUG(Service_MM, "(STUBBED) called"); - - IPC::RequestParser rp{ctx}; - const auto module = rp.PopEnum(); - rp.Pop(); - const auto event_clear_mode = rp.Pop(); - - const bool is_auto_clear_event = event_clear_mode == 1; - - sessions.push_back({module, request_id++, is_auto_clear_event}); + LOG_DEBUG(Service_MM, "(STUBBED) called"); + + IPC::RequestParser rp{ctx}; + const auto module = rp.PopEnum(); + rp.Pop(); + const auto event_clear_mode = rp.Pop(); + + const bool is_auto_clear_event = event_clear_mode == 1; + + sessions.push_back({module, request_id++, is_auto_clear_event}); IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); - rb.Push(request_id - 1); + rb.Push(request_id - 1); } void Finalize(HLERequestContext& ctx) { - LOG_DEBUG(Service_MM, "(STUBBED) called"); - - IPC::RequestParser rp{ctx}; - const auto id = rp.Pop(); - - for (auto it = sessions.begin(); it != sessions.end(); ++it) { - if (it->request_id == id) { - sessions.erase(it); - break; - } - } - + LOG_DEBUG(Service_MM, "(STUBBED) called"); + + IPC::RequestParser rp{ctx}; + const auto id = rp.Pop(); + + for (auto it = sessions.begin(); it != sessions.end(); ++it) { + if (it->request_id == id) { + sessions.erase(it); + break; + } + } + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } void SetAndWait(HLERequestContext& ctx) { - LOG_DEBUG(Service_MM, "(STUBBED) called"); - + LOG_DEBUG(Service_MM, "(STUBBED) called"); + IPC::RequestParser rp{ctx}; - const auto id = rp.Pop(); - const auto min = rp.Pop(); - const auto max = rp.Pop(); - - for (auto& session : sessions) { - if (session.request_id == id) { - session.SetAndWait(min, max); - break; - } - } - + const auto id = rp.Pop(); + const auto min = rp.Pop(); + const auto max = rp.Pop(); + + for (auto& session : sessions) { + if (session.request_id == id) { + session.SetAndWait(min, max); + break; + } + } + IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } @@ -192,25 +192,25 @@ private: void Get(HLERequestContext& ctx) { LOG_DEBUG(Service_MM, "(STUBBED) called"); - IPC::RequestParser rp{ctx}; - const auto id = rp.Pop(); - - for (const auto& session : sessions) { - if (session.request_id == id) { - IPC::ResponseBuilder rb{ctx, 3}; - rb.Push(ResultSuccess); - rb.Push(session.min); - return; - } - } - + IPC::RequestParser rp{ctx}; + const auto id = rp.Pop(); + + for (const auto& session : sessions) { + if (session.request_id == id) { + IPC::ResponseBuilder rb{ctx, 3}; + rb.Push(ResultSuccess); + rb.Push(session.min); + return; + } + } + IPC::ResponseBuilder rb{ctx, 3}; rb.Push(ResultSuccess); - rb.Push(0); + rb.Push(0); } - std::vector sessions; - u32 request_id{1}; + std::vector sessions; + u32 request_id{1}; }; void LoopProcess(Core::System& system) { diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp index 8210fd92a6..fc7dda26f1 100644 --- a/src/core/hle/service/nim/nim.cpp +++ b/src/core/hle/service/nim/nim.cpp @@ -232,7 +232,7 @@ public: {2, nullptr, "ClearDebugResponse"}, {3, nullptr, "RegisterDebugResponse"}, {4, &NIM_ECA::IsLargeResourceAvailable, "IsLargeResourceAvailable"}, - {5, &NIM_ECA::CreateServerInterface2, "CreateServerInterface2"} // 17.0.0+ + {5, &NIM_ECA::CreateServerInterface2, "CreateServerInterface2"} // 17.0.0+ }; // clang-format on @@ -241,7 +241,7 @@ public: private: void CreateServerInterface(HLERequestContext& ctx) { - LOG_DEBUG(Service_NIM, "(STUBBED) called"); + LOG_DEBUG(Service_NIM, "(STUBBED) called"); IPC::ResponseBuilder rb{ctx, 2, 0, 1}; rb.Push(ResultSuccess); rb.PushIpcInterface(system); @@ -258,14 +258,14 @@ private: rb.Push(ResultSuccess); rb.Push(false); } - - void CreateServerInterface2(HLERequestContext& ctx) { - LOG_DEBUG(Service_NIM, "(STUBBED) called."); - - IPC::ResponseBuilder rb{ctx, 2, 0, 1}; - rb.Push(ResultSuccess); - rb.PushIpcInterface(system); - } + + void CreateServerInterface2(HLERequestContext& ctx) { + LOG_DEBUG(Service_NIM, "(STUBBED) called."); + + IPC::ResponseBuilder rb{ctx, 2, 0, 1}; + rb.Push(ResultSuccess); + rb.PushIpcInterface(system); + } }; class NIM_SHP final : public ServiceFramework { diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt index e86f007cce..0bb51b250e 100644 --- a/src/yuzu/CMakeLists.txt +++ b/src/yuzu/CMakeLists.txt @@ -386,6 +386,7 @@ elseif(WIN32) set_target_properties(yuzu PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS") elseif(MINGW) set_target_properties(yuzu PROPERTIES LINK_FLAGS_RELEASE "-Wl,--subsystem,windows") + target_link_libraries(yuzu PRIVATE dwmapi) endif() endif()