[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>
This commit is contained in:
@@ -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
Normal file
52
.patch/httplib/0001-mingw.patch
Normal file
@@ -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
|
||||
|
||||
@@ -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.
|
||||
# =======================================================================
|
||||
|
||||
@@ -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
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
vendored
5
externals/cpmfile.json
vendored
@@ -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",
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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>
|
||||
|
||||
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 <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_;
|
||||
}
|
||||
};
|
||||
|
||||
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>();
|
||||
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});
|
||||
|
||||
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");
|
||||
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto module = rp.PopEnum<Module>();
|
||||
const auto min = rp.Pop<u32>();
|
||||
const auto max = rp.Pop<s32>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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");
|
||||
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::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");
|
||||
|
||||
IPC::RequestParser rp{ctx};
|
||||
const auto id = rp.Pop<u32>();
|
||||
const auto min = rp.Pop<u32>();
|
||||
const auto max = rp.Pop<s32>();
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user