Compare commits

...

127 Commits

Author SHA1 Message Date
lizzie f3cb65df4b vk open icd 2026-08-28 19:04:24 +00:00
lizzie 0f15e5f8a7 fix emu cmd 2026-08-28 16:53:32 +00:00
lizzie bbb8c35116 hook back the patches 2026-08-28 16:53:32 +00:00
lizzie 2ddd730b89 fix fullscreen stuff on debian? 2026-08-28 16:53:32 +00:00
lizzie ee0e2f4541 FIX FOR DETECT PLATFORM 2026-08-28 16:53:32 +00:00
lizzie 9380ea0aba remove unused run_on_host 2026-08-28 16:53:32 +00:00
lizzie b68d5767d4 softpipe enabled mesa support 2026-08-28 16:53:32 +00:00
lizzie 3432372bc8 all audio issues magically fixed 2026-08-28 16:53:32 +00:00
lizzie bbb99d4fb1 fix mappings 2026-08-28 16:53:32 +00:00
lizzie 954938a1c0 fix input finally 2026-08-28 16:53:32 +00:00
lizzie 721e2d1614 various SDL driver fixes for joystick, initialize video 2026-08-28 16:53:32 +00:00
lizzie 6898383393 better PS4 patches for SDL3 2026-08-28 16:53:32 +00:00
lizzie 27819ddf8e ps4 joystick 2026-08-28 16:53:32 +00:00
lizzie 63d4918921 guard bundled openssl 2026-08-28 16:53:32 +00:00
lizzie 3b59c8d353 fixup for new openssl 2026-08-28 16:53:32 +00:00
lizzie a4c1090eca properly build with new openssl cpm mechanism 2026-08-28 16:53:32 +00:00
lizzie e320719439 license fix? 2026-08-28 16:53:32 +00:00
lizzie f313249771 novideo 2026-08-28 16:53:32 +00:00
lizzie 195f0aaa24 random fixes 2026-08-28 16:53:32 +00:00
lizzie 37c194b74c sdl3 compiles now 2026-08-28 16:53:32 +00:00
lizzie 60ed431f74 SDL3 port 2026-08-28 16:53:32 +00:00
lizzie 2e4ea05781 adjust samples to PS4<->switch 2026-08-28 16:53:32 +00:00
lizzie 46125e43c5 use 16k pages again 2026-08-28 16:53:32 +00:00
lizzie 6d13f17f96 restore old audio size 2026-08-28 16:53:32 +00:00
lizzie 1c93686a33 wait after audio process 2026-08-28 16:53:32 +00:00
lizzie e48f6a29df hostmem doesn't exist? 2026-08-28 16:53:32 +00:00
lizzie 25cf89beb9 fix pagesize 2026-08-28 16:53:32 +00:00
lizzie ccfc829050 fix timestamps due to wrong stat 2026-08-28 16:53:32 +00:00
lizzie 3503e552bd fix stat being wrong 2026-08-28 16:53:32 +00:00
lizzie 7d007a40f2 fix std exchange, fix host mem unused funcs 2026-08-28 16:53:32 +00:00
lizzie d1f9fd9251 checkout useless changs 2026-08-28 16:53:32 +00:00
lizzie 054eba7de4 make fiber bigger, build.sh 2026-08-28 16:53:32 +00:00
lizzie 981bab94a0 disable openssl on httplib hdr 2026-08-28 16:53:32 +00:00
lizzie 9528dbd96f update license 2026-08-28 16:53:32 +00:00
lizzie 7d418d0983 remove outdated make-toolchain 2026-08-28 16:53:32 +00:00
lizzie cc4b2dea8a put swap proper 2026-08-28 16:53:32 +00:00
lizzie d866221e7e file loggin is safe now, settings too 2026-08-28 16:53:31 +00:00
lizzie beefc88168 properly define orbis page size 2026-08-28 16:53:16 +00:00
lizzie 0b9fc33d4d exclude tests that dont work 2026-08-28 16:53:16 +00:00
lizzie 936c772984 proper virtual base, remove uneeded sysconf things 2026-08-28 16:53:16 +00:00
lizzie 3c31d0eb83 skip exception handler register on PS4 and use xbyak::inner:getpagesize 2026-08-28 16:53:16 +00:00
lizzie df488bea24 remove thread remnants 2026-08-28 16:53:16 +00:00
lizzie 5971fd5f0d ryujinx was never ported to PS4 2026-08-28 16:53:16 +00:00
lizzie 4b773b5b91 fucking rng 2026-08-28 16:53:16 +00:00
lizzie 439ab6a8dd random stray devices ugh 2026-08-28 16:53:16 +00:00
lizzie 2e208ac95b httplib partial thing 2026-08-28 16:53:16 +00:00
lizzie 97dd23daaa fix shit 2026-08-28 16:53:16 +00:00
lizzie ff8574cc61 fix nproc 2026-08-28 16:53:16 +00:00
lizzie dc4754f163 disable openssl and register user 2026-08-28 16:53:16 +00:00
lizzie c88956709b needs libscienternal 2026-08-28 16:53:16 +00:00
lizzie fddd0153e8 try fix musl 2 2026-08-28 16:53:16 +00:00
lizzie e9dc40b3fc native ps4 audio sink 2026-08-28 16:53:16 +00:00
lizzie 47ce6f289c init audio 2026-08-28 16:53:16 +00:00
lizzie e7a7cd0b56 fix virtual buffers 2026-08-28 16:53:16 +00:00
lizzie 81e7d3baa6 fix openssl 2026-08-28 16:53:16 +00:00
lizzie d99e754d05 disable stdio buffering 2026-08-28 16:53:16 +00:00
lizzie e03e98106c FX 2026-08-28 16:53:16 +00:00
lizzie 55ec9f7e03 let it rip 2026-08-28 16:53:16 +00:00
lizzie 1e265eb337 leave pending param package stuff 2026-08-28 16:53:16 +00:00
lizzie 0e8784239c restore protection 2026-08-28 16:53:16 +00:00
lizzie 0bb30de112 immediately terminate in OO, use 2MB swap handler 2026-08-28 16:53:15 +00:00
lizzie db109b2f54 use btver2 2026-08-28 16:53:15 +00:00
lizzie 6ae4c6c418 reduce fiber sizes 2026-08-28 16:53:15 +00:00
lizzie 4215c11f83 fix yuzu cpp 2026-08-28 16:53:15 +00:00
lizzie 04bfac0fe4 use dmem for swap buffers, restore full jit sizes 2026-08-28 16:53:15 +00:00
lizzie f1dc1d3118 force ankerl + fixup for OO with prelude commits 2026-08-28 16:53:15 +00:00
lizzie 771c782373 fix 2026-08-28 16:53:15 +00:00
lizzie 2120c1546e fixup shit 2026-08-28 16:53:15 +00:00
lizzie ec3408f950 SDL2 PS4 patch 2026-08-28 16:53:15 +00:00
lizzie c2121bd02b use newer sdl2, make bigger stack 2026-08-28 16:53:15 +00:00
lizzie 3ca48a4bba mark codeblocks as noexcept 2026-08-28 16:53:15 +00:00
lizzie a541c942d1 fix2 2026-08-28 16:53:15 +00:00
lizzie ee04868b1f make a bit more mergeable 2026-08-28 16:53:15 +00:00
lizzie 099d3eaa23 Use updated SDL2 2026-08-28 16:53:15 +00:00
lizzie 10396f15e5 revert input system to main 2026-08-28 16:53:15 +00:00
lizzie c9bedf700f stub add proper iostream init 2026-08-28 16:53:15 +00:00
lizzie 3914efb3e6 ps4 icon 2026-08-28 16:53:15 +00:00
lizzie 0e54f3483f update loicense 2026-08-28 16:53:15 +00:00
lizzie 9fa8494d2a restore stupid lock, make ps4sup library 2026-08-28 16:53:15 +00:00
lizzie ae02326341 bs fix 2026-08-28 16:53:15 +00:00
lizzie b0978f109f fix eboot 2026-08-28 16:53:15 +00:00
lizzie c354b616f6 temp fix for dpad 2026-08-28 16:53:15 +00:00
lizzie 621fb3efbd add emutls.c 2026-08-28 16:53:15 +00:00
lizzie 3b6b5a064f reduce arm codeisze, force 16x4 pages again 2026-08-28 16:53:15 +00:00
lizzie 8684dafde8 extra buffer precautions to not exhaust DMem, format better + perf history nerf 2026-08-28 16:53:15 +00:00
lizzie 5ac6ba0bde more inline pt2 2026-08-28 16:53:15 +00:00
lizzie d9539554d2 fix atexit impl 2026-08-28 16:53:15 +00:00
lizzie 02c08099d6 fibers that don't immediately crash?!!?!?!!? 2026-08-28 16:53:15 +00:00
lizzie 7986a9fbcd force running services on host 2026-08-28 16:53:15 +00:00
lizzie 2b9cc8584e fix alloc failures 2026-08-28 16:53:15 +00:00
lizzie c80604d660 fix for crashes on TLS due to openorbis being W E I R D 2026-08-28 16:53:15 +00:00
lizzie 1c4c836cc8 opengl bullshit 2026-08-28 16:53:15 +00:00
lizzie fdf182a02b proper memswap mechanism 2026-08-28 16:53:15 +00:00
lizzie 132cf2b3b4 more stupid stuff 2026-08-28 16:53:15 +00:00
lizzie 927113439c fixes 4 stuff 2026-08-28 16:53:15 +00:00
lizzie e2a1de0a43 swap handling 2026-08-28 16:53:15 +00:00
lizzie 9cebeaf2bd license 2026-08-28 16:53:15 +00:00
lizzie af9f62d5da add sce_module so it loads on real hw 2026-08-28 16:53:15 +00:00
lizzie b2fff6d30b fixes for mbedtls 2026-08-28 16:53:15 +00:00
lizzie 23fc9fcfb4 adapt to new master 2026-08-28 16:53:14 +00:00
lizzie 365e140d86 evil haxx 2026-08-28 16:53:14 +00:00
lizzie 345bec282b extra ps4 defs 2026-08-28 16:53:14 +00:00
lizzie 55f07658b7 force NO fastmem 2026-08-28 16:53:14 +00:00
lizzie 8c7bf53748 more memory shit 2026-08-28 16:53:14 +00:00
lizzie 9ad6fd6343 MAP_SYSTEM 2026-08-28 16:53:14 +00:00
lizzie 47de27888c (likely) fixes for virtual dmem? 2026-08-28 16:53:14 +00:00
lizzie e4c91ec727 disable fastmem 2026-08-28 16:53:14 +00:00
lizzie 9742c60044 try to fix the paths 2026-08-28 16:53:14 +00:00
lizzie 374d958d57 sysconf stub cuz crash(?) + some stderrp stuff 2026-08-28 16:53:14 +00:00
lizzie bf7787f0d1 the orb 2026-08-28 16:53:14 +00:00
lizzie eb2cf74e7c fself + pkg stuffs 2026-08-28 16:53:14 +00:00
lizzie 67a9e4472b make .pkg and .self 2026-08-28 16:53:14 +00:00
lizzie 7082bfd026 exclude more stuff from vulkan 2026-08-28 16:53:14 +00:00
lizzie dec3f05465 exclude from vulkan surface selection 2026-08-28 16:53:14 +00:00
lizzie bbcb1059e1 buildable toolchain script + fixes for ffmpeg 2026-08-28 16:53:14 +00:00
lizzie ef7a000512 merge 2026-08-28 16:53:12 +00:00
lizzie abf96fa96c merge 2026-08-28 16:50:27 +00:00
lizzie 6c0e5cda14 merge 2026-08-28 16:45:54 +00:00
lizzie a92fd72eb8 fix 2026-08-28 16:45:54 +00:00
lizzie 63f5d30e03 toolchain-fix 2026-08-28 16:45:54 +00:00
lizzie 119291dc77 [qt_common/discord] fix boxart not being used (#4275)
Signed-off-by: lizzie <lizzie@eden-emu.dev>

- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.

-------------------

issue was first reported here
https://github.com/eden-emulator/Issue-Reports/issues/607

tl;dr wrong boolean, now boxarts should work

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4275
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-08-28 03:46:36 +02:00
lizzie f7dbff2157 [core/hle/services/am] Fix MK8D crash (#4313)
Signed-off-by: lizzie <lizzie@eden-emu.dev>

- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.

-------------------

This fixes a random mk8d crash when connecting via LDN

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4313
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-08-28 03:44:45 +02:00
lizzie b859d7fdf4 [dynarmic/backend/exception_handler] normalize EH for arches, use LOG_ERROR instead of fmt::print (#4283)
Signed-off-by: lizzie <lizzie@eden-emu.dev>

- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.

-------------------

this should simplify a bit of code logic
akin to NetBSD's UC_CONTEXT_PC...
additionally use LOG_ERROR so the
"unhandled ..."
is logged unto a file
before sigsegv'ing

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4283
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-08-28 02:30:18 +02:00
lizzie f635827fa6 [common/stb] remove unused I/O funcs from non-LTO builds, use common/stb.h on ns service (#4282)
Signed-off-by: lizzie <lizzie@eden-emu.dev>

- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.

-------------------

- remove I/O functions that are unused from LTO builds
- use common/stb.h on ns
simple change really, not much to explain here

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4282
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>
2026-08-28 02:29:52 +02:00
lizzie 243453c172 [dynarmic, loong64] fix build error due to new term handlers (#4286)
Signed-off-by: lizzie <lizzie@eden-emu.dev>

- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.

-------------------

trivial fix

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4286
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-08-28 02:24:39 +02:00
lizzie 39158b67a7 [audio/sdl3] fix mismatches OS mixer settings for sdl3/cubeb audio backends (#4298)
Signed-off-by: lizzie <lizzie@eden-emu.dev>

- [x] I have read and followed the [Contribution Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/CONTRIBUTING.md#code-contributions).
- [x] I have read and followed the [AI Policy](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/AI.md)
- [x] I have read and followed the [Coding Guidelines](https://git.eden-emu.dev/eden-emu/eden/src/branch/master/docs/policies/Coding.md) to the best of my ability.

-------------------

basically makes it so SDL3 and cubeb audio backends now share the same
identifier string so OS mixers (ok a bit of a misnormer, its like pulseaudio
pipewire and such, but yknow what i mean) -- dont conflate due to the
fact that "Eden" != "yuzu Latency Getter".
fix taken from pcsx2 https://github.com/PCSX2/pcsx2/pull/12312

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4298
Reviewed-by: Maufeat <sahyno1996@gmail.com>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
2026-08-28 01:50:55 +02:00
CamilleLaVey 50cb8fd1c9 [vulkan] Implementation for VK_EXT_shader_quad_control (#4168)
An experimental approach to introduce an smarter way to use and access QUAD's capabilities on shaders, suggested by @gidoly some months ago, finally came into something usable; current implementation checks GLASM, GLSL and Vulkan on their own way, stablishes proper emitters and receivers for Quads inside our recompiler, which are the introductions for future changes; checks for support and actual feature bit, OpCodes and mask were added within this PR. Meanwhile the expected behavior was to reduce graphical issues (on games with Quad shaders reliant), we encountered a very slight performance increase depending on what game and shader are actually compiled.

Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/4168
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
Reviewed-by: Samuel <lizzie@eden-emu.dev>
2026-08-28 01:21:22 +02:00
97 changed files with 3053 additions and 279 deletions
+66
View File
@@ -0,0 +1,66 @@
#!/usr/local/bin/bash -ex
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
[ -z ${OO_PS4_TOOLCHAIN+x} ] && exit
# cmake
[ -f "ps4-toolchain.cmake" ] || cat << EOF >"ps4-toolchain.cmake"
set(CMAKE_SYSROOT "$OO_PS4_TOOLCHAIN")
set(CMAKE_STAGING_PREFIX "$OO_PS4_TOOLCHAIN")
set(CMAKE_SYSTEM_NAME "OpenOrbis")
set(CMAKE_C_FLAGS "-D__OPENORBIS__ -D_LIBCPP_HAS_MUSL_LIBC=1 -D_GNU_SOURCE=1 --target=x86_64-pc-freebsd12-elf -mtune=btver2 -march=btver2 -fPIC -funwind-tables -femulated-tls")
set(CMAKE_CXX_FLAGS "-D__OPENORBIS__ -D_LIBCPP_HAS_MUSL_LIBC=1 -D_GNU_SOURCE=1 --target=x86_64-pc-freebsd12-elf -mtune=btver2 -march=btver2 -fPIC -funwind-tables -femulated-tls")
set(CMAKE_EXE_LINKER_FLAGS "-m elf_x86_64 -pie -T $OO_PS4_TOOLCHAIN/link.x --eh-frame-hdr -L$OO_PS4_TOOLCHAIN/lib")
set(CMAKE_C_LINK_FLAGS "-m elf_x86_64 -pie -T $OO_PS4_TOOLCHAIN/link.x --eh-frame-hdr -L$OO_PS4_TOOLCHAIN/lib")
set(CMAKE_CXX_LINK_FLAGS "-m elf_x86_64 -pie -T $OO_PS4_TOOLCHAIN/link.x --eh-frame-hdr -L$OO_PS4_TOOLCHAIN/lib")
set(CMAKE_C_COMPILER clang)
set(CMAKE_CXX_COMPILER clang++)
set(CMAKE_LINKER ld.lld)
set(CMAKE_C_LINK_EXECUTABLE "<CMAKE_LINKER> <CMAKE_C_LINK_FLAGS> <OBJECTS> -o <TARGET> -lc -lkernel -lSceUserService -lSceSysmodule -lSceNet -lSceLibcInternal $OO_PS4_TOOLCHAIN/lib/crt1.o <LINK_LIBRARIES>")
set(CMAKE_CXX_LINK_EXECUTABLE "<CMAKE_LINKER> <CMAKE_CXX_LINK_FLAGS> <OBJECTS> -o <TARGET> -lc -lkernel -lc++ -lSceUserService -lSceSysmodule -lSceNet -lSceLibcInternal $OO_PS4_TOOLCHAIN/lib/crt1.o <LINK_LIBRARIES>")
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
# TODO: Why does cmake not set this?
set(CMAKE_SIZEOF_VOID_P 8)
EOF
[ -z ${NPROC+x} ] && NPROC=$(nproc || 1)
# Normally a platform has a package manager
# PS4 does not, atleast not in the normal sense
export EXTRA_CMAKE_FLAGS=("${EXTRA_CMAKE_FLAGS[@]}" $@)
[ -f "build/Makefile" ] || cmake -S . -B build -G "Unix Makefiles" \
-DCMAKE_TOOLCHAIN_FILE="ps4-toolchain.cmake" \
-DENABLE_QT_TRANSLATION=OFF \
-DENABLE_CUBEB=OFF \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_CXX_FLAGS="$ARCH_FLAGS" \
-DCMAKE_C_FLAGS="$ARCH_FLAGS" \
-DENABLE_SDL2=ON \
-DENABLE_LIBUSB=OFF \
-DENABLE_UPDATE_CHECKER=OFF \
-DENABLE_QT=OFF \
-DENABLE_OPENGL=ON \
-DENABLE_WEB_SERVICE=OFF \
-DUSE_DISCORD_PRESENCE=OFF \
-DCPMUTIL_FORCE_BUNDLED=ON \
-DYUZU_USE_EXTERNAL_FFMPEG=ON \
-DYUZU_USE_CPM=ON \
-DDYNARMIC_ENABLE_NO_EXECUTE_SUPPORT=OFF \
-DDYNARMIC_TESTS=ON \
-DYUZU_TESTS=ON \
-DYUZU_USE_EXTERNAL_SDL2=ON \
"${EXTRA_CMAKE_FLAGS[@]}" || exit
cmake --build build -t yuzu-cmd_pkg -- -j$NPROC
#cmake --build build -t dynarmic_tests_pkg -- -j$NPROC
#cmake --build build -t testps4_pkg -- -j$NPROC
+3
View File
@@ -63,3 +63,6 @@ artifacts
/install* /install*
vulkansdk*.exe vulkansdk*.exe
*.tar.zst *.tar.zst
# PS4 toolchain stuff
ps4-toolchain.cmake
+17
View File
@@ -0,0 +1,17 @@
diff --git a/libs/asio/include/boost/asio/detail/impl/socket_ops.ipp b/libs/asio/include/boost/asio/detail/impl/socket_ops.ipp
index 0129511c..10fc9b04 100644
--- a/libs/asio/include/boost/asio/detail/impl/socket_ops.ipp
+++ b/libs/asio/include/boost/asio/detail/impl/socket_ops.ipp
@@ -15,6 +15,12 @@
# pragma once
#endif // defined(_MSC_VER) && (_MSC_VER >= 1200)
+// hacky fix for ps4
+#if defined(__OPENORBIS__)
+# define FIONBIO 0
+# define FIONREAD 1
+#endif
+
#include <boost/asio/detail/config.hpp>
#include <cctype>
+13
View File
@@ -0,0 +1,13 @@
diff --git a/unix.c b/unix.c
index 6669216..86a2faa 100644
--- a/unix.c
+++ b/unix.c
@@ -53,7 +53,7 @@
#include <poll.h>
#endif
-#if !defined(HAS_SOCKLEN_T) && !defined(__socklen_t_defined)
+#if !defined(__OPENORBIS__) && !defined(HAS_SOCKLEN_T) && !defined(__socklen_t_defined)
typedef int socklen_t;
#endif
+15
View File
@@ -0,0 +1,15 @@
diff --git a/libavutil/cpu.c b/libavutil/cpu.c
index 03e2720..874258f 100644
--- a/libavutil/cpu.c
+++ b/libavutil/cpu.c
@@ -43,8 +43,10 @@
#include <sys/param.h>
#endif
#include <sys/types.h>
+#ifndef __OPENORBIS__
#include <sys/sysctl.h>
#endif
+#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
@@ -0,0 +1,40 @@
diff --git a/cmake/ConfigureOpenSSL.cmake b/cmake/ConfigureOpenSSL.cmake
index 3012e05..2ae23ff 100644
--- a/cmake/ConfigureOpenSSL.cmake
+++ b/cmake/ConfigureOpenSSL.cmake
@@ -108,7 +108,8 @@ function(configure_openssl)
)
if(NOT "${CONFIGURE_OPTIONS_OLD}" STREQUAL "")
- if(CONFIGURE_OPTIONS STREQUAL CONFIGURE_OPTIONS_OLD)
+ # TODO(lizzie): Emscripten has issues with rebuilding due to the wrapper it uses
+ if(CMAKE_SYSTEM_NAME MATCHES "Emscripten" OR CONFIGURE_OPTIONS STREQUAL CONFIGURE_OPTIONS_OLD)
message(STATUS "Found previous configure results. Don't perform configuration")
return()
endif()
@@ -134,10 +135,24 @@ function(configure_openssl)
set(VERBOSE_OPTION OUTPUT_QUIET)
endif()
+ if (CMAKE_SYSTEM_NAME MATCHES "Emscripten")
+ set(EMSCRIPTEN_CMAKE_WRAPPER "emcmake")
+ find_program(EMCC emcc REQUIRED)
+ set(EMSCRIPTEN_LINKER ${EMCC})
+ list(APPEND CONFIGURE_COMMAND wasm64)
+ else()
+ set(EMSCRIPTEN_CMAKE_WRAPPER "")
+ set(EMSCRIPTEN_LINKER ${CMAKE_LINKER})
+ endif ()
+
execute_process(
- COMMAND ${CMAKE_COMMAND} -E env
+ COMMAND ${EMSCRIPTEN_CMAKE_WRAPPER} ${CMAKE_COMMAND} -E env
"CFLAGS=${CMAKE_C_FLAGS}"
"CXXFLAGS=${CMAKE_CXX_FLAGS}"
+ "LDFLAGS=${CMAKE_CXX_LINK_FLAGS}"
+ "CC=${CMAKE_C_COMPILER}"
+ "CXX=${CMAKE_CXX_COMPILER}"
+ "LD=${EMSCRIPTEN_LINKER}"
${CONFIGURE_COMMAND}
WORKING_DIRECTORY ${CONFIGURE_BUILD_DIR}
${VERBOSE_OPTION}
@@ -0,0 +1,33 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1ca57e1..593fd62 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -148,6 +148,16 @@ if(NOT BUILD_SHARED_LIBS)
list(APPEND OPENSSL_CONFIGURE_OPTIONS no-shared)
endif()
+list(APPEND OPENSSL_CONFIGURE_OPTIONS
+ no-threads no-thread-pool no-shared no-afalgeng no-async no-capieng no-cmp no-cms no-comp no-ct
+ no-docs no-dgram no-dso no-dynamic-engine no-engine no-filenames no-gost
+ no-http no-legacy no-module no-nextprotoneg no-ocsp no-padlockeng no-quic
+ no-srp no-srtp no-ssl-trace no-static-engine no-tests no-thread-pool no-ts
+ no-ui-console no-uplink no-ssl3-method no-tls1-method no-tls1_1-method
+ no-dtls1-method no-dtls1_2-method no-argon2 no-bf no-blake2 no-cast
+ no-dsa no-idea no-md4 no-mdc2 no-ocb no-rc2 no-rc4 no-rmd160 no-scrypt
+ no-siphash no-siv no-sm2 no-sm3 no-sm4 no-whirlpool no-apps)
+
list(SORT OPENSSL_CONFIGURE_OPTIONS)
list(REMOVE_DUPLICATES OPENSSL_CONFIGURE_OPTIONS)
list(PREPEND OPENSSL_CONFIGURE_OPTIONS ${OPENSSL_TARGET_PLATFORM})
diff --git a/cmake/ConfigureOpenSSL.cmake b/cmake/ConfigureOpenSSL.cmake
index 2ae23ff..22a4a27 100644
--- a/cmake/ConfigureOpenSSL.cmake
+++ b/cmake/ConfigureOpenSSL.cmake
@@ -154,6 +154,7 @@ function(configure_openssl)
"CXX=${CMAKE_CXX_COMPILER}"
"LD=${EMSCRIPTEN_LINKER}"
${CONFIGURE_COMMAND}
+ "--prefix=${CMAKE_SYSROOT}"
WORKING_DIRECTORY ${CONFIGURE_BUILD_DIR}
${VERBOSE_OPTION}
COMMAND_ERROR_IS_FATAL ANY
@@ -0,0 +1,13 @@
diff --git a/crypto/o_str.c b/crypto/o_str.c
index 8aadff5..ba427c9 100644
--- a/crypto/o_str.c
+++ b/crypto/o_str.c
@@ -385,7 +385,7 @@ int openssl_strerror_r(int errnum, char *buf, size_t buflen)
* It can return a pointer to some (immutable) static string in which case
* buf is left unused.
*/
- err = strerror_r(errnum, buf, buflen);
+ err = (char *)strerror_r(errnum, buf, buflen);
if (err == NULL || buflen == 0)
return 0;
/*
+196
View File
@@ -0,0 +1,196 @@
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8872895..b0eeca8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1770,7 +1770,6 @@ elseif(EMSCRIPTEN)
CheckPTHREAD()
CheckLibUnwind()
-
elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
set(SDL_DISABLE_DLOPEN_NOTES TRUE)
@@ -3647,10 +3646,30 @@ if(NOT HAVE_CAMERA)
)
endif()
+# Always on?
+if (OPENORBIS)
+ sdl_sources(
+ "${SDL3_SOURCE_DIR}/src/thread/pthread/SDL_systhread.c"
+ "${SDL3_SOURCE_DIR}/src/thread/pthread/SDL_sysmutex.c" # Can be faked, if necessary
+ "${SDL3_SOURCE_DIR}/src/thread/pthread/SDL_syscond.c" # Can be faked, if necessary
+ "${SDL3_SOURCE_DIR}/src/thread/pthread/SDL_sysrwlock.c" # Can be faked, if necessary
+ "${SDL3_SOURCE_DIR}/src/thread/pthread/SDL_systls.c"
+ "${SDL3_SOURCE_DIR}/src/thread/generic/SDL_syssem.c"
+ )
+ sdl_glob_sources("${SDL3_SOURCE_DIR}/src/time/unix/*.c")
+ sdl_glob_sources("${SDL3_SOURCE_DIR}/src/timer/unix/*.c")
+ set(HAVE_SDL_THREADS TRUE)
+ set(HAVE_SDL_TIMERS TRUE)
+ set(HAVE_SDL_TIME TRUE)
+ set(SDL_TIME_UNIX 1)
+ set(SDL_TIMER_UNIX 1)
+ set(SDL_THREAD_PTHREAD 1)
+endif ()
+
# We always need to have threads and timers around
if(NOT HAVE_SDL_THREADS)
# The Emscripten and N-Gage platform has been carefully vetted to work without threads
- if(EMSCRIPTEN OR NGAGE)
+ if(EMSCRIPTEN OR NGAGE OR OPENORBIS)
set(SDL_THREADS_DISABLED 1)
sdl_glob_sources(
"${SDL3_SOURCE_DIR}/src/thread/generic/*.c"
diff --git a/build-scripts/rename_macros.py b/build-scripts/rename_macros.py
index 978120c..b6063dd 100755
--- a/build-scripts/rename_macros.py
+++ b/build-scripts/rename_macros.py
@@ -124,6 +124,7 @@ RENAMED_MACROS = {
"__RISCOS__": "SDL_PLATFORM_RISCOS",
"__SOLARIS__": "SDL_PLATFORM_SOLARIS",
"__PSP__": "SDL_PLATFORM_PSP",
+ "__PS4__": "SDL_PLATFORM_PS4",
"__PS2__": "SDL_PLATFORM_PS2",
"__VITA__": "SDL_PLATFORM_VITA",
"__3DS__": "SDL_PLATFORM_3DS",
diff --git a/include/SDL3/SDL_platform_defines.h b/include/SDL3/SDL_platform_defines.h
index 7963149..6c0dd5d 100644
--- a/include/SDL3/SDL_platform_defines.h
+++ b/include/SDL3/SDL_platform_defines.h
@@ -442,6 +442,16 @@
#define SDL_PLATFORM_PSP 1
#endif
+#if defined(__PS4__) || defined(__OPENORBIS__)
+
+/**
+ * A preprocessor macro that is only defined if compiling for Sony PSP.
+ *
+ * \since This macro is available since SDL 3.2.0.
+ */
+#define SDL_PLATFORM_PS4 1
+#endif
+
#if defined(__PS2__) || defined(PS2)
/**
diff --git a/src/SDL.c b/src/SDL.c
index b1a1a56..0a3fec6 100644
--- a/src/SDL.c
+++ b/src/SDL.c
@@ -714,7 +714,7 @@ void SDL_Quit(void)
SDL_DBus_Quit();
#endif
-#if defined(SDL_PLATFORM_UNIX) && !defined(SDL_PLATFORM_ANDROID) && !defined(SDL_PLATFORM_EMSCRIPTEN) && !defined(SDL_PLATFORM_PRIVATE)
+#if defined(SDL_PLATFORM_UNIX) && !defined(SDL_PLATFORM_ANDROID) && !defined(SDL_PLATFORM_EMSCRIPTEN) && !defined(SDL_PLATFORM_PRIVATE) && !defined(SDL_PLATFORM_PS4)
SDL_Gtk_Quit();
#endif
@@ -813,6 +813,8 @@ const char *SDL_GetPlatform(void)
return "tvOS";
#elif defined(SDL_PLATFORM_PS2)
return "PlayStation 2";
+#elif defined(SDL_PLATFORM_PS4)
+ return "PlayStation 4";
#elif defined(SDL_PLATFORM_PSP)
return "PlayStation Portable";
#elif defined(SDL_PLATFORM_VITA)
diff --git a/src/audio/SDL_audio.c b/src/audio/SDL_audio.c
index c1e4241..65b1e6d 100644
--- a/src/audio/SDL_audio.c
+++ b/src/audio/SDL_audio.c
@@ -80,6 +80,9 @@ static const AudioBootStrap *const bootstrap[] = {
#ifdef SDL_AUDIO_DRIVER_NGAGE
&NGAGEAUDIO_bootstrap,
#endif
+#ifdef SDL_AUDIO_DRIVER_PS4
+ &PS4AUDIO_bootstrap,
+#endif
#ifdef SDL_AUDIO_DRIVER_EMSCRIPTEN
&EMSCRIPTENAUDIO_bootstrap,
#endif
diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c
index 60c9743..2d12c3a 100644
--- a/src/joystick/SDL_joystick.c
+++ b/src/joystick/SDL_joystick.c
@@ -106,6 +106,9 @@ static SDL_JoystickDriver *SDL_joystick_drivers[] = {
#ifdef SDL_JOYSTICK_N3DS
&SDL_N3DS_JoystickDriver,
#endif
+#ifdef SDL_JOYSTICK_PS4
+ &SDL_PS4_JoystickDriver,
+#endif
#if defined(SDL_JOYSTICK_DUMMY) || defined(SDL_JOYSTICK_DISABLED)
&SDL_DUMMY_JoystickDriver
#endif
diff --git a/src/joystick/SDL_sysjoystick.h b/src/joystick/SDL_sysjoystick.h
index 47ce42c..42ab9de 100644
--- a/src/joystick/SDL_sysjoystick.h
+++ b/src/joystick/SDL_sysjoystick.h
@@ -253,6 +253,7 @@ extern SDL_JoystickDriver SDL_HAIKU_JoystickDriver;
extern SDL_JoystickDriver SDL_HIDAPI_JoystickDriver;
extern SDL_JoystickDriver SDL_RAWINPUT_JoystickDriver;
extern SDL_JoystickDriver SDL_IOS_JoystickDriver;
+extern SDL_JoystickDriver SDL_PS4_JoystickDriver;
extern SDL_JoystickDriver SDL_LINUX_JoystickDriver;
extern SDL_JoystickDriver SDL_VIRTUAL_JoystickDriver;
extern SDL_JoystickDriver SDL_WGI_JoystickDriver;
diff --git a/src/render/SDL_sysrender.h b/src/render/SDL_sysrender.h
index a1bb44a..51843c4 100644
--- a/src/render/SDL_sysrender.h
+++ b/src/render/SDL_sysrender.h
@@ -381,6 +381,7 @@ extern SDL_RenderDriver NGAGE_RenderDriver;
extern SDL_RenderDriver VULKAN_RenderDriver;
extern SDL_RenderDriver PS2_RenderDriver;
extern SDL_RenderDriver PSP_RenderDriver;
+extern SDL_RenderDriver PS4_RenderDriver;
extern SDL_RenderDriver SW_RenderDriver;
extern SDL_RenderDriver VITA_GXM_RenderDriver;
extern SDL_RenderDriver GPU_RenderDriver;
diff --git a/src/stdlib/SDL_string.c b/src/stdlib/SDL_string.c
index 4a870f6..69ca1db 100644
--- a/src/stdlib/SDL_string.c
+++ b/src/stdlib/SDL_string.c
@@ -32,7 +32,9 @@
#include "SDL_casefolding.h"
-#if defined(__SIZEOF_WCHAR_T__)
+#if defined(SDL_PLATFORM_PS4)
+#define SDL_SIZEOF_WCHAR_T 2
+#elif defined(__SIZEOF_WCHAR_T__)
#define SDL_SIZEOF_WCHAR_T __SIZEOF_WCHAR_T__
#elif defined(SDL_PLATFORM_NGAGE)
#define SDL_SIZEOF_WCHAR_T 2
@@ -43,7 +45,6 @@
#endif
SDL_COMPILE_TIME_ASSERT(sizeof_wchar_t, sizeof(wchar_t) == SDL_SIZEOF_WCHAR_T);
-
char *SDL_UCS4ToUTF8(Uint32 codepoint, char *dst)
{
if (!dst) {
diff --git a/src/video/SDL_video.c b/src/video/SDL_video.c
index f650f27..e23424f 100644
--- a/src/video/SDL_video.c
+++ b/src/video/SDL_video.c
@@ -131,6 +131,9 @@ static VideoBootStrap *bootstrap[] = {
#ifdef SDL_VIDEO_DRIVER_NGAGE
&NGAGE_bootstrap,
#endif
+#ifdef SDL_VIDEO_DRIVER_PS4
+ &PS4_bootstrap,
+#endif
#ifdef SDL_VIDEO_DRIVER_KMSDRM
&KMSDRM_bootstrap,
#endif
@@ -314,6 +317,7 @@ static bool SDL_CreateWindowTexture(SDL_VideoDevice *_this, SDL_Window *window,
SDL_GetWindowSizeInPixels(window, &w, &h);
if (!data) {
+
SDL_Renderer *renderer = NULL;
const char *render_driver = NULL;
File diff suppressed because it is too large Load Diff
+25
View File
@@ -0,0 +1,25 @@
diff --git a/source/opt/loop_dependence.cpp b/source/opt/loop_dependence.cpp
index e41c044..a51b53b 100644
--- a/source/opt/loop_dependence.cpp
+++ b/source/opt/loop_dependence.cpp
@@ -12,6 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+// PS4: issue?
+#ifdef __PS4__
+#pragma clang diagnostic ignored "-Wabsolute-value"
+#pragma clang diagnostic ignored "-Wshorten-64-to-32"
+#endif
+
#include "source/opt/loop_dependence.h"
#include <functional>
@@ -19,6 +25,7 @@
#include <string>
#include <utility>
#include <vector>
+#include <cstdlib>
#include "source/opt/instruction.h"
#include "source/opt/scalar_analysis_nodes.h"
+1
View File
@@ -22,6 +22,7 @@ include(UseCcache)
include(CMakeDependentOption) include(CMakeDependentOption)
include(CTest) include(CTest)
include(CPMUtil) include(CPMUtil)
include(OpenOrbis)
if (NOT DEFINED ARCHITECTURE) if (NOT DEFINED ARCHITECTURE)
message(FATAL_ERROR "Architecture didn't make it out of scope, did you delete DetectArchitecture.cmake?") message(FATAL_ERROR "Architecture didn't make it out of scope, did you delete DetectArchitecture.cmake?")
+4 -1
View File
@@ -18,10 +18,13 @@ if (DEFINED GIT_RELEASE)
set(BUILD_VERSION "${GIT_TAG}") set(BUILD_VERSION "${GIT_TAG}")
set(GIT_REFSPEC "${GIT_RELEASE}") set(GIT_REFSPEC "${GIT_RELEASE}")
set(IS_DEV_BUILD false) set(IS_DEV_BUILD false)
else() elseif(DEFINED GIT_COMMIT)
string(SUBSTRING ${GIT_COMMIT} 0 10 BUILD_VERSION) string(SUBSTRING ${GIT_COMMIT} 0 10 BUILD_VERSION)
set(BUILD_VERSION "${BUILD_VERSION}-${GIT_REFSPEC}") set(BUILD_VERSION "${BUILD_VERSION}-${GIT_REFSPEC}")
set(IS_DEV_BUILD true) set(IS_DEV_BUILD true)
else()
set(BUILD_VERSION "NoGitInfo")
set(IS_DEV_BUILD true)
endif() endif()
if (NIGHTLY_BUILD) if (NIGHTLY_BUILD)
+46
View File
@@ -0,0 +1,46 @@
# SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
# SPDX-License-Identifier: GPL-3.0-or-later
function(create_ps4_eboot project target content_id)
set(sce_sys_dir sce_sys)
set(sce_sys_param ${sce_sys_dir}/param.sfo)
add_custom_command(
OUTPUT "${target}.pkg"
COMMAND ${CMAKE_SYSROOT}/bin/create-fself -in=bin/${target} -out=${target}.oelf --eboot ${target}_eboot.bin
VERBATIM
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
DEPENDS ${project}
)
add_custom_target(${project}_pkg ALL DEPENDS "${target}.pkg")
endfunction()
function(create_ps4_pkg project target content_id)
set(sce_sys_dir sce_sys)
set(sce_sys_param ${sce_sys_dir}/param.sfo)
add_custom_command(
OUTPUT "${target}.pkg"
COMMAND ${CMAKE_SYSROOT}/bin/create-fself -in=bin/${target} -out=${target}.oelf --eboot ${target}_eboot.bin
COMMAND mkdir -p ${sce_sys_dir}
COMMAND ${CMAKE_SYSROOT}/bin/PkgTool.Core sfo_new ${sce_sys_param}
COMMAND ${CMAKE_SYSROOT}/bin/PkgTool.Core sfo_setentry ${sce_sys_param} APP_TYPE --type Integer --maxsize 4 --value 1
COMMAND ${CMAKE_SYSROOT}/bin/PkgTool.Core sfo_setentry ${sce_sys_param} APP_VER --type Utf8 --maxsize 8 --value 1.03
COMMAND ${CMAKE_SYSROOT}/bin/PkgTool.Core sfo_setentry ${sce_sys_param} ATTRIBUTE --type Integer --maxsize 4 --value 0
COMMAND ${CMAKE_SYSROOT}/bin/PkgTool.Core sfo_setentry ${sce_sys_param} CATEGORY --type Utf8 --maxsize 4 --value gd
COMMAND ${CMAKE_SYSROOT}/bin/PkgTool.Core sfo_setentry ${sce_sys_param} CONTENT_ID --type Utf8 --maxsize 48 --value ${content_id}
COMMAND ${CMAKE_SYSROOT}/bin/PkgTool.Core sfo_setentry ${sce_sys_param} DOWNLOAD_DATA_SIZE --type Integer --maxsize 4 --value 0
COMMAND ${CMAKE_SYSROOT}/bin/PkgTool.Core sfo_setentry ${sce_sys_param} SYSTEM_VER --type Integer --maxsize 4 --value 0
COMMAND ${CMAKE_SYSROOT}/bin/PkgTool.Core sfo_setentry ${sce_sys_param} TITLE --type Utf8 --maxsize 128 --value ${target}
COMMAND ${CMAKE_SYSROOT}/bin/PkgTool.Core sfo_setentry ${sce_sys_param} TITLE_ID --type Utf8 --maxsize 12 --value BREW00090
COMMAND ${CMAKE_SYSROOT}/bin/PkgTool.Core sfo_setentry ${sce_sys_param} VERSION --type Utf8 --maxsize 8 --value 1.03
COMMAND ${CMAKE_SYSROOT}/bin/create-gp4 -out ${target}.gp4 --content-id=${content_id} --files "${target}_eboot.bin ${sce_sys_param} sce_module/libc.prx sce_module/libSceFios2.prx"
COMMAND ${CMAKE_SYSROOT}/bin/PkgTool.Core pkg_build ${target}.gp4 .
VERBATIM
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
DEPENDS ${project}
)
add_custom_target(${project}_pkg ALL DEPENDS "${target}.pkg")
endfunction()
if (NOT DEFINED ENV{OO_PS4_TOOLCHAIN})
set(ENV{OO_PS4_TOOLCHAIN} ${CMAKE_SYSROOT})
endif ()
+20 -6
View File
@@ -12,7 +12,8 @@
"min_version": "1.57", "min_version": "1.57",
"package": "Boost", "package": "Boost",
"patches": [ "patches": [
"0001-clang-cl.patch" "0001-clang-cl.patch",
"0004-openorbis.patch"
], ],
"repo": "boostorg/boost", "repo": "boostorg/boost",
"version": "boost-1.90.0" "version": "boost-1.90.0"
@@ -70,12 +71,18 @@
"hash": "a0d2fa8c957704dd49e00a726284ac5ca034b50b00d2b20a94fa1bbfbb80841467834bfdc84aa0ed0d6aab894608fd6c86c3b94eee46343f0e6d9c22e391dbf9", "hash": "a0d2fa8c957704dd49e00a726284ac5ca034b50b00d2b20a94fa1bbfbb80841467834bfdc84aa0ed0d6aab894608fd6c86c3b94eee46343f0e6d9c22e391dbf9",
"min_version": "1.3", "min_version": "1.3",
"repo": "lsalzman/enet", "repo": "lsalzman/enet",
"version": "v1.3.18" "version": "v1.3.18",
"patches": [
"0001-openorbis.patch"
]
}, },
"ffmpeg": { "ffmpeg": {
"hash": "ed177621176b3961bdcaa339187d3a7688c1c8b060b79c4bb0257cbc67ad7021ae5d5adca5303b45625abbbe3d9aafdd87ce777b8690ac295290d744c875489a", "hash": "ed177621176b3961bdcaa339187d3a7688c1c8b060b79c4bb0257cbc67ad7021ae5d5adca5303b45625abbbe3d9aafdd87ce777b8690ac295290d744c875489a",
"repo": "FFmpeg/FFmpeg", "repo": "FFmpeg/FFmpeg",
"version": "c7b5f1537d" "version": "c7b5f1537d",
"patches": [
"0001-sysctl-openorbis.patch"
]
}, },
"ffmpeg-ci": { "ffmpeg-ci": {
"ci": true, "ci": true,
@@ -190,7 +197,8 @@
"min_version": "3.0.0", "min_version": "3.0.0",
"package": "OpenSSL", "package": "OpenSSL",
"patches": [ "patches": [
"0001-add-bundled-cert.patch" "0001-add-bundled-cert.patch",
"0002-fix-gnu-openorbis.patch"
], ],
"repo": "openssl/openssl", "repo": "openssl/openssl",
"version": "openssl-3.6.2" "version": "openssl-3.6.2"
@@ -213,7 +221,9 @@
"0001-cpmutil-compat.patch", "0001-cpmutil-compat.patch",
"0002-use-ccache.patch", "0002-use-ccache.patch",
"0003-use-cmake-compiler-flags.patch", "0003-use-cmake-compiler-flags.patch",
"0004-use-shell-wrapper.patch" "0004-use-shell-wrapper.patch",
"0005-wasm-support.patch",
"0006-openorbis-prefix.patch"
], ],
"repo": "jimmy-park/openssl-cmake", "repo": "jimmy-park/openssl-cmake",
"version": "3.6.2" "version": "3.6.2"
@@ -251,7 +261,11 @@
"min_version": "3.2.10", "min_version": "3.2.10",
"package": "SDL3", "package": "SDL3",
"repo": "libsdl-org/SDL", "repo": "libsdl-org/SDL",
"version": "release-3.4.8" "version": "release-3.4.8",
"patches": [
"0001-ps4.patch",
"0002-ps4-drivers.patch"
]
}, },
"sdl3-ci": { "sdl3-ci": {
"ci": true, "ci": true,
+215
View File
@@ -0,0 +1,215 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
width="512"
height="512"
fill="none"
viewBox="0 0 512 512"
version="1.1"
id="svg7"
sodipodi:docname="ps4.svg"
inkscape:version="1.4.2 (ebf0e940d0, 2025-05-08)"
inkscape:export-filename="base.svg.2026_01_12_14_43_47.0.svg"
inkscape:export-xdpi="96"
inkscape:export-ydpi="96"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs7">
<linearGradient
id="linearGradient5"
inkscape:collect="always">
<stop
style="stop-color:#003e74;stop-opacity:1;"
offset="0"
id="stop4" />
<stop
style="stop-color:#2ea8ff;stop-opacity:1;"
offset="1"
id="stop5" />
</linearGradient>
<linearGradient
id="linearGradient1"
inkscape:collect="always">
<stop
style="stop-color:#3579ff;stop-opacity:1;"
offset="0"
id="stop2" />
<stop
style="stop-color:#0b00ff;stop-opacity:1;"
offset="1"
id="stop3" />
</linearGradient>
<linearGradient
id="swatch37"
inkscape:swatch="solid">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop37" />
</linearGradient>
<linearGradient
id="swatch28"
inkscape:swatch="solid">
<stop
style="stop-color:#252525;stop-opacity:1;"
offset="0"
id="stop28" />
</linearGradient>
<linearGradient
id="swatch27"
inkscape:swatch="solid">
<stop
style="stop-color:#000000;stop-opacity:1;"
offset="0"
id="stop27" />
</linearGradient>
<linearGradient
id="swatch15"
inkscape:swatch="solid">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop16" />
</linearGradient>
<linearGradient
id="linearGradient14"
inkscape:swatch="gradient">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop14" />
<stop
style="stop-color:#ffffff;stop-opacity:0;"
offset="1"
id="stop15" />
</linearGradient>
<linearGradient
id="swatch9"
inkscape:swatch="solid">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop10" />
</linearGradient>
<linearGradient
id="swatch8"
inkscape:swatch="solid">
<stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="0"
id="stop9" />
</linearGradient>
<rect
x="22.627417"
y="402.76802"
width="521.34025"
height="248.94868"
id="rect24" />
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath18">
<circle
style="opacity:1;mix-blend-mode:normal;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10.8382;stroke-opacity:0.566238;paint-order:stroke fill markers"
id="circle18"
cx="-246.8315"
cy="246.8338"
inkscape:label="Circle"
r="191.89999" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath22">
<circle
style="opacity:1;mix-blend-mode:normal;fill:none;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:10.8382;stroke-opacity:0.566238;paint-order:stroke fill markers"
id="circle22"
cx="256"
cy="256"
inkscape:label="Circle"
r="191.89999" />
</clipPath>
<clipPath
clipPathUnits="userSpaceOnUse"
id="clipPath128">
<circle
style="fill:none;fill-opacity:1;stroke:#03ffff;stroke-width:0;stroke-dasharray:none;stroke-opacity:1"
id="circle128"
cx="256"
cy="256"
r="192" />
</clipPath>
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient1"
id="linearGradient3"
x1="256"
y1="64"
x2="256"
y2="448"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(1.1874952,0,0,-1.1874952,-47.370662,560.66391)" />
<linearGradient
inkscape:collect="always"
xlink:href="#linearGradient5"
id="linearGradient4"
gradientUnits="userSpaceOnUse"
gradientTransform="matrix(-1.1874952,0,0,1.1874952,560.61528,-47.345282)"
x1="256"
y1="64"
x2="256"
y2="448" />
</defs>
<sodipodi:namedview
id="namedview7"
pagecolor="#ffffff"
bordercolor="#000000"
borderopacity="0.25"
inkscape:showpageshadow="2"
inkscape:pageopacity="0.0"
inkscape:pagecheckerboard="0"
inkscape:deskcolor="#d1d1d1"
inkscape:zoom="1"
inkscape:cx="286.49999"
inkscape:cy="236.99999"
inkscape:window-width="1600"
inkscape:window-height="849"
inkscape:window-x="0"
inkscape:window-y="27"
inkscape:window-maximized="1"
inkscape:current-layer="svg7" />
<path
id="path8-7"
style="display:inline;mix-blend-mode:color;fill:url(#linearGradient3);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-dasharray:none;stroke-opacity:0.566238;paint-order:stroke fill markers"
inkscape:label="Circle"
d="m 256.62812,484.66422 a 227.99908,228.00372 0 0 1 -94.5288,-20.52182 c 17.54241,-0.96226 34.77843,-4.71825 46.2868,-10.46733 12.69502,-6.3416 25.70492,-17.24174 35.38366,-26.3736 h 36.45053 c 0.93211,0.61234 1.88758,1.23061 2.86668,1.85086 4.89722,14.18571 13.27668,38.80747 17.49933,51.23264 a 227.99908,228.00372 0 0 1 -43.9582,4.27925 z m 55.26491,-6.80041 -16.39068,-41.47736 c 6.99845,3.71973 14.6813,7.07649 22.62503,9.76921 20.75463,7.03513 39.46594,9.14022 49.31353,9.76688 a 227.99908,228.00372 0 0 1 -55.54788,21.94127 z m 58.6952,-23.72487 c -8.69086,-4.31956 -29.66977,-14.9556 -49.97917,-26.83747 h 87.23219 a 227.99908,228.00372 0 0 1 -37.25302,26.83747 z m -241.49988,-8.48659 a 227.99908,228.00372 0 0 1 -23.67337,-18.35088 h 95.80906 c -1.32304,0.72101 -2.11058,1.13186 -2.11058,1.13186 l 9.37935,10.63433 -34.47214,-6.30174 c 0,-2e-5 -10.96427,4.13624 -36.05858,11.02861 -3.09966,0.85131 -6.06162,1.45425 -8.87374,1.85782 z M 96.054184,418.52496 A 227.99908,228.00372 0 0 1 64.743277,379.80069 h 53.833883 c 16.2593,10.82121 36.03109,20.56336 55.93056,22.04797 47.50893,3.54468 62.979,-1.67459 62.979,-1.67459 0,0 -4.13964,4.3321 -13.0323,12.01204 -2.4447,2.11135 -5.46123,4.28998 -8.54904,6.33885 z m 156.603246,0 c 4.10483,-4.24043 6.54978,-7.04162 6.54978,-7.04162 0,0 3.17296,2.8621 8.63949,7.04162 z m 54.10293,0 c -19.35695,-13.88741 -22.86161,-25.14433 -22.86161,-25.14433 0,0 49.2172,17.2685 90.39112,0.28064 10.4477,-4.31055 19.37408,-9.1049 26.88099,-13.86058 h 47.3421 a 227.99908,228.00372 0 0 1 -31.31091,38.72427 z M 59.385631,371.02418 A 227.99908,228.00372 0 0 1 41.543041,332.29992 H 159.20017 c 1.30773,2.3199 2.75142,4.57103 4.34409,6.73083 12.77878,17.32895 25.06121,26.96783 33.0852,31.99343 h -27.15468 c -5.2719,-0.84 -10.81534,-1.78919 -16.40924,-2.84819 -27.04349,-5.11994 -72.845405,-20.48007 -72.845405,-20.48007 0,0 10.296355,11.13669 26.131855,23.32826 z m 238.424449,0 c 30.05703,-10.10404 47.05829,-24.07021 56.34572,-38.72426 h 117.55739 a 227.99908,228.00372 0 0 1 -17.84258,38.72426 h -40.22176 c 13.33114,-10.41219 19.38725,-18.85882 19.38725,-18.85882 0,0 -30.08919,11.11726 -59.29823,18.85882 z m -41.2585,-14.62133 c -0.90134,-0.01 -9.08983,-0.64727 -40.38179,-18.55498 -2.80164,-1.60327 -5.61377,-3.47048 -8.41452,-5.54795 h 37.53597 c 6.43727,15.58979 11.34615,24.10293 11.34615,24.10293 0,0 -0.0258,6.4e-4 -0.0858,0 z m 12.72847,-0.0418 c 0,0 -2.97304,-8.3824 -6.55675,-24.06118 h 46.48163 c -24.16151,23.08045 -39.92488,24.06123 -39.92488,24.06123 z M 38.653164,323.52341 a 227.99908,228.00372 0 0 1 -8.28,-38.72426 H 147.25331 c 0.50409,11.4347 2.40394,25.61361 7.73264,38.72426 z m 158.567726,0 c -12.80955,-11.77756 -24.77977,-26.58932 -33.71374,-38.72426 h 65.85729 c 4.01234,15.08912 8.39298,28.09557 12.44549,38.72426 z m 63.60057,0 c -2.16662,-10.57203 -4.40101,-23.55135 -6.23667,-38.72426 h 95.8253 c -7.46906,9.7857 -18.55287,23.51811 -32.62829,38.72426 z m 97.99155,0 c 5.95644,-13.69644 6.2152,-27.44278 5.00743,-38.72426 h 119.06262 a 227.99908,228.00372 0 0 1 -8.28,38.72426 z M 29.452392,276.02264 A 227.99908,228.00372 0 0 1 28.62903,256.6605 227.99908,228.00372 0 0 1 29.452392,237.29836 H 219.64878 c 2.02639,13.95226 4.61647,26.90106 7.48446,38.72428 H 157.2241 c -5.80191,-8.33616 -9.27267,-13.98815 -9.27267,-13.98815 0,0 -0.7416,5.5263 -0.8396,13.98815 z m 224.144368,0 c -1.22897,-11.76966 -2.19512,-24.70616 -2.7113,-38.72428 h 232.91837 a 227.99908,228.00372 0 0 1 0.82337,19.36214 227.99908,228.00372 0 0 1 -0.82337,19.36214 H 362.56568 c -0.39943,-2.2888 -0.8157,-4.40137 -1.19214,-6.30638 0,0 -1.52342,2.281 -4.43454,6.30638 z M 30.373164,228.52186 a 227.99908,228.00372 0 0 1 8.28,-38.72427 H 218.96921 c -1.16001,13.8461 -1.41371,26.99937 -0.37573,38.72427 z m 220.252536,0 c -0.27246,-12.17105 -0.19776,-25.09608 0.33166,-38.72427 h 223.6457 a 227.99908,228.00372 0 0 1 8.28,38.72427 z M 41.540725,181.02109 a 227.99908,228.00372 0 0 1 17.84259,-38.72427 H 225.63264 c -2.42151,12.98777 -4.45297,26.07281 -5.81919,38.72427 z m 209.892105,0 c 1.03997,-13.90922 3.42234,-26.81596 6.74692,-38.72427 h 195.69317 a 227.99908,228.00372 0 0 1 17.84258,38.72427 z M 64.740961,133.52032 A 227.99908,228.00372 0 0 1 96.051856,94.796041 H 236.06961 c -3.05987,12.287259 -6.07477,25.390049 -8.74155,38.724279 z m 196.112969,0 c 4.80192,-14.52175 10.96848,-27.42708 17.67095,-38.724279 h 138.6795 a 227.99908,228.00372 0 0 1 31.3109,38.724279 z M 105.41267,86.019537 A 227.99908,228.00372 0 0 1 254.61726,28.666053 c -3.30134,10.858112 -9.7429,31.901037 -16.31878,57.353484 z m 178.62756,0 C 299.82749,62.260898 317.24402,46.83239 326.52798,39.636692 a 227.99908,228.00372 0 0 1 81.31559,46.382845 z" />
<path
id="path8-7-2"
style="display:inline;mix-blend-mode:color;fill:url(#linearGradient4);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-dasharray:none;stroke-opacity:0.566238;paint-order:stroke fill markers"
inkscape:label="Circle"
d="m 256.61651,28.654412 a 227.99908,228.00372 0 0 1 94.5288,20.521817 C 333.6029,50.138492 316.36688,53.89448 304.85851,59.64356 292.1635,65.985164 279.15359,76.8853 269.47486,86.017162 h -36.45054 c -0.93211,-0.612343 -1.88758,-1.230613 -2.86668,-1.850865 -4.89722,-14.18571 -13.27667,-38.807461 -17.49932,-51.232639 a 227.99908,228.00372 0 0 1 43.95819,-4.279246 z m -55.26491,6.800405 16.39068,41.477366 c -6.99844,-3.719734 -14.6813,-7.076497 -22.62503,-9.769213 -20.75463,-7.035126 -39.46594,-9.140222 -49.31352,-9.766875 A 227.99908,228.00372 0 0 1 201.3516,35.454817 Z m -58.6952,23.724872 c 8.69086,4.319561 29.66977,14.955598 49.97917,26.837473 H 105.40338 A 227.99908,228.00372 0 0 1 142.6564,59.179689 Z m 241.49988,8.486589 a 227.99908,228.00372 0 0 1 23.67337,18.350884 h -95.80906 c 1.32305,-0.721011 2.11058,-1.131861 2.11058,-1.131861 l -9.37935,-10.634328 34.47215,6.30174 c 0,1.2e-5 10.96426,-4.136248 36.05857,-11.028611 3.09966,-0.851315 6.06162,-1.454254 8.87374,-1.857824 z m 33.03417,27.127388 a 227.99908,228.00372 0 0 1 31.31091,38.724274 h -53.83388 c -16.25931,-10.82121 -36.0311,-20.56336 -55.93057,-22.04797 -47.50892,-3.54468 -62.97899,1.67459 -62.97899,1.67459 0,0 4.13963,-4.3321 13.03229,-12.01204 2.4447,-2.111347 5.46123,-4.289985 8.54904,-6.338854 z m -156.60325,0 c -4.10482,4.240439 -6.54978,7.041624 -6.54978,7.041624 0,0 -3.17295,-2.862104 -8.63949,-7.041624 z m -54.10293,0 c 19.35695,13.887414 22.86161,25.144334 22.86161,25.144334 0,0 -49.2172,-17.2685 -90.39112,-0.28064 -10.4477,4.31055 -19.37408,9.1049 -26.88099,13.86058 H 64.73166 A 227.99908,228.00372 0 0 1 96.042582,94.793666 Z m 247.37474,47.500784 a 227.99908,228.00372 0 0 1 17.84257,38.72426 H 354.04446 c -1.30773,-2.3199 -2.75142,-4.57103 -4.34409,-6.73083 -12.77878,-17.32895 -25.06121,-26.96783 -33.0852,-31.99343 h 27.15468 c 5.2719,0.84 10.81534,1.78919 16.40924,2.84819 27.04349,5.11994 72.84541,20.48007 72.84541,20.48007 0,0 -10.29636,-11.13669 -26.13186,-23.32826 z m -238.42446,0 c -30.05702,10.10404 -47.05829,24.07021 -56.34572,38.72426 H 41.531435 a 227.99908,228.00372 0 0 1 17.842579,-38.72426 h 40.221767 c -13.331141,10.41219 -19.387248,18.85882 -19.387248,18.85882 0,0 30.089197,-11.11726 59.298227,-18.85882 z m 41.2585,14.62133 c 0.90134,0.009 9.08984,0.64727 40.38179,18.55498 2.80164,1.60327 5.61377,3.47048 8.41452,5.54795 h -37.53597 c -6.43727,-15.58979 -11.34615,-24.10293 -11.34615,-24.10293 0,0 0.0258,-6.4e-4 0.0859,0 z m -12.72847,0.0418 c 0,0 2.97304,8.3824 6.55675,24.06118 H 204.0397 c 24.16152,-23.08045 39.92488,-24.06123 39.92488,-24.06123 z m 230.62688,32.83764 a 227.99908,228.00372 0 0 1 8.28,38.72426 H 365.99132 c -0.50409,-11.4347 -2.40394,-25.61361 -7.73264,-38.72426 z m -158.56772,0 c 12.80955,11.77756 24.77977,26.58932 33.71374,38.72426 h -65.85729 c -4.01234,-15.08912 -8.39298,-28.09557 -12.44549,-38.72426 z m -63.60057,0 c 2.16662,10.57203 4.40101,23.55135 6.23667,38.72426 h -95.8253 c 7.46906,-9.7857 18.55287,-23.51811 32.62829,-38.72426 z m -97.99154,0 c -5.95644,13.69644 -6.21521,27.44278 -5.00743,38.72426 H 30.361558 a 227.99908,228.00372 0 0 1 8.280001,-38.72426 z m 329.3606,47.50077 a 227.99908,228.00372 0 0 1 0.82336,19.36214 227.99908,228.00372 0 0 1 -0.82336,19.36214 H 293.59585 c -2.02639,-13.95226 -4.61647,-26.90106 -7.48446,-38.72428 h 69.90914 c 5.80191,8.33616 9.27267,13.98815 9.27267,13.98815 0,0 0.74161,-5.5263 0.8396,-13.98815 z m -224.14436,0 c 1.22897,11.76966 2.19512,24.70616 2.7113,38.72428 H 29.440786 a 227.99908,228.00372 0 0 1 -0.823361,-19.36214 227.99908,228.00372 0 0 1 0.823361,-19.36214 H 150.67895 c 0.39943,2.2888 0.8157,4.40137 1.19214,6.30638 0,0 1.52343,-2.281 4.43455,-6.30638 z m 223.22359,47.50078 a 227.99908,228.00372 0 0 1 -8.28,38.72427 H 294.27542 c 1.16002,-13.8461 1.41371,-26.99937 0.37574,-38.72427 z m -220.25252,0 c 0.27245,12.17105 0.19775,25.09608 -0.33167,38.72427 H 38.641559 a 227.99908,228.00372 0 0 1 -8.280001,-38.72427 z m 209.08496,47.50077 a 227.99908,228.00372 0 0 1 -17.84258,38.72427 H 287.61199 c 2.42151,-12.98777 4.45297,-26.07281 5.81919,-38.72427 z m -209.89209,0 c -1.03998,13.90921 -3.42235,26.81596 -6.74692,38.72427 H 59.371698 A 227.99908,228.00372 0 0 1 41.52912,332.29754 Z m 186.69187,47.50077 a 227.99908,228.00372 0 0 1 -31.3109,38.72428 H 277.17503 c 3.05986,-12.28726 6.07476,-25.39005 8.74154,-38.72428 z m -196.11297,0 c -4.80193,14.52175 -10.96849,27.42708 -17.67095,38.72428 H 96.040255 A 227.99908,228.00372 0 0 1 64.729344,379.79831 Z m 155.44125,47.50078 a 227.99908,228.00372 0 0 1 -149.20459,57.35348 c 3.30135,-10.85811 9.7429,-31.90104 16.31879,-57.35348 z m -178.62756,0 c -15.78726,23.75863 -33.20379,39.18714 -42.48775,46.38284 a 227.99908,228.00372 0 0 1 -81.31558,-46.38284 z" />
<ellipse
style="fill:none;fill-opacity:0.679924;stroke:#97f0e5;stroke-width:17.5749;stroke-dasharray:none;stroke-opacity:1"
id="path192"
cx="88.20919"
cy="216.80666"
rx="43.306744"
ry="42.75507" />
<path
style="fill:none;fill-opacity:0.679924;stroke:#97f0e5;stroke-width:17.5749;stroke-dasharray:none;stroke-opacity:1"
d="M 211.35225,346.71976 151.38374,303.96994 137.1338,384.12586 Z"
id="path195" />
<path
id="path196-7"
style="fill:none;fill-opacity:0.679924;stroke:#97f0e5;stroke-width:17.5749;stroke-dasharray:none;stroke-opacity:1"
d="m 309.50171,362.30735 86.0678,57.93833 m -75.48269,11.93227 57.93833,-86.0678" />
<rect
style="fill:none;fill-opacity:0.679924;stroke:#97f0e5;stroke-width:13.9781;stroke-dasharray:none;stroke-opacity:1"
id="rect197"
width="66.112526"
height="59.501274"
x="93.831078"
y="-503.61469"
transform="rotate(108)" />
</svg>

After

Width:  |  Height:  |  Size: 16 KiB

+12
View File
@@ -12,6 +12,7 @@
- [NetBSD](#netbsd) - [NetBSD](#netbsd)
- [MSYS2](#msys2) - [MSYS2](#msys2)
- [RedoxOS](#redoxos) - [RedoxOS](#redoxos)
- [PlayStation 4](#playstation-4)
- [Windows](#windows) - [Windows](#windows)
- [Windows 7, Windows 8 and Windows 8.1](#windows-7-windows-8-and-windows-81) - [Windows 7, Windows 8 and Windows 8.1](#windows-7-windows-8-and-windows-81)
- [Windows Vista and below](#windows-vista-and-below) - [Windows Vista and below](#windows-vista-and-below)
@@ -245,6 +246,17 @@ The package install may randomly hang at times, in which case it has to be resta
When CMake invokes certain file syscalls - it may sometimes cause crashes or corruptions on the (kernel?) address space - so reboot the system if there is a "hang" in CMake. When CMake invokes certain file syscalls - it may sometimes cause crashes or corruptions on the (kernel?) address space - so reboot the system if there is a "hang" in CMake.
## PlayStation 4
```sh
export OO_PS4_TOOLCHAIN="$HOME/OpenOrbis/PS4Toolchain/prefix"
export DOTNET_SYSTEM_GLOBALIZATION_INVARIANT=1
```
```sh
cp $OO_PS4_TOOLCHAIN/include/endian.h $OO_PS4_TOOLCHAIN/include/sys/endian.h
```
## Windows ## Windows
### Windows 7, Windows 8 and Windows 8.1 ### Windows 7, Windows 8 and Windows 8.1
+1
View File
@@ -35,6 +35,7 @@ Eden will store configuration files in the following directories:
- **Android**: Data is stored internally. - **Android**: Data is stored internally.
- **Linux, macOS, FreeBSD, Solaris, OpenBSD**: `$XDG_DATA_HOME`, `$XDG_CACHE_HOME`, `$XDG_CONFIG_HOME`. - **Linux, macOS, FreeBSD, Solaris, OpenBSD**: `$XDG_DATA_HOME`, `$XDG_CACHE_HOME`, `$XDG_CONFIG_HOME`.
- **HaikuOS**: `/boot/home/config/settings/eden` - **HaikuOS**: `/boot/home/config/settings/eden`
- **PlayStation 4**: `/data/eden`
If a `user` directory is present in the current working directory, that will override all global configuration directories and the emulator will use that instead. If a `user` directory is present in the current working directory, that will override all global configuration directories and the emulator will use that instead.
+5
View File
@@ -260,6 +260,11 @@ target_include_directories(tz PUBLIC ./tz)
add_library(bc_decoder bc_decoder/bc_decoder.cpp) add_library(bc_decoder bc_decoder/bc_decoder.cpp)
target_include_directories(bc_decoder PUBLIC ./bc_decoder) target_include_directories(bc_decoder PUBLIC ./bc_decoder)
if (OPENORBIS)
add_library(ps4sup ps4sup/emutls.c ps4sup/stub.cpp)
target_include_directories(ps4sup PUBLIC ./ps4sup)
endif()
if (NOT TARGET RenderDoc::API) if (NOT TARGET RenderDoc::API)
add_library(renderdoc INTERFACE) add_library(renderdoc INTERFACE)
target_include_directories(renderdoc SYSTEM INTERFACE ./renderdoc) target_include_directories(renderdoc SYSTEM INTERFACE ./renderdoc)
+184
View File
@@ -0,0 +1,184 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
/* ===---------- emutls.c - Implements __emutls_get_address ---------------===
*
* The LLVM Compiler Infrastructure
*
* This file is dual licensed under the MIT and the University of Illinois Open
* Source Licenses. See LICENSE.TXT for details.
*
* ===----------------------------------------------------------------------===
*/
#include <pthread.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
//#include "int_util.h"
/* Default is not to use posix_memalign, so systems like Android
* can use thread local data without heavier POSIX memory allocators.
*/
#ifndef EMUTLS_USE_POSIX_MEMALIGN
#define EMUTLS_USE_POSIX_MEMALIGN 0
#endif
/* For every TLS variable xyz,
* there is one __emutls_control variable named __emutls_v.xyz.
* If xyz has non-zero initial value, __emutls_v.xyz's "value"
* will point to __emutls_t.xyz, which has the initial value.
*/
typedef struct __emutls_control {
size_t size; /* size of the object in bytes */
size_t align; /* alignment of the object in bytes */
union {
uintptr_t index; /* data[index-1] is the object address */
void* address; /* object address, when in single thread env */
} object;
void* value; /* null or non-zero initial value for the object */
} __emutls_control;
static inline void* emutls_memalign_alloc(size_t align, size_t size) {
void *base;
#if EMUTLS_USE_POSIX_MEMALIGN
if (posix_memalign(&base, align, size) != 0)
abort();
#else
#define EXTRA_ALIGN_PTR_BYTES (align - 1 + sizeof(void*))
char* object;
if ((object = malloc(EXTRA_ALIGN_PTR_BYTES + size)) == NULL)
abort();
base = (void*)(((uintptr_t)(object + EXTRA_ALIGN_PTR_BYTES))
& ~(uintptr_t)(align - 1));
((void**)base)[-1] = object;
#endif
return base;
}
static inline void emutls_memalign_free(void* base) {
#if EMUTLS_USE_POSIX_MEMALIGN
free(base);
#else
/* The mallocated address is in ((void**)base)[-1] */
free(((void**)base)[-1]);
#endif
}
/* Emulated TLS objects are always allocated at run-time. */
static inline void* emutls_allocate_object(__emutls_control* control) {
/* Use standard C types, check with gcc's emutls.o. */
//typedef unsigned int gcc_word __attribute__((mode(word)));
//typedef unsigned int gcc_pointer __attribute__((mode(pointer)));
//COMPILE_TIME_ASSERT(sizeof(size_t) == sizeof(gcc_word));
//COMPILE_TIME_ASSERT(sizeof(uintptr_t) == sizeof(gcc_pointer));
//COMPILE_TIME_ASSERT(sizeof(uintptr_t) == sizeof(void*));
size_t size = control->size;
size_t align = control->align;
if (align < sizeof(void*))
align = sizeof(void*);
/* Make sure that align is power of 2. */
if ((align & (align - 1)) != 0)
abort();
void* base = emutls_memalign_alloc(align, size);
if (control->value)
memcpy(base, control->value, size);
else
memset(base, 0, size);
return base;
}
static pthread_mutex_t emutls_mutex = PTHREAD_MUTEX_INITIALIZER;
static size_t emutls_num_object = 0; /* number of allocated TLS objects */
typedef struct emutls_address_array {
uintptr_t size; /* number of elements in the 'data' array */
void* data[];
} emutls_address_array;
static pthread_key_t emutls_pthread_key;
static void emutls_key_destructor(void* ptr) {
emutls_address_array* array = (emutls_address_array*)ptr;
uintptr_t i;
for (i = 0; i < array->size; ++i) {
if (array->data[i])
emutls_memalign_free(array->data[i]);
}
free(ptr);
}
static void emutls_init(void) {
if (pthread_key_create(&emutls_pthread_key, emutls_key_destructor) != 0)
abort();
}
/* Returns control->object.index; set index if not allocated yet. */
static inline uintptr_t emutls_get_index(__emutls_control* control) {
uintptr_t index = __atomic_load_n(&control->object.index, __ATOMIC_ACQUIRE);
if (!index) {
static pthread_once_t once = PTHREAD_ONCE_INIT;
pthread_once(&once, emutls_init);
pthread_mutex_lock(&emutls_mutex);
index = control->object.index;
if (!index) {
index = ++emutls_num_object;
__atomic_store_n(&control->object.index, index, __ATOMIC_RELEASE);
}
pthread_mutex_unlock(&emutls_mutex);
}
return index;
}
/* Updates newly allocated thread local emutls_address_array. */
static inline void emutls_check_array_set_size(emutls_address_array* array,
uintptr_t size) {
if (array == NULL)
abort();
array->size = size;
pthread_setspecific(emutls_pthread_key, (void*)array);
}
/* Returns the new 'data' array size, number of elements,
* which must be no smaller than the given index.
*/
static inline uintptr_t emutls_new_data_array_size(uintptr_t index) {
/* Need to allocate emutls_address_array with one extra slot
* to store the data array size.
* Round up the emutls_address_array size to multiple of 16.
*/
return ((index + 1 + 15) & ~((uintptr_t)15)) - 1;
}
/* Returns the thread local emutls_address_array.
* Extends its size if necessary to hold address at index.
*/
static inline emutls_address_array* emutls_get_address_array(uintptr_t index) {
emutls_address_array* array = pthread_getspecific(emutls_pthread_key);
if (array == NULL) {
uintptr_t new_size = emutls_new_data_array_size(index);
array = calloc(new_size + 1, sizeof(void*));
emutls_check_array_set_size(array, new_size);
} else if (index > array->size) {
uintptr_t orig_size = array->size;
uintptr_t new_size = emutls_new_data_array_size(index);
array = realloc(array, (new_size + 1) * sizeof(void*));
if (array)
memset(array->data + orig_size, 0,
(new_size - orig_size) * sizeof(void*));
emutls_check_array_set_size(array, new_size);
}
return array;
}
void* __emutls_get_address(__emutls_control* control) {
uintptr_t index = emutls_get_index(control);
emutls_address_array* array = emutls_get_address_array(index);
if (array->data[index - 1] == NULL)
array->data[index - 1] = emutls_allocate_object(control);
return array->data[index - 1];
}
+38
View File
@@ -0,0 +1,38 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include <stdio.h>
#define STUB_WEAK(name) \
extern "C" void name() { \
printf("called " #name); \
asm volatile("ud2"); \
}
extern "C" int __pthread_cxa_finalize();
extern "C" void __cxa_thread_atexit_impl() {
//printf("__cxa_thread_atexit_impl called!\n");
//__pthread_cxa_finalize();
}
STUB_WEAK(__assert)
STUB_WEAK(ZSTD_trace_compress_begin)
STUB_WEAK(ZSTD_trace_compress_end)
STUB_WEAK(ZSTD_trace_decompress_begin)
STUB_WEAK(ZSTD_trace_decompress_end)
extern "C" thread_local struct {
char pad[512];
} _ThreadRuneLocale = {};
extern "C" struct {
char pad[512];
} __h_errno = {};
FILE* __stderrp = stdout;
FILE* __stdinp = stdin;
#undef STUB_WEAK
// THIS MAKES STD::COUT AND SUCH WORK :)
#include <iostream>
std::ios_base::Init init;
+6
View File
@@ -254,4 +254,10 @@ else()
target_compile_definitions(audio_core PRIVATE HAVE_SDL3) target_compile_definitions(audio_core PRIVATE HAVE_SDL3)
endif() endif()
if(OPENORBIS)
target_sources(audio_core PRIVATE
sink/ps4_sink.cpp
sink/ps4_sink.h)
endif()
create_target_directory_groups(audio_core) create_target_directory_groups(audio_core)
+160
View File
@@ -0,0 +1,160 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
#include <span>
#include <stop_token>
#include <vector>
#include <orbis/AudioOut.h>
#include "audio_core/common/common.h"
#include "audio_core/sink/ps4_sink.h"
#include "audio_core/sink/sink_stream.h"
#include "common/alignment.h"
#include "common/logging.h"
#include "common/scope_exit.h"
#include "core/core.h"
namespace AudioCore::Sink {
/// @brief PS4 sink stream, responsible for sinking samples to hardware.
struct PS4SinkStream final : public SinkStream {
/// @brief Create a new sink stream.
/// @param device_channels_ - Number of channels supported by the hardware.
/// @param system_channels_ - Number of channels the audio systems expect.
/// @param output_device - Name of the output device to use for this stream.
/// @param input_device - Name of the input device to use for this stream.
/// @param type_ - Type of this stream.
/// @param system_ - Core system.
/// @param event - Event used only for audio renderer, signalled on buffer consume.
PS4SinkStream(u32 device_channels_, u32 system_channels_, const std::string& output_device, const std::string& input_device, StreamType type_, Core::System& system_)
: SinkStream{system_, type_}
{
system_channels = system_channels_;
device_channels = device_channels_;
constexpr size_t PREFERRED_SAMPLE_COUNT = 1024;
auto const param = (device_channels > 1 ? ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_STEREO : ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_MONO);
audio_dev = sceAudioOutOpen(ORBIS_USER_SERVICE_USER_ID_SYSTEM, ORBIS_AUDIO_OUT_PORT_TYPE_MAIN, 0, PREFERRED_SAMPLE_COUNT, TargetSampleRate, param);
if (audio_dev > 0) {
audio_thread = std::jthread([=, this](std::stop_token stop_token) {
std::array<s16, PREFERRED_SAMPLE_COUNT * MaxChannels> buffer;
while (!stop_token.stop_requested()) {
if (this->type == StreamType::In) {
this->ProcessAudioIn(buffer, PREFERRED_SAMPLE_COUNT);
(void)buffer; // TODO: microphone support
} else {
int err = 0;
std::fill(buffer.begin(), buffer.end(), 0);
this->ProcessAudioOutAndRender(buffer, PREFERRED_SAMPLE_COUNT);
sceAudioOutOutput(audio_dev, nullptr);
if ((err = sceAudioOutOutput(audio_dev, buffer.data())) < 0)
LOG_ERROR(Service_Audio, "{}", err);
}
// Wait for pause, we don't really have a native pause
// so this is the best i can do
while (paused && !stop_token.stop_requested())
asm volatile ("pause"); //dont shootup cpu usage to 100%
}
sceAudioOutClose(audio_dev);
});
} else {
LOG_ERROR(Service_Audio, "Failed to create audio device! {:#x}", uint32_t(audio_dev));
}
}
~PS4SinkStream() override {
LOG_DEBUG(Service_Audio, "Destroying PS4 stream {}", name);
if (audio_thread.joinable()) {
audio_thread.request_stop();
audio_thread.join();
}
}
void Finalize() override {
if (audio_dev > 0) {
}
}
void Start(bool resume = false) override {
if (audio_dev > 0 && paused) {
paused = false;
}
}
void Stop() override {
if (audio_dev > 0 && !paused) {
SignalPause();
}
}
std::jthread audio_thread;
int32_t audio_dev{};
};
PS4Sink::PS4Sink(std::string_view target_device_name) {
int32_t rc = sceAudioOutInit();
if (rc == 0 || unsigned(rc) == ORBIS_AUDIO_OUT_ERROR_ALREADY_INIT) {
if (target_device_name != auto_device_name && !target_device_name.empty()) {
output_device = target_device_name;
} else {
output_device.clear();
}
device_channels = 2;
} else {
LOG_ERROR(Service_Audio, "Unable to open audio out! {:#x}", uint32_t(rc));
}
}
PS4Sink::~PS4Sink() = default;
/// @brief Create a new sink stream.
/// @param system - Core system.
/// @param system_channels - Number of channels the audio system expects. May differ from the device's channel count.
/// @param name - Name of this stream.
/// @param type - Type of this stream, render/in/out.
/// @return A pointer to the created SinkStream
SinkStream* PS4Sink::AcquireSinkStream(Core::System& system, u32 system_channels_, const std::string&, StreamType type) {
system_channels = system_channels_;
SinkStreamPtr& stream = sink_streams.emplace_back(std::make_unique<PS4SinkStream>(device_channels, system_channels, output_device, input_device, type, system));
return stream.get();
}
void PS4Sink::CloseStream(SinkStream* stream) {
for (size_t i = 0; i < sink_streams.size(); i++) {
if (sink_streams[i].get() == stream) {
sink_streams[i].reset();
sink_streams.erase(sink_streams.begin() + i);
break;
}
}
}
void PS4Sink::CloseStreams() {
sink_streams.clear();
}
f32 PS4Sink::GetDeviceVolume() const {
return sink_streams.size() > 0 ? sink_streams[0]->GetDeviceVolume() : 1.f;
}
void PS4Sink::SetDeviceVolume(f32 volume) {
for (auto& stream : sink_streams)
stream->SetDeviceVolume(volume);
}
void PS4Sink::SetSystemVolume(f32 volume) {
for (auto& stream : sink_streams)
stream->SetSystemVolume(volume);
}
std::vector<std::string> ListPS4SinkDevices(bool capture) {
return {{"Default"}};
}
u32 GetPS4Latency() {
return TargetSampleCount;
}
} // namespace AudioCore::Sink
+43
View File
@@ -0,0 +1,43 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2018 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#pragma once
#include <string>
#include <vector>
#include "audio_core/sink/sink.h"
namespace Core {
class System;
}
namespace AudioCore::Sink {
class SinkStream;
/// @brief PS4 backend sink, holds multiple output streams and is responsible for sinking samples to
/// hardware. Used by Audio Render, Audio In and Audio Out.
struct PS4Sink final : public Sink {
explicit PS4Sink(std::string_view device_id);
~PS4Sink() override;
SinkStream* AcquireSinkStream(Core::System& system, u32 system_channels, const std::string& name, StreamType type) override;
void CloseStream(SinkStream* stream) override;
void CloseStreams() override;
f32 GetDeviceVolume() const override;
void SetDeviceVolume(f32 volume) override;
void SetSystemVolume(f32 volume) override;
/// Name of the output device used by streams
std::string output_device;
/// Name of the input device used by streams
std::string input_device;
/// Vector of streams managed by this sink
std::vector<SinkStreamPtr> sink_streams;
};
std::vector<std::string> ListPS4SinkDevices(bool capture);
u32 GetPS4Latency();
} // namespace AudioCore::Sink
+28 -27
View File
@@ -19,6 +19,23 @@
namespace AudioCore::Sink { namespace AudioCore::Sink {
namespace { namespace {
[[nodiscard]] bool InitializeAudio() {
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
// See https://github.com/PCSX2/pcsx2/pull/12312
// "SDL and cubeb backends previously resulted in different names for the output which
// caused them be identified as different applications by the OS."
//
// Keep in sync with cubeb_sink.cpp name.
SDL_SetHint("SDL_AUDIO_DEVICE_APP_NAME", "yuzu Latency Getter");
if (!SDL_InitSubSystem(SDL_INIT_AUDIO)) {
LOG_CRITICAL(Audio_Sink, "SDL_InitSubSystem audio failed: {}", SDL_GetError());
return false;
}
}
return true;
}
SDL_AudioDeviceID FindAudioDeviceByName(const std::string& device_name, bool capture) { SDL_AudioDeviceID FindAudioDeviceByName(const std::string& device_name, bool capture) {
int device_count = 0; int device_count = 0;
SDL_AudioDeviceID* devices = capture ? SDL_GetAudioRecordingDevices(&device_count) SDL_AudioDeviceID* devices = capture ? SDL_GetAudioRecordingDevices(&device_count)
@@ -204,20 +221,14 @@ private:
}; };
SDLSink::SDLSink(std::string_view target_device_name) { SDLSink::SDLSink(std::string_view target_device_name) {
if (!SDL_WasInit(SDL_INIT_AUDIO)) { if (InitializeAudio()) {
if (!SDL_InitSubSystem(SDL_INIT_AUDIO)) { if (target_device_name != auto_device_name && !target_device_name.empty()) {
LOG_CRITICAL(Audio_Sink, "SDL_InitSubSystem audio failed: {}", SDL_GetError()); output_device = target_device_name;
return; } else {
output_device.clear();
} }
device_channels = 2;
} }
if (target_device_name != auto_device_name && !target_device_name.empty()) {
output_device = target_device_name;
} else {
output_device.clear();
}
device_channels = 2;
} }
SDLSink::~SDLSink() = default; SDLSink::~SDLSink() = default;
@@ -265,15 +276,10 @@ void SDLSink::SetSystemVolume(f32 volume) {
} }
std::vector<std::string> ListSDLSinkDevices(bool capture) { std::vector<std::string> ListSDLSinkDevices(bool capture) {
if (!InitializeAudio())
return {}; //no devices
std::vector<std::string> device_list; std::vector<std::string> device_list;
if (!SDL_WasInit(SDL_INIT_AUDIO)) {
if (!SDL_InitSubSystem(SDL_INIT_AUDIO)) {
LOG_CRITICAL(Audio_Sink, "SDL_InitSubSystem audio failed: {}", SDL_GetError());
return {};
}
}
int device_count = 0; int device_count = 0;
SDL_AudioDeviceID* devices = SDL_AudioDeviceID* devices =
capture ? SDL_GetAudioRecordingDevices(&device_count) capture ? SDL_GetAudioRecordingDevices(&device_count)
@@ -304,13 +310,8 @@ bool IsSDLSuitable() {
return false; return false;
#else #else
// Check SDL can init // Check SDL can init
if (!SDL_WasInit(SDL_INIT_AUDIO)) { if (!InitializeAudio()!
if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) { return false;
LOG_ERROR(Audio_Sink, "SDL failed to init, it is not suitable. Error: {}",
SDL_GetError());
return false;
}
}
// We can set any latency frequency we want with SDL, so no need to check that. // We can set any latency frequency we want with SDL, so no need to check that.
+16 -1
View File
@@ -19,6 +19,9 @@
#ifdef HAVE_SDL3 #ifdef HAVE_SDL3
#include "audio_core/sink/sdl3_sink.h" #include "audio_core/sink/sdl3_sink.h"
#endif #endif
#ifdef __OPENORBIS__
#include "audio_core/sink/ps4_sink.h"
#endif
#include "audio_core/sink/null_sink.h" #include "audio_core/sink/null_sink.h"
#include "common/logging.h" #include "common/logging.h"
#include "common/settings_enums.h" #include "common/settings_enums.h"
@@ -51,6 +54,16 @@ struct SinkDetails {
// sink_details is ordered in terms of desirability, with the best choice at the top. // sink_details is ordered in terms of desirability, with the best choice at the top.
constexpr SinkDetails sink_details[] = { constexpr SinkDetails sink_details[] = {
#ifdef __OPENORBIS__
SinkDetails{
Settings::AudioEngine::Ps4,
[](std::string_view device_id) -> std::unique_ptr<Sink> {
return std::make_unique<PS4Sink>(device_id);
},
&ListPS4SinkDevices,
&GetPS4Latency,
},
#endif
#ifdef HAVE_OBOE #ifdef HAVE_OBOE
SinkDetails{ SinkDetails{
Settings::AudioEngine::Oboe, Settings::AudioEngine::Oboe,
@@ -115,7 +128,9 @@ const SinkDetails& GetOutputSinkDetails(Settings::AudioEngine sink_id) {
// BEGIN REINTRODUCED FROM 3833 - REPLACED CODE BLOCK ABOVE - DIABLO 3 FIX // BEGIN REINTRODUCED FROM 3833 - REPLACED CODE BLOCK ABOVE - DIABLO 3 FIX
// Auto-select a backend. Prefer CubeB, but it may report a large minimum latency which // Auto-select a backend. Prefer CubeB, but it may report a large minimum latency which
// causes audio issues, in that case go with SDL. // causes audio issues, in that case go with SDL.
#if defined(HAVE_CUBEB) && defined(HAVE_SDL3) #if defined(__OPENORBIS__)
iter = find_backend(Settings::AudioEngine::Ps4);
#elif defined(HAVE_CUBEB) && defined(HAVE_SDL3)
iter = find_backend(Settings::AudioEngine::Cubeb); iter = find_backend(Settings::AudioEngine::Cubeb);
if (iter->latency() > TargetSampleCount * 3) { if (iter->latency() > TargetSampleCount * 3) {
iter = find_backend(Settings::AudioEngine::Sdl3); iter = find_backend(Settings::AudioEngine::Sdl3);
+1
View File
@@ -229,6 +229,7 @@ if(CXX_CLANG)
$<$<VERSION_LESS:$<CXX_COMPILER_VERSION>,15>:CANNOT_EXPLICITLY_INSTANTIATE>) $<$<VERSION_LESS:$<CXX_COMPILER_VERSION>,15>:CANNOT_EXPLICITLY_INSTANTIATE>)
endif() endif()
# Has to be BEFORE httplib
if (BOOST_NO_HEADERS) if (BOOST_NO_HEADERS)
target_link_libraries(common PUBLIC Boost::algorithm Boost::heap Boost::icl Boost::pool) target_link_libraries(common PUBLIC Boost::algorithm Boost::heap Boost::icl Boost::pool)
else() else()
+12 -10
View File
@@ -20,6 +20,9 @@
#else #else
#include <unistd.h> #include <unistd.h>
#endif #endif
#ifdef __OPENORBIS__
#include <sys/stat.h>
#endif
#ifdef _MSC_VER #ifdef _MSC_VER
#define fileno _fileno #define fileno _fileno
@@ -402,28 +405,27 @@ u64 IOFile::GetSize() const {
file_size = Android::GetSize(file_path); file_size = Android::GetSize(file_path);
} else { } else {
std::error_code ec; std::error_code ec;
file_size = fs::file_size(file_path, ec); file_size = fs::file_size(file_path, ec);
if (ec) { if (ec) {
LOG_ERROR(Common_Filesystem, LOG_ERROR(Common_Filesystem, "Failed to retrieve the file size of path={}, ec_message={}", PathToUTF8String(file_path), ec.message());
"Failed to retrieve the file size of path={}, ec_message={}",
PathToUTF8String(file_path), ec.message());
return 0; return 0;
} }
} }
#elif defined(__OPENORBIS__)
// TODO: implementation of fs::file_size() is buggy on PS4, why?
// probably toolchain issue... ugh
OrbisKernelStat st{};
stat(file_path.c_str(), reinterpret_cast<struct stat *>(std::addressof(st)));
auto const file_size = st.st_size;
LOG_DEBUG(Common_Filesystem, "size for {} = {}", file_path.c_str(), file_size);
#else #else
std::error_code ec; std::error_code ec;
const auto file_size = fs::file_size(file_path, ec); const auto file_size = fs::file_size(file_path, ec);
if (ec) { if (ec) {
LOG_ERROR(Common_Filesystem, "Failed to retrieve the file size of path={}, ec_message={}", LOG_ERROR(Common_Filesystem, "Failed to retrieve the file size of path={}, ec_message={}", PathToUTF8String(file_path), ec.message());
PathToUTF8String(file_path), ec.message());
return 0; return 0;
} }
#endif #endif
return file_size; return file_size;
} }
+3
View File
@@ -174,11 +174,14 @@ bool CreateDir(const fs::path& path) {
return false; return false;
} }
// TODO: Maybe this is what causes death?
#ifndef __OPENORBIS__
if (!Exists(path.parent_path())) { if (!Exists(path.parent_path())) {
LOG_ERROR(Common_Filesystem, "Parent directory of path={} does not exist", LOG_ERROR(Common_Filesystem, "Parent directory of path={} does not exist",
PathToUTF8String(path)); PathToUTF8String(path));
return false; return false;
} }
#endif
if (IsDir(path)) { if (IsDir(path)) {
LOG_DEBUG(Common_Filesystem, "Filesystem object at path={} exists and is a directory", LOG_DEBUG(Common_Filesystem, "Filesystem object at path={} exists and is a directory",
+11 -12
View File
@@ -130,6 +130,10 @@ public:
ASSERT(!eden_path.empty()); ASSERT(!eden_path.empty());
eden_path_cache = eden_path / CACHE_DIR; eden_path_cache = eden_path / CACHE_DIR;
eden_path_config = eden_path / CONFIG_DIR; eden_path_config = eden_path / CONFIG_DIR;
#elif defined(__OPENORBIS__)
eden_path = "/data/eden";
eden_path_cache = eden_path / CACHE_DIR;
eden_path_config = eden_path / CONFIG_DIR;
#else #else
eden_path = GetCurrentDir() / PORTABLE_DIR; eden_path = GetCurrentDir() / PORTABLE_DIR;
if (!Exists(eden_path) || !IsDir(eden_path)) { if (!Exists(eden_path) || !IsDir(eden_path)) {
@@ -172,12 +176,11 @@ public:
GenerateEdenPath(EdenPath::ShaderDir, eden_path_cache / SHADER_DIR); GenerateEdenPath(EdenPath::ShaderDir, eden_path_cache / SHADER_DIR);
#ifdef _WIN32 #ifdef _WIN32
GenerateLegacyPath(EmuPath::RyujinxDir, GetAppDataRoamingDirectory() / RYUJINX_DIR); GenerateLegacyPath(EmuPath::RyujinxDir, GetAppDataRoamingDirectory() / RYUJINX_DIR);
#else #elif !defined(__OPENORBIS__)
// In Ryujinx's infinite wisdom, it places EVERYTHING in the config directory on UNIX // In Ryujinx's infinite wisdom, it places EVERYTHING in the config directory on UNIX
// This is incredibly stupid and violates a million XDG standards, but whatever // This is incredibly stupid and violates a million XDG standards, but whatever
GenerateLegacyPath(EmuPath::RyujinxDir, GetDataDirectory("XDG_CONFIG_HOME") / RYUJINX_DIR); GenerateLegacyPath(EmuPath::RyujinxDir, GetDataDirectory("XDG_CONFIG_HOME") / RYUJINX_DIR);
#endif #endif
} }
private: private:
@@ -339,36 +342,33 @@ fs::path GetAppDataRoamingDirectory() {
return fs_appdata_roaming_path; return fs_appdata_roaming_path;
} }
#elif defined(__OPENORBIS__)
// Not required/defined
#else #else
fs::path GetHomeDirectory() { fs::path GetHomeDirectory() {
const char* home_env_var = getenv("HOME"); const char* home_env_var = getenv("HOME");
if (home_env_var) { if (home_env_var) {
return fs::path{home_env_var}; return fs::path{home_env_var};
} }
LOG_INFO(Common_Filesystem, LOG_INFO(Common_Filesystem,
"$HOME is not defined in the environment variables, " "$HOME is not defined in the environment variables, "
"attempting to query passwd to get the home path of the current user"); "attempting to query passwd to get the home path of the current user");
const auto* pw = getpwuid(getuid()); const auto* pw = getpwuid(getuid());
if (!pw) { if (!pw) {
LOG_ERROR(Common_Filesystem, "Failed to get the home path of the current user"); LOG_ERROR(Common_Filesystem, "Failed to get the home path of the current user");
return {}; return {};
} }
return fs::path{pw->pw_dir}; return fs::path{pw->pw_dir};
} }
fs::path GetDataDirectory(const std::string& env_name) { fs::path GetDataDirectory(const std::string& env_name) {
const char* data_env_var = getenv(env_name.c_str()); const char* data_env_var = getenv(env_name.c_str());
if (data_env_var) { if (data_env_var) {
return fs::path{data_env_var}; return fs::path{data_env_var};
} }
if (env_name == "XDG_DATA_HOME") { if (env_name == "XDG_DATA_HOME") {
return GetHomeDirectory() / ".local/share"; return GetHomeDirectory() / ".local/share";
} else if (env_name == "XDG_CACHE_HOME") { } else if (env_name == "XDG_CACHE_HOME") {
@@ -376,7 +376,6 @@ fs::path GetDataDirectory(const std::string& env_name) {
} else if (env_name == "XDG_CONFIG_HOME") { } else if (env_name == "XDG_CONFIG_HOME") {
return GetHomeDirectory() / ".config"; return GetHomeDirectory() / ".config";
} }
return {}; return {};
} }
+10 -10
View File
@@ -38,15 +38,15 @@
// FreeBSD // FreeBSD
#ifndef MAP_NORESERVE #ifndef MAP_NORESERVE
#define MAP_NORESERVE 0 # define MAP_NORESERVE 0
#endif #endif
// Solaris 11 and illumos // Solaris 11 and illumos
#ifndef MAP_ALIGNED_SUPER #ifndef MAP_ALIGNED_SUPER
#define MAP_ALIGNED_SUPER 0 # define MAP_ALIGNED_SUPER 0
#endif #endif
// macOS // macOS
#ifndef MAP_ANONYMOUS #ifndef MAP_ANONYMOUS
#define MAP_ANONYMOUS MAP_ANON # define MAP_ANONYMOUS MAP_ANON
#endif #endif
#endif // ^^^ POSIX ^^^ #endif // ^^^ POSIX ^^^
@@ -441,13 +441,15 @@ static void* ChooseVirtualBase(size_t virtual_size) {
#else #else
static void* ChooseVirtualBase(size_t virtual_size) { static void* ChooseVirtualBase(size_t size) {
#if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) || defined(__sun__) || defined(__HAIKU__) || defined(__managarm__) || defined(__AIX__) #if defined(__FreeBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) || defined(__sun__) || defined(__HAIKU__) || defined(__managarm__) || defined(__AIX__)
void* virtual_base = mmap(nullptr, virtual_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE | MAP_ALIGNED_SUPER, -1, 0); void* virtual_base = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE | MAP_ALIGNED_SUPER, -1, 0);
if (virtual_base != MAP_FAILED) if (virtual_base != MAP_FAILED)
return virtual_base; return virtual_base;
return mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
#else
return mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
#endif #endif
return mmap(nullptr, virtual_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0);
} }
#endif #endif
@@ -729,9 +731,8 @@ void HostMemory::Map(size_t virtual_offset, size_t host_offset, size_t length, M
ASSERT(length % PageAlignment == 0); ASSERT(length % PageAlignment == 0);
ASSERT(virtual_offset + length <= virtual_size); ASSERT(virtual_offset + length <= virtual_size);
ASSERT(host_offset + length <= backing_size); ASSERT(host_offset + length <= backing_size);
if (length == 0 || !virtual_base || !impl) { if (length == 0 || !virtual_base || !impl)
return; return;
}
impl->Map(virtual_offset + virtual_base_offset, host_offset, length, perms); impl->Map(virtual_offset + virtual_base_offset, host_offset, length, perms);
#endif #endif
} }
@@ -741,9 +742,8 @@ void HostMemory::Unmap(size_t virtual_offset, size_t length, bool separate_heap)
ASSERT(virtual_offset % PageAlignment == 0); ASSERT(virtual_offset % PageAlignment == 0);
ASSERT(length % PageAlignment == 0); ASSERT(length % PageAlignment == 0);
ASSERT(virtual_offset + length <= virtual_size); ASSERT(virtual_offset + length <= virtual_size);
if (length == 0 || !virtual_base || !impl) { if (length == 0 || !virtual_base || !impl)
return; return;
}
impl->Unmap(virtual_offset + virtual_base_offset, length); impl->Unmap(virtual_offset + virtual_base_offset, length);
#endif #endif
} }
+2 -3
View File
@@ -74,14 +74,13 @@ public:
} }
private: private:
size_t backing_size{};
size_t virtual_size{};
#if !(defined(__OPENORBIS__) || defined(__managarm__)) #if !(defined(__OPENORBIS__) || defined(__managarm__))
// Low level handler for the platform dependent memory routines // Low level handler for the platform dependent memory routines
class Impl; class Impl;
std::unique_ptr<Impl> impl; std::unique_ptr<Impl> impl;
#endif #endif
size_t backing_size{};
size_t virtual_size{};
u8* backing_base{}; u8* backing_base{};
u8* virtual_base{}; u8* virtual_base{};
size_t virtual_base_offset{}; size_t virtual_base_offset{};
+6
View File
@@ -3,8 +3,14 @@
#pragma once #pragma once
// TODO: httplib port can't use OpenSSL because of package misconfigs on OO toolchain
// right now the solution is to tell httplib that OpenSSL doesn't exist, but that's bad
// and the issue is a bit more of how OpenSSL lacks some essential functionality
// which is a bit annoying to reconfigure atm.
#ifndef __OPENORBIS__
#define CPPHTTPLIB_DISABLE_MACOSX_AUTOMATIC_ROOT_CERTIFICATES 1 #define CPPHTTPLIB_DISABLE_MACOSX_AUTOMATIC_ROOT_CERTIFICATES 1
#define CPPHTTPLIB_OPENSSL_SUPPORT 1 #define CPPHTTPLIB_OPENSSL_SUPPORT 1
#endif
#ifdef __GNUC__ #ifdef __GNUC__
#pragma GCC diagnostic push #pragma GCC diagnostic push
+1 -8
View File
@@ -236,7 +236,6 @@ struct ColorConsoleBackend final : public Backend {
#endif #endif
}; };
#ifndef __OPENORBIS__
/// @brief Backend that writes to a file passed into the constructor /// @brief Backend that writes to a file passed into the constructor
struct FileBackend final : public Backend { struct FileBackend final : public Backend {
explicit FileBackend(const std::filesystem::path filename) noexcept { explicit FileBackend(const std::filesystem::path filename) noexcept {
@@ -299,7 +298,7 @@ private:
std::size_t bytes_written = 0; std::size_t bytes_written = 0;
bool enabled = true; bool enabled = true;
}; };
#endif
#ifdef _WIN32 #ifdef _WIN32
/// @brief Backend that writes to Visual Studio's output window /// @brief Backend that writes to Visual Studio's output window
struct DebuggerBackend final : public Backend { struct DebuggerBackend final : public Backend {
@@ -343,10 +342,8 @@ struct Impl {
template<typename F> template<typename F>
void ForEachBackend(F&& lambda) noexcept { void ForEachBackend(F&& lambda) noexcept {
lambda(static_cast<Backend&>(color_console_backend)); lambda(static_cast<Backend&>(color_console_backend));
#ifndef __OPENORBIS__
if (file_backend) if (file_backend)
lambda(static_cast<Backend&>(*file_backend)); lambda(static_cast<Backend&>(*file_backend));
#endif
#ifdef _WIN32 #ifdef _WIN32
lambda(static_cast<Backend&>(debugger_backend)); lambda(static_cast<Backend&>(debugger_backend));
#endif #endif
@@ -357,9 +354,7 @@ struct Impl {
Filter filter; Filter filter;
ColorConsoleBackend color_console_backend{}; ColorConsoleBackend color_console_backend{};
#ifndef __OPENORBIS__
std::optional<FileBackend> file_backend; std::optional<FileBackend> file_backend;
#endif
#ifdef _WIN32 #ifdef _WIN32
DebuggerBackend debugger_backend{}; DebuggerBackend debugger_backend{};
#endif #endif
@@ -396,12 +391,10 @@ void Initialize() {
} else { } else {
logging_instance.emplace(); logging_instance.emplace();
logging_instance->filter.ParseFilterString(Settings::values.log_filter.GetValue()); logging_instance->filter.ParseFilterString(Settings::values.log_filter.GetValue());
#ifndef __OPENORBIS__
using namespace Common::FS; using namespace Common::FS;
const auto& log_dir = GetEdenPath(EdenPath::LogDir); const auto& log_dir = GetEdenPath(EdenPath::LogDir);
void(CreateDir(log_dir)); void(CreateDir(log_dir));
logging_instance->file_backend.emplace(log_dir / LOG_FILE); logging_instance->file_backend.emplace(log_dir / LOG_FILE);
#endif
} }
} }
+4 -1
View File
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -8,7 +11,7 @@
// clang-format on // clang-format on
#else #else
#include <sys/types.h> #include <sys/types.h>
#if defined(__APPLE__) || defined(__FreeBSD__) #if defined(__APPLE__) || (defined(__FreeBSD__) && !defined(__OPENORBIS__))
#include <sys/sysctl.h> #include <sys/sysctl.h>
#elif defined(__linux__) #elif defined(__linux__)
#include <sys/sysinfo.h> #include <sys/sysinfo.h>
+1 -1
View File
@@ -213,7 +213,7 @@ std::optional<std::string> MakeRequest(const std::string& url, const std::string
client->set_read_timeout(timeout_seconds); client->set_read_timeout(timeout_seconds);
client->set_write_timeout(timeout_seconds); client->set_write_timeout(timeout_seconds);
#ifdef YUZU_BUNDLED_OPENSSL #if defined(YUZU_BUNDLED_OPENSSL) && !defined(__OPENORBIS__)
client->load_ca_cert_store(kCert, sizeof(kCert)); client->load_ca_cert_store(kCert, sizeof(kCert));
#endif #endif
+3 -6
View File
@@ -27,7 +27,7 @@
#include "common/settings.h" #include "common/settings.h"
#include "common/time_zone.h" #include "common/time_zone.h"
#if defined(__linux__ ) && defined(ARCHITECTURE_arm64) #ifdef __unix__
#include <unistd.h> #include <unistd.h>
#endif #endif
@@ -187,12 +187,9 @@ bool IsFastmemEnabled() {
return bool(values.cpuopt_fastmem); return bool(values.cpuopt_fastmem);
else if (values.cpu_accuracy.GetValue() == CpuAccuracy::Unsafe) else if (values.cpu_accuracy.GetValue() == CpuAccuracy::Unsafe)
return bool(values.cpuopt_unsafe_host_mmu); return bool(values.cpuopt_unsafe_host_mmu);
#if defined(__linux__) && defined(ARCHITECTURE_arm64) #if defined(__unix__)
// Only 4kb systems support host MMU right now // TODO: Support this since only 4kb systems support host MMU right now
// TODO: Support this
return getpagesize() == 4096; return getpagesize() == 4096;
#elif !defined(__APPLE__) && !defined(__ANDROID__) && !defined(_WIN32) && !defined(__linux__) && !defined(__FreeBSD__)
return false;
#else #else
return true; return true;
#endif #endif
+9 -2
View File
@@ -196,7 +196,14 @@ struct Values {
linkage, false, "dump_audio_commands", Category::Audio, Specialization::Default, false}; linkage, false, "dump_audio_commands", Category::Audio, Specialization::Default, false};
// Core // Core
SwitchableSetting<bool> use_multi_core{linkage, true, "use_multi_core", Category::Core}; SwitchableSetting<bool> use_multi_core{linkage,
#ifdef __OPENORBIS__
// Re-enable once proper TLS support is added
false,
#else
true,
#endif
"use_multi_core", Category::Core};
SwitchableSetting<MemoryLayout, true> memory_layout_mode{linkage, SwitchableSetting<MemoryLayout, true> memory_layout_mode{linkage,
MemoryLayout::Memory_4Gb, MemoryLayout::Memory_4Gb,
"memory_layout_mode", "memory_layout_mode",
@@ -330,7 +337,7 @@ struct Values {
// Renderer // Renderer
SwitchableSetting<RendererBackend, true> renderer_backend{linkage, SwitchableSetting<RendererBackend, true> renderer_backend{linkage,
#if defined(__sun__) || defined(__managarm__) #if defined(__sun__) || defined(__managarm__) || defined(__OPENORBIS__)
RendererBackend::OpenGL_GLSL, RendererBackend::OpenGL_GLSL,
#else #else
RendererBackend::Vulkan, RendererBackend::Vulkan,
+2 -1
View File
@@ -92,7 +92,7 @@ struct EnumMetadata {
// AudioEngine must be specified discretely due to having existing but slightly different // AudioEngine must be specified discretely due to having existing but slightly different
// canonicalizations // canonicalizations
// TODO (lat9nq): Remove explicit definition of AudioEngine/sink_id // TODO (lat9nq): Remove explicit definition of AudioEngine/sink_id
enum class AudioEngine : u32 { Auto, Cubeb, Sdl3, Null, Oboe, }; enum class AudioEngine : u32 { Auto, Cubeb, Sdl3, Null, Oboe, Ps4, };
template<> template<>
inline std::vector<std::pair<std::string_view, AudioEngine>> EnumMetadata<AudioEngine>::Canonicalizations() { inline std::vector<std::pair<std::string_view, AudioEngine>> EnumMetadata<AudioEngine>::Canonicalizations() {
return { return {
@@ -100,6 +100,7 @@ inline std::vector<std::pair<std::string_view, AudioEngine>> EnumMetadata<AudioE
{"cubeb", AudioEngine::Cubeb}, {"cubeb", AudioEngine::Cubeb},
{"sdl3", AudioEngine::Sdl3}, {"sdl3", AudioEngine::Sdl3},
{"null", AudioEngine::Null}, {"oboe", AudioEngine::Oboe}, {"null", AudioEngine::Null}, {"oboe", AudioEngine::Oboe},
{"ps4", AudioEngine::Ps4},
}; };
} }
/// @brief This is just a sufficiently large number that is more than the number of other enums declared here /// @brief This is just a sufficiently large number that is more than the number of other enums declared here
-2
View File
@@ -7,6 +7,4 @@
#define STB_IMAGE_IMPLEMENTATION 1 #define STB_IMAGE_IMPLEMENTATION 1
#define STB_IMAGE_RESIZE_IMPLEMENTATION 1 #define STB_IMAGE_RESIZE_IMPLEMENTATION 1
#define STB_IMAGE_WRITE_IMPLEMENTATION 1 #define STB_IMAGE_WRITE_IMPLEMENTATION 1
#define STBI_ONLY_JPEG 1
#include "common/stb.h" #include "common/stb.h"
+1
View File
@@ -7,6 +7,7 @@
#pragma once #pragma once
#define STBI_ONLY_JPEG 1 #define STBI_ONLY_JPEG 1
#define STBI_WRITE_NO_STDIO 1
#include <stb_image.h> #include <stb_image.h>
#include <stb_image_resize.h> #include <stb_image_resize.h>
#include <stb_image_write.h> #include <stb_image_write.h>
+172 -9
View File
@@ -10,11 +10,135 @@
#include <sys/mman.h> #include <sys/mman.h>
#endif #endif
#ifdef __OPENORBIS__
#include <ranges>
#include <csignal>
#include <fcntl.h>
#include <boost/container/static_vector.hpp>
#include <orbis/SystemService.h>
#include <orbis/libkernel.h>
typedef void (*SceKernelExceptionHandler)(int32_t, void*);
extern "C" int32_t sceKernelInstallExceptionHandler(int32_t signum, SceKernelExceptionHandler handler);
#endif
#include "common/assert.h" #include "common/assert.h"
#include "common/virtual_buffer.h" #include "common/virtual_buffer.h"
#include "common/logging.h"
// PlayStation 4
// Flag needs to be undef-ed on non PS4 since it has different semantics
// on some platforms.
#ifdef __OPENORBIS__
# ifndef MAP_SYSTEM
# define MAP_SYSTEM 0x2000
# endif
# ifndef MAP_VOID
# define MAP_VOID 0x100
# endif
// sigaction(2) has a motherfucking bug on musl where the thing isnt even properly prefixed
# undef sa_sigaction
# define sa_sigaction __sa_handler.__sa_sigaction
#endif
namespace Common { namespace Common {
#ifdef __OPENORBIS__
namespace Orbis {
constexpr size_t ORBIS_PAGE_SIZE = 16384;
struct Ucontext {
struct Sigset {
u64 bits[2];
} uc_sigmask;
int field1_0x10[12];
struct Mcontext {
u64 mc_onstack;
u64 mc_rdi;
u64 mc_rsi;
u64 mc_rdx;
u64 mc_rcx;
u64 mc_r8;
u64 mc_r9;
u64 mc_rax;
u64 mc_rbx;
u64 mc_rbp;
u64 mc_r10;
u64 mc_r11;
u64 mc_r12;
u64 mc_r13;
u64 mc_r14;
u64 mc_r15;
int mc_trapno;
u16 mc_fs;
u16 mc_gs;
u64 mc_addr;
int mc_flags;
u16 mc_es;
u16 mc_ds;
u64 mc_err;
u64 mc_rip;
u64 mc_cs;
u64 mc_rflags;
u64 mc_rsp;
u64 mc_ss;
u64 mc_len;
u64 mc_fpformat;
u64 mc_ownedfp;
u64 mc_lbrfrom;
u64 mc_lbrto;
u64 mc_aux1;
u64 mc_aux2;
u64 mc_fpstate[104];
u64 mc_fsbase;
u64 mc_gsbase;
u64 mc_spare[6];
} uc_mcontext;
struct Ucontext* uc_link;
struct ExStack {
void* ss_sp;
std::size_t ss_size;
int ss_flags;
int _align;
} uc_stack;
int uc_flags;
int __spare[4];
int field7_0x4f4[3];
};
}
static boost::container::static_vector<std::pair<void*, size_t>, 16> swap_regions;
static std::mutex evil_swap_mutex;
extern "C" int sceKernelRemoveExceptionHandler(s32 sig_num);
static void SwapHandler(int sig, void* raw_context) {
std::unique_lock lk{evil_swap_mutex};
auto& mctx = ((Orbis::Ucontext*)raw_context)->uc_mcontext;
if (auto const it = std::ranges::find_if(swap_regions, [addr = mctx.mc_addr](auto const& e) {
return uintptr_t(addr) >= uintptr_t(e.first) && uintptr_t(addr) < uintptr_t(e.first) + e.second;
}); it != swap_regions.end()) {
size_t const page_size = Orbis::ORBIS_PAGE_SIZE * 128; //128K
size_t const page_mask = ~(page_size - 1);
// should replace the existing mapping... ugh
void* aligned_addr = reinterpret_cast<void*>(uintptr_t(mctx.mc_addr) & page_mask);
void* res = mmap(aligned_addr, page_size, PROT_READ | PROT_WRITE, MAP_FIXED | MAP_ANON | MAP_PRIVATE, -1, 0);
if (res == MAP_FAILED) {
LOG_ERROR(HW_Memory, "{:#x},{} @ {}:{:#x}", mctx.mc_addr, aligned_addr, it->first, it->second);
sceKernelRemoveExceptionHandler(SIGSEGV); // to not catch the next signal
} else {
LOG_DEBUG(HW_Memory, "{:#x},{} @ {}:{:#x}", mctx.mc_addr, aligned_addr, it->first, it->second);
}
} else {
LOG_ERROR(HW_Memory, "fault in addr {:#x} at {:#x}", mctx.mc_addr, mctx.mc_rip); // print caller address
sceKernelRemoveExceptionHandler(SIGSEGV); // to not catch the next signal
}
}
void InitSwap() noexcept {
sceKernelInstallExceptionHandler(SIGSEGV, &SwapHandler);
}
#else
void InitSwap() noexcept {}
#endif
void* AllocateMemoryPages(std::size_t size) noexcept { void* AllocateMemoryPages(std::size_t size) noexcept {
#ifdef _WIN32 #ifdef _WIN32
void* base = VirtualAlloc(nullptr, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); void* base = VirtualAlloc(nullptr, size, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
@@ -22,22 +146,61 @@ void* AllocateMemoryPages(std::size_t size) noexcept {
// Probably failing to reserve is less likely than failing to commit // Probably failing to reserve is less likely than failing to commit
base = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_READWRITE); base = VirtualAlloc(nullptr, size, MEM_COMMIT, PAGE_READWRITE);
} }
#elif defined(__OPENORBIS__)
bool use_void_mem = true;
void* addr = nullptr;
if (size < 4294967296ull) {
size_t align = Orbis::ORBIS_PAGE_SIZE;
off_t offset;
int32_t res;
size = (size + align - 1) / align * align;
if ((res = sceKernelAllocateDirectMemory(0, ORBIS_KERNEL_MAIN_DMEM_SIZE, size, align, ORBIS_KERNEL_WB_ONION, &offset)) == 0) {
if ((res = sceKernelMapDirectMemory(&addr, size, ORBIS_KERNEL_PROT_CPU_READ | ORBIS_KERNEL_PROT_CPU_WRITE, 0, offset, size)) == 0) {
if ((res = sceKernelMprotect(addr, size, VM_PROT_ALL)) == 0 && addr != nullptr) {
LOG_WARNING(HW_Memory, "Using DMem for {} bytes area @ {}", size, addr);
use_void_mem = false; //Memory properly mapped
} else {
sceKernelReleaseDirectMemory(offset, size);
LOG_ERROR(HW_Memory, "{} = sceKernelMprotect({}, {})", res, offset, size);
}
} else {
sceKernelReleaseDirectMemory(offset, size);
LOG_ERROR(HW_Memory, "{} = sceKernelMapDirectMemory({}, {})", res, offset, size);
}
} else {
LOG_ERROR(HW_Memory, "{} = sceKernelAllocateDirectMemory({}, {}, {})", res, size, align, offset);
}
}
if (use_void_mem) {
addr = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_VOID | MAP_PRIVATE, -1, 0);
LOG_WARNING(HW_Memory, "Using VoidMem for {} bytes area @ {}", size, addr);
ASSERT(addr != MAP_FAILED);
swap_regions.emplace_back(addr, size);
}
#else #else
void* base = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0); void* addr = mmap(nullptr, size, PROT_READ | PROT_WRITE, MAP_ANON | MAP_PRIVATE, -1, 0);
if (base == MAP_FAILED) ASSERT(addr != MAP_FAILED);
base = nullptr;
#endif #endif
ASSERT(base); return addr;
return base;
} }
void FreeMemoryPages(void* base, [[maybe_unused]] std::size_t size) noexcept { void FreeMemoryPages(void* addr, [[maybe_unused]] std::size_t size) noexcept {
if (!base) if (!addr)
return; return;
#ifdef _WIN32 #ifdef _WIN32
ASSERT(VirtualFree(base, 0, MEM_RELEASE)); VirtualFree(addr, 0, MEM_RELEASE);
#elif defined(__OPENORBIS__)
if (auto const it = std::ranges::find_if(swap_regions, [=](auto const& e) {
return uintptr_t(addr) >= uintptr_t(e.first) && uintptr_t(addr) < uintptr_t(e.first) + e.second;
}); it != swap_regions.end()) {
int rc = munmap(addr, size);
ASSERT(rc == 0);
} else {
sceKernelCheckedReleaseDirectMemory(off_t(addr), size_t(size));
}
#else #else
ASSERT(munmap(base, size) == 0); int rc = munmap(addr, size);
ASSERT(rc == 0);
#endif #endif
} }
+1
View File
@@ -12,6 +12,7 @@ namespace Common {
void* AllocateMemoryPages(std::size_t size) noexcept; void* AllocateMemoryPages(std::size_t size) noexcept;
void FreeMemoryPages(void* base, std::size_t size) noexcept; void FreeMemoryPages(void* base, std::size_t size) noexcept;
void InitSwap() noexcept;
template <typename T> template <typename T>
class VirtualBuffer final { class VirtualBuffer final {
+3 -1
View File
@@ -199,7 +199,9 @@ void ArmDynarmic32::MakeJit(Common::PageTable* page_table) {
config.enable_cycle_counting = !m_uses_wall_clock; config.enable_cycle_counting = !m_uses_wall_clock;
// Code cache size // Code cache size
#if defined(ARCHITECTURE_arm64) || defined(__sun__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) #if defined(__OPENORBIS__)
config.code_cache_size = std::uint32_t(8_MiB);
#elif defined(ARCHITECTURE_arm64) || defined(__sun__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__)
config.code_cache_size = std::uint32_t(128_MiB); config.code_cache_size = std::uint32_t(128_MiB);
#else #else
config.code_cache_size = std::uint32_t(512_MiB); config.code_cache_size = std::uint32_t(512_MiB);
+3 -1
View File
@@ -252,7 +252,9 @@ void ArmDynarmic64::MakeJit(Common::PageTable* page_table, std::size_t address_s
config.enable_cycle_counting = !m_uses_wall_clock; config.enable_cycle_counting = !m_uses_wall_clock;
// Code cache size // Code cache size
#if defined(ARCHITECTURE_arm64) || defined(__sun__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) #if defined(__OPENORBIS__)
config.code_cache_size = std::uint32_t(8_MiB);
#elif defined(ARCHITECTURE_arm64) || defined(__sun__) || defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__)
config.code_cache_size = std::uint32_t(128_MiB); config.code_cache_size = std::uint32_t(128_MiB);
#else #else
config.code_cache_size = std::uint32_t(512_MiB); config.code_cache_size = std::uint32_t(512_MiB);
+17 -8
View File
@@ -461,8 +461,19 @@ std::vector<VirtualFile> RealVfsDirectory::GetFiles() const {
FileTimeStampRaw RealVfsDirectory::GetFileTimeStamp(std::string_view path_) const { FileTimeStampRaw RealVfsDirectory::GetFileTimeStamp(std::string_view path_) const {
const auto full_path = FS::SanitizePath(path + '/' + std::string(path_)); const auto full_path = FS::SanitizePath(path + '/' + std::string(path_));
#ifdef __OPENORBIS__
// DO NOT USE NORMAL STAT, it's bugged on OO toolchain
OrbisKernelStat st{};
const auto stat_result = stat(full_path.c_str(), reinterpret_cast<struct stat *>(std::addressof(st)));
if (stat_result != 0)
return {};
return {
.created{u64(st.st_ctime)},
.accessed{u64(st.st_atime)},
.modified{u64(st.st_mtime)},
};
#else
const auto fs_path = std::filesystem::path{FS::ToU8String(full_path)}; const auto fs_path = std::filesystem::path{FS::ToU8String(full_path)};
#ifdef _WIN32 #ifdef _WIN32
struct _stat64 file_status; struct _stat64 file_status;
const auto stat_result = _wstat64(fs_path.c_str(), &file_status); const auto stat_result = _wstat64(fs_path.c_str(), &file_status);
@@ -470,16 +481,14 @@ FileTimeStampRaw RealVfsDirectory::GetFileTimeStamp(std::string_view path_) cons
struct stat file_status; struct stat file_status;
const auto stat_result = stat(fs_path.c_str(), &file_status); const auto stat_result = stat(fs_path.c_str(), &file_status);
#endif #endif
if (stat_result != 0)
if (stat_result != 0) {
return {}; return {};
}
return { return {
.created{static_cast<u64>(file_status.st_ctime)}, .created{u64(file_status.st_ctime)},
.accessed{static_cast<u64>(file_status.st_atime)}, .accessed{u64(file_status.st_atime)},
.modified{static_cast<u64>(file_status.st_mtime)}, .modified{u64(file_status.st_mtime)},
}; };
#endif
} }
std::vector<VirtualDir> RealVfsDirectory::GetSubdirectories() const { std::vector<VirtualDir> RealVfsDirectory::GetSubdirectories() const {
@@ -324,6 +324,7 @@ Result IApplicationFunctions::NotifyRunning(Out<bool> out_became_running) {
Result IApplicationFunctions::GetPseudoDeviceId(Out<Common::UUID> out_pseudo_device_id) { Result IApplicationFunctions::GetPseudoDeviceId(Out<Common::UUID> out_pseudo_device_id) {
LOG_WARNING(Service_AM, "(stubbed)"); LOG_WARNING(Service_AM, "(stubbed)");
R_UNLESS(out_pseudo_device_id, ResultUnknown);
// This should be hashed with the device specific hash // This should be hashed with the device specific hash
// for now this will do // for now this will do
@@ -88,7 +88,7 @@ std::vector<u8> DownloadImage(const std::string& url_path, const std::filesystem
cli.set_connection_timeout(std::chrono::seconds(2)); cli.set_connection_timeout(std::chrono::seconds(2));
cli.set_read_timeout(std::chrono::seconds(2)); cli.set_read_timeout(std::chrono::seconds(2));
#ifdef YUZU_BUNDLED_OPENSSL #if defined(YUZU_BUNDLED_OPENSSL) && !defined(__OPENORBIS__)
cli.load_ca_cert_store(kCert, sizeof(kCert)); cli.load_ca_cert_store(kCert, sizeof(kCert));
#endif #endif
@@ -34,12 +34,13 @@ struct FontRegion {
// The below data is specific to shared font data dumped from Switch on f/w 2.2 // The below data is specific to shared font data dumped from Switch on f/w 2.2
// Virtual address and offsets/sizes likely will vary by dump // Virtual address and offsets/sizes likely will vary by dump
[[maybe_unused]] constexpr VAddr SHARED_FONT_MEM_VADDR{0x00000009d3016000ULL}; [[maybe_unused]] constexpr VAddr SHARED_FONT_MEM_VADDR = 0x00000009d3016000ULL;
constexpr u32 EXPECTED_RESULT{0x7f9a0218}; // What we expect the decrypted bfttf first 4 bytes to be constexpr u32 EXPECTED_RESULT = 0x7f9a0218; // What we expect the decrypted bfttf first 4 bytes to be
constexpr u32 EXPECTED_MAGIC{0x36f81a1e}; // What we expect the encrypted bfttf first 4 bytes to be constexpr u32 EXPECTED_MAGIC = 0x36f81a1e; // What we expect the encrypted bfttf first 4 bytes to be
constexpr u64 SHARED_FONT_MEM_SIZE{0x1100000}; constexpr u64 SHARED_FONT_MEM_SIZE = 0x1100000;
constexpr FontRegion EMPTY_REGION{0, 0}; constexpr FontRegion EMPTY_REGION{0, 0};
#ifndef __OPENORBIS__
static void DecryptSharedFont(const std::span<u32 const> input, std::span<u8> output, std::size_t& offset) { static void DecryptSharedFont(const std::span<u32 const> input, std::span<u8> output, std::size_t& offset) {
ASSERT(offset + (input.size() * sizeof(u32)) < SHARED_FONT_MEM_SIZE && "Shared fonts exceeds 17mb!"); ASSERT(offset + (input.size() * sizeof(u32)) < SHARED_FONT_MEM_SIZE && "Shared fonts exceeds 17mb!");
ASSERT(input[0] == EXPECTED_MAGIC && "Failed to derive key, unexpected magic number"); ASSERT(input[0] == EXPECTED_MAGIC && "Failed to derive key, unexpected magic number");
@@ -51,6 +52,7 @@ static void DecryptSharedFont(const std::span<u32 const> input, std::span<u8> ou
std::memcpy(output.data() + offset, transformed_font.data(), transformed_font.size() * sizeof(u32)); std::memcpy(output.data() + offset, transformed_font.data(), transformed_font.size() * sizeof(u32));
offset += transformed_font.size() * sizeof(u32); offset += transformed_font.size() * sizeof(u32);
} }
#endif
void DecryptSharedFontToTTF(const std::vector<u32>& input, std::vector<u8>& output) { void DecryptSharedFontToTTF(const std::vector<u32>& input, std::vector<u8>& output) {
ASSERT_MSG(input[0] == EXPECTED_MAGIC, "Failed to derive key, unexpected magic number"); ASSERT_MSG(input[0] == EXPECTED_MAGIC, "Failed to derive key, unexpected magic number");
@@ -70,7 +72,7 @@ void EncryptSharedFont(const std::vector<u32>& input, std::vector<u8>& output, s
const auto key = Common::swap32(EXPECTED_RESULT ^ EXPECTED_MAGIC); const auto key = Common::swap32(EXPECTED_RESULT ^ EXPECTED_MAGIC);
std::vector<u32> transformed_font(input.size() + 2); std::vector<u32> transformed_font(input.size() + 2);
transformed_font[0] = Common::swap32(EXPECTED_MAGIC); transformed_font[0] = Common::swap32(EXPECTED_MAGIC);
transformed_font[1] = Common::swap32(static_cast<u32>(input.size() * sizeof(u32))) ^ key; transformed_font[1] = Common::swap32(u32(input.size() * sizeof(u32))) ^ key;
std::transform(input.begin(), input.end(), transformed_font.begin() + 2, [key](u32 in) { return in ^ key; }); std::transform(input.begin(), input.end(), transformed_font.begin() + 2, [key](u32 in) { return in ^ key; });
std::memcpy(output.data() + offset, transformed_font.data(), transformed_font.size() * sizeof(u32)); std::memcpy(output.data() + offset, transformed_font.data(), transformed_font.size() * sizeof(u32));
offset += transformed_font.size() * sizeof(u32); offset += transformed_font.size() * sizeof(u32);
@@ -83,8 +85,10 @@ struct IPlatformServiceManager::Impl {
// Automatically populated based on shared_fonts dump or system archives. // Automatically populated based on shared_fonts dump or system archives.
// 6 builtin fonts + extra 2 for whatever may come after // 6 builtin fonts + extra 2 for whatever may come after
boost::container::static_vector<FontRegion, 8> shared_font_regions; boost::container::static_vector<FontRegion, 8> shared_font_regions;
#ifndef __OPENORBIS__
/// Backing memory for the shared font data /// Backing memory for the shared font data
std::array<u8, SHARED_FONT_MEM_SIZE> shared_font; std::array<u8, SHARED_FONT_MEM_SIZE> shared_font;
#endif
}; };
IPlatformServiceManager::IPlatformServiceManager(Core::System& system_, const char* service_name_) IPlatformServiceManager::IPlatformServiceManager(Core::System& system_, const char* service_name_)
@@ -111,49 +115,40 @@ IPlatformServiceManager::IPlatformServiceManager(Core::System& system_, const ch
// clang-format on // clang-format on
RegisterHandlers(functions); RegisterHandlers(functions);
#ifndef __OPENORBIS__
auto& fsc = system.GetFileSystemController(); auto& fsc = system.GetFileSystemController();
// Attempt to load shared font data from disk // Attempt to load shared font data from disk
const auto* nand = fsc.GetSystemNANDContents(); const auto* nand = fsc.GetSystemNANDContents();
std::size_t offset = 0; std::size_t offset = 0;
// Rebuild shared fonts from data ncas or synthesize // Rebuild shared fonts from data ncas or synthesize
for (auto& font : SHARED_FONTS) { for (auto& font : SHARED_FONTS) {
FileSys::VirtualFile romfs; FileSys::VirtualFile romfs;
const auto nca = if (auto const nca = nand->GetEntry(u64(font.first), FileSys::ContentRecordType::Data); nca)
nand->GetEntry(static_cast<u64>(font.first), FileSys::ContentRecordType::Data);
if (nca) {
romfs = nca->GetRomFS(); romfs = nca->GetRomFS();
} if (!romfs)
romfs = FileSys::SystemArchive::SynthesizeSystemArchive(u64(font.first));
if (!romfs) { if (romfs) {
romfs = FileSys::SystemArchive::SynthesizeSystemArchive(static_cast<u64>(font.first)); if (auto const extracted_romfs = FileSys::ExtractRomFS(romfs); extracted_romfs) {
} if (auto const font_fp = extracted_romfs->GetFile(font.second); font_fp) {
std::vector<u32> font_data_u32(font_fp->GetSize() / sizeof(u32));
if (!romfs) { font_fp->ReadBytes<u32>(font_data_u32.data(), font_fp->GetSize());
// We need to be BigEndian as u32s for the xor encryption
std::transform(font_data_u32.begin(), font_data_u32.end(), font_data_u32.begin(), Common::swap32);
// Font offset and size do not account for the header
const FontRegion region{u32(offset + 8), u32((font_data_u32.size() * sizeof(u32)) - 8)};
DecryptSharedFont(font_data_u32, impl->shared_font, offset);
impl->shared_font_regions.push_back(region);
} else {
LOG_ERROR(Service_NS, "{:016X} has no file \"{}\"! Skipping", font.first, font.second);
}
} else {
LOG_ERROR(Service_NS, "Failed to extract RomFS for {:016X}! Skipping", font.first);
}
} else {
LOG_ERROR(Service_NS, "Failed to find or synthesize {:016X}! Skipping", font.first); LOG_ERROR(Service_NS, "Failed to find or synthesize {:016X}! Skipping", font.first);
continue;
} }
const auto extracted_romfs = FileSys::ExtractRomFS(romfs);
if (!extracted_romfs) {
LOG_ERROR(Service_NS, "Failed to extract RomFS for {:016X}! Skipping", font.first);
continue;
}
const auto font_fp = extracted_romfs->GetFile(font.second);
if (!font_fp) {
LOG_ERROR(Service_NS, "{:016X} has no file \"{}\"! Skipping", font.first, font.second);
continue;
}
std::vector<u32> font_data_u32(font_fp->GetSize() / sizeof(u32));
font_fp->ReadBytes<u32>(font_data_u32.data(), font_fp->GetSize());
// We need to be BigEndian as u32s for the xor encryption
std::transform(font_data_u32.begin(), font_data_u32.end(), font_data_u32.begin(),
Common::swap32);
// Font offset and size do not account for the header
const FontRegion region{u32(offset + 8), u32((font_data_u32.size() * sizeof(u32)) - 8)};
DecryptSharedFont(font_data_u32, impl->shared_font, offset);
impl->shared_font_regions.push_back(region);
} }
#endif
} }
IPlatformServiceManager::~IPlatformServiceManager() = default; IPlatformServiceManager::~IPlatformServiceManager() = default;
@@ -187,8 +182,10 @@ Result IPlatformServiceManager::GetSharedMemoryNativeHandle(OutCopyHandle<Kernel
// Map backing memory for the font data // Map backing memory for the font data
LOG_DEBUG(Service_NS, "called"); LOG_DEBUG(Service_NS, "called");
#ifndef __OPENORBIS__
// Create shared font memory object // Create shared font memory object
std::memcpy(kernel.GetFontSharedMem().GetPointer(), impl->shared_font.data(), impl->shared_font.size()); std::memcpy(kernel.GetFontSharedMem().GetPointer(), impl->shared_font.data(), impl->shared_font.size());
#endif
// FIXME: this shouldn't belong to the kernel // FIXME: this shouldn't belong to the kernel
*out_shared_memory_native_handle = &kernel.GetFontSharedMem(); *out_shared_memory_native_handle = &kernel.GetFontSharedMem();
@@ -9,11 +9,7 @@
#include <optional> #include <optional>
#include <string> #include <string>
#define STBI_ONLY_JPEG 1 #include "common/stb.h"
#include <stb_image.h>
#include <stb_image_resize.h>
#include <stb_image_write.h>
#include "common/settings.h" #include "common/settings.h"
#include "core/file_sys/control_metadata.h" #include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h" #include "core/file_sys/patch_manager.h"
+7
View File
@@ -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-FileCopyrightText: 2017 Citra Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -60,7 +63,11 @@ private:
std::size_t current_index{0}; std::size_t current_index{0};
/// Stores an hour of historical frametime data useful for processing and tracking performance /// Stores an hour of historical frametime data useful for processing and tracking performance
/// regressions with code changes. /// regressions with code changes.
#ifdef __OPENORBIS__
std::array<double, 60> perf_history{};
#else
std::array<double, 216000> perf_history{}; std::array<double, 216000> perf_history{};
#endif
/// Point when the cumulative counters were reset /// Point when the cumulative counters were reset
Clock::time_point reset_point = Clock::now(); Clock::time_point reset_point = Clock::now();
@@ -22,6 +22,7 @@
#include <sys/mman.h> #include <sys/mman.h>
#include "common/assert.h" #include "common/assert.h"
#include "common/logging.h"
#include "common/common_types.h" #include "common/common_types.h"
#include "dynarmic/backend/exception_handler.h" #include "dynarmic/backend/exception_handler.h"
#include "dynarmic/common/context.h" #include "dynarmic/common/context.h"
@@ -53,26 +54,28 @@ class SigHandler {
return e.first <= offset && e.first + e.second.size > offset; return e.first <= offset && e.first + e.second.size > offset;
}); });
} }
static void SigAction(int sig, siginfo_t* info, void* raw_context);
bool supports_fast_mem = true;
void* signal_stack_memory = nullptr;
ankerl::unordered_dense::map<u64, CodeBlockInfo> code_block_infos; ankerl::unordered_dense::map<u64, CodeBlockInfo> code_block_infos;
std::shared_mutex code_block_infos_mutex; std::shared_mutex code_block_infos_mutex;
struct sigaction old_sa_segv; struct sigaction old_sa_segv;
struct sigaction old_sa_bus; struct sigaction old_sa_bus;
std::size_t signal_stack_size; std::unique_ptr<uint8_t[]> signal_stack_memory;
bool supports_fast_mem = true;
public: public:
SigHandler() noexcept { SigHandler() noexcept {
signal_stack_size = std::max<size_t>(SIGSTKSZ, 2 * 1024 * 1024); auto const stack_size = std::max<size_t>(SIGSTKSZ, 2 * 1024 * 1024);
signal_stack_memory = mmap(nullptr, signal_stack_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); signal_stack_memory = std::make_unique<uint8_t[]>(stack_size);
#ifdef __OPENORBIS__
fmt::print(stderr, "no fastmem on PS4\n");
supports_fast_mem = false;
#else
stack_t signal_stack{}; stack_t signal_stack{};
signal_stack.ss_sp = signal_stack_memory; signal_stack.ss_sp = signal_stack_memory.get();
signal_stack.ss_size = signal_stack_size; signal_stack.ss_size = stack_size;
signal_stack.ss_flags = 0; signal_stack.ss_flags = 0;
if (sigaltstack(&signal_stack, nullptr) != 0) { if (sigaltstack(&signal_stack, nullptr) != 0) {
fmt::print(stderr, "dynarmic: POSIX SigHandler: init failure at sigaltstack\n"); fmt::print(stderr, "POSIX SigHandler: init failure at sigaltstack\n");
supports_fast_mem = false; supports_fast_mem = false;
return; return;
} }
@@ -83,23 +86,20 @@ public:
sa.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_RESTART; sa.sa_flags = SA_SIGINFO | SA_ONSTACK | SA_RESTART;
sigemptyset(&sa.sa_mask); sigemptyset(&sa.sa_mask);
if (sigaction(SIGSEGV, &sa, &old_sa_segv) != 0) { if (sigaction(SIGSEGV, &sa, &old_sa_segv) != 0) {
fmt::print(stderr, "dynarmic: POSIX SigHandler: could not set SIGSEGV handler\n"); fmt::print(stderr, "POSIX SigHandler: could not set SIGSEGV handler\n");
supports_fast_mem = false; supports_fast_mem = false;
return; return;
} }
#ifdef __APPLE__ #if defined(__APPLE__)
if (sigaction(SIGBUS, &sa, &old_sa_bus) != 0) { if (sigaction(SIGBUS, &sa, &old_sa_bus) != 0) {
fmt::print(stderr, "dynarmic: POSIX SigHandler: could not set SIGBUS handler\n"); fmt::print(stderr, "POSIX SigHandler: could not set SIGBUS handler\n");
supports_fast_mem = false; supports_fast_mem = false;
return; return;
} }
# endif
#endif #endif
} }
~SigHandler() noexcept {
munmap(signal_stack_memory, signal_stack_size);
}
void AddCodeBlock(u64 offset, CodeBlockInfo cbi) noexcept { void AddCodeBlock(u64 offset, CodeBlockInfo cbi) noexcept {
std::unique_lock guard(code_block_infos_mutex); std::unique_lock guard(code_block_infos_mutex);
code_block_infos.insert_or_assign(offset, cbi); code_block_infos.insert_or_assign(offset, cbi);
@@ -109,14 +109,17 @@ public:
code_block_infos.erase(offset); code_block_infos.erase(offset);
} }
bool SupportsFastmem() const noexcept { return supports_fast_mem; } [[nodiscard]] inline bool SupportsFastmem() const noexcept {
return supports_fast_mem;
}
static void RegisterHandler();
static void SigAction(int sig, siginfo_t* info, void* raw_context);
}; };
std::mutex handler_lock;
std::optional<SigHandler> sig_handler; std::optional<SigHandler> sig_handler;
void RegisterHandler() { void SigHandler::RegisterHandler() {
std::lock_guard<std::mutex> guard(handler_lock);
if (!sig_handler) { if (!sig_handler) {
sig_handler.emplace(); sig_handler.emplace();
} }
@@ -125,52 +128,31 @@ void RegisterHandler() {
void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) { void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) {
DEBUG_ASSERT(sig == SIGSEGV || sig == SIGBUS); DEBUG_ASSERT(sig == SIGSEGV || sig == SIGBUS);
CTX_DECLARE(raw_context); CTX_DECLARE(raw_context);
#if defined(ARCHITECTURE_x86_64)
{ {
std::shared_lock guard(sig_handler->code_block_infos_mutex); std::shared_lock guard(sig_handler->code_block_infos_mutex);
if (auto const iter = sig_handler->FindCodeBlockInfo(CTX_PC); iter != sig_handler->code_block_infos.end()) { if (auto const iter = sig_handler->FindCodeBlockInfo(CTX_PC); iter != sig_handler->code_block_infos.end()) {
FakeCall fc = iter->second.cb(CTX_PC); FakeCall fc = iter->second.cb(CTX_PC);
#if defined(ARCHITECTURE_x86_64)
CTX_SP -= sizeof(u64); CTX_SP -= sizeof(u64);
*std::bit_cast<u64*>(CTX_SP) = fc.ret_rip; *std::bit_cast<u64*>(CTX_SP) = fc.ret_rip;
CTX_PC = fc.call_rip; CTX_PC = fc.call_rip;
return;
}
}
fmt::print(stderr, "Unhandled {} at rip {:#018x}\n", sig == SIGSEGV ? "SIGSEGV" : "SIGBUS", CTX_PC);
#elif defined(ARCHITECTURE_arm64) #elif defined(ARCHITECTURE_arm64)
{
std::shared_lock guard(sig_handler->code_block_infos_mutex);
if (const auto iter = sig_handler->FindCodeBlockInfo(CTX_PC); iter != sig_handler->code_block_infos.end()) {
FakeCall fc = iter->second.cb(CTX_PC);
CTX_PC = fc.call_pc; CTX_PC = fc.call_pc;
return;
}
}
fmt::print(stderr, "Unhandled {} at pc {:#018x}\n", sig == SIGSEGV ? "SIGSEGV" : "SIGBUS", CTX_PC);
#elif defined(ARCHITECTURE_riscv64) #elif defined(ARCHITECTURE_riscv64)
{ CTX_PC = fc.call_sepc;
std::shared_lock guard(sig_handler->code_block_infos_mutex);
if (const auto iter = sig_handler->FindCodeBlockInfo(CTX_SEPC); iter != sig_handler->code_block_infos.end()) {
FakeCall fc = iter->second.cb(CTX_SEPC);
CTX_SEPC = fc.call_sepc;
return;
}
}
fmt::print(stderr, "Unhandled {} at pc {:#018x}\n", sig == SIGSEGV ? "SIGSEGV" : "SIGBUS", CTX_SEPC);
#elif defined(ARCHITECTURE_loongarch64) #elif defined(ARCHITECTURE_loongarch64)
{
std::shared_lock guard(sig_handler->code_block_infos_mutex);
if (const auto iter = sig_handler->FindCodeBlockInfo(CTX_PC); iter != sig_handler->code_block_infos.end()) {
FakeCall fc = iter->second.cb(CTX_PC);
CTX_PC = fc.call_pc; CTX_PC = fc.call_pc;
#else
ASSERT(false);
#endif
return; return;
} }
} }
fmt::print(stderr, "Unhandled {} at pc {:#018x}\n", sig == SIGSEGV ? "SIGSEGV" : "SIGBUS", CTX_PC); LOG_ERROR(Core, "Unhandled {} at {:#018x}\n", sig == SIGSEGV ? "SIGSEGV" : "SIGBUS", CTX_PC);
#else
# error "Invalid architecture"
#endif
#ifdef __OPENORBIS__
// No fastmem
#else
struct sigaction* retry_sa = sig == SIGSEGV ? &sig_handler->old_sa_segv : &sig_handler->old_sa_bus; struct sigaction* retry_sa = sig == SIGSEGV ? &sig_handler->old_sa_segv : &sig_handler->old_sa_bus;
if (retry_sa->sa_flags & SA_SIGINFO) { if (retry_sa->sa_flags & SA_SIGINFO) {
retry_sa->sa_sigaction(sig, info, raw_context); retry_sa->sa_sigaction(sig, info, raw_context);
@@ -184,15 +166,17 @@ void SigHandler::SigAction(int sig, siginfo_t* info, void* raw_context) {
return; return;
} }
retry_sa->sa_handler(sig); retry_sa->sa_handler(sig);
#endif
} }
} // anonymous namespace } // anonymous namespace
struct ExceptionHandler::Impl final { struct ExceptionHandler::Impl final {
Impl(u64 offset_, u64 size_) Impl(u64 offset_, u64 size_)
: offset(offset_) : offset(offset_)
, size(size_) { , size(size_)
RegisterHandler(); {
SigHandler::RegisterHandler();
} }
void SetCallback(std::function<FakeCall(u64)> cb) { void SetCallback(std::function<FakeCall(u64)> cb) {
@@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project // SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
#include <variant>
#include "dynarmic/backend/loongarch64/emit_loongarch64.h" #include "dynarmic/backend/loongarch64/emit_loongarch64.h"
#include "dynarmic/backend/loongarch64/a32_jitstate.h" #include "dynarmic/backend/loongarch64/a32_jitstate.h"
@@ -95,7 +96,8 @@ EmittedBlockInfo EmitLoongArch64(lagoon_assembler_t& as, IR::Block block, const
// TODO: Emit Terminal // TODO: Emit Terminal
const auto term = block.GetTerminal(); const auto term = block.GetTerminal();
const IR::Term::LinkBlock* link_block_term = boost::get<IR::Term::LinkBlock>(&term); const IR::Term::LeafTerminal* leaft_term = std::get_if<IR::Term::LeafTerminal>(&term);
const IR::Term::LinkBlock* link_block_term = std::get_if<IR::Term::LinkBlock>(leaft_term);
ASSERT(link_block_term); ASSERT(link_block_term);
la_load_immediate64(&as, Xscratch0, link_block_term->next.Value()); la_load_immediate64(&as, Xscratch0, link_block_term->next.Value());
la_st_w(&as, Xscratch0, Xstate, static_cast<int32_t>(offsetof(A32JitState, regs) + sizeof(u32) * 15)); la_st_w(&as, Xscratch0, Xstate, static_cast<int32_t>(offsetof(A32JitState, regs) + sizeof(u32) * 15));
@@ -66,8 +66,14 @@ public:
const void* code_ptr = nullptr; const void* code_ptr = nullptr;
}; };
static_assert(sizeof(FastDispatchEntry) == 0x10); static_assert(sizeof(FastDispatchEntry) == 0x10);
#ifdef __OPENORBIS__
static constexpr u64 fast_dispatch_table_mask = 0xFF0;
static constexpr size_t fast_dispatch_table_size = 0x100;
#else
static constexpr u64 fast_dispatch_table_mask = 0xFFFF0; static constexpr u64 fast_dispatch_table_mask = 0xFFFF0;
static constexpr size_t fast_dispatch_table_size = 0x10000; static constexpr size_t fast_dispatch_table_size = 0x10000;
#endif
void ClearFastDispatchTable(); void ClearFastDispatchTable();
void GenFastmemFallbacks(); void GenFastmemFallbacks();
void GenTerminalHandlers(); void GenTerminalHandlers();
@@ -59,8 +59,13 @@ public:
const void* code_ptr = nullptr; const void* code_ptr = nullptr;
}; };
static_assert(sizeof(FastDispatchEntry) == 0x10); static_assert(sizeof(FastDispatchEntry) == 0x10);
#ifdef __OPENORBIS__
static constexpr u64 fast_dispatch_table_mask = 0xFF0;
static constexpr size_t fast_dispatch_table_size = 0x100;
#else
static constexpr u64 fast_dispatch_table_mask = 0xFFFFF0; static constexpr u64 fast_dispatch_table_mask = 0xFFFFF0;
static constexpr size_t fast_dispatch_table_size = 0x100000; static constexpr size_t fast_dispatch_table_size = 0x100000;
#endif
void ClearFastDispatchTable(); void ClearFastDispatchTable();
void GenMemory128Accessors(); void GenMemory128Accessors();
@@ -7,6 +7,7 @@
*/ */
#include "dynarmic/backend/x64/block_of_code.h" #include "dynarmic/backend/x64/block_of_code.h"
#include "xbyak/xbyak.h"
#ifdef _WIN32 #ifdef _WIN32
# define WIN32_LEAN_AND_MEAN # define WIN32_LEAN_AND_MEAN
@@ -67,8 +68,12 @@ public:
uint8_t* alloc(size_t size) override { uint8_t* alloc(size_t size) override {
void* p = VirtualAlloc(nullptr, size, MEM_RESERVE, PAGE_READWRITE); void* p = VirtualAlloc(nullptr, size, MEM_RESERVE, PAGE_READWRITE);
if (p == nullptr) { if (p == nullptr) {
#ifndef XBYAK_NO_EXCEPTION
using Xbyak::Error; using Xbyak::Error;
XBYAK_THROW(Xbyak::ERR_CANT_ALLOC); XBYAK_THROW(Xbyak::ERR_CANT_ALLOC);
#else
std::abort();
#endif
} }
return static_cast<uint8_t*>(p); return static_cast<uint8_t*>(p);
} }
@@ -79,13 +84,12 @@ public:
bool useProtect() const override { return false; } bool useProtect() const override { return false; }
#else #else
static constexpr size_t DYNARMIC_PAGE_SIZE = 4096;
// Can't subclass Xbyak::MmapAllocator because it is not a pure interface // Can't subclass Xbyak::MmapAllocator because it is not a pure interface
// and doesn't expose its construtor // and doesn't expose its construtor
uint8_t* alloc(size_t size) override { uint8_t* alloc(size_t size) override {
auto const page_size = Xbyak::inner::getPageSize();
// Waste a page to store the size // Waste a page to store the size
size += DYNARMIC_PAGE_SIZE; size += page_size;
int mode = MAP_PRIVATE; int mode = MAP_PRIVATE;
#if defined(MAP_ANONYMOUS) #if defined(MAP_ANONYMOUS)
@@ -106,17 +110,22 @@ public:
#endif #endif
void* p = mmap(nullptr, size, prot, mode, -1, 0); void* p = mmap(nullptr, size, prot, mode, -1, 0);
if (p == MAP_FAILED) { if (p == MAP_FAILED) {
#ifndef XBYAK_NO_EXCEPTION
using Xbyak::Error; using Xbyak::Error;
XBYAK_THROW(Xbyak::ERR_CANT_ALLOC); XBYAK_THROW(Xbyak::ERR_CANT_ALLOC);
#else
std::abort();
#endif
} }
std::memcpy(p, &size, sizeof(size_t)); std::memcpy(p, &size, sizeof(size_t));
return static_cast<uint8_t*>(p) + DYNARMIC_PAGE_SIZE; return static_cast<uint8_t*>(p) + page_size;
} }
void free(uint8_t* p) override { void free(uint8_t* p) override {
auto const page_size = Xbyak::inner::getPageSize();
size_t size; size_t size;
std::memcpy(&size, p - DYNARMIC_PAGE_SIZE, sizeof(size_t)); std::memcpy(&size, p - page_size, sizeof(size_t));
munmap(p - DYNARMIC_PAGE_SIZE, size); munmap(p - page_size, size);
} }
# ifdef DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT # ifdef DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT
@@ -233,18 +242,16 @@ bool IsUnderRosetta() {
} // anonymous namespace } // anonymous namespace
#ifdef DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT BlockOfCode::BlockOfCode(RunCodeCallbacks cb, JitStateInfo jsi, size_t total_code_size, std::function<void(BlockOfCode&)> rcp) noexcept
static const auto default_cg_mode = Xbyak::DontSetProtectRWE; #if defined(DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT)
: Xbyak::CodeGenerator(total_code_size, Xbyak::DontSetProtectRWE, &s_allocator)
#else #else
static const auto default_cg_mode = nullptr; //Allow RWE : Xbyak::CodeGenerator(total_code_size, nullptr, &s_allocator)
#endif #endif
, cb(std::move(cb))
BlockOfCode::BlockOfCode(RunCodeCallbacks cb, JitStateInfo jsi, size_t total_code_size, std::function<void(BlockOfCode&)> rcp) , jsi(jsi)
: Xbyak::CodeGenerator(total_code_size, default_cg_mode, &s_allocator) , constant_pool(*this, CONSTANT_POOL_SIZE)
, cb(std::move(cb)) , host_features(GetHostFeatures()) {
, jsi(jsi)
, constant_pool(*this, CONSTANT_POOL_SIZE)
, host_features(GetHostFeatures()) {
EnableWriting(); EnableWriting();
EnsureMemoryCommitted(PRELUDE_COMMIT_SIZE); EnsureMemoryCommitted(PRELUDE_COMMIT_SIZE);
GenRunCode(rcp); GenRunCode(rcp);
@@ -533,8 +540,12 @@ size_t BlockOfCode::GetTotalCodeSize() const {
void* BlockOfCode::AllocateFromCodeSpace(size_t alloc_size) { void* BlockOfCode::AllocateFromCodeSpace(size_t alloc_size) {
if (size_ + alloc_size >= maxSize_) { if (size_ + alloc_size >= maxSize_) {
#ifndef XBYAK_NO_EXCEPTION
using Xbyak::Error; using Xbyak::Error;
XBYAK_THROW(Xbyak::ERR_CODE_IS_TOO_BIG); XBYAK_THROW(Xbyak::ERR_CODE_IS_TOO_BIG);
#else
std::abort();
#endif
} }
EnsureMemoryCommitted(alloc_size); EnsureMemoryCommitted(alloc_size);
@@ -39,8 +39,8 @@ struct RunCodeCallbacks {
class BlockOfCode final : public Xbyak::CodeGenerator { class BlockOfCode final : public Xbyak::CodeGenerator {
public: public:
BlockOfCode(RunCodeCallbacks cb, JitStateInfo jsi, size_t total_code_size, std::function<void(BlockOfCode&)> rcp); BlockOfCode(RunCodeCallbacks cb, JitStateInfo jsi, size_t total_code_size, std::function<void(BlockOfCode&)> rcp) noexcept;
BlockOfCode(const BlockOfCode&) = delete; BlockOfCode(const BlockOfCode&) noexcept = delete;
/// Call when external emitters have finished emitting their preludes. /// Call when external emitters have finished emitting their preludes.
void PreludeComplete(); void PreludeComplete();
@@ -40,9 +40,10 @@ EmitContext::EmitContext(RegAlloc& reg_alloc, IR::Block& block, boost::container
EmitContext::~EmitContext() = default; EmitContext::~EmitContext() = default;
EmitX64::EmitX64(BlockOfCode& code) EmitX64::EmitX64(BlockOfCode& code) : code(code) {
: code(code) { #ifndef __OPENORBIS__
exception_handler.Register(code); exception_handler.Register(code);
#endif
} }
EmitX64::~EmitX64() = default; EmitX64::~EmitX64() = default;
+7 -4
View File
@@ -88,7 +88,7 @@
# define CTX_Q(i) (fpctx->vregs[i]) # define CTX_Q(i) (fpctx->vregs[i])
# define CTX_FPSR (fpctx->fpsr) # define CTX_FPSR (fpctx->fpsr)
# define CTX_FPCR (fpctx->fpcr) # define CTX_FPCR (fpctx->fpcr)
# elif defined(__FreeBSD__) # elif defined(__FreeBSD__) || defined(__DragonFly__)
# define CTX_PC (mctx.mc_gpregs.gp_elr) # define CTX_PC (mctx.mc_gpregs.gp_elr)
# define CTX_SP (mctx.mc_gpregs.gp_sp) # define CTX_SP (mctx.mc_gpregs.gp_sp)
# define CTX_LR (mctx.mc_gpregs.gp_lr) # define CTX_LR (mctx.mc_gpregs.gp_lr)
@@ -131,19 +131,22 @@
# elif defined(__managarm__) # elif defined(__managarm__)
# define CTX_PC (mctx.__pollution(gregs)[REG_RIP]) # define CTX_PC (mctx.__pollution(gregs)[REG_RIP])
# define CTX_SP (mctx.__pollution(gregs)[REG_RSP]) # define CTX_SP (mctx.__pollution(gregs)[REG_RSP])
# elif defined(__OPENORBIS__)
# define CTX_RIP (mctx.gregs[REG_RIP])
# define CTX_RSP (mctx.gregs[REG_RSP])
# else # else
# error "unknown platform" # error "unknown platform"
# endif # endif
#elif defined(ARCHITECTURE_riscv64) #elif defined(ARCHITECTURE_riscv64)
# if defined(__FreeBSD__) # if defined(__FreeBSD__)
# define CTX_SEPC (mctx.mc_gpregs.gp_sepc) # define CTX_PC (mctx.mc_gpregs.gp_sepc)
# define CTX_SP (mctx.mc_gpregs.gp_sp) # define CTX_SP (mctx.mc_gpregs.gp_sp)
# elif defined(__linux__) # elif defined(__linux__)
# define CTX_SEPC (mctx.__gregs[REG_PC]) # define CTX_PC (mctx.__gregs[REG_PC])
# define CTX_SP (mctx.__gregs[REG_SP]) # define CTX_SP (mctx.__gregs[REG_SP])
# elif defined(__OpenBSD__) # elif defined(__OpenBSD__)
// https://github.com/openbsd/src/blob/master/sys/arch/riscv64/include/signal.h // https://github.com/openbsd/src/blob/master/sys/arch/riscv64/include/signal.h
# define CTX_SEPC (ucontext->sc_sepc) # define CTX_PC (ucontext->sc_sepc)
# define CTX_SP (ucontext->sc_sp) # define CTX_SP (ucontext->sc_sp)
# else # else
# error "unknown platform" # error "unknown platform"
@@ -13,6 +13,7 @@
#include "dynarmic/backend/x64/abi.h" #include "dynarmic/backend/x64/abi.h"
#include "dynarmic/backend/x64/hostloc.h" #include "dynarmic/backend/x64/hostloc.h"
#include "dynarmic/common/spin_lock.h" #include "dynarmic/common/spin_lock.h"
#include "xbyak/xbyak.h"
#ifdef DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT #ifdef DYNARMIC_ENABLE_NO_EXECUTE_SUPPORT
static const auto default_cg_mode = Xbyak::DontSetProtectRWE; static const auto default_cg_mode = Xbyak::DontSetProtectRWE;
@@ -78,7 +79,7 @@ namespace {
struct SpinLockImpl { struct SpinLockImpl {
void Initialize() noexcept; void Initialize() noexcept;
static void GlobalInitialize() noexcept; static void GlobalInitialize() noexcept;
Xbyak::CodeGenerator code = Xbyak::CodeGenerator(4096, default_cg_mode); Xbyak::CodeGenerator code = Xbyak::CodeGenerator(Xbyak::inner::getPageSize(), default_cg_mode);
void (*lock)(volatile int*) = nullptr; void (*lock)(volatile int*) = nullptr;
void (*unlock)(volatile int*) = nullptr; void (*unlock)(volatile int*) = nullptr;
}; };
+5
View File
@@ -134,3 +134,8 @@ target_compile_options(dynarmic_tests PRIVATE ${DYNARMIC_CXX_FLAGS})
target_compile_definitions(dynarmic_tests PRIVATE FMT_USE_USER_DEFINED_LITERALS=1) target_compile_definitions(dynarmic_tests PRIVATE FMT_USE_USER_DEFINED_LITERALS=1)
add_test(NAME dynarmic_tests COMMAND dynarmic_tests --durations yes) add_test(NAME dynarmic_tests COMMAND dynarmic_tests --durations yes)
if (OPENORBIS)
target_link_libraries(dynarmic_tests PRIVATE SceVideoOut SceAudioOut ScePad SceSystemService ps4sup)
create_ps4_eboot(dynarmic_tests dynarmic_tests IV0000-BREW00090_00-DYNARMICTS000000)
endif()
+5 -12
View File
@@ -1033,27 +1033,20 @@ ButtonBindings SDLDriver::GetDefaultButtonBinding(
}; };
} }
ButtonMapping SDLDriver::GetSingleControllerMapping( ButtonMapping SDLDriver::GetSingleControllerMapping(const std::shared_ptr<SDLJoystick>& joystick, const ButtonBindings& switch_to_sdl_button, const ZButtonBindings& switch_to_sdl_axis) const {
const std::shared_ptr<SDLJoystick>& joystick, const ButtonBindings& switch_to_sdl_button,
const ZButtonBindings& switch_to_sdl_axis) const {
ButtonMapping mapping; ButtonMapping mapping;
mapping.reserve(switch_to_sdl_button.size() + switch_to_sdl_axis.size()); mapping.reserve(switch_to_sdl_button.size() + switch_to_sdl_axis.size());
auto* controller = joystick->GetSDLGameController(); if (auto* controller = joystick->GetSDLGameController(); controller) {
const auto bindings = GetBindings(controller); const auto bindings = GetBindings(controller);
for (const auto& [switch_button, sdl_button] : switch_to_sdl_button) { for (const auto& [switch_button, sdl_button] : switch_to_sdl_button) {
const auto binding = GetBindingForButton(bindings, sdl_button); const auto binding = GetBindingForButton(bindings, sdl_button);
mapping.insert_or_assign( mapping.insert_or_assign(switch_button, BuildParamPackageForBinding(joystick->GetPort(), joystick->GetGUID(), binding));
switch_button,
BuildParamPackageForBinding(joystick->GetPort(), joystick->GetGUID(), binding));
} }
for (const auto& [switch_button, sdl_axis] : switch_to_sdl_axis) { for (const auto& [switch_button, sdl_axis] : switch_to_sdl_axis) {
const auto binding = GetBindingForAxis(bindings, sdl_axis); const auto binding = GetBindingForAxis(bindings, sdl_axis);
mapping.insert_or_assign( mapping.insert_or_assign(switch_button, BuildParamPackageForBinding(joystick->GetPort(), joystick->GetGUID(), binding));
switch_button, }
BuildParamPackageForBinding(joystick->GetPort(), joystick->GetGUID(), binding));
} }
return mapping; return mapping;
} }
+19
View File
@@ -82,7 +82,10 @@ struct InputSubsystem::Impl {
#ifdef ENABLE_LIBUSB #ifdef ENABLE_LIBUSB
RegisterEngine("gcpad", gcadapter); RegisterEngine("gcpad", gcadapter);
#endif #endif
#ifndef __OPENORBIS__
// TODO: Issue in PS4, crash for UDP_client
RegisterEngine("cemuhookudp", udp_client); RegisterEngine("cemuhookudp", udp_client);
#endif
RegisterEngine("tas", tas_input); RegisterEngine("tas", tas_input);
RegisterEngine("camera", camera); RegisterEngine("camera", camera);
#ifdef __ANDROID__ #ifdef __ANDROID__
@@ -116,7 +119,9 @@ struct InputSubsystem::Impl {
#ifdef ENABLE_LIBUSB #ifdef ENABLE_LIBUSB
UnregisterEngine(gcadapter); UnregisterEngine(gcadapter);
#endif #endif
#ifndef __OPENORBIS__
UnregisterEngine(udp_client); UnregisterEngine(udp_client);
#endif
UnregisterEngine(tas_input); UnregisterEngine(tas_input);
UnregisterEngine(camera); UnregisterEngine(camera);
#ifdef __ANDROID__ #ifdef __ANDROID__
@@ -152,8 +157,10 @@ struct InputSubsystem::Impl {
auto gcadapter_devices = gcadapter->GetInputDevices(); auto gcadapter_devices = gcadapter->GetInputDevices();
devices.insert(devices.end(), gcadapter_devices.begin(), gcadapter_devices.end()); devices.insert(devices.end(), gcadapter_devices.begin(), gcadapter_devices.end());
#endif #endif
#ifndef __OPENORBIS__
auto udp_devices = udp_client->GetInputDevices(); auto udp_devices = udp_client->GetInputDevices();
devices.insert(devices.end(), udp_devices.begin(), udp_devices.end()); devices.insert(devices.end(), udp_devices.begin(), udp_devices.end());
#endif
#ifdef HAVE_SDL3 #ifdef HAVE_SDL3
auto joycon_devices = joycon->GetInputDevices(); auto joycon_devices = joycon->GetInputDevices();
devices.insert(devices.end(), joycon_devices.begin(), joycon_devices.end()); devices.insert(devices.end(), joycon_devices.begin(), joycon_devices.end());
@@ -186,9 +193,11 @@ struct InputSubsystem::Impl {
return gcadapter; return gcadapter;
} }
#endif #endif
#ifndef __OPENORBIS__
if (engine == udp_client->GetEngineName()) { if (engine == udp_client->GetEngineName()) {
return udp_client; return udp_client;
} }
#endif
#ifdef HAVE_SDL3 #ifdef HAVE_SDL3
if (engine == sdl->GetEngineName()) { if (engine == sdl->GetEngineName()) {
return sdl; return sdl;
@@ -271,9 +280,11 @@ struct InputSubsystem::Impl {
return true; return true;
} }
#endif #endif
#ifndef __OPENORBIS__
if (engine == udp_client->GetEngineName()) { if (engine == udp_client->GetEngineName()) {
return true; return true;
} }
#endif
if (engine == tas_input->GetEngineName()) { if (engine == tas_input->GetEngineName()) {
return true; return true;
} }
@@ -300,7 +311,9 @@ struct InputSubsystem::Impl {
#ifdef ENABLE_LIBUSB #ifdef ENABLE_LIBUSB
gcadapter->BeginConfiguration(); gcadapter->BeginConfiguration();
#endif #endif
#ifndef __OPENORBIS__
udp_client->BeginConfiguration(); udp_client->BeginConfiguration();
#endif
#ifdef HAVE_SDL3 #ifdef HAVE_SDL3
sdl->BeginConfiguration(); sdl->BeginConfiguration();
joycon->BeginConfiguration(); joycon->BeginConfiguration();
@@ -316,7 +329,9 @@ struct InputSubsystem::Impl {
#ifdef ENABLE_LIBUSB #ifdef ENABLE_LIBUSB
gcadapter->EndConfiguration(); gcadapter->EndConfiguration();
#endif #endif
#ifndef __OPENORBIS__
udp_client->EndConfiguration(); udp_client->EndConfiguration();
#endif
#ifdef HAVE_SDL3 #ifdef HAVE_SDL3
sdl->EndConfiguration(); sdl->EndConfiguration();
joycon->EndConfiguration(); joycon->EndConfiguration();
@@ -341,7 +356,9 @@ struct InputSubsystem::Impl {
std::shared_ptr<Mouse> mouse; std::shared_ptr<Mouse> mouse;
std::shared_ptr<TouchScreen> touch_screen; std::shared_ptr<TouchScreen> touch_screen;
std::shared_ptr<TasInput::Tas> tas_input; std::shared_ptr<TasInput::Tas> tas_input;
#ifndef __OPENORBIS__
std::shared_ptr<CemuhookUDP::UDPClient> udp_client; std::shared_ptr<CemuhookUDP::UDPClient> udp_client;
#endif
std::shared_ptr<Camera> camera; std::shared_ptr<Camera> camera;
std::shared_ptr<VirtualAmiibo> virtual_amiibo; std::shared_ptr<VirtualAmiibo> virtual_amiibo;
std::shared_ptr<VirtualGamepad> virtual_gamepad; std::shared_ptr<VirtualGamepad> virtual_gamepad;
@@ -470,7 +487,9 @@ bool InputSubsystem::IsStickInverted(const Common::ParamPackage& params) const {
} }
void InputSubsystem::ReloadInputDevices() { void InputSubsystem::ReloadInputDevices() {
#ifndef __OPENORBIS__
impl->udp_client.get()->ReloadSockets(); impl->udp_client.get()->ReloadSockets();
#endif
} }
void InputSubsystem::BeginMapping(Polling::InputType type) { void InputSubsystem::BeginMapping(Polling::InputType type) {
+7 -1
View File
@@ -160,7 +160,13 @@ struct Values {
Setting<bool> enable_discord_presence{linkage, false, "enable_discord_presence", Category::Ui}; Setting<bool> enable_discord_presence{linkage, false, "enable_discord_presence", Category::Ui};
// logging // logging
Setting<bool> show_console{linkage, false, "showConsole", Category::Ui}; Setting<bool> show_console{linkage,
#ifdef __OPENORBIS__
true,
#else
false,
#endif
"showConsole", Category::Ui};
// Screenshots // Screenshots
Setting<bool> enable_screenshot_save_as{linkage, true, "enable_screenshot_save_as", Setting<bool> enable_screenshot_save_as{linkage, true, "enable_screenshot_save_as",
+4 -4
View File
@@ -74,8 +74,8 @@ static constexpr char DEFAULT_DISCORD_IMAGE[] =
"https://git.eden-emu.dev/eden-emu/eden/raw/branch/master/dist/qt_themes/default/icons/256x256/" "https://git.eden-emu.dev/eden-emu/eden/raw/branch/master/dist/qt_themes/default/icons/256x256/"
"eden.png"; "eden.png";
void DiscordImpl::UpdateGameStatus(bool use_default) { void DiscordImpl::UpdateGameStatus(std::string_view game_url, bool has_boxart) {
const std::string url = use_default ? std::string{DEFAULT_DISCORD_IMAGE} : game_url; const std::string url = std::string{has_boxart ? game_url : DEFAULT_DISCORD_IMAGE};
s64 start_time = std::chrono::duration_cast<std::chrono::seconds>( s64 start_time = std::chrono::duration_cast<std::chrono::seconds>(
std::chrono::system_clock::now().time_since_epoch()) std::chrono::system_clock::now().time_since_epoch())
.count(); .count();
@@ -98,7 +98,7 @@ void DiscordImpl::Update() {
// Used to format Icon URL for yuzu website game compatibility page // Used to format Icon URL for yuzu website game compatibility page
std::string icon_name = GetGameString(game_title); std::string icon_name = GetGameString(game_title);
game_url = fmt::format( auto const game_url = fmt::format(
"https://raw.githubusercontent.com/eden-emulator/boxart/refs/heads/master/img/{}.png", "https://raw.githubusercontent.com/eden-emulator/boxart/refs/heads/master/img/{}.png",
icon_name); icon_name);
@@ -117,7 +117,7 @@ void DiscordImpl::Update() {
}; };
auto res = client.send(request); auto res = client.send(request);
UpdateGameStatus(res && res->status == 200); UpdateGameStatus(game_url, res && res->status == 200);
return; return;
} }
+2 -4
View File
@@ -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-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: 2018 Citra Emulator Project // SPDX-FileCopyrightText: 2018 Citra Emulator Project
@@ -26,11 +26,9 @@ public:
private: private:
std::string GetGameString(const std::string& title); std::string GetGameString(const std::string& title);
void UpdateGameStatus(bool use_default); void UpdateGameStatus(std::string_view game_url, bool use_default);
std::string game_url{};
std::string game_title{}; std::string game_title{};
Core::System& system; Core::System& system;
}; };
@@ -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-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
@@ -665,6 +665,8 @@ void EmitShuffleDown(EmitContext& ctx, IR::Inst& inst, ScalarU32 value, ScalarU3
const IR::Value& clamp, const IR::Value& segmentation_mask); const IR::Value& clamp, const IR::Value& segmentation_mask);
void EmitShuffleButterfly(EmitContext& ctx, IR::Inst& inst, ScalarU32 value, ScalarU32 index, void EmitShuffleButterfly(EmitContext& ctx, IR::Inst& inst, ScalarU32 value, ScalarU32 index,
const IR::Value& clamp, const IR::Value& segmentation_mask); const IR::Value& clamp, const IR::Value& segmentation_mask);
void EmitQuadBroadcast(EmitContext& ctx, IR::Inst& inst, ScalarU32 value, ScalarU32 lane);
void EmitQuadSwap(EmitContext& ctx, IR::Inst& inst, ScalarU32 value, ScalarU32 direction);
void EmitFSwizzleAdd(EmitContext& ctx, IR::Inst& inst, ScalarF32 op_a, ScalarF32 op_b, void EmitFSwizzleAdd(EmitContext& ctx, IR::Inst& inst, ScalarF32 op_a, ScalarF32 op_b,
ScalarU32 swizzle); ScalarU32 swizzle);
void EmitDPdxFine(EmitContext& ctx, IR::Inst& inst, ScalarF32 op_a); void EmitDPdxFine(EmitContext& ctx, IR::Inst& inst, ScalarF32 op_a);
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -97,6 +100,24 @@ void EmitShuffleButterfly(EmitContext& ctx, IR::Inst& inst, ScalarU32 value, Sca
Shuffle(ctx, inst, value, index, clamp, segmentation_mask, "XOR"); Shuffle(ctx, inst, value, index, clamp, segmentation_mask, "XOR");
} }
void EmitQuadBroadcast(EmitContext& ctx, IR::Inst& inst, ScalarU32 value, ScalarU32 lane) {
const Register ret{ctx.reg_alloc.Define(inst)};
ctx.Add("AND.U RC.x,{}.threadid,~3;"
"AND.U RC.y,{},3;"
"OR.U RC.x,RC.x,RC.y;"
"SHFIDX.U {},{},RC.x,0x1C03;"
"MOV.U {}.x,{}.y;",
ctx.stage_name, lane, ret, value, ret, ret);
}
void EmitQuadSwap(EmitContext& ctx, IR::Inst& inst, ScalarU32 value, ScalarU32 direction) {
const Register ret{ctx.reg_alloc.Define(inst)};
ctx.Add("ADD.U RC.x,{},1;"
"SHFXOR.U {},{},RC.x,0x1C03;"
"MOV.U {}.x,{}.y;",
direction, ret, value, ret, ret);
}
void EmitFSwizzleAdd(EmitContext& ctx, IR::Inst& inst, ScalarF32 op_a, ScalarF32 op_b, void EmitFSwizzleAdd(EmitContext& ctx, IR::Inst& inst, ScalarF32 op_a, ScalarF32 op_b,
ScalarU32 swizzle) { ScalarU32 swizzle) {
const auto ret{ctx.reg_alloc.Define(inst)}; const auto ret{ctx.reg_alloc.Define(inst)};
@@ -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-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
@@ -743,6 +743,10 @@ void EmitShuffleDown(EmitContext& ctx, IR::Inst& inst, std::string_view value,
void EmitShuffleButterfly(EmitContext& ctx, IR::Inst& inst, std::string_view value, void EmitShuffleButterfly(EmitContext& ctx, IR::Inst& inst, std::string_view value,
std::string_view index, std::string_view clamp, std::string_view index, std::string_view clamp,
std::string_view segmentation_mask); std::string_view segmentation_mask);
void EmitQuadBroadcast(EmitContext& ctx, IR::Inst& inst, std::string_view value,
std::string_view lane);
void EmitQuadSwap(EmitContext& ctx, IR::Inst& inst, std::string_view value,
std::string_view direction);
void EmitFSwizzleAdd(EmitContext& ctx, IR::Inst& inst, std::string_view op_a, std::string_view op_b, void EmitFSwizzleAdd(EmitContext& ctx, IR::Inst& inst, std::string_view op_a, std::string_view op_b,
std::string_view swizzle); std::string_view swizzle);
void EmitDPdxFine(EmitContext& ctx, IR::Inst& inst, std::string_view op_a); void EmitDPdxFine(EmitContext& ctx, IR::Inst& inst, std::string_view op_a);
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -200,6 +203,18 @@ void EmitShuffleButterfly(EmitContext& ctx, IR::Inst& inst, std::string_view val
ctx.AddU32("{}=shfl_in_bounds?shfl_result:{};", inst, value); ctx.AddU32("{}=shfl_in_bounds?shfl_result:{};", inst, value);
} }
void EmitQuadBroadcast(EmitContext& ctx, IR::Inst& inst, std::string_view value,
std::string_view lane) {
const auto src_thread_id{fmt::format("(({}&~3)|({}& 3))", THREAD_ID, lane)};
ctx.AddU32("{}=readInvocationARB({},{});", inst, value, src_thread_id);
}
void EmitQuadSwap(EmitContext& ctx, IR::Inst& inst, std::string_view value,
std::string_view direction) {
const auto src_thread_id{fmt::format("({}^({}+1))", THREAD_ID, direction)};
ctx.AddU32("{}=readInvocationARB({},{});", inst, value, src_thread_id);
}
void EmitFSwizzleAdd(EmitContext& ctx, IR::Inst& inst, std::string_view op_a, std::string_view op_b, void EmitFSwizzleAdd(EmitContext& ctx, IR::Inst& inst, std::string_view op_a, std::string_view op_b,
std::string_view swizzle) { std::string_view swizzle) {
const auto mask{fmt::format("({}>>((gl_SubGroupInvocationARB&3)<<1))&3", swizzle)}; const auto mask{fmt::format("({}>>((gl_SubGroupInvocationARB&3)<<1))&3", swizzle)};
@@ -322,6 +322,11 @@ void DefineEntryPoint(const IR::Program& program, EmitContext& ctx, Id main) {
if (ctx.runtime_info.force_early_z) { if (ctx.runtime_info.force_early_z) {
ctx.AddExecutionMode(main, spv::ExecutionMode::EarlyFragmentTests); ctx.AddExecutionMode(main, spv::ExecutionMode::EarlyFragmentTests);
} }
if (ctx.profile.support_shader_quad_control && program.info.uses_quad_shuffles) {
ctx.AddExtension("SPV_KHR_quad_control");
ctx.AddCapability(spv::Capability::QuadControlKHR);
ctx.AddExecutionMode(main, spv::ExecutionMode::RequireFullQuadsKHR);
}
break; break;
default: default:
throw NotImplementedException("Stage {}", program.stage); throw NotImplementedException("Stage {}", program.stage);
@@ -443,6 +448,12 @@ void SetupCapabilities(const Profile& profile, const Info& info, EmitContext& ct
ctx.AddCapability(spv::Capability::GroupNonUniformVote); ctx.AddCapability(spv::Capability::GroupNonUniformVote);
} }
} }
if (info.uses_quad_shuffles) {
if (profile.support_quad_shuffles) {
ctx.AddCapability(spv::Capability::GroupNonUniformQuad);
}
ctx.AddCapability(spv::Capability::GroupNonUniformShuffle);
}
if (info.uses_int64_bit_atomics && profile.support_int64_atomics) { if (info.uses_int64_bit_atomics && profile.support_int64_atomics) {
ctx.AddCapability(spv::Capability::Int64Atomics); ctx.AddCapability(spv::Capability::Int64Atomics);
} }
@@ -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-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
@@ -622,6 +622,8 @@ Id EmitShuffleDown(EmitContext& ctx, IR::Inst* inst, Id value, Id index, Id clam
Id segmentation_mask); Id segmentation_mask);
Id EmitShuffleButterfly(EmitContext& ctx, IR::Inst* inst, Id value, Id index, Id clamp, Id EmitShuffleButterfly(EmitContext& ctx, IR::Inst* inst, Id value, Id index, Id clamp,
Id segmentation_mask); Id segmentation_mask);
Id EmitQuadBroadcast(EmitContext& ctx, Id value, Id lane);
Id EmitQuadSwap(EmitContext& ctx, Id value, Id direction);
Id EmitFSwizzleAdd(EmitContext& ctx, Id op_a, Id op_b, Id swizzle); Id EmitFSwizzleAdd(EmitContext& ctx, Id op_a, Id op_b, Id swizzle);
Id EmitDPdxFine(EmitContext& ctx, Id op_a); Id EmitDPdxFine(EmitContext& ctx, Id op_a);
Id EmitDPdyFine(EmitContext& ctx, Id op_a); Id EmitDPdyFine(EmitContext& ctx, Id op_a);
@@ -260,6 +260,21 @@ Id EmitShuffleButterfly(EmitContext& ctx, IR::Inst* inst, Id value, Id index, Id
return SelectValue(ctx, in_range, value, src_thread_id); return SelectValue(ctx, in_range, value, src_thread_id);
} }
Id EmitQuadBroadcast(EmitContext& ctx, Id value, Id lane) {
if (ctx.profile.support_quad_shuffles) {
return ctx.OpGroupNonUniformQuadBroadcast(ctx.U32[1], SubgroupScope(ctx), value, lane);
}
const Id base{ctx.OpBitwiseAnd(ctx.U32[1], GetThreadId(ctx), ctx.Const(~3u))};
const Id local_lane{ctx.OpBitwiseAnd(ctx.U32[1], lane, ctx.Const(3u))};
const Id src_thread_id{ctx.OpBitwiseOr(ctx.U32[1], base, local_lane)};
return ctx.OpGroupNonUniformShuffle(ctx.U32[1], SubgroupScope(ctx), value, src_thread_id);
}
Id EmitQuadSwap(EmitContext& ctx, Id value, Id direction) {
const Id xor_mask{ctx.OpIAdd(ctx.U32[1], direction, ctx.Const(1u))};
return ctx.OpGroupNonUniformShuffleXor(ctx.U32[1], SubgroupScope(ctx), value, xor_mask);
}
Id EmitFSwizzleAdd(EmitContext& ctx, Id op_a, Id op_b, Id swizzle) { Id EmitFSwizzleAdd(EmitContext& ctx, Id op_a, Id op_b, Id swizzle) {
const Id three{ctx.Const(3U)}; const Id three{ctx.Const(3U)};
Id mask{GetThreadId(ctx)}; Id mask{GetThreadId(ctx)};
@@ -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-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
@@ -2100,6 +2100,14 @@ U32 IREmitter::ShuffleButterfly(const IR::U32& value, const IR::U32& index, cons
return Inst<U32>(Opcode::ShuffleButterfly, value, index, clamp, seg_mask); return Inst<U32>(Opcode::ShuffleButterfly, value, index, clamp, seg_mask);
} }
U32 IREmitter::QuadBroadcast(const IR::U32& value, const IR::U32& lane) {
return Inst<U32>(Opcode::QuadBroadcast, value, lane);
}
U32 IREmitter::QuadSwap(const IR::U32& value, const IR::U32& direction) {
return Inst<U32>(Opcode::QuadSwap, value, direction);
}
F32 IREmitter::FSwizzleAdd(const F32& a, const F32& b, const U32& swizzle, FpControl control) { F32 IREmitter::FSwizzleAdd(const F32& a, const F32& b, const U32& swizzle, FpControl control) {
return Inst<F32>(Opcode::FSwizzleAdd, Flags{control}, a, b, swizzle); return Inst<F32>(Opcode::FSwizzleAdd, Flags{control}, a, b, swizzle);
} }
@@ -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-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
@@ -394,6 +394,8 @@ public:
const IR::U32& seg_mask); const IR::U32& seg_mask);
[[nodiscard]] U32 ShuffleButterfly(const IR::U32& value, const IR::U32& index, [[nodiscard]] U32 ShuffleButterfly(const IR::U32& value, const IR::U32& index,
const IR::U32& clamp, const IR::U32& seg_mask); const IR::U32& clamp, const IR::U32& seg_mask);
[[nodiscard]] U32 QuadBroadcast(const IR::U32& value, const IR::U32& lane);
[[nodiscard]] U32 QuadSwap(const IR::U32& value, const IR::U32& direction);
[[nodiscard]] F32 FSwizzleAdd(const F32& a, const F32& b, const U32& swizzle, [[nodiscard]] F32 FSwizzleAdd(const F32& a, const F32& b, const U32& swizzle,
FpControl control = {}); FpControl control = {});
@@ -10,7 +10,7 @@ namespace Shader::IR {
namespace Detail { namespace Detail {
OpcodeMeta META_TABLE[532] = { OpcodeMeta META_TABLE[534] = {
#define OPCODE(name_token, type_token, ...) \ #define OPCODE(name_token, type_token, ...) \
{ \ { \
.name{#name_token}, \ .name{#name_token}, \
@@ -21,7 +21,7 @@ OpcodeMeta META_TABLE[532] = {
#undef OPCODE #undef OPCODE
}; };
u8 NUM_ARGS[532] = { u8 NUM_ARGS[534] = {
#define OPCODE(name_token, type_token, ...) u8(CalculateNumArgsOf(Opcode::name_token)), #define OPCODE(name_token, type_token, ...) u8(CalculateNumArgsOf(Opcode::name_token)),
#include "opcodes.inc" #include "opcodes.inc"
#undef OPCODE #undef OPCODE
+2 -2
View File
@@ -57,12 +57,12 @@ static constexpr Type F64x2{Type::F64x2};
static constexpr Type F64x3{Type::F64x3}; static constexpr Type F64x3{Type::F64x3};
static constexpr Type F64x4{Type::F64x4}; static constexpr Type F64x4{Type::F64x4};
extern OpcodeMeta META_TABLE[532]; extern OpcodeMeta META_TABLE[534];
constexpr size_t CalculateNumArgsOf(Opcode op) noexcept { constexpr size_t CalculateNumArgsOf(Opcode op) noexcept {
const auto& arg_types = META_TABLE[size_t(op)].arg_types; const auto& arg_types = META_TABLE[size_t(op)].arg_types;
return size_t(std::distance(arg_types.begin(), std::ranges::find(arg_types, Type::Void))); return size_t(std::distance(arg_types.begin(), std::ranges::find(arg_types, Type::Void)));
} }
extern u8 NUM_ARGS[532]; extern u8 NUM_ARGS[534];
} // namespace Detail } // namespace Detail
/// Get return type of an opcode /// Get return type of an opcode
@@ -1,3 +1,6 @@
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
// SPDX-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later // SPDX-License-Identifier: GPL-2.0-or-later
@@ -579,6 +582,8 @@ OPCODE(ShuffleIndex, U32, U32,
OPCODE(ShuffleUp, U32, U32, U32, U32, U32, ) OPCODE(ShuffleUp, U32, U32, U32, U32, U32, )
OPCODE(ShuffleDown, U32, U32, U32, U32, U32, ) OPCODE(ShuffleDown, U32, U32, U32, U32, U32, )
OPCODE(ShuffleButterfly, U32, U32, U32, U32, U32, ) OPCODE(ShuffleButterfly, U32, U32, U32, U32, U32, )
OPCODE(QuadBroadcast, U32, U32, U32, )
OPCODE(QuadSwap, U32, U32, U32, )
OPCODE(FSwizzleAdd, F32, F32, F32, U32, ) OPCODE(FSwizzleAdd, F32, F32, F32, U32, )
OPCODE(DPdxFine, F32, F32, ) OPCODE(DPdxFine, F32, F32, )
OPCODE(DPdyFine, F32, F32, ) OPCODE(DPdyFine, F32, F32, )
@@ -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-License-Identifier: GPL-3.0-or-later
// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project // SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
@@ -36,7 +36,10 @@ enum class ShuffleMode : u64 {
} }
} }
void Shuffle(TranslatorVisitor& v, u64 insn, const IR::U32& index, const IR::U32& mask) { constexpr u32 QUAD_MASK = (28u << 8) | 3u;
void Shuffle(TranslatorVisitor& v, u64 insn, const IR::U32& index, const IR::U32& mask,
bool index_is_imm, u32 index_imm, bool mask_is_imm, u32 mask_imm) {
union { union {
u64 insn; u64 insn;
BitField<0, 8, IR::Reg> dest_reg; BitField<0, 8, IR::Reg> dest_reg;
@@ -45,6 +48,21 @@ void Shuffle(TranslatorVisitor& v, u64 insn, const IR::U32& index, const IR::U32
BitField<48, 3, IR::Pred> pred; BitField<48, 3, IR::Pred> pred;
} const shfl{insn}; } const shfl{insn};
const bool is_quad_candidate{mask_is_imm && mask_imm == QUAD_MASK && index_is_imm &&
v.env.ShaderStage() == Stage::Fragment};
if (is_quad_candidate) {
if (shfl.mode == ShuffleMode::IDX && index_imm <= 3) {
v.X(shfl.dest_reg, v.ir.QuadBroadcast(v.X(shfl.src_reg), v.ir.Imm32(index_imm)));
v.ir.SetPred(shfl.pred, v.ir.Imm1(true));
return;
}
if (shfl.mode == ShuffleMode::BFLY && index_imm >= 1 && index_imm <= 3) {
v.X(shfl.dest_reg, v.ir.QuadSwap(v.X(shfl.src_reg), v.ir.Imm32(index_imm - 1)));
v.ir.SetPred(shfl.pred, v.ir.Imm1(true));
return;
}
}
const IR::U32 result{ShuffleOperation(v.ir, v.X(shfl.src_reg), index, mask, shfl.mode)}; const IR::U32 result{ShuffleOperation(v.ir, v.X(shfl.src_reg), index, mask, shfl.mode)};
v.ir.SetPred(shfl.pred, v.ir.GetInBoundsFromOp(result)); v.ir.SetPred(shfl.pred, v.ir.GetInBoundsFromOp(result));
v.X(shfl.dest_reg, result); v.X(shfl.dest_reg, result);
@@ -59,11 +77,14 @@ void TranslatorVisitor::SHFL(u64 insn) {
BitField<29, 1, u64> src_b_flag; BitField<29, 1, u64> src_b_flag;
BitField<34, 13, u64> src_b_imm; BitField<34, 13, u64> src_b_imm;
} const flags{insn}; } const flags{insn};
const IR::U32 src_a{flags.src_a_flag != 0 ? ir.Imm32(static_cast<u32>(flags.src_a_imm)) const bool index_is_imm{flags.src_a_flag != 0};
: GetReg20(insn)}; const bool mask_is_imm{flags.src_b_flag != 0};
const IR::U32 src_b{flags.src_b_flag != 0 ? ir.Imm32(static_cast<u32>(flags.src_b_imm)) const IR::U32 src_a{index_is_imm ? ir.Imm32(static_cast<u32>(flags.src_a_imm))
: GetReg39(insn)}; : GetReg20(insn)};
Shuffle(*this, insn, src_a, src_b); const IR::U32 src_b{mask_is_imm ? ir.Imm32(static_cast<u32>(flags.src_b_imm))
: GetReg39(insn)};
Shuffle(*this, insn, src_a, src_b, index_is_imm, static_cast<u32>(flags.src_a_imm),
mask_is_imm, static_cast<u32>(flags.src_b_imm));
} }
} // namespace Shader::Maxwell } // namespace Shader::Maxwell
@@ -498,6 +498,10 @@ void VisitUsages(Info& info, IR::Inst& inst) {
case IR::Opcode::ShuffleButterfly: case IR::Opcode::ShuffleButterfly:
info.uses_subgroup_shuffles = true; info.uses_subgroup_shuffles = true;
break; break;
case IR::Opcode::QuadBroadcast:
case IR::Opcode::QuadSwap:
info.uses_quad_shuffles = true;
break;
case IR::Opcode::GetCbufU8: case IR::Opcode::GetCbufU8:
case IR::Opcode::GetCbufS8: case IR::Opcode::GetCbufS8:
case IR::Opcode::GetCbufU16: case IR::Opcode::GetCbufU16:
+2
View File
@@ -37,6 +37,8 @@ struct Profile {
bool support_explicit_workgroup_layout{}; bool support_explicit_workgroup_layout{};
bool support_workgroup_layout_8bit_access{}; bool support_workgroup_layout_8bit_access{};
bool support_workgroup_layout_16bit_access{}; bool support_workgroup_layout_16bit_access{};
bool support_shader_quad_control{};
bool support_quad_shuffles{};
bool support_vote{}; bool support_vote{};
u32 supported_subgroup_stages{0x7F}; u32 supported_subgroup_stages{0x7F};
bool support_viewport_index_layer_non_geometry{}; bool support_viewport_index_layer_non_geometry{};
+1
View File
@@ -252,6 +252,7 @@ struct Info {
bool uses_is_helper_invocation{}; bool uses_is_helper_invocation{};
bool uses_subgroup_invocation_id{}; bool uses_subgroup_invocation_id{};
bool uses_subgroup_shuffles{}; bool uses_subgroup_shuffles{};
bool uses_quad_shuffles{};
std::array<bool, 30> uses_patches{}; std::array<bool, 30> uses_patches{};
std::array<Interpolation, 32> interpolation{}; std::array<Interpolation, 32> interpolation{};
+5
View File
@@ -37,3 +37,8 @@ if (NOT MSVC)
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-unused-parameter> $<$<COMPILE_LANGUAGE:C,CXX>:-Wno-unused-parameter>
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-missing-field-initializers>) $<$<COMPILE_LANGUAGE:C,CXX>:-Wno-missing-field-initializers>)
endif() endif()
if (OPENORBIS)
target_link_libraries(tests PRIVATE SceVideoOut SceAudioOut ScePad SceSystemService ps4sup)
create_ps4_eboot(tests tests IV0000-BREW00090_00-DYNARMICTS000000)
endif()
+71
View File
@@ -209,3 +209,74 @@ TEST_CASE("HostMemory: Partial sparse middle unmap and check bindings", "[common
REQUIRE(ptr[0x0000] == 19); REQUIRE(ptr[0x0000] == 19);
REQUIRE(ptr[0x3fff] == 12); REQUIRE(ptr[0x3fff] == 12);
} }
TEST_CASE("HostMemory: Nieche allocation", "[common]") {
HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE);
REQUIRE(mem.BackingBasePointer() != nullptr);
mem.Map(0x0000, 0, 0x20000, PERMS, HEAP);
mem.Unmap(0x0000, 0x4000, HEAP);
mem.Map(0x1000, 0, 0x2000, PERMS, HEAP);
mem.Map(0x3000, 0, 0x1000, PERMS, HEAP);
mem.Map(0, 0, 0x1000, PERMS, HEAP);
}
TEST_CASE("HostMemory: Full unmap", "[common]") {
HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE);
REQUIRE(mem.BackingBasePointer() != nullptr);
mem.Map(0x8000, 0, 0x4000, PERMS, HEAP);
mem.Unmap(0x8000, 0x4000, HEAP);
mem.Map(0x6000, 0, 0x16000, PERMS, HEAP);
}
TEST_CASE("HostMemory: Right out of bounds unmap", "[common]") {
HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE);
REQUIRE(mem.BackingBasePointer() != nullptr);
mem.Map(0x0000, 0, 0x4000, PERMS, HEAP);
mem.Unmap(0x2000, 0x4000, HEAP);
mem.Map(0x2000, 0x80000, 0x4000, PERMS, HEAP);
}
TEST_CASE("HostMemory: Left out of bounds unmap", "[common]") {
HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE);
REQUIRE(mem.BackingBasePointer() != nullptr);
mem.Map(0x8000, 0, 0x4000, PERMS, HEAP);
mem.Unmap(0x6000, 0x4000, HEAP);
mem.Map(0x8000, 0, 0x2000, PERMS, HEAP);
}
TEST_CASE("HostMemory: Multiple placeholder unmap", "[common]") {
HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE);
REQUIRE(mem.BackingBasePointer() != nullptr);
mem.Map(0x0000, 0, 0x4000, PERMS, HEAP);
mem.Map(0x4000, 0, 0x1b000, PERMS, HEAP);
mem.Unmap(0x3000, 0x1c000, HEAP);
mem.Map(0x3000, 0, 0x20000, PERMS, HEAP);
}
TEST_CASE("HostMemory: Unmap between placeholders", "[common]") {
HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE);
REQUIRE(mem.BackingBasePointer() != nullptr);
mem.Map(0x0000, 0, 0x4000, PERMS, HEAP);
mem.Map(0x4000, 0, 0x4000, PERMS, HEAP);
mem.Unmap(0x2000, 0x4000, HEAP);
mem.Map(0x2000, 0, 0x4000, PERMS, HEAP);
}
TEST_CASE("HostMemory: Unmap to origin", "[common]") {
HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE);
REQUIRE(mem.BackingBasePointer() != nullptr);
mem.Map(0x4000, 0, 0x4000, PERMS, HEAP);
mem.Map(0x8000, 0, 0x4000, PERMS, HEAP);
mem.Unmap(0x4000, 0x4000, HEAP);
mem.Map(0, 0, 0x4000, PERMS, HEAP);
mem.Map(0x4000, 0, 0x4000, PERMS, HEAP);
}
TEST_CASE("HostMemory: Unmap to right", "[common]") {
HostMemory mem(BACKING_SIZE, VIRTUAL_SIZE);
REQUIRE(mem.BackingBasePointer() != nullptr);
mem.Map(0x4000, 0, 0x4000, PERMS, HEAP);
mem.Map(0x8000, 0, 0x4000, PERMS, HEAP);
mem.Unmap(0x8000, 0x4000, HEAP);
mem.Map(0x8000, 0, 0x4000, PERMS, HEAP);
}
@@ -15,7 +15,8 @@
#include "input_common/drivers/udp_client.h" #include "input_common/drivers/udp_client.h"
#include "input_common/helpers/udp_protocol.h" #include "input_common/helpers/udp_protocol.h"
// PS4 doesn't support cemuhook
#ifndef __OPENORBIS__
class FakeCemuhookServer { class FakeCemuhookServer {
public: public:
FakeCemuhookServer() FakeCemuhookServer()
@@ -132,3 +133,4 @@ TEST_CASE("CalibrationConfigurationJob completed", "[input_common]") {
REQUIRE(max_x == 200); REQUIRE(max_x == 200);
REQUIRE(max_y == 200); REQUIRE(max_y == 200);
} }
#endif
@@ -404,6 +404,8 @@ PipelineCache::PipelineCache(Tegra::MaxwellDeviceMemoryManager& device_memory_,
device.IsWorkgroupMemoryExplicitLayout8BitAccessSupported(), device.IsWorkgroupMemoryExplicitLayout8BitAccessSupported(),
.support_workgroup_layout_16bit_access = .support_workgroup_layout_16bit_access =
device.IsWorkgroupMemoryExplicitLayout16BitAccessSupported(), device.IsWorkgroupMemoryExplicitLayout16BitAccessSupported(),
.support_shader_quad_control = device.IsKhrShaderQuadControlSupported(),
.support_quad_shuffles = device.IsSubgroupFeatureSupported(VK_SUBGROUP_FEATURE_QUAD_BIT),
.support_vote = device.IsSubgroupFeatureSupported(VK_SUBGROUP_FEATURE_VOTE_BIT), .support_vote = device.IsSubgroupFeatureSupported(VK_SUBGROUP_FEATURE_VOTE_BIT),
.supported_subgroup_stages = supported_subgroup_stages, .supported_subgroup_stages = supported_subgroup_stages,
.support_viewport_index_layer_non_geometry = .support_viewport_index_layer_non_geometry =
+2
View File
@@ -15,6 +15,8 @@
#define VK_USE_PLATFORM_ANDROID_KHR #define VK_USE_PLATFORM_ANDROID_KHR
#elif defined(__HAIKU__) #elif defined(__HAIKU__)
#define VK_USE_PLATFORM_XCB_KHR #define VK_USE_PLATFORM_XCB_KHR
#elif defined(__OPENORBIS__)
// No fucking vulkan on the PlayStation 4
#else #else
#define VK_USE_PLATFORM_XLIB_KHR #define VK_USE_PLATFORM_XLIB_KHR
#define VK_USE_PLATFORM_WAYLAND_KHR #define VK_USE_PLATFORM_WAYLAND_KHR
@@ -1386,6 +1386,11 @@ void Device::RemoveUnsuitableExtensions() {
VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME); VK_KHR_PIPELINE_EXECUTABLE_PROPERTIES_EXTENSION_NAME);
} }
// VK_KHR_shader_quad_control
extensions.shader_quad_control = features.shader_quad_control.shaderQuadControl;
RemoveExtensionFeatureIfUnsuitable(extensions.shader_quad_control, features.shader_quad_control,
VK_KHR_SHADER_QUAD_CONTROL_EXTENSION_NAME);
// VK_KHR_workgroup_memory_explicit_layout // VK_KHR_workgroup_memory_explicit_layout
extensions.workgroup_memory_explicit_layout = extensions.workgroup_memory_explicit_layout =
features.workgroup_memory_explicit_layout.workgroupMemoryExplicitLayout && features.workgroup_memory_explicit_layout.workgroupMemoryExplicitLayout &&
@@ -75,6 +75,7 @@ VK_DEFINE_HANDLE(VmaAllocator)
FEATURE(KHR, Maintenance6, MAINTENANCE_6, maintenance6) \ FEATURE(KHR, Maintenance6, MAINTENANCE_6, maintenance6) \
FEATURE(KHR, PipelineExecutableProperties, PIPELINE_EXECUTABLE_PROPERTIES, \ FEATURE(KHR, PipelineExecutableProperties, PIPELINE_EXECUTABLE_PROPERTIES, \
pipeline_executable_properties) \ pipeline_executable_properties) \
FEATURE(KHR, ShaderQuadControl, SHADER_QUAD_CONTROL, shader_quad_control) \
FEATURE(KHR, WorkgroupMemoryExplicitLayout, WORKGROUP_MEMORY_EXPLICIT_LAYOUT, \ FEATURE(KHR, WorkgroupMemoryExplicitLayout, WORKGROUP_MEMORY_EXPLICIT_LAYOUT, \
workgroup_memory_explicit_layout) workgroup_memory_explicit_layout)
@@ -586,6 +587,11 @@ FN_MAX_LIMIT_LIST
features.features.shaderInt16; features.features.shaderInt16;
} }
/// Returns true if the device supports VK_KHR_shader_quad_control.
bool IsKhrShaderQuadControlSupported() const {
return extensions.shader_quad_control && features.shader_quad_control.shaderQuadControl;
}
/// Returns true if the device supports VK_KHR_image_format_list. /// Returns true if the device supports VK_KHR_image_format_list.
bool IsKhrImageFormatListSupported() const { bool IsKhrImageFormatListSupported() const {
return extensions.image_format_list || instance_version >= VK_API_VERSION_1_2; return extensions.image_format_list || instance_version >= VK_API_VERSION_1_2;
@@ -59,6 +59,8 @@ namespace {
case Core::Frontend::WindowSystemType::Xcb: case Core::Frontend::WindowSystemType::Xcb:
extensions.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME); extensions.push_back(VK_KHR_XCB_SURFACE_EXTENSION_NAME);
break; break;
#elif defined(__OPENORBIS__)
// No vulkan
#else #else
case Core::Frontend::WindowSystemType::X11: case Core::Frontend::WindowSystemType::X11:
extensions.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME); extensions.push_back(VK_KHR_XLIB_SURFACE_EXTENSION_NAME);
@@ -113,9 +115,19 @@ void RemoveUnavailableLayers(const vk::InstanceDispatch& dld, std::vector<const
} }
} // Anonymous namespace } // Anonymous namespace
#ifdef __OPENORBIS__
extern "C" {
extern PFN_vkVoidFunction VKAPI_CALL vk_icdGetInstanceProcAddr(VkInstance instance, const char *pName);
}
#endif
vk::Instance CreateInstance(const Common::DynamicLibrary& library, vk::InstanceDispatch& dld, vk::Instance CreateInstance(const Common::DynamicLibrary& library, vk::InstanceDispatch& dld,
u32 required_version, Core::Frontend::WindowSystemType window_type, u32 required_version, Core::Frontend::WindowSystemType window_type,
bool enable_validation) { bool enable_validation) {
// ps4 doesn't have dlopen() or equivalent, Vulkan is directly shipped with the emu
#ifdef __OPENORBIS__
dld.vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)vk_icdGetInstanceProcAddr;
#else
if (!library.IsOpen()) { if (!library.IsOpen()) {
LOG_ERROR(Render_Vulkan, "Vulkan library not available"); LOG_ERROR(Render_Vulkan, "Vulkan library not available");
throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED); throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
@@ -124,6 +136,7 @@ vk::Instance CreateInstance(const Common::DynamicLibrary& library, vk::InstanceD
LOG_ERROR(Render_Vulkan, "vkGetInstanceProcAddr not present in Vulkan"); LOG_ERROR(Render_Vulkan, "vkGetInstanceProcAddr not present in Vulkan");
throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED); throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
} }
#endif
if (!vk::Load(dld)) { if (!vk::Load(dld)) {
LOG_ERROR(Render_Vulkan, "Failed to load Vulkan function pointers"); LOG_ERROR(Render_Vulkan, "Failed to load Vulkan function pointers");
throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED); throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
@@ -13,9 +13,11 @@
namespace Vulkan { namespace Vulkan {
std::shared_ptr<Common::DynamicLibrary> OpenLibrary( std::shared_ptr<Common::DynamicLibrary> OpenLibrary([[maybe_unused]] Core::Frontend::GraphicsContext* context) {
[[maybe_unused]] Core::Frontend::GraphicsContext* context) {
LOG_DEBUG(Render_Vulkan, "Looking for a Vulkan library"); LOG_DEBUG(Render_Vulkan, "Looking for a Vulkan library");
#if defined(__OPENORBIS__)
return std::make_shared<Common::DynamicLibrary>();
#else
#if defined(__ANDROID__) && defined(ARCHITECTURE_arm64) #if defined(__ANDROID__) && defined(ARCHITECTURE_arm64)
// Android manages its Vulkan driver from the frontend. // Android manages its Vulkan driver from the frontend.
return context->GetDriverLibrary(); return context->GetDriverLibrary();
@@ -46,6 +48,7 @@ std::shared_ptr<Common::DynamicLibrary> OpenLibrary(
#endif #endif
return library; return library;
#endif #endif
#endif
} }
} // namespace Vulkan } // namespace Vulkan
@@ -76,6 +76,8 @@ vk::SurfaceKHR CreateSurface(
throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED); throw vk::Exception(VK_ERROR_INITIALIZATION_FAILED);
} }
} }
#elif defined(__OPENORBIS__)
// No native
#else #else
if (window_info.type == Core::Frontend::WindowSystemType::X11) { if (window_info.type == Core::Frontend::WindowSystemType::X11) {
const VkXlibSurfaceCreateInfoKHR xlib_ci{ const VkXlibSurfaceCreateInfoKHR xlib_ci{
+1 -1
View File
@@ -100,7 +100,7 @@ void UpdateDialog::Download() {
client->set_read_timeout(timeout_seconds); client->set_read_timeout(timeout_seconds);
client->set_write_timeout(timeout_seconds); client->set_write_timeout(timeout_seconds);
#ifdef YUZU_BUNDLED_OPENSSL #if defined(YUZU_BUNDLED_OPENSSL) && !defined(__OPENORBIS__)
client->load_ca_cert_store(kCert, sizeof(kCert)); client->load_ca_cert_store(kCert, sizeof(kCert));
#endif #endif
+8
View File
@@ -75,3 +75,11 @@ if (NOT MSVC)
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-unused-parameter> $<$<COMPILE_LANGUAGE:C,CXX>:-Wno-unused-parameter>
$<$<COMPILE_LANGUAGE:C,CXX>:-Wno-missing-field-initializers>) $<$<COMPILE_LANGUAGE:C,CXX>:-Wno-missing-field-initializers>)
endif() endif()
if (OPENORBIS)
target_link_libraries(yuzu-cmd
PRIVATE OSMesa
PRIVATE SceVideoOut SceAudioOut ScePad SceSystemService
PRIVATE ps4sup)
create_ps4_eboot(yuzu-cmd eden-cli IV0000-BREW00090_00-EDENEMULAT000000)
endif()
+6 -4
View File
@@ -26,10 +26,12 @@
EmuWindow_SDL3::EmuWindow_SDL3(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_) EmuWindow_SDL3::EmuWindow_SDL3(InputCommon::InputSubsystem* input_subsystem_, Core::System& system_)
: input_subsystem{input_subsystem_}, system{system_} { : input_subsystem{input_subsystem_}, system{system_} {
input_subsystem->Initialize(); input_subsystem->Initialize();
if (!SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD)) { if (!SDL_InitSubSystem(SDL_INIT_VIDEO))
LOG_CRITICAL(Frontend, "Failed to initialize SDL3: {}, Exiting...", SDL_GetError()); LOG_CRITICAL(Frontend, "SDL_INIT_VIDEO: {}", SDL_GetError());
exit(1); if (!SDL_InitSubSystem(SDL_INIT_JOYSTICK))
} LOG_CRITICAL(Frontend, "SDL_INIT_JOYSTICK: {}", SDL_GetError());
if (!SDL_InitSubSystem(SDL_INIT_GAMEPAD))
LOG_CRITICAL(Frontend, "SDL_INIT_GAMEPAD: {}", SDL_GetError());
titlebar_timer = SDL_AddTimer(2000, [](void *userdata, SDL_TimerID, Uint32) -> Uint32 { titlebar_timer = SDL_AddTimer(2000, [](void *userdata, SDL_TimerID, Uint32) -> Uint32 {
auto* this_ = (EmuWindow_SDL3*)userdata; auto* this_ = (EmuWindow_SDL3*)userdata;
auto const results = this_->system.GetAndResetPerfStats(); auto const results = this_->system.GetAndResetPerfStats();
@@ -81,8 +81,12 @@ EmuWindow_SDL3_VK::EmuWindow_SDL3_VK(InputCommon::InputSubsystem* input_subsyste
window_info.type = Core::Frontend::WindowSystemType::Android; window_info.type = Core::Frontend::WindowSystemType::Android;
window_info.render_surface = android_window; window_info.render_surface = android_window;
} else { } else {
#ifdef __OPENORBIS__
window_info.type = Core::Frontend::WindowSystemType::Headless;
#else
LOG_CRITICAL(Frontend, "Unable to determine native window backend from SDL properties"); LOG_CRITICAL(Frontend, "Unable to determine native window backend from SDL properties");
std::exit(EXIT_FAILURE); std::exit(EXIT_FAILURE);
#endif
} }
OnResize(); OnResize();
+67 -2
View File
@@ -18,9 +18,12 @@
#include <fmt/ostream.h> #include <fmt/ostream.h>
#include "common/logging.h" #include "common/logging.h"
#include "common/param_package.h"
#include "common/scm_rev.h" #include "common/scm_rev.h"
#include "common/settings.h" #include "common/settings.h"
#include "common/settings_enums.h"
#include "common/string_util.h" #include "common/string_util.h"
#include "common/virtual_buffer.h"
#include "core/core.h" #include "core/core.h"
#include "core/core_timing.h" #include "core/core_timing.h"
#include "core/cpu_manager.h" #include "core/cpu_manager.h"
@@ -31,6 +34,8 @@
#include "core/hle/service/filesystem/filesystem.h" #include "core/hle/service/filesystem/filesystem.h"
#include "core/loader/loader.h" #include "core/loader/loader.h"
#include "frontend_common/config.h" #include "frontend_common/config.h"
#include "hid_core/frontend/emulated_controller.h"
#include "hid_core/hid_core.h"
#include "input_common/main.h" #include "input_common/main.h"
#include "network/network.h" #include "network/network.h"
#include "sdl_config.h" #include "sdl_config.h"
@@ -55,7 +60,13 @@
#include <unistd.h> #include <unistd.h>
#endif #endif
#ifdef _WIN32 #if defined(__OPENORBIS__)
#include <orbis/libkernel.h>
#include <orbis/SystemService.h>
#include <orbis/AudioOut.h>
#include <orbis/Pad.h>
#include <orbis/UserService.h>
#elif defined(_WIN32)
extern "C" { extern "C" {
// tells Nvidia and AMD drivers to use the dedicated GPU by default on laptops with switchable // tells Nvidia and AMD drivers to use the dedicated GPU by default on laptops with switchable
// graphics // graphics
@@ -192,6 +203,14 @@ extern "C" SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
freopen("CONOUT$", "wb", stderr); freopen("CONOUT$", "wb", stderr);
} }
#endif #endif
#ifdef __OPENORBIS__
// May prevent spurious crashes on swap handlers...
setvbuf(stdout, nullptr, _IONBF, 0);
setvbuf(stderr, nullptr, _IONBF, 0);
sceUserServiceInitialize(nullptr);
Common::InitSwap();
#endif
Common::Log::Initialize(); Common::Log::Initialize();
Common::Log::SetColorConsoleBackendEnabled(true); Common::Log::SetColorConsoleBackendEnabled(true);
@@ -212,7 +231,12 @@ extern "C" SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
std::optional<int> selected_user{}; std::optional<int> selected_user{};
std::optional<u16> override_gdb_port{}; std::optional<u16> override_gdb_port{};
bool use_multiplayer = false; bool use_multiplayer = false;
// Platforms that start with fullscreen
#if defined(__OPENORBIS__) || defined(__ANDROID__)
bool fullscreen = true;
#else
bool fullscreen = false; bool fullscreen = false;
#endif
bool force_null_render = false; bool force_null_render = false;
bool force_single_core = false; bool force_single_core = false;
std::string nickname{}; std::string nickname{};
@@ -240,7 +264,11 @@ extern "C" SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
{0, 0, 0, 0}, {0, 0, 0, 0},
// clang-format on // clang-format on
}; };
#ifdef __OPENORBIS__
// PS4 will use this path by default UNLESS overriden; this is so users
// can quickly launch whatever they want.
filepath = "/data/eden/games/test.nro";
#endif
while (optind < argc) { while (optind < argc) {
int arg = getopt_long(argc, argv, "g:fhvcip::c:u:d:", long_options, &option_index); int arg = getopt_long(argc, argv, "g:fhvcip::c:u:d:", long_options, &option_index);
if (arg != -1) { if (arg != -1) {
@@ -377,6 +405,8 @@ extern "C" SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
// Apply the command line arguments // Apply the command line arguments
state->system.ApplySettings(); state->system.ApplySettings();
Settings::values.renderer_backend.SetValue(Settings::RendererBackend::OpenGL_GLSL);
Common::Log::SetGlobalFilter(Common::Log::Filter(Common::Log::Level::Info));
switch (Settings::values.renderer_backend.GetValue()) { switch (Settings::values.renderer_backend.GetValue()) {
#ifdef HAS_OPENGL #ifdef HAS_OPENGL
@@ -451,6 +481,41 @@ extern "C" SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) {
} }
} }
{
auto emulated_controller = state->system.HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
auto const input_devices = input_subsystem.GetInputDevices();
for (const auto& e : input_devices) {
LOG_INFO(Input, "FOUND=Device -> {} {}", e.Get("display", "Unknown"), e.Serialize());
}
auto const& device = input_devices[3];
LOG_INFO(Input, "selected? {}", device.Serialize());
auto const button_mappings = input_subsystem.GetButtonMappingForDevice(device);
auto const analog_mappings = input_subsystem.GetAnalogMappingForDevice(device);
auto const motion_mappings = input_subsystem.GetMotionMappingForDevice(device);
for (const auto& pair : button_mappings)
emulated_controller->SetButtonParam(pair.first, pair.second);
for (const auto& pair : analog_mappings)
emulated_controller->SetStickParam(pair.first, pair.second);
for (const auto& pair : motion_mappings)
emulated_controller->SetMotionParam(pair.first, pair.second);
for (const auto& pair : button_mappings)
LOG_INFO(Input, "btn:{}:{}", pair.first, pair.second.Serialize());
for (const auto& pair : analog_mappings)
LOG_INFO(Input, "ang:{}:{}", pair.first, pair.second.Serialize());
for (const auto& pair : motion_mappings)
LOG_INFO(Input, "mot:{}:{}", pair.first, pair.second.Serialize());
emulated_controller->SaveCurrentConfig();
emulated_controller->ReloadFromSettings();
auto const mapped_devices = emulated_controller->GetMappedDevices();
LOG_INFO(Input, "AND SO, WHAT MAPPED DEVICES WE GOT?");
for (const auto& e : mapped_devices) {
LOG_INFO(Input, "Mapped=Device? -> {}", e.Get("display", "Unknown"));
}
}
// Core is loaded, start the GPU (makes the GPU contexts current to this thread) // Core is loaded, start the GPU (makes the GPU contexts current to this thread)
state->system.GPU().Start(); state->system.GPU().Start();
state->system.GetCpuManager().OnGpuReady(); state->system.GetCpuManager().OnGpuReady();