[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()
|
endforeach()
|
||||||
endfunction()
|
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)
|
add_subdirectory(externals)
|
||||||
|
|
||||||
# pass targets from externals
|
# pass targets from externals
|
||||||
@@ -732,34 +761,6 @@ endif()
|
|||||||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||||
find_package(Threads REQUIRED)
|
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
|
# 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.
|
# 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+
|
- GCC 12 also requires Clang 14+
|
||||||
* On Windows, this is either:
|
* On Windows, this is either:
|
||||||
- **[MSVC](https://visualstudio.microsoft.com/downloads/)** (you should select *Community* option),
|
- **[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,
|
- clang-cl - can be downloaded from the MSVC installer,
|
||||||
- or **[MSYS2](https://www.msys2.org)**
|
- or **[MSYS2](https://www.msys2.org)**
|
||||||
* On macOS, this is Apple Clang
|
* 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.
|
* Linux and macOS users may choose to use the installer as well.
|
||||||
* MSYS2 can also install Qt 6 via the package manager
|
* 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.
|
If you are on Windows and NOT building with MSYS2, you may go [back home](Build.md) and continue.
|
||||||
|
|
||||||
## Externals
|
## Externals
|
||||||
@@ -204,12 +206,26 @@ Then install the libraries: `sudo pkg install qt6 boost glslang libzip library/l
|
|||||||
<summary>MSYS2</summary>
|
<summary>MSYS2</summary>
|
||||||
|
|
||||||
* Open the `MSYS2 MinGW 64-bit` shell (`mingw64.exe`)
|
* Open the `MSYS2 MinGW 64-bit` shell (`mingw64.exe`)
|
||||||
* Download and install all dependencies using:
|
* Download and install all dependencies:
|
||||||
* `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:
|
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`
|
* `echo 'PATH=/mingw64/bin:$PATH' >> ~/.bashrc`
|
||||||
* Add VulkanSDK to the PATH:
|
* or `echo 'PATH=/mingw64/bin:$PATH' >> ~/.zshrc`
|
||||||
* `echo 'PATH=$(readlink -e /c/VulkanSDK/*/Bin/):$PATH' >> ~/.bashrc`
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
|
|||||||
5
externals/cpmfile.json
vendored
5
externals/cpmfile.json
vendored
@@ -30,7 +30,10 @@
|
|||||||
"tag": "v%VERSION%",
|
"tag": "v%VERSION%",
|
||||||
"hash": "b364500f76e2ecb0fe21b032d831272e3f1dfeea71af74e325f8fc4ce9dcdb3c941b97a5b422bdeafb9facd058597b90f8bfc284fb9afe3c33fefa15dd5a010b",
|
"hash": "b364500f76e2ecb0fe21b032d831272e3f1dfeea71af74e325f8fc4ce9dcdb3c941b97a5b422bdeafb9facd058597b90f8bfc284fb9afe3c33fefa15dd5a010b",
|
||||||
"git_version": "0.26.0",
|
"git_version": "0.26.0",
|
||||||
"find_args": "MODULE GLOBAL"
|
"find_args": "MODULE GLOBAL",
|
||||||
|
"patches": [
|
||||||
|
"0001-mingw.patch"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"cpp-jwt": {
|
"cpp-jwt": {
|
||||||
"version": "1.4",
|
"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)
|
target_link_libraries(core PRIVATE fmt::fmt nlohmann_json::nlohmann_json RenderDoc::API MbedTLS::mbedcrypto MbedTLS::mbedtls)
|
||||||
if (MINGW)
|
if (MINGW)
|
||||||
target_link_libraries(core PRIVATE ${MSWSOCK_LIBRARY})
|
target_link_libraries(core PRIVATE ws2_32 mswsock wlanapi)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (ENABLE_WEB_SERVICE)
|
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-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -7,43 +10,43 @@
|
|||||||
#include "core/hle/service/server_manager.h"
|
#include "core/hle/service/server_manager.h"
|
||||||
#include "core/hle/service/sm/sm.h"
|
#include "core/hle/service/sm/sm.h"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace Service::MM {
|
namespace Service::MM {
|
||||||
enum class Module : u32 {
|
enum class Module : u32 {
|
||||||
CPU = 0,
|
CPU = 0,
|
||||||
GPU = 1,
|
GPU = 1,
|
||||||
EMC = 2,
|
EMC = 2,
|
||||||
SYS_BUS = 3,
|
SYS_BUS = 3,
|
||||||
M_SELECT = 4,
|
M_SELECT = 4,
|
||||||
NVDEC = 5,
|
NVDEC = 5,
|
||||||
NVENC = 6,
|
NVENC = 6,
|
||||||
NVJPG = 7,
|
NVJPG = 7,
|
||||||
TEST = 8
|
TEST = 8
|
||||||
};
|
};
|
||||||
|
|
||||||
class Session {
|
class Session {
|
||||||
public:
|
public:
|
||||||
Session(Module module_, u32 request_id_, bool is_auto_clear_event_) {
|
Session(Module module_, u32 request_id_, bool is_auto_clear_event_) {
|
||||||
this->module = module_;
|
this->module = module_;
|
||||||
this->request_id = request_id_;
|
this->request_id = request_id_;
|
||||||
this->is_auto_clear_event = is_auto_clear_event_;
|
this->is_auto_clear_event = is_auto_clear_event_;
|
||||||
this->min = 0;
|
this->min = 0;
|
||||||
this->max = -1;
|
this->max = -1;
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Module module;
|
Module module;
|
||||||
u32 request_id, min;
|
u32 request_id, min;
|
||||||
s32 max;
|
s32 max;
|
||||||
bool is_auto_clear_event;
|
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> {
|
class MM_U final : public ServiceFramework<MM_U> {
|
||||||
public:
|
public:
|
||||||
explicit MM_U(Core::System& system_) : ServiceFramework{system_, "mm:u"} {
|
explicit MM_U(Core::System& system_) : ServiceFramework{system_, "mm:u"} {
|
||||||
@@ -65,53 +68,53 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void InitializeOld(HLERequestContext& ctx) {
|
void InitializeOld(HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_MM, "(STUBBED) called");
|
LOG_DEBUG(Service_MM, "(STUBBED) called");
|
||||||
|
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const auto module = rp.PopEnum<Module>();
|
const auto module = rp.PopEnum<Module>();
|
||||||
rp.Pop<u32>();
|
rp.Pop<u32>();
|
||||||
const auto event_clear_mode = 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};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FinalizeOld(HLERequestContext& ctx) {
|
void FinalizeOld(HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_MM, "(STUBBED) called");
|
LOG_DEBUG(Service_MM, "(STUBBED) called");
|
||||||
|
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const auto module = rp.PopEnum<Module>();
|
const auto module = rp.PopEnum<Module>();
|
||||||
|
|
||||||
for (auto it = sessions.begin(); it != sessions.end(); ++it) {
|
for (auto it = sessions.begin(); it != sessions.end(); ++it) {
|
||||||
if (it->module == module) {
|
if (it->module == module) {
|
||||||
sessions.erase(it);
|
sessions.erase(it);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetAndWaitOld(HLERequestContext& ctx) {
|
void SetAndWaitOld(HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_MM, "(STUBBED) called");
|
LOG_DEBUG(Service_MM, "(STUBBED) called");
|
||||||
|
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const auto module = rp.PopEnum<Module>();
|
const auto module = rp.PopEnum<Module>();
|
||||||
const auto min = rp.Pop<u32>();
|
const auto min = rp.Pop<u32>();
|
||||||
const auto max = rp.Pop<s32>();
|
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};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
}
|
}
|
||||||
@@ -119,72 +122,72 @@ private:
|
|||||||
void GetOld(HLERequestContext& ctx) {
|
void GetOld(HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_MM, "(STUBBED) called");
|
LOG_DEBUG(Service_MM, "(STUBBED) called");
|
||||||
|
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const auto module = rp.PopEnum<Module>();
|
const auto module = rp.PopEnum<Module>();
|
||||||
|
|
||||||
for (const auto& session : sessions) {
|
for (const auto& session : sessions) {
|
||||||
if (session.module == module) {
|
if (session.module == module) {
|
||||||
IPC::ResponseBuilder rb{ctx, 2};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
rb.Push(session.min);
|
rb.Push(session.min);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 3};
|
IPC::ResponseBuilder rb{ctx, 3};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
rb.Push<u32>(0);
|
rb.Push<u32>(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Initialize(HLERequestContext& ctx) {
|
void Initialize(HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_MM, "(STUBBED) called");
|
LOG_DEBUG(Service_MM, "(STUBBED) called");
|
||||||
|
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const auto module = rp.PopEnum<Module>();
|
const auto module = rp.PopEnum<Module>();
|
||||||
rp.Pop<u32>();
|
rp.Pop<u32>();
|
||||||
const auto event_clear_mode = rp.Pop<u32>();
|
const auto event_clear_mode = rp.Pop<u32>();
|
||||||
|
|
||||||
const bool is_auto_clear_event = event_clear_mode == 1;
|
const bool is_auto_clear_event = event_clear_mode == 1;
|
||||||
|
|
||||||
sessions.push_back({module, request_id++, is_auto_clear_event});
|
sessions.push_back({module, request_id++, is_auto_clear_event});
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 3};
|
IPC::ResponseBuilder rb{ctx, 3};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
rb.Push(request_id - 1);
|
rb.Push(request_id - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Finalize(HLERequestContext& ctx) {
|
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};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetAndWait(HLERequestContext& ctx) {
|
void SetAndWait(HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_MM, "(STUBBED) called");
|
LOG_DEBUG(Service_MM, "(STUBBED) called");
|
||||||
|
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const auto id = rp.Pop<u32>();
|
const auto id = rp.Pop<u32>();
|
||||||
const auto min = rp.Pop<u32>();
|
const auto min = rp.Pop<u32>();
|
||||||
const auto max = rp.Pop<s32>();
|
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};
|
IPC::ResponseBuilder rb{ctx, 2};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
}
|
}
|
||||||
@@ -192,25 +195,25 @@ private:
|
|||||||
void Get(HLERequestContext& ctx) {
|
void Get(HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_MM, "(STUBBED) called");
|
LOG_DEBUG(Service_MM, "(STUBBED) called");
|
||||||
|
|
||||||
IPC::RequestParser rp{ctx};
|
IPC::RequestParser rp{ctx};
|
||||||
const auto id = rp.Pop<u32>();
|
const auto id = rp.Pop<u32>();
|
||||||
|
|
||||||
for (const auto& session : sessions) {
|
for (const auto& session : sessions) {
|
||||||
if (session.request_id == id) {
|
if (session.request_id == id) {
|
||||||
IPC::ResponseBuilder rb{ctx, 3};
|
IPC::ResponseBuilder rb{ctx, 3};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
rb.Push(session.min);
|
rb.Push(session.min);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 3};
|
IPC::ResponseBuilder rb{ctx, 3};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
rb.Push<u32>(0);
|
rb.Push<u32>(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Session> sessions;
|
std::vector<Session> sessions;
|
||||||
u32 request_id{1};
|
u32 request_id{1};
|
||||||
};
|
};
|
||||||
|
|
||||||
void LoopProcess(Core::System& system) {
|
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-FileCopyrightText: Copyright 2018 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -232,7 +235,7 @@ public:
|
|||||||
{2, nullptr, "ClearDebugResponse"},
|
{2, nullptr, "ClearDebugResponse"},
|
||||||
{3, nullptr, "RegisterDebugResponse"},
|
{3, nullptr, "RegisterDebugResponse"},
|
||||||
{4, &NIM_ECA::IsLargeResourceAvailable, "IsLargeResourceAvailable"},
|
{4, &NIM_ECA::IsLargeResourceAvailable, "IsLargeResourceAvailable"},
|
||||||
{5, &NIM_ECA::CreateServerInterface2, "CreateServerInterface2"} // 17.0.0+
|
{5, &NIM_ECA::CreateServerInterface2, "CreateServerInterface2"} // 17.0.0+
|
||||||
};
|
};
|
||||||
// clang-format on
|
// clang-format on
|
||||||
|
|
||||||
@@ -241,7 +244,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void CreateServerInterface(HLERequestContext& ctx) {
|
void CreateServerInterface(HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_NIM, "(STUBBED) called");
|
LOG_DEBUG(Service_NIM, "(STUBBED) called");
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
rb.PushIpcInterface<IShopServiceAccessServer>(system);
|
rb.PushIpcInterface<IShopServiceAccessServer>(system);
|
||||||
@@ -258,14 +261,14 @@ private:
|
|||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
rb.Push(false);
|
rb.Push(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CreateServerInterface2(HLERequestContext& ctx) {
|
void CreateServerInterface2(HLERequestContext& ctx) {
|
||||||
LOG_DEBUG(Service_NIM, "(STUBBED) called.");
|
LOG_DEBUG(Service_NIM, "(STUBBED) called.");
|
||||||
|
|
||||||
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
IPC::ResponseBuilder rb{ctx, 2, 0, 1};
|
||||||
rb.Push(ResultSuccess);
|
rb.Push(ResultSuccess);
|
||||||
rb.PushIpcInterface<IShopServiceAccessServer>(system);
|
rb.PushIpcInterface<IShopServiceAccessServer>(system);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class NIM_SHP final : public ServiceFramework<NIM_SHP> {
|
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)
|
find_package(OpenSSL REQUIRED)
|
||||||
target_link_libraries(web_service PRIVATE OpenSSL::SSL OpenSSL::Crypto)
|
target_link_libraries(web_service PRIVATE OpenSSL::SSL OpenSSL::Crypto)
|
||||||
|
target_compile_definitions(web_service PRIVATE CPPHTTPLIB_OPENSSL_SUPPORT)
|
||||||
|
|
||||||
if (YUZU_USE_PRECOMPILED_HEADERS)
|
if (YUZU_USE_PRECOMPILED_HEADERS)
|
||||||
target_precompile_headers(web_service PRIVATE precompiled_headers.h)
|
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-FileCopyrightText: 2017 Citra Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
@@ -18,6 +21,10 @@
|
|||||||
#pragma GCC diagnostic pop
|
#pragma GCC diagnostic pop
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef YUZU_BUNDLED_OPENSSL
|
||||||
|
#include <openssl/cert.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "common/logging/log.h"
|
#include "common/logging/log.h"
|
||||||
#include "web_service/web_backend.h"
|
#include "web_service/web_backend.h"
|
||||||
#include "web_service/web_result.h"
|
#include "web_service/web_result.h"
|
||||||
@@ -80,6 +87,9 @@ struct Client::Impl {
|
|||||||
cli->set_connection_timeout(TIMEOUT_SECONDS);
|
cli->set_connection_timeout(TIMEOUT_SECONDS);
|
||||||
cli->set_read_timeout(TIMEOUT_SECONDS);
|
cli->set_read_timeout(TIMEOUT_SECONDS);
|
||||||
cli->set_write_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()) {
|
if (!cli->is_valid()) {
|
||||||
LOG_ERROR(WebService, "Invalid URL {}", host + path);
|
LOG_ERROR(WebService, "Invalid URL {}", host + path);
|
||||||
|
|||||||
@@ -386,6 +386,7 @@ elseif(WIN32)
|
|||||||
set_target_properties(yuzu PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS")
|
set_target_properties(yuzu PROPERTIES LINK_FLAGS_RELEASE "/SUBSYSTEM:WINDOWS")
|
||||||
elseif(MINGW)
|
elseif(MINGW)
|
||||||
set_target_properties(yuzu PROPERTIES LINK_FLAGS_RELEASE "-Wl,--subsystem,windows")
|
set_target_properties(yuzu PROPERTIES LINK_FLAGS_RELEASE "-Wl,--subsystem,windows")
|
||||||
|
target_link_libraries(yuzu PRIVATE dwmapi)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user