syncMerge branch 'Feature/initial-ps4-ime-keyboard' of https://github.com/w1naenator/shadPS4 into Feature/initial-ps4-ime-keyboard
21
.github/ISSUE_TEMPLATE/app-bug-report.yaml
vendored
|
@ -53,3 +53,24 @@ body:
|
|||
placeholder: "Example: Windows 11, Arch Linux, MacOS 15"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: cpu
|
||||
attributes:
|
||||
label: CPU
|
||||
placeholder: "Example: Intel Core i7-8700"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: gpu
|
||||
attributes:
|
||||
label: GPU
|
||||
placeholder: "Example: nVidia GTX 1650"
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: ram
|
||||
attributes:
|
||||
label: Amount of RAM in GB
|
||||
placeholder: "Example: 16 GB"
|
||||
validations:
|
||||
required: true
|
||||
|
|
5
.gitmodules
vendored
|
@ -97,7 +97,7 @@
|
|||
shallow = true
|
||||
[submodule "externals/MoltenVK/SPIRV-Cross"]
|
||||
path = externals/MoltenVK/SPIRV-Cross
|
||||
url = https://github.com/KhronosGroup/SPIRV-Cross
|
||||
url = https://github.com/billhollings/SPIRV-Cross
|
||||
shallow = true
|
||||
[submodule "externals/MoltenVK/MoltenVK"]
|
||||
path = externals/MoltenVK/MoltenVK
|
||||
|
@ -107,3 +107,6 @@
|
|||
path = externals/MoltenVK/cereal
|
||||
url = https://github.com/USCiLab/cereal
|
||||
shallow = true
|
||||
[submodule "externals/libusb"]
|
||||
path = externals/libusb
|
||||
url = https://github.com/libusb/libusb-cmake.git
|
||||
|
|
|
@ -9,7 +9,8 @@ set(CMAKE_CXX_STANDARD_REQUIRED True)
|
|||
|
||||
if(APPLE)
|
||||
list(APPEND ADDITIONAL_LANGUAGES OBJC)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 14)
|
||||
# Starting with 15.4, Rosetta 2 has support for all the necessary instruction sets.
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET 15.4 CACHE STRING "")
|
||||
endif()
|
||||
|
||||
if (NOT CMAKE_BUILD_TYPE)
|
||||
|
@ -53,8 +54,9 @@ else()
|
|||
endif()
|
||||
|
||||
if (ARCHITECTURE STREQUAL "x86_64")
|
||||
# Set x86_64 target level to Sandy Bridge to generally match what is supported for PS4 guest code with CPU patches.
|
||||
add_compile_options(-march=sandybridge)
|
||||
# Target the same CPU architecture as the PS4, to maintain the same level of compatibility.
|
||||
# Exclude SSE4a as it is only available on AMD CPUs.
|
||||
add_compile_options(-march=btver2 -mtune=generic -mno-sse4a)
|
||||
endif()
|
||||
|
||||
if (APPLE AND ARCHITECTURE STREQUAL "x86_64" AND CMAKE_HOST_SYSTEM_PROCESSOR STREQUAL "arm64")
|
||||
|
@ -103,11 +105,8 @@ if (CLANG_FORMAT)
|
|||
unset(CCOMMENT)
|
||||
endif()
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
|
||||
# generate git revision information
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules/")
|
||||
include(GetGitRevisionDescription)
|
||||
include("${CMAKE_CURRENT_SOURCE_DIR}/externals/cmake-modules/GetGitRevisionDescription.cmake")
|
||||
get_git_head_revision(GIT_REF_SPEC GIT_REV)
|
||||
git_describe(GIT_DESC --always --long --dirty)
|
||||
git_branch_name(GIT_BRANCH)
|
||||
|
@ -201,10 +200,20 @@ execute_process(
|
|||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||
)
|
||||
|
||||
# Set Version
|
||||
set(EMULATOR_VERSION_MAJOR "0")
|
||||
set(EMULATOR_VERSION_MINOR "7")
|
||||
set(EMULATOR_VERSION_PATCH "1")
|
||||
|
||||
set_source_files_properties(src/shadps4.rc PROPERTIES COMPILE_DEFINITIONS "EMULATOR_VERSION_MAJOR=${EMULATOR_VERSION_MAJOR};EMULATOR_VERSION_MINOR=${EMULATOR_VERSION_MINOR};EMULATOR_VERSION_PATCH=${EMULATOR_VERSION_PATCH}")
|
||||
|
||||
set(APP_VERSION "${EMULATOR_VERSION_MAJOR}.${EMULATOR_VERSION_MINOR}.${EMULATOR_VERSION_PATCH} WIP")
|
||||
set(APP_IS_RELEASE false)
|
||||
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/common/scm_rev.cpp.in" "${CMAKE_CURRENT_BINARY_DIR}/src/common/scm_rev.cpp" @ONLY)
|
||||
|
||||
message("end git things, remote: ${GIT_REMOTE_NAME}, branch: ${GIT_BRANCH}")
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||
find_package(Boost 1.84.0 CONFIG)
|
||||
find_package(FFmpeg 5.1.2 MODULE)
|
||||
find_package(fmt 10.2.0 CONFIG)
|
||||
|
@ -217,21 +226,18 @@ find_package(SDL3 3.1.2 CONFIG)
|
|||
find_package(stb MODULE)
|
||||
find_package(toml11 4.2.0 CONFIG)
|
||||
find_package(tsl-robin-map 1.3.0 CONFIG)
|
||||
find_package(VulkanHeaders 1.4.305 CONFIG)
|
||||
find_package(VulkanHeaders 1.4.309 CONFIG)
|
||||
find_package(VulkanMemoryAllocator 3.1.0 CONFIG)
|
||||
find_package(xbyak 7.07 CONFIG)
|
||||
find_package(xxHash 0.8.2 MODULE)
|
||||
find_package(ZLIB 1.3 MODULE)
|
||||
find_package(Zydis 5.0.0 CONFIG)
|
||||
find_package(pugixml 1.14 CONFIG)
|
||||
|
||||
if (NOT CMAKE_CXX_COMPILER_ID STREQUAL "Clang" OR NOT MSVC)
|
||||
find_package(cryptopp 8.9.0 MODULE)
|
||||
endif()
|
||||
|
||||
find_package(libusb 1.0.27 MODULE)
|
||||
if (APPLE)
|
||||
find_package(date 3.0.1 CONFIG)
|
||||
endif()
|
||||
list(POP_BACK CMAKE_MODULE_PATH)
|
||||
|
||||
# Note: Windows always has these functions through winpthreads
|
||||
include(CheckSymbolExists)
|
||||
|
@ -451,8 +457,6 @@ set(SYSTEM_LIBS src/core/libraries/system/commondialog.cpp
|
|||
src/core/libraries/audio3d/audio3d.cpp
|
||||
src/core/libraries/audio3d/audio3d.h
|
||||
src/core/libraries/audio3d/audio3d_error.h
|
||||
src/core/libraries/audio3d/audio3d_impl.cpp
|
||||
src/core/libraries/audio3d/audio3d_impl.h
|
||||
src/core/libraries/game_live_streaming/gamelivestreaming.cpp
|
||||
src/core/libraries/game_live_streaming/gamelivestreaming.h
|
||||
src/core/libraries/remote_play/remoteplay.cpp
|
||||
|
@ -570,6 +574,8 @@ set(NP_LIBS src/core/libraries/np_common/np_common.cpp
|
|||
src/core/libraries/np_web_api/np_web_api.h
|
||||
src/core/libraries/np_party/np_party.cpp
|
||||
src/core/libraries/np_party/np_party.h
|
||||
src/core/libraries/np_auth/np_auth.cpp
|
||||
src/core/libraries/np_auth/np_auth.h
|
||||
)
|
||||
|
||||
set(ZLIB_LIB src/core/libraries/zlib/zlib.cpp
|
||||
|
@ -585,6 +591,8 @@ set(MISC_LIBS src/core/libraries/screenshot/screenshot.cpp
|
|||
src/core/libraries/screenshot/screenshot.h
|
||||
src/core/libraries/move/move.cpp
|
||||
src/core/libraries/move/move.h
|
||||
src/core/libraries/ulobjmgr/ulobjmgr.cpp
|
||||
src/core/libraries/ulobjmgr/ulobjmgr.h
|
||||
)
|
||||
|
||||
set(DEV_TOOLS src/core/devtools/layer.cpp
|
||||
|
@ -675,7 +683,6 @@ set(COMMON src/common/logging/backend.cpp
|
|||
src/common/uint128.h
|
||||
src/common/unique_function.h
|
||||
src/common/va_ctx.h
|
||||
src/common/version.h
|
||||
src/common/ntapi.h
|
||||
src/common/ntapi.cpp
|
||||
src/common/number_utils.h
|
||||
|
@ -1065,7 +1072,7 @@ endif()
|
|||
create_target_directory_groups(shadps4)
|
||||
|
||||
target_link_libraries(shadps4 PRIVATE magic_enum::magic_enum fmt::fmt toml11::toml11 tsl::robin_map xbyak::xbyak Tracy::TracyClient RenderDoc::API FFmpeg::ffmpeg Dear_ImGui gcn half::half ZLIB::ZLIB PNG::PNG)
|
||||
target_link_libraries(shadps4 PRIVATE Boost::headers GPUOpen::VulkanMemoryAllocator LibAtrac9 sirit Vulkan::Headers xxHash::xxhash Zydis::Zydis glslang::glslang SDL3::SDL3 pugixml::pugixml stb::headers)
|
||||
target_link_libraries(shadps4 PRIVATE Boost::headers GPUOpen::VulkanMemoryAllocator LibAtrac9 sirit Vulkan::Headers xxHash::xxhash Zydis::Zydis glslang::glslang SDL3::SDL3 pugixml::pugixml stb::headers libusb::usb)
|
||||
|
||||
target_compile_definitions(shadps4 PRIVATE IMGUI_USER_CONFIG="imgui/imgui_config.h")
|
||||
target_compile_definitions(Dear_ImGui PRIVATE IMGUI_USER_CONFIG="${PROJECT_SOURCE_DIR}/src/imgui/imgui_config.h")
|
||||
|
@ -1176,7 +1183,7 @@ target_include_directories(shadps4 PRIVATE ${HOST_SHADERS_INCLUDE})
|
|||
|
||||
# embed resources
|
||||
|
||||
include(CMakeRC)
|
||||
include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/CMakeRC.cmake")
|
||||
cmrc_add_resource_library(embedded-resources
|
||||
ALIAS res::embedded
|
||||
NAMESPACE res
|
||||
|
@ -1197,8 +1204,8 @@ if (ENABLE_QT_GUI)
|
|||
MACOSX_BUNDLE ON
|
||||
MACOSX_BUNDLE_INFO_PLIST "${CMAKE_CURRENT_SOURCE_DIR}/dist/MacOSBundleInfo.plist.in"
|
||||
MACOSX_BUNDLE_ICON_FILE "shadPS4.icns"
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING "0.4.1"
|
||||
)
|
||||
MACOSX_BUNDLE_SHORT_VERSION_STRING "${APP_VERSION}"
|
||||
)
|
||||
|
||||
set_source_files_properties(src/images/shadPS4.icns PROPERTIES
|
||||
MACOSX_PACKAGE_LOCATION Resources)
|
||||
|
|
36
README.md
|
@ -13,7 +13,7 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
|||
|
||||
<h1 align="center">
|
||||
<a href="https://discord.gg/bFJxfftGW6">
|
||||
<img src="https://img.shields.io/discord/1080089157554155590?color=5865F2&label=shadPS4 Discord&logo=Discord&logoColor=white" width="240">
|
||||
<img src="https://img.shields.io/discord/1080089157554155590?color=5865F2&label=shadPS4%20Discord&logo=Discord&logoColor=white" width="275">
|
||||
<a href="https://github.com/shadps4-emu/shadPS4/releases/latest">
|
||||
<img src="https://img.shields.io/github/downloads/shadps4-emu/shadPS4/total.svg" width="140">
|
||||
<a href="https://shadps4.net/">
|
||||
|
@ -71,7 +71,7 @@ Check the build instructions for [**Linux**](https://github.com/shadps4-emu/shad
|
|||
Check the build instructions for [**macOS**](https://github.com/shadps4-emu/shadPS4/blob/main/documents/building-macos.md).
|
||||
|
||||
> [!IMPORTANT]
|
||||
> macOS users need at least macOS 15 on Apple Silicon-based Mac devices and at least macOS 14 on Intel-based Mac devices.
|
||||
> macOS users need at least macOS 15.4 to run shadPS4. Due to GPU issues there are currently heavy bugs on Intel Macs.
|
||||
|
||||
# Debugging and reporting issues
|
||||
|
||||
|
@ -122,19 +122,37 @@ R3 | M |
|
|||
Keyboard and mouse inputs can be customized in the settings menu by clicking the Controller button, and further details and help on controls are also found there. Custom bindings are saved per-game. Inputs support up to three keys per binding, mouse buttons, mouse movement mapped to joystick input, and more.
|
||||
|
||||
|
||||
# Firmware files
|
||||
|
||||
shadPS4 can load some PlayStation 4 firmware files, these must be dumped from your legally owned PlayStation 4 console.\
|
||||
The following firmware modules are supported and must be placed in shadPS4's `user/sys_modules` folder.
|
||||
|
||||
<div align="center">
|
||||
|
||||
| Modules | Modules | Modules | Modules |
|
||||
|-------------------------|-------------------------|-------------------------|-------------------------|
|
||||
| libSceCesCs.sprx | libSceFont.sprx | libSceFontFt.sprx | libSceFreeTypeOt.sprx |
|
||||
| libSceJson.sprx | libSceJson2.sprx | libSceLibcInternal.sprx | libSceNgs2.sprx |
|
||||
| libSceRtc.sprx | libSceUlt.sprx | | |
|
||||
|
||||
</div>
|
||||
|
||||
> [!Caution]
|
||||
> The above modules are required to run the games properly and must be extracted from your PlayStation 4.\
|
||||
> **We do not provide any information or support on how to do this**.
|
||||
|
||||
|
||||
|
||||
# Main team
|
||||
|
||||
- [**georgemoralis**](https://github.com/georgemoralis)
|
||||
- [**raphaelthegreat**](https://github.com/raphaelthegreat)
|
||||
- [**psucien**](https://github.com/psucien)
|
||||
- [**skmp**](https://github.com/skmp)
|
||||
- [**wheremyfoodat**](https://github.com/wheremyfoodat)
|
||||
- [**raziel1000**](https://github.com/raziel1000)
|
||||
- [**viniciuslrangel**](https://github.com/viniciuslrangel)
|
||||
- [**roamic**](https://github.com/vladmikhalin)
|
||||
- [**poly**](https://github.com/polybiusproxy)
|
||||
- [**squidbus**](https://github.com/squidbus)
|
||||
- [**frodo**](https://github.com/baggins183)
|
||||
- [**Stephen Miller**](https://github.com/StevenMiller123)
|
||||
- [**kalaposfos13**](https://github.com/kalaposfos13)
|
||||
|
||||
Logo is done by [**Xphalnos**](https://github.com/Xphalnos)
|
||||
|
||||
|
@ -145,11 +163,11 @@ Open a PR and we'll check it :)
|
|||
|
||||
# Translations
|
||||
|
||||
If you want to translate shadPS4 to your language we use [**crowdin**](https://crowdin.com/project/shadps4-emulator).
|
||||
If you want to translate shadPS4 to your language we use [**Crowdin**](https://crowdin.com/project/shadps4-emulator).
|
||||
# Contributors
|
||||
|
||||
<a href="https://github.com/shadps4-emu/shadPS4/graphs/contributors">
|
||||
<img src="https://contrib.rocks/image?repo=shadps4-emu/shadPS4&max=15">
|
||||
<img src="https://contrib.rocks/image?repo=shadps4-emu/shadPS4&max=24">
|
||||
</a>
|
||||
|
||||
|
||||
|
|
|
@ -57,11 +57,18 @@ path = [
|
|||
"src/images/utils_icon.png",
|
||||
"src/images/shadPS4.icns",
|
||||
"src/images/shadps4.ico",
|
||||
"src/images/shadps4.png",
|
||||
"src/images/net.shadps4.shadPS4.svg",
|
||||
"src/images/themes_icon.png",
|
||||
"src/images/update_icon.png",
|
||||
"src/images/youtube.png",
|
||||
"src/images/website.png",
|
||||
"src/images/discord.svg",
|
||||
"src/images/github.svg",
|
||||
"src/images/ko-fi.svg",
|
||||
"src/images/shadps4.svg",
|
||||
"src/images/website.svg",
|
||||
"src/images/youtube.svg",
|
||||
"src/shadps4.qrc",
|
||||
"src/shadps4.rc",
|
||||
"src/qt_gui/translations/update_translation.sh",
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
# SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_search_module(CRYPTOPP QUIET IMPORTED_TARGET libcryptopp)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(cryptopp
|
||||
REQUIRED_VARS CRYPTOPP_LINK_LIBRARIES
|
||||
VERSION_VAR CRYPTOPP_VERSION
|
||||
)
|
||||
|
||||
if (cryptopp_FOUND AND NOT TARGET cryptopp::cryptopp)
|
||||
add_library(cryptopp::cryptopp ALIAS PkgConfig::CRYPTOPP)
|
||||
endif()
|
15
cmake/Findlibusb.cmake
Normal file
|
@ -0,0 +1,15 @@
|
|||
# SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
|
||||
# SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
find_package(PkgConfig QUIET)
|
||||
pkg_search_module(LIBUSB QUIET IMPORTED_TARGET libusb-1.0)
|
||||
|
||||
include(FindPackageHandleStandardArgs)
|
||||
find_package_handle_standard_args(libusb
|
||||
REQUIRED_VARS LIBUSB_LINK_LIBRARIES
|
||||
VERSION_VAR LIBUSB_VERSION
|
||||
)
|
||||
|
||||
if (libusb_FOUND AND NOT TARGET libusb::usb)
|
||||
add_library(libusb::usb ALIAS PkgConfig::LIBUSB)
|
||||
endif()
|
|
@ -24,13 +24,13 @@ SPDX-License-Identifier: GPL-2.0-or-later
|
|||
- A CPU supporting the following instruction sets: MMX, SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, F16C, CLMUL, AES, BMI1, MOVBE, XSAVE, ABM
|
||||
- **Intel**: Haswell generation or newer
|
||||
- **AMD**: Jaguar generation or newer
|
||||
- **Apple**: Rosetta 2 on macOS 15 or newer
|
||||
- **Apple**: Rosetta 2 on macOS 15.4 or newer
|
||||
|
||||
### GPU
|
||||
|
||||
- A graphics card with at least 1GB of VRAM
|
||||
- Keep your graphics drivers up to date
|
||||
- Vulkan 1.3 support (required)
|
||||
- Up-to-date graphics drivers
|
||||
- Vulkan 1.3 with the `VK_KHR_swapchain` and `VK_KHR_push_descriptor` extensions
|
||||
|
||||
### RAM
|
||||
|
||||
|
|
6
externals/CMakeLists.txt
vendored
|
@ -201,6 +201,12 @@ if (NOT TARGET pugixml::pugixml)
|
|||
add_subdirectory(pugixml)
|
||||
endif()
|
||||
|
||||
# libusb
|
||||
if (NOT TARGET libusb::usb)
|
||||
add_subdirectory(libusb)
|
||||
add_library(libusb::usb ALIAS usb-1.0)
|
||||
endif()
|
||||
|
||||
# Discord RPC
|
||||
if (ENABLE_DISCORD_RPC)
|
||||
add_subdirectory(discord-rpc)
|
||||
|
|
1
externals/libusb
vendored
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit a63a7e43e0950a595cf4b98a0eaf4051749ace5f
|
|
@ -7,10 +7,10 @@
|
|||
#include <fmt/xchar.h> // for wstring support
|
||||
#include <toml.hpp>
|
||||
|
||||
#include "common/config.h"
|
||||
#include "common/logging/formatter.h"
|
||||
#include "common/path_util.h"
|
||||
#include "config.h"
|
||||
#include "logging/formatter.h"
|
||||
#include "version.h"
|
||||
#include "common/scm_rev.h"
|
||||
|
||||
namespace toml {
|
||||
template <typename TC, typename K>
|
||||
|
@ -763,7 +763,7 @@ void load(const std::filesystem::path& path) {
|
|||
logFilter = toml::find_or<std::string>(general, "logFilter", "");
|
||||
logType = toml::find_or<std::string>(general, "logType", "sync");
|
||||
userName = toml::find_or<std::string>(general, "userName", "shadPS4");
|
||||
if (Common::isRelease) {
|
||||
if (Common::g_is_release) {
|
||||
updateChannel = toml::find_or<std::string>(general, "updateChannel", "Release");
|
||||
} else {
|
||||
updateChannel = toml::find_or<std::string>(general, "updateChannel", "Nightly");
|
||||
|
@ -1108,7 +1108,7 @@ void setDefaultValues() {
|
|||
logFilter = "";
|
||||
logType = "sync";
|
||||
userName = "shadPS4";
|
||||
if (Common::isRelease) {
|
||||
if (Common::g_is_release) {
|
||||
updateChannel = "Release";
|
||||
} else {
|
||||
updateChannel = "Nightly";
|
||||
|
|
|
@ -101,6 +101,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) {
|
|||
SUB(Lib, Ssl2) \
|
||||
SUB(Lib, SysModule) \
|
||||
SUB(Lib, Move) \
|
||||
SUB(Lib, NpAuth) \
|
||||
SUB(Lib, NpCommon) \
|
||||
SUB(Lib, NpManager) \
|
||||
SUB(Lib, NpScore) \
|
||||
|
|
|
@ -69,6 +69,7 @@ enum class Class : u8 {
|
|||
Lib_Http2, ///< The LibSceHttp2 implementation.
|
||||
Lib_SysModule, ///< The LibSceSysModule implementation
|
||||
Lib_NpCommon, ///< The LibSceNpCommon implementation
|
||||
Lib_NpAuth, ///< The LibSceNpAuth implementation
|
||||
Lib_NpManager, ///< The LibSceNpManager implementation
|
||||
Lib_NpScore, ///< The LibSceNpScore implementation
|
||||
Lib_NpTrophy, ///< The LibSceNpTrophy implementation
|
||||
|
|
|
@ -3,21 +3,17 @@
|
|||
|
||||
#include "common/scm_rev.h"
|
||||
|
||||
#define GIT_REV "@GIT_REV@"
|
||||
#define GIT_BRANCH "@GIT_BRANCH@"
|
||||
#define GIT_DESC "@GIT_DESC@"
|
||||
#define GIT_REMOTE_NAME "@GIT_REMOTE_NAME@"
|
||||
#define GIT_REMOTE_URL "@GIT_REMOTE_URL@"
|
||||
#define BUILD_DATE "@BUILD_DATE@"
|
||||
|
||||
namespace Common {
|
||||
|
||||
const char g_scm_rev[] = GIT_REV;
|
||||
const char g_scm_branch[] = GIT_BRANCH;
|
||||
const char g_scm_desc[] = GIT_DESC;
|
||||
const char g_scm_remote_name[] = GIT_REMOTE_NAME;
|
||||
const char g_scm_remote_url[] = GIT_REMOTE_URL;
|
||||
const char g_scm_date[] = BUILD_DATE;
|
||||
constexpr char g_version[] = "@APP_VERSION@";
|
||||
constexpr bool g_is_release = @APP_IS_RELEASE@;
|
||||
|
||||
constexpr char g_scm_rev[] = "@GIT_REV@";
|
||||
constexpr char g_scm_branch[] = "@GIT_BRANCH@";
|
||||
constexpr char g_scm_desc[] = "@GIT_DESC@";
|
||||
constexpr char g_scm_remote_name[] = "@GIT_REMOTE_NAME@";
|
||||
constexpr char g_scm_remote_url[] = "@GIT_REMOTE_URL@";
|
||||
constexpr char g_scm_date[] = "@BUILD_DATE@";
|
||||
|
||||
} // namespace
|
||||
|
||||
|
|
|
@ -5,6 +5,9 @@
|
|||
|
||||
namespace Common {
|
||||
|
||||
extern const char g_version[];
|
||||
extern const bool g_is_release;
|
||||
|
||||
extern const char g_scm_rev[];
|
||||
extern const char g_scm_branch[];
|
||||
extern const char g_scm_desc[];
|
||||
|
|
|
@ -1,14 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
|
||||
namespace Common {
|
||||
|
||||
constexpr char VERSION[] = "0.7.1 WIP";
|
||||
constexpr bool isRelease = false;
|
||||
|
||||
} // namespace Common
|
|
@ -22,10 +22,6 @@
|
|||
#include <windows.h>
|
||||
#else
|
||||
#include <pthread.h>
|
||||
#ifdef __APPLE__
|
||||
#include <half.hpp>
|
||||
#include <sys/sysctl.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
using namespace Xbyak::util;
|
||||
|
@ -81,538 +77,6 @@ static Xbyak::Address ZydisToXbyakMemoryOperand(const ZydisDecodedOperand& opera
|
|||
return ptr[expression];
|
||||
}
|
||||
|
||||
static u64 ZydisToXbyakImmediateOperand(const ZydisDecodedOperand& operand) {
|
||||
ASSERT_MSG(operand.type == ZYDIS_OPERAND_TYPE_IMMEDIATE,
|
||||
"Expected immediate operand, got type: {}", static_cast<u32>(operand.type));
|
||||
return operand.imm.value.u;
|
||||
}
|
||||
|
||||
static std::unique_ptr<Xbyak::Operand> ZydisToXbyakOperand(const ZydisDecodedOperand& operand) {
|
||||
switch (operand.type) {
|
||||
case ZYDIS_OPERAND_TYPE_REGISTER: {
|
||||
return std::make_unique<Xbyak::Reg>(ZydisToXbyakRegisterOperand(operand));
|
||||
}
|
||||
case ZYDIS_OPERAND_TYPE_MEMORY: {
|
||||
return std::make_unique<Xbyak::Address>(ZydisToXbyakMemoryOperand(operand));
|
||||
}
|
||||
default:
|
||||
UNREACHABLE_MSG("Unsupported operand type: {}", static_cast<u32>(operand.type));
|
||||
}
|
||||
}
|
||||
|
||||
static bool OperandUsesRegister(const Xbyak::Operand* operand, int index) {
|
||||
if (operand->isREG()) {
|
||||
return operand->getIdx() == index;
|
||||
}
|
||||
if (operand->isMEM()) {
|
||||
const Xbyak::RegExp& reg_exp = operand->getAddress().getRegExp();
|
||||
return reg_exp.getBase().getIdx() == index || reg_exp.getIndex().getIdx() == index;
|
||||
}
|
||||
UNREACHABLE_MSG("Unsupported operand kind: {}", static_cast<u32>(operand->getKind()));
|
||||
}
|
||||
|
||||
static bool IsRegisterAllocated(
|
||||
const std::initializer_list<const Xbyak::Operand*>& allocated_registers, const int index) {
|
||||
return std::ranges::find_if(allocated_registers.begin(), allocated_registers.end(),
|
||||
[index](const Xbyak::Operand* operand) {
|
||||
return OperandUsesRegister(operand, index);
|
||||
}) != allocated_registers.end();
|
||||
}
|
||||
|
||||
static Xbyak::Reg AllocateScratchRegister(
|
||||
const std::initializer_list<const Xbyak::Operand*> allocated_registers, const u32 bits) {
|
||||
for (int index = Xbyak::Operand::R8; index <= Xbyak::Operand::R15; index++) {
|
||||
if (!IsRegisterAllocated(allocated_registers, index)) {
|
||||
return Xbyak::Reg32e(index, static_cast<int>(bits));
|
||||
}
|
||||
}
|
||||
UNREACHABLE_MSG("Out of scratch registers!");
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
static pthread_key_t stack_pointer_slot;
|
||||
static pthread_key_t patch_stack_slot;
|
||||
static std::once_flag patch_context_slots_init_flag;
|
||||
static constexpr u32 patch_stack_size = 0x1000;
|
||||
|
||||
static_assert(sizeof(void*) == sizeof(u64),
|
||||
"Cannot fit a register inside a thread local storage slot.");
|
||||
|
||||
static void FreePatchStack(void* patch_stack) {
|
||||
// Subtract back to the bottom of the stack for free.
|
||||
std::free(static_cast<u8*>(patch_stack) - patch_stack_size);
|
||||
}
|
||||
|
||||
static void InitializePatchContextSlots() {
|
||||
ASSERT_MSG(pthread_key_create(&stack_pointer_slot, nullptr) == 0,
|
||||
"Unable to allocate thread-local register for stack pointer.");
|
||||
ASSERT_MSG(pthread_key_create(&patch_stack_slot, FreePatchStack) == 0,
|
||||
"Unable to allocate thread-local register for patch stack.");
|
||||
}
|
||||
|
||||
void InitializeThreadPatchStack() {
|
||||
std::call_once(patch_context_slots_init_flag, InitializePatchContextSlots);
|
||||
|
||||
pthread_setspecific(patch_stack_slot,
|
||||
static_cast<u8*>(std::malloc(patch_stack_size)) + patch_stack_size);
|
||||
}
|
||||
|
||||
/// Saves the stack pointer to thread local storage and loads the patch stack.
|
||||
static void SaveStack(Xbyak::CodeGenerator& c) {
|
||||
std::call_once(patch_context_slots_init_flag, InitializePatchContextSlots);
|
||||
|
||||
// Save original stack pointer and load patch stack.
|
||||
c.putSeg(gs);
|
||||
c.mov(qword[reinterpret_cast<void*>(stack_pointer_slot * sizeof(void*))], rsp);
|
||||
c.putSeg(gs);
|
||||
c.mov(rsp, qword[reinterpret_cast<void*>(patch_stack_slot * sizeof(void*))]);
|
||||
}
|
||||
|
||||
/// Restores the stack pointer from thread local storage.
|
||||
static void RestoreStack(Xbyak::CodeGenerator& c) {
|
||||
std::call_once(patch_context_slots_init_flag, InitializePatchContextSlots);
|
||||
|
||||
// Save patch stack pointer and load original stack.
|
||||
c.putSeg(gs);
|
||||
c.mov(qword[reinterpret_cast<void*>(patch_stack_slot * sizeof(void*))], rsp);
|
||||
c.putSeg(gs);
|
||||
c.mov(rsp, qword[reinterpret_cast<void*>(stack_pointer_slot * sizeof(void*))]);
|
||||
}
|
||||
|
||||
/// Validates that the dst register is supported given the SaveStack/RestoreStack implementation.
|
||||
static void ValidateDst(const Xbyak::Reg& dst) {
|
||||
// No restrictions.
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void InitializeThreadPatchStack() {
|
||||
// No-op
|
||||
}
|
||||
|
||||
// NOTE: Since stack pointer here is subtracted through safe zone and not saved anywhere,
|
||||
// it must not be modified during the instruction. Otherwise, we will not be able to find
|
||||
// and load registers back from where they were saved. Thus, a limitation is placed on
|
||||
// instructions, that they must not use the stack pointer register as a destination.
|
||||
|
||||
/// Saves the stack pointer to thread local storage and loads the patch stack.
|
||||
static void SaveStack(Xbyak::CodeGenerator& c) {
|
||||
c.lea(rsp, ptr[rsp - 128]); // red zone
|
||||
}
|
||||
|
||||
/// Restores the stack pointer from thread local storage.
|
||||
static void RestoreStack(Xbyak::CodeGenerator& c) {
|
||||
c.lea(rsp, ptr[rsp + 128]); // red zone
|
||||
}
|
||||
|
||||
/// Validates that the dst register is supported given the SaveStack/RestoreStack implementation.
|
||||
static void ValidateDst(const Xbyak::Reg& dst) {
|
||||
// Stack pointer is not preserved, so it can't be used as a dst.
|
||||
ASSERT_MSG(dst.getIdx() != rsp.getIdx(), "Stack pointer not supported as destination.");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/// Switches to the patch stack, saves registers, and restores the original stack.
|
||||
static void SaveRegisters(Xbyak::CodeGenerator& c, const std::initializer_list<Xbyak::Reg> regs) {
|
||||
// Uses a more robust solution for saving registers on MacOS to avoid potential stack corruption
|
||||
// if games decide to not follow the ABI and use the red zone.
|
||||
SaveStack(c);
|
||||
for (const auto& reg : regs) {
|
||||
c.push(reg.cvt64());
|
||||
}
|
||||
RestoreStack(c);
|
||||
}
|
||||
|
||||
/// Switches to the patch stack, restores registers, and restores the original stack.
|
||||
static void RestoreRegisters(Xbyak::CodeGenerator& c,
|
||||
const std::initializer_list<Xbyak::Reg> regs) {
|
||||
SaveStack(c);
|
||||
for (const auto& reg : regs) {
|
||||
c.pop(reg.cvt64());
|
||||
}
|
||||
RestoreStack(c);
|
||||
}
|
||||
|
||||
/// Switches to the patch stack and stores all registers.
|
||||
static void SaveContext(Xbyak::CodeGenerator& c, bool save_flags = false) {
|
||||
SaveStack(c);
|
||||
for (int reg = Xbyak::Operand::RAX; reg <= Xbyak::Operand::R15; reg++) {
|
||||
c.push(Xbyak::Reg64(reg));
|
||||
}
|
||||
c.lea(rsp, ptr[rsp - 32 * 16]);
|
||||
for (int reg = 0; reg <= 15; reg++) {
|
||||
c.vmovdqu(ptr[rsp + 32 * reg], Xbyak::Ymm(reg));
|
||||
}
|
||||
if (save_flags) {
|
||||
c.pushfq();
|
||||
}
|
||||
}
|
||||
|
||||
/// Restores all registers and restores the original stack.
|
||||
/// If the destination is a register, it is not restored to preserve the output.
|
||||
static void RestoreContext(Xbyak::CodeGenerator& c, const Xbyak::Operand& dst,
|
||||
bool restore_flags = false) {
|
||||
if (restore_flags) {
|
||||
c.popfq();
|
||||
}
|
||||
for (int reg = 15; reg >= 0; reg--) {
|
||||
if ((!dst.isXMM() && !dst.isYMM()) || dst.getIdx() != reg) {
|
||||
c.vmovdqu(Xbyak::Ymm(reg), ptr[rsp + 32 * reg]);
|
||||
}
|
||||
}
|
||||
c.lea(rsp, ptr[rsp + 32 * 16]);
|
||||
for (int reg = Xbyak::Operand::R15; reg >= Xbyak::Operand::RAX; reg--) {
|
||||
if (!dst.isREG() || dst.getIdx() != reg) {
|
||||
c.pop(Xbyak::Reg64(reg));
|
||||
} else {
|
||||
c.lea(rsp, ptr[rsp + 8]);
|
||||
}
|
||||
}
|
||||
RestoreStack(c);
|
||||
}
|
||||
|
||||
static void GenerateANDN(const ZydisDecodedOperand* operands, Xbyak::CodeGenerator& c) {
|
||||
const auto dst = ZydisToXbyakRegisterOperand(operands[0]);
|
||||
const auto src1 = ZydisToXbyakRegisterOperand(operands[1]);
|
||||
const auto src2 = ZydisToXbyakOperand(operands[2]);
|
||||
ValidateDst(dst);
|
||||
|
||||
// Check if src2 is a memory operand or a register different to dst.
|
||||
// In those cases, we don't need to use a temporary register and are free to modify dst.
|
||||
// In cases where dst and src2 are the same register, a temporary needs to be used to avoid
|
||||
// modifying src2.
|
||||
bool src2_uses_dst = false;
|
||||
if (src2->isMEM()) {
|
||||
const auto base = src2->getAddress().getRegExp().getBase().getIdx();
|
||||
const auto index = src2->getAddress().getRegExp().getIndex().getIdx();
|
||||
src2_uses_dst = base == dst.getIdx() || index == dst.getIdx();
|
||||
} else {
|
||||
ASSERT(src2->isREG());
|
||||
src2_uses_dst = src2->getReg() == dst;
|
||||
}
|
||||
|
||||
if (!src2_uses_dst) {
|
||||
if (dst != src1)
|
||||
c.mov(dst, src1);
|
||||
c.not_(dst);
|
||||
c.and_(dst, *src2);
|
||||
} else {
|
||||
const auto scratch = AllocateScratchRegister({&dst, &src1, src2.get()}, dst.getBit());
|
||||
|
||||
SaveRegisters(c, {scratch});
|
||||
|
||||
c.mov(scratch, src1);
|
||||
c.not_(scratch);
|
||||
c.and_(scratch, *src2);
|
||||
c.mov(dst, scratch);
|
||||
|
||||
RestoreRegisters(c, {scratch});
|
||||
}
|
||||
}
|
||||
|
||||
static void GenerateBEXTR(const ZydisDecodedOperand* operands, Xbyak::CodeGenerator& c) {
|
||||
const auto dst = ZydisToXbyakRegisterOperand(operands[0]);
|
||||
const auto src = ZydisToXbyakOperand(operands[1]);
|
||||
const auto start_len = ZydisToXbyakRegisterOperand(operands[2]);
|
||||
ValidateDst(dst);
|
||||
|
||||
const Xbyak::Reg32e shift(Xbyak::Operand::RCX, static_cast<int>(start_len.getBit()));
|
||||
const auto scratch1 =
|
||||
AllocateScratchRegister({&dst, src.get(), &start_len, &shift}, dst.getBit());
|
||||
const auto scratch2 =
|
||||
AllocateScratchRegister({&dst, src.get(), &start_len, &shift, &scratch1}, dst.getBit());
|
||||
|
||||
if (dst.getIdx() == shift.getIdx()) {
|
||||
SaveRegisters(c, {scratch1, scratch2});
|
||||
} else {
|
||||
SaveRegisters(c, {scratch1, scratch2, shift});
|
||||
}
|
||||
|
||||
c.mov(scratch1, *src);
|
||||
if (shift.getIdx() != start_len.getIdx()) {
|
||||
c.mov(shift, start_len);
|
||||
}
|
||||
|
||||
c.shr(scratch1, shift.cvt8());
|
||||
c.shr(shift, 8);
|
||||
c.mov(scratch2, 1);
|
||||
c.shl(scratch2, shift.cvt8());
|
||||
c.dec(scratch2);
|
||||
|
||||
c.mov(dst, scratch1);
|
||||
c.and_(dst, scratch2);
|
||||
|
||||
if (dst.getIdx() == shift.getIdx()) {
|
||||
RestoreRegisters(c, {scratch2, scratch1});
|
||||
} else {
|
||||
RestoreRegisters(c, {shift, scratch2, scratch1});
|
||||
}
|
||||
}
|
||||
|
||||
static void GenerateBLSI(const ZydisDecodedOperand* operands, Xbyak::CodeGenerator& c) {
|
||||
const auto dst = ZydisToXbyakRegisterOperand(operands[0]);
|
||||
const auto src = ZydisToXbyakOperand(operands[1]);
|
||||
ValidateDst(dst);
|
||||
|
||||
const auto scratch = AllocateScratchRegister({&dst, src.get()}, dst.getBit());
|
||||
|
||||
SaveRegisters(c, {scratch});
|
||||
|
||||
// BLSI sets CF to zero if source is zero, otherwise it sets CF to one.
|
||||
Xbyak::Label clear_carry, end;
|
||||
|
||||
c.mov(scratch, *src);
|
||||
c.neg(scratch); // NEG, like BLSI, clears CF if the source is zero and sets it otherwise
|
||||
c.jnc(clear_carry);
|
||||
|
||||
c.and_(scratch, *src);
|
||||
c.stc(); // setting/clearing carry needs to happen after the AND because that clears CF
|
||||
c.jmp(end);
|
||||
|
||||
c.L(clear_carry);
|
||||
c.and_(scratch, *src);
|
||||
// We don't need to clear carry here since AND does that for us
|
||||
|
||||
c.L(end);
|
||||
c.mov(dst, scratch);
|
||||
|
||||
RestoreRegisters(c, {scratch});
|
||||
}
|
||||
|
||||
static void GenerateBLSMSK(const ZydisDecodedOperand* operands, Xbyak::CodeGenerator& c) {
|
||||
const auto dst = ZydisToXbyakRegisterOperand(operands[0]);
|
||||
const auto src = ZydisToXbyakOperand(operands[1]);
|
||||
ValidateDst(dst);
|
||||
|
||||
const auto scratch = AllocateScratchRegister({&dst, src.get()}, dst.getBit());
|
||||
|
||||
SaveRegisters(c, {scratch});
|
||||
|
||||
Xbyak::Label clear_carry, end;
|
||||
|
||||
// BLSMSK sets CF to zero if source is NOT zero, otherwise it sets CF to one.
|
||||
c.mov(scratch, *src);
|
||||
c.test(scratch, scratch);
|
||||
c.jnz(clear_carry);
|
||||
|
||||
c.dec(scratch);
|
||||
c.xor_(scratch, *src);
|
||||
c.stc();
|
||||
c.jmp(end);
|
||||
|
||||
c.L(clear_carry);
|
||||
c.dec(scratch);
|
||||
c.xor_(scratch, *src);
|
||||
// We don't need to clear carry here since XOR does that for us
|
||||
|
||||
c.L(end);
|
||||
c.mov(dst, scratch);
|
||||
|
||||
RestoreRegisters(c, {scratch});
|
||||
}
|
||||
|
||||
static void GenerateTZCNT(const ZydisDecodedOperand* operands, Xbyak::CodeGenerator& c) {
|
||||
const auto dst = ZydisToXbyakRegisterOperand(operands[0]);
|
||||
const auto src = ZydisToXbyakOperand(operands[1]);
|
||||
ValidateDst(dst);
|
||||
|
||||
Xbyak::Label src_zero, end;
|
||||
|
||||
c.cmp(*src, 0);
|
||||
c.je(src_zero);
|
||||
|
||||
// If src is not zero, functions like a BSF, but also clears the CF
|
||||
c.bsf(dst, *src);
|
||||
c.clc();
|
||||
c.jmp(end);
|
||||
|
||||
c.L(src_zero);
|
||||
c.mov(dst, operands[0].size);
|
||||
// Since dst is not zero, also set ZF to zero. Testing dst with itself when we know
|
||||
// it isn't zero is a good way to do this.
|
||||
// Use cvt32 to avoid REX/Operand size prefixes.
|
||||
c.test(dst.cvt32(), dst.cvt32());
|
||||
// When source is zero, TZCNT also sets CF.
|
||||
c.stc();
|
||||
|
||||
c.L(end);
|
||||
}
|
||||
|
||||
static void GenerateBLSR(const ZydisDecodedOperand* operands, Xbyak::CodeGenerator& c) {
|
||||
const auto dst = ZydisToXbyakRegisterOperand(operands[0]);
|
||||
const auto src = ZydisToXbyakOperand(operands[1]);
|
||||
ValidateDst(dst);
|
||||
|
||||
const auto scratch = AllocateScratchRegister({&dst, src.get()}, dst.getBit());
|
||||
|
||||
SaveRegisters(c, {scratch});
|
||||
|
||||
Xbyak::Label clear_carry, end;
|
||||
|
||||
// BLSR sets CF to zero if source is NOT zero, otherwise it sets CF to one.
|
||||
c.mov(scratch, *src);
|
||||
c.test(scratch, scratch);
|
||||
c.jnz(clear_carry);
|
||||
|
||||
c.dec(scratch);
|
||||
c.and_(scratch, *src);
|
||||
c.stc();
|
||||
c.jmp(end);
|
||||
|
||||
c.L(clear_carry);
|
||||
c.dec(scratch);
|
||||
c.and_(scratch, *src);
|
||||
// We don't need to clear carry here since AND does that for us
|
||||
|
||||
c.L(end);
|
||||
c.mov(dst, scratch);
|
||||
|
||||
RestoreRegisters(c, {scratch});
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
static __attribute__((sysv_abi)) void PerformVCVTPH2PS(float* out, const half_float::half* in,
|
||||
const u32 count) {
|
||||
for (u32 i = 0; i < count; i++) {
|
||||
out[i] = half_float::half_cast<float>(in[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void GenerateVCVTPH2PS(const ZydisDecodedOperand* operands, Xbyak::CodeGenerator& c) {
|
||||
const auto dst = ZydisToXbyakRegisterOperand(operands[0]);
|
||||
const auto src = ZydisToXbyakOperand(operands[1]);
|
||||
|
||||
const auto float_count = dst.getBit() / 32;
|
||||
const auto byte_count = float_count * 4;
|
||||
|
||||
SaveContext(c, true);
|
||||
|
||||
// Allocate stack space for outputs and load into first parameter.
|
||||
c.sub(rsp, byte_count);
|
||||
c.mov(rdi, rsp);
|
||||
|
||||
if (src->isXMM()) {
|
||||
// Allocate stack space for inputs and load into second parameter.
|
||||
c.sub(rsp, byte_count);
|
||||
c.mov(rsi, rsp);
|
||||
|
||||
// Move input to the allocated space.
|
||||
c.movdqu(ptr[rsp], *reinterpret_cast<Xbyak::Xmm*>(src.get()));
|
||||
} else {
|
||||
c.lea(rsi, src->getAddress());
|
||||
}
|
||||
|
||||
// Load float count into third parameter.
|
||||
c.mov(rdx, float_count);
|
||||
|
||||
c.mov(rax, reinterpret_cast<u64>(PerformVCVTPH2PS));
|
||||
c.call(rax);
|
||||
|
||||
if (src->isXMM()) {
|
||||
// Clean up after inputs space.
|
||||
c.add(rsp, byte_count);
|
||||
}
|
||||
|
||||
// Load outputs into destination register and clean up space.
|
||||
if (dst.isYMM()) {
|
||||
c.vmovdqu(*reinterpret_cast<const Xbyak::Ymm*>(&dst), ptr[rsp]);
|
||||
} else {
|
||||
c.movdqu(*reinterpret_cast<const Xbyak::Xmm*>(&dst), ptr[rsp]);
|
||||
}
|
||||
c.add(rsp, byte_count);
|
||||
|
||||
RestoreContext(c, dst, true);
|
||||
}
|
||||
|
||||
using SingleToHalfFloatConverter = half_float::half (*)(float);
|
||||
static const SingleToHalfFloatConverter SingleToHalfFloatConverters[4] = {
|
||||
half_float::half_cast<half_float::half, std::round_to_nearest, float>,
|
||||
half_float::half_cast<half_float::half, std::round_toward_neg_infinity, float>,
|
||||
half_float::half_cast<half_float::half, std::round_toward_infinity, float>,
|
||||
half_float::half_cast<half_float::half, std::round_toward_zero, float>,
|
||||
};
|
||||
|
||||
static __attribute__((sysv_abi)) void PerformVCVTPS2PH(half_float::half* out, const float* in,
|
||||
const u32 count, const u8 rounding_mode) {
|
||||
const auto conversion_func = SingleToHalfFloatConverters[rounding_mode];
|
||||
|
||||
for (u32 i = 0; i < count; i++) {
|
||||
out[i] = conversion_func(in[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void GenerateVCVTPS2PH(const ZydisDecodedOperand* operands, Xbyak::CodeGenerator& c) {
|
||||
const auto dst = ZydisToXbyakOperand(operands[0]);
|
||||
const auto src = ZydisToXbyakRegisterOperand(operands[1]);
|
||||
const auto ctrl = ZydisToXbyakImmediateOperand(operands[2]);
|
||||
|
||||
const auto float_count = src.getBit() / 32;
|
||||
const auto byte_count = float_count * 4;
|
||||
|
||||
SaveContext(c, true);
|
||||
|
||||
if (dst->isXMM()) {
|
||||
// Allocate stack space for outputs and load into first parameter.
|
||||
c.sub(rsp, byte_count);
|
||||
c.mov(rdi, rsp);
|
||||
} else {
|
||||
c.lea(rdi, dst->getAddress());
|
||||
}
|
||||
|
||||
// Allocate stack space for inputs and load into second parameter.
|
||||
c.sub(rsp, byte_count);
|
||||
c.mov(rsi, rsp);
|
||||
|
||||
// Move input to the allocated space.
|
||||
if (src.isYMM()) {
|
||||
c.vmovdqu(ptr[rsp], *reinterpret_cast<const Xbyak::Ymm*>(&src));
|
||||
} else {
|
||||
c.movdqu(ptr[rsp], *reinterpret_cast<const Xbyak::Xmm*>(&src));
|
||||
}
|
||||
|
||||
// Load float count into third parameter.
|
||||
c.mov(rdx, float_count);
|
||||
|
||||
// Load rounding mode into fourth parameter.
|
||||
if (ctrl & 4) {
|
||||
// Load from MXCSR.RC.
|
||||
c.stmxcsr(ptr[rsp - 4]);
|
||||
c.mov(rcx, ptr[rsp - 4]);
|
||||
c.shr(rcx, 13);
|
||||
c.and_(rcx, 3);
|
||||
} else {
|
||||
c.mov(rcx, ctrl & 3);
|
||||
}
|
||||
|
||||
c.mov(rax, reinterpret_cast<u64>(PerformVCVTPS2PH));
|
||||
c.call(rax);
|
||||
|
||||
// Clean up after inputs space.
|
||||
c.add(rsp, byte_count);
|
||||
|
||||
if (dst->isXMM()) {
|
||||
// Load outputs into destination register and clean up space.
|
||||
c.movdqu(*reinterpret_cast<Xbyak::Xmm*>(dst.get()), ptr[rsp]);
|
||||
c.add(rsp, byte_count);
|
||||
}
|
||||
|
||||
RestoreContext(c, *dst, true);
|
||||
}
|
||||
|
||||
static bool FilterRosetta2Only(const ZydisDecodedOperand*) {
|
||||
int ret = 0;
|
||||
size_t size = sizeof(ret);
|
||||
if (sysctlbyname("sysctl.proc_translated", &ret, &size, nullptr, 0) != 0) {
|
||||
return false;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#else // __APPLE__
|
||||
|
||||
static bool FilterTcbAccess(const ZydisDecodedOperand* operands) {
|
||||
const auto& dst_op = operands[0];
|
||||
const auto& src_op = operands[1];
|
||||
|
@ -657,18 +121,11 @@ static void GenerateTcbAccess(const ZydisDecodedOperand* operands, Xbyak::CodeGe
|
|||
#endif
|
||||
}
|
||||
|
||||
#endif // __APPLE__
|
||||
|
||||
static bool FilterNoSSE4a(const ZydisDecodedOperand*) {
|
||||
Cpu cpu;
|
||||
return !cpu.has(Cpu::tSSE4a);
|
||||
}
|
||||
|
||||
static bool FilterNoBMI1(const ZydisDecodedOperand*) {
|
||||
Cpu cpu;
|
||||
return !cpu.has(Cpu::tBMI1);
|
||||
}
|
||||
|
||||
static void GenerateEXTRQ(const ZydisDecodedOperand* operands, Xbyak::CodeGenerator& c) {
|
||||
bool immediateForm = operands[1].type == ZYDIS_OPERAND_TYPE_IMMEDIATE &&
|
||||
operands[2].type == ZYDIS_OPERAND_TYPE_IMMEDIATE;
|
||||
|
@ -940,30 +397,16 @@ struct PatchInfo {
|
|||
};
|
||||
|
||||
static const std::unordered_map<ZydisMnemonic, PatchInfo> Patches = {
|
||||
// SSE4a
|
||||
{ZYDIS_MNEMONIC_EXTRQ, {FilterNoSSE4a, GenerateEXTRQ, true}},
|
||||
{ZYDIS_MNEMONIC_INSERTQ, {FilterNoSSE4a, GenerateINSERTQ, true}},
|
||||
|
||||
#if defined(_WIN32)
|
||||
// Windows needs a trampoline.
|
||||
{ZYDIS_MNEMONIC_MOV, {FilterTcbAccess, GenerateTcbAccess, true}},
|
||||
#elif !defined(__APPLE__)
|
||||
{ZYDIS_MNEMONIC_MOV, {FilterTcbAccess, GenerateTcbAccess, false}},
|
||||
#endif
|
||||
|
||||
{ZYDIS_MNEMONIC_EXTRQ, {FilterNoSSE4a, GenerateEXTRQ, true}},
|
||||
{ZYDIS_MNEMONIC_INSERTQ, {FilterNoSSE4a, GenerateINSERTQ, true}},
|
||||
|
||||
// BMI1
|
||||
{ZYDIS_MNEMONIC_ANDN, {FilterNoBMI1, GenerateANDN, true}},
|
||||
{ZYDIS_MNEMONIC_BEXTR, {FilterNoBMI1, GenerateBEXTR, true}},
|
||||
{ZYDIS_MNEMONIC_BLSI, {FilterNoBMI1, GenerateBLSI, true}},
|
||||
{ZYDIS_MNEMONIC_BLSMSK, {FilterNoBMI1, GenerateBLSMSK, true}},
|
||||
{ZYDIS_MNEMONIC_BLSR, {FilterNoBMI1, GenerateBLSR, true}},
|
||||
{ZYDIS_MNEMONIC_TZCNT, {FilterNoBMI1, GenerateTZCNT, true}},
|
||||
|
||||
#ifdef __APPLE__
|
||||
// Patches for instruction sets not supported by Rosetta 2.
|
||||
// F16C
|
||||
{ZYDIS_MNEMONIC_VCVTPH2PS, {FilterRosetta2Only, GenerateVCVTPH2PS, true}},
|
||||
{ZYDIS_MNEMONIC_VCVTPS2PH, {FilterRosetta2Only, GenerateVCVTPS2PH, true}},
|
||||
#endif
|
||||
};
|
||||
|
||||
static std::once_flag init_flag;
|
||||
|
@ -1280,18 +723,7 @@ void RegisterPatchModule(void* module_ptr, u64 module_size, void* trampoline_are
|
|||
}
|
||||
|
||||
void PrePatchInstructions(u64 segment_addr, u64 segment_size) {
|
||||
#if defined(__APPLE__)
|
||||
// HACK: For some reason patching in the signal handler at the start of a page does not work
|
||||
// under Rosetta 2. Patch any instructions at the start of a page ahead of time.
|
||||
if (!Patches.empty()) {
|
||||
auto* code_page = reinterpret_cast<u8*>(Common::AlignUp(segment_addr, 0x1000));
|
||||
const auto* end_page = code_page + Common::AlignUp(segment_size, 0x1000);
|
||||
while (code_page < end_page) {
|
||||
TryPatchJit(code_page);
|
||||
code_page += 0x1000;
|
||||
}
|
||||
}
|
||||
#elif !defined(_WIN32)
|
||||
#if !defined(_WIN32) && !defined(__APPLE__)
|
||||
// Linux and others have an FS segment pointing to valid memory, so continue to do full
|
||||
// ahead-of-time patching for now until a better solution is worked out.
|
||||
if (!Patches.empty()) {
|
||||
|
|
|
@ -7,12 +7,6 @@
|
|||
|
||||
namespace Core {
|
||||
|
||||
/// Initializes a stack for the current thread for use by patch implementations.
|
||||
void InitializeThreadPatchStack();
|
||||
|
||||
/// Cleans up the patch stack for the current thread.
|
||||
void CleanupThreadPatchStack();
|
||||
|
||||
/// Registers a module for patching, providing an area to generate trampoline code.
|
||||
void RegisterPatchModule(void* module_ptr, u64 module_size, void* trampoline_area_ptr,
|
||||
u64 trampoline_area_size);
|
||||
|
|
|
@ -627,65 +627,56 @@ void TextEditor::HandleKeyboardInputs() {
|
|||
io.WantCaptureKeyboard = true;
|
||||
io.WantTextInput = true;
|
||||
|
||||
if (!IsReadOnly() && ctrl && !shift && !alt &&
|
||||
ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Z)))
|
||||
if (!IsReadOnly() && ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_Z))
|
||||
Undo();
|
||||
else if (!IsReadOnly() && !ctrl && !shift && alt &&
|
||||
ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Backspace)))
|
||||
else if (!IsReadOnly() && !ctrl && !shift && alt && ImGui::IsKeyPressed(ImGuiKey_Backspace))
|
||||
Undo();
|
||||
else if (!IsReadOnly() && ctrl && !shift && !alt &&
|
||||
ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Y)))
|
||||
else if (!IsReadOnly() && ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_Y))
|
||||
Redo();
|
||||
else if (!ctrl && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_UpArrow)))
|
||||
else if (!ctrl && !alt && ImGui::IsKeyPressed(ImGuiKey_UpArrow))
|
||||
MoveUp(1, shift);
|
||||
else if (!ctrl && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_DownArrow)))
|
||||
else if (!ctrl && !alt && ImGui::IsKeyPressed(ImGuiKey_DownArrow))
|
||||
MoveDown(1, shift);
|
||||
else if (!alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_LeftArrow)))
|
||||
else if (!alt && ImGui::IsKeyPressed(ImGuiKey_LeftArrow))
|
||||
MoveLeft(1, shift, ctrl);
|
||||
else if (!alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_RightArrow)))
|
||||
else if (!alt && ImGui::IsKeyPressed(ImGuiKey_RightArrow))
|
||||
MoveRight(1, shift, ctrl);
|
||||
else if (!alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_PageUp)))
|
||||
else if (!alt && ImGui::IsKeyPressed(ImGuiKey_PageUp))
|
||||
MoveUp(GetPageSize() - 4, shift);
|
||||
else if (!alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_PageDown)))
|
||||
else if (!alt && ImGui::IsKeyPressed(ImGuiKey_PageDown))
|
||||
MoveDown(GetPageSize() - 4, shift);
|
||||
else if (!alt && ctrl && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Home)))
|
||||
else if (!alt && ctrl && ImGui::IsKeyPressed(ImGuiKey_Home))
|
||||
MoveTop(shift);
|
||||
else if (ctrl && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_End)))
|
||||
else if (ctrl && !alt && ImGui::IsKeyPressed(ImGuiKey_End))
|
||||
MoveBottom(shift);
|
||||
else if (!ctrl && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Home)))
|
||||
else if (!ctrl && !alt && ImGui::IsKeyPressed(ImGuiKey_Home))
|
||||
MoveHome(shift);
|
||||
else if (!ctrl && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_End)))
|
||||
else if (!ctrl && !alt && ImGui::IsKeyPressed(ImGuiKey_End))
|
||||
MoveEnd(shift);
|
||||
else if (!IsReadOnly() && !ctrl && !shift && !alt &&
|
||||
ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Delete)))
|
||||
else if (!IsReadOnly() && !ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_Delete))
|
||||
Delete();
|
||||
else if (!IsReadOnly() && !ctrl && !shift && !alt &&
|
||||
ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Backspace)))
|
||||
ImGui::IsKeyPressed(ImGuiKey_Backspace))
|
||||
Backspace();
|
||||
else if (!ctrl && !shift && !alt &&
|
||||
ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Insert)))
|
||||
else if (!ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_Insert))
|
||||
mOverwrite ^= true;
|
||||
else if (ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Insert)))
|
||||
else if (ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_Insert))
|
||||
Copy();
|
||||
else if (ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_C)))
|
||||
else if (ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_C))
|
||||
Copy();
|
||||
else if (!IsReadOnly() && !ctrl && shift && !alt &&
|
||||
ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Insert)))
|
||||
else if (!IsReadOnly() && !ctrl && shift && !alt && ImGui::IsKeyPressed(ImGuiKey_Insert))
|
||||
Paste();
|
||||
else if (!IsReadOnly() && ctrl && !shift && !alt &&
|
||||
ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_V)))
|
||||
else if (!IsReadOnly() && ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_V))
|
||||
Paste();
|
||||
else if (ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_X)))
|
||||
else if (ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_X))
|
||||
Cut();
|
||||
else if (!ctrl && shift && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Delete)))
|
||||
else if (!ctrl && shift && !alt && ImGui::IsKeyPressed(ImGuiKey_Delete))
|
||||
Cut();
|
||||
else if (ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_A)))
|
||||
else if (ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_A))
|
||||
SelectAll();
|
||||
else if (!IsReadOnly() && !ctrl && !shift && !alt &&
|
||||
ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Enter)))
|
||||
else if (!IsReadOnly() && !ctrl && !shift && !alt && ImGui::IsKeyPressed(ImGuiKey_Enter))
|
||||
EnterCharacter('\n', false);
|
||||
else if (!IsReadOnly() && !ctrl && !alt &&
|
||||
ImGui::IsKeyPressed(ImGui::GetKeyIndex(ImGuiKey_Tab)))
|
||||
else if (!IsReadOnly() && !ctrl && !alt && ImGui::IsKeyPressed(ImGuiKey_Tab))
|
||||
EnterCharacter('\t', shift);
|
||||
|
||||
if (!IsReadOnly() && !io.InputQueueCharacters.empty()) {
|
||||
|
|
|
@ -191,6 +191,7 @@ int PS4_SYSV_ABI sceAudioOutGetPortState(s32 handle, OrbisAudioOutPortState* sta
|
|||
case OrbisAudioOutPort::Main:
|
||||
case OrbisAudioOutPort::Bgm:
|
||||
case OrbisAudioOutPort::Voice:
|
||||
case OrbisAudioOutPort::Audio3d:
|
||||
state->output = 1;
|
||||
state->channel = port.format_info.num_channels > 2 ? 2 : port.format_info.num_channels;
|
||||
break;
|
||||
|
@ -316,7 +317,7 @@ s32 PS4_SYSV_ABI sceAudioOutOpen(UserService::OrbisUserServiceUserId user_id,
|
|||
return ORBIS_AUDIO_OUT_ERROR_NOT_INIT;
|
||||
}
|
||||
if ((port_type < OrbisAudioOutPort::Main || port_type > OrbisAudioOutPort::Padspk) &&
|
||||
(port_type != OrbisAudioOutPort::Aux)) {
|
||||
(port_type != OrbisAudioOutPort::Audio3d && port_type != OrbisAudioOutPort::Aux)) {
|
||||
LOG_ERROR(Lib_AudioOut, "Invalid port type");
|
||||
return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT_TYPE;
|
||||
}
|
||||
|
|
|
@ -20,7 +20,15 @@ class PortBackend;
|
|||
constexpr s32 SCE_AUDIO_OUT_NUM_PORTS = 22;
|
||||
constexpr s32 SCE_AUDIO_OUT_VOLUME_0DB = 32768; // max volume value
|
||||
|
||||
enum class OrbisAudioOutPort { Main = 0, Bgm = 1, Voice = 2, Personal = 3, Padspk = 4, Aux = 127 };
|
||||
enum class OrbisAudioOutPort {
|
||||
Main = 0,
|
||||
Bgm = 1,
|
||||
Voice = 2,
|
||||
Personal = 3,
|
||||
Padspk = 4,
|
||||
Audio3d = 126,
|
||||
Aux = 127,
|
||||
};
|
||||
|
||||
enum class OrbisAudioOutParamFormat : u32 {
|
||||
S16Mono = 0,
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include <SDL3/SDL_audio.h>
|
||||
#include <magic_enum/magic_enum.hpp>
|
||||
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/audio/audioout.h"
|
||||
#include "core/libraries/audio/audioout_error.h"
|
||||
#include "core/libraries/audio3d/audio3d.h"
|
||||
#include "core/libraries/audio3d/audio3d_error.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
|
@ -10,331 +15,577 @@
|
|||
|
||||
namespace Libraries::Audio3d {
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dInitialize(s64 iReserved) {
|
||||
LOG_INFO(Lib_Audio3d, "iReserved = {}", iReserved);
|
||||
return ORBIS_OK;
|
||||
static constexpr u32 AUDIO3D_SAMPLE_RATE = 48000;
|
||||
|
||||
static constexpr AudioOut::OrbisAudioOutParamFormat AUDIO3D_OUTPUT_FORMAT =
|
||||
AudioOut::OrbisAudioOutParamFormat::S16Stereo;
|
||||
static constexpr u32 AUDIO3D_OUTPUT_NUM_CHANNELS = 2;
|
||||
static constexpr u32 AUDIO3D_OUTPUT_BUFFER_FRAMES = 0x100;
|
||||
|
||||
static std::unique_ptr<Audio3dState> state;
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutClose(const s32 handle) {
|
||||
LOG_INFO(Lib_Audio3d, "called, handle = {}", handle);
|
||||
return AudioOut::sceAudioOutClose(handle);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dTerminate() {
|
||||
// TODO: When not initialized or some ports still open, return ORBIS_AUDIO3D_ERROR_NOT_READY
|
||||
LOG_INFO(Lib_Audio3d, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
void PS4_SYSV_ABI sceAudio3dGetDefaultOpenParameters(OrbisAudio3dOpenParameters* parameters) {
|
||||
if (parameters == nullptr) {
|
||||
LOG_ERROR(Lib_Audio3d, "Invalid OpenParameters ptr");
|
||||
return;
|
||||
}
|
||||
|
||||
parameters->size_this = sizeof(OrbisAudio3dOpenParameters);
|
||||
parameters->granularity = 256;
|
||||
parameters->rate = OrbisAudio3dRate::Rate48000;
|
||||
parameters->max_objects = 512;
|
||||
parameters->queue_depth = 2;
|
||||
parameters->buffer_mode = OrbisAudio3dBufferMode::AdvanceAndPush;
|
||||
parameters->num_beds = 2;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortOpen(OrbisUserServiceUserId iUserId,
|
||||
const OrbisAudio3dOpenParameters* pParameters,
|
||||
OrbisAudio3dPortId* pId) {
|
||||
LOG_INFO(Lib_Audio3d, "iUserId = {}", iUserId);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortClose(OrbisAudio3dPortId uiPortId) {
|
||||
LOG_INFO(Lib_Audio3d, "uiPortId = {}", uiPortId);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortSetAttribute(OrbisAudio3dPortId uiPortId,
|
||||
OrbisAudio3dAttributeId uiAttributeId,
|
||||
const void* pAttribute, size_t szAttribute) {
|
||||
LOG_INFO(Lib_Audio3d, "uiPortId = {}, uiAttributeId = {}, szAttribute = {}", uiPortId,
|
||||
uiAttributeId, szAttribute);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortFlush(OrbisAudio3dPortId uiPortId) {
|
||||
LOG_INFO(Lib_Audio3d, "uiPortId = {}", uiPortId);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortAdvance(OrbisAudio3dPortId uiPortId) {
|
||||
LOG_TRACE(Lib_Audio3d, "uiPortId = {}", uiPortId);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortPush(OrbisAudio3dPortId uiPortId, OrbisAudio3dBlocking eBlocking) {
|
||||
LOG_TRACE(Lib_Audio3d, "uiPortId = {}", uiPortId);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortGetAttributesSupported(OrbisAudio3dPortId uiPortId,
|
||||
OrbisAudio3dAttributeId* pCapabilities,
|
||||
u32* pNumCapabilities) {
|
||||
LOG_INFO(Lib_Audio3d, "uiPortId = {}", uiPortId);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortGetQueueLevel(OrbisAudio3dPortId uiPortId, u32* pQueueLevel,
|
||||
u32* pQueueAvailable) {
|
||||
LOG_TRACE(Lib_Audio3d, "uiPortId = {}", uiPortId);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dObjectReserve(OrbisAudio3dPortId uiPortId, OrbisAudio3dObjectId* pId) {
|
||||
LOG_INFO(Lib_Audio3d, "uiPortId = {}", uiPortId);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dObjectUnreserve(OrbisAudio3dPortId uiPortId,
|
||||
OrbisAudio3dObjectId uiObjectId) {
|
||||
LOG_INFO(Lib_Audio3d, "uiPortId = {}, uiObjectId = {}", uiPortId, uiObjectId);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dObjectSetAttributes(OrbisAudio3dPortId uiPortId,
|
||||
OrbisAudio3dObjectId uiObjectId,
|
||||
size_t szNumAttributes,
|
||||
const OrbisAudio3dAttribute* pAttributeArray) {
|
||||
LOG_INFO(Lib_Audio3d, "uiPortId = {}, uiObjectId = {}, szNumAttributes = {}", uiPortId,
|
||||
uiObjectId, szNumAttributes);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dBedWrite(OrbisAudio3dPortId uiPortId, u32 uiNumChannels,
|
||||
OrbisAudio3dFormat eFormat, const void* pBuffer,
|
||||
u32 uiNumSamples) {
|
||||
LOG_TRACE(Lib_Audio3d, "uiPortId = {}, uiNumChannels = {}, uiNumSamples = {}", uiPortId,
|
||||
uiNumChannels, uiNumSamples);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dBedWrite2(OrbisAudio3dPortId uiPortId, u32 uiNumChannels,
|
||||
OrbisAudio3dFormat eFormat, const void* pBuffer,
|
||||
u32 uiNumSamples, OrbisAudio3dOutputRoute eOutputRoute,
|
||||
bool bRestricted) {
|
||||
LOG_INFO(Lib_Audio3d, "uiPortId = {}, uiNumChannels = {}, uiNumSamples = {}, bRestricted = {}",
|
||||
uiPortId, uiNumChannels, uiNumSamples, bRestricted);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
size_t PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMemorySize(u32 uiNumSpeakers, bool bIs3d) {
|
||||
LOG_INFO(Lib_Audio3d, "uiNumSpeakers = {}, bIs3d = {}", uiNumSpeakers, bIs3d);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI
|
||||
sceAudio3dCreateSpeakerArray(OrbisAudio3dSpeakerArrayHandle* pHandle,
|
||||
const OrbisAudio3dSpeakerArrayParameters* pParameters) {
|
||||
if (pHandle == nullptr || pParameters == nullptr) {
|
||||
LOG_ERROR(Lib_Audio3d, "invalid SpeakerArray parameters");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
LOG_INFO(Lib_Audio3d, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dDeleteSpeakerArray(OrbisAudio3dSpeakerArrayHandle handle) {
|
||||
if (handle == nullptr) {
|
||||
LOG_ERROR(Lib_Audio3d, "invalid SpeakerArrayHandle");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
LOG_INFO(Lib_Audio3d, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMixCoefficients(OrbisAudio3dSpeakerArrayHandle handle,
|
||||
OrbisAudio3dPosition pos, float fSpread,
|
||||
float* pCoefficients,
|
||||
u32 uiNumCoefficients) {
|
||||
LOG_INFO(Lib_Audio3d, "fSpread = {}, uiNumCoefficients = {}", fSpread, uiNumCoefficients);
|
||||
if (handle == nullptr) {
|
||||
LOG_ERROR(Lib_Audio3d, "invalid SpeakerArrayHandle");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMixCoefficients2(OrbisAudio3dSpeakerArrayHandle handle,
|
||||
OrbisAudio3dPosition pos, float fSpread,
|
||||
float* pCoefficients,
|
||||
u32 uiNumCoefficients, bool bHeightAware,
|
||||
float fDownmixSpreadRadius) {
|
||||
s32 PS4_SYSV_ABI
|
||||
sceAudio3dAudioOutOpen(const OrbisAudio3dPortId port_id, const OrbisUserServiceUserId user_id,
|
||||
s32 type, const s32 index, const u32 len, const u32 freq,
|
||||
const AudioOut::OrbisAudioOutParamExtendedInformation param) {
|
||||
LOG_INFO(Lib_Audio3d,
|
||||
"fSpread = {}, uiNumCoefficients = {}, bHeightAware = {}, fDownmixSpreadRadius = {}",
|
||||
fSpread, uiNumCoefficients, bHeightAware, fDownmixSpreadRadius);
|
||||
if (handle == nullptr) {
|
||||
LOG_ERROR(Lib_Audio3d, "invalid SpeakerArrayHandle");
|
||||
"called, port_id = {}, user_id = {}, type = {}, index = {}, len = {}, freq = {}",
|
||||
port_id, user_id, type, index, len, freq);
|
||||
|
||||
if (!state->ports.contains(port_id)) {
|
||||
LOG_ERROR(Lib_Audio3d, "!state->ports.contains(port_id)");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PORT;
|
||||
}
|
||||
|
||||
if (len != state->ports[port_id].parameters.granularity) {
|
||||
LOG_ERROR(Lib_Audio3d, "len != state->ports[port_id].parameters.granularity");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return sceAudioOutOpen(user_id, static_cast<AudioOut::OrbisAudioOutPort>(type), index, len,
|
||||
freq, param);
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutOutput(const s32 handle, void* ptr) {
|
||||
LOG_DEBUG(Lib_Audio3d, "called, handle = {}, ptr = {}", handle, ptr);
|
||||
|
||||
if (!ptr) {
|
||||
LOG_ERROR(Lib_Audio3d, "!ptr");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (handle < 0 || (handle & 0xFFFF) > 25) {
|
||||
LOG_ERROR(Lib_Audio3d, "handle < 0 || (handle & 0xFFFF) > 25");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PORT;
|
||||
}
|
||||
|
||||
return AudioOut::sceAudioOutOutput(handle, ptr);
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutOutputs(AudioOut::OrbisAudioOutOutputParam* param,
|
||||
const u32 num) {
|
||||
LOG_DEBUG(Lib_Audio3d, "called, param = {}, num = {}", static_cast<void*>(param), num);
|
||||
|
||||
if (!param || !num) {
|
||||
LOG_ERROR(Lib_Audio3d, "!param || !num");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
return AudioOut::sceAudioOutOutputs(param, num);
|
||||
}
|
||||
|
||||
static s32 PortQueueAudio(Port& port, const OrbisAudio3dPcm& pcm, const u32 num_channels) {
|
||||
// Audio3d output is configured for stereo signed 16-bit PCM. Convert the data to match.
|
||||
const SDL_AudioSpec src_spec = {
|
||||
.format = pcm.format == OrbisAudio3dFormat::ORBIS_AUDIO3D_FORMAT_S16 ? SDL_AUDIO_S16LE
|
||||
: SDL_AUDIO_F32LE,
|
||||
.channels = static_cast<int>(num_channels),
|
||||
.freq = AUDIO3D_SAMPLE_RATE,
|
||||
};
|
||||
constexpr SDL_AudioSpec dst_spec = {
|
||||
.format = SDL_AUDIO_S16LE,
|
||||
.channels = AUDIO3D_OUTPUT_NUM_CHANNELS,
|
||||
.freq = AUDIO3D_SAMPLE_RATE,
|
||||
};
|
||||
const auto src_size = pcm.num_samples *
|
||||
(pcm.format == OrbisAudio3dFormat::ORBIS_AUDIO3D_FORMAT_S16 ? 2 : 4) *
|
||||
num_channels;
|
||||
|
||||
u8* dst_data;
|
||||
int dst_len;
|
||||
if (!SDL_ConvertAudioSamples(&src_spec, static_cast<u8*>(pcm.sample_buffer),
|
||||
static_cast<int>(src_size), &dst_spec, &dst_data, &dst_len)) {
|
||||
LOG_ERROR(Lib_Audio3d, "SDL_ConvertAudioSamples failed: {}", SDL_GetError());
|
||||
return ORBIS_AUDIO3D_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
port.queue.emplace_back(AudioData{
|
||||
.sample_buffer = dst_data,
|
||||
.num_samples = pcm.num_samples,
|
||||
});
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dBedWrite(const OrbisAudio3dPortId port_id, const u32 num_channels,
|
||||
const OrbisAudio3dFormat format, void* buffer,
|
||||
const u32 num_samples) {
|
||||
return sceAudio3dBedWrite2(port_id, num_channels, format, buffer, num_samples,
|
||||
OrbisAudio3dOutputRoute::ORBIS_AUDIO3D_OUTPUT_BOTH, false);
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dBedWrite2(const OrbisAudio3dPortId port_id, const u32 num_channels,
|
||||
const OrbisAudio3dFormat format, void* buffer,
|
||||
const u32 num_samples,
|
||||
const OrbisAudio3dOutputRoute output_route,
|
||||
const bool restricted) {
|
||||
LOG_DEBUG(
|
||||
Lib_Audio3d,
|
||||
"called, port_id = {}, num_channels = {}, format = {}, num_samples = {}, output_route "
|
||||
"= {}, restricted = {}",
|
||||
port_id, num_channels, magic_enum::enum_name(format), num_samples,
|
||||
magic_enum::enum_name(output_route), restricted);
|
||||
|
||||
if (!state->ports.contains(port_id)) {
|
||||
LOG_ERROR(Lib_Audio3d, "!state->ports.contains(port_id)");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PORT;
|
||||
}
|
||||
|
||||
if (output_route > OrbisAudio3dOutputRoute::ORBIS_AUDIO3D_OUTPUT_BOTH) {
|
||||
LOG_ERROR(Lib_Audio3d, "output_route > ORBIS_AUDIO3D_OUTPUT_BOTH");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (format > OrbisAudio3dFormat::ORBIS_AUDIO3D_FORMAT_FLOAT) {
|
||||
LOG_ERROR(Lib_Audio3d, "format > ORBIS_AUDIO3D_FORMAT_FLOAT");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (num_channels != 2 && num_channels != 8) {
|
||||
LOG_ERROR(Lib_Audio3d, "num_channels != 2 && num_channels != 8");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (!buffer || !num_samples) {
|
||||
LOG_ERROR(Lib_Audio3d, "!buffer || !num_samples");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (format == OrbisAudio3dFormat::ORBIS_AUDIO3D_FORMAT_FLOAT) {
|
||||
if ((reinterpret_cast<uintptr_t>(buffer) & 3) != 0) {
|
||||
LOG_ERROR(Lib_Audio3d, "buffer & 3 != 0");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
} else if (format == OrbisAudio3dFormat::ORBIS_AUDIO3D_FORMAT_S16) {
|
||||
if ((reinterpret_cast<uintptr_t>(buffer) & 1) != 0) {
|
||||
LOG_ERROR(Lib_Audio3d, "buffer & 1 != 0");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
}
|
||||
|
||||
return PortQueueAudio(state->ports[port_id],
|
||||
OrbisAudio3dPcm{
|
||||
.format = format,
|
||||
.sample_buffer = buffer,
|
||||
.num_samples = num_samples,
|
||||
},
|
||||
num_channels);
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dCreateSpeakerArray() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dDeleteSpeakerArray() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dGetDefaultOpenParameters(OrbisAudio3dOpenParameters* params) {
|
||||
LOG_DEBUG(Lib_Audio3d, "called");
|
||||
if (params) {
|
||||
*params = OrbisAudio3dOpenParameters{
|
||||
.size_this = 0x20,
|
||||
.granularity = 0x100,
|
||||
.rate = OrbisAudio3dRate::ORBIS_AUDIO3D_RATE_48000,
|
||||
.max_objects = 512,
|
||||
.queue_depth = 2,
|
||||
.buffer_mode = OrbisAudio3dBufferMode::ORBIS_AUDIO3D_BUFFER_ADVANCE_AND_PUSH,
|
||||
};
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutOpen(OrbisAudio3dPortId uiPortId, OrbisUserServiceUserId userId,
|
||||
s32 type, s32 index, u32 len, u32 freq, u32 param) {
|
||||
s32 PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMemorySize() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMixCoefficients() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMixCoefficients2() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dInitialize(const s64 reserved) {
|
||||
LOG_INFO(Lib_Audio3d, "called, reserved = {}", reserved);
|
||||
|
||||
if (reserved != 0) {
|
||||
LOG_ERROR(Lib_Audio3d, "reserved != 0");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
if (state) {
|
||||
LOG_ERROR(Lib_Audio3d, "already initialized");
|
||||
return ORBIS_AUDIO3D_ERROR_NOT_READY;
|
||||
}
|
||||
|
||||
state = std::make_unique<Audio3dState>();
|
||||
|
||||
if (const auto init_ret = AudioOut::sceAudioOutInit();
|
||||
init_ret < 0 && init_ret != ORBIS_AUDIO_OUT_ERROR_ALREADY_INIT) {
|
||||
return init_ret;
|
||||
}
|
||||
|
||||
AudioOut::OrbisAudioOutParamExtendedInformation ext_info{};
|
||||
ext_info.data_format.Assign(AUDIO3D_OUTPUT_FORMAT);
|
||||
state->audio_out_handle =
|
||||
AudioOut::sceAudioOutOpen(0xFF, AudioOut::OrbisAudioOutPort::Audio3d, 0,
|
||||
AUDIO3D_OUTPUT_BUFFER_FRAMES, AUDIO3D_SAMPLE_RATE, ext_info);
|
||||
if (state->audio_out_handle < 0) {
|
||||
return state->audio_out_handle;
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dObjectReserve(const OrbisAudio3dPortId port_id,
|
||||
OrbisAudio3dObjectId* object_id) {
|
||||
LOG_INFO(Lib_Audio3d, "called, port_id = {}, object_id = {}", port_id,
|
||||
static_cast<void*>(object_id));
|
||||
|
||||
if (!state->ports.contains(port_id)) {
|
||||
LOG_ERROR(Lib_Audio3d, "!state->ports.contains(port_id)");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PORT;
|
||||
}
|
||||
|
||||
if (!object_id) {
|
||||
LOG_ERROR(Lib_Audio3d, "!object_id");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
static int last_id = 0;
|
||||
*object_id = ++last_id;
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dObjectSetAttributes(const OrbisAudio3dPortId port_id,
|
||||
OrbisAudio3dObjectId object_id,
|
||||
const u64 num_attributes,
|
||||
const OrbisAudio3dAttribute* attribute_array) {
|
||||
LOG_DEBUG(Lib_Audio3d,
|
||||
"called, port_id = {}, object_id = {}, num_attributes = {}, attribute_array = {}",
|
||||
port_id, object_id, num_attributes, fmt::ptr(attribute_array));
|
||||
|
||||
if (!state->ports.contains(port_id)) {
|
||||
LOG_ERROR(Lib_Audio3d, "!state->ports.contains(port_id)");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PORT;
|
||||
}
|
||||
|
||||
auto& port = state->ports[port_id];
|
||||
|
||||
for (u64 i = 0; i < num_attributes; i++) {
|
||||
const auto& attribute = attribute_array[i];
|
||||
|
||||
switch (attribute.attribute_id) {
|
||||
case OrbisAudio3dAttributeId::ORBIS_AUDIO3D_ATTRIBUTE_PCM: {
|
||||
const auto pcm = static_cast<OrbisAudio3dPcm*>(attribute.value);
|
||||
// Object audio has 1 channel.
|
||||
if (const auto ret = PortQueueAudio(port, *pcm, 1); ret != ORBIS_OK) {
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LOG_ERROR(Lib_Audio3d, "Unsupported attribute ID: {:#x}",
|
||||
static_cast<u32>(attribute.attribute_id));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dObjectUnreserve() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortAdvance(const OrbisAudio3dPortId port_id) {
|
||||
LOG_DEBUG(Lib_Audio3d, "called, port_id = {}", port_id);
|
||||
|
||||
if (!state->ports.contains(port_id)) {
|
||||
LOG_ERROR(Lib_Audio3d, "!state->ports.contains(port_id)");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PORT;
|
||||
}
|
||||
|
||||
if (state->ports[port_id].parameters.buffer_mode ==
|
||||
OrbisAudio3dBufferMode::ORBIS_AUDIO3D_BUFFER_NO_ADVANCE) {
|
||||
LOG_ERROR(Lib_Audio3d, "port doesn't have advance capability");
|
||||
return ORBIS_AUDIO3D_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
auto& port = state->ports[port_id];
|
||||
if (port.current_buffer.has_value()) {
|
||||
// Free existing buffer before replacing.
|
||||
SDL_free(port.current_buffer->sample_buffer);
|
||||
}
|
||||
|
||||
if (!port.queue.empty()) {
|
||||
port.current_buffer = port.queue.front();
|
||||
port.queue.pop_front();
|
||||
} else {
|
||||
// Nothing to advance to.
|
||||
LOG_DEBUG(Lib_Audio3d, "Port advance with no buffer queued");
|
||||
port.current_buffer = std::nullopt;
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortClose() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortCreate() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortDestroy() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortFlush() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortFreeState() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortGetAttributesSupported() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortGetList() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortGetParameters() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortGetQueueLevel(const OrbisAudio3dPortId port_id, u32* queue_level,
|
||||
u32* queue_available) {
|
||||
LOG_DEBUG(Lib_Audio3d, "called, port_id = {}, queue_level = {}, queue_available = {}", port_id,
|
||||
static_cast<void*>(queue_level), static_cast<void*>(queue_available));
|
||||
|
||||
if (!state->ports.contains(port_id)) {
|
||||
LOG_ERROR(Lib_Audio3d, "!state->ports.contains(port_id)");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PORT;
|
||||
}
|
||||
|
||||
if (!queue_level && !queue_available) {
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
const auto port = state->ports[port_id];
|
||||
const size_t size = port.queue.size();
|
||||
|
||||
if (queue_level) {
|
||||
*queue_level = size;
|
||||
}
|
||||
|
||||
if (queue_available) {
|
||||
*queue_available = port.parameters.queue_depth - size;
|
||||
}
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortGetState() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortGetStatus() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortOpen(const OrbisUserServiceUserId user_id,
|
||||
const OrbisAudio3dOpenParameters* parameters,
|
||||
OrbisAudio3dPortId* port_id) {
|
||||
LOG_INFO(Lib_Audio3d, "called, user_id = {}, parameters = {}, id = {}", user_id,
|
||||
static_cast<const void*>(parameters), static_cast<void*>(port_id));
|
||||
|
||||
if (!state) {
|
||||
LOG_ERROR(Lib_Audio3d, "!initialized");
|
||||
return ORBIS_AUDIO3D_ERROR_NOT_READY;
|
||||
}
|
||||
|
||||
if (!parameters || !port_id) {
|
||||
LOG_ERROR(Lib_Audio3d, "!parameters || !id");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
const int id = static_cast<int>(state->ports.size()) + 1;
|
||||
|
||||
if (id > 3) {
|
||||
LOG_ERROR(Lib_Audio3d, "id > 3");
|
||||
return ORBIS_AUDIO3D_ERROR_OUT_OF_RESOURCES;
|
||||
}
|
||||
|
||||
*port_id = id;
|
||||
std::memcpy(&state->ports[id].parameters, parameters, sizeof(OrbisAudio3dOpenParameters));
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortPush(const OrbisAudio3dPortId port_id,
|
||||
const OrbisAudio3dBlocking blocking) {
|
||||
LOG_DEBUG(Lib_Audio3d, "called, port_id = {}, blocking = {}", port_id,
|
||||
magic_enum::enum_name(blocking));
|
||||
|
||||
if (!state->ports.contains(port_id)) {
|
||||
LOG_ERROR(Lib_Audio3d, "!state->ports.contains(port_id)");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PORT;
|
||||
}
|
||||
|
||||
const auto& port = state->ports[port_id];
|
||||
if (port.parameters.buffer_mode !=
|
||||
OrbisAudio3dBufferMode::ORBIS_AUDIO3D_BUFFER_ADVANCE_AND_PUSH) {
|
||||
LOG_ERROR(Lib_Audio3d, "port doesn't have push capability");
|
||||
return ORBIS_AUDIO3D_ERROR_NOT_SUPPORTED;
|
||||
}
|
||||
|
||||
if (!port.current_buffer.has_value()) {
|
||||
// Nothing to push.
|
||||
LOG_DEBUG(Lib_Audio3d, "Port push with no buffer ready");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
// TODO: Implement asynchronous blocking mode.
|
||||
const auto& [sample_buffer, num_samples] = port.current_buffer.value();
|
||||
return AudioOut::sceAudioOutOutput(state->audio_out_handle, sample_buffer);
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortQueryDebug() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortSetAttribute(const OrbisAudio3dPortId port_id,
|
||||
const OrbisAudio3dAttributeId attribute_id,
|
||||
void* attribute, const u64 attribute_size) {
|
||||
LOG_INFO(Lib_Audio3d,
|
||||
"uiPortId = {}, userId = {}, type = {}, index = {}, len = {}, freq = {}, param = {}",
|
||||
uiPortId, userId, type, index, len, freq, param);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
"called, port_id = {}, attribute_id = {}, attribute = {}, attribute_size = {}",
|
||||
port_id, static_cast<u32>(attribute_id), attribute, attribute_size);
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutClose(s32 handle) {
|
||||
LOG_INFO(Lib_Audio3d, "handle = {}", handle);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
if (!state->ports.contains(port_id)) {
|
||||
LOG_ERROR(Lib_Audio3d, "!state->ports.contains(port_id)");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PORT;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutOutput(s32 handle, const void* ptr) {
|
||||
LOG_TRACE(Lib_Audio3d, "handle = {}", handle);
|
||||
if (ptr == nullptr) {
|
||||
LOG_ERROR(Lib_Audio3d, "invalid Output ptr");
|
||||
if (!attribute) {
|
||||
LOG_ERROR(Lib_Audio3d, "!attribute");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// TODO
|
||||
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutOutputs(::Libraries::AudioOut::OrbisAudioOutOutputParam* param,
|
||||
s32 num) {
|
||||
LOG_INFO(Lib_Audio3d, "num = {}", num);
|
||||
if (param == nullptr) {
|
||||
LOG_ERROR(Lib_Audio3d, "invalid OutputParam ptr");
|
||||
return ORBIS_AUDIO3D_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortCreate(u32 uiGranularity, OrbisAudio3dRate eRate, s64 iReserved,
|
||||
OrbisAudio3dPortId* pId) {
|
||||
LOG_INFO(Lib_Audio3d, "uiGranularity = {}, iReserved = {}", uiGranularity, iReserved);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortDestroy(OrbisAudio3dPortId uiPortId) {
|
||||
LOG_INFO(Lib_Audio3d, "uiPortId = {}", uiPortId);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
// Audio3dPrivate
|
||||
|
||||
const char* PS4_SYSV_ABI sceAudio3dStrError(int iErrorCode) {
|
||||
LOG_ERROR(Lib_Audio3d, "(PRIVATE) called, iErrorCode = {}", iErrorCode);
|
||||
return "NOT_IMPLEMENTED";
|
||||
}
|
||||
|
||||
// Audio3dDebug
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortQueryDebug() {
|
||||
LOG_WARNING(Lib_Audio3d, "(DEBUG) sceAudio3dPortQueryDebug called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortGetList() {
|
||||
LOG_WARNING(Lib_Audio3d, "(DEBUG) sceAudio3dPortGetList called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortGetParameters() {
|
||||
LOG_WARNING(Lib_Audio3d, "(DEBUG) sceAudio3dPortGetParameters called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortGetState() {
|
||||
LOG_WARNING(Lib_Audio3d, "(DEBUG) sceAudio3dPortGetState called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortFreeState() {
|
||||
LOG_WARNING(Lib_Audio3d, "(DEBUG) sceAudio3dPortFreeState called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
// Unknown
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortGetBufferLevel() {
|
||||
s32 PS4_SYSV_ABI sceAudio3dReportRegisterHandler() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dPortGetStatus() {
|
||||
s32 PS4_SYSV_ABI sceAudio3dReportUnregisterHandler() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dReportRegisterHandler() {
|
||||
s32 PS4_SYSV_ABI sceAudio3dSetGpuRenderer() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dReportUnregisterHandler() {
|
||||
s32 PS4_SYSV_ABI sceAudio3dStrError() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceAudio3dSetGpuRenderer() {
|
||||
s32 PS4_SYSV_ABI sceAudio3dTerminate() {
|
||||
LOG_ERROR(Lib_Audio3d, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
void RegisterlibSceAudio3d(Core::Loader::SymbolsResolver* sym) {
|
||||
LIB_FUNCTION("pZlOm1aF3aA", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dAudioOutClose);
|
||||
LIB_FUNCTION("ucEsi62soTo", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dAudioOutOpen);
|
||||
LIB_FUNCTION("7NYEzJ9SJbM", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dAudioOutOutput);
|
||||
LIB_FUNCTION("HbxYY27lK6E", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dAudioOutOutputs);
|
||||
LIB_FUNCTION("9tEwE0GV0qo", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dBedWrite);
|
||||
LIB_FUNCTION("xH4Q9UILL3o", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dBedWrite2);
|
||||
LIB_FUNCTION("lvWMW6vEqFU", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dCreateSpeakerArray);
|
||||
LIB_FUNCTION("8hm6YdoQgwg", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dDeleteSpeakerArray);
|
||||
LIB_FUNCTION("Im+jOoa5WAI", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dGetDefaultOpenParameters);
|
||||
LIB_FUNCTION("kEqqyDkmgdI", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dGetSpeakerArrayMemorySize);
|
||||
LIB_FUNCTION("-R1DukFq7Dk", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dGetSpeakerArrayMixCoefficients);
|
||||
LIB_FUNCTION("-Re+pCWvwjQ", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dGetSpeakerArrayMixCoefficients2);
|
||||
LIB_FUNCTION("-pzYDZozm+M", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dPortQueryDebug);
|
||||
LIB_FUNCTION("1HXxo-+1qCw", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dObjectUnreserve);
|
||||
LIB_FUNCTION("UmCvjSmuZIw", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dInitialize);
|
||||
LIB_FUNCTION("jO2tec4dJ2M", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dObjectReserve);
|
||||
LIB_FUNCTION("4uyHN9q4ZeU", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dObjectSetAttributes);
|
||||
LIB_FUNCTION("7NYEzJ9SJbM", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dAudioOutOutput);
|
||||
LIB_FUNCTION("8hm6YdoQgwg", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dDeleteSpeakerArray);
|
||||
LIB_FUNCTION("1HXxo-+1qCw", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dObjectUnreserve);
|
||||
LIB_FUNCTION("lw0qrdSjZt8", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortAdvance);
|
||||
LIB_FUNCTION("OyVqOeVNtSk", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortClose);
|
||||
LIB_FUNCTION("UHFOgVNz0kk", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortCreate);
|
||||
LIB_FUNCTION("Mw9mRQtWepY", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortDestroy);
|
||||
LIB_FUNCTION("ZOGrxWLgQzE", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortFlush);
|
||||
LIB_FUNCTION("uJ0VhGcxCTQ", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortFreeState);
|
||||
LIB_FUNCTION("9ZA23Ia46Po", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dPortGetAttributesSupported);
|
||||
LIB_FUNCTION("9tEwE0GV0qo", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dBedWrite);
|
||||
LIB_FUNCTION("Aacl5qkRU6U", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dStrError);
|
||||
LIB_FUNCTION("CKHlRW2E9dA", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortGetState);
|
||||
LIB_FUNCTION("HbxYY27lK6E", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dAudioOutOutputs);
|
||||
LIB_FUNCTION("Im+jOoa5WAI", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dGetDefaultOpenParameters);
|
||||
LIB_FUNCTION("Mw9mRQtWepY", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortDestroy);
|
||||
LIB_FUNCTION("OyVqOeVNtSk", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortClose);
|
||||
LIB_FUNCTION("QfNXBrKZeI0", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dReportRegisterHandler);
|
||||
LIB_FUNCTION("QqgTQQdzEMY", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dPortGetBufferLevel);
|
||||
LIB_FUNCTION("SEggctIeTcI", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortGetList);
|
||||
LIB_FUNCTION("UHFOgVNz0kk", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortCreate);
|
||||
LIB_FUNCTION("UmCvjSmuZIw", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dInitialize);
|
||||
LIB_FUNCTION("VEVhZ9qd4ZY", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortPush);
|
||||
LIB_FUNCTION("WW1TS2iz5yc", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dTerminate);
|
||||
LIB_FUNCTION("XeDDK0xJWQA", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortOpen);
|
||||
LIB_FUNCTION("YaaDbDwKpFM", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dPortGetQueueLevel);
|
||||
LIB_FUNCTION("Yq9bfUQ0uJg", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dPortSetAttribute);
|
||||
LIB_FUNCTION("ZOGrxWLgQzE", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortFlush);
|
||||
LIB_FUNCTION("flPcUaXVXcw", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dPortGetParameters);
|
||||
LIB_FUNCTION("YaaDbDwKpFM", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dPortGetQueueLevel);
|
||||
LIB_FUNCTION("CKHlRW2E9dA", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortGetState);
|
||||
LIB_FUNCTION("iRX6GJs9tvE", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortGetStatus);
|
||||
LIB_FUNCTION("jO2tec4dJ2M", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dObjectReserve);
|
||||
LIB_FUNCTION("kEqqyDkmgdI", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dGetSpeakerArrayMemorySize);
|
||||
LIB_FUNCTION("lvWMW6vEqFU", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dCreateSpeakerArray);
|
||||
LIB_FUNCTION("lw0qrdSjZt8", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortAdvance);
|
||||
LIB_FUNCTION("pZlOm1aF3aA", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dAudioOutClose);
|
||||
LIB_FUNCTION("XeDDK0xJWQA", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortOpen);
|
||||
LIB_FUNCTION("VEVhZ9qd4ZY", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortPush);
|
||||
LIB_FUNCTION("-pzYDZozm+M", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dPortQueryDebug);
|
||||
LIB_FUNCTION("Yq9bfUQ0uJg", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dPortSetAttribute);
|
||||
LIB_FUNCTION("QfNXBrKZeI0", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dReportRegisterHandler);
|
||||
LIB_FUNCTION("psv2gbihC1A", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dReportUnregisterHandler);
|
||||
LIB_FUNCTION("uJ0VhGcxCTQ", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dPortFreeState);
|
||||
LIB_FUNCTION("ucEsi62soTo", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dAudioOutOpen);
|
||||
LIB_FUNCTION("xH4Q9UILL3o", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dBedWrite2);
|
||||
LIB_FUNCTION("yEYXcbAGK14", "libSceAudio3d", 1, "libSceAudio3d", 1, 1,
|
||||
sceAudio3dSetGpuRenderer);
|
||||
LIB_FUNCTION("Aacl5qkRU6U", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dStrError);
|
||||
LIB_FUNCTION("WW1TS2iz5yc", "libSceAudio3d", 1, "libSceAudio3d", 1, 1, sceAudio3dTerminate);
|
||||
};
|
||||
|
||||
} // namespace Libraries::Audio3d
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.h"
|
||||
#include <optional>
|
||||
#include <queue>
|
||||
|
||||
#include <stddef.h>
|
||||
#include "common/types.h"
|
||||
#include "core/libraries/audio/audioout.h"
|
||||
|
||||
namespace Core::Loader {
|
||||
class SymbolsResolver;
|
||||
|
@ -13,123 +15,131 @@ class SymbolsResolver;
|
|||
|
||||
namespace Libraries::Audio3d {
|
||||
|
||||
class Audio3d;
|
||||
|
||||
using OrbisUserServiceUserId = s32;
|
||||
using OrbisAudio3dPortId = u32;
|
||||
using OrbisAudio3dObjectId = u32;
|
||||
using OrbisAudio3dAttributeId = u32;
|
||||
|
||||
enum class OrbisAudio3dFormat {
|
||||
S16 = 0,
|
||||
Float = 1,
|
||||
enum class OrbisAudio3dRate : u32 {
|
||||
ORBIS_AUDIO3D_RATE_48000 = 0,
|
||||
};
|
||||
|
||||
enum class OrbisAudio3dRate {
|
||||
Rate48000 = 0,
|
||||
enum class OrbisAudio3dBufferMode : u32 {
|
||||
ORBIS_AUDIO3D_BUFFER_NO_ADVANCE = 0,
|
||||
ORBIS_AUDIO3D_BUFFER_ADVANCE_NO_PUSH = 1,
|
||||
ORBIS_AUDIO3D_BUFFER_ADVANCE_AND_PUSH = 2,
|
||||
};
|
||||
|
||||
enum class OrbisAudio3dBufferMode { NoAdvance = 0, AdvanceNoPush = 1, AdvanceAndPush = 2 };
|
||||
|
||||
enum class OrbisAudio3dBlocking {
|
||||
Async = 0,
|
||||
Sync = 1,
|
||||
};
|
||||
|
||||
enum class OrbisAudio3dPassthrough {
|
||||
None = 0,
|
||||
Left = 1,
|
||||
Right = 2,
|
||||
};
|
||||
|
||||
enum class OrbisAudio3dOutputRoute {
|
||||
Both = 0,
|
||||
HmuOnly = 1,
|
||||
TvOnly = 2,
|
||||
};
|
||||
|
||||
enum class OrbisAudio3dAmbisonics : u32 {
|
||||
None = ~0U,
|
||||
W = 0,
|
||||
X = 1,
|
||||
Y = 2,
|
||||
Z = 3,
|
||||
R = 4,
|
||||
S = 5,
|
||||
T = 6,
|
||||
U = 7,
|
||||
V = 8,
|
||||
K = 9,
|
||||
L = 10,
|
||||
M = 11,
|
||||
N = 12,
|
||||
O = 13,
|
||||
P = 14,
|
||||
Q = 15
|
||||
};
|
||||
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributePcm = 0x00000001;
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributePriority = 0x00000002;
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributePosition = 0x00000003;
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeSpread = 0x00000004;
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeGain = 0x00000005;
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributePassthrough = 0x00000006;
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeResetState = 0x00000007;
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeApplicationSpecific = 0x00000008;
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeAmbisonics = 0x00000009;
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeRestricted = 0x0000000A;
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeOutputRoute = 0x0000000B;
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeLateReverbLevel = 0x00010001;
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeDownmixSpreadRadius = 0x00010002;
|
||||
static const OrbisAudio3dAttributeId s_sceAudio3dAttributeDownmixSpreadHeightAware = 0x00010003;
|
||||
|
||||
struct OrbisAudio3dSpeakerArray;
|
||||
using OrbisAudio3dSpeakerArrayHandle = OrbisAudio3dSpeakerArray*; // head
|
||||
|
||||
struct OrbisAudio3dOpenParameters {
|
||||
size_t size_this;
|
||||
u64 size_this;
|
||||
u32 granularity;
|
||||
OrbisAudio3dRate rate;
|
||||
u32 max_objects;
|
||||
u32 queue_depth;
|
||||
OrbisAudio3dBufferMode buffer_mode;
|
||||
char padding[32];
|
||||
int : 32;
|
||||
u32 num_beds;
|
||||
};
|
||||
|
||||
struct OrbisAudio3dAttribute {
|
||||
OrbisAudio3dAttributeId attribute_id;
|
||||
char padding[32];
|
||||
const void* p_value;
|
||||
size_t value;
|
||||
enum class OrbisAudio3dFormat : u32 {
|
||||
ORBIS_AUDIO3D_FORMAT_S16 = 0,
|
||||
ORBIS_AUDIO3D_FORMAT_FLOAT = 1,
|
||||
};
|
||||
|
||||
struct OrbisAudio3dPosition {
|
||||
float fX;
|
||||
float fY;
|
||||
float fZ;
|
||||
enum class OrbisAudio3dOutputRoute : u32 {
|
||||
ORBIS_AUDIO3D_OUTPUT_BOTH = 0,
|
||||
ORBIS_AUDIO3D_OUTPUT_HMU_ONLY = 1,
|
||||
ORBIS_AUDIO3D_OUTPUT_TV_ONLY = 2,
|
||||
};
|
||||
|
||||
enum class OrbisAudio3dBlocking : u32 {
|
||||
ORBIS_AUDIO3D_BLOCKING_ASYNC = 0,
|
||||
ORBIS_AUDIO3D_BLOCKING_SYNC = 1,
|
||||
};
|
||||
|
||||
struct OrbisAudio3dPcm {
|
||||
OrbisAudio3dFormat format;
|
||||
const void* sample_buffer;
|
||||
void* sample_buffer;
|
||||
u32 num_samples;
|
||||
};
|
||||
|
||||
struct OrbisAudio3dSpeakerArrayParameters {
|
||||
OrbisAudio3dPosition* speaker_position;
|
||||
u32 num_speakers;
|
||||
bool is_3d;
|
||||
void* buffer;
|
||||
size_t size;
|
||||
enum class OrbisAudio3dAttributeId : u32 {
|
||||
ORBIS_AUDIO3D_ATTRIBUTE_PCM = 1,
|
||||
};
|
||||
|
||||
struct OrbisAudio3dApplicationSpecific {
|
||||
size_t size_this;
|
||||
u8 application_specific[32];
|
||||
using OrbisAudio3dPortId = u32;
|
||||
using OrbisAudio3dObjectId = u32;
|
||||
|
||||
struct OrbisAudio3dAttribute {
|
||||
OrbisAudio3dAttributeId attribute_id;
|
||||
int : 32;
|
||||
void* value;
|
||||
u64 value_size;
|
||||
};
|
||||
|
||||
void PS4_SYSV_ABI sceAudio3dGetDefaultOpenParameters(OrbisAudio3dOpenParameters* sParameters);
|
||||
struct AudioData {
|
||||
u8* sample_buffer;
|
||||
u32 num_samples;
|
||||
};
|
||||
|
||||
struct Port {
|
||||
OrbisAudio3dOpenParameters parameters{};
|
||||
std::deque<AudioData> queue; // Only stores PCM buffers for now
|
||||
std::optional<AudioData> current_buffer{};
|
||||
};
|
||||
|
||||
struct Audio3dState {
|
||||
std::unordered_map<OrbisAudio3dPortId, Port> ports;
|
||||
s32 audio_out_handle;
|
||||
};
|
||||
|
||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutClose(s32 handle);
|
||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutOpen(OrbisAudio3dPortId port_id, OrbisUserServiceUserId user_id,
|
||||
s32 type, s32 index, u32 len, u32 freq,
|
||||
AudioOut::OrbisAudioOutParamExtendedInformation param);
|
||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutOutput(s32 handle, void* ptr);
|
||||
s32 PS4_SYSV_ABI sceAudio3dAudioOutOutputs(AudioOut::OrbisAudioOutOutputParam* param, u32 num);
|
||||
s32 PS4_SYSV_ABI sceAudio3dBedWrite(OrbisAudio3dPortId port_id, u32 num_channels,
|
||||
OrbisAudio3dFormat format, void* buffer, u32 num_samples);
|
||||
s32 PS4_SYSV_ABI sceAudio3dBedWrite2(OrbisAudio3dPortId port_id, u32 num_channels,
|
||||
OrbisAudio3dFormat format, void* buffer, u32 num_samples,
|
||||
OrbisAudio3dOutputRoute output_route, bool restricted);
|
||||
s32 PS4_SYSV_ABI sceAudio3dCreateSpeakerArray();
|
||||
s32 PS4_SYSV_ABI sceAudio3dDeleteSpeakerArray();
|
||||
s32 PS4_SYSV_ABI sceAudio3dGetDefaultOpenParameters(OrbisAudio3dOpenParameters* params);
|
||||
s32 PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMemorySize();
|
||||
s32 PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMixCoefficients();
|
||||
s32 PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMixCoefficients2();
|
||||
s32 PS4_SYSV_ABI sceAudio3dInitialize(s64 reserved);
|
||||
s32 PS4_SYSV_ABI sceAudio3dObjectReserve(OrbisAudio3dPortId port_id,
|
||||
OrbisAudio3dObjectId* object_id);
|
||||
s32 PS4_SYSV_ABI sceAudio3dObjectSetAttributes(OrbisAudio3dPortId port_id,
|
||||
OrbisAudio3dObjectId object_id, u64 num_attributes,
|
||||
const OrbisAudio3dAttribute* attribute_array);
|
||||
s32 PS4_SYSV_ABI sceAudio3dObjectUnreserve();
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortAdvance(OrbisAudio3dPortId port_id);
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortClose();
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortCreate();
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortDestroy();
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortFlush();
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortFreeState();
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortGetAttributesSupported();
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortGetList();
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortGetParameters();
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortGetQueueLevel(OrbisAudio3dPortId port_id, u32* queue_level,
|
||||
u32* queue_available);
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortGetState();
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortGetStatus();
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortOpen(OrbisUserServiceUserId user_id,
|
||||
const OrbisAudio3dOpenParameters* parameters,
|
||||
OrbisAudio3dPortId* port_id);
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortPush(OrbisAudio3dPortId port_id, OrbisAudio3dBlocking blocking);
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortQueryDebug();
|
||||
s32 PS4_SYSV_ABI sceAudio3dPortSetAttribute(OrbisAudio3dPortId port_id,
|
||||
OrbisAudio3dAttributeId attribute_id, void* attribute,
|
||||
u64 attribute_size);
|
||||
s32 PS4_SYSV_ABI sceAudio3dReportRegisterHandler();
|
||||
s32 PS4_SYSV_ABI sceAudio3dReportUnregisterHandler();
|
||||
s32 PS4_SYSV_ABI sceAudio3dSetGpuRenderer();
|
||||
s32 PS4_SYSV_ABI sceAudio3dStrError();
|
||||
s32 PS4_SYSV_ABI sceAudio3dTerminate();
|
||||
|
||||
void RegisterlibSceAudio3d(Core::Loader::SymbolsResolver* sym);
|
||||
} // namespace Libraries::Audio3d
|
||||
|
|
|
@ -3,8 +3,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "core/libraries/error_codes.h"
|
||||
|
||||
constexpr int ORBIS_AUDIO3D_ERROR_UNKNOWN = 0x80EA0001;
|
||||
constexpr int ORBIS_AUDIO3D_ERROR_INVALID_PORT = 0x80EA0002;
|
||||
constexpr int ORBIS_AUDIO3D_ERROR_INVALID_OBJECT = 0x80EA0003;
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "audio3d_error.h"
|
||||
#include "audio3d_impl.h"
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/kernel/kernel.h"
|
||||
|
||||
using namespace Libraries::Kernel;
|
||||
|
||||
namespace Libraries::Audio3d {} // namespace Libraries::Audio3d
|
|
@ -1,16 +0,0 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "audio3d.h"
|
||||
|
||||
namespace Libraries::Audio3d {
|
||||
|
||||
class Audio3d {
|
||||
public:
|
||||
private:
|
||||
using OrbisAudio3dPluginId = u32;
|
||||
};
|
||||
|
||||
} // namespace Libraries::Audio3d
|
|
@ -2804,7 +2804,7 @@ void RegisterlibSceGnmDriver(Core::Loader::SymbolsResolver* sym) {
|
|||
liverpool = std::make_unique<AmdGpu::Liverpool>();
|
||||
presenter = std::make_unique<Vulkan::Presenter>(*g_window, liverpool.get());
|
||||
|
||||
const int result = sceKernelGetCompiledSdkVersion(&sdk_version);
|
||||
const s32 result = sceKernelGetCompiledSdkVersion(&sdk_version);
|
||||
if (result != ORBIS_OK) {
|
||||
sdk_version = 0;
|
||||
}
|
||||
|
|
|
@ -190,16 +190,16 @@ s32 PS4_SYSV_ABI sceKernelOpen(const char* path, s32 flags, /* SceKernelMode*/ u
|
|||
}
|
||||
|
||||
s32 PS4_SYSV_ABI close(s32 fd) {
|
||||
if (fd < 3) {
|
||||
// This is technically possible, but it's usually caused by some stubbed function instead.
|
||||
LOG_WARNING(Kernel_Fs, "called on an std handle, fd = {}", fd);
|
||||
}
|
||||
auto* h = Common::Singleton<Core::FileSys::HandleTable>::Instance();
|
||||
auto* file = h->GetFile(fd);
|
||||
if (file == nullptr) {
|
||||
*__Error() = POSIX_EBADF;
|
||||
return -1;
|
||||
}
|
||||
if (fd < 3) {
|
||||
// This is technically possible, but it's usually caused by some stubbed function instead.
|
||||
LOG_WARNING(Kernel_Fs, "called on an std handle, fd = {}", fd);
|
||||
}
|
||||
if (file->type == Core::FileSys::FileType::Regular) {
|
||||
file->f.Close();
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
namespace Libraries::Kernel {
|
||||
|
||||
u64 PS4_SYSV_ABI sceKernelGetDirectMemorySize() {
|
||||
LOG_WARNING(Kernel_Vmm, "called");
|
||||
LOG_TRACE(Kernel_Vmm, "called");
|
||||
const auto* memory = Core::Memory::Instance();
|
||||
return memory->GetTotalDirectSize();
|
||||
}
|
||||
|
@ -106,12 +106,6 @@ s32 PS4_SYSV_ABI sceKernelAvailableDirectMemorySize(u64 searchStart, u64 searchE
|
|||
if (physAddrOut == nullptr || sizeOut == nullptr) {
|
||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
if (searchEnd > sceKernelGetDirectMemorySize()) {
|
||||
return ORBIS_KERNEL_ERROR_EINVAL;
|
||||
}
|
||||
if (searchEnd <= searchStart) {
|
||||
return ORBIS_KERNEL_ERROR_ENOMEM;
|
||||
}
|
||||
|
||||
auto* memory = Core::Memory::Instance();
|
||||
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
#include "core/libraries/network/netctl.h"
|
||||
#include "core/libraries/network/ssl.h"
|
||||
#include "core/libraries/network/ssl2.h"
|
||||
#include "core/libraries/np_auth/np_auth.h"
|
||||
#include "core/libraries/np_common/np_common.h"
|
||||
#include "core/libraries/np_manager/np_manager.h"
|
||||
#include "core/libraries/np_party/np_party.h"
|
||||
|
@ -50,6 +51,7 @@
|
|||
#include "core/libraries/system/sysmodule.h"
|
||||
#include "core/libraries/system/systemservice.h"
|
||||
#include "core/libraries/system/userservice.h"
|
||||
#include "core/libraries/ulobjmgr/ulobjmgr.h"
|
||||
#include "core/libraries/usbd/usbd.h"
|
||||
#include "core/libraries/videodec/videodec.h"
|
||||
#include "core/libraries/videodec/videodec2.h"
|
||||
|
@ -87,6 +89,7 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) {
|
|||
Libraries::NpScore::RegisterlibSceNpScore(sym);
|
||||
Libraries::NpTrophy::RegisterlibSceNpTrophy(sym);
|
||||
Libraries::NpWebApi::RegisterlibSceNpWebApi(sym);
|
||||
Libraries::NpAuth::RegisterlibSceNpAuth(sym);
|
||||
Libraries::ScreenShot::RegisterlibSceScreenShot(sym);
|
||||
Libraries::AppContent::RegisterlibSceAppContent(sym);
|
||||
Libraries::PngDec::RegisterlibScePngDec(sym);
|
||||
|
@ -116,6 +119,7 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) {
|
|||
Libraries::Zlib::RegisterlibSceZlib(sym);
|
||||
Libraries::Hmd::RegisterlibSceHmd(sym);
|
||||
Libraries::DiscMap::RegisterlibSceDiscMap(sym);
|
||||
Libraries::Ulobjmgr::RegisterlibSceUlobjmgr(sym);
|
||||
}
|
||||
|
||||
} // namespace Libraries
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
namespace Libraries::Move {
|
||||
|
||||
int PS4_SYSV_ABI sceMoveOpen() {
|
||||
LOG_ERROR(Lib_Move, "(STUBBED) called");
|
||||
LOG_TRACE(Lib_Move, "(STUBBED) called");
|
||||
return ORBIS_FAIL;
|
||||
}
|
||||
|
||||
|
@ -18,6 +18,11 @@ int PS4_SYSV_ABI sceMoveGetDeviceInfo() {
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceMoveReadStateLatest() {
|
||||
LOG_TRACE(Lib_Move, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceMoveReadStateRecent() {
|
||||
LOG_TRACE(Lib_Move, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
|
@ -36,6 +41,7 @@ int PS4_SYSV_ABI sceMoveInit() {
|
|||
void RegisterlibSceMove(Core::Loader::SymbolsResolver* sym) {
|
||||
LIB_FUNCTION("HzC60MfjJxU", "libSceMove", 1, "libSceMove", 1, 1, sceMoveOpen);
|
||||
LIB_FUNCTION("GWXTyxs4QbE", "libSceMove", 1, "libSceMove", 1, 1, sceMoveGetDeviceInfo);
|
||||
LIB_FUNCTION("ttU+JOhShl4", "libSceMove", 1, "libSceMove", 1, 1, sceMoveReadStateLatest);
|
||||
LIB_FUNCTION("f2bcpK6kJfg", "libSceMove", 1, "libSceMove", 1, 1, sceMoveReadStateRecent);
|
||||
LIB_FUNCTION("tsZi60H4ypY", "libSceMove", 1, "libSceMove", 1, 1, sceMoveTerm);
|
||||
LIB_FUNCTION("j1ITE-EoJmE", "libSceMove", 1, "libSceMove", 1, 1, sceMoveInit);
|
||||
|
|
|
@ -18,36 +18,32 @@ namespace Libraries::Ngs2 {
|
|||
|
||||
s32 PS4_SYSV_ABI sceNgs2CalcWaveformBlock(const OrbisNgs2WaveformFormat* format, u32 samplePos,
|
||||
u32 numSamples, OrbisNgs2WaveformBlock* outBlock) {
|
||||
LOG_INFO(Lib_Ngs2, "samplePos = {}, numSamples = {}", samplePos, numSamples);
|
||||
LOG_ERROR(Lib_Ngs2, "samplePos = {}, numSamples = {}", samplePos, numSamples);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2GetWaveformFrameInfo(const OrbisNgs2WaveformFormat* format,
|
||||
u32* outFrameSize, u32* outNumFrameSamples,
|
||||
u32* outUnitsPerFrame, u32* outNumDelaySamples) {
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
LOG_ERROR(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2ParseWaveformData(const void* data, size_t dataSize,
|
||||
OrbisNgs2WaveformInfo* outInfo) {
|
||||
LOG_INFO(Lib_Ngs2, "dataSize = {}", dataSize);
|
||||
LOG_ERROR(Lib_Ngs2, "dataSize = {}", dataSize);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2ParseWaveformFile(const char* path, u64 offset,
|
||||
OrbisNgs2WaveformInfo* outInfo) {
|
||||
LOG_INFO(Lib_Ngs2, "path = {}, offset = {}", path, offset);
|
||||
LOG_ERROR(Lib_Ngs2, "path = {}, offset = {}", path, offset);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2ParseWaveformUser(OrbisNgs2ParseReadHandler handler, uintptr_t userData,
|
||||
OrbisNgs2WaveformInfo* outInfo) {
|
||||
LOG_INFO(Lib_Ngs2, "userData = {}", userData);
|
||||
if (!handler) {
|
||||
LOG_ERROR(Lib_Ngs2, "handler is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_HANDLE;
|
||||
}
|
||||
LOG_ERROR(Lib_Ngs2, "userData = {}", userData);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
|
@ -55,7 +51,7 @@ s32 PS4_SYSV_ABI sceNgs2RackCreate(OrbisNgs2Handle systemHandle, u32 rackId,
|
|||
const OrbisNgs2RackOption* option,
|
||||
const OrbisNgs2ContextBufferInfo* bufferInfo,
|
||||
OrbisNgs2Handle* outHandle) {
|
||||
LOG_INFO(Lib_Ngs2, "rackId = {}", rackId);
|
||||
LOG_ERROR(Lib_Ngs2, "rackId = {}", rackId);
|
||||
if (!systemHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE;
|
||||
|
@ -67,7 +63,7 @@ s32 PS4_SYSV_ABI sceNgs2RackCreateWithAllocator(OrbisNgs2Handle systemHandle, u3
|
|||
const OrbisNgs2RackOption* option,
|
||||
const OrbisNgs2BufferAllocator* allocator,
|
||||
OrbisNgs2Handle* outHandle) {
|
||||
LOG_INFO(Lib_Ngs2, "rackId = {}", rackId);
|
||||
LOG_ERROR(Lib_Ngs2, "rackId = {}", rackId);
|
||||
if (!systemHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE;
|
||||
|
@ -77,73 +73,45 @@ s32 PS4_SYSV_ABI sceNgs2RackCreateWithAllocator(OrbisNgs2Handle systemHandle, u3
|
|||
|
||||
s32 PS4_SYSV_ABI sceNgs2RackDestroy(OrbisNgs2Handle rackHandle,
|
||||
OrbisNgs2ContextBufferInfo* outBufferInfo) {
|
||||
if (!rackHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "rackHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE;
|
||||
}
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
LOG_ERROR(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2RackGetInfo(OrbisNgs2Handle rackHandle, OrbisNgs2RackInfo* outInfo,
|
||||
size_t infoSize) {
|
||||
LOG_INFO(Lib_Ngs2, "infoSize = {}", infoSize);
|
||||
if (!rackHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "rackHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE;
|
||||
}
|
||||
LOG_ERROR(Lib_Ngs2, "infoSize = {}", infoSize);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2RackGetUserData(OrbisNgs2Handle rackHandle, uintptr_t* outUserData) {
|
||||
if (!rackHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "rackHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE;
|
||||
}
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
LOG_ERROR(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2RackGetVoiceHandle(OrbisNgs2Handle rackHandle, u32 voiceIndex,
|
||||
OrbisNgs2Handle* outHandle) {
|
||||
LOG_INFO(Lib_Ngs2, "voiceIndex = {}", voiceIndex);
|
||||
if (!rackHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "rackHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE;
|
||||
}
|
||||
LOG_DEBUG(Lib_Ngs2, "(STUBBED) voiceIndex = {}", voiceIndex);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2RackLock(OrbisNgs2Handle rackHandle) {
|
||||
if (!rackHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "rackHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE;
|
||||
}
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
LOG_ERROR(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2RackQueryBufferSize(u32 rackId, const OrbisNgs2RackOption* option,
|
||||
OrbisNgs2ContextBufferInfo* outBufferInfo) {
|
||||
LOG_INFO(Lib_Ngs2, "rackId = {}", rackId);
|
||||
LOG_ERROR(Lib_Ngs2, "rackId = {}", rackId);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2RackSetUserData(OrbisNgs2Handle rackHandle, uintptr_t userData) {
|
||||
LOG_INFO(Lib_Ngs2, "userData = {}", userData);
|
||||
if (!rackHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "rackHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE;
|
||||
}
|
||||
LOG_ERROR(Lib_Ngs2, "userData = {}", userData);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2RackUnlock(OrbisNgs2Handle rackHandle) {
|
||||
if (!rackHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "rackHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE;
|
||||
}
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
LOG_ERROR(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
|
@ -188,17 +156,17 @@ s32 PS4_SYSV_ABI sceNgs2SystemCreateWithAllocator(const OrbisNgs2SystemOption* o
|
|||
OrbisNgs2BufferAllocHandler hostAlloc = allocator->allocHandler;
|
||||
if (outHandle) {
|
||||
OrbisNgs2BufferFreeHandler hostFree = allocator->freeHandler;
|
||||
OrbisNgs2ContextBufferInfo* bufferInfo = 0;
|
||||
result = SystemSetup(option, bufferInfo, 0, 0);
|
||||
OrbisNgs2ContextBufferInfo bufferInfo;
|
||||
result = SystemSetup(option, &bufferInfo, 0, 0);
|
||||
if (result >= 0) {
|
||||
uintptr_t sysUserData = allocator->userData;
|
||||
result = hostAlloc(bufferInfo);
|
||||
result = Core::ExecuteGuest(hostAlloc, &bufferInfo);
|
||||
if (result >= 0) {
|
||||
OrbisNgs2Handle* handleCopy = outHandle;
|
||||
result = SystemSetup(option, bufferInfo, hostFree, handleCopy);
|
||||
result = SystemSetup(option, &bufferInfo, hostFree, handleCopy);
|
||||
if (result < 0) {
|
||||
if (hostFree) {
|
||||
hostFree(bufferInfo);
|
||||
Core::ExecuteGuest(hostFree, &bufferInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -226,13 +194,13 @@ s32 PS4_SYSV_ABI sceNgs2SystemDestroy(OrbisNgs2Handle systemHandle,
|
|||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2SystemEnumHandles(OrbisNgs2Handle* aOutHandle, u32 maxHandles) {
|
||||
LOG_INFO(Lib_Ngs2, "maxHandles = {}", maxHandles);
|
||||
LOG_ERROR(Lib_Ngs2, "maxHandles = {}", maxHandles);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2SystemEnumRackHandles(OrbisNgs2Handle systemHandle,
|
||||
OrbisNgs2Handle* aOutHandle, u32 maxHandles) {
|
||||
LOG_INFO(Lib_Ngs2, "maxHandles = {}", maxHandles);
|
||||
LOG_ERROR(Lib_Ngs2, "maxHandles = {}", maxHandles);
|
||||
if (!systemHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE;
|
||||
|
@ -242,11 +210,7 @@ s32 PS4_SYSV_ABI sceNgs2SystemEnumRackHandles(OrbisNgs2Handle systemHandle,
|
|||
|
||||
s32 PS4_SYSV_ABI sceNgs2SystemGetInfo(OrbisNgs2Handle rackHandle, OrbisNgs2SystemInfo* outInfo,
|
||||
size_t infoSize) {
|
||||
LOG_INFO(Lib_Ngs2, "infoSize = {}", infoSize);
|
||||
if (!rackHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "rackHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE;
|
||||
}
|
||||
LOG_ERROR(Lib_Ngs2, "infoSize = {}", infoSize);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
|
@ -255,7 +219,7 @@ s32 PS4_SYSV_ABI sceNgs2SystemGetUserData(OrbisNgs2Handle systemHandle, uintptr_
|
|||
LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE;
|
||||
}
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
LOG_ERROR(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
|
@ -264,7 +228,7 @@ s32 PS4_SYSV_ABI sceNgs2SystemLock(OrbisNgs2Handle systemHandle) {
|
|||
LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE;
|
||||
}
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
LOG_ERROR(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
|
@ -285,7 +249,7 @@ s32 PS4_SYSV_ABI sceNgs2SystemQueryBufferSize(const OrbisNgs2SystemOption* optio
|
|||
s32 PS4_SYSV_ABI sceNgs2SystemRender(OrbisNgs2Handle systemHandle,
|
||||
const OrbisNgs2RenderBufferInfo* aBufferInfo,
|
||||
u32 numBufferInfo) {
|
||||
LOG_INFO(Lib_Ngs2, "numBufferInfo = {}", numBufferInfo);
|
||||
LOG_DEBUG(Lib_Ngs2, "(STUBBED) numBufferInfo = {}", numBufferInfo);
|
||||
if (!systemHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE;
|
||||
|
@ -308,7 +272,7 @@ static s32 PS4_SYSV_ABI sceNgs2SystemResetOption(OrbisNgs2SystemOption* outOptio
|
|||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2SystemSetGrainSamples(OrbisNgs2Handle systemHandle, u32 numSamples) {
|
||||
LOG_INFO(Lib_Ngs2, "numSamples = {}", numSamples);
|
||||
LOG_ERROR(Lib_Ngs2, "numSamples = {}", numSamples);
|
||||
if (!systemHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE;
|
||||
|
@ -317,7 +281,7 @@ s32 PS4_SYSV_ABI sceNgs2SystemSetGrainSamples(OrbisNgs2Handle systemHandle, u32
|
|||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2SystemSetSampleRate(OrbisNgs2Handle systemHandle, u32 sampleRate) {
|
||||
LOG_INFO(Lib_Ngs2, "sampleRate = {}", sampleRate);
|
||||
LOG_ERROR(Lib_Ngs2, "sampleRate = {}", sampleRate);
|
||||
if (!systemHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE;
|
||||
|
@ -326,7 +290,7 @@ s32 PS4_SYSV_ABI sceNgs2SystemSetSampleRate(OrbisNgs2Handle systemHandle, u32 sa
|
|||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2SystemSetUserData(OrbisNgs2Handle systemHandle, uintptr_t userData) {
|
||||
LOG_INFO(Lib_Ngs2, "userData = {}", userData);
|
||||
LOG_ERROR(Lib_Ngs2, "userData = {}", userData);
|
||||
if (!systemHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE;
|
||||
|
@ -339,66 +303,42 @@ s32 PS4_SYSV_ABI sceNgs2SystemUnlock(OrbisNgs2Handle systemHandle) {
|
|||
LOG_ERROR(Lib_Ngs2, "systemHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_SYSTEM_HANDLE;
|
||||
}
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
LOG_ERROR(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2VoiceControl(OrbisNgs2Handle voiceHandle,
|
||||
const OrbisNgs2VoiceParamHeader* paramList) {
|
||||
if (!voiceHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "voiceHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_VOICE_HANDLE;
|
||||
}
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
LOG_ERROR(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2VoiceGetMatrixInfo(OrbisNgs2Handle voiceHandle, u32 matrixId,
|
||||
OrbisNgs2VoiceMatrixInfo* outInfo, size_t outInfoSize) {
|
||||
LOG_INFO(Lib_Ngs2, "matrixId = {}, outInfoSize = {}", matrixId, outInfoSize);
|
||||
if (!voiceHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "voiceHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_VOICE_HANDLE;
|
||||
}
|
||||
LOG_ERROR(Lib_Ngs2, "matrixId = {}, outInfoSize = {}", matrixId, outInfoSize);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2VoiceGetOwner(OrbisNgs2Handle voiceHandle, OrbisNgs2Handle* outRackHandle,
|
||||
u32* outVoiceId) {
|
||||
if (!voiceHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "voiceHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_VOICE_HANDLE;
|
||||
}
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
LOG_ERROR(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2VoiceGetPortInfo(OrbisNgs2Handle voiceHandle, u32 port,
|
||||
OrbisNgs2VoicePortInfo* outInfo, size_t outInfoSize) {
|
||||
LOG_INFO(Lib_Ngs2, "port = {}, outInfoSize = {}", port, outInfoSize);
|
||||
if (!voiceHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "voiceHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_VOICE_HANDLE;
|
||||
}
|
||||
LOG_ERROR(Lib_Ngs2, "port = {}, outInfoSize = {}", port, outInfoSize);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2VoiceGetState(OrbisNgs2Handle voiceHandle, OrbisNgs2VoiceState* outState,
|
||||
size_t stateSize) {
|
||||
LOG_INFO(Lib_Ngs2, "stateSize = {}", stateSize);
|
||||
if (!voiceHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "voiceHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_VOICE_HANDLE;
|
||||
}
|
||||
LOG_ERROR(Lib_Ngs2, "stateSize = {}", stateSize);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2VoiceGetStateFlags(OrbisNgs2Handle voiceHandle, u32* outStateFlags) {
|
||||
if (!voiceHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "voiceHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_VOICE_HANDLE;
|
||||
}
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
LOG_ERROR(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
|
@ -407,36 +347,32 @@ s32 PS4_SYSV_ABI sceNgs2VoiceGetStateFlags(OrbisNgs2Handle voiceHandle, u32* out
|
|||
s32 PS4_SYSV_ABI sceNgs2CustomRackGetModuleInfo(OrbisNgs2Handle rackHandle, u32 moduleIndex,
|
||||
OrbisNgs2CustomModuleInfo* outInfo,
|
||||
size_t infoSize) {
|
||||
LOG_INFO(Lib_Ngs2, "moduleIndex = {}, infoSize = {}", moduleIndex, infoSize);
|
||||
if (!rackHandle) {
|
||||
LOG_ERROR(Lib_Ngs2, "rackHandle is nullptr");
|
||||
return ORBIS_NGS2_ERROR_INVALID_RACK_HANDLE;
|
||||
}
|
||||
LOG_ERROR(Lib_Ngs2, "moduleIndex = {}, infoSize = {}", moduleIndex, infoSize);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
// Ngs2Geom
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2GeomResetListenerParam(OrbisNgs2GeomListenerParam* outListenerParam) {
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
LOG_ERROR(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2GeomResetSourceParam(OrbisNgs2GeomSourceParam* outSourceParam) {
|
||||
LOG_INFO(Lib_Ngs2, "called");
|
||||
LOG_ERROR(Lib_Ngs2, "called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2GeomCalcListener(const OrbisNgs2GeomListenerParam* param,
|
||||
OrbisNgs2GeomListenerWork* outWork, u32 flags) {
|
||||
LOG_INFO(Lib_Ngs2, "flags = {}", flags);
|
||||
LOG_ERROR(Lib_Ngs2, "flags = {}", flags);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2GeomApply(const OrbisNgs2GeomListenerWork* listener,
|
||||
const OrbisNgs2GeomSourceParam* source,
|
||||
OrbisNgs2GeomAttribute* outAttrib, u32 flags) {
|
||||
LOG_INFO(Lib_Ngs2, "flags = {}", flags);
|
||||
LOG_ERROR(Lib_Ngs2, "flags = {}", flags);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
|
@ -444,15 +380,15 @@ s32 PS4_SYSV_ABI sceNgs2GeomApply(const OrbisNgs2GeomListenerWork* listener,
|
|||
|
||||
s32 PS4_SYSV_ABI sceNgs2PanInit(OrbisNgs2PanWork* work, const float* aSpeakerAngle, float unitAngle,
|
||||
u32 numSpeakers) {
|
||||
LOG_INFO(Lib_Ngs2, "aSpeakerAngle = {}, unitAngle = {}, numSpeakers = {}", *aSpeakerAngle,
|
||||
unitAngle, numSpeakers);
|
||||
LOG_ERROR(Lib_Ngs2, "aSpeakerAngle = {}, unitAngle = {}, numSpeakers = {}", *aSpeakerAngle,
|
||||
unitAngle, numSpeakers);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNgs2PanGetVolumeMatrix(OrbisNgs2PanWork* work, const OrbisNgs2PanParam* aParam,
|
||||
u32 numParams, u32 matrixFormat,
|
||||
float* outVolumeMatrix) {
|
||||
LOG_INFO(Lib_Ngs2, "numParams = {}, matrixFormat = {}", numParams, matrixFormat);
|
||||
LOG_ERROR(Lib_Ngs2, "numParams = {}, matrixFormat = {}", numParams, matrixFormat);
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,8 @@ class SymbolsResolver;
|
|||
|
||||
namespace Libraries::Ngs2 {
|
||||
|
||||
typedef s32 (*OrbisNgs2ParseReadHandler)(uintptr_t userData, u32 offset, void* data, size_t size);
|
||||
using OrbisNgs2ParseReadHandler = s32 PS4_SYSV_ABI (*)(uintptr_t user_data, u32 offset, void* data,
|
||||
size_t size);
|
||||
|
||||
enum class OrbisNgs2HandleType : u32 {
|
||||
Invalid = 0,
|
||||
|
@ -90,7 +91,7 @@ struct OrbisNgs2UserFxProcessContext {
|
|||
u32 sampleRate;
|
||||
};
|
||||
|
||||
typedef s32 (*OrbisNgs2UserFxProcessHandler)(OrbisNgs2UserFxProcessContext* context);
|
||||
using OrbisNgs2UserFxProcessHandler = s32 PS4_SYSV_ABI (*)(OrbisNgs2UserFxProcessContext* context);
|
||||
|
||||
struct OrbisNgs2UserFx2SetupContext {
|
||||
void* common;
|
||||
|
@ -102,7 +103,7 @@ struct OrbisNgs2UserFx2SetupContext {
|
|||
u64 reserved[4];
|
||||
};
|
||||
|
||||
typedef s32 (*OrbisNgs2UserFx2SetupHandler)(OrbisNgs2UserFx2SetupContext* context);
|
||||
using OrbisNgs2UserFx2SetupHandler = s32 PS4_SYSV_ABI (*)(OrbisNgs2UserFx2SetupContext* context);
|
||||
|
||||
struct OrbisNgs2UserFx2CleanupContext {
|
||||
void* common;
|
||||
|
@ -114,7 +115,8 @@ struct OrbisNgs2UserFx2CleanupContext {
|
|||
u64 reserved[4];
|
||||
};
|
||||
|
||||
typedef s32 (*OrbisNgs2UserFx2CleanupHandler)(OrbisNgs2UserFx2CleanupContext* context);
|
||||
using OrbisNgs2UserFx2CleanupHandler =
|
||||
s32 PS4_SYSV_ABI (*)(OrbisNgs2UserFx2CleanupContext* context);
|
||||
|
||||
struct OrbisNgs2UserFx2ControlContext {
|
||||
const void* data;
|
||||
|
@ -125,7 +127,8 @@ struct OrbisNgs2UserFx2ControlContext {
|
|||
u64 reserved[4];
|
||||
};
|
||||
|
||||
typedef s32 (*OrbisNgs2UserFx2ControlHandler)(OrbisNgs2UserFx2ControlContext* context);
|
||||
using OrbisNgs2UserFx2ControlHandler =
|
||||
s32 PS4_SYSV_ABI (*)(OrbisNgs2UserFx2ControlContext* context);
|
||||
|
||||
struct OrbisNgs2UserFx2ProcessContext {
|
||||
float** aChannelData;
|
||||
|
@ -143,7 +146,8 @@ struct OrbisNgs2UserFx2ProcessContext {
|
|||
u64 reserved2[4];
|
||||
};
|
||||
|
||||
typedef s32 (*OrbisNgs2UserFx2ProcessHandler)(OrbisNgs2UserFx2ProcessContext* context);
|
||||
using OrbisNgs2UserFx2ProcessHandler =
|
||||
s32 PS4_SYSV_ABI (*)(OrbisNgs2UserFx2ProcessContext* context);
|
||||
|
||||
struct OrbisNgs2BufferAllocator {
|
||||
OrbisNgs2BufferAllocHandler allocHandler;
|
||||
|
@ -237,7 +241,7 @@ struct OrbisNgs2VoiceCallbackInfo {
|
|||
} param;
|
||||
};
|
||||
|
||||
typedef void (*OrbisNgs2VoiceCallbackHandler)(const OrbisNgs2VoiceCallbackInfo* info);
|
||||
using OrbisNgs2VoiceCallbackHandler = void PS4_SYSV_ABI (*)(const OrbisNgs2VoiceCallbackInfo* info);
|
||||
|
||||
struct OrbisNgs2VoiceCallbackParam {
|
||||
OrbisNgs2VoiceParamHeader header;
|
||||
|
|
|
@ -30,8 +30,9 @@ struct OrbisNgs2SystemOption {
|
|||
u32 aReserved[6];
|
||||
};
|
||||
|
||||
typedef s32 (*OrbisNgs2BufferAllocHandler)(OrbisNgs2ContextBufferInfo* ioBufferInfo);
|
||||
typedef s32 (*OrbisNgs2BufferFreeHandler)(OrbisNgs2ContextBufferInfo* ioBufferInfo);
|
||||
using OrbisNgs2BufferAllocHandler =
|
||||
s32 PS4_SYSV_ABI (*)(OrbisNgs2ContextBufferInfo* io_buffer_info);
|
||||
using OrbisNgs2BufferFreeHandler = s32 PS4_SYSV_ABI (*)(OrbisNgs2ContextBufferInfo* io_buffer_info);
|
||||
|
||||
struct OrbisNgs2SystemInfo {
|
||||
char name[ORBIS_NGS2_SYSTEM_NAME_LENGTH]; // 0
|
||||
|
|
|
@ -18,7 +18,8 @@ struct OrbisNgs2ReportDataHeader {
|
|||
s32 result;
|
||||
};
|
||||
|
||||
typedef void (*OrbisNgs2ReportHandler)(const OrbisNgs2ReportDataHeader* data, uintptr_t userData);
|
||||
using OrbisNgs2ReportHandler = void PS4_SYSV_ABI (*)(const OrbisNgs2ReportDataHeader* data,
|
||||
uintptr_t user_data);
|
||||
|
||||
struct OrbisNgs2ReportMessageData {
|
||||
OrbisNgs2ReportDataHeader header;
|
||||
|
|
99
src/core/libraries/np_auth/np_auth.cpp
Normal file
|
@ -0,0 +1,99 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/libs.h"
|
||||
#include "core/libraries/np_auth/np_auth.h"
|
||||
|
||||
namespace Libraries::NpAuth {
|
||||
|
||||
s32 PS4_SYSV_ABI sceNpAuthGetAuthorizationCode() {
|
||||
LOG_ERROR(Lib_NpAuth, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNpAuthGetIdToken() {
|
||||
LOG_ERROR(Lib_NpAuth, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNpAuthAbortRequest() {
|
||||
LOG_ERROR(Lib_NpAuth, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNpAuthCreateAsyncRequest() {
|
||||
LOG_ERROR(Lib_NpAuth, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNpAuthCreateRequest() {
|
||||
LOG_WARNING(Lib_NpAuth, "(DUMMY) called");
|
||||
return 1;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNpAuthDeleteRequest(s32 id) {
|
||||
LOG_WARNING(Lib_NpAuth, "(DUMMY) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNpAuthGetAuthorizationCodeA() {
|
||||
LOG_ERROR(Lib_NpAuth, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNpAuthGetAuthorizationCodeV3() {
|
||||
LOG_ERROR(Lib_NpAuth, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNpAuthGetIdTokenA() {
|
||||
LOG_ERROR(Lib_NpAuth, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNpAuthGetIdTokenV3() {
|
||||
LOG_ERROR(Lib_NpAuth, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNpAuthPollAsync() {
|
||||
LOG_ERROR(Lib_NpAuth, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNpAuthSetTimeout() {
|
||||
LOG_ERROR(Lib_NpAuth, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceNpAuthWaitAsync() {
|
||||
LOG_ERROR(Lib_NpAuth, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
void RegisterlibSceNpAuth(Core::Loader::SymbolsResolver* sym) {
|
||||
LIB_FUNCTION("KxGkOrQJTqY", "libSceNpAuthCompat", 1, "libSceNpAuth", 1, 1,
|
||||
sceNpAuthGetAuthorizationCode);
|
||||
LIB_FUNCTION("uaB-LoJqHis", "libSceNpAuthCompat", 1, "libSceNpAuth", 1, 1, sceNpAuthGetIdToken);
|
||||
LIB_FUNCTION("cE7wIsqXdZ8", "libSceNpAuth", 1, "libSceNpAuth", 1, 1, sceNpAuthAbortRequest);
|
||||
LIB_FUNCTION("N+mr7GjTvr8", "libSceNpAuth", 1, "libSceNpAuth", 1, 1,
|
||||
sceNpAuthCreateAsyncRequest);
|
||||
LIB_FUNCTION("6bwFkosYRQg", "libSceNpAuth", 1, "libSceNpAuth", 1, 1, sceNpAuthCreateRequest);
|
||||
LIB_FUNCTION("H8wG9Bk-nPc", "libSceNpAuth", 1, "libSceNpAuth", 1, 1, sceNpAuthDeleteRequest);
|
||||
LIB_FUNCTION("KxGkOrQJTqY", "libSceNpAuth", 1, "libSceNpAuth", 1, 1,
|
||||
sceNpAuthGetAuthorizationCode);
|
||||
LIB_FUNCTION("qAUXQ9GdWp8", "libSceNpAuth", 1, "libSceNpAuth", 1, 1,
|
||||
sceNpAuthGetAuthorizationCodeA);
|
||||
LIB_FUNCTION("KI4dHLlTNl0", "libSceNpAuth", 1, "libSceNpAuth", 1, 1,
|
||||
sceNpAuthGetAuthorizationCodeV3);
|
||||
LIB_FUNCTION("uaB-LoJqHis", "libSceNpAuth", 1, "libSceNpAuth", 1, 1, sceNpAuthGetIdToken);
|
||||
LIB_FUNCTION("CocbHVIKPE8", "libSceNpAuth", 1, "libSceNpAuth", 1, 1, sceNpAuthGetIdTokenA);
|
||||
LIB_FUNCTION("RdsFVsgSpZY", "libSceNpAuth", 1, "libSceNpAuth", 1, 1, sceNpAuthGetIdTokenV3);
|
||||
LIB_FUNCTION("gjSyfzSsDcE", "libSceNpAuth", 1, "libSceNpAuth", 1, 1, sceNpAuthPollAsync);
|
||||
LIB_FUNCTION("PM3IZCw-7m0", "libSceNpAuth", 1, "libSceNpAuth", 1, 1, sceNpAuthSetTimeout);
|
||||
LIB_FUNCTION("SK-S7daqJSE", "libSceNpAuth", 1, "libSceNpAuth", 1, 1, sceNpAuthWaitAsync);
|
||||
};
|
||||
|
||||
} // namespace Libraries::NpAuth
|
29
src/core/libraries/np_auth/np_auth.h
Normal file
|
@ -0,0 +1,29 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.h"
|
||||
|
||||
namespace Core::Loader {
|
||||
class SymbolsResolver;
|
||||
}
|
||||
|
||||
namespace Libraries::NpAuth {
|
||||
|
||||
s32 PS4_SYSV_ABI sceNpAuthGetAuthorizationCode();
|
||||
s32 PS4_SYSV_ABI sceNpAuthGetIdToken();
|
||||
s32 PS4_SYSV_ABI sceNpAuthAbortRequest();
|
||||
s32 PS4_SYSV_ABI sceNpAuthCreateAsyncRequest();
|
||||
s32 PS4_SYSV_ABI sceNpAuthCreateRequest();
|
||||
s32 PS4_SYSV_ABI sceNpAuthDeleteRequest(s32 id);
|
||||
s32 PS4_SYSV_ABI sceNpAuthGetAuthorizationCodeA();
|
||||
s32 PS4_SYSV_ABI sceNpAuthGetAuthorizationCodeV3();
|
||||
s32 PS4_SYSV_ABI sceNpAuthGetIdTokenA();
|
||||
s32 PS4_SYSV_ABI sceNpAuthGetIdTokenV3();
|
||||
s32 PS4_SYSV_ABI sceNpAuthPollAsync();
|
||||
s32 PS4_SYSV_ABI sceNpAuthSetTimeout();
|
||||
s32 PS4_SYSV_ABI sceNpAuthWaitAsync();
|
||||
|
||||
void RegisterlibSceNpAuth(Core::Loader::SymbolsResolver* sym);
|
||||
} // namespace Libraries::NpAuth
|
|
@ -250,7 +250,6 @@ int PS4_SYSV_ABI scePadMbusTerm() {
|
|||
}
|
||||
|
||||
int PS4_SYSV_ABI scePadOpen(s32 userId, s32 type, s32 index, const OrbisPadOpenParam* pParam) {
|
||||
LOG_INFO(Lib_Pad, "(DUMMY) called user_id = {} type = {} index = {}", userId, type, index);
|
||||
if (userId == -1) {
|
||||
return ORBIS_PAD_ERROR_DEVICE_NO_HANDLE;
|
||||
}
|
||||
|
@ -261,6 +260,7 @@ int PS4_SYSV_ABI scePadOpen(s32 userId, s32 type, s32 index, const OrbisPadOpenP
|
|||
if (type != ORBIS_PAD_PORT_TYPE_STANDARD && type != ORBIS_PAD_PORT_TYPE_REMOTE_CONTROL)
|
||||
return ORBIS_PAD_ERROR_DEVICE_NOT_CONNECTED;
|
||||
}
|
||||
LOG_INFO(Lib_Pad, "(DUMMY) called user_id = {} type = {} index = {}", userId, type, index);
|
||||
scePadResetLightBar(1);
|
||||
return 1; // dummy
|
||||
}
|
||||
|
|
45
src/core/libraries/ulobjmgr/ulobjmgr.cpp
Normal file
|
@ -0,0 +1,45 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "common/logging/log.h"
|
||||
#include "core/libraries/error_codes.h"
|
||||
#include "core/libraries/kernel/posix_error.h"
|
||||
#include "core/libraries/libs.h"
|
||||
#include "core/libraries/ulobjmgr/ulobjmgr.h"
|
||||
|
||||
namespace Libraries::Ulobjmgr {
|
||||
|
||||
s32 PS4_SYSV_ABI Func_046DBA8411A2365C(u64 arg0, s32 arg1, u32* arg2) {
|
||||
if (arg0 == 0 || arg1 == 0 || arg2 == nullptr) {
|
||||
return POSIX_EINVAL;
|
||||
}
|
||||
*arg2 = 0;
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI Func_1D9F50D9CFB8054E() {
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI Func_4A67FE7D435B94F7(u32 arg0) {
|
||||
if (arg0 >= 0x4000) {
|
||||
return POSIX_EINVAL;
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI Func_4B07893BBB77A649(u64 arg0) {
|
||||
if (arg0 == 0) {
|
||||
return POSIX_EINVAL;
|
||||
}
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
void RegisterlibSceUlobjmgr(Core::Loader::SymbolsResolver* sym) {
|
||||
LIB_FUNCTION("BG26hBGiNlw", "ulobjmgr", 1, "ulobjmgr", 1, 1, Func_046DBA8411A2365C);
|
||||
LIB_FUNCTION("HZ9Q2c+4BU4", "ulobjmgr", 1, "ulobjmgr", 1, 1, Func_1D9F50D9CFB8054E);
|
||||
LIB_FUNCTION("Smf+fUNblPc", "ulobjmgr", 1, "ulobjmgr", 1, 1, Func_4A67FE7D435B94F7);
|
||||
LIB_FUNCTION("SweJO7t3pkk", "ulobjmgr", 1, "ulobjmgr", 1, 1, Func_4B07893BBB77A649);
|
||||
};
|
||||
|
||||
} // namespace Libraries::Ulobjmgr
|
14
src/core/libraries/ulobjmgr/ulobjmgr.h
Normal file
|
@ -0,0 +1,14 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.h"
|
||||
|
||||
namespace Core::Loader {
|
||||
class SymbolsResolver;
|
||||
}
|
||||
|
||||
namespace Libraries::Ulobjmgr {
|
||||
void RegisterlibSceUlobjmgr(Core::Loader::SymbolsResolver* sym);
|
||||
} // namespace Libraries::Ulobjmgr
|
|
@ -7,311 +7,455 @@
|
|||
#include "core/libraries/libs.h"
|
||||
#include "usbd.h"
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <libusb.h>
|
||||
|
||||
namespace Libraries::Usbd {
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdAllocTransfer() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 libusb_to_orbis_error(int retVal) {
|
||||
if (retVal == LIBUSB_ERROR_OTHER)
|
||||
return 0x802400FF;
|
||||
if (retVal < 0) {
|
||||
LOG_ERROR(Lib_Usbd, "libusb returned: {}", libusb_error_name(retVal));
|
||||
return 0x80240000 - retVal;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdAttachKernelDriver() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
libusb_context* g_libusb_context;
|
||||
|
||||
#if defined(_WIN32)
|
||||
bool s_has_removed_driver = false;
|
||||
#endif
|
||||
|
||||
s32 PS4_SYSV_ABI sceUsbdInit() {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_to_orbis_error(libusb_init(&g_libusb_context));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdBulkTransfer() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
void PS4_SYSV_ABI sceUsbdExit() {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
libusb_exit(g_libusb_context);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdCancelTransfer() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s64 PS4_SYSV_ABI sceUsbdGetDeviceList(SceUsbdDevice*** list) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_to_orbis_error(libusb_get_device_list(g_libusb_context, list));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdCheckConnected() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
void PS4_SYSV_ABI sceUsbdFreeDeviceList(SceUsbdDevice** list, s32 unref_devices) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
libusb_free_device_list(list, unref_devices);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdClaimInterface() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
SceUsbdDevice* PS4_SYSV_ABI sceUsbdRefDevice(SceUsbdDevice* device) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_ref_device(device);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdClearHalt() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
void PS4_SYSV_ABI sceUsbdUnrefDevice(SceUsbdDevice* device) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
libusb_unref_device(device);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdClose() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdGetConfiguration(SceUsbdDeviceHandle* dev_handle, s32* config) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_to_orbis_error(libusb_get_configuration(dev_handle, config));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdControlTransfer() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdGetDeviceDescriptor(SceUsbdDevice* device, SceUsbdDeviceDescriptor* desc) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_to_orbis_error(libusb_get_device_descriptor(device, desc));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdControlTransferGetData() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdGetActiveConfigDescriptor(SceUsbdDevice* device,
|
||||
SceUsbdConfigDescriptor** config) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_to_orbis_error(libusb_get_active_config_descriptor(device, config));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdControlTransferGetSetup() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdGetConfigDescriptor(SceUsbdDevice* device, u8 config_index,
|
||||
SceUsbdConfigDescriptor** config) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_to_orbis_error(libusb_get_config_descriptor(device, config_index, config));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdDetachKernelDriver() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdGetConfigDescriptorByValue(SceUsbdDevice* device, u8 bConfigurationValue,
|
||||
SceUsbdConfigDescriptor** config) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_to_orbis_error(
|
||||
libusb_get_config_descriptor_by_value(device, bConfigurationValue, config));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdEventHandlerActive() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
void PS4_SYSV_ABI sceUsbdFreeConfigDescriptor(SceUsbdConfigDescriptor* config) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
libusb_free_config_descriptor(config);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdEventHandlingOk() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
u8 PS4_SYSV_ABI sceUsbdGetBusNumber(SceUsbdDevice* device) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_get_bus_number(device);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdExit() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
u8 PS4_SYSV_ABI sceUsbdGetDeviceAddress(SceUsbdDevice* device) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_get_device_address(device);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdFillBulkTransfer() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
SceUsbdSpeed PS4_SYSV_ABI sceUsbdGetDeviceSpeed(SceUsbdDevice* device) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return static_cast<SceUsbdSpeed>(libusb_get_device_speed(device));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdFillControlSetup() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdGetMaxPacketSize(SceUsbdDevice* device, u8 endpoint) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_to_orbis_error(libusb_get_max_packet_size(device, endpoint));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdFillControlTransfer() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdGetMaxIsoPacketSize(SceUsbdDevice* device, u8 endpoint) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_to_orbis_error(libusb_get_max_iso_packet_size(device, endpoint));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdFillInterruptTransfer() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdOpen(SceUsbdDevice* device, SceUsbdDeviceHandle** dev_handle) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_to_orbis_error(libusb_open(device, dev_handle));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdFillIsoTransfer() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
void PS4_SYSV_ABI sceUsbdClose(SceUsbdDeviceHandle* dev_handle) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
libusb_close(dev_handle);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdFreeConfigDescriptor() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
SceUsbdDevice* PS4_SYSV_ABI sceUsbdGetDevice(SceUsbdDeviceHandle* dev_handle) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_get_device(dev_handle);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdFreeDeviceList() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdSetConfiguration(SceUsbdDeviceHandle* dev_handle, s32 config) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_to_orbis_error(libusb_set_configuration(dev_handle, config));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdFreeTransfer() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdClaimInterface(SceUsbdDeviceHandle* dev_handle, s32 interface_number) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
if (sceUsbdKernelDriverActive(dev_handle, interface_number)) {
|
||||
sceUsbdDetachKernelDriver(dev_handle, interface_number);
|
||||
}
|
||||
|
||||
return libusb_to_orbis_error(libusb_claim_interface(dev_handle, interface_number));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdGetActiveConfigDescriptor() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdReleaseInterface(SceUsbdDeviceHandle* dev_handle, s32 interface_number) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_to_orbis_error(libusb_release_interface(dev_handle, interface_number));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdGetBusNumber() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
SceUsbdDeviceHandle* PS4_SYSV_ABI sceUsbdOpenDeviceWithVidPid(u16 vendor_id, u16 product_id) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_open_device_with_vid_pid(g_libusb_context, vendor_id, product_id);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdGetConfigDescriptor() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdSetInterfaceAltSetting(SceUsbdDeviceHandle* dev_handle,
|
||||
int interface_number, int alternate_setting) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_to_orbis_error(
|
||||
libusb_set_interface_alt_setting(dev_handle, interface_number, alternate_setting));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdGetConfigDescriptorByValue() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdClearHalt(SceUsbdDeviceHandle* dev_handle, uint8_t endpoint) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_to_orbis_error(libusb_clear_halt(dev_handle, endpoint));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdGetConfiguration() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdResetDevice(SceUsbdDeviceHandle* dev_handle) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_to_orbis_error(libusb_reset_device(dev_handle));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdGetDescriptor() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdKernelDriverActive(SceUsbdDeviceHandle* dev_handle, int interface_number) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
#if defined(_WIN32)
|
||||
if (!s_has_removed_driver)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
return libusb_to_orbis_error(libusb_kernel_driver_active(dev_handle, interface_number));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdGetDevice() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdDetachKernelDriver(SceUsbdDeviceHandle* dev_handle, int interface_number) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
#if defined(_WIN32)
|
||||
s_has_removed_driver = true;
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
return libusb_to_orbis_error(libusb_detach_kernel_driver(dev_handle, interface_number));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdGetDeviceAddress() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdAttachKernelDriver(SceUsbdDeviceHandle* dev_handle, int interface_number) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
#if defined(_WIN32)
|
||||
s_has_removed_driver = false;
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
return libusb_to_orbis_error(libusb_attach_kernel_driver(dev_handle, interface_number));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdGetDeviceDescriptor() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
u8* PS4_SYSV_ABI sceUsbdControlTransferGetData(SceUsbdTransfer* transfer) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_control_transfer_get_data(transfer);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdGetDeviceList() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
SceUsbdControlSetup* PS4_SYSV_ABI sceUsbdControlTransferGetSetup(SceUsbdTransfer* transfer) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_control_transfer_get_setup(transfer);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdGetDeviceSpeed() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
void PS4_SYSV_ABI sceUsbdFillControlSetup(u8* buf, u8 bmRequestType, u8 bRequest, u16 wValue,
|
||||
u16 wIndex, u16 wLength) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_fill_control_setup(buf, bmRequestType, bRequest, wValue, wIndex, wLength);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdGetIsoPacketBuffer() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
SceUsbdTransfer* PS4_SYSV_ABI sceUsbdAllocTransfer(int iso_packets) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_alloc_transfer(iso_packets);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdGetMaxIsoPacketSize() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdSubmitTransfer(SceUsbdTransfer* transfer) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_to_orbis_error(libusb_submit_transfer(transfer));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdGetMaxPacketSize() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdCancelTransfer(SceUsbdTransfer* transfer) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_to_orbis_error(libusb_cancel_transfer(transfer));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdGetStringDescriptor() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
void PS4_SYSV_ABI sceUsbdFreeTransfer(SceUsbdTransfer* transfer) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
libusb_free_transfer(transfer);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdGetStringDescriptorAscii() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
void PS4_SYSV_ABI sceUsbdFillControlTransfer(SceUsbdTransfer* transfer,
|
||||
SceUsbdDeviceHandle* dev_handle, u8* buffer,
|
||||
SceUsbdTransferCallback callback, void* user_data,
|
||||
u32 timeout) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
libusb_fill_control_transfer(transfer, dev_handle, buffer, callback, user_data, timeout);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdHandleEvents() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
void PS4_SYSV_ABI sceUsbdFillBulkTransfer(SceUsbdTransfer* transfer,
|
||||
SceUsbdDeviceHandle* dev_handle, uint8_t endpoint,
|
||||
u8* buffer, s32 length, SceUsbdTransferCallback callback,
|
||||
void* user_data, u32 timeout) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
libusb_fill_bulk_transfer(transfer, dev_handle, endpoint, buffer, length, callback, user_data,
|
||||
timeout);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdHandleEventsLocked() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
void PS4_SYSV_ABI sceUsbdFillInterruptTransfer(SceUsbdTransfer* transfer,
|
||||
SceUsbdDeviceHandle* dev_handle, uint8_t endpoint,
|
||||
u8* buffer, s32 length,
|
||||
SceUsbdTransferCallback callback, void* user_data,
|
||||
u32 timeout) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
libusb_fill_interrupt_transfer(transfer, dev_handle, endpoint, buffer, length, callback,
|
||||
user_data, timeout);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdHandleEventsTimeout() {
|
||||
LOG_DEBUG(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
void PS4_SYSV_ABI sceUsbdFillIsoTransfer(SceUsbdTransfer* transfer, SceUsbdDeviceHandle* dev_handle,
|
||||
uint8_t endpoint, u8* buffer, s32 length,
|
||||
s32 num_iso_packets, SceUsbdTransferCallback callback,
|
||||
void* user_data, u32 timeout) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
libusb_fill_iso_transfer(transfer, dev_handle, endpoint, buffer, length, num_iso_packets,
|
||||
callback, user_data, timeout);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdInit() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return 0x80240005; // Skip
|
||||
void PS4_SYSV_ABI sceUsbdSetIsoPacketLengths(SceUsbdTransfer* transfer, u32 length) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
libusb_set_iso_packet_lengths(transfer, length);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdInterruptTransfer() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
u8* PS4_SYSV_ABI sceUsbdGetIsoPacketBuffer(SceUsbdTransfer* transfer, u32 packet) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_get_iso_packet_buffer(transfer, packet);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdKernelDriverActive() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdControlTransfer(SceUsbdDeviceHandle* dev_handle, u8 request_type,
|
||||
u8 bRequest, u16 wValue, u16 wIndex, u8* data, s32 wLength,
|
||||
u32 timeout) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_to_orbis_error(libusb_control_transfer(dev_handle, request_type, bRequest, wValue,
|
||||
wIndex, data, wLength, timeout));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdLockEvents() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdBulkTransfer(SceUsbdDeviceHandle* dev_handle, u8 endpoint, u8* data,
|
||||
s32 length, s32* actual_length, u32 timeout) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_to_orbis_error(
|
||||
libusb_bulk_transfer(dev_handle, endpoint, data, length, actual_length, timeout));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdLockEventWaiters() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdInterruptTransfer(SceUsbdDeviceHandle* dev_handle, u8 endpoint, u8* data,
|
||||
s32 length, s32* actual_length, u32 timeout) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_to_orbis_error(
|
||||
libusb_interrupt_transfer(dev_handle, endpoint, data, length, actual_length, timeout));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdOpen() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdGetDescriptor(SceUsbdDeviceHandle* dev_handle, u8 descType, u8 descIndex,
|
||||
u8* data, s32 length) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_to_orbis_error(
|
||||
libusb_get_descriptor(dev_handle, descType, descIndex, data, length));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdOpenDeviceWithVidPid() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdGetStringDescriptor(SceUsbdDeviceHandle* dev_handle, u8 desc_index,
|
||||
u16 langid, u8* data, s32 length) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_to_orbis_error(
|
||||
libusb_get_string_descriptor(dev_handle, desc_index, langid, data, length));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdRefDevice() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdGetStringDescriptorAscii(SceUsbdDeviceHandle* dev_handle, u8 desc_index,
|
||||
u8* data, s32 length) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_to_orbis_error(
|
||||
libusb_get_string_descriptor_ascii(dev_handle, desc_index, data, length));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdReleaseInterface() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdTryLockEvents() {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_try_lock_events(g_libusb_context);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdResetDevice() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
void PS4_SYSV_ABI sceUsbdLockEvents() {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
libusb_lock_events(g_libusb_context);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdSetConfiguration() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
void PS4_SYSV_ABI sceUsbdUnlockEvents() {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
libusb_unlock_events(g_libusb_context);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdSetInterfaceAltSetting() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdEventHandlingOk() {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_event_handling_ok(g_libusb_context);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdSetIsoPacketLengths() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdEventHandlerActive() {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_event_handler_active(g_libusb_context);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdSubmitTransfer() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
void PS4_SYSV_ABI sceUsbdLockEventWaiters() {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
libusb_lock_event_waiters(g_libusb_context);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdTryLockEvents() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
void PS4_SYSV_ABI sceUsbdUnlockEventWaiters() {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
libusb_unlock_event_waiters(g_libusb_context);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdUnlockEvents() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdWaitForEvent(timeval* tv) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_to_orbis_error(libusb_wait_for_event(g_libusb_context, tv));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdUnlockEventWaiters() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdHandleEventsTimeout(timeval* tv) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_to_orbis_error(libusb_handle_events_timeout(g_libusb_context, tv));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdUnrefDevice() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdHandleEvents() {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_to_orbis_error(libusb_handle_events(g_libusb_context));
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdWaitForEvent() {
|
||||
LOG_ERROR(Lib_Usbd, "(STUBBED) called");
|
||||
return ORBIS_OK;
|
||||
s32 PS4_SYSV_ABI sceUsbdHandleEventsLocked(timeval* tv) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
return libusb_to_orbis_error(libusb_handle_events_locked(g_libusb_context, tv));
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceUsbdCheckConnected(SceUsbdDeviceHandle* dev_handle) {
|
||||
LOG_DEBUG(Lib_Usbd, "called");
|
||||
|
||||
// There's no libusb version of this function.
|
||||
// Simulate by querying data.
|
||||
|
||||
int config;
|
||||
int r = libusb_get_configuration(dev_handle, &config);
|
||||
|
||||
return libusb_to_orbis_error(r);
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI Func_65F6EF33E38FFF50() {
|
||||
|
@ -406,4 +550,4 @@ void RegisterlibSceUsbd(Core::Loader::SymbolsResolver* sym) {
|
|||
LIB_FUNCTION("1WtDBgcgseA", "libSceUsbd", 1, "libSceUsbd", 1, 1, Func_D56B43060720B1E0);
|
||||
};
|
||||
|
||||
} // namespace Libraries::Usbd
|
||||
} // namespace Libraries::Usbd
|
|
@ -1,76 +1,150 @@
|
|||
// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX - FileCopyrightText : Copyright 2024 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "common/types.h"
|
||||
|
||||
extern "C" {
|
||||
struct libusb_device;
|
||||
struct libusb_device_handle;
|
||||
struct libusb_device_descriptor;
|
||||
struct libusb_config_descriptor;
|
||||
struct libusb_transfer;
|
||||
struct libusb_control_setup;
|
||||
struct timeval;
|
||||
}
|
||||
|
||||
namespace Core::Loader {
|
||||
class SymbolsResolver;
|
||||
}
|
||||
|
||||
namespace Libraries::Usbd {
|
||||
|
||||
int PS4_SYSV_ABI sceUsbdAllocTransfer();
|
||||
int PS4_SYSV_ABI sceUsbdAttachKernelDriver();
|
||||
int PS4_SYSV_ABI sceUsbdBulkTransfer();
|
||||
int PS4_SYSV_ABI sceUsbdCancelTransfer();
|
||||
int PS4_SYSV_ABI sceUsbdCheckConnected();
|
||||
int PS4_SYSV_ABI sceUsbdClaimInterface();
|
||||
int PS4_SYSV_ABI sceUsbdClearHalt();
|
||||
int PS4_SYSV_ABI sceUsbdClose();
|
||||
int PS4_SYSV_ABI sceUsbdControlTransfer();
|
||||
int PS4_SYSV_ABI sceUsbdControlTransferGetData();
|
||||
int PS4_SYSV_ABI sceUsbdControlTransferGetSetup();
|
||||
int PS4_SYSV_ABI sceUsbdDetachKernelDriver();
|
||||
int PS4_SYSV_ABI sceUsbdEventHandlerActive();
|
||||
int PS4_SYSV_ABI sceUsbdEventHandlingOk();
|
||||
int PS4_SYSV_ABI sceUsbdExit();
|
||||
int PS4_SYSV_ABI sceUsbdFillBulkTransfer();
|
||||
int PS4_SYSV_ABI sceUsbdFillControlSetup();
|
||||
int PS4_SYSV_ABI sceUsbdFillControlTransfer();
|
||||
int PS4_SYSV_ABI sceUsbdFillInterruptTransfer();
|
||||
int PS4_SYSV_ABI sceUsbdFillIsoTransfer();
|
||||
int PS4_SYSV_ABI sceUsbdFreeConfigDescriptor();
|
||||
int PS4_SYSV_ABI sceUsbdFreeDeviceList();
|
||||
int PS4_SYSV_ABI sceUsbdFreeTransfer();
|
||||
int PS4_SYSV_ABI sceUsbdGetActiveConfigDescriptor();
|
||||
int PS4_SYSV_ABI sceUsbdGetBusNumber();
|
||||
int PS4_SYSV_ABI sceUsbdGetConfigDescriptor();
|
||||
int PS4_SYSV_ABI sceUsbdGetConfigDescriptorByValue();
|
||||
int PS4_SYSV_ABI sceUsbdGetConfiguration();
|
||||
int PS4_SYSV_ABI sceUsbdGetDescriptor();
|
||||
int PS4_SYSV_ABI sceUsbdGetDevice();
|
||||
int PS4_SYSV_ABI sceUsbdGetDeviceAddress();
|
||||
int PS4_SYSV_ABI sceUsbdGetDeviceDescriptor();
|
||||
int PS4_SYSV_ABI sceUsbdGetDeviceList();
|
||||
int PS4_SYSV_ABI sceUsbdGetDeviceSpeed();
|
||||
int PS4_SYSV_ABI sceUsbdGetIsoPacketBuffer();
|
||||
int PS4_SYSV_ABI sceUsbdGetMaxIsoPacketSize();
|
||||
int PS4_SYSV_ABI sceUsbdGetMaxPacketSize();
|
||||
int PS4_SYSV_ABI sceUsbdGetStringDescriptor();
|
||||
int PS4_SYSV_ABI sceUsbdGetStringDescriptorAscii();
|
||||
int PS4_SYSV_ABI sceUsbdHandleEvents();
|
||||
int PS4_SYSV_ABI sceUsbdHandleEventsLocked();
|
||||
int PS4_SYSV_ABI sceUsbdHandleEventsTimeout();
|
||||
int PS4_SYSV_ABI sceUsbdInit();
|
||||
int PS4_SYSV_ABI sceUsbdInterruptTransfer();
|
||||
int PS4_SYSV_ABI sceUsbdKernelDriverActive();
|
||||
int PS4_SYSV_ABI sceUsbdLockEvents();
|
||||
int PS4_SYSV_ABI sceUsbdLockEventWaiters();
|
||||
int PS4_SYSV_ABI sceUsbdOpen();
|
||||
int PS4_SYSV_ABI sceUsbdOpenDeviceWithVidPid();
|
||||
int PS4_SYSV_ABI sceUsbdRefDevice();
|
||||
int PS4_SYSV_ABI sceUsbdReleaseInterface();
|
||||
int PS4_SYSV_ABI sceUsbdResetDevice();
|
||||
int PS4_SYSV_ABI sceUsbdSetConfiguration();
|
||||
int PS4_SYSV_ABI sceUsbdSetInterfaceAltSetting();
|
||||
int PS4_SYSV_ABI sceUsbdSetIsoPacketLengths();
|
||||
int PS4_SYSV_ABI sceUsbdSubmitTransfer();
|
||||
int PS4_SYSV_ABI sceUsbdTryLockEvents();
|
||||
int PS4_SYSV_ABI sceUsbdUnlockEvents();
|
||||
int PS4_SYSV_ABI sceUsbdUnlockEventWaiters();
|
||||
int PS4_SYSV_ABI sceUsbdUnrefDevice();
|
||||
int PS4_SYSV_ABI sceUsbdWaitForEvent();
|
||||
using SceUsbdDevice = libusb_device;
|
||||
using SceUsbdDeviceHandle = libusb_device_handle;
|
||||
using SceUsbdDeviceDescriptor = libusb_device_descriptor;
|
||||
using SceUsbdConfigDescriptor = libusb_config_descriptor;
|
||||
using SceUsbdTransfer = libusb_transfer;
|
||||
using SceUsbdControlSetup = libusb_control_setup;
|
||||
using SceUsbdTransferCallback = void (*)(SceUsbdTransfer* transfer);
|
||||
|
||||
enum class SceUsbdSpeed : u32 {
|
||||
UNKNOWN = 0,
|
||||
LOW = 1,
|
||||
FULL = 2,
|
||||
HIGH = 3,
|
||||
SUPER = 4,
|
||||
SUPER_PLUS = 5
|
||||
};
|
||||
|
||||
s32 PS4_SYSV_ABI sceUsbdInit();
|
||||
void PS4_SYSV_ABI sceUsbdExit();
|
||||
|
||||
s64 PS4_SYSV_ABI sceUsbdGetDeviceList(SceUsbdDevice*** list);
|
||||
void PS4_SYSV_ABI sceUsbdFreeDeviceList(SceUsbdDevice** list, s32 unref_devices);
|
||||
|
||||
SceUsbdDevice* PS4_SYSV_ABI sceUsbdRefDevice(SceUsbdDevice* device);
|
||||
void PS4_SYSV_ABI sceUsbdUnrefDevice(SceUsbdDevice* device);
|
||||
|
||||
s32 PS4_SYSV_ABI sceUsbdGetConfiguration(SceUsbdDeviceHandle* dev_handle, s32* config);
|
||||
s32 PS4_SYSV_ABI sceUsbdGetDeviceDescriptor(SceUsbdDevice* device, SceUsbdDeviceDescriptor* desc);
|
||||
s32 PS4_SYSV_ABI sceUsbdGetActiveConfigDescriptor(SceUsbdDevice* device,
|
||||
SceUsbdConfigDescriptor** config);
|
||||
s32 PS4_SYSV_ABI sceUsbdGetConfigDescriptor(SceUsbdDevice* device, u8 config_index,
|
||||
SceUsbdConfigDescriptor** config);
|
||||
s32 PS4_SYSV_ABI sceUsbdGetConfigDescriptorByValue(SceUsbdDevice* device, u8 bConfigurationValue,
|
||||
SceUsbdConfigDescriptor** config);
|
||||
void PS4_SYSV_ABI sceUsbdFreeConfigDescriptor(SceUsbdConfigDescriptor* config);
|
||||
|
||||
u8 PS4_SYSV_ABI sceUsbdGetBusNumber(SceUsbdDevice* device);
|
||||
u8 PS4_SYSV_ABI sceUsbdGetDeviceAddress(SceUsbdDevice* device);
|
||||
|
||||
SceUsbdSpeed PS4_SYSV_ABI sceUsbdGetDeviceSpeed(SceUsbdDevice* device);
|
||||
s32 PS4_SYSV_ABI sceUsbdGetMaxPacketSize(SceUsbdDevice* device, u8 endpoint);
|
||||
s32 PS4_SYSV_ABI sceUsbdGetMaxIsoPacketSize(SceUsbdDevice* device, u8 endpoint);
|
||||
|
||||
s32 PS4_SYSV_ABI sceUsbdOpen(SceUsbdDevice* device, SceUsbdDeviceHandle** dev_handle);
|
||||
void PS4_SYSV_ABI sceUsbdClose(SceUsbdDeviceHandle* dev_handle);
|
||||
SceUsbdDevice* PS4_SYSV_ABI sceUsbdGetDevice(SceUsbdDeviceHandle* dev_handle);
|
||||
|
||||
s32 PS4_SYSV_ABI sceUsbdSetConfiguration(SceUsbdDeviceHandle* dev_handle, s32 config);
|
||||
s32 PS4_SYSV_ABI sceUsbdClaimInterface(SceUsbdDeviceHandle* dev_handle, s32 interface_number);
|
||||
s32 PS4_SYSV_ABI sceUsbdReleaseInterface(SceUsbdDeviceHandle* dev_handle, s32 interface_number);
|
||||
|
||||
SceUsbdDeviceHandle* PS4_SYSV_ABI sceUsbdOpenDeviceWithVidPid(u16 vendor_id, u16 product_id);
|
||||
|
||||
s32 PS4_SYSV_ABI sceUsbdSetInterfaceAltSetting(SceUsbdDeviceHandle* dev_handle,
|
||||
int interface_number, int alternate_setting);
|
||||
s32 PS4_SYSV_ABI sceUsbdClearHalt(SceUsbdDeviceHandle* dev_handle, u8 endpoint);
|
||||
s32 PS4_SYSV_ABI sceUsbdResetDevice(SceUsbdDeviceHandle* dev_handle);
|
||||
|
||||
s32 PS4_SYSV_ABI sceUsbdKernelDriverActive(SceUsbdDeviceHandle* dev_handle, int interface_number);
|
||||
s32 PS4_SYSV_ABI sceUsbdDetachKernelDriver(SceUsbdDeviceHandle* dev_handle, int interface_number);
|
||||
s32 PS4_SYSV_ABI sceUsbdAttachKernelDriver(SceUsbdDeviceHandle* dev_handle, int interface_number);
|
||||
|
||||
u8* PS4_SYSV_ABI sceUsbdControlTransferGetData(SceUsbdTransfer* transfer);
|
||||
SceUsbdControlSetup* PS4_SYSV_ABI sceUsbdControlTransferGetSetup(SceUsbdTransfer* transfer);
|
||||
|
||||
void PS4_SYSV_ABI sceUsbdFillControlSetup(u8* buf, u8 bmRequestType, u8 bRequest, u16 wValue,
|
||||
u16 wIndex, u16 wLength);
|
||||
|
||||
SceUsbdTransfer* PS4_SYSV_ABI sceUsbdAllocTransfer(int iso_packets);
|
||||
s32 PS4_SYSV_ABI sceUsbdSubmitTransfer(SceUsbdTransfer* transfer);
|
||||
s32 PS4_SYSV_ABI sceUsbdCancelTransfer(SceUsbdTransfer* transfer);
|
||||
void PS4_SYSV_ABI sceUsbdFreeTransfer(SceUsbdTransfer* transfer);
|
||||
|
||||
void PS4_SYSV_ABI sceUsbdFillControlTransfer(SceUsbdTransfer* transfer,
|
||||
SceUsbdDeviceHandle* dev_handle, u8* buffer,
|
||||
SceUsbdTransferCallback callback, void* user_data,
|
||||
u32 timeout);
|
||||
void PS4_SYSV_ABI sceUsbdFillBulkTransfer(SceUsbdTransfer* transfer,
|
||||
SceUsbdDeviceHandle* dev_handle, u8 endpoint, u8* buffer,
|
||||
s32 length, SceUsbdTransferCallback callback,
|
||||
void* user_data, u32 timeout);
|
||||
void PS4_SYSV_ABI sceUsbdFillInterruptTransfer(SceUsbdTransfer* transfer,
|
||||
SceUsbdDeviceHandle* dev_handle, u8 endpoint,
|
||||
u8* buffer, s32 length,
|
||||
SceUsbdTransferCallback callback, void* user_data,
|
||||
u32 timeout);
|
||||
void PS4_SYSV_ABI sceUsbdFillIsoTransfer(SceUsbdTransfer* transfer, SceUsbdDeviceHandle* dev_handle,
|
||||
u8 endpoint, u8* buffer, s32 length, s32 num_iso_packets,
|
||||
SceUsbdTransferCallback callback, void* userData,
|
||||
u32 timeout);
|
||||
|
||||
void PS4_SYSV_ABI sceUsbdSetIsoPacketLengths(SceUsbdTransfer* transfer, u32 length);
|
||||
u8* PS4_SYSV_ABI sceUsbdGetIsoPacketBuffer(SceUsbdTransfer* transfer, u32 packet);
|
||||
|
||||
s32 PS4_SYSV_ABI sceUsbdControlTransfer(SceUsbdDeviceHandle* dev_handle, u8 request_type,
|
||||
u8 bRequest, u16 wValue, u16 wIndex, u8* data, s32 wLength,
|
||||
u32 timeout);
|
||||
s32 PS4_SYSV_ABI sceUsbdBulkTransfer(SceUsbdDeviceHandle* dev_handle, u8 endpoint, u8* data,
|
||||
s32 length, s32* actual_length, u32 timeout);
|
||||
s32 PS4_SYSV_ABI sceUsbdInterruptTransfer(SceUsbdDeviceHandle* dev_handle, u8 endpoint, u8* data,
|
||||
s32 length, s32* actual_length, u32 timeout);
|
||||
|
||||
s32 PS4_SYSV_ABI sceUsbdGetDescriptor(SceUsbdDeviceHandle* dev_handle, u8 descType, u8 descIndex,
|
||||
u8* data, s32 length);
|
||||
s32 PS4_SYSV_ABI sceUsbdGetStringDescriptor(SceUsbdDeviceHandle* dev_handle, u8 desc_index,
|
||||
u16 langid, u8* data, s32 length);
|
||||
s32 PS4_SYSV_ABI sceUsbdGetStringDescriptorAscii(SceUsbdDeviceHandle* dev_handle, u8 desc_index,
|
||||
u8* data, s32 length);
|
||||
|
||||
s32 PS4_SYSV_ABI sceUsbdTryLockEvents();
|
||||
void PS4_SYSV_ABI sceUsbdLockEvents();
|
||||
void PS4_SYSV_ABI sceUsbdUnlockEvents();
|
||||
s32 PS4_SYSV_ABI sceUsbdEventHandlingOk();
|
||||
s32 PS4_SYSV_ABI sceUsbdEventHandlerActive();
|
||||
void PS4_SYSV_ABI sceUsbdLockEventWaiters();
|
||||
void PS4_SYSV_ABI sceUsbdUnlockEventWaiters();
|
||||
s32 PS4_SYSV_ABI sceUsbdWaitForEvent(timeval* tv);
|
||||
|
||||
s32 PS4_SYSV_ABI sceUsbdHandleEventsTimeout(timeval* tv);
|
||||
s32 PS4_SYSV_ABI sceUsbdHandleEvents();
|
||||
s32 PS4_SYSV_ABI sceUsbdHandleEventsLocked(timeval* tv);
|
||||
|
||||
s32 PS4_SYSV_ABI sceUsbdCheckConnected(SceUsbdDeviceHandle* dev_handle);
|
||||
|
||||
int PS4_SYSV_ABI Func_65F6EF33E38FFF50();
|
||||
int PS4_SYSV_ABI Func_97F056BAD90AADE7();
|
||||
int PS4_SYSV_ABI Func_C55104A33B35B264();
|
||||
|
|
|
@ -104,6 +104,20 @@ s32 PS4_SYSV_ABI sceVideoOutAddVblankEvent(Kernel::SceKernelEqueue eq, s32 handl
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceVideoOutDeleteVblankEvent(Kernel::SceKernelEqueue eq, s32 handle) {
|
||||
auto* port = driver->GetPort(handle);
|
||||
if (port == nullptr) {
|
||||
return ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE;
|
||||
}
|
||||
|
||||
if (eq == nullptr) {
|
||||
return ORBIS_VIDEO_OUT_ERROR_INVALID_EVENT_QUEUE;
|
||||
}
|
||||
eq->RemoveEvent(handle, Kernel::SceKernelEvent::Filter::VideoOut);
|
||||
port->vblank_events.erase(find(port->vblank_events.begin(), port->vblank_events.end(), eq));
|
||||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceVideoOutRegisterBuffers(s32 handle, s32 startIndex, void* const* addresses,
|
||||
s32 bufferNum, const BufferAttribute* attribute) {
|
||||
if (!addresses || !attribute) {
|
||||
|
@ -166,7 +180,7 @@ s32 PS4_SYSV_ABI sceVideoOutSubmitFlip(s32 handle, s32 bufferIndex, s32 flipMode
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceVideoOutGetEventId(const Kernel::SceKernelEvent* ev) {
|
||||
s32 PS4_SYSV_ABI sceVideoOutGetEventId(const Kernel::SceKernelEvent* ev) {
|
||||
if (ev == nullptr) {
|
||||
return ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS;
|
||||
}
|
||||
|
@ -194,7 +208,7 @@ int PS4_SYSV_ABI sceVideoOutGetEventId(const Kernel::SceKernelEvent* ev) {
|
|||
}
|
||||
}
|
||||
|
||||
int PS4_SYSV_ABI sceVideoOutGetEventData(const Kernel::SceKernelEvent* ev, int64_t* data) {
|
||||
s32 PS4_SYSV_ABI sceVideoOutGetEventData(const Kernel::SceKernelEvent* ev, s64* data) {
|
||||
if (ev == nullptr || data == nullptr) {
|
||||
return ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS;
|
||||
}
|
||||
|
@ -211,6 +225,17 @@ int PS4_SYSV_ABI sceVideoOutGetEventData(const Kernel::SceKernelEvent* ev, int64
|
|||
return ORBIS_OK;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceVideoOutGetEventCount(const Kernel::SceKernelEvent* ev) {
|
||||
if (ev == nullptr) {
|
||||
return ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS;
|
||||
}
|
||||
if (ev->filter != Kernel::SceKernelEvent::Filter::VideoOut) {
|
||||
return ORBIS_VIDEO_OUT_ERROR_INVALID_EVENT;
|
||||
}
|
||||
|
||||
return (ev->data >> 0xc) & 0xf;
|
||||
}
|
||||
|
||||
s32 PS4_SYSV_ABI sceVideoOutGetFlipStatus(s32 handle, FlipStatus* status) {
|
||||
if (!status) {
|
||||
LOG_ERROR(Lib_VideoOut, "Flip status is null");
|
||||
|
@ -447,12 +472,16 @@ void RegisterLib(Core::Loader::SymbolsResolver* sym) {
|
|||
LIB_FUNCTION("U2JJtSqNKZI", "libSceVideoOut", 1, "libSceVideoOut", 0, 0, sceVideoOutGetEventId);
|
||||
LIB_FUNCTION("rWUTcKdkUzQ", "libSceVideoOut", 1, "libSceVideoOut", 0, 0,
|
||||
sceVideoOutGetEventData);
|
||||
LIB_FUNCTION("Mt4QHHkxkOc", "libSceVideoOut", 1, "libSceVideoOut", 0, 0,
|
||||
sceVideoOutGetEventCount);
|
||||
LIB_FUNCTION("DYhhWbJSeRg", "libSceVideoOut", 1, "libSceVideoOut", 0, 0,
|
||||
sceVideoOutColorSettingsSetGamma);
|
||||
LIB_FUNCTION("pv9CI5VC+R0", "libSceVideoOut", 1, "libSceVideoOut", 0, 0,
|
||||
sceVideoOutAdjustColor);
|
||||
LIB_FUNCTION("-Ozn0F1AFRg", "libSceVideoOut", 1, "libSceVideoOut", 0, 0,
|
||||
sceVideoOutDeleteFlipEvent);
|
||||
LIB_FUNCTION("oNOQn3knW6s", "libSceVideoOut", 1, "libSceVideoOut", 0, 0,
|
||||
sceVideoOutDeleteVblankEvent);
|
||||
LIB_FUNCTION("pjkDsgxli6c", "libSceVideoOut", 1, "libSceVideoOut", 0, 0,
|
||||
sceVideoOutModeSetAny_);
|
||||
LIB_FUNCTION("N1bEoJ4SRw4", "libSceVideoOut", 1, "libSceVideoOut", 0, 0,
|
||||
|
|
|
@ -108,10 +108,22 @@ void Linker::Execute(const std::vector<std::string> args) {
|
|||
static constexpr s64 InternalMemorySize = 0x1000000;
|
||||
void* addr_out{reinterpret_cast<void*>(KernelAllocBase)};
|
||||
|
||||
const s32 ret = Libraries::Kernel::sceKernelMapNamedFlexibleMemory(
|
||||
&addr_out, InternalMemorySize, 3, 0, "SceKernelInternalMemory");
|
||||
s32 ret = Libraries::Kernel::sceKernelMapNamedFlexibleMemory(&addr_out, InternalMemorySize, 3,
|
||||
0, "SceKernelInternalMemory");
|
||||
ASSERT_MSG(ret == 0, "Unable to perform sceKernelInternalMemory mapping");
|
||||
|
||||
// Simulate libSceGnmDriver initialization, which maps a chunk of direct memory.
|
||||
// Some games fail without accurately emulating this behavior.
|
||||
s64 phys_addr{};
|
||||
ret = Libraries::Kernel::sceKernelAllocateDirectMemory(
|
||||
0, Libraries::Kernel::sceKernelGetDirectMemorySize(), 0x10000, 0x10000, 3, &phys_addr);
|
||||
if (ret == 0) {
|
||||
void* addr{reinterpret_cast<void*>(0xfe0000000)};
|
||||
ret = Libraries::Kernel::sceKernelMapNamedDirectMemory(&addr, 0x10000, 0x13, 0, phys_addr,
|
||||
0x10000, "SceGnmDriver");
|
||||
}
|
||||
ASSERT_MSG(ret == 0, "Unable to emulate libSceGnmDriver initialization");
|
||||
|
||||
main_thread.Run([this, module, args](std::stop_token) {
|
||||
Common::SetCurrentThreadName("GAME_MainThread");
|
||||
LoadSharedLibraries();
|
||||
|
|
|
@ -139,35 +139,35 @@ PAddr MemoryManager::Allocate(PAddr search_start, PAddr search_end, size_t size,
|
|||
alignment = alignment > 0 ? alignment : 16_KB;
|
||||
|
||||
auto dmem_area = FindDmemArea(search_start);
|
||||
auto mapping_start = search_start > dmem_area->second.base
|
||||
? Common::AlignUp(search_start, alignment)
|
||||
: Common::AlignUp(dmem_area->second.base, alignment);
|
||||
auto mapping_end = Common::AlignUp(mapping_start + size, alignment);
|
||||
|
||||
const auto is_suitable = [&] {
|
||||
if (dmem_area == dmem_map.end()) {
|
||||
return false;
|
||||
}
|
||||
const auto aligned_base = Common::AlignUp(dmem_area->second.base, alignment);
|
||||
const auto alignment_size = aligned_base - dmem_area->second.base;
|
||||
const auto remaining_size =
|
||||
dmem_area->second.size >= alignment_size ? dmem_area->second.size - alignment_size : 0;
|
||||
return dmem_area->second.is_free && remaining_size >= size;
|
||||
};
|
||||
while (dmem_area != dmem_map.end() && !is_suitable() &&
|
||||
dmem_area->second.GetEnd() <= search_end) {
|
||||
++dmem_area;
|
||||
// Find the first free, large enough dmem area in the range.
|
||||
while ((!dmem_area->second.is_free || dmem_area->second.GetEnd() < mapping_end) &&
|
||||
dmem_area != dmem_map.end()) {
|
||||
// The current dmem_area isn't suitable, move to the next one.
|
||||
dmem_area++;
|
||||
|
||||
// Update local variables based on the new dmem_area
|
||||
mapping_start = search_start > dmem_area->second.base
|
||||
? Common::AlignUp(search_start, alignment)
|
||||
: Common::AlignUp(dmem_area->second.base, alignment);
|
||||
mapping_end = Common::AlignUp(mapping_start + size, alignment);
|
||||
}
|
||||
if (!is_suitable()) {
|
||||
|
||||
if (dmem_area == dmem_map.end()) {
|
||||
// There are no suitable mappings in this range
|
||||
LOG_ERROR(Kernel_Vmm, "Unable to find free direct memory area: size = {:#x}", size);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Align free position
|
||||
PAddr free_addr = dmem_area->second.base;
|
||||
free_addr = Common::AlignUp(free_addr, alignment);
|
||||
|
||||
// Add the allocated region to the list and commit its pages.
|
||||
auto& area = CarveDmemArea(free_addr, size)->second;
|
||||
auto& area = CarveDmemArea(mapping_start, size)->second;
|
||||
area.memory_type = memory_type;
|
||||
area.is_free = false;
|
||||
return free_addr;
|
||||
return mapping_start;
|
||||
}
|
||||
|
||||
void MemoryManager::Free(PAddr phys_addr, size_t size) {
|
||||
|
@ -632,17 +632,34 @@ int MemoryManager::DirectQueryAvailable(PAddr search_start, PAddr search_end, si
|
|||
auto dmem_area = FindDmemArea(search_start);
|
||||
PAddr paddr{};
|
||||
size_t max_size{};
|
||||
while (dmem_area != dmem_map.end() && dmem_area->second.GetEnd() <= search_end) {
|
||||
|
||||
while (dmem_area != dmem_map.end()) {
|
||||
if (!dmem_area->second.is_free) {
|
||||
dmem_area++;
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto aligned_base = alignment > 0 ? Common::AlignUp(dmem_area->second.base, alignment)
|
||||
: dmem_area->second.base;
|
||||
auto aligned_base = alignment > 0 ? Common::AlignUp(dmem_area->second.base, alignment)
|
||||
: dmem_area->second.base;
|
||||
const auto alignment_size = aligned_base - dmem_area->second.base;
|
||||
const auto remaining_size =
|
||||
auto remaining_size =
|
||||
dmem_area->second.size >= alignment_size ? dmem_area->second.size - alignment_size : 0;
|
||||
|
||||
if (dmem_area->second.base < search_start) {
|
||||
// We need to trim remaining_size to ignore addresses before search_start
|
||||
remaining_size = remaining_size > (search_start - dmem_area->second.base)
|
||||
? remaining_size - (search_start - dmem_area->second.base)
|
||||
: 0;
|
||||
aligned_base = alignment > 0 ? Common::AlignUp(search_start, alignment) : search_start;
|
||||
}
|
||||
|
||||
if (dmem_area->second.GetEnd() > search_end) {
|
||||
// We need to trim remaining_size to ignore addresses beyond search_end
|
||||
remaining_size = remaining_size > (dmem_area->second.GetEnd() - search_end)
|
||||
? remaining_size - (dmem_area->second.GetEnd() - search_end)
|
||||
: 0;
|
||||
}
|
||||
|
||||
if (remaining_size > max_size) {
|
||||
paddr = aligned_base;
|
||||
max_size = remaining_size;
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
#include "common/arch.h"
|
||||
#include "common/assert.h"
|
||||
#include "common/types.h"
|
||||
#include "core/cpu_patches.h"
|
||||
#include "core/libraries/kernel/threads/pthread.h"
|
||||
#include "core/tls.h"
|
||||
|
||||
|
@ -197,12 +196,7 @@ Tcb* GetTcbBase() {
|
|||
thread_local std::once_flag init_tls_flag;
|
||||
|
||||
void EnsureThreadInitialized() {
|
||||
std::call_once(init_tls_flag, [] {
|
||||
#ifdef ARCH_X86_64
|
||||
InitializeThreadPatchStack();
|
||||
#endif
|
||||
SetTcbBase(Libraries::Kernel::g_curthread->tcb);
|
||||
});
|
||||
std::call_once(init_tls_flag, [] { SetTcbBase(Libraries::Kernel::g_curthread->tcb); });
|
||||
}
|
||||
|
||||
} // namespace Core
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include "common/polyfill_thread.h"
|
||||
#include "common/scm_rev.h"
|
||||
#include "common/singleton.h"
|
||||
#include "common/version.h"
|
||||
#include "core/file_format/psf.h"
|
||||
#include "core/file_format/trp.h"
|
||||
#include "core/file_sys/fs.h"
|
||||
|
@ -123,7 +122,7 @@ void Emulator::Run(const std::filesystem::path& file, const std::vector<std::str
|
|||
Common::Log::Initialize(id + ".log");
|
||||
Common::Log::Start();
|
||||
}
|
||||
LOG_INFO(Loader, "Starting shadps4 emulator v{} ", Common::VERSION);
|
||||
LOG_INFO(Loader, "Starting shadps4 emulator v{} ", Common::g_version);
|
||||
LOG_INFO(Loader, "Revision {}", Common::g_scm_rev);
|
||||
LOG_INFO(Loader, "Branch {}", Common::g_scm_branch);
|
||||
LOG_INFO(Loader, "Description {}", Common::g_scm_desc);
|
||||
|
@ -197,8 +196,8 @@ void Emulator::Run(const std::filesystem::path& file, const std::vector<std::str
|
|||
|
||||
std::string game_title = fmt::format("{} - {} <{}>", id, title, app_version);
|
||||
std::string window_title = "";
|
||||
if (Common::isRelease) {
|
||||
window_title = fmt::format("shadPS4 v{} | {}", Common::VERSION, game_title);
|
||||
if (Common::g_is_release) {
|
||||
window_title = fmt::format("shadPS4 v{} | {}", Common::g_version, game_title);
|
||||
} else {
|
||||
std::string remote_url(Common::g_scm_remote_url);
|
||||
std::string remote_host;
|
||||
|
@ -208,10 +207,10 @@ void Emulator::Run(const std::filesystem::path& file, const std::vector<std::str
|
|||
remote_host = "unknown";
|
||||
}
|
||||
if (remote_host == "shadps4-emu" || remote_url.length() == 0) {
|
||||
window_title = fmt::format("shadPS4 v{} {} {} | {}", Common::VERSION,
|
||||
window_title = fmt::format("shadPS4 v{} {} {} | {}", Common::g_version,
|
||||
Common::g_scm_branch, Common::g_scm_desc, game_title);
|
||||
} else {
|
||||
window_title = fmt::format("shadPS4 v{} {}/{} {} | {}", Common::VERSION, remote_host,
|
||||
window_title = fmt::format("shadPS4 v{} {}/{} {} | {}", Common::g_version, remote_host,
|
||||
Common::g_scm_branch, Common::g_scm_desc, game_title);
|
||||
}
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 67 KiB After Width: | Height: | Size: 43 KiB |
24
src/images/discord.svg
Normal file
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="270.93332mm"
|
||||
height="270.93332mm"
|
||||
viewBox="0 0 270.93332 270.93332"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
xml:space="preserve"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs1" /><g
|
||||
id="layer1"><circle
|
||||
style="fill:#000000;stroke-width:0.333618;fill-opacity:1"
|
||||
id="path1"
|
||||
cx="135.46666"
|
||||
cy="135.46666"
|
||||
r="135.46666" /><path
|
||||
d="m 194.12363,81.01373 c -10.93928,-5.11822 -22.63609,-8.83793 -34.86478,-10.95597 -1.50182,2.71524 -3.2564,6.36731 -4.46607,9.27253 -12.99943,-1.95495 -25.87929,-1.95495 -38.63961,0 -1.20947,-2.90522 -3.00389,-6.55729 -4.51915,-9.27253 -12.241889,2.11804 -23.952119,5.85142 -34.891409,10.98307 -22.06463,33.34254 -28.045983,65.85691 -25.055298,97.90961 14.634418,10.92863 28.816948,17.56744 42.760118,21.91169 3.44265,-4.73808 6.513019,-9.77474 9.158059,-15.08293 -5.037579,-1.91418 -9.862539,-4.27637 -14.421539,-7.01873 1.20947,-0.89604 2.39255,-1.83288 3.53556,-2.79678 27.806639,13.00588 58.019289,13.00588 85.493719,0 1.15643,0.9639 2.33926,1.90074 3.53556,2.79678 -4.57246,2.75579 -9.41061,5.11798 -14.4482,7.03241 2.64504,5.29451 5.70223,10.34483 9.15805,15.08268 13.95665,-4.34425 28.1523,-10.98282 42.78675,-21.92512 3.50912,-37.15724 -5.99459,-69.37299 -25.12176,-97.93671 z m -86.72985,78.22459 c -8.347289,0 -15.192739,-7.79268 -15.192739,-17.28227 0,-9.48958 6.69928,-17.29569 15.192739,-17.29569 8.49367,0 15.33891,7.79244 15.19272,17.29569 0.0124,9.48959 -6.69905,17.28227 -15.19272,17.28227 z m 56.14517,0 c -8.34727,0 -15.19272,-7.79268 -15.19272,-17.28227 0,-9.48958 6.69904,-17.29569 15.19272,-17.29569 8.49344,0 15.3389,7.79244 15.19272,17.29569 0,9.48959 -6.69928,17.28227 -15.19272,17.28227 z"
|
||||
fill="#5865F2"
|
||||
fill-rule="nonzero"
|
||||
id="path1-1"
|
||||
style="fill:#ffffff;stroke-width:0.660131" /></g></svg>
|
After Width: | Height: | Size: 2 KiB |
Before Width: | Height: | Size: 114 KiB After Width: | Height: | Size: 42 KiB |
22
src/images/github.svg
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="270.93332mm"
|
||||
height="270.93332mm"
|
||||
viewBox="0 0 270.93332 270.93332"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
xml:space="preserve"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs1" /><g
|
||||
id="layer1"><circle
|
||||
style="fill:#000000;fill-opacity:1;stroke-width:0.638749"
|
||||
id="path6"
|
||||
cx="135.46666"
|
||||
cy="135.46666"
|
||||
r="135.46666" /><path
|
||||
d="m 169.16642,266.41733 0.03,-25.82065 c 0.0275,-14.56818 0.019,-22.82654 -0.0238,-23.70553 -0.45287,-9.28878 -3.18131,-16.59646 -8.00675,-21.44417 -0.51833,-0.52073 -0.93407,-0.95373 -0.92397,-0.96273 0.0101,-0.009 0.44777,-0.0663 0.97255,-0.12764 37.08454,-4.33929 55.61974,-20.97235 59.5452,-53.43395 2.47353,-20.45482 -1.25492,-35.28308 -11.991,-47.687007 -0.441,-0.50949 -0.85644,-0.996495 -0.92294,-1.082105 -0.11924,-0.153612 -0.11632,-0.168083 0.21291,-1.092956 3.48926,-9.801891 3.08146,-21.84476 -1.12293,-33.147331 -0.65397,-1.758042 -0.47565,-1.634201 -2.5709,-1.78077 -7.91812,-0.553905 -20.35359,4.335862 -33.80673,13.293762 l -1.15135,0.766879 -0.52658,-0.150896 c -12.92077,-3.704851 -29.09272,-5.157035 -43.79112,-3.932576 -7.21573,0.601112 -14.83438,1.91638 -21.45193,3.70365 l -1.41438,0.381889 -0.95446,-0.635621 C 86.99336,60.049959 72.837429,54.806634 65.589795,56.343848 l -0.309542,0.06563 -0.326595,0.837675 c -4.332806,11.118399 -4.907871,23.48198 -1.547192,33.270837 0.236072,0.687637 0.444934,1.31371 0.464054,1.39113 0.02704,0.109638 -0.130307,0.328834 -0.711584,0.990637 -9.160582,10.429614 -13.392033,22.887494 -12.958383,38.152714 1.106869,38.96344 19.486075,58.39373 59.852157,63.27469 0.65144,0.0787 1.19093,0.14903 1.19993,0.15503 0.008,0.007 -0.42227,0.45425 -0.95705,0.99477 -3.85869,3.90015 -6.54793,9.80164 -7.46414,16.38039 l -0.0827,0.59221 -0.36174,0.17829 c -1.57996,0.77769 -4.999926,1.92702 -7.319448,2.4598 -12.017875,2.76038 -22.054909,-0.77155 -29.200801,-10.27535 -0.611821,-0.81369 -1.002109,-1.39605 -2.631881,-3.92379 -6.342866,-9.8377 -15.85558,-14.92007 -24.055896,-12.85296 -4.140227,1.04365 -2.520489,4.818 3.538802,8.24704 4.584375,2.59434 11.458806,12.02482 14.328324,19.65565 5.313949,14.13125 20.872615,19.63362 43.89345,15.52308 0.48859,-0.0872 0.93963,-0.15902 1.00303,-0.15916 0.10915,-2.5e-4 0.11524,0.79731 0.11524,15.82539 v 19.35334 a 135.46666,135.46666 0 0 0 33.40882,4.45244 135.46666,135.46666 0 0 0 33.69975,-4.516 z"
|
||||
style="fill:#ffffff;stroke-width:0.777192"
|
||||
id="path5" /></g></svg>
|
After Width: | Height: | Size: 2.6 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
22
src/images/ko-fi.svg
Normal file
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="270.93332mm"
|
||||
height="270.93332mm"
|
||||
viewBox="0 0 270.93332 270.93332"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
xml:space="preserve"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs1" /><g
|
||||
id="layer1"><circle
|
||||
style="fill:#000000;fill-opacity:1;stroke-width:0.638749"
|
||||
id="path6"
|
||||
cx="135.46666"
|
||||
cy="135.46666"
|
||||
r="135.46666" /><path
|
||||
d="M 245.29662,112.91788 C 238.59944,77.525962 203.19888,73.124713 203.19888,73.124713 H 44.658761 c -5.232973,0 -5.882763,6.913782 -5.882763,6.913782 0,0 -0.710438,63.454165 -0.190612,102.424225 1.420874,21.00124 22.404764,23.14987 22.404764,23.14987 0,0 71.62419,-0.19923 103.67183,-0.42453 21.12252,-3.69082 23.24517,-22.23147 23.02856,-32.35089 37.70517,2.07933 64.30326,-24.52739 57.60608,-59.91929 z m -95.83971,30.41882 c -10.79518,12.58861 -34.75078,34.44754 -34.75078,34.44754 0,0 -1.04833,1.031 -2.6858,0.19924 -0.65845,-0.49382 -0.93569,-0.77972 -0.93569,-0.77972 -3.83809,-3.82079 -29.179908,-26.41616 -34.950046,-34.25694 -6.14268,-8.36065 -9.019085,-23.39244 -0.788412,-32.14296 8.239342,-8.75052 26.034928,-9.40895 37.800448,3.5262 0,0 13.55896,-15.439026 30.0463,-8.34332 16.49601,7.1044 15.8722,26.0869 6.26398,37.34992 z m 53.48205,4.14135 c -8.04007,1.00499 -14.57263,0.24252 -14.57263,0.24252 V 98.501153 h 15.33506 c 0,0 17.07647,4.773777 17.07647,22.855257 0,16.57399 -8.53391,23.10655 -17.8389,26.12157 z"
|
||||
id="path1"
|
||||
style="fill:#ffffff;stroke-width:8.66388" /></g></svg>
|
After Width: | Height: | Size: 1.6 KiB |
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 401 KiB |
BIN
src/images/shadps4.png
Normal file
After Width: | Height: | Size: 34 KiB |
105
src/images/shadps4.svg
Normal file
|
@ -0,0 +1,105 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
version="1.1"
|
||||
viewBox="0 0 256 256"
|
||||
xml:space="preserve"
|
||||
id="svg10"
|
||||
width="256"
|
||||
height="256"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs3"><linearGradient
|
||||
id="linearGradient1"><stop
|
||||
stop-color="#0b034f"
|
||||
offset="0"
|
||||
id="stop1" /><stop
|
||||
stop-color="#4461f2"
|
||||
offset="1"
|
||||
id="stop2" /></linearGradient><linearGradient
|
||||
id="linearGradient2"
|
||||
x1="100"
|
||||
x2="100"
|
||||
y1="185.84"
|
||||
y2="14.157"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
xlink:href="#linearGradient1"
|
||||
gradientTransform="matrix(1.4489308,0,0,1.4489308,-16.890188,-16.890188)" /><mask
|
||||
id="mask9"
|
||||
maskUnits="userSpaceOnUse"><path
|
||||
d="m -4.1597,120.43 65.304,22.774 -20.899,59.926 -65.304,-22.774 z"
|
||||
fill="none"
|
||||
stroke="#149ffb"
|
||||
stroke-linecap="square"
|
||||
stroke-width="11"
|
||||
style="paint-order:markers fill stroke"
|
||||
id="path2" /></mask><mask
|
||||
id="mask10"
|
||||
maskUnits="userSpaceOnUse"><path
|
||||
d="M 178.79,52.448 133.386,71.834 139.2995,22.82 Z"
|
||||
fill="none"
|
||||
stroke="#149ffb"
|
||||
stroke-linecap="square"
|
||||
stroke-width="6.75"
|
||||
style="paint-order:markers fill stroke"
|
||||
id="path3" /></mask><linearGradient
|
||||
xlink:href="#linearGradient1"
|
||||
id="linearGradient10"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
x1="100"
|
||||
y1="185.84"
|
||||
x2="100"
|
||||
y2="14.157"
|
||||
gradientTransform="matrix(1.4489308,0,0,1.4489308,-16.890188,-16.890188)" /></defs><path
|
||||
d="M 53.640867,3.6223249 H 202.35913 c 27.70935,0 50.01854,22.3077391 50.01854,50.0185421 V 202.35913 c 0,27.70935 -22.30774,50.01854 -50.01854,50.01854 H 53.640867 c -27.709354,0 -50.0185421,-22.30774 -50.0185421,-50.01854 V 53.640867 c 0,-27.709354 22.3077391,-50.0185421 50.0185421,-50.0185421 z"
|
||||
fill="url(#linearGradient2)"
|
||||
stroke="#ffffff"
|
||||
stroke-linecap="square"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="7.24465"
|
||||
style="fill:url(#linearGradient10);paint-order:markers fill stroke"
|
||||
id="path4" /><path
|
||||
d="M 53.640867,3.6223249 H 202.35913 c 27.70935,0 50.01854,22.3077391 50.01854,50.0185421 V 202.35913 c 0,27.70935 -22.30774,50.01854 -50.01854,50.01854 H 53.640867 c -27.709354,0 -50.0185421,-22.30774 -50.0185421,-50.01854 V 53.640867 c 0,-27.709354 22.3077391,-50.0185421 50.0185421,-50.0185421 z"
|
||||
fill="url(#linearGradient2)"
|
||||
stroke="#ffffff"
|
||||
stroke-linecap="square"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="7.24465"
|
||||
style="fill:url(#linearGradient2);paint-order:markers fill stroke"
|
||||
id="path5" /><path
|
||||
d="m 50.17,16.403 h 99.848 c 18.603,0 33.58,14.977 33.58,33.58 v 99.848 c 0,18.603 -14.977,33.58 -33.58,33.58 H 50.17 c -18.603,0 -33.58,-14.977 -33.58,-33.58 V 49.983 c 0,-18.603 14.977,-33.58 33.58,-33.58 z"
|
||||
fill="#00ffff"
|
||||
mask="url(#mask9)"
|
||||
style="paint-order:markers fill stroke"
|
||||
id="path6"
|
||||
transform="matrix(1.4489308,0,0,1.4489308,-16.890189,-16.890189)" /><path
|
||||
d="m 50.076,16.496 h 99.848 c 18.603,0 33.58,14.977 33.58,33.58 v 99.848 c 0,18.603 -14.977,33.58 -33.58,33.58 H 50.076 c -18.603,0 -33.58,-14.977 -33.58,-33.58 V 50.076 c 0,-18.603 14.977,-33.58 33.58,-33.58 z"
|
||||
fill="#00ffff"
|
||||
mask="url(#mask10)"
|
||||
style="paint-order:markers fill stroke"
|
||||
id="path7"
|
||||
transform="matrix(1.4489308,0,0,1.4489308,-16.890189,-16.890189)" /><g
|
||||
fill="none"
|
||||
id="g10"
|
||||
transform="matrix(1.4489308,0,0,1.4489308,-16.890189,-16.890189)"><path
|
||||
transform="matrix(0.91041,0.0063593,-0.0063593,0.91041,28.548,42.178)"
|
||||
d="m 166.13,88.68 -23.677,14.288 13.949,23.879 -14.288,-23.677 -23.879,13.949 23.677,-14.288 -13.949,-23.879 14.288,23.677 z"
|
||||
stroke="#139ffb"
|
||||
stroke-linecap="square"
|
||||
stroke-width="12.43"
|
||||
style="paint-order:markers fill stroke"
|
||||
id="path8" /><path
|
||||
d="M 117.98,135.88 V 47.598 l -65.093,69.568 h 83.807"
|
||||
stroke="#ffffff"
|
||||
stroke-linecap="square"
|
||||
stroke-linejoin="round"
|
||||
stroke-width="10"
|
||||
style="font-variation-settings:normal;paint-order:markers fill stroke"
|
||||
id="path9" /><path
|
||||
d="M 69.923,56.468 A 20.994,21.009 0 0 1 49.012,77.477 20.994,21.009 0 0 1 27.936,56.634 20.994,21.009 0 0 1 48.68,35.46 20.994,21.009 0 0 1 69.92,56.135"
|
||||
stop-color="#000000"
|
||||
stroke="#139ffb"
|
||||
stroke-linecap="round"
|
||||
stroke-width="9.4488"
|
||||
style="paint-order:markers fill stroke"
|
||||
id="path10" /></g></svg>
|
After Width: | Height: | Size: 4.6 KiB |
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 72 KiB |
22
src/images/website.svg
Normal file
After Width: | Height: | Size: 6.1 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 32 KiB |
28
src/images/youtube.svg
Normal file
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
width="270.93332mm"
|
||||
height="270.93332mm"
|
||||
viewBox="0 0 270.93332 270.93332"
|
||||
version="1.1"
|
||||
id="svg1"
|
||||
xml:space="preserve"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"><defs
|
||||
id="defs1" /><g
|
||||
id="layer1"><circle
|
||||
style="fill:#000000;fill-opacity:1;stroke-width:0.638749"
|
||||
id="path6"
|
||||
cx="135.46666"
|
||||
cy="135.46666"
|
||||
r="135.46666" /><g
|
||||
style="fill:#ffffff;fill-rule:nonzero;stroke:none;stroke-width:0;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none"
|
||||
transform="matrix(1.8837557,0,0,1.8837557,50.69765,50.69765)"
|
||||
id="g1">
|
||||
<path
|
||||
d="M 88.119,23.338 C 87.084,19.466 84.034,16.416 80.162,15.381 73.144,13.5 45,13.5 45,13.5 c 0,0 -28.144,0 -35.162,1.881 C 5.966,16.416 2.916,19.466 1.881,23.338 0,30.356 0,45 0,45 0,45 0,59.644 1.881,66.662 2.916,70.534 5.966,73.584 9.838,74.619 16.856,76.5 45,76.5 45,76.5 c 0,0 28.144,0 35.162,-1.881 3.872,-1.035 6.922,-4.085 7.957,-7.957 C 90,59.644 90,45 90,45 90,45 90,30.356 88.119,23.338 Z M 36,58.5 v -27 L 59.382,45 Z"
|
||||
style="opacity:1;fill:#ffffff;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:10;stroke-dasharray:none"
|
||||
stroke-linecap="round"
|
||||
id="path1" />
|
||||
</g></g></svg>
|
After Width: | Height: | Size: 1.4 KiB |
|
@ -50,14 +50,14 @@ inline void KeepWindowInside(ImVec2 display_size = GetIO().DisplaySize) {
|
|||
}
|
||||
|
||||
inline void KeepNavHighlight() {
|
||||
GetCurrentContext()->NavDisableHighlight = false;
|
||||
GetCurrentContext()->NavCursorVisible = true;
|
||||
}
|
||||
|
||||
inline void SetItemCurrentNavFocus(const ImGuiID id = -1) {
|
||||
const auto ctx = GetCurrentContext();
|
||||
SetFocusID(id == -1 ? ctx->LastItemData.ID : id, ctx->CurrentWindow);
|
||||
ctx->NavInitResult.Clear();
|
||||
ctx->NavDisableHighlight = false;
|
||||
ctx->NavCursorVisible = true;
|
||||
}
|
||||
|
||||
inline void DrawPrettyBackground() {
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
#include "common/elf_info.h"
|
||||
#include "common/io_file.h"
|
||||
#include "common/path_util.h"
|
||||
#include "common/version.h"
|
||||
#include "input/controller.h"
|
||||
#include "input/input_mouse.h"
|
||||
|
||||
|
@ -551,18 +550,18 @@ void ControllerOutput::FinalizeUpdate() {
|
|||
break;
|
||||
case Axis::TriggerLeft:
|
||||
ApplyDeadzone(new_param, lefttrigger_deadzone);
|
||||
controller->Axis(0, c_axis, GetAxis(0x0, 0x80, *new_param));
|
||||
controller->Axis(0, c_axis, GetAxis(0x0, 0x7f, *new_param));
|
||||
controller->CheckButton(0, OrbisPadButtonDataOffset::L2, *new_param > 0x20);
|
||||
return;
|
||||
case Axis::TriggerRight:
|
||||
ApplyDeadzone(new_param, righttrigger_deadzone);
|
||||
controller->Axis(0, c_axis, GetAxis(0x0, 0x80, *new_param));
|
||||
controller->Axis(0, c_axis, GetAxis(0x0, 0x7f, *new_param));
|
||||
controller->CheckButton(0, OrbisPadButtonDataOffset::R2, *new_param > 0x20);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
controller->Axis(0, c_axis, GetAxis(-0x80, 0x80, *new_param * multiplier));
|
||||
controller->Axis(0, c_axis, GetAxis(-0x80, 0x7f, *new_param * multiplier));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -61,11 +61,11 @@ Uint32 MousePolling(void* param, Uint32 id, Uint32 interval) {
|
|||
float a_x = cos(angle) * output_speed, a_y = sin(angle) * output_speed;
|
||||
|
||||
if (d_x != 0 && d_y != 0) {
|
||||
controller->Axis(0, axis_x, GetAxis(-0x80, 0x80, a_x));
|
||||
controller->Axis(0, axis_y, GetAxis(-0x80, 0x80, a_y));
|
||||
controller->Axis(0, axis_x, GetAxis(-0x80, 0x7f, a_x));
|
||||
controller->Axis(0, axis_y, GetAxis(-0x80, 0x7f, a_y));
|
||||
} else {
|
||||
controller->Axis(0, axis_x, GetAxis(-0x80, 0x80, 0));
|
||||
controller->Axis(0, axis_y, GetAxis(-0x80, 0x80, 0));
|
||||
controller->Axis(0, axis_x, GetAxis(-0x80, 0x7f, 0));
|
||||
controller->Axis(0, axis_y, GetAxis(-0x80, 0x7f, 0));
|
||||
}
|
||||
|
||||
return interval;
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
<string/>
|
||||
</property>
|
||||
<property name="pixmap">
|
||||
<pixmap>:/images/shadps4.ico</pixmap>
|
||||
<pixmap>:/images/shadps4.png</pixmap>
|
||||
</property>
|
||||
<property name="scaledContents">
|
||||
<bool>true</bool>
|
||||
|
|
|
@ -24,7 +24,6 @@
|
|||
#include <common/config.h>
|
||||
#include <common/path_util.h>
|
||||
#include <common/scm_rev.h>
|
||||
#include <common/version.h>
|
||||
#include "check_update.h"
|
||||
|
||||
using namespace Common::FS;
|
||||
|
@ -52,7 +51,7 @@ void CheckUpdate::CheckForUpdates(const bool showMessage) {
|
|||
url = QUrl("https://api.github.com/repos/shadps4-emu/shadPS4/releases/latest");
|
||||
checkName = false;
|
||||
} else {
|
||||
if (Common::isRelease) {
|
||||
if (Common::g_is_release) {
|
||||
Config::setUpdateChannel("Release");
|
||||
} else {
|
||||
Config::setUpdateChannel("Nightly");
|
||||
|
@ -162,7 +161,7 @@ tr("The Auto Updater allows up to 60 update checks per hour.\\nYou have reached
|
|||
|
||||
QString currentRev = (updateChannel == "Nightly")
|
||||
? QString::fromStdString(Common::g_scm_rev)
|
||||
: "v." + QString::fromStdString(Common::VERSION);
|
||||
: "v." + QString::fromStdString(Common::g_version);
|
||||
QString currentDate = Common::g_scm_date;
|
||||
|
||||
QDateTime dateTime = QDateTime::fromString(latestDate, Qt::ISODate);
|
||||
|
@ -189,7 +188,7 @@ void CheckUpdate::setupUI(const QString& downloadUrl, const QString& latestDate,
|
|||
QHBoxLayout* titleLayout = new QHBoxLayout();
|
||||
|
||||
QLabel* imageLabel = new QLabel(this);
|
||||
QPixmap pixmap(":/images/shadps4.ico");
|
||||
QPixmap pixmap(":/images/shadps4.png");
|
||||
imageLabel->setPixmap(pixmap);
|
||||
imageLabel->setScaledContents(true);
|
||||
imageLabel->setFixedSize(50, 50);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include "cheats_patches.h"
|
||||
#include "common/config.h"
|
||||
#include "common/path_util.h"
|
||||
#include "common/version.h"
|
||||
#include "common/scm_rev.h"
|
||||
#include "compatibility_info.h"
|
||||
#include "game_info.h"
|
||||
#include "trophy_viewer.h"
|
||||
|
@ -115,14 +115,15 @@ public:
|
|||
|
||||
compatibilityMenu->addAction(updateCompatibility);
|
||||
compatibilityMenu->addAction(viewCompatibilityReport);
|
||||
if (Common::isRelease) {
|
||||
if (Common::g_is_release) {
|
||||
compatibilityMenu->addAction(submitCompatibilityReport);
|
||||
}
|
||||
|
||||
menu.addMenu(compatibilityMenu);
|
||||
|
||||
compatibilityMenu->setEnabled(Config::getCompatibilityEnabled());
|
||||
viewCompatibilityReport->setEnabled(!m_games[itemID].compatibility.url.isEmpty());
|
||||
viewCompatibilityReport->setEnabled(m_games[itemID].compatibility.status !=
|
||||
CompatibilityStatus::Unknown);
|
||||
|
||||
// Show menu.
|
||||
auto selected = menu.exec(global_pos);
|
||||
|
@ -557,24 +558,36 @@ public:
|
|||
}
|
||||
|
||||
if (selected == viewCompatibilityReport) {
|
||||
if (!m_games[itemID].compatibility.url.isEmpty())
|
||||
QDesktopServices::openUrl(QUrl(m_games[itemID].compatibility.url));
|
||||
if (m_games[itemID].compatibility.issue_number != "") {
|
||||
auto url_issues =
|
||||
"https://github.com/shadps4-emu/shadps4-game-compatibility/issues/";
|
||||
QDesktopServices::openUrl(
|
||||
QUrl(url_issues + m_games[itemID].compatibility.issue_number));
|
||||
}
|
||||
}
|
||||
|
||||
if (selected == submitCompatibilityReport) {
|
||||
QUrl url = QUrl("https://github.com/shadps4-emu/shadps4-game-compatibility/issues/new");
|
||||
QUrlQuery query;
|
||||
query.addQueryItem("template", QString("game_compatibility.yml"));
|
||||
query.addQueryItem(
|
||||
"title", QString("%1 - %2").arg(QString::fromStdString(m_games[itemID].serial),
|
||||
QString::fromStdString(m_games[itemID].name)));
|
||||
query.addQueryItem("game-name", QString::fromStdString(m_games[itemID].name));
|
||||
query.addQueryItem("game-serial", QString::fromStdString(m_games[itemID].serial));
|
||||
query.addQueryItem("game-version", QString::fromStdString(m_games[itemID].version));
|
||||
query.addQueryItem("emulator-version", QString(Common::VERSION));
|
||||
url.setQuery(query);
|
||||
if (m_games[itemID].compatibility.issue_number == "") {
|
||||
QUrl url =
|
||||
QUrl("https://github.com/shadps4-emu/shadps4-game-compatibility/issues/new");
|
||||
QUrlQuery query;
|
||||
query.addQueryItem("template", QString("game_compatibility.yml"));
|
||||
query.addQueryItem(
|
||||
"title", QString("%1 - %2").arg(QString::fromStdString(m_games[itemID].serial),
|
||||
QString::fromStdString(m_games[itemID].name)));
|
||||
query.addQueryItem("game-name", QString::fromStdString(m_games[itemID].name));
|
||||
query.addQueryItem("game-serial", QString::fromStdString(m_games[itemID].serial));
|
||||
query.addQueryItem("game-version", QString::fromStdString(m_games[itemID].version));
|
||||
query.addQueryItem("emulator-version", QString(Common::g_version));
|
||||
url.setQuery(query);
|
||||
|
||||
QDesktopServices::openUrl(url);
|
||||
QDesktopServices::openUrl(url);
|
||||
} else {
|
||||
auto url_issues =
|
||||
"https://github.com/shadps4-emu/shadps4-game-compatibility/issues/";
|
||||
QDesktopServices::openUrl(
|
||||
QUrl(url_issues + m_games[itemID].compatibility.issue_number));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -127,58 +127,9 @@ tr("Do you want to overwrite existing mappings with the mappings from the Common
|
|||
}
|
||||
|
||||
void KBMSettings::ButtonConnects() {
|
||||
connect(ui->CrossButton, &QPushButton::clicked, this,
|
||||
[this]() { StartTimer(ui->CrossButton); });
|
||||
connect(ui->CircleButton, &QPushButton::clicked, this,
|
||||
[this]() { StartTimer(ui->CircleButton); });
|
||||
connect(ui->TriangleButton, &QPushButton::clicked, this,
|
||||
[this]() { StartTimer(ui->TriangleButton); });
|
||||
connect(ui->SquareButton, &QPushButton::clicked, this,
|
||||
[this]() { StartTimer(ui->SquareButton); });
|
||||
|
||||
connect(ui->L1Button, &QPushButton::clicked, this, [this]() { StartTimer(ui->L1Button); });
|
||||
connect(ui->L2Button, &QPushButton::clicked, this, [this]() { StartTimer(ui->L2Button); });
|
||||
connect(ui->L3Button, &QPushButton::clicked, this, [this]() { StartTimer(ui->L3Button); });
|
||||
connect(ui->R1Button, &QPushButton::clicked, this, [this]() { StartTimer(ui->R1Button); });
|
||||
connect(ui->R2Button, &QPushButton::clicked, this, [this]() { StartTimer(ui->R2Button); });
|
||||
connect(ui->R3Button, &QPushButton::clicked, this, [this]() { StartTimer(ui->R3Button); });
|
||||
|
||||
connect(ui->TouchpadButton, &QPushButton::clicked, this,
|
||||
[this]() { StartTimer(ui->TouchpadButton); });
|
||||
connect(ui->OptionsButton, &QPushButton::clicked, this,
|
||||
[this]() { StartTimer(ui->OptionsButton); });
|
||||
|
||||
connect(ui->DpadUpButton, &QPushButton::clicked, this,
|
||||
[this]() { StartTimer(ui->DpadUpButton); });
|
||||
connect(ui->DpadDownButton, &QPushButton::clicked, this,
|
||||
[this]() { StartTimer(ui->DpadDownButton); });
|
||||
connect(ui->DpadLeftButton, &QPushButton::clicked, this,
|
||||
[this]() { StartTimer(ui->DpadLeftButton); });
|
||||
connect(ui->DpadRightButton, &QPushButton::clicked, this,
|
||||
[this]() { StartTimer(ui->DpadRightButton); });
|
||||
|
||||
connect(ui->LStickUpButton, &QPushButton::clicked, this,
|
||||
[this]() { StartTimer(ui->LStickUpButton); });
|
||||
connect(ui->LStickDownButton, &QPushButton::clicked, this,
|
||||
[this]() { StartTimer(ui->LStickDownButton); });
|
||||
connect(ui->LStickLeftButton, &QPushButton::clicked, this,
|
||||
[this]() { StartTimer(ui->LStickLeftButton); });
|
||||
connect(ui->LStickRightButton, &QPushButton::clicked, this,
|
||||
[this]() { StartTimer(ui->LStickRightButton); });
|
||||
|
||||
connect(ui->RStickUpButton, &QPushButton::clicked, this,
|
||||
[this]() { StartTimer(ui->RStickUpButton); });
|
||||
connect(ui->RStickDownButton, &QPushButton::clicked, this,
|
||||
[this]() { StartTimer(ui->RStickDownButton); });
|
||||
connect(ui->RStickLeftButton, &QPushButton::clicked, this,
|
||||
[this]() { StartTimer(ui->RStickLeftButton); });
|
||||
connect(ui->RStickRightButton, &QPushButton::clicked, this,
|
||||
[this]() { StartTimer(ui->RStickRightButton); });
|
||||
|
||||
connect(ui->LHalfButton, &QPushButton::clicked, this,
|
||||
[this]() { StartTimer(ui->LHalfButton); });
|
||||
connect(ui->RHalfButton, &QPushButton::clicked, this,
|
||||
[this]() { StartTimer(ui->RHalfButton); });
|
||||
for (auto& button : ButtonsList) {
|
||||
connect(button, &QPushButton::clicked, this, [this, &button]() { StartTimer(button); });
|
||||
}
|
||||
}
|
||||
|
||||
void KBMSettings::DisableMappingButtons() {
|
||||
|
|
|
@ -18,7 +18,6 @@
|
|||
#include "common/path_util.h"
|
||||
#include "common/scm_rev.h"
|
||||
#include "common/string_util.h"
|
||||
#include "common/version.h"
|
||||
#include "control_settings.h"
|
||||
#include "game_install_dialog.h"
|
||||
#include "kbm_gui.h"
|
||||
|
@ -58,8 +57,8 @@ bool MainWindow::Init() {
|
|||
// show ui
|
||||
setMinimumSize(720, 405);
|
||||
std::string window_title = "";
|
||||
if (Common::isRelease) {
|
||||
window_title = fmt::format("shadPS4 v{}", Common::VERSION);
|
||||
if (Common::g_is_release) {
|
||||
window_title = fmt::format("shadPS4 v{}", Common::g_version);
|
||||
} else {
|
||||
std::string remote_url(Common::g_scm_remote_url);
|
||||
std::string remote_host;
|
||||
|
@ -69,10 +68,10 @@ bool MainWindow::Init() {
|
|||
remote_host = "unknown";
|
||||
}
|
||||
if (remote_host == "shadps4-emu" || remote_url.length() == 0) {
|
||||
window_title = fmt::format("shadPS4 v{} {} {}", Common::VERSION, Common::g_scm_branch,
|
||||
window_title = fmt::format("shadPS4 v{} {} {}", Common::g_version, Common::g_scm_branch,
|
||||
Common::g_scm_desc);
|
||||
} else {
|
||||
window_title = fmt::format("shadPS4 v{} {}/{} {}", Common::VERSION, remote_host,
|
||||
window_title = fmt::format("shadPS4 v{} {}/{} {}", Common::g_version, remote_host,
|
||||
Common::g_scm_branch, Common::g_scm_desc);
|
||||
}
|
||||
}
|
||||
|
@ -517,9 +516,11 @@ void MainWindow::CreateConnects() {
|
|||
Config::setIconSize(36);
|
||||
Config::setSliderPosition(0);
|
||||
} else {
|
||||
m_game_grid_frame->icon_size = 69;
|
||||
ui->sizeSlider->setValue(0); // icone_size - 36
|
||||
Config::setIconSizeGrid(69);
|
||||
Config::setSliderPositionGrid(0);
|
||||
m_game_grid_frame->PopulateGameGrid(m_game_info->m_games, false);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -530,9 +531,11 @@ void MainWindow::CreateConnects() {
|
|||
Config::setIconSize(64);
|
||||
Config::setSliderPosition(28);
|
||||
} else {
|
||||
m_game_grid_frame->icon_size = 97;
|
||||
ui->sizeSlider->setValue(28);
|
||||
Config::setIconSizeGrid(97);
|
||||
Config::setSliderPositionGrid(28);
|
||||
m_game_grid_frame->PopulateGameGrid(m_game_info->m_games, false);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -543,9 +546,11 @@ void MainWindow::CreateConnects() {
|
|||
Config::setIconSize(128);
|
||||
Config::setSliderPosition(92);
|
||||
} else {
|
||||
m_game_grid_frame->icon_size = 161;
|
||||
ui->sizeSlider->setValue(92);
|
||||
Config::setIconSizeGrid(160);
|
||||
Config::setSliderPositionGrid(91);
|
||||
Config::setIconSizeGrid(161);
|
||||
Config::setSliderPositionGrid(92);
|
||||
m_game_grid_frame->PopulateGameGrid(m_game_info->m_games, false);
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -556,9 +561,11 @@ void MainWindow::CreateConnects() {
|
|||
Config::setIconSize(256);
|
||||
Config::setSliderPosition(220);
|
||||
} else {
|
||||
m_game_grid_frame->icon_size = 256;
|
||||
ui->sizeSlider->setValue(220);
|
||||
Config::setIconSizeGrid(256);
|
||||
Config::setSliderPositionGrid(220);
|
||||
m_game_grid_frame->PopulateGameGrid(m_game_info->m_games, false);
|
||||
}
|
||||
});
|
||||
// List
|
||||
|
@ -578,6 +585,7 @@ void MainWindow::CreateConnects() {
|
|||
ui->sizeSlider->setEnabled(true);
|
||||
ui->sizeSlider->setSliderPosition(slider_pos);
|
||||
ui->mw_searchbar->setText("");
|
||||
SetLastIconSizeBullet();
|
||||
});
|
||||
// Grid
|
||||
connect(ui->setlistModeGridAct, &QAction::triggered, m_dock_widget.data(), [this]() {
|
||||
|
@ -596,6 +604,7 @@ void MainWindow::CreateConnects() {
|
|||
ui->sizeSlider->setEnabled(true);
|
||||
ui->sizeSlider->setSliderPosition(slider_pos_grid);
|
||||
ui->mw_searchbar->setText("");
|
||||
SetLastIconSizeBullet();
|
||||
});
|
||||
// Elf Viewer
|
||||
connect(ui->setlistElfAct, &QAction::triggered, m_dock_widget.data(), [this]() {
|
||||
|
@ -607,6 +616,7 @@ void MainWindow::CreateConnects() {
|
|||
isTableList = false;
|
||||
ui->sizeSlider->setDisabled(true);
|
||||
Config::setTableMode(2);
|
||||
SetLastIconSizeBullet();
|
||||
});
|
||||
|
||||
// Cheats/Patches Download.
|
||||
|
@ -1032,19 +1042,37 @@ void MainWindow::SetLastUsedTheme() {
|
|||
void MainWindow::SetLastIconSizeBullet() {
|
||||
// set QAction bullet point if applicable
|
||||
int lastSize = Config::getIconSize();
|
||||
switch (lastSize) {
|
||||
case 36:
|
||||
ui->setIconSizeTinyAct->setChecked(true);
|
||||
break;
|
||||
case 64:
|
||||
ui->setIconSizeSmallAct->setChecked(true);
|
||||
break;
|
||||
case 128:
|
||||
ui->setIconSizeMediumAct->setChecked(true);
|
||||
break;
|
||||
case 256:
|
||||
ui->setIconSizeLargeAct->setChecked(true);
|
||||
break;
|
||||
int lastSizeGrid = Config::getIconSizeGrid();
|
||||
if (isTableList) {
|
||||
switch (lastSize) {
|
||||
case 36:
|
||||
ui->setIconSizeTinyAct->setChecked(true);
|
||||
break;
|
||||
case 64:
|
||||
ui->setIconSizeSmallAct->setChecked(true);
|
||||
break;
|
||||
case 128:
|
||||
ui->setIconSizeMediumAct->setChecked(true);
|
||||
break;
|
||||
case 256:
|
||||
ui->setIconSizeLargeAct->setChecked(true);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch (lastSizeGrid) {
|
||||
case 69:
|
||||
ui->setIconSizeTinyAct->setChecked(true);
|
||||
break;
|
||||
case 97:
|
||||
ui->setIconSizeSmallAct->setChecked(true);
|
||||
break;
|
||||
case 161:
|
||||
ui->setIconSizeMediumAct->setChecked(true);
|
||||
break;
|
||||
case 256:
|
||||
ui->setIconSizeLargeAct->setChecked(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -106,8 +106,6 @@ public:
|
|||
|
||||
toggleLabelsAct = new QAction(MainWindow);
|
||||
toggleLabelsAct->setObjectName("toggleLabelsAct");
|
||||
toggleLabelsAct->setText(
|
||||
QCoreApplication::translate("MainWindow", "Show Labels Under Icons"));
|
||||
toggleLabelsAct->setCheckable(true);
|
||||
toggleLabelsAct->setChecked(Config::getShowLabelsUnderIcons());
|
||||
|
||||
|
@ -413,6 +411,8 @@ public:
|
|||
setThemeTokyoNight->setText("Tokyo Night");
|
||||
setThemeOled->setText("OLED");
|
||||
toolBar->setWindowTitle(QCoreApplication::translate("MainWindow", "toolBar", nullptr));
|
||||
toggleLabelsAct->setText(
|
||||
QCoreApplication::translate("MainWindow", "Show Labels Under Icons"));
|
||||
} // retranslateUi
|
||||
};
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#include <fmt/format.h>
|
||||
|
||||
#include "common/config.h"
|
||||
#include "common/version.h"
|
||||
#include "common/scm_rev.h"
|
||||
#include "qt_gui/compatibility_info.h"
|
||||
#ifdef ENABLE_DISCORD_RPC
|
||||
#include "common/discord_rpc_handler.h"
|
||||
|
@ -491,7 +491,7 @@ void SettingsDialog::LoadValuesFromConfig() {
|
|||
QString updateChannel = QString::fromStdString(Config::getUpdateChannel());
|
||||
ui->updateComboBox->setCurrentText(
|
||||
channelMap.key(updateChannel != "Release" && updateChannel != "Nightly"
|
||||
? (Common::isRelease ? "Release" : "Nightly")
|
||||
? (Common::g_is_release ? "Release" : "Nightly")
|
||||
: updateChannel));
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1277,11 +1277,11 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Trophy Viewer</source>
|
||||
<translation type="unfinished">Trophy Viewer</translation>
|
||||
<translation>Trophäenansicht</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>No games found. Please add your games to your library first.</source>
|
||||
<translation type="unfinished">No games found. Please add your games to your library first.</translation>
|
||||
<translation>Keine Spiele gefunden. Bitte fügen Sie zuerst Ihre Spiele zu Ihrer Bibliothek hinzu.</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Search...</source>
|
||||
|
@ -1409,43 +1409,43 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Play</source>
|
||||
<translation type="unfinished">Play</translation>
|
||||
<translation>Spielen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Pause</source>
|
||||
<translation type="unfinished">Pause</translation>
|
||||
<translation>Pause</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Stop</source>
|
||||
<translation type="unfinished">Stop</translation>
|
||||
<translation>Stopp</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Restart</source>
|
||||
<translation type="unfinished">Restart</translation>
|
||||
<translation>Neustarten</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Full Screen</source>
|
||||
<translation type="unfinished">Full Screen</translation>
|
||||
<translation>Vollbild</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Controllers</source>
|
||||
<translation type="unfinished">Controllers</translation>
|
||||
<translation>Controller</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Keyboard</source>
|
||||
<translation type="unfinished">Keyboard</translation>
|
||||
<translation>Tastatur</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Refresh List</source>
|
||||
<translation type="unfinished">Refresh List</translation>
|
||||
<translation>Liste aktualisieren</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Resume</source>
|
||||
<translation type="unfinished">Resume</translation>
|
||||
<translation>Fortsetzen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Show Labels Under Icons</source>
|
||||
<translation type="unfinished">Show Labels Under Icons</translation>
|
||||
<translation>Etiketten unter Symbolen anzeigen</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -2048,7 +2048,11 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Open the custom trophy images/sounds folder:\nYou can add custom images to the trophies and an audio.\nAdd the files to custom_trophy with the following names:\ntrophy.wav OR trophy.mp3, bronze.png, gold.png, platinum.png, silver.png\nNote: The sound will only work in QT versions.</source>
|
||||
<translation type="unfinished">Open the custom trophy images/sounds folder:\nYou can add custom images to the trophies and an audio.\nAdd the files to custom_trophy with the following names:\ntrophy.wav OR trophy.mp3, bronze.png, gold.png, platinum.png, silver.png\nNote: The sound will only work in QT versions.</translation>
|
||||
<translation>Öffnen Sie den Ordner für benutzerdefinierte Trophäenbilder/-sounds:\n
|
||||
Sie können benutzerdefinierte Bilder zu den Trophäen hinzufügen und einen Ton hinzufügen.\n
|
||||
Fügen Sie die Dateien dem Ordner custom_trophy mit folgenden Namen hinzu:\n
|
||||
trophy.wav ODER trophy.mp3, bronze.png, gold.png, platinum.png, silver.png\n
|
||||
Hinweis: Der Sound funktioniert nur in Qt-Versionen.</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
@ -2059,23 +2063,23 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Select Game:</source>
|
||||
<translation type="unfinished">Select Game:</translation>
|
||||
<translation>Spiel auswählen:</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Progress</source>
|
||||
<translation type="unfinished">Progress</translation>
|
||||
<translation>Fortschritt</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Show Earned Trophies</source>
|
||||
<translation type="unfinished">Show Earned Trophies</translation>
|
||||
<translation>Verdiente Trophäen anzeigen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Show Not Earned Trophies</source>
|
||||
<translation type="unfinished">Show Not Earned Trophies</translation>
|
||||
<translation>Nicht verdiente Trophäen anzeigen</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Show Hidden Trophies</source>
|
||||
<translation type="unfinished">Show Hidden Trophies</translation>
|
||||
<translation>Verborgene Trophäen anzeigen</translation>
|
||||
</message>
|
||||
</context>
|
||||
</TS>
|
||||
|
|
|
@ -138,7 +138,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>File Exists</source>
|
||||
<translation>Il file è presente</translation>
|
||||
<translation>Il file esiste già </translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>File already exists. Do you want to replace it?</source>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
<name>AboutDialog</name>
|
||||
<message>
|
||||
<source>About shadPS4</source>
|
||||
<translation type="unfinished">About shadPS4</translation>
|
||||
<translation>Over shadPS4</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>shadPS4 is an experimental open-source emulator for the PlayStation 4.</source>
|
||||
|
@ -582,7 +582,7 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Could not open the file for reading</source>
|
||||
<translation type="unfinished">Could not open the file for reading</translation>
|
||||
<translation/>
|
||||
</message>
|
||||
<message>
|
||||
<source>Could not open the file for writing</source>
|
||||
|
|
2081
src/qt_gui/translations/sl_SI.ts
Normal file
|
@ -1409,43 +1409,43 @@
|
|||
</message>
|
||||
<message>
|
||||
<source>Play</source>
|
||||
<translation type="unfinished">Play</translation>
|
||||
<translation>Luaj</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Pause</source>
|
||||
<translation type="unfinished">Pause</translation>
|
||||
<translation>Pezullo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Stop</source>
|
||||
<translation type="unfinished">Stop</translation>
|
||||
<translation>Ndalo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Restart</source>
|
||||
<translation type="unfinished">Restart</translation>
|
||||
<translation>Rinis</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Full Screen</source>
|
||||
<translation type="unfinished">Full Screen</translation>
|
||||
<translation>Ekran i Plotë</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Controllers</source>
|
||||
<translation type="unfinished">Controllers</translation>
|
||||
<translation>Dorezat</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Keyboard</source>
|
||||
<translation type="unfinished">Keyboard</translation>
|
||||
<translation>Tastiera</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Refresh List</source>
|
||||
<translation type="unfinished">Refresh List</translation>
|
||||
<translation>Rifresko Listën</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Resume</source>
|
||||
<translation type="unfinished">Resume</translation>
|
||||
<translation>Rifillo</translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Show Labels Under Icons</source>
|
||||
<translation type="unfinished">Show Labels Under Icons</translation>
|
||||
<translation>Shfaq Etiketat Poshtë Ikonave</translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
#include "common/assert.h"
|
||||
#include "common/config.h"
|
||||
#include "common/elf_info.h"
|
||||
#include "common/version.h"
|
||||
#include "core/debug_state.h"
|
||||
#include "core/libraries/kernel/time.h"
|
||||
#include "core/libraries/pad/pad.h"
|
||||
|
|
|
@ -21,6 +21,15 @@ Id SharedAtomicU32(EmitContext& ctx, Id offset, Id value,
|
|||
return (ctx.*atomic_func)(ctx.U32[1], pointer, scope, semantics, value);
|
||||
}
|
||||
|
||||
Id SharedAtomicU32_IncDec(EmitContext& ctx, Id offset,
|
||||
Id (Sirit::Module::*atomic_func)(Id, Id, Id, Id)) {
|
||||
const Id shift_id{ctx.ConstU32(2U)};
|
||||
const Id index{ctx.OpShiftRightArithmetic(ctx.U32[1], offset, shift_id)};
|
||||
const Id pointer{ctx.OpAccessChain(ctx.shared_u32, ctx.shared_memory_u32, index)};
|
||||
const auto [scope, semantics]{AtomicArgs(ctx)};
|
||||
return (ctx.*atomic_func)(ctx.U32[1], pointer, scope, semantics);
|
||||
}
|
||||
|
||||
Id BufferAtomicU32BoundsCheck(EmitContext& ctx, Id index, Id buffer_size, auto emit_func) {
|
||||
if (Sirit::ValidId(buffer_size)) {
|
||||
// Bounds checking enabled, wrap in a conditional branch to make sure that
|
||||
|
@ -99,6 +108,18 @@ Id EmitSharedAtomicXor32(EmitContext& ctx, Id offset, Id value) {
|
|||
return SharedAtomicU32(ctx, offset, value, &Sirit::Module::OpAtomicXor);
|
||||
}
|
||||
|
||||
Id EmitSharedAtomicISub32(EmitContext& ctx, Id offset, Id value) {
|
||||
return SharedAtomicU32(ctx, offset, value, &Sirit::Module::OpAtomicISub);
|
||||
}
|
||||
|
||||
Id EmitSharedAtomicIIncrement32(EmitContext& ctx, Id offset) {
|
||||
return SharedAtomicU32_IncDec(ctx, offset, &Sirit::Module::OpAtomicIIncrement);
|
||||
}
|
||||
|
||||
Id EmitSharedAtomicIDecrement32(EmitContext& ctx, Id offset) {
|
||||
return SharedAtomicU32_IncDec(ctx, offset, &Sirit::Module::OpAtomicIDecrement);
|
||||
}
|
||||
|
||||
Id EmitBufferAtomicIAdd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) {
|
||||
return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicIAdd);
|
||||
}
|
||||
|
|
|
@ -75,6 +75,28 @@ Id EmitFPMin64(EmitContext& ctx, Id a, Id b) {
|
|||
return ctx.OpFMin(ctx.F64[1], a, b);
|
||||
}
|
||||
|
||||
Id EmitFPMinTri32(EmitContext& ctx, Id a, Id b, Id c) {
|
||||
if (ctx.profile.supports_trinary_minmax) {
|
||||
return ctx.OpFMin3AMD(ctx.F32[1], a, b, c);
|
||||
}
|
||||
return ctx.OpFMin(ctx.F32[1], a, ctx.OpFMin(ctx.F32[1], b, c));
|
||||
}
|
||||
|
||||
Id EmitFPMaxTri32(EmitContext& ctx, Id a, Id b, Id c) {
|
||||
if (ctx.profile.supports_trinary_minmax) {
|
||||
return ctx.OpFMax3AMD(ctx.F32[1], a, b, c);
|
||||
}
|
||||
return ctx.OpFMax(ctx.F32[1], a, ctx.OpFMax(ctx.F32[1], b, c));
|
||||
}
|
||||
|
||||
Id EmitFPMedTri32(EmitContext& ctx, Id a, Id b, Id c) {
|
||||
if (ctx.profile.supports_trinary_minmax) {
|
||||
return ctx.OpFMid3AMD(ctx.F32[1], a, b, c);
|
||||
}
|
||||
const Id mmx{ctx.OpFMin(ctx.F32[1], ctx.OpFMax(ctx.F32[1], a, b), c)};
|
||||
return ctx.OpFMax(ctx.F32[1], ctx.OpFMin(ctx.F32[1], a, b), mmx);
|
||||
}
|
||||
|
||||
Id EmitFPMul16(EmitContext& ctx, IR::Inst* inst, Id a, Id b) {
|
||||
return Decorate(ctx, inst, ctx.OpFMul(ctx.F16[1], a, b));
|
||||
}
|
||||
|
@ -245,12 +267,12 @@ Id EmitFPFrexpSig64(EmitContext& ctx, Id value) {
|
|||
|
||||
Id EmitFPFrexpExp32(EmitContext& ctx, Id value) {
|
||||
const auto frexp = ctx.OpFrexpStruct(ctx.frexp_result_f32, value);
|
||||
return ctx.OpCompositeExtract(ctx.U32[1], frexp, 1);
|
||||
return ctx.OpBitcast(ctx.U32[1], ctx.OpCompositeExtract(ctx.S32[1], frexp, 1));
|
||||
}
|
||||
|
||||
Id EmitFPFrexpExp64(EmitContext& ctx, Id value) {
|
||||
const auto frexp = ctx.OpFrexpStruct(ctx.frexp_result_f64, value);
|
||||
return ctx.OpCompositeExtract(ctx.U32[1], frexp, 1);
|
||||
return ctx.OpBitcast(ctx.U32[1], ctx.OpCompositeExtract(ctx.S32[1], frexp, 1));
|
||||
}
|
||||
|
||||
Id EmitFPOrdEqual16(EmitContext& ctx, Id lhs, Id rhs) {
|
||||
|
|
|
@ -130,6 +130,10 @@ Id EmitSharedAtomicSMin32(EmitContext& ctx, Id offset, Id value);
|
|||
Id EmitSharedAtomicAnd32(EmitContext& ctx, Id offset, Id value);
|
||||
Id EmitSharedAtomicOr32(EmitContext& ctx, Id offset, Id value);
|
||||
Id EmitSharedAtomicXor32(EmitContext& ctx, Id offset, Id value);
|
||||
Id EmitSharedAtomicIIncrement32(EmitContext& ctx, Id offset);
|
||||
Id EmitSharedAtomicIDecrement32(EmitContext& ctx, Id offset);
|
||||
Id EmitSharedAtomicISub32(EmitContext& ctx, Id offset, Id value);
|
||||
|
||||
Id EmitCompositeConstructU32x2(EmitContext& ctx, IR::Inst* inst, Id e1, Id e2);
|
||||
Id EmitCompositeConstructU32x3(EmitContext& ctx, IR::Inst* inst, Id e1, Id e2, Id e3);
|
||||
Id EmitCompositeConstructU32x4(EmitContext& ctx, IR::Inst* inst, Id e1, Id e2, Id e3, Id e4);
|
||||
|
@ -247,6 +251,9 @@ Id EmitFPMax32(EmitContext& ctx, Id a, Id b, bool is_legacy = false);
|
|||
Id EmitFPMax64(EmitContext& ctx, Id a, Id b);
|
||||
Id EmitFPMin32(EmitContext& ctx, Id a, Id b, bool is_legacy = false);
|
||||
Id EmitFPMin64(EmitContext& ctx, Id a, Id b);
|
||||
Id EmitFPMinTri32(EmitContext& ctx, Id a, Id b, Id c);
|
||||
Id EmitFPMaxTri32(EmitContext& ctx, Id a, Id b, Id c);
|
||||
Id EmitFPMedTri32(EmitContext& ctx, Id a, Id b, Id c);
|
||||
Id EmitFPMul16(EmitContext& ctx, IR::Inst* inst, Id a, Id b);
|
||||
Id EmitFPMul32(EmitContext& ctx, IR::Inst* inst, Id a, Id b);
|
||||
Id EmitFPMul64(EmitContext& ctx, IR::Inst* inst, Id a, Id b);
|
||||
|
@ -335,8 +342,8 @@ Id EmitIAdd64(EmitContext& ctx, Id a, Id b);
|
|||
Id EmitIAddCary32(EmitContext& ctx, Id a, Id b);
|
||||
Id EmitISub32(EmitContext& ctx, Id a, Id b);
|
||||
Id EmitISub64(EmitContext& ctx, Id a, Id b);
|
||||
Id EmitSMulExt(EmitContext& ctx, Id a, Id b);
|
||||
Id EmitUMulExt(EmitContext& ctx, Id a, Id b);
|
||||
Id EmitSMulHi(EmitContext& ctx, Id a, Id b);
|
||||
Id EmitUMulHi(EmitContext& ctx, Id a, Id b);
|
||||
Id EmitIMul32(EmitContext& ctx, Id a, Id b);
|
||||
Id EmitIMul64(EmitContext& ctx, Id a, Id b);
|
||||
Id EmitSDiv32(EmitContext& ctx, Id a, Id b);
|
||||
|
@ -372,6 +379,12 @@ Id EmitSMin32(EmitContext& ctx, Id a, Id b);
|
|||
Id EmitUMin32(EmitContext& ctx, Id a, Id b);
|
||||
Id EmitSMax32(EmitContext& ctx, Id a, Id b);
|
||||
Id EmitUMax32(EmitContext& ctx, Id a, Id b);
|
||||
Id EmitSMinTri32(EmitContext& ctx, Id a, Id b, Id c);
|
||||
Id EmitUMinTri32(EmitContext& ctx, Id a, Id b, Id c);
|
||||
Id EmitSMaxTri32(EmitContext& ctx, Id a, Id b, Id c);
|
||||
Id EmitUMaxTri32(EmitContext& ctx, Id a, Id b, Id c);
|
||||
Id EmitSMedTri32(EmitContext& ctx, Id a, Id b, Id c);
|
||||
Id EmitUMedTri32(EmitContext& ctx, Id a, Id b, Id c);
|
||||
Id EmitSClamp32(EmitContext& ctx, IR::Inst* inst, Id value, Id min, Id max);
|
||||
Id EmitUClamp32(EmitContext& ctx, IR::Inst* inst, Id value, Id min, Id max);
|
||||
Id EmitSLessThan32(EmitContext& ctx, Id lhs, Id rhs);
|
||||
|
|
|
@ -72,12 +72,17 @@ Id EmitISub64(EmitContext& ctx, Id a, Id b) {
|
|||
return ctx.OpISub(ctx.U64, a, b);
|
||||
}
|
||||
|
||||
Id EmitSMulExt(EmitContext& ctx, Id a, Id b) {
|
||||
return ctx.OpSMulExtended(ctx.full_result_i32x2, a, b);
|
||||
Id EmitSMulHi(EmitContext& ctx, Id a, Id b) {
|
||||
const auto signed_a{ctx.OpBitcast(ctx.S32[1], a)};
|
||||
const auto signed_b{ctx.OpBitcast(ctx.S32[1], b)};
|
||||
const auto mul_ext{ctx.OpSMulExtended(ctx.full_result_i32x2, signed_a, signed_b)};
|
||||
const auto signed_hi{ctx.OpCompositeExtract(ctx.S32[1], mul_ext, 1)};
|
||||
return ctx.OpBitcast(ctx.U32[1], signed_hi);
|
||||
}
|
||||
|
||||
Id EmitUMulExt(EmitContext& ctx, Id a, Id b) {
|
||||
return ctx.OpUMulExtended(ctx.full_result_u32x2, a, b);
|
||||
Id EmitUMulHi(EmitContext& ctx, Id a, Id b) {
|
||||
const auto mul_ext{ctx.OpUMulExtended(ctx.full_result_u32x2, a, b)};
|
||||
return ctx.OpCompositeExtract(ctx.U32[1], mul_ext, 1);
|
||||
}
|
||||
|
||||
Id EmitIMul32(EmitContext& ctx, Id a, Id b) {
|
||||
|
@ -256,6 +261,50 @@ Id EmitUMax32(EmitContext& ctx, Id a, Id b) {
|
|||
return ctx.OpUMax(ctx.U32[1], a, b);
|
||||
}
|
||||
|
||||
Id EmitSMinTri32(EmitContext& ctx, Id a, Id b, Id c) {
|
||||
if (ctx.profile.supports_trinary_minmax) {
|
||||
return ctx.OpSMin3AMD(ctx.U32[1], a, b, c);
|
||||
}
|
||||
return ctx.OpSMin(ctx.U32[1], a, ctx.OpSMin(ctx.U32[1], b, c));
|
||||
}
|
||||
|
||||
Id EmitUMinTri32(EmitContext& ctx, Id a, Id b, Id c) {
|
||||
if (ctx.profile.supports_trinary_minmax) {
|
||||
return ctx.OpUMin3AMD(ctx.U32[1], a, b, c);
|
||||
}
|
||||
return ctx.OpUMin(ctx.U32[1], a, ctx.OpUMin(ctx.U32[1], b, c));
|
||||
}
|
||||
|
||||
Id EmitSMaxTri32(EmitContext& ctx, Id a, Id b, Id c) {
|
||||
if (ctx.profile.supports_trinary_minmax) {
|
||||
return ctx.OpSMax3AMD(ctx.U32[1], a, b, c);
|
||||
}
|
||||
return ctx.OpSMax(ctx.U32[1], a, ctx.OpSMax(ctx.U32[1], b, c));
|
||||
}
|
||||
|
||||
Id EmitUMaxTri32(EmitContext& ctx, Id a, Id b, Id c) {
|
||||
if (ctx.profile.supports_trinary_minmax) {
|
||||
return ctx.OpUMax3AMD(ctx.U32[1], a, b, c);
|
||||
}
|
||||
return ctx.OpUMax(ctx.U32[1], a, ctx.OpUMax(ctx.U32[1], b, c));
|
||||
}
|
||||
|
||||
Id EmitSMedTri32(EmitContext& ctx, Id a, Id b, Id c) {
|
||||
if (ctx.profile.supports_trinary_minmax) {
|
||||
return ctx.OpSMid3AMD(ctx.U32[1], a, b, c);
|
||||
}
|
||||
const Id mmx{ctx.OpSMin(ctx.U32[1], ctx.OpSMax(ctx.U32[1], a, b), c)};
|
||||
return ctx.OpSMax(ctx.U32[1], ctx.OpSMin(ctx.U32[1], a, b), mmx);
|
||||
}
|
||||
|
||||
Id EmitUMedTri32(EmitContext& ctx, Id a, Id b, Id c) {
|
||||
if (ctx.profile.supports_trinary_minmax) {
|
||||
return ctx.OpUMid3AMD(ctx.U32[1], a, b, c);
|
||||
}
|
||||
const Id mmx{ctx.OpUMin(ctx.U32[1], ctx.OpUMax(ctx.U32[1], a, b), c)};
|
||||
return ctx.OpUMax(ctx.U32[1], ctx.OpUMin(ctx.U32[1], a, b), mmx);
|
||||
}
|
||||
|
||||
Id EmitSClamp32(EmitContext& ctx, IR::Inst* inst, Id value, Id min, Id max) {
|
||||
Id result{};
|
||||
if (ctx.profile.has_broken_spirv_clamp) {
|
||||
|
|
|
@ -153,9 +153,9 @@ void EmitContext::DefineArithmeticTypes() {
|
|||
|
||||
full_result_i32x2 = Name(TypeStruct(S32[1], S32[1]), "full_result_i32x2");
|
||||
full_result_u32x2 = Name(TypeStruct(U32[1], U32[1]), "full_result_u32x2");
|
||||
frexp_result_f32 = Name(TypeStruct(F32[1], U32[1]), "frexp_result_f32");
|
||||
frexp_result_f32 = Name(TypeStruct(F32[1], S32[1]), "frexp_result_f32");
|
||||
if (info.uses_fp64) {
|
||||
frexp_result_f64 = Name(TypeStruct(F64[1], U32[1]), "frexp_result_f64");
|
||||
frexp_result_f64 = Name(TypeStruct(F64[1], S32[1]), "frexp_result_f64");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2784,8 +2784,7 @@ constexpr std::array<InstFormat, 256> InstructionFormatDS = {{
|
|||
// 62 = DS_APPEND
|
||||
{InstClass::DsAppendCon, InstCategory::DataShare, 3, 1, ScalarType::Uint32, ScalarType::Uint32},
|
||||
// 63 = DS_ORDERED_COUNT
|
||||
{InstClass::GdsOrdCnt, InstCategory::DataShare, 3, 1, ScalarType::Undefined,
|
||||
ScalarType::Undefined},
|
||||
{InstClass::GdsOrdCnt, InstCategory::DataShare, 3, 1, ScalarType::Uint32, ScalarType::Uint32},
|
||||
// 64 = DS_ADD_U64
|
||||
{InstClass::DsAtomicArith64, InstCategory::DataShare, 3, 1, ScalarType::Uint64,
|
||||
ScalarType::Uint64},
|
||||
|
@ -3570,19 +3569,19 @@ constexpr std::array<InstFormat, 112> InstructionFormatMIMG = {{
|
|||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||
ScalarType::Float32},
|
||||
// 65 = IMAGE_GATHER4_CL
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined,
|
||||
ScalarType::Undefined},
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||
ScalarType::Float32},
|
||||
{},
|
||||
{},
|
||||
// 68 = IMAGE_GATHER4_L
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined,
|
||||
ScalarType::Undefined},
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||
ScalarType::Float32},
|
||||
// 69 = IMAGE_GATHER4_B
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined,
|
||||
ScalarType::Undefined},
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||
ScalarType::Float32},
|
||||
// 70 = IMAGE_GATHER4_B_CL
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined,
|
||||
ScalarType::Undefined},
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||
ScalarType::Float32},
|
||||
// 71 = IMAGE_GATHER4_LZ
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||
ScalarType::Float32},
|
||||
|
@ -3590,19 +3589,19 @@ constexpr std::array<InstFormat, 112> InstructionFormatMIMG = {{
|
|||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||
ScalarType::Float32},
|
||||
// 73 = IMAGE_GATHER4_C_CL
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined,
|
||||
ScalarType::Undefined},
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||
ScalarType::Float32},
|
||||
{},
|
||||
{},
|
||||
// 76 = IMAGE_GATHER4_C_L
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined,
|
||||
ScalarType::Undefined},
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||
ScalarType::Float32},
|
||||
// 77 = IMAGE_GATHER4_C_B
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined,
|
||||
ScalarType::Undefined},
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||
ScalarType::Float32},
|
||||
// 78 = IMAGE_GATHER4_C_B_CL
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined,
|
||||
ScalarType::Undefined},
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||
ScalarType::Float32},
|
||||
// 79 = IMAGE_GATHER4_C_LZ
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||
ScalarType::Float32},
|
||||
|
@ -3610,19 +3609,19 @@ constexpr std::array<InstFormat, 112> InstructionFormatMIMG = {{
|
|||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||
ScalarType::Float32},
|
||||
// 81 = IMAGE_GATHER4_CL_O
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined,
|
||||
ScalarType::Undefined},
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||
ScalarType::Float32},
|
||||
{},
|
||||
{},
|
||||
// 84 = IMAGE_GATHER4_L_O
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined,
|
||||
ScalarType::Undefined},
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||
ScalarType::Float32},
|
||||
// 85 = IMAGE_GATHER4_B_O
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined,
|
||||
ScalarType::Undefined},
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||
ScalarType::Float32},
|
||||
// 86 = IMAGE_GATHER4_B_CL_O
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined,
|
||||
ScalarType::Undefined},
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||
ScalarType::Float32},
|
||||
// 87 = IMAGE_GATHER4_LZ_O
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||
ScalarType::Float32},
|
||||
|
@ -3630,19 +3629,19 @@ constexpr std::array<InstFormat, 112> InstructionFormatMIMG = {{
|
|||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||
ScalarType::Float32},
|
||||
// 89 = IMAGE_GATHER4_C_CL_O
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined,
|
||||
ScalarType::Undefined},
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||
ScalarType::Float32},
|
||||
{},
|
||||
{},
|
||||
// 92 = IMAGE_GATHER4_C_L_O
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined,
|
||||
ScalarType::Undefined},
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||
ScalarType::Float32},
|
||||
// 93 = IMAGE_GATHER4_C_B_O
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined,
|
||||
ScalarType::Undefined},
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||
ScalarType::Float32},
|
||||
// 94 = IMAGE_GATHER4_C_B_CL_O
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Undefined,
|
||||
ScalarType::Undefined},
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||
ScalarType::Float32},
|
||||
// 95 = IMAGE_GATHER4_C_LZ_O
|
||||
{InstClass::VectorMemImgSmp, InstCategory::VectorMemory, 4, 1, ScalarType::Uint32,
|
||||
ScalarType::Float32},
|
||||
|
|
|
@ -13,6 +13,12 @@ void Translator::EmitDataShare(const GcnInst& inst) {
|
|||
// DS
|
||||
case Opcode::DS_ADD_U32:
|
||||
return DS_ADD_U32(inst, false);
|
||||
case Opcode::DS_SUB_U32:
|
||||
return DS_SUB_U32(inst, false);
|
||||
case Opcode::DS_INC_U32:
|
||||
return DS_INC_U32(inst, false);
|
||||
case Opcode::DS_DEC_U32:
|
||||
return DS_DEC_U32(inst, false);
|
||||
case Opcode::DS_MIN_I32:
|
||||
return DS_MIN_U32(inst, true, false);
|
||||
case Opcode::DS_MAX_I32:
|
||||
|
@ -35,6 +41,8 @@ void Translator::EmitDataShare(const GcnInst& inst) {
|
|||
return DS_WRITE(32, false, true, true, inst);
|
||||
case Opcode::DS_ADD_RTN_U32:
|
||||
return DS_ADD_U32(inst, true);
|
||||
case Opcode::DS_SUB_RTN_U32:
|
||||
return DS_SUB_U32(inst, true);
|
||||
case Opcode::DS_MIN_RTN_U32:
|
||||
return DS_MIN_U32(inst, false, true);
|
||||
case Opcode::DS_MAX_RTN_U32:
|
||||
|
@ -67,6 +75,8 @@ void Translator::EmitDataShare(const GcnInst& inst) {
|
|||
return DS_READ(64, false, false, false, inst);
|
||||
case Opcode::DS_READ2_B64:
|
||||
return DS_READ(64, false, true, false, inst);
|
||||
case Opcode::DS_READ2ST64_B64:
|
||||
return DS_READ(64, false, true, true, inst);
|
||||
default:
|
||||
LogMissingOpcode(inst);
|
||||
}
|
||||
|
@ -226,6 +236,40 @@ void Translator::DS_SWIZZLE_B32(const GcnInst& inst) {
|
|||
SetDst(inst.dst[0], ir.QuadShuffle(src, index));
|
||||
}
|
||||
|
||||
void Translator::DS_INC_U32(const GcnInst& inst, bool rtn) {
|
||||
const IR::U32 addr{GetSrc(inst.src[0])};
|
||||
const IR::U32 offset =
|
||||
ir.Imm32((u32(inst.control.ds.offset1) << 8u) + u32(inst.control.ds.offset0));
|
||||
const IR::U32 addr_offset = ir.IAdd(addr, offset);
|
||||
const IR::Value original_val = ir.SharedAtomicIIncrement(addr_offset);
|
||||
if (rtn) {
|
||||
SetDst(inst.dst[0], IR::U32{original_val});
|
||||
}
|
||||
}
|
||||
|
||||
void Translator::DS_DEC_U32(const GcnInst& inst, bool rtn) {
|
||||
const IR::U32 addr{GetSrc(inst.src[0])};
|
||||
const IR::U32 offset =
|
||||
ir.Imm32((u32(inst.control.ds.offset1) << 8u) + u32(inst.control.ds.offset0));
|
||||
const IR::U32 addr_offset = ir.IAdd(addr, offset);
|
||||
const IR::Value original_val = ir.SharedAtomicIDecrement(addr_offset);
|
||||
if (rtn) {
|
||||
SetDst(inst.dst[0], IR::U32{original_val});
|
||||
}
|
||||
}
|
||||
|
||||
void Translator::DS_SUB_U32(const GcnInst& inst, bool rtn) {
|
||||
const IR::U32 addr{GetSrc(inst.src[0])};
|
||||
const IR::U32 data{GetSrc(inst.src[1])};
|
||||
const IR::U32 offset =
|
||||
ir.Imm32((u32(inst.control.ds.offset1) << 8u) + u32(inst.control.ds.offset0));
|
||||
const IR::U32 addr_offset = ir.IAdd(addr, offset);
|
||||
const IR::Value original_val = ir.SharedAtomicISub(addr_offset, data);
|
||||
if (rtn) {
|
||||
SetDst(inst.dst[0], IR::U32{original_val});
|
||||
}
|
||||
}
|
||||
|
||||
void Translator::DS_READ(int bit_size, bool is_signed, bool is_pair, bool stride64,
|
||||
const GcnInst& inst) {
|
||||
const IR::U32 addr{ir.GetVectorReg(IR::VectorReg(inst.src[0].code))};
|
||||
|
|
|
@ -30,6 +30,8 @@ void Translator::EmitScalarAlu(const GcnInst& inst) {
|
|||
return S_SUB_I32(inst);
|
||||
case Opcode::S_ADDC_U32:
|
||||
return S_ADDC_U32(inst);
|
||||
case Opcode::S_SUBB_U32:
|
||||
return S_SUBB_U32(inst);
|
||||
case Opcode::S_MIN_I32:
|
||||
return S_MIN_U32(true, inst);
|
||||
case Opcode::S_MIN_U32:
|
||||
|
@ -110,6 +112,8 @@ void Translator::EmitScalarAlu(const GcnInst& inst) {
|
|||
return S_FF1_I32_B32(inst);
|
||||
case Opcode::S_FF1_I32_B64:
|
||||
return S_FF1_I32_B64(inst);
|
||||
case Opcode::S_FLBIT_I32_B32:
|
||||
return S_FLBIT_I32_B32(inst);
|
||||
case Opcode::S_BITSET0_B32:
|
||||
return S_BITSET_B32(inst, 0);
|
||||
case Opcode::S_BITSET1_B32:
|
||||
|
@ -236,6 +240,17 @@ void Translator::S_SUB_U32(const GcnInst& inst) {
|
|||
ir.SetScc(ir.IGreaterThan(src1, src0, false));
|
||||
}
|
||||
|
||||
void Translator::S_SUBB_U32(const GcnInst& inst) {
|
||||
const IR::U32 src0{GetSrc(inst.src[0])};
|
||||
const IR::U32 src1{GetSrc(inst.src[1])};
|
||||
const IR::U32 borrow{ir.Select(ir.GetScc(), ir.Imm32(1U), ir.Imm32(0U))};
|
||||
const IR::U32 result{ir.ISub(ir.ISub(src0, src1), borrow)};
|
||||
SetDst(inst.dst[0], result);
|
||||
|
||||
const IR::U32 sum_with_borrow{ir.IAdd(src1, borrow)};
|
||||
ir.SetScc(ir.ILessThan(src0, sum_with_borrow, false));
|
||||
}
|
||||
|
||||
void Translator::S_ADD_I32(const GcnInst& inst) {
|
||||
const IR::U32 src0{GetSrc(inst.src[0])};
|
||||
const IR::U32 src1{GetSrc(inst.src[1])};
|
||||
|
@ -660,6 +675,17 @@ void Translator::S_FF1_I32_B64(const GcnInst& inst) {
|
|||
SetDst(inst.dst[0], result);
|
||||
}
|
||||
|
||||
void Translator::S_FLBIT_I32_B32(const GcnInst& inst) {
|
||||
const IR::U32 src0{GetSrc(inst.src[0])};
|
||||
// Gcn wants the MSB position counting from the left, but SPIR-V counts from the rightmost (LSB)
|
||||
// position
|
||||
const IR::U32 msb_pos = ir.FindUMsb(src0);
|
||||
const IR::U32 pos_from_left = ir.ISub(ir.Imm32(31), msb_pos);
|
||||
// Select 0xFFFFFFFF if src0 was 0
|
||||
const IR::U1 cond = ir.INotEqual(src0, ir.Imm32(0));
|
||||
SetDst(inst.dst[0], IR::U32{ir.Select(cond, pos_from_left, ir.Imm32(~0U))});
|
||||
}
|
||||
|
||||
void Translator::S_BITSET_B32(const GcnInst& inst, u32 bit_value) {
|
||||
const IR::U32 old_value{GetSrc(inst.dst[0])};
|
||||
const IR::U32 offset{ir.BitFieldExtract(GetSrc(inst.src[0]), ir.Imm32(0U), ir.Imm32(5U))};
|
||||
|
|
|
@ -80,6 +80,7 @@ public:
|
|||
// SOP2
|
||||
void S_ADD_U32(const GcnInst& inst);
|
||||
void S_SUB_U32(const GcnInst& inst);
|
||||
void S_SUBB_U32(const GcnInst& inst);
|
||||
void S_ADD_I32(const GcnInst& inst);
|
||||
void S_SUB_I32(const GcnInst& inst);
|
||||
void S_ADDC_U32(const GcnInst& inst);
|
||||
|
@ -119,6 +120,7 @@ public:
|
|||
void S_BCNT1_I32_B64(const GcnInst& inst);
|
||||
void S_FF1_I32_B32(const GcnInst& inst);
|
||||
void S_FF1_I32_B64(const GcnInst& inst);
|
||||
void S_FLBIT_I32_B32(const GcnInst& inst);
|
||||
void S_BITSET_B32(const GcnInst& inst, u32 bit_value);
|
||||
void S_GETPC_B64(u32 pc, const GcnInst& inst);
|
||||
void S_SAVEEXEC_B64(NegateMode negate, bool is_or, const GcnInst& inst);
|
||||
|
@ -238,13 +240,11 @@ public:
|
|||
void V_FMA_F32(const GcnInst& inst);
|
||||
void V_FMA_F64(const GcnInst& inst);
|
||||
void V_MIN3_F32(const GcnInst& inst);
|
||||
void V_MIN3_I32(const GcnInst& inst);
|
||||
void V_MIN3_U32(const GcnInst& inst);
|
||||
void V_MIN3_U32(bool is_signed, const GcnInst& inst);
|
||||
void V_MAX3_F32(const GcnInst& inst);
|
||||
void V_MAX3_U32(bool is_signed, const GcnInst& inst);
|
||||
void V_MED3_F32(const GcnInst& inst);
|
||||
void V_MED3_I32(const GcnInst& inst);
|
||||
void V_MED3_U32(const GcnInst& inst);
|
||||
void V_MED3_U32(bool is_signed, const GcnInst& inst);
|
||||
void V_SAD(const GcnInst& inst);
|
||||
void V_SAD_U32(const GcnInst& inst);
|
||||
void V_CVT_PK_U16_U32(const GcnInst& inst);
|
||||
|
@ -275,6 +275,9 @@ public:
|
|||
void DS_READ(int bit_size, bool is_signed, bool is_pair, bool stride64, const GcnInst& inst);
|
||||
void DS_APPEND(const GcnInst& inst);
|
||||
void DS_CONSUME(const GcnInst& inst);
|
||||
void DS_SUB_U32(const GcnInst& inst, bool rtn);
|
||||
void DS_INC_U32(const GcnInst& inst, bool rtn);
|
||||
void DS_DEC_U32(const GcnInst& inst, bool rtn);
|
||||
|
||||
// Buffer Memory
|
||||
// MUBUF / MTBUF
|
||||
|
|
|
@ -359,9 +359,9 @@ void Translator::EmitVectorAlu(const GcnInst& inst) {
|
|||
case Opcode::V_MIN3_F32:
|
||||
return V_MIN3_F32(inst);
|
||||
case Opcode::V_MIN3_I32:
|
||||
return V_MIN3_I32(inst);
|
||||
return V_MIN3_U32(true, inst);
|
||||
case Opcode::V_MIN3_U32:
|
||||
return V_MIN3_U32(inst);
|
||||
return V_MIN3_U32(false, inst);
|
||||
case Opcode::V_MAX3_F32:
|
||||
return V_MAX3_F32(inst);
|
||||
case Opcode::V_MAX3_I32:
|
||||
|
@ -371,9 +371,9 @@ void Translator::EmitVectorAlu(const GcnInst& inst) {
|
|||
case Opcode::V_MED3_F32:
|
||||
return V_MED3_F32(inst);
|
||||
case Opcode::V_MED3_I32:
|
||||
return V_MED3_I32(inst);
|
||||
return V_MED3_U32(true, inst);
|
||||
case Opcode::V_MED3_U32:
|
||||
return V_MED3_U32(inst);
|
||||
return V_MED3_U32(false, inst);
|
||||
case Opcode::V_SAD_U32:
|
||||
return V_SAD_U32(inst);
|
||||
case Opcode::V_CVT_PK_U16_U32:
|
||||
|
@ -394,6 +394,8 @@ void Translator::EmitVectorAlu(const GcnInst& inst) {
|
|||
return V_MUL_HI_U32(false, inst);
|
||||
case Opcode::V_MUL_LO_I32:
|
||||
return V_MUL_LO_U32(inst);
|
||||
case Opcode::V_MUL_HI_I32:
|
||||
return V_MUL_HI_U32(true, inst);
|
||||
case Opcode::V_MAD_U64_U32:
|
||||
return V_MAD_U64_U32(inst);
|
||||
case Opcode::V_NOP:
|
||||
|
@ -1010,8 +1012,10 @@ void Translator::V_CMP_CLASS_F32(const GcnInst& inst) {
|
|||
value = ir.FPIsNan(src0);
|
||||
} else if ((class_mask & IR::FloatClassFunc::Infinity) == IR::FloatClassFunc::Infinity) {
|
||||
value = ir.FPIsInf(src0);
|
||||
} else if ((class_mask & IR::FloatClassFunc::Negative) == IR::FloatClassFunc::Negative) {
|
||||
value = ir.FPLessThanEqual(src0, ir.Imm32(-0.f));
|
||||
} else {
|
||||
UNREACHABLE();
|
||||
UNREACHABLE_MSG("Unsupported float class mask: {:#x}", static_cast<u32>(class_mask));
|
||||
}
|
||||
} else {
|
||||
// We don't know the type yet, delay its resolution.
|
||||
|
@ -1166,59 +1170,42 @@ void Translator::V_MIN3_F32(const GcnInst& inst) {
|
|||
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||
const IR::F32 src1{GetSrc<IR::F32>(inst.src[1])};
|
||||
const IR::F32 src2{GetSrc<IR::F32>(inst.src[2])};
|
||||
SetDst(inst.dst[0], ir.FPMin(src0, ir.FPMin(src1, src2)));
|
||||
SetDst(inst.dst[0], ir.FPMinTri(src0, src1, src2));
|
||||
}
|
||||
|
||||
void Translator::V_MIN3_I32(const GcnInst& inst) {
|
||||
void Translator::V_MIN3_U32(bool is_signed, const GcnInst& inst) {
|
||||
const IR::U32 src0{GetSrc(inst.src[0])};
|
||||
const IR::U32 src1{GetSrc(inst.src[1])};
|
||||
const IR::U32 src2{GetSrc(inst.src[2])};
|
||||
SetDst(inst.dst[0], ir.SMin(src0, ir.SMin(src1, src2)));
|
||||
}
|
||||
|
||||
void Translator::V_MIN3_U32(const GcnInst& inst) {
|
||||
const IR::U32 src0{GetSrc(inst.src[0])};
|
||||
const IR::U32 src1{GetSrc(inst.src[1])};
|
||||
const IR::U32 src2{GetSrc(inst.src[2])};
|
||||
SetDst(inst.dst[0], ir.UMin(src0, ir.UMin(src1, src2)));
|
||||
SetDst(inst.dst[0], ir.IMinTri(src0, src1, src2, is_signed));
|
||||
}
|
||||
|
||||
void Translator::V_MAX3_F32(const GcnInst& inst) {
|
||||
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||
const IR::F32 src1{GetSrc<IR::F32>(inst.src[1])};
|
||||
const IR::F32 src2{GetSrc<IR::F32>(inst.src[2])};
|
||||
SetDst(inst.dst[0], ir.FPMax(src0, ir.FPMax(src1, src2)));
|
||||
SetDst(inst.dst[0], ir.FPMaxTri(src0, src1, src2));
|
||||
}
|
||||
|
||||
void Translator::V_MAX3_U32(bool is_signed, const GcnInst& inst) {
|
||||
const IR::U32 src0{GetSrc(inst.src[0])};
|
||||
const IR::U32 src1{GetSrc(inst.src[1])};
|
||||
const IR::U32 src2{GetSrc(inst.src[2])};
|
||||
SetDst(inst.dst[0], ir.IMax(src0, ir.IMax(src1, src2, is_signed), is_signed));
|
||||
SetDst(inst.dst[0], ir.IMaxTri(src0, src1, src2, is_signed));
|
||||
}
|
||||
|
||||
void Translator::V_MED3_F32(const GcnInst& inst) {
|
||||
const IR::F32 src0{GetSrc<IR::F32>(inst.src[0])};
|
||||
const IR::F32 src1{GetSrc<IR::F32>(inst.src[1])};
|
||||
const IR::F32 src2{GetSrc<IR::F32>(inst.src[2])};
|
||||
const IR::F32 mmx = ir.FPMin(ir.FPMax(src0, src1), src2);
|
||||
SetDst(inst.dst[0], ir.FPMax(ir.FPMin(src0, src1), mmx));
|
||||
SetDst(inst.dst[0], ir.FPMedTri(src0, src1, src2));
|
||||
}
|
||||
|
||||
void Translator::V_MED3_I32(const GcnInst& inst) {
|
||||
void Translator::V_MED3_U32(bool is_signed, const GcnInst& inst) {
|
||||
const IR::U32 src0{GetSrc(inst.src[0])};
|
||||
const IR::U32 src1{GetSrc(inst.src[1])};
|
||||
const IR::U32 src2{GetSrc(inst.src[2])};
|
||||
const IR::U32 mmx = ir.SMin(ir.SMax(src0, src1), src2);
|
||||
SetDst(inst.dst[0], ir.SMax(ir.SMin(src0, src1), mmx));
|
||||
}
|
||||
|
||||
void Translator::V_MED3_U32(const GcnInst& inst) {
|
||||
const IR::U32 src0{GetSrc(inst.src[0])};
|
||||
const IR::U32 src1{GetSrc(inst.src[1])};
|
||||
const IR::U32 src2{GetSrc(inst.src[2])};
|
||||
const IR::U32 mmx = ir.UMin(ir.UMax(src0, src1), src2);
|
||||
SetDst(inst.dst[0], ir.UMax(ir.UMin(src0, src1), mmx));
|
||||
SetDst(inst.dst[0], ir.IMedTri(src0, src1, src2, is_signed));
|
||||
}
|
||||
|
||||
void Translator::V_SAD(const GcnInst& inst) {
|
||||
|
@ -1294,7 +1281,7 @@ void Translator::V_MUL_LO_U32(const GcnInst& inst) {
|
|||
void Translator::V_MUL_HI_U32(bool is_signed, const GcnInst& inst) {
|
||||
const IR::U32 src0{GetSrc(inst.src[0])};
|
||||
const IR::U32 src1{GetSrc(inst.src[1])};
|
||||
const IR::U32 hi{ir.CompositeExtract(ir.IMulExt(src0, src1, is_signed), 1)};
|
||||
const IR::U32 hi{ir.IMulHi(src0, src1, is_signed)};
|
||||
SetDst(inst.dst[0], hi);
|
||||
}
|
||||
|
||||
|
|
|
@ -357,6 +357,18 @@ U32 IREmitter::SharedAtomicXor(const U32& address, const U32& data) {
|
|||
return Inst<U32>(Opcode::SharedAtomicXor32, address, data);
|
||||
}
|
||||
|
||||
U32 IREmitter::SharedAtomicIIncrement(const U32& address) {
|
||||
return Inst<U32>(Opcode::SharedAtomicIIncrement32, address);
|
||||
}
|
||||
|
||||
U32 IREmitter::SharedAtomicIDecrement(const U32& address) {
|
||||
return Inst<U32>(Opcode::SharedAtomicIDecrement32, address);
|
||||
}
|
||||
|
||||
U32 IREmitter::SharedAtomicISub(const U32& address, const U32& data) {
|
||||
return Inst<U32>(Opcode::SharedAtomicISub32, address, data);
|
||||
}
|
||||
|
||||
U32 IREmitter::ReadConst(const Value& base, const U32& offset) {
|
||||
return Inst<U32>(Opcode::ReadConst, base, offset);
|
||||
}
|
||||
|
@ -1336,6 +1348,18 @@ F32F64 IREmitter::FPMin(const F32F64& lhs, const F32F64& rhs, bool is_legacy) {
|
|||
}
|
||||
}
|
||||
|
||||
F32F64 IREmitter::FPMinTri(const F32F64& a, const F32F64& b, const F32F64& c) {
|
||||
return Inst<F32>(Opcode::FPMinTri32, a, b, c);
|
||||
}
|
||||
|
||||
F32F64 IREmitter::FPMaxTri(const F32F64& a, const F32F64& b, const F32F64& c) {
|
||||
return Inst<F32>(Opcode::FPMaxTri32, a, b, c);
|
||||
}
|
||||
|
||||
F32F64 IREmitter::FPMedTri(const F32F64& a, const F32F64& b, const F32F64& c) {
|
||||
return Inst<F32>(Opcode::FPMedTri32, a, b, c);
|
||||
}
|
||||
|
||||
U32U64 IREmitter::IAdd(const U32U64& a, const U32U64& b) {
|
||||
if (a.Type() != b.Type()) {
|
||||
UNREACHABLE_MSG("Mismatching types {} and {}", a.Type(), b.Type());
|
||||
|
@ -1376,8 +1400,8 @@ U32U64 IREmitter::ISub(const U32U64& a, const U32U64& b) {
|
|||
}
|
||||
}
|
||||
|
||||
IR::Value IREmitter::IMulExt(const U32& a, const U32& b, bool is_signed) {
|
||||
return Inst(is_signed ? Opcode::SMulExt : Opcode::UMulExt, a, b);
|
||||
U32 IREmitter::IMulHi(const U32& a, const U32& b, bool is_signed) {
|
||||
return Inst<U32>(is_signed ? Opcode::SMulHi : Opcode::UMulHi, a, b);
|
||||
}
|
||||
|
||||
U32U64 IREmitter::IMul(const U32U64& a, const U32U64& b) {
|
||||
|
@ -1567,6 +1591,42 @@ U32 IREmitter::IMax(const U32& a, const U32& b, bool is_signed) {
|
|||
return is_signed ? SMax(a, b) : UMax(a, b);
|
||||
}
|
||||
|
||||
U32 IREmitter::SMinTri(const U32& a, const U32& b, const U32& c) {
|
||||
return Inst<U32>(Opcode::SMinTri32, a, b, c);
|
||||
}
|
||||
|
||||
U32 IREmitter::UMinTri(const U32& a, const U32& b, const U32& c) {
|
||||
return Inst<U32>(Opcode::UMinTri32, a, b, c);
|
||||
}
|
||||
|
||||
U32 IREmitter::IMinTri(const U32& a, const U32& b, const U32& c, bool is_signed) {
|
||||
return is_signed ? SMinTri(a, b, c) : UMinTri(a, b, c);
|
||||
}
|
||||
|
||||
U32 IREmitter::SMaxTri(const U32& a, const U32& b, const U32& c) {
|
||||
return Inst<U32>(Opcode::SMaxTri32, a, b, c);
|
||||
}
|
||||
|
||||
U32 IREmitter::UMaxTri(const U32& a, const U32& b, const U32& c) {
|
||||
return Inst<U32>(Opcode::UMaxTri32, a, b, c);
|
||||
}
|
||||
|
||||
U32 IREmitter::IMaxTri(const U32& a, const U32& b, const U32& c, bool is_signed) {
|
||||
return is_signed ? SMaxTri(a, b, c) : UMaxTri(a, b, c);
|
||||
}
|
||||
|
||||
U32 IREmitter::SMedTri(const U32& a, const U32& b, const U32& c) {
|
||||
return Inst<U32>(Opcode::SMedTri32, a, b, c);
|
||||
}
|
||||
|
||||
U32 IREmitter::UMedTri(const U32& a, const U32& b, const U32& c) {
|
||||
return Inst<U32>(Opcode::UMedTri32, a, b, c);
|
||||
}
|
||||
|
||||
U32 IREmitter::IMedTri(const U32& a, const U32& b, const U32& c, bool is_signed) {
|
||||
return is_signed ? SMedTri(a, b, c) : UMedTri(a, b, c);
|
||||
}
|
||||
|
||||
U32 IREmitter::SClamp(const U32& value, const U32& min, const U32& max) {
|
||||
return Inst<U32>(Opcode::SClamp32, value, min, max);
|
||||
}
|
||||
|
|
|
@ -106,6 +106,10 @@ public:
|
|||
[[nodiscard]] U32 SharedAtomicOr(const U32& address, const U32& data);
|
||||
[[nodiscard]] U32 SharedAtomicXor(const U32& address, const U32& data);
|
||||
|
||||
[[nodiscard]] U32 SharedAtomicIIncrement(const U32& address);
|
||||
[[nodiscard]] U32 SharedAtomicIDecrement(const U32& address);
|
||||
[[nodiscard]] U32 SharedAtomicISub(const U32& address, const U32& data);
|
||||
|
||||
[[nodiscard]] U32 ReadConst(const Value& base, const U32& offset);
|
||||
[[nodiscard]] U32 ReadConstBuffer(const Value& handle, const U32& index);
|
||||
|
||||
|
@ -233,11 +237,14 @@ public:
|
|||
[[nodiscard]] U1 FPUnordered(const F32F64& lhs, const F32F64& rhs);
|
||||
[[nodiscard]] F32F64 FPMax(const F32F64& lhs, const F32F64& rhs, bool is_legacy = false);
|
||||
[[nodiscard]] F32F64 FPMin(const F32F64& lhs, const F32F64& rhs, bool is_legacy = false);
|
||||
[[nodiscard]] F32F64 FPMinTri(const F32F64& a, const F32F64& b, const F32F64& c);
|
||||
[[nodiscard]] F32F64 FPMaxTri(const F32F64& a, const F32F64& b, const F32F64& c);
|
||||
[[nodiscard]] F32F64 FPMedTri(const F32F64& a, const F32F64& b, const F32F64& c);
|
||||
|
||||
[[nodiscard]] U32U64 IAdd(const U32U64& a, const U32U64& b);
|
||||
[[nodiscard]] Value IAddCary(const U32& a, const U32& b);
|
||||
[[nodiscard]] U32U64 ISub(const U32U64& a, const U32U64& b);
|
||||
[[nodiscard]] Value IMulExt(const U32& a, const U32& b, bool is_signed = false);
|
||||
[[nodiscard]] U32 IMulHi(const U32& a, const U32& b, bool is_signed = false);
|
||||
[[nodiscard]] U32U64 IMul(const U32U64& a, const U32U64& b);
|
||||
[[nodiscard]] U32 IDiv(const U32& a, const U32& b, bool is_signed = false);
|
||||
[[nodiscard]] U32 IMod(const U32& a, const U32& b, bool is_signed = false);
|
||||
|
@ -266,6 +273,15 @@ public:
|
|||
[[nodiscard]] U32 SMax(const U32& a, const U32& b);
|
||||
[[nodiscard]] U32 UMax(const U32& a, const U32& b);
|
||||
[[nodiscard]] U32 IMax(const U32& a, const U32& b, bool is_signed);
|
||||
[[nodiscard]] U32 SMinTri(const U32& a, const U32& b, const U32& c);
|
||||
[[nodiscard]] U32 UMinTri(const U32& a, const U32& b, const U32& c);
|
||||
[[nodiscard]] U32 IMinTri(const U32& a, const U32& b, const U32& c, bool is_signed);
|
||||
[[nodiscard]] U32 SMaxTri(const U32& a, const U32& b, const U32& c);
|
||||
[[nodiscard]] U32 UMaxTri(const U32& a, const U32& b, const U32& c);
|
||||
[[nodiscard]] U32 IMaxTri(const U32& a, const U32& b, const U32& c, bool is_signed);
|
||||
[[nodiscard]] U32 SMedTri(const U32& a, const U32& b, const U32& c);
|
||||
[[nodiscard]] U32 UMedTri(const U32& a, const U32& b, const U32& c);
|
||||
[[nodiscard]] U32 IMedTri(const U32& a, const U32& b, const U32& c, bool is_signed);
|
||||
[[nodiscard]] U32 SClamp(const U32& value, const U32& min, const U32& max);
|
||||
[[nodiscard]] U32 UClamp(const U32& value, const U32& min, const U32& max);
|
||||
|
||||
|
|
|
@ -44,6 +44,9 @@ OPCODE(SharedAtomicUMax32, U32, U32,
|
|||
OPCODE(SharedAtomicAnd32, U32, U32, U32, )
|
||||
OPCODE(SharedAtomicOr32, U32, U32, U32, )
|
||||
OPCODE(SharedAtomicXor32, U32, U32, U32, )
|
||||
OPCODE(SharedAtomicISub32, U32, U32, U32, )
|
||||
OPCODE(SharedAtomicIIncrement32, U32, U32, )
|
||||
OPCODE(SharedAtomicIDecrement32, U32, U32, )
|
||||
|
||||
// Context getters/setters
|
||||
OPCODE(GetUserData, U32, ScalarReg, )
|
||||
|
@ -241,6 +244,9 @@ OPCODE(FPMax32, F32, F32,
|
|||
OPCODE(FPMax64, F64, F64, F64, )
|
||||
OPCODE(FPMin32, F32, F32, F32, U1, )
|
||||
OPCODE(FPMin64, F64, F64, F64, )
|
||||
OPCODE(FPMinTri32, F32, F32, F32, F32, )
|
||||
OPCODE(FPMaxTri32, F32, F32, F32, F32, )
|
||||
OPCODE(FPMedTri32, F32, F32, F32, F32, )
|
||||
OPCODE(FPMul32, F32, F32, F32, )
|
||||
OPCODE(FPMul64, F64, F64, F64, )
|
||||
OPCODE(FPDiv32, F32, F32, F32, )
|
||||
|
@ -314,8 +320,8 @@ OPCODE(ISub32, U32, U32,
|
|||
OPCODE(ISub64, U64, U64, U64, )
|
||||
OPCODE(IMul32, U32, U32, U32, )
|
||||
OPCODE(IMul64, U64, U64, U64, )
|
||||
OPCODE(SMulExt, U32x2, U32, U32, )
|
||||
OPCODE(UMulExt, U32x2, U32, U32, )
|
||||
OPCODE(SMulHi, U32, U32, U32, )
|
||||
OPCODE(UMulHi, U32, U32, U32, )
|
||||
OPCODE(SDiv32, U32, U32, U32, )
|
||||
OPCODE(UDiv32, U32, U32, U32, )
|
||||
OPCODE(SMod32, U32, U32, U32, )
|
||||
|
@ -350,6 +356,12 @@ OPCODE(SMin32, U32, U32,
|
|||
OPCODE(UMin32, U32, U32, U32, )
|
||||
OPCODE(SMax32, U32, U32, U32, )
|
||||
OPCODE(UMax32, U32, U32, U32, )
|
||||
OPCODE(SMinTri32, U32, U32, U32, U32, )
|
||||
OPCODE(UMinTri32, U32, U32, U32, U32, )
|
||||
OPCODE(SMaxTri32, U32, U32, U32, U32, )
|
||||
OPCODE(UMaxTri32, U32, U32, U32, U32, )
|
||||
OPCODE(SMedTri32, U32, U32, U32, U32, )
|
||||
OPCODE(UMedTri32, U32, U32, U32, U32, )
|
||||
OPCODE(SClamp32, U32, U32, U32, U32, )
|
||||
OPCODE(UClamp32, U32, U32, U32, U32, )
|
||||
OPCODE(SLessThan32, U1, U32, U32, )
|
||||
|
|
|
@ -235,9 +235,12 @@ std::pair<const IR::Inst*, bool> TryDisableAnisoLod0(const IR::Inst* inst) {
|
|||
return {prod2, true};
|
||||
}
|
||||
|
||||
SharpLocation TrackSharp(const IR::Inst* inst, const Shader::Info& info) {
|
||||
SharpLocation AttemptTrackSharp(const IR::Inst* inst, auto& visited_insts) {
|
||||
// Search until we find a potential sharp source.
|
||||
const auto pred = [](const IR::Inst* inst) -> std::optional<const IR::Inst*> {
|
||||
const auto pred = [&visited_insts](const IR::Inst* inst) -> std::optional<const IR::Inst*> {
|
||||
if (std::ranges::find(visited_insts, inst) != visited_insts.end()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
if (inst->GetOpcode() == IR::Opcode::GetUserData ||
|
||||
inst->GetOpcode() == IR::Opcode::ReadConst) {
|
||||
return inst;
|
||||
|
@ -247,6 +250,7 @@ SharpLocation TrackSharp(const IR::Inst* inst, const Shader::Info& info) {
|
|||
const auto result = IR::BreadthFirstSearch(inst, pred);
|
||||
ASSERT_MSG(result, "Unable to track sharp source");
|
||||
inst = result.value();
|
||||
visited_insts.emplace_back(inst);
|
||||
if (inst->GetOpcode() == IR::Opcode::GetUserData) {
|
||||
return static_cast<u32>(inst->Arg(0).ScalarReg());
|
||||
} else {
|
||||
|
@ -256,6 +260,29 @@ SharpLocation TrackSharp(const IR::Inst* inst, const Shader::Info& info) {
|
|||
}
|
||||
}
|
||||
|
||||
/// Tracks a sharp with validation of the chosen data type.
|
||||
template <typename DataType>
|
||||
std::pair<SharpLocation, DataType> TrackSharp(const IR::Inst* inst, const Info& info) {
|
||||
boost::container::small_vector<const IR::Inst*, 4> visited_insts{};
|
||||
while (true) {
|
||||
const auto prev_size = visited_insts.size();
|
||||
const auto sharp = AttemptTrackSharp(inst, visited_insts);
|
||||
if (const auto data = info.ReadUdSharp<DataType>(sharp); data.Valid()) {
|
||||
return std::make_pair(sharp, data);
|
||||
}
|
||||
if (prev_size == visited_insts.size()) {
|
||||
// No change in visited instructions, we've run out of paths.
|
||||
UNREACHABLE_MSG("Unable to find valid sharp.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Tracks a sharp without data validation.
|
||||
SharpLocation TrackSharp(const IR::Inst* inst, const Info& info) {
|
||||
boost::container::static_vector<const IR::Inst*, 1> visited_insts{};
|
||||
return AttemptTrackSharp(inst, visited_insts);
|
||||
}
|
||||
|
||||
s32 TryHandleInlineCbuf(IR::Inst& inst, Info& info, Descriptors& descriptors,
|
||||
AmdGpu::Buffer& cbuf) {
|
||||
|
||||
|
@ -293,8 +320,8 @@ void PatchBufferSharp(IR::Block& block, IR::Inst& inst, Info& info, Descriptors&
|
|||
if (binding = TryHandleInlineCbuf(inst, info, descriptors, buffer); binding == -1) {
|
||||
IR::Inst* handle = inst.Arg(0).InstRecursive();
|
||||
IR::Inst* producer = handle->Arg(0).InstRecursive();
|
||||
const auto sharp = TrackSharp(producer, info);
|
||||
buffer = info.ReadUdSharp<AmdGpu::Buffer>(sharp);
|
||||
SharpLocation sharp;
|
||||
std::tie(sharp, buffer) = TrackSharp<AmdGpu::Buffer>(producer, info);
|
||||
binding = descriptors.Add(BufferResource{
|
||||
.sharp_idx = sharp,
|
||||
.used_types = BufferDataType(inst, buffer.GetNumberFmt()),
|
||||
|
|
|
@ -25,6 +25,7 @@ enum class FloatClassFunc : u32 {
|
|||
|
||||
NaN = SignalingNan | QuietNan,
|
||||
Infinity = PositiveInfinity | NegativeInfinity,
|
||||
Negative = NegativeInfinity | NegativeNormal | NegativeDenorm | NegativeZero,
|
||||
Finite = NegativeNormal | NegativeDenorm | NegativeZero | PositiveNormal | PositiveDenorm |
|
||||
PositiveZero,
|
||||
};
|
||||
|
|
|
@ -26,6 +26,7 @@ struct Profile {
|
|||
bool support_legacy_vertex_attributes{};
|
||||
bool supports_image_load_store_lod{};
|
||||
bool supports_native_cube_calc{};
|
||||
bool supports_trinary_minmax{};
|
||||
bool supports_robust_buffer_access{};
|
||||
bool has_broken_spirv_clamp{};
|
||||
bool lower_left_origin_mode{};
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
<RCC>
|
||||
<qresource prefix="/">
|
||||
<file>images/shadps4.ico</file>
|
||||
<file>images/shadps4.png</file>
|
||||
<file>images/about_icon.png</file>
|
||||
<file>images/dump_icon.png</file>
|
||||
<file>images/play_icon.png</file>
|
||||
|
|
|
@ -1 +1,43 @@
|
|||
IDI_ICON1 ICON "images/shadps4.ico"
|
||||
// SPDX-FileCopyrightText: Copyright 2025 shadPS4 Emulator Project
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
#include "winresrc.h"
|
||||
|
||||
#define xstr(s) str(s)
|
||||
#define str(s) #s
|
||||
|
||||
// NEUTRAL LANG
|
||||
LANGUAGE LANG_NEUTRAL, 0x8
|
||||
|
||||
// ICON
|
||||
IDI_ICON1 ICON "images/shadps4.ico"
|
||||
|
||||
// VERSION
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION EMULATOR_VERSION_MAJOR, EMULATOR_VERSION_MINOR, EMULATOR_VERSION_PATCH, 0
|
||||
PRODUCTVERSION EMULATOR_VERSION_MAJOR, EMULATOR_VERSION_MINOR, EMULATOR_VERSION_PATCH, 0
|
||||
FILEFLAGSMASK 0x3fL
|
||||
FILEFLAGS 0x0L
|
||||
FILEOS 0x40004L
|
||||
FILETYPE 0x2L
|
||||
FILESUBTYPE 0x0L
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "\0"
|
||||
VALUE "FileDescription", "shadPS4 - PlayStation 4 Emulator\0"
|
||||
VALUE "FileVersion", xstr(EMULATOR_VERSION_MAJOR) "." xstr(EMULATOR_VERSION_MINOR) "." xstr(EMULATOR_VERSION_PATCH) ".0\0"
|
||||
VALUE "InternalName", "shadPS4\0"
|
||||
VALUE "LegalCopyright", "Copyright 2025 shadPS4 Team\0"
|
||||
VALUE "OriginalFilename", "shadPS4.exe\0"
|
||||
VALUE "ProductName", "shadPS4\0"
|
||||
VALUE "ProductVersion", xstr(EMULATOR_VERSION_MAJOR) "." xstr(EMULATOR_VERSION_MINOR) "." xstr(EMULATOR_VERSION_PATCH) ".0\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
||||
|
|
|
@ -1423,6 +1423,10 @@ struct Liverpool {
|
|||
return num_samples;
|
||||
}
|
||||
|
||||
bool IsClipDisabled() const {
|
||||
return clipper_control.clip_disable || primitive_type == PrimitiveType::RectList;
|
||||
}
|
||||
|
||||
void SetDefaults();
|
||||
};
|
||||
|
||||
|
|
|
@ -156,6 +156,18 @@ vk::CullModeFlags CullMode(Liverpool::CullMode mode) {
|
|||
}
|
||||
}
|
||||
|
||||
vk::FrontFace FrontFace(Liverpool::FrontFace face) {
|
||||
switch (face) {
|
||||
case Liverpool::FrontFace::Clockwise:
|
||||
return vk::FrontFace::eClockwise;
|
||||
case Liverpool::FrontFace::CounterClockwise:
|
||||
return vk::FrontFace::eCounterClockwise;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
return vk::FrontFace::eClockwise;
|
||||
}
|
||||
}
|
||||
|
||||
vk::BlendFactor BlendFactor(Liverpool::BlendControl::BlendFactor factor) {
|
||||
using BlendFactor = Liverpool::BlendControl::BlendFactor;
|
||||
switch (factor) {
|
||||
|
|
|
@ -26,6 +26,8 @@ vk::PolygonMode PolygonMode(Liverpool::PolygonMode mode);
|
|||
|
||||
vk::CullModeFlags CullMode(Liverpool::CullMode mode);
|
||||
|
||||
vk::FrontFace FrontFace(Liverpool::FrontFace mode);
|
||||
|
||||
vk::BlendFactor BlendFactor(Liverpool::BlendControl::BlendFactor factor);
|
||||
|
||||
vk::BlendOp BlendOp(Liverpool::BlendControl::BlendFunc func);
|
||||
|
|
|
@ -28,6 +28,15 @@ static constexpr std::array LogicalStageToStageBit = {
|
|||
vk::ShaderStageFlagBits::eCompute,
|
||||
};
|
||||
|
||||
static bool IsPrimitiveTopologyList(const vk::PrimitiveTopology topology) {
|
||||
return topology == vk::PrimitiveTopology::ePointList ||
|
||||
topology == vk::PrimitiveTopology::eLineList ||
|
||||
topology == vk::PrimitiveTopology::eTriangleList ||
|
||||
topology == vk::PrimitiveTopology::eLineListWithAdjacency ||
|
||||
topology == vk::PrimitiveTopology::eTriangleListWithAdjacency ||
|
||||
topology == vk::PrimitiveTopology::ePatchList;
|
||||
}
|
||||
|
||||
GraphicsPipeline::GraphicsPipeline(
|
||||
const Instance& instance, Scheduler& scheduler, DescriptorHeap& desc_heap,
|
||||
const Shader::Profile& profile, const GraphicsPipelineKey& key_,
|
||||
|
@ -75,19 +84,15 @@ GraphicsPipeline::GraphicsPipeline(
|
|||
.pVertexAttributeDescriptions = vertex_attributes.data(),
|
||||
};
|
||||
|
||||
auto prim_restart = key.enable_primitive_restart != 0;
|
||||
if (prim_restart && IsPrimitiveListTopology() && !instance.IsListRestartSupported()) {
|
||||
LOG_DEBUG(Render_Vulkan,
|
||||
"Primitive restart is enabled for list topology but not supported by driver.");
|
||||
prim_restart = false;
|
||||
}
|
||||
const auto topology = LiverpoolToVK::PrimitiveType(key.prim_type);
|
||||
const vk::PipelineInputAssemblyStateCreateInfo input_assembly = {
|
||||
.topology = LiverpoolToVK::PrimitiveType(key.prim_type),
|
||||
.primitiveRestartEnable = prim_restart,
|
||||
.topology = topology,
|
||||
// Avoid warning spam on all pipelines about unsupported restart disable, if not supported.
|
||||
// However, must be false for list topologies to avoid validation errors.
|
||||
.primitiveRestartEnable =
|
||||
!instance.IsPrimitiveRestartDisableSupported() && !IsPrimitiveTopologyList(topology),
|
||||
};
|
||||
ASSERT_MSG(!prim_restart || key.primitive_restart_index == 0xFFFF ||
|
||||
key.primitive_restart_index == 0xFFFFFFFF,
|
||||
"Primitive restart index other than -1 is not supported yet");
|
||||
|
||||
const bool is_rect_list = key.prim_type == AmdGpu::PrimitiveType::RectList;
|
||||
const bool is_quad_list = key.prim_type == AmdGpu::PrimitiveType::QuadList;
|
||||
const auto& fs_info = runtime_infos[u32(Shader::LogicalStage::Fragment)].fs_info;
|
||||
|
@ -99,13 +104,6 @@ GraphicsPipeline::GraphicsPipeline(
|
|||
.depthClampEnable = false,
|
||||
.rasterizerDiscardEnable = false,
|
||||
.polygonMode = LiverpoolToVK::PolygonMode(key.polygon_mode),
|
||||
.cullMode = LiverpoolToVK::IsPrimitiveCulled(key.prim_type)
|
||||
? LiverpoolToVK::CullMode(key.cull_mode)
|
||||
: vk::CullModeFlagBits::eNone,
|
||||
.frontFace = key.front_face == Liverpool::FrontFace::Clockwise
|
||||
? vk::FrontFace::eClockwise
|
||||
: vk::FrontFace::eCounterClockwise,
|
||||
.depthBiasEnable = key.depth_bias_enable,
|
||||
.lineWidth = 1.0f,
|
||||
};
|
||||
|
||||
|
@ -123,18 +121,24 @@ GraphicsPipeline::GraphicsPipeline(
|
|||
.pNext = instance.IsDepthClipControlSupported() ? &clip_control : nullptr,
|
||||
};
|
||||
|
||||
boost::container::static_vector<vk::DynamicState, 14> dynamic_states = {
|
||||
vk::DynamicState::eViewportWithCountEXT,
|
||||
vk::DynamicState::eScissorWithCountEXT,
|
||||
vk::DynamicState::eBlendConstants,
|
||||
vk::DynamicState::eDepthBounds,
|
||||
vk::DynamicState::eDepthBias,
|
||||
vk::DynamicState::eStencilReference,
|
||||
vk::DynamicState::eStencilCompareMask,
|
||||
vk::DynamicState::eStencilWriteMask,
|
||||
vk::DynamicState::eStencilOpEXT,
|
||||
boost::container::static_vector<vk::DynamicState, 20> dynamic_states = {
|
||||
vk::DynamicState::eViewportWithCountEXT, vk::DynamicState::eScissorWithCountEXT,
|
||||
vk::DynamicState::eBlendConstants, vk::DynamicState::eDepthTestEnableEXT,
|
||||
vk::DynamicState::eDepthWriteEnableEXT, vk::DynamicState::eDepthCompareOpEXT,
|
||||
vk::DynamicState::eDepthBiasEnableEXT, vk::DynamicState::eDepthBias,
|
||||
vk::DynamicState::eStencilTestEnableEXT, vk::DynamicState::eStencilReference,
|
||||
vk::DynamicState::eStencilCompareMask, vk::DynamicState::eStencilWriteMask,
|
||||
vk::DynamicState::eStencilOpEXT, vk::DynamicState::eCullModeEXT,
|
||||
vk::DynamicState::eFrontFaceEXT,
|
||||
};
|
||||
|
||||
if (instance.IsPrimitiveRestartDisableSupported()) {
|
||||
dynamic_states.push_back(vk::DynamicState::ePrimitiveRestartEnableEXT);
|
||||
}
|
||||
if (instance.IsDepthBoundsSupported()) {
|
||||
dynamic_states.push_back(vk::DynamicState::eDepthBoundsTestEnableEXT);
|
||||
dynamic_states.push_back(vk::DynamicState::eDepthBounds);
|
||||
}
|
||||
if (instance.IsDynamicColorWriteMaskSupported()) {
|
||||
dynamic_states.push_back(vk::DynamicState::eColorWriteMaskEXT);
|
||||
}
|
||||
|
@ -149,14 +153,6 @@ GraphicsPipeline::GraphicsPipeline(
|
|||
.pDynamicStates = dynamic_states.data(),
|
||||
};
|
||||
|
||||
const vk::PipelineDepthStencilStateCreateInfo depth_info = {
|
||||
.depthTestEnable = key.depth_test_enable,
|
||||
.depthWriteEnable = key.depth_write_enable,
|
||||
.depthCompareOp = key.depth_compare_op,
|
||||
.depthBoundsTestEnable = key.depth_bounds_test_enable,
|
||||
.stencilTestEnable = key.stencil_test_enable,
|
||||
};
|
||||
|
||||
boost::container::static_vector<vk::PipelineShaderStageCreateInfo, MaxShaderStages>
|
||||
shader_stages;
|
||||
auto stage = u32(Shader::LogicalStage::Vertex);
|
||||
|
@ -292,7 +288,6 @@ GraphicsPipeline::GraphicsPipeline(
|
|||
.pViewportState = &viewport_info,
|
||||
.pRasterizationState = &raster_state,
|
||||
.pMultisampleState = &multisampling,
|
||||
.pDepthStencilState = &depth_info,
|
||||
.pColorBlendState = &color_blending,
|
||||
.pDynamicState = &dynamic_info,
|
||||
.layout = *pipeline_layout,
|
||||
|
|