mirror of
https://git.eden-emu.dev/eden-emu/eden
synced 2026-04-22 23:08:57 +02:00
Compare commits
51 commits
02a4cc54d5
...
3cc2caf4fe
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3cc2caf4fe | ||
|
|
5d6cea5cf9 | ||
|
|
0a8cbe6d8d | ||
|
|
0b0778f38b | ||
|
|
4b7cf24cc5 | ||
|
|
f1acc2887e | ||
|
|
3dc0dcef83 | ||
|
|
cf84258120 | ||
|
|
93e9f7ea3e | ||
|
|
7b720d0d3c | ||
|
|
22e822f788 | ||
|
|
67a0039a7d | ||
|
|
39878272e1 | ||
|
|
697fa4f10a | ||
|
|
36da1f1cb8 | ||
|
|
4801476a29 | ||
|
|
ef664e3764 | ||
|
|
326f840b2f | ||
|
|
237f7ca725 | ||
|
|
7ae28eb89c | ||
|
|
d4ccdd4e13 | ||
|
|
680394f339 | ||
|
|
36c8b3a126 | ||
|
|
36506b04a5 | ||
|
|
d25307ceee | ||
|
|
db35ed37ce | ||
|
|
561c00de90 | ||
|
|
616e598d2e | ||
|
|
812bceb2ed | ||
|
|
81f3646db4 | ||
|
|
0b85a3f063 | ||
|
|
68c8899159 | ||
|
|
42dffccc64 | ||
|
|
d58d7b3682 | ||
|
|
83a7c5db13 | ||
|
|
d683e902a7 | ||
|
|
b86f28b2d8 | ||
|
|
f01ae5fcf6 | ||
|
|
47459d5a44 | ||
|
|
e2e281f957 | ||
|
|
2c002d9721 | ||
|
|
833a3118b4 | ||
|
|
43d6d9b3db | ||
|
|
66fea843d4 | ||
|
|
9f3656d969 | ||
|
|
6192b6a182 | ||
|
|
c296153d71 | ||
|
|
1d072f1244 | ||
|
|
5d725d6d08 | ||
|
|
2f9687dfcf | ||
|
|
7811457de5 |
64 changed files with 3410 additions and 107 deletions
19
.ci/ios/build.sh
Executable file
19
.ci/ios/build.sh
Executable file
|
|
@ -0,0 +1,19 @@
|
|||
#!/bin/sh -ex
|
||||
|
||||
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
WORK_DIR="$PWD"
|
||||
xcrun --sdk iphoneos --show-sdk-path
|
||||
|
||||
# TODO: support iphonesimulator sdk
|
||||
|
||||
cmake -G Xcode -B build/ios \
|
||||
-DCMAKE_OSX_DEPLOYMENT_TARGET=16.0 \
|
||||
-DCMAKE_OSX_SYSROOT=iphoneos \
|
||||
-DCMAKE_SYSTEM_NAME=iOS \
|
||||
-DCMAKE_OSX_ARCHITECTURES="arm64" \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
"$@"
|
||||
|
||||
cmake --build build/ios -t eden-ios --config Release
|
||||
1180
.ci/ios/ios-toolchain.cmake
Normal file
1180
.ci/ios/ios-toolchain.cmake
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -115,7 +115,7 @@ for file in $FILES; do
|
|||
*.cmake|*.sh|*CMakeLists.txt)
|
||||
begin="#"
|
||||
;;
|
||||
*.kt*|*.cpp|*.h|*.qml)
|
||||
*.kt*|*.cpp|*.h|*.qml|*.swift|*.mm)
|
||||
begin="//"
|
||||
;;
|
||||
*)
|
||||
|
|
|
|||
31
.patch/boost/0002-ios-fix.patch
Normal file
31
.patch/boost/0002-ios-fix.patch
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
diff --git a/libs/process/src/shell.cpp b/libs/process/src/shell.cpp
|
||||
index bf4bbfd8..bc4aae89 100644
|
||||
--- a/libs/process/src/shell.cpp
|
||||
+++ b/libs/process/src/shell.cpp
|
||||
@@ -19,7 +19,7 @@
|
||||
#if defined(BOOST_PROCESS_V2_WINDOWS)
|
||||
#include <windows.h>
|
||||
#include <shellapi.h>
|
||||
-#elif !defined(__OpenBSD__) && !defined(__ANDROID__)
|
||||
+#elif !defined(__OpenBSD__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IPHONE)
|
||||
#include <wordexp.h>
|
||||
#endif
|
||||
|
||||
@@ -30,7 +30,7 @@ BOOST_PROCESS_V2_DECL const error_category& get_shell_category()
|
||||
{
|
||||
return system_category();
|
||||
}
|
||||
-#elif !defined(__OpenBSD__) && !defined(__ANDROID__)
|
||||
+#elif !defined(__OpenBSD__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IPHONE)
|
||||
|
||||
struct shell_category_t final : public error_category
|
||||
{
|
||||
@@ -99,7 +99,7 @@ auto shell::args() const-> args_type
|
||||
return input_.c_str();
|
||||
}
|
||||
|
||||
-#elif !defined(__OpenBSD__) && !defined(__ANDROID__)
|
||||
+#elif !defined(__OpenBSD__) && !defined(__ANDROID__) && !(defined(__APPLE__) && TARGET_OS_IPHONE)
|
||||
|
||||
void shell::parse_()
|
||||
{
|
||||
33
.patch/spirv-tools/0003-ios-fix.patch
Normal file
33
.patch/spirv-tools/0003-ios-fix.patch
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
diff --git a/source/CMakeLists.txt b/source/CMakeLists.txt
|
||||
index 7ab2319..333e325 100644
|
||||
--- a/source/CMakeLists.txt
|
||||
+++ b/source/CMakeLists.txt
|
||||
@@ -151,9 +151,11 @@ add_custom_command(OUTPUT ${SPIRV_TOOLS_BUILD_VERSION_INC}
|
||||
COMMENT "Update build-version.inc in the SPIRV-Tools build directory (if necessary).")
|
||||
# Convenience target for standalone generation of the build-version.inc file.
|
||||
# This is not required for any dependence chain.
|
||||
-add_custom_target(spirv-tools-build-version
|
||||
- DEPENDS ${SPIRV_TOOLS_BUILD_VERSION_INC})
|
||||
-set_property(TARGET spirv-tools-build-version PROPERTY FOLDER "SPIRV-Tools build")
|
||||
+if (NOT IOS)
|
||||
+ add_custom_target(spirv-tools-build-version
|
||||
+ DEPENDS ${SPIRV_TOOLS_BUILD_VERSION_INC})
|
||||
+ set_property(TARGET spirv-tools-build-version PROPERTY FOLDER "SPIRV-Tools build")
|
||||
+endif()
|
||||
|
||||
list(APPEND PCH_DEPENDS
|
||||
${CORE_TABLES_HEADER_INC_FILE}
|
||||
@@ -338,8 +340,11 @@ function(spirv_tools_default_target_options target)
|
||||
)
|
||||
set_property(TARGET ${target} PROPERTY FOLDER "SPIRV-Tools libraries")
|
||||
spvtools_check_symbol_exports(${target})
|
||||
- add_dependencies(${target}
|
||||
- spirv-tools-build-version core_tables extinst_tables)
|
||||
+ if (IOS)
|
||||
+ add_dependencies(${target} core_tables extinst_tables)
|
||||
+ else ()
|
||||
+ add_dependencies(${target} spirv-tools-build-version core_tables extinst_tables)
|
||||
+ endif()
|
||||
endfunction()
|
||||
|
||||
if (SPIRV_TOOLS_BUILD_SHARED)
|
||||
|
|
@ -21,6 +21,29 @@ include(CMakeDependentOption)
|
|||
include(CTest)
|
||||
include(CPMUtil)
|
||||
|
||||
# TODO(crueter): Make this more automatic.
|
||||
if (IOS)
|
||||
list(APPEND CMAKE_FIND_ROOT_PATH "${CMAKE_OSX_SYSROOT_INT}" CACHE INTERNAL "")
|
||||
list(APPEND CMAKE_PROGRAM_PATH "/opt/homebrew/bin" CACHE INTERNAL "")
|
||||
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM BOTH CACHE INTERNAL "")
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY BOTH CACHE INTERNAL "")
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE BOTH CACHE INTERNAL "")
|
||||
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE BOTH CACHE INTERNAL "")
|
||||
|
||||
list(LENGTH CMAKE_OSX_ARCHITECTURES _arch_len)
|
||||
if (NOT _arch_len EQUAL 1)
|
||||
message(FATAL_ERROR "CMAKE_OSX_ARCHITECTURES must contain exactly one architecture.")
|
||||
endif()
|
||||
|
||||
# TODO(crueter): Proper handling for this.
|
||||
if (CMAKE_OSX_ARCHITECTURES STREQUAL arm64)
|
||||
set(CMAKE_SYSTEM_PROCESSOR aarch64)
|
||||
else()
|
||||
set(CMAKE_SYSTEM_PROCESSOR ${CMAKE_OSX_ARCHITECTURES})
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED ARCHITECTURE)
|
||||
message(FATAL_ERROR "Architecture didn't make it out of scope, did you delete DetectArchitecture.cmake?")
|
||||
endif()
|
||||
|
|
@ -42,7 +65,7 @@ if (PLATFORM_NETBSD)
|
|||
set(ENV{PKG_CONFIG_PATH} "${PKG_CONFIG_PATH}:${CMAKE_SYSROOT}/usr/pkg/lib/ffmpeg7/pkgconfig")
|
||||
endif()
|
||||
|
||||
cmake_dependent_option(YUZU_STATIC_ROOM "Build a static room executable only (CI only)" OFF "PLATFORM_LINUX" OFF)
|
||||
cmake_dependent_option(YUZU_STATIC_ROOM "Build a static room executable only (CI only)" OFF "PLATFORM_LINUX OR WIN32 OR (APPLE AND NOT IOS)" OFF)
|
||||
if (YUZU_STATIC_ROOM)
|
||||
set(YUZU_ROOM ON)
|
||||
set(YUZU_ROOM_STANDALONE ON)
|
||||
|
|
@ -67,9 +90,15 @@ if (YUZU_STATIC_ROOM)
|
|||
endif()
|
||||
|
||||
# qt stuff
|
||||
option(ENABLE_QT "Enable the Qt frontend" ON)
|
||||
if (IOS OR ANDROID)
|
||||
set(_default_qt OFF)
|
||||
else()
|
||||
set(_default_qt ON)
|
||||
endif()
|
||||
|
||||
option(ENABLE_QT "Enable the Qt frontend" ${_default_qt})
|
||||
option(ENABLE_QT_TRANSLATION "Enable translations for the Qt frontend" OFF)
|
||||
option(ENABLE_UPDATE_CHECKER "Enable update checker (for Qt and Android)" OFF)
|
||||
cmake_dependent_option(ENABLE_UPDATE_CHECKER "Enable update checker (for Qt and Android)" OFF "ENABLE_QT OR ANDROID" OFF)
|
||||
cmake_dependent_option(YUZU_USE_QT_MULTIMEDIA "Use QtMultimedia for Camera" OFF "NOT YUZU_USE_BUNDLED_QT" OFF)
|
||||
cmake_dependent_option(YUZU_USE_QT_WEB_ENGINE "Use QtWebEngine for web applet implementation" OFF "NOT YUZU_USE_BUNDLED_QT" OFF)
|
||||
set(YUZU_QT_MIRROR "" CACHE STRING "What mirror to use for downloading the bundled Qt libraries")
|
||||
|
|
@ -170,31 +199,32 @@ if (MSVC AND NOT CXX_CLANG)
|
|||
set(CMAKE_CXX_FLAGS_INIT "${CMAKE_CXX_FLAGS_INIT} /W3 /WX-")
|
||||
endif()
|
||||
|
||||
# TODO(crueter): Cleanup, each dep that has a bundled option should allow to choose between bundled, external, system
|
||||
cmake_dependent_option(YUZU_USE_EXTERNAL_SDL2 "Build SDL2 from external source" OFF "NOT MSVC;NOT ANDROID" OFF)
|
||||
cmake_dependent_option(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 build" "${MSVC}" "NOT ANDROID" OFF)
|
||||
|
||||
option(ENABLE_CUBEB "Enables the cubeb audio backend" ON)
|
||||
|
||||
set(EXT_DEFAULT OFF)
|
||||
if (MSVC OR ANDROID)
|
||||
if (MSVC OR ANDROID OR IOS)
|
||||
set(EXT_DEFAULT ON)
|
||||
endif()
|
||||
|
||||
# TODO(crueter): Cleanup, each dep that has a bundled option should allow to choose between bundled, external, system
|
||||
cmake_dependent_option(YUZU_USE_EXTERNAL_SDL2 "Build SDL2 from external source" OFF "NOT MSVC;NOT ANDROID" OFF)
|
||||
cmake_dependent_option(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 build" "${EXT_DEFAULT}" "NOT ANDROID" OFF)
|
||||
|
||||
# TODO(crueter): did not find header 'AudioHardware.h' in framework 'CoreAudio'
|
||||
cmake_dependent_option(ENABLE_CUBEB "Enables the cubeb audio backend" ON "NOT IOS" OFF)
|
||||
|
||||
# ffmpeg
|
||||
option(YUZU_USE_BUNDLED_FFMPEG "Download bundled FFmpeg" ${EXT_DEFAULT})
|
||||
cmake_dependent_option(YUZU_USE_EXTERNAL_FFMPEG "Build FFmpeg from external source" "${PLATFORM_SUN}" "NOT WIN32 AND NOT ANDROID" OFF)
|
||||
|
||||
# sirit
|
||||
set(BUNDLED_SIRIT_DEFAULT OFF)
|
||||
if (MSVC AND NOT (CMAKE_BUILD_TYPE MATCHES "Deb") OR ANDROID)
|
||||
if ((MSVC AND NOT (CMAKE_BUILD_TYPE MATCHES "Deb")) OR ANDROID OR IOS)
|
||||
set(BUNDLED_SIRIT_DEFAULT ON)
|
||||
endif()
|
||||
|
||||
option(YUZU_USE_BUNDLED_SIRIT "Download bundled sirit" ${BUNDLED_SIRIT_DEFAULT})
|
||||
|
||||
# FreeBSD 15+ has libusb, versions below should disable it
|
||||
cmake_dependent_option(ENABLE_LIBUSB "Enable the use of LibUSB" ON "WIN32 OR PLATFORM_LINUX OR PLATFORM_FREEBSD OR APPLE" OFF)
|
||||
cmake_dependent_option(ENABLE_LIBUSB "Enable the use of LibUSB" ON "WIN32 OR PLATFORM_LINUX OR PLATFORM_FREEBSD OR (APPLE AND NOT IOS)" OFF)
|
||||
|
||||
cmake_dependent_option(ENABLE_OPENGL "Enable OpenGL" ON "NOT (WIN32 AND ARCHITECTURE_arm64) AND NOT APPLE" OFF)
|
||||
mark_as_advanced(FORCE ENABLE_OPENGL)
|
||||
|
|
@ -212,10 +242,10 @@ option(YUZU_LEGACY "Apply patches that improve compatibility with older GPUs (e.
|
|||
|
||||
option(NIGHTLY_BUILD "Use Nightly qualifiers in the update checker and build metadata" OFF)
|
||||
|
||||
cmake_dependent_option(YUZU_ROOM "Enable dedicated room functionality" ON "NOT ANDROID" OFF)
|
||||
cmake_dependent_option(YUZU_ROOM "Enable dedicated room functionality" ON "NOT ANDROID AND NOT IOS" OFF)
|
||||
cmake_dependent_option(YUZU_ROOM_STANDALONE "Enable standalone room executable" ON "YUZU_ROOM" OFF)
|
||||
|
||||
cmake_dependent_option(YUZU_CMD "Compile the eden-cli executable" ON "NOT ANDROID" OFF)
|
||||
cmake_dependent_option(YUZU_CMD "Compile the eden-cli executable" ON "NOT ANDROID AND NOT IOS" OFF)
|
||||
|
||||
cmake_dependent_option(YUZU_CRASH_DUMPS "Compile crash dump (Minidump) support" OFF "WIN32 OR PLATFORM_LINUX" OFF)
|
||||
|
||||
|
|
@ -283,7 +313,7 @@ if (YUZU_ROOM)
|
|||
add_compile_definitions(YUZU_ROOM)
|
||||
endif()
|
||||
|
||||
if ((ANDROID OR APPLE OR UNIX) AND (NOT PLATFORM_LINUX OR ANDROID) AND NOT WIN32)
|
||||
if ((ANDROID OR APPLE OR UNIX OR IOS) AND (NOT PLATFORM_LINUX OR ANDROID) AND NOT WIN32)
|
||||
if(CXX_APPLE OR CXX_CLANG)
|
||||
# libc++ has stop_token and jthread as experimental
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fexperimental-library")
|
||||
|
|
@ -359,7 +389,10 @@ set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}/bin)
|
|||
set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
find_package(RenderDoc MODULE)
|
||||
find_package(RenderDoc MODULE QUIET)
|
||||
if (NOT RenderDoc_FOUND)
|
||||
message(WARNING "RenderDoc not found. Some debugging features may be disabled.")
|
||||
endif()
|
||||
|
||||
# openssl funniness
|
||||
if (YUZU_USE_BUNDLED_OPENSSL)
|
||||
|
|
@ -484,9 +517,15 @@ endfunction()
|
|||
# Platform-specific library requirements
|
||||
# Put these BEFORE EXTERNALS or Boost WILL die
|
||||
# =============================================
|
||||
|
||||
if (APPLE)
|
||||
foreach(fw Carbon Metal Cocoa IOKit CoreVideo CoreMedia)
|
||||
set(_libs Metal IOKit CoreVideo CoreMedia)
|
||||
if (IOS)
|
||||
list(APPEND _libs objc)
|
||||
else()
|
||||
list(APPEND _libs Carbon Cocoa)
|
||||
endif()
|
||||
|
||||
foreach(fw ${_libs})
|
||||
find_library(${fw}_LIBRARY ${fw} REQUIRED)
|
||||
list(APPEND PLATFORM_LIBRARIES ${${fw}_LIBRARY})
|
||||
endforeach()
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
set(CPM_SOURCE_CACHE "${PROJECT_SOURCE_DIR}/.cache/cpm" CACHE STRING "" FORCE)
|
||||
|
||||
if(MSVC OR ANDROID)
|
||||
if(MSVC OR ANDROID OR IOS)
|
||||
set(BUNDLED_DEFAULT ON)
|
||||
else()
|
||||
set(BUNDLED_DEFAULT OFF)
|
||||
|
|
@ -690,8 +690,10 @@ function(AddCIPackage)
|
|||
set(pkgname linux-amd64)
|
||||
elseif(PLATFORM_LINUX AND ARCHITECTURE_arm64)
|
||||
set(pkgname linux-aarch64)
|
||||
elseif(APPLE)
|
||||
elseif(APPLE AND NOT IOS)
|
||||
set(pkgname macos-universal)
|
||||
elseif(IOS AND ARCHITECTURE_arm64)
|
||||
set(pkgname ios-aarch64)
|
||||
endif()
|
||||
|
||||
if (DEFINED pkgname AND NOT "${pkgname}" IN_LIST DISABLED_PLATFORMS)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@
|
|||
"version": "1.57",
|
||||
"find_args": "CONFIG OPTIONAL_COMPONENTS headers context system fiber filesystem",
|
||||
"patches": [
|
||||
"0001-clang-cl.patch"
|
||||
"0001-clang-cl.patch",
|
||||
"0002-ios-fix.patch"
|
||||
]
|
||||
},
|
||||
"fmt": {
|
||||
|
|
|
|||
|
|
@ -18,3 +18,4 @@
|
|||
- `linux-amd64`
|
||||
- `linux-aarch64`
|
||||
- `macos-universal`
|
||||
- `ios-aarch64`
|
||||
|
|
|
|||
|
|
@ -61,7 +61,8 @@ In order: OpenSSL CI, Boost (tag + artifact), Opus (options + find_args), discor
|
|||
"version": "3.6.0",
|
||||
"min_version": "1.1.1",
|
||||
"disabled_platforms": [
|
||||
"macos-universal"
|
||||
"macos-universal",
|
||||
"ios-aarch64"
|
||||
]
|
||||
},
|
||||
"boost": {
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
- [Arch Linux](#arch-linux)
|
||||
- [Gentoo Linux](#gentoo-linux)
|
||||
- [macOS](#macos)
|
||||
- [iOS](#ios)
|
||||
- [Solaris](#solaris)
|
||||
- [HaikuOS](#haikuos)
|
||||
- [OpenBSD](#openbsd)
|
||||
|
|
@ -31,6 +32,16 @@ If you're having issues with building, always consult that ebuild.
|
|||
|
||||
macOS is largely untested. Expect crashes, significant Vulkan issues, and other fun stuff.
|
||||
|
||||
## iOS
|
||||
|
||||
iOS has a dedicated build script, we **highly** recommend using that instead of doing anything else, we don't support any other configuration than the one present in said build script.
|
||||
|
||||
To build, it's simply as easy as doing
|
||||
```sh
|
||||
chmod +x .ci/ios/build.sh
|
||||
.ci/ios/build.sh
|
||||
```
|
||||
|
||||
## Solaris
|
||||
|
||||
Always consult [the OpenIndiana package list](https://pkg.openindiana.org/hipster/en/index.shtml) to cross-verify availability.
|
||||
|
|
|
|||
4
externals/CMakeLists.txt
vendored
4
externals/CMakeLists.txt
vendored
|
|
@ -228,6 +228,10 @@ if (VulkanMemoryAllocator_ADDED)
|
|||
endif()
|
||||
|
||||
# httplib
|
||||
if (IOS)
|
||||
set(HTTPLIB_USE_BROTLI_IF_AVAILABLE OFF)
|
||||
endif()
|
||||
|
||||
AddJsonPackage(httplib)
|
||||
|
||||
# cpp-jwt
|
||||
|
|
|
|||
23
externals/cmake-modules/DetectArchitecture.cmake
vendored
23
externals/cmake-modules/DetectArchitecture.cmake
vendored
|
|
@ -35,16 +35,21 @@ This file is based off of Yuzu and Dynarmic.
|
|||
# Do note that situations where multiple architectures are defined
|
||||
# should NOT be too dependent on the architecture
|
||||
# otherwise, you may end up with duplicate code
|
||||
if (CMAKE_OSX_ARCHITECTURES)
|
||||
if (DEFINED CMAKE_OSX_ARCHITECTURES)
|
||||
set(MULTIARCH_BUILD 1)
|
||||
set(ARCHITECTURE "${CMAKE_OSX_ARCHITECTURES}")
|
||||
|
||||
# hope and pray the architecture names match
|
||||
foreach(ARCH IN ${CMAKE_OSX_ARCHITECTURES})
|
||||
set(ARCHITECTURE_${ARCH} 1 PARENT_SCOPE)
|
||||
add_definitions(-DARCHITECTURE_${ARCH}=1)
|
||||
endforeach()
|
||||
|
||||
if (IOS)
|
||||
# TODO: Right... the toolchain file won't properly accomodate OSX_ARCHITECTURE
|
||||
# they aren't defining it as a list properly I assume?
|
||||
set(ARCHITECTURE_arm64 1)
|
||||
add_definitions(-DARCHITECTURE_arm64=1)
|
||||
else ()
|
||||
# hope and pray the architecture names match
|
||||
foreach(ARCH ${CMAKE_OSX_ARCHITECTURES})
|
||||
set(ARCHITECTURE_${ARCH} 1)
|
||||
add_definitions(-DARCHITECTURE_${ARCH}=1)
|
||||
endforeach()
|
||||
endif()
|
||||
return()
|
||||
endif()
|
||||
|
||||
|
|
@ -218,4 +223,4 @@ if (NOT DEFINED ARCHITECTURE)
|
|||
add_definitions(-DARCHITECTURE_GENERIC=1)
|
||||
endif()
|
||||
|
||||
message(STATUS "[DetectArchitecture] Target architecture: ${ARCHITECTURE}")
|
||||
message(STATUS "[DetectArchitecture] Target architecture: ${ARCHITECTURE}")
|
||||
|
|
|
|||
6
externals/cmake-modules/DetectPlatform.cmake
vendored
6
externals/cmake-modules/DetectPlatform.cmake
vendored
|
|
@ -51,6 +51,12 @@ elseif (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang")
|
|||
set(CXX_APPLE ON)
|
||||
endif()
|
||||
|
||||
# This fixes some quirks with xcrun or weird iOS toolchain cmake files
|
||||
if (IOS)
|
||||
unset(CXX_CLANG)
|
||||
set(CXX_APPLE ON)
|
||||
endif()
|
||||
|
||||
# https://gitlab.kitware.com/cmake/cmake/-/merge_requests/11112
|
||||
# This works totally fine on MinGW64, but not CLANG{,ARM}64
|
||||
if(MINGW AND CXX_CLANG)
|
||||
|
|
|
|||
8
externals/cpmfile.json
vendored
8
externals/cpmfile.json
vendored
|
|
@ -23,7 +23,7 @@
|
|||
"package": "sirit",
|
||||
"name": "sirit",
|
||||
"repo": "eden-emulator/sirit",
|
||||
"version": "1.0.4"
|
||||
"version": "1.0.5"
|
||||
},
|
||||
"httplib": {
|
||||
"repo": "yhirose/cpp-httplib",
|
||||
|
|
@ -36,7 +36,8 @@
|
|||
"0002-fix-zstd.patch"
|
||||
],
|
||||
"options": [
|
||||
"HTTPLIB_REQUIRE_OPENSSL ON"
|
||||
"HTTPLIB_REQUIRE_OPENSSL ON",
|
||||
"HTTPLIB_DISABLE_MACOSX_AUTOMATIC_ROOT_CERTIFICATES ON"
|
||||
]
|
||||
},
|
||||
"cpp-jwt": {
|
||||
|
|
@ -111,7 +112,8 @@
|
|||
],
|
||||
"patches": [
|
||||
"0001-netbsd-fix.patch",
|
||||
"0002-allow-static-only.patch"
|
||||
"0002-allow-static-only.patch",
|
||||
"0003-ios-fix.patch"
|
||||
]
|
||||
},
|
||||
"spirv-headers": {
|
||||
|
|
|
|||
28
externals/ffmpeg/CMakeLists.txt
vendored
28
externals/ffmpeg/CMakeLists.txt
vendored
|
|
@ -1,4 +1,4 @@
|
|||
# SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
# SPDX-FileCopyrightText: 2021 yuzu Emulator Project
|
||||
|
|
@ -11,9 +11,9 @@ set(FFmpeg_HWACCEL_FLAGS)
|
|||
set(FFmpeg_HWACCEL_INCLUDE_DIRS)
|
||||
set(FFmpeg_HWACCEL_LDFLAGS)
|
||||
|
||||
if (UNIX AND NOT ANDROID)
|
||||
if (UNIX AND NOT ANDROID AND NOT IOS)
|
||||
find_package(PkgConfig REQUIRED)
|
||||
if (NOT ANDROID)
|
||||
if (NOT ANDROID AND NOT IOS)
|
||||
pkg_check_modules(LIBVA libva)
|
||||
pkg_check_modules(CUDA cuda)
|
||||
pkg_check_modules(FFNVCODEC ffnvcodec)
|
||||
|
|
@ -182,6 +182,10 @@ else()
|
|||
find_program(BASH_PROGRAM bash REQUIRED)
|
||||
|
||||
set(FFmpeg_CROSS_COMPILE_FLAGS "")
|
||||
# `configure` parameters builds only exactly what yuzu needs from FFmpeg
|
||||
# `--disable-vdpau` is needed to avoid linking issues
|
||||
set(FFmpeg_CC ${CMAKE_C_COMPILER_LAUNCHER} ${CMAKE_C_COMPILER})
|
||||
set(FFmpeg_CXX ${CMAKE_CXX_COMPILER_LAUNCHER} ${CMAKE_CXX_COMPILER})
|
||||
if (ANDROID)
|
||||
string(TOLOWER "${CMAKE_HOST_SYSTEM_NAME}" FFmpeg_HOST_SYSTEM_NAME)
|
||||
set(TOOLCHAIN "${ANDROID_NDK}/toolchains/llvm/prebuilt/${FFmpeg_HOST_SYSTEM_NAME}-${CMAKE_HOST_SYSTEM_PROCESSOR}")
|
||||
|
|
@ -197,12 +201,22 @@ else()
|
|||
--extra-ldflags="--ld-path=${TOOLCHAIN}/bin/ld.lld"
|
||||
--extra-ldflags="-nostdlib"
|
||||
)
|
||||
elseif(IOS)
|
||||
execute_process(COMMAND xcrun --sdk iphoneos --show-sdk-path OUTPUT_VARIABLE SYSROOT)
|
||||
# Lovely extra newline apple adds that **we** must remove... thank you apple!
|
||||
string(STRIP "${SYSROOT}" SYSROOT)
|
||||
set(FFmpeg_CC xcrun --sdk iphoneos clang -arch arm64)
|
||||
set(FFmpeg_CXX xcrun --sdk iphoneos clang++ -arch arm64)
|
||||
list(APPEND FFmpeg_CROSS_COMPILE_FLAGS
|
||||
--arch=arm64
|
||||
--enable-cross-compile
|
||||
--sysroot="${SYSROOT}"
|
||||
--extra-ldflags="-miphoneos-version-min=16.0"
|
||||
--install-name-dir='@rpath'
|
||||
--disable-audiotoolbox
|
||||
)
|
||||
endif()
|
||||
|
||||
# `configure` parameters builds only exactly what yuzu needs from FFmpeg
|
||||
# `--disable-vdpau` is needed to avoid linking issues
|
||||
set(FFmpeg_CC ${CMAKE_C_COMPILER_LAUNCHER} ${CMAKE_C_COMPILER})
|
||||
set(FFmpeg_CXX ${CMAKE_CXX_COMPILER_LAUNCHER} ${CMAKE_CXX_COMPILER})
|
||||
add_custom_command(
|
||||
OUTPUT
|
||||
${FFmpeg_MAKEFILE}
|
||||
|
|
|
|||
3
externals/libusb/CMakeLists.txt
vendored
3
externals/libusb/CMakeLists.txt
vendored
|
|
@ -24,7 +24,8 @@ if (MINGW OR PLATFORM_LINUX OR APPLE)
|
|||
message(FATAL_ERROR "Required program `autoconf` not found.")
|
||||
endif()
|
||||
|
||||
find_program(LIBTOOLIZE libtoolize)
|
||||
find_program(LIBTOOLIZE
|
||||
NAMES libtoolize glibtoolize)
|
||||
if ("${LIBTOOLIZE}" STREQUAL "LIBTOOLIZE-NOTFOUND")
|
||||
message(FATAL_ERROR "Required program `libtoolize` not found.")
|
||||
endif()
|
||||
|
|
|
|||
|
|
@ -127,13 +127,15 @@ else()
|
|||
add_compile_options(
|
||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Werror=all>
|
||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Werror=extra>
|
||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Werror=missing-declarations>
|
||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Werror=shadow>
|
||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Werror=unused>
|
||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-attributes>
|
||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-invalid-offsetof>
|
||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-unused-parameter>
|
||||
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-missing-field-initializers>)
|
||||
if (NOT IOS)
|
||||
add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:-Werror=missing-declarations>)
|
||||
endif()
|
||||
|
||||
if (CXX_CLANG OR CXX_ICC OR CXX_APPLE) # Clang, AppleClang, or Intel C++
|
||||
if (NOT MSVC)
|
||||
|
|
@ -249,4 +251,9 @@ if (ANDROID)
|
|||
target_include_directories(yuzu-android PRIVATE android/app/src/main)
|
||||
endif()
|
||||
|
||||
if (IOS)
|
||||
add_subdirectory(ios)
|
||||
add_compile_options($<$<COMPILE_LANGUAGE:C,CXX>:-Wno-error>)
|
||||
endif()
|
||||
|
||||
include(GenerateDepHashes)
|
||||
|
|
|
|||
|
|
@ -144,7 +144,8 @@ add_library(
|
|||
zstd_compression.cpp
|
||||
zstd_compression.h
|
||||
fs/ryujinx_compat.h fs/ryujinx_compat.cpp
|
||||
fs/symlink.h fs/symlink.cpp)
|
||||
fs/symlink.h fs/symlink.cpp
|
||||
httplib.h)
|
||||
|
||||
if(WIN32)
|
||||
target_sources(common PRIVATE windows/timer_resolution.cpp
|
||||
|
|
@ -242,7 +243,7 @@ else()
|
|||
target_link_libraries(common PUBLIC Boost::headers)
|
||||
endif()
|
||||
|
||||
target_link_libraries(common PUBLIC Boost::filesystem Boost::context)
|
||||
target_link_libraries(common PUBLIC Boost::filesystem Boost::context httplib::httplib)
|
||||
|
||||
if (lz4_ADDED)
|
||||
target_include_directories(common PRIVATE ${lz4_SOURCE_DIR}/lib)
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "device_power_state.h"
|
||||
|
|
@ -14,11 +14,14 @@ extern std::atomic<bool> g_has_battery;
|
|||
|
||||
#elif defined(__APPLE__)
|
||||
#include <TargetConditionals.h>
|
||||
#if TARGET_OS_MAC
|
||||
#if defined(TARGET_OS_MAC) && TARGET_OS_MAC
|
||||
#if TARGET_OS_IPHONE
|
||||
// ios doesnt have this
|
||||
#else
|
||||
#include <IOKit/ps/IOPSKeys.h>
|
||||
#include <IOKit/ps/IOPowerSources.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#elif defined(__linux__)
|
||||
#include <fstream>
|
||||
#include <string>
|
||||
|
|
@ -48,7 +51,9 @@ namespace Common {
|
|||
info.percentage = g_battery_percentage.load(std::memory_order_relaxed);
|
||||
info.charging = g_is_charging.load(std::memory_order_relaxed);
|
||||
info.has_battery = g_has_battery.load(std::memory_order_relaxed);
|
||||
|
||||
#elif defined(__APPLE__) && TARGET_OS_IPHONE
|
||||
// Not implemented
|
||||
info.has_battery = false;
|
||||
#elif defined(__APPLE__) && TARGET_OS_MAC
|
||||
CFTypeRef info_ref = IOPSCopyPowerSourcesInfo();
|
||||
CFArrayRef sources = IOPSCopyPowerSourcesList(info_ref);
|
||||
|
|
@ -96,7 +101,6 @@ namespace Common {
|
|||
#else
|
||||
info.has_battery = false;
|
||||
#endif
|
||||
|
||||
return info;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,7 +27,11 @@
|
|||
#include <sys/random.h>
|
||||
#elif defined(__APPLE__)
|
||||
#include <sys/types.h>
|
||||
#if defined(TARGET_OS_IPHONE) && TARGET_OS_IPHONE
|
||||
// Not available on iOS for some fucking stupid reason...
|
||||
#else
|
||||
#include <sys/random.h>
|
||||
#endif
|
||||
#include <mach/vm_map.h>
|
||||
#include <mach/mach.h>
|
||||
#elif defined(__FreeBSD__)
|
||||
|
|
|
|||
9
src/common/httplib.h
Normal file
9
src/common/httplib.h
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#define CPPHTTPLIB_DISABLE_MACOSX_AUTOMATIC_ROOT_CERTIFICATES
|
||||
#define CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
|
||||
#include <httplib.h>
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: 2013 Dolphin Emulator Project
|
||||
|
|
@ -116,18 +116,119 @@ std::string ReplaceAll(std::string result, const std::string& src, const std::st
|
|||
}
|
||||
|
||||
std::string UTF16ToUTF8(std::u16string_view input) {
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
|
||||
return convert.to_bytes(input.data(), input.data() + input.size());
|
||||
std::string result;
|
||||
result.reserve(input.size());
|
||||
for (size_t i = 0; i < input.size(); ++i) {
|
||||
uint32_t codepoint = input[i];
|
||||
// Handle surrogate pairs
|
||||
if (codepoint >= 0xD800 && codepoint <= 0xDBFF) {
|
||||
if (i + 1 < input.size()) {
|
||||
uint32_t low = input[i + 1];
|
||||
if (low >= 0xDC00 && low <= 0xDFFF) {
|
||||
codepoint = ((codepoint - 0xD800) << 10) + (low - 0xDC00) + 0x10000;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (codepoint <= 0x7F) {
|
||||
result.push_back(static_cast<char>(codepoint));
|
||||
} else if (codepoint <= 0x7FF) {
|
||||
result.push_back(static_cast<char>(0xC0 | (codepoint >> 6)));
|
||||
result.push_back(static_cast<char>(0x80 | (codepoint & 0x3F)));
|
||||
} else if (codepoint <= 0xFFFF) {
|
||||
result.push_back(static_cast<char>(0xE0 | (codepoint >> 12)));
|
||||
result.push_back(static_cast<char>(0x80 | ((codepoint >> 6) & 0x3F)));
|
||||
result.push_back(static_cast<char>(0x80 | (codepoint & 0x3F)));
|
||||
} else {
|
||||
result.push_back(static_cast<char>(0xF0 | (codepoint >> 18)));
|
||||
result.push_back(static_cast<char>(0x80 | ((codepoint >> 12) & 0x3F)));
|
||||
result.push_back(static_cast<char>(0x80 | ((codepoint >> 6) & 0x3F)));
|
||||
result.push_back(static_cast<char>(0x80 | (codepoint & 0x3F)));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::u16string UTF8ToUTF16(std::string_view input) {
|
||||
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t> convert;
|
||||
return convert.from_bytes(input.data(), input.data() + input.size());
|
||||
std::u16string result;
|
||||
size_t i = 0;
|
||||
while (i < input.size()) {
|
||||
uint32_t codepoint = 0;
|
||||
unsigned char c = input[i];
|
||||
size_t extra = 0;
|
||||
if ((c & 0x80) == 0) {
|
||||
codepoint = c;
|
||||
extra = 0;
|
||||
} else if ((c & 0xE0) == 0xC0) {
|
||||
codepoint = c & 0x1F;
|
||||
extra = 1;
|
||||
} else if ((c & 0xF0) == 0xE0) {
|
||||
codepoint = c & 0x0F;
|
||||
extra = 2;
|
||||
} else if ((c & 0xF8) == 0xF0) {
|
||||
codepoint = c & 0x07;
|
||||
extra = 3;
|
||||
} else {
|
||||
// Invalid UTF-8
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
if (i + extra >= input.size()) break;
|
||||
for (size_t j = 1; j <= extra; ++j) {
|
||||
if ((input[i + j] & 0xC0) != 0x80) {
|
||||
codepoint = 0xFFFD;
|
||||
break;
|
||||
}
|
||||
codepoint = (codepoint << 6) | (input[i + j] & 0x3F);
|
||||
}
|
||||
if (codepoint <= 0xFFFF) {
|
||||
result.push_back(static_cast<char16_t>(codepoint));
|
||||
} else {
|
||||
codepoint -= 0x10000;
|
||||
result.push_back(static_cast<char16_t>(0xD800 + (codepoint >> 10)));
|
||||
result.push_back(static_cast<char16_t>(0xDC00 + (codepoint & 0x3FF)));
|
||||
}
|
||||
i += extra + 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::u32string UTF8ToUTF32(std::string_view input) {
|
||||
std::wstring_convert<std::codecvt_utf8<char32_t>, char32_t> convert;
|
||||
return convert.from_bytes(input.data(), input.data() + input.size());
|
||||
std::u32string result;
|
||||
size_t i = 0;
|
||||
while (i < input.size()) {
|
||||
uint32_t codepoint = 0;
|
||||
unsigned char c = input[i];
|
||||
size_t extra = 0;
|
||||
if ((c & 0x80) == 0) {
|
||||
codepoint = c;
|
||||
extra = 0;
|
||||
} else if ((c & 0xE0) == 0xC0) {
|
||||
codepoint = c & 0x1F;
|
||||
extra = 1;
|
||||
} else if ((c & 0xF0) == 0xE0) {
|
||||
codepoint = c & 0x0F;
|
||||
extra = 2;
|
||||
} else if ((c & 0xF8) == 0xF0) {
|
||||
codepoint = c & 0x07;
|
||||
extra = 3;
|
||||
} else {
|
||||
// Invalid UTF-8
|
||||
++i;
|
||||
continue;
|
||||
}
|
||||
if (i + extra >= input.size()) break;
|
||||
for (size_t j = 1; j <= extra; ++j) {
|
||||
if ((input[i + j] & 0xC0) != 0x80) {
|
||||
codepoint = 0xFFFD;
|
||||
break;
|
||||
}
|
||||
codepoint = (codepoint << 6) | (input[i + j] & 0x3F);
|
||||
}
|
||||
result.push_back(codepoint);
|
||||
i += extra + 1;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
|
|
|
|||
|
|
@ -1264,12 +1264,15 @@ if (ARCHITECTURE_x86_64 OR ARCHITECTURE_arm64)
|
|||
hle/service/jit/jit.cpp
|
||||
hle/service/jit/jit.h)
|
||||
target_link_libraries(core PRIVATE dynarmic::dynarmic)
|
||||
# Quick hack for XCode generator...
|
||||
if (IOS)
|
||||
target_include_directories(core PRIVATE "${CMAKE_SOURCE_DIR}/dynarmic/src")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
target_sources(core PRIVATE hle/service/ssl/ssl_backend_openssl.cpp)
|
||||
|
||||
target_link_libraries(core PRIVATE OpenSSL::SSL OpenSSL::Crypto)
|
||||
target_compile_definitions(core PRIVATE CPPHTTPLIB_OPENSSL_SUPPORT)
|
||||
|
||||
# TODO
|
||||
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <dynarmic/interface/halt_reason.h>
|
||||
#include "dynarmic/src/dynarmic/interface/halt_reason.h"
|
||||
|
||||
#include "core/arm/arm_interface.h"
|
||||
|
||||
|
|
|
|||
|
|
@ -6,8 +6,8 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <dynarmic/interface/A32/a32.h>
|
||||
#include <dynarmic/interface/code_page.h>
|
||||
#include "dynarmic/src/dynarmic/interface/A32/a32.h"
|
||||
#include "dynarmic/src/dynarmic/interface/code_page.h"
|
||||
|
||||
#include "core/arm/arm_interface.h"
|
||||
#include "core/arm/dynarmic/dynarmic_exclusive_monitor.h"
|
||||
|
|
|
|||
|
|
@ -10,12 +10,12 @@
|
|||
#include <memory>
|
||||
#include <ankerl/unordered_dense.h>
|
||||
|
||||
#include <dynarmic/interface/A64/a64.h>
|
||||
#include <dynarmic/interface/code_page.h>
|
||||
#include "common/common_types.h"
|
||||
#include "common/hash.h"
|
||||
#include "core/arm/arm_interface.h"
|
||||
#include "core/arm/dynarmic/dynarmic_exclusive_monitor.h"
|
||||
#include "../../../dynarmic/src/dynarmic/interface/A64/a64.h"
|
||||
#include "../../../dynarmic/src/dynarmic/interface/code_page.h"
|
||||
#include "../../../common/common_types.h"
|
||||
#include "../../../common/hash.h"
|
||||
#include "../arm_interface.h"
|
||||
#include "dynarmic_exclusive_monitor.h"
|
||||
|
||||
namespace Core::Memory {
|
||||
class Memory;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 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
|
||||
|
||||
|
|
@ -5,7 +8,7 @@
|
|||
|
||||
#include <optional>
|
||||
|
||||
#include <dynarmic/interface/A32/coprocessor.h>
|
||||
#include "dynarmic/interface/A32/coprocessor.h"
|
||||
#include "common/common_types.h"
|
||||
|
||||
namespace Core {
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <dynarmic/interface/exclusive_monitor.h>
|
||||
#include "dynarmic/src/dynarmic/interface/exclusive_monitor.h"
|
||||
|
||||
#include "common/common_types.h"
|
||||
#include "core/arm/exclusive_monitor.h"
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2023 merryhime <https://mary.rs>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
|
@ -7,9 +10,9 @@
|
|||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Wshadow"
|
||||
|
||||
#include <dynarmic/frontend/A64/a64_types.h>
|
||||
#include <dynarmic/frontend/A64/decoder/a64.h>
|
||||
#include <dynarmic/frontend/imm.h>
|
||||
#include "dynarmic/frontend/A64/a64_types.h"
|
||||
#include "dynarmic/frontend/A64/decoder/a64.h"
|
||||
#include "dynarmic/frontend/imm.h"
|
||||
|
||||
#pragma GCC diagnostic pop
|
||||
|
||||
|
|
|
|||
|
|
@ -15,9 +15,7 @@
|
|||
#include <fmt/format.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
#include <httplib.h>
|
||||
#endif
|
||||
#include "common/httplib.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
|
|
@ -37,7 +35,7 @@
|
|||
namespace Service::News {
|
||||
namespace {
|
||||
|
||||
constexpr const char* GitHubAPI_EdenReleases = "/repos/eden-emulator/Releases/releases";
|
||||
[[maybe_unused]] constexpr const char* GitHubAPI_EdenReleases = "/repos/eden-emulator/Releases/releases";
|
||||
|
||||
// Cached logo data
|
||||
std::vector<u8> default_logo_small;
|
||||
|
|
@ -104,7 +102,6 @@ std::vector<u8> TryLoadFromDisk(const std::filesystem::path& path) {
|
|||
std::vector<u8> DownloadImage(const std::string& url_path, const std::filesystem::path& cache_path) {
|
||||
LOG_INFO(Service_BCAT, "Downloading image: https://eden-emu.dev{}", url_path);
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
try {
|
||||
httplib::Client cli("https://eden-emu.dev");
|
||||
cli.set_follow_location(true);
|
||||
|
|
@ -128,7 +125,6 @@ std::vector<u8> DownloadImage(const std::string& url_path, const std::filesystem
|
|||
} catch (...) {
|
||||
LOG_WARNING(Service_BCAT, "Failed to download: {}", url_path);
|
||||
}
|
||||
#endif
|
||||
|
||||
return {};
|
||||
}
|
||||
|
|
@ -233,7 +229,6 @@ void WriteCachedJson(std::string_view json) {
|
|||
|
||||
std::optional<std::string> DownloadReleasesJson() {
|
||||
|
||||
#ifdef CPPHTTPLIB_OPENSSL_SUPPORT
|
||||
try {
|
||||
httplib::SSLClient cli{"api.github.com", 443};
|
||||
cli.set_connection_timeout(10);
|
||||
|
|
@ -255,7 +250,7 @@ std::optional<std::string> DownloadReleasesJson() {
|
|||
} catch (...) {
|
||||
LOG_WARNING(Service_BCAT, " failed to download releases");
|
||||
}
|
||||
#endif
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -8,9 +8,9 @@
|
|||
#include <map>
|
||||
#include <span>
|
||||
#include <boost/icl/interval_set.hpp>
|
||||
#include <dynarmic/interface/A64/a64.h>
|
||||
#include <dynarmic/interface/A64/config.h>
|
||||
#include <dynarmic/interface/code_page.h>
|
||||
#include "dynarmic/interface/A64/a64.h"
|
||||
#include "dynarmic/interface/A64/config.h"
|
||||
#include "dynarmic/interface/code_page.h"
|
||||
|
||||
#include "common/alignment.h"
|
||||
#include "common/common_funcs.h"
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
/* This file is part of the dynarmic project.
|
||||
|
|
@ -14,8 +14,8 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "dynarmic/interface/A32/config.h"
|
||||
#include "dynarmic/interface/halt_reason.h"
|
||||
#include "config.h"
|
||||
#include "dynarmic/src/dynarmic/interface/halt_reason.h"
|
||||
|
||||
namespace Dynarmic {
|
||||
namespace A32 {
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@
|
|||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
#include "dynarmic/frontend/A32/translate/translate_callbacks.h"
|
||||
#include "dynarmic/interface/A32/arch_version.h"
|
||||
#include "dynarmic/interface/optimization_flags.h"
|
||||
#include "../../frontend/A32/translate/translate_callbacks.h"
|
||||
#include "arch_version.h"
|
||||
#include "../optimization_flags.h"
|
||||
|
||||
namespace Dynarmic {
|
||||
class ExclusiveMonitor;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
/* This file is part of the dynarmic project.
|
||||
|
|
@ -15,8 +15,8 @@
|
|||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "dynarmic/interface/A64/config.h"
|
||||
#include "dynarmic/interface/halt_reason.h"
|
||||
#include "config.h"
|
||||
#include "../halt_reason.h"
|
||||
|
||||
namespace Dynarmic {
|
||||
namespace A64 {
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
#include "dynarmic/interface/optimization_flags.h"
|
||||
#include "../optimization_flags.h"
|
||||
|
||||
namespace Dynarmic {
|
||||
class ExclusiveMonitor;
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
/* This file is part of the dynarmic project.
|
||||
* Copyright (c) 2018 MerryMage
|
||||
* SPDX-License-Identifier: 0BSD
|
||||
|
|
@ -11,7 +14,7 @@
|
|||
#include <cstring>
|
||||
#include <boost/container/static_vector.hpp>
|
||||
|
||||
#include <dynarmic/common/spin_lock.h>
|
||||
#include "dynarmic/src/dynarmic/common/spin_lock.h"
|
||||
|
||||
namespace Dynarmic {
|
||||
|
||||
|
|
|
|||
|
|
@ -22,8 +22,6 @@ if (ENABLE_UPDATE_CHECKER)
|
|||
target_sources(frontend_common PRIVATE
|
||||
update_checker.cpp
|
||||
update_checker.h)
|
||||
|
||||
target_compile_definitions(frontend_common PUBLIC CPPHTTPLIB_OPENSSL_SUPPORT)
|
||||
target_link_libraries(frontend_common PRIVATE OpenSSL::SSL OpenSSL::Crypto)
|
||||
endif()
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
#include "common/scm_rev.h"
|
||||
#include "update_checker.h"
|
||||
|
||||
#include <httplib.h>
|
||||
#include "common/httplib.h"
|
||||
|
||||
#ifdef YUZU_BUNDLED_OPENSSL
|
||||
#include <openssl/cert.h>
|
||||
|
|
|
|||
11
src/ios/AppUI-Bridging-Header.h
Normal file
11
src/ios/AppUI-Bridging-Header.h
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: Copyright 2024 Jarrod Norwell
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#ifndef AppUI_Bridging_Header_h
|
||||
#define AppUI_Bridging_Header_h
|
||||
|
||||
#import "AppUIObjC.h"
|
||||
|
||||
#endif /* AppUI_Bridging_Header_h */
|
||||
105
src/ios/AppUI.swift
Normal file
105
src/ios/AppUI.swift
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: Copyright 2024 Jarrod Norwell
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import UIKit
|
||||
import Foundation
|
||||
import QuartzCore.CAMetalLayer
|
||||
|
||||
public struct AppUI {
|
||||
|
||||
public static let shared = AppUI()
|
||||
|
||||
fileprivate let appUIObjC = AppUIObjC.shared()
|
||||
|
||||
public func configure(layer: CAMetalLayer, with size: CGSize) {
|
||||
appUIObjC.configure(layer: layer, with: size)
|
||||
}
|
||||
|
||||
public func information(for url: URL) -> AppUIInformation {
|
||||
appUIObjC.gameInformation.information(for: url)
|
||||
}
|
||||
|
||||
public func insert(game url: URL) {
|
||||
appUIObjC.insert(game: url)
|
||||
}
|
||||
|
||||
public func insert(games urls: [URL]) {
|
||||
appUIObjC.insert(games: urls)
|
||||
}
|
||||
|
||||
public func bootOS() {
|
||||
appUIObjC.bootOS()
|
||||
}
|
||||
|
||||
public func pause() {
|
||||
appUIObjC.pause()
|
||||
}
|
||||
|
||||
public func play() {
|
||||
appUIObjC.play()
|
||||
}
|
||||
|
||||
public func ispaused() -> Bool {
|
||||
return appUIObjC.ispaused()
|
||||
}
|
||||
|
||||
public func FirstFrameShowed() -> Bool {
|
||||
return appUIObjC.hasfirstfame()
|
||||
}
|
||||
|
||||
public func canGetFullPath() -> Bool {
|
||||
return appUIObjC.canGetFullPath()
|
||||
}
|
||||
|
||||
|
||||
public func exit() {
|
||||
appUIObjC.quit()
|
||||
}
|
||||
|
||||
public func step() {
|
||||
appUIObjC.step()
|
||||
}
|
||||
|
||||
public func orientationChanged(orientation: UIInterfaceOrientation, with layer: CAMetalLayer, size: CGSize) {
|
||||
appUIObjC.orientationChanged(orientation: orientation, with: layer, size: size)
|
||||
}
|
||||
|
||||
public func touchBegan(at point: CGPoint, for index: UInt) {
|
||||
appUIObjC.touchBegan(at: point, for: index)
|
||||
}
|
||||
|
||||
public func touchEnded(for index: UInt) {
|
||||
appUIObjC.touchEnded(for: index)
|
||||
}
|
||||
|
||||
public func touchMoved(at point: CGPoint, for index: UInt) {
|
||||
appUIObjC.touchMoved(at: point, for: index)
|
||||
}
|
||||
|
||||
public func gyroMoved(x: Float, y: Float, z: Float, accelX: Float, accelY: Float, accelZ: Float, controllerId: Int32, deltaTimestamp: Int32) {
|
||||
// Calling the Objective-C function with both gyroscope and accelerometer data
|
||||
appUIObjC.virtualControllerGyro(controllerId,
|
||||
deltaTimestamp: deltaTimestamp,
|
||||
gyroX: x, gyroY: y, gyroZ: z,
|
||||
accelX: accelX, accelY: accelY, accelZ: accelZ)
|
||||
}
|
||||
|
||||
|
||||
public func thumbstickMoved(analog: VirtualControllerAnalogType, x: Float, y: Float, controllerid: Int) {
|
||||
appUIObjC.thumbstickMoved(analog, x: CGFloat(x), y: CGFloat(y), controllerId: Int32(controllerid))
|
||||
}
|
||||
|
||||
public func virtualControllerButtonDown(button: VirtualControllerButtonType, controllerid: Int) {
|
||||
appUIObjC.virtualControllerButtonDown(button, controllerId: Int32(controllerid))
|
||||
}
|
||||
|
||||
public func virtualControllerButtonUp(button: VirtualControllerButtonType, controllerid: Int) {
|
||||
appUIObjC.virtualControllerButtonUp(button, controllerId: Int32(controllerid))
|
||||
}
|
||||
|
||||
public func settingsSaved() {
|
||||
appUIObjC.settingsChanged()
|
||||
}
|
||||
}
|
||||
26
src/ios/AppUIGameInformation.h
Normal file
26
src/ios/AppUIGameInformation.h
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: Copyright 2024 Jarrod Norwell
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface AppUIInformation : NSObject
|
||||
@property (nonatomic, strong) NSString *developer;
|
||||
@property (nonatomic, strong) NSData *iconData;
|
||||
@property (nonatomic) BOOL isHomebrew;
|
||||
@property (nonatomic) uint64_t programID;
|
||||
@property (nonatomic, strong) NSString *title, *version;
|
||||
|
||||
-(AppUIInformation *) initWithDeveloper:(NSString *)developer iconData:(NSData *)iconData isHomebrew:(BOOL)isHomebrew programID:(uint64_t)programID title:(NSString *)title version:(NSString *)version;
|
||||
@end
|
||||
|
||||
@interface AppUIGameInformation : NSObject
|
||||
+(AppUIGameInformation *) sharedInstance NS_SWIFT_NAME(shared());
|
||||
|
||||
-(AppUIInformation *) informationForGame:(NSURL *)url NS_SWIFT_NAME(information(for:));
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
436
src/ios/AppUIGameInformation.mm
Normal file
436
src/ios/AppUIGameInformation.mm
Normal file
|
|
@ -0,0 +1,436 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: Copyright 2024 Jarrod Norwell
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "AppUIGameInformation.h"
|
||||
#import "EmulationSession.h"
|
||||
|
||||
#include "common/fs/fs.h"
|
||||
#include "common/fs/path_util.h"
|
||||
#include "core/core.h"
|
||||
#include "core/file_sys/fs_filesystem.h"
|
||||
#include "core/file_sys/patch_manager.h"
|
||||
#include "core/loader/loader.h"
|
||||
#include "core/loader/nro.h"
|
||||
#include "frontend_common/config.h"
|
||||
|
||||
struct GameMetadata {
|
||||
std::string title;
|
||||
u64 programId;
|
||||
std::string developer;
|
||||
std::string version;
|
||||
std::vector<u8> icon;
|
||||
bool isHomebrew;
|
||||
};
|
||||
|
||||
|
||||
class SdlConfig final : public Config {
|
||||
public:
|
||||
explicit SdlConfig(std::optional<std::string> config_path);
|
||||
~SdlConfig() override;
|
||||
|
||||
void ReloadAllValues() override;
|
||||
void SaveAllValues() override;
|
||||
|
||||
protected:
|
||||
void ReadSdlValues();
|
||||
void ReadSdlPlayerValues(std::size_t player_index);
|
||||
void ReadSdlControlValues();
|
||||
void ReadHidbusValues() override;
|
||||
void ReadDebugControlValues() override;
|
||||
void ReadPathValues() override {}
|
||||
void ReadShortcutValues() override {}
|
||||
void ReadUIValues() override {}
|
||||
void ReadUIGamelistValues() override {}
|
||||
void ReadUILayoutValues() override {}
|
||||
void ReadMultiplayerValues() override {}
|
||||
|
||||
void SaveSdlValues();
|
||||
void SaveSdlPlayerValues(std::size_t player_index);
|
||||
void SaveSdlControlValues();
|
||||
void SaveHidbusValues() override;
|
||||
void SaveDebugControlValues() override;
|
||||
void SavePathValues() override {}
|
||||
void SaveShortcutValues() override {}
|
||||
void SaveUIValues() override {}
|
||||
void SaveUIGamelistValues() override {}
|
||||
void SaveUILayoutValues() override {}
|
||||
void SaveMultiplayerValues() override {}
|
||||
|
||||
std::vector<Settings::BasicSetting*>& FindRelevantList(Settings::Category category) override;
|
||||
|
||||
public:
|
||||
static const std::array<int, Settings::NativeButton::NumButtons> default_buttons;
|
||||
static const std::array<int, Settings::NativeMotion::NumMotions> default_motions;
|
||||
static const std::array<std::array<int, 4>, Settings::NativeAnalog::NumAnalogs> default_analogs;
|
||||
static const std::array<int, 2> default_stick_mod;
|
||||
static const std::array<int, 2> default_ringcon_analogs;
|
||||
};
|
||||
|
||||
|
||||
#define SDL_MAIN_HANDLED
|
||||
#include <SDL.h>
|
||||
|
||||
#include "common/logging.h"
|
||||
#include "input_common/main.h"
|
||||
|
||||
const std::array<int, Settings::NativeButton::NumButtons> SdlConfig::default_buttons = {
|
||||
SDL_SCANCODE_A, SDL_SCANCODE_S, SDL_SCANCODE_Z, SDL_SCANCODE_X, SDL_SCANCODE_T,
|
||||
SDL_SCANCODE_G, SDL_SCANCODE_F, SDL_SCANCODE_H, SDL_SCANCODE_Q, SDL_SCANCODE_W,
|
||||
SDL_SCANCODE_M, SDL_SCANCODE_N, SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_B,
|
||||
};
|
||||
|
||||
const std::array<int, Settings::NativeMotion::NumMotions> SdlConfig::default_motions = {
|
||||
SDL_SCANCODE_7,
|
||||
SDL_SCANCODE_8,
|
||||
};
|
||||
|
||||
const std::array<std::array<int, 4>, Settings::NativeAnalog::NumAnalogs> SdlConfig::default_analogs{
|
||||
{
|
||||
{
|
||||
SDL_SCANCODE_UP,
|
||||
SDL_SCANCODE_DOWN,
|
||||
SDL_SCANCODE_LEFT,
|
||||
SDL_SCANCODE_RIGHT,
|
||||
},
|
||||
{
|
||||
SDL_SCANCODE_I,
|
||||
SDL_SCANCODE_K,
|
||||
SDL_SCANCODE_J,
|
||||
SDL_SCANCODE_L,
|
||||
},
|
||||
}};
|
||||
|
||||
const std::array<int, 2> SdlConfig::default_stick_mod = {
|
||||
SDL_SCANCODE_D,
|
||||
0,
|
||||
};
|
||||
|
||||
const std::array<int, 2> SdlConfig::default_ringcon_analogs{{
|
||||
0,
|
||||
0,
|
||||
}};
|
||||
|
||||
SdlConfig::SdlConfig(const std::optional<std::string> config_path) {
|
||||
Initialize(config_path);
|
||||
ReadSdlValues();
|
||||
SaveSdlValues();
|
||||
}
|
||||
|
||||
SdlConfig::~SdlConfig() {
|
||||
if (global) {
|
||||
SdlConfig::SaveAllValues();
|
||||
}
|
||||
}
|
||||
|
||||
void SdlConfig::ReloadAllValues() {
|
||||
Reload();
|
||||
ReadSdlValues();
|
||||
SaveSdlValues();
|
||||
}
|
||||
|
||||
void SdlConfig::SaveAllValues() {
|
||||
SaveValues();
|
||||
SaveSdlValues();
|
||||
}
|
||||
|
||||
void SdlConfig::ReadSdlValues() {
|
||||
ReadSdlControlValues();
|
||||
}
|
||||
|
||||
void SdlConfig::ReadSdlControlValues() {
|
||||
BeginGroup(Settings::TranslateCategory(Settings::Category::Controls));
|
||||
|
||||
Settings::values.players.SetGlobal(!IsCustomConfig());
|
||||
for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) {
|
||||
ReadSdlPlayerValues(p);
|
||||
}
|
||||
if (IsCustomConfig()) {
|
||||
EndGroup();
|
||||
return;
|
||||
}
|
||||
ReadDebugControlValues();
|
||||
ReadHidbusValues();
|
||||
|
||||
EndGroup();
|
||||
}
|
||||
|
||||
void SdlConfig::ReadSdlPlayerValues(const std::size_t player_index) {
|
||||
std::string player_prefix;
|
||||
if (type != ConfigType::InputProfile) {
|
||||
player_prefix.append("player_").append(ToString(player_index)).append("_");
|
||||
}
|
||||
|
||||
auto& player = Settings::values.players.GetValue()[player_index];
|
||||
if (IsCustomConfig()) {
|
||||
const auto profile_name =
|
||||
ReadStringSetting(std::string(player_prefix).append("profile_name"));
|
||||
if (profile_name.empty()) {
|
||||
// Use the global input config
|
||||
player = Settings::values.players.GetValue(true)[player_index];
|
||||
player.profile_name = "";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
|
||||
const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
|
||||
auto& player_buttons = player.buttons[i];
|
||||
|
||||
player_buttons = ReadStringSetting(
|
||||
std::string(player_prefix).append(Settings::NativeButton::mapping[i]), default_param);
|
||||
if (player_buttons.empty()) {
|
||||
player_buttons = default_param;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
|
||||
const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
|
||||
default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
|
||||
default_analogs[i][3], default_stick_mod[i], 0.5f);
|
||||
auto& player_analogs = player.analogs[i];
|
||||
|
||||
player_analogs = ReadStringSetting(
|
||||
std::string(player_prefix).append(Settings::NativeAnalog::mapping[i]), default_param);
|
||||
if (player_analogs.empty()) {
|
||||
player_analogs = default_param;
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) {
|
||||
const std::string default_param = InputCommon::GenerateKeyboardParam(default_motions[i]);
|
||||
auto& player_motions = player.motions[i];
|
||||
|
||||
player_motions = ReadStringSetting(
|
||||
std::string(player_prefix).append(Settings::NativeMotion::mapping[i]), default_param);
|
||||
if (player_motions.empty()) {
|
||||
player_motions = default_param;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SdlConfig::ReadDebugControlValues() {
|
||||
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
|
||||
const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
|
||||
auto& debug_pad_buttons = Settings::values.debug_pad_buttons[i];
|
||||
debug_pad_buttons = ReadStringSetting(
|
||||
std::string("debug_pad_").append(Settings::NativeButton::mapping[i]), default_param);
|
||||
if (debug_pad_buttons.empty()) {
|
||||
debug_pad_buttons = default_param;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
|
||||
const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
|
||||
default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
|
||||
default_analogs[i][3], default_stick_mod[i], 0.5f);
|
||||
auto& debug_pad_analogs = Settings::values.debug_pad_analogs[i];
|
||||
debug_pad_analogs = ReadStringSetting(
|
||||
std::string("debug_pad_").append(Settings::NativeAnalog::mapping[i]), default_param);
|
||||
if (debug_pad_analogs.empty()) {
|
||||
debug_pad_analogs = default_param;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SdlConfig::ReadHidbusValues() {
|
||||
const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
|
||||
0, 0, default_ringcon_analogs[0], default_ringcon_analogs[1], 0, 0.05f);
|
||||
auto& ringcon_analogs = Settings::values.ringcon_analogs;
|
||||
|
||||
ringcon_analogs = ReadStringSetting(std::string("ring_controller"), default_param);
|
||||
if (ringcon_analogs.empty()) {
|
||||
ringcon_analogs = default_param;
|
||||
}
|
||||
}
|
||||
|
||||
void SdlConfig::SaveSdlValues() {
|
||||
LOG_DEBUG(Config, "Saving SDL configuration values");
|
||||
SaveSdlControlValues();
|
||||
|
||||
WriteToIni();
|
||||
}
|
||||
|
||||
void SdlConfig::SaveSdlControlValues() {
|
||||
BeginGroup(Settings::TranslateCategory(Settings::Category::Controls));
|
||||
|
||||
Settings::values.players.SetGlobal(!IsCustomConfig());
|
||||
for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) {
|
||||
SaveSdlPlayerValues(p);
|
||||
}
|
||||
if (IsCustomConfig()) {
|
||||
EndGroup();
|
||||
return;
|
||||
}
|
||||
SaveDebugControlValues();
|
||||
SaveHidbusValues();
|
||||
|
||||
EndGroup();
|
||||
}
|
||||
|
||||
void SdlConfig::SaveSdlPlayerValues(const std::size_t player_index) {
|
||||
std::string player_prefix;
|
||||
if (type != ConfigType::InputProfile) {
|
||||
player_prefix = std::string("player_").append(ToString(player_index)).append("_");
|
||||
}
|
||||
|
||||
const auto& player = Settings::values.players.GetValue()[player_index];
|
||||
if (IsCustomConfig() && player.profile_name.empty()) {
|
||||
// No custom profile selected
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
|
||||
const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
|
||||
WriteStringSetting(std::string(player_prefix).append(Settings::NativeButton::mapping[i]),
|
||||
player.buttons[i], std::make_optional(default_param));
|
||||
}
|
||||
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
|
||||
const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
|
||||
default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
|
||||
default_analogs[i][3], default_stick_mod[i], 0.5f);
|
||||
WriteStringSetting(std::string(player_prefix).append(Settings::NativeAnalog::mapping[i]),
|
||||
player.analogs[i], std::make_optional(default_param));
|
||||
}
|
||||
for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) {
|
||||
const std::string default_param = InputCommon::GenerateKeyboardParam(default_motions[i]);
|
||||
WriteStringSetting(std::string(player_prefix).append(Settings::NativeMotion::mapping[i]),
|
||||
player.motions[i], std::make_optional(default_param));
|
||||
}
|
||||
}
|
||||
|
||||
void SdlConfig::SaveDebugControlValues() {
|
||||
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
|
||||
const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
|
||||
WriteStringSetting(std::string("debug_pad_").append(Settings::NativeButton::mapping[i]),
|
||||
Settings::values.debug_pad_buttons[i],
|
||||
std::make_optional(default_param));
|
||||
}
|
||||
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
|
||||
const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
|
||||
default_analogs[i][0], default_analogs[i][1], default_analogs[i][2],
|
||||
default_analogs[i][3], default_stick_mod[i], 0.5f);
|
||||
WriteStringSetting(std::string("debug_pad_").append(Settings::NativeAnalog::mapping[i]),
|
||||
Settings::values.debug_pad_analogs[i],
|
||||
std::make_optional(default_param));
|
||||
}
|
||||
}
|
||||
|
||||
void SdlConfig::SaveHidbusValues() {
|
||||
const std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
|
||||
0, 0, default_ringcon_analogs[0], default_ringcon_analogs[1], 0, 0.05f);
|
||||
WriteStringSetting(std::string("ring_controller"), Settings::values.ringcon_analogs,
|
||||
std::make_optional(default_param));
|
||||
}
|
||||
|
||||
std::vector<Settings::BasicSetting*>& SdlConfig::FindRelevantList(Settings::Category category) {
|
||||
return Settings::values.linkage.by_category[category];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
std::unordered_map<std::string, GameMetadata> m_game_metadata_cache;
|
||||
|
||||
GameMetadata CacheGameMetadata(const std::string& path) {
|
||||
const auto file =
|
||||
Core::GetGameFileFromPath(EmulationSession::GetInstance().System().GetFilesystem(), path);
|
||||
auto loader = Loader::GetLoader(EmulationSession::GetInstance().System(), file, 0, 0);
|
||||
|
||||
GameMetadata entry;
|
||||
loader->ReadTitle(entry.title);
|
||||
loader->ReadProgramId(entry.programId);
|
||||
loader->ReadIcon(entry.icon);
|
||||
|
||||
const FileSys::PatchManager pm{
|
||||
entry.programId, EmulationSession::GetInstance().System().GetFileSystemController(),
|
||||
EmulationSession::GetInstance().System().GetContentProvider()};
|
||||
const auto control = pm.GetControlMetadata();
|
||||
|
||||
if (control.first != nullptr) {
|
||||
entry.developer = control.first->GetDeveloperName();
|
||||
entry.version = control.first->GetVersionString();
|
||||
} else {
|
||||
FileSys::NACP nacp;
|
||||
if (loader->ReadControlData(nacp) == Loader::ResultStatus::Success) {
|
||||
entry.developer = nacp.GetDeveloperName();
|
||||
} else {
|
||||
entry.developer = "";
|
||||
}
|
||||
|
||||
entry.version = "1.0.0";
|
||||
}
|
||||
|
||||
if (loader->GetFileType() == Loader::FileType::NRO) {
|
||||
auto loader_nro = reinterpret_cast<Loader::AppLoader_NRO*>(loader.get());
|
||||
entry.isHomebrew = loader_nro->IsHomebrew();
|
||||
} else {
|
||||
entry.isHomebrew = false;
|
||||
}
|
||||
|
||||
m_game_metadata_cache[path] = entry;
|
||||
|
||||
return entry;
|
||||
}
|
||||
|
||||
GameMetadata GameMetadata(const std::string& path, bool reload = false) {
|
||||
if (!EmulationSession::GetInstance().IsInitialized()) {
|
||||
NSURL *dir_url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] firstObject];
|
||||
const char *directory_cstr = [[dir_url path] UTF8String];
|
||||
Common::FS::SetAppDirectory(directory_cstr);
|
||||
|
||||
EmulationSession::GetInstance().System().Initialize();
|
||||
EmulationSession::GetInstance().InitializeSystem(false);
|
||||
}
|
||||
|
||||
if (reload) {
|
||||
return CacheGameMetadata(path);
|
||||
}
|
||||
|
||||
if (auto search = m_game_metadata_cache.find(path); search != m_game_metadata_cache.end()) {
|
||||
return search->second;
|
||||
}
|
||||
|
||||
return CacheGameMetadata(path);
|
||||
}
|
||||
|
||||
|
||||
@implementation AppUIInformation
|
||||
-(AppUIInformation *) initWithDeveloper:(NSString *)developer iconData:(NSData *)iconData isHomebrew:(BOOL)isHomebrew programID:(uint64_t)programID
|
||||
title:(NSString *)title version:(NSString *)version {
|
||||
if (self = [super init]) {
|
||||
self.developer = developer;
|
||||
self.iconData = iconData;
|
||||
self.isHomebrew = isHomebrew;
|
||||
self.programID = programID;
|
||||
self.title = title;
|
||||
self.version = version;
|
||||
} return self;
|
||||
}
|
||||
@end
|
||||
|
||||
@implementation AppUIGameInformation
|
||||
+(AppUIGameInformation *) sharedInstance {
|
||||
static AppUIGameInformation *sharedInstance = NULL;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
sharedInstance = [[self alloc] init];
|
||||
});
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
|
||||
-(AppUIInformation *) informationForGame:(NSURL *)url {
|
||||
auto gameMetadata = GameMetadata([url.path UTF8String]);
|
||||
|
||||
return [[AppUIInformation alloc] initWithDeveloper:[NSString stringWithCString:gameMetadata.developer.c_str() encoding:NSUTF8StringEncoding]
|
||||
iconData:[NSData dataWithBytes:gameMetadata.icon.data() length:gameMetadata.icon.size()]
|
||||
isHomebrew:gameMetadata.isHomebrew programID:gameMetadata.programId
|
||||
title:[NSString stringWithCString:gameMetadata.title.c_str() encoding:NSUTF8StringEncoding]
|
||||
version:[NSString stringWithCString:gameMetadata.version.c_str() encoding:NSUTF8StringEncoding]];
|
||||
}
|
||||
@end
|
||||
93
src/ios/AppUIObjC.h
Normal file
93
src/ios/AppUIObjC.h
Normal file
|
|
@ -0,0 +1,93 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: Copyright 2024 Jarrod Norwell
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <MetalKit/MetalKit.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "AppUIGameInformation.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
typedef NS_ENUM(NSUInteger, VirtualControllerAnalogType) {
|
||||
VirtualControllerAnalogTypeLeft = 0,
|
||||
VirtualControllerAnalogTypeRight = 1
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSUInteger, VirtualControllerButtonType) {
|
||||
VirtualControllerButtonTypeA = 0,
|
||||
VirtualControllerButtonTypeB = 1,
|
||||
VirtualControllerButtonTypeX = 2,
|
||||
VirtualControllerButtonTypeY = 3,
|
||||
VirtualControllerButtonTypeL = 4,
|
||||
VirtualControllerButtonTypeR = 5,
|
||||
VirtualControllerButtonTypeTriggerL = 6,
|
||||
VirtualControllerButtonTypeTriggerR = 7,
|
||||
VirtualControllerButtonTypeTriggerZL = 8,
|
||||
VirtualControllerButtonTypeTriggerZR = 9,
|
||||
VirtualControllerButtonTypePlus = 10,
|
||||
VirtualControllerButtonTypeMinus = 11,
|
||||
VirtualControllerButtonTypeDirectionalPadLeft = 12,
|
||||
VirtualControllerButtonTypeDirectionalPadUp = 13,
|
||||
VirtualControllerButtonTypeDirectionalPadRight = 14,
|
||||
VirtualControllerButtonTypeDirectionalPadDown = 15,
|
||||
VirtualControllerButtonTypeSL = 16,
|
||||
VirtualControllerButtonTypeSR = 17,
|
||||
VirtualControllerButtonTypeHome = 18,
|
||||
VirtualControllerButtonTypeCapture = 19
|
||||
};
|
||||
|
||||
@interface AppUIObjC : NSObject {
|
||||
CAMetalLayer *_layer;
|
||||
CGSize _size;
|
||||
}
|
||||
|
||||
@property (nonatomic, strong) AppUIGameInformation *gameInformation;
|
||||
|
||||
+(AppUIObjC *) sharedInstance NS_SWIFT_NAME(shared());
|
||||
-(void) configureLayer:(CAMetalLayer *)layer withSize:(CGSize)size NS_SWIFT_NAME(configure(layer:with:));
|
||||
-(void) bootOS;
|
||||
-(void) pause;
|
||||
-(void) play;
|
||||
-(BOOL) ispaused;
|
||||
-(BOOL) canGetFullPath;
|
||||
-(void) quit;
|
||||
-(void) insertGame:(NSURL *)url NS_SWIFT_NAME(insert(game:));
|
||||
-(void) insertGames:(NSArray<NSURL *> *)games NS_SWIFT_NAME(insert(games:));
|
||||
-(void) step;
|
||||
-(BOOL) hasfirstfame;
|
||||
|
||||
-(void) touchBeganAtPoint:(CGPoint)point index:(NSUInteger)index NS_SWIFT_NAME(touchBegan(at:for:));
|
||||
-(void) touchEndedForIndex:(NSUInteger)index;
|
||||
-(void) touchMovedAtPoint:(CGPoint)point index:(NSUInteger)index NS_SWIFT_NAME(touchMoved(at:for:));
|
||||
|
||||
-(void) thumbstickMoved:(VirtualControllerAnalogType)analog
|
||||
x:(CGFloat)x
|
||||
y:(CGFloat)y
|
||||
controllerId:(int)controllerId;
|
||||
|
||||
-(void) virtualControllerGyro:(int)controllerId
|
||||
deltaTimestamp:(int)delta_timestamp
|
||||
gyroX:(float)gyro_x
|
||||
gyroY:(float)gyro_y
|
||||
gyroZ:(float)gyro_z
|
||||
accelX:(float)accel_x
|
||||
accelY:(float)accel_y
|
||||
accelZ:(float)accel_z;
|
||||
|
||||
-(void) virtualControllerButtonDown:(VirtualControllerButtonType)button
|
||||
controllerId:(int)controllerId;
|
||||
|
||||
-(void) virtualControllerButtonUp:(VirtualControllerButtonType)button
|
||||
controllerId:(int)controllerId;
|
||||
|
||||
|
||||
-(void) orientationChanged:(UIInterfaceOrientation)orientation with:(CAMetalLayer *)layer size:(CGSize)size NS_SWIFT_NAME(orientationChanged(orientation:with:size:));
|
||||
|
||||
-(void) settingsChanged;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
251
src/ios/AppUIObjC.mm
Normal file
251
src/ios/AppUIObjC.mm
Normal file
|
|
@ -0,0 +1,251 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: Copyright 2024 Jarrod Norwell
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#import "AppUIObjC.h"
|
||||
|
||||
#import "Config.h"
|
||||
#import "EmulationSession.h"
|
||||
|
||||
#include "common/fs/fs.h"
|
||||
#include "common/fs/path_util.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/fs/fs.h"
|
||||
#include "core/file_sys/patch_manager.h"
|
||||
#include "core/file_sys/savedata_factory.h"
|
||||
#include "core/loader/nro.h"
|
||||
#include "frontend_common/content_manager.h"
|
||||
#include "common/settings_enums.h"
|
||||
#include "network/announce_multiplayer_session.h"
|
||||
#include "common/announce_multiplayer_room.h"
|
||||
#include "network/network.h"
|
||||
|
||||
#include "common/detached_tasks.h"
|
||||
#include "common/dynamic_library.h"
|
||||
#include "common/fs/path_util.h"
|
||||
#include "common/logging.h"
|
||||
#include "common/scope_exit.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/string_util.h"
|
||||
#include "core/core.h"
|
||||
#include "core/cpu_manager.h"
|
||||
#include "core/crypto/key_manager.h"
|
||||
#include "core/file_sys/card_image.h"
|
||||
#include "core/file_sys/content_archive.h"
|
||||
#include "core/file_sys/fs_filesystem.h"
|
||||
#include "core/file_sys/submission_package.h"
|
||||
#include "core/file_sys/vfs/vfs.h"
|
||||
#include "core/file_sys/vfs/vfs_real.h"
|
||||
#include "core/frontend/applets/cabinet.h"
|
||||
#include "core/frontend/applets/controller.h"
|
||||
#include "core/frontend/applets/error.h"
|
||||
#include "core/frontend/applets/general.h"
|
||||
#include "core/frontend/applets/mii_edit.h"
|
||||
#include "core/frontend/applets/profile_select.h"
|
||||
#include "core/frontend/applets/software_keyboard.h"
|
||||
#include "core/frontend/applets/web_browser.h"
|
||||
#include "core/hle/service/am/applet_manager.h"
|
||||
#include "core/hle/service/am/frontend/applets.h"
|
||||
#include "core/hle/service/filesystem/filesystem.h"
|
||||
#include "core/loader/loader.h"
|
||||
#include "hid_core/hid_core.h"
|
||||
#include "hid_core/hid_types.h"
|
||||
#include "video_core/renderer_base.h"
|
||||
#include "video_core/renderer_vulkan/renderer_vulkan.h"
|
||||
#include "video_core/vulkan_common/vulkan_instance.h"
|
||||
#include "video_core/vulkan_common/vulkan_surface.h"
|
||||
|
||||
|
||||
#import <mach/mach.h>
|
||||
|
||||
@implementation AppUIObjC
|
||||
-(AppUIObjC *) init {
|
||||
if (self = [super init]) {
|
||||
_gameInformation = [AppUIGameInformation sharedInstance];
|
||||
|
||||
NSURL *dir_url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] firstObject];
|
||||
const char *directory_cstr = [[dir_url path] UTF8String];
|
||||
|
||||
Common::FS::SetAppDirectory(directory_cstr);
|
||||
// Config{"config", Config::ConfigType::GlobalConfig};
|
||||
|
||||
EmulationSession::GetInstance().System().Initialize();
|
||||
EmulationSession::GetInstance().InitializeSystem(false);
|
||||
EmulationSession::GetInstance().InitializeGpuDriver();
|
||||
|
||||
|
||||
Settings::values.dump_shaders.SetValue(true);
|
||||
Settings::values.use_asynchronous_shaders.SetValue(true);
|
||||
// Settings::values.astc_recompression.SetValue(Settings::AstcRecompression::Bc3);
|
||||
// Settings::values.resolution_setup.SetValue(Settings::ResolutionSetup::Res1X);
|
||||
// Settings::values.scaling_filter.SetValue(Settings::ScalingFilter::Bilinear);
|
||||
} return self;
|
||||
}
|
||||
|
||||
|
||||
+(AppUIObjC *) sharedInstance {
|
||||
static AppUIObjC *sharedInstance = NULL;
|
||||
static dispatch_once_t onceToken;
|
||||
dispatch_once(&onceToken, ^{
|
||||
sharedInstance = [[self alloc] init];
|
||||
});
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
- (BOOL)ispaused {
|
||||
return EmulationSession::GetInstance().IsPaused();
|
||||
}
|
||||
|
||||
-(void) pause {
|
||||
EmulationSession::GetInstance().System().Pause();
|
||||
EmulationSession::GetInstance().HaltEmulation();
|
||||
EmulationSession::GetInstance().PauseEmulation();
|
||||
}
|
||||
|
||||
-(void) play {
|
||||
|
||||
EmulationSession::GetInstance().System().Run();
|
||||
EmulationSession::GetInstance().RunEmulation();
|
||||
EmulationSession::GetInstance().UnPauseEmulation();
|
||||
}
|
||||
|
||||
-(BOOL)hasfirstfame {
|
||||
@try {
|
||||
auto* window = &EmulationSession::GetInstance().Window();
|
||||
if (window && window->HasFirstFrame()) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
@catch (NSException *exception) {
|
||||
NSLog(@"Exception occurred: %@", exception);
|
||||
// Handle the exception, maybe return a default value
|
||||
return NO;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)canGetFullPath {
|
||||
@try {
|
||||
Core::System& system = EmulationSession::GetInstance().System();
|
||||
auto bis_system = system.GetFileSystemController().GetSystemNANDContents();
|
||||
|
||||
if (bis_system == nullptr) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
constexpr u64 QLaunchId = static_cast<u64>(Service::AM::AppletProgramId::QLaunch);
|
||||
auto qlaunch_applet_nca = bis_system->GetEntry(QLaunchId, FileSys::ContentRecordType::Program);
|
||||
|
||||
if (qlaunch_applet_nca == nullptr) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
const auto filename = qlaunch_applet_nca->GetFullPath();
|
||||
|
||||
// If GetFullPath() is successful
|
||||
return YES;
|
||||
} @catch (NSException *exception) {
|
||||
// Handle the exception if needed
|
||||
return NO;
|
||||
}
|
||||
}
|
||||
|
||||
-(void) quit {
|
||||
EmulationSession::GetInstance().ShutdownEmulation();
|
||||
}
|
||||
|
||||
-(void) configureLayer:(CAMetalLayer *)layer withSize:(CGSize)size {
|
||||
_layer = layer;
|
||||
_size = size;
|
||||
EmulationSession::GetInstance().SetNativeWindow(layer, size);
|
||||
}
|
||||
|
||||
-(void) bootOS {
|
||||
EmulationSession::GetInstance().BootOS();
|
||||
}
|
||||
|
||||
-(void) insertGame:(NSURL *)url {
|
||||
EmulationSession::GetInstance().InitializeEmulation([url.path UTF8String], [_gameInformation informationForGame:url].programID, true);
|
||||
}
|
||||
|
||||
-(void) insertGames:(NSArray<NSURL *> *)games {
|
||||
for (NSURL *url in games) {
|
||||
EmulationSession::GetInstance().ConfigureFilesystemProvider([url.path UTF8String]);
|
||||
}
|
||||
}
|
||||
|
||||
-(void) step {
|
||||
void(EmulationSession::GetInstance().System().Run());
|
||||
}
|
||||
|
||||
-(void) touchBeganAtPoint:(CGPoint)point index:(NSUInteger)index {
|
||||
float h_ratio, w_ratio;
|
||||
h_ratio = EmulationSession::GetInstance().Window().GetFramebufferLayout().height / (_size.height * [[UIScreen mainScreen] nativeScale]);
|
||||
w_ratio = EmulationSession::GetInstance().Window().GetFramebufferLayout().width / (_size.width * [[UIScreen mainScreen] nativeScale]);
|
||||
|
||||
EmulationSession::GetInstance().Window().OnTouchPressed([[NSNumber numberWithUnsignedInteger:index] intValue],
|
||||
(point.x) * [[UIScreen mainScreen] nativeScale] * w_ratio,
|
||||
((point.y) * [[UIScreen mainScreen] nativeScale] * h_ratio));
|
||||
}
|
||||
|
||||
-(void) touchEndedForIndex:(NSUInteger)index {
|
||||
EmulationSession::GetInstance().Window().OnTouchReleased([[NSNumber numberWithUnsignedInteger:index] intValue]);
|
||||
}
|
||||
|
||||
-(void) touchMovedAtPoint:(CGPoint)point index:(NSUInteger)index {
|
||||
float h_ratio, w_ratio;
|
||||
h_ratio = EmulationSession::GetInstance().Window().GetFramebufferLayout().height / (_size.height * [[UIScreen mainScreen] nativeScale]);
|
||||
w_ratio = EmulationSession::GetInstance().Window().GetFramebufferLayout().width / (_size.width * [[UIScreen mainScreen] nativeScale]);
|
||||
|
||||
EmulationSession::GetInstance().Window().OnTouchMoved([[NSNumber numberWithUnsignedInteger:index] intValue],
|
||||
(point.x) * [[UIScreen mainScreen] nativeScale] * w_ratio,
|
||||
((point.y) * [[UIScreen mainScreen] nativeScale] * h_ratio));
|
||||
}
|
||||
|
||||
-(void) thumbstickMoved:(VirtualControllerAnalogType)analog
|
||||
x:(CGFloat)x
|
||||
y:(CGFloat)y
|
||||
controllerId:(int)controllerId {
|
||||
EmulationSession::GetInstance().OnGamepadConnectEvent(controllerId);
|
||||
EmulationSession::GetInstance().Window().OnGamepadJoystickEvent(controllerId, [[NSNumber numberWithUnsignedInteger:analog] intValue], CGFloat(x), CGFloat(y));
|
||||
}
|
||||
|
||||
-(void) virtualControllerButtonDown:(VirtualControllerButtonType)button
|
||||
controllerId:(int)controllerId {
|
||||
EmulationSession::GetInstance().OnGamepadConnectEvent(controllerId);
|
||||
EmulationSession::GetInstance().Window().OnGamepadButtonEvent(controllerId, [[NSNumber numberWithUnsignedInteger:button] intValue], true);
|
||||
}
|
||||
|
||||
-(void) virtualControllerGyro:(int)controllerId
|
||||
deltaTimestamp:(int)delta_timestamp
|
||||
gyroX:(float)gyro_x
|
||||
gyroY:(float)gyro_y
|
||||
gyroZ:(float)gyro_z
|
||||
accelX:(float)accel_x
|
||||
accelY:(float)accel_y
|
||||
accelZ:(float)accel_z
|
||||
{
|
||||
EmulationSession::GetInstance().OnGamepadConnectEvent(controllerId);
|
||||
EmulationSession::GetInstance().Window().OnGamepadMotionEvent(controllerId, delta_timestamp, gyro_x, gyro_y, gyro_z, accel_x, accel_y, accel_z);
|
||||
}
|
||||
|
||||
|
||||
-(void) virtualControllerButtonUp:(VirtualControllerButtonType)button
|
||||
controllerId:(int)controllerId {
|
||||
EmulationSession::GetInstance().OnGamepadConnectEvent(controllerId);
|
||||
EmulationSession::GetInstance().Window().OnGamepadButtonEvent(controllerId, [[NSNumber numberWithUnsignedInteger:button] intValue], false);
|
||||
}
|
||||
|
||||
|
||||
-(void) orientationChanged:(UIInterfaceOrientation)orientation with:(CAMetalLayer *)layer size:(CGSize)size {
|
||||
_layer = layer;
|
||||
_size = size;
|
||||
EmulationSession::GetInstance().Window().OnSurfaceChanged(layer, size);
|
||||
}
|
||||
|
||||
-(void) settingsChanged {
|
||||
//
|
||||
}
|
||||
|
||||
@end
|
||||
73
src/ios/CMakeLists.txt
Normal file
73
src/ios/CMakeLists.txt
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
enable_language(Swift OBJCXX)
|
||||
add_executable(eden-ios
|
||||
AppUI-Bridging-Header.h
|
||||
AppUI.swift
|
||||
AppUIGameInformation.h
|
||||
AppUIGameInformation.mm
|
||||
AppUIObjC.h
|
||||
AppUIObjC.mm
|
||||
Config.h
|
||||
Config.mm
|
||||
EmulationSession.h
|
||||
EmulationSession.mm
|
||||
EmulationWindow.h
|
||||
EmulationWindow.mm
|
||||
VMA.cpp
|
||||
|
||||
PomeloApp.swift
|
||||
ContentView.swift
|
||||
)
|
||||
|
||||
set(MACOSX_BUNDLE_GUI_IDENTIFIER "dev.eden-emu.eden")
|
||||
set(MACOSX_BUNDLE_BUNDLE_NAME "Eden")
|
||||
set(MACOSX_BUNDLE_INFO_STRING "Eden: A high-performance Nintendo Switch emulator")
|
||||
|
||||
# TODO(crueter): Copyright, and versioning
|
||||
|
||||
# Keep bundle identifier as-is, for compatibility sake
|
||||
set_target_properties(eden-ios PROPERTIES
|
||||
XCODE_ATTRIBUTE_SWIFT_OBJC_BRIDGING_HEADER "${CMAKE_CURRENT_SOURCE_DIR}/AppUI-Bridging-Header.h"
|
||||
XCODE_ATTRIBUTE_SWIFT_OBJC_INTERFACE_HEADER_NAME "eden-ios-Swift.h"
|
||||
XCODE_ATTRIBUTE_DERIVED_FILE_DIR "${CMAKE_CURRENT_BINARY_DIR}")
|
||||
|
||||
target_link_libraries(eden-ios PRIVATE common core input_common frontend_common video_core sirit::sirit)
|
||||
target_link_libraries(eden-ios PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads)
|
||||
target_link_libraries(eden-ios PRIVATE SDL2::SDL2 glad stb::headers)
|
||||
create_target_directory_groups(eden-ios)
|
||||
|
||||
# FIXME(crueter): This should /all/ be in a module of some kind!
|
||||
|
||||
# Xcode will automatically generate the Assets.car and icns file for us.
|
||||
set(_dist "${CMAKE_SOURCE_DIR}/dist")
|
||||
if (CMAKE_GENERATOR MATCHES "Xcode")
|
||||
set(_icons "${_dist}/eden.icon")
|
||||
|
||||
set_target_properties(eden-ios PROPERTIES
|
||||
XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME eden
|
||||
MACOSX_BUNDLE_ICON_FILE eden
|
||||
# Also force xcode to manage signing for us.
|
||||
XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED ON
|
||||
XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED ON
|
||||
XCODE_ATTRIBUTE_CODE_SIGN_STYLE Automatic)
|
||||
# Otherwise, we'll use our own.
|
||||
else()
|
||||
set(_icons "${_dist}/eden.icns" "${_dist}/Assets.car")
|
||||
endif()
|
||||
|
||||
set_source_files_properties(${_icons} PROPERTIES
|
||||
MACOSX_PACKAGE_LOCATION Resources)
|
||||
target_sources(eden-ios PRIVATE ${_icons})
|
||||
|
||||
set_target_properties(eden-ios PROPERTIES MACOSX_BUNDLE TRUE)
|
||||
|
||||
set(CMAKE_FIND_LIBRARY_SUFFIXES ".dylib")
|
||||
find_library(MOLTENVK_LIBRARY MoltenVK REQUIRED)
|
||||
message(STATUS "Using MoltenVK at ${MOLTENVK_LIBRARY}.")
|
||||
|
||||
set_source_files_properties(${MOLTENVK_LIBRARY} PROPERTIES
|
||||
MACOSX_PACKAGE_LOCATION Frameworks
|
||||
XCODE_FILE_ATTRIBUTES "CodeSignOnCopy")
|
||||
target_sources(eden-ios PRIVATE ${MOLTENVK_LIBRARY})
|
||||
19
src/ios/Config.h
Normal file
19
src/ios/Config.h
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <common/settings_common.h>
|
||||
#include "common/common_types.h"
|
||||
#include "common/settings_setting.h"
|
||||
#include "common/settings_enums.h"
|
||||
|
||||
namespace IOSSettings {
|
||||
struct Values {
|
||||
Settings::Linkage linkage;
|
||||
Settings::Setting<bool> touchscreen{linkage, true, "touchscreen", Settings::Category::Overlay};
|
||||
};
|
||||
|
||||
extern Values values;
|
||||
|
||||
} // namespace IOSSettings
|
||||
11
src/ios/Config.mm
Normal file
11
src/ios/Config.mm
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
|
||||
#include "Config.h"
|
||||
|
||||
namespace IOSSettings {
|
||||
|
||||
Values values;
|
||||
|
||||
} // namespace IOSSettings
|
||||
19
src/ios/ContentView.swift
Normal file
19
src/ios/ContentView.swift
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: Copyright 2024 Pomelo, Stossy11
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
import SwiftUI
|
||||
//import AppUI
|
||||
|
||||
struct ContentView: View {
|
||||
// @State var core = Core(games: [], root: FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0])
|
||||
var body: some View {
|
||||
// HomeView(core: core).onAppear() {
|
||||
// Air.play(AnyView(
|
||||
// Text("Select Game").font(.system(size: 100))
|
||||
// ))
|
||||
// // rest of death
|
||||
// }
|
||||
}
|
||||
}
|
||||
103
src/ios/EmulationSession.h
Normal file
103
src/ios/EmulationSession.h
Normal file
|
|
@ -0,0 +1,103 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: Copyright 2024 Jarrod Norwell
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
#import <QuartzCore/CAMetalLayer.h>
|
||||
|
||||
#if __has_include(<Metal/Metal.hpp>)
|
||||
#import <Metal/Metal.hpp>
|
||||
#else
|
||||
#import <Metal/Metal.h>
|
||||
#endif
|
||||
#import "EmulationWindow.h"
|
||||
|
||||
#include "common/detached_tasks.h"
|
||||
#include "core/core.h"
|
||||
#include "core/file_sys/registered_cache.h"
|
||||
#include "core/hle/service/acc/profile_manager.h"
|
||||
#include "core/perf_stats.h"
|
||||
#include "frontend_common/content_manager.h"
|
||||
#include "video_core/rasterizer_interface.h"
|
||||
|
||||
class EmulationSession final {
|
||||
public:
|
||||
explicit EmulationSession();
|
||||
~EmulationSession() = default;
|
||||
|
||||
static EmulationSession& GetInstance();
|
||||
const Core::System& System() const;
|
||||
Core::System& System();
|
||||
FileSys::ManualContentProvider* GetContentProvider();
|
||||
InputCommon::InputSubsystem& GetInputSubsystem();
|
||||
|
||||
const EmulationWindow& Window() const;
|
||||
EmulationWindow& Window();
|
||||
CAMetalLayer* NativeWindow() const;
|
||||
void SetNativeWindow(CAMetalLayer* native_window, CGSize size);
|
||||
void SurfaceChanged();
|
||||
|
||||
void InitializeGpuDriver();
|
||||
|
||||
bool IsRunning() const;
|
||||
bool IsPaused() const;
|
||||
void PauseEmulation();
|
||||
void UnPauseEmulation();
|
||||
void HaltEmulation();
|
||||
void RunEmulation();
|
||||
void ShutdownEmulation();
|
||||
|
||||
const Core::PerfStatsResults& PerfStats();
|
||||
void ConfigureFilesystemProvider(const std::string& filepath);
|
||||
void InitializeSystem(bool reload);
|
||||
void SetAppletId(int applet_id);
|
||||
Core::SystemResultStatus InitializeEmulation(const std::string& filepath,
|
||||
const std::size_t program_index,
|
||||
const bool frontend_initiated);
|
||||
Core::SystemResultStatus BootOS();
|
||||
|
||||
static void OnEmulationStarted();
|
||||
static u64 GetProgramId(std::string programId);
|
||||
bool IsInitialized() { return is_initialized; };
|
||||
|
||||
bool IsHandheldOnly();
|
||||
void SetDeviceType([[maybe_unused]] int index, int type);
|
||||
void OnGamepadConnectEvent([[maybe_unused]] int index);
|
||||
void OnGamepadDisconnectEvent([[maybe_unused]] int index);
|
||||
private:
|
||||
static void LoadDiskCacheProgress(VideoCore::LoadCallbackStage stage, int progress, int max);
|
||||
static void OnEmulationStopped(Core::SystemResultStatus result);
|
||||
static void ChangeProgram(std::size_t program_index);
|
||||
|
||||
private:
|
||||
// Window management
|
||||
std::unique_ptr<EmulationWindow> m_window;
|
||||
CAMetalLayer* m_native_window{};
|
||||
|
||||
// Core emulation
|
||||
Core::System m_system;
|
||||
InputCommon::InputSubsystem m_input_subsystem;
|
||||
Common::DetachedTasks m_detached_tasks;
|
||||
Core::PerfStatsResults m_perf_stats{};
|
||||
std::shared_ptr<FileSys::VfsFilesystem> m_vfs;
|
||||
Core::SystemResultStatus m_load_result{Core::SystemResultStatus::ErrorNotInitialized};
|
||||
std::atomic<bool> m_is_running = false;
|
||||
std::atomic<bool> m_is_paused = false;
|
||||
std::unique_ptr<FileSys::ManualContentProvider> m_manual_provider;
|
||||
int m_applet_id{1};
|
||||
|
||||
// GPU driver parameters
|
||||
std::shared_ptr<Common::DynamicLibrary> m_vulkan_library;
|
||||
|
||||
// Synchronization
|
||||
std::condition_variable_any m_cv;
|
||||
mutable std::mutex m_mutex;
|
||||
bool is_initialized = false;
|
||||
CGSize m_size;
|
||||
|
||||
// Program index for next boot
|
||||
std::atomic<s32> m_next_program_index = -1;
|
||||
};
|
||||
474
src/ios/EmulationSession.mm
Normal file
474
src/ios/EmulationSession.mm
Normal file
|
|
@ -0,0 +1,474 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: Copyright 2024 Jarrod Norwell
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#import "EmulationSession.h"
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include <codecvt>
|
||||
#include <locale>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "common/fs/fs.h"
|
||||
#include "core/file_sys/patch_manager.h"
|
||||
#include "core/file_sys/savedata_factory.h"
|
||||
#include "core/loader/nro.h"
|
||||
#include "frontend_common/content_manager.h"
|
||||
|
||||
#include "common/detached_tasks.h"
|
||||
#include "common/dynamic_library.h"
|
||||
#include "common/fs/path_util.h"
|
||||
#include "common/logging.h"
|
||||
#include "common/scm_rev.h"
|
||||
#include "common/scope_exit.h"
|
||||
#include "common/settings.h"
|
||||
#include "common/string_util.h"
|
||||
#include "core/core.h"
|
||||
#include "core/cpu_manager.h"
|
||||
#include "core/crypto/key_manager.h"
|
||||
#include "core/file_sys/card_image.h"
|
||||
#include "core/file_sys/content_archive.h"
|
||||
#include "core/file_sys/fs_filesystem.h"
|
||||
#include "core/file_sys/submission_package.h"
|
||||
#include "core/file_sys/vfs/vfs.h"
|
||||
#include "core/file_sys/vfs/vfs_real.h"
|
||||
#include "core/frontend/applets/cabinet.h"
|
||||
#include "core/frontend/applets/controller.h"
|
||||
#include "core/frontend/applets/error.h"
|
||||
#include "core/frontend/applets/general.h"
|
||||
#include "core/frontend/applets/mii_edit.h"
|
||||
#include "core/frontend/applets/profile_select.h"
|
||||
#include "core/frontend/applets/software_keyboard.h"
|
||||
#include "core/frontend/applets/web_browser.h"
|
||||
#include "core/hle/service/am/applet_manager.h"
|
||||
#include "core/hle/service/am/frontend/applets.h"
|
||||
#include "core/hle/service/filesystem/filesystem.h"
|
||||
#include "core/loader/loader.h"
|
||||
#include "frontend_common/config.h"
|
||||
#include "hid_core/frontend/emulated_controller.h"
|
||||
#include "hid_core/hid_core.h"
|
||||
#include "hid_core/hid_types.h"
|
||||
#include "video_core/renderer_base.h"
|
||||
#include "video_core/renderer_vulkan/renderer_vulkan.h"
|
||||
#include "video_core/vulkan_common/vulkan_instance.h"
|
||||
#include "video_core/vulkan_common/vulkan_surface.h"
|
||||
|
||||
#define jconst [[maybe_unused]] const auto
|
||||
#define jauto [[maybe_unused]] auto
|
||||
|
||||
static EmulationSession s_instance;
|
||||
|
||||
EmulationSession::EmulationSession() {
|
||||
m_vfs = std::make_shared<FileSys::RealVfsFilesystem>();
|
||||
}
|
||||
|
||||
EmulationSession& EmulationSession::GetInstance() {
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
const Core::System& EmulationSession::System() const {
|
||||
return m_system;
|
||||
}
|
||||
|
||||
Core::System& EmulationSession::System() {
|
||||
return m_system;
|
||||
}
|
||||
|
||||
FileSys::ManualContentProvider* EmulationSession::GetContentProvider() {
|
||||
return m_manual_provider.get();
|
||||
}
|
||||
|
||||
InputCommon::InputSubsystem& EmulationSession::GetInputSubsystem() {
|
||||
return m_input_subsystem;
|
||||
}
|
||||
|
||||
const EmulationWindow& EmulationSession::Window() const {
|
||||
return *m_window;
|
||||
}
|
||||
|
||||
EmulationWindow& EmulationSession::Window() {
|
||||
return *m_window;
|
||||
}
|
||||
|
||||
CAMetalLayer* EmulationSession::NativeWindow() const {
|
||||
return m_native_window;
|
||||
}
|
||||
|
||||
void EmulationSession::SetNativeWindow(CAMetalLayer* native_window, CGSize size) {
|
||||
m_native_window = native_window;
|
||||
m_size = size;
|
||||
}
|
||||
|
||||
void EmulationSession::InitializeGpuDriver() {
|
||||
m_vulkan_library = std::make_shared<Common::DynamicLibrary>(dlopen("@executable_path/Frameworks/MoltenVK", RTLD_NOW));
|
||||
}
|
||||
|
||||
bool EmulationSession::IsRunning() const {
|
||||
return m_is_running;
|
||||
}
|
||||
|
||||
bool EmulationSession::IsPaused() const {
|
||||
return m_is_running && m_is_paused;
|
||||
}
|
||||
|
||||
const Core::PerfStatsResults& EmulationSession::PerfStats() {
|
||||
m_perf_stats = m_system.GetAndResetPerfStats();
|
||||
return m_perf_stats;
|
||||
}
|
||||
|
||||
void EmulationSession::SurfaceChanged() {
|
||||
if (!IsRunning()) {
|
||||
return;
|
||||
}
|
||||
m_window->OnSurfaceChanged(m_native_window, m_size);
|
||||
}
|
||||
|
||||
void EmulationSession::ConfigureFilesystemProvider(const std::string& filepath) {
|
||||
const auto file = m_system.GetFilesystem()->OpenFile(filepath, FileSys::OpenMode::Read);
|
||||
if (!file) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto loader = Loader::GetLoader(m_system, file);
|
||||
if (!loader) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto file_type = loader->GetFileType();
|
||||
if (file_type == Loader::FileType::Unknown || file_type == Loader::FileType::Error) {
|
||||
return;
|
||||
}
|
||||
|
||||
u64 program_id = 0;
|
||||
const auto res2 = loader->ReadProgramId(program_id);
|
||||
if (res2 == Loader::ResultStatus::Success && file_type == Loader::FileType::NCA) {
|
||||
m_manual_provider->AddEntry(FileSys::TitleType::Application,
|
||||
FileSys::GetCRTypeFromNCAType(FileSys::NCA{file}.GetType()),
|
||||
program_id, file);
|
||||
} else if (res2 == Loader::ResultStatus::Success &&
|
||||
(file_type == Loader::FileType::XCI || file_type == Loader::FileType::NSP)) {
|
||||
const auto nsp = file_type == Loader::FileType::NSP
|
||||
? std::make_shared<FileSys::NSP>(file)
|
||||
: FileSys::XCI{file}.GetSecurePartitionNSP();
|
||||
for (const auto& title : nsp->GetNCAs()) {
|
||||
for (const auto& entry : title.second) {
|
||||
m_manual_provider->AddEntry(entry.first.first, entry.first.second, title.first,
|
||||
entry.second->GetBaseFile());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EmulationSession::InitializeSystem(bool reload) {
|
||||
if (!reload) {
|
||||
SDL_SetMainReady();
|
||||
|
||||
// Initialize logging system
|
||||
Common::Log::Initialize();
|
||||
Common::Log::SetColorConsoleBackendEnabled(true);
|
||||
Common::Log::Start();
|
||||
}
|
||||
|
||||
// Initialize filesystem.
|
||||
m_system.SetFilesystem(m_vfs);
|
||||
m_system.GetUserChannel().clear();
|
||||
m_manual_provider = std::make_unique<FileSys::ManualContentProvider>();
|
||||
m_system.SetContentProvider(std::make_unique<FileSys::ContentProviderUnion>());
|
||||
m_system.RegisterContentProvider(FileSys::ContentProviderUnionSlot::FrontendManual,
|
||||
m_manual_provider.get());
|
||||
m_system.GetFileSystemController().CreateFactories(*m_vfs);
|
||||
|
||||
is_initialized = true;
|
||||
}
|
||||
|
||||
void EmulationSession::SetAppletId(int applet_id) {
|
||||
m_applet_id = applet_id;
|
||||
m_system.GetFrontendAppletHolder().SetCurrentAppletId(
|
||||
static_cast<Service::AM::AppletId>(m_applet_id));
|
||||
}
|
||||
|
||||
Core::SystemResultStatus EmulationSession::InitializeEmulation(const std::string& filepath,
|
||||
const std::size_t program_index,
|
||||
const bool frontend_initiated) {
|
||||
std::scoped_lock lock(m_mutex);
|
||||
|
||||
// Create the render window.
|
||||
m_window = std::make_unique<EmulationWindow>(&m_input_subsystem, m_native_window, m_size, m_vulkan_library);
|
||||
|
||||
// Initialize system.
|
||||
m_system.SetShuttingDown(false);
|
||||
m_system.ApplySettings();
|
||||
Settings::LogSettings();
|
||||
m_system.HIDCore().ReloadInputDevices();
|
||||
m_system.SetFrontendAppletSet(Service::AM::Frontend::FrontendAppletSet{});
|
||||
|
||||
// Initialize filesystem.
|
||||
ConfigureFilesystemProvider(filepath);
|
||||
|
||||
// Load the ROM.
|
||||
Service::AM::FrontendAppletParameters params{
|
||||
.applet_id = static_cast<Service::AM::AppletId>(m_applet_id),
|
||||
.launch_type = frontend_initiated ? Service::AM::LaunchType::FrontendInitiated
|
||||
: Service::AM::LaunchType::ApplicationInitiated,
|
||||
.program_index = static_cast<s32>(program_index),
|
||||
};
|
||||
m_load_result = m_system.Load(EmulationSession::GetInstance().Window(), filepath, params);
|
||||
if (m_load_result != Core::SystemResultStatus::Success) {
|
||||
return m_load_result;
|
||||
}
|
||||
|
||||
// Complete initialization.
|
||||
m_system.GPU().Start();
|
||||
m_system.GetCpuManager().OnGpuReady();
|
||||
m_system.RegisterExitCallback([&] { HaltEmulation(); });
|
||||
|
||||
if (Settings::values.use_disk_shader_cache.GetValue()) {
|
||||
m_system.Renderer().ReadRasterizer()->LoadDiskResources(
|
||||
m_system.GetApplicationProcessProgramID(), std::stop_token{},
|
||||
[](VideoCore::LoadCallbackStage, size_t value, size_t total) {});
|
||||
}
|
||||
|
||||
// Register an ExecuteProgram callback such that Core can execute a sub-program
|
||||
m_system.RegisterExecuteProgramCallback([&](std::size_t program_index_) {
|
||||
m_next_program_index = program_index_;
|
||||
EmulationSession::GetInstance().HaltEmulation();
|
||||
ChangeProgram(m_next_program_index);
|
||||
});
|
||||
|
||||
OnEmulationStarted();
|
||||
return Core::SystemResultStatus::Success;
|
||||
}
|
||||
|
||||
|
||||
Core::SystemResultStatus EmulationSession::BootOS() {
|
||||
std::scoped_lock lock(m_mutex);
|
||||
|
||||
// Create the render window.
|
||||
m_window = std::make_unique<EmulationWindow>(&m_input_subsystem, m_native_window, m_size, m_vulkan_library);
|
||||
|
||||
// Initialize system.
|
||||
m_system.SetShuttingDown(false);
|
||||
m_system.ApplySettings();
|
||||
Settings::LogSettings();
|
||||
m_system.HIDCore().ReloadInputDevices();
|
||||
m_system.SetFrontendAppletSet(Service::AM::Frontend::FrontendAppletSet{});
|
||||
|
||||
constexpr u64 QLaunchId = static_cast<u64>(Service::AM::AppletProgramId::QLaunch);
|
||||
auto bis_system = m_system.GetFileSystemController().GetSystemNANDContents();
|
||||
|
||||
auto qlaunch_applet_nca = bis_system->GetEntry(QLaunchId, FileSys::ContentRecordType::Program);
|
||||
|
||||
m_system.GetFrontendAppletHolder().SetCurrentAppletId(Service::AM::AppletId::QLaunch);
|
||||
|
||||
const auto filename = qlaunch_applet_nca->GetFullPath();
|
||||
|
||||
auto params = Service::AM::FrontendAppletParameters {
|
||||
.program_id = QLaunchId,
|
||||
.applet_id = Service::AM::AppletId::QLaunch,
|
||||
.applet_type = Service::AM::AppletType::LibraryApplet
|
||||
};
|
||||
|
||||
m_load_result = m_system.Load(EmulationSession::GetInstance().Window(), filename, params);
|
||||
|
||||
if (m_load_result != Core::SystemResultStatus::Success) {
|
||||
return m_load_result;
|
||||
}
|
||||
|
||||
// Complete initialization.
|
||||
m_system.GPU().Start();
|
||||
m_system.GetCpuManager().OnGpuReady();
|
||||
m_system.RegisterExitCallback([&] { HaltEmulation(); });
|
||||
|
||||
if (Settings::values.use_disk_shader_cache.GetValue()) {
|
||||
m_system.Renderer().ReadRasterizer()->LoadDiskResources(
|
||||
m_system.GetApplicationProcessProgramID(), std::stop_token{},
|
||||
[](VideoCore::LoadCallbackStage, size_t value, size_t total) {});
|
||||
}
|
||||
|
||||
// Register an ExecuteProgram callback such that Core can execute a sub-program
|
||||
m_system.RegisterExecuteProgramCallback([&](std::size_t program_index_) {
|
||||
m_next_program_index = program_index_;
|
||||
EmulationSession::GetInstance().HaltEmulation();
|
||||
});
|
||||
|
||||
OnEmulationStarted();
|
||||
return Core::SystemResultStatus::Success;
|
||||
}
|
||||
|
||||
void EmulationSession::ShutdownEmulation() {
|
||||
std::scoped_lock lock(m_mutex);
|
||||
|
||||
if (m_next_program_index != -1) {
|
||||
ChangeProgram(m_next_program_index);
|
||||
m_next_program_index = -1;
|
||||
}
|
||||
|
||||
m_is_running = false;
|
||||
|
||||
// Unload user input.
|
||||
m_system.HIDCore().UnloadInputDevices();
|
||||
|
||||
// Enable all controllers
|
||||
m_system.HIDCore().SetSupportedStyleTag({Core::HID::NpadStyleSet::All});
|
||||
|
||||
// Shutdown the main emulated process
|
||||
if (m_load_result == Core::SystemResultStatus::Success) {
|
||||
m_system.DetachDebugger();
|
||||
m_system.ShutdownMainProcess();
|
||||
m_detached_tasks.WaitForAllTasks();
|
||||
m_load_result = Core::SystemResultStatus::ErrorNotInitialized;
|
||||
m_window.reset();
|
||||
OnEmulationStopped(Core::SystemResultStatus::Success);
|
||||
return;
|
||||
}
|
||||
|
||||
// Tear down the render window.
|
||||
m_window.reset();
|
||||
}
|
||||
|
||||
void EmulationSession::PauseEmulation() {
|
||||
std::scoped_lock lock(m_mutex);
|
||||
m_system.Pause();
|
||||
m_is_paused = true;
|
||||
}
|
||||
|
||||
void EmulationSession::UnPauseEmulation() {
|
||||
std::scoped_lock lock(m_mutex);
|
||||
m_system.Run();
|
||||
m_is_paused = false;
|
||||
}
|
||||
|
||||
void EmulationSession::HaltEmulation() {
|
||||
std::scoped_lock lock(m_mutex);
|
||||
m_is_running = false;
|
||||
m_cv.notify_one();
|
||||
}
|
||||
|
||||
void EmulationSession::RunEmulation() {
|
||||
{
|
||||
std::scoped_lock lock(m_mutex);
|
||||
m_is_running = true;
|
||||
}
|
||||
|
||||
// Load the disk shader cache.
|
||||
if (Settings::values.use_disk_shader_cache.GetValue()) {
|
||||
LoadDiskCacheProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0);
|
||||
m_system.Renderer().ReadRasterizer()->LoadDiskResources(
|
||||
m_system.GetApplicationProcessProgramID(), std::stop_token{}, LoadDiskCacheProgress);
|
||||
LoadDiskCacheProgress(VideoCore::LoadCallbackStage::Complete, 0, 0);
|
||||
}
|
||||
|
||||
void(m_system.Run());
|
||||
|
||||
if (m_system.DebuggerEnabled()) {
|
||||
m_system.InitializeDebugger();
|
||||
}
|
||||
|
||||
while (true) {
|
||||
{
|
||||
[[maybe_unused]] std::unique_lock lock(m_mutex);
|
||||
if (m_cv.wait_for(lock, std::chrono::milliseconds(800),
|
||||
[&]() { return !m_is_running; })) {
|
||||
// Emulation halted.
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Reset current applet ID.
|
||||
m_applet_id = static_cast<int>(Service::AM::AppletId::Application);
|
||||
}
|
||||
|
||||
void EmulationSession::LoadDiskCacheProgress(VideoCore::LoadCallbackStage stage, int progress,
|
||||
int max) {
|
||||
|
||||
}
|
||||
|
||||
void EmulationSession::OnEmulationStarted() {
|
||||
|
||||
}
|
||||
|
||||
void EmulationSession::OnEmulationStopped(Core::SystemResultStatus result) {
|
||||
|
||||
}
|
||||
|
||||
void EmulationSession::ChangeProgram(std::size_t program_index) {
|
||||
LOG_INFO(Frontend, "Trying To Switch Program");
|
||||
// Halt current emulation session
|
||||
EmulationSession::GetInstance().HaltEmulation();
|
||||
// Save the current state if necessary
|
||||
|
||||
// Shutdown the current emulation session cleanly
|
||||
// Update the program index
|
||||
EmulationSession::GetInstance().m_next_program_index = program_index;
|
||||
|
||||
// Initialize the new program
|
||||
// Start the new emulation session
|
||||
EmulationSession::GetInstance().RunEmulation();
|
||||
}
|
||||
|
||||
u64 EmulationSession::GetProgramId(std::string programId) {
|
||||
try {
|
||||
return std::stoull(programId);
|
||||
} catch (...) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool EmulationSession::IsHandheldOnly() {
|
||||
jconst npad_style_set = m_system.HIDCore().GetSupportedStyleTag();
|
||||
|
||||
if (npad_style_set.fullkey == 1) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (npad_style_set.handheld == 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !Settings::IsDockedMode();
|
||||
}
|
||||
|
||||
void EmulationSession::SetDeviceType([[maybe_unused]] int index, int type) {
|
||||
jauto controller = m_system.HIDCore().GetEmulatedControllerByIndex(index);
|
||||
controller->SetNpadStyleIndex(static_cast<Core::HID::NpadStyleIndex>(type));
|
||||
}
|
||||
|
||||
void EmulationSession::OnGamepadConnectEvent([[maybe_unused]] int index) {
|
||||
jauto controller = m_system.HIDCore().GetEmulatedControllerByIndex(index);
|
||||
|
||||
// Ensure that player1 is configured correctly and handheld disconnected
|
||||
if (controller->GetNpadIdType() == Core::HID::NpadIdType::Player1) {
|
||||
jauto handheld = m_system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Handheld);
|
||||
|
||||
if (controller->GetNpadStyleIndex() == Core::HID::NpadStyleIndex::Handheld) {
|
||||
handheld->SetNpadStyleIndex(Core::HID::NpadStyleIndex::Fullkey);
|
||||
controller->SetNpadStyleIndex(Core::HID::NpadStyleIndex::Fullkey);
|
||||
handheld->Disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that handheld is configured correctly and player 1 disconnected
|
||||
if (controller->GetNpadIdType() == Core::HID::NpadIdType::Handheld) {
|
||||
jauto player1 = m_system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
|
||||
|
||||
if (controller->GetNpadStyleIndex() != Core::HID::NpadStyleIndex::Handheld) {
|
||||
player1->SetNpadStyleIndex(Core::HID::NpadStyleIndex::Handheld);
|
||||
controller->SetNpadStyleIndex(Core::HID::NpadStyleIndex::Handheld);
|
||||
player1->Disconnect();
|
||||
}
|
||||
}
|
||||
|
||||
if (!controller->IsConnected()) {
|
||||
controller->Connect();
|
||||
}
|
||||
}
|
||||
|
||||
void EmulationSession::OnGamepadDisconnectEvent([[maybe_unused]] int index) {
|
||||
jauto controller = m_system.HIDCore().GetEmulatedControllerByIndex(index);
|
||||
controller->Disconnect();
|
||||
}
|
||||
86
src/ios/EmulationWindow.h
Normal file
86
src/ios/EmulationWindow.h
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: Copyright 2024 Jarrod Norwell
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#if __has_include(<Metal/Metal.hpp>)
|
||||
#import <Metal/Metal.hpp>
|
||||
#else
|
||||
#import <Metal/Metal.h>
|
||||
#endif
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <QuartzCore/QuartzCore.h>
|
||||
#import <QuartzCore/CAMetalLayer.h>
|
||||
|
||||
#include <memory>
|
||||
#include <span>
|
||||
|
||||
#include "core/frontend/emu_window.h"
|
||||
#include "core/frontend/graphics_context.h"
|
||||
#include "input_common/main.h"
|
||||
|
||||
class GraphicsContext_Apple final : public Core::Frontend::GraphicsContext {
|
||||
public:
|
||||
explicit GraphicsContext_Apple(std::shared_ptr<Common::DynamicLibrary> driver_library)
|
||||
: m_driver_library{driver_library} {}
|
||||
|
||||
~GraphicsContext_Apple() = default;
|
||||
|
||||
std::shared_ptr<Common::DynamicLibrary> GetDriverLibrary() override {
|
||||
return m_driver_library;
|
||||
}
|
||||
|
||||
private:
|
||||
std::shared_ptr<Common::DynamicLibrary> m_driver_library;
|
||||
};
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
class EmulationWindow final : public Core::Frontend::EmuWindow {
|
||||
public:
|
||||
EmulationWindow(InputCommon::InputSubsystem* input_subsystem, CAMetalLayer* surface, CGSize size,
|
||||
std::shared_ptr<Common::DynamicLibrary> driver_library);
|
||||
|
||||
~EmulationWindow() = default;
|
||||
|
||||
void OnSurfaceChanged(CAMetalLayer* surface, CGSize size);
|
||||
void OrientationChanged(UIInterfaceOrientation orientation);
|
||||
void OnFrameDisplayed() override;
|
||||
|
||||
void OnTouchPressed(int id, float x, float y);
|
||||
void OnTouchMoved(int id, float x, float y);
|
||||
void OnTouchReleased(int id);
|
||||
|
||||
void OnGamepadButtonEvent(int player_index, int button_id, bool pressed);
|
||||
void OnGamepadJoystickEvent(int player_index, int stick_id, float x, float y);
|
||||
void OnGamepadMotionEvent(int player_index, u64 delta_timestamp, float gyro_x, float gyro_y, float gyro_z, float accel_x, float accel_y, float accel_z);
|
||||
|
||||
std::unique_ptr<Core::Frontend::GraphicsContext> CreateSharedContext() const override {
|
||||
return {std::make_unique<GraphicsContext_Apple>(m_driver_library)};
|
||||
}
|
||||
|
||||
|
||||
bool HasFirstFrame() const {
|
||||
return m_first_frame;
|
||||
}
|
||||
|
||||
bool IsShown() const override {
|
||||
return true;
|
||||
};
|
||||
|
||||
private:
|
||||
float m_window_width{};
|
||||
float m_window_height{};
|
||||
CGSize m_size;
|
||||
bool is_portrait = true;
|
||||
|
||||
InputCommon::InputSubsystem* m_input_subsystem{};
|
||||
std::shared_ptr<Common::DynamicLibrary> m_driver_library;
|
||||
|
||||
bool m_first_frame = false;
|
||||
};
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
82
src/ios/EmulationWindow.mm
Normal file
82
src/ios/EmulationWindow.mm
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: Copyright 2024 Jarrod Norwell
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#import "EmulationWindow.h"
|
||||
#import "EmulationSession.h"
|
||||
|
||||
#include <SDL.h>
|
||||
|
||||
#include "common/logging.h"
|
||||
#include "input_common/drivers/touch_screen.h"
|
||||
#include "input_common/drivers/virtual_amiibo.h"
|
||||
#include "input_common/drivers/virtual_gamepad.h"
|
||||
#include "input_common/main.h"
|
||||
|
||||
void EmulationWindow::OnSurfaceChanged(CAMetalLayer* surface, CGSize size) {
|
||||
m_size = size;
|
||||
|
||||
m_window_width = size.width;
|
||||
m_window_height = size.height;
|
||||
|
||||
// Ensures that we emulate with the correct aspect ratio.
|
||||
// UpdateCurrentFramebufferLayout(m_window_width, m_window_height);
|
||||
|
||||
window_info.render_surface = (__bridge void *)surface;
|
||||
window_info.render_surface_scale = [[UIScreen mainScreen] nativeScale];
|
||||
}
|
||||
|
||||
void EmulationWindow::OrientationChanged(UIInterfaceOrientation orientation) {
|
||||
is_portrait = orientation == UIInterfaceOrientationPortrait;
|
||||
}
|
||||
|
||||
void EmulationWindow::OnTouchPressed(int id, float x, float y) {
|
||||
const auto [touch_x, touch_y] = MapToTouchScreen(x, y);
|
||||
EmulationSession::GetInstance().GetInputSubsystem().GetTouchScreen()->TouchPressed(touch_x,
|
||||
touch_y, id);
|
||||
}
|
||||
|
||||
void EmulationWindow::OnTouchMoved(int id, float x, float y) {
|
||||
const auto [touch_x, touch_y] = MapToTouchScreen(x, y);
|
||||
EmulationSession::GetInstance().GetInputSubsystem().GetTouchScreen()->TouchMoved(touch_x,
|
||||
touch_y, id);
|
||||
}
|
||||
|
||||
void EmulationWindow::OnTouchReleased(int id) {
|
||||
EmulationSession::GetInstance().GetInputSubsystem().GetTouchScreen()->TouchReleased(id);
|
||||
}
|
||||
|
||||
void EmulationWindow::OnGamepadButtonEvent(int player_index, int button_id, bool pressed) {
|
||||
m_input_subsystem->GetVirtualGamepad()->SetButtonState(player_index, button_id, pressed);
|
||||
}
|
||||
|
||||
void EmulationWindow::OnGamepadJoystickEvent(int player_index, int stick_id, float x, float y) {
|
||||
m_input_subsystem->GetVirtualGamepad()->SetStickPosition(player_index, stick_id, x, y);
|
||||
}
|
||||
|
||||
void EmulationWindow::OnGamepadMotionEvent(int player_index, u64 delta_timestamp, float gyro_x, float gyro_y, float gyro_z, float accel_x, float accel_y, float accel_z) {
|
||||
m_input_subsystem->GetVirtualGamepad()->SetMotionState(player_index, delta_timestamp, gyro_x, gyro_y, gyro_z, accel_x, accel_y, accel_z);
|
||||
}
|
||||
|
||||
void EmulationWindow::OnFrameDisplayed() {
|
||||
if (!m_first_frame) {
|
||||
m_first_frame = true;
|
||||
}
|
||||
}
|
||||
|
||||
EmulationWindow::EmulationWindow(InputCommon::InputSubsystem* input_subsystem, CAMetalLayer* surface, CGSize size, std::shared_ptr<Common::DynamicLibrary> driver_library)
|
||||
: m_window_width{}, m_window_height{}, m_size{size}, is_portrait{true}, m_input_subsystem{input_subsystem}, m_driver_library{driver_library}, m_first_frame{false} {
|
||||
LOG_INFO(Frontend, "initializing");
|
||||
|
||||
if (!surface) {
|
||||
LOG_CRITICAL(Frontend, "surface is nullptr");
|
||||
return;
|
||||
}
|
||||
|
||||
OnSurfaceChanged(surface, m_size);
|
||||
window_info.render_surface_scale = [[UIScreen mainScreen] nativeScale];
|
||||
window_info.type = Core::Frontend::WindowSystemType::Cocoa;
|
||||
|
||||
m_input_subsystem->Initialize();
|
||||
}
|
||||
19
src/ios/PomeloApp.swift
Normal file
19
src/ios/PomeloApp.swift
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: Copyright 2024 Pomelo, Stossy11
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
import SwiftUI
|
||||
|
||||
infix operator --: LogicalDisjunctionPrecedence
|
||||
|
||||
func --(lhs: Bool, rhs: Bool) -> Bool {
|
||||
return lhs || rhs
|
||||
}
|
||||
|
||||
@main
|
||||
struct PomeloApp: App {
|
||||
var body: some Scene {
|
||||
WindowGroup { ContentView() }
|
||||
}
|
||||
}
|
||||
5
src/ios/VMA.cpp
Normal file
5
src/ios/VMA.cpp
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#define VMA_IMPLEMENTATION
|
||||
#include "video_core/vulkan_common/vma.h"
|
||||
|
|
@ -50,7 +50,6 @@ if (USE_DISCORD_PRESENCE)
|
|||
|
||||
if (YUZU_USE_BUNDLED_OPENSSL)
|
||||
target_link_libraries(qt_common PUBLIC OpenSSL::SSL OpenSSL::Crypto)
|
||||
target_compile_definitions(qt_common PRIVATE CPPHTTPLIB_OPENSSL_SUPPORT)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(qt_common PUBLIC USE_DISCORD_PRESENCE)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
|
||||
#include <QEventLoop>
|
||||
#include <boost/algorithm/string/replace.hpp>
|
||||
#include <httplib.h>
|
||||
#include "common/httplib.h"
|
||||
|
||||
#include <discord_rpc.h>
|
||||
#include <fmt/format.h>
|
||||
|
|
|
|||
|
|
@ -369,7 +369,6 @@ else()
|
|||
else()
|
||||
target_compile_options(video_core PRIVATE $<$<COMPILE_LANGUAGE:C,CXX>:-Werror=conversion>)
|
||||
endif()
|
||||
|
||||
target_compile_options(video_core PRIVATE $<$<COMPILE_LANGUAGE:C,CXX>:-Wno-sign-conversion>)
|
||||
|
||||
# xbyak
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2025 Eden Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
// SPDX-FileCopyrightText: Copyright 2023 yuzu Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
|
@ -13,9 +13,14 @@
|
|||
#ifdef _MSC_VER
|
||||
#pragma warning( push )
|
||||
#pragma warning( disable : 4189 )
|
||||
#elif defined(__clang__)
|
||||
#pragma clang diagnostic push
|
||||
#pragma clang diagnostic ignored "-Wunused-variable"
|
||||
#endif
|
||||
#include "vk_mem_alloc.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning( pop )
|
||||
#elif defined(__clang__)
|
||||
#pragma clang diagnostic pop
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,3 +1,6 @@
|
|||
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
# SPDX-FileCopyrightText: 2018 yuzu Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||
#endif
|
||||
#endif
|
||||
#include <httplib.h>
|
||||
#include "common/httplib.h"
|
||||
#ifdef __GNUC__
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -369,7 +369,7 @@ if (APPLE)
|
|||
if (CMAKE_GENERATOR MATCHES "Xcode")
|
||||
set(_icons "${_dist}/eden.icon")
|
||||
|
||||
set_target_properties(eden PROPERTIES
|
||||
set_target_properties(yuzu PROPERTIES
|
||||
XCODE_ATTRIBUTE_ASSETCATALOG_COMPILER_APPICON_NAME eden
|
||||
MACOSX_BUNDLE_ICON_FILE eden
|
||||
# Also force xcode to manage signing for us.
|
||||
|
|
|
|||
|
|
@ -83,7 +83,7 @@ ci_package() {
|
|||
android-aarch64 android-x86_64 \
|
||||
solaris-amd64 freebsd-amd64 openbsd-amd64 \
|
||||
linux-amd64 linux-aarch64 \
|
||||
macos-universal; do
|
||||
macos-universal ios-aarch64; do
|
||||
echo "-- * platform $platform"
|
||||
|
||||
case $DISABLED in
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ mingw-amd64 mingw-arm64
|
|||
android-aarch64 android-x86_64
|
||||
solaris-amd64 freebsd-amd64 openbsd-amd64
|
||||
linux-amd64 linux-aarch64
|
||||
macos-universal"
|
||||
macos-universal ios-aarch64"
|
||||
|
||||
DISABLED_PLATFORMS="$reply"
|
||||
fi
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue