From a0769ad835116e2538e6c8659a0bf6348143b3bf Mon Sep 17 00:00:00 2001 From: crueter Date: Sun, 26 Oct 2025 17:28:14 +0100 Subject: [PATCH] [cmake] MinGW builds; fix line endings; fix weird multiplayer lobby behavior (#2835) MinGW builds perform pretty dramatically better than MSVC in my (brief) testing, getting 40% better FPS on my KVM than MSVC. How this will translate to the real world, who knows, but this is a really good target to have. TODO: Add this to CI, potentially replace clang-cl Signed-off-by: crueter Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2835 Reviewed-by: MaranBr --- .ci/windows/install-msvc.ps1 | 60 ------- .patch/httplib/0001-mingw.patch | 52 ++++++ CMakeLists.txt | 57 +++---- CMakeModules/MSVCCache.cmake | 15 -- docs/Deps.md | 28 +++- externals/cpmfile.json | 5 +- src/core/CMakeLists.txt | 2 +- src/core/hle/service/mm/mm_u.cpp | 269 ++++++++++++++++--------------- src/core/hle/service/nim/nim.cpp | 23 +-- src/web_service/CMakeLists.txt | 1 + src/web_service/web_backend.cpp | 10 ++ src/yuzu/CMakeLists.txt | 1 + 12 files changed, 269 insertions(+), 254 deletions(-) delete mode 100755 .ci/windows/install-msvc.ps1 create mode 100644 .patch/httplib/0001-mingw.patch delete mode 100644 CMakeModules/MSVCCache.cmake diff --git a/.ci/windows/install-msvc.ps1 b/.ci/windows/install-msvc.ps1 deleted file mode 100755 index 788b2848ad..0000000000 --- a/.ci/windows/install-msvc.ps1 +++ /dev/null @@ -1,60 +0,0 @@ -# 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/CMakeLists.txt b/CMakeLists.txt index e5e97c32d5..e51f9c7238 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -579,6 +579,35 @@ function(create_target_directory_groups target_name) endforeach() endfunction() +# Platform-specific library requirements +# Put these BEFORE EXTERNALS or Boost WILL die +# ============================================= + +if (APPLE) + # Umbrella framework for everything GUI-related + find_library(COCOA_LIBRARY Cocoa) + set(PLATFORM_LIBRARIES ${COCOA_LIBRARY} ${IOKIT_LIBRARY} ${COREVIDEO_LIBRARY}) + find_library(ICONV_LIBRARY iconv REQUIRED) + list(APPEND PLATFORM_LIBRARIES ${ICONV_LIBRARY}) +elseif (WIN32) + # Target Windows 10 + add_compile_definitions(_WIN32_WINNT=0x0A00 WINVER=0x0A00) + set(PLATFORM_LIBRARIES winmm ws2_32 iphlpapi) + if (MINGW) + # PSAPI is the Process Status API + set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} psapi imm32 version) + endif() +elseif (PLATFORM_HAIKU) + # Haiku is so special :) + # Some fucking genius decided to name an entire module "network" in 2019 + # this caused great disaster amongst the Haiku community who had came first with + # their "libnetwork.so"; since CMake doesn't do magic, we have to use an ABSOLUTE PATH + # to the library itself, otherwise it will think we are linking to... our network thing + set(PLATFORM_LIBRARIES bsd /boot/system/lib/libnetwork.so) +elseif (CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU|SunOS)$") + set(PLATFORM_LIBRARIES rt) +endif() + add_subdirectory(externals) # pass targets from externals @@ -732,34 +761,6 @@ endif() set(THREADS_PREFER_PTHREAD_FLAG ON) find_package(Threads REQUIRED) -# Platform-specific library requirements -# ====================================== - -if (APPLE) - # Umbrella framework for everything GUI-related - find_library(COCOA_LIBRARY Cocoa) - set(PLATFORM_LIBRARIES ${COCOA_LIBRARY} ${IOKIT_LIBRARY} ${COREVIDEO_LIBRARY}) - find_library(ICONV_LIBRARY iconv REQUIRED) - list(APPEND PLATFORM_LIBRARIES ${ICONV_LIBRARY}) -elseif (WIN32) - # Target Windows 10 - add_compile_definitions(_WIN32_WINNT=0x0A00 WINVER=0x0A00) - set(PLATFORM_LIBRARIES winmm ws2_32 iphlpapi) - if (MINGW) - # PSAPI is the Process Status API - set(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} psapi imm32 version) - endif() -elseif (PLATFORM_HAIKU) - # Haiku is so special :) - # Some fucking genius decided to name an entire module "network" in 2019 - # this caused great disaster amongst the Haiku community who had came first with - # their "libnetwork.so"; since CMake doesn't do magic, we have to use an ABSOLUTE PATH - # to the library itself, otherwise it will think we are linking to... our network thing - set(PLATFORM_LIBRARIES bsd /boot/system/lib/libnetwork.so) -elseif (CMAKE_SYSTEM_NAME MATCHES "^(Linux|kFreeBSD|GNU|SunOS)$") - set(PLATFORM_LIBRARIES rt) -endif() - # Setup a custom clang-format target (if clang-format can be found) that will run # against all the src files. This should be used before making a pull request. # ======================================================================= diff --git a/CMakeModules/MSVCCache.cmake b/CMakeModules/MSVCCache.cmake deleted file mode 100644 index ba0d22d9ee..0000000000 --- a/CMakeModules/MSVCCache.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# 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/docs/Deps.md b/docs/Deps.md index 466f27f44e..338d3a5dcb 100644 --- a/docs/Deps.md +++ b/docs/Deps.md @@ -5,7 +5,6 @@ To build Eden, you MUST have a C++ compiler. - GCC 12 also requires Clang 14+ * On Windows, this is either: - **[MSVC](https://visualstudio.microsoft.com/downloads/)** (you should select *Community* option), - * *A convenience script to install the Visual Community Studio 2022 with necessary tools is provided in `.ci/windows/install-msvc.ps1`* - clang-cl - can be downloaded from the MSVC installer, - or **[MSYS2](https://www.msys2.org)** * On macOS, this is Apple Clang @@ -26,6 +25,9 @@ If you are on desktop and plan to use the Qt frontend, you *must* install Qt 6, * Linux and macOS users may choose to use the installer as well. * MSYS2 can also install Qt 6 via the package manager +If you are on Windows, a convenience script to install MSVC, MSYS2, Qt, all necessary packages for MSYS2, and set up a zsh environment with useful keybinds and aliases can be found [here](https://git.crueter.xyz/scripts/windev). +- For help setting up Qt Creator, run `./install.sh -h qtcreator` + If you are on Windows and NOT building with MSYS2, you may go [back home](Build.md) and continue. ## Externals @@ -204,12 +206,26 @@ Then install the libraries: `sudo pkg install qt6 boost glslang libzip library/l MSYS2 * Open the `MSYS2 MinGW 64-bit` shell (`mingw64.exe`) -* Download and install all dependencies using: - * `pacman -Syu git make mingw-w64-x86_64-SDL2 mingw-w64-x86_64-cmake mingw-w64-x86_64-python-pip mingw-w64-x86_64-qt6 mingw-w64-x86_64-toolchain autoconf libtool automake-wrapper` -* Add MinGW binaries to the PATH: +* Download and install all dependencies: +``` +BASE="git make autoconf libtool automake-wrapper jq patch" +MINGW="SDL2 cmake python-pip qt6-base toolchain ffmpeg boost catch fmt lz4 nlohmann-json openssl zlib zstd enet opus mbedtls vulkan-devel libusb vulkan-memory-allocator unordered_dense zydis clang ccache" + +packages="$BASE" +for pkg in $MINGW; do + packages="$packages mingw-w64-x86_64-$pkg" +done + +pacman -Syu --needed --noconfirm $packages +``` +* Notes: + - Using `qt6-static` is possible but currently untested. + - Other environments are entirely untested, but should theoretically work provided you install all the necessary packages. + - Clang is installed as it generally works better here. You can compile with GCC just fine, however. + - Add `qt-creator` to the `MINGW` variable to install Qt Creator. You can then create a Start Menu shortcut to the MinGW Qt Creator by running `powershell "\$s=(New-Object -COM WScript.Shell).CreateShortcut('C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Qt Creator.lnk');\$s.TargetPath='C:\\msys64\\mingw64\\bin\\qtcreator.exe';\$s.Save()"` in Git Bash or MSYS2. +* Add MinGW binaries to the PATH if they aren't already: * `echo 'PATH=/mingw64/bin:$PATH' >> ~/.bashrc` -* Add VulkanSDK to the PATH: - * `echo 'PATH=$(readlink -e /c/VulkanSDK/*/Bin/):$PATH' >> ~/.bashrc` + * or `echo 'PATH=/mingw64/bin:$PATH' >> ~/.zshrc`
diff --git a/externals/cpmfile.json b/externals/cpmfile.json index c46404986c..e1eb15fad3 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..a5195da061 100644 --- a/src/core/hle/service/mm/mm_u.cpp +++ b/src/core/hle/service/mm/mm_u.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -7,43 +10,43 @@ #include "core/hle/service/server_manager.h" #include "core/hle/service/sm/sm.h" -#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; +#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_; + } +}; - 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 +68,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(); + 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}); - 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"); - - IPC::RequestParser rp{ctx}; - const auto module = rp.PopEnum(); - const auto min = rp.Pop(); - const auto max = rp.Pop(); + 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; + } + } - for (auto& session : sessions) { - if (session.module == module) { - session.SetAndWait(min, max); - break; - } - } - IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } @@ -119,72 +122,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"); + 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::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"); - - IPC::RequestParser rp{ctx}; - const auto id = rp.Pop(); - const auto min = rp.Pop(); - const auto max = rp.Pop(); + 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; + } + } - for (auto& session : sessions) { - if (session.request_id == id) { - session.SetAndWait(min, max); - break; - } - } - IPC::ResponseBuilder rb{ctx, 2}; rb.Push(ResultSuccess); } @@ -192,25 +195,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..98a01308a0 100644 --- a/src/core/hle/service/nim/nim.cpp +++ b/src/core/hle/service/nim/nim.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -232,7 +235,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 +244,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 +261,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/web_service/CMakeLists.txt b/src/web_service/CMakeLists.txt index c1aaac9881..af56502827 100644 --- a/src/web_service/CMakeLists.txt +++ b/src/web_service/CMakeLists.txt @@ -20,6 +20,7 @@ target_link_libraries(web_service PRIVATE common network nlohmann_json::nlohmann find_package(OpenSSL REQUIRED) target_link_libraries(web_service PRIVATE OpenSSL::SSL OpenSSL::Crypto) +target_compile_definitions(web_service PRIVATE CPPHTTPLIB_OPENSSL_SUPPORT) if (YUZU_USE_PRECOMPILED_HEADERS) target_precompile_headers(web_service PRIVATE precompiled_headers.h) diff --git a/src/web_service/web_backend.cpp b/src/web_service/web_backend.cpp index c04cdd9707..1dfe6039da 100644 --- a/src/web_service/web_backend.cpp +++ b/src/web_service/web_backend.cpp @@ -1,3 +1,6 @@ +// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + // SPDX-FileCopyrightText: 2017 Citra Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later @@ -18,6 +21,10 @@ #pragma GCC diagnostic pop #endif +#ifdef YUZU_BUNDLED_OPENSSL +#include +#endif + #include "common/logging/log.h" #include "web_service/web_backend.h" #include "web_service/web_result.h" @@ -80,6 +87,9 @@ struct Client::Impl { cli->set_connection_timeout(TIMEOUT_SECONDS); cli->set_read_timeout(TIMEOUT_SECONDS); cli->set_write_timeout(TIMEOUT_SECONDS); +#ifdef YUZU_BUNDLED_OPENSSL + cli->load_ca_cert_store(kCert, sizeof(kCert)); +#endif } if (!cli->is_valid()) { LOG_ERROR(WebService, "Invalid URL {}", host + path); 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()