Browse Source

[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 <crueter@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/2835
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
pull/2842/head
crueter 2 months ago
parent
commit
a0769ad835
No known key found for this signature in database GPG Key ID: 425ACD2D4830EBC6
  1. 60
      .ci/windows/install-msvc.ps1
  2. 52
      .patch/httplib/0001-mingw.patch
  3. 57
      CMakeLists.txt
  4. 15
      CMakeModules/MSVCCache.cmake
  5. 28
      docs/Deps.md
  6. 5
      externals/cpmfile.json
  7. 2
      src/core/CMakeLists.txt
  8. 273
      src/core/hle/service/mm/mm_u.cpp
  9. 23
      src/core/hle/service/nim/nim.cpp
  10. 1
      src/web_service/CMakeLists.txt
  11. 10
      src/web_service/web_backend.cpp
  12. 1
      src/yuzu/CMakeLists.txt

60
.ci/windows/install-msvc.ps1

@ -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"

52
.patch/httplib/0001-mingw.patch

@ -0,0 +1,52 @@
From e1a946ffb79022d38351a0623f819a5419965c3e Mon Sep 17 00:00:00 2001
From: crueter <crueter@eden-emu.dev>
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 <crueter@eden-emu.dev>
---
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<DWORD>(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

57
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.
# =======================================================================

15
CMakeModules/MSVCCache.cmake

@ -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)

28
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
<summary>MSYS2</summary>
* 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`
</details>
<details>

5
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",

2
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)

273
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 <vector>
#include <vector>
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<MM_U> {
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<Module>();
rp.Pop<u32>();
const auto event_clear_mode = rp.Pop<u32>();
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<Module>();
rp.Pop<u32>();
const auto event_clear_mode = rp.Pop<u32>();
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<Module>();
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<Module>();
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<Module>();
const auto min = rp.Pop<u32>();
const auto max = rp.Pop<s32>();
for (auto& session : sessions) {
if (session.module == module) {
session.SetAndWait(min, max);
break;
}
}
const auto module = rp.PopEnum<Module>();
const auto min = rp.Pop<u32>();
const auto max = rp.Pop<s32>();
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<Module>();
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<Module>();
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<u32>(0);
rb.Push<u32>(0);
}
void Initialize(HLERequestContext& ctx) {
LOG_DEBUG(Service_MM, "(STUBBED) called");
IPC::RequestParser rp{ctx};
const auto module = rp.PopEnum<Module>();
rp.Pop<u32>();
const auto event_clear_mode = rp.Pop<u32>();
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<Module>();
rp.Pop<u32>();
const auto event_clear_mode = rp.Pop<u32>();
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<u32>();
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<u32>();
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<u32>();
const auto min = rp.Pop<u32>();
const auto max = rp.Pop<s32>();
for (auto& session : sessions) {
if (session.request_id == id) {
session.SetAndWait(min, max);
break;
}
}
const auto id = rp.Pop<u32>();
const auto min = rp.Pop<u32>();
const auto max = rp.Pop<s32>();
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<u32>();
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<u32>();
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<u32>(0);
rb.Push<u32>(0);
}
std::vector<Session> sessions;
u32 request_id{1};
std::vector<Session> sessions;
u32 request_id{1};
};
void LoopProcess(Core::System& system) {

23
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<IShopServiceAccessServer>(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<IShopServiceAccessServer>(system);
}
void CreateServerInterface2(HLERequestContext& ctx) {
LOG_DEBUG(Service_NIM, "(STUBBED) called.");
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
rb.Push(ResultSuccess);
rb.PushIpcInterface<IShopServiceAccessServer>(system);
}
};
class NIM_SHP final : public ServiceFramework<NIM_SHP> {

1
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)

10
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 <openssl/cert.h>
#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);

1
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()

Loading…
Cancel
Save