Compare commits
210 Commits
__refs_pul
...
__refs_pul
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e7cb20fbf0 | ||
|
|
add8d40f3f | ||
|
|
bba785d643 | ||
|
|
d904b0db58 | ||
|
|
defaaf4519 | ||
|
|
602cd3886d | ||
|
|
9d6339b887 | ||
|
|
07cfab72e0 | ||
|
|
3315af8f09 | ||
|
|
557b2496d7 | ||
|
|
96f446ff65 | ||
|
|
425b3923d2 | ||
|
|
096be16636 | ||
|
|
1e662e6e9a | ||
|
|
1a4e429d9e | ||
|
|
c3e22a2f6c | ||
|
|
6cccbf0eb3 | ||
|
|
ff883cc563 | ||
|
|
de7aa3106a | ||
|
|
386df282a3 | ||
|
|
e75aba3ed0 | ||
|
|
023aef053c | ||
|
|
2dafd0d287 | ||
|
|
c8a094e164 | ||
|
|
0b6da0c1ab | ||
|
|
dd62f125c3 | ||
|
|
7b219539a9 | ||
|
|
c457f34eb2 | ||
|
|
d9ca9d3472 | ||
|
|
0f363d37e6 | ||
|
|
c3005ee4d1 | ||
|
|
deec326ddf | ||
|
|
1d49680613 | ||
|
|
e27accc15d | ||
|
|
de646cef2d | ||
|
|
e1ee8f4657 | ||
|
|
d80991977a | ||
|
|
c85d04ebe1 | ||
|
|
8f13499bb8 | ||
|
|
952dba9c2b | ||
|
|
1a5098e8b8 | ||
|
|
6b4f37b544 | ||
|
|
5e46a9bb2b | ||
|
|
cb3ab6ec77 | ||
|
|
da3e13fea5 | ||
|
|
3a409d5c8f | ||
|
|
0e7749a500 | ||
|
|
59575d5cae | ||
|
|
463356f0a7 | ||
|
|
195b4b5129 | ||
|
|
378cea2ae2 | ||
|
|
c7c180fdf1 | ||
|
|
2ff1cebfbe | ||
|
|
b5bc94bce0 | ||
|
|
da21545a77 | ||
|
|
be0e14ab3e | ||
|
|
4ca5f0c145 | ||
|
|
22465c8722 | ||
|
|
ed788742bf | ||
|
|
cf0daed0b8 | ||
|
|
32eb620ef4 | ||
|
|
01b3bf119e | ||
|
|
3ebe56524c | ||
|
|
138c03d565 | ||
|
|
5d38bb36c3 | ||
|
|
36dc44fb22 | ||
|
|
e710a1b989 | ||
|
|
6a36ffb86c | ||
|
|
18507b09b2 | ||
|
|
73c0ef7453 | ||
|
|
4497eb4528 | ||
|
|
c81ed5eb33 | ||
|
|
62a8c61e36 | ||
|
|
3d19102c48 | ||
|
|
14069e6ec4 | ||
|
|
b16c89bf65 | ||
|
|
01f379baa7 | ||
|
|
501d1cc33d | ||
|
|
94a6515b71 | ||
|
|
15318b6601 | ||
|
|
33eba9b96e | ||
|
|
ed296e47f1 | ||
|
|
2b3ee30a46 | ||
|
|
e50188374f | ||
|
|
ee08c39b72 | ||
|
|
d3e63e4220 | ||
|
|
e2f06dbc17 | ||
|
|
b17763e3d4 | ||
|
|
5fcf8d530a | ||
|
|
6f22471a72 | ||
|
|
c65ac49238 | ||
|
|
c7452bab90 | ||
|
|
f2b4b668e3 | ||
|
|
0568346cc3 | ||
|
|
8bff9c9152 | ||
|
|
10955d72ef | ||
|
|
66388f7576 | ||
|
|
7fa32af1c7 | ||
|
|
30d2ba9de3 | ||
|
|
1998a16557 | ||
|
|
7172ff4d9a | ||
|
|
b2386fc712 | ||
|
|
b588cbcb1d | ||
|
|
1c98f3a9b3 | ||
|
|
60d650cc4e | ||
|
|
d92636d424 | ||
|
|
d05dc3f4dd | ||
|
|
008823724f | ||
|
|
9ae55884d2 | ||
|
|
30cb98f874 | ||
|
|
d15cadd760 | ||
|
|
a66eb7351b | ||
|
|
dc905463dc | ||
|
|
4b156d2e64 | ||
|
|
eff90550a1 | ||
|
|
36b89787ce | ||
|
|
8c05e935bd | ||
|
|
f621310da2 | ||
|
|
9a9d33a741 | ||
|
|
cb75b56e45 | ||
|
|
30657f9ca1 | ||
|
|
f827b17dd4 | ||
|
|
c5a0408ccc | ||
|
|
f7dc637a61 | ||
|
|
bf0e20c571 | ||
|
|
3442f4b96a | ||
|
|
5bc14e791a | ||
|
|
1aa4cdc3c8 | ||
|
|
cb8d5328d5 | ||
|
|
0f6e3421c8 | ||
|
|
7338f089f8 | ||
|
|
4dc989f073 | ||
|
|
5f6e29831f | ||
|
|
07b465d24e | ||
|
|
bb7221c5d5 | ||
|
|
52fe15278b | ||
|
|
104dd867c4 | ||
|
|
68143af636 | ||
|
|
c903372111 | ||
|
|
aec3b28547 | ||
|
|
5d5f1dfb68 | ||
|
|
f4f64cc197 | ||
|
|
f10a7081e3 | ||
|
|
33778e4984 | ||
|
|
e35644c005 | ||
|
|
153205edbb | ||
|
|
af9a4539b1 | ||
|
|
1de165506f | ||
|
|
c2e4666579 | ||
|
|
09bcc2042c | ||
|
|
f53dc4c9d6 | ||
|
|
7c6c8da218 | ||
|
|
0a8d13801a | ||
|
|
2d7a85f7af | ||
|
|
8b097aa17e | ||
|
|
d818791866 | ||
|
|
3b28d382d0 | ||
|
|
8cdc1be0df | ||
|
|
f473780c52 | ||
|
|
d20a883194 | ||
|
|
b5b0d4e7c3 | ||
|
|
e026b66bbb | ||
|
|
713c1ed203 | ||
|
|
21f5161ad8 | ||
|
|
eaff98dbb3 | ||
|
|
20a745aa71 | ||
|
|
6f904bb622 | ||
|
|
e9cf161917 | ||
|
|
1a3b3e9100 | ||
|
|
1148e2ce7b | ||
|
|
5bc14ab0de | ||
|
|
8e2f62c6a5 | ||
|
|
67c8b671d2 | ||
|
|
054d3e5fc3 | ||
|
|
325f72aceb | ||
|
|
a4f5ccbf0a | ||
|
|
8d968780c1 | ||
|
|
58ee23f16d | ||
|
|
27960d8c2c | ||
|
|
af6e0faf0a | ||
|
|
9fba2d68fe | ||
|
|
1ea49442f9 | ||
|
|
bb1fcfac33 | ||
|
|
aa4fa8bded | ||
|
|
801d6c1b6f | ||
|
|
cdb43e64c1 | ||
|
|
74aa14c9b4 | ||
|
|
e08c132175 | ||
|
|
f2d55bb881 | ||
|
|
22347e8844 | ||
|
|
af1ca87be1 | ||
|
|
2678dbfbe6 | ||
|
|
b1712b8312 | ||
|
|
92801b1c34 | ||
|
|
f3264dd78d | ||
|
|
ebd613c2cc | ||
|
|
2adde6ae8b | ||
|
|
554cc9488f | ||
|
|
71eeab257f | ||
|
|
7bedea73a8 | ||
|
|
d81a984d4a | ||
|
|
2e8246a02c | ||
|
|
7a50d56d0e | ||
|
|
f4a3d28224 | ||
|
|
979483c7dd | ||
|
|
b20dfb357b | ||
|
|
115d3e133f | ||
|
|
22659afcd0 | ||
|
|
974362bc12 | ||
|
|
bd58c5470c |
3
.gitmodules
vendored
3
.gitmodules
vendored
@@ -19,3 +19,6 @@
|
||||
[submodule "lz4"]
|
||||
path = externals/lz4
|
||||
url = http://github.com/lz4/lz4.git
|
||||
[submodule "unicorn"]
|
||||
path = externals/unicorn
|
||||
url = https://github.com/yuzu-emu/unicorn
|
||||
|
||||
24
.travis.yml
24
.travis.yml
@@ -1,6 +1,18 @@
|
||||
language: cpp
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
env: NAME="clang-format"
|
||||
dist: trusty
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- sourceline: 'deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-6.0 main'
|
||||
key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key'
|
||||
- sourceline: 'deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu trusty main'
|
||||
packages:
|
||||
- clang-format-6.0
|
||||
script: "./.travis/clang-format/script.sh"
|
||||
- os: linux
|
||||
env: NAME="linux build"
|
||||
sudo: required
|
||||
@@ -16,23 +28,15 @@ matrix:
|
||||
- os: osx
|
||||
env: NAME="macos build"
|
||||
sudo: false
|
||||
osx_image: xcode7.3
|
||||
osx_image: xcode9.2
|
||||
install: "./.travis/macos/deps.sh"
|
||||
script: "./.travis/macos/build.sh"
|
||||
after_success: "./.travis/macos/upload.sh"
|
||||
- os: linux
|
||||
env: NAME="clang-format"
|
||||
dist: trusty
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- clang-format-3.9
|
||||
script: "./.travis/clang-format/script.sh"
|
||||
|
||||
deploy:
|
||||
provider: releases
|
||||
api_key:
|
||||
secure: Mck15DIWaJdxDiS3aYVlM9N3G6y8VKUI1rnwII7/iolfm1s94U+tgvbheZDmT7SSbFyaGaYO/E8HrV/uZR9Vvs7ev20sHsTN1u60OTWfDIIyHs9SqjhcGbtq95m9/dMFschOYqTOR+gAs5BsxjuoeAotHdhpQEwvkO2oo5oR0zhGy45gjFnVvtcxT/IfpZBIpVgcK3aLb9zT6ekcJbSiPmEB15iLq3xXd0nFUNtEZdX3D6Veye4n5jB6n72qN8JVoKvPZAwaC2K0pZxpcGJaXDchLsw1q+4eCvdz6UJfUemeQ/uMAmjfeQ3wrzYGXe3nCM3WmX5wosCsB0mw4zYatzl3si6CZ1W+0GkV4Rwlx03dfp7v3EeFhTsXYCaXqhwuLZnWOLUik8t9vaSoFUx4nUIRwfO9kAMUJQSpLuHNO2nT01s3GxvqxzczuLQ9he5nGSi0RRodUzDwek1qUp6I4uV3gRHKz4B07YIc1i2fK88NLXjyQ0uLVZ+7Oq1+kgDp6+N7vvXXZ5qZ17tdaysSbKEE0Y8zsoXw7Rk1tPN19vrCS+TSpomNMyQyne1k+I5iZ/qkxPTLAS5qI6Utc2dL3GJdxWRAEfGNO9AIX3GV/jmmKfdcvwGsCYP8hxqs5vLYfgacw3D8NLf1941lQUwavC17jm9EV9g5G3Pn1Cp516E=
|
||||
secure: ElsIAlbvVXBNKsP31nVPysh+mf0GQA4DiL/y5iJeQxKQYR6iRoNo+RfzOBmdswdo0bE/PGeBAlfzCkp15gjhWf6Je0N6dRpczmcmLq6SSQFn1Mpq00xMJB2AgQIlaHs6KFgoUA173EBKbPwgU/NubTFpJFm/Wa+NcSWAHQXKL9KT2M3qKpxNkPl3mKEVsbch4REP+T/46vsa+ikw0VE0kIs6V93LqUQZpI2F0Dhihx8Cxr5iedkE1QsNK+QSX9iItMHbfek9OH980gP7L3lkZltyAA1Pk0c37OAgz2PwczwNKwCT8jg9PMzdcKmWouvLyAkZFuA806ElzwHY3oEd91Zm6+Bk5n24yBKZ9027AZzw38NK2Z2m9Akb8+ar8PdsKU6N5pDutX9qSLayr0oMgJ0s7/xnGBGdL3gfkPCFc50xO/2DxlsOR+zAhPNM9Y76hhGy6A7/40+9uzrJvd4nAuDvIXRzi2Yl2L7mKBE4suMKbFLtk2LlgM0qY5JMVTQ8NliaEtqopfPur2KWFVJUpWDNLtNX8xGqhfwg7cLjIiGmnxSaJBTDuZI6dpEjkWkU0n1xYhGqEqit8DbehYzazozMJ+Vsr8hku7jGlUtlw+U6HG1e19O2y4aGeSwYPROcCNz+BLwmVM8oZE3Roy3qoaa2yiFf+sy6rUHznrhsfEM=
|
||||
file_glob: true
|
||||
file: "artifacts/*"
|
||||
skip_cleanup: true
|
||||
|
||||
@@ -7,7 +7,7 @@ if grep -nr '\s$' src *.yml *.txt *.md Doxyfile .gitignore .gitmodules .travis*
|
||||
fi
|
||||
|
||||
# Default clang-format points to default 3.5 version one
|
||||
CLANG_FORMAT=clang-format-3.9
|
||||
CLANG_FORMAT=clang-format-6.0
|
||||
$CLANG_FORMAT --version
|
||||
|
||||
if [ "$TRAVIS_EVENT_TYPE" = "pull_request" ]; then
|
||||
|
||||
@@ -1,22 +1,16 @@
|
||||
#!/bin/bash -ex
|
||||
|
||||
apt-get update
|
||||
apt-get install -y build-essential git libcurl4-openssl-dev libqt5opengl5-dev libsdl2-dev libssl-dev python qtbase5-dev wget
|
||||
apt-get install -y build-essential git libqt5opengl5-dev libsdl2-dev libssl-dev python qtbase5-dev wget
|
||||
|
||||
# Get a recent version of CMake
|
||||
wget https://cmake.org/files/v3.10/cmake-3.10.1-Linux-x86_64.sh
|
||||
sh cmake-3.10.1-Linux-x86_64.sh --exclude-subdir --prefix=/ --skip-license
|
||||
|
||||
mkdir /unicorn
|
||||
cd /unicorn
|
||||
git clone https://github.com/yuzu-emu/unicorn .
|
||||
UNICORN_ARCHS=aarch64 ./make.sh
|
||||
./make.sh install
|
||||
|
||||
cd /yuzu
|
||||
|
||||
mkdir build && cd build
|
||||
cmake .. -DUSE_SYSTEM_CURL=ON -DCMAKE_BUILD_TYPE=Release
|
||||
cmake .. -DYUZU_BUILD_UNICORN=ON -DCMAKE_BUILD_TYPE=Release
|
||||
make -j4
|
||||
|
||||
ctest -VV -C Release
|
||||
|
||||
@@ -8,7 +8,7 @@ export UNICORNDIR=$(pwd)/externals/unicorn
|
||||
|
||||
mkdir build && cd build
|
||||
cmake --version
|
||||
cmake .. -DUSE_SYSTEM_CURL=ON -DCMAKE_OSX_ARCHITECTURES="x86_64;x86_64h" -DCMAKE_BUILD_TYPE=Release
|
||||
cmake .. -DYUZU_BUILD_UNICORN=ON -DCMAKE_OSX_ARCHITECTURES="x86_64;x86_64h" -DCMAKE_BUILD_TYPE=Release
|
||||
make -j4
|
||||
|
||||
ctest -VV -C Release
|
||||
|
||||
@@ -2,9 +2,4 @@
|
||||
|
||||
brew update
|
||||
brew install dylibbundler p7zip qt5 sdl2
|
||||
|
||||
mkdir externals/unicorn
|
||||
pushd externals/unicorn
|
||||
git clone https://github.com/yuzu-emu/unicorn .
|
||||
UNICORN_ARCHS=aarch64 ./make.sh macos-universal-no
|
||||
popd
|
||||
brew outdated cmake || brew upgrade cmake
|
||||
|
||||
159
CMakeLists.txt
159
CMakeLists.txt
@@ -3,16 +3,19 @@ cmake_minimum_required(VERSION 3.6)
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/CMakeModules")
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules")
|
||||
include(DownloadExternals)
|
||||
include(CMakeDependentOption)
|
||||
|
||||
project(yuzu)
|
||||
|
||||
# Set bundled sdl2/qt as dependent options.
|
||||
# OFF by default, but if ENABLE_SDL2 and MSVC are true then ON
|
||||
option(ENABLE_SDL2 "Enable the SDL2 frontend" ON)
|
||||
option(CITRA_USE_BUNDLED_SDL2 "Download bundled SDL2 binaries" OFF)
|
||||
CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_SDL2 "Download bundled SDL2 binaries" ON "ENABLE_SDL2;MSVC" OFF)
|
||||
|
||||
option(ENABLE_QT "Enable the Qt frontend" ON)
|
||||
option(CITRA_USE_BUNDLED_QT "Download bundled Qt binaries" OFF)
|
||||
CMAKE_DEPENDENT_OPTION(YUZU_USE_BUNDLED_QT "Download bundled Qt binaries" ON "ENABLE_SDL2;MSVC" OFF)
|
||||
|
||||
option(YUZU_USE_BUNDLED_UNICORN "Download bundled Unicorn binaries" OFF)
|
||||
option(YUZU_USE_BUNDLED_UNICORN "Build/Download bundled Unicorn" ON)
|
||||
|
||||
if(NOT EXISTS ${CMAKE_SOURCE_DIR}/.git/hooks/pre-commit)
|
||||
message(STATUS "Copying pre-commit hook")
|
||||
@@ -29,7 +32,7 @@ function(check_submodules_present)
|
||||
foreach(module ${gitmodules})
|
||||
string(REGEX REPLACE "path *= *" "" module ${module})
|
||||
if (NOT EXISTS "${CMAKE_SOURCE_DIR}/${module}/.git")
|
||||
message(SEND_ERROR "Git submodule ${module} not found."
|
||||
message(FATAL_ERROR "Git submodule ${module} not found. "
|
||||
"Please run: git submodule update --init --recursive")
|
||||
endif()
|
||||
endforeach()
|
||||
@@ -56,15 +59,18 @@ function(detect_architecture symbol arch)
|
||||
endif()
|
||||
endfunction()
|
||||
|
||||
if (MSVC)
|
||||
detect_architecture("_M_AMD64" x86_64)
|
||||
detect_architecture("_M_IX86" x86)
|
||||
detect_architecture("_M_ARM" ARM)
|
||||
else()
|
||||
detect_architecture("__x86_64__" x86_64)
|
||||
detect_architecture("__i386__" x86)
|
||||
detect_architecture("__arm__" ARM)
|
||||
if (NOT ENABLE_GENERIC)
|
||||
if (MSVC)
|
||||
detect_architecture("_M_AMD64" x86_64)
|
||||
detect_architecture("_M_IX86" x86)
|
||||
detect_architecture("_M_ARM" ARM)
|
||||
else()
|
||||
detect_architecture("__x86_64__" x86_64)
|
||||
detect_architecture("__i386__" x86)
|
||||
detect_architecture("__arm__" ARM)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (NOT DEFINED ARCHITECTURE)
|
||||
set(ARCHITECTURE "GENERIC")
|
||||
set(ARCHITECTURE_GENERIC 1)
|
||||
@@ -134,6 +140,12 @@ else()
|
||||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE "/DEBUG /MANIFEST:NO /INCREMENTAL:NO /OPT:REF,ICF" CACHE STRING "" FORCE)
|
||||
endif()
|
||||
|
||||
# Fix GCC C++17 and Boost.ICL incompatibility (needed to build dynarmic)
|
||||
# See https://bugzilla.redhat.com/show_bug.cgi?id=1485641#c1
|
||||
if (CMAKE_COMPILER_IS_GNUCC)
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-new-ttp-matching")
|
||||
endif()
|
||||
|
||||
# Set file offset size to 64 bits.
|
||||
#
|
||||
# On modern Unixes, this is typically already the case. The lone exception is
|
||||
@@ -168,12 +180,12 @@ set(THREADS_PREFER_PTHREAD_FLAG ON)
|
||||
find_package(Threads REQUIRED)
|
||||
|
||||
if (ENABLE_SDL2)
|
||||
if (CITRA_USE_BUNDLED_SDL2)
|
||||
if (YUZU_USE_BUNDLED_SDL2)
|
||||
# Detect toolchain and platform
|
||||
if (MSVC14 AND ARCHITECTURE_x86_64)
|
||||
set(SDL2_VER "SDL2-2.0.5")
|
||||
else()
|
||||
message(FATAL_ERROR "No bundled SDL2 binaries for your toolchain. Disable CITRA_USE_BUNDLED_SDL2 and provide your own.")
|
||||
message(FATAL_ERROR "No bundled SDL2 binaries for your toolchain. Disable YUZU_USE_BUNDLED_SDL2 and provide your own.")
|
||||
endif()
|
||||
|
||||
if (DEFINED SDL2_VER)
|
||||
@@ -198,26 +210,56 @@ else()
|
||||
set(SDL2_FOUND NO)
|
||||
endif()
|
||||
|
||||
# If unicorn isn't found, msvc -> download bundled unicorn; everyone else -> build external
|
||||
if (YUZU_USE_BUNDLED_UNICORN)
|
||||
# Detect toolchain and platform
|
||||
if (MSVC14 AND ARCHITECTURE_x86_64)
|
||||
set(UNICORN_VER "unicorn-yuzu")
|
||||
if (MSVC)
|
||||
message(STATUS "unicorn not found, falling back to bundled")
|
||||
# Detect toolchain and platform
|
||||
if (MSVC14 AND ARCHITECTURE_x86_64)
|
||||
set(UNICORN_VER "unicorn-yuzu")
|
||||
else()
|
||||
message(FATAL_ERROR "No bundled Unicorn binaries for your toolchain. Disable YUZU_USE_BUNDLED_UNICORN and provide your own.")
|
||||
endif()
|
||||
|
||||
if (DEFINED UNICORN_VER)
|
||||
download_bundled_external("unicorn/" ${UNICORN_VER} UNICORN_PREFIX)
|
||||
endif()
|
||||
|
||||
if (DEFINED UNICORN_VER)
|
||||
download_bundled_external("unicorn/" ${UNICORN_VER} UNICORN_PREFIX)
|
||||
endif()
|
||||
|
||||
set(UNICORN_FOUND YES)
|
||||
set(LIBUNICORN_INCLUDE_DIR "${UNICORN_PREFIX}/include" CACHE PATH "Path to Unicorn headers" FORCE)
|
||||
set(LIBUNICORN_LIBRARY "${UNICORN_PREFIX}/lib/x64/unicorn_dynload.lib" CACHE PATH "Path to Unicorn library" FORCE)
|
||||
set(UNICORN_DLL_DIR "${UNICORN_PREFIX}/lib/x64/" CACHE PATH "Path to unicorn.dll" FORCE)
|
||||
else()
|
||||
message(FATAL_ERROR "No bundled Unicorn binaries for your toolchain. Disable YUZU_USE_BUNDLED_UNICORN and provide your own.")
|
||||
endif()
|
||||
message(STATUS "unicorn not found, falling back to externals")
|
||||
if (MINGW)
|
||||
set(UNICORN_LIB_NAME "unicorn.a")
|
||||
else()
|
||||
set(UNICORN_LIB_NAME "libunicorn.a")
|
||||
endif()
|
||||
|
||||
if (DEFINED UNICORN_VER)
|
||||
download_bundled_external("unicorn/" ${UNICORN_VER} UNICORN_PREFIX)
|
||||
endif()
|
||||
set(UNICORN_FOUND YES)
|
||||
set(UNICORN_PREFIX ${CMAKE_SOURCE_DIR}/externals/unicorn)
|
||||
set(LIBUNICORN_LIBRARY "${UNICORN_PREFIX}/${UNICORN_LIB_NAME}" CACHE PATH "Path to Unicorn library" FORCE)
|
||||
set(LIBUNICORN_INCLUDE_DIR "${UNICORN_PREFIX}/include" CACHE PATH "Path to Unicorn headers" FORCE)
|
||||
set(UNICORN_DLL_DIR "${UNICORN_PREFIX}/" CACHE PATH "Path to unicorn dynamic library" FORCE)
|
||||
|
||||
if (DEFINED UNICORN_VER)
|
||||
download_bundled_external("unicorn/" ${UNICORN_VER} UNICORN_PREFIX)
|
||||
endif()
|
||||
find_package(PythonInterp 2.7 REQUIRED)
|
||||
|
||||
set(UNICORN_FOUND YES)
|
||||
set(LIBUNICORN_INCLUDE_DIR "${UNICORN_PREFIX}/include" CACHE PATH "Path to Unicorn headers")
|
||||
set(LIBUNICORN_LIBRARY "${UNICORN_PREFIX}/lib/x64/unicorn_dynload.lib" CACHE PATH "Path to Unicorn library")
|
||||
set(UNICORN_DLL_DIR "${UNICORN_PREFIX}/lib/x64/" CACHE PATH "Path to unicorn.dll")
|
||||
add_custom_command(OUTPUT ${LIBUNICORN_LIBRARY}
|
||||
COMMAND ${CMAKE_COMMAND} -E env UNICORN_ARCHS="aarch64" PYTHON="${PYTHON_EXECUTABLE}" /bin/sh make.sh macos-universal-no
|
||||
WORKING_DIRECTORY ${UNICORN_PREFIX}
|
||||
)
|
||||
# ALL makes this custom target build every time
|
||||
# but it won't actually build if LIBUNICORN_LIBRARY is up to date
|
||||
add_custom_target(unicorn-build ALL
|
||||
DEPENDS ${LIBUNICORN_LIBRARY}
|
||||
)
|
||||
unset(UNICORN_LIB_NAME)
|
||||
endif()
|
||||
else()
|
||||
find_package(Unicorn REQUIRED)
|
||||
endif()
|
||||
@@ -226,14 +268,16 @@ if (UNICORN_FOUND)
|
||||
add_library(unicorn INTERFACE)
|
||||
target_link_libraries(unicorn INTERFACE "${LIBUNICORN_LIBRARY}")
|
||||
target_include_directories(unicorn INTERFACE "${LIBUNICORN_INCLUDE_DIR}")
|
||||
else()
|
||||
message(FATAL_ERROR "Could not find or build unicorn which is required.")
|
||||
endif()
|
||||
|
||||
if (ENABLE_QT)
|
||||
if (CITRA_USE_BUNDLED_QT)
|
||||
if (YUZU_USE_BUNDLED_QT)
|
||||
if (MSVC14 AND ARCHITECTURE_x86_64)
|
||||
set(QT_VER qt-5.7-msvc2015_64)
|
||||
else()
|
||||
message(FATAL_ERROR "No bundled Qt binaries for your toolchain. Disable CITRA_USE_BUNDLED_QT and provide your own.")
|
||||
message(FATAL_ERROR "No bundled Qt binaries for your toolchain. Disable YUZU_USE_BUNDLED_QT and provide your own.")
|
||||
endif()
|
||||
|
||||
if (DEFINED QT_VER)
|
||||
@@ -281,6 +325,53 @@ if (UNIX OR MINGW)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Setup a custom clang-format target (if clang-format can be found) that will run
|
||||
# against all the src files. This should be used before making a pull request.
|
||||
# =======================================================================
|
||||
|
||||
set(CLANG_FORMAT_POSTFIX "-6.0")
|
||||
find_program(CLANG_FORMAT
|
||||
NAMES clang-format${CLANG_FORMAT_POSTFIX}
|
||||
clang-format
|
||||
PATHS ${CMAKE_BINARY_DIR}/externals)
|
||||
# if find_program doesn't find it, try to download from externals
|
||||
if (NOT CLANG_FORMAT)
|
||||
if (WIN32)
|
||||
message(STATUS "Clang format not found! Downloading...")
|
||||
set(CLANG_FORMAT "${CMAKE_BINARY_DIR}/externals/clang-format${CLANG_FORMAT_POSTFIX}.exe")
|
||||
file(DOWNLOAD
|
||||
https://github.com/yuzu-emu/ext-windows-bin/raw/master/clang-format${CLANG_FORMAT_POSTFIX}.exe
|
||||
"${CLANG_FORMAT}" SHOW_PROGRESS
|
||||
STATUS DOWNLOAD_SUCCESS)
|
||||
if (NOT DOWNLOAD_SUCCESS EQUAL 0)
|
||||
message(WARNING "Could not download clang format! Disabling the clang format target")
|
||||
file(REMOVE ${CLANG_FORMAT})
|
||||
unset(CLANG_FORMAT)
|
||||
endif()
|
||||
else()
|
||||
message(WARNING "Clang format not found! Disabling the clang format target")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if (CLANG_FORMAT)
|
||||
set(SRCS ${CMAKE_SOURCE_DIR}/src)
|
||||
set(CCOMMENT "Running clang format against all the .h and .cpp files in src/")
|
||||
if (WIN32)
|
||||
add_custom_target(clang-format
|
||||
COMMAND powershell.exe -Command "${CLANG_FORMAT} -i @(Get-ChildItem -Recurse ${SRCS}/* -Include \'*.h\', \'*.cpp\')"
|
||||
COMMENT ${CCOMMENT})
|
||||
elseif(MINGW)
|
||||
add_custom_target(clang-format
|
||||
COMMAND find `cygpath -u ${SRCS}` -iname *.h -o -iname *.cpp | xargs `cygpath -u ${CLANG_FORMAT}` -i
|
||||
COMMENT ${CCOMMENT})
|
||||
else()
|
||||
add_custom_target(clang-format
|
||||
COMMAND find ${SRCS} -iname *.h -o -iname *.cpp | xargs ${CLANG_FORMAT} -i
|
||||
COMMENT ${CCOMMENT})
|
||||
endif()
|
||||
unset(SRCS)
|
||||
unset(CCOMMENT)
|
||||
endif()
|
||||
|
||||
# Include source code
|
||||
# ===================
|
||||
@@ -288,12 +379,14 @@ endif()
|
||||
# This function should be passed a list of all files in a target. It will automatically generate
|
||||
# file groups following the directory hierarchy, so that the layout of the files in IDEs matches the
|
||||
# one in the filesystem.
|
||||
function(create_directory_groups)
|
||||
function(create_target_directory_groups target_name)
|
||||
# Place any files that aren't in the source list in a separate group so that they don't get in
|
||||
# the way.
|
||||
source_group("Other Files" REGULAR_EXPRESSION ".")
|
||||
|
||||
foreach(file_name ${ARGV})
|
||||
get_target_property(target_sources "${target_name}" SOURCES)
|
||||
|
||||
foreach(file_name IN LISTS target_sources)
|
||||
get_filename_component(dir_name "${file_name}" PATH)
|
||||
# Group names use '\' as a separator even though the entire rest of CMake uses '/'...
|
||||
string(REPLACE "/" "\\" group_name "${dir_name}")
|
||||
|
||||
@@ -5,7 +5,16 @@
|
||||
If you believe you have a valid issue report, please post text or a screenshot from the log (the console window that opens alongside yuzu) and build version (hex string visible in the titlebar and zip filename), as well as your hardware and software information if applicable.
|
||||
|
||||
# Contributing
|
||||
yuzu is a brand new project, so we have a great opportunity to keep things clean and well organized early on. As such, coding style is very important when making commits. We run clang-format on our CI to check the code. Please use it to format your code when contributing. However, it doesn't cover all the rules below. Some of them aren't very strict rules since we want to be flexible and we understand that under certain circumstances some of them can be counterproductive. Just try to follow as many of them as possible:
|
||||
yuzu is a brand new project, so we have a great opportunity to keep things clean and well organized early on. As such, coding style is very important when making commits. We run clang-format on our CI to check the code. Please use it to format your code when contributing. However, it doesn't cover all the rules below. Some of them aren't very strict rules since we want to be flexible and we understand that under certain circumstances some of them can be counterproductive. Just try to follow as many of them as possible.
|
||||
|
||||
# Using clang format (version 6.0)
|
||||
When generating the native build script for your toolset, cmake will try to find the correct version of clang format (or will download it on windows). Before running cmake, please install clang format version 6.0 for your platform as follows:
|
||||
|
||||
* Windows: do nothing; cmake will download a pre built binary for MSVC and MINGW. MSVC users can additionally install a clang format Visual Studio extension to add features like format on save.
|
||||
* OSX: run `brew install clang-format`.
|
||||
* Linux: use your package manager to get an appropriate binary.
|
||||
|
||||
If clang format is found, then cmake will add a custom build target that can be run at any time to run clang format against *all* source files and update the formatting in them. This should be used before making a pull request so that the reviewers can spend more time reviewing the code instead of having to worry about minor style violations. On MSVC, you can run clang format by building the clang-format project in the solution. On OSX, you can either use the Makefile target `make clang-format` or by building the clang-format target in XCode. For Makefile builds, you can use the clang-format target with `make clang-format`
|
||||
|
||||
### General Rules
|
||||
* A lot of code was taken from other projects (e.g. Citra, Dolphin, PPSSPP, Gekko). In general, when editing other people's code, follow the style of the module you're in (or better yet, fix the style if it drastically differs from our guide).
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
yuzu emulator
|
||||
=============
|
||||
[](https://travis-ci.org/yuzu-emu/yuzu)
|
||||
[](https://ci.appveyor.com/project/bunnei/yuzu)
|
||||
|
||||
yuzu is an experimental open-source emulator for the Nintendo Switch from the creators of [Citra](https://citra-emu.org/).
|
||||
|
||||
It is written in C++ with portability in mind, with builds actively maintained for Windows, Linux and macOS. The emulator is currently only useful for homebrew development and research purposes.
|
||||
@@ -10,7 +13,7 @@ yuzu is licensed under the GPLv2 (or any later version). Refer to the license.tx
|
||||
|
||||
Check out our [website](https://yuzu-emu.org/)!
|
||||
|
||||
For development discussion, please join us on [Discord](https://discord.gg/VXqngT3).
|
||||
For development discussion, please join us on [Discord](https://discord.gg/XQV6dn9).
|
||||
|
||||
### Development
|
||||
|
||||
|
||||
31
appveyor.yml
31
appveyor.yml
@@ -13,8 +13,8 @@ environment:
|
||||
# Tell msys2 to inherit the current directory when starting the shell
|
||||
CHERE_INVOKING: 1
|
||||
matrix:
|
||||
- BUILD_TYPE: mingw
|
||||
- BUILD_TYPE: msvc
|
||||
- BUILD_TYPE: mingw
|
||||
|
||||
platform:
|
||||
- x64
|
||||
@@ -28,7 +28,6 @@ install:
|
||||
if ($env:BUILD_TYPE -eq 'mingw') {
|
||||
$dependencies = "mingw64/mingw-w64-x86_64-cmake",
|
||||
"mingw64/mingw-w64-x86_64-qt5",
|
||||
"mingw64/mingw-w64-x86_64-curl",
|
||||
"mingw64/mingw-w64-x86_64-SDL2"
|
||||
# redirect err to null to prevent warnings from becoming errors
|
||||
# workaround to prevent pacman from failing due to cyclical dependencies
|
||||
@@ -42,9 +41,9 @@ before_build:
|
||||
- ps: |
|
||||
if ($env:BUILD_TYPE -eq 'msvc') {
|
||||
# redirect stderr and change the exit code to prevent powershell from cancelling the build if cmake prints a warning
|
||||
cmd /C 'cmake -G "Visual Studio 15 2017 Win64" -DYUZU_USE_BUNDLED_QT=1 -DYUZU_USE_BUNDLED_SDL2=1 -DYUZU_USE_BUNDLED_UNICORN=1 -DCMAKE_USE_OPENSSL=0 .. 2>&1 && exit 0'
|
||||
cmd /C 'cmake -G "Visual Studio 15 2017 Win64" -DYUZU_USE_BUNDLED_QT=1 -DYUZU_USE_BUNDLED_SDL2=1 -DYUZU_USE_BUNDLED_UNICORN=1 .. 2>&1 && exit 0'
|
||||
} else {
|
||||
C:\msys64\usr\bin\bash.exe -lc "cmake -G 'MSYS Makefiles' -DUSE_SYSTEM_CURL=1 -DYUZU_USE_BUNDLED_CURL=1 -DCMAKE_BUILD_TYPE=Release .. 2>&1"
|
||||
C:\msys64\usr\bin\bash.exe -lc "cmake -G 'MSYS Makefiles' -DYUZU_BUILD_UNICORN=1 -DCMAKE_BUILD_TYPE=Release .. 2>&1"
|
||||
}
|
||||
- cd ..
|
||||
|
||||
@@ -81,11 +80,19 @@ after_build:
|
||||
$env:BUILD_SYMBOLS = $MSVC_BUILD_PDB
|
||||
$env:BUILD_UPDATE = $MSVC_SEVENZIP
|
||||
|
||||
7z a -tzip $MSVC_BUILD_PDB .\msvc_build\bin\release\*.pdb
|
||||
rm .\msvc_build\bin\release\*.pdb
|
||||
$BUILD_DIR = ".\msvc_build\bin\Release"
|
||||
|
||||
# Make a debug symbol upload
|
||||
mkdir pdb
|
||||
Get-ChildItem "$BUILD_DIR\" -Recurse -Filter "*.pdb" | Copy-Item -destination .\pdb
|
||||
7z a -tzip $MSVC_BUILD_PDB .\pdb\*.pdb
|
||||
rm "$BUILD_DIR\*.pdb"
|
||||
|
||||
mkdir $RELEASE_DIST
|
||||
Copy-Item .\msvc_build\bin\release\* -Destination $RELEASE_DIST -Recurse
|
||||
# get rid of extra exes by copying everything over, then deleting all the exes, then copying just the exes we want
|
||||
Copy-Item "$BUILD_DIR\*" -Destination $RELEASE_DIST -Recurse
|
||||
rm "$RELEASE_DIST\*.exe"
|
||||
Get-ChildItem "$BUILD_DIR" -Recurse -Filter "yuzu*.exe" | Copy-Item -destination $RELEASE_DIST
|
||||
Copy-Item .\license.txt -Destination $RELEASE_DIST
|
||||
Copy-Item .\README.md -Destination $RELEASE_DIST
|
||||
7z a -tzip $MSVC_BUILD_ZIP $RELEASE_DIST\*
|
||||
@@ -104,16 +111,14 @@ after_build:
|
||||
$env:BUILD_UPDATE = $MINGW_SEVENZIP
|
||||
|
||||
$CMAKE_SOURCE_DIR = "$env:APPVEYOR_BUILD_FOLDER"
|
||||
$CMAKE_BINARY_DIR = "$CMAKE_SOURCE_DIR/mingw_build"
|
||||
$CMAKE_BINARY_DIR = "$CMAKE_SOURCE_DIR/mingw_build/bin"
|
||||
$RELEASE_DIST = $RELEASE_DIST + "-mingw"
|
||||
|
||||
mkdir $RELEASE_DIST
|
||||
mkdir $RELEASE_DIST/platforms
|
||||
|
||||
# copy the compiled binaries and other release files to the release folder
|
||||
Get-ChildItem "$CMAKE_BINARY_DIR" -Recurse -Filter "yuzu*.exe" | Copy-Item -destination $RELEASE_DIST
|
||||
# copy the libcurl dll
|
||||
Get-ChildItem "$CMAKE_BINARY_DIR" -Recurse -Filter "libcurl.dll" | Copy-Item -destination $RELEASE_DIST
|
||||
Get-ChildItem "$CMAKE_BINARY_DIR" -Filter "yuzu*.exe" | Copy-Item -destination $RELEASE_DIST
|
||||
Copy-Item -path "$CMAKE_SOURCE_DIR/license.txt" -destination $RELEASE_DIST
|
||||
Copy-Item -path "$CMAKE_SOURCE_DIR/README.md" -destination $RELEASE_DIST
|
||||
# copy all the dll dependencies to the release folder
|
||||
@@ -122,7 +127,7 @@ after_build:
|
||||
# QT dll dependencies
|
||||
"libbz2-*.dll","libicudt*.dll","libicuin*.dll","libicuuc*.dll","libffi-*.dll",
|
||||
"libfreetype-*.dll","libglib-*.dll","libgobject-*.dll","libgraphite2.dll","libiconv-*.dll",
|
||||
"libharfbuzz-*.dll","libintl-*.dll","libpcre-*.dll","libpcre16-*.dll","libpng16-*.dll",
|
||||
"libharfbuzz-*.dll","libintl-*.dll","libpcre-*.dll","libpcre2-16-*.dll","libpcre16-*.dll","libpng16-*.dll",
|
||||
# Runtime/Other dependencies
|
||||
"libgcc_s_seh-*.dll","libstdc++-*.dll","libwinpthread-*.dll","SDL2.dll","zlib1.dll"
|
||||
foreach ($file in $MingwDLLs) {
|
||||
@@ -165,7 +170,7 @@ deploy:
|
||||
provider: GitHub
|
||||
release: $(appveyor_repo_tag_name)
|
||||
auth_token:
|
||||
secure: "dbpsMC/MgPKWFNJCXpQl4cR8FYhepkPLjgNp/pRMktZ8oLKTqPYErfreaIxb/4P1"
|
||||
secure: QqePPnXbkzmXct5c8hZ2X5AbsthbI6cS1Sr+VBzcD8oUOIjfWJJKXVAQGUbQAbb0
|
||||
artifact: update,build
|
||||
draft: false
|
||||
prerelease: false
|
||||
|
||||
2
externals/catch
vendored
2
externals/catch
vendored
Submodule externals/catch updated: 3dcc923351...cd76f5730c
2
externals/dynarmic
vendored
2
externals/dynarmic
vendored
Submodule externals/dynarmic updated: bc73004dd5...a6d17e6bb0
14
externals/getopt/CMakeLists.txt
vendored
14
externals/getopt/CMakeLists.txt
vendored
@@ -1,11 +1,9 @@
|
||||
set(SRCS
|
||||
getopt.c
|
||||
)
|
||||
set(HEADERS
|
||||
getopt.h
|
||||
)
|
||||
add_library(getopt
|
||||
getopt.c
|
||||
getopt.h
|
||||
)
|
||||
|
||||
create_target_directory_groups(getopt)
|
||||
|
||||
create_directory_groups(${SRCS} ${HEADERS})
|
||||
add_library(getopt ${SRCS} ${HEADERS})
|
||||
target_compile_definitions(getopt PUBLIC STATIC_GETOPT)
|
||||
target_include_directories(getopt INTERFACE ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
|
||||
15
externals/glad/CMakeLists.txt
vendored
15
externals/glad/CMakeLists.txt
vendored
@@ -1,13 +1,10 @@
|
||||
set(SRCS
|
||||
src/glad.c
|
||||
)
|
||||
set(HEADERS
|
||||
include/KHR/khrplatform.h
|
||||
include/glad/glad.h
|
||||
)
|
||||
add_library(glad STATIC
|
||||
src/glad.c
|
||||
include/KHR/khrplatform.h
|
||||
include/glad/glad.h
|
||||
)
|
||||
|
||||
create_directory_groups(${SRCS} ${HEADERS})
|
||||
add_library(glad STATIC ${SRCS} ${HEADERS})
|
||||
create_target_directory_groups(glad)
|
||||
target_include_directories(glad PUBLIC "include/")
|
||||
|
||||
if ("${CMAKE_SYSTEM_NAME}" MATCHES "Linux")
|
||||
|
||||
17
externals/inih/CMakeLists.txt
vendored
17
externals/inih/CMakeLists.txt
vendored
@@ -1,12 +1,9 @@
|
||||
set(SRCS
|
||||
inih/ini.c
|
||||
inih/cpp/INIReader.cpp
|
||||
)
|
||||
set(HEADERS
|
||||
inih/ini.h
|
||||
inih/cpp/INIReader.h
|
||||
)
|
||||
add_library(inih
|
||||
inih/ini.c
|
||||
inih/ini.h
|
||||
inih/cpp/INIReader.cpp
|
||||
inih/cpp/INIReader.h
|
||||
)
|
||||
|
||||
create_directory_groups(${SRCS} ${HEADERS})
|
||||
add_library(inih ${SRCS} ${HEADERS})
|
||||
create_target_directory_groups(inih)
|
||||
target_include_directories(inih INTERFACE .)
|
||||
|
||||
14
externals/microprofile/microprofileui.h
vendored
14
externals/microprofile/microprofileui.h
vendored
@@ -1853,7 +1853,7 @@ void MicroProfileDrawBarView(uint32_t nScreenWidth, uint32_t nScreenHeight)
|
||||
{
|
||||
if(nMetaIndex < MICROPROFILE_META_MAX && S.MetaCounters[nMetaIndex].pName)
|
||||
{
|
||||
uint32_t nStrWidth = strlen(S.MetaCounters[nMetaIndex].pName);
|
||||
uint32_t nStrWidth = static_cast<uint32_t>(strlen(S.MetaCounters[nMetaIndex].pName));
|
||||
if(S.nBars & MP_DRAW_TIMERS)
|
||||
nWidth += 6 + (1+MICROPROFILE_TEXT_WIDTH) * (nStrWidth);
|
||||
if(S.nBars & MP_DRAW_AVERAGE)
|
||||
@@ -1907,7 +1907,7 @@ void MicroProfileDrawBarView(uint32_t nScreenWidth, uint32_t nScreenHeight)
|
||||
{
|
||||
if(0 != (S.nBars & (MP_DRAW_META_FIRST<<i)) && S.MetaCounters[i].pName)
|
||||
{
|
||||
uint32_t nBufferSize = strlen(S.MetaCounters[i].pName) + 32;
|
||||
uint32_t nBufferSize = static_cast<uint32_t>(strlen(S.MetaCounters[i].pName) + 32);
|
||||
char* buffer = (char*)alloca(nBufferSize);
|
||||
if(S.nBars & MP_DRAW_TIMERS)
|
||||
nX += MicroProfileDrawBarMetaCount(nX, nY, &S.MetaCounters[i].nCounters[0], S.MetaCounters[i].pName, nTotalHeight) + 1;
|
||||
@@ -1991,7 +1991,7 @@ const char* MicroProfileUIMenuGroups(int nIndex, bool* bSelected)
|
||||
else
|
||||
{
|
||||
nIndex = nIndex-1;
|
||||
if(nIndex < UI.GroupMenuCount)
|
||||
if(static_cast<uint32_t>(nIndex) < UI.GroupMenuCount)
|
||||
{
|
||||
MicroProfileGroupMenuItem& Item = UI.GroupMenu[nIndex];
|
||||
static char buffer[MICROPROFILE_NAME_MAX_LEN+32];
|
||||
@@ -2134,7 +2134,7 @@ const char* MicroProfileUIMenuCustom(int nIndex, bool* bSelected)
|
||||
case 1: return "--";
|
||||
default:
|
||||
nIndex -= 2;
|
||||
if(nIndex < UI.nCustomCount)
|
||||
if(static_cast<uint32_t>(nIndex) < UI.nCustomCount)
|
||||
{
|
||||
return UI.Custom[nIndex].pName;
|
||||
}
|
||||
@@ -2184,7 +2184,7 @@ void MicroProfileUIClickGroups(int nIndex)
|
||||
else
|
||||
{
|
||||
nIndex -= 1;
|
||||
if(nIndex < UI.GroupMenuCount)
|
||||
if(static_cast<uint32_t>(nIndex) < UI.GroupMenuCount)
|
||||
{
|
||||
MicroProfileGroupMenuItem& Item = UI.GroupMenu[nIndex];
|
||||
if(Item.nIsCategory)
|
||||
@@ -2599,7 +2599,7 @@ void MicroProfileDrawCustom(uint32_t nWidth, uint32_t nHeight)
|
||||
nOffsetY = nOffsetYBase;
|
||||
float* pMs = pCustom->nFlags & MICROPROFILE_CUSTOM_BAR_SOURCE_MAX ? pTimeMax : pTimeAvg;
|
||||
const char* pString = pCustom->nFlags & MICROPROFILE_CUSTOM_BAR_SOURCE_MAX ? "Max" : "Avg";
|
||||
MicroProfileDrawText(nMaxOffsetX, nOffsetY, (uint32_t)-1, pString, strlen(pString));
|
||||
MicroProfileDrawText(nMaxOffsetX, nOffsetY, (uint32_t)-1, pString, static_cast<uint32_t>(strlen(pString)));
|
||||
int nSize = snprintf(Buffer, sizeof(Buffer)-1, "%6.2fms", fReference);
|
||||
MicroProfileDrawText(nReducedWidth - (1+nSize) * (MICROPROFILE_TEXT_WIDTH+1), nOffsetY, (uint32_t)-1, Buffer, nSize);
|
||||
for(uint32_t i = 0; i < nCount; ++i)
|
||||
@@ -2613,7 +2613,7 @@ void MicroProfileDrawCustom(uint32_t nWidth, uint32_t nHeight)
|
||||
{
|
||||
nOffsetY += 2*(1+MICROPROFILE_TEXT_HEIGHT);
|
||||
const char* pString = pCustom->nFlags & MICROPROFILE_CUSTOM_STACK_SOURCE_MAX ? "Max" : "Avg";
|
||||
MicroProfileDrawText(MICROPROFILE_CUSTOM_PADDING, nOffsetY, (uint32_t)-1, pString, strlen(pString));
|
||||
MicroProfileDrawText(MICROPROFILE_CUSTOM_PADDING, nOffsetY, (uint32_t)-1, pString, static_cast<uint32_t>(strlen(pString)));
|
||||
int nSize = snprintf(Buffer, sizeof(Buffer)-1, "%6.2fms", fReference);
|
||||
MicroProfileDrawText(nReducedWidth - (1+nSize) * (MICROPROFILE_TEXT_WIDTH+1), nOffsetY, (uint32_t)-1, Buffer, nSize);
|
||||
nOffsetY += (1+MICROPROFILE_TEXT_HEIGHT);
|
||||
|
||||
1
externals/unicorn
vendored
Submodule
1
externals/unicorn
vendored
Submodule
Submodule externals/unicorn added at 73f4573535
@@ -24,78 +24,72 @@ if ($ENV{CI})
|
||||
endif()
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/scm_rev.cpp.in" "${CMAKE_CURRENT_SOURCE_DIR}/scm_rev.cpp" @ONLY)
|
||||
|
||||
set(SRCS
|
||||
break_points.cpp
|
||||
file_util.cpp
|
||||
hash.cpp
|
||||
logging/filter.cpp
|
||||
logging/text_formatter.cpp
|
||||
logging/backend.cpp
|
||||
memory_util.cpp
|
||||
microprofile.cpp
|
||||
misc.cpp
|
||||
param_package.cpp
|
||||
scm_rev.cpp
|
||||
string_util.cpp
|
||||
telemetry.cpp
|
||||
thread.cpp
|
||||
timer.cpp
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
alignment.h
|
||||
assert.h
|
||||
bit_field.h
|
||||
bit_set.h
|
||||
break_points.h
|
||||
chunk_file.h
|
||||
code_block.h
|
||||
color.h
|
||||
common_funcs.h
|
||||
common_paths.h
|
||||
common_types.h
|
||||
file_util.h
|
||||
hash.h
|
||||
linear_disk_cache.h
|
||||
logging/text_formatter.h
|
||||
logging/filter.h
|
||||
logging/log.h
|
||||
logging/backend.h
|
||||
math_util.h
|
||||
memory_util.h
|
||||
microprofile.h
|
||||
microprofileui.h
|
||||
param_package.h
|
||||
platform.h
|
||||
quaternion.h
|
||||
scm_rev.h
|
||||
scope_exit.h
|
||||
string_util.h
|
||||
swap.h
|
||||
synchronized_wrapper.h
|
||||
telemetry.h
|
||||
thread.h
|
||||
thread_queue_list.h
|
||||
threadsafe_queue.h
|
||||
timer.h
|
||||
vector_math.h
|
||||
)
|
||||
add_library(common STATIC
|
||||
alignment.h
|
||||
assert.h
|
||||
bit_field.h
|
||||
bit_set.h
|
||||
break_points.cpp
|
||||
break_points.h
|
||||
chunk_file.h
|
||||
code_block.h
|
||||
color.h
|
||||
common_funcs.h
|
||||
common_paths.h
|
||||
common_types.h
|
||||
file_util.cpp
|
||||
file_util.h
|
||||
hash.cpp
|
||||
hash.h
|
||||
linear_disk_cache.h
|
||||
logging/backend.cpp
|
||||
logging/backend.h
|
||||
logging/filter.cpp
|
||||
logging/filter.h
|
||||
logging/log.h
|
||||
logging/text_formatter.cpp
|
||||
logging/text_formatter.h
|
||||
math_util.h
|
||||
memory_util.cpp
|
||||
memory_util.h
|
||||
microprofile.cpp
|
||||
microprofile.h
|
||||
microprofileui.h
|
||||
misc.cpp
|
||||
param_package.cpp
|
||||
param_package.h
|
||||
platform.h
|
||||
quaternion.h
|
||||
scm_rev.cpp
|
||||
scm_rev.h
|
||||
scope_exit.h
|
||||
string_util.cpp
|
||||
string_util.h
|
||||
swap.h
|
||||
synchronized_wrapper.h
|
||||
telemetry.cpp
|
||||
telemetry.h
|
||||
thread.cpp
|
||||
thread.h
|
||||
thread_queue_list.h
|
||||
threadsafe_queue.h
|
||||
timer.cpp
|
||||
timer.h
|
||||
vector_math.h
|
||||
)
|
||||
|
||||
if(ARCHITECTURE_x86_64)
|
||||
set(SRCS ${SRCS}
|
||||
target_sources(common
|
||||
PRIVATE
|
||||
x64/cpu_detect.cpp
|
||||
)
|
||||
|
||||
set(HEADERS ${HEADERS}
|
||||
x64/cpu_detect.h
|
||||
x64/xbyak_abi.h
|
||||
x64/xbyak_util.h
|
||||
)
|
||||
)
|
||||
endif()
|
||||
|
||||
create_directory_groups(${SRCS} ${HEADERS})
|
||||
create_target_directory_groups(common)
|
||||
|
||||
add_library(common STATIC ${SRCS} ${HEADERS})
|
||||
target_link_libraries(common PUBLIC Boost::boost microprofile)
|
||||
if (ARCHITECTURE_x86_64)
|
||||
target_link_libraries(common PRIVATE xbyak)
|
||||
|
||||
@@ -236,7 +236,7 @@ public:
|
||||
IntTy m_val;
|
||||
};
|
||||
|
||||
} // Common
|
||||
} // namespace Common
|
||||
|
||||
typedef Common::BitSet<u8> BitSet8;
|
||||
typedef Common::BitSet<u16> BitSet16;
|
||||
|
||||
@@ -607,8 +607,9 @@ public:
|
||||
u32 cookie = arbitraryNumber;
|
||||
Do(cookie);
|
||||
if (mode == PointerWrap::MODE_READ && cookie != arbitraryNumber) {
|
||||
LOG_ERROR(Common, "After \"%s\", found %d (0x%X) instead of save marker %d (0x%X). "
|
||||
"Aborting savestate load...",
|
||||
LOG_ERROR(Common,
|
||||
"After \"%s\", found %d (0x%X) instead of save marker %d (0x%X). "
|
||||
"Aborting savestate load...",
|
||||
prevName, cookie, cookie, arbitraryNumber, arbitraryNumber);
|
||||
SetError(ERROR_FAILURE);
|
||||
}
|
||||
|
||||
@@ -256,4 +256,4 @@ inline void EncodeX24S8(u8 stencil, u8* bytes) {
|
||||
bytes[3] = stencil;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace Color
|
||||
|
||||
@@ -873,20 +873,19 @@ bool IOFile::Flush() {
|
||||
}
|
||||
|
||||
bool IOFile::Resize(u64 size) {
|
||||
if (!IsOpen() ||
|
||||
0 !=
|
||||
if (!IsOpen() || 0 !=
|
||||
#ifdef _WIN32
|
||||
// ector: _chsize sucks, not 64-bit safe
|
||||
// F|RES: changed to _chsize_s. i think it is 64-bit safe
|
||||
_chsize_s(_fileno(m_file), size)
|
||||
// ector: _chsize sucks, not 64-bit safe
|
||||
// F|RES: changed to _chsize_s. i think it is 64-bit safe
|
||||
_chsize_s(_fileno(m_file), size)
|
||||
#else
|
||||
// TODO: handle 64bit and growing
|
||||
ftruncate(fileno(m_file), size)
|
||||
// TODO: handle 64bit and growing
|
||||
ftruncate(fileno(m_file), size)
|
||||
#endif
|
||||
)
|
||||
)
|
||||
m_good = false;
|
||||
|
||||
return m_good;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace FileUtil
|
||||
|
||||
@@ -253,7 +253,7 @@ private:
|
||||
bool m_good = true;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace FileUtil
|
||||
|
||||
// To deal with Windows being dumb at unicode:
|
||||
template <typename T>
|
||||
|
||||
@@ -43,6 +43,7 @@ namespace Log {
|
||||
SUB(HW, LCD) \
|
||||
SUB(HW, GPU) \
|
||||
SUB(HW, AES) \
|
||||
CLS(IPC) \
|
||||
CLS(Frontend) \
|
||||
CLS(Render) \
|
||||
SUB(Render, Software) \
|
||||
@@ -91,8 +92,8 @@ const char* GetLevelName(Level log_level) {
|
||||
|
||||
Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsigned int line_nr,
|
||||
const char* function, const char* format, va_list args) {
|
||||
using std::chrono::steady_clock;
|
||||
using std::chrono::duration_cast;
|
||||
using std::chrono::steady_clock;
|
||||
|
||||
static steady_clock::time_point time_origin = steady_clock::now();
|
||||
|
||||
@@ -131,4 +132,4 @@ void LogMessage(Class log_class, Level log_level, const char* filename, unsigned
|
||||
|
||||
PrintColoredMessage(entry);
|
||||
}
|
||||
}
|
||||
} // namespace Log
|
||||
|
||||
@@ -47,4 +47,4 @@ Entry CreateEntry(Class log_class, Level log_level, const char* filename, unsign
|
||||
const char* function, const char* format, va_list args);
|
||||
|
||||
void SetFilter(Filter* filter);
|
||||
}
|
||||
} // namespace Log
|
||||
|
||||
@@ -94,4 +94,4 @@ bool Filter::ParseFilterRule(const std::string::const_iterator begin,
|
||||
bool Filter::CheckMessage(Class log_class, Level level) const {
|
||||
return static_cast<u8>(level) >= static_cast<u8>(class_levels[static_cast<size_t>(log_class)]);
|
||||
}
|
||||
}
|
||||
} // namespace Log
|
||||
|
||||
@@ -50,4 +50,4 @@ public:
|
||||
private:
|
||||
std::array<Level, (size_t)Class::Count> class_levels;
|
||||
};
|
||||
}
|
||||
} // namespace Log
|
||||
|
||||
@@ -60,6 +60,7 @@ enum class Class : ClassType {
|
||||
HW_LCD, ///< LCD register emulation
|
||||
HW_GPU, ///< GPU control emulation
|
||||
HW_AES, ///< AES engine emulation
|
||||
IPC, ///< IPC interface
|
||||
Frontend, ///< Emulator UI
|
||||
Render, ///< Emulator video output and hardware acceleration
|
||||
Render_Software, ///< Software renderer backend
|
||||
|
||||
@@ -129,4 +129,4 @@ void PrintColoredMessage(const Entry& entry) {
|
||||
#undef ESC
|
||||
#endif
|
||||
}
|
||||
}
|
||||
} // namespace Log
|
||||
|
||||
@@ -28,4 +28,4 @@ void FormatLogMessage(const Entry& entry, char* out_text, size_t text_len);
|
||||
void PrintMessage(const Entry& entry);
|
||||
/// Prints the same message as `PrintMessage`, but colored acoording to the severity level.
|
||||
void PrintColoredMessage(const Entry& entry);
|
||||
}
|
||||
} // namespace Log
|
||||
|
||||
@@ -40,11 +40,12 @@ void* AllocateExecutableMemory(size_t size, bool low) {
|
||||
if (low && (!map_hint))
|
||||
map_hint = (char*)round_page(512 * 1024 * 1024); /* 0.5 GB rounded up to the next page */
|
||||
#endif
|
||||
void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_ANON | MAP_PRIVATE
|
||||
void* ptr = mmap(map_hint, size, PROT_READ | PROT_WRITE | PROT_EXEC,
|
||||
MAP_ANON | MAP_PRIVATE
|
||||
#if defined(ARCHITECTURE_X64) && defined(MAP_32BIT)
|
||||
| (low ? MAP_32BIT : 0)
|
||||
| (low ? MAP_32BIT : 0)
|
||||
#endif
|
||||
,
|
||||
,
|
||||
-1, 0);
|
||||
#endif /* defined(_WIN32) */
|
||||
|
||||
|
||||
@@ -46,4 +46,4 @@ inline Quaternion<float> MakeQuaternion(const Math::Vec3<float>& axis, float ang
|
||||
return {axis * std::sin(angle / 2), std::cos(angle / 2)};
|
||||
}
|
||||
|
||||
} // namspace Math
|
||||
} // namespace Math
|
||||
|
||||
@@ -12,4 +12,4 @@ extern const char g_scm_desc[];
|
||||
extern const char g_build_name[];
|
||||
extern const char g_build_date[];
|
||||
|
||||
} // namespace
|
||||
} // namespace Common
|
||||
|
||||
@@ -22,7 +22,7 @@ template <typename Func>
|
||||
ScopeExitHelper<Func> ScopeExit(Func&& func) {
|
||||
return ScopeExitHelper<Func>(std::move(func));
|
||||
}
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
/**
|
||||
* This macro allows you to conveniently specify a block of code that will run on scope exit. Handy
|
||||
|
||||
@@ -202,7 +202,7 @@ bool SplitPath(const std::string& full_path, std::string* _pPath, std::string* _
|
||||
#ifdef _WIN32
|
||||
":"
|
||||
#endif
|
||||
);
|
||||
);
|
||||
if (std::string::npos == dir_end)
|
||||
dir_end = 0;
|
||||
else
|
||||
@@ -462,4 +462,4 @@ std::string StringFromFixedZeroTerminatedBuffer(const char* buffer, size_t max_l
|
||||
|
||||
return std::string(buffer, len);
|
||||
}
|
||||
}
|
||||
} // namespace Common
|
||||
|
||||
@@ -134,4 +134,4 @@ bool ComparePartialString(InIt begin, InIt end, const char* other) {
|
||||
* NUL-terminated then the string ends at max_len characters.
|
||||
*/
|
||||
std::string StringFromFixedZeroTerminatedBuffer(const char* buffer, size_t max_len);
|
||||
}
|
||||
} // namespace Common
|
||||
|
||||
@@ -53,10 +53,10 @@ template <typename T>
|
||||
class Field : public FieldInterface {
|
||||
public:
|
||||
Field(FieldType type, std::string name, const T& value)
|
||||
: type(type), name(std::move(name)), value(value) {}
|
||||
: name(std::move(name)), type(type), value(value) {}
|
||||
|
||||
Field(FieldType type, std::string name, T&& value)
|
||||
: type(type), name(std::move(name)), value(std::move(value)) {}
|
||||
: name(std::move(name)), type(type), value(std::move(value)) {}
|
||||
|
||||
Field(const Field& other) : Field(other.type, other.name, other.value) {}
|
||||
|
||||
|
||||
@@ -158,4 +158,4 @@ private:
|
||||
std::array<Queue, NUM_QUEUES> queues;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace Common
|
||||
|
||||
@@ -60,20 +60,41 @@ const Xbyak::Reg ABI_PARAM4 = Xbyak::util::r9;
|
||||
|
||||
const BitSet32 ABI_ALL_CALLER_SAVED = BuildRegSet({
|
||||
// GPRs
|
||||
Xbyak::util::rcx, Xbyak::util::rdx, Xbyak::util::r8, Xbyak::util::r9, Xbyak::util::r10,
|
||||
Xbyak::util::rcx,
|
||||
Xbyak::util::rdx,
|
||||
Xbyak::util::r8,
|
||||
Xbyak::util::r9,
|
||||
Xbyak::util::r10,
|
||||
Xbyak::util::r11,
|
||||
// XMMs
|
||||
Xbyak::util::xmm0, Xbyak::util::xmm1, Xbyak::util::xmm2, Xbyak::util::xmm3, Xbyak::util::xmm4,
|
||||
Xbyak::util::xmm0,
|
||||
Xbyak::util::xmm1,
|
||||
Xbyak::util::xmm2,
|
||||
Xbyak::util::xmm3,
|
||||
Xbyak::util::xmm4,
|
||||
Xbyak::util::xmm5,
|
||||
});
|
||||
|
||||
const BitSet32 ABI_ALL_CALLEE_SAVED = BuildRegSet({
|
||||
// GPRs
|
||||
Xbyak::util::rbx, Xbyak::util::rsi, Xbyak::util::rdi, Xbyak::util::rbp, Xbyak::util::r12,
|
||||
Xbyak::util::r13, Xbyak::util::r14, Xbyak::util::r15,
|
||||
Xbyak::util::rbx,
|
||||
Xbyak::util::rsi,
|
||||
Xbyak::util::rdi,
|
||||
Xbyak::util::rbp,
|
||||
Xbyak::util::r12,
|
||||
Xbyak::util::r13,
|
||||
Xbyak::util::r14,
|
||||
Xbyak::util::r15,
|
||||
// XMMs
|
||||
Xbyak::util::xmm6, Xbyak::util::xmm7, Xbyak::util::xmm8, Xbyak::util::xmm9, Xbyak::util::xmm10,
|
||||
Xbyak::util::xmm11, Xbyak::util::xmm12, Xbyak::util::xmm13, Xbyak::util::xmm14,
|
||||
Xbyak::util::xmm6,
|
||||
Xbyak::util::xmm7,
|
||||
Xbyak::util::xmm8,
|
||||
Xbyak::util::xmm9,
|
||||
Xbyak::util::xmm10,
|
||||
Xbyak::util::xmm11,
|
||||
Xbyak::util::xmm12,
|
||||
Xbyak::util::xmm13,
|
||||
Xbyak::util::xmm14,
|
||||
Xbyak::util::xmm15,
|
||||
});
|
||||
|
||||
@@ -90,18 +111,40 @@ const Xbyak::Reg ABI_PARAM4 = Xbyak::util::rcx;
|
||||
|
||||
const BitSet32 ABI_ALL_CALLER_SAVED = BuildRegSet({
|
||||
// GPRs
|
||||
Xbyak::util::rcx, Xbyak::util::rdx, Xbyak::util::rdi, Xbyak::util::rsi, Xbyak::util::r8,
|
||||
Xbyak::util::r9, Xbyak::util::r10, Xbyak::util::r11,
|
||||
Xbyak::util::rcx,
|
||||
Xbyak::util::rdx,
|
||||
Xbyak::util::rdi,
|
||||
Xbyak::util::rsi,
|
||||
Xbyak::util::r8,
|
||||
Xbyak::util::r9,
|
||||
Xbyak::util::r10,
|
||||
Xbyak::util::r11,
|
||||
// XMMs
|
||||
Xbyak::util::xmm0, Xbyak::util::xmm1, Xbyak::util::xmm2, Xbyak::util::xmm3, Xbyak::util::xmm4,
|
||||
Xbyak::util::xmm5, Xbyak::util::xmm6, Xbyak::util::xmm7, Xbyak::util::xmm8, Xbyak::util::xmm9,
|
||||
Xbyak::util::xmm10, Xbyak::util::xmm11, Xbyak::util::xmm12, Xbyak::util::xmm13,
|
||||
Xbyak::util::xmm14, Xbyak::util::xmm15,
|
||||
Xbyak::util::xmm0,
|
||||
Xbyak::util::xmm1,
|
||||
Xbyak::util::xmm2,
|
||||
Xbyak::util::xmm3,
|
||||
Xbyak::util::xmm4,
|
||||
Xbyak::util::xmm5,
|
||||
Xbyak::util::xmm6,
|
||||
Xbyak::util::xmm7,
|
||||
Xbyak::util::xmm8,
|
||||
Xbyak::util::xmm9,
|
||||
Xbyak::util::xmm10,
|
||||
Xbyak::util::xmm11,
|
||||
Xbyak::util::xmm12,
|
||||
Xbyak::util::xmm13,
|
||||
Xbyak::util::xmm14,
|
||||
Xbyak::util::xmm15,
|
||||
});
|
||||
|
||||
const BitSet32 ABI_ALL_CALLEE_SAVED = BuildRegSet({
|
||||
// GPRs
|
||||
Xbyak::util::rbx, Xbyak::util::rbp, Xbyak::util::r12, Xbyak::util::r13, Xbyak::util::r14,
|
||||
Xbyak::util::rbx,
|
||||
Xbyak::util::rbp,
|
||||
Xbyak::util::r12,
|
||||
Xbyak::util::r13,
|
||||
Xbyak::util::r14,
|
||||
Xbyak::util::r15,
|
||||
});
|
||||
|
||||
|
||||
@@ -1,163 +1,190 @@
|
||||
set(SRCS
|
||||
arm/dynarmic/arm_dynarmic.cpp
|
||||
arm/unicorn/arm_unicorn.cpp
|
||||
core.cpp
|
||||
core_timing.cpp
|
||||
file_sys/archive_backend.cpp
|
||||
file_sys/disk_archive.cpp
|
||||
file_sys/ivfc_archive.cpp
|
||||
file_sys/path_parser.cpp
|
||||
file_sys/savedata_archive.cpp
|
||||
file_sys/title_metadata.cpp
|
||||
frontend/emu_window.cpp
|
||||
frontend/framebuffer_layout.cpp
|
||||
gdbstub/gdbstub.cpp
|
||||
hle/config_mem.cpp
|
||||
hle/kernel/address_arbiter.cpp
|
||||
hle/kernel/client_port.cpp
|
||||
hle/kernel/client_session.cpp
|
||||
hle/kernel/condition_variable.cpp
|
||||
hle/kernel/domain.cpp
|
||||
hle/kernel/event.cpp
|
||||
hle/kernel/handle_table.cpp
|
||||
hle/kernel/hle_ipc.cpp
|
||||
hle/kernel/kernel.cpp
|
||||
hle/kernel/memory.cpp
|
||||
hle/kernel/mutex.cpp
|
||||
hle/kernel/object_address_table.cpp
|
||||
hle/kernel/process.cpp
|
||||
hle/kernel/resource_limit.cpp
|
||||
hle/kernel/server_port.cpp
|
||||
hle/kernel/server_session.cpp
|
||||
hle/kernel/shared_memory.cpp
|
||||
hle/kernel/svc.cpp
|
||||
hle/kernel/thread.cpp
|
||||
hle/kernel/timer.cpp
|
||||
hle/kernel/vm_manager.cpp
|
||||
hle/kernel/wait_object.cpp
|
||||
hle/lock.cpp
|
||||
hle/romfs.cpp
|
||||
hle/service/am/am.cpp
|
||||
hle/service/am/applet_oe.cpp
|
||||
hle/service/aoc/aoc_u.cpp
|
||||
hle/service/apm/apm.cpp
|
||||
hle/service/hid/hid.cpp
|
||||
hle/service/lm/lm.cpp
|
||||
hle/service/nvdrv/devices/nvdisp_disp0.cpp
|
||||
hle/service/nvdrv/devices/nvhost_as_gpu.cpp
|
||||
hle/service/nvdrv/devices/nvmap.cpp
|
||||
hle/service/nvdrv/nvdrv.cpp
|
||||
hle/service/nvdrv/nvdrv_a.cpp
|
||||
hle/service/pctl/pctl.cpp
|
||||
hle/service/pctl/pctl_a.cpp
|
||||
hle/service/service.cpp
|
||||
hle/service/sm/controller.cpp
|
||||
hle/service/sm/sm.cpp
|
||||
hle/service/vi/vi.cpp
|
||||
hle/service/vi/vi_m.cpp
|
||||
hle/shared_page.cpp
|
||||
hw/hw.cpp
|
||||
hw/lcd.cpp
|
||||
loader/elf.cpp
|
||||
loader/linker.cpp
|
||||
loader/loader.cpp
|
||||
loader/nro.cpp
|
||||
loader/nso.cpp
|
||||
tracer/recorder.cpp
|
||||
memory.cpp
|
||||
perf_stats.cpp
|
||||
settings.cpp
|
||||
telemetry_session.cpp
|
||||
)
|
||||
add_library(core STATIC
|
||||
arm/arm_interface.h
|
||||
arm/unicorn/arm_unicorn.cpp
|
||||
arm/unicorn/arm_unicorn.h
|
||||
core.cpp
|
||||
core.h
|
||||
core_timing.cpp
|
||||
core_timing.h
|
||||
file_sys/archive_backend.cpp
|
||||
file_sys/archive_backend.h
|
||||
file_sys/directory_backend.h
|
||||
file_sys/disk_archive.cpp
|
||||
file_sys/disk_archive.h
|
||||
file_sys/errors.h
|
||||
file_sys/file_backend.h
|
||||
file_sys/ivfc_archive.cpp
|
||||
file_sys/ivfc_archive.h
|
||||
file_sys/path_parser.cpp
|
||||
file_sys/path_parser.h
|
||||
file_sys/savedata_archive.cpp
|
||||
file_sys/savedata_archive.h
|
||||
file_sys/title_metadata.cpp
|
||||
file_sys/title_metadata.h
|
||||
frontend/emu_window.cpp
|
||||
frontend/emu_window.h
|
||||
frontend/framebuffer_layout.cpp
|
||||
frontend/framebuffer_layout.h
|
||||
frontend/input.h
|
||||
gdbstub/gdbstub.cpp
|
||||
gdbstub/gdbstub.h
|
||||
hle/config_mem.cpp
|
||||
hle/config_mem.h
|
||||
hle/ipc.h
|
||||
hle/ipc_helpers.h
|
||||
hle/kernel/address_arbiter.cpp
|
||||
hle/kernel/address_arbiter.h
|
||||
hle/kernel/client_port.cpp
|
||||
hle/kernel/client_port.h
|
||||
hle/kernel/client_session.cpp
|
||||
hle/kernel/client_session.h
|
||||
hle/kernel/condition_variable.cpp
|
||||
hle/kernel/condition_variable.h
|
||||
hle/kernel/domain.cpp
|
||||
hle/kernel/domain.h
|
||||
hle/kernel/errors.h
|
||||
hle/kernel/event.cpp
|
||||
hle/kernel/event.h
|
||||
hle/kernel/handle_table.cpp
|
||||
hle/kernel/handle_table.h
|
||||
hle/kernel/hle_ipc.cpp
|
||||
hle/kernel/hle_ipc.h
|
||||
hle/kernel/kernel.cpp
|
||||
hle/kernel/kernel.h
|
||||
hle/kernel/memory.cpp
|
||||
hle/kernel/memory.h
|
||||
hle/kernel/mutex.cpp
|
||||
hle/kernel/mutex.h
|
||||
hle/kernel/object_address_table.cpp
|
||||
hle/kernel/object_address_table.h
|
||||
hle/kernel/process.cpp
|
||||
hle/kernel/process.h
|
||||
hle/kernel/resource_limit.cpp
|
||||
hle/kernel/resource_limit.h
|
||||
hle/kernel/server_port.cpp
|
||||
hle/kernel/server_port.h
|
||||
hle/kernel/server_session.cpp
|
||||
hle/kernel/server_session.h
|
||||
hle/kernel/session.h
|
||||
hle/kernel/shared_memory.cpp
|
||||
hle/kernel/shared_memory.h
|
||||
hle/kernel/svc.cpp
|
||||
hle/kernel/svc.h
|
||||
hle/kernel/svc_wrap.h
|
||||
hle/kernel/sync_object.h
|
||||
hle/kernel/thread.cpp
|
||||
hle/kernel/thread.h
|
||||
hle/kernel/timer.cpp
|
||||
hle/kernel/timer.h
|
||||
hle/kernel/vm_manager.cpp
|
||||
hle/kernel/vm_manager.h
|
||||
hle/kernel/wait_object.cpp
|
||||
hle/kernel/wait_object.h
|
||||
hle/lock.cpp
|
||||
hle/lock.h
|
||||
hle/result.h
|
||||
hle/romfs.cpp
|
||||
hle/romfs.h
|
||||
hle/service/acc/acc.cpp
|
||||
hle/service/acc/acc.h
|
||||
hle/service/acc/acc_u0.cpp
|
||||
hle/service/acc/acc_u0.h
|
||||
hle/service/am/am.cpp
|
||||
hle/service/am/am.h
|
||||
hle/service/am/applet_oe.cpp
|
||||
hle/service/am/applet_oe.h
|
||||
hle/service/aoc/aoc_u.cpp
|
||||
hle/service/aoc/aoc_u.h
|
||||
hle/service/apm/apm.cpp
|
||||
hle/service/apm/apm.h
|
||||
hle/service/audio/audio.cpp
|
||||
hle/service/audio/audio.h
|
||||
hle/service/audio/audout_u.cpp
|
||||
hle/service/audio/audout_u.h
|
||||
hle/service/hid/hid.cpp
|
||||
hle/service/hid/hid.h
|
||||
hle/service/lm/lm.cpp
|
||||
hle/service/lm/lm.h
|
||||
hle/service/nvdrv/devices/nvdevice.h
|
||||
hle/service/nvdrv/devices/nvdisp_disp0.cpp
|
||||
hle/service/nvdrv/devices/nvdisp_disp0.h
|
||||
hle/service/nvdrv/devices/nvhost_as_gpu.cpp
|
||||
hle/service/nvdrv/devices/nvhost_as_gpu.h
|
||||
hle/service/nvdrv/devices/nvmap.cpp
|
||||
hle/service/nvdrv/devices/nvmap.h
|
||||
hle/service/nvdrv/interface.cpp
|
||||
hle/service/nvdrv/interface.h
|
||||
hle/service/nvdrv/nvdrv.cpp
|
||||
hle/service/nvdrv/nvdrv.h
|
||||
hle/service/pctl/pctl.cpp
|
||||
hle/service/pctl/pctl.h
|
||||
hle/service/pctl/pctl_a.cpp
|
||||
hle/service/pctl/pctl_a.h
|
||||
hle/service/service.cpp
|
||||
hle/service/service.h
|
||||
hle/service/set/set.cpp
|
||||
hle/service/set/set.h
|
||||
hle/service/sm/controller.cpp
|
||||
hle/service/sm/controller.h
|
||||
hle/service/sm/sm.cpp
|
||||
hle/service/sm/sm.h
|
||||
hle/service/sockets/bsd_u.cpp
|
||||
hle/service/sockets/bsd_u.h
|
||||
hle/service/sockets/sfdnsres.h
|
||||
hle/service/sockets/sockets.cpp
|
||||
hle/service/sockets/sockets.h
|
||||
hle/service/time/time.cpp
|
||||
hle/service/time/time.h
|
||||
hle/service/time/time_s.cpp
|
||||
hle/service/time/time_s.h
|
||||
hle/service/time/time_u.cpp
|
||||
hle/service/time/time_u.h
|
||||
hle/service/vi/vi.cpp
|
||||
hle/service/vi/vi.h
|
||||
hle/service/vi/vi_m.cpp
|
||||
hle/service/vi/vi_m.h
|
||||
hle/shared_page.cpp
|
||||
hle/shared_page.h
|
||||
hw/hw.cpp
|
||||
hw/hw.h
|
||||
hw/lcd.cpp
|
||||
hw/lcd.h
|
||||
loader/deconstructed_rom_directory.cpp
|
||||
loader/deconstructed_rom_directory.h
|
||||
loader/elf.cpp
|
||||
loader/elf.h
|
||||
loader/linker.cpp
|
||||
loader/linker.h
|
||||
loader/loader.cpp
|
||||
loader/loader.h
|
||||
loader/nro.cpp
|
||||
loader/nro.h
|
||||
loader/nso.cpp
|
||||
loader/nso.h
|
||||
memory.cpp
|
||||
memory.h
|
||||
memory_setup.h
|
||||
mmio.h
|
||||
perf_stats.cpp
|
||||
perf_stats.h
|
||||
settings.cpp
|
||||
settings.h
|
||||
telemetry_session.cpp
|
||||
telemetry_session.h
|
||||
tracer/citrace.h
|
||||
tracer/recorder.cpp
|
||||
tracer/recorder.h
|
||||
)
|
||||
|
||||
set(HEADERS
|
||||
arm/arm_interface.h
|
||||
arm/dynarmic/arm_dynarmic.h
|
||||
arm/unicorn/arm_unicorn.h
|
||||
core.h
|
||||
core_timing.h
|
||||
file_sys/archive_backend.h
|
||||
file_sys/directory_backend.h
|
||||
file_sys/disk_archive.h
|
||||
file_sys/errors.h
|
||||
file_sys/file_backend.h
|
||||
file_sys/ivfc_archive.h
|
||||
file_sys/path_parser.h
|
||||
file_sys/savedata_archive.h
|
||||
frontend/emu_window.h
|
||||
frontend/framebuffer_layout.h
|
||||
frontend/input.h
|
||||
gdbstub/gdbstub.h
|
||||
hle/config_mem.h
|
||||
hle/ipc.h
|
||||
hle/ipc_helpers.h
|
||||
hle/kernel/address_arbiter.h
|
||||
hle/kernel/client_port.h
|
||||
hle/kernel/client_session.h
|
||||
hle/kernel/condition_variable.h
|
||||
hle/kernel/domain.h
|
||||
hle/kernel/errors.h
|
||||
hle/kernel/event.h
|
||||
hle/kernel/handle_table.h
|
||||
hle/kernel/hle_ipc.h
|
||||
hle/kernel/kernel.h
|
||||
hle/kernel/memory.h
|
||||
hle/kernel/mutex.h
|
||||
hle/kernel/object_address_table.h
|
||||
hle/kernel/process.h
|
||||
hle/kernel/resource_limit.h
|
||||
hle/kernel/server_port.h
|
||||
hle/kernel/server_session.h
|
||||
hle/kernel/session.h
|
||||
hle/kernel/shared_memory.h
|
||||
hle/kernel/sync_object.h
|
||||
hle/kernel/svc.h
|
||||
hle/kernel/svc_wrap.h
|
||||
hle/kernel/thread.h
|
||||
hle/kernel/timer.h
|
||||
hle/kernel/vm_manager.h
|
||||
hle/kernel/wait_object.h
|
||||
hle/lock.h
|
||||
hle/result.h
|
||||
hle/romfs.h
|
||||
hle/service/am/am.h
|
||||
hle/service/am/applet_oe.h
|
||||
hle/service/aoc/aoc_u.h
|
||||
hle/service/apm/apm.h
|
||||
hle/service/hid/hid.h
|
||||
hle/service/lm/lm.h
|
||||
hle/service/nvdrv/devices/nvdevice.h
|
||||
hle/service/nvdrv/devices/nvdisp_disp0.h
|
||||
hle/service/nvdrv/devices/nvhost_as_gpu.h
|
||||
hle/service/nvdrv/devices/nvmap.h
|
||||
hle/service/nvdrv/nvdrv.h
|
||||
hle/service/nvdrv/nvdrv_a.h
|
||||
hle/service/pctl/pctl.h
|
||||
hle/service/pctl/pctl_a.h
|
||||
hle/service/service.h
|
||||
hle/service/sm/controller.h
|
||||
hle/service/sm/sm.h
|
||||
hle/service/vi/vi.h
|
||||
hle/service/vi/vi_m.h
|
||||
hle/shared_page.h
|
||||
hw/hw.h
|
||||
hw/lcd.h
|
||||
loader/elf.h
|
||||
loader/linker.h
|
||||
loader/loader.h
|
||||
loader/nro.h
|
||||
loader/nso.h
|
||||
tracer/recorder.h
|
||||
tracer/citrace.h
|
||||
memory.h
|
||||
memory_setup.h
|
||||
mmio.h
|
||||
perf_stats.h
|
||||
settings.h
|
||||
telemetry_session.h
|
||||
)
|
||||
create_target_directory_groups(core)
|
||||
|
||||
create_directory_groups(${SRCS} ${HEADERS})
|
||||
add_library(core STATIC ${SRCS} ${HEADERS})
|
||||
target_link_libraries(core PUBLIC common PRIVATE dynarmic video_core)
|
||||
target_link_libraries(core PUBLIC common PRIVATE video_core)
|
||||
target_link_libraries(core PUBLIC Boost::boost PRIVATE fmt lz4_static unicorn)
|
||||
|
||||
if (ARCHITECTURE_x86_64)
|
||||
target_sources(core PRIVATE
|
||||
arm/dynarmic/arm_dynarmic.cpp
|
||||
arm/dynarmic/arm_dynarmic.h
|
||||
)
|
||||
target_link_libraries(core PRIVATE dynarmic)
|
||||
endif()
|
||||
|
||||
@@ -39,7 +39,8 @@ public:
|
||||
Run(1);
|
||||
}
|
||||
|
||||
virtual void MapBackingMemory(VAddr address, size_t size, u8* memory, Kernel::VMAPermission perms) {}
|
||||
virtual void MapBackingMemory(VAddr address, size_t size, u8* memory,
|
||||
Kernel::VMAPermission perms) {}
|
||||
|
||||
/// Clear all instruction cache
|
||||
virtual void ClearInstructionCache() = 0;
|
||||
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
ARM_Interface::ThreadContext ctx;
|
||||
parent.SaveContext(ctx);
|
||||
parent.inner_unicorn.LoadContext(ctx);
|
||||
parent.inner_unicorn.ExecuteInstructions(num_instructions);
|
||||
parent.inner_unicorn.ExecuteInstructions(static_cast<int>(num_instructions));
|
||||
parent.inner_unicorn.SaveContext(ctx);
|
||||
parent.LoadContext(ctx);
|
||||
num_interpreted_instructions += num_instructions;
|
||||
@@ -163,9 +163,9 @@ void ARM_Dynarmic::LoadContext(const ARM_Interface::ThreadContext& ctx) {
|
||||
jit.SetRegisters(ctx.cpu_registers);
|
||||
jit.SetSP(ctx.sp);
|
||||
jit.SetPC(ctx.pc);
|
||||
jit.SetPstate(ctx.cpsr);
|
||||
jit.SetPstate(static_cast<u32>(ctx.cpsr));
|
||||
jit.SetVectors(ctx.fpu_registers);
|
||||
jit.SetFpcr(ctx.fpscr);
|
||||
jit.SetFpcr(static_cast<u32>(ctx.fpscr));
|
||||
cb->tpidrr0_el0 = ctx.tls_address;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
#include "core/hle/kernel/svc.h"
|
||||
|
||||
// Load Unicorn DLL once on Windows using RAII
|
||||
#ifdef _WIN32
|
||||
#ifdef _MSC_VER
|
||||
#include <unicorn_dynload.h>
|
||||
struct LoadDll {
|
||||
private:
|
||||
|
||||
@@ -5,7 +5,9 @@
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include "common/logging/log.h"
|
||||
#ifdef ARCHITECTURE_x86_64
|
||||
#include "core/arm/dynarmic/arm_dynarmic.h"
|
||||
#endif
|
||||
#include "core/arm/unicorn/arm_unicorn.h"
|
||||
#include "core/core.h"
|
||||
#include "core/core_timing.h"
|
||||
@@ -80,7 +82,6 @@ System::ResultStatus System::Load(EmuWindow* emu_window, const std::string& file
|
||||
if (system_mode.second != Loader::ResultStatus::Success) {
|
||||
LOG_CRITICAL(Core, "Failed to determine system mode (Error %i)!",
|
||||
static_cast<int>(system_mode.second));
|
||||
System::Shutdown();
|
||||
|
||||
switch (system_mode.second) {
|
||||
case Loader::ResultStatus::ErrorEncrypted:
|
||||
@@ -144,7 +145,12 @@ System::ResultStatus System::Init(EmuWindow* emu_window, u32 system_mode) {
|
||||
break;
|
||||
case Settings::CpuCore::Dynarmic:
|
||||
default:
|
||||
#ifdef ARCHITECTURE_x86_64
|
||||
cpu_core = std::make_unique<ARM_Dynarmic>();
|
||||
#else
|
||||
cpu_core = std::make_unique<ARM_Unicorn>();
|
||||
LOG_WARNING(Core, "CPU JIT requested, but Dynarmic not available");
|
||||
#endif
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -122,7 +122,7 @@ u64 GetTicks() {
|
||||
}
|
||||
|
||||
void AddTicks(u64 ticks) {
|
||||
downcount -= ticks;
|
||||
downcount -= static_cast<int>(ticks);
|
||||
}
|
||||
|
||||
u64 GetIdleTicks() {
|
||||
@@ -208,7 +208,7 @@ void Advance() {
|
||||
Event evt = std::move(event_queue.front());
|
||||
std::pop_heap(event_queue.begin(), event_queue.end(), std::greater<Event>());
|
||||
event_queue.pop_back();
|
||||
evt.type->callback(evt.userdata, global_timer - evt.time);
|
||||
evt.type->callback(evt.userdata, static_cast<int>(global_timer - evt.time));
|
||||
}
|
||||
|
||||
is_global_timer_sane = false;
|
||||
|
||||
@@ -119,4 +119,4 @@ std::vector<u8> Path::AsBinary() const {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace FileSys
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "common/common_types.h"
|
||||
|
||||
@@ -183,11 +183,11 @@ static u8 NibbleToHex(u8 n) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Converts input hex string characters into an array of equivalent of u8 bytes.
|
||||
*
|
||||
* @param src Pointer to array of output hex string characters.
|
||||
* @param len Length of src array.
|
||||
*/
|
||||
* Converts input hex string characters into an array of equivalent of u8 bytes.
|
||||
*
|
||||
* @param src Pointer to array of output hex string characters.
|
||||
* @param len Length of src array.
|
||||
*/
|
||||
static u32 HexToInt(const u8* src, size_t len) {
|
||||
u32 output = 0;
|
||||
while (len-- > 0) {
|
||||
@@ -299,17 +299,17 @@ static std::map<u32, Breakpoint>& GetBreakpointList(BreakpointType type) {
|
||||
static void RemoveBreakpoint(BreakpointType type, PAddr addr) {
|
||||
std::map<u32, Breakpoint>& p = GetBreakpointList(type);
|
||||
|
||||
auto bp = p.find(addr);
|
||||
auto bp = p.find(static_cast<u32>(addr));
|
||||
if (bp != p.end()) {
|
||||
LOG_DEBUG(Debug_GDBStub, "gdb: removed a breakpoint: %08x bytes at %08x of type %d\n",
|
||||
bp->second.len, bp->second.addr, type);
|
||||
p.erase(addr);
|
||||
p.erase(static_cast<u32>(addr));
|
||||
}
|
||||
}
|
||||
|
||||
BreakpointAddress GetNextBreakpointFromAddress(PAddr addr, BreakpointType type) {
|
||||
std::map<u32, Breakpoint>& p = GetBreakpointList(type);
|
||||
auto next_breakpoint = p.lower_bound(addr);
|
||||
auto next_breakpoint = p.lower_bound(static_cast<u32>(addr));
|
||||
BreakpointAddress breakpoint;
|
||||
|
||||
if (next_breakpoint != p.end()) {
|
||||
@@ -330,7 +330,7 @@ bool CheckBreakpoint(PAddr addr, BreakpointType type) {
|
||||
|
||||
std::map<u32, Breakpoint>& p = GetBreakpointList(type);
|
||||
|
||||
auto bp = p.find(addr);
|
||||
auto bp = p.find(static_cast<u32>(addr));
|
||||
if (bp != p.end()) {
|
||||
u32 len = bp->second.len;
|
||||
|
||||
@@ -452,7 +452,8 @@ static void SendSignal(u32 signal) {
|
||||
|
||||
std::string buffer =
|
||||
Common::StringFromFormat("T%02x%02x:%08x;%02x:%08x;", latest_signal, 15,
|
||||
htonl(Core::CPU().GetPC()), 13, htonl(Core::CPU().GetReg(13)));
|
||||
htonl(static_cast<u_long>(Core::CPU().GetPC())), 13,
|
||||
htonl(static_cast<u_long>(Core::CPU().GetReg(13))));
|
||||
LOG_DEBUG(Debug_GDBStub, "Response: %s", buffer.c_str());
|
||||
SendReply(buffer.c_str());
|
||||
}
|
||||
@@ -539,7 +540,7 @@ static void ReadRegister() {
|
||||
}
|
||||
|
||||
if (id <= R15_REGISTER) {
|
||||
IntToGdbHex(reply, Core::CPU().GetReg(id));
|
||||
IntToGdbHex(reply, static_cast<u32>(Core::CPU().GetReg(static_cast<u64>(id))));
|
||||
} else if (id == CPSR_REGISTER) {
|
||||
IntToGdbHex(reply, Core::CPU().GetCPSR());
|
||||
} else if (id > CPSR_REGISTER && id < FPSCR_REGISTER) {
|
||||
@@ -563,7 +564,7 @@ static void ReadRegisters() {
|
||||
u8* bufptr = buffer;
|
||||
|
||||
for (int reg = 0; reg <= R15_REGISTER; reg++) {
|
||||
IntToGdbHex(bufptr + reg * CHAR_BIT, Core::CPU().GetReg(reg));
|
||||
IntToGdbHex(bufptr + reg * CHAR_BIT, static_cast<u32>(Core::CPU().GetReg(reg)));
|
||||
}
|
||||
|
||||
bufptr += (16 * CHAR_BIT);
|
||||
@@ -905,7 +906,7 @@ void ToggleServer(bool status) {
|
||||
server_enabled = status;
|
||||
|
||||
// Start server
|
||||
if (!IsConnected() && Core::System().GetInstance().IsPoweredOn()) {
|
||||
if (!IsConnected() && Core::System::GetInstance().IsPoweredOn()) {
|
||||
Init();
|
||||
}
|
||||
} else {
|
||||
@@ -1034,4 +1035,4 @@ bool GetCpuStepFlag() {
|
||||
void SetCpuStepFlag(bool is_step) {
|
||||
step_loop = is_step;
|
||||
}
|
||||
};
|
||||
}; // namespace GDBStub
|
||||
|
||||
@@ -91,4 +91,4 @@ bool GetCpuStepFlag();
|
||||
* @param is_step
|
||||
*/
|
||||
void SetCpuStepFlag(bool is_step);
|
||||
}
|
||||
} // namespace GDBStub
|
||||
|
||||
@@ -28,4 +28,4 @@ void Init() {
|
||||
config_mem.firm_ctr_sdk_ver = 0x0000F297;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace ConfigMem
|
||||
|
||||
@@ -53,4 +53,4 @@ extern ConfigMemDef config_mem;
|
||||
|
||||
void Init();
|
||||
|
||||
} // namespace
|
||||
} // namespace ConfigMem
|
||||
|
||||
@@ -19,7 +19,6 @@ constexpr size_t COMMAND_BUFFER_LENGTH = 0x100 / sizeof(u32);
|
||||
// TODO(yuriks): These will probably go away once translation is implemented inside the kernel.
|
||||
constexpr auto ERR_INVALID_HANDLE = Kernel::ERR_INVALID_HANDLE_OS;
|
||||
|
||||
|
||||
enum class ControlCommand : u32 {
|
||||
ConvertSessionToDomain = 0,
|
||||
ConvertDomainToSession = 1,
|
||||
@@ -81,13 +80,13 @@ struct BufferDescriptorX {
|
||||
u32_le address_bits_0_31;
|
||||
|
||||
u32_le Counter() const {
|
||||
u32_le counter{ counter_bits_0_5 };
|
||||
u32_le counter{counter_bits_0_5};
|
||||
counter |= counter_bits_9_11 << 9;
|
||||
return counter;
|
||||
}
|
||||
|
||||
VAddr Address() const {
|
||||
VAddr address{ address_bits_0_31 };
|
||||
VAddr address{address_bits_0_31};
|
||||
address |= static_cast<VAddr>(address_bits_32_35) << 32;
|
||||
address |= static_cast<VAddr>(address_bits_36_38) << 36;
|
||||
return address;
|
||||
@@ -107,14 +106,14 @@ struct BufferDescriptorABW {
|
||||
};
|
||||
|
||||
VAddr Address() const {
|
||||
VAddr address{ address_bits_0_31 };
|
||||
VAddr address{address_bits_0_31};
|
||||
address |= static_cast<VAddr>(address_bits_32_35) << 32;
|
||||
address |= static_cast<VAddr>(address_bits_36_38) << 36;
|
||||
return address;
|
||||
}
|
||||
|
||||
u64 Size() const {
|
||||
u64 size{ size_bits_0_31 };
|
||||
u64 size{size_bits_0_31};
|
||||
size |= static_cast<u64>(size_bits_32_35) << 32;
|
||||
return size;
|
||||
}
|
||||
@@ -130,10 +129,14 @@ struct BufferDescriptorC {
|
||||
};
|
||||
|
||||
VAddr Address() const {
|
||||
VAddr address{ address_bits_0_31 };
|
||||
VAddr address{address_bits_0_31};
|
||||
address |= static_cast<VAddr>(address_bits_32_47) << 32;
|
||||
return address;
|
||||
}
|
||||
|
||||
u64 Size() const {
|
||||
return static_cast<u64>(size);
|
||||
}
|
||||
};
|
||||
static_assert(sizeof(BufferDescriptorC) == 8, "BufferDescriptorC size is incorrect");
|
||||
|
||||
@@ -144,6 +147,11 @@ struct DataPayloadHeader {
|
||||
static_assert(sizeof(DataPayloadHeader) == 8, "DataPayloadRequest size is incorrect");
|
||||
|
||||
struct DomainMessageHeader {
|
||||
enum class CommandType : u32_le {
|
||||
SendMessage = 1,
|
||||
CloseVirtualHandle = 2,
|
||||
};
|
||||
|
||||
union {
|
||||
// Used when responding to an IPC request, Server -> Client.
|
||||
struct {
|
||||
@@ -154,7 +162,7 @@ struct DomainMessageHeader {
|
||||
// Used when performing an IPC request, Client -> Server.
|
||||
struct {
|
||||
union {
|
||||
BitField<0, 8, u32_le> command;
|
||||
BitField<0, 8, CommandType> command;
|
||||
BitField<16, 16, u32_le> size;
|
||||
};
|
||||
u32_le object_id;
|
||||
|
||||
@@ -9,10 +9,13 @@
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include "core/hle/ipc.h"
|
||||
#include "core/hle/kernel/client_port.h"
|
||||
#include "core/hle/kernel/client_session.h"
|
||||
#include "core/hle/kernel/domain.h"
|
||||
#include "core/hle/kernel/handle_table.h"
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/kernel/server_port.h"
|
||||
|
||||
namespace IPC {
|
||||
|
||||
@@ -51,6 +54,10 @@ public:
|
||||
unsigned GetCurrentOffset() const {
|
||||
return static_cast<unsigned>(index);
|
||||
}
|
||||
|
||||
void SetCurrentOffset(unsigned offset) {
|
||||
index = static_cast<ptrdiff_t>(offset);
|
||||
}
|
||||
};
|
||||
|
||||
class RequestBuilder : public RequestHelperBase {
|
||||
@@ -63,13 +70,20 @@ public:
|
||||
: RequestHelperBase(context) {
|
||||
memset(cmdbuf, 0, sizeof(u32) * IPC::COMMAND_BUFFER_LENGTH);
|
||||
|
||||
context.ClearIncomingObjects();
|
||||
|
||||
IPC::CommandHeader header{};
|
||||
|
||||
// The entire size of the raw data section in u32 units, including the 16 bytes of mandatory
|
||||
// padding.
|
||||
u32 raw_data_size = sizeof(IPC::DataPayloadHeader) / 4 + 4 + normal_params_size;
|
||||
if (context.IsDomain())
|
||||
if (context.IsDomain()) {
|
||||
raw_data_size += sizeof(DomainMessageHeader) / 4 + num_domain_objects;
|
||||
} else {
|
||||
// If we're not in a domain, turn the domain object parameters into move handles.
|
||||
num_handles_to_move += num_domain_objects;
|
||||
num_domain_objects = 0;
|
||||
}
|
||||
|
||||
header.data_size.Assign(raw_data_size);
|
||||
if (num_handles_to_copy || num_handles_to_move) {
|
||||
@@ -100,7 +114,15 @@ public:
|
||||
|
||||
template <class T, class... Args>
|
||||
void PushIpcInterface(Args&&... args) {
|
||||
context->AddDomainObject(std::make_shared<T>(std::forward<Args>(args)...));
|
||||
auto iface = std::make_shared<T>(std::forward<Args>(args)...);
|
||||
if (context->IsDomain()) {
|
||||
context->AddDomainObject(std::move(iface));
|
||||
} else {
|
||||
auto port = iface->CreatePort();
|
||||
auto session = port->Connect();
|
||||
ASSERT(session.Succeeded());
|
||||
context->AddMoveObject(std::move(session).Unwrap());
|
||||
}
|
||||
}
|
||||
|
||||
// Validate on destruction, as there shouldn't be any case where we don't want it
|
||||
|
||||
@@ -57,4 +57,4 @@ private:
|
||||
~AddressArbiter() override;
|
||||
};
|
||||
|
||||
} // namespace FileSys
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -39,4 +39,4 @@ ResultVal<SharedPtr<ClientSession>> ClientPort::Connect() {
|
||||
return MakeResult(std::get<SharedPtr<ClientSession>>(sessions));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -47,4 +47,4 @@ private:
|
||||
~ClientPort() override;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -48,4 +48,4 @@ ResultCode ClientSession::SendSyncRequest(SharedPtr<Thread> thread) {
|
||||
return server->HandleSyncRequest(std::move(thread));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -45,4 +45,4 @@ private:
|
||||
~ClientSession() override;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -43,7 +43,7 @@ void ConditionVariable::Acquire(Thread* thread) {
|
||||
ResultCode ConditionVariable::Release(s32 target) {
|
||||
if (target == -1) {
|
||||
// When -1, wake up all waiting threads
|
||||
SetAvailableCount(GetWaitingThreads().size());
|
||||
SetAvailableCount(static_cast<s32>(GetWaitingThreads().size()));
|
||||
WakeupAllWaitingThreads();
|
||||
} else {
|
||||
// Otherwise, wake up just a single thread
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <queue>
|
||||
#include <string>
|
||||
#include <queue>
|
||||
#include "common/common_types.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/kernel/wait_object.h"
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/client_port.h"
|
||||
#include "core/hle/kernel/domain.h"
|
||||
#include "core/hle/kernel/handle_table.h"
|
||||
@@ -36,7 +38,24 @@ ResultCode Domain::SendSyncRequest(SharedPtr<Thread> thread) {
|
||||
if (domain_message_header) {
|
||||
// If there is a DomainMessageHeader, then this is CommandType "Request"
|
||||
const u32 object_id{context.GetDomainMessageHeader()->object_id};
|
||||
return request_handlers[object_id - 1]->HandleSyncRequest(context);
|
||||
switch (domain_message_header->command) {
|
||||
case IPC::DomainMessageHeader::CommandType::SendMessage:
|
||||
return request_handlers[object_id - 1]->HandleSyncRequest(context);
|
||||
|
||||
case IPC::DomainMessageHeader::CommandType::CloseVirtualHandle: {
|
||||
LOG_DEBUG(IPC, "CloseVirtualHandle, object_id=0x%08X", object_id);
|
||||
|
||||
request_handlers[object_id - 1] = nullptr;
|
||||
|
||||
IPC::RequestBuilder rb{context, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_CRITICAL(IPC, "Unknown domain command=%d", domain_message_header->command.Value());
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
return request_handlers.front()->HandleSyncRequest(context);
|
||||
}
|
||||
|
||||
@@ -52,4 +52,4 @@ void Event::WakeupAllWaitingThreads() {
|
||||
signaled = false;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -49,4 +49,4 @@ private:
|
||||
~Event() override;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -104,4 +104,4 @@ void HandleTable::Clear() {
|
||||
next_free_slot = 0;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -130,4 +130,4 @@ private:
|
||||
|
||||
extern HandleTable g_handle_table;
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -81,13 +81,8 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) {
|
||||
for (unsigned i = 0; i < command_header->num_buf_w_descriptors; ++i) {
|
||||
buffer_w_desciptors.push_back(rp.PopRaw<IPC::BufferDescriptorABW>());
|
||||
}
|
||||
if (command_header->buf_c_descriptor_flags !=
|
||||
IPC::CommandHeader::BufferDescriptorCFlag::Disabled) {
|
||||
if (command_header->buf_c_descriptor_flags !=
|
||||
IPC::CommandHeader::BufferDescriptorCFlag::OneDescriptor) {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
}
|
||||
|
||||
buffer_c_offset = rp.GetCurrentOffset() + command_header->data_size;
|
||||
|
||||
// Padding to align to 16 bytes
|
||||
rp.AlignWithPadding();
|
||||
@@ -102,13 +97,45 @@ void HLERequestContext::ParseCommandBuffer(u32_le* src_cmdbuf, bool incoming) {
|
||||
data_payload_header =
|
||||
std::make_unique<IPC::DataPayloadHeader>(rp.PopRaw<IPC::DataPayloadHeader>());
|
||||
|
||||
data_payload_offset = rp.GetCurrentOffset();
|
||||
|
||||
if (domain_message_header && domain_message_header->command ==
|
||||
IPC::DomainMessageHeader::CommandType::CloseVirtualHandle) {
|
||||
// CloseVirtualHandle command does not have SFC* or any data
|
||||
return;
|
||||
}
|
||||
|
||||
if (incoming) {
|
||||
ASSERT(data_payload_header->magic == Common::MakeMagic('S', 'F', 'C', 'I'));
|
||||
} else {
|
||||
ASSERT(data_payload_header->magic == Common::MakeMagic('S', 'F', 'C', 'O'));
|
||||
}
|
||||
|
||||
data_payload_offset = rp.GetCurrentOffset();
|
||||
rp.SetCurrentOffset(buffer_c_offset);
|
||||
|
||||
// For Inline buffers, the response data is written directly to buffer_c_offset
|
||||
// and in this case we don't have any BufferDescriptorC on the request.
|
||||
if (command_header->buf_c_descriptor_flags >
|
||||
IPC::CommandHeader::BufferDescriptorCFlag::InlineDescriptor) {
|
||||
if (command_header->buf_c_descriptor_flags ==
|
||||
IPC::CommandHeader::BufferDescriptorCFlag::OneDescriptor) {
|
||||
buffer_c_desciptors.push_back(rp.PopRaw<IPC::BufferDescriptorC>());
|
||||
} else {
|
||||
unsigned num_buf_c_descriptors =
|
||||
static_cast<unsigned>(command_header->buf_c_descriptor_flags.Value()) - 2;
|
||||
|
||||
// This is used to detect possible underflows, in case something is broken
|
||||
// with the two ifs above and the flags value is == 0 || == 1.
|
||||
ASSERT(num_buf_c_descriptors < 14);
|
||||
|
||||
for (unsigned i = 0; i < num_buf_c_descriptors; ++i) {
|
||||
buffer_c_desciptors.push_back(rp.PopRaw<IPC::BufferDescriptorC>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
rp.SetCurrentOffset(data_payload_offset);
|
||||
|
||||
command = rp.Pop<u32_le>();
|
||||
rp.Skip(1, false); // The command is actually an u64, but we don't use the high part.
|
||||
}
|
||||
@@ -182,7 +209,7 @@ ResultCode HLERequestContext::WriteToOutgoingCommandBuffer(u32_le* dst_cmdbuf, P
|
||||
|
||||
for (auto& object : domain_objects) {
|
||||
request_handlers.emplace_back(object);
|
||||
dst_cmdbuf[domain_offset++] = request_handlers.size();
|
||||
dst_cmdbuf[domain_offset++] = static_cast<u32_le>(request_handlers.size());
|
||||
}
|
||||
}
|
||||
return RESULT_SUCCESS;
|
||||
|
||||
@@ -143,6 +143,10 @@ public:
|
||||
return buffer_b_desciptors;
|
||||
}
|
||||
|
||||
const std::vector<IPC::BufferDescriptorC>& BufferDescriptorC() const {
|
||||
return buffer_c_desciptors;
|
||||
}
|
||||
|
||||
const std::unique_ptr<IPC::DomainMessageHeader>& GetDomainMessageHeader() const {
|
||||
return domain_message_header;
|
||||
}
|
||||
@@ -151,13 +155,13 @@ public:
|
||||
return domain != nullptr;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
SharedPtr<T> GetCopyObject(size_t index) {
|
||||
ASSERT(index < copy_objects.size());
|
||||
return DynamicObjectCast<T>(copy_objects[index]);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
template <typename T>
|
||||
SharedPtr<T> GetMoveObject(size_t index) {
|
||||
ASSERT(index < move_objects.size());
|
||||
return DynamicObjectCast<T>(move_objects[index]);
|
||||
@@ -175,6 +179,14 @@ public:
|
||||
domain_objects.emplace_back(std::move(object));
|
||||
}
|
||||
|
||||
/// Clears the list of objects so that no lingering objects are written accidentally to the
|
||||
/// response buffer.
|
||||
void ClearIncomingObjects() {
|
||||
move_objects.clear();
|
||||
copy_objects.clear();
|
||||
domain_objects.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
std::array<u32, IPC::COMMAND_BUFFER_LENGTH> cmd_buf;
|
||||
SharedPtr<Kernel::Domain> domain;
|
||||
@@ -192,8 +204,10 @@ private:
|
||||
std::vector<IPC::BufferDescriptorABW> buffer_a_desciptors;
|
||||
std::vector<IPC::BufferDescriptorABW> buffer_b_desciptors;
|
||||
std::vector<IPC::BufferDescriptorABW> buffer_w_desciptors;
|
||||
std::vector<IPC::BufferDescriptorC> buffer_c_desciptors;
|
||||
|
||||
unsigned data_payload_offset{};
|
||||
unsigned buffer_c_offset{};
|
||||
u32_le command{};
|
||||
};
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ enum class HandleType : u32 {
|
||||
};
|
||||
|
||||
enum {
|
||||
DEFAULT_STACK_SIZE = 0x4000,
|
||||
DEFAULT_STACK_SIZE = 0x10000,
|
||||
};
|
||||
|
||||
enum class ResetType {
|
||||
@@ -105,7 +105,6 @@ public:
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
|
||||
public:
|
||||
static unsigned int next_object_id;
|
||||
|
||||
|
||||
@@ -95,10 +95,8 @@ MemoryRegionInfo* GetMemoryRegion(MemoryRegion region) {
|
||||
}
|
||||
}
|
||||
|
||||
void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mapping) {
|
||||
}
|
||||
void HandleSpecialMapping(VMManager& address_space, const AddressMapping& mapping) {}
|
||||
|
||||
void MapSharedPages(VMManager& address_space) {
|
||||
}
|
||||
void MapSharedPages(VMManager& address_space) {}
|
||||
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -41,9 +41,9 @@ public:
|
||||
return HANDLE_TYPE;
|
||||
}
|
||||
|
||||
u32 priority; ///< The priority of the mutex, used for priority inheritance.
|
||||
std::string name; ///< Name of mutex (optional)
|
||||
VAddr guest_addr; ///< Address of the guest mutex value
|
||||
u32 priority; ///< The priority of the mutex, used for priority inheritance.
|
||||
std::string name; ///< Name of mutex (optional)
|
||||
VAddr guest_addr; ///< Address of the guest mutex value
|
||||
|
||||
/**
|
||||
* Elevate the mutex priority to the best priority
|
||||
|
||||
@@ -131,6 +131,8 @@ public:
|
||||
/// Bitmask of allowed CPUs that this process' threads can run on. TODO(Subv): Actually parse
|
||||
/// this value from the process header.
|
||||
u32 allowed_processor_mask = THREADPROCESSORID_DEFAULT_MASK;
|
||||
u32 allowed_thread_priority_mask = 0xFFFFFFFF;
|
||||
u32 is_virtual_address_memory_enabled = 0;
|
||||
/// Current status of the process
|
||||
ProcessStatus status;
|
||||
|
||||
|
||||
@@ -151,4 +151,4 @@ void ResourceLimitsInit() {
|
||||
|
||||
void ResourceLimitsShutdown() {}
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -123,4 +123,4 @@ void ResourceLimitsInit();
|
||||
// Destroys the resource limits
|
||||
void ResourceLimitsShutdown();
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -50,4 +50,4 @@ std::tuple<SharedPtr<ServerPort>, SharedPtr<ClientPort>> ServerPort::CreatePortP
|
||||
return std::make_tuple(std::move(server_port), std::move(client_port));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -72,4 +72,4 @@ private:
|
||||
~ServerPort() override;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -113,4 +113,4 @@ private:
|
||||
* in the command buffer.
|
||||
*/
|
||||
ResultCode TranslateHLERequest(ServerSession* server_session);
|
||||
}
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -9,4 +9,4 @@ namespace Kernel {
|
||||
|
||||
Session::Session() {}
|
||||
Session::~Session() {}
|
||||
}
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -24,4 +24,4 @@ public:
|
||||
ServerSession* server = nullptr; ///< The server endpoint of the session.
|
||||
SharedPtr<ClientPort> port; ///< The port that this session is associated with (optional).
|
||||
};
|
||||
}
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -106,14 +106,14 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
|
||||
|
||||
// Error out if the requested permissions don't match what the creator process allows.
|
||||
if (static_cast<u32>(permissions) & ~static_cast<u32>(own_other_permissions)) {
|
||||
LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X name=%s, permissions don't match",
|
||||
LOG_ERROR(Kernel, "cannot map id=%u, address=0x%llx name=%s, permissions don't match",
|
||||
GetObjectId(), address, name.c_str());
|
||||
return ERR_INVALID_COMBINATION;
|
||||
}
|
||||
|
||||
// Heap-backed memory blocks can not be mapped with other_permissions = DontCare
|
||||
if (base_address != 0 && other_permissions == MemoryPermission::DontCare) {
|
||||
LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X name=%s, permissions don't match",
|
||||
LOG_ERROR(Kernel, "cannot map id=%u, address=0x%llx name=%s, permissions don't match",
|
||||
GetObjectId(), address, name.c_str());
|
||||
return ERR_INVALID_COMBINATION;
|
||||
}
|
||||
@@ -121,7 +121,7 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
|
||||
// Error out if the provided permissions are not compatible with what the creator process needs.
|
||||
if (other_permissions != MemoryPermission::DontCare &&
|
||||
static_cast<u32>(this->permissions) & ~static_cast<u32>(other_permissions)) {
|
||||
LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X name=%s, permissions don't match",
|
||||
LOG_ERROR(Kernel, "cannot map id=%u, address=0x%llx name=%s, permissions don't match",
|
||||
GetObjectId(), address, name.c_str());
|
||||
return ERR_WRONG_PERMISSION;
|
||||
}
|
||||
@@ -136,8 +136,8 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
|
||||
// can not map it in its own address space unless it was created with addr=0, result 0xD900182C.
|
||||
|
||||
if (address != 0) {
|
||||
if (address < Memory::HEAP_VADDR || address + size >= Memory::SHARED_MEMORY_VADDR_END) {
|
||||
LOG_ERROR(Kernel, "cannot map id=%u, address=0x%08X name=%s, invalid address",
|
||||
if (address < Memory::HEAP_VADDR) {
|
||||
LOG_ERROR(Kernel, "cannot map id=%u, address=0x%llx name=%s, invalid address",
|
||||
GetObjectId(), address, name.c_str());
|
||||
return ERR_INVALID_ADDRESS;
|
||||
}
|
||||
@@ -156,7 +156,7 @@ ResultCode SharedMemory::Map(Process* target_process, VAddr address, MemoryPermi
|
||||
if (result.Failed()) {
|
||||
LOG_ERROR(
|
||||
Kernel,
|
||||
"cannot map id=%u, target_address=0x%08X name=%s, error mapping to virtual memory",
|
||||
"cannot map id=%u, target_address=0x%llx name=%s, error mapping to virtual memory",
|
||||
GetObjectId(), target_address, name.c_str());
|
||||
return result.Code();
|
||||
}
|
||||
|
||||
@@ -98,10 +98,10 @@ public:
|
||||
ResultCode Unmap(Process* target_process, VAddr address);
|
||||
|
||||
/**
|
||||
* Gets a pointer to the shared memory block
|
||||
* @param offset Offset from the start of the shared memory block to get pointer
|
||||
* @return Pointer to the shared memory block from the specified offset
|
||||
*/
|
||||
* Gets a pointer to the shared memory block
|
||||
* @param offset Offset from the start of the shared memory block to get pointer
|
||||
* @return Pointer to the shared memory block from the specified offset
|
||||
*/
|
||||
u8* GetPointer(u32 offset = 0);
|
||||
|
||||
/// Process that created this shared memory block.
|
||||
@@ -129,4 +129,4 @@ private:
|
||||
~SharedMemory() override;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
#include "core/hle/kernel/object_address_table.h"
|
||||
#include "core/hle/kernel/process.h"
|
||||
#include "core/hle/kernel/resource_limit.h"
|
||||
#include "core/hle/kernel/shared_memory.h"
|
||||
#include "core/hle/kernel/svc.h"
|
||||
#include "core/hle/kernel/svc_wrap.h"
|
||||
#include "core/hle/kernel/sync_object.h"
|
||||
@@ -56,7 +57,7 @@ static ResultCode UnmapMemory(VAddr dst_addr, VAddr src_addr, u64 size) {
|
||||
}
|
||||
|
||||
/// Connect to an OS service given the port name, returns the handle to the port to out
|
||||
static ResultCode ConnectToPort(Handle* out_handle, VAddr port_name_address) {
|
||||
static ResultCode ConnectToNamedPort(Handle* out_handle, VAddr port_name_address) {
|
||||
if (!Memory::IsValidVirtualAddress(port_name_address))
|
||||
return ERR_NOT_FOUND;
|
||||
|
||||
@@ -252,8 +253,8 @@ static ResultCode CancelSynchronization(Handle thread_handle) {
|
||||
}
|
||||
|
||||
/// Attempts to locks a mutex, creating it if it does not already exist
|
||||
static ResultCode LockMutex(Handle holding_thread_handle, VAddr mutex_addr,
|
||||
Handle requesting_thread_handle) {
|
||||
static ResultCode ArbitrateLock(Handle holding_thread_handle, VAddr mutex_addr,
|
||||
Handle requesting_thread_handle) {
|
||||
LOG_TRACE(Kernel_SVC,
|
||||
"called holding_thread_handle=0x%08X, mutex_addr=0x%llx, "
|
||||
"requesting_current_thread_handle=0x%08X",
|
||||
@@ -277,7 +278,7 @@ static ResultCode LockMutex(Handle holding_thread_handle, VAddr mutex_addr,
|
||||
}
|
||||
|
||||
/// Unlock a mutex
|
||||
static ResultCode UnlockMutex(VAddr mutex_addr) {
|
||||
static ResultCode ArbitrateUnlock(VAddr mutex_addr) {
|
||||
LOG_TRACE(Kernel_SVC, "called mutex_addr=0x%llx", mutex_addr);
|
||||
|
||||
SharedPtr<Mutex> mutex = g_object_address_table.Get<Mutex>(mutex_addr);
|
||||
@@ -304,14 +305,27 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
|
||||
LOG_TRACE(Kernel_SVC, "called info_id=0x%X, info_sub_id=0x%X, handle=0x%08X", info_id,
|
||||
info_sub_id, handle);
|
||||
|
||||
ASSERT(handle == 0 || handle == CurrentProcess);
|
||||
|
||||
auto& vm_manager = g_current_process->vm_manager;
|
||||
|
||||
switch (static_cast<GetInfoType>(info_id)) {
|
||||
case GetInfoType::AllowedCpuIdBitmask:
|
||||
*result = g_current_process->allowed_processor_mask;
|
||||
break;
|
||||
case GetInfoType::AllowedThreadPrioBitmask:
|
||||
*result = g_current_process->allowed_thread_priority_mask;
|
||||
break;
|
||||
case GetInfoType::MapRegionBaseAddr:
|
||||
*result = vm_manager.GetMapRegionBaseAddr();
|
||||
break;
|
||||
case GetInfoType::MapRegionSize:
|
||||
*result = vm_manager.GetAddressSpaceSize();
|
||||
break;
|
||||
case GetInfoType::HeapRegionBaseAddr:
|
||||
*result = vm_manager.GetNewMapRegionBaseAddr() + vm_manager.GetNewMapRegionSize();
|
||||
break;
|
||||
case GetInfoType::HeapRegionSize:
|
||||
*result = Memory::HEAP_SIZE;
|
||||
break;
|
||||
case GetInfoType::TotalMemoryUsage:
|
||||
*result = vm_manager.GetTotalMemoryUsage();
|
||||
break;
|
||||
@@ -333,6 +347,18 @@ static ResultCode GetInfo(u64* result, u64 info_id, u64 handle, u64 info_sub_id)
|
||||
case GetInfoType::NewMapRegionSize:
|
||||
*result = vm_manager.GetNewMapRegionSize();
|
||||
break;
|
||||
case GetInfoType::IsVirtualAddressMemoryEnabled:
|
||||
*result = g_current_process->is_virtual_address_memory_enabled;
|
||||
break;
|
||||
case GetInfoType::TitleId:
|
||||
LOG_WARNING(Kernel_SVC, "(STUBBED) Attempted to query titleid, returned 0");
|
||||
*result = 0;
|
||||
break;
|
||||
case GetInfoType::PrivilegedProcessId:
|
||||
LOG_WARNING(Kernel_SVC,
|
||||
"(STUBBED) Attempted to query priviledged process id bounds, returned 0");
|
||||
*result = 0;
|
||||
break;
|
||||
default:
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
@@ -384,6 +410,37 @@ static u32 GetCurrentProcessorNumber() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ResultCode MapSharedMemory(Handle shared_memory_handle, VAddr addr, u64 size,
|
||||
u32 permissions) {
|
||||
LOG_TRACE(Kernel_SVC,
|
||||
"called, shared_memory_handle=0x%08X, addr=0x%llx, size=0x%llx, permissions=0x%08X",
|
||||
shared_memory_handle, addr, size, permissions);
|
||||
|
||||
SharedPtr<SharedMemory> shared_memory =
|
||||
Kernel::g_handle_table.Get<SharedMemory>(shared_memory_handle);
|
||||
if (!shared_memory) {
|
||||
return ERR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
MemoryPermission permissions_type = static_cast<MemoryPermission>(permissions);
|
||||
switch (permissions_type) {
|
||||
case MemoryPermission::Read:
|
||||
case MemoryPermission::Write:
|
||||
case MemoryPermission::ReadWrite:
|
||||
case MemoryPermission::Execute:
|
||||
case MemoryPermission::ReadExecute:
|
||||
case MemoryPermission::WriteExecute:
|
||||
case MemoryPermission::ReadWriteExecute:
|
||||
case MemoryPermission::DontCare:
|
||||
return shared_memory->Map(Kernel::g_current_process.get(), addr, permissions_type,
|
||||
MemoryPermission::DontCare);
|
||||
default:
|
||||
LOG_ERROR(Kernel_SVC, "unknown permissions=0x%08X", permissions);
|
||||
}
|
||||
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
/// Query process memory
|
||||
static ResultCode QueryProcessMemory(MemoryInfo* memory_info, PageInfo* /*page_info*/,
|
||||
Handle process_handle, u64 addr) {
|
||||
@@ -677,6 +734,23 @@ static ResultCode CreateTransferMemory(Handle* handle, VAddr addr, u64 size, u32
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
static ResultCode SetThreadCoreMask(u64, u64, u64) {
|
||||
LOG_WARNING(Kernel_SVC, "(STUBBED) called");
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
static ResultCode CreateSharedMemory(Handle* handle, u64 sz, u32 local_permissions,
|
||||
u32 remote_permissions) {
|
||||
LOG_TRACE(Kernel_SVC, "called, sz=0x%llx, localPerms=0x%08x, remotePerms=0x%08x", sz,
|
||||
local_permissions, remote_permissions);
|
||||
auto sharedMemHandle = SharedMemory::Create(
|
||||
g_handle_table.Get<Process>(KernelHandle::CurrentProcess), sz,
|
||||
(Kernel::MemoryPermission)local_permissions, (Kernel::MemoryPermission)remote_permissions);
|
||||
|
||||
CASCADE_RESULT(*handle, g_handle_table.Create(sharedMemHandle));
|
||||
return RESULT_SUCCESS;
|
||||
}
|
||||
|
||||
namespace {
|
||||
struct FunctionDef {
|
||||
using Func = void();
|
||||
@@ -703,23 +777,23 @@ static const FunctionDef SVC_Table[] = {
|
||||
{0x0C, SvcWrap<GetThreadPriority>, "GetThreadPriority"},
|
||||
{0x0D, SvcWrap<SetThreadPriority>, "SetThreadPriority"},
|
||||
{0x0E, nullptr, "GetThreadCoreMask"},
|
||||
{0x0F, nullptr, "SetThreadCoreMask"},
|
||||
{0x0F, SvcWrap<SetThreadCoreMask>, "SetThreadCoreMask"},
|
||||
{0x10, SvcWrap<GetCurrentProcessorNumber>, "GetCurrentProcessorNumber"},
|
||||
{0x11, nullptr, "SignalEvent"},
|
||||
{0x12, nullptr, "ClearEvent"},
|
||||
{0x13, nullptr, "MapSharedMemory"},
|
||||
{0x13, SvcWrap<MapSharedMemory>, "MapSharedMemory"},
|
||||
{0x14, nullptr, "UnmapSharedMemory"},
|
||||
{0x15, SvcWrap<CreateTransferMemory>, "CreateTransferMemory"},
|
||||
{0x16, SvcWrap<CloseHandle>, "CloseHandle"},
|
||||
{0x17, SvcWrap<ResetSignal>, "ResetSignal"},
|
||||
{0x18, SvcWrap<WaitSynchronization>, "WaitSynchronization"},
|
||||
{0x19, SvcWrap<CancelSynchronization>, "CancelSynchronization"},
|
||||
{0x1A, SvcWrap<LockMutex>, "LockMutex"},
|
||||
{0x1B, SvcWrap<UnlockMutex>, "UnlockMutex"},
|
||||
{0x1A, SvcWrap<ArbitrateLock>, "ArbitrateLock"},
|
||||
{0x1B, SvcWrap<ArbitrateUnlock>, "ArbitrateUnlock"},
|
||||
{0x1C, SvcWrap<WaitProcessWideKeyAtomic>, "WaitProcessWideKeyAtomic"},
|
||||
{0x1D, SvcWrap<SignalProcessWideKey>, "SignalProcessWideKey"},
|
||||
{0x1E, SvcWrap<GetSystemTick>, "GetSystemTick"},
|
||||
{0x1F, SvcWrap<ConnectToPort>, "ConnectToPort"},
|
||||
{0x1F, SvcWrap<ConnectToNamedPort>, "ConnectToNamedPort"},
|
||||
{0x20, nullptr, "SendSyncRequestLight"},
|
||||
{0x21, SvcWrap<SendSyncRequest>, "SendSyncRequest"},
|
||||
{0x22, nullptr, "SendSyncRequestWithUserBuffer"},
|
||||
@@ -763,12 +837,12 @@ static const FunctionDef SVC_Table[] = {
|
||||
{0x48, nullptr, "Unknown"},
|
||||
{0x49, nullptr, "Unknown"},
|
||||
{0x4A, nullptr, "Unknown"},
|
||||
{0x4B, nullptr, "Unknown"},
|
||||
{0x4C, nullptr, "Unknown"},
|
||||
{0x4B, nullptr, "CreateJitMemory"},
|
||||
{0x4C, nullptr, "MapJitMemory"},
|
||||
{0x4D, nullptr, "SleepSystem"},
|
||||
{0x4E, nullptr, "ReadWriteRegister"},
|
||||
{0x4F, nullptr, "SetProcessActivity"},
|
||||
{0x50, nullptr, "CreateSharedMemory"},
|
||||
{0x50, SvcWrap<CreateSharedMemory>, "CreateSharedMemory"},
|
||||
{0x51, nullptr, "MapTransferMemory"},
|
||||
{0x52, nullptr, "UnmapTransferMemory"},
|
||||
{0x53, nullptr, "CreateInterruptEvent"},
|
||||
|
||||
@@ -14,7 +14,11 @@ struct MemoryInfo {
|
||||
u32 type;
|
||||
u32 attributes;
|
||||
u32 permission;
|
||||
u32 device_refcount;
|
||||
u32 ipc_refcount;
|
||||
INSERT_PADDING_WORDS(1);
|
||||
};
|
||||
static_assert(sizeof(MemoryInfo) == 0x28, "MemoryInfo has incorrect size.");
|
||||
|
||||
struct PageInfo {
|
||||
u64 flags;
|
||||
@@ -24,14 +28,28 @@ struct PageInfo {
|
||||
enum class GetInfoType : u64 {
|
||||
// 1.0.0+
|
||||
AllowedCpuIdBitmask = 0,
|
||||
AllowedThreadPrioBitmask = 1,
|
||||
MapRegionBaseAddr = 2,
|
||||
MapRegionSize = 3,
|
||||
HeapRegionBaseAddr = 4,
|
||||
HeapRegionSize = 5,
|
||||
TotalMemoryUsage = 6,
|
||||
TotalHeapUsage = 7,
|
||||
IsCurrentProcessBeingDebugged = 8,
|
||||
ResourceHandleLimit = 9,
|
||||
IdleTickCount = 10,
|
||||
RandomEntropy = 11,
|
||||
PerformanceCounter = 0xF0000002,
|
||||
// 2.0.0+
|
||||
AddressSpaceBaseAddr = 12,
|
||||
AddressSpaceSize = 13,
|
||||
NewMapRegionBaseAddr = 14,
|
||||
NewMapRegionSize = 15,
|
||||
// 3.0.0+
|
||||
IsVirtualAddressMemoryEnabled = 16,
|
||||
TitleId = 18,
|
||||
// 4.0.0+
|
||||
PrivilegedProcessId = 19,
|
||||
};
|
||||
|
||||
void CallSVC(u32 immediate);
|
||||
|
||||
@@ -86,6 +86,11 @@ void SvcWrap() {
|
||||
FuncReturn(func(PARAM(0), PARAM(1), PARAM(2)).raw);
|
||||
}
|
||||
|
||||
template <ResultCode func(u32, u64, u64, u32)>
|
||||
void SvcWrap() {
|
||||
FuncReturn(func((u32)PARAM(0), PARAM(1), PARAM(2), (u32)PARAM(3)).raw);
|
||||
}
|
||||
|
||||
template <ResultCode func(u32*, u64, u64, s64)>
|
||||
void SvcWrap() {
|
||||
u32 param_1 = 0;
|
||||
@@ -140,6 +145,15 @@ void SvcWrap() {
|
||||
FuncReturn(retval);
|
||||
}
|
||||
|
||||
template <ResultCode func(Handle*, u64, u32, u32)>
|
||||
void SvcWrap() {
|
||||
u32 param_1 = 0;
|
||||
u32 retval =
|
||||
func(¶m_1, PARAM(1), (u32)(PARAM(2) & 0xFFFFFFFF), (u32)(PARAM(3) & 0xFFFFFFFF)).raw;
|
||||
Core::CPU().SetReg(1, param_1);
|
||||
FuncReturn(retval);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Function wrappers that return type u32
|
||||
|
||||
|
||||
@@ -111,4 +111,4 @@ void TimersInit() {
|
||||
|
||||
void TimersShutdown() {}
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -76,4 +76,4 @@ void TimersInit();
|
||||
/// Tears down the timer variables
|
||||
void TimersShutdown();
|
||||
|
||||
} // namespace
|
||||
} // namespace Kernel
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/arm/arm_interface.h"
|
||||
#include "core/core.h"
|
||||
#include "core/hle/kernel/errors.h"
|
||||
#include "core/hle/kernel/vm_manager.h"
|
||||
#include "core/core.h"
|
||||
#include "core/memory.h"
|
||||
#include "core/memory_setup.h"
|
||||
#include "core/mmio.h"
|
||||
@@ -86,7 +86,8 @@ ResultVal<VMManager::VMAHandle> VMManager::MapMemoryBlock(VAddr target,
|
||||
VirtualMemoryArea& final_vma = vma_handle->second;
|
||||
ASSERT(final_vma.size == size);
|
||||
|
||||
Core::CPU().MapBackingMemory(target, size, block->data() + offset, VMAPermission::ReadWriteExecute);
|
||||
Core::CPU().MapBackingMemory(target, size, block->data() + offset,
|
||||
VMAPermission::ReadWriteExecute);
|
||||
|
||||
final_vma.type = VMAType::AllocatedMemoryBlock;
|
||||
final_vma.permissions = VMAPermission::ReadWrite;
|
||||
@@ -356,12 +357,12 @@ void VMManager::UpdatePageTableForVMA(const VirtualMemoryArea& vma) {
|
||||
|
||||
u64 VMManager::GetTotalMemoryUsage() {
|
||||
LOG_WARNING(Kernel, "(STUBBED) called");
|
||||
return 0x400000;
|
||||
return 0xBE000000;
|
||||
}
|
||||
|
||||
u64 VMManager::GetTotalHeapUsage() {
|
||||
LOG_WARNING(Kernel, "(STUBBED) called");
|
||||
return 0x10000;
|
||||
return 0x0;
|
||||
}
|
||||
|
||||
VAddr VMManager::GetAddressSpaceBaseAddr() {
|
||||
@@ -374,6 +375,11 @@ u64 VMManager::GetAddressSpaceSize() {
|
||||
return MAX_ADDRESS;
|
||||
}
|
||||
|
||||
VAddr VMManager::GetMapRegionBaseAddr() {
|
||||
LOG_WARNING(Kernel, "(STUBBED) called");
|
||||
return Memory::HEAP_VADDR;
|
||||
}
|
||||
|
||||
VAddr VMManager::GetNewMapRegionBaseAddr() {
|
||||
LOG_WARNING(Kernel, "(STUBBED) called");
|
||||
return 0x8000000;
|
||||
|
||||
@@ -192,6 +192,9 @@ public:
|
||||
/// Gets the total address space address size, used by svcGetInfo
|
||||
u64 GetAddressSpaceSize();
|
||||
|
||||
/// Gets the map region base address, used by svcGetInfo
|
||||
VAddr GetMapRegionBaseAddr();
|
||||
|
||||
/// Gets the base address for a new memory region, used by svcGetInfo
|
||||
VAddr GetNewMapRegionBaseAddr();
|
||||
|
||||
|
||||
16
src/core/hle/service/acc/acc.cpp
Normal file
16
src/core/hle/service/acc/acc.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "core/hle/service/acc/acc.h"
|
||||
#include "core/hle/service/acc/acc_u0.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Account {
|
||||
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager) {
|
||||
std::make_shared<ACC_U0>()->InstallAsService(service_manager);
|
||||
}
|
||||
|
||||
} // namespace Account
|
||||
} // namespace Service
|
||||
16
src/core/hle/service/acc/acc.h
Normal file
16
src/core/hle/service/acc/acc.h
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Account {
|
||||
|
||||
/// Registers all ACC services with the specified service manager.
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager);
|
||||
|
||||
} // namespace Account
|
||||
} // namespace Service
|
||||
87
src/core/hle/service/acc/acc_u0.cpp
Normal file
87
src/core/hle/service/acc/acc_u0.cpp
Normal file
@@ -0,0 +1,87 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/service/acc/acc_u0.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Account {
|
||||
|
||||
class IProfile final : public ServiceFramework<IProfile> {
|
||||
public:
|
||||
IProfile() : ServiceFramework("IProfile") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{1, &IProfile::GetBase, "GetBase"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
private:
|
||||
void GetBase(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
ProfileBase profile_base{};
|
||||
IPC::RequestBuilder rb{ctx, 16};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushRaw(profile_base);
|
||||
}
|
||||
};
|
||||
|
||||
class IManagerForApplication final : public ServiceFramework<IManagerForApplication> {
|
||||
public:
|
||||
IManagerForApplication() : ServiceFramework("IProfile") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IManagerForApplication::CheckAvailability, "CheckAvailability"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
private:
|
||||
void CheckAvailability(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
IPC::RequestBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(true); // TODO: Check when this is supposed to return true and when not
|
||||
}
|
||||
};
|
||||
|
||||
void ACC_U0::GetUserExistence(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
IPC::RequestBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(true); // TODO: Check when this is supposed to return true and when not
|
||||
}
|
||||
|
||||
void ACC_U0::GetProfile(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 2, 0, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IProfile>();
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
|
||||
void ACC_U0::InitializeApplicationInfo(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
IPC::RequestBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
void ACC_U0::GetBaasAccountManagerForApplication(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 2, 0, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IManagerForApplication>();
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
|
||||
ACC_U0::ACC_U0() : ServiceFramework("acc:u0") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{1, &ACC_U0::GetUserExistence, "GetUserExistence"},
|
||||
{5, &ACC_U0::GetProfile, "GetProfile"},
|
||||
{100, &ACC_U0::InitializeApplicationInfo, "InitializeApplicationInfo"},
|
||||
{101, &ACC_U0::GetBaasAccountManagerForApplication, "GetBaasAccountManagerForApplication"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
} // namespace Account
|
||||
} // namespace Service
|
||||
37
src/core/hle/service/acc/acc_u0.h
Normal file
37
src/core/hle/service/acc/acc_u0.h
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Account {
|
||||
|
||||
// TODO: RE this structure
|
||||
struct UserData {
|
||||
INSERT_PADDING_BYTES(0x80);
|
||||
};
|
||||
static_assert(sizeof(UserData) == 0x80, "UserData structure has incorrect size");
|
||||
|
||||
// TODO: RE this structure
|
||||
struct ProfileBase {
|
||||
INSERT_PADDING_BYTES(0x38);
|
||||
};
|
||||
static_assert(sizeof(ProfileBase) == 0x38, "ProfileBase structure has incorrect size");
|
||||
|
||||
class ACC_U0 final : public ServiceFramework<ACC_U0> {
|
||||
public:
|
||||
ACC_U0();
|
||||
~ACC_U0() = default;
|
||||
|
||||
private:
|
||||
void GetUserExistence(Kernel::HLERequestContext& ctx);
|
||||
void GetProfile(Kernel::HLERequestContext& ctx);
|
||||
void InitializeApplicationInfo(Kernel::HLERequestContext& ctx);
|
||||
void GetBaasAccountManagerForApplication(Kernel::HLERequestContext& ctx);
|
||||
};
|
||||
|
||||
} // namespace Account
|
||||
} // namespace Service
|
||||
@@ -6,6 +6,7 @@
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/event.h"
|
||||
#include "core/hle/service/am/applet_oe.h"
|
||||
#include "core/hle/service/apm/apm.h"
|
||||
|
||||
namespace Service {
|
||||
namespace AM {
|
||||
@@ -52,7 +53,97 @@ public:
|
||||
|
||||
class ISelfController final : public ServiceFramework<ISelfController> {
|
||||
public:
|
||||
ISelfController() : ServiceFramework("ISelfController") {}
|
||||
ISelfController() : ServiceFramework("ISelfController") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{1, &ISelfController::LockExit, "LockExit"},
|
||||
{2, &ISelfController::UnlockExit, "UnlockExit"},
|
||||
{11, &ISelfController::SetOperationModeChangedNotification,
|
||||
"SetOperationModeChangedNotification"},
|
||||
{12, &ISelfController::SetPerformanceModeChangedNotification,
|
||||
"SetPerformanceModeChangedNotification"},
|
||||
{13, &ISelfController::SetFocusHandlingMode, "SetFocusHandlingMode"},
|
||||
{14, &ISelfController::SetRestartMessageEnabled, "SetRestartMessageEnabled"},
|
||||
{16, &ISelfController::SetOutOfFocusSuspendingEnabled,
|
||||
"SetOutOfFocusSuspendingEnabled"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
private:
|
||||
void SetFocusHandlingMode(Kernel::HLERequestContext& ctx) {
|
||||
// Takes 3 input u8s with each field located immediately after the previous u8, these are
|
||||
// bool flags. No output.
|
||||
|
||||
IPC::RequestParser rp{ctx};
|
||||
|
||||
struct FocusHandlingModeParams {
|
||||
u8 unknown0;
|
||||
u8 unknown1;
|
||||
u8 unknown2;
|
||||
};
|
||||
auto flags = rp.PopRaw<FocusHandlingModeParams>();
|
||||
|
||||
IPC::RequestBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void SetRestartMessageEnabled(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void SetPerformanceModeChangedNotification(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
|
||||
bool flag = rp.Pop<bool>();
|
||||
|
||||
IPC::RequestBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_WARNING(Service, "(STUBBED) called flag=%u", static_cast<u32>(flag));
|
||||
}
|
||||
|
||||
void SetOperationModeChangedNotification(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
|
||||
bool flag = rp.Pop<bool>();
|
||||
|
||||
IPC::RequestBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_WARNING(Service, "(STUBBED) called flag=%u", static_cast<u32>(flag));
|
||||
}
|
||||
|
||||
void SetOutOfFocusSuspendingEnabled(Kernel::HLERequestContext& ctx) {
|
||||
// Takes 3 input u8s with each field located immediately after the previous u8, these are
|
||||
// bool flags. No output.
|
||||
IPC::RequestParser rp{ctx};
|
||||
|
||||
bool enabled = rp.Pop<bool>();
|
||||
|
||||
IPC::RequestBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_WARNING(Service, "(STUBBED) called enabled=%u", static_cast<u32>(enabled));
|
||||
}
|
||||
|
||||
void LockExit(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void UnlockExit(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
}
|
||||
};
|
||||
|
||||
class ICommonStateGetter final : public ServiceFramework<ICommonStateGetter> {
|
||||
@@ -61,6 +152,9 @@ public:
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &ICommonStateGetter::GetEventHandle, "GetEventHandle"},
|
||||
{1, &ICommonStateGetter::ReceiveMessage, "ReceiveMessage"},
|
||||
{5, &ICommonStateGetter::GetOperationMode, "GetOperationMode"},
|
||||
{6, &ICommonStateGetter::GetPerformanceMode, "GetPerformanceMode"},
|
||||
{9, &ICommonStateGetter::GetCurrentFocusState, "GetCurrentFocusState"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
|
||||
@@ -68,6 +162,16 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
enum class FocusState : u8 {
|
||||
InFocus = 1,
|
||||
NotInFocus = 2,
|
||||
};
|
||||
|
||||
enum class OperationMode : u8 {
|
||||
Handheld = 0,
|
||||
Docked = 1,
|
||||
};
|
||||
|
||||
void GetEventHandle(Kernel::HLERequestContext& ctx) {
|
||||
event->Signal();
|
||||
|
||||
@@ -81,7 +185,31 @@ private:
|
||||
void ReceiveMessage(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(1);
|
||||
rb.Push<u32>(15);
|
||||
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void GetCurrentFocusState(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(static_cast<u8>(FocusState::InFocus));
|
||||
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void GetOperationMode(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(static_cast<u8>(OperationMode::Handheld));
|
||||
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void GetPerformanceMode(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(static_cast<u32>(APM::PerformanceMode::Handheld));
|
||||
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
}
|
||||
@@ -89,9 +217,147 @@ private:
|
||||
Kernel::SharedPtr<Kernel::Event> event;
|
||||
};
|
||||
|
||||
class IStorageAccessor final : public ServiceFramework<IStorageAccessor> {
|
||||
public:
|
||||
explicit IStorageAccessor(std::vector<u8> buffer)
|
||||
: ServiceFramework("IStorageAccessor"), buffer(std::move(buffer)) {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IStorageAccessor::GetSize, "GetSize"},
|
||||
{11, &IStorageAccessor::Read, "Read"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<u8> buffer;
|
||||
|
||||
void GetSize(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 4};
|
||||
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push(static_cast<u64>(buffer.size()));
|
||||
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
|
||||
void Read(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
|
||||
u64 offset = rp.Pop<u64>();
|
||||
|
||||
const auto& output_buffer = ctx.BufferDescriptorC()[0];
|
||||
|
||||
ASSERT(offset + output_buffer.Size() <= buffer.size());
|
||||
|
||||
Memory::WriteBlock(output_buffer.Address(), buffer.data() + offset, output_buffer.Size());
|
||||
|
||||
IPC::RequestBuilder rb{ctx, 2};
|
||||
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
};
|
||||
|
||||
class IStorage final : public ServiceFramework<IStorage> {
|
||||
public:
|
||||
explicit IStorage(std::vector<u8> buffer)
|
||||
: ServiceFramework("IStorage"), buffer(std::move(buffer)) {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IStorage::Open, "Open"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<u8> buffer;
|
||||
|
||||
void Open(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 2, 0, 0, 1};
|
||||
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<AM::IStorageAccessor>(buffer);
|
||||
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
};
|
||||
|
||||
class IApplicationFunctions final : public ServiceFramework<IApplicationFunctions> {
|
||||
public:
|
||||
IApplicationFunctions() : ServiceFramework("IApplicationFunctions") {}
|
||||
IApplicationFunctions() : ServiceFramework("IApplicationFunctions") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{1, &IApplicationFunctions::PopLaunchParameter, "PopLaunchParameter"},
|
||||
{21, &IApplicationFunctions::GetDesiredLanguage, "GetDesiredLanguage"},
|
||||
{22, &IApplicationFunctions::SetTerminateResult, "SetTerminateResult"},
|
||||
{66, &IApplicationFunctions::InitializeGamePlayRecording,
|
||||
"InitializeGamePlayRecording"},
|
||||
{67, &IApplicationFunctions::SetGamePlayRecordingState, "SetGamePlayRecordingState"},
|
||||
{40, &IApplicationFunctions::NotifyRunning, "NotifyRunning"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
private:
|
||||
void PopLaunchParameter(Kernel::HLERequestContext& ctx) {
|
||||
constexpr u8 data[0x88] = {
|
||||
0xca, 0x97, 0x94, 0xc7, // Magic
|
||||
1, 0, 0, 0, // IsAccountSelected (bool)
|
||||
1, 0, 0, 0, // User Id (word 0)
|
||||
0, 0, 0, 0, // User Id (word 1)
|
||||
0, 0, 0, 0, // User Id (word 2)
|
||||
0, 0, 0, 0 // User Id (word 3)
|
||||
};
|
||||
|
||||
std::vector<u8> buffer(data, data + sizeof(data));
|
||||
|
||||
IPC::RequestBuilder rb{ctx, 2, 0, 0, 1};
|
||||
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<AM::IStorage>(buffer);
|
||||
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
|
||||
void SetTerminateResult(Kernel::HLERequestContext& ctx) {
|
||||
// Takes an input u32 Result, no output.
|
||||
// For example, in some cases official apps use this with error 0x2A2 then uses svcBreak.
|
||||
|
||||
IPC::RequestParser rp{ctx};
|
||||
u32 result = rp.Pop<u32>();
|
||||
|
||||
IPC::RequestBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_WARNING(Service, "(STUBBED) called, result=0x%08X", result);
|
||||
}
|
||||
|
||||
void GetDesiredLanguage(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 4};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u64>(SystemLanguage::English);
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void InitializeGamePlayRecording(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void SetGamePlayRecordingState(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
}
|
||||
|
||||
void NotifyRunning(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u8>(0); // Unknown, seems to be ignored by official processes
|
||||
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
}
|
||||
};
|
||||
|
||||
class ILibraryAppletCreator final : public ServiceFramework<ILibraryAppletCreator> {
|
||||
@@ -120,48 +386,56 @@ private:
|
||||
IPC::RequestBuilder rb{ctx, 2, 0, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IAudioController>();
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
|
||||
void GetDisplayController(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 2, 0, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IDisplayController>();
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
|
||||
void GetDebugFunctions(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 2, 0, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IDebugFunctions>();
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
|
||||
void GetWindowController(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 2, 0, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IWindowController>();
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
|
||||
void GetSelfController(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 2, 0, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<ISelfController>();
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
|
||||
void GetCommonStateGetter(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 2, 0, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<ICommonStateGetter>();
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
|
||||
void GetLibraryAppletCreator(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 2, 0, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<ILibraryAppletCreator>();
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
|
||||
void GetApplicationFunctions(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 2, 0, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IApplicationFunctions>();
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
};
|
||||
|
||||
@@ -169,6 +443,7 @@ void AppletOE::OpenApplicationProxy(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 2, 0, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<IApplicationProxy>();
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
|
||||
AppletOE::AppletOE() : ServiceFramework("appletOE") {
|
||||
|
||||
@@ -10,6 +10,12 @@
|
||||
namespace Service {
|
||||
namespace AM {
|
||||
|
||||
// TODO: Add more languages
|
||||
enum SystemLanguage {
|
||||
Japanese = 0,
|
||||
English = 1,
|
||||
};
|
||||
|
||||
class AppletOE final : public ServiceFramework<AppletOE> {
|
||||
public:
|
||||
AppletOE();
|
||||
|
||||
@@ -13,13 +13,55 @@ void InstallInterfaces(SM::ServiceManager& service_manager) {
|
||||
std::make_shared<APM>()->InstallAsService(service_manager);
|
||||
}
|
||||
|
||||
class ISession final : public ServiceFramework<ISession> {
|
||||
public:
|
||||
ISession() : ServiceFramework("ISession") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &ISession::SetPerformanceConfiguration, "SetPerformanceConfiguration"},
|
||||
{1, &ISession::GetPerformanceConfiguration, "GetPerformanceConfiguration"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
private:
|
||||
void SetPerformanceConfiguration(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
|
||||
auto mode = static_cast<PerformanceMode>(rp.Pop<u32>());
|
||||
u32 config = rp.Pop<u32>();
|
||||
|
||||
IPC::RequestBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
|
||||
LOG_WARNING(Service, "(STUBBED) called mode=%u config=%u", static_cast<u32>(mode), config);
|
||||
}
|
||||
|
||||
void GetPerformanceConfiguration(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestParser rp{ctx};
|
||||
|
||||
auto mode = static_cast<PerformanceMode>(rp.Pop<u32>());
|
||||
|
||||
IPC::RequestBuilder rb{ctx, 3};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.Push<u32>(0); // Performance configuration
|
||||
|
||||
LOG_WARNING(Service, "(STUBBED) called mode=%u", static_cast<u32>(mode));
|
||||
}
|
||||
};
|
||||
|
||||
APM::APM() : ServiceFramework("apm") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0x00000000, nullptr, "OpenSession"},
|
||||
{0x00000000, &APM::OpenSession, "OpenSession"},
|
||||
{0x00000001, nullptr, "GetPerformanceMode"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
void APM::OpenSession(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 2, 0, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushIpcInterface<ISession>();
|
||||
}
|
||||
|
||||
} // namespace APM
|
||||
} // namespace Service
|
||||
|
||||
@@ -9,10 +9,18 @@
|
||||
namespace Service {
|
||||
namespace APM {
|
||||
|
||||
enum class PerformanceMode : u8 {
|
||||
Handheld = 0,
|
||||
Docked = 1,
|
||||
};
|
||||
|
||||
class APM final : public ServiceFramework<APM> {
|
||||
public:
|
||||
APM();
|
||||
~APM() = default;
|
||||
|
||||
private:
|
||||
void OpenSession(Kernel::HLERequestContext& ctx);
|
||||
};
|
||||
|
||||
/// Registers all AM services with the specified service manager.
|
||||
|
||||
16
src/core/hle/service/audio/audio.cpp
Normal file
16
src/core/hle/service/audio/audio.cpp
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "core/hle/service/audio/audio.h"
|
||||
#include "core/hle/service/audio/audout_u.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Audio {
|
||||
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager) {
|
||||
std::make_shared<AudOutU>()->InstallAsService(service_manager);
|
||||
}
|
||||
|
||||
} // namespace Audio
|
||||
} // namespace Service
|
||||
16
src/core/hle/service/audio/audio.h
Normal file
16
src/core/hle/service/audio/audio.h
Normal file
@@ -0,0 +1,16 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Audio {
|
||||
|
||||
/// Registers all Audio services with the specified service manager.
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager);
|
||||
|
||||
} // namespace Audio
|
||||
} // namespace Service
|
||||
26
src/core/hle/service/audio/audout_u.cpp
Normal file
26
src/core/hle/service/audio/audout_u.cpp
Normal file
@@ -0,0 +1,26 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/service/audio/audout_u.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Audio {
|
||||
|
||||
void AudOutU::ListAudioOuts(Kernel::HLERequestContext& ctx) {
|
||||
LOG_WARNING(Service, "(STUBBED) called");
|
||||
IPC::RequestBuilder rb{ctx, 2};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
}
|
||||
|
||||
AudOutU::AudOutU() : ServiceFramework("audout:u") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0x00000000, &AudOutU::ListAudioOuts, "ListAudioOuts"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
|
||||
} // namespace Audio
|
||||
} // namespace Service
|
||||
23
src/core/hle/service/audio/audout_u.h
Normal file
23
src/core/hle/service/audio/audout_u.h
Normal file
@@ -0,0 +1,23 @@
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "core/hle/kernel/hle_ipc.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service {
|
||||
namespace Audio {
|
||||
|
||||
class AudOutU final : public ServiceFramework<AudOutU> {
|
||||
public:
|
||||
AudOutU();
|
||||
~AudOutU() = default;
|
||||
|
||||
private:
|
||||
void ListAudioOuts(Kernel::HLERequestContext& ctx);
|
||||
};
|
||||
|
||||
} // namespace Audio
|
||||
} // namespace Service
|
||||
@@ -1,19 +1,187 @@
|
||||
// Copyright 2015 Citra Emulator Project
|
||||
// Copyright 2018 yuzu emulator team
|
||||
// Licensed under GPLv2 or any later version
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <atomic>
|
||||
#include "common/logging/log.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/frontend/input.h"
|
||||
#include "core/hle/ipc_helpers.h"
|
||||
#include "core/hle/kernel/client_port.h"
|
||||
#include "core/hle/kernel/client_session.h"
|
||||
#include "core/hle/kernel/shared_memory.h"
|
||||
#include "core/hle/service/hid/hid.h"
|
||||
#include "core/hle/service/service.h"
|
||||
|
||||
namespace Service {
|
||||
namespace HID {
|
||||
|
||||
void Init() {}
|
||||
// Updating period for each HID device.
|
||||
// TODO(shinyquagsire23): These need better values.
|
||||
constexpr u64 pad_update_ticks = BASE_CLOCK_RATE / 10000;
|
||||
constexpr u64 accelerometer_update_ticks = BASE_CLOCK_RATE / 10000;
|
||||
constexpr u64 gyroscope_update_ticks = BASE_CLOCK_RATE / 10000;
|
||||
|
||||
void Shutdown() {}
|
||||
class IAppletResource final : public ServiceFramework<IAppletResource> {
|
||||
public:
|
||||
IAppletResource() : ServiceFramework("IAppletResource") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0, &IAppletResource::GetSharedMemoryHandle, "GetSharedMemoryHandle"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
|
||||
shared_mem = Kernel::SharedMemory::Create(
|
||||
nullptr, 0x40000, Kernel::MemoryPermission::ReadWrite, Kernel::MemoryPermission::Read,
|
||||
0, Kernel::MemoryRegion::BASE, "HID:SharedMemory");
|
||||
|
||||
// Register update callbacks
|
||||
pad_update_event = CoreTiming::RegisterEvent(
|
||||
"HID::UpdatePadCallback",
|
||||
[this](u64 userdata, int cycles_late) { UpdatePadCallback(userdata, cycles_late); });
|
||||
|
||||
// TODO(shinyquagsire23): Other update callbacks? (accel, gyro?)
|
||||
|
||||
CoreTiming::ScheduleEvent(pad_update_ticks, pad_update_event);
|
||||
}
|
||||
|
||||
private:
|
||||
void GetSharedMemoryHandle(Kernel::HLERequestContext& ctx) {
|
||||
IPC::RequestBuilder rb{ctx, 2, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushCopyObjects(shared_mem);
|
||||
LOG_DEBUG(Service, "called");
|
||||
}
|
||||
|
||||
void LoadInputDevices() {
|
||||
std::transform(Settings::values.buttons.begin() + Settings::NativeButton::BUTTON_HID_BEGIN,
|
||||
Settings::values.buttons.begin() + Settings::NativeButton::BUTTON_HID_END,
|
||||
buttons.begin(), Input::CreateDevice<Input::ButtonDevice>);
|
||||
// TODO(shinyquagsire23): sticks, gyro, touch, mouse, keyboard
|
||||
}
|
||||
|
||||
void UpdatePadCallback(u64 userdata, int cycles_late) {
|
||||
SharedMemory* mem = reinterpret_cast<SharedMemory*>(shared_mem->GetPointer());
|
||||
|
||||
if (is_device_reload_pending.exchange(false))
|
||||
LoadInputDevices();
|
||||
|
||||
// Set up controllers as neon red+blue Joy-Con attached to console
|
||||
ControllerHeader& controller_header = mem->controllers[Controller_Handheld].header;
|
||||
controller_header.type = ControllerType_Handheld | ControllerType_JoyconPair;
|
||||
controller_header.single_colors_descriptor = ColorDesc_ColorsNonexistent;
|
||||
controller_header.right_color_body = JOYCON_BODY_NEON_RED;
|
||||
controller_header.right_color_buttons = JOYCON_BUTTONS_NEON_RED;
|
||||
controller_header.left_color_body = JOYCON_BODY_NEON_BLUE;
|
||||
controller_header.left_color_buttons = JOYCON_BUTTONS_NEON_BLUE;
|
||||
|
||||
for (int layoutIdx = 0; layoutIdx < HID_NUM_LAYOUTS; layoutIdx++) {
|
||||
ControllerLayout& layout = mem->controllers[Controller_Handheld].layouts[layoutIdx];
|
||||
layout.header.num_entries = HID_NUM_ENTRIES;
|
||||
layout.header.max_entry_index = HID_NUM_ENTRIES - 1;
|
||||
|
||||
// HID shared memory stores the state of the past 17 samples in a circlular buffer,
|
||||
// each with a timestamp in number of samples since boot.
|
||||
layout.header.timestamp_ticks = CoreTiming::GetTicks();
|
||||
layout.header.latest_entry = (layout.header.latest_entry + 1) % HID_NUM_ENTRIES;
|
||||
|
||||
ControllerInputEntry& entry = layout.entries[layout.header.latest_entry];
|
||||
entry.connection_state = ConnectionState_Connected | ConnectionState_Wired;
|
||||
entry.timestamp++;
|
||||
entry.timestamp_2++; // TODO(shinyquagsire23): Is this always identical to timestamp?
|
||||
|
||||
// TODO(shinyquagsire23): Set up some LUTs for each layout mapping in the future?
|
||||
// For now everything is just the default handheld layout, but split Joy-Con will
|
||||
// rotate the face buttons and directions for certain layouts.
|
||||
ControllerPadState& state = entry.buttons;
|
||||
using namespace Settings::NativeButton;
|
||||
state.a.Assign(buttons[A - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.b.Assign(buttons[B - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.x.Assign(buttons[X - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.y.Assign(buttons[Y - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.lstick.Assign(buttons[LStick - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.rstick.Assign(buttons[RStick - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.l.Assign(buttons[L - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.r.Assign(buttons[R - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.zl.Assign(buttons[ZL - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.zr.Assign(buttons[ZR - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.plus.Assign(buttons[Plus - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.minus.Assign(buttons[Minus - BUTTON_HID_BEGIN]->GetStatus());
|
||||
|
||||
state.dleft.Assign(buttons[DLeft - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.dup.Assign(buttons[DUp - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.dright.Assign(buttons[DRight - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.ddown.Assign(buttons[DDown - BUTTON_HID_BEGIN]->GetStatus());
|
||||
|
||||
state.lstick_left.Assign(buttons[LStick_Left - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.lstick_up.Assign(buttons[LStick_Up - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.lstick_right.Assign(buttons[LStick_Right - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.lstick_down.Assign(buttons[LStick_Down - BUTTON_HID_BEGIN]->GetStatus());
|
||||
|
||||
state.rstick_left.Assign(buttons[RStick_Left - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.rstick_up.Assign(buttons[RStick_Up - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.rstick_right.Assign(buttons[RStick_Right - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.rstick_down.Assign(buttons[RStick_Down - BUTTON_HID_BEGIN]->GetStatus());
|
||||
|
||||
state.sl.Assign(buttons[SL - BUTTON_HID_BEGIN]->GetStatus());
|
||||
state.sr.Assign(buttons[SR - BUTTON_HID_BEGIN]->GetStatus());
|
||||
|
||||
// TODO(shinyquagsire23): Analog stick vals
|
||||
|
||||
// TODO(shinyquagsire23): Update pad info proper, (circular buffers, timestamps,
|
||||
// layouts)
|
||||
}
|
||||
|
||||
// TODO(shinyquagsire23): Update touch info
|
||||
|
||||
// TODO(shinyquagsire23): Signal events
|
||||
|
||||
// Reschedule recurrent event
|
||||
CoreTiming::ScheduleEvent(pad_update_ticks - cycles_late, pad_update_event);
|
||||
}
|
||||
|
||||
// Handle to shared memory region designated to HID service
|
||||
Kernel::SharedPtr<Kernel::SharedMemory> shared_mem;
|
||||
|
||||
// CoreTiming update events
|
||||
CoreTiming::EventType* pad_update_event;
|
||||
|
||||
// Stored input state info
|
||||
std::atomic<bool> is_device_reload_pending{true};
|
||||
std::array<std::unique_ptr<Input::ButtonDevice>, Settings::NativeButton::NUM_BUTTONS_HID>
|
||||
buttons;
|
||||
};
|
||||
|
||||
class Hid final : public ServiceFramework<Hid> {
|
||||
public:
|
||||
Hid() : ServiceFramework("hid") {
|
||||
static const FunctionInfo functions[] = {
|
||||
{0x00000000, &Hid::CreateAppletResource, "CreateAppletResource"},
|
||||
};
|
||||
RegisterHandlers(functions);
|
||||
}
|
||||
~Hid() = default;
|
||||
|
||||
private:
|
||||
void CreateAppletResource(Kernel::HLERequestContext& ctx) {
|
||||
auto client_port = std::make_shared<IAppletResource>()->CreatePort();
|
||||
auto session = client_port->Connect();
|
||||
if (session.Succeeded()) {
|
||||
LOG_DEBUG(Service, "called, initialized IAppletResource -> session=%u",
|
||||
(*session)->GetObjectId());
|
||||
IPC::RequestBuilder rb{ctx, 2, 0, 1};
|
||||
rb.Push(RESULT_SUCCESS);
|
||||
rb.PushMoveObjects(std::move(session).Unwrap());
|
||||
} else {
|
||||
UNIMPLEMENTED();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void ReloadInputDevices() {}
|
||||
|
||||
void InstallInterfaces(SM::ServiceManager& service_manager) {
|
||||
std::make_shared<Hid>()->InstallAsService(service_manager);
|
||||
}
|
||||
|
||||
} // namespace HID
|
||||
} // namespace Service
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user