From d6d1ec4f22840298749844d2bb830aa3b1590739 Mon Sep 17 00:00:00 2001 From: psucien Date: Fri, 29 Nov 2024 14:17:53 +0100 Subject: [PATCH 01/32] hot-fix: apply vgt index offset to draw commands --- src/shader_recompiler/info.h | 7 ++++--- src/video_core/amdgpu/liverpool.h | 4 +++- src/video_core/renderer_vulkan/vk_rasterizer.cpp | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/src/shader_recompiler/info.h b/src/shader_recompiler/info.h index f9cbacaf2..c7ae2a1e5 100644 --- a/src/shader_recompiler/info.h +++ b/src/shader_recompiler/info.h @@ -17,6 +17,7 @@ #include "shader_recompiler/ir/type.h" #include "shader_recompiler/params.h" #include "shader_recompiler/runtime_info.h" +#include "video_core/amdgpu/liverpool.h" #include "video_core/amdgpu/resource.h" namespace Shader { @@ -251,10 +252,10 @@ struct Info { bnd.user_data += ud_mask.NumRegs(); } - [[nodiscard]] std::pair GetDrawOffsets() const { - u32 vertex_offset = 0; + [[nodiscard]] std::pair GetDrawOffsets(const AmdGpu::Liverpool::Regs& regs) const { + u32 vertex_offset = regs.index_offset; u32 instance_offset = 0; - if (vertex_offset_sgpr != -1) { + if (vertex_offset == 0 && vertex_offset_sgpr != -1) { vertex_offset = user_data[vertex_offset_sgpr]; } if (instance_offset_sgpr != -1) { diff --git a/src/video_core/amdgpu/liverpool.h b/src/video_core/amdgpu/liverpool.h index 0ef9397b0..2b2f2c00a 100644 --- a/src/video_core/amdgpu/liverpool.h +++ b/src/video_core/amdgpu/liverpool.h @@ -1111,7 +1111,8 @@ struct Liverpool { INSERT_PADDING_WORDS(2); std::array viewport_scissors; std::array viewport_depths; - INSERT_PADDING_WORDS(0xA103 - 0xA0D4); + INSERT_PADDING_WORDS(0xA102 - 0xA0D4); + u32 index_offset; u32 primitive_restart_index; INSERT_PADDING_WORDS(1); BlendConstants blend_constants; @@ -1380,6 +1381,7 @@ static_assert(GFX6_3D_REG_INDEX(color_target_mask) == 0xA08E); static_assert(GFX6_3D_REG_INDEX(color_shader_mask) == 0xA08F); static_assert(GFX6_3D_REG_INDEX(generic_scissor) == 0xA090); static_assert(GFX6_3D_REG_INDEX(viewport_scissors) == 0xA094); +static_assert(GFX6_3D_REG_INDEX(index_offset) == 0xA102); static_assert(GFX6_3D_REG_INDEX(primitive_restart_index) == 0xA103); static_assert(GFX6_3D_REG_INDEX(stencil_control) == 0xA10B); static_assert(GFX6_3D_REG_INDEX(viewports) == 0xA10F); diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index e66d12517..a6fc872d9 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -200,7 +200,7 @@ void Rasterizer::Draw(bool is_indexed, u32 index_offset) { BeginRendering(*pipeline, state); UpdateDynamicState(*pipeline); - const auto [vertex_offset, instance_offset] = vs_info.GetDrawOffsets(); + const auto [vertex_offset, instance_offset] = vs_info.GetDrawOffsets(regs); const auto cmdbuf = scheduler.CommandBuffer(); cmdbuf.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline->Handle()); From 9f6261524b6305d0d718aed5ba6dd004d4f76810 Mon Sep 17 00:00:00 2001 From: "Daniel R." <47796739+polybiusproxy@users.noreply.github.com> Date: Fri, 29 Nov 2024 20:02:45 +0100 Subject: [PATCH 02/32] core: fix patch paths applying when no folder exists --- src/core/file_sys/fs.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/core/file_sys/fs.cpp b/src/core/file_sys/fs.cpp index 769940cf0..b6d0d188f 100644 --- a/src/core/file_sys/fs.cpp +++ b/src/core/file_sys/fs.cpp @@ -56,11 +56,12 @@ std::filesystem::path MntPoints::GetHostPath(std::string_view path, bool* is_rea std::filesystem::path host_path = mount->host_path / rel_path; std::filesystem::path patch_path = mount->host_path; patch_path += "-UPDATE"; - patch_path /= rel_path; - if ((corrected_path.starts_with("/app0") || corrected_path.starts_with("/hostapp")) && - std::filesystem::exists(patch_path)) { - return patch_path; + if (corrected_path.starts_with("/app0") || corrected_path.starts_with("/hostapp")) { + if (std::filesystem::exists(patch_path)) { + patch_path /= rel_path; + return patch_path; + } } if (!NeedsCaseInsensitiveSearch) { From 086c5802f4bec35ffa6457f287a4177537444965 Mon Sep 17 00:00:00 2001 From: Vladislav Mikhalin Date: Fri, 29 Nov 2024 23:13:36 +0300 Subject: [PATCH 03/32] Fixed DS_SWIZZLE_32 (#1619) --- src/shader_recompiler/frontend/translate/data_share.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/shader_recompiler/frontend/translate/data_share.cpp b/src/shader_recompiler/frontend/translate/data_share.cpp index 9685ee352..2f5932f80 100644 --- a/src/shader_recompiler/frontend/translate/data_share.cpp +++ b/src/shader_recompiler/frontend/translate/data_share.cpp @@ -158,13 +158,12 @@ void Translator::DS_WRITE(int bit_size, bool is_signed, bool is_pair, bool strid void Translator::DS_SWIZZLE_B32(const GcnInst& inst) { const u8 offset0 = inst.control.ds.offset0; const u8 offset1 = inst.control.ds.offset1; - const IR::U32 src{GetSrc(inst.src[1])}; + const IR::U32 src{GetSrc(inst.src[0])}; // ASSERT(offset1 & 0x80); const IR::U32 lane_id = ir.LaneId(); const IR::U32 id_in_group = ir.BitwiseAnd(lane_id, ir.Imm32(0b11)); const IR::U32 base = ir.ShiftLeftLogical(id_in_group, ir.Imm32(1)); - const IR::U32 index = - ir.IAdd(lane_id, ir.BitFieldExtract(ir.Imm32(offset0), base, ir.Imm32(2))); + const IR::U32 index = ir.BitFieldExtract(ir.Imm32(offset0), base, ir.Imm32(2)); SetDst(inst.dst[0], ir.QuadShuffle(src, index)); } From 6c215e672dce22ba1a923a34ad15e2d3eb837e8a Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Fri, 29 Nov 2024 12:57:56 -0800 Subject: [PATCH 04/32] Revert "core: fix patch paths applying when no folder exists" (#1620) This reverts commit 9f6261524b6305d0d718aed5ba6dd004d4f76810. --- src/core/file_sys/fs.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/core/file_sys/fs.cpp b/src/core/file_sys/fs.cpp index b6d0d188f..769940cf0 100644 --- a/src/core/file_sys/fs.cpp +++ b/src/core/file_sys/fs.cpp @@ -56,12 +56,11 @@ std::filesystem::path MntPoints::GetHostPath(std::string_view path, bool* is_rea std::filesystem::path host_path = mount->host_path / rel_path; std::filesystem::path patch_path = mount->host_path; patch_path += "-UPDATE"; + patch_path /= rel_path; - if (corrected_path.starts_with("/app0") || corrected_path.starts_with("/hostapp")) { - if (std::filesystem::exists(patch_path)) { - patch_path /= rel_path; - return patch_path; - } + if ((corrected_path.starts_with("/app0") || corrected_path.starts_with("/hostapp")) && + std::filesystem::exists(patch_path)) { + return patch_path; } if (!NeedsCaseInsensitiveSearch) { From 7b68004a4086577c766fe44caf18f0dcc1fe0e65 Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Sat, 30 Nov 2024 00:08:46 -0800 Subject: [PATCH 05/32] sysmodule: Remove need for libSceRazorCpu (#1622) --- CMakeLists.txt | 1 + src/core/libraries/system/sysmodule.cpp | 17 +++++++++++++++-- src/core/libraries/system/sysmodule.h | 6 +++++- src/core/libraries/system/system_error.h | 8 ++++++++ src/emulator.cpp | 3 +-- 5 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 src/core/libraries/system/system_error.h diff --git a/CMakeLists.txt b/CMakeLists.txt index a967c540c..657b7c5bf 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -276,6 +276,7 @@ set(SYSTEM_LIBS src/core/libraries/system/commondialog.cpp src/core/libraries/save_data/dialog/savedatadialog_ui.h src/core/libraries/system/sysmodule.cpp src/core/libraries/system/sysmodule.h + src/core/libraries/system/system_error.h src/core/libraries/system/systemservice.cpp src/core/libraries/system/systemservice.h src/core/libraries/system/userservice.cpp diff --git a/src/core/libraries/system/sysmodule.cpp b/src/core/libraries/system/sysmodule.cpp index d37c375bf..8ea61e177 100644 --- a/src/core/libraries/system/sysmodule.cpp +++ b/src/core/libraries/system/sysmodule.cpp @@ -9,6 +9,7 @@ #include "core/libraries/error_codes.h" #include "core/libraries/libs.h" #include "core/libraries/system/sysmodule.h" +#include "core/libraries/system/system_error.h" namespace Libraries::SysModule { @@ -34,11 +35,23 @@ int PS4_SYSV_ABI sceSysmoduleIsCameraPreloaded() { int PS4_SYSV_ABI sceSysmoduleIsLoaded(OrbisSysModule id) { LOG_ERROR(Lib_SysModule, "(DUMMY) called module = {}", magic_enum::enum_name(id)); + if (static_cast(id) == 0) { + LOG_ERROR(Lib_SysModule, "Invalid sysmodule ID: {:#x}", static_cast(id)); + return ORBIS_SYSMODULE_INVALID_ID; + } return ORBIS_OK; } -int PS4_SYSV_ABI sceSysmoduleIsLoadedInternal() { - LOG_ERROR(Lib_SysModule, "(STUBBED) called"); +int PS4_SYSV_ABI sceSysmoduleIsLoadedInternal(OrbisSysModuleInternal id) { + LOG_ERROR(Lib_SysModule, "(DUMMY) called module = {:#x}", static_cast(id)); + if ((static_cast(id) & 0x7FFFFFFF) == 0) { + LOG_ERROR(Lib_SysModule, "Invalid internal sysmodule ID: {:#x}", static_cast(id)); + return ORBIS_SYSMODULE_INVALID_ID; + } + if (id == OrbisSysModuleInternal::ORBIS_SYSMODULE_INTERNAL_RAZOR_CPU) { + // Internal debugging library, report as not loaded so it won't be used. + return ORBIS_SYSMODULE_NOT_LOADED; + } return ORBIS_OK; } diff --git a/src/core/libraries/system/sysmodule.h b/src/core/libraries/system/sysmodule.h index c9ec97ce9..3630fb58e 100644 --- a/src/core/libraries/system/sysmodule.h +++ b/src/core/libraries/system/sysmodule.h @@ -147,12 +147,16 @@ enum class OrbisSysModule : u16 { ORBIS_SYSMODULE_KEYBOARD = 0x0106, }; +enum class OrbisSysModuleInternal : u32 { + ORBIS_SYSMODULE_INTERNAL_RAZOR_CPU = 0x80000019, // libSceRazorCpu.sprx +}; + int PS4_SYSV_ABI sceSysmoduleGetModuleHandleInternal(); int PS4_SYSV_ABI sceSysmoduleGetModuleInfoForUnwind(); int PS4_SYSV_ABI sceSysmoduleIsCalledFromSysModule(); int PS4_SYSV_ABI sceSysmoduleIsCameraPreloaded(); int PS4_SYSV_ABI sceSysmoduleIsLoaded(OrbisSysModule id); -int PS4_SYSV_ABI sceSysmoduleIsLoadedInternal(); +int PS4_SYSV_ABI sceSysmoduleIsLoadedInternal(OrbisSysModuleInternal id); int PS4_SYSV_ABI sceSysmoduleLoadModule(OrbisSysModule id); int PS4_SYSV_ABI sceSysmoduleLoadModuleByNameInternal(); int PS4_SYSV_ABI sceSysmoduleLoadModuleInternal(); diff --git a/src/core/libraries/system/system_error.h b/src/core/libraries/system/system_error.h new file mode 100644 index 000000000..615e4cd5f --- /dev/null +++ b/src/core/libraries/system/system_error.h @@ -0,0 +1,8 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +constexpr int ORBIS_SYSMODULE_INVALID_ID = 0x805A1000; +constexpr int ORBIS_SYSMODULE_NOT_LOADED = 0x805A1001; +constexpr int ORBIS_SYSMODULE_LOCK_FAILED = 0x805A10FF; \ No newline at end of file diff --git a/src/emulator.cpp b/src/emulator.cpp index c0b01229a..27291707d 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -269,7 +269,7 @@ void Emulator::Run(const std::filesystem::path& file) { } void Emulator::LoadSystemModules(const std::filesystem::path& file, std::string game_serial) { - constexpr std::array ModulesToLoad{ + constexpr std::array ModulesToLoad{ {{"libSceNgs2.sprx", &Libraries::Ngs2::RegisterlibSceNgs2}, {"libSceFiber.sprx", &Libraries::Fiber::RegisterlibSceFiber}, {"libSceUlt.sprx", nullptr}, @@ -279,7 +279,6 @@ void Emulator::LoadSystemModules(const std::filesystem::path& file, std::string {"libSceDiscMap.sprx", &Libraries::DiscMap::RegisterlibSceDiscMap}, {"libSceRtc.sprx", &Libraries::Rtc::RegisterlibSceRtc}, {"libSceJpegEnc.sprx", nullptr}, - {"libSceRazorCpu.sprx", nullptr}, {"libSceCesCs.sprx", nullptr}}}; std::vector found_modules; From b1a024efbd09a2babcae8abd3aee589f0ca8819c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C2=A5IGA?= <164882787+Xphalnos@users.noreply.github.com> Date: Sat, 30 Nov 2024 09:25:55 +0100 Subject: [PATCH 06/32] Remove save migration code (#1621) --- src/common/config.cpp | 55 +++++++++++++++++++++++++++++-------------- 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/src/common/config.cpp b/src/common/config.cpp index e97a46005..5c857afb4 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -3,13 +3,14 @@ #include #include -#include #include #include // for wstring support #include -#include "common/logging/formatter.h" + #include "common/path_util.h" #include "config.h" +#include "logging/formatter.h" +#include "version.h" namespace toml { template @@ -81,7 +82,8 @@ std::vector m_pkg_viewer; std::vector m_elf_viewer; std::vector m_recent_files; std::string emulator_language = "en"; -// Settings + +// Language u32 m_language = 1; // english bool isNeoMode() { @@ -334,6 +336,7 @@ void setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h) { main_window_geometry_w = w; main_window_geometry_h = h; } + bool addGameInstallDir(const std::filesystem::path& dir) { if (std::find(settings_install_dirs.begin(), settings_install_dirs.end(), dir) == settings_install_dirs.end()) { @@ -342,47 +345,60 @@ bool addGameInstallDir(const std::filesystem::path& dir) { } return false; } + void removeGameInstallDir(const std::filesystem::path& dir) { auto iterator = std::find(settings_install_dirs.begin(), settings_install_dirs.end(), dir); if (iterator != settings_install_dirs.end()) { settings_install_dirs.erase(iterator); } } + void setAddonInstallDir(const std::filesystem::path& dir) { settings_addon_install_dir = dir; } + void setMainWindowTheme(u32 theme) { mw_themes = theme; } + void setIconSize(u32 size) { m_icon_size = size; } + void setIconSizeGrid(u32 size) { m_icon_size_grid = size; } + void setSliderPosition(u32 pos) { m_slider_pos = pos; } + void setSliderPositionGrid(u32 pos) { m_slider_pos_grid = pos; } + void setTableMode(u32 mode) { m_table_mode = mode; } + void setMainWindowWidth(u32 width) { m_window_size_W = width; } + void setMainWindowHeight(u32 height) { m_window_size_H = height; } + void setPkgViewer(const std::vector& pkgList) { m_pkg_viewer.resize(pkgList.size()); m_pkg_viewer = pkgList; } + void setElfViewer(const std::vector& elfList) { m_elf_viewer.resize(elfList.size()); m_elf_viewer = elfList; } + void setRecentFiles(const std::vector& recentFiles) { m_recent_files.resize(recentFiles.size()); m_recent_files = recentFiles; @@ -395,18 +411,23 @@ void setEmulatorLanguage(std::string language) { u32 getMainWindowGeometryX() { return main_window_geometry_x; } + u32 getMainWindowGeometryY() { return main_window_geometry_y; } + u32 getMainWindowGeometryW() { return main_window_geometry_w; } + u32 getMainWindowGeometryH() { return main_window_geometry_h; } + const std::vector& getGameInstallDirs() { return settings_install_dirs; } + std::filesystem::path getAddonInstallDir() { if (settings_addon_install_dir.empty()) { // Default for users without a config file or a config file from before this option existed @@ -414,36 +435,47 @@ std::filesystem::path getAddonInstallDir() { } return settings_addon_install_dir; } + u32 getMainWindowTheme() { return mw_themes; } + u32 getIconSize() { return m_icon_size; } + u32 getIconSizeGrid() { return m_icon_size_grid; } + u32 getSliderPosition() { return m_slider_pos; } + u32 getSliderPositionGrid() { return m_slider_pos_grid; } + u32 getTableMode() { return m_table_mode; } + u32 getMainWindowWidth() { return m_window_size_W; } + u32 getMainWindowHeight() { return m_window_size_H; } + std::vector getPkgViewer() { return m_pkg_viewer; } + std::vector getElfViewer() { return m_elf_viewer; } + std::vector getRecentFiles() { return m_recent_files; } @@ -455,6 +487,7 @@ std::string getEmulatorLanguage() { u32 GetLanguage() { return m_language; } + void load(const std::filesystem::path& path) { // If the configuration file does not exist, create it and return std::error_code error; @@ -545,18 +578,6 @@ void load(const std::filesystem::path& path) { m_window_size_W = toml::find_or(gui, "mw_width", 0); m_window_size_H = toml::find_or(gui, "mw_height", 0); - // TODO Migration code, after a major release this should be removed. - auto old_game_install_dir = toml::find_fs_path_or(gui, "installDir", {}); - if (!old_game_install_dir.empty()) { - addGameInstallDir(std::filesystem::path{old_game_install_dir}); - } else { - const auto install_dir_array = - toml::find_or>(gui, "installDirs", {}); - for (const auto& dir : install_dir_array) { - addGameInstallDir(std::filesystem::path{dir}); - } - } - settings_addon_install_dir = toml::find_fs_path_or(gui, "addonInstallDir", {}); main_window_geometry_x = toml::find_or(gui, "geometry_x", 0); main_window_geometry_y = toml::find_or(gui, "geometry_y", 0); @@ -575,6 +596,7 @@ void load(const std::filesystem::path& path) { m_language = toml::find_or(settings, "consoleLanguage", 1); } } + void save(const std::filesystem::path& path) { toml::value data; @@ -655,9 +677,6 @@ void save(const std::filesystem::path& path) { data["Settings"]["consoleLanguage"] = m_language; - // TODO Migration code, after a major release this should be removed. - data.at("GUI").as_table().erase("installDir"); - std::ofstream file(path, std::ios::binary); file << data; file.close(); From 7e525a59e46fe0771c774f9fe38ee5fe3d6a5ade Mon Sep 17 00:00:00 2001 From: Stephen Miller <56742918+StevenMiller123@users.noreply.github.com> Date: Sat, 30 Nov 2024 02:28:31 -0600 Subject: [PATCH 07/32] Kernel Fixes (#1605) * scePthreadSetprio Changes FindThread uses posix error codes, so the function export should apply the ORBIS wrapper to convert these. Since it uses posix codes, I've also renamed the function to align with other posix functions. Lastly, this fixes a compile warning about ret sometimes not getting initialized. * Implement posix_munmap Used by Hatsune Miku Project Diva X during intros. May help with stability on Linux, probably won't change anything on Windows. * Exports Some missing function exports I've seen in my tests. sceKernelAvailableFlexibleMemorySize export is used in Final Fantasy XV Episode Duscae posix_pthread_setprio and posix_pthread_getschedparam are used by Spider-Man Miles Morales scePthreadKeyDelete is used in UE4 games. I've also added in a typo fix related to my previous PR. * libScePosix export for posix_pthread_attr_setguardsize Used in Hatsune Miku Project Diva X v1.02 --- src/core/libraries/kernel/file_system.cpp | 2 +- src/core/libraries/kernel/memory.cpp | 15 +++++++++++++++ src/core/libraries/kernel/threads/pthread.cpp | 12 ++++++------ .../libraries/kernel/threads/pthread_attr.cpp | 2 ++ .../libraries/kernel/threads/pthread_spec.cpp | 1 + 5 files changed, 25 insertions(+), 7 deletions(-) diff --git a/src/core/libraries/kernel/file_system.cpp b/src/core/libraries/kernel/file_system.cpp index c4f1e4799..d0ffa21ca 100644 --- a/src/core/libraries/kernel/file_system.cpp +++ b/src/core/libraries/kernel/file_system.cpp @@ -502,7 +502,7 @@ s32 PS4_SYSV_ABI sceKernelFsync(int fd) { s32 PS4_SYSV_ABI posix_fsync(int fd) { s32 result = sceKernelFsync(fd); if (result < 0) { - LOG_ERROR(Kernel_Pthread, "posix_fstat: error = {}", result); + LOG_ERROR(Kernel_Pthread, "posix_fsync: error = {}", result); ErrSceToPosix(result); return -1; } diff --git a/src/core/libraries/kernel/memory.cpp b/src/core/libraries/kernel/memory.cpp index 13b3a9f48..4d55fc2a3 100644 --- a/src/core/libraries/kernel/memory.cpp +++ b/src/core/libraries/kernel/memory.cpp @@ -10,6 +10,7 @@ #include "common/singleton.h" #include "core/file_sys/fs.h" #include "core/libraries/error_codes.h" +#include "core/libraries/kernel/kernel.h" #include "core/libraries/kernel/memory.h" #include "core/libraries/libs.h" #include "core/linker.h" @@ -495,6 +496,16 @@ int PS4_SYSV_ABI sceKernelMunmap(void* addr, size_t len) { return SCE_OK; } +int PS4_SYSV_ABI posix_munmap(void* addr, size_t len) { + int result = sceKernelMunmap(addr, len); + if (result < 0) { + LOG_ERROR(Kernel_Pthread, "posix_munmap: error = {}", result); + ErrSceToPosix(result); + return -1; + } + return result; +} + void RegisterMemory(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("rTXw65xmLIA", "libkernel", 1, "libkernel", 1, 1, sceKernelAllocateDirectMemory); LIB_FUNCTION("B+vc2AO2Zrc", "libkernel", 1, "libkernel", 1, 1, @@ -517,6 +528,8 @@ void RegisterMemory(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("mL8NDH86iQI", "libkernel", 1, "libkernel", 1, 1, sceKernelMapNamedFlexibleMemory); LIB_FUNCTION("aNz11fnnzi4", "libkernel", 1, "libkernel", 1, 1, sceKernelAvailableFlexibleMemorySize); + LIB_FUNCTION("aNz11fnnzi4", "libkernel_avlfmem", 1, "libkernel", 1, 1, + sceKernelAvailableFlexibleMemorySize); LIB_FUNCTION("IWIBBdTHit4", "libkernel", 1, "libkernel", 1, 1, sceKernelMapFlexibleMemory); LIB_FUNCTION("p5EcQeEeJAE", "libkernel", 1, "libkernel", 1, 1, _sceKernelRtldSetApplicationHeapAPI); @@ -537,6 +550,8 @@ void RegisterMemory(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("BPE9s9vQQXo", "libkernel", 1, "libkernel", 1, 1, posix_mmap); LIB_FUNCTION("BPE9s9vQQXo", "libScePosix", 1, "libkernel", 1, 1, posix_mmap); + LIB_FUNCTION("UqDGjXA5yUM", "libkernel", 1, "libkernel", 1, 1, posix_munmap); + LIB_FUNCTION("UqDGjXA5yUM", "libScePosix", 1, "libkernel", 1, 1, posix_munmap); } } // namespace Libraries::Kernel diff --git a/src/core/libraries/kernel/threads/pthread.cpp b/src/core/libraries/kernel/threads/pthread.cpp index 28e2be06e..18ddcb9bf 100644 --- a/src/core/libraries/kernel/threads/pthread.cpp +++ b/src/core/libraries/kernel/threads/pthread.cpp @@ -421,29 +421,27 @@ int PS4_SYSV_ABI scePthreadGetprio(PthreadT thread, int* priority) { return 0; } -int PS4_SYSV_ABI scePthreadSetprio(PthreadT thread, int prio) { +int PS4_SYSV_ABI posix_pthread_setprio(PthreadT thread, int prio) { SchedParam param; - int ret; param.sched_priority = prio; auto* thread_state = ThrState::Instance(); if (thread == g_curthread) { g_curthread->lock.lock(); - } else if (int ret = thread_state->FindThread(thread, /*include dead*/ 0)) { + } else if (int ret = thread_state->FindThread(thread, /*include dead*/ 0); ret != 0) { return ret; } if (thread->attr.sched_policy == SchedPolicy::Other || thread->attr.prio == prio) { thread->attr.prio = prio; - ret = 0; } else { // TODO: _thr_setscheduler thread->attr.prio = prio; } thread->lock.unlock(); - return ret; + return 0; } enum class PthreadCancelState : u32 { @@ -495,6 +493,8 @@ void RegisterThread(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("OxhIB8LB-PQ", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_create); LIB_FUNCTION("Jmi+9w9u0E4", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_create_name_np); LIB_FUNCTION("lZzFeSxPl08", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_setcancelstate); + LIB_FUNCTION("a2P9wYGeZvc", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_setprio); + LIB_FUNCTION("FIs3-UQT9sg", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_getschedparam); LIB_FUNCTION("6XG4B33N09g", "libScePosix", 1, "libkernel", 1, 1, sched_yield); // Posix-Kernel @@ -517,7 +517,7 @@ void RegisterThread(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("T72hz6ffq08", "libkernel", 1, "libkernel", 1, 1, posix_pthread_yield); LIB_FUNCTION("EI-5-jlq2dE", "libkernel", 1, "libkernel", 1, 1, posix_pthread_getthreadid_np); LIB_FUNCTION("1tKyG7RlMJo", "libkernel", 1, "libkernel", 1, 1, scePthreadGetprio); - LIB_FUNCTION("W0Hpm2X0uPE", "libkernel", 1, "libkernel", 1, 1, scePthreadSetprio); + LIB_FUNCTION("W0Hpm2X0uPE", "libkernel", 1, "libkernel", 1, 1, ORBIS(posix_pthread_setprio)); LIB_FUNCTION("rNhWz+lvOMU", "libkernel", 1, "libkernel", 1, 1, _sceKernelSetThreadDtors); LIB_FUNCTION("6XG4B33N09g", "libkernel", 1, "libkernel", 1, 1, sched_yield); } diff --git a/src/core/libraries/kernel/threads/pthread_attr.cpp b/src/core/libraries/kernel/threads/pthread_attr.cpp index db32fa3d5..ead0ff7df 100644 --- a/src/core/libraries/kernel/threads/pthread_attr.cpp +++ b/src/core/libraries/kernel/threads/pthread_attr.cpp @@ -303,6 +303,8 @@ void RegisterThreadAttr(Core::Loader::SymbolsResolver* sym) { posix_pthread_attr_getstacksize); LIB_FUNCTION("VUT1ZSrHT0I", "libScePosix", 1, "libkernel", 1, 1, posix_pthread_attr_getdetachstate); + LIB_FUNCTION("JKyG3SWyA10", "libScePosix", 1, "libkernel", 1, 1, + posix_pthread_attr_setguardsize); // Orbis LIB_FUNCTION("4+h9EzwKF4I", "libkernel", 1, "libkernel", 1, 1, diff --git a/src/core/libraries/kernel/threads/pthread_spec.cpp b/src/core/libraries/kernel/threads/pthread_spec.cpp index 3d6b0f4d9..f0803b671 100644 --- a/src/core/libraries/kernel/threads/pthread_spec.cpp +++ b/src/core/libraries/kernel/threads/pthread_spec.cpp @@ -150,6 +150,7 @@ void RegisterSpec(Core::Loader::SymbolsResolver* sym) { // Orbis LIB_FUNCTION("geDaqgH9lTg", "libkernel", 1, "libkernel", 1, 1, ORBIS(posix_pthread_key_create)); + LIB_FUNCTION("PrdHuuDekhY", "libkernel", 1, "libkernel", 1, 1, ORBIS(posix_pthread_key_delete)); LIB_FUNCTION("eoht7mQOCmo", "libkernel", 1, "libkernel", 1, 1, posix_pthread_getspecific); LIB_FUNCTION("+BzXYkqYeLE", "libkernel", 1, "libkernel", 1, 1, ORBIS(posix_pthread_setspecific)); From 7bf168e47fcead28585194560a37580edb71ddbb Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Sat, 30 Nov 2024 11:28:46 +0200 Subject: [PATCH 08/32] Revert "Remove save migration code (#1621)" This reverts commit b1a024efbd09a2babcae8abd3aee589f0ca8819c. --- src/common/config.cpp | 55 ++++++++++++++----------------------------- 1 file changed, 18 insertions(+), 37 deletions(-) diff --git a/src/common/config.cpp b/src/common/config.cpp index 5c857afb4..e97a46005 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -3,14 +3,13 @@ #include #include +#include #include #include // for wstring support #include - +#include "common/logging/formatter.h" #include "common/path_util.h" #include "config.h" -#include "logging/formatter.h" -#include "version.h" namespace toml { template @@ -82,8 +81,7 @@ std::vector m_pkg_viewer; std::vector m_elf_viewer; std::vector m_recent_files; std::string emulator_language = "en"; - -// Language +// Settings u32 m_language = 1; // english bool isNeoMode() { @@ -336,7 +334,6 @@ void setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h) { main_window_geometry_w = w; main_window_geometry_h = h; } - bool addGameInstallDir(const std::filesystem::path& dir) { if (std::find(settings_install_dirs.begin(), settings_install_dirs.end(), dir) == settings_install_dirs.end()) { @@ -345,60 +342,47 @@ bool addGameInstallDir(const std::filesystem::path& dir) { } return false; } - void removeGameInstallDir(const std::filesystem::path& dir) { auto iterator = std::find(settings_install_dirs.begin(), settings_install_dirs.end(), dir); if (iterator != settings_install_dirs.end()) { settings_install_dirs.erase(iterator); } } - void setAddonInstallDir(const std::filesystem::path& dir) { settings_addon_install_dir = dir; } - void setMainWindowTheme(u32 theme) { mw_themes = theme; } - void setIconSize(u32 size) { m_icon_size = size; } - void setIconSizeGrid(u32 size) { m_icon_size_grid = size; } - void setSliderPosition(u32 pos) { m_slider_pos = pos; } - void setSliderPositionGrid(u32 pos) { m_slider_pos_grid = pos; } - void setTableMode(u32 mode) { m_table_mode = mode; } - void setMainWindowWidth(u32 width) { m_window_size_W = width; } - void setMainWindowHeight(u32 height) { m_window_size_H = height; } - void setPkgViewer(const std::vector& pkgList) { m_pkg_viewer.resize(pkgList.size()); m_pkg_viewer = pkgList; } - void setElfViewer(const std::vector& elfList) { m_elf_viewer.resize(elfList.size()); m_elf_viewer = elfList; } - void setRecentFiles(const std::vector& recentFiles) { m_recent_files.resize(recentFiles.size()); m_recent_files = recentFiles; @@ -411,23 +395,18 @@ void setEmulatorLanguage(std::string language) { u32 getMainWindowGeometryX() { return main_window_geometry_x; } - u32 getMainWindowGeometryY() { return main_window_geometry_y; } - u32 getMainWindowGeometryW() { return main_window_geometry_w; } - u32 getMainWindowGeometryH() { return main_window_geometry_h; } - const std::vector& getGameInstallDirs() { return settings_install_dirs; } - std::filesystem::path getAddonInstallDir() { if (settings_addon_install_dir.empty()) { // Default for users without a config file or a config file from before this option existed @@ -435,47 +414,36 @@ std::filesystem::path getAddonInstallDir() { } return settings_addon_install_dir; } - u32 getMainWindowTheme() { return mw_themes; } - u32 getIconSize() { return m_icon_size; } - u32 getIconSizeGrid() { return m_icon_size_grid; } - u32 getSliderPosition() { return m_slider_pos; } - u32 getSliderPositionGrid() { return m_slider_pos_grid; } - u32 getTableMode() { return m_table_mode; } - u32 getMainWindowWidth() { return m_window_size_W; } - u32 getMainWindowHeight() { return m_window_size_H; } - std::vector getPkgViewer() { return m_pkg_viewer; } - std::vector getElfViewer() { return m_elf_viewer; } - std::vector getRecentFiles() { return m_recent_files; } @@ -487,7 +455,6 @@ std::string getEmulatorLanguage() { u32 GetLanguage() { return m_language; } - void load(const std::filesystem::path& path) { // If the configuration file does not exist, create it and return std::error_code error; @@ -578,6 +545,18 @@ void load(const std::filesystem::path& path) { m_window_size_W = toml::find_or(gui, "mw_width", 0); m_window_size_H = toml::find_or(gui, "mw_height", 0); + // TODO Migration code, after a major release this should be removed. + auto old_game_install_dir = toml::find_fs_path_or(gui, "installDir", {}); + if (!old_game_install_dir.empty()) { + addGameInstallDir(std::filesystem::path{old_game_install_dir}); + } else { + const auto install_dir_array = + toml::find_or>(gui, "installDirs", {}); + for (const auto& dir : install_dir_array) { + addGameInstallDir(std::filesystem::path{dir}); + } + } + settings_addon_install_dir = toml::find_fs_path_or(gui, "addonInstallDir", {}); main_window_geometry_x = toml::find_or(gui, "geometry_x", 0); main_window_geometry_y = toml::find_or(gui, "geometry_y", 0); @@ -596,7 +575,6 @@ void load(const std::filesystem::path& path) { m_language = toml::find_or(settings, "consoleLanguage", 1); } } - void save(const std::filesystem::path& path) { toml::value data; @@ -677,6 +655,9 @@ void save(const std::filesystem::path& path) { data["Settings"]["consoleLanguage"] = m_language; + // TODO Migration code, after a major release this should be removed. + data.at("GUI").as_table().erase("installDir"); + std::ofstream file(path, std::ios::binary); file << data; file.close(); From 99ac10a41723edfcb3419bb19934163aada23660 Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Sat, 30 Nov 2024 01:30:22 -0800 Subject: [PATCH 09/32] libraries: Add libSceRazorCpu HLE skeleton. (#1624) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Remove save migration code (#1621) * Kernel Fixes (#1605) * scePthreadSetprio Changes FindThread uses posix error codes, so the function export should apply the ORBIS wrapper to convert these. Since it uses posix codes, I've also renamed the function to align with other posix functions. Lastly, this fixes a compile warning about ret sometimes not getting initialized. * Implement posix_munmap Used by Hatsune Miku Project Diva X during intros. May help with stability on Linux, probably won't change anything on Windows. * Exports Some missing function exports I've seen in my tests. sceKernelAvailableFlexibleMemorySize export is used in Final Fantasy XV Episode Duscae posix_pthread_setprio and posix_pthread_getschedparam are used by Spider-Man Miles Morales scePthreadKeyDelete is used in UE4 games. I've also added in a typo fix related to my previous PR. * libScePosix export for posix_pthread_attr_setguardsize Used in Hatsune Miku Project Diva X v1.02 * libraries: Add libSceRazorCpu HLE skeleton. --------- Co-authored-by: ¥IGA <164882787+Xphalnos@users.noreply.github.com> Co-authored-by: Stephen Miller <56742918+StevenMiller123@users.noreply.github.com> --- CMakeLists.txt | 2 + src/common/config.cpp | 55 +++-- src/common/logging/filter.cpp | 1 + src/common/logging/types.h | 1 + src/core/libraries/libs.cpp | 2 + src/core/libraries/razor_cpu/razor_cpu.cpp | 249 +++++++++++++++++++++ src/core/libraries/razor_cpu/razor_cpu.h | 17 ++ src/core/libraries/system/sysmodule.cpp | 4 - 8 files changed, 309 insertions(+), 22 deletions(-) create mode 100644 src/core/libraries/razor_cpu/razor_cpu.cpp create mode 100644 src/core/libraries/razor_cpu/razor_cpu.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 657b7c5bf..55f1172f2 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -318,6 +318,8 @@ set(SYSTEM_LIBS src/core/libraries/system/commondialog.cpp src/core/libraries/remote_play/remoteplay.h src/core/libraries/share_play/shareplay.cpp src/core/libraries/share_play/shareplay.h + src/core/libraries/razor_cpu/razor_cpu.cpp + src/core/libraries/razor_cpu/razor_cpu.h ) set(VIDEOOUT_LIB src/core/libraries/videoout/buffer.h diff --git a/src/common/config.cpp b/src/common/config.cpp index e97a46005..5c857afb4 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -3,13 +3,14 @@ #include #include -#include #include #include // for wstring support #include -#include "common/logging/formatter.h" + #include "common/path_util.h" #include "config.h" +#include "logging/formatter.h" +#include "version.h" namespace toml { template @@ -81,7 +82,8 @@ std::vector m_pkg_viewer; std::vector m_elf_viewer; std::vector m_recent_files; std::string emulator_language = "en"; -// Settings + +// Language u32 m_language = 1; // english bool isNeoMode() { @@ -334,6 +336,7 @@ void setMainWindowGeometry(u32 x, u32 y, u32 w, u32 h) { main_window_geometry_w = w; main_window_geometry_h = h; } + bool addGameInstallDir(const std::filesystem::path& dir) { if (std::find(settings_install_dirs.begin(), settings_install_dirs.end(), dir) == settings_install_dirs.end()) { @@ -342,47 +345,60 @@ bool addGameInstallDir(const std::filesystem::path& dir) { } return false; } + void removeGameInstallDir(const std::filesystem::path& dir) { auto iterator = std::find(settings_install_dirs.begin(), settings_install_dirs.end(), dir); if (iterator != settings_install_dirs.end()) { settings_install_dirs.erase(iterator); } } + void setAddonInstallDir(const std::filesystem::path& dir) { settings_addon_install_dir = dir; } + void setMainWindowTheme(u32 theme) { mw_themes = theme; } + void setIconSize(u32 size) { m_icon_size = size; } + void setIconSizeGrid(u32 size) { m_icon_size_grid = size; } + void setSliderPosition(u32 pos) { m_slider_pos = pos; } + void setSliderPositionGrid(u32 pos) { m_slider_pos_grid = pos; } + void setTableMode(u32 mode) { m_table_mode = mode; } + void setMainWindowWidth(u32 width) { m_window_size_W = width; } + void setMainWindowHeight(u32 height) { m_window_size_H = height; } + void setPkgViewer(const std::vector& pkgList) { m_pkg_viewer.resize(pkgList.size()); m_pkg_viewer = pkgList; } + void setElfViewer(const std::vector& elfList) { m_elf_viewer.resize(elfList.size()); m_elf_viewer = elfList; } + void setRecentFiles(const std::vector& recentFiles) { m_recent_files.resize(recentFiles.size()); m_recent_files = recentFiles; @@ -395,18 +411,23 @@ void setEmulatorLanguage(std::string language) { u32 getMainWindowGeometryX() { return main_window_geometry_x; } + u32 getMainWindowGeometryY() { return main_window_geometry_y; } + u32 getMainWindowGeometryW() { return main_window_geometry_w; } + u32 getMainWindowGeometryH() { return main_window_geometry_h; } + const std::vector& getGameInstallDirs() { return settings_install_dirs; } + std::filesystem::path getAddonInstallDir() { if (settings_addon_install_dir.empty()) { // Default for users without a config file or a config file from before this option existed @@ -414,36 +435,47 @@ std::filesystem::path getAddonInstallDir() { } return settings_addon_install_dir; } + u32 getMainWindowTheme() { return mw_themes; } + u32 getIconSize() { return m_icon_size; } + u32 getIconSizeGrid() { return m_icon_size_grid; } + u32 getSliderPosition() { return m_slider_pos; } + u32 getSliderPositionGrid() { return m_slider_pos_grid; } + u32 getTableMode() { return m_table_mode; } + u32 getMainWindowWidth() { return m_window_size_W; } + u32 getMainWindowHeight() { return m_window_size_H; } + std::vector getPkgViewer() { return m_pkg_viewer; } + std::vector getElfViewer() { return m_elf_viewer; } + std::vector getRecentFiles() { return m_recent_files; } @@ -455,6 +487,7 @@ std::string getEmulatorLanguage() { u32 GetLanguage() { return m_language; } + void load(const std::filesystem::path& path) { // If the configuration file does not exist, create it and return std::error_code error; @@ -545,18 +578,6 @@ void load(const std::filesystem::path& path) { m_window_size_W = toml::find_or(gui, "mw_width", 0); m_window_size_H = toml::find_or(gui, "mw_height", 0); - // TODO Migration code, after a major release this should be removed. - auto old_game_install_dir = toml::find_fs_path_or(gui, "installDir", {}); - if (!old_game_install_dir.empty()) { - addGameInstallDir(std::filesystem::path{old_game_install_dir}); - } else { - const auto install_dir_array = - toml::find_or>(gui, "installDirs", {}); - for (const auto& dir : install_dir_array) { - addGameInstallDir(std::filesystem::path{dir}); - } - } - settings_addon_install_dir = toml::find_fs_path_or(gui, "addonInstallDir", {}); main_window_geometry_x = toml::find_or(gui, "geometry_x", 0); main_window_geometry_y = toml::find_or(gui, "geometry_y", 0); @@ -575,6 +596,7 @@ void load(const std::filesystem::path& path) { m_language = toml::find_or(settings, "consoleLanguage", 1); } } + void save(const std::filesystem::path& path) { toml::value data; @@ -655,9 +677,6 @@ void save(const std::filesystem::path& path) { data["Settings"]["consoleLanguage"] = m_language; - // TODO Migration code, after a major release this should be removed. - data.at("GUI").as_table().erase("installDir"); - std::ofstream file(path, std::ios::binary); file << data; file.close(); diff --git a/src/common/logging/filter.cpp b/src/common/logging/filter.cpp index 5ca594bf7..fc9fa0557 100644 --- a/src/common/logging/filter.cpp +++ b/src/common/logging/filter.cpp @@ -121,6 +121,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) { SUB(Lib, Fiber) \ SUB(Lib, Vdec2) \ SUB(Lib, Videodec) \ + SUB(Lib, RazorCpu) \ CLS(Frontend) \ CLS(Render) \ SUB(Render, Vulkan) \ diff --git a/src/common/logging/types.h b/src/common/logging/types.h index 2821729d4..1422c3926 100644 --- a/src/common/logging/types.h +++ b/src/common/logging/types.h @@ -88,6 +88,7 @@ enum class Class : u8 { Lib_Fiber, ///< The LibSceFiber implementation. Lib_Vdec2, ///< The LibSceVideodec2 implementation. Lib_Videodec, ///< The LibSceVideodec implementation. + Lib_RazorCpu, ///< The LibRazorCpu implementation. Frontend, ///< Emulator UI Render, ///< Video Core Render_Vulkan, ///< Vulkan backend diff --git a/src/core/libraries/libs.cpp b/src/core/libraries/libs.cpp index 537862a6c..53b67b395 100644 --- a/src/core/libraries/libs.cpp +++ b/src/core/libraries/libs.cpp @@ -28,6 +28,7 @@ #include "core/libraries/pad/pad.h" #include "core/libraries/playgo/playgo.h" #include "core/libraries/random/random.h" +#include "core/libraries/razor_cpu/razor_cpu.h" #include "core/libraries/remote_play/remoteplay.h" #include "core/libraries/rtc/rtc.h" #include "core/libraries/save_data/dialog/savedatadialog.h" @@ -87,6 +88,7 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) { Libraries::SharePlay::RegisterlibSceSharePlay(sym); Libraries::Remoteplay::RegisterlibSceRemoteplay(sym); Libraries::Videodec::RegisterlibSceVideodec(sym); + Libraries::RazorCpu::RegisterlibSceRazorCpu(sym); } } // namespace Libraries diff --git a/src/core/libraries/razor_cpu/razor_cpu.cpp b/src/core/libraries/razor_cpu/razor_cpu.cpp new file mode 100644 index 000000000..99707e972 --- /dev/null +++ b/src/core/libraries/razor_cpu/razor_cpu.cpp @@ -0,0 +1,249 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "razor_cpu.h" + +#include "common/logging/log.h" +#include "core/libraries/error_codes.h" +#include "core/libraries/libs.h" + +namespace Libraries::RazorCpu { + +s32 PS4_SYSV_ABI sceRazorCpuBeginLogicalFileAccess() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +void PS4_SYSV_ABI sceRazorCpuDisableFiberUserMarkers() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); +} + +s32 PS4_SYSV_ABI sceRazorCpuEndLogicalFileAccess() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceRazorCpuFiberLogNameChange() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceRazorCpuFiberSwitch() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +bool PS4_SYSV_ABI sceRazorCpuFlushOccurred() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return false; +} + +s32 PS4_SYSV_ABI sceRazorCpuGetDataTagStorageSize() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceRazorCpuGpuMarkerSync() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceRazorCpuInitDataTags() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceRazorCpuInitializeGpuMarkerContext() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceRazorCpuInitializeInternal() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +bool PS4_SYSV_ABI sceRazorCpuIsCapturing() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return false; +} + +s32 PS4_SYSV_ABI sceRazorCpuJobManagerDispatch() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceRazorCpuJobManagerJob() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceRazorCpuJobManagerSequence() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceRazorCpuNamedSync() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceRazorCpuPlotValue() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceRazorCpuPopMarker() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceRazorCpuPushMarker() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceRazorCpuPushMarkerStatic() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceRazorCpuResizeTaggedBuffer() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +void PS4_SYSV_ABI sceRazorCpuSetPopMarkerCallback() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); +} + +void PS4_SYSV_ABI sceRazorCpuSetPushMarkerCallback() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); +} + +void PS4_SYSV_ABI sceRazorCpuSetPushMarkerStaticCallback() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); +} + +s32 PS4_SYSV_ABI sceRazorCpuShutdownDataTags() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceRazorCpuStartCaptureInternal() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceRazorCpuStopCaptureInternal() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceRazorCpuSync() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceRazorCpuTagArray() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceRazorCpuTagBuffer() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceRazorCpuUnTagBuffer() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceRazorCpuWorkloadRunBegin() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceRazorCpuWorkloadRunEnd() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceRazorCpuWorkloadSubmit() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceRazorCpuWriteBookmark() { + LOG_DEBUG(Lib_RazorCpu, "(STUBBED) called"); + return ORBIS_OK; +} + +void RegisterlibSceRazorCpu(Core::Loader::SymbolsResolver* sym) { + LIB_FUNCTION("JFzLJBlYIJE", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuBeginLogicalFileAccess); + LIB_FUNCTION("SfRTRZ1Sh+U", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuDisableFiberUserMarkers); + LIB_FUNCTION("gVioM9cbiDs", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuEndLogicalFileAccess); + LIB_FUNCTION("G90IIOtgFQ0", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuFiberLogNameChange); + LIB_FUNCTION("PAytDtFGpqY", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuFiberSwitch); + LIB_FUNCTION("sPhrQD31ClM", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuFlushOccurred); + LIB_FUNCTION("B782NptkGUc", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuGetDataTagStorageSize); + LIB_FUNCTION("EH9Au2RlSrE", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuGpuMarkerSync); + LIB_FUNCTION("A7oRMdaOJP8", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuInitDataTags); + LIB_FUNCTION("NFwh-J-BrI0", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuInitializeGpuMarkerContext); + LIB_FUNCTION("ElNyedXaa4o", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuInitializeInternal); + LIB_FUNCTION("EboejOQvLL4", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuIsCapturing); + LIB_FUNCTION("dnEdyY4+klQ", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuJobManagerDispatch); + LIB_FUNCTION("KP+TBWGHlgs", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuJobManagerJob); + LIB_FUNCTION("9FowWFMEIM8", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuJobManagerSequence); + LIB_FUNCTION("XCuZoBSVFG8", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, sceRazorCpuNamedSync); + LIB_FUNCTION("njGikRrxkC0", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, sceRazorCpuPlotValue); + LIB_FUNCTION("YpkGsMXP3ew", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, sceRazorCpuPopMarker); + LIB_FUNCTION("zw+celG7zSI", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, sceRazorCpuPushMarker); + LIB_FUNCTION("uZrOwuNJX-M", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuPushMarkerStatic); + LIB_FUNCTION("D0yUjM33QqU", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuResizeTaggedBuffer); + LIB_FUNCTION("jqYWaTfgZs0", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuSetPopMarkerCallback); + LIB_FUNCTION("DJsHcEb94n0", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuSetPushMarkerCallback); + LIB_FUNCTION("EZtqozPTS4M", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuSetPushMarkerStaticCallback); + LIB_FUNCTION("emklx7RK-LY", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuShutdownDataTags); + LIB_FUNCTION("TIytAjYeaik", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuStartCaptureInternal); + LIB_FUNCTION("jWpkVWdMrsM", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuStopCaptureInternal); + LIB_FUNCTION("Ax7NjOzctIM", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, sceRazorCpuSync); + LIB_FUNCTION("we3oTKSPSTw", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, sceRazorCpuTagArray); + LIB_FUNCTION("vyjdThnQfQQ", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, sceRazorCpuTagBuffer); + LIB_FUNCTION("0yNHPIkVTmw", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuUnTagBuffer); + LIB_FUNCTION("Crha9LvwvJM", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuWorkloadRunBegin); + LIB_FUNCTION("q1GxBfGHO0s", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuWorkloadRunEnd); + LIB_FUNCTION("6rUvx-6QmYc", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuWorkloadSubmit); + LIB_FUNCTION("G3brhegfyNg", "libSceRazorCpu", 1, "libSceRazorCpu", 1, 1, + sceRazorCpuWriteBookmark); +} + +} // namespace Libraries::RazorCpu \ No newline at end of file diff --git a/src/core/libraries/razor_cpu/razor_cpu.h b/src/core/libraries/razor_cpu/razor_cpu.h new file mode 100644 index 000000000..ec25e44b9 --- /dev/null +++ b/src/core/libraries/razor_cpu/razor_cpu.h @@ -0,0 +1,17 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/types.h" + +#include +#include + +namespace Core::Loader { +class SymbolsResolver; +} + +namespace Libraries::RazorCpu { +void RegisterlibSceRazorCpu(Core::Loader::SymbolsResolver* sym); +} // namespace Libraries::RazorCpu \ No newline at end of file diff --git a/src/core/libraries/system/sysmodule.cpp b/src/core/libraries/system/sysmodule.cpp index 8ea61e177..9bed4ef31 100644 --- a/src/core/libraries/system/sysmodule.cpp +++ b/src/core/libraries/system/sysmodule.cpp @@ -48,10 +48,6 @@ int PS4_SYSV_ABI sceSysmoduleIsLoadedInternal(OrbisSysModuleInternal id) { LOG_ERROR(Lib_SysModule, "Invalid internal sysmodule ID: {:#x}", static_cast(id)); return ORBIS_SYSMODULE_INVALID_ID; } - if (id == OrbisSysModuleInternal::ORBIS_SYSMODULE_INTERNAL_RAZOR_CPU) { - // Internal debugging library, report as not loaded so it won't be used. - return ORBIS_SYSMODULE_NOT_LOADED; - } return ORBIS_OK; } From 36044043bcf4600fcda33eb80efde4c4ec5a514d Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Sat, 30 Nov 2024 02:08:34 -0800 Subject: [PATCH 10/32] config: Fix loading install directories. (#1626) --- src/common/config.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/common/config.cpp b/src/common/config.cpp index 5c857afb4..c01583990 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -578,6 +578,12 @@ void load(const std::filesystem::path& path) { m_window_size_W = toml::find_or(gui, "mw_width", 0); m_window_size_H = toml::find_or(gui, "mw_height", 0); + const auto install_dir_array = + toml::find_or>(gui, "installDirs", {}); + for (const auto& dir : install_dir_array) { + addGameInstallDir(std::filesystem::path{dir}); + } + settings_addon_install_dir = toml::find_fs_path_or(gui, "addonInstallDir", {}); main_window_geometry_x = toml::find_or(gui, "geometry_x", 0); main_window_geometry_y = toml::find_or(gui, "geometry_y", 0); From c0d43a1a5f304d21f4b7c9457108c2d21447905e Mon Sep 17 00:00:00 2001 From: Vladislav Mikhalin Date: Sat, 30 Nov 2024 17:05:08 +0300 Subject: [PATCH 11/32] Fixed incorrectly skipped RTs --- src/video_core/renderer_vulkan/vk_pipeline_cache.cpp | 5 ++--- src/video_core/renderer_vulkan/vk_rasterizer.cpp | 7 ------- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index b576d4780..fb158c55f 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -260,7 +260,7 @@ bool PipelineCache::RefreshGraphicsKey() { // recompiler. for (auto cb = 0u, remapped_cb = 0u; cb < Liverpool::NumColorBuffers; ++cb) { auto const& col_buf = regs.color_buffers[cb]; - if (skip_cb_binding || !col_buf || !regs.color_target_mask.GetMask(cb)) { + if (skip_cb_binding || !col_buf) { continue; } const auto base_format = @@ -362,8 +362,7 @@ bool PipelineCache::RefreshGraphicsKey() { // Second pass to fill remain CB pipeline key data for (auto cb = 0u, remapped_cb = 0u; cb < Liverpool::NumColorBuffers; ++cb) { auto const& col_buf = regs.color_buffers[cb]; - if (skip_cb_binding || !col_buf || !regs.color_target_mask.GetMask(cb) || - (key.mrt_mask & (1u << cb)) == 0) { + if (skip_cb_binding || !col_buf || (key.mrt_mask & (1u << cb)) == 0) { key.color_formats[cb] = vk::Format::eUndefined; key.mrt_swizzles[cb] = Liverpool::ColorBuffer::SwapMode::Standard; continue; diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index a6fc872d9..ff5e88141 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -95,13 +95,6 @@ RenderState Rasterizer::PrepareRenderState(u32 mrt_mask) { continue; } - // If the color buffer is still bound but rendering to it is disabled by the target - // mask, we need to prevent the render area from being affected by unbound render target - // extents. - if (!regs.color_target_mask.GetMask(col_buf_id)) { - continue; - } - // Skip stale color buffers if shader doesn't output to them. Otherwise it will perform // an unnecessary transition and may result in state conflict if the resource is already // bound for reading. From 07f4a0305ba9c53a220774c92aae5bbd9f9dae45 Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Sat, 30 Nov 2024 09:19:07 -0800 Subject: [PATCH 12/32] semaphore: Use condvars with separate signaled flag to prevent races (#1615) * Revert "semaphore: Use binary_semaphore instead of condvar" This reverts commit 85dc57b86875f7b0807dbc8d886cd5b1bdc407e7. * semaphore: Use separate signaled flag to prevent races * mutex: Few misc fixes * condvar: Few misc fixes * signals: Add thread name to unhandled signal message. --- src/core/libraries/kernel/threads/condvar.cpp | 7 +++-- src/core/libraries/kernel/threads/mutex.cpp | 5 +-- src/core/libraries/kernel/threads/pthread.h | 2 +- .../libraries/kernel/threads/semaphore.cpp | 31 ++++++++++--------- src/core/signals.cpp | 20 +++++++++--- 5 files changed, 40 insertions(+), 25 deletions(-) diff --git a/src/core/libraries/kernel/threads/condvar.cpp b/src/core/libraries/kernel/threads/condvar.cpp index 5831df9be..4437af964 100644 --- a/src/core/libraries/kernel/threads/condvar.cpp +++ b/src/core/libraries/kernel/threads/condvar.cpp @@ -122,7 +122,7 @@ int PthreadCond::Wait(PthreadMutexT* mutex, const OrbisKernelTimespec* abstime, SleepqUnlock(this); //_thr_cancel_enter2(curthread, 0); - int error = curthread->Sleep(abstime, usec) ? 0 : POSIX_ETIMEDOUT; + error = curthread->Sleep(abstime, usec) ? 0 : POSIX_ETIMEDOUT; //_thr_cancel_leave(curthread, 0); SleepqLock(this); @@ -145,7 +145,10 @@ int PthreadCond::Wait(PthreadMutexT* mutex, const OrbisKernelTimespec* abstime, } SleepqUnlock(this); curthread->mutex_obj = nullptr; - mp->CvLock(recurse); + int error2 = mp->CvLock(recurse); + if (error == 0) { + error = error2; + } return error; } diff --git a/src/core/libraries/kernel/threads/mutex.cpp b/src/core/libraries/kernel/threads/mutex.cpp index 2e3e689fa..fc0bf09bd 100644 --- a/src/core/libraries/kernel/threads/mutex.cpp +++ b/src/core/libraries/kernel/threads/mutex.cpp @@ -121,6 +121,7 @@ int PthreadMutex::SelfTryLock() { switch (Type()) { case PthreadMutexType::ErrorCheck: case PthreadMutexType::Normal: + case PthreadMutexType::AdaptiveNp: return POSIX_EBUSY; case PthreadMutexType::Recursive: { /* Increment the lock count: */ @@ -224,7 +225,7 @@ int PthreadMutex::Lock(const OrbisKernelTimespec* abstime, u64 usec) { [[unlikely]] { ret = POSIX_EINVAL; } else { - if (THR_RELTIME) { + if (abstime == THR_RELTIME) { ret = m_lock.try_lock_for(std::chrono::microseconds(usec)) ? 0 : POSIX_ETIMEDOUT; } else { ret = m_lock.try_lock_until(abstime->TimePoint()) ? 0 : POSIX_ETIMEDOUT; @@ -336,7 +337,7 @@ int PS4_SYSV_ABI posix_pthread_mutex_isowned_np(PthreadMutexT* mutex) { return m->m_owner == g_curthread; } -bool PthreadMutex::IsOwned(Pthread* curthread) const { +int PthreadMutex::IsOwned(Pthread* curthread) const { if (this <= THR_MUTEX_DESTROYED) [[unlikely]] { if (this == THR_MUTEX_DESTROYED) { return POSIX_EINVAL; diff --git a/src/core/libraries/kernel/threads/pthread.h b/src/core/libraries/kernel/threads/pthread.h index 0a3ab57dd..b41ca2abd 100644 --- a/src/core/libraries/kernel/threads/pthread.h +++ b/src/core/libraries/kernel/threads/pthread.h @@ -79,7 +79,7 @@ struct PthreadMutex { return Unlock(); } - bool IsOwned(Pthread* curthread) const; + int IsOwned(Pthread* curthread) const; }; using PthreadMutexT = PthreadMutex*; diff --git a/src/core/libraries/kernel/threads/semaphore.cpp b/src/core/libraries/kernel/threads/semaphore.cpp index 9fcbd4356..db14c298c 100644 --- a/src/core/libraries/kernel/threads/semaphore.cpp +++ b/src/core/libraries/kernel/threads/semaphore.cpp @@ -49,9 +49,7 @@ public: const auto it = AddWaiter(&waiter); // Perform the wait. - lk.unlock(); - const s32 result = waiter.Wait(timeout); - lk.lock(); + const s32 result = waiter.Wait(lk, timeout); if (result == SCE_KERNEL_ERROR_ETIMEDOUT) { wait_list.erase(it); } @@ -74,7 +72,8 @@ public: } it = wait_list.erase(it); token_count -= waiter->need_count; - waiter->sema.release(); + waiter->was_signaled = true; + waiter->cv.notify_one(); } return true; @@ -87,7 +86,7 @@ public: } for (auto* waiter : wait_list) { waiter->was_cancled = true; - waiter->sema.release(); + waiter->cv.notify_one(); } wait_list.clear(); token_count = set_count < 0 ? init_count : set_count; @@ -98,20 +97,21 @@ public: std::scoped_lock lk{mutex}; for (auto* waiter : wait_list) { waiter->was_deleted = true; - waiter->sema.release(); + waiter->cv.notify_one(); } wait_list.clear(); } public: struct WaitingThread { - std::binary_semaphore sema; + std::condition_variable cv; u32 priority; s32 need_count; + bool was_signaled{}; bool was_deleted{}; bool was_cancled{}; - explicit WaitingThread(s32 need_count, bool is_fifo) : sema{0}, need_count{need_count} { + explicit WaitingThread(s32 need_count, bool is_fifo) : need_count{need_count} { // Retrieve calling thread priority for sorting into waiting threads list. if (!is_fifo) { priority = g_curthread->attr.prio; @@ -131,24 +131,25 @@ public: return SCE_OK; } - int Wait(u32* timeout) { + int Wait(std::unique_lock& lk, u32* timeout) { if (!timeout) { // Wait indefinitely until we are woken up. - sema.acquire(); + cv.wait(lk); return GetResult(false); } // Wait until timeout runs out, recording how much remaining time there was. const auto start = std::chrono::high_resolution_clock::now(); - const auto sema_timeout = !sema.try_acquire_for(std::chrono::microseconds(*timeout)); + const auto signaled = cv.wait_for(lk, std::chrono::microseconds(*timeout), + [this] { return was_signaled; }); const auto end = std::chrono::high_resolution_clock::now(); const auto time = std::chrono::duration_cast(end - start).count(); - if (sema_timeout) { - *timeout = 0; - } else { + if (signaled) { *timeout -= time; + } else { + *timeout = 0; } - return GetResult(sema_timeout); + return GetResult(!signaled); } }; diff --git a/src/core/signals.cpp b/src/core/signals.cpp index 8faf794ed..89844ae25 100644 --- a/src/core/signals.cpp +++ b/src/core/signals.cpp @@ -41,6 +41,14 @@ static LONG WINAPI SignalHandler(EXCEPTION_POINTERS* pExp) noexcept { #else +static std::string GetThreadName() { + char name[256]; + if (pthread_getname_np(pthread_self(), name, sizeof(name)) != 0) { + return ""; + } + return std::string{name}; +} + static std::string DisassembleInstruction(void* code_address) { char buffer[256] = ""; @@ -71,16 +79,18 @@ static void SignalHandler(int sig, siginfo_t* info, void* raw_context) { case SIGBUS: { const bool is_write = Common::IsWriteError(raw_context); if (!signals->DispatchAccessViolation(raw_context, info->si_addr)) { - UNREACHABLE_MSG("Unhandled access violation at code address {}: {} address {}", - fmt::ptr(code_address), is_write ? "Write to" : "Read from", - fmt::ptr(info->si_addr)); + UNREACHABLE_MSG( + "Unhandled access violation in thread '{}' at code address {}: {} address {}", + GetThreadName(), fmt::ptr(code_address), is_write ? "Write to" : "Read from", + fmt::ptr(info->si_addr)); } break; } case SIGILL: if (!signals->DispatchIllegalInstruction(raw_context)) { - UNREACHABLE_MSG("Unhandled illegal instruction at code address {}: {}", - fmt::ptr(code_address), DisassembleInstruction(code_address)); + UNREACHABLE_MSG("Unhandled illegal instruction in thread '{}' at code address {}: {}", + GetThreadName(), fmt::ptr(code_address), + DisassembleInstruction(code_address)); } break; case SIGUSR1: { // Sleep thread until signal is received From 2002e37ce9a3581ab7668ee289e57a4d44a96a78 Mon Sep 17 00:00:00 2001 From: Vinicius Rangel Date: Sat, 30 Nov 2024 16:15:55 -0300 Subject: [PATCH 13/32] Allow shader patching (#1633) --- documents/patching-shader.md | 19 ++++++++++++ src/common/config.cpp | 7 +++++ src/common/config.h | 1 + .../renderer_vulkan/vk_pipeline_cache.cpp | 30 ++++++++++++++++++- .../renderer_vulkan/vk_pipeline_cache.h | 2 ++ 5 files changed, 58 insertions(+), 1 deletion(-) create mode 100644 documents/patching-shader.md diff --git a/documents/patching-shader.md b/documents/patching-shader.md new file mode 100644 index 000000000..613e89bf9 --- /dev/null +++ b/documents/patching-shader.md @@ -0,0 +1,19 @@ + + +### Install Vulkan SDK and \*ensure `spirv-cross` and `glslc` are in PATH\*. + +1. Enable `dumpShaders` in config.toml + +2. Run `spirv-cross -V fs_0x000000.spv --output fs_0x000000.glsl` to decompile the SPIR-V IR to GLSL. + +3. Edit the GLSL file as you wish + +4. To compile back to SPIR-V, run (change the _**-fshader-stage**_ to correct stage): + `glslc --target-env=vulkan1.3 --target-spv=spv1.6 -fshader-stage=frag fs_0x000000.glsl -o fs_0x000000.spv` + +5. Put the updated .spv file to `shader/patch` folder with the same name as the original shader + +6. Enable `patchShaders` in config.toml \ No newline at end of file diff --git a/src/common/config.cpp b/src/common/config.cpp index c01583990..5c2c8cda6 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -52,6 +52,7 @@ static bool isAutoUpdate = false; static bool isNullGpu = false; static bool shouldCopyGPUBuffers = false; static bool shouldDumpShaders = false; +static bool shouldPatchShaders = true; static u32 vblankDivider = 1; static bool vkValidation = false; static bool vkValidationSync = false; @@ -178,6 +179,10 @@ bool dumpShaders() { return shouldDumpShaders; } +bool patchShaders() { + return shouldPatchShaders; +} + bool isRdocEnabled() { return rdocEnable; } @@ -546,6 +551,7 @@ void load(const std::filesystem::path& path) { isNullGpu = toml::find_or(gpu, "nullGpu", false); shouldCopyGPUBuffers = toml::find_or(gpu, "copyGPUBuffers", false); shouldDumpShaders = toml::find_or(gpu, "dumpShaders", false); + shouldPatchShaders = toml::find_or(gpu, "patchShaders", true); vblankDivider = toml::find_or(gpu, "vblankDivider", 1); } @@ -646,6 +652,7 @@ void save(const std::filesystem::path& path) { data["GPU"]["nullGpu"] = isNullGpu; data["GPU"]["copyGPUBuffers"] = shouldCopyGPUBuffers; data["GPU"]["dumpShaders"] = shouldDumpShaders; + data["GPU"]["patchShaders"] = shouldPatchShaders; data["GPU"]["vblankDivider"] = vblankDivider; data["Vulkan"]["gpuId"] = gpuId; data["Vulkan"]["validation"] = vkValidation; diff --git a/src/common/config.h b/src/common/config.h index 9c71c96a8..400115745 100644 --- a/src/common/config.h +++ b/src/common/config.h @@ -42,6 +42,7 @@ bool autoUpdate(); bool nullGpu(); bool copyGPUCmdBuffers(); bool dumpShaders(); +bool patchShaders(); bool isRdocEnabled(); u32 vblankDiv(); diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index b576d4780..d2220dec0 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -406,8 +406,13 @@ vk::ShaderModule PipelineCache::CompileModule(Shader::Info& info, DumpShader(code, info.pgm_hash, info.stage, perm_idx, "bin"); const auto ir_program = Shader::TranslateProgram(code, pools, info, runtime_info, profile); - const auto spv = Shader::Backend::SPIRV::EmitSPIRV(profile, runtime_info, ir_program, binding); + auto spv = Shader::Backend::SPIRV::EmitSPIRV(profile, runtime_info, ir_program, binding); DumpShader(spv, info.pgm_hash, info.stage, perm_idx, "spv"); + auto patch = GetShaderPatch(info.pgm_hash, info.stage, perm_idx, "spv"); + if (patch) { + spv = *patch; + LOG_INFO(Loader, "Loaded patch for {} shader {:#x}", info.stage, info.pgm_hash); + } const auto module = CompileSPV(spv, instance.GetDevice()); const auto name = fmt::format("{}_{:#x}_{}", info.stage, info.pgm_hash, perm_idx); @@ -465,4 +470,27 @@ void PipelineCache::DumpShader(std::span code, u64 hash, Shader::Stag file.WriteSpan(code); } +std::optional> PipelineCache::GetShaderPatch(u64 hash, Shader::Stage stage, + size_t perm_idx, + std::string_view ext) { + if (!Config::patchShaders()) { + return {}; + } + + using namespace Common::FS; + const auto patch_dir = GetUserPath(PathType::ShaderDir) / "patch"; + if (!std::filesystem::exists(patch_dir)) { + std::filesystem::create_directories(patch_dir); + } + const auto filename = fmt::format("{}_{:#018x}_{}.{}", stage, hash, perm_idx, ext); + const auto filepath = patch_dir / filename; + if (!std::filesystem::exists(filepath)) { + return {}; + } + const auto file = IOFile{patch_dir / filename, FileAccessMode::Read}; + std::vector code(file.GetSize() / sizeof(u32)); + file.Read(code); + return code; +} + } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h index 43facbae4..662bcbd80 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h @@ -56,6 +56,8 @@ private: void DumpShader(std::span code, u64 hash, Shader::Stage stage, size_t perm_idx, std::string_view ext); + std::optional> GetShaderPatch(u64 hash, Shader::Stage stage, size_t perm_idx, + std::string_view ext); vk::ShaderModule CompileModule(Shader::Info& info, const Shader::RuntimeInfo& runtime_info, std::span code, size_t perm_idx, Shader::Backend::Bindings& binding); From 7153838c4ec8b3363fd3e72a8c58880b142eb439 Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Sat, 30 Nov 2024 11:43:12 -0800 Subject: [PATCH 14/32] libraries: Add initial HLE JPEG encoder skeleton (#1607) * libraries: Add initial HLE JPEG encoder skeleton * jpegenc: Finish adding parameter validation. * updated enums , added logging * jpegenc: Clean up parameter validations. * jpegenc: Fix missing log. * externals: Update ffmpeg-core --------- Co-authored-by: georgemoralis --- CMakeLists.txt | 6 + externals/ffmpeg-core | 2 +- src/common/alignment.h | 6 + src/common/logging/filter.cpp | 1 + src/common/logging/types.h | 1 + src/core/libraries/jpeg/jpeg_error.h | 9 ++ src/core/libraries/jpeg/jpegenc.cpp | 207 +++++++++++++++++++++++++++ src/core/libraries/jpeg/jpegenc.h | 84 +++++++++++ src/emulator.cpp | 3 +- 9 files changed, 317 insertions(+), 2 deletions(-) create mode 100644 src/core/libraries/jpeg/jpeg_error.h create mode 100644 src/core/libraries/jpeg/jpegenc.cpp create mode 100644 src/core/libraries/jpeg/jpegenc.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 55f1172f2..c4f639bdd 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -354,6 +354,11 @@ set(PNG_LIB src/core/libraries/libpng/pngdec.cpp src/core/libraries/libpng/pngdec.h ) +set(JPEG_LIB src/core/libraries/jpeg/jpeg_error.h + src/core/libraries/jpeg/jpegenc.cpp + src/core/libraries/jpeg/jpegenc.h +) + set(PLAYGO_LIB src/core/libraries/playgo/playgo.cpp src/core/libraries/playgo/playgo.h src/core/libraries/playgo/playgo_types.h @@ -536,6 +541,7 @@ set(CORE src/core/aerolib/stubs.cpp ${VIDEOOUT_LIB} ${NP_LIBS} ${PNG_LIB} + ${JPEG_LIB} ${PLAYGO_LIB} ${RANDOM_LIB} ${USBD_LIB} diff --git a/externals/ffmpeg-core b/externals/ffmpeg-core index e30b7d7fe..27de97c82 160000 --- a/externals/ffmpeg-core +++ b/externals/ffmpeg-core @@ -1 +1 @@ -Subproject commit e30b7d7fe228bfb3f6e41ce1040b44a15eb7d5e0 +Subproject commit 27de97c826b6b40c255891c37ac046a25836a575 diff --git a/src/common/alignment.h b/src/common/alignment.h index 8480fae26..3fb961c63 100644 --- a/src/common/alignment.h +++ b/src/common/alignment.h @@ -22,6 +22,12 @@ template return static_cast(value - value % size); } +template + requires std::is_integral_v +[[nodiscard]] constexpr bool IsAligned(T value, std::size_t alignment) { + return (value & (alignment - 1)) == 0; +} + template requires std::is_integral_v [[nodiscard]] constexpr bool Is16KBAligned(T value) { diff --git a/src/common/logging/filter.cpp b/src/common/logging/filter.cpp index fc9fa0557..5f44658f0 100644 --- a/src/common/logging/filter.cpp +++ b/src/common/logging/filter.cpp @@ -105,6 +105,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) { SUB(Lib, Rtc) \ SUB(Lib, DiscMap) \ SUB(Lib, Png) \ + SUB(Lib, Jpeg) \ SUB(Lib, PlayGo) \ SUB(Lib, Random) \ SUB(Lib, Usbd) \ diff --git a/src/common/logging/types.h b/src/common/logging/types.h index 1422c3926..a373e8f1b 100644 --- a/src/common/logging/types.h +++ b/src/common/logging/types.h @@ -72,6 +72,7 @@ enum class Class : u8 { Lib_Rtc, ///< The LibSceRtc implementation. Lib_DiscMap, ///< The LibSceDiscMap implementation. Lib_Png, ///< The LibScePng implementation. + Lib_Jpeg, ///< The LibSceJpeg implementation. Lib_PlayGo, ///< The LibScePlayGo implementation. Lib_Random, ///< The libSceRandom implementation. Lib_Usbd, ///< The LibSceUsbd implementation. diff --git a/src/core/libraries/jpeg/jpeg_error.h b/src/core/libraries/jpeg/jpeg_error.h new file mode 100644 index 000000000..b9aa7483c --- /dev/null +++ b/src/core/libraries/jpeg/jpeg_error.h @@ -0,0 +1,9 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +constexpr int ORBIS_JPEG_ENC_ERROR_INVALID_ADDR = 0x80650101; +constexpr int ORBIS_JPEG_ENC_ERROR_INVALID_SIZE = 0x80650102; +constexpr int ORBIS_JPEG_ENC_ERROR_INVALID_PARAM = 0x80650103; +constexpr int ORBIS_JPEG_ENC_ERROR_INVALID_HANDLE = 0x80650104; diff --git a/src/core/libraries/jpeg/jpegenc.cpp b/src/core/libraries/jpeg/jpegenc.cpp new file mode 100644 index 000000000..b664a2334 --- /dev/null +++ b/src/core/libraries/jpeg/jpegenc.cpp @@ -0,0 +1,207 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include "common/alignment.h" +#include "common/assert.h" +#include "common/logging/log.h" +#include "core/libraries/error_codes.h" +#include "core/libraries/libs.h" +#include "jpeg_error.h" +#include "jpegenc.h" + +namespace Libraries::JpegEnc { + +constexpr s32 ORBIS_JPEG_ENC_MINIMUM_MEMORY_SIZE = 0x800; +constexpr u32 ORBIS_JPEG_ENC_MAX_IMAGE_DIMENSION = 0xFFFF; +constexpr u32 ORBIS_JPEG_ENC_MAX_IMAGE_PITCH = 0xFFFFFFF; +constexpr u32 ORBIS_JPEG_ENC_MAX_IMAGE_SIZE = 0x7FFFFFFF; + +static s32 ValidateJpegEncCreateParam(const OrbisJpegEncCreateParam* param) { + if (!param) { + return ORBIS_JPEG_ENC_ERROR_INVALID_ADDR; + } + if (param->size != sizeof(OrbisJpegEncCreateParam)) { + return ORBIS_JPEG_ENC_ERROR_INVALID_SIZE; + } + if (param->attr != ORBIS_JPEG_ENC_ATTRIBUTE_NONE) { + return ORBIS_JPEG_ENC_ERROR_INVALID_PARAM; + } + return ORBIS_OK; +} + +static s32 ValidateJpegEncMemory(const void* memory, const u32 memory_size) { + if (!memory) { + return ORBIS_JPEG_ENC_ERROR_INVALID_ADDR; + } + if (memory_size < ORBIS_JPEG_ENC_MINIMUM_MEMORY_SIZE) { + return ORBIS_JPEG_ENC_ERROR_INVALID_SIZE; + } + return ORBIS_OK; +} + +static s32 ValidateJpegEncEncodeParam(const OrbisJpegEncEncodeParam* param) { + + // Validate addresses + if (!param) { + return ORBIS_JPEG_ENC_ERROR_INVALID_ADDR; + } + if (!param->image || (param->pixel_format != ORBIS_JPEG_ENC_PIXEL_FORMAT_Y8 && + !Common::IsAligned(reinterpret_cast(param->image), 4))) { + return ORBIS_JPEG_ENC_ERROR_INVALID_ADDR; + } + if (!param->jpeg) { + return ORBIS_JPEG_ENC_ERROR_INVALID_ADDR; + } + + // Validate sizes + if (param->image_size == 0 || param->jpeg_size == 0) { + return ORBIS_JPEG_ENC_ERROR_INVALID_SIZE; + } + + // Validate parameters + if (param->image_width > ORBIS_JPEG_ENC_MAX_IMAGE_DIMENSION || + param->image_height > ORBIS_JPEG_ENC_MAX_IMAGE_DIMENSION) { + return ORBIS_JPEG_ENC_ERROR_INVALID_PARAM; + } + if (param->image_pitch == 0 || param->image_pitch > ORBIS_JPEG_ENC_MAX_IMAGE_PITCH || + (param->pixel_format != ORBIS_JPEG_ENC_PIXEL_FORMAT_Y8 && + !Common::IsAligned(param->image_pitch, 4))) { + return ORBIS_JPEG_ENC_ERROR_INVALID_PARAM; + } + const auto calculated_size = param->image_height * param->image_pitch; + if (calculated_size > ORBIS_JPEG_ENC_MAX_IMAGE_SIZE || calculated_size > param->image_size) { + return ORBIS_JPEG_ENC_ERROR_INVALID_PARAM; + } + if (param->encode_mode != ORBIS_JPEG_ENC_ENCODE_MODE_NORMAL && + param->encode_mode != ORBIS_JPEG_ENC_ENCODE_MODE_MJPEG) { + return ORBIS_JPEG_ENC_ERROR_INVALID_PARAM; + } + if (param->color_space != ORBIS_JPEG_ENC_COLOR_SPACE_YCC && + param->color_space != ORBIS_JPEG_ENC_COLOR_SPACE_GRAYSCALE) { + return ORBIS_JPEG_ENC_ERROR_INVALID_PARAM; + } + if (param->sampling_type != ORBIS_JPEG_ENC_SAMPLING_TYPE_FULL && + param->sampling_type != ORBIS_JPEG_ENC_SAMPLING_TYPE_422 && + param->sampling_type != ORBIS_JPEG_ENC_SAMPLING_TYPE_420) { + return ORBIS_JPEG_ENC_ERROR_INVALID_PARAM; + } + if (param->restart_interval > ORBIS_JPEG_ENC_MAX_IMAGE_DIMENSION) { + return ORBIS_JPEG_ENC_ERROR_INVALID_PARAM; + } + switch (param->pixel_format) { + case ORBIS_JPEG_ENC_PIXEL_FORMAT_R8G8B8A8: + case ORBIS_JPEG_ENC_PIXEL_FORMAT_B8G8R8A8: + if (param->image_pitch >> 2 < param->image_width || + param->color_space != ORBIS_JPEG_ENC_COLOR_SPACE_YCC || + param->sampling_type == ORBIS_JPEG_ENC_SAMPLING_TYPE_FULL) { + return ORBIS_JPEG_ENC_ERROR_INVALID_PARAM; + } + break; + case ORBIS_JPEG_ENC_PIXEL_FORMAT_Y8U8Y8V8: + if (param->image_pitch >> 1 < Common::AlignUp(param->image_width, 2) || + param->color_space != ORBIS_JPEG_ENC_COLOR_SPACE_YCC || + param->sampling_type == ORBIS_JPEG_ENC_SAMPLING_TYPE_FULL) { + return ORBIS_JPEG_ENC_ERROR_INVALID_PARAM; + } + break; + case ORBIS_JPEG_ENC_PIXEL_FORMAT_Y8: + if (param->image_pitch < param->image_width || + param->color_space != ORBIS_JPEG_ENC_COLOR_SPACE_GRAYSCALE || + param->sampling_type != ORBIS_JPEG_ENC_SAMPLING_TYPE_FULL) { + return ORBIS_JPEG_ENC_ERROR_INVALID_PARAM; + } + break; + default: + return ORBIS_JPEG_ENC_ERROR_INVALID_PARAM; + } + + return ORBIS_OK; +} + +static s32 ValidateJpecEngHandle(OrbisJpegEncHandle handle) { + if (!handle || !Common::IsAligned(reinterpret_cast(handle), 0x20) || + handle->handle != handle) { + return ORBIS_JPEG_ENC_ERROR_INVALID_HANDLE; + } + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceJpegEncCreate(const OrbisJpegEncCreateParam* param, void* memory, + const u32 memory_size, OrbisJpegEncHandle* handle) { + if (auto param_ret = ValidateJpegEncCreateParam(param); param_ret != ORBIS_OK) { + LOG_ERROR(Lib_Jpeg, "Invalid create param"); + return param_ret; + } + if (auto memory_ret = ValidateJpegEncMemory(memory, memory_size); memory_ret != ORBIS_OK) { + LOG_ERROR(Lib_Jpeg, "Invalid memory"); + return memory_ret; + } + if (!handle) { + LOG_ERROR(Lib_Jpeg, "Invalid handle output"); + return ORBIS_JPEG_ENC_ERROR_INVALID_ADDR; + } + + auto* handle_internal = reinterpret_cast( + Common::AlignUp(reinterpret_cast(memory), 0x20)); + handle_internal->handle = handle_internal; + handle_internal->handle_size = sizeof(OrbisJpegEncHandleInternal*); + *handle = handle_internal; + + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceJpegEncDelete(OrbisJpegEncHandle handle) { + if (auto handle_ret = ValidateJpecEngHandle(handle); handle_ret != ORBIS_OK) { + LOG_ERROR(Lib_Jpeg, "Invalid handle"); + return handle_ret; + } + handle->handle = nullptr; + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceJpegEncEncode(OrbisJpegEncHandle handle, const OrbisJpegEncEncodeParam* param, + OrbisJpegEncOutputInfo* output_info) { + if (auto handle_ret = ValidateJpecEngHandle(handle); handle_ret != ORBIS_OK) { + LOG_ERROR(Lib_Jpeg, "Invalid handle"); + return handle_ret; + } + if (auto param_ret = ValidateJpegEncEncodeParam(param); param_ret != ORBIS_OK) { + LOG_ERROR(Lib_Jpeg, "Invalid encode param"); + return param_ret; + } + + LOG_ERROR(Lib_Jpeg, + "(STUBBED) image_size = {} , jpeg_size = {} , image_width = {} , image_height = {} , " + "image_pitch = {} , pixel_format = {} , encode_mode = {} , color_space = {} , " + "sampling_type = {} , compression_ratio = {} , restart_interval = {}", + param->image_size, param->jpeg_size, param->image_width, param->image_height, + param->image_pitch, magic_enum::enum_name(param->pixel_format), + magic_enum::enum_name(param->encode_mode), magic_enum::enum_name(param->color_space), + magic_enum::enum_name(param->sampling_type), param->compression_ratio, + param->restart_interval); + + if (output_info) { + output_info->size = param->jpeg_size; + output_info->height = param->image_height; + } + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceJpegEncQueryMemorySize(const OrbisJpegEncCreateParam* param) { + if (auto param_ret = ValidateJpegEncCreateParam(param); param_ret != ORBIS_OK) { + LOG_ERROR(Lib_Jpeg, "Invalid create param"); + return param_ret; + } + return ORBIS_JPEG_ENC_MINIMUM_MEMORY_SIZE; +} + +void RegisterlibSceJpegEnc(Core::Loader::SymbolsResolver* sym) { + LIB_FUNCTION("K+rocojkr-I", "libSceJpegEnc", 1, "libSceJpegEnc", 1, 1, sceJpegEncCreate); + LIB_FUNCTION("j1LyMdaM+C0", "libSceJpegEnc", 1, "libSceJpegEnc", 1, 1, sceJpegEncDelete); + LIB_FUNCTION("QbrU0cUghEM", "libSceJpegEnc", 1, "libSceJpegEnc", 1, 1, sceJpegEncEncode); + LIB_FUNCTION("o6ZgXfFdWXQ", "libSceJpegEnc", 1, "libSceJpegEnc", 1, 1, + sceJpegEncQueryMemorySize); +}; + +} // namespace Libraries::JpegEnc diff --git a/src/core/libraries/jpeg/jpegenc.h b/src/core/libraries/jpeg/jpegenc.h new file mode 100644 index 000000000..a6b4d311a --- /dev/null +++ b/src/core/libraries/jpeg/jpegenc.h @@ -0,0 +1,84 @@ +// 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::JpegEnc { + +enum OrbisJpegEncCreateParamAttributes : u32 { ORBIS_JPEG_ENC_ATTRIBUTE_NONE = 0 }; + +enum OrbisJpegEncEncodeParamPixelFormat : u16 { + ORBIS_JPEG_ENC_PIXEL_FORMAT_R8G8B8A8 = 0, + ORBIS_JPEG_ENC_PIXEL_FORMAT_B8G8R8A8 = 1, + ORBIS_JPEG_ENC_PIXEL_FORMAT_Y8U8Y8V8 = 10, + ORBIS_JPEG_ENC_PIXEL_FORMAT_Y8 = 11 +}; + +enum OrbisJpengEncEncodeParamEncodeMode : u16 { + ORBIS_JPEG_ENC_ENCODE_MODE_NORMAL = 0, + ORBIS_JPEG_ENC_ENCODE_MODE_MJPEG = 1 +}; + +enum OrbisJpengEncEncodeParamColorSpace : u16 { + ORBIS_JPEG_ENC_COLOR_SPACE_YCC = 1, + ORBIS_JPEG_ENC_COLOR_SPACE_GRAYSCALE = 2 +}; + +enum OrbisJpengEncEncodeParamSamplingType : u8 { + ORBIS_JPEG_ENC_SAMPLING_TYPE_FULL = 0, + ORBIS_JPEG_ENC_SAMPLING_TYPE_422 = 1, + ORBIS_JPEG_ENC_SAMPLING_TYPE_420 = 2 +}; + +struct OrbisJpegEncHandleInternal { + OrbisJpegEncHandleInternal* handle; + u32 handle_size; +}; +static_assert(sizeof(OrbisJpegEncHandleInternal) == 0x10); + +typedef OrbisJpegEncHandleInternal* OrbisJpegEncHandle; + +struct OrbisJpegEncCreateParam { + u32 size; + OrbisJpegEncCreateParamAttributes attr; +}; +static_assert(sizeof(OrbisJpegEncCreateParam) == 0x8); + +struct OrbisJpegEncEncodeParam { + void* image; + void* jpeg; + u32 image_size; + u32 jpeg_size; + u32 image_width; + u32 image_height; + u32 image_pitch; + OrbisJpegEncEncodeParamPixelFormat pixel_format; + OrbisJpengEncEncodeParamEncodeMode encode_mode; + OrbisJpengEncEncodeParamColorSpace color_space; + OrbisJpengEncEncodeParamSamplingType sampling_type; + u8 compression_ratio; + s32 restart_interval; +}; +static_assert(sizeof(OrbisJpegEncEncodeParam) == 0x30); + +struct OrbisJpegEncOutputInfo { + u32 size; + u32 height; +}; +static_assert(sizeof(OrbisJpegEncOutputInfo) == 0x8); + +s32 PS4_SYSV_ABI sceJpegEncCreate(const OrbisJpegEncCreateParam* param, void* memory, + u32 memory_size, OrbisJpegEncHandle* handle); +s32 PS4_SYSV_ABI sceJpegEncDelete(OrbisJpegEncHandle handle); +s32 PS4_SYSV_ABI sceJpegEncEncode(OrbisJpegEncHandle handle, const OrbisJpegEncEncodeParam* param, + OrbisJpegEncOutputInfo* output_info); +s32 PS4_SYSV_ABI sceJpegEncQueryMemorySize(const OrbisJpegEncCreateParam* param); + +void RegisterlibSceJpegEnc(Core::Loader::SymbolsResolver* sym); +} // namespace Libraries::JpegEnc diff --git a/src/emulator.cpp b/src/emulator.cpp index 27291707d..a01eb816b 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -29,6 +29,7 @@ #include "core/file_sys/fs.h" #include "core/libraries/disc_map/disc_map.h" #include "core/libraries/fiber/fiber.h" +#include "core/libraries/jpeg/jpegenc.h" #include "core/libraries/libc_internal/libc_internal.h" #include "core/libraries/libs.h" #include "core/libraries/ngs2/ngs2.h" @@ -278,7 +279,7 @@ void Emulator::LoadSystemModules(const std::filesystem::path& file, std::string {"libSceLibcInternal.sprx", &Libraries::LibcInternal::RegisterlibSceLibcInternal}, {"libSceDiscMap.sprx", &Libraries::DiscMap::RegisterlibSceDiscMap}, {"libSceRtc.sprx", &Libraries::Rtc::RegisterlibSceRtc}, - {"libSceJpegEnc.sprx", nullptr}, + {"libSceJpegEnc.sprx", &Libraries::JpegEnc::RegisterlibSceJpegEnc}, {"libSceCesCs.sprx", nullptr}}}; std::vector found_modules; From 3d0aacd43d315e031d2efea0876627f4983cc79a Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Sat, 30 Nov 2024 12:24:32 -0800 Subject: [PATCH 15/32] ci: Limit build parallelism to number of processors. (#1632) --- .github/workflows/build.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 53b4c7386..878c10868 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -92,7 +92,7 @@ jobs: run: cmake --fresh -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache - name: Build - run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel + run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $env:NUMBER_OF_PROCESSORS - name: Upload Windows SDL artifact uses: actions/upload-artifact@v4 @@ -146,7 +146,7 @@ jobs: run: cmake --fresh -G Ninja -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DENABLE_QT_GUI=ON -DENABLE_UPDATER=ON -DCMAKE_C_COMPILER=clang-cl -DCMAKE_CXX_COMPILER=clang-cl -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache - name: Build - run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel + run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $env:NUMBER_OF_PROCESSORS - name: Deploy and Package run: | @@ -315,7 +315,7 @@ jobs: run: cmake --fresh -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache - name: Build - run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel + run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $(nproc) - name: Package and Upload Linux(ubuntu64) SDL artifact run: | @@ -371,7 +371,7 @@ jobs: run: cmake --fresh -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}} -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DENABLE_QT_GUI=ON -DENABLE_UPDATER=ON -DCMAKE_C_COMPILER_LAUNCHER=ccache -DCMAKE_CXX_COMPILER_LAUNCHER=ccache - name: Build - run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel3 + run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}} --parallel $(nproc) - name: Run AppImage packaging script run: ./.github/linux-appimage-qt.sh From 5b6e0ab238fe6893dbc0777d98bc2662b5aa7f96 Mon Sep 17 00:00:00 2001 From: TheTurtle Date: Sat, 30 Nov 2024 22:37:36 +0200 Subject: [PATCH 16/32] core: Library cleanup (#1631) * core: Split error codes into separate files * Reduces build times and is cleaner * core: Bring structs and enums to codebase style * core: More style changes --- CMakeLists.txt | 50 +- src/audio_core/sdl_audio.cpp | 166 ----- src/audio_core/sdl_audio.h | 39 -- src/common/memory_patcher.cpp | 10 +- src/core/cpu_patches.h | 2 + .../devtools/widget/imgui_memory_editor.h | 2 +- src/core/devtools/widget/text_editor.cpp | 2 +- src/core/file_format/playgo_chunk.h | 21 +- .../libraries/app_content/app_content.cpp | 59 +- src/core/libraries/app_content/app_content.h | 20 +- .../libraries/app_content/app_content_error.h | 11 + src/core/libraries/audio/audioout.cpp | 84 ++- src/core/libraries/audio/audioout.h | 56 +- src/core/libraries/audio/audioout_error.h | 34 + src/core/libraries/audio/sdl_audio.cpp | 141 ++++ src/core/libraries/audio/sdl_audio.h | 42 ++ src/core/libraries/audio3d/audio3d.cpp | 58 +- src/core/libraries/audio3d/audio3d.h | 123 ++-- src/core/libraries/audio3d/audio3d_error.h | 2 + src/core/libraries/audio3d/audio3d_impl.h | 2 +- src/core/libraries/avplayer/avplayer.cpp | 2 +- src/core/libraries/avplayer/avplayer.h | 106 +-- .../libraries/avplayer/avplayer_common.cpp | 12 +- src/core/libraries/avplayer/avplayer_error.h | 19 + src/core/libraries/avplayer/avplayer_impl.cpp | 2 +- .../libraries/avplayer/avplayer_source.cpp | 19 +- .../libraries/avplayer/avplayer_state.cpp | 33 +- src/core/libraries/avplayer/avplayer_state.h | 2 +- src/core/libraries/error_codes.h | 620 ------------------ src/core/libraries/fiber/fiber.cpp | 2 +- src/core/libraries/fiber/fiber.h | 7 +- src/core/libraries/fiber/fiber_error.h | 14 + src/core/libraries/gnmdriver/gnm_error.h | 2 + src/core/libraries/gnmdriver/gnmdriver.cpp | 3 +- src/core/libraries/ime/ime.cpp | 28 +- src/core/libraries/ime/ime.h | 37 +- src/core/libraries/ime/ime_common.h | 137 ++-- src/core/libraries/ime/ime_dialog.cpp | 58 +- src/core/libraries/ime/ime_dialog.h | 84 +-- src/core/libraries/ime/ime_dialog_ui.cpp | 68 +- src/core/libraries/ime/ime_dialog_ui.h | 4 +- src/core/libraries/ime/ime_error.h | 51 ++ src/core/libraries/ime/ime_ui.cpp | 38 +- src/core/libraries/kernel/equeue.cpp | 6 +- src/core/libraries/kernel/file_system.cpp | 50 +- src/core/libraries/kernel/file_system.h | 4 +- src/core/libraries/kernel/kernel.cpp | 35 +- src/core/libraries/kernel/kernel.h | 5 +- src/core/libraries/kernel/memory.cpp | 52 +- src/core/libraries/kernel/orbis_error.h | 108 +++ src/core/libraries/kernel/posix_error.h | 128 ++++ src/core/libraries/kernel/process.cpp | 4 +- src/core/libraries/kernel/threads/condvar.cpp | 2 +- .../libraries/kernel/threads/event_flag.cpp | 2 +- src/core/libraries/kernel/threads/mutex.cpp | 3 +- src/core/libraries/kernel/threads/pthread.cpp | 4 +- .../libraries/kernel/threads/pthread_attr.cpp | 2 +- .../libraries/kernel/threads/pthread_spec.cpp | 3 +- src/core/libraries/kernel/threads/rwlock.cpp | 2 +- .../libraries/kernel/threads/semaphore.cpp | 20 +- src/core/libraries/kernel/threads/sleepq.h | 7 +- .../libraries/kernel/threads/thread_state.cpp | 2 +- src/core/libraries/kernel/time.cpp | 24 +- src/core/libraries/kernel/time.h | 2 +- src/core/libraries/libpng/pngdec.cpp | 146 ++--- src/core/libraries/libpng/pngdec.h | 73 ++- src/core/libraries/libpng/pngdec_error.h | 17 + src/core/libraries/network/netctl.h | 4 +- src/core/libraries/ngs2/ngs2.cpp | 9 +- src/core/libraries/ngs2/ngs2.h | 11 +- src/core/libraries/np_manager/np_manager.cpp | 26 +- src/core/libraries/np_manager/np_manager.h | 10 +- src/core/libraries/np_trophy/np_trophy.cpp | 6 +- src/core/libraries/np_trophy/np_trophy.h | 68 +- .../libraries/np_trophy/np_trophy_error.h | 49 ++ src/core/libraries/pad/pad.cpp | 13 +- src/core/libraries/pad/pad.h | 67 +- src/core/libraries/pad/pad_errors.h | 22 + src/core/libraries/playgo/playgo.cpp | 231 ++++--- src/core/libraries/playgo/playgo_types.h | 50 +- src/core/libraries/random/random.h | 6 +- src/core/libraries/rtc/rtc.cpp | 87 ++- src/core/libraries/rtc/rtc.h | 27 +- src/core/libraries/rtc/rtc_error.h | 4 +- src/core/libraries/system/systemservice.cpp | 47 +- src/core/libraries/system/systemservice.h | 187 +++--- .../libraries/system/systemservice_error.h | 10 + src/core/libraries/system/userservice.cpp | 8 +- src/core/libraries/system/userservice.h | 18 +- src/core/libraries/system/userservice_error.h | 17 + src/core/libraries/videodec/videodec.cpp | 9 +- src/core/libraries/videodec/videodec2.cpp | 9 +- src/core/libraries/videodec/videodec2.h | 2 +- .../libraries/videodec/videodec2_impl.cpp | 3 +- src/core/libraries/videodec/videodec_error.h | 68 ++ src/core/libraries/videodec/videodec_impl.cpp | 2 +- src/core/libraries/videoout/driver.cpp | 38 +- src/core/libraries/videoout/video_out.cpp | 15 +- src/core/libraries/videoout/video_out.h | 36 +- src/core/libraries/videoout/videoout_error.h | 35 + src/core/linker.cpp | 5 +- src/core/memory.cpp | 5 +- src/core/virtual_memory.cpp | 180 ----- src/core/virtual_memory.h | 47 -- src/emulator.cpp | 6 +- src/imgui/renderer/imgui_core.cpp | 6 +- src/input/controller.cpp | 31 +- src/input/controller.h | 5 +- src/sdl_window.cpp | 176 +++-- src/sdl_window.h | 23 +- .../renderer_vulkan/vk_instance.cpp | 2 +- .../renderer_vulkan/vk_platform.cpp | 2 +- .../renderer_vulkan/vk_presenter.cpp | 10 +- .../renderer_vulkan/vk_swapchain.cpp | 2 +- 114 files changed, 2158 insertions(+), 2509 deletions(-) delete mode 100644 src/audio_core/sdl_audio.cpp delete mode 100644 src/audio_core/sdl_audio.h create mode 100644 src/core/libraries/app_content/app_content_error.h create mode 100644 src/core/libraries/audio/audioout_error.h create mode 100644 src/core/libraries/audio/sdl_audio.cpp create mode 100644 src/core/libraries/audio/sdl_audio.h create mode 100644 src/core/libraries/avplayer/avplayer_error.h create mode 100644 src/core/libraries/fiber/fiber_error.h create mode 100644 src/core/libraries/ime/ime_error.h create mode 100644 src/core/libraries/kernel/orbis_error.h create mode 100644 src/core/libraries/kernel/posix_error.h create mode 100644 src/core/libraries/libpng/pngdec_error.h create mode 100644 src/core/libraries/np_trophy/np_trophy_error.h create mode 100644 src/core/libraries/pad/pad_errors.h create mode 100644 src/core/libraries/system/systemservice_error.h create mode 100644 src/core/libraries/system/userservice_error.h create mode 100644 src/core/libraries/videodec/videodec_error.h create mode 100644 src/core/libraries/videoout/videoout_error.h delete mode 100644 src/core/virtual_memory.cpp delete mode 100644 src/core/virtual_memory.h diff --git a/CMakeLists.txt b/CMakeLists.txt index c4f639bdd..a8c3275f7 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -176,10 +176,6 @@ if(ENABLE_QT_GUI) qt_add_resources(TRANSLATIONS ${TRANSLATIONS_QRC}) endif() -set(AUDIO_CORE src/audio_core/sdl_audio.cpp - src/audio_core/sdl_audio.h -) - set(AJM_LIB src/core/libraries/ajm/ajm.cpp src/core/libraries/ajm/ajm.h src/core/libraries/ajm/ajm_at9.cpp @@ -199,6 +195,9 @@ set(AUDIO_LIB src/core/libraries/audio/audioin.cpp src/core/libraries/audio/audioin.h src/core/libraries/audio/audioout.cpp src/core/libraries/audio/audioout.h + src/core/libraries/audio/sdl_audio.cpp + src/core/libraries/audio/sdl_audio.h + src/core/libraries/audio/audioout_error.h src/core/libraries/ngs2/ngs2.cpp src/core/libraries/ngs2/ngs2.h ) @@ -240,6 +239,8 @@ set(KERNEL_LIB src/core/libraries/kernel/threads/condvar.cpp src/core/libraries/kernel/threads.h src/core/libraries/kernel/time.cpp src/core/libraries/kernel/time.h + src/core/libraries/kernel/orbis_error.h + src/core/libraries/kernel/posix_error.h ) set(NETWORK_LIBS src/core/libraries/network/http.cpp @@ -255,6 +256,21 @@ set(NETWORK_LIBS src/core/libraries/network/http.cpp src/core/libraries/network/ssl.h ) +set(AVPLAYER_LIB src/core/libraries/avplayer/avplayer_common.cpp + src/core/libraries/avplayer/avplayer_common.h + src/core/libraries/avplayer/avplayer_file_streamer.cpp + src/core/libraries/avplayer/avplayer_file_streamer.h + src/core/libraries/avplayer/avplayer_impl.cpp + src/core/libraries/avplayer/avplayer_impl.h + src/core/libraries/avplayer/avplayer_source.cpp + src/core/libraries/avplayer/avplayer_source.h + src/core/libraries/avplayer/avplayer_state.cpp + src/core/libraries/avplayer/avplayer_state.h + src/core/libraries/avplayer/avplayer.cpp + src/core/libraries/avplayer/avplayer.h + src/core/libraries/avplayer/avplayer_error.h +) + set(SYSTEM_LIBS src/core/libraries/system/commondialog.cpp src/core/libraries/system/commondialog.h src/core/libraries/system/msgdialog.cpp @@ -279,28 +295,19 @@ set(SYSTEM_LIBS src/core/libraries/system/commondialog.cpp src/core/libraries/system/system_error.h src/core/libraries/system/systemservice.cpp src/core/libraries/system/systemservice.h + src/core/libraries/system/systemservice_error.h src/core/libraries/system/userservice.cpp src/core/libraries/system/userservice.h + src/core/libraries/system/userservice_error.h src/core/libraries/app_content/app_content.cpp src/core/libraries/app_content/app_content.h + src/core/libraries/app_content/app_content_error.h src/core/libraries/rtc/rtc.cpp src/core/libraries/rtc/rtc.h src/core/libraries/rtc/rtc_error.h src/core/libraries/disc_map/disc_map.cpp src/core/libraries/disc_map/disc_map.h src/core/libraries/disc_map/disc_map_codes.h - src/core/libraries/avplayer/avplayer_common.cpp - src/core/libraries/avplayer/avplayer_common.h - src/core/libraries/avplayer/avplayer_file_streamer.cpp - src/core/libraries/avplayer/avplayer_file_streamer.h - src/core/libraries/avplayer/avplayer_impl.cpp - src/core/libraries/avplayer/avplayer_impl.h - src/core/libraries/avplayer/avplayer_source.cpp - src/core/libraries/avplayer/avplayer_source.h - src/core/libraries/avplayer/avplayer_state.cpp - src/core/libraries/avplayer/avplayer_state.h - src/core/libraries/avplayer/avplayer.cpp - src/core/libraries/avplayer/avplayer.h src/core/libraries/ngs2/ngs2.cpp src/core/libraries/ngs2/ngs2.h src/core/libraries/ngs2/ngs2_error.h @@ -327,6 +334,7 @@ set(VIDEOOUT_LIB src/core/libraries/videoout/buffer.h src/core/libraries/videoout/driver.h src/core/libraries/videoout/video_out.cpp src/core/libraries/videoout/video_out.h + src/core/libraries/videoout/videoout_error.h ) set(LIBC_SOURCES src/core/libraries/libc_internal/libc_internal.cpp @@ -344,14 +352,17 @@ set(IME_LIB src/core/libraries/ime/error_dialog.cpp src/core/libraries/ime/ime_ui.h src/core/libraries/ime/ime.cpp src/core/libraries/ime/ime.h + src/core/libraries/ime/ime_error.h ) set(PAD_LIB src/core/libraries/pad/pad.cpp src/core/libraries/pad/pad.h + src/core/libraries/pad/pad_errors.h ) set(PNG_LIB src/core/libraries/libpng/pngdec.cpp src/core/libraries/libpng/pngdec.h + src/core/libraries/libpng/pngdec_error.h ) set(JPEG_LIB src/core/libraries/jpeg/jpeg_error.h @@ -375,6 +386,7 @@ set(USBD_LIB src/core/libraries/usbd/usbd.cpp set(FIBER_LIB src/core/libraries/fiber/fiber.cpp src/core/libraries/fiber/fiber.h + src/core/libraries/fiber/fiber_error.h ) set(VDEC_LIB src/core/libraries/videodec/videodec2_impl.cpp @@ -384,6 +396,7 @@ set(VDEC_LIB src/core/libraries/videodec/videodec2_impl.cpp src/core/libraries/videodec/videodec2_avc.h src/core/libraries/videodec/videodec.cpp src/core/libraries/videodec/videodec.h + src/core/libraries/videodec/videodec_error.h src/core/libraries/videodec/videodec_impl.cpp src/core/libraries/videodec/videodec_impl.h ) @@ -396,6 +409,7 @@ set(NP_LIBS src/core/libraries/np_manager/np_manager.cpp src/core/libraries/np_trophy/np_trophy.h src/core/libraries/np_trophy/trophy_ui.cpp src/core/libraries/np_trophy/trophy_ui.h + src/core/libraries/np_trophy/np_trophy_error.h ) set(MISC_LIBS src/core/libraries/screenshot/screenshot.cpp @@ -527,10 +541,10 @@ set(CORE src/core/aerolib/stubs.cpp src/core/loader/elf.h src/core/loader/symbols_resolver.h src/core/loader/symbols_resolver.cpp - src/core/libraries/error_codes.h src/core/libraries/libs.h src/core/libraries/libs.cpp ${AJM_LIB} + ${AVPLAYER_LIB} ${AUDIO_LIB} ${GNM_LIB} ${KERNEL_LIB} @@ -565,8 +579,6 @@ set(CORE src/core/aerolib/stubs.cpp src/core/thread.h src/core/tls.cpp src/core/tls.h - src/core/virtual_memory.cpp - src/core/virtual_memory.h ) if (ARCHITECTURE STREQUAL "x86_64") diff --git a/src/audio_core/sdl_audio.cpp b/src/audio_core/sdl_audio.cpp deleted file mode 100644 index 7fed42a44..000000000 --- a/src/audio_core/sdl_audio.cpp +++ /dev/null @@ -1,166 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "sdl_audio.h" - -#include "common/assert.h" -#include "core/libraries/error_codes.h" - -#include -#include -#include - -#include // std::unique_lock - -namespace Audio { - -constexpr int AUDIO_STREAM_BUFFER_THRESHOLD = 65536; // Define constant for buffer threshold - -s32 SDLAudio::AudioOutOpen(int type, u32 samples_num, u32 freq, - Libraries::AudioOut::OrbisAudioOutParamFormat format) { - using Libraries::AudioOut::OrbisAudioOutParamFormat; - std::unique_lock lock{m_mutex}; - for (int id = 0; id < portsOut.size(); id++) { - auto& port = portsOut[id]; - if (!port.isOpen) { - port.isOpen = true; - port.type = type; - port.samples_num = samples_num; - port.freq = freq; - port.format = format; - SDL_AudioFormat sampleFormat; - switch (format) { - case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_MONO: - sampleFormat = SDL_AUDIO_S16; - port.channels_num = 1; - port.sample_size = 2; - break; - case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_MONO: - sampleFormat = SDL_AUDIO_F32; - port.channels_num = 1; - port.sample_size = 4; - break; - case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_STEREO: - sampleFormat = SDL_AUDIO_S16; - port.channels_num = 2; - port.sample_size = 2; - break; - case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_STEREO: - sampleFormat = SDL_AUDIO_F32; - port.channels_num = 2; - port.sample_size = 4; - break; - case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH: - sampleFormat = SDL_AUDIO_S16; - port.channels_num = 8; - port.sample_size = 2; - break; - case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH: - sampleFormat = SDL_AUDIO_F32; - port.channels_num = 8; - port.sample_size = 4; - break; - case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH_STD: - sampleFormat = SDL_AUDIO_S16; - port.channels_num = 8; - port.sample_size = 2; - break; - case OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH_STD: - sampleFormat = SDL_AUDIO_F32; - port.channels_num = 8; - port.sample_size = 4; - break; - default: - UNREACHABLE_MSG("Unknown format"); - } - - for (int i = 0; i < port.channels_num; i++) { - port.volume[i] = Libraries::AudioOut::SCE_AUDIO_OUT_VOLUME_0DB; - } - - SDL_AudioSpec fmt; - SDL_zero(fmt); - fmt.format = sampleFormat; - fmt.channels = port.channels_num; - fmt.freq = freq; // Set frequency from the argument - port.stream = - SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &fmt, NULL, NULL); - SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(port.stream)); - return id + 1; - } - } - - LOG_ERROR(Lib_AudioOut, "Audio ports are full"); - return ORBIS_AUDIO_OUT_ERROR_PORT_FULL; // all ports are used -} - -s32 SDLAudio::AudioOutOutput(s32 handle, const void* ptr) { - std::shared_lock lock{m_mutex}; - auto& port = portsOut[handle - 1]; - if (!port.isOpen) { - return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT; - } - - const size_t data_size = port.samples_num * port.sample_size * port.channels_num; - - bool result = SDL_PutAudioStreamData(port.stream, ptr, data_size); - - lock.unlock(); // Unlock only after necessary operations - - while (SDL_GetAudioStreamAvailable(port.stream) > AUDIO_STREAM_BUFFER_THRESHOLD) { - SDL_Delay(0); - } - - return result ? ORBIS_OK : -1; -} - -s32 SDLAudio::AudioOutSetVolume(s32 handle, s32 bitflag, s32* volume) { - using Libraries::AudioOut::OrbisAudioOutParamFormat; - std::shared_lock lock{m_mutex}; - auto& port = portsOut[handle - 1]; - if (!port.isOpen) { - return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT; - } - - for (int i = 0; i < port.channels_num; i++, bitflag >>= 1u) { - auto bit = bitflag & 0x1u; - - if (bit == 1) { - int src_index = i; - if (port.format == - OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH_STD || - port.format == OrbisAudioOutParamFormat::ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH_STD) { - switch (i) { - case 4: - src_index = 6; - break; - case 5: - src_index = 7; - break; - case 6: - src_index = 4; - break; - case 7: - src_index = 5; - break; - default: - break; - } - } - port.volume[i] = volume[src_index]; - } - } - - return ORBIS_OK; -} - -s32 SDLAudio::AudioOutGetStatus(s32 handle, int* type, int* channels_num) { - std::shared_lock lock{m_mutex}; - auto& port = portsOut[handle - 1]; - *type = port.type; - *channels_num = port.channels_num; - - return ORBIS_OK; -} - -} // namespace Audio diff --git a/src/audio_core/sdl_audio.h b/src/audio_core/sdl_audio.h deleted file mode 100644 index 0d4783f19..000000000 --- a/src/audio_core/sdl_audio.h +++ /dev/null @@ -1,39 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include -#include -#include "core/libraries/audio/audioout.h" - -namespace Audio { - -class SDLAudio { -public: - SDLAudio() = default; - virtual ~SDLAudio() = default; - - s32 AudioOutOpen(int type, u32 samples_num, u32 freq, - Libraries::AudioOut::OrbisAudioOutParamFormat format); - s32 AudioOutOutput(s32 handle, const void* ptr); - s32 AudioOutSetVolume(s32 handle, s32 bitflag, s32* volume); - s32 AudioOutGetStatus(s32 handle, int* type, int* channels_num); - -private: - struct PortOut { - SDL_AudioStream* stream = nullptr; - u32 samples_num = 0; - u32 freq = 0; - u32 format = -1; - int type = 0; - int channels_num = 0; - int volume[8] = {}; - u8 sample_size = 0; - bool isOpen = false; - }; - std::shared_mutex m_mutex; - std::array portsOut; -}; - -} // namespace Audio diff --git a/src/common/memory_patcher.cpp b/src/common/memory_patcher.cpp index d2930cf5e..6b79edb9f 100644 --- a/src/common/memory_patcher.cpp +++ b/src/common/memory_patcher.cpp @@ -28,7 +28,7 @@ std::string g_game_serial; std::string patchFile; std::vector pending_patches; -std::string toHex(unsigned long long value, size_t byteSize) { +std::string toHex(u64 value, size_t byteSize) { std::stringstream ss; ss << std::hex << std::setfill('0') << std::setw(byteSize * 2) << value; return ss.str(); @@ -38,16 +38,16 @@ std::string convertValueToHex(const std::string type, const std::string valueStr std::string result; if (type == "byte") { - unsigned int value = std::stoul(valueStr, nullptr, 16); + const u32 value = std::stoul(valueStr, nullptr, 16); result = toHex(value, 1); } else if (type == "bytes16") { - unsigned int value = std::stoul(valueStr, nullptr, 16); + const u32 value = std::stoul(valueStr, nullptr, 16); result = toHex(value, 2); } else if (type == "bytes32") { - unsigned long value = std::stoul(valueStr, nullptr, 16); + const u32 value = std::stoul(valueStr, nullptr, 16); result = toHex(value, 4); } else if (type == "bytes64") { - unsigned long long value = std::stoull(valueStr, nullptr, 16); + const u64 value = std::stoull(valueStr, nullptr, 16); result = toHex(value, 8); } else if (type == "float32") { union { diff --git a/src/core/cpu_patches.h b/src/core/cpu_patches.h index f9f7fe646..1ccac073a 100644 --- a/src/core/cpu_patches.h +++ b/src/core/cpu_patches.h @@ -3,6 +3,8 @@ #pragma once +#include "common/types.h" + namespace Core { /// Initializes a stack for the current thread for use by patch implementations. diff --git a/src/core/devtools/widget/imgui_memory_editor.h b/src/core/devtools/widget/imgui_memory_editor.h index f90387a77..086cfb1d2 100644 --- a/src/core/devtools/widget/imgui_memory_editor.h +++ b/src/core/devtools/widget/imgui_memory_editor.h @@ -458,7 +458,7 @@ struct MemoryEditor { data_write = data_next = true; if (data_editing_addr_next != (size_t)-1) data_write = data_next = false; - unsigned int data_input_value = 0; + u32 data_input_value = 0; if (!ReadOnly && data_write && sscanf(DataInputBuf, "%X", &data_input_value) == 1) { if (WriteFn) diff --git a/src/core/devtools/widget/text_editor.cpp b/src/core/devtools/widget/text_editor.cpp index f447e45a2..07f2f658d 100644 --- a/src/core/devtools/widget/text_editor.cpp +++ b/src/core/devtools/widget/text_editor.cpp @@ -131,7 +131,7 @@ static int UTF8CharLength(TextEditor::Char c) { } // "Borrowed" from ImGui source -static inline int ImTextCharToUtf8(char* buf, int buf_size, unsigned int c) { +static inline int ImTextCharToUtf8(char* buf, int buf_size, u32 c) { if (c < 0x80) { buf[0] = (char)c; return 1; diff --git a/src/core/file_format/playgo_chunk.h b/src/core/file_format/playgo_chunk.h index b6d38e0e1..2a234f5fe 100644 --- a/src/core/file_format/playgo_chunk.h +++ b/src/core/file_format/playgo_chunk.h @@ -97,24 +97,23 @@ struct PlaygoChunk { class PlaygoFile { public: - bool initialized; - OrbisPlayGoHandle handle; - OrbisPlayGoChunkId id; - OrbisPlayGoLocus locus; - OrbisPlayGoInstallSpeed speed; - s64 speed_tick; - OrbisPlayGoEta eta; - OrbisPlayGoLanguageMask langMask; + bool initialized = false; + OrbisPlayGoHandle handle = 0; + OrbisPlayGoChunkId id = 0; + OrbisPlayGoLocus locus = OrbisPlayGoLocus::NotDownloaded; + OrbisPlayGoInstallSpeed speed = OrbisPlayGoInstallSpeed::Trickle; + s64 speed_tick = 0; + OrbisPlayGoEta eta = 0; + OrbisPlayGoLanguageMask langMask = 0; std::vector chunks; public: - PlaygoFile() - : initialized(false), handle(0), id(0), locus(0), speed(ORBIS_PLAYGO_INSTALL_SPEED_TRICKLE), - speed_tick(0), eta(0), langMask(0), playgoHeader{0} {} + explicit PlaygoFile() = default; ~PlaygoFile() = default; bool Open(const std::filesystem::path& filepath); bool LoadChunks(const Common::FS::IOFile& file); + PlaygoHeader& GetPlaygoHeader() { return playgoHeader; } diff --git a/src/core/libraries/app_content/app_content.cpp b/src/core/libraries/app_content/app_content.cpp index f912639eb..ca3cdad39 100644 --- a/src/core/libraries/app_content/app_content.cpp +++ b/src/core/libraries/app_content/app_content.cpp @@ -6,34 +6,30 @@ #include "app_content.h" #include "common/assert.h" #include "common/config.h" -#include "common/io_file.h" #include "common/logging/log.h" -#include "common/path_util.h" #include "common/singleton.h" -#include "common/string_util.h" #include "core/file_format/psf.h" #include "core/file_sys/fs.h" -#include "core/libraries/error_codes.h" +#include "core/libraries/app_content/app_content_error.h" #include "core/libraries/libs.h" namespace Libraries::AppContent { -int32_t addcont_count = 0; - struct AddContInfo { - char entitlementLabel[ORBIS_NP_UNIFIED_ENTITLEMENT_LABEL_SIZE]; + char entitlement_label[ORBIS_NP_UNIFIED_ENTITLEMENT_LABEL_SIZE]; OrbisAppContentAddcontDownloadStatus status; OrbisAppContentGetEntitlementKey key; }; -std::array addcont_info = {{ +static std::array addcont_info = {{ {"0000000000000000", - ORBIS_APP_CONTENT_ADDCONT_DOWNLOAD_STATUS_INSTALLED, + OrbisAppContentAddcontDownloadStatus::Installed, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}}, }}; -std::string title_id; +static s32 addcont_count = 0; +static std::string title_id; int PS4_SYSV_ABI _Z5dummyv() { LOG_ERROR(Lib_AppContent, "(STUBBED) called"); @@ -64,12 +60,11 @@ int PS4_SYSV_ABI sceAppContentAddcontMount(u32 service_label, auto* mnt = Common::Singleton::Instance(); for (int i = 0; i < addcont_count; i++) { - if (strncmp(entitlement_label->data, addcont_info[i].entitlementLabel, + if (strncmp(entitlement_label->data, addcont_info[i].entitlement_label, ORBIS_NP_UNIFIED_ENTITLEMENT_LABEL_SIZE - 1) != 0) { continue; } - - if (addcont_info[i].status != ORBIS_APP_CONTENT_ADDCONT_DOWNLOAD_STATUS_INSTALLED) { + if (addcont_info[i].status != OrbisAppContentAddcontDownloadStatus::Installed) { return ORBIS_APP_CONTENT_ERROR_NOT_FOUND; } @@ -170,14 +165,14 @@ int PS4_SYSV_ABI sceAppContentGetAddcontInfo(u32 service_label, } for (auto i = 0; i < addcont_count; i++) { - if (strncmp(entitlementLabel->data, addcont_info[i].entitlementLabel, + if (strncmp(entitlementLabel->data, addcont_info[i].entitlement_label, ORBIS_NP_UNIFIED_ENTITLEMENT_LABEL_SIZE - 1) != 0) { continue; } LOG_INFO(Lib_AppContent, "found DLC {}", entitlementLabel->data); - strncpy(info->entitlement_label.data, addcont_info[i].entitlementLabel, + strncpy(info->entitlement_label.data, addcont_info[i].entitlement_label, ORBIS_NP_UNIFIED_ENTITLEMENT_LABEL_SIZE); info->status = addcont_info[i].status; return ORBIS_OK; @@ -202,7 +197,7 @@ int PS4_SYSV_ABI sceAppContentGetAddcontInfoList(u32 service_label, int dlcs_to_list = addcont_count < list_num ? addcont_count : list_num; for (int i = 0; i < dlcs_to_list; i++) { - strncpy(list[i].entitlement_label.data, addcont_info[i].entitlementLabel, + strncpy(list[i].entitlement_label.data, addcont_info[i].entitlement_label, ORBIS_NP_UNIFIED_ENTITLEMENT_LABEL_SIZE); list[i].status = addcont_info[i].status; } @@ -224,7 +219,7 @@ int PS4_SYSV_ABI sceAppContentGetEntitlementKey( } for (int i = 0; i < addcont_count; i++) { - if (strncmp(entitlement_label->data, addcont_info[i].entitlementLabel, + if (strncmp(entitlement_label->data, addcont_info[i].entitlement_label, ORBIS_NP_UNIFIED_ENTITLEMENT_LABEL_SIZE - 1) != 0) { continue; } @@ -252,21 +247,19 @@ int PS4_SYSV_ABI sceAppContentInitialize(const OrbisAppContentInitParam* initPar } else { UNREACHABLE_MSG("Failed to get TITLE_ID"); } - auto addon_path = addons_dir / title_id; - if (std::filesystem::exists(addon_path)) { - for (const auto& entry : std::filesystem::directory_iterator(addon_path)) { - if (entry.is_directory()) { - auto entitlement_label = entry.path().filename().string(); - - AddContInfo info{}; - info.status = ORBIS_APP_CONTENT_ADDCONT_DOWNLOAD_STATUS_INSTALLED; - strcpy(info.entitlementLabel, entitlement_label.c_str()); - - addcont_info[addcont_count++] = info; - } - } + const auto addon_path = addons_dir / title_id; + if (!std::filesystem::exists(addon_path)) { + return ORBIS_OK; } + for (const auto& entry : std::filesystem::directory_iterator(addon_path)) { + if (entry.is_directory()) { + auto entitlement_label = entry.path().filename().string(); + auto& info = addcont_info[addcont_count++]; + info.status = OrbisAppContentAddcontDownloadStatus::Installed; + entitlement_label.copy(info.entitlement_label, sizeof(info.entitlement_label)); + } + } return ORBIS_OK; } @@ -314,9 +307,11 @@ int PS4_SYSV_ABI sceAppContentTemporaryDataMount() { int PS4_SYSV_ABI sceAppContentTemporaryDataMount2(OrbisAppContentTemporaryDataOption option, OrbisAppContentMountPoint* mountPoint) { - if (mountPoint == nullptr) + if (mountPoint == nullptr) { return ORBIS_APP_CONTENT_ERROR_PARAMETER; - strncpy(mountPoint->data, "/temp0", 16); + } + static constexpr std::string_view TmpMount = "/temp0"; + TmpMount.copy(mountPoint->data, sizeof(mountPoint->data)); LOG_INFO(Lib_AppContent, "sceAppContentTemporaryDataMount2: option = {}, mountPoint = {}", option, mountPoint->data); return ORBIS_OK; diff --git a/src/core/libraries/app_content/app_content.h b/src/core/libraries/app_content/app_content.h index a16da5b40..f41f7dccf 100644 --- a/src/core/libraries/app_content/app_content.h +++ b/src/core/libraries/app_content/app_content.h @@ -30,7 +30,7 @@ struct OrbisAppContentBootParam { char reserved2[32]; }; -typedef u32 OrbisAppContentTemporaryDataOption; +using OrbisAppContentTemporaryDataOption = u32; constexpr int ORBIS_APP_CONTENT_MOUNTPOINT_DATA_MAXSIZE = 16; @@ -44,12 +44,12 @@ constexpr int ORBIS_NP_UNIFIED_ENTITLEMENT_LABEL_SIZE = 17; constexpr int ORBIS_APP_CONTENT_ENTITLEMENT_KEY_SIZE = 16; constexpr int ORBIS_APP_CONTENT_INFO_LIST_MAX_SIZE = 2500; -enum OrbisAppContentAddcontDownloadStatus : u32 { - ORBIS_APP_CONTENT_ADDCONT_DOWNLOAD_STATUS_NO_EXTRA_DATA = 0, - ORBIS_APP_CONTENT_ADDCONT_DOWNLOAD_STATUS_NO_IN_QUEUE = 1, - ORBIS_APP_CONTENT_ADDCONT_DOWNLOAD_STATUS_DOWNLOADING = 2, - ORBIS_APP_CONTENT_ADDCONT_DOWNLOAD_STATUS_DOWNLOAD_SUSPENDED = 3, - ORBIS_APP_CONTENT_ADDCONT_DOWNLOAD_STATUS_INSTALLED = 4 +enum class OrbisAppContentAddcontDownloadStatus : u32 { + NoExtraData = 0, + NoInQueue = 1, + Downloading = 2, + DownloadSuspended = 3, + Installed = 4 }; struct OrbisNpUnifiedEntitlementLabel { @@ -57,11 +57,11 @@ struct OrbisNpUnifiedEntitlementLabel { char padding[3]; }; -typedef u32 OrbisAppContentAppParamId; +using OrbisAppContentAppParamId = u32; struct OrbisAppContentAddcontInfo { OrbisNpUnifiedEntitlementLabel entitlement_label; - u32 status; + OrbisAppContentAddcontDownloadStatus status; }; struct OrbisAppContentGetEntitlementKey { @@ -119,4 +119,4 @@ int PS4_SYSV_ABI sceAppContentGetAddcontInfoListByIroTag(); int PS4_SYSV_ABI sceAppContentGetDownloadedStoreCountry(); void RegisterlibSceAppContent(Core::Loader::SymbolsResolver* sym); -} // namespace Libraries::AppContent \ No newline at end of file +} // namespace Libraries::AppContent diff --git a/src/core/libraries/app_content/app_content_error.h b/src/core/libraries/app_content/app_content_error.h new file mode 100644 index 000000000..3a582b998 --- /dev/null +++ b/src/core/libraries/app_content/app_content_error.h @@ -0,0 +1,11 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/libraries/error_codes.h" + +// AppContent library +constexpr int ORBIS_APP_CONTENT_ERROR_PARAMETER = 0x80D90002; +constexpr int ORBIS_APP_CONTENT_ERROR_DRM_NO_ENTITLEMENT = 0x80D90007; +constexpr int ORBIS_APP_CONTENT_ERROR_NOT_FOUND = 0x80D90005; diff --git a/src/core/libraries/audio/audioout.cpp b/src/core/libraries/audio/audioout.cpp index 778d777c2..b92c75a8f 100644 --- a/src/core/libraries/audio/audioout.cpp +++ b/src/core/libraries/audio/audioout.cpp @@ -4,30 +4,30 @@ #include #include -#include "audio_core/sdl_audio.h" #include "common/assert.h" #include "common/logging/log.h" #include "core/libraries/audio/audioout.h" -#include "core/libraries/error_codes.h" +#include "core/libraries/audio/audioout_error.h" +#include "core/libraries/audio/sdl_audio.h" #include "core/libraries/libs.h" namespace Libraries::AudioOut { -static std::unique_ptr audio; +static std::unique_ptr audio; -static std::string_view GetAudioOutPort(u32 port) { +static std::string_view GetAudioOutPort(OrbisAudioOutPort port) { switch (port) { - case ORBIS_AUDIO_OUT_PORT_TYPE_MAIN: + case OrbisAudioOutPort::Main: return "MAIN"; - case ORBIS_AUDIO_OUT_PORT_TYPE_BGM: + case OrbisAudioOutPort::Bgm: return "BGM"; - case ORBIS_AUDIO_OUT_PORT_TYPE_VOICE: + case OrbisAudioOutPort::Voice: return "VOICE"; - case ORBIS_AUDIO_OUT_PORT_TYPE_PERSONAL: + case OrbisAudioOutPort::Personal: return "PERSONAL"; - case ORBIS_AUDIO_OUT_PORT_TYPE_PADSPK: + case OrbisAudioOutPort::Padspk: return "PADSPK"; - case ORBIS_AUDIO_OUT_PORT_TYPE_AUX: + case OrbisAudioOutPort::Aux: return "AUX"; default: return "INVALID"; @@ -36,21 +36,21 @@ static std::string_view GetAudioOutPort(u32 port) { static std::string_view GetAudioOutParamFormat(OrbisAudioOutParamFormat param) { switch (param) { - case ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_MONO: + case OrbisAudioOutParamFormat::S16Mono: return "S16_MONO"; - case ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_STEREO: + case OrbisAudioOutParamFormat::S16Stereo: return "S16_STEREO"; - case ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH: + case OrbisAudioOutParamFormat::S16_8CH: return "S16_8CH"; - case ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_MONO: + case OrbisAudioOutParamFormat::FloatMono: return "FLOAT_MONO"; - case ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_STEREO: + case OrbisAudioOutParamFormat::FloatStereo: return "FLOAT_STEREO"; - case ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH: + case OrbisAudioOutParamFormat::Float_8CH: return "FLOAT_8CH"; - case ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH_STD: + case OrbisAudioOutParamFormat::S16_8CH_Std: return "S16_8CH_STD"; - case ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH_STD: + case OrbisAudioOutParamFormat::Float_8CH_Std: return "FLOAT_8CH_STD"; default: return "INVALID"; @@ -59,11 +59,11 @@ static std::string_view GetAudioOutParamFormat(OrbisAudioOutParamFormat param) { static std::string_view GetAudioOutParamAttr(OrbisAudioOutParamAttr attr) { switch (attr) { - case ORBIS_AUDIO_OUT_PARAM_ATTR_NONE: + case OrbisAudioOutParamAttr::None: return "NONE"; - case ORBIS_AUDIO_OUT_PARAM_ATTR_RESTRICTED: + case OrbisAudioOutParamAttr::Restricted: return "RESTRICTED"; - case ORBIS_AUDIO_OUT_PARAM_ATTR_MIX_TO_MAIN: + case OrbisAudioOutParamAttr::MixToMain: return "MIX_TO_MAIN"; default: return "INVALID"; @@ -180,29 +180,23 @@ int PS4_SYSV_ABI sceAudioOutGetPortState(s32 handle, OrbisAudioOutPortState* sta return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT; } - int type = 0; - int channels_num = 0; - - if (const auto err = audio->AudioOutGetStatus(handle, &type, &channels_num); err != ORBIS_OK) { - return err; - } - + const auto [type, channels_num] = audio->GetStatus(handle); state->rerouteCounter = 0; - state->volume = 127; // max volume + state->volume = 127; switch (type) { - case ORBIS_AUDIO_OUT_PORT_TYPE_MAIN: - case ORBIS_AUDIO_OUT_PORT_TYPE_BGM: - case ORBIS_AUDIO_OUT_PORT_TYPE_VOICE: + case OrbisAudioOutPort::Main: + case OrbisAudioOutPort::Bgm: + case OrbisAudioOutPort::Voice: state->output = 1; state->channel = (channels_num > 2 ? 2 : channels_num); break; - case ORBIS_AUDIO_OUT_PORT_TYPE_PERSONAL: - case ORBIS_AUDIO_OUT_PORT_TYPE_PADSPK: + case OrbisAudioOutPort::Personal: + case OrbisAudioOutPort::Padspk: state->output = 4; state->channel = 1; break; - case ORBIS_AUDIO_OUT_PORT_TYPE_AUX: + case OrbisAudioOutPort::Aux: state->output = 0; state->channel = 0; break; @@ -243,7 +237,7 @@ int PS4_SYSV_ABI sceAudioOutInit() { if (audio != nullptr) { return ORBIS_AUDIO_OUT_ERROR_ALREADY_INIT; } - audio = std::make_unique(); + audio = std::make_unique(); return ORBIS_OK; } @@ -287,7 +281,8 @@ s32 PS4_SYSV_ABI sceAudioOutOpen(UserService::OrbisUserServiceUserId user_id, user_id, GetAudioOutPort(port_type), index, length, sample_rate, GetAudioOutParamFormat(param_type.data_format), GetAudioOutParamAttr(param_type.attributes)); - if ((port_type < 0 || port_type > 4) && (port_type != 127)) { + if ((port_type < OrbisAudioOutPort::Main || port_type > OrbisAudioOutPort::Padspk) && + (port_type != OrbisAudioOutPort::Aux)) { LOG_ERROR(Lib_AudioOut, "Invalid port type"); return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT_TYPE; } @@ -303,18 +298,19 @@ s32 PS4_SYSV_ABI sceAudioOutOpen(UserService::OrbisUserServiceUserId user_id, if (index != 0) { LOG_ERROR(Lib_AudioOut, "index is not valid !=0 {}", index); } - OrbisAudioOutParamFormat format = param_type.data_format; - if (format < 0 || format > 7) { + const auto format = param_type.data_format.Value(); + if (format < OrbisAudioOutParamFormat::S16Mono || + format > OrbisAudioOutParamFormat::Float_8CH_Std) { LOG_ERROR(Lib_AudioOut, "Invalid format"); return ORBIS_AUDIO_OUT_ERROR_INVALID_FORMAT; } - OrbisAudioOutParamAttr attr = param_type.attributes; - if (attr < 0 || attr > 2) { + const auto attr = param_type.attributes; + if (attr < OrbisAudioOutParamAttr::None || attr > OrbisAudioOutParamAttr::MixToMain) { // TODO Handle attributes in output audio device LOG_ERROR(Lib_AudioOut, "Invalid format attribute"); return ORBIS_AUDIO_OUT_ERROR_INVALID_FORMAT; } - return audio->AudioOutOpen(port_type, length, sample_rate, format); + return audio->Open(port_type, length, sample_rate, format); } int PS4_SYSV_ABI sceAudioOutOpenEx() { @@ -330,7 +326,7 @@ s32 PS4_SYSV_ABI sceAudioOutOutput(s32 handle, const void* ptr) { // Nothing to output return ORBIS_OK; } - return audio->AudioOutOutput(handle, ptr); + return audio->Output(handle, ptr); } int PS4_SYSV_ABI sceAudioOutOutputs(OrbisAudioOutOutputParam* param, u32 num) { @@ -435,7 +431,7 @@ s32 PS4_SYSV_ABI sceAudioOutSetVolume(s32 handle, s32 flag, s32* vol) { if (handle < 1 || handle > SCE_AUDIO_OUT_NUM_PORTS) { return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT; } - return audio->AudioOutSetVolume(handle, flag, vol); + return audio->SetVolume(handle, flag, vol); } int PS4_SYSV_ABI sceAudioOutSetVolumeDown() { diff --git a/src/core/libraries/audio/audioout.h b/src/core/libraries/audio/audioout.h index 95cfc1707..e8e718b87 100644 --- a/src/core/libraries/audio/audioout.h +++ b/src/core/libraries/audio/audioout.h @@ -9,46 +9,36 @@ namespace Libraries::AudioOut { -constexpr int SCE_AUDIO_OUT_VOLUME_0DB = 32768; // max volume value - -// main up to 8 ports, BGM 1 port, voice up to 4 ports, +// Main up to 8 ports, BGM 1 port, voice up to 4 ports, // personal up to 4 ports, padspk up to 5 ports, aux 1 port constexpr int SCE_AUDIO_OUT_NUM_PORTS = 22; +constexpr int SCE_AUDIO_OUT_VOLUME_0DB = 32768; // max volume value -enum OrbisAudioOutPort { - ORBIS_AUDIO_OUT_PORT_TYPE_MAIN = 0, - ORBIS_AUDIO_OUT_PORT_TYPE_BGM = 1, - ORBIS_AUDIO_OUT_PORT_TYPE_VOICE = 2, - ORBIS_AUDIO_OUT_PORT_TYPE_PERSONAL = 3, - ORBIS_AUDIO_OUT_PORT_TYPE_PADSPK = 4, - ORBIS_AUDIO_OUT_PORT_TYPE_AUX = 127 +enum class OrbisAudioOutPort { Main = 0, Bgm = 1, Voice = 2, Personal = 3, Padspk = 4, Aux = 127 }; + +enum class OrbisAudioOutParamFormat { + S16Mono = 0, + S16Stereo = 1, + S16_8CH = 2, + FloatMono = 3, + FloatStereo = 4, + Float_8CH = 5, + S16_8CH_Std = 6, + Float_8CH_Std = 7 }; -enum OrbisAudioOutParamFormat { - ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_MONO = 0, - ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_STEREO = 1, - ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH = 2, - ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_MONO = 3, - ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_STEREO = 4, - ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH = 5, - ORBIS_AUDIO_OUT_PARAM_FORMAT_S16_8CH_STD = 6, - ORBIS_AUDIO_OUT_PARAM_FORMAT_FLOAT_8CH_STD = 7 +enum class OrbisAudioOutParamAttr { + None = 0, + Restricted = 1, + MixToMain = 2, }; -enum OrbisAudioOutParamAttr { - ORBIS_AUDIO_OUT_PARAM_ATTR_NONE = 0, - ORBIS_AUDIO_OUT_PARAM_ATTR_RESTRICTED = 1, - ORBIS_AUDIO_OUT_PARAM_ATTR_MIX_TO_MAIN = 2, -}; - -struct OrbisAudioOutParamExtendedInformation { - union { - BitField<0, 8, OrbisAudioOutParamFormat> data_format; - BitField<8, 8, u32> reserve0; - BitField<16, 4, OrbisAudioOutParamAttr> attributes; - BitField<20, 10, u32> reserve1; - BitField<31, 1, u32> unused; - }; +union OrbisAudioOutParamExtendedInformation { + BitField<0, 8, OrbisAudioOutParamFormat> data_format; + BitField<8, 8, u32> reserve0; + BitField<16, 4, OrbisAudioOutParamAttr> attributes; + BitField<20, 10, u32> reserve1; + BitField<31, 1, u32> unused; }; struct OrbisAudioOutOutputParam { diff --git a/src/core/libraries/audio/audioout_error.h b/src/core/libraries/audio/audioout_error.h new file mode 100644 index 000000000..7642e87e7 --- /dev/null +++ b/src/core/libraries/audio/audioout_error.h @@ -0,0 +1,34 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/libraries/error_codes.h" + +// AudioOut library +constexpr int ORBIS_AUDIO_OUT_ERROR_NOT_OPENED = 0x80260001; +constexpr int ORBIS_AUDIO_OUT_ERROR_BUSY = 0x80260002; +constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_PORT = 0x80260003; +constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_POINTER = 0x80260004; +constexpr int ORBIS_AUDIO_OUT_ERROR_PORT_FULL = 0x80260005; +constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_SIZE = 0x80260006; +constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_FORMAT = 0x80260007; +constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_SAMPLE_FREQ = 0x80260008; +constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_VOLUME = 0x80260009; +constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_PORT_TYPE = 0x8026000A; +constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_CONF_TYPE = 0x8026000C; +constexpr int ORBIS_AUDIO_OUT_ERROR_OUT_OF_MEMORY = 0x8026000D; +constexpr int ORBIS_AUDIO_OUT_ERROR_ALREADY_INIT = 0x8026000E; +constexpr int ORBIS_AUDIO_OUT_ERROR_NOT_INIT = 0x8026000F; +constexpr int ORBIS_AUDIO_OUT_ERROR_MEMORY = 0x80260010; +constexpr int ORBIS_AUDIO_OUT_ERROR_SYSTEM_RESOURCE = 0x80260011; +constexpr int ORBIS_AUDIO_OUT_ERROR_TRANS_EVENT = 0x80260012; +constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_FLAG = 0x80260013; +constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_MIXLEVEL = 0x80260014; +constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_ARG = 0x80260015; +constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_PARAM = 0x80260016; +constexpr int ORBIS_AUDIO_OUT_ERROR_MASTERING_FATAL = 0x80260200; +constexpr int ORBIS_AUDIO_OUT_ERROR_MASTERING_INVALID_API_PARAM = 0x80260201; +constexpr int ORBIS_AUDIO_OUT_ERROR_MASTERING_INVALID_CONFIG = 0x80260202; +constexpr int ORBIS_AUDIO_OUT_ERROR_MASTERING_NOT_INITIALIZED = 0x80260203; +constexpr int ORBIS_AUDIO_OUT_ERROR_MASTERING_INVALID_STATES_ID = 0x80260204; diff --git a/src/core/libraries/audio/sdl_audio.cpp b/src/core/libraries/audio/sdl_audio.cpp new file mode 100644 index 000000000..8cc823abe --- /dev/null +++ b/src/core/libraries/audio/sdl_audio.cpp @@ -0,0 +1,141 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include +#include +#include + +#include "common/assert.h" +#include "core/libraries/audio/audioout_error.h" +#include "core/libraries/audio/sdl_audio.h" + +namespace Libraries::AudioOut { + +constexpr int AUDIO_STREAM_BUFFER_THRESHOLD = 65536; // Define constant for buffer threshold + +s32 SDLAudioOut::Open(OrbisAudioOutPort type, u32 samples_num, u32 freq, + OrbisAudioOutParamFormat format) { + std::scoped_lock lock{m_mutex}; + const auto port = std::ranges::find(ports_out, false, &PortOut::is_open); + if (port == ports_out.end()) { + LOG_ERROR(Lib_AudioOut, "Audio ports are full"); + return ORBIS_AUDIO_OUT_ERROR_PORT_FULL; + } + + port->is_open = true; + port->type = type; + port->samples_num = samples_num; + port->freq = freq; + port->format = format; + SDL_AudioFormat sampleFormat; + switch (format) { + case OrbisAudioOutParamFormat::S16Mono: + sampleFormat = SDL_AUDIO_S16; + port->channels_num = 1; + port->sample_size = 2; + break; + case OrbisAudioOutParamFormat::FloatMono: + sampleFormat = SDL_AUDIO_F32; + port->channels_num = 1; + port->sample_size = 4; + break; + case OrbisAudioOutParamFormat::S16Stereo: + sampleFormat = SDL_AUDIO_S16; + port->channels_num = 2; + port->sample_size = 2; + break; + case OrbisAudioOutParamFormat::FloatStereo: + sampleFormat = SDL_AUDIO_F32; + port->channels_num = 2; + port->sample_size = 4; + break; + case OrbisAudioOutParamFormat::S16_8CH: + sampleFormat = SDL_AUDIO_S16; + port->channels_num = 8; + port->sample_size = 2; + break; + case OrbisAudioOutParamFormat::Float_8CH: + sampleFormat = SDL_AUDIO_F32; + port->channels_num = 8; + port->sample_size = 4; + break; + case OrbisAudioOutParamFormat::S16_8CH_Std: + sampleFormat = SDL_AUDIO_S16; + port->channels_num = 8; + port->sample_size = 2; + break; + case OrbisAudioOutParamFormat::Float_8CH_Std: + sampleFormat = SDL_AUDIO_F32; + port->channels_num = 8; + port->sample_size = 4; + break; + default: + UNREACHABLE_MSG("Unknown format"); + } + + port->volume.fill(Libraries::AudioOut::SCE_AUDIO_OUT_VOLUME_0DB); + + SDL_AudioSpec fmt; + SDL_zero(fmt); + fmt.format = sampleFormat; + fmt.channels = port->channels_num; + fmt.freq = freq; + port->stream = SDL_OpenAudioDeviceStream(SDL_AUDIO_DEVICE_DEFAULT_PLAYBACK, &fmt, NULL, NULL); + SDL_ResumeAudioDevice(SDL_GetAudioStreamDevice(port->stream)); + return std::distance(ports_out.begin(), port) + 1; +} + +s32 SDLAudioOut::Output(s32 handle, const void* ptr) { + auto& port = ports_out.at(handle - 1); + if (!port.is_open) { + return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT; + } + + const size_t data_size = port.samples_num * port.sample_size * port.channels_num; + bool result = SDL_PutAudioStreamData(port.stream, ptr, data_size); + while (SDL_GetAudioStreamAvailable(port.stream) > AUDIO_STREAM_BUFFER_THRESHOLD) { + SDL_Delay(0); + } + return result ? ORBIS_OK : -1; +} + +s32 SDLAudioOut::SetVolume(s32 handle, s32 bitflag, s32* volume) { + using Libraries::AudioOut::OrbisAudioOutParamFormat; + auto& port = ports_out.at(handle - 1); + if (!port.is_open) { + return ORBIS_AUDIO_OUT_ERROR_INVALID_PORT; + } + + for (int i = 0; i < port.channels_num; i++, bitflag >>= 1u) { + auto bit = bitflag & 0x1u; + + if (bit == 1) { + int src_index = i; + if (port.format == OrbisAudioOutParamFormat::Float_8CH_Std || + port.format == OrbisAudioOutParamFormat::S16_8CH_Std) { + switch (i) { + case 4: + src_index = 6; + break; + case 5: + src_index = 7; + break; + case 6: + src_index = 4; + break; + case 7: + src_index = 5; + break; + default: + break; + } + } + port.volume[i] = volume[src_index]; + } + } + + return ORBIS_OK; +} + +} // namespace Libraries::AudioOut diff --git a/src/core/libraries/audio/sdl_audio.h b/src/core/libraries/audio/sdl_audio.h new file mode 100644 index 000000000..2c34f8e29 --- /dev/null +++ b/src/core/libraries/audio/sdl_audio.h @@ -0,0 +1,42 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include +#include +#include "core/libraries/audio/audioout.h" + +namespace Libraries::AudioOut { + +class SDLAudioOut { +public: + explicit SDLAudioOut() = default; + ~SDLAudioOut() = default; + + s32 Open(OrbisAudioOutPort type, u32 samples_num, u32 freq, OrbisAudioOutParamFormat format); + s32 Output(s32 handle, const void* ptr); + s32 SetVolume(s32 handle, s32 bitflag, s32* volume); + + constexpr std::pair GetStatus(s32 handle) const { + const auto& port = ports_out.at(handle - 1); + return std::make_pair(port.type, port.channels_num); + } + +private: + struct PortOut { + SDL_AudioStream* stream; + u32 samples_num; + u32 freq; + OrbisAudioOutParamFormat format; + OrbisAudioOutPort type; + int channels_num; + std::array volume; + u8 sample_size; + bool is_open; + }; + std::shared_mutex m_mutex; + std::array ports_out{}; +}; + +} // namespace Libraries::AudioOut diff --git a/src/core/libraries/audio3d/audio3d.cpp b/src/core/libraries/audio3d/audio3d.cpp index 8aeb88da8..44670d87b 100644 --- a/src/core/libraries/audio3d/audio3d.cpp +++ b/src/core/libraries/audio3d/audio3d.cpp @@ -1,19 +1,15 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "audio3d.h" -#include "audio3d_error.h" -#include "audio3d_impl.h" - #include "common/logging/log.h" #include "core/libraries/audio/audioout.h" +#include "core/libraries/audio3d/audio3d.h" +#include "core/libraries/audio3d/audio3d_error.h" #include "core/libraries/error_codes.h" #include "core/libraries/libs.h" namespace Libraries::Audio3d { -// Audio3d - int PS4_SYSV_ABI sceAudio3dInitialize(s64 iReserved) { LOG_INFO(Lib_Audio3d, "iReserved = {}", iReserved); return ORBIS_OK; @@ -25,18 +21,19 @@ int PS4_SYSV_ABI sceAudio3dTerminate() { return ORBIS_OK; } -void PS4_SYSV_ABI sceAudio3dGetDefaultOpenParameters(OrbisAudio3dOpenParameters* sParameters) { - if (sParameters != NULL) { - sParameters->szSizeThis = sizeof(OrbisAudio3dOpenParameters); - sParameters->uiGranularity = 256; - sParameters->eRate = ORBIS_AUDIO3D_RATE_48000; - sParameters->uiMaxObjects = 512; - sParameters->uiQueueDepth = 2; - sParameters->eBufferMode = ORBIS_AUDIO3D_BUFFER_ADVANCE_AND_PUSH; - sParameters->uiNumBeds = 2; - } else { +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, @@ -76,13 +73,13 @@ int PS4_SYSV_ABI sceAudio3dPortPush(OrbisAudio3dPortId uiPortId, OrbisAudio3dBlo int PS4_SYSV_ABI sceAudio3dPortGetAttributesSupported(OrbisAudio3dPortId uiPortId, OrbisAudio3dAttributeId* pCapabilities, - unsigned int* pNumCapabilities) { + u32* pNumCapabilities) { LOG_INFO(Lib_Audio3d, "uiPortId = {}", uiPortId); return ORBIS_OK; } -int PS4_SYSV_ABI sceAudio3dPortGetQueueLevel(OrbisAudio3dPortId uiPortId, unsigned int* pQueueLevel, - unsigned int* pQueueAvailable) { +int PS4_SYSV_ABI sceAudio3dPortGetQueueLevel(OrbisAudio3dPortId uiPortId, u32* pQueueLevel, + u32* pQueueAvailable) { LOG_INFO(Lib_Audio3d, "uiPortId = {}", uiPortId); return ORBIS_OK; } @@ -107,24 +104,24 @@ int PS4_SYSV_ABI sceAudio3dObjectSetAttributes(OrbisAudio3dPortId uiPortId, return ORBIS_OK; } -int PS4_SYSV_ABI sceAudio3dBedWrite(OrbisAudio3dPortId uiPortId, unsigned int uiNumChannels, +int PS4_SYSV_ABI sceAudio3dBedWrite(OrbisAudio3dPortId uiPortId, u32 uiNumChannels, OrbisAudio3dFormat eFormat, const void* pBuffer, - unsigned int uiNumSamples) { + u32 uiNumSamples) { LOG_TRACE(Lib_Audio3d, "uiPortId = {}, uiNumChannels = {}, uiNumSamples = {}", uiPortId, uiNumChannels, uiNumSamples); return ORBIS_OK; } -int PS4_SYSV_ABI sceAudio3dBedWrite2(OrbisAudio3dPortId uiPortId, unsigned int uiNumChannels, +int PS4_SYSV_ABI sceAudio3dBedWrite2(OrbisAudio3dPortId uiPortId, u32 uiNumChannels, OrbisAudio3dFormat eFormat, const void* pBuffer, - unsigned int uiNumSamples, - OrbisAudio3dOutputRoute eOutputRoute, bool bRestricted) { + 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(unsigned int uiNumSpeakers, bool bIs3d) { +size_t PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMemorySize(u32 uiNumSpeakers, bool bIs3d) { LOG_INFO(Lib_Audio3d, "uiNumSpeakers = {}, bIs3d = {}", uiNumSpeakers, bIs3d); return ORBIS_OK; } @@ -152,7 +149,7 @@ int PS4_SYSV_ABI sceAudio3dDeleteSpeakerArray(OrbisAudio3dSpeakerArrayHandle han int PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMixCoefficients(OrbisAudio3dSpeakerArrayHandle handle, OrbisAudio3dPosition pos, float fSpread, float* pCoefficients, - unsigned int uiNumCoefficients) { + u32 uiNumCoefficients) { LOG_INFO(Lib_Audio3d, "fSpread = {}, uiNumCoefficients = {}", fSpread, uiNumCoefficients); if (handle == nullptr) { LOG_ERROR(Lib_Audio3d, "invalid SpeakerArrayHandle"); @@ -164,8 +161,7 @@ int PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMixCoefficients(OrbisAudio3dSpeakerArr int PS4_SYSV_ABI sceAudio3dGetSpeakerArrayMixCoefficients2(OrbisAudio3dSpeakerArrayHandle handle, OrbisAudio3dPosition pos, float fSpread, float* pCoefficients, - unsigned int uiNumCoefficients, - bool bHeightAware, + u32 uiNumCoefficients, bool bHeightAware, float fDownmixSpreadRadius) { LOG_INFO(Lib_Audio3d, "fSpread = {}, uiNumCoefficients = {}, bHeightAware = {}, fDownmixSpreadRadius = {}", @@ -209,8 +205,8 @@ s32 PS4_SYSV_ABI sceAudio3dAudioOutOutputs(::Libraries::AudioOut::OrbisAudioOutO return ORBIS_OK; } -int PS4_SYSV_ABI sceAudio3dPortCreate(unsigned int uiGranularity, OrbisAudio3dRate eRate, - s64 iReserved, OrbisAudio3dPortId* pId) { +int PS4_SYSV_ABI sceAudio3dPortCreate(u32 uiGranularity, OrbisAudio3dRate eRate, s64 iReserved, + OrbisAudio3dPortId* pId) { LOG_INFO(Lib_Audio3d, "uiGranularity = {}, iReserved = {}", uiGranularity, iReserved); return ORBIS_OK; } @@ -341,4 +337,4 @@ void RegisterlibSceAudio3d(Core::Loader::SymbolsResolver* sym) { sceAudio3dSetGpuRenderer); }; -} // namespace Libraries::Audio3d \ No newline at end of file +} // namespace Libraries::Audio3d diff --git a/src/core/libraries/audio3d/audio3d.h b/src/core/libraries/audio3d/audio3d.h index 6cbe2d02f..6f344226f 100644 --- a/src/core/libraries/audio3d/audio3d.h +++ b/src/core/libraries/audio3d/audio3d.h @@ -15,56 +15,57 @@ namespace Libraries::Audio3d { class Audio3d; -typedef int OrbisUserServiceUserId; -typedef unsigned int OrbisAudio3dPortId; -typedef unsigned int OrbisAudio3dObjectId; -typedef unsigned int OrbisAudio3dAttributeId; +using OrbisUserServiceUserId = s32; +using OrbisAudio3dPortId = u32; +using OrbisAudio3dObjectId = u32; +using OrbisAudio3dAttributeId = u32; -enum OrbisAudio3dFormat { - ORBIS_AUDIO3D_FORMAT_S16 = 0, // s16 - ORBIS_AUDIO3D_FORMAT_FLOAT = 1 // f32 +enum class OrbisAudio3dFormat { + S16 = 0, + Float = 1, }; -enum OrbisAudio3dRate { ORBIS_AUDIO3D_RATE_48000 = 0 }; - -enum OrbisAudio3dBufferMode { - ORBIS_AUDIO3D_BUFFER_NO_ADVANCE = 0, - ORBIS_AUDIO3D_BUFFER_ADVANCE_NO_PUSH = 1, - ORBIS_AUDIO3D_BUFFER_ADVANCE_AND_PUSH = 2 +enum class OrbisAudio3dRate { + Rate48000 = 0, }; -enum OrbisAudio3dBlocking { ORBIS_AUDIO3D_BLOCKING_ASYNC = 0, ORBIS_AUDIO3D_BLOCKING_SYNC = 1 }; +enum class OrbisAudio3dBufferMode { NoAdvance = 0, AdvanceNoPush = 1, AdvanceAndPush = 2 }; -enum OrbisAudio3dPassthrough { - ORBIS_AUDIO3D_PASSTHROUGH_NONE = 0, - ORBIS_AUDIO3D_PASSTHROUGH_LEFT = 1, - ORBIS_AUDIO3D_PASSTHROUGH_RIGHT = 2 +enum class OrbisAudio3dBlocking { + Async = 0, + Sync = 1, }; -enum OrbisAudio3dOutputRoute { - ORBIS_AUDIO3D_OUTPUT_BOTH = 0, - ORBIS_AUDIO3D_OUTPUT_HMU_ONLY = 1, - ORBIS_AUDIO3D_OUTPUT_TV_ONLY = 2 +enum class OrbisAudio3dPassthrough { + None = 0, + Left = 1, + Right = 2, }; -enum OrbisAudio3dAmbisonics { - ORBIS_AUDIO3D_AMBISONICS_NONE = ~0, - ORBIS_AUDIO3D_AMBISONICS_W = 0, - ORBIS_AUDIO3D_AMBISONICS_X = 1, - ORBIS_AUDIO3D_AMBISONICS_Y = 2, - ORBIS_AUDIO3D_AMBISONICS_Z = 3, - ORBIS_AUDIO3D_AMBISONICS_R = 4, - ORBIS_AUDIO3D_AMBISONICS_S = 5, - ORBIS_AUDIO3D_AMBISONICS_T = 6, - ORBIS_AUDIO3D_AMBISONICS_U = 7, - ORBIS_AUDIO3D_AMBISONICS_V = 8, - ORBIS_AUDIO3D_AMBISONICS_K = 9, - ORBIS_AUDIO3D_AMBISONICS_L = 10, - ORBIS_AUDIO3D_AMBISONICS_M = 11, - ORBIS_AUDIO3D_AMBISONICS_N = 12, - ORBIS_AUDIO3D_AMBISONICS_O = 13, - ORBIS_AUDIO3D_AMBISONICS_P = 14, - ORBIS_AUDIO3D_AMBISONICS_Q = 15 +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; @@ -86,21 +87,21 @@ struct OrbisAudio3dSpeakerArray; using OrbisAudio3dSpeakerArrayHandle = OrbisAudio3dSpeakerArray*; // head struct OrbisAudio3dOpenParameters { - size_t szSizeThis; - unsigned int uiGranularity; - OrbisAudio3dRate eRate; - unsigned int uiMaxObjects; - unsigned int uiQueueDepth; - OrbisAudio3dBufferMode eBufferMode; + size_t size_this; + u32 granularity; + OrbisAudio3dRate rate; + u32 max_objects; + u32 queue_depth; + OrbisAudio3dBufferMode buffer_mode; char padding[32]; - unsigned int uiNumBeds; + u32 num_beds; }; struct OrbisAudio3dAttribute { - OrbisAudio3dAttributeId uiAttributeId; + OrbisAudio3dAttributeId attribute_id; char padding[32]; - const void* pValue; - size_t szValue; + const void* p_value; + size_t value; }; struct OrbisAudio3dPosition { @@ -110,25 +111,25 @@ struct OrbisAudio3dPosition { }; struct OrbisAudio3dPcm { - OrbisAudio3dFormat eFormat; - const void* pSampleBuffer; - unsigned int uiNumSamples; + OrbisAudio3dFormat format; + const void* sample_buffer; + u32 num_samples; }; struct OrbisAudio3dSpeakerArrayParameters { - OrbisAudio3dPosition* pSpeakerPosition; - unsigned int uiNumSpeakers; - bool bIs3d; - void* pBuffer; - size_t szSize; + OrbisAudio3dPosition* speaker_position; + u32 num_speakers; + bool is_3d; + void* buffer; + size_t size; }; struct OrbisAudio3dApplicationSpecific { - size_t szSizeThis; - u8 cApplicationSpecific[32]; + size_t size_this; + u8 application_specific[32]; }; void PS4_SYSV_ABI sceAudio3dGetDefaultOpenParameters(OrbisAudio3dOpenParameters* sParameters); void RegisterlibSceAudio3d(Core::Loader::SymbolsResolver* sym); -} // namespace Libraries::Audio3d \ No newline at end of file +} // namespace Libraries::Audio3d diff --git a/src/core/libraries/audio3d/audio3d_error.h b/src/core/libraries/audio3d/audio3d_error.h index ff9d9749c..626ac8699 100644 --- a/src/core/libraries/audio3d/audio3d_error.h +++ b/src/core/libraries/audio3d/audio3d_error.h @@ -3,6 +3,8 @@ #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; diff --git a/src/core/libraries/audio3d/audio3d_impl.h b/src/core/libraries/audio3d/audio3d_impl.h index 4e6342b1b..1213a030e 100644 --- a/src/core/libraries/audio3d/audio3d_impl.h +++ b/src/core/libraries/audio3d/audio3d_impl.h @@ -10,7 +10,7 @@ namespace Libraries::Audio3d { class Audio3d { public: private: - typedef unsigned int OrbisAudio3dPluginId; + using OrbisAudio3dPluginId = u32; }; } // namespace Libraries::Audio3d diff --git a/src/core/libraries/avplayer/avplayer.cpp b/src/core/libraries/avplayer/avplayer.cpp index 1257473e1..176fda137 100644 --- a/src/core/libraries/avplayer/avplayer.cpp +++ b/src/core/libraries/avplayer/avplayer.cpp @@ -3,8 +3,8 @@ #include "common/logging/log.h" #include "core/libraries/avplayer/avplayer.h" +#include "core/libraries/avplayer/avplayer_error.h" #include "core/libraries/avplayer/avplayer_impl.h" -#include "core/libraries/error_codes.h" #include "core/libraries/libs.h" namespace Libraries::AvPlayer { diff --git a/src/core/libraries/avplayer/avplayer.h b/src/core/libraries/avplayer/avplayer.h index 9f100bef3..2d472f801 100644 --- a/src/core/libraries/avplayer/avplayer.h +++ b/src/core/libraries/avplayer/avplayer.h @@ -18,17 +18,26 @@ class AvPlayer; using SceAvPlayerHandle = AvPlayer*; -enum SceAvPlayerUriType { SCE_AVPLAYER_URI_TYPE_SOURCE = 0 }; +enum class SceAvPlayerUriType : u32 { + Source = 0, +}; struct SceAvPlayerUri { const char* name; u32 length; }; -enum SceAvPlayerSourceType { - SCE_AVPLAYER_SOURCE_TYPE_UNKNOWN = 0, - SCE_AVPLAYER_SOURCE_TYPE_FILE_MP4 = 1, - SCE_AVPLAYER_SOURCE_TYPE_HLS = 8 +enum class SceAvPlayerSourceType { + Unknown = 0, + FileMp4 = 1, + Hls = 8, +}; + +enum class SceAvPlayerStreamType : u32 { + Video, + Audio, + TimedText, + Unknown, }; struct SceAvPlayerSourceDetails { @@ -50,7 +59,7 @@ struct SceAvPlayerVideo { u32 width; u32 height; f32 aspect_ratio; - u8 language_code[4]; + char language_code[4]; }; struct SceAvPlayerTextPosition { @@ -82,7 +91,7 @@ struct SceAvPlayerFrameInfo { }; struct SceAvPlayerStreamInfo { - u32 type; + SceAvPlayerStreamType type; u8 reserved[4]; SceAvPlayerStreamDetails details; u64 duration; @@ -135,10 +144,10 @@ struct SceAvPlayerFrameInfoEx { SceAvPlayerStreamDetailsEx details; }; -typedef void* PS4_SYSV_ABI (*SceAvPlayerAllocate)(void* p, u32 align, u32 size); -typedef void PS4_SYSV_ABI (*SceAvPlayerDeallocate)(void* p, void* mem); -typedef void* PS4_SYSV_ABI (*SceAvPlayerAllocateTexture)(void* p, u32 align, u32 size); -typedef void PS4_SYSV_ABI (*SceAvPlayerDeallocateTexture)(void* p, void* mem); +using SceAvPlayerAllocate = void* PS4_SYSV_ABI (*)(void* p, u32 align, u32 size); +using SceAvPlayerDeallocate = void PS4_SYSV_ABI (*)(void* p, void* mem); +using SceAvPlayerAllocateTexture = void* PS4_SYSV_ABI (*)(void* p, u32 align, u32 size); +using SceAvPlayerDeallocateTexture = void PS4_SYSV_ABI (*)(void* p, void* mem); struct SceAvPlayerMemAllocator { void* object_ptr; @@ -148,10 +157,10 @@ struct SceAvPlayerMemAllocator { SceAvPlayerDeallocateTexture deallocate_texture; }; -typedef s32 PS4_SYSV_ABI (*SceAvPlayerOpenFile)(void* p, const char* name); -typedef s32 PS4_SYSV_ABI (*SceAvPlayerCloseFile)(void* p); -typedef s32 PS4_SYSV_ABI (*SceAvPlayerReadOffsetFile)(void* p, u8* buf, u64 pos, u32 len); -typedef u64 PS4_SYSV_ABI (*SceAvPlayerSizeFile)(void* p); +using SceAvPlayerOpenFile = s32 PS4_SYSV_ABI (*)(void* p, const char* name); +using SceAvPlayerCloseFile = s32 PS4_SYSV_ABI (*)(void* p); +using SceAvPlayerReadOffsetFile = s32 PS4_SYSV_ABI (*)(void* p, u8* buf, u64 pos, u32 len); +using SceAvPlayerSizeFile = u64 PS4_SYSV_ABI (*)(void* p); struct SceAvPlayerFileReplacement { void* object_ptr; @@ -161,31 +170,31 @@ struct SceAvPlayerFileReplacement { SceAvPlayerSizeFile size; }; -enum SceAvPlayerEvents { - SCE_AVPLAYER_STATE_STOP = 0x01, - SCE_AVPLAYER_STATE_READY = 0x02, - SCE_AVPLAYER_STATE_PLAY = 0x03, - SCE_AVPLAYER_STATE_PAUSE = 0x04, - SCE_AVPLAYER_STATE_BUFFERING = 0x05, - SCE_AVPLAYER_TIMED_TEXT_DELIVERY = 0x10, - SCE_AVPLAYER_WARNING_ID = 0x20, - SCE_AVPLAYER_ENCRYPTION = 0x30, - SCE_AVPLAYER_DRM_ERROR = 0x40 +enum class SceAvPlayerEvents { + StateStop = 0x01, + StateReady = 0x02, + StatePlay = 0x03, + StatePause = 0x04, + StateBuffering = 0x05, + TimedTextDelivery = 0x10, + WarningId = 0x20, + Encryption = 0x30, + DrmError = 0x40, }; -typedef void PS4_SYSV_ABI (*SceAvPlayerEventCallback)(void* p, SceAvPlayerEvents event, s32 src_id, - void* data); +using SceAvPlayerEventCallback = void PS4_SYSV_ABI (*)(void* p, SceAvPlayerEvents event, s32 src_id, + void* data); struct SceAvPlayerEventReplacement { void* object_ptr; SceAvPlayerEventCallback event_callback; }; -enum SceAvPlayerDebuglevels { - SCE_AVPLAYER_DBG_NONE, - SCE_AVPLAYER_DBG_INFO, - SCE_AVPLAYER_DBG_WARNINGS, - SCE_AVPLAYER_DBG_ALL +enum class SceAvPlayerDebuglevels { + None, + Info, + Warnings, + All, }; struct SceAvPlayerInitData { @@ -224,24 +233,17 @@ struct SceAvPlayerInitDataEx { u8 reserved[3]; }; -enum SceAvPlayerStreamType { - SCE_AVPLAYER_VIDEO, - SCE_AVPLAYER_AUDIO, - SCE_AVPLAYER_TIMEDTEXT, - SCE_AVPLAYER_UNKNOWN +enum class SceAvPlayerVideoDecoderType { + Default = 0, + Reserved1, + Software, + Software2, }; -enum SceAvPlayerVideoDecoderType { - SCE_AVPLAYER_VIDEO_DECODER_TYPE_DEFAULT = 0, - SCE_AVPLAYER_VIDEO_DECODER_TYPE_RESERVED1, - SCE_AVPLAYER_VIDEO_DECODER_TYPE_SOFTWARE, - SCE_AVPLAYER_VIDEO_DECODER_TYPE_SOFTWARE2 -}; - -enum SceAvPlayerAudioDecoderType { - SCE_AVPLAYER_AUDIO_DECODER_TYPE_DEFAULT = 0, - SCE_AVPLAYER_AUDIO_DECODER_TYPE_RESERVED1, - SCE_AVPLAYER_AUDIO_DECODER_TYPE_RESERVED2 +enum class SceAvPlayerAudioDecoderType { + Default = 0, + Reserved1, + Reserved2, }; struct SceAvPlayerDecoderInit { @@ -281,12 +283,12 @@ struct SceAvPlayerPostInitData { u8 reserved[56]; }; -enum SceAvPlayerAvSyncMode { - SCE_AVPLAYER_AV_SYNC_MODE_DEFAULT = 0, - SCE_AVPLAYER_AV_SYNC_MODE_NONE +enum class SceAvPlayerAvSyncMode { + Default = 0, + None, }; -typedef int PS4_SYSV_ABI (*SceAvPlayerLogCallback)(void* p, const char* format, va_list args); +using SceAvPlayerLogCallback = int PS4_SYSV_ABI (*)(void* p, const char* format, va_list args); void RegisterlibSceAvPlayer(Core::Loader::SymbolsResolver* sym); diff --git a/src/core/libraries/avplayer/avplayer_common.cpp b/src/core/libraries/avplayer/avplayer_common.cpp index 805920a3d..28d7803a1 100644 --- a/src/core/libraries/avplayer/avplayer_common.cpp +++ b/src/core/libraries/avplayer/avplayer_common.cpp @@ -15,7 +15,7 @@ static bool iequals(std::string_view l, std::string_view r) { SceAvPlayerSourceType GetSourceType(std::string_view path) { if (path.empty()) { - return SCE_AVPLAYER_SOURCE_TYPE_UNKNOWN; + return SceAvPlayerSourceType::Unknown; } std::string_view name = path; @@ -25,14 +25,14 @@ SceAvPlayerSourceType GetSourceType(std::string_view path) { // -> schema://server.domain/path/to/file.ext/and/beyond name = path.substr(0, path.find_first_of("?#")); if (name.empty()) { - return SCE_AVPLAYER_SOURCE_TYPE_UNKNOWN; + return SceAvPlayerSourceType::Unknown; } } // schema://server.domain/path/to/file.ext/and/beyond -> .ext/and/beyond auto ext = name.substr(name.rfind('.')); if (ext.empty()) { - return SCE_AVPLAYER_SOURCE_TYPE_UNKNOWN; + return SceAvPlayerSourceType::Unknown; } // .ext/and/beyond -> .ext @@ -40,14 +40,14 @@ SceAvPlayerSourceType GetSourceType(std::string_view path) { if (iequals(ext, ".mp4") || iequals(ext, ".m4v") || iequals(ext, ".m3d") || iequals(ext, ".m4a") || iequals(ext, ".mov")) { - return SCE_AVPLAYER_SOURCE_TYPE_FILE_MP4; + return SceAvPlayerSourceType::FileMp4; } if (iequals(ext, ".m3u8")) { - return SCE_AVPLAYER_SOURCE_TYPE_HLS; + return SceAvPlayerSourceType::Hls; } - return SCE_AVPLAYER_SOURCE_TYPE_UNKNOWN; + return SceAvPlayerSourceType::Unknown; } } // namespace Libraries::AvPlayer diff --git a/src/core/libraries/avplayer/avplayer_error.h b/src/core/libraries/avplayer/avplayer_error.h new file mode 100644 index 000000000..ebe4d0dd3 --- /dev/null +++ b/src/core/libraries/avplayer/avplayer_error.h @@ -0,0 +1,19 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/libraries/error_codes.h" + +// AvPlayer library +constexpr int ORBIS_AVPLAYER_ERROR_INVALID_PARAMS = 0x806A0001; +constexpr int ORBIS_AVPLAYER_ERROR_OPERATION_FAILED = 0x806A0002; +constexpr int ORBIS_AVPLAYER_ERROR_NO_MEMORY = 0x806A0003; +constexpr int ORBIS_AVPLAYER_ERROR_NOT_SUPPORTED = 0x806A0004; +constexpr int ORBIS_AVPLAYER_ERROR_WAR_FILE_NONINTERLEAVED = 0x806A00A0; +constexpr int ORBIS_AVPLAYER_ERROR_WAR_LOOPING_BACK = 0x806A00A1; +constexpr int ORBIS_AVPLAYER_ERROR_WAR_JUMP_COMPLETE = 0x806A00A3; +constexpr int ORBIS_AVPLAYER_ERROR_INFO_MARLIN_ENCRY = 0x806A00B0; +constexpr int ORBIS_AVPLAYER_ERROR_INFO_PLAYREADY_ENCRY = 0x806A00B4; +constexpr int ORBIS_AVPLAYER_ERROR_INFO_AES_ENCRY = 0x806A00B5; +constexpr int ORBIS_AVPLAYER_ERROR_INFO_OTHER_ENCRY = 0x806A00BF; diff --git a/src/core/libraries/avplayer/avplayer_impl.cpp b/src/core/libraries/avplayer/avplayer_impl.cpp index 0f39acfdc..d9a67134c 100644 --- a/src/core/libraries/avplayer/avplayer_impl.cpp +++ b/src/core/libraries/avplayer/avplayer_impl.cpp @@ -2,8 +2,8 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "core/libraries/avplayer/avplayer_common.h" +#include "core/libraries/avplayer/avplayer_error.h" #include "core/libraries/avplayer/avplayer_impl.h" -#include "core/libraries/error_codes.h" #include "core/tls.h" namespace Libraries::AvPlayer { diff --git a/src/core/libraries/avplayer/avplayer_source.cpp b/src/core/libraries/avplayer/avplayer_source.cpp index 8a65377c2..8e43e7277 100644 --- a/src/core/libraries/avplayer/avplayer_source.cpp +++ b/src/core/libraries/avplayer/avplayer_source.cpp @@ -85,17 +85,17 @@ s32 AvPlayerSource::GetStreamCount() { return m_avformat_context->nb_streams; } -static s32 CodecTypeToStreamType(AVMediaType codec_type) { +static SceAvPlayerStreamType CodecTypeToStreamType(AVMediaType codec_type) { switch (codec_type) { case AVMediaType::AVMEDIA_TYPE_VIDEO: - return SCE_AVPLAYER_VIDEO; + return SceAvPlayerStreamType::Video; case AVMediaType::AVMEDIA_TYPE_AUDIO: - return SCE_AVPLAYER_AUDIO; + return SceAvPlayerStreamType::Audio; case AVMediaType::AVMEDIA_TYPE_SUBTITLE: - return SCE_AVPLAYER_TIMEDTEXT; + return SceAvPlayerStreamType::TimedText; default: LOG_ERROR(Lib_AvPlayer, "Unexpected AVMediaType {}", magic_enum::enum_name(codec_type)); - return -1; + return SceAvPlayerStreamType::Unknown; } } @@ -124,7 +124,7 @@ bool AvPlayerSource::GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info LOG_WARNING(Lib_AvPlayer, "Stream {} language is unknown", stream_index); } switch (info.type) { - case SCE_AVPLAYER_VIDEO: { + case SceAvPlayerStreamType::Video: { LOG_INFO(Lib_AvPlayer, "Stream {} is a video stream.", stream_index); info.details.video.aspect_ratio = f32(p_stream->codecpar->width) / p_stream->codecpar->height; @@ -142,7 +142,7 @@ bool AvPlayerSource::GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info } break; } - case SCE_AVPLAYER_AUDIO: { + case SceAvPlayerStreamType::Audio: { LOG_INFO(Lib_AvPlayer, "Stream {} is an audio stream.", stream_index); info.details.audio.channel_count = p_stream->codecpar->ch_layout.nb_channels; info.details.audio.sample_rate = p_stream->codecpar->sample_rate; @@ -153,7 +153,7 @@ bool AvPlayerSource::GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info } break; } - case SCE_AVPLAYER_TIMEDTEXT: { + case SceAvPlayerStreamType::TimedText: { LOG_WARNING(Lib_AvPlayer, "Stream {} is a timedtext stream.", stream_index); info.details.subs.font_size = 12; info.details.subs.text_size = 12; @@ -164,7 +164,8 @@ bool AvPlayerSource::GetStreamInfo(u32 stream_index, SceAvPlayerStreamInfo& info break; } default: { - LOG_ERROR(Lib_AvPlayer, "Stream {} type is unknown: {}.", stream_index, info.type); + LOG_ERROR(Lib_AvPlayer, "Stream {} type is unknown: {}.", stream_index, + magic_enum::enum_name(info.type)); return false; } } diff --git a/src/core/libraries/avplayer/avplayer_state.cpp b/src/core/libraries/avplayer/avplayer_state.cpp index 3d9840a1b..c3694eec0 100644 --- a/src/core/libraries/avplayer/avplayer_state.cpp +++ b/src/core/libraries/avplayer/avplayer_state.cpp @@ -3,9 +3,9 @@ #include "common/logging/log.h" #include "common/thread.h" +#include "core/libraries/avplayer/avplayer_error.h" #include "core/libraries/avplayer/avplayer_source.h" #include "core/libraries/avplayer/avplayer_state.h" -#include "core/libraries/error_codes.h" #include "core/tls.h" #include @@ -16,7 +16,7 @@ void PS4_SYSV_ABI AvPlayerState::AutoPlayEventCallback(void* opaque, SceAvPlayer s32 source_id, void* event_data) { auto const self = reinterpret_cast(opaque); - if (event_id == SCE_AVPLAYER_STATE_READY) { + if (event_id == SceAvPlayerEvents::StateReady) { s32 video_stream_index = -1; s32 audio_stream_index = -1; s32 timedtext_stream_index = -1; @@ -36,36 +36,37 @@ void PS4_SYSV_ABI AvPlayerState::AutoPlayEventCallback(void* opaque, SceAvPlayer return; } - const std::string_view default_language( - reinterpret_cast(self->m_default_language)); + const std::string_view default_language{self->m_default_language}; switch (info.type) { - case SCE_AVPLAYER_VIDEO: + case SceAvPlayerStreamType::Video: if (video_stream_index == -1) { video_stream_index = stream_index; } if (!default_language.empty() && - default_language == reinterpret_cast(info.details.video.language_code)) { + default_language == info.details.video.language_code) { video_stream_index = stream_index; } break; - case SCE_AVPLAYER_AUDIO: + case SceAvPlayerStreamType::Audio: if (audio_stream_index == -1) { audio_stream_index = stream_index; } if (!default_language.empty() && - default_language == reinterpret_cast(info.details.video.language_code)) { + default_language == info.details.video.language_code) { audio_stream_index = stream_index; } break; - case SCE_AVPLAYER_TIMEDTEXT: + case SceAvPlayerStreamType::TimedText: if (default_language.empty()) { timedtext_stream_index = stream_index; break; } - if (default_language == reinterpret_cast(info.details.video.language_code)) { + if (default_language == info.details.video.language_code) { timedtext_stream_index = stream_index; } break; + default: + break; } } @@ -141,7 +142,7 @@ bool AvPlayerState::AddSource(std::string_view path, SceAvPlayerSourceType sourc m_up_source = std::make_unique( *this, m_post_init_data.video_decoder_init.decoderType.video_type == - SCE_AVPLAYER_VIDEO_DECODER_TYPE_SOFTWARE2); + SceAvPlayerVideoDecoderType::Software2); if (!m_up_source->Init(m_init_data, path)) { SetState(AvState::Error); m_up_source.reset(); @@ -317,23 +318,23 @@ void AvPlayerState::OnEOF() { void AvPlayerState::OnPlaybackStateChanged(AvState state) { switch (state) { case AvState::Ready: { - EmitEvent(SCE_AVPLAYER_STATE_READY); + EmitEvent(SceAvPlayerEvents::StateReady); break; } case AvState::Play: { - EmitEvent(SCE_AVPLAYER_STATE_PLAY); + EmitEvent(SceAvPlayerEvents::StatePlay); break; } case AvState::Stop: { - EmitEvent(SCE_AVPLAYER_STATE_STOP); + EmitEvent(SceAvPlayerEvents::StateStop); break; } case AvState::Pause: { - EmitEvent(SCE_AVPLAYER_STATE_PAUSE); + EmitEvent(SceAvPlayerEvents::StatePause); break; } case AvState::Buffering: { - EmitEvent(SCE_AVPLAYER_STATE_BUFFERING); + EmitEvent(SceAvPlayerEvents::StateBuffering); break; } default: diff --git a/src/core/libraries/avplayer/avplayer_state.h b/src/core/libraries/avplayer/avplayer_state.h index 8a0d7f4f8..48cd17bf2 100644 --- a/src/core/libraries/avplayer/avplayer_state.h +++ b/src/core/libraries/avplayer/avplayer_state.h @@ -69,7 +69,7 @@ private: SceAvPlayerPostInitData m_post_init_data{}; SceAvPlayerEventReplacement m_event_replacement{}; bool m_auto_start{}; - u8 m_default_language[4]{}; + char m_default_language[4]{}; std::atomic m_current_state; std::atomic m_previous_state; diff --git a/src/core/libraries/error_codes.h b/src/core/libraries/error_codes.h index 280ddf1cb..e1902b61c 100644 --- a/src/core/libraries/error_codes.h +++ b/src/core/libraries/error_codes.h @@ -3,626 +3,6 @@ #pragma once -// posix error codes -constexpr int POSIX_EPERM = 1; -constexpr int POSIX_ENOENT = 2; -constexpr int POSIX_ESRCH = 3; -constexpr int POSIX_EINTR = 4; -constexpr int POSIX_EIO = 5; -constexpr int POSIX_ENXIO = 6; -constexpr int POSIX_E2BIG = 7; -constexpr int POSIX_ENOEXEC = 8; -constexpr int POSIX_EBADF = 9; -constexpr int POSIX_ECHILD = 10; -constexpr int POSIX_EDEADLK = 11; -constexpr int POSIX_ENOMEM = 12; -constexpr int POSIX_EACCES = 13; -constexpr int POSIX_EFAULT = 14; -constexpr int POSIX_ENOTBLK = 15; -constexpr int POSIX_EBUSY = 16; -constexpr int POSIX_EEXIST = 17; -constexpr int POSIX_EXDEV = 18; -constexpr int POSIX_ENODEV = 19; -constexpr int POSIX_ENOTDIR = 20; -constexpr int POSIX_EISDIR = 21; -constexpr int POSIX_EINVAL = 22; -constexpr int POSIX_ENFILE = 23; -constexpr int POSIX_EMFILE = 24; -constexpr int POSIX_ENOTTY = 25; -constexpr int POSIX_ETXTBSY = 26; -constexpr int POSIX_EFBIG = 27; -constexpr int POSIX_ENOSPC = 28; -constexpr int POSIX_ESPIPE = 29; -constexpr int POSIX_EROFS = 30; -constexpr int POSIX_EMLINK = 31; -constexpr int POSIX_EPIPE = 32; -constexpr int POSIX_EDOM = 33; -constexpr int POSIX_ERANGE = 34; -constexpr int POSIX_EAGAIN = 35; -constexpr int POSIX_EWOULDBLOCK = 35; -constexpr int POSIX_EINPROGRESS = 36; -constexpr int POSIX_EALREADY = 37; -constexpr int POSIX_ENOTSOCK = 38; -constexpr int POSIX_EDESTADDRREQ = 39; -constexpr int POSIX_EMSGSIZE = 40; -constexpr int POSIX_EPROTOTYPE = 41; -constexpr int POSIX_ENOPROTOOPT = 42; -constexpr int POSIX_EPROTONOSUPPORT = 43; -constexpr int POSIX_ESOCKTNOSUPPORT = 44; -constexpr int POSIX_EOPNOTSUPP = 45; -constexpr int POSIX_ENOTSUP = 45; -constexpr int POSIX_EPFNOSUPPORT = 46; -constexpr int POSIX_EAFNOSUPPORT = 47; -constexpr int POSIX_EADDRINUSE = 48; -constexpr int POSIX_EADDRNOTAVAIL = 49; -constexpr int POSIX_ENETDOWN = 50; -constexpr int POSIX_ENETUNREACH = 51; -constexpr int POSIX_ENETRESET = 52; -constexpr int POSIX_ECONNABORTED = 53; -constexpr int POSIX_ECONNRESET = 54; -constexpr int POSIX_ENOBUFS = 55; -constexpr int POSIX_EISCONN = 56; -constexpr int POSIX_ENOTCONN = 57; -constexpr int POSIX_ESHUTDOWN = 58; -constexpr int POSIX_ETOOMANYREFS = 59; -constexpr int POSIX_ETIMEDOUT = 60; -constexpr int POSIX_ECONNREFUSED = 61; -constexpr int POSIX_ELOOP = 62; -constexpr int POSIX_ENAMETOOLONG = 63; -constexpr int POSIX_EHOSTDOWN = 64; -constexpr int POSIX_EHOSTUNREACH = 65; -constexpr int POSIX_ENOTEMPTY = 66; -constexpr int POSIX_EPROCLIM = 67; -constexpr int POSIX_EUSERS = 68; -constexpr int POSIX_EDQUOT = 69; -constexpr int POSIX_ESTALE = 70; -constexpr int POSIX_EREMOTE = 71; -constexpr int POSIX_EBADRPC = 72; -constexpr int POSIX_ERPCMISMATCH = 73; -constexpr int POSIX_EPROGUNAVAIL = 74; -constexpr int POSIX_EPROGMISMATCH = 75; -constexpr int POSIX_EPROCUNAVAIL = 76; -constexpr int POSIX_ENOLCK = 77; -constexpr int POSIX_ENOSYS = 78; -constexpr int POSIX_EFTYPE = 79; -constexpr int POSIX_EAUTH = 80; -constexpr int POSIX_ENEEDAUTH = 81; -constexpr int POSIX_EIDRM = 82; -constexpr int POSIX_ENOMSG = 83; -constexpr int POSIX_EOVERFLOW = 84; -constexpr int POSIX_ECANCELED = 85; -constexpr int POSIX_EILSEQ = 86; -constexpr int POSIX_ENOATTR = 87; -constexpr int POSIX_EDOOFUS = 88; -constexpr int POSIX_EBADMSG = 89; -constexpr int POSIX_EMULTIHOP = 90; -constexpr int POSIX_ENOLINK = 91; -constexpr int POSIX_EPROTO = 92; -constexpr int POSIX_ENOTCAPABLE = 93; -constexpr int POSIX_ECAPMODE = 94; -constexpr int POSIX_ENOBLK = 95; -constexpr int POSIX_EICV = 96; -constexpr int POSIX_ENOPLAYGOENT = 97; -constexpr int POSIX_EREVOKE = 98; -constexpr int POSIX_ESDKVERSION = 99; -constexpr int POSIX_ESTART = 100; -constexpr int POSIX_ESTOP = 101; -constexpr int POSIX_EINVALID2MB = 102; -constexpr int POSIX_ELAST = 102; -constexpr int POSIX_EADHOC = 160; -constexpr int POSIX_EINACTIVEDISABLED = 163; -constexpr int POSIX_ENETNODATA = 164; -constexpr int POSIX_ENETDESC = 165; -constexpr int POSIX_ENETDESCTIMEDOUT = 166; -constexpr int POSIX_ENETINTR = 167; -constexpr int POSIX_ERETURN = 205; -constexpr int POSIX_EFPOS = 152; -constexpr int POSIX_ENODATA = 1040; -constexpr int POSIX_ENOSR = 1050; -constexpr int POSIX_ENOSTR = 1051; -constexpr int POSIX_ENOTRECOVERABLE = 1056; -constexpr int POSIX_EOTHER = 1062; -constexpr int POSIX_EOWNERDEAD = 1064; -constexpr int POSIX_ETIME = 1074; - -constexpr int SCE_OK = 0; - -// kernel error codes -constexpr int SCE_KERNEL_ERROR_UNKNOWN = 0x80020000; -constexpr int SCE_KERNEL_ERROR_EPERM = 0x80020001; -constexpr int SCE_KERNEL_ERROR_ENOENT = 0x80020002; -constexpr int SCE_KERNEL_ERROR_ESRCH = 0x80020003; -constexpr int SCE_KERNEL_ERROR_EINTR = 0x80020004; -constexpr int SCE_KERNEL_ERROR_EIO = 0x80020005; -constexpr int SCE_KERNEL_ERROR_ENXIO = 0x80020006; -constexpr int SCE_KERNEL_ERROR_E2BIG = 0x80020007; -constexpr int SCE_KERNEL_ERROR_ENOEXEC = 0x80020008; -constexpr int SCE_KERNEL_ERROR_EBADF = 0x80020009; -constexpr int SCE_KERNEL_ERROR_ECHILD = 0x8002000A; -constexpr int SCE_KERNEL_ERROR_EDEADLK = 0x8002000B; -constexpr int SCE_KERNEL_ERROR_ENOMEM = 0x8002000C; -constexpr int SCE_KERNEL_ERROR_EACCES = 0x8002000D; -constexpr int SCE_KERNEL_ERROR_EFAULT = 0x8002000E; -constexpr int SCE_KERNEL_ERROR_ENOTBLK = 0x8002000F; -constexpr int SCE_KERNEL_ERROR_EBUSY = 0x80020010; -constexpr int SCE_KERNEL_ERROR_EEXIST = 0x80020011; -constexpr int SCE_KERNEL_ERROR_EXDEV = 0x80020012; -constexpr int SCE_KERNEL_ERROR_ENODEV = 0x80020013; -constexpr int SCE_KERNEL_ERROR_ENOTDIR = 0x80020014; -constexpr int SCE_KERNEL_ERROR_EISDIR = 0x80020015; -constexpr int SCE_KERNEL_ERROR_EINVAL = 0x80020016; -constexpr int SCE_KERNEL_ERROR_ENFILE = 0x80020017; -constexpr int SCE_KERNEL_ERROR_EMFILE = 0x80020018; -constexpr int SCE_KERNEL_ERROR_ENOTTY = 0x80020019; -constexpr int SCE_KERNEL_ERROR_ETXTBSY = 0x8002001A; -constexpr int SCE_KERNEL_ERROR_EFBIG = 0x8002001B; -constexpr int SCE_KERNEL_ERROR_ENOSPC = 0x8002001C; -constexpr int SCE_KERNEL_ERROR_ESPIPE = 0x8002001D; -constexpr int SCE_KERNEL_ERROR_EROFS = 0x8002001E; -constexpr int SCE_KERNEL_ERROR_EMLINK = 0x8002001F; -constexpr int SCE_KERNEL_ERROR_EPIPE = 0x80020020; -constexpr int SCE_KERNEL_ERROR_EDOM = 0x80020021; -constexpr int SCE_KERNEL_ERROR_ERANGE = 0x80020022; -constexpr int SCE_KERNEL_ERROR_EAGAIN = 0x80020023; -constexpr int SCE_KERNEL_ERROR_EWOULDBLOCK = 0x80020023; -constexpr int SCE_KERNEL_ERROR_EINPROGRESS = 0x80020024; -constexpr int SCE_KERNEL_ERROR_EALREADY = 0x80020025; -constexpr int SCE_KERNEL_ERROR_ENOTSOCK = 0x80020026; -constexpr int SCE_KERNEL_ERROR_EDESTADDRREQ = 0x80020027; -constexpr int SCE_KERNEL_ERROR_EMSGSIZE = 0x80020028; -constexpr int SCE_KERNEL_ERROR_EPROTOTYPE = 0x80020029; -constexpr int SCE_KERNEL_ERROR_ENOPROTOOPT = 0x8002002A; -constexpr int SCE_KERNEL_ERROR_EPROTONOSUPPORT = 0x8002002B; -constexpr int SCE_KERNEL_ERROR_ESOCKTNOSUPPORT = 0x8002002C; -constexpr int SCE_KERNEL_ERROR_EOPNOTSUPP = 0x8002002D; -constexpr int SCE_KERNEL_ERROR_ENOTSUP = 0x8002002D; -constexpr int SCE_KERNEL_ERROR_EPFNOSUPPORT = 0x8002002E; -constexpr int SCE_KERNEL_ERROR_EAFNOSUPPORT = 0x8002002F; -constexpr int SCE_KERNEL_ERROR_EADDRINUSE = 0x80020030; -constexpr int SCE_KERNEL_ERROR_EADDRNOTAVAIL = 0x80020031; -constexpr int SCE_KERNEL_ERROR_ENETDOWN = 0x80020032; -constexpr int SCE_KERNEL_ERROR_ENETUNREACH = 0x80020033; -constexpr int SCE_KERNEL_ERROR_ENETRESET = 0x80020034; -constexpr int SCE_KERNEL_ERROR_ECONNABORTED = 0x80020035; -constexpr int SCE_KERNEL_ERROR_ECONNRESET = 0x80020036; -constexpr int SCE_KERNEL_ERROR_ENOBUFS = 0x80020037; -constexpr int SCE_KERNEL_ERROR_EISCONN = 0x80020038; -constexpr int SCE_KERNEL_ERROR_ENOTCONN = 0x80020039; -constexpr int SCE_KERNEL_ERROR_ESHUTDOWN = 0x8002003A; -constexpr int SCE_KERNEL_ERROR_ETOOMANYREFS = 0x8002003B; -constexpr int SCE_KERNEL_ERROR_ETIMEDOUT = 0x8002003C; -constexpr int SCE_KERNEL_ERROR_ECONNREFUSED = 0x8002003D; -constexpr int SCE_KERNEL_ERROR_ELOOP = 0x8002003E; -constexpr int SCE_KERNEL_ERROR_ENAMETOOLONG = 0x8002003F; -constexpr int SCE_KERNEL_ERROR_EHOSTDOWN = 0x80020040; -constexpr int SCE_KERNEL_ERROR_EHOSTUNREACH = 0x80020041; -constexpr int SCE_KERNEL_ERROR_ENOTEMPTY = 0x80020042; -constexpr int SCE_KERNEL_ERROR_EPROCLIM = 0x80020043; -constexpr int SCE_KERNEL_ERROR_EUSERS = 0x80020044; -constexpr int SCE_KERNEL_ERROR_EDQUOT = 0x80020045; -constexpr int SCE_KERNEL_ERROR_ESTALE = 0x80020046; -constexpr int SCE_KERNEL_ERROR_EREMOTE = 0x80020047; -constexpr int SCE_KERNEL_ERROR_EBADRPC = 0x80020048; -constexpr int SCE_KERNEL_ERROR_ERPCMISMATCH = 0x80020049; -constexpr int SCE_KERNEL_ERROR_EPROGUNAVAIL = 0x8002004A; -constexpr int SCE_KERNEL_ERROR_EPROGMISMATCH = 0x8002004B; -constexpr int SCE_KERNEL_ERROR_EPROCUNAVAIL = 0x8002004C; -constexpr int SCE_KERNEL_ERROR_ENOLCK = 0x8002004D; -constexpr int SCE_KERNEL_ERROR_ENOSYS = 0x8002004E; -constexpr int SCE_KERNEL_ERROR_EFTYPE = 0x8002004F; -constexpr int SCE_KERNEL_ERROR_EAUTH = 0x80020050; -constexpr int SCE_KERNEL_ERROR_ENEEDAUTH = 0x80020051; -constexpr int SCE_KERNEL_ERROR_EIDRM = 0x80020052; -constexpr int SCE_KERNEL_ERROR_ENOMSG = 0x80020053; -constexpr int SCE_KERNEL_ERROR_EOVERFLOW = 0x80020054; -constexpr int SCE_KERNEL_ERROR_ECANCELED = 0x80020055; -constexpr int SCE_KERNEL_ERROR_EILSEQ = 0x80020056; -constexpr int SCE_KERNEL_ERROR_ENOATTR = 0x80020057; -constexpr int SCE_KERNEL_ERROR_EDOOFUS = 0x80020058; -constexpr int SCE_KERNEL_ERROR_EBADMSG = 0x80020059; -constexpr int SCE_KERNEL_ERROR_EMULTIHOP = 0x8002005A; -constexpr int SCE_KERNEL_ERROR_ENOLINK = 0x8002005B; -constexpr int SCE_KERNEL_ERROR_EPROTO = 0x8002005C; -constexpr int SCE_KERNEL_ERROR_ENOTCAPABLE = 0x8002005D; -constexpr int SCE_KERNEL_ERROR_ECAPMODE = 0x8002005E; -constexpr int SCE_KERNEL_ERROR_ENOBLK = 0x8002005F; -constexpr int SCE_KERNEL_ERROR_EICV = 0x80020060; -constexpr int SCE_KERNEL_ERROR_ENOPLAYGOENT = 0x80020061; -constexpr int SCE_KERNEL_ERROR_EREVOKE = 0x80020062; -constexpr int SCE_KERNEL_ERROR_ESDKVERSION = 0x80020063; -constexpr int SCE_KERNEL_ERROR_ESTART = 0x80020064; -constexpr int SCE_KERNEL_ERROR_ESTOP = 0x80020065; - -// videoOut -constexpr int SCE_VIDEO_OUT_ERROR_INVALID_VALUE = 0x80290001; // invalid argument -constexpr int SCE_VIDEO_OUT_ERROR_INVALID_ADDRESS = 0x80290002; // invalid addresses -constexpr int SCE_VIDEO_OUT_ERROR_INVALID_TILING_MODE = 0x80290007; // invalid tiling mode -constexpr int SCE_VIDEO_OUT_ERROR_INVALID_ASPECT_RATIO = 0x80290008; // invalid aspect ration -constexpr int SCE_VIDEO_OUT_ERROR_RESOURCE_BUSY = 0x80290009; // already opened -constexpr int SCE_VIDEO_OUT_ERROR_INVALID_INDEX = 0x8029000A; // invalid buffer index -constexpr int SCE_VIDEO_OUT_ERROR_INVALID_HANDLE = 0x8029000B; // invalid handle -constexpr int SCE_VIDEO_OUT_ERROR_INVALID_EVENT_QUEUE = 0x8029000C; // Invalid event queue -constexpr int SCE_VIDEO_OUT_ERROR_SLOT_OCCUPIED = 0x80290010; // slot already used -constexpr int SCE_VIDEO_OUT_ERROR_FLIP_QUEUE_FULL = 0x80290012; // flip queue is full -constexpr int SCE_VIDEO_OUT_ERROR_INVALID_OPTION = 0x8029001A; // Invalid buffer attribute option - // Generic constexpr int ORBIS_OK = 0x00000000; constexpr int ORBIS_FAIL = 0xFFFFFFFF; - -// Libkernel library -constexpr int ORBIS_KERNEL_ERROR_UNKNOWN = 0x80020000; -constexpr int ORBIS_KERNEL_ERROR_EPERM = 0x80020001; -constexpr int ORBIS_KERNEL_ERROR_ENOENT = 0x80020002; -constexpr int ORBIS_KERNEL_ERROR_ESRCH = 0x80020003; -constexpr int ORBIS_KERNEL_ERROR_EINTR = 0x80020004; -constexpr int ORBIS_KERNEL_ERROR_EIO = 0x80020005; -constexpr int ORBIS_KERNEL_ERROR_ENXIO = 0x80020006; -constexpr int ORBIS_KERNEL_ERROR_E2BIG = 0x80020007; -constexpr int ORBIS_KERNEL_ERROR_ENOEXEC = 0x80020008; -constexpr int ORBIS_KERNEL_ERROR_EBADF = 0x80020009; -constexpr int ORBIS_KERNEL_ERROR_ECHILD = 0x8002000A; -constexpr int ORBIS_KERNEL_ERROR_EDEADLK = 0x8002000B; -constexpr int ORBIS_KERNEL_ERROR_ENOMEM = 0x8002000C; -constexpr int ORBIS_KERNEL_ERROR_EACCES = 0x8002000D; -constexpr int ORBIS_KERNEL_ERROR_EFAULT = 0x8002000E; -constexpr int ORBIS_KERNEL_ERROR_ENOTBLK = 0x8002000F; -constexpr int ORBIS_KERNEL_ERROR_EBUSY = 0x80020010; -constexpr int ORBIS_KERNEL_ERROR_EEXIST = 0x80020011; -constexpr int ORBIS_KERNEL_ERROR_EXDEV = 0x80020012; -constexpr int ORBIS_KERNEL_ERROR_ENODEV = 0x80020013; -constexpr int ORBIS_KERNEL_ERROR_ENOTDIR = 0x80020014; -constexpr int ORBIS_KERNEL_ERROR_EISDIR = 0x80020015; -constexpr int ORBIS_KERNEL_ERROR_EINVAL = 0x80020016; -constexpr int ORBIS_KERNEL_ERROR_ENFILE = 0x80020017; -constexpr int ORBIS_KERNEL_ERROR_EMFILE = 0x80020018; -constexpr int ORBIS_KERNEL_ERROR_ENOTTY = 0x80020019; -constexpr int ORBIS_KERNEL_ERROR_ETXTBSY = 0x8002001A; -constexpr int ORBIS_KERNEL_ERROR_EFBIG = 0x8002001B; -constexpr int ORBIS_KERNEL_ERROR_ENOSPC = 0x8002001C; -constexpr int ORBIS_KERNEL_ERROR_ESPIPE = 0x8002001D; -constexpr int ORBIS_KERNEL_ERROR_EROFS = 0x8002001E; -constexpr int ORBIS_KERNEL_ERROR_EMLINK = 0x8002001F; -constexpr int ORBIS_KERNEL_ERROR_EPIPE = 0x80020020; -constexpr int ORBIS_KERNEL_ERROR_EDOM = 0x80020021; -constexpr int ORBIS_KERNEL_ERROR_ERANGE = 0x80020022; -constexpr int ORBIS_KERNEL_ERROR_EAGAIN = 0x80020023; -constexpr int ORBIS_KERNEL_ERROR_EWOULDBLOCK = 0x80020023; -constexpr int ORBIS_KERNEL_ERROR_EINPROGRESS = 0x80020024; -constexpr int ORBIS_KERNEL_ERROR_EALREADY = 0x80020025; -constexpr int ORBIS_KERNEL_ERROR_ENOTSOCK = 0x80020026; -constexpr int ORBIS_KERNEL_ERROR_EDESTADDRREQ = 0x80020027; -constexpr int ORBIS_KERNEL_ERROR_EMSGSIZE = 0x80020028; -constexpr int ORBIS_KERNEL_ERROR_EPROTOTYPE = 0x80020029; -constexpr int ORBIS_KERNEL_ERROR_ENOPROTOOPT = 0x8002002A; -constexpr int ORBIS_KERNEL_ERROR_EPROTONOSUPPORT = 0x8002002B; -constexpr int ORBIS_KERNEL_ERROR_ESOCKTNOSUPPORT = 0x8002002C; -constexpr int ORBIS_KERNEL_ERROR_ENOTSUP = 0x8002002D; -constexpr int ORBIS_KERNEL_ERROR_EOPNOTSUPP = 0x8002002D; -constexpr int ORBIS_KERNEL_ERROR_EPFNOSUPPORT = 0x8002002E; -constexpr int ORBIS_KERNEL_ERROR_EAFNOSUPPORT = 0x8002002F; -constexpr int ORBIS_KERNEL_ERROR_EADDRINUSE = 0x80020030; -constexpr int ORBIS_KERNEL_ERROR_EADDRNOTAVAIL = 0x80020031; -constexpr int ORBIS_KERNEL_ERROR_ENETDOWN = 0x80020032; -constexpr int ORBIS_KERNEL_ERROR_ENETUNREACH = 0x80020033; -constexpr int ORBIS_KERNEL_ERROR_ENETRESET = 0x80020034; -constexpr int ORBIS_KERNEL_ERROR_ECONNABORTED = 0x80020035; -constexpr int ORBIS_KERNEL_ERROR_ECONNRESET = 0x80020036; -constexpr int ORBIS_KERNEL_ERROR_ENOBUFS = 0x80020037; -constexpr int ORBIS_KERNEL_ERROR_EISCONN = 0x80020038; -constexpr int ORBIS_KERNEL_ERROR_ENOTCONN = 0x80020039; -constexpr int ORBIS_KERNEL_ERROR_ESHUTDOWN = 0x8002003A; -constexpr int ORBIS_KERNEL_ERROR_ETOOMANYREFS = 0x8002003B; -constexpr int ORBIS_KERNEL_ERROR_ETIMEDOUT = 0x8002003C; -constexpr int ORBIS_KERNEL_ERROR_ECONNREFUSED = 0x8002003D; -constexpr int ORBIS_KERNEL_ERROR_ELOOP = 0x8002003E; -constexpr int ORBIS_KERNEL_ERROR_ENAMETOOLONG = 0x8002003F; -constexpr int ORBIS_KERNEL_ERROR_EHOSTDOWN = 0x80020040; -constexpr int ORBIS_KERNEL_ERROR_EHOSTUNREACH = 0x80020041; -constexpr int ORBIS_KERNEL_ERROR_ENOTEMPTY = 0x80020042; -constexpr int ORBIS_KERNEL_ERROR_EPROCLIM = 0x80020043; -constexpr int ORBIS_KERNEL_ERROR_EUSERS = 0x80020044; -constexpr int ORBIS_KERNEL_ERROR_EDQUOT = 0x80020045; -constexpr int ORBIS_KERNEL_ERROR_ESTALE = 0x80020046; -constexpr int ORBIS_KERNEL_ERROR_EREMOTE = 0x80020047; -constexpr int ORBIS_KERNEL_ERROR_EBADRPC = 0x80020048; -constexpr int ORBIS_KERNEL_ERROR_ERPCMISMATCH = 0x80020049; -constexpr int ORBIS_KERNEL_ERROR_EPROGUNAVAIL = 0x8002004A; -constexpr int ORBIS_KERNEL_ERROR_EPROGMISMATCH = 0x8002004B; -constexpr int ORBIS_KERNEL_ERROR_EPROCUNAVAIL = 0x8002004C; -constexpr int ORBIS_KERNEL_ERROR_ENOLCK = 0x8002004D; -constexpr int ORBIS_KERNEL_ERROR_ENOSYS = 0x8002004E; -constexpr int ORBIS_KERNEL_ERROR_EFTYPE = 0x8002004F; -constexpr int ORBIS_KERNEL_ERROR_EAUTH = 0x80020050; -constexpr int ORBIS_KERNEL_ERROR_ENEEDAUTH = 0x80020051; -constexpr int ORBIS_KERNEL_ERROR_EIDRM = 0x80020052; -constexpr int ORBIS_KERNEL_ERROR_ENOMSG = 0x80020053; -constexpr int ORBIS_KERNEL_ERROR_EOVERFLOW = 0x80020054; -constexpr int ORBIS_KERNEL_ERROR_ECANCELED = 0x80020055; -constexpr int ORBIS_KERNEL_ERROR_EILSEQ = 0x80020056; -constexpr int ORBIS_KERNEL_ERROR_ENOATTR = 0x80020057; -constexpr int ORBIS_KERNEL_ERROR_EDOOFUS = 0x80020058; -constexpr int ORBIS_KERNEL_ERROR_EBADMSG = 0x80020059; -constexpr int ORBIS_KERNEL_ERROR_EMULTIHOP = 0x8002005A; -constexpr int ORBIS_KERNEL_ERROR_ENOLINK = 0x8002005B; -constexpr int ORBIS_KERNEL_ERROR_EPROTO = 0x8002005C; -constexpr int ORBIS_KERNEL_ERROR_ENOTCAPABLE = 0x8002005D; -constexpr int ORBIS_KERNEL_ERROR_ECAPMODE = 0x8002005E; -constexpr int ORBIS_KERNEL_ERROR_ENOBLK = 0x8002005F; -constexpr int ORBIS_KERNEL_ERROR_EICV = 0x80020060; -constexpr int ORBIS_KERNEL_ERROR_ENOPLAYGOENT = 0x80020061; - -// AudioOut library -constexpr int ORBIS_AUDIO_OUT_ERROR_NOT_OPENED = 0x80260001; -constexpr int ORBIS_AUDIO_OUT_ERROR_BUSY = 0x80260002; -constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_PORT = 0x80260003; -constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_POINTER = 0x80260004; -constexpr int ORBIS_AUDIO_OUT_ERROR_PORT_FULL = 0x80260005; -constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_SIZE = 0x80260006; -constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_FORMAT = 0x80260007; -constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_SAMPLE_FREQ = 0x80260008; -constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_VOLUME = 0x80260009; -constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_PORT_TYPE = 0x8026000A; -constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_CONF_TYPE = 0x8026000C; -constexpr int ORBIS_AUDIO_OUT_ERROR_OUT_OF_MEMORY = 0x8026000D; -constexpr int ORBIS_AUDIO_OUT_ERROR_ALREADY_INIT = 0x8026000E; -constexpr int ORBIS_AUDIO_OUT_ERROR_NOT_INIT = 0x8026000F; -constexpr int ORBIS_AUDIO_OUT_ERROR_MEMORY = 0x80260010; -constexpr int ORBIS_AUDIO_OUT_ERROR_SYSTEM_RESOURCE = 0x80260011; -constexpr int ORBIS_AUDIO_OUT_ERROR_TRANS_EVENT = 0x80260012; -constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_FLAG = 0x80260013; -constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_MIXLEVEL = 0x80260014; -constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_ARG = 0x80260015; -constexpr int ORBIS_AUDIO_OUT_ERROR_INVALID_PARAM = 0x80260016; -constexpr int ORBIS_AUDIO_OUT_ERROR_MASTERING_FATAL = 0x80260200; -constexpr int ORBIS_AUDIO_OUT_ERROR_MASTERING_INVALID_API_PARAM = 0x80260201; -constexpr int ORBIS_AUDIO_OUT_ERROR_MASTERING_INVALID_CONFIG = 0x80260202; -constexpr int ORBIS_AUDIO_OUT_ERROR_MASTERING_NOT_INITIALIZED = 0x80260203; -constexpr int ORBIS_AUDIO_OUT_ERROR_MASTERING_INVALID_STATES_ID = 0x80260204; - -// VideoOut library -constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_VALUE = 0x80290001; -constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS = 0x80290002; -constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_PIXEL_FORMAT = 0x80290003; -constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_PITCH = 0x80290004; -constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_RESOLUTION = 0x80290005; -constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_FLIP_MODE = 0x80290006; -constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_TILING_MODE = 0x80290007; -constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_ASPECT_RATIO = 0x80290008; -constexpr int ORBIS_VIDEO_OUT_ERROR_RESOURCE_BUSY = 0x80290009; -constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_INDEX = 0x8029000A; -constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE = 0x8029000B; -constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_EVENT_QUEUE = 0x8029000C; -constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_EVENT = 0x8029000D; -constexpr int ORBIS_VIDEO_OUT_ERROR_NO_EMPTY_SLOT = 0x8029000F; -constexpr int ORBIS_VIDEO_OUT_ERROR_SLOT_OCCUPIED = 0x80290010; -constexpr int ORBIS_VIDEO_OUT_ERROR_FLIP_QUEUE_FULL = 0x80290012; -constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_MEMORY = 0x80290013; -constexpr int ORBIS_VIDEO_OUT_ERROR_MEMORY_NOT_PHYSICALLY_CONTIGUOUS = 0x80290014; -constexpr int ORBIS_VIDEO_OUT_ERROR_MEMORY_INVALID_ALIGNMENT = 0x80290015; -constexpr int ORBIS_VIDEO_OUT_ERROR_UNSUPPORTED_OUTPUT_MODE = 0x80290016; -constexpr int ORBIS_VIDEO_OUT_ERROR_OVERFLOW = 0x80290017; -constexpr int ORBIS_VIDEO_OUT_ERROR_NO_DEVICE = 0x80290018; -constexpr int ORBIS_VIDEO_OUT_ERROR_UNAVAILABLE_OUTPUT_MODE = 0x80290019; -constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_OPTION = 0x8029001A; -constexpr int ORBIS_VIDEO_OUT_ERROR_UNKNOWN = 0x802900FE; -constexpr int ORBIS_VIDEO_OUT_ERROR_FATAL = 0x802900FF; -constexpr int ORBIS_VIDEO_OUT_ERROR_ENOMEM = 0x8029100C; - -// Pad library -constexpr int ORBIS_PAD_ERROR_INVALID_ARG = 0x80920001; -constexpr int ORBIS_PAD_ERROR_INVALID_PORT = 0x80920002; -constexpr int ORBIS_PAD_ERROR_INVALID_HANDLE = 0x80920003; -constexpr int ORBIS_PAD_ERROR_ALREADY_OPENED = 0x80920004; -constexpr int ORBIS_PAD_ERROR_NOT_INITIALIZED = 0x80920005; -constexpr int ORBIS_PAD_ERROR_INVALID_LIGHTBAR_SETTING = 0x80920006; -constexpr int ORBIS_PAD_ERROR_DEVICE_NOT_CONNECTED = 0x80920007; -constexpr int ORBIS_PAD_ERROR_DEVICE_NO_HANDLE = 0x80920008; -constexpr int ORBIS_PAD_ERROR_FATAL = 0x809200FF; -constexpr int ORBIS_PAD_ERROR_NOT_PERMITTED = 0x80920101; -constexpr int ORBIS_PAD_ERROR_INVALID_BUFFER_LENGTH = 0x80920102; -constexpr int ORBIS_PAD_ERROR_INVALID_REPORT_LENGTH = 0x80920103; -constexpr int ORBIS_PAD_ERROR_INVALID_REPORT_ID = 0x80920104; -constexpr int ORBIS_PAD_ERROR_SEND_AGAIN = 0x80920105; - -// UserService library -constexpr int ORBIS_USER_SERVICE_ERROR_INTERNAL = 0x80960001; -constexpr int ORBIS_USER_SERVICE_ERROR_NOT_INITIALIZED = 0x80960002; -constexpr int ORBIS_USER_SERVICE_ERROR_ALREADY_INITIALIZED = 0x80960003; -constexpr int ORBIS_USER_SERVICE_ERROR_NO_MEMORY = 0x80960004; -constexpr int ORBIS_USER_SERVICE_ERROR_INVALID_ARGUMENT = 0x80960005; -constexpr int ORBIS_USER_SERVICE_ERROR_OPERATION_NOT_SUPPORTED = 0x80960006; -constexpr int ORBIS_USER_SERVICE_ERROR_NO_EVENT = 0x80960007; -constexpr int ORBIS_USER_SERVICE_ERROR_NOT_LOGGED_IN = 0x80960009; -constexpr int ORBIS_USER_SERVICE_ERROR_BUFFER_TOO_SHORT = 0x8096000A; - -// SystemService library -constexpr int ORBIS_SYSTEM_SERVICE_ERROR_PARAMETER = 0x80A10003; -constexpr int ORBIS_SYSTEM_SERVICE_ERROR_NO_EVENT = 0x80A10004; - -// NpTrophy library -constexpr int ORBIS_NP_TROPHY_ERROR_UNKNOWN = 0x80551600; -constexpr int ORBIS_NP_TROPHY_ERROR_NOT_INITIALIZED = 0x80551601; -constexpr int ORBIS_NP_TROPHY_ERROR_ALREADY_INITIALIZED = 0x80551602; -constexpr int ORBIS_NP_TROPHY_ERROR_OUT_OF_MEMORY = 0x80551603; -constexpr int ORBIS_NP_TROPHY_ERROR_INVALID_ARGUMENT = 0x80551604; -constexpr int ORBIS_NP_TROPHY_ERROR_INSUFFICIENT_BUFFER = 0x80551605; -constexpr int ORBIS_NP_TROPHY_ERROR_EXCEEDS_MAX = 0x80551606; -constexpr int ORBIS_NP_TROPHY_ERROR_ABORT = 0x80551607; -constexpr int ORBIS_NP_TROPHY_ERROR_INVALID_HANDLE = 0x80551608; -constexpr int ORBIS_NP_TROPHY_ERROR_INVALID_CONTEXT = 0x80551609; -constexpr int ORBIS_NP_TROPHY_ERROR_INVALID_TROPHY_ID = 0x8055160A; -constexpr int ORBIS_NP_TROPHY_ERROR_INVALID_GROUP_ID = 0x8055160B; -constexpr int ORBIS_NP_TROPHY_ERROR_TROPHY_ALREADY_UNLOCKED = 0x8055160C; -constexpr int ORBIS_NP_TROPHY_ERROR_PLATINUM_CANNOT_UNLOCK = 0x8055160D; -constexpr int ORBIS_NP_TROPHY_ERROR_ACCOUNTID_NOT_MATCH = 0x8055160E; -constexpr int ORBIS_NP_TROPHY_ERROR_NOT_REGISTERED = 0x8055160F; -constexpr int ORBIS_NP_TROPHY_ERROR_ALREADY_REGISTERED = 0x80551610; -constexpr int ORBIS_NP_TROPHY_ERROR_BROKEN_DATA = 0x80551611; -constexpr int ORBIS_NP_TROPHY_ERROR_INSUFFICIENT_SPACE = 0x80551612; -constexpr int ORBIS_NP_TROPHY_ERROR_CONTEXT_ALREADY_EXISTS = 0x80551613; -constexpr int ORBIS_NP_TROPHY_ERROR_ICON_FILE_NOT_FOUND = 0x80551614; -constexpr int ORBIS_NP_TROPHY_ERROR_INVALID_TRP_FILE_FORMAT = 0x80551616; -constexpr int ORBIS_NP_TROPHY_ERROR_UNSUPPORTED_TRP_FILE = 0x80551617; -constexpr int ORBIS_NP_TROPHY_ERROR_INVALID_TROPHY_CONF_FORMAT = 0x80551618; -constexpr int ORBIS_NP_TROPHY_ERROR_UNSUPPORTED_TROPHY_CONF = 0x80551619; -constexpr int ORBIS_NP_TROPHY_ERROR_TROPHY_NOT_UNLOCKED = 0x8055161A; -constexpr int ORBIS_NP_TROPHY_ERROR_USER_NOT_FOUND = 0x8055161C; -constexpr int ORBIS_NP_TROPHY_ERROR_USER_NOT_LOGGED_IN = 0x8055161D; -constexpr int ORBIS_NP_TROPHY_ERROR_CONTEXT_USER_LOGOUT = 0x8055161E; -constexpr int ORBIS_NP_TROPHY_ERROR_USE_TRP_FOR_DEVELOPMENT = 0x8055161F; -constexpr int ORBIS_NP_TROPHY_ERROR_INVALID_NP_SERVICE_LABEL = 0x80551621; -constexpr int ORBIS_NP_TROPHY_ERROR_NOT_SUPPORTED = 0x80551622; -constexpr int ORBIS_NP_TROPHY_ERROR_CONTEXT_EXCEEDS_MAX = 0x80551623; -constexpr int ORBIS_NP_TROPHY_ERROR_HANDLE_EXCEEDS_MAX = 0x80551624; -constexpr int ORBIS_NP_TROPHY_ERROR_INVALID_USER_ID = 0x80551625; -constexpr int ORBIS_NP_TROPHY_ERROR_TITLE_CONF_NOT_INSTALLED = 0x80551626; -constexpr int ORBIS_NP_TROPHY_ERROR_BROKEN_TITLE_CONF = 0x80551627; -constexpr int ORBIS_NP_TROPHY_ERROR_INCONSISTENT_TITLE_CONF = 0x80551628; -constexpr int ORBIS_NP_TROPHY_ERROR_TITLE_BACKGROUND = 0x80551629; -constexpr int ORBIS_NP_TROPHY_ERROR_SCREENSHOT_DISABLED = 0x8055162B; -constexpr int ORBIS_NP_TROPHY_ERROR_SCREENSHOT_DISPLAY_BUFFER_NOT_IN_USE = 0x8055162D; - -// AvPlayer library -constexpr int ORBIS_AVPLAYER_ERROR_INVALID_PARAMS = 0x806A0001; -constexpr int ORBIS_AVPLAYER_ERROR_OPERATION_FAILED = 0x806A0002; -constexpr int ORBIS_AVPLAYER_ERROR_NO_MEMORY = 0x806A0003; -constexpr int ORBIS_AVPLAYER_ERROR_NOT_SUPPORTED = 0x806A0004; -constexpr int ORBIS_AVPLAYER_ERROR_WAR_FILE_NONINTERLEAVED = 0x806A00A0; -constexpr int ORBIS_AVPLAYER_ERROR_WAR_LOOPING_BACK = 0x806A00A1; -constexpr int ORBIS_AVPLAYER_ERROR_WAR_JUMP_COMPLETE = 0x806A00A3; -constexpr int ORBIS_AVPLAYER_ERROR_INFO_MARLIN_ENCRY = 0x806A00B0; -constexpr int ORBIS_AVPLAYER_ERROR_INFO_PLAYREADY_ENCRY = 0x806A00B4; -constexpr int ORBIS_AVPLAYER_ERROR_INFO_AES_ENCRY = 0x806A00B5; -constexpr int ORBIS_AVPLAYER_ERROR_INFO_OTHER_ENCRY = 0x806A00BF; - -// AppContent library -constexpr int ORBIS_APP_CONTENT_ERROR_PARAMETER = 0x80D90002; -constexpr int ORBIS_APP_CONTENT_ERROR_DRM_NO_ENTITLEMENT = 0x80D90007; -constexpr int ORBIS_APP_CONTENT_ERROR_NOT_FOUND = 0x80D90005; - -// Fiber library -constexpr int ORBIS_FIBER_ERROR_NULL = 0x80590001; -constexpr int ORBIS_FIBER_ERROR_ALIGNMENT = 0x80590002; -constexpr int ORBIS_FIBER_ERROR_RANGE = 0x80590003; -constexpr int ORBIS_FIBER_ERROR_INVALID = 0x80590004; -constexpr int ORBIS_FIBER_ERROR_PERMISSION = 0x80590005; -constexpr int ORBIS_FIBER_ERROR_STATE = 0x80590006; - -// ImeDialog library -constexpr int ORBIS_ERROR_DIALOG_ERROR_NOT_INITIALIZED = 0x80ED0001; -constexpr int ORBIS_ERROR_DIALOG_ERROR_ALREADY_INITIALIZED = 0x80ED0002; -constexpr int ORBIS_ERROR_DIALOG_ERROR_PARAM_INVALID = 0x80ED0003; -constexpr int ORBIS_ERROR_DIALOG_ERROR_UNEXPECTED_FATAL = 0x80ED0004; -constexpr int ORBIS_ERROR_DIALOG_ERROR_INVALID_STATE = 0x80ED0005; -constexpr int ORBIS_ERROR_DIALOG_ERROR_SERVICE_BUSY = 0x80ED0006; -constexpr int ORBIS_ERROR_DIALOG_ERROR_INVALID_USER_ID = 0x80ED0007; - -// Ime library -constexpr int ORBIS_IME_ERROR_BUSY = 0x80BC0001; -constexpr int ORBIS_IME_ERROR_NOT_OPENED = 0x80BC0002; -constexpr int ORBIS_IME_ERROR_NO_MEMORY = 0x80BC0003; -constexpr int ORBIS_IME_ERROR_CONNECTION_FAILED = 0x80BC0004; -constexpr int ORBIS_IME_ERROR_TOO_MANY_REQUESTS = 0x80BC0005; -constexpr int ORBIS_IME_ERROR_INVALID_TEXT = 0x80BC0006; -constexpr int ORBIS_IME_ERROR_EVENT_OVERFLOW = 0x80BC0007; -constexpr int ORBIS_IME_ERROR_NOT_ACTIVE = 0x80BC0008; -constexpr int ORBIS_IME_ERROR_IME_SUSPENDING = 0x80BC0009; -constexpr int ORBIS_IME_ERROR_DEVICE_IN_USE = 0x80BC000A; -constexpr int ORBIS_IME_ERROR_INVALID_USER_ID = 0x80BC0010; -constexpr int ORBIS_IME_ERROR_INVALID_TYPE = 0x80BC0011; -constexpr int ORBIS_IME_ERROR_INVALID_SUPPORTED_LANGUAGES = 0x80BC0012; -constexpr int ORBIS_IME_ERROR_INVALID_ENTER_LABEL = 0x80BC0013; -constexpr int ORBIS_IME_ERROR_INVALID_INPUT_METHOD = 0x80BC0014; -constexpr int ORBIS_IME_ERROR_INVALID_OPTION = 0x80BC0015; -constexpr int ORBIS_IME_ERROR_INVALID_MAX_TEXT_LENGTH = 0x80BC0016; -constexpr int ORBIS_IME_ERROR_INVALID_INPUT_TEXT_BUFFER = 0x80BC0017; -constexpr int ORBIS_IME_ERROR_INVALID_POSX = 0x80BC0018; -constexpr int ORBIS_IME_ERROR_INVALID_POSY = 0x80BC0019; -constexpr int ORBIS_IME_ERROR_INVALID_HORIZONTAL_ALIGNMENT = 0x80BC001A; -constexpr int ORBIS_IME_ERROR_INVALID_VERTICAL_ALIGNMENT = 0x80BC001B; -constexpr int ORBIS_IME_ERROR_INVALID_EXTENDED = 0x80BC001C; -constexpr int ORBIS_IME_ERROR_INVALID_KEYBOARD_TYPE = 0x80BC001D; -constexpr int ORBIS_IME_ERROR_INVALID_WORK = 0x80BC0020; -constexpr int ORBIS_IME_ERROR_INVALID_ARG = 0x80BC0021; -constexpr int ORBIS_IME_ERROR_INVALID_HANDLER = 0x80BC0022; -constexpr int ORBIS_IME_ERROR_NO_RESOURCE_ID = 0x80BC0023; -constexpr int ORBIS_IME_ERROR_INVALID_MODE = 0x80BC0024; -constexpr int ORBIS_IME_ERROR_INVALID_PARAM = 0x80BC0030; -constexpr int ORBIS_IME_ERROR_INVALID_ADDRESS = 0x80BC0031; -constexpr int ORBIS_IME_ERROR_INVALID_RESERVED = 0x80BC0032; -constexpr int ORBIS_IME_ERROR_INVALID_TIMING = 0x80BC0033; -constexpr int ORBIS_IME_ERROR_INTERNAL = 0x80BC00FF; - -// Videodec2 library -constexpr int ORBIS_VIDEODEC2_ERROR_API_FAIL = 0x811D0100; -constexpr int ORBIS_VIDEODEC2_ERROR_STRUCT_SIZE = 0x811D0101; -constexpr int ORBIS_VIDEODEC2_ERROR_ARGUMENT_POINTER = 0x811D0102; -constexpr int ORBIS_VIDEODEC2_ERROR_DECODER_INSTANCE = 0x811D0103; -constexpr int ORBIS_VIDEODEC2_ERROR_MEMORY_SIZE = 0x811D0104; -constexpr int ORBIS_VIDEODEC2_ERROR_MEMORY_POINTER = 0x811D0105; -constexpr int ORBIS_VIDEODEC2_ERROR_FRAME_BUFFER_SIZE = 0x811D0106; -constexpr int ORBIS_VIDEODEC2_ERROR_FRAME_BUFFER_POINTER = 0x811D0107; -constexpr int ORBIS_VIDEODEC2_ERROR_FRAME_BUFFER_ALIGNMENT = 0x811D0108; -constexpr int ORBIS_VIDEODEC2_ERROR_NOT_ONION_MEMORY = 0x811D0109; -constexpr int ORBIS_VIDEODEC2_ERROR_NOT_GARLIC_MEMORY = 0x811D010A; -constexpr int ORBIS_VIDEODEC2_ERROR_NOT_DIRECT_MEMORY = 0x811D010B; -constexpr int ORBIS_VIDEODEC2_ERROR_MEMORY_INFO = 0x811D010C; -constexpr int ORBIS_VIDEODEC2_ERROR_ACCESS_UNIT_SIZE = 0x811D010D; -constexpr int ORBIS_VIDEODEC2_ERROR_ACCESS_UNIT_POINTER = 0x811D010E; -constexpr int ORBIS_VIDEODEC2_ERROR_OUTPUT_INFO = 0x811D010F; -constexpr int ORBIS_VIDEODEC2_ERROR_COMPUTE_QUEUE = 0x811D0110; -constexpr int ORBIS_VIDEODEC2_ERROR_FATAL_STATE = 0x811D0111; -constexpr int ORBIS_VIDEODEC2_ERROR_PRESET_VALUE = 0x811D0112; -constexpr int ORBIS_VIDEODEC2_ERROR_CONFIG_INFO = 0x811D0200; -constexpr int ORBIS_VIDEODEC2_ERROR_COMPUTE_PIPE_ID = 0x811D0201; -constexpr int ORBIS_VIDEODEC2_ERROR_COMPUTE_QUEUE_ID = 0x811D0202; -constexpr int ORBIS_VIDEODEC2_ERROR_RESOURCE_TYPE = 0x811D0203; -constexpr int ORBIS_VIDEODEC2_ERROR_CODEC_TYPE = 0x811D0204; -constexpr int ORBIS_VIDEODEC2_ERROR_PROFILE_LEVEL = 0x811D0205; -constexpr int ORBIS_VIDEODEC2_ERROR_PIPELINE_DEPTH = 0x811D0206; -constexpr int ORBIS_VIDEODEC2_ERROR_AFFINITY_MASK = 0x811D0207; -constexpr int ORBIS_VIDEODEC2_ERROR_THREAD_PRIORITY = 0x811D0208; -constexpr int ORBIS_VIDEODEC2_ERROR_DPB_FRAME_COUNT = 0x811D0209; -constexpr int ORBIS_VIDEODEC2_ERROR_FRAME_WIDTH_HEIGHT = 0x811D020A; -constexpr int ORBIS_VIDEODEC2_ERROR_EXTRA_CONFIG_INFO = 0x811D020B; -constexpr int ORBIS_VIDEODEC2_ERROR_NEW_SEQUENCE = 0x811D0300; -constexpr int ORBIS_VIDEODEC2_ERROR_ACCESS_UNIT = 0x811D0301; -constexpr int ORBIS_VIDEODEC2_ERROR_OVERSIZE_DECODE = 0x811D0302; -constexpr int ORBIS_VIDEODEC2_ERROR_INVALID_SEQUENCE = 0x811D0303; -constexpr int ORBIS_VIDEODEC2_ERROR_FATAL_STREAM = 0x811D0304; - -// Videodec library -constexpr int ORBIS_VIDEODEC_ERROR_API_FAIL = 0x80C10000; -constexpr int ORBIS_VIDEODEC_ERROR_CODEC_TYPE = 0x80C10001; -constexpr int ORBIS_VIDEODEC_ERROR_STRUCT_SIZE = 0x80C10002; -constexpr int ORBIS_VIDEODEC_ERROR_HANDLE = 0x80C10003; -constexpr int ORBIS_VIDEODEC_ERROR_CPU_MEMORY_SIZE = 0x80C10004; -constexpr int ORBIS_VIDEODEC_ERROR_CPU_MEMORY_POINTER = 0x80C10005; -constexpr int ORBIS_VIDEODEC_ERROR_CPU_GPU_MEMORY_SIZE = 0x80C10006; -constexpr int ORBIS_VIDEODEC_ERROR_CPU_GPU_MEMORY_POINTER = 0x80C10007; -constexpr int ORBIS_VIDEODEC_ERROR_SHADER_CONTEXT_POINTER = 0x80C10008; -constexpr int ORBIS_VIDEODEC_ERROR_AU_SIZE = 0x80C10009; -constexpr int ORBIS_VIDEODEC_ERROR_AU_POINTER = 0x80C1000A; -constexpr int ORBIS_VIDEODEC_ERROR_FRAME_BUFFER_SIZE = 0x80C1000B; -constexpr int ORBIS_VIDEODEC_ERROR_FRAME_BUFFER_POINTER = 0x80C1000C; -constexpr int ORBIS_VIDEODEC_ERROR_FRAME_BUFFER_ALIGNMENT = 0x80C1000D; -constexpr int ORBIS_VIDEODEC_ERROR_CONFIG_INFO = 0x80C1000E; -constexpr int ORBIS_VIDEODEC_ERROR_ARGUMENT_POINTER = 0x80C1000F; -constexpr int ORBIS_VIDEODEC_ERROR_NEW_SEQUENCE = 0x80C10010; -constexpr int ORBIS_VIDEODEC_ERROR_DECODE_AU = 0x80C10011; -constexpr int ORBIS_VIDEODEC_ERROR_MISMATCH_SPEC = 0x80C10012; -constexpr int ORBIS_VIDEODEC_ERROR_INVALID_SEQUENCE = 0x80C10013; -constexpr int ORBIS_VIDEODEC_ERROR_FATAL_STREAM = 0x80C10014; -constexpr int ORBIS_VIDEODEC_ERROR_FATAL_STATE = 0x80C10015; - -// PngDec library -constexpr int ORBIS_PNG_DEC_ERROR_INVALID_ADDR = 0x80690001; -constexpr int ORBIS_PNG_DEC_ERROR_INVALID_SIZE = 0x80690002; -constexpr int ORBIS_PNG_DEC_ERROR_INVALID_PARAM = 0x80690003; -constexpr int ORBIS_PNG_DEC_ERROR_INVALID_HANDLE = 0x80690004; -constexpr int ORBIS_PNG_DEC_ERROR_INVALID_WORK_MEMORY = 0x80690005; -constexpr int ORBIS_PNG_DEC_ERROR_INVALID_DATA = 0x80690010; -constexpr int ORBIS_PNG_DEC_ERROR_UNSUPPORT_DATA = 0x80690011; -constexpr int ORBIS_PNG_DEC_ERROR_DECODE_ERROR = 0x80690012; -constexpr int ORBIS_PNG_DEC_ERROR_FATAL = 0x80690020; \ No newline at end of file diff --git a/src/core/libraries/fiber/fiber.cpp b/src/core/libraries/fiber/fiber.cpp index 92bf894b5..c28d8d734 100644 --- a/src/core/libraries/fiber/fiber.cpp +++ b/src/core/libraries/fiber/fiber.cpp @@ -4,7 +4,7 @@ #include "fiber.h" #include "common/logging/log.h" -#include "core/libraries/error_codes.h" +#include "core/libraries/fiber/fiber_error.h" #include "core/libraries/libs.h" #include "core/tls.h" diff --git a/src/core/libraries/fiber/fiber.h b/src/core/libraries/fiber/fiber.h index 930409caa..00099f93b 100644 --- a/src/core/libraries/fiber/fiber.h +++ b/src/core/libraries/fiber/fiber.h @@ -26,17 +26,12 @@ struct SceFiber { u64 signature; FiberState state; SceFiberEntry entry; - u64 argOnInitialize; - u64 argRun; u64* pArgRun; - u64 argReturn; u64* pArgReturn; - u64 sizeContext; - char name[ORBIS_FIBER_MAX_NAME_LENGTH]; void* handle; }; @@ -53,7 +48,7 @@ struct SceFiberInfo { }; static_assert(sizeof(SceFiberInfo) <= 128); -typedef void* SceFiberOptParam; +using SceFiberOptParam = void*; s32 PS4_SYSV_ABI sceFiberInitialize(SceFiber* fiber, const char* name, SceFiberEntry entry, u64 argOnInitialize, void* addrContext, u64 sizeContext, diff --git a/src/core/libraries/fiber/fiber_error.h b/src/core/libraries/fiber/fiber_error.h new file mode 100644 index 000000000..c89fe30b1 --- /dev/null +++ b/src/core/libraries/fiber/fiber_error.h @@ -0,0 +1,14 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/libraries/error_codes.h" + +// Fiber library +constexpr int ORBIS_FIBER_ERROR_NULL = 0x80590001; +constexpr int ORBIS_FIBER_ERROR_ALIGNMENT = 0x80590002; +constexpr int ORBIS_FIBER_ERROR_RANGE = 0x80590003; +constexpr int ORBIS_FIBER_ERROR_INVALID = 0x80590004; +constexpr int ORBIS_FIBER_ERROR_PERMISSION = 0x80590005; +constexpr int ORBIS_FIBER_ERROR_STATE = 0x80590006; diff --git a/src/core/libraries/gnmdriver/gnm_error.h b/src/core/libraries/gnmdriver/gnm_error.h index eab684a24..b8e57f6f5 100644 --- a/src/core/libraries/gnmdriver/gnm_error.h +++ b/src/core/libraries/gnmdriver/gnm_error.h @@ -3,6 +3,8 @@ #pragma once +#include "core/libraries/error_codes.h" + constexpr int ORBIS_GNM_ERROR_SUBMISSION_FAILED_INVALID_ARGUMENT = 0x80D11000; constexpr int ORBIS_GNM_ERROR_SUBMISSION_NOT_ENOUGH_RESOURCES = 0x80D11001; constexpr int ORBIS_GNM_ERROR_SUBMISSION_AND_FLIP_FAILED_INVALID_COMMAND_BUFFER = 0x80D11080; diff --git a/src/core/libraries/gnmdriver/gnmdriver.cpp b/src/core/libraries/gnmdriver/gnmdriver.cpp index 70cf09a97..10d121afe 100644 --- a/src/core/libraries/gnmdriver/gnmdriver.cpp +++ b/src/core/libraries/gnmdriver/gnmdriver.cpp @@ -11,7 +11,8 @@ #include "common/slot_vector.h" #include "core/address_space.h" #include "core/debug_state.h" -#include "core/libraries/error_codes.h" +#include "core/libraries/gnmdriver/gnm_error.h" +#include "core/libraries/kernel/orbis_error.h" #include "core/libraries/kernel/process.h" #include "core/libraries/libs.h" #include "core/libraries/videoout/video_out.h" diff --git a/src/core/libraries/ime/ime.cpp b/src/core/libraries/ime/ime.cpp index efb988c72..700585ff3 100644 --- a/src/core/libraries/ime/ime.cpp +++ b/src/core/libraries/ime/ime.cpp @@ -2,14 +2,12 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include -#include "ime.h" -#include "ime_ui.h" - #include "common/logging/log.h" -#include "common/singleton.h" -#include "core/libraries/error_codes.h" +#include "core/libraries/ime/ime.h" +#include "core/libraries/ime/ime_error.h" +#include "core/libraries/ime/ime_ui.h" #include "core/libraries/libs.h" -#include "core/linker.h" +#include "core/tls.h" namespace Libraries::Ime { @@ -37,7 +35,7 @@ public: // Open an event to let the game know the IME has started OrbisImeEvent openEvent{}; - openEvent.id = (ime_mode ? OrbisImeEventId::OPEN : OrbisImeEventId::KEYBOARD_OPEN); + openEvent.id = (ime_mode ? OrbisImeEventId::Open : OrbisImeEventId::KeyboardOpen); if (ime_mode) { sceImeGetPanelSize(&m_param.ime, &openEvent.param.rect.width, @@ -45,8 +43,8 @@ public: openEvent.param.rect.x = m_param.ime.posx; openEvent.param.rect.y = m_param.ime.posy; } else { - openEvent.param.resourceIdArray.userId = 1; - openEvent.param.resourceIdArray.resourceId[0] = 1; + openEvent.param.resource_id_array.userId = 1; + openEvent.param.resource_id_array.resource_id[0] = 1; } Execute(nullptr, &openEvent, true); @@ -215,15 +213,15 @@ s32 PS4_SYSV_ABI sceImeGetPanelSize(const OrbisImeParam* param, u32* width, u32* } switch (param->type) { - case OrbisImeType::DEFAULT: - case OrbisImeType::BASIC_LATIN: - case OrbisImeType::URL: - case OrbisImeType::MAIL: + case OrbisImeType::Default: + case OrbisImeType::BasicLatin: + case OrbisImeType::Url: + case OrbisImeType::Mail: // We set our custom sizes, commented sizes are the original ones *width = 500; // 793 *height = 100; // 408 break; - case OrbisImeType::NUMBER: + case OrbisImeType::Number: *width = 370; *height = 402; break; @@ -315,7 +313,7 @@ void PS4_SYSV_ABI sceImeParamInit(OrbisImeParam* param) { } memset(param, 0, sizeof(OrbisImeParam)); - param->userId = -1; + param->user_id = -1; } int PS4_SYSV_ABI sceImeSetCandidateIndex() { diff --git a/src/core/libraries/ime/ime.h b/src/core/libraries/ime/ime.h index fc98d426a..2915b70da 100644 --- a/src/core/libraries/ime/ime.h +++ b/src/core/libraries/ime/ime.h @@ -3,9 +3,9 @@ #pragma once +#include "common/enum.h" #include "common/types.h" - -#include "ime_common.h" +#include "core/libraries/ime/ime_common.h" namespace Core::Loader { class SymbolsResolver; @@ -16,13 +16,13 @@ namespace Libraries::Ime { constexpr u32 ORBIS_IME_MAX_TEXT_LENGTH = 2048; enum class OrbisImeKeyboardOption : u32 { - DEFAULT = 0, - REPEAT = 1, - REPEAT_EACH_KEY = 2, - ADD_OSK = 4, - EFFECTIVE_WITH_TIME = 8, - DISABLE_RESUME = 16, - DISABLE_CAPSLOCK_WITHOUT_SHIFT = 32, + Default = 0, + Repeat = 1, + RepeatEachKey = 2, + AddOsk = 4, + EffectiveWithTime = 8, + DisableResume = 16, + DisableCapslockWithoutShift = 32, }; DECLARE_ENUM_FLAG_OPERATORS(OrbisImeKeyboardOption) @@ -35,19 +35,19 @@ struct OrbisImeKeyboardParam { }; struct OrbisImeParam { - s32 userId; + s32 user_id; OrbisImeType type; - u64 supportedLanguages; - OrbisImeEnterLabel enterLabel; - OrbisImeInputMethod inputMethod; + u64 supported_languages; + OrbisImeEnterLabel enter_label; + OrbisImeInputMethod input_method; OrbisImeTextFilter filter; u32 option; - u32 maxTextLength; - char16_t* inputTextBuffer; + u32 max_text_length; + char16_t* input_text_buffer; float posx; float posy; - OrbisImeHorizontalAlignment horizontalAlignment; - OrbisImeVerticalAlignment verticalAlignment; + OrbisImeHorizontalAlignment horizontal_alignment; + OrbisImeVerticalAlignment vertical_alignment; void* work; void* arg; OrbisImeEventHandler handler; @@ -117,4 +117,5 @@ int PS4_SYSV_ABI sceImeVshUpdateContext(); int PS4_SYSV_ABI sceImeVshUpdateContext2(); void RegisterlibSceIme(Core::Loader::SymbolsResolver* sym); -} // namespace Libraries::Ime \ No newline at end of file + +} // namespace Libraries::Ime diff --git a/src/core/libraries/ime/ime_common.h b/src/core/libraries/ime/ime_common.h index 078a6469e..77f23d91d 100644 --- a/src/core/libraries/ime/ime_common.h +++ b/src/core/libraries/ime/ime_common.h @@ -2,65 +2,64 @@ // SPDX-License-Identifier: GPL-2.0-or-later #pragma once -#include -#include "common/enum.h" + #include "common/types.h" #include "core/libraries/rtc/rtc.h" enum class OrbisImeType : u32 { - DEFAULT = 0, - BASIC_LATIN = 1, - URL = 2, - MAIL = 3, - NUMBER = 4, + Default = 0, + BasicLatin = 1, + Url = 2, + Mail = 3, + Number = 4, }; enum class OrbisImeHorizontalAlignment : u32 { - LEFT = 0, - CENTER = 1, - RIGHT = 2, + Left = 0, + Center = 1, + Right = 2, }; enum class OrbisImeVerticalAlignment : u32 { - TOP = 0, - CENTER = 1, - BOTTOM = 2, + Top = 0, + Center = 1, + Bottom = 2, }; enum class OrbisImeEnterLabel : u32 { - DEFAULT = 0, - SEND = 1, - SEARCH = 2, - GO = 3, + Default = 0, + Send = 1, + Search = 2, + Go = 3, }; enum class OrbisImeInputMethod : u32 { - DEFAULT = 0, + Default = 0, }; enum class OrbisImeEventId : u32 { - OPEN = 0, - UPDATE_TEXT = 1, - UPDATE_CARET = 2, - PRESS_CLOSE = 4, - PRESS_ENTER = 5, - ABORT = 6, - CANDIDATE_LIST_START = 7, - CANDIDATE_LIST_END = 8, - CANDIDATE_WORD = 9, - CANDIDATE_INDEX = 10, - CANDIDATE_DONE = 11, - CANDIDATE_CANCEL = 12, - CHANGE_DEVICE = 14, - CHANGE_INPUT_METHOD_STATE = 18, + Open = 0, + UpdateText = 1, + UpdateCaret = 2, + PressClose = 4, + PressEnter = 5, + Abort = 6, + CandidateListStart = 7, + CandidateListEnd = 8, + CandidateWord = 9, + CandidateIndex = 10, + CandidateDone = 11, + CandidateCancel = 12, + ChangeDevice = 14, + ChangeInputMethodState = 18, - KEYBOARD_OPEN = 256, - KEYBOARD_KEYCODE_DOWN = 257, - KEYBOARD_KEYCODE_UP = 258, - KEYBOARD_KEYCODE_REPEAT = 259, - KEYBOARD_CONNECTION = 260, - KEYBOARD_DISCONNECTION = 261, - KEYBOARD_ABORT = 262, + KeyboardOpen = 256, + KeyboardKeycodeDoen = 257, + KeyboardKeycodeUp = 258, + KeyboardKeycodeRepeat = 259, + KeyboardConnection = 260, + KeyboardDisconnection = 261, + KeyboardAbort = 262, }; enum class OrbisImeKeyboardType : u32 { @@ -105,10 +104,10 @@ enum class OrbisImeKeyboardType : u32 { }; enum class OrbisImeDeviceType : u32 { - NONE = 0, - CONTROLLER = 1, - EXT_KEYBOARD = 2, - REMOTE_OSK = 3, + None = 0, + Controller = 1, + ExtKeyboard = 2, + RemoteOsk = 3, }; struct OrbisImeRect { @@ -126,9 +125,9 @@ struct OrbisImeTextAreaProperty { struct OrbisImeEditText { char16_t* str; - u32 caretIndex; - u32 areaNum; - OrbisImeTextAreaProperty textArea[4]; + u32 caret_index; + u32 area_num; + OrbisImeTextAreaProperty text_area[4]; }; struct OrbisImeKeycode { @@ -136,40 +135,40 @@ struct OrbisImeKeycode { char16_t character; u32 status; OrbisImeKeyboardType type; - s32 userId; - u32 resourceId; + s32 user_id; + u32 resource_id; Libraries::Rtc::OrbisRtcTick timestamp; }; struct OrbisImeKeyboardResourceIdArray { s32 userId; - u32 resourceId[6]; + u32 resource_id[6]; }; enum class OrbisImeCaretMovementDirection : u32 { - STILL = 0, - LEFT = 1, - RIGHT = 2, - UP = 3, - DOWN = 4, - HOME = 5, - END = 6, - PAGE_UP = 7, - PAGE_DOWN = 8, - TOP = 9, - BOTTOM = 10, + Still = 0, + Left = 1, + Right = 2, + Up = 3, + Down = 4, + Home = 5, + End = 6, + PageUp = 7, + PageDown = 8, + Top = 9, + Bottom = 10, }; union OrbisImeEventParam { OrbisImeRect rect; OrbisImeEditText text; - OrbisImeCaretMovementDirection caretMove; + OrbisImeCaretMovementDirection caret_move; OrbisImeKeycode keycode; - OrbisImeKeyboardResourceIdArray resourceIdArray; - char16_t* candidateWord; - s32 candidateIndex; - OrbisImeDeviceType deviceType; - u32 inputMethodState; + OrbisImeKeyboardResourceIdArray resource_id_array; + char16_t* candidate_word; + s32 candidate_index; + OrbisImeDeviceType device_type; + u32 input_method_state; s8 reserved[64]; }; @@ -178,7 +177,7 @@ struct OrbisImeEvent { OrbisImeEventParam param; }; -typedef PS4_SYSV_ABI int (*OrbisImeTextFilter)(char16_t* outText, u32* outTextLength, - const char16_t* srcText, u32 srcTextLength); +using OrbisImeTextFilter = PS4_SYSV_ABI int (*)(char16_t* outText, u32* outTextLength, + const char16_t* srcText, u32 srcTextLength); -typedef PS4_SYSV_ABI void (*OrbisImeEventHandler)(void* arg, const OrbisImeEvent* e); +using OrbisImeEventHandler = PS4_SYSV_ABI void (*)(void* arg, const OrbisImeEvent* e); diff --git a/src/core/libraries/ime/ime_dialog.cpp b/src/core/libraries/ime/ime_dialog.cpp index 63b52706a..d6d027885 100644 --- a/src/core/libraries/ime/ime_dialog.cpp +++ b/src/core/libraries/ime/ime_dialog.cpp @@ -14,24 +14,24 @@ static constexpr std::array MAX_Y_POSITIONS = {2160.0f, 1080.0f}; namespace Libraries::ImeDialog { -static OrbisImeDialogStatus g_ime_dlg_status = OrbisImeDialogStatus::NONE; +static OrbisImeDialogStatus g_ime_dlg_status = OrbisImeDialogStatus::None; static OrbisImeDialogResult g_ime_dlg_result{}; static ImeDialogState g_ime_dlg_state{}; static ImeDialogUi g_ime_dlg_ui; static bool IsValidOption(OrbisImeDialogOption option, OrbisImeType type) { if (False(~option & - (OrbisImeDialogOption::MULTILINE | OrbisImeDialogOption::NO_AUTO_COMPLETION))) { + (OrbisImeDialogOption::Multiline | OrbisImeDialogOption::NoAutoCompletion))) { return false; } - if (True(option & OrbisImeDialogOption::MULTILINE) && type != OrbisImeType::DEFAULT && - type != OrbisImeType::BASIC_LATIN) { + if (True(option & OrbisImeDialogOption::Multiline) && type != OrbisImeType::Default && + type != OrbisImeType::BasicLatin) { return false; } - if (True(option & OrbisImeDialogOption::NO_AUTO_COMPLETION) && type != OrbisImeType::NUMBER && - type != OrbisImeType::BASIC_LATIN) { + if (True(option & OrbisImeDialogOption::NoAutoCompletion) && type != OrbisImeType::Number && + type != OrbisImeType::BasicLatin) { return false; } @@ -39,29 +39,29 @@ static bool IsValidOption(OrbisImeDialogOption option, OrbisImeType type) { } Error PS4_SYSV_ABI sceImeDialogAbort() { - if (g_ime_dlg_status == OrbisImeDialogStatus::NONE) { + if (g_ime_dlg_status == OrbisImeDialogStatus::None) { LOG_INFO(Lib_ImeDialog, "IME dialog not in use"); return Error::DIALOG_NOT_IN_USE; } - if (g_ime_dlg_status != OrbisImeDialogStatus::RUNNING) { + if (g_ime_dlg_status != OrbisImeDialogStatus::Running) { LOG_INFO(Lib_ImeDialog, "IME dialog not running"); return Error::DIALOG_NOT_RUNNING; } - g_ime_dlg_status = OrbisImeDialogStatus::FINISHED; - g_ime_dlg_result.endstatus = OrbisImeDialogEndStatus::ABORTED; + g_ime_dlg_status = OrbisImeDialogStatus::Finished; + g_ime_dlg_result.endstatus = OrbisImeDialogEndStatus::Aborted; return Error::OK; } Error PS4_SYSV_ABI sceImeDialogForceClose() { - if (g_ime_dlg_status == OrbisImeDialogStatus::NONE) { + if (g_ime_dlg_status == OrbisImeDialogStatus::None) { LOG_INFO(Lib_ImeDialog, "IME dialog not in use"); return Error::DIALOG_NOT_IN_USE; } - g_ime_dlg_status = OrbisImeDialogStatus::NONE; + g_ime_dlg_status = OrbisImeDialogStatus::None; g_ime_dlg_ui = ImeDialogUi(); g_ime_dlg_state = ImeDialogState(); @@ -93,7 +93,7 @@ int PS4_SYSV_ABI sceImeDialogGetPanelSizeExtended() { } Error PS4_SYSV_ABI sceImeDialogGetResult(OrbisImeDialogResult* result) { - if (g_ime_dlg_status == OrbisImeDialogStatus::NONE) { + if (g_ime_dlg_status == OrbisImeDialogStatus::None) { LOG_INFO(Lib_ImeDialog, "IME dialog is not running"); return Error::DIALOG_NOT_IN_USE; } @@ -105,7 +105,7 @@ Error PS4_SYSV_ABI sceImeDialogGetResult(OrbisImeDialogResult* result) { result->endstatus = g_ime_dlg_result.endstatus; - if (g_ime_dlg_status == OrbisImeDialogStatus::RUNNING) { + if (g_ime_dlg_status == OrbisImeDialogStatus::Running) { return Error::DIALOG_NOT_FINISHED; } @@ -114,7 +114,7 @@ Error PS4_SYSV_ABI sceImeDialogGetResult(OrbisImeDialogResult* result) { } OrbisImeDialogStatus PS4_SYSV_ABI sceImeDialogGetStatus() { - if (g_ime_dlg_status == OrbisImeDialogStatus::RUNNING) { + if (g_ime_dlg_status == OrbisImeDialogStatus::Running) { g_ime_dlg_state.CallTextFilter(); } @@ -122,7 +122,7 @@ OrbisImeDialogStatus PS4_SYSV_ABI sceImeDialogGetStatus() { } Error PS4_SYSV_ABI sceImeDialogInit(OrbisImeDialogParam* param, OrbisImeParamExtended* extended) { - if (g_ime_dlg_status != OrbisImeDialogStatus::NONE) { + if (g_ime_dlg_status != OrbisImeDialogStatus::None) { LOG_INFO(Lib_ImeDialog, "IME dialog is already running"); return Error::BUSY; } @@ -142,24 +142,24 @@ Error PS4_SYSV_ABI sceImeDialogInit(OrbisImeDialogParam* param, OrbisImeParamExt if (param->posx < 0.0f || param->posx >= - MAX_X_POSITIONS[False(param->option & OrbisImeDialogOption::LARGE_RESOLUTION)]) { + MAX_X_POSITIONS[False(param->option & OrbisImeDialogOption::LargeResolution)]) { LOG_INFO(Lib_ImeDialog, "Invalid param->posx"); return Error::INVALID_POSX; } if (param->posy < 0.0f || param->posy >= - MAX_Y_POSITIONS[False(param->option & OrbisImeDialogOption::LARGE_RESOLUTION)]) { + MAX_Y_POSITIONS[False(param->option & OrbisImeDialogOption::LargeResolution)]) { LOG_INFO(Lib_ImeDialog, "Invalid param->posy"); return Error::INVALID_POSY; } - if (!magic_enum::enum_contains(param->horizontalAlignment)) { + if (!magic_enum::enum_contains(param->horizontal_alignment)) { LOG_INFO(Lib_ImeDialog, "Invalid param->horizontalAlignment"); return Error::INVALID_HORIZONTALIGNMENT; } - if (!magic_enum::enum_contains(param->verticalAlignment)) { + if (!magic_enum::enum_contains(param->vertical_alignment)) { LOG_INFO(Lib_ImeDialog, "Invalid param->verticalAlignment"); return Error::INVALID_VERTICALALIGNMENT; } @@ -169,7 +169,7 @@ Error PS4_SYSV_ABI sceImeDialogInit(OrbisImeDialogParam* param, OrbisImeParamExt return Error::INVALID_PARAM; } - if (param->inputTextBuffer == nullptr) { + if (param->input_text_buffer == nullptr) { LOG_INFO(Lib_ImeDialog, "Invalid param->inputTextBuffer"); return Error::INVALID_INPUT_TEXT_BUFFER; } @@ -182,25 +182,25 @@ Error PS4_SYSV_ABI sceImeDialogInit(OrbisImeDialogParam* param, OrbisImeParamExt // TODO: do correct extended->option validation - if ((extended->extKeyboardMode & 0xe3fffffc) != 0) { + if ((extended->ext_keyboard_mode & 0xe3fffffc) != 0) { LOG_INFO(Lib_ImeDialog, "Invalid extended->extKeyboardMode"); return Error::INVALID_EXTENDED; } - if (extended->disableDevice > 7) { + if (extended->disable_device > 7) { LOG_INFO(Lib_ImeDialog, "Invalid extended->disableDevice"); return Error::INVALID_EXTENDED; } } - if (param->maxTextLength > ORBIS_IME_DIALOG_MAX_TEXT_LENGTH) { + if (param->max_text_length > ORBIS_IME_DIALOG_MAX_TEXT_LENGTH) { LOG_INFO(Lib_ImeDialog, "Invalid param->maxTextLength"); return Error::INVALID_MAX_TEXT_LENGTH; } g_ime_dlg_result = {}; g_ime_dlg_state = ImeDialogState(param, extended); - g_ime_dlg_status = OrbisImeDialogStatus::RUNNING; + g_ime_dlg_status = OrbisImeDialogStatus::Running; g_ime_dlg_ui = ImeDialogUi(&g_ime_dlg_state, &g_ime_dlg_status, &g_ime_dlg_result); return Error::OK; @@ -227,17 +227,17 @@ int PS4_SYSV_ABI sceImeDialogSetPanelPosition() { } Error PS4_SYSV_ABI sceImeDialogTerm() { - if (g_ime_dlg_status == OrbisImeDialogStatus::NONE) { + if (g_ime_dlg_status == OrbisImeDialogStatus::None) { LOG_INFO(Lib_ImeDialog, "IME dialog not in use"); return Error::DIALOG_NOT_IN_USE; } - if (g_ime_dlg_status == OrbisImeDialogStatus::RUNNING) { + if (g_ime_dlg_status == OrbisImeDialogStatus::Running) { LOG_INFO(Lib_ImeDialog, "IME dialog is still running"); return Error::DIALOG_NOT_FINISHED; } - g_ime_dlg_status = OrbisImeDialogStatus::NONE; + g_ime_dlg_status = OrbisImeDialogStatus::None; g_ime_dlg_ui = ImeDialogUi(); g_ime_dlg_state = ImeDialogState(); @@ -274,4 +274,4 @@ void RegisterlibSceImeDialog(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("gyTyVn+bXMw", "libSceImeDialog", 1, "libSceImeDialog", 1, 1, sceImeDialogTerm); }; -} // namespace Libraries::ImeDialog \ No newline at end of file +} // namespace Libraries::ImeDialog diff --git a/src/core/libraries/ime/ime_dialog.h b/src/core/libraries/ime/ime_dialog.h index e99d29613..c8b228498 100644 --- a/src/core/libraries/ime/ime_dialog.h +++ b/src/core/libraries/ime/ime_dialog.h @@ -58,32 +58,32 @@ enum class Error : u32 { }; enum class OrbisImeDialogStatus : u32 { - NONE = 0, - RUNNING = 1, - FINISHED = 2, + None = 0, + Running = 1, + Finished = 2, }; enum class OrbisImeDialogEndStatus : u32 { - OK = 0, - USER_CANCELED = 1, - ABORTED = 2, + Ok = 0, + UserCanceled = 1, + Aborted = 2, }; enum class OrbisImeDialogOption : u32 { - DEFAULT = 0, - MULTILINE = 1, - NO_AUTO_CORRECTION = 2, - NO_AUTO_COMPLETION = 4, + Default = 0, + Multiline = 1, + NoAutoCorrection = 2, + NoAutoCompletion = 4, // TODO: Document missing options - LARGE_RESOLUTION = 1024, + LargeResolution = 1024, }; DECLARE_ENUM_FLAG_OPERATORS(OrbisImeDialogOption) enum class OrbisImePanelPriority : u32 { - DEFAULT = 0, - ALPHABET = 1, - SYMBOL = 2, - ACCENT = 3, + Default = 0, + Alphabet = 1, + Symbol = 2, + Accent = 3, }; struct OrbisImeColor { @@ -103,29 +103,29 @@ struct OrbisImeKeycode { char16_t character; u32 status; OrbisImeKeyboardType type; - s32 userId; - u32 resourceId; + s32 user_id; + u32 resource_id; u64 timestamp; }; -typedef PS4_SYSV_ABI int (*OrbisImeExtKeyboardFilter)(const OrbisImeKeycode* srcKeycode, - u16* outKeycode, u32* outStatus, - void* reserved); +using OrbisImeExtKeyboardFilter = PS4_SYSV_ABI int (*)(const OrbisImeKeycode* srcKeycode, + u16* outKeycode, u32* outStatus, + void* reserved); struct OrbisImeDialogParam { - s32 userId; + s32 user_id; OrbisImeType type; - u64 supportedLanguages; - OrbisImeEnterLabel enterLabel; - OrbisImeInputMethod inputMethod; + u64 supported_languages; + OrbisImeEnterLabel enter_label; + OrbisImeInputMethod input_method; OrbisImeTextFilter filter; OrbisImeDialogOption option; - u32 maxTextLength; - char16_t* inputTextBuffer; + u32 max_text_length; + char16_t* input_text_buffer; float posx; float posy; - OrbisImeHorizontalAlignment horizontalAlignment; - OrbisImeVerticalAlignment verticalAlignment; + OrbisImeHorizontalAlignment horizontal_alignment; + OrbisImeVerticalAlignment vertical_alignment; const char16_t* placeholder; const char16_t* title; s8 reserved[16]; @@ -133,20 +133,20 @@ struct OrbisImeDialogParam { struct OrbisImeParamExtended { u32 option; // OrbisImeDialogOptionExtended - OrbisImeColor colorBase; - OrbisImeColor colorLine; - OrbisImeColor colorTextField; - OrbisImeColor colorPreedit; - OrbisImeColor colorButtonDefault; - OrbisImeColor colorButtonFunction; - OrbisImeColor colorButtonSymbol; - OrbisImeColor colorText; - OrbisImeColor colorSpecial; + OrbisImeColor color_base; + OrbisImeColor color_line; + OrbisImeColor color_text_field; + OrbisImeColor color_preedit; + OrbisImeColor color_button_default; + OrbisImeColor color_button_function; + OrbisImeColor color_button_symbol; + OrbisImeColor color_text; + OrbisImeColor color_special; OrbisImePanelPriority priority; - char* additionalDictionaryPath; - OrbisImeExtKeyboardFilter extKeyboardFilter; - uint32_t disableDevice; - uint32_t extKeyboardMode; + char* additional_dictionary_path; + OrbisImeExtKeyboardFilter ext_keyboard_filter; + uint32_t disable_device; + uint32_t ext_keyboard_mode; int8_t reserved[60]; }; @@ -167,4 +167,4 @@ int PS4_SYSV_ABI sceImeDialogSetPanelPosition(); Error PS4_SYSV_ABI sceImeDialogTerm(); void RegisterlibSceImeDialog(Core::Loader::SymbolsResolver* sym); -} // namespace Libraries::ImeDialog \ No newline at end of file +} // namespace Libraries::ImeDialog diff --git a/src/core/libraries/ime/ime_dialog_ui.cpp b/src/core/libraries/ime/ime_dialog_ui.cpp index de64de5fa..5957606eb 100644 --- a/src/core/libraries/ime/ime_dialog_ui.cpp +++ b/src/core/libraries/ime/ime_dialog_ui.cpp @@ -8,7 +8,6 @@ #include "common/assert.h" #include "common/logging/log.h" -#include "common/singleton.h" #include "core/libraries/ime/ime_dialog.h" #include "core/libraries/ime/ime_dialog_ui.h" #include "core/tls.h" @@ -26,15 +25,15 @@ ImeDialogState::ImeDialogState(const OrbisImeDialogParam* param, return; } - userId = param->userId; - is_multiLine = True(param->option & OrbisImeDialogOption::MULTILINE); - is_numeric = param->type == OrbisImeType::NUMBER; + user_id = param->user_id; + is_multi_line = True(param->option & OrbisImeDialogOption::Multiline); + is_numeric = param->type == OrbisImeType::Number; type = param->type; - enter_label = param->enterLabel; + enter_label = param->enter_label; text_filter = param->filter; - keyboard_filter = extended ? extended->extKeyboardFilter : nullptr; - max_text_length = param->maxTextLength; - text_buffer = param->inputTextBuffer; + keyboard_filter = extended ? extended->ext_keyboard_filter : nullptr; + max_text_length = param->max_text_length; + text_buffer = param->input_text_buffer; if (param->title) { std::size_t title_len = std::char_traits::length(param->title); @@ -65,12 +64,12 @@ ImeDialogState::ImeDialogState(const OrbisImeDialogParam* param, } ImeDialogState::ImeDialogState(ImeDialogState&& other) noexcept - : input_changed(other.input_changed), userId(other.userId), is_multiLine(other.is_multiLine), - is_numeric(other.is_numeric), type(other.type), enter_label(other.enter_label), - text_filter(other.text_filter), keyboard_filter(other.keyboard_filter), - max_text_length(other.max_text_length), text_buffer(other.text_buffer), - title(std::move(other.title)), placeholder(std::move(other.placeholder)), - current_text(other.current_text) { + : input_changed(other.input_changed), user_id(other.user_id), + is_multi_line(other.is_multi_line), is_numeric(other.is_numeric), type(other.type), + enter_label(other.enter_label), text_filter(other.text_filter), + keyboard_filter(other.keyboard_filter), max_text_length(other.max_text_length), + text_buffer(other.text_buffer), title(std::move(other.title)), + placeholder(std::move(other.placeholder)), current_text(other.current_text) { other.text_buffer = nullptr; } @@ -78,8 +77,8 @@ ImeDialogState::ImeDialogState(ImeDialogState&& other) noexcept ImeDialogState& ImeDialogState::operator=(ImeDialogState&& other) { if (this != &other) { input_changed = other.input_changed; - userId = other.userId; - is_multiLine = other.is_multiLine; + user_id = other.user_id; + is_multi_line = other.is_multi_line; is_numeric = other.is_numeric; type = other.type; enter_label = other.enter_label; @@ -171,7 +170,7 @@ ImeDialogUi::ImeDialogUi(ImeDialogState* state, OrbisImeDialogStatus* status, OrbisImeDialogResult* result) : state(state), status(status), result(result) { - if (state && *status == OrbisImeDialogStatus::RUNNING) { + if (state && *status == OrbisImeDialogStatus::Running) { AddLayer(this); } } @@ -191,7 +190,7 @@ ImeDialogUi::ImeDialogUi(ImeDialogUi&& other) noexcept other.status = nullptr; other.result = nullptr; - if (state && *status == OrbisImeDialogStatus::RUNNING) { + if (state && *status == OrbisImeDialogStatus::Running) { AddLayer(this); } } @@ -208,7 +207,7 @@ ImeDialogUi& ImeDialogUi::operator=(ImeDialogUi&& other) { other.status = nullptr; other.result = nullptr; - if (state && *status == OrbisImeDialogStatus::RUNNING) { + if (state && *status == OrbisImeDialogStatus::Running) { AddLayer(this); } @@ -226,7 +225,7 @@ void ImeDialogUi::Draw() { return; } - if (!status || *status != OrbisImeDialogStatus::RUNNING) { + if (!status || *status != OrbisImeDialogStatus::Running) { return; } @@ -235,7 +234,7 @@ void ImeDialogUi::Draw() { ImVec2 window_size; - if (state->is_multiLine) { + if (state->is_multi_line) { window_size = {500.0f, 300.0f}; } else { window_size = {500.0f, 150.0f}; @@ -259,7 +258,7 @@ void ImeDialogUi::Draw() { SetWindowFontScale(1.0f); } - if (state->is_multiLine) { + if (state->is_multi_line) { DrawMultiLineInputText(); } else { DrawInputText(); @@ -270,16 +269,16 @@ void ImeDialogUi::Draw() { const char* button_text; switch (state->enter_label) { - case OrbisImeEnterLabel::GO: + case OrbisImeEnterLabel::Go: button_text = "Go##ImeDialogOK"; break; - case OrbisImeEnterLabel::SEARCH: + case OrbisImeEnterLabel::Search: button_text = "Search##ImeDialogOK"; break; - case OrbisImeEnterLabel::SEND: + case OrbisImeEnterLabel::Send: button_text = "Send##ImeDialogOK"; break; - case OrbisImeEnterLabel::DEFAULT: + case OrbisImeEnterLabel::Default: default: button_text = "OK##ImeDialogOK"; break; @@ -292,16 +291,16 @@ void ImeDialogUi::Draw() { SetCursorPosX(button_start_pos); if (Button(button_text, BUTTON_SIZE) || - (!state->is_multiLine && IsKeyPressed(ImGuiKey_Enter))) { - *status = OrbisImeDialogStatus::FINISHED; - result->endstatus = OrbisImeDialogEndStatus::OK; + (!state->is_multi_line && IsKeyPressed(ImGuiKey_Enter))) { + *status = OrbisImeDialogStatus::Finished; + result->endstatus = OrbisImeDialogEndStatus::Ok; } SameLine(0.0f, button_spacing); if (Button("Cancel##ImeDialogCancel", BUTTON_SIZE)) { - *status = OrbisImeDialogStatus::FINISHED; - result->endstatus = OrbisImeDialogEndStatus::USER_CANCELED; + *status = OrbisImeDialogStatus::Finished; + result->endstatus = OrbisImeDialogEndStatus::UserCanceled; } } End(); @@ -362,9 +361,10 @@ int ImeDialogUi::InputTextCallback(ImGuiInputTextCallbackData* data) { .status = 1, // ??? 1 = key pressed, 0 = key released .type = OrbisImeKeyboardType::ENGLISH_US, // TODO set this to the correct value (maybe use // the current language?) - .userId = ui->state->userId, - .resourceId = 0, - .timestamp = 0}; + .user_id = ui->state->user_id, + .resource_id = 0, + .timestamp = 0, + }; if (!ui->state->ConvertUTF8ToOrbis(event_char, 4, &src_keycode.character, 1)) { LOG_ERROR(Lib_ImeDialog, "Failed to convert orbis char to utf8"); diff --git a/src/core/libraries/ime/ime_dialog_ui.h b/src/core/libraries/ime/ime_dialog_ui.h index a4cf6e9f7..10dff5eeb 100644 --- a/src/core/libraries/ime/ime_dialog_ui.h +++ b/src/core/libraries/ime/ime_dialog_ui.h @@ -20,8 +20,8 @@ class ImeDialogState final { bool input_changed = false; - s32 userId{}; - bool is_multiLine{}; + s32 user_id{}; + bool is_multi_line{}; bool is_numeric{}; OrbisImeType type{}; OrbisImeEnterLabel enter_label{}; diff --git a/src/core/libraries/ime/ime_error.h b/src/core/libraries/ime/ime_error.h new file mode 100644 index 000000000..77eeada39 --- /dev/null +++ b/src/core/libraries/ime/ime_error.h @@ -0,0 +1,51 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/libraries/error_codes.h" + +// ImeDialog library +constexpr int ORBIS_ERROR_DIALOG_ERROR_NOT_INITIALIZED = 0x80ED0001; +constexpr int ORBIS_ERROR_DIALOG_ERROR_ALREADY_INITIALIZED = 0x80ED0002; +constexpr int ORBIS_ERROR_DIALOG_ERROR_PARAM_INVALID = 0x80ED0003; +constexpr int ORBIS_ERROR_DIALOG_ERROR_UNEXPECTED_FATAL = 0x80ED0004; +constexpr int ORBIS_ERROR_DIALOG_ERROR_INVALID_STATE = 0x80ED0005; +constexpr int ORBIS_ERROR_DIALOG_ERROR_SERVICE_BUSY = 0x80ED0006; +constexpr int ORBIS_ERROR_DIALOG_ERROR_INVALID_USER_ID = 0x80ED0007; + +// Ime library +constexpr int ORBIS_IME_ERROR_BUSY = 0x80BC0001; +constexpr int ORBIS_IME_ERROR_NOT_OPENED = 0x80BC0002; +constexpr int ORBIS_IME_ERROR_NO_MEMORY = 0x80BC0003; +constexpr int ORBIS_IME_ERROR_CONNECTION_FAILED = 0x80BC0004; +constexpr int ORBIS_IME_ERROR_TOO_MANY_REQUESTS = 0x80BC0005; +constexpr int ORBIS_IME_ERROR_INVALID_TEXT = 0x80BC0006; +constexpr int ORBIS_IME_ERROR_EVENT_OVERFLOW = 0x80BC0007; +constexpr int ORBIS_IME_ERROR_NOT_ACTIVE = 0x80BC0008; +constexpr int ORBIS_IME_ERROR_IME_SUSPENDING = 0x80BC0009; +constexpr int ORBIS_IME_ERROR_DEVICE_IN_USE = 0x80BC000A; +constexpr int ORBIS_IME_ERROR_INVALID_USER_ID = 0x80BC0010; +constexpr int ORBIS_IME_ERROR_INVALID_TYPE = 0x80BC0011; +constexpr int ORBIS_IME_ERROR_INVALID_SUPPORTED_LANGUAGES = 0x80BC0012; +constexpr int ORBIS_IME_ERROR_INVALID_ENTER_LABEL = 0x80BC0013; +constexpr int ORBIS_IME_ERROR_INVALID_INPUT_METHOD = 0x80BC0014; +constexpr int ORBIS_IME_ERROR_INVALID_OPTION = 0x80BC0015; +constexpr int ORBIS_IME_ERROR_INVALID_MAX_TEXT_LENGTH = 0x80BC0016; +constexpr int ORBIS_IME_ERROR_INVALID_INPUT_TEXT_BUFFER = 0x80BC0017; +constexpr int ORBIS_IME_ERROR_INVALID_POSX = 0x80BC0018; +constexpr int ORBIS_IME_ERROR_INVALID_POSY = 0x80BC0019; +constexpr int ORBIS_IME_ERROR_INVALID_HORIZONTAL_ALIGNMENT = 0x80BC001A; +constexpr int ORBIS_IME_ERROR_INVALID_VERTICAL_ALIGNMENT = 0x80BC001B; +constexpr int ORBIS_IME_ERROR_INVALID_EXTENDED = 0x80BC001C; +constexpr int ORBIS_IME_ERROR_INVALID_KEYBOARD_TYPE = 0x80BC001D; +constexpr int ORBIS_IME_ERROR_INVALID_WORK = 0x80BC0020; +constexpr int ORBIS_IME_ERROR_INVALID_ARG = 0x80BC0021; +constexpr int ORBIS_IME_ERROR_INVALID_HANDLER = 0x80BC0022; +constexpr int ORBIS_IME_ERROR_NO_RESOURCE_ID = 0x80BC0023; +constexpr int ORBIS_IME_ERROR_INVALID_MODE = 0x80BC0024; +constexpr int ORBIS_IME_ERROR_INVALID_PARAM = 0x80BC0030; +constexpr int ORBIS_IME_ERROR_INVALID_ADDRESS = 0x80BC0031; +constexpr int ORBIS_IME_ERROR_INVALID_RESERVED = 0x80BC0032; +constexpr int ORBIS_IME_ERROR_INVALID_TIMING = 0x80BC0033; +constexpr int ORBIS_IME_ERROR_INTERNAL = 0x80BC00FF; diff --git a/src/core/libraries/ime/ime_ui.cpp b/src/core/libraries/ime/ime_ui.cpp index 09d361263..c5f41c5e8 100644 --- a/src/core/libraries/ime/ime_ui.cpp +++ b/src/core/libraries/ime/ime_ui.cpp @@ -16,7 +16,7 @@ ImeState::ImeState(const OrbisImeParam* param) { } work_buffer = param->work; - text_buffer = param->inputTextBuffer; + text_buffer = param->input_text_buffer; std::size_t text_len = std::char_traits::length(text_buffer); if (!ConvertOrbisToUTF8(text_buffer, text_len, current_text.begin(), @@ -52,13 +52,13 @@ void ImeState::SendEvent(OrbisImeEvent* event) { void ImeState::SendEnterEvent() { OrbisImeEvent enterEvent{}; - enterEvent.id = OrbisImeEventId::PRESS_ENTER; + enterEvent.id = OrbisImeEventId::PressEnter; SendEvent(&enterEvent); } void ImeState::SendCloseEvent() { OrbisImeEvent closeEvent{}; - closeEvent.id = OrbisImeEventId::PRESS_CLOSE; + closeEvent.id = OrbisImeEventId::PressClose; closeEvent.param.text.str = reinterpret_cast(work_buffer); SendEvent(&closeEvent); } @@ -180,7 +180,7 @@ void ImeUi::DrawInputText() { if (first_render) { SetKeyboardFocusHere(); } - if (InputTextEx("##ImeInput", nullptr, state->current_text.begin(), ime_param->maxTextLength, + if (InputTextEx("##ImeInput", nullptr, state->current_text.begin(), ime_param->max_text_length, input_size, ImGuiInputTextFlags_CallbackAlways, InputTextCallback, this)) { state->input_changed = true; } @@ -194,16 +194,16 @@ int ImeUi::InputTextCallback(ImGuiInputTextCallbackData* data) { if (lastCaretPos == -1) { lastCaretPos = data->CursorPos; } else if (data->CursorPos != lastCaretPos) { - OrbisImeCaretMovementDirection caretDirection = OrbisImeCaretMovementDirection::STILL; + OrbisImeCaretMovementDirection caretDirection = OrbisImeCaretMovementDirection::Still; if (data->CursorPos < lastCaretPos) { - caretDirection = OrbisImeCaretMovementDirection::LEFT; + caretDirection = OrbisImeCaretMovementDirection::Left; } else if (data->CursorPos > lastCaretPos) { - caretDirection = OrbisImeCaretMovementDirection::RIGHT; + caretDirection = OrbisImeCaretMovementDirection::Right; } OrbisImeEvent event{}; - event.id = OrbisImeEventId::UPDATE_CARET; - event.param.caretMove = caretDirection; + event.id = OrbisImeEventId::UpdateCaret; + event.param.caret_move = caretDirection; lastCaretPos = data->CursorPos; ui->state->SendEvent(&event); @@ -214,28 +214,28 @@ int ImeUi::InputTextCallback(ImGuiInputTextCallbackData* data) { if (currentText != lastText) { OrbisImeEditText eventParam{}; eventParam.str = reinterpret_cast(ui->ime_param->work); - eventParam.caretIndex = data->CursorPos; - eventParam.areaNum = 1; + eventParam.caret_index = data->CursorPos; + eventParam.area_num = 1; - eventParam.textArea[0].mode = 1; // Edit mode - eventParam.textArea[0].index = data->CursorPos; - eventParam.textArea[0].length = data->BufTextLen; + eventParam.text_area[0].mode = 1; // Edit mode + eventParam.text_area[0].index = data->CursorPos; + eventParam.text_area[0].length = data->BufTextLen; if (!ui->state->ConvertUTF8ToOrbis(data->Buf, data->BufTextLen, eventParam.str, - ui->ime_param->maxTextLength)) { + ui->ime_param->max_text_length)) { LOG_ERROR(Lib_ImeDialog, "Failed to convert Orbis char to UTF-8"); return 0; } if (!ui->state->ConvertUTF8ToOrbis(data->Buf, data->BufTextLen, - ui->ime_param->inputTextBuffer, - ui->ime_param->maxTextLength)) { + ui->ime_param->input_text_buffer, + ui->ime_param->max_text_length)) { LOG_ERROR(Lib_ImeDialog, "Failed to convert Orbis char to UTF-8"); return 0; } OrbisImeEvent event{}; - event.id = OrbisImeEventId::UPDATE_TEXT; + event.id = OrbisImeEventId::UpdateText; event.param.text = eventParam; lastText = currentText; @@ -249,4 +249,4 @@ void ImeUi::Free() { RemoveLayer(this); } -}; // namespace Libraries::Ime \ No newline at end of file +}; // namespace Libraries::Ime diff --git a/src/core/libraries/kernel/equeue.cpp b/src/core/libraries/kernel/equeue.cpp index d4f7eabaa..6543cc319 100644 --- a/src/core/libraries/kernel/equeue.cpp +++ b/src/core/libraries/kernel/equeue.cpp @@ -4,8 +4,8 @@ #include "common/assert.h" #include "common/debug.h" #include "common/logging/log.h" -#include "core/libraries/error_codes.h" #include "core/libraries/kernel/equeue.h" +#include "core/libraries/kernel/orbis_error.h" #include "core/libraries/libs.h" namespace Libraries::Kernel { @@ -77,9 +77,8 @@ bool EqueueInternal::TriggerEvent(u64 ident, s16 filter, void* trigger_data) { bool has_found = false; { std::scoped_lock lock{m_mutex}; - for (auto& event : m_events) { - if ((event.event.ident == ident) && (event.event.filter == filter)) { + if (event.event.ident == ident && event.event.filter == filter) { event.Trigger(trigger_data); has_found = true; } @@ -91,7 +90,6 @@ bool EqueueInternal::TriggerEvent(u64 ident, s16 filter, void* trigger_data) { int EqueueInternal::GetTriggeredEvents(SceKernelEvent* ev, int num) { int count = 0; - for (auto& event : m_events) { if (event.IsTriggered()) { if (event.event.flags & SceKernelEvent::Flags::Clear) { diff --git a/src/core/libraries/kernel/file_system.cpp b/src/core/libraries/kernel/file_system.cpp index d0ffa21ca..1b95e5270 100644 --- a/src/core/libraries/kernel/file_system.cpp +++ b/src/core/libraries/kernel/file_system.cpp @@ -6,8 +6,8 @@ #include "common/scope_exit.h" #include "common/singleton.h" #include "core/file_sys/fs.h" -#include "core/libraries/error_codes.h" #include "core/libraries/kernel/file_system.h" +#include "core/libraries/kernel/orbis_error.h" #include "core/libraries/libs.h" #include "kernel.h" @@ -128,12 +128,12 @@ int PS4_SYSV_ABI sceKernelClose(int d) { return ORBIS_KERNEL_ERROR_EPERM; } if (d == 2003) { // dev/urandom case - return SCE_OK; + return ORBIS_OK; } auto* h = Common::Singleton::Instance(); auto* file = h->GetFile(d); if (file == nullptr) { - return SCE_KERNEL_ERROR_EBADF; + return ORBIS_KERNEL_ERROR_EBADF; } if (!file->is_directory) { file->f.Close(); @@ -141,7 +141,7 @@ int PS4_SYSV_ABI sceKernelClose(int d) { file->is_opened = false; LOG_INFO(Kernel_Fs, "Closing {}", file->m_guest_name); h->DeleteHandle(d); - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI posix_close(int d) { @@ -166,7 +166,7 @@ size_t PS4_SYSV_ABI sceKernelWrite(int d, const void* buf, size_t nbytes) { auto* h = Common::Singleton::Instance(); auto* file = h->GetFile(d); if (file == nullptr) { - return SCE_KERNEL_ERROR_EBADF; + return ORBIS_KERNEL_ERROR_EBADF; } std::scoped_lock lk{file->m_mutex}; @@ -175,7 +175,7 @@ size_t PS4_SYSV_ABI sceKernelWrite(int d, const void* buf, size_t nbytes) { int PS4_SYSV_ABI sceKernelUnlink(const char* path) { if (path == nullptr) { - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } auto* h = Common::Singleton::Instance(); @@ -184,15 +184,15 @@ int PS4_SYSV_ABI sceKernelUnlink(const char* path) { bool ro = false; const auto host_path = mnt->GetHostPath(path, &ro); if (host_path.empty()) { - return SCE_KERNEL_ERROR_EACCES; + return ORBIS_KERNEL_ERROR_EACCES; } if (ro) { - return SCE_KERNEL_ERROR_EROFS; + return ORBIS_KERNEL_ERROR_EROFS; } if (std::filesystem::is_directory(host_path)) { - return SCE_KERNEL_ERROR_EPERM; + return ORBIS_KERNEL_ERROR_EPERM; } auto* file = h->GetFile(host_path); @@ -201,7 +201,7 @@ int PS4_SYSV_ABI sceKernelUnlink(const char* path) { } LOG_INFO(Kernel_Fs, "Unlinked {}", path); - return SCE_OK; + return ORBIS_OK; } size_t PS4_SYSV_ABI _readv(int d, const SceKernelIovec* iov, int iovcnt) { @@ -231,7 +231,7 @@ s64 PS4_SYSV_ABI sceKernelLseek(int d, s64 offset, int whence) { std::scoped_lock lk{file->m_mutex}; if (!file->f.Seek(offset, origin)) { LOG_CRITICAL(Kernel_Fs, "sceKernelLseek: failed to seek"); - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } return file->f.Tell(); } @@ -257,7 +257,7 @@ s64 PS4_SYSV_ABI sceKernelRead(int d, void* buf, size_t nbytes) { auto* h = Common::Singleton::Instance(); auto* file = h->GetFile(d); if (file == nullptr) { - return SCE_KERNEL_ERROR_EBADF; + return ORBIS_KERNEL_ERROR_EBADF; } std::scoped_lock lk{file->m_mutex}; @@ -277,7 +277,7 @@ int PS4_SYSV_ABI posix_read(int d, void* buf, size_t nbytes) { int PS4_SYSV_ABI sceKernelMkdir(const char* path, u16 mode) { LOG_INFO(Kernel_Fs, "path = {} mode = {}", path, mode); if (path == nullptr) { - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } auto* mnt = Common::Singleton::Instance(); @@ -285,21 +285,21 @@ int PS4_SYSV_ABI sceKernelMkdir(const char* path, u16 mode) { const auto dir_name = mnt->GetHostPath(path, &ro); if (std::filesystem::exists(dir_name)) { - return SCE_KERNEL_ERROR_EEXIST; + return ORBIS_KERNEL_ERROR_EEXIST; } if (ro) { - return SCE_KERNEL_ERROR_EROFS; + return ORBIS_KERNEL_ERROR_EROFS; } // CUSA02456: path = /aotl after sceSaveDataMount(mode = 1) std::error_code ec; if (dir_name.empty() || !std::filesystem::create_directory(dir_name, ec)) { - return SCE_KERNEL_ERROR_EIO; + return ORBIS_KERNEL_ERROR_EIO; } if (!std::filesystem::exists(dir_name)) { - return SCE_KERNEL_ERROR_ENOENT; + return ORBIS_KERNEL_ERROR_ENOENT; } return ORBIS_OK; } @@ -323,13 +323,13 @@ int PS4_SYSV_ABI sceKernelRmdir(const char* path) { if (dir_name.empty()) { LOG_ERROR(Kernel_Fs, "Failed to remove directory: {}, permission denied", fmt::UTF(dir_name.u8string())); - return SCE_KERNEL_ERROR_EACCES; + return ORBIS_KERNEL_ERROR_EACCES; } if (ro) { LOG_ERROR(Kernel_Fs, "Failed to remove directory: {}, directory is read only", fmt::UTF(dir_name.u8string())); - return SCE_KERNEL_ERROR_EROFS; + return ORBIS_KERNEL_ERROR_EROFS; } if (!std::filesystem::is_directory(dir_name)) { @@ -411,7 +411,7 @@ int PS4_SYSV_ABI sceKernelCheckReachability(const char* path) { auto* mnt = Common::Singleton::Instance(); const auto path_name = mnt->GetHostPath(path); if (!std::filesystem::exists(path_name)) { - return SCE_KERNEL_ERROR_ENOENT; + return ORBIS_KERNEL_ERROR_ENOENT; } return ORBIS_OK; } @@ -514,15 +514,15 @@ int PS4_SYSV_ABI sceKernelFtruncate(int fd, s64 length) { auto* file = h->GetFile(fd); if (file == nullptr) { - return SCE_KERNEL_ERROR_EBADF; + return ORBIS_KERNEL_ERROR_EBADF; } if (file->m_host_name.empty()) { - return SCE_KERNEL_ERROR_EACCES; + return ORBIS_KERNEL_ERROR_EACCES; } file->f.SetSize(length); - return SCE_OK; + return ORBIS_OK; } static int GetDents(int fd, char* buf, int nbytes, s64* basep) { @@ -605,11 +605,11 @@ s32 PS4_SYSV_ABI sceKernelRename(const char* from, const char* to) { return ORBIS_KERNEL_ERROR_ENOENT; } if (ro) { - return SCE_KERNEL_ERROR_EROFS; + return ORBIS_KERNEL_ERROR_EROFS; } const auto dst_path = mnt->GetHostPath(to, &ro); if (ro) { - return SCE_KERNEL_ERROR_EROFS; + return ORBIS_KERNEL_ERROR_EROFS; } const bool src_is_dir = std::filesystem::is_directory(src_path); const bool dst_is_dir = std::filesystem::is_directory(dst_path); diff --git a/src/core/libraries/kernel/file_system.h b/src/core/libraries/kernel/file_system.h index 0bc473ec0..dcbb3957d 100644 --- a/src/core/libraries/kernel/file_system.h +++ b/src/core/libraries/kernel/file_system.h @@ -37,8 +37,8 @@ struct OrbisKernelStat { u32 st_gen; s32 st_lspare; OrbisKernelTimespec st_birthtim; - unsigned int : (8 / 2) * (16 - static_cast(sizeof(OrbisKernelTimespec))); - unsigned int : (8 / 2) * (16 - static_cast(sizeof(OrbisKernelTimespec))); + u32 : (8 / 2) * (16 - static_cast(sizeof(OrbisKernelTimespec))); + u32 : (8 / 2) * (16 - static_cast(sizeof(OrbisKernelTimespec))); }; struct OrbisKernelDirent { diff --git a/src/core/libraries/kernel/kernel.cpp b/src/core/libraries/kernel/kernel.cpp index 512e77bc6..b310c7be9 100644 --- a/src/core/libraries/kernel/kernel.cpp +++ b/src/core/libraries/kernel/kernel.cpp @@ -2,36 +2,27 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include - #include #include "common/assert.h" #include "common/debug.h" #include "common/logging/log.h" #include "common/polyfill_thread.h" -#include "common/singleton.h" #include "common/thread.h" -#include "core/file_sys/fs.h" -#include "core/libraries/error_codes.h" #include "core/libraries/kernel/equeue.h" #include "core/libraries/kernel/file_system.h" #include "core/libraries/kernel/kernel.h" #include "core/libraries/kernel/memory.h" +#include "core/libraries/kernel/orbis_error.h" +#include "core/libraries/kernel/posix_error.h" #include "core/libraries/kernel/process.h" #include "core/libraries/kernel/threads.h" #include "core/libraries/kernel/threads/exception.h" #include "core/libraries/kernel/time.h" #include "core/libraries/libs.h" -#include "core/linker.h" #ifdef _WIN64 -#include -#include -#include -#else -#ifdef __APPLE__ -#include -#endif +#include #endif namespace Libraries::Kernel { @@ -39,10 +30,10 @@ namespace Libraries::Kernel { static u64 g_stack_chk_guard = 0xDEADBEEF54321ABC; // dummy return boost::asio::io_context io_context; -std::mutex m_asio_req; -std::condition_variable_any cv_asio_req; -std::atomic asio_requests; -std::jthread service_thread; +static std::mutex m_asio_req; +static std::condition_variable_any cv_asio_req; +static std::atomic asio_requests; +static std::jthread service_thread; void KernelSignalRequest() { std::unique_lock lock{m_asio_req}; @@ -93,16 +84,12 @@ int* PS4_SYSV_ABI __Error() { return &g_posix_errno; } -void ErrSceToPosix(int result) { - const int rt = result > SCE_KERNEL_ERROR_UNKNOWN && result <= SCE_KERNEL_ERROR_ESTOP - ? result + -SCE_KERNEL_ERROR_UNKNOWN - : POSIX_EOTHER; - g_posix_errno = rt; +void ErrSceToPosix(int error) { + g_posix_errno = error - ORBIS_KERNEL_ERROR_UNKNOWN; } -int ErrnoToSceKernelError(int e) { - const auto res = SCE_KERNEL_ERROR_UNKNOWN + e; - return res > SCE_KERNEL_ERROR_ESTOP ? SCE_KERNEL_ERROR_UNKNOWN : res; +int ErrnoToSceKernelError(int error) { + return error + ORBIS_KERNEL_ERROR_UNKNOWN; } void SetPosixErrno(int e) { diff --git a/src/core/libraries/kernel/kernel.h b/src/core/libraries/kernel/kernel.h index f6865d22f..8e7f475ad 100644 --- a/src/core/libraries/kernel/kernel.h +++ b/src/core/libraries/kernel/kernel.h @@ -5,9 +5,8 @@ #include #include -#include "common/logging/log.h" #include "common/types.h" -#include "core/libraries/error_codes.h" +#include "core/libraries/kernel/orbis_error.h" namespace Core::Loader { class SymbolsResolver; @@ -38,7 +37,7 @@ struct WrapperImpl { u32 ret = f(args...); if (ret != 0) { // LOG_ERROR(Lib_Kernel, "Function {} returned {}", std::string_view{name.value}, ret); - ret += SCE_KERNEL_ERROR_UNKNOWN; + ret += ORBIS_KERNEL_ERROR_UNKNOWN; } return ret; } diff --git a/src/core/libraries/kernel/memory.cpp b/src/core/libraries/kernel/memory.cpp index 4d55fc2a3..606c5c185 100644 --- a/src/core/libraries/kernel/memory.cpp +++ b/src/core/libraries/kernel/memory.cpp @@ -9,9 +9,9 @@ #include "common/scope_exit.h" #include "common/singleton.h" #include "core/file_sys/fs.h" -#include "core/libraries/error_codes.h" #include "core/libraries/kernel/kernel.h" #include "core/libraries/kernel/memory.h" +#include "core/libraries/kernel/orbis_error.h" #include "core/libraries/libs.h" #include "core/linker.h" #include "core/memory.h" @@ -28,20 +28,20 @@ int PS4_SYSV_ABI sceKernelAllocateDirectMemory(s64 searchStart, s64 searchEnd, u u64 alignment, int memoryType, s64* physAddrOut) { if (searchStart < 0 || searchEnd <= searchStart) { LOG_ERROR(Kernel_Vmm, "Provided address range is invalid!"); - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } const bool is_in_range = searchEnd - searchStart >= len; if (len <= 0 || !Common::Is16KBAligned(len) || !is_in_range) { LOG_ERROR(Kernel_Vmm, "Provided address range is invalid!"); - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } if (alignment != 0 && !Common::Is16KBAligned(alignment)) { LOG_ERROR(Kernel_Vmm, "Alignment value is invalid!"); - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } if (physAddrOut == nullptr) { LOG_ERROR(Kernel_Vmm, "Result physical address pointer is null!"); - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } auto* memory = Core::Memory::Instance(); @@ -53,7 +53,7 @@ int PS4_SYSV_ABI sceKernelAllocateDirectMemory(s64 searchStart, s64 searchEnd, u "alignment = {:#x}, memoryType = {:#x}, physAddrOut = {:#x}", searchStart, searchEnd, len, alignment, memoryType, phys_addr); - return SCE_OK; + return ORBIS_OK; } s32 PS4_SYSV_ABI sceKernelAllocateMainDirectMemory(size_t len, size_t alignment, int memoryType, @@ -111,7 +111,7 @@ s32 PS4_SYSV_ABI sceKernelVirtualQuery(const void* addr, int flags, OrbisVirtual size_t infoSize) { LOG_INFO(Kernel_Vmm, "called addr = {}, flags = {:#x}", fmt::ptr(addr), flags); if (!addr) { - return SCE_KERNEL_ERROR_EACCES; + return ORBIS_KERNEL_ERROR_EACCES; } auto* memory = Core::Memory::Instance(); return memory->VirtualQuery(std::bit_cast(addr), flags, info); @@ -123,16 +123,16 @@ s32 PS4_SYSV_ABI sceKernelReserveVirtualRange(void** addr, u64 len, int flags, u if (addr == nullptr) { LOG_ERROR(Kernel_Vmm, "Address is invalid!"); - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } if (len == 0 || !Common::Is16KBAligned(len)) { LOG_ERROR(Kernel_Vmm, "Map size is either zero or not 16KB aligned!"); - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } if (alignment != 0) { if ((!std::has_single_bit(alignment) && !Common::Is16KBAligned(alignment))) { LOG_ERROR(Kernel_Vmm, "Alignment value is invalid!"); - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } } @@ -141,7 +141,7 @@ s32 PS4_SYSV_ABI sceKernelReserveVirtualRange(void** addr, u64 len, int flags, u const auto map_flags = static_cast(flags); memory->Reserve(addr, in_addr, len, map_flags, alignment); - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceKernelMapNamedDirectMemory(void** addr, u64 len, int prot, int flags, @@ -149,16 +149,16 @@ int PS4_SYSV_ABI sceKernelMapNamedDirectMemory(void** addr, u64 len, int prot, i const char* name) { if (len == 0 || !Common::Is16KBAligned(len)) { LOG_ERROR(Kernel_Vmm, "Map size is either zero or not 16KB aligned!"); - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } if (!Common::Is16KBAligned(directMemoryStart)) { LOG_ERROR(Kernel_Vmm, "Start address is not 16KB aligned!"); - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } if (alignment != 0) { if ((!std::has_single_bit(alignment) && !Common::Is16KBAligned(alignment))) { LOG_ERROR(Kernel_Vmm, "Alignment value is invalid!"); - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } } @@ -357,20 +357,20 @@ s32 PS4_SYSV_ABI sceKernelMemoryPoolExpand(u64 searchStart, u64 searchEnd, size_ size_t alignment, u64* physAddrOut) { if (searchStart < 0 || searchEnd <= searchStart) { LOG_ERROR(Kernel_Vmm, "Provided address range is invalid!"); - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } const bool is_in_range = searchEnd - searchStart >= len; if (len <= 0 || !Common::Is64KBAligned(len) || !is_in_range) { LOG_ERROR(Kernel_Vmm, "Provided address range is invalid!"); - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } if (alignment != 0 && !Common::Is64KBAligned(alignment)) { LOG_ERROR(Kernel_Vmm, "Alignment value is invalid!"); - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } if (physAddrOut == nullptr) { LOG_ERROR(Kernel_Vmm, "Result physical address pointer is null!"); - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } auto* memory = Core::Memory::Instance(); @@ -391,16 +391,16 @@ s32 PS4_SYSV_ABI sceKernelMemoryPoolReserve(void* addrIn, size_t len, size_t ali if (addrIn == nullptr) { LOG_ERROR(Kernel_Vmm, "Address is invalid!"); - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } if (len == 0 || !Common::Is2MBAligned(len)) { LOG_ERROR(Kernel_Vmm, "Map size is either zero or not 2MB aligned!"); - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } if (alignment != 0) { if ((!std::has_single_bit(alignment) && !Common::Is2MBAligned(alignment))) { LOG_ERROR(Kernel_Vmm, "Alignment value is invalid!"); - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } } @@ -415,11 +415,11 @@ s32 PS4_SYSV_ABI sceKernelMemoryPoolReserve(void* addrIn, size_t len, size_t ali s32 PS4_SYSV_ABI sceKernelMemoryPoolCommit(void* addr, size_t len, int type, int prot, int flags) { if (addr == nullptr) { LOG_ERROR(Kernel_Vmm, "Address is invalid!"); - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } if (len == 0 || !Common::Is64KBAligned(len)) { LOG_ERROR(Kernel_Vmm, "Map size is either zero or not 64KB aligned!"); - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } LOG_INFO(Kernel_Vmm, "addr = {}, len = {:#x}, type = {:#x}, prot = {:#x}, flags = {:#x}", @@ -434,11 +434,11 @@ s32 PS4_SYSV_ABI sceKernelMemoryPoolCommit(void* addr, size_t len, int type, int s32 PS4_SYSV_ABI sceKernelMemoryPoolDecommit(void* addr, size_t len, int flags) { if (addr == nullptr) { LOG_ERROR(Kernel_Vmm, "Address is invalid!"); - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } if (len == 0 || !Common::Is64KBAligned(len)) { LOG_ERROR(Kernel_Vmm, "Map size is either zero or not 64KB aligned!"); - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } LOG_INFO(Kernel_Vmm, "addr = {}, len = {:#x}, flags = {:#x}", fmt::ptr(addr), len, flags); @@ -493,7 +493,7 @@ int PS4_SYSV_ABI sceKernelMunmap(void* addr, size_t len) { } auto* memory = Core::Memory::Instance(); memory->UnmapMemory(std::bit_cast(addr), len); - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI posix_munmap(void* addr, size_t len) { diff --git a/src/core/libraries/kernel/orbis_error.h b/src/core/libraries/kernel/orbis_error.h new file mode 100644 index 000000000..d19b3f3f1 --- /dev/null +++ b/src/core/libraries/kernel/orbis_error.h @@ -0,0 +1,108 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/libraries/error_codes.h" + +// Libkernel library +constexpr int ORBIS_KERNEL_ERROR_UNKNOWN = 0x80020000; +constexpr int ORBIS_KERNEL_ERROR_EPERM = 0x80020001; +constexpr int ORBIS_KERNEL_ERROR_ENOENT = 0x80020002; +constexpr int ORBIS_KERNEL_ERROR_ESRCH = 0x80020003; +constexpr int ORBIS_KERNEL_ERROR_EINTR = 0x80020004; +constexpr int ORBIS_KERNEL_ERROR_EIO = 0x80020005; +constexpr int ORBIS_KERNEL_ERROR_ENXIO = 0x80020006; +constexpr int ORBIS_KERNEL_ERROR_E2BIG = 0x80020007; +constexpr int ORBIS_KERNEL_ERROR_ENOEXEC = 0x80020008; +constexpr int ORBIS_KERNEL_ERROR_EBADF = 0x80020009; +constexpr int ORBIS_KERNEL_ERROR_ECHILD = 0x8002000A; +constexpr int ORBIS_KERNEL_ERROR_EDEADLK = 0x8002000B; +constexpr int ORBIS_KERNEL_ERROR_ENOMEM = 0x8002000C; +constexpr int ORBIS_KERNEL_ERROR_EACCES = 0x8002000D; +constexpr int ORBIS_KERNEL_ERROR_EFAULT = 0x8002000E; +constexpr int ORBIS_KERNEL_ERROR_ENOTBLK = 0x8002000F; +constexpr int ORBIS_KERNEL_ERROR_EBUSY = 0x80020010; +constexpr int ORBIS_KERNEL_ERROR_EEXIST = 0x80020011; +constexpr int ORBIS_KERNEL_ERROR_EXDEV = 0x80020012; +constexpr int ORBIS_KERNEL_ERROR_ENODEV = 0x80020013; +constexpr int ORBIS_KERNEL_ERROR_ENOTDIR = 0x80020014; +constexpr int ORBIS_KERNEL_ERROR_EISDIR = 0x80020015; +constexpr int ORBIS_KERNEL_ERROR_EINVAL = 0x80020016; +constexpr int ORBIS_KERNEL_ERROR_ENFILE = 0x80020017; +constexpr int ORBIS_KERNEL_ERROR_EMFILE = 0x80020018; +constexpr int ORBIS_KERNEL_ERROR_ENOTTY = 0x80020019; +constexpr int ORBIS_KERNEL_ERROR_ETXTBSY = 0x8002001A; +constexpr int ORBIS_KERNEL_ERROR_EFBIG = 0x8002001B; +constexpr int ORBIS_KERNEL_ERROR_ENOSPC = 0x8002001C; +constexpr int ORBIS_KERNEL_ERROR_ESPIPE = 0x8002001D; +constexpr int ORBIS_KERNEL_ERROR_EROFS = 0x8002001E; +constexpr int ORBIS_KERNEL_ERROR_EMLINK = 0x8002001F; +constexpr int ORBIS_KERNEL_ERROR_EPIPE = 0x80020020; +constexpr int ORBIS_KERNEL_ERROR_EDOM = 0x80020021; +constexpr int ORBIS_KERNEL_ERROR_ERANGE = 0x80020022; +constexpr int ORBIS_KERNEL_ERROR_EAGAIN = 0x80020023; +constexpr int ORBIS_KERNEL_ERROR_EWOULDBLOCK = 0x80020023; +constexpr int ORBIS_KERNEL_ERROR_EINPROGRESS = 0x80020024; +constexpr int ORBIS_KERNEL_ERROR_EALREADY = 0x80020025; +constexpr int ORBIS_KERNEL_ERROR_ENOTSOCK = 0x80020026; +constexpr int ORBIS_KERNEL_ERROR_EDESTADDRREQ = 0x80020027; +constexpr int ORBIS_KERNEL_ERROR_EMSGSIZE = 0x80020028; +constexpr int ORBIS_KERNEL_ERROR_EPROTOTYPE = 0x80020029; +constexpr int ORBIS_KERNEL_ERROR_ENOPROTOOPT = 0x8002002A; +constexpr int ORBIS_KERNEL_ERROR_EPROTONOSUPPORT = 0x8002002B; +constexpr int ORBIS_KERNEL_ERROR_ESOCKTNOSUPPORT = 0x8002002C; +constexpr int ORBIS_KERNEL_ERROR_ENOTSUP = 0x8002002D; +constexpr int ORBIS_KERNEL_ERROR_EOPNOTSUPP = 0x8002002D; +constexpr int ORBIS_KERNEL_ERROR_EPFNOSUPPORT = 0x8002002E; +constexpr int ORBIS_KERNEL_ERROR_EAFNOSUPPORT = 0x8002002F; +constexpr int ORBIS_KERNEL_ERROR_EADDRINUSE = 0x80020030; +constexpr int ORBIS_KERNEL_ERROR_EADDRNOTAVAIL = 0x80020031; +constexpr int ORBIS_KERNEL_ERROR_ENETDOWN = 0x80020032; +constexpr int ORBIS_KERNEL_ERROR_ENETUNREACH = 0x80020033; +constexpr int ORBIS_KERNEL_ERROR_ENETRESET = 0x80020034; +constexpr int ORBIS_KERNEL_ERROR_ECONNABORTED = 0x80020035; +constexpr int ORBIS_KERNEL_ERROR_ECONNRESET = 0x80020036; +constexpr int ORBIS_KERNEL_ERROR_ENOBUFS = 0x80020037; +constexpr int ORBIS_KERNEL_ERROR_EISCONN = 0x80020038; +constexpr int ORBIS_KERNEL_ERROR_ENOTCONN = 0x80020039; +constexpr int ORBIS_KERNEL_ERROR_ESHUTDOWN = 0x8002003A; +constexpr int ORBIS_KERNEL_ERROR_ETOOMANYREFS = 0x8002003B; +constexpr int ORBIS_KERNEL_ERROR_ETIMEDOUT = 0x8002003C; +constexpr int ORBIS_KERNEL_ERROR_ECONNREFUSED = 0x8002003D; +constexpr int ORBIS_KERNEL_ERROR_ELOOP = 0x8002003E; +constexpr int ORBIS_KERNEL_ERROR_ENAMETOOLONG = 0x8002003F; +constexpr int ORBIS_KERNEL_ERROR_EHOSTDOWN = 0x80020040; +constexpr int ORBIS_KERNEL_ERROR_EHOSTUNREACH = 0x80020041; +constexpr int ORBIS_KERNEL_ERROR_ENOTEMPTY = 0x80020042; +constexpr int ORBIS_KERNEL_ERROR_EPROCLIM = 0x80020043; +constexpr int ORBIS_KERNEL_ERROR_EUSERS = 0x80020044; +constexpr int ORBIS_KERNEL_ERROR_EDQUOT = 0x80020045; +constexpr int ORBIS_KERNEL_ERROR_ESTALE = 0x80020046; +constexpr int ORBIS_KERNEL_ERROR_EREMOTE = 0x80020047; +constexpr int ORBIS_KERNEL_ERROR_EBADRPC = 0x80020048; +constexpr int ORBIS_KERNEL_ERROR_ERPCMISMATCH = 0x80020049; +constexpr int ORBIS_KERNEL_ERROR_EPROGUNAVAIL = 0x8002004A; +constexpr int ORBIS_KERNEL_ERROR_EPROGMISMATCH = 0x8002004B; +constexpr int ORBIS_KERNEL_ERROR_EPROCUNAVAIL = 0x8002004C; +constexpr int ORBIS_KERNEL_ERROR_ENOLCK = 0x8002004D; +constexpr int ORBIS_KERNEL_ERROR_ENOSYS = 0x8002004E; +constexpr int ORBIS_KERNEL_ERROR_EFTYPE = 0x8002004F; +constexpr int ORBIS_KERNEL_ERROR_EAUTH = 0x80020050; +constexpr int ORBIS_KERNEL_ERROR_ENEEDAUTH = 0x80020051; +constexpr int ORBIS_KERNEL_ERROR_EIDRM = 0x80020052; +constexpr int ORBIS_KERNEL_ERROR_ENOMSG = 0x80020053; +constexpr int ORBIS_KERNEL_ERROR_EOVERFLOW = 0x80020054; +constexpr int ORBIS_KERNEL_ERROR_ECANCELED = 0x80020055; +constexpr int ORBIS_KERNEL_ERROR_EILSEQ = 0x80020056; +constexpr int ORBIS_KERNEL_ERROR_ENOATTR = 0x80020057; +constexpr int ORBIS_KERNEL_ERROR_EDOOFUS = 0x80020058; +constexpr int ORBIS_KERNEL_ERROR_EBADMSG = 0x80020059; +constexpr int ORBIS_KERNEL_ERROR_EMULTIHOP = 0x8002005A; +constexpr int ORBIS_KERNEL_ERROR_ENOLINK = 0x8002005B; +constexpr int ORBIS_KERNEL_ERROR_EPROTO = 0x8002005C; +constexpr int ORBIS_KERNEL_ERROR_ENOTCAPABLE = 0x8002005D; +constexpr int ORBIS_KERNEL_ERROR_ECAPMODE = 0x8002005E; +constexpr int ORBIS_KERNEL_ERROR_ENOBLK = 0x8002005F; +constexpr int ORBIS_KERNEL_ERROR_EICV = 0x80020060; +constexpr int ORBIS_KERNEL_ERROR_ENOPLAYGOENT = 0x80020061; diff --git a/src/core/libraries/kernel/posix_error.h b/src/core/libraries/kernel/posix_error.h new file mode 100644 index 000000000..0f7cf3e50 --- /dev/null +++ b/src/core/libraries/kernel/posix_error.h @@ -0,0 +1,128 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/libraries/error_codes.h" + +// Posix error codes +constexpr int POSIX_EPERM = 1; +constexpr int POSIX_ENOENT = 2; +constexpr int POSIX_ESRCH = 3; +constexpr int POSIX_EINTR = 4; +constexpr int POSIX_EIO = 5; +constexpr int POSIX_ENXIO = 6; +constexpr int POSIX_E2BIG = 7; +constexpr int POSIX_ENOEXEC = 8; +constexpr int POSIX_EBADF = 9; +constexpr int POSIX_ECHILD = 10; +constexpr int POSIX_EDEADLK = 11; +constexpr int POSIX_ENOMEM = 12; +constexpr int POSIX_EACCES = 13; +constexpr int POSIX_EFAULT = 14; +constexpr int POSIX_ENOTBLK = 15; +constexpr int POSIX_EBUSY = 16; +constexpr int POSIX_EEXIST = 17; +constexpr int POSIX_EXDEV = 18; +constexpr int POSIX_ENODEV = 19; +constexpr int POSIX_ENOTDIR = 20; +constexpr int POSIX_EISDIR = 21; +constexpr int POSIX_EINVAL = 22; +constexpr int POSIX_ENFILE = 23; +constexpr int POSIX_EMFILE = 24; +constexpr int POSIX_ENOTTY = 25; +constexpr int POSIX_ETXTBSY = 26; +constexpr int POSIX_EFBIG = 27; +constexpr int POSIX_ENOSPC = 28; +constexpr int POSIX_ESPIPE = 29; +constexpr int POSIX_EROFS = 30; +constexpr int POSIX_EMLINK = 31; +constexpr int POSIX_EPIPE = 32; +constexpr int POSIX_EDOM = 33; +constexpr int POSIX_ERANGE = 34; +constexpr int POSIX_EAGAIN = 35; +constexpr int POSIX_EWOULDBLOCK = 35; +constexpr int POSIX_EINPROGRESS = 36; +constexpr int POSIX_EALREADY = 37; +constexpr int POSIX_ENOTSOCK = 38; +constexpr int POSIX_EDESTADDRREQ = 39; +constexpr int POSIX_EMSGSIZE = 40; +constexpr int POSIX_EPROTOTYPE = 41; +constexpr int POSIX_ENOPROTOOPT = 42; +constexpr int POSIX_EPROTONOSUPPORT = 43; +constexpr int POSIX_ESOCKTNOSUPPORT = 44; +constexpr int POSIX_EOPNOTSUPP = 45; +constexpr int POSIX_ENOTSUP = 45; +constexpr int POSIX_EPFNOSUPPORT = 46; +constexpr int POSIX_EAFNOSUPPORT = 47; +constexpr int POSIX_EADDRINUSE = 48; +constexpr int POSIX_EADDRNOTAVAIL = 49; +constexpr int POSIX_ENETDOWN = 50; +constexpr int POSIX_ENETUNREACH = 51; +constexpr int POSIX_ENETRESET = 52; +constexpr int POSIX_ECONNABORTED = 53; +constexpr int POSIX_ECONNRESET = 54; +constexpr int POSIX_ENOBUFS = 55; +constexpr int POSIX_EISCONN = 56; +constexpr int POSIX_ENOTCONN = 57; +constexpr int POSIX_ESHUTDOWN = 58; +constexpr int POSIX_ETOOMANYREFS = 59; +constexpr int POSIX_ETIMEDOUT = 60; +constexpr int POSIX_ECONNREFUSED = 61; +constexpr int POSIX_ELOOP = 62; +constexpr int POSIX_ENAMETOOLONG = 63; +constexpr int POSIX_EHOSTDOWN = 64; +constexpr int POSIX_EHOSTUNREACH = 65; +constexpr int POSIX_ENOTEMPTY = 66; +constexpr int POSIX_EPROCLIM = 67; +constexpr int POSIX_EUSERS = 68; +constexpr int POSIX_EDQUOT = 69; +constexpr int POSIX_ESTALE = 70; +constexpr int POSIX_EREMOTE = 71; +constexpr int POSIX_EBADRPC = 72; +constexpr int POSIX_ERPCMISMATCH = 73; +constexpr int POSIX_EPROGUNAVAIL = 74; +constexpr int POSIX_EPROGMISMATCH = 75; +constexpr int POSIX_EPROCUNAVAIL = 76; +constexpr int POSIX_ENOLCK = 77; +constexpr int POSIX_ENOSYS = 78; +constexpr int POSIX_EFTYPE = 79; +constexpr int POSIX_EAUTH = 80; +constexpr int POSIX_ENEEDAUTH = 81; +constexpr int POSIX_EIDRM = 82; +constexpr int POSIX_ENOMSG = 83; +constexpr int POSIX_EOVERFLOW = 84; +constexpr int POSIX_ECANCELED = 85; +constexpr int POSIX_EILSEQ = 86; +constexpr int POSIX_ENOATTR = 87; +constexpr int POSIX_EDOOFUS = 88; +constexpr int POSIX_EBADMSG = 89; +constexpr int POSIX_EMULTIHOP = 90; +constexpr int POSIX_ENOLINK = 91; +constexpr int POSIX_EPROTO = 92; +constexpr int POSIX_ENOTCAPABLE = 93; +constexpr int POSIX_ECAPMODE = 94; +constexpr int POSIX_ENOBLK = 95; +constexpr int POSIX_EICV = 96; +constexpr int POSIX_ENOPLAYGOENT = 97; +constexpr int POSIX_EREVOKE = 98; +constexpr int POSIX_ESDKVERSION = 99; +constexpr int POSIX_ESTART = 100; +constexpr int POSIX_ESTOP = 101; +constexpr int POSIX_EINVALID2MB = 102; +constexpr int POSIX_ELAST = 102; +constexpr int POSIX_EADHOC = 160; +constexpr int POSIX_EINACTIVEDISABLED = 163; +constexpr int POSIX_ENETNODATA = 164; +constexpr int POSIX_ENETDESC = 165; +constexpr int POSIX_ENETDESCTIMEDOUT = 166; +constexpr int POSIX_ENETINTR = 167; +constexpr int POSIX_ERETURN = 205; +constexpr int POSIX_EFPOS = 152; +constexpr int POSIX_ENODATA = 1040; +constexpr int POSIX_ENOSR = 1050; +constexpr int POSIX_ENOSTR = 1051; +constexpr int POSIX_ENOTRECOVERABLE = 1056; +constexpr int POSIX_EOTHER = 1062; +constexpr int POSIX_EOWNERDEAD = 1064; +constexpr int POSIX_ETIME = 1074; diff --git a/src/core/libraries/kernel/process.cpp b/src/core/libraries/kernel/process.cpp index fc1d6e137..15e4ff820 100644 --- a/src/core/libraries/kernel/process.cpp +++ b/src/core/libraries/kernel/process.cpp @@ -5,7 +5,7 @@ #include "common/elf_info.h" #include "common/logging/log.h" #include "core/file_sys/fs.h" -#include "core/libraries/error_codes.h" +#include "core/libraries/kernel/orbis_error.h" #include "core/libraries/kernel/process.h" #include "core/libraries/libs.h" #include "core/linker.h" @@ -91,7 +91,7 @@ s32 PS4_SYSV_ABI sceKernelGetModuleInfoForUnwind(VAddr addr, int flags, OrbisModuleInfoForUnwind* info) { if (flags >= 3) { std::memset(info, 0, sizeof(OrbisModuleInfoForUnwind)); - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } if (!info) { return ORBIS_KERNEL_ERROR_EFAULT; diff --git a/src/core/libraries/kernel/threads/condvar.cpp b/src/core/libraries/kernel/threads/condvar.cpp index 4437af964..cbe8f6ca7 100644 --- a/src/core/libraries/kernel/threads/condvar.cpp +++ b/src/core/libraries/kernel/threads/condvar.cpp @@ -3,8 +3,8 @@ #include #include "common/assert.h" -#include "core/libraries/error_codes.h" #include "core/libraries/kernel/kernel.h" +#include "core/libraries/kernel/posix_error.h" #include "core/libraries/kernel/threads/pthread.h" #include "core/libraries/kernel/threads/sleepq.h" #include "core/libraries/libs.h" diff --git a/src/core/libraries/kernel/threads/event_flag.cpp b/src/core/libraries/kernel/threads/event_flag.cpp index b0f08b91c..39925153c 100644 --- a/src/core/libraries/kernel/threads/event_flag.cpp +++ b/src/core/libraries/kernel/threads/event_flag.cpp @@ -7,7 +7,7 @@ #include "common/assert.h" #include "common/logging/log.h" -#include "core/libraries/error_codes.h" +#include "core/libraries/kernel/orbis_error.h" #include "core/libraries/libs.h" namespace Libraries::Kernel { diff --git a/src/core/libraries/kernel/threads/mutex.cpp b/src/core/libraries/kernel/threads/mutex.cpp index fc0bf09bd..4f11e32da 100644 --- a/src/core/libraries/kernel/threads/mutex.cpp +++ b/src/core/libraries/kernel/threads/mutex.cpp @@ -3,10 +3,9 @@ #include #include "common/assert.h" -#include "common/scope_exit.h" #include "common/types.h" -#include "core/libraries/error_codes.h" #include "core/libraries/kernel/kernel.h" +#include "core/libraries/kernel/posix_error.h" #include "core/libraries/kernel/threads/pthread.h" #include "core/libraries/libs.h" diff --git a/src/core/libraries/kernel/threads/pthread.cpp b/src/core/libraries/kernel/threads/pthread.cpp index 18ddcb9bf..4629980c9 100644 --- a/src/core/libraries/kernel/threads/pthread.cpp +++ b/src/core/libraries/kernel/threads/pthread.cpp @@ -4,8 +4,8 @@ #include "common/assert.h" #include "common/thread.h" #include "core/debug_state.h" -#include "core/libraries/error_codes.h" #include "core/libraries/kernel/kernel.h" +#include "core/libraries/kernel/posix_error.h" #include "core/libraries/kernel/threads/pthread.h" #include "core/libraries/kernel/threads/thread_state.h" #include "core/libraries/libs.h" @@ -380,7 +380,7 @@ int PS4_SYSV_ABI posix_sched_get_priority_min() { int PS4_SYSV_ABI posix_pthread_rename_np(PthreadT thread, const char* name) { LOG_INFO(Kernel_Pthread, "name = {}", name); thread->name = name; - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI posix_pthread_getschedparam(PthreadT pthread, SchedPolicy* policy, diff --git a/src/core/libraries/kernel/threads/pthread_attr.cpp b/src/core/libraries/kernel/threads/pthread_attr.cpp index ead0ff7df..a8e60ccf8 100644 --- a/src/core/libraries/kernel/threads/pthread_attr.cpp +++ b/src/core/libraries/kernel/threads/pthread_attr.cpp @@ -1,8 +1,8 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "core/libraries/error_codes.h" #include "core/libraries/kernel/kernel.h" +#include "core/libraries/kernel/posix_error.h" #include "core/libraries/kernel/threads/pthread.h" #include "core/libraries/kernel/threads/thread_state.h" #include "core/libraries/libs.h" diff --git a/src/core/libraries/kernel/threads/pthread_spec.cpp b/src/core/libraries/kernel/threads/pthread_spec.cpp index f0803b671..9e625da32 100644 --- a/src/core/libraries/kernel/threads/pthread_spec.cpp +++ b/src/core/libraries/kernel/threads/pthread_spec.cpp @@ -1,9 +1,8 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "common/assert.h" -#include "core/libraries/error_codes.h" #include "core/libraries/kernel/kernel.h" +#include "core/libraries/kernel/posix_error.h" #include "core/libraries/kernel/threads/pthread.h" #include "core/libraries/libs.h" diff --git a/src/core/libraries/kernel/threads/rwlock.cpp b/src/core/libraries/kernel/threads/rwlock.cpp index 2d5a4cdb6..affaaf994 100644 --- a/src/core/libraries/kernel/threads/rwlock.cpp +++ b/src/core/libraries/kernel/threads/rwlock.cpp @@ -1,8 +1,8 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "core/libraries/error_codes.h" #include "core/libraries/kernel/kernel.h" +#include "core/libraries/kernel/posix_error.h" #include "core/libraries/kernel/threads/pthread.h" #include "core/libraries/libs.h" diff --git a/src/core/libraries/kernel/threads/semaphore.cpp b/src/core/libraries/kernel/threads/semaphore.cpp index db14c298c..e3c7e9092 100644 --- a/src/core/libraries/kernel/threads/semaphore.cpp +++ b/src/core/libraries/kernel/threads/semaphore.cpp @@ -5,9 +5,11 @@ #include #include #include + #include "common/logging/log.h" -#include "core/libraries/error_codes.h" #include "core/libraries/kernel/kernel.h" +#include "core/libraries/kernel/orbis_error.h" +#include "core/libraries/kernel/posix_error.h" #include "core/libraries/kernel/threads/pthread.h" #include "core/libraries/kernel/time.h" #include "core/libraries/libs.h" @@ -41,7 +43,7 @@ public: } if (timeout && *timeout == 0) { - return SCE_KERNEL_ERROR_ETIMEDOUT; + return ORBIS_KERNEL_ERROR_ETIMEDOUT; } // Create waiting thread object and add it into the list of waiters. @@ -50,7 +52,7 @@ public: // Perform the wait. const s32 result = waiter.Wait(lk, timeout); - if (result == SCE_KERNEL_ERROR_ETIMEDOUT) { + if (result == ORBIS_KERNEL_ERROR_ETIMEDOUT) { wait_list.erase(it); } return result; @@ -120,15 +122,15 @@ public: int GetResult(bool timed_out) { if (timed_out) { - return SCE_KERNEL_ERROR_ETIMEDOUT; + return ORBIS_KERNEL_ERROR_ETIMEDOUT; } if (was_deleted) { - return SCE_KERNEL_ERROR_EACCES; + return ORBIS_KERNEL_ERROR_EACCES; } if (was_cancled) { - return SCE_KERNEL_ERROR_ECANCELED; + return ORBIS_KERNEL_ERROR_ECANCELED; } - return SCE_OK; + return ORBIS_OK; } int Wait(std::unique_lock& lk, u32* timeout) { @@ -223,13 +225,13 @@ int PS4_SYSV_ABI sceKernelCancelSema(OrbisKernelSema sem, s32 setCount, s32* pNu int PS4_SYSV_ABI sceKernelDeleteSema(OrbisKernelSema sem) { if (!sem) { - return SCE_KERNEL_ERROR_ESRCH; + return ORBIS_KERNEL_ERROR_ESRCH; } sem->Delete(); return ORBIS_OK; } -int PS4_SYSV_ABI posix_sem_init(PthreadSem** sem, int pshared, unsigned int value) { +int PS4_SYSV_ABI posix_sem_init(PthreadSem** sem, int pshared, u32 value) { if (value > ORBIS_KERNEL_SEM_VALUE_MAX) { *__Error() = POSIX_EINVAL; return -1; diff --git a/src/core/libraries/kernel/threads/sleepq.h b/src/core/libraries/kernel/threads/sleepq.h index 9274942e3..5dc37645d 100644 --- a/src/core/libraries/kernel/threads/sleepq.h +++ b/src/core/libraries/kernel/threads/sleepq.h @@ -2,14 +2,13 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include -#include #include #include -#include "common/types.h" namespace Libraries::Kernel { struct Pthread; +struct SleepQueue; using ListBaseHook = boost::intrusive::list_base_hook>; @@ -17,7 +16,7 @@ using ListBaseHook = using SleepqList = boost::intrusive::list>; struct SleepQueue : public ListBaseHook { - std::list sq_blocked; + std::forward_list sq_blocked; SleepqList sq_freeq; void* sq_wchan; int sq_type; @@ -35,4 +34,4 @@ int SleepqRemove(SleepQueue* sq, Pthread* td); void SleepqDrop(SleepQueue* sq, void (*callback)(Pthread*, void*), void* arg); -} // namespace Libraries::Kernel \ No newline at end of file +} // namespace Libraries::Kernel diff --git a/src/core/libraries/kernel/threads/thread_state.cpp b/src/core/libraries/kernel/threads/thread_state.cpp index e968c39ae..6c2d4d7ef 100644 --- a/src/core/libraries/kernel/threads/thread_state.cpp +++ b/src/core/libraries/kernel/threads/thread_state.cpp @@ -4,7 +4,7 @@ #include #include "common/alignment.h" #include "common/scope_exit.h" -#include "core/libraries/error_codes.h" +#include "core/libraries/kernel/posix_error.h" #include "core/libraries/kernel/threads/pthread.h" #include "core/libraries/kernel/threads/sleepq.h" #include "core/libraries/kernel/threads/thread_state.h" diff --git a/src/core/libraries/kernel/time.cpp b/src/core/libraries/kernel/time.cpp index 76ea5e353..b586431ab 100644 --- a/src/core/libraries/kernel/time.cpp +++ b/src/core/libraries/kernel/time.cpp @@ -5,7 +5,7 @@ #include "common/assert.h" #include "common/native_clock.h" -#include "core/libraries/error_codes.h" +#include "core/libraries/kernel/orbis_error.h" #include "core/libraries/kernel/time.h" #include "core/libraries/libs.h" @@ -80,7 +80,7 @@ u32 PS4_SYSV_ABI sceKernelSleep(u32 seconds) { int PS4_SYSV_ABI sceKernelClockGettime(s32 clock_id, OrbisKernelTimespec* tp) { if (tp == nullptr) { - return SCE_KERNEL_ERROR_EFAULT; + return ORBIS_KERNEL_ERROR_EFAULT; } clockid_t pclock_id = CLOCK_REALTIME; switch (clock_id) { @@ -105,9 +105,9 @@ int PS4_SYSV_ABI sceKernelClockGettime(s32 clock_id, OrbisKernelTimespec* tp) { tp->tv_sec = t.tv_sec; tp->tv_nsec = t.tv_nsec; if (result == 0) { - return SCE_OK; + return ORBIS_OK; } - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } int PS4_SYSV_ABI posix_clock_gettime(s32 clock_id, OrbisKernelTimespec* time) { @@ -126,11 +126,11 @@ int PS4_SYSV_ABI posix_nanosleep(const OrbisKernelTimespec* rqtp, OrbisKernelTim int PS4_SYSV_ABI sceKernelNanosleep(const OrbisKernelTimespec* rqtp, OrbisKernelTimespec* rmtp) { if (!rqtp || !rmtp) { - return SCE_KERNEL_ERROR_EFAULT; + return ORBIS_KERNEL_ERROR_EFAULT; } if (rqtp->tv_sec < 0 || rqtp->tv_nsec < 0) { - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } return posix_nanosleep(rqtp, rmtp); @@ -197,7 +197,7 @@ s32 PS4_SYSV_ABI sceKernelGettimezone(OrbisKernelTimezone* tz) { int PS4_SYSV_ABI posix_clock_getres(u32 clock_id, OrbisKernelTimespec* res) { if (res == nullptr) { - return SCE_KERNEL_ERROR_EFAULT; + return ORBIS_KERNEL_ERROR_EFAULT; } clockid_t pclock_id = CLOCK_REALTIME; switch (clock_id) { @@ -221,9 +221,9 @@ int PS4_SYSV_ABI posix_clock_getres(u32 clock_id, OrbisKernelTimespec* res) { res->tv_sec = t.tv_sec; res->tv_nsec = t.tv_nsec; if (result == 0) { - return SCE_OK; + return ORBIS_OK; } - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } int PS4_SYSV_ABI sceKernelConvertLocaltimeToUtc(time_t param_1, int64_t param_2, time_t* seconds, @@ -237,9 +237,9 @@ int PS4_SYSV_ABI sceKernelConvertLocaltimeToUtc(time_t param_1, int64_t param_2, if (dst_seconds) *dst_seconds = timezone->tz_dsttime * 60; } else { - return SCE_KERNEL_ERROR_EINVAL; + return ORBIS_KERNEL_ERROR_EINVAL; } - return SCE_OK; + return ORBIS_OK; } namespace Dev { @@ -254,7 +254,7 @@ Common::NativeClock* GetClock() { } // namespace Dev int PS4_SYSV_ABI sceKernelConvertUtcToLocaltime(time_t time, time_t* local_time, - struct OrbisTimesec* st, unsigned long* dst_sec) { + struct OrbisTimesec* st, u64* dst_sec) { LOG_TRACE(Kernel, "Called"); #ifdef __APPLE__ // std::chrono::current_zone() not available yet. diff --git a/src/core/libraries/kernel/time.h b/src/core/libraries/kernel/time.h index 508ef2152..6aa281aaf 100644 --- a/src/core/libraries/kernel/time.h +++ b/src/core/libraries/kernel/time.h @@ -81,7 +81,7 @@ int PS4_SYSV_ABI sceKernelConvertLocaltimeToUtc(time_t param_1, int64_t param_2, OrbisKernelTimezone* timezone, int* dst_seconds); int PS4_SYSV_ABI sceKernelConvertUtcToLocaltime(time_t time, time_t* local_time, OrbisTimesec* st, - unsigned long* dst_sec); + u64* dst_sec); void RegisterTime(Core::Loader::SymbolsResolver* sym); diff --git a/src/core/libraries/libpng/pngdec.cpp b/src/core/libraries/libpng/pngdec.cpp index fb9fae4d6..d6f291a62 100644 --- a/src/core/libraries/libpng/pngdec.cpp +++ b/src/core/libraries/libpng/pngdec.cpp @@ -4,9 +4,9 @@ #include #include "common/assert.h" #include "common/logging/log.h" -#include "core/libraries/error_codes.h" +#include "core/libraries/libpng/pngdec.h" +#include "core/libraries/libpng/pngdec_error.h" #include "core/libraries/libs.h" -#include "pngdec.h" namespace Libraries::PngDec { @@ -15,24 +15,25 @@ struct PngHandler { png_infop info_ptr; }; +struct PngStruct { + const u8* data; + size_t size; + u64 offset; +}; + static inline OrbisPngDecColorSpace MapPngColor(int color) { switch (color) { case PNG_COLOR_TYPE_GRAY: - return OrbisPngDecColorSpace::ORBIS_PNG_DEC_COLOR_SPACE_GRAYSCALE; - + return OrbisPngDecColorSpace::Grayscale; case PNG_COLOR_TYPE_GRAY_ALPHA: - return OrbisPngDecColorSpace::ORBIS_PNG_DEC_COLOR_SPACE_GRAYSCALE_ALPHA; - + return OrbisPngDecColorSpace::GrayscaleAlpha; case PNG_COLOR_TYPE_PALETTE: - return OrbisPngDecColorSpace::ORBIS_PNG_DEC_COLOR_SPACE_CLUT; - + return OrbisPngDecColorSpace::Clut; case PNG_COLOR_TYPE_RGB: - return OrbisPngDecColorSpace::ORBIS_PNG_DEC_COLOR_SPACE_RGB; - + return OrbisPngDecColorSpace::Rgb; case PNG_COLOR_TYPE_RGB_ALPHA: - return OrbisPngDecColorSpace::ORBIS_PNG_DEC_COLOR_SPACE_RGBA; + return OrbisPngDecColorSpace::Rgba; } - UNREACHABLE_MSG("unknown png color type"); } @@ -54,8 +55,8 @@ s32 PS4_SYSV_ABI scePngDecCreate(const OrbisPngDecCreateParam* param, void* memo LOG_ERROR(Lib_Png, "Invalid memory address!"); return ORBIS_PNG_DEC_ERROR_INVALID_ADDR; } - if (param->maxImageWidth - 1 > 1000000) { - LOG_ERROR(Lib_Png, "Invalid size! width = {}", param->maxImageWidth); + if (param->max_image_width - 1 > 1000000) { + LOG_ERROR(Lib_Png, "Invalid size! width = {}", param->max_image_width); return ORBIS_PNG_DEC_ERROR_INVALID_SIZE; } auto pngh = (PngHandler*)memoryAddress; @@ -86,7 +87,7 @@ s32 PS4_SYSV_ABI scePngDecDecode(OrbisPngDecHandle handle, const OrbisPngDecDeco LOG_ERROR(Lib_Png, "Invalid param!"); return ORBIS_PNG_DEC_ERROR_INVALID_PARAM; } - if (param->pngMemAddr == nullptr || param->pngMemAddr == nullptr) { + if (param->png_mem_addr == nullptr || param->image_mem_addr == nullptr) { LOG_ERROR(Lib_Png, "invalid image address!"); return ORBIS_PNG_DEC_ERROR_INVALID_ADDR; } @@ -98,76 +99,74 @@ s32 PS4_SYSV_ABI scePngDecDecode(OrbisPngDecHandle handle, const OrbisPngDecDeco auto pngh = (PngHandler*)handle; - struct pngstruct { - const u8* data; - size_t size; - u64 offset; - } pngdata = { - .data = (const u8*)param->pngMemAddr, - .size = param->pngMemSize, + const auto pngdata = PngStruct{ + .data = param->png_mem_addr, + .size = param->png_mem_size, .offset = 0, }; - - // Read png from memory png_set_read_fn(pngh->png_ptr, (void*)&pngdata, [](png_structp ps, png_bytep data, png_size_t len) { if (len == 0) return; - auto pngdata = (pngstruct*)png_get_io_ptr(ps); + auto pngdata = (PngStruct*)png_get_io_ptr(ps); ::memcpy(data, pngdata->data + pngdata->offset, len); pngdata->offset += len; }); - u32 width, height; - int color_type, bit_depth; png_read_info(pngh->png_ptr, pngh->info_ptr); - - width = png_get_image_width(pngh->png_ptr, pngh->info_ptr); - height = png_get_image_height(pngh->png_ptr, pngh->info_ptr); - color_type = MapPngColor(png_get_color_type(pngh->png_ptr, pngh->info_ptr)); - bit_depth = png_get_bit_depth(pngh->png_ptr, pngh->info_ptr); + const u32 width = png_get_image_width(pngh->png_ptr, pngh->info_ptr); + const u32 height = png_get_image_height(pngh->png_ptr, pngh->info_ptr); + const auto color_type = MapPngColor(png_get_color_type(pngh->png_ptr, pngh->info_ptr)); + const auto bit_depth = png_get_bit_depth(pngh->png_ptr, pngh->info_ptr); if (imageInfo != nullptr) { - imageInfo->bitDepth = bit_depth; - imageInfo->imageWidth = width; - imageInfo->imageHeight = height; - imageInfo->colorSpace = color_type; - imageInfo->imageFlag = 0; + imageInfo->bit_depth = bit_depth; + imageInfo->image_width = width; + imageInfo->image_height = height; + imageInfo->color_space = color_type; + imageInfo->image_flag = OrbisPngDecImageFlag::None; if (png_get_interlace_type(pngh->png_ptr, pngh->info_ptr) == 1) { - imageInfo->imageFlag |= OrbisPngDecImageFlag::ORBIS_PNG_DEC_IMAGE_FLAG_ADAM7_INTERLACE; + imageInfo->image_flag |= OrbisPngDecImageFlag::Adam7Interlace; } if (png_get_valid(pngh->png_ptr, pngh->info_ptr, PNG_INFO_tRNS)) { - - imageInfo->imageFlag |= ORBIS_PNG_DEC_IMAGE_FLAG_TRNS_CHUNK_EXIST; + imageInfo->image_flag |= OrbisPngDecImageFlag::TrnsChunkExist; } } - if (bit_depth == 16) + if (bit_depth == 16) { png_set_strip_16(pngh->png_ptr); - if (color_type == PNG_COLOR_TYPE_PALETTE) + } + if (color_type == OrbisPngDecColorSpace::Clut) { png_set_palette_to_rgb(pngh->png_ptr); - if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) + } + if (color_type == OrbisPngDecColorSpace::Grayscale && bit_depth < 8) { png_set_expand_gray_1_2_4_to_8(pngh->png_ptr); - if (png_get_valid(pngh->png_ptr, pngh->info_ptr, PNG_INFO_tRNS)) + } + if (png_get_valid(pngh->png_ptr, pngh->info_ptr, PNG_INFO_tRNS)) { png_set_tRNS_to_alpha(pngh->png_ptr); - if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + } + if (color_type == OrbisPngDecColorSpace::Grayscale || + color_type == OrbisPngDecColorSpace::GrayscaleAlpha) { png_set_gray_to_rgb(pngh->png_ptr); - if (param->pixelFormat == OrbisPngDecPixelFormat::ORBIS_PNG_DEC_PIXEL_FORMAT_B8G8R8A8) + } + if (param->pixel_format == OrbisPngDecPixelFormat::B8G8R8A8) { png_set_bgr(pngh->png_ptr); - if (color_type == PNG_COLOR_TYPE_RGB || color_type == PNG_COLOR_TYPE_GRAY || - color_type == PNG_COLOR_TYPE_PALETTE) - png_set_add_alpha(pngh->png_ptr, param->alphaValue, PNG_FILLER_AFTER); + } + if (color_type == OrbisPngDecColorSpace::Rgb || + color_type == OrbisPngDecColorSpace::Grayscale || + color_type == OrbisPngDecColorSpace::Clut) { + png_set_add_alpha(pngh->png_ptr, param->alpha_value, PNG_FILLER_AFTER); + } - int pass = png_set_interlace_handling(pngh->png_ptr); + const s32 pass = png_set_interlace_handling(pngh->png_ptr); png_read_update_info(pngh->png_ptr, pngh->info_ptr); - auto const numChannels = png_get_channels(pngh->png_ptr, pngh->info_ptr); - auto horizontal_bytes = numChannels * width; + const s32 num_channels = png_get_channels(pngh->png_ptr, pngh->info_ptr); + const s32 horizontal_bytes = num_channels * width; + const s32 stride = param->image_pitch > 0 ? param->image_pitch : horizontal_bytes; - int stride = param->imagePitch > 0 ? param->imagePitch : horizontal_bytes; - - for (int j = 0; j < pass; j++) { // interlaced - auto ptr = (png_bytep)param->imageMemAddr; + for (int j = 0; j < pass; j++) { + auto ptr = reinterpret_cast(param->image_mem_addr); for (int y = 0; y < height; y++) { png_read_row(pngh->png_ptr, ptr, nullptr); ptr += stride; @@ -196,7 +195,7 @@ s32 PS4_SYSV_ABI scePngDecParseHeader(const OrbisPngDecParseParam* param, } u8 header[8]; - memcpy(header, param->pngMemAddr, 8); + memcpy(header, param->png_mem_addr, 8); // Check if the header indicates a valid PNG file if (png_sig_cmp(header, 0, 8)) { LOG_ERROR(Lib_Png, "Memory doesn't contain a valid png file"); @@ -209,18 +208,14 @@ s32 PS4_SYSV_ABI scePngDecParseHeader(const OrbisPngDecParseParam* param, // Create a libpng info structure auto info_ptr = png_create_info_struct(png_ptr); - struct pngstruct { - const u8* data; - size_t size; - u64 offset; - } pngdata = { - .data = (const u8*)param->pngMemAddr, - .size = param->pngMemSize, + const auto pngdata = PngStruct{ + .data = param->png_mem_addr, + .size = param->png_mem_size, .offset = 0, }; png_set_read_fn(png_ptr, (void*)&pngdata, [](png_structp ps, png_bytep data, png_size_t len) { - auto pngdata = (pngstruct*)png_get_io_ptr(ps); + auto pngdata = (PngStruct*)png_get_io_ptr(ps); ::memcpy(data, pngdata->data + pngdata->offset, len); pngdata->offset += len; }); @@ -229,17 +224,16 @@ s32 PS4_SYSV_ABI scePngDecParseHeader(const OrbisPngDecParseParam* param, // info. png_read_info(png_ptr, info_ptr); - imageInfo->imageWidth = png_get_image_width(png_ptr, info_ptr); - imageInfo->imageHeight = png_get_image_height(png_ptr, info_ptr); - imageInfo->colorSpace = MapPngColor(png_get_color_type(png_ptr, info_ptr)); - imageInfo->bitDepth = png_get_bit_depth(png_ptr, info_ptr); - imageInfo->imageFlag = 0; + imageInfo->image_width = png_get_image_width(png_ptr, info_ptr); + imageInfo->image_height = png_get_image_height(png_ptr, info_ptr); + imageInfo->color_space = MapPngColor(png_get_color_type(png_ptr, info_ptr)); + imageInfo->bit_depth = png_get_bit_depth(png_ptr, info_ptr); + imageInfo->image_flag = OrbisPngDecImageFlag::None; if (png_get_interlace_type(png_ptr, info_ptr) == 1) { - imageInfo->imageFlag |= OrbisPngDecImageFlag::ORBIS_PNG_DEC_IMAGE_FLAG_ADAM7_INTERLACE; + imageInfo->image_flag |= OrbisPngDecImageFlag::Adam7Interlace; } if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) { - - imageInfo->imageFlag |= ORBIS_PNG_DEC_IMAGE_FLAG_TRNS_CHUNK_EXIST; + imageInfo->image_flag |= OrbisPngDecImageFlag::TrnsChunkExist; } png_destroy_read_struct(&png_ptr, &info_ptr, nullptr); @@ -260,8 +254,8 @@ s32 PS4_SYSV_ABI scePngDecQueryMemorySize(const OrbisPngDecCreateParam* param) { LOG_ERROR(Lib_Png, "Invalid attribute! attribute = {}", param->attribute); return ORBIS_PNG_DEC_ERROR_INVALID_ADDR; } - if (param->maxImageWidth - 1 > 1000000) { - LOG_ERROR(Lib_Png, "Invalid size! width = {}", param->maxImageWidth); + if (param->max_image_width - 1 > 1000000) { + LOG_ERROR(Lib_Png, "Invalid size! width = {}", param->max_image_width); return ORBIS_PNG_DEC_ERROR_INVALID_SIZE; } return sizeof(PngHandler); @@ -279,4 +273,4 @@ void RegisterlibScePngDec(Core::Loader::SymbolsResolver* sym) { scePngDecDecodeWithInputControl); }; -} // namespace Libraries::PngDec \ No newline at end of file +} // namespace Libraries::PngDec diff --git a/src/core/libraries/libpng/pngdec.h b/src/core/libraries/libpng/pngdec.h index 9d807166c..c897d7c95 100644 --- a/src/core/libraries/libpng/pngdec.h +++ b/src/core/libraries/libpng/pngdec.h @@ -3,6 +3,7 @@ #pragma once +#include "common/enum.h" #include "common/types.h" namespace Core::Loader { @@ -11,59 +12,61 @@ class SymbolsResolver; namespace Libraries::PngDec { -enum OrbisPngDecColorSpace { - ORBIS_PNG_DEC_COLOR_SPACE_GRAYSCALE = 2, - ORBIS_PNG_DEC_COLOR_SPACE_RGB, - ORBIS_PNG_DEC_COLOR_SPACE_CLUT, - ORBIS_PNG_DEC_COLOR_SPACE_GRAYSCALE_ALPHA = 18, - ORBIS_PNG_DEC_COLOR_SPACE_RGBA +enum class OrbisPngDecColorSpace : u16 { + Grayscale = 2, + Rgb, + Clut, + GrayscaleAlpha = 18, + Rgba, }; -enum OrbisPngDecImageFlag { - ORBIS_PNG_DEC_IMAGE_FLAG_ADAM7_INTERLACE = 1, - ORBIS_PNG_DEC_IMAGE_FLAG_TRNS_CHUNK_EXIST = 2 +enum class OrbisPngDecImageFlag : u32 { + None = 0, + Adam7Interlace = 1, + TrnsChunkExist = 2, +}; +DECLARE_ENUM_FLAG_OPERATORS(OrbisPngDecImageFlag) + +enum class OrbisPngDecPixelFormat : u16 { + R8G8B8A8 = 0, + B8G8R8A8, }; -enum OrbisPngDecPixelFormat { - ORBIS_PNG_DEC_PIXEL_FORMAT_R8G8B8A8 = 0, - ORBIS_PNG_DEC_PIXEL_FORMAT_B8G8R8A8 -}; - -enum OrbisPngDecAttribute { - ORBIS_PNG_DEC_ATTRIBUTE_NONE = 0, - ORBIS_PNG_DEC_ATTRIBUTE_BIT_DEPTH_16 +enum class OrbisPngDecAttribute { + None = 0, + BitDepth16, }; struct OrbisPngDecParseParam { - const void* pngMemAddr; - u32 pngMemSize; + const u8* png_mem_addr; + u32 png_mem_size; u32 reserved; }; struct OrbisPngDecImageInfo { - u32 imageWidth; - u32 imageHeight; - u16 colorSpace; - u16 bitDepth; - u32 imageFlag; + u32 image_width; + u32 image_height; + OrbisPngDecColorSpace color_space; + u16 bit_depth; + OrbisPngDecImageFlag image_flag; }; struct OrbisPngDecCreateParam { - u32 thisSize; + u32 this_size; u32 attribute; - u32 maxImageWidth; + u32 max_image_width; }; -typedef void* OrbisPngDecHandle; +using OrbisPngDecHandle = void*; struct OrbisPngDecDecodeParam { - const void* pngMemAddr; - void* imageMemAddr; - u32 pngMemSize; - u32 imageMemSize; - u16 pixelFormat; - u16 alphaValue; - u32 imagePitch; + const u8* png_mem_addr; + u8* image_mem_addr; + u32 png_mem_size; + u32 image_mem_size; + OrbisPngDecPixelFormat pixel_format; + u16 alpha_value; + u32 image_pitch; }; s32 PS4_SYSV_ABI scePngDecCreate(const OrbisPngDecCreateParam* param, void* memoryAddress, @@ -77,4 +80,4 @@ s32 PS4_SYSV_ABI scePngDecParseHeader(const OrbisPngDecParseParam* param, s32 PS4_SYSV_ABI scePngDecQueryMemorySize(const OrbisPngDecCreateParam* param); void RegisterlibScePngDec(Core::Loader::SymbolsResolver* sym); -} // namespace Libraries::PngDec \ No newline at end of file +} // namespace Libraries::PngDec diff --git a/src/core/libraries/libpng/pngdec_error.h b/src/core/libraries/libpng/pngdec_error.h new file mode 100644 index 000000000..9745ed5d1 --- /dev/null +++ b/src/core/libraries/libpng/pngdec_error.h @@ -0,0 +1,17 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/libraries/error_codes.h" + +// PngDec library +constexpr int ORBIS_PNG_DEC_ERROR_INVALID_ADDR = 0x80690001; +constexpr int ORBIS_PNG_DEC_ERROR_INVALID_SIZE = 0x80690002; +constexpr int ORBIS_PNG_DEC_ERROR_INVALID_PARAM = 0x80690003; +constexpr int ORBIS_PNG_DEC_ERROR_INVALID_HANDLE = 0x80690004; +constexpr int ORBIS_PNG_DEC_ERROR_INVALID_WORK_MEMORY = 0x80690005; +constexpr int ORBIS_PNG_DEC_ERROR_INVALID_DATA = 0x80690010; +constexpr int ORBIS_PNG_DEC_ERROR_UNSUPPORT_DATA = 0x80690011; +constexpr int ORBIS_PNG_DEC_ERROR_DECODE_ERROR = 0x80690012; +constexpr int ORBIS_PNG_DEC_ERROR_FATAL = 0x80690020; diff --git a/src/core/libraries/network/netctl.h b/src/core/libraries/network/netctl.h index 4482729a3..4992fffa9 100644 --- a/src/core/libraries/network/netctl.h +++ b/src/core/libraries/network/netctl.h @@ -23,7 +23,7 @@ constexpr int ORBIS_NET_CTL_HOSTNAME_LEN = 255 + 1; constexpr int ORBIS_NET_CTL_AUTH_NAME_LEN = 127 + 1; constexpr int ORBIS_NET_CTL_IPV4_ADDR_STR_LEN = 16; -typedef union OrbisNetCtlInfo { +union OrbisNetCtlInfo { u32 device; OrbisNetEtherAddr ether_addr; u32 mtu; @@ -45,7 +45,7 @@ typedef union OrbisNetCtlInfo { u32 http_proxy_config; char http_proxy_server[ORBIS_NET_CTL_HOSTNAME_LEN]; u16 http_proxy_port; -} SceNetCtlInfo; +}; // GetInfo codes constexpr int ORBIS_NET_CTL_INFO_DEVICE = 1; diff --git a/src/core/libraries/ngs2/ngs2.cpp b/src/core/libraries/ngs2/ngs2.cpp index b66c9b15b..7eb663413 100644 --- a/src/core/libraries/ngs2/ngs2.cpp +++ b/src/core/libraries/ngs2/ngs2.cpp @@ -1,13 +1,12 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "ngs2.h" -#include "ngs2_error.h" -#include "ngs2_impl.h" - #include "common/logging/log.h" #include "core/libraries/error_codes.h" #include "core/libraries/libs.h" +#include "core/libraries/ngs2/ngs2.h" +#include "core/libraries/ngs2/ngs2_error.h" +#include "core/libraries/ngs2/ngs2_impl.h" namespace Libraries::Ngs2 { @@ -416,4 +415,4 @@ void RegisterlibSceNgs2(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("AbYvTOZ8Pts", "libSceNgs2", 1, "libSceNgs2", 1, 1, sceNgs2VoiceRunCommands); }; -} // namespace Libraries::Ngs2 \ No newline at end of file +} // namespace Libraries::Ngs2 diff --git a/src/core/libraries/ngs2/ngs2.h b/src/core/libraries/ngs2/ngs2.h index 0df83f565..a5f1f52a6 100644 --- a/src/core/libraries/ngs2/ngs2.h +++ b/src/core/libraries/ngs2/ngs2.h @@ -3,10 +3,8 @@ #pragma once -#include "common/types.h" - #include -#include +#include "common/types.h" namespace Core::Loader { class SymbolsResolver; @@ -18,7 +16,9 @@ class Ngs2; using SceNgs2Handle = Ngs2*; -enum SceNgs2HandleType { SCE_NGS2_HANDLE_TYPE_SYSTEM = 0 }; +enum class SceNgs2HandleType : u32 { + System = 0, +}; struct Ngs2Handle { void* selfPointer; @@ -69,4 +69,5 @@ struct StackBuffer { }; void RegisterlibSceNgs2(Core::Loader::SymbolsResolver* sym); -} // namespace Libraries::Ngs2 \ No newline at end of file + +} // namespace Libraries::Ngs2 diff --git a/src/core/libraries/np_manager/np_manager.cpp b/src/core/libraries/np_manager/np_manager.cpp index 00070ef89..ec9cc6bf5 100644 --- a/src/core/libraries/np_manager/np_manager.cpp +++ b/src/core/libraries/np_manager/np_manager.cpp @@ -971,12 +971,11 @@ int PS4_SYSV_ABI sceNpGetGamePresenceStatusA() { return ORBIS_OK; } -int PS4_SYSV_ABI sceNpGetNpId(OrbisUserServiceUserId userId, OrbisNpId* npId) { - LOG_INFO(Lib_NpManager, "userId {}", userId); - std::string name = Config::getUserName(); - // Fill the unused stuffs to 0 - memset(npId, 0, sizeof(*npId)); - strcpy(npId->handle.data, name.c_str()); +int PS4_SYSV_ABI sceNpGetNpId(OrbisUserServiceUserId user_id, OrbisNpId* np_id) { + LOG_INFO(Lib_NpManager, "user_id {}", user_id); + const auto name = Config::getUserName(); + std::memset(np_id, 0, sizeof(OrbisNpId)); + name.copy(np_id->handle.data, sizeof(np_id->handle.data)); return ORBIS_OK; } @@ -985,12 +984,11 @@ int PS4_SYSV_ABI sceNpGetNpReachabilityState() { return ORBIS_OK; } -int PS4_SYSV_ABI sceNpGetOnlineId(s32 userId, OrbisNpOnlineId* onlineId) { - LOG_DEBUG(Lib_NpManager, "userId {}", userId); - std::string name = Config::getUserName(); - // Fill the unused stuffs to 0 - memset(onlineId, 0, sizeof(*onlineId)); - strcpy(onlineId->data, name.c_str()); +int PS4_SYSV_ABI sceNpGetOnlineId(s32 user_id, OrbisNpOnlineId* online_id) { + LOG_DEBUG(Lib_NpManager, "user_id {}", user_id); + const auto name = Config::getUserName(); + std::memset(online_id, 0, sizeof(OrbisNpOnlineId)); + name.copy(online_id->data, sizeof(online_id->data)); return ORBIS_OK; } @@ -1005,7 +1003,7 @@ int PS4_SYSV_ABI sceNpGetParentalControlInfoA() { } int PS4_SYSV_ABI sceNpGetState(s32 userId, OrbisNpState* state) { - *state = ORBIS_NP_STATE_SIGNED_OUT; + *state = OrbisNpState::SignedOut; LOG_DEBUG(Lib_NpManager, "Signed out"); return ORBIS_OK; } @@ -2518,7 +2516,7 @@ struct NpStateCallbackForNpToolkit { NpStateCallbackForNpToolkit NpStateCbForNp; int PS4_SYSV_ABI sceNpCheckCallbackForLib() { - Core::ExecuteGuest(NpStateCbForNp.func, 1, ORBIS_NP_STATE_SIGNED_OUT, NpStateCbForNp.userdata); + Core::ExecuteGuest(NpStateCbForNp.func, 1, OrbisNpState::SignedOut, NpStateCbForNp.userdata); return ORBIS_OK; } diff --git a/src/core/libraries/np_manager/np_manager.h b/src/core/libraries/np_manager/np_manager.h index 7e906cdc8..6ba588e5e 100644 --- a/src/core/libraries/np_manager/np_manager.h +++ b/src/core/libraries/np_manager/np_manager.h @@ -13,18 +13,14 @@ namespace Libraries::NpManager { constexpr int ORBIS_NP_ERROR_SIGNED_OUT = 0x80550006; -enum OrbisNpState { - ORBIS_NP_STATE_UNKNOWN = 0, - ORBIS_NP_STATE_SIGNED_OUT, - ORBIS_NP_STATE_SIGNED_IN -}; +enum class OrbisNpState : u32 { Unknown = 0, SignedOut, SignedIn }; using OrbisNpStateCallbackForNpToolkit = PS4_SYSV_ABI void (*)(s32 userId, OrbisNpState state, void* userdata); constexpr int ORBIS_NP_ONLINEID_MAX_LENGTH = 16; -typedef int OrbisUserServiceUserId; +using OrbisUserServiceUserId = s32; struct OrbisNpOnlineId { char data[ORBIS_NP_ONLINEID_MAX_LENGTH]; @@ -542,4 +538,4 @@ int PS4_SYSV_ABI sceNpRegisterStateCallbackForToolkit(OrbisNpStateCallbackForNpT int PS4_SYSV_ABI sceNpUnregisterStateCallbackForToolkit(); void RegisterlibSceNpManager(Core::Loader::SymbolsResolver* sym); -} // namespace Libraries::NpManager \ No newline at end of file +} // namespace Libraries::NpManager diff --git a/src/core/libraries/np_trophy/np_trophy.cpp b/src/core/libraries/np_trophy/np_trophy.cpp index e8fd57ef1..9324ed6bb 100644 --- a/src/core/libraries/np_trophy/np_trophy.cpp +++ b/src/core/libraries/np_trophy/np_trophy.cpp @@ -7,10 +7,10 @@ #include "common/logging/log.h" #include "common/path_util.h" #include "common/slot_vector.h" -#include "core/libraries/error_codes.h" #include "core/libraries/libs.h" -#include "np_trophy.h" -#include "trophy_ui.h" +#include "core/libraries/np_trophy/np_trophy.h" +#include "core/libraries/np_trophy/np_trophy_error.h" +#include "core/libraries/np_trophy/trophy_ui.h" namespace Libraries::NpTrophy { diff --git a/src/core/libraries/np_trophy/np_trophy.h b/src/core/libraries/np_trophy/np_trophy.h index ac13a9ab7..9abc795bc 100644 --- a/src/core/libraries/np_trophy/np_trophy.h +++ b/src/core/libraries/np_trophy/np_trophy.h @@ -29,14 +29,14 @@ constexpr int ORBIS_NP_TROPHY_INVALID_HANDLE = -1; constexpr int ORBIS_NP_TROPHY_INVALID_CONTEXT = -1; constexpr int ORBIS_NP_TROPHY_INVALID_TROPHY_ID = -1; -typedef int32_t OrbisNpTrophyHandle; -typedef int32_t OrbisNpTrophyContext; -typedef int32_t OrbisNpTrophyId; -typedef uint32_t OrbisNpTrophyFlagMask; +using OrbisNpTrophyHandle = s32; +using OrbisNpTrophyContext = s32; +using OrbisNpTrophyId = s32; +using OrbisNpTrophyFlagMask = u32; struct OrbisNpTrophyFlagArray { - OrbisNpTrophyFlagMask - flag_bits[ORBIS_NP_TROPHY_FLAG_SETSIZE >> ORBIS_NP_TROPHY_FLAG_BITS_SHIFT]; + static constexpr int NumMasks = ORBIS_NP_TROPHY_FLAG_SETSIZE >> ORBIS_NP_TROPHY_FLAG_BITS_SHIFT; + std::array flag_bits; }; void ORBIS_NP_TROPHY_FLAG_ZERO(OrbisNpTrophyFlagArray* p); @@ -49,18 +49,18 @@ struct OrbisNpTrophyData { size_t size; OrbisNpTrophyId trophy_id; bool unlocked; - uint8_t reserved[3]; + u8 reserved[3]; Rtc::OrbisRtcTick timestamp; }; -typedef int32_t OrbisNpTrophyGrade; +using OrbisNpTrophyGrade = s32; constexpr int ORBIS_NP_TROPHY_GRADE_UNKNOWN = 0; constexpr int ORBIS_NP_TROPHY_GRADE_PLATINUM = 1; constexpr int ORBIS_NP_TROPHY_GRADE_GOLD = 2; constexpr int ORBIS_NP_TROPHY_GRADE_SILVER = 3; constexpr int ORBIS_NP_TROPHY_GRADE_BRONZE = 4; -typedef int32_t OrbisNpTrophyGroupId; +using OrbisNpTrophyGroupId = s32; constexpr int ORBIS_NP_TROPHY_BASE_GAME_GROUP_ID = -1; constexpr int ORBIS_NP_TROPHY_INVALID_GROUP_ID = -2; @@ -70,29 +70,29 @@ struct OrbisNpTrophyDetails { OrbisNpTrophyGrade trophy_grade; OrbisNpTrophyGroupId group_id; bool hidden; - uint8_t reserved[3]; + u8 reserved[3]; char name[ORBIS_NP_TROPHY_NAME_MAX_SIZE]; char description[ORBIS_NP_TROPHY_DESCR_MAX_SIZE]; }; struct OrbisNpTrophyGameData { size_t size; - uint32_t unlocked_trophies; - uint32_t unlocked_platinum; - uint32_t unlocked_gold; - uint32_t unlocked_silver; - uint32_t unlocked_bronze; - uint32_t progress_percentage; + u32 unlocked_trophies; + u32 unlocked_platinum; + u32 unlocked_gold; + u32 unlocked_silver; + u32 unlocked_bronze; + u32 progress_percentage; }; struct OrbisNpTrophyGameDetails { size_t size; - uint32_t num_groups; - uint32_t num_trophies; - uint32_t num_platinum; - uint32_t num_gold; - uint32_t num_silver; - uint32_t num_bronze; + u32 num_groups; + u32 num_trophies; + u32 num_platinum; + u32 num_gold; + u32 num_silver; + u32 num_bronze; char title[ORBIS_NP_TROPHY_GAME_TITLE_MAX_SIZE]; char description[ORBIS_NP_TROPHY_GAME_DESCR_MAX_SIZE]; }; @@ -100,23 +100,23 @@ struct OrbisNpTrophyGameDetails { struct OrbisNpTrophyGroupData { size_t size; OrbisNpTrophyGroupId group_id; - uint32_t unlocked_trophies; - uint32_t unlocked_platinum; - uint32_t unlocked_gold; - uint32_t unlocked_silver; - uint32_t unlocked_bronze; - uint32_t progress_percentage; + u32 unlocked_trophies; + u32 unlocked_platinum; + u32 unlocked_gold; + u32 unlocked_silver; + u32 unlocked_bronze; + u32 progress_percentage; uint8_t reserved[4]; }; struct OrbisNpTrophyGroupDetails { size_t size; OrbisNpTrophyGroupId group_id; - uint32_t num_trophies; - uint32_t num_platinum; - uint32_t num_gold; - uint32_t num_silver; - uint32_t num_bronze; + u32 num_trophies; + u32 num_platinum; + u32 num_gold; + u32 num_silver; + u32 num_bronze; char title[ORBIS_NP_TROPHY_GROUP_TITLE_MAX_SIZE]; char description[ORBIS_NP_TROPHY_GROUP_DESCR_MAX_SIZE]; }; @@ -133,7 +133,7 @@ int PS4_SYSV_ABI sceNpTrophyConfigGetTrophySetVersion(); int PS4_SYSV_ABI sceNpTrophyConfigGetTrophyTitleDetails(); int PS4_SYSV_ABI sceNpTrophyConfigHasGroupFeature(); s32 PS4_SYSV_ABI sceNpTrophyCreateContext(OrbisNpTrophyContext* context, int32_t user_id, - uint32_t service_label, uint64_t options); + u32 service_label, uint64_t options); s32 PS4_SYSV_ABI sceNpTrophyCreateHandle(OrbisNpTrophyHandle* handle); int PS4_SYSV_ABI sceNpTrophyDestroyContext(OrbisNpTrophyContext context); s32 PS4_SYSV_ABI sceNpTrophyDestroyHandle(OrbisNpTrophyHandle handle); diff --git a/src/core/libraries/np_trophy/np_trophy_error.h b/src/core/libraries/np_trophy/np_trophy_error.h new file mode 100644 index 000000000..9506d9ca4 --- /dev/null +++ b/src/core/libraries/np_trophy/np_trophy_error.h @@ -0,0 +1,49 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/libraries/error_codes.h" + +// NpTrophy library +constexpr int ORBIS_NP_TROPHY_ERROR_UNKNOWN = 0x80551600; +constexpr int ORBIS_NP_TROPHY_ERROR_NOT_INITIALIZED = 0x80551601; +constexpr int ORBIS_NP_TROPHY_ERROR_ALREADY_INITIALIZED = 0x80551602; +constexpr int ORBIS_NP_TROPHY_ERROR_OUT_OF_MEMORY = 0x80551603; +constexpr int ORBIS_NP_TROPHY_ERROR_INVALID_ARGUMENT = 0x80551604; +constexpr int ORBIS_NP_TROPHY_ERROR_INSUFFICIENT_BUFFER = 0x80551605; +constexpr int ORBIS_NP_TROPHY_ERROR_EXCEEDS_MAX = 0x80551606; +constexpr int ORBIS_NP_TROPHY_ERROR_ABORT = 0x80551607; +constexpr int ORBIS_NP_TROPHY_ERROR_INVALID_HANDLE = 0x80551608; +constexpr int ORBIS_NP_TROPHY_ERROR_INVALID_CONTEXT = 0x80551609; +constexpr int ORBIS_NP_TROPHY_ERROR_INVALID_TROPHY_ID = 0x8055160A; +constexpr int ORBIS_NP_TROPHY_ERROR_INVALID_GROUP_ID = 0x8055160B; +constexpr int ORBIS_NP_TROPHY_ERROR_TROPHY_ALREADY_UNLOCKED = 0x8055160C; +constexpr int ORBIS_NP_TROPHY_ERROR_PLATINUM_CANNOT_UNLOCK = 0x8055160D; +constexpr int ORBIS_NP_TROPHY_ERROR_ACCOUNTID_NOT_MATCH = 0x8055160E; +constexpr int ORBIS_NP_TROPHY_ERROR_NOT_REGISTERED = 0x8055160F; +constexpr int ORBIS_NP_TROPHY_ERROR_ALREADY_REGISTERED = 0x80551610; +constexpr int ORBIS_NP_TROPHY_ERROR_BROKEN_DATA = 0x80551611; +constexpr int ORBIS_NP_TROPHY_ERROR_INSUFFICIENT_SPACE = 0x80551612; +constexpr int ORBIS_NP_TROPHY_ERROR_CONTEXT_ALREADY_EXISTS = 0x80551613; +constexpr int ORBIS_NP_TROPHY_ERROR_ICON_FILE_NOT_FOUND = 0x80551614; +constexpr int ORBIS_NP_TROPHY_ERROR_INVALID_TRP_FILE_FORMAT = 0x80551616; +constexpr int ORBIS_NP_TROPHY_ERROR_UNSUPPORTED_TRP_FILE = 0x80551617; +constexpr int ORBIS_NP_TROPHY_ERROR_INVALID_TROPHY_CONF_FORMAT = 0x80551618; +constexpr int ORBIS_NP_TROPHY_ERROR_UNSUPPORTED_TROPHY_CONF = 0x80551619; +constexpr int ORBIS_NP_TROPHY_ERROR_TROPHY_NOT_UNLOCKED = 0x8055161A; +constexpr int ORBIS_NP_TROPHY_ERROR_USER_NOT_FOUND = 0x8055161C; +constexpr int ORBIS_NP_TROPHY_ERROR_USER_NOT_LOGGED_IN = 0x8055161D; +constexpr int ORBIS_NP_TROPHY_ERROR_CONTEXT_USER_LOGOUT = 0x8055161E; +constexpr int ORBIS_NP_TROPHY_ERROR_USE_TRP_FOR_DEVELOPMENT = 0x8055161F; +constexpr int ORBIS_NP_TROPHY_ERROR_INVALID_NP_SERVICE_LABEL = 0x80551621; +constexpr int ORBIS_NP_TROPHY_ERROR_NOT_SUPPORTED = 0x80551622; +constexpr int ORBIS_NP_TROPHY_ERROR_CONTEXT_EXCEEDS_MAX = 0x80551623; +constexpr int ORBIS_NP_TROPHY_ERROR_HANDLE_EXCEEDS_MAX = 0x80551624; +constexpr int ORBIS_NP_TROPHY_ERROR_INVALID_USER_ID = 0x80551625; +constexpr int ORBIS_NP_TROPHY_ERROR_TITLE_CONF_NOT_INSTALLED = 0x80551626; +constexpr int ORBIS_NP_TROPHY_ERROR_BROKEN_TITLE_CONF = 0x80551627; +constexpr int ORBIS_NP_TROPHY_ERROR_INCONSISTENT_TITLE_CONF = 0x80551628; +constexpr int ORBIS_NP_TROPHY_ERROR_TITLE_BACKGROUND = 0x80551629; +constexpr int ORBIS_NP_TROPHY_ERROR_SCREENSHOT_DISABLED = 0x8055162B; +constexpr int ORBIS_NP_TROPHY_ERROR_SCREENSHOT_DISPLAY_BUFFER_NOT_IN_USE = 0x8055162D; diff --git a/src/core/libraries/pad/pad.cpp b/src/core/libraries/pad/pad.cpp index a1897d047..ec4186f11 100644 --- a/src/core/libraries/pad/pad.cpp +++ b/src/core/libraries/pad/pad.cpp @@ -1,12 +1,11 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "common/assert.h" #include "common/config.h" #include "common/logging/log.h" #include "common/singleton.h" -#include "core/libraries/error_codes.h" #include "core/libraries/libs.h" +#include "core/libraries/pad/pad_errors.h" #include "input/controller.h" #include "pad.h" @@ -99,8 +98,8 @@ int PS4_SYSV_ABI scePadGetControllerInformation(s32 handle, OrbisPadControllerIn pInfo->connectionType = ORBIS_PAD_PORT_TYPE_STANDARD; pInfo->connectedCount = 1; pInfo->connected = false; - pInfo->deviceClass = ORBIS_PAD_DEVICE_CLASS_STANDARD; - return SCE_OK; + pInfo->deviceClass = OrbisPadDeviceClass::Standard; + return ORBIS_OK; } pInfo->touchPadInfo.pixelDensity = 1; pInfo->touchPadInfo.resolution.x = 1920; @@ -110,12 +109,12 @@ int PS4_SYSV_ABI scePadGetControllerInformation(s32 handle, OrbisPadControllerIn pInfo->connectionType = ORBIS_PAD_PORT_TYPE_STANDARD; pInfo->connectedCount = 1; pInfo->connected = true; - pInfo->deviceClass = ORBIS_PAD_DEVICE_CLASS_STANDARD; + pInfo->deviceClass = OrbisPadDeviceClass::Standard; if (Config::getUseSpecialPad()) { pInfo->connectionType = ORBIS_PAD_PORT_TYPE_SPECIAL; pInfo->deviceClass = (OrbisPadDeviceClass)Config::getSpecialPadClass(); } - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI scePadGetDataInternal() { @@ -382,7 +381,7 @@ int PS4_SYSV_ABI scePadReadState(s32 handle, OrbisPadData* pData) { pData->connectedCount = 1; // connectedCount; pData->deviceUniqueDataLen = 0; - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI scePadReadStateExt() { diff --git a/src/core/libraries/pad/pad.h b/src/core/libraries/pad/pad.h index f94a642cf..68943b460 100644 --- a/src/core/libraries/pad/pad.h +++ b/src/core/libraries/pad/pad.h @@ -3,6 +3,7 @@ #pragma once +#include "common/enum.h" #include "common/types.h" namespace Core::Loader { @@ -18,18 +19,18 @@ constexpr int ORBIS_PAD_PORT_TYPE_STANDARD = 0; constexpr int ORBIS_PAD_PORT_TYPE_SPECIAL = 2; constexpr int ORBIS_PAD_PORT_TYPE_REMOTE_CONTROL = 16; -enum OrbisPadDeviceClass { - ORBIS_PAD_DEVICE_CLASS_INVALID = -1, - ORBIS_PAD_DEVICE_CLASS_STANDARD = 0, - ORBIS_PAD_DEVICE_CLASS_GUITAR = 1, - ORBIS_PAD_DEVICE_CLASS_DRUM = 2, - ORBIS_PAD_DEVICE_CLASS_DJ_TURNTABLE = 3, - ORBIS_PAD_DEVICE_CLASS_DANCEMAT = 4, - ORBIS_PAD_DEVICE_CLASS_NAVIGATION = 5, - ORBIS_PAD_DEVICE_CLASS_STEERING_WHEEL = 6, - ORBIS_PAD_DEVICE_CLASS_STICK = 7, - ORBIS_PAD_DEVICE_CLASS_FLIGHT_STICK = 8, - ORBIS_PAD_DEVICE_CLASS_GUN = 9, +enum class OrbisPadDeviceClass { + Invalid = -1, + Standard = 0, + Guitar = 1, + Drum = 2, + DjTurntable = 3, + Dancemat = 4, + Navigation = 5, + SteeringWheel = 6, + Stick = 7, + FightStick = 8, + Gun = 9, }; struct OrbisPadDeviceClassExtendedInformation { @@ -123,25 +124,27 @@ struct OrbisPadAnalogStick { u8 y; }; -enum OrbisPadButtonDataOffset { - ORBIS_PAD_BUTTON_L3 = 0x00000002, - ORBIS_PAD_BUTTON_R3 = 0x00000004, - ORBIS_PAD_BUTTON_OPTIONS = 0x00000008, - ORBIS_PAD_BUTTON_UP = 0x00000010, - ORBIS_PAD_BUTTON_RIGHT = 0x00000020, - ORBIS_PAD_BUTTON_DOWN = 0x00000040, - ORBIS_PAD_BUTTON_LEFT = 0x00000080, - ORBIS_PAD_BUTTON_L2 = 0x00000100, - ORBIS_PAD_BUTTON_R2 = 0x00000200, - ORBIS_PAD_BUTTON_L1 = 0x00000400, - ORBIS_PAD_BUTTON_R1 = 0x00000800, - ORBIS_PAD_BUTTON_TRIANGLE = 0x00001000, - ORBIS_PAD_BUTTON_CIRCLE = 0x00002000, - ORBIS_PAD_BUTTON_CROSS = 0x00004000, - ORBIS_PAD_BUTTON_SQUARE = 0x00008000, - ORBIS_PAD_BUTTON_TOUCH_PAD = 0x00100000, - ORBIS_PAD_BUTTON_INTERCEPTED = 0x80000000, +enum class OrbisPadButtonDataOffset : u32 { + None = 0, + L3 = 0x2, + R3 = 0x4, + Options = 0x8, + Up = 0x10, + Right = 0x20, + Down = 0x40, + Left = 0x80, + L2 = 0x100, + R2 = 0x200, + L1 = 0x400, + R1 = 0x800, + Triangle = 0x1000, + Circle = 0x2000, + Cross = 0x4000, + Square = 0x8000, + TouchPad = 0x100000, + Intercepted = 0x80000000, }; +DECLARE_ENUM_FLAG_OPERATORS(OrbisPadButtonDataOffset) struct OrbisFQuaternion { float x, y, z, w; @@ -173,7 +176,7 @@ struct OrbisPadExtensionUnitData { }; struct OrbisPadData { - u32 buttons; + OrbisPadButtonDataOffset buttons; OrbisPadAnalogStick leftStick; OrbisPadAnalogStick rightStick; OrbisPadAnalogButtons analogButtons; @@ -346,4 +349,4 @@ int PS4_SYSV_ABI Func_89C9237E393DA243(); int PS4_SYSV_ABI Func_EF103E845B6F0420(); void RegisterlibScePad(Core::Loader::SymbolsResolver* sym); -} // namespace Libraries::Pad \ No newline at end of file +} // namespace Libraries::Pad diff --git a/src/core/libraries/pad/pad_errors.h b/src/core/libraries/pad/pad_errors.h new file mode 100644 index 000000000..182c89219 --- /dev/null +++ b/src/core/libraries/pad/pad_errors.h @@ -0,0 +1,22 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/libraries/error_codes.h" + +// Pad library +constexpr int ORBIS_PAD_ERROR_INVALID_ARG = 0x80920001; +constexpr int ORBIS_PAD_ERROR_INVALID_PORT = 0x80920002; +constexpr int ORBIS_PAD_ERROR_INVALID_HANDLE = 0x80920003; +constexpr int ORBIS_PAD_ERROR_ALREADY_OPENED = 0x80920004; +constexpr int ORBIS_PAD_ERROR_NOT_INITIALIZED = 0x80920005; +constexpr int ORBIS_PAD_ERROR_INVALID_LIGHTBAR_SETTING = 0x80920006; +constexpr int ORBIS_PAD_ERROR_DEVICE_NOT_CONNECTED = 0x80920007; +constexpr int ORBIS_PAD_ERROR_DEVICE_NO_HANDLE = 0x80920008; +constexpr int ORBIS_PAD_ERROR_FATAL = 0x809200FF; +constexpr int ORBIS_PAD_ERROR_NOT_PERMITTED = 0x80920101; +constexpr int ORBIS_PAD_ERROR_INVALID_BUFFER_LENGTH = 0x80920102; +constexpr int ORBIS_PAD_ERROR_INVALID_REPORT_LENGTH = 0x80920103; +constexpr int ORBIS_PAD_ERROR_INVALID_REPORT_ID = 0x80920104; +constexpr int ORBIS_PAD_ERROR_SEND_AGAIN = 0x80920105; diff --git a/src/core/libraries/playgo/playgo.cpp b/src/core/libraries/playgo/playgo.cpp index d4f5c6b7c..6fcf875da 100644 --- a/src/core/libraries/playgo/playgo.cpp +++ b/src/core/libraries/playgo/playgo.cpp @@ -2,7 +2,6 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "common/logging/log.h" -#include "common/singleton.h" #include "core/file_format/playgo_chunk.h" #include "core/libraries/error_codes.h" #include "core/libraries/libs.h" @@ -11,6 +10,9 @@ namespace Libraries::PlayGo { +static constexpr OrbisPlayGoHandle PlaygoHandle = 1; +static std::unique_ptr playgo; + s32 PS4_SYSV_ABI sceDbgPlayGoRequestNextChunk() { LOG_ERROR(Lib_PlayGo, "(STUBBED)called"); return ORBIS_OK; @@ -24,57 +26,63 @@ s32 PS4_SYSV_ABI sceDbgPlayGoSnapshot() { s32 PS4_SYSV_ABI scePlayGoClose(OrbisPlayGoHandle handle) { LOG_INFO(Lib_PlayGo, "called"); - auto* playgo = Common::Singleton::Instance(); - - if (handle != 1) + if (handle != PlaygoHandle) { return ORBIS_PLAYGO_ERROR_BAD_HANDLE; - if (!playgo->initialized) + } + if (!playgo->initialized) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; + } + playgo.reset(); return ORBIS_OK; } s32 PS4_SYSV_ABI scePlayGoGetChunkId(OrbisPlayGoHandle handle, OrbisPlayGoChunkId* outChunkIdList, u32 numberOfEntries, u32* outEntries) { LOG_INFO(Lib_PlayGo, "called"); - auto* playgo = Common::Singleton::Instance(); - if (handle != 1) + if (handle != PlaygoHandle) { return ORBIS_PLAYGO_ERROR_BAD_HANDLE; - if (outEntries == nullptr) + } + if (outEntries == nullptr) { return ORBIS_PLAYGO_ERROR_BAD_POINTER; - if (outChunkIdList != nullptr && numberOfEntries == 0) + } + if (outChunkIdList != nullptr && numberOfEntries == 0) { return ORBIS_PLAYGO_ERROR_BAD_SIZE; + } if (playgo->GetPlaygoHeader().file_size == 0) { *outEntries = 0; - } else { - if (outChunkIdList == nullptr) { - *outEntries = playgo->chunks.size(); - } else { - if (numberOfEntries > playgo->chunks.size()) { - numberOfEntries = playgo->chunks.size(); - } - - if (numberOfEntries != 0) { - for (u32 i = 0; i < numberOfEntries; i++) { - outChunkIdList[i] = i; - } - *outEntries = numberOfEntries; - } - } + return ORBIS_OK; } + + if (outChunkIdList == nullptr) { + *outEntries = playgo->chunks.size(); + return ORBIS_OK; + } + + if (numberOfEntries > playgo->chunks.size()) { + numberOfEntries = playgo->chunks.size(); + } + + for (u32 i = 0; i < numberOfEntries; i++) { + outChunkIdList[i] = i; + } + *outEntries = numberOfEntries; return ORBIS_OK; } s32 PS4_SYSV_ABI scePlayGoGetEta(OrbisPlayGoHandle handle, const OrbisPlayGoChunkId* chunkIds, u32 numberOfEntries, OrbisPlayGoEta* outEta) { LOG_INFO(Lib_PlayGo, "called"); - if (handle != 1) + if (handle != PlaygoHandle) { return ORBIS_PLAYGO_ERROR_BAD_HANDLE; - if (chunkIds == nullptr || outEta == nullptr) + } + if (chunkIds == nullptr || outEta == nullptr) { return ORBIS_PLAYGO_ERROR_BAD_POINTER; - if (numberOfEntries == 0) + } + if (numberOfEntries == 0) { return ORBIS_PLAYGO_ERROR_BAD_SIZE; + } *outEta = 0; // all is loaded return ORBIS_OK; @@ -84,22 +92,23 @@ s32 PS4_SYSV_ABI scePlayGoGetInstallSpeed(OrbisPlayGoHandle handle, OrbisPlayGoInstallSpeed* outSpeed) { LOG_INFO(Lib_PlayGo, "called"); - auto* playgo = Common::Singleton::Instance(); - - if (handle != 1) + if (handle != PlaygoHandle) { return ORBIS_PLAYGO_ERROR_BAD_HANDLE; - if (outSpeed == nullptr) + } + if (outSpeed == nullptr) { return ORBIS_PLAYGO_ERROR_BAD_POINTER; - if (!playgo->initialized) + } + if (!playgo->initialized) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; + } std::scoped_lock lk{playgo->GetSpeedMutex()}; - if (playgo->speed == 0) { + if (playgo->speed == OrbisPlayGoInstallSpeed::Suspended) { using namespace std::chrono; if ((duration_cast(steady_clock::now().time_since_epoch()).count() - playgo->speed_tick) > 30 * 1000) { // 30sec - playgo->speed = ORBIS_PLAYGO_INSTALL_SPEED_TRICKLE; + playgo->speed = OrbisPlayGoInstallSpeed::Trickle; } } *outSpeed = playgo->speed; @@ -111,14 +120,15 @@ s32 PS4_SYSV_ABI scePlayGoGetLanguageMask(OrbisPlayGoHandle handle, OrbisPlayGoLanguageMask* outLanguageMask) { LOG_INFO(Lib_PlayGo, "called"); - auto* playgo = Common::Singleton::Instance(); - - if (handle != 1) + if (handle != PlaygoHandle) { return ORBIS_PLAYGO_ERROR_BAD_HANDLE; - if (outLanguageMask == nullptr) + } + if (outLanguageMask == nullptr) { return ORBIS_PLAYGO_ERROR_BAD_POINTER; - if (!playgo->initialized) + } + if (!playgo->initialized) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; + } *outLanguageMask = playgo->langMask; return ORBIS_OK; @@ -129,24 +139,27 @@ s32 PS4_SYSV_ABI scePlayGoGetLocus(OrbisPlayGoHandle handle, const OrbisPlayGoCh LOG_INFO(Lib_PlayGo, "called handle = {}, chunkIds = {}, numberOfEntries = {}", handle, *chunkIds, numberOfEntries); - auto* playgo = Common::Singleton::Instance(); - - if (handle != 1) + if (handle != PlaygoHandle) { return ORBIS_PLAYGO_ERROR_BAD_HANDLE; - if (chunkIds == nullptr || outLoci == nullptr) + } + if (chunkIds == nullptr || outLoci == nullptr) { return ORBIS_PLAYGO_ERROR_BAD_POINTER; - if (numberOfEntries == 0) + } + if (numberOfEntries == 0) { return ORBIS_PLAYGO_ERROR_BAD_SIZE; - if (!playgo->initialized) + } + if (!playgo->initialized) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; - if (playgo->GetPlaygoHeader().file_size == 0) + } + if (playgo->GetPlaygoHeader().file_size == 0) { return ORBIS_PLAYGO_ERROR_NOT_SUPPORT_PLAYGO; + } - for (uint32_t i = 0; i < numberOfEntries; i++) { + for (int i = 0; i < numberOfEntries; i++) { if (chunkIds[i] <= playgo->chunks.size()) { - outLoci[i] = OrbisPlayGoLocusValue::ORBIS_PLAYGO_LOCUS_LOCAL_FAST; + outLoci[i] = OrbisPlayGoLocus::LocalFast; } else { - outLoci[i] = ORBIS_PLAYGO_LOCUS_NOT_DOWNLOADED; + outLoci[i] = OrbisPlayGoLocus::NotDownloaded; return ORBIS_PLAYGO_ERROR_BAD_CHUNK_ID; } } @@ -158,18 +171,21 @@ s32 PS4_SYSV_ABI scePlayGoGetProgress(OrbisPlayGoHandle handle, const OrbisPlayG LOG_INFO(Lib_PlayGo, "called handle = {}, chunkIds = {}, numberOfEntries = {}", handle, *chunkIds, numberOfEntries); - auto* playgo = Common::Singleton::Instance(); - - if (handle != 1) + if (handle != PlaygoHandle) { return ORBIS_PLAYGO_ERROR_BAD_HANDLE; - if (chunkIds == nullptr || outProgress == nullptr) + } + if (chunkIds == nullptr || outProgress == nullptr) { return ORBIS_PLAYGO_ERROR_BAD_POINTER; - if (numberOfEntries == 0) + } + if (numberOfEntries == 0) { return ORBIS_PLAYGO_ERROR_BAD_SIZE; - if (!playgo->initialized) + } + if (!playgo->initialized) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; - if (playgo->GetPlaygoHeader().file_size == 0) + } + if (playgo->GetPlaygoHeader().file_size == 0) { return ORBIS_PLAYGO_ERROR_BAD_CHUNK_ID; + } outProgress->progressSize = 0; outProgress->totalSize = 0; @@ -194,16 +210,18 @@ s32 PS4_SYSV_ABI scePlayGoGetToDoList(OrbisPlayGoHandle handle, OrbisPlayGoToDo* u32 numberOfEntries, u32* outEntries) { LOG_INFO(Lib_PlayGo, "called handle = {} numberOfEntries = {}", handle, numberOfEntries); - auto* playgo = Common::Singleton::Instance(); - - if (handle != 1) + if (handle != PlaygoHandle) { return ORBIS_PLAYGO_ERROR_BAD_HANDLE; - if (outTodoList == nullptr || outEntries == nullptr) + } + if (outTodoList == nullptr || outEntries == nullptr) { return ORBIS_PLAYGO_ERROR_BAD_POINTER; - if (numberOfEntries == 0) + } + if (numberOfEntries == 0) { return ORBIS_PLAYGO_ERROR_BAD_SIZE; - if (!playgo->initialized) + } + if (!playgo->initialized) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; + } *outEntries = 0; // nothing to do return ORBIS_OK; } @@ -218,19 +236,19 @@ int scePlayGoConvertLanguage(int systemLang) { s32 PS4_SYSV_ABI scePlayGoInitialize(OrbisPlayGoInitParams* param) { LOG_INFO(Lib_PlayGo, "called, bufSize = {}", param->bufSize); - if (param->bufAddr == nullptr) + if (param->bufAddr == nullptr) { return ORBIS_PLAYGO_ERROR_BAD_POINTER; - if (param->bufSize < 0x200000) + } + if (param->bufSize < 0x200000) { return ORBIS_PLAYGO_ERROR_BAD_SIZE; + } - auto* playgo = Common::Singleton::Instance(); - + playgo = std::make_unique(); if (!playgo->initialized) { using namespace SystemService; - // get system lang - int systemLang = 0; - sceSystemServiceParamGetInt(ORBIS_SYSTEM_SERVICE_PARAM_ID_LANG, &systemLang); - playgo->langMask = scePlayGoConvertLanguage(systemLang); + s32 system_lang = 0; + sceSystemServiceParamGetInt(OrbisSystemServiceParamId::Lang, &system_lang); + playgo->langMask = scePlayGoConvertLanguage(system_lang); playgo->initialized = true; } else { return ORBIS_PLAYGO_ERROR_ALREADY_INITIALIZED; @@ -241,18 +259,20 @@ s32 PS4_SYSV_ABI scePlayGoInitialize(OrbisPlayGoInitParams* param) { s32 PS4_SYSV_ABI scePlayGoOpen(OrbisPlayGoHandle* outHandle, const void* param) { LOG_INFO(Lib_PlayGo, "called"); - auto* playgo = Common::Singleton::Instance(); - - if (outHandle == nullptr) + if (outHandle == nullptr) { return ORBIS_PLAYGO_ERROR_BAD_POINTER; - if (param) + } + if (param) { return ORBIS_PLAYGO_ERROR_INVALID_ARGUMENT; - if (!playgo->initialized) + } + if (!playgo->initialized) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; - if (playgo->GetPlaygoHeader().file_size == 0) + } + if (playgo->GetPlaygoHeader().file_size == 0) { return ORBIS_PLAYGO_ERROR_NOT_SUPPORT_PLAYGO; + } - playgo->handle = *outHandle = 1; + playgo->handle = *outHandle = PlaygoHandle; return ORBIS_OK; } @@ -260,21 +280,23 @@ s32 PS4_SYSV_ABI scePlayGoPrefetch(OrbisPlayGoHandle handle, const OrbisPlayGoCh u32 numberOfEntries, OrbisPlayGoLocus minimumLocus) { LOG_INFO(Lib_PlayGo, "called"); - auto* playgo = Common::Singleton::Instance(); - - if (handle != 1) + if (handle != PlaygoHandle) { return ORBIS_PLAYGO_ERROR_BAD_HANDLE; - if (chunkIds == nullptr) + } + if (chunkIds == nullptr) { return ORBIS_PLAYGO_ERROR_BAD_POINTER; - if (numberOfEntries == 0) + } + if (numberOfEntries == 0) { return ORBIS_PLAYGO_ERROR_BAD_SIZE; - if (!playgo->initialized) + } + if (!playgo->initialized) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; + } switch (minimumLocus) { - case ORBIS_PLAYGO_LOCUS_NOT_DOWNLOADED: - case ORBIS_PLAYGO_LOCUS_LOCAL_SLOW: - case ORBIS_PLAYGO_LOCUS_LOCAL_FAST: + case OrbisPlayGoLocus::NotDownloaded: + case OrbisPlayGoLocus::LocalSlow: + case OrbisPlayGoLocus::LocalFast: break; default: return ORBIS_PLAYGO_ERROR_BAD_LOCUS; @@ -285,24 +307,23 @@ s32 PS4_SYSV_ABI scePlayGoPrefetch(OrbisPlayGoHandle handle, const OrbisPlayGoCh s32 PS4_SYSV_ABI scePlayGoSetInstallSpeed(OrbisPlayGoHandle handle, OrbisPlayGoInstallSpeed speed) { LOG_INFO(Lib_PlayGo, "called"); - auto* playgo = Common::Singleton::Instance(); - - if (handle != 1) + if (handle != PlaygoHandle) { return ORBIS_PLAYGO_ERROR_BAD_HANDLE; - if (!playgo->initialized) + } + if (!playgo->initialized) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; + } switch (speed) { - case ORBIS_PLAYGO_INSTALL_SPEED_SUSPENDED: - case ORBIS_PLAYGO_INSTALL_SPEED_TRICKLE: - case ORBIS_PLAYGO_INSTALL_SPEED_FULL: + case OrbisPlayGoInstallSpeed::Suspended: + case OrbisPlayGoInstallSpeed::Trickle: + case OrbisPlayGoInstallSpeed::Full: break; default: return ORBIS_PLAYGO_ERROR_INVALID_ARGUMENT; } std::scoped_lock lk{playgo->GetSpeedMutex()}; - using namespace std::chrono; playgo->speed = speed; playgo->speed_tick = @@ -314,12 +335,13 @@ s32 PS4_SYSV_ABI scePlayGoSetInstallSpeed(OrbisPlayGoHandle handle, OrbisPlayGoI s32 PS4_SYSV_ABI scePlayGoSetLanguageMask(OrbisPlayGoHandle handle, OrbisPlayGoLanguageMask languageMask) { LOG_INFO(Lib_PlayGo, "called"); - auto* playgo = Common::Singleton::Instance(); - if (handle != 1) + if (handle != 1) { return ORBIS_PLAYGO_ERROR_BAD_HANDLE; - if (!playgo->initialized) + } + if (!playgo->initialized) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; + } playgo->langMask = languageMask; return ORBIS_OK; @@ -329,23 +351,24 @@ s32 PS4_SYSV_ABI scePlayGoSetToDoList(OrbisPlayGoHandle handle, const OrbisPlayG uint32_t numberOfEntries) { LOG_INFO(Lib_PlayGo, "called"); - auto* playgo = Common::Singleton::Instance(); - - if (handle != 1) + if (handle != PlaygoHandle) { return ORBIS_PLAYGO_ERROR_BAD_HANDLE; - if (todoList == nullptr) + } + if (todoList == nullptr) { return ORBIS_PLAYGO_ERROR_BAD_POINTER; - if (numberOfEntries == 0) + } + if (numberOfEntries == 0) { return ORBIS_PLAYGO_ERROR_BAD_SIZE; - if (!playgo->initialized) + } + if (!playgo->initialized) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; + } return ORBIS_OK; } s32 PS4_SYSV_ABI scePlayGoTerminate() { LOG_INFO(Lib_PlayGo, "called"); - auto* playgo = Common::Singleton::Instance(); if (playgo->initialized) { playgo->initialized = false; } else { diff --git a/src/core/libraries/playgo/playgo_types.h b/src/core/libraries/playgo/playgo_types.h index 62dea4f4e..885eee035 100644 --- a/src/core/libraries/playgo/playgo_types.h +++ b/src/core/libraries/playgo/playgo_types.h @@ -5,41 +5,39 @@ #include "common/types.h" -typedef u32 OrbisPlayGoHandle; -typedef u16 OrbisPlayGoChunkId; -typedef s8 OrbisPlayGoLocus; -typedef s32 OrbisPlayGoInstallSpeed; -typedef s64 OrbisPlayGoEta; -typedef u64 OrbisPlayGoLanguageMask; +using OrbisPlayGoHandle = u32; +using OrbisPlayGoChunkId = u16; +using OrbisPlayGoEta = s64; +using OrbisPlayGoLanguageMask = u64; -typedef struct OrbisPlayGoInitParams { +enum class OrbisPlayGoLocus : s8 { + NotDownloaded = 0, + LocalSlow = 2, + LocalFast = 3, +}; + +enum class OrbisPlayGoInstallSpeed : s32 { + Suspended = 0, + Trickle = 1, + Full = 2, +}; + +struct OrbisPlayGoInitParams { const void* bufAddr; u32 bufSize; u32 reserved; -} OrbisPlayGoInitParams; +}; -typedef struct OrbisPlayGoToDo { +struct OrbisPlayGoToDo { OrbisPlayGoChunkId chunkId; OrbisPlayGoLocus locus; s8 reserved; -} OrbisPlayGoToDo; +}; -typedef struct OrbisPlayGoProgress { - uint64_t progressSize; - uint64_t totalSize; -} OrbisPlayGoProgress; - -typedef enum OrbisPlayGoLocusValue { - ORBIS_PLAYGO_LOCUS_NOT_DOWNLOADED = 0, - ORBIS_PLAYGO_LOCUS_LOCAL_SLOW = 2, - ORBIS_PLAYGO_LOCUS_LOCAL_FAST = 3 -} OrbisPlayGoLocusValue; - -typedef enum OrbisPlayGoInstallSpeedValue { - ORBIS_PLAYGO_INSTALL_SPEED_SUSPENDED = 0, - ORBIS_PLAYGO_INSTALL_SPEED_TRICKLE = 1, - ORBIS_PLAYGO_INSTALL_SPEED_FULL = 2 -} OrbisPlayGoInstallSpeedValue; +struct OrbisPlayGoProgress { + u64 progressSize; + u64 totalSize; +}; constexpr int ORBIS_PLAYGO_ERROR_UNKNOWN = -2135818239; /* 0x80B20001 */ constexpr int ORBIS_PLAYGO_ERROR_FATAL = -2135818238; /* 0x80B20002 */ diff --git a/src/core/libraries/random/random.h b/src/core/libraries/random/random.h index b483cf6ed..172494106 100644 --- a/src/core/libraries/random/random.h +++ b/src/core/libraries/random/random.h @@ -10,9 +10,11 @@ class SymbolsResolver; } namespace Libraries::Random { -constexpr int32_t SCE_RANDOM_MAX_SIZE = 64; + +constexpr s32 SCE_RANDOM_MAX_SIZE = 64; s32 PS4_SYSV_ABI sceRandomGetRandomNumber(u8* buf, std::size_t size); void RegisterlibSceRandom(Core::Loader::SymbolsResolver* sym); -} // namespace Libraries::Random \ No newline at end of file + +} // namespace Libraries::Random diff --git a/src/core/libraries/rtc/rtc.cpp b/src/core/libraries/rtc/rtc.cpp index 1b8802970..f94c00134 100644 --- a/src/core/libraries/rtc/rtc.cpp +++ b/src/core/libraries/rtc/rtc.cpp @@ -4,7 +4,6 @@ #include #include "common/logging/log.h" -#include "core/libraries/error_codes.h" #include "core/libraries/kernel/process.h" #include "core/libraries/kernel/time.h" #include "core/libraries/libs.h" @@ -49,7 +48,7 @@ int PS4_SYSV_ABI sceRtcCheckValid(OrbisRtcDateTime* pTime) { if (pTime->microsecond >= 1000000) return ORBIS_RTC_ERROR_INVALID_MICROSECOND; - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceRtcCompareTick(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2) { @@ -102,7 +101,7 @@ int PS4_SYSV_ABI sceRtcConvertUtcToLocalTime(OrbisRtcTick* pTickUtc, OrbisRtcTic } int PS4_SYSV_ABI sceRtcEnd() { - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceRtcFormatRFC2822(char* pszDateTime, const OrbisRtcTick* pTickUtc, @@ -253,7 +252,7 @@ int PS4_SYSV_ABI sceRtcFormatRFC2822(char* pszDateTime, const OrbisRtcTick* pTic } } - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceRtcFormatRFC2822LocalTime(char* pszDateTime, const OrbisRtcTick* pTickUtc) { @@ -374,7 +373,7 @@ int PS4_SYSV_ABI sceRtcFormatRFC3339Precise(char* pszDateTime, const OrbisRtcTic pszDateTime[i] = formattedString.c_str()[i]; } - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceRtcFormatRFC3339PreciseLocalTime(char* pszDateTime, @@ -397,13 +396,13 @@ int PS4_SYSV_ABI sceRtcGetCurrentAdNetworkTick(OrbisRtcTick* pTick) { Kernel::OrbisKernelTimespec clocktime; int returnValue = Kernel::sceKernelClockGettime(Kernel::ORBIS_CLOCK_REALTIME, &clocktime); - if (returnValue == SCE_OK) { + if (returnValue == ORBIS_OK) { pTick->tick = clocktime.tv_nsec / 1000 + clocktime.tv_sec * 1000000 + UNIX_EPOCH_TICKS; } else { return ORBIS_RTC_ERROR_NOT_INITIALIZED; } - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceRtcGetCurrentClock(OrbisRtcDateTime* pTime, int timeZone) { @@ -415,7 +414,7 @@ int PS4_SYSV_ABI sceRtcGetCurrentClock(OrbisRtcDateTime* pTime, int timeZone) { Kernel::OrbisKernelTimespec clocktime; int returnValue = Kernel::sceKernelClockGettime(Kernel::ORBIS_CLOCK_REALTIME, &clocktime); - if (returnValue == SCE_OK) { + if (returnValue == ORBIS_OK) { OrbisRtcTick clockTick; clockTick.tick = clocktime.tv_nsec / 1000 + clocktime.tv_sec * 1000000 + UNIX_EPOCH_TICKS; @@ -461,13 +460,13 @@ int PS4_SYSV_ABI sceRtcGetCurrentDebugNetworkTick(OrbisRtcTick* pTick) { Kernel::OrbisKernelTimespec clocktime; int returnValue = Kernel::sceKernelClockGettime(Kernel::ORBIS_CLOCK_REALTIME, &clocktime); - if (returnValue == SCE_OK) { + if (returnValue == ORBIS_OK) { pTick->tick = clocktime.tv_nsec / 1000 + clocktime.tv_sec * 1000000 + UNIX_EPOCH_TICKS; } else { return ORBIS_RTC_ERROR_NOT_INITIALIZED; } - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceRtcGetCurrentNetworkTick(OrbisRtcTick* pTick) { @@ -479,13 +478,13 @@ int PS4_SYSV_ABI sceRtcGetCurrentNetworkTick(OrbisRtcTick* pTick) { Kernel::OrbisKernelTimespec clocktime; int returnValue = Kernel::sceKernelClockGettime(Kernel::ORBIS_CLOCK_REALTIME, &clocktime); - if (returnValue == SCE_OK) { + if (returnValue == ORBIS_OK) { pTick->tick = clocktime.tv_nsec / 1000 + clocktime.tv_sec * 1000000 + UNIX_EPOCH_TICKS; } else { return ORBIS_RTC_ERROR_NOT_INITIALIZED; } - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceRtcGetCurrentRawNetworkTick(OrbisRtcTick* pTick) { @@ -497,13 +496,13 @@ int PS4_SYSV_ABI sceRtcGetCurrentRawNetworkTick(OrbisRtcTick* pTick) { Kernel::OrbisKernelTimespec clocktime; int returnValue = Kernel::sceKernelClockGettime(Kernel::ORBIS_CLOCK_REALTIME, &clocktime); - if (returnValue == SCE_OK) { + if (returnValue == ORBIS_OK) { pTick->tick = clocktime.tv_nsec / 1000 + clocktime.tv_sec * 1000000 + UNIX_EPOCH_TICKS; } else { return ORBIS_RTC_ERROR_NOT_INITIALIZED; } - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceRtcGetCurrentTick(OrbisRtcTick* pTick) { @@ -519,7 +518,7 @@ int PS4_SYSV_ABI sceRtcGetCurrentTick(OrbisRtcTick* pTick) { pTick->tick = clocktime.tv_nsec / 1000 + clocktime.tv_sec * 1000000 + UNIX_EPOCH_TICKS; } - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceRtcGetDayOfWeek(int year, int month, int day) { @@ -576,14 +575,14 @@ int PS4_SYSV_ABI sceRtcGetDaysInMonth(int year, int month) { return lastDay; } -int PS4_SYSV_ABI sceRtcGetDosTime(OrbisRtcDateTime* pTime, unsigned int* dosTime) { +int PS4_SYSV_ABI sceRtcGetDosTime(OrbisRtcDateTime* pTime, u32* dosTime) { LOG_TRACE(Lib_Rtc, "called"); if (pTime == nullptr || dosTime == nullptr) return ORBIS_RTC_ERROR_INVALID_POINTER; int isValid = sceRtcCheckValid(pTime); - if (isValid != SCE_OK) { + if (isValid != ORBIS_OK) { return isValid; } @@ -594,7 +593,7 @@ int PS4_SYSV_ABI sceRtcGetDosTime(OrbisRtcDateTime* pTime, unsigned int* dosTime *dosTime |= (pTime->month & 0x0F) << 21; *dosTime |= ((pTime->year - 1980) & 0x7F) << 25; - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceRtcGetTick(OrbisRtcDateTime* pTime, OrbisRtcTick* pTick) { @@ -629,10 +628,10 @@ int PS4_SYSV_ABI sceRtcGetTick(OrbisRtcDateTime* pTime, OrbisRtcTick* pTick) { pTick->tick = days + msec; - return SCE_OK; + return ORBIS_OK; } -unsigned int PS4_SYSV_ABI sceRtcGetTickResolution() { +u32 PS4_SYSV_ABI sceRtcGetTickResolution() { LOG_TRACE(Lib_Rtc, "called"); return 1000000; @@ -645,7 +644,7 @@ int PS4_SYSV_ABI sceRtcGetTime_t(OrbisRtcDateTime* pTime, time_t* llTime) { return ORBIS_RTC_ERROR_INVALID_POINTER; int isValid = sceRtcCheckValid(pTime); - if (isValid != SCE_OK) { + if (isValid != ORBIS_OK) { return isValid; } @@ -658,7 +657,7 @@ int PS4_SYSV_ABI sceRtcGetTime_t(OrbisRtcDateTime* pTime, time_t* llTime) { *llTime = (timeTick.tick - UNIX_EPOCH_TICKS) / 1000000; } - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceRtcGetWin32FileTime(OrbisRtcDateTime* pTime, uint64_t* ulWin32Time) { @@ -668,7 +667,7 @@ int PS4_SYSV_ABI sceRtcGetWin32FileTime(OrbisRtcDateTime* pTime, uint64_t* ulWin return ORBIS_RTC_ERROR_INVALID_POINTER; int isValid = sceRtcCheckValid(pTime); - if (isValid != SCE_OK) { + if (isValid != ORBIS_OK) { return isValid; } @@ -681,11 +680,11 @@ int PS4_SYSV_ABI sceRtcGetWin32FileTime(OrbisRtcDateTime* pTime, uint64_t* ulWin *ulWin32Time = (timeTick.tick - WIN32_FILETIME_EPOCH_TICKS) * 10; } - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceRtcInit() { - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceRtcIsLeapYear(int yearInt) { @@ -790,7 +789,7 @@ int PS4_SYSV_ABI sceRtcParseDateTime(OrbisRtcTick* pTickUtc, const char* pszDate sceRtcGetTick(&dateTime, pTickUtc); } - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceRtcParseRFC3339(OrbisRtcTick* pTickUtc, const char* pszDateTime) { @@ -825,7 +824,7 @@ int PS4_SYSV_ABI sceRtcParseRFC3339(OrbisRtcTick* pTickUtc, const char* pszDateT } } - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceRtcSetConf() { @@ -869,7 +868,7 @@ int PS4_SYSV_ABI sceRtcSetDosTime(OrbisRtcDateTime* pTime, u32 dosTime) { pTime->day = days & 0x1f; pTime->month = (days >> 5) & 0x0f; pTime->year = (days >> 9) + 1980; - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceRtcSetTick(OrbisRtcDateTime* pTime, OrbisRtcTick* pTick) { @@ -918,7 +917,7 @@ int PS4_SYSV_ABI sceRtcSetTick(OrbisRtcDateTime* pTime, OrbisRtcTick* pTick) { msec %= 1000000; pTime->microsecond = msec; - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceRtcSetTime_t(OrbisRtcDateTime* pTime, time_t llTime) { @@ -946,7 +945,7 @@ int PS4_SYSV_ABI sceRtcSetTime_t(OrbisRtcDateTime* pTime, time_t llTime) { newTick.tick += UNIX_EPOCH_TICKS; sceRtcSetTick(pTime, &newTick); - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceRtcSetWin32FileTime(OrbisRtcDateTime* pTime, int64_t ulWin32Time) { @@ -962,7 +961,7 @@ int PS4_SYSV_ABI sceRtcSetWin32FileTime(OrbisRtcDateTime* pTime, int64_t ulWin32 sceRtcSetTick(pTime, &convertedTick); - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceRtcTickAddDays(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int32_t lAdd) { @@ -973,7 +972,7 @@ int PS4_SYSV_ABI sceRtcTickAddDays(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, i pTick1->tick = (lAdd * 86400000000) + pTick2->tick; - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceRtcTickAddHours(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int32_t lAdd) { @@ -984,7 +983,7 @@ int PS4_SYSV_ABI sceRtcTickAddHours(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, pTick1->tick = (lAdd * 3600000000) + pTick2->tick; - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceRtcTickAddMicroseconds(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, @@ -996,7 +995,7 @@ int PS4_SYSV_ABI sceRtcTickAddMicroseconds(OrbisRtcTick* pTick1, OrbisRtcTick* p pTick1->tick = lAdd + pTick2->tick; - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceRtcTickAddMinutes(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int64_t lAdd) { @@ -1007,7 +1006,7 @@ int PS4_SYSV_ABI sceRtcTickAddMinutes(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2 pTick1->tick = (lAdd * 60000000) + pTick2->tick; - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceRtcTickAddMonths(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int32_t lAdd) { @@ -1018,7 +1017,7 @@ int PS4_SYSV_ABI sceRtcTickAddMonths(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, if (lAdd == 0) { pTick1->tick = pTick2->tick; - return SCE_OK; + return ORBIS_OK; } OrbisRtcDateTime time; @@ -1054,13 +1053,13 @@ int PS4_SYSV_ABI sceRtcTickAddMonths(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, } int timeIsValid = sceRtcCheckValid(&time); - if (timeIsValid == SCE_OK) { + if (timeIsValid == ORBIS_OK) { sceRtcGetTick(&time, pTick1); } else { return timeIsValid; } - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceRtcTickAddSeconds(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int64_t lAdd) { @@ -1071,7 +1070,7 @@ int PS4_SYSV_ABI sceRtcTickAddSeconds(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2 pTick1->tick = (lAdd * 1000000) + pTick2->tick; - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceRtcTickAddTicks(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int64_t lAdd) { @@ -1082,7 +1081,7 @@ int PS4_SYSV_ABI sceRtcTickAddTicks(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, pTick1->tick = lAdd + pTick2->tick; - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceRtcTickAddWeeks(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int32_t lAdd) { @@ -1093,7 +1092,7 @@ int PS4_SYSV_ABI sceRtcTickAddWeeks(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, pTick1->tick = (lAdd * 604800000000) + pTick2->tick; - return SCE_OK; + return ORBIS_OK; } int PS4_SYSV_ABI sceRtcTickAddYears(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int32_t lAdd) { @@ -1106,7 +1105,7 @@ int PS4_SYSV_ABI sceRtcTickAddYears(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, if (lAdd == 0) { pTick1->tick = pTick2->tick; - return SCE_OK; + return ORBIS_OK; } sceRtcSetTick(&time, pTick1); @@ -1114,13 +1113,13 @@ int PS4_SYSV_ABI sceRtcTickAddYears(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, time.year += lAdd; int timeIsValid = sceRtcCheckValid(&time); - if (timeIsValid == SCE_OK) { + if (timeIsValid == ORBIS_OK) { sceRtcGetTick(&time, pTick1); } else { return timeIsValid; } - return SCE_OK; + return ORBIS_OK; } void RegisterlibSceRtc(Core::Loader::SymbolsResolver* sym) { diff --git a/src/core/libraries/rtc/rtc.h b/src/core/libraries/rtc/rtc.h index c41040863..eb7afa00c 100644 --- a/src/core/libraries/rtc/rtc.h +++ b/src/core/libraries/rtc/rtc.h @@ -3,6 +3,7 @@ #pragma once +#include #include "common/types.h" namespace Core::Loader { @@ -19,21 +20,21 @@ constexpr int ORBIS_RTC_DAYOFWEEK_THURSDAY = 4; constexpr int ORBIS_RTC_DAYOFWEEK_FRIDAY = 5; constexpr int ORBIS_RTC_DAYOFWEEK_SATURDAY = 6; -constexpr int64_t UNIX_EPOCH_TICKS = 0xdcbffeff2bc000; -constexpr int64_t WIN32_FILETIME_EPOCH_TICKS = 0xb36168b6a58000; +constexpr s64 UNIX_EPOCH_TICKS = 0xdcbffeff2bc000; +constexpr s64 WIN32_FILETIME_EPOCH_TICKS = 0xb36168b6a58000; struct OrbisRtcTick { - uint64_t tick; + u64 tick; }; struct OrbisRtcDateTime { - uint16_t year; - uint16_t month; - uint16_t day; - uint16_t hour; - uint16_t minute; - uint16_t second; - uint32_t microsecond; + u16 year; + u16 month; + u16 day; + u16 hour; + u16 minute; + u16 second; + u32 microsecond; }; int PS4_SYSV_ABI sceRtcCheckValid(OrbisRtcDateTime* pTime); @@ -58,9 +59,9 @@ int PS4_SYSV_ABI sceRtcGetCurrentRawNetworkTick(OrbisRtcTick* pTick); int PS4_SYSV_ABI sceRtcGetCurrentTick(OrbisRtcTick* pTick); int PS4_SYSV_ABI sceRtcGetDayOfWeek(int year, int month, int day); int PS4_SYSV_ABI sceRtcGetDaysInMonth(int year, int month); -int PS4_SYSV_ABI sceRtcGetDosTime(OrbisRtcDateTime* pTime, unsigned int* dosTime); +int PS4_SYSV_ABI sceRtcGetDosTime(OrbisRtcDateTime* pTime, u32* dosTime); int PS4_SYSV_ABI sceRtcGetTick(OrbisRtcDateTime* pTime, OrbisRtcTick* pTick); -unsigned int PS4_SYSV_ABI sceRtcGetTickResolution(); +u32 PS4_SYSV_ABI sceRtcGetTickResolution(); int PS4_SYSV_ABI sceRtcGetTime_t(OrbisRtcDateTime* pTime, time_t* llTime); int PS4_SYSV_ABI sceRtcGetWin32FileTime(OrbisRtcDateTime* pTime, uint64_t* ulWin32Time); int PS4_SYSV_ABI sceRtcInit(); @@ -88,4 +89,4 @@ int PS4_SYSV_ABI sceRtcTickAddWeeks(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int PS4_SYSV_ABI sceRtcTickAddYears(OrbisRtcTick* pTick1, OrbisRtcTick* pTick2, int32_t lAdd); void RegisterlibSceRtc(Core::Loader::SymbolsResolver* sym); -} // namespace Libraries::Rtc \ No newline at end of file +} // namespace Libraries::Rtc diff --git a/src/core/libraries/rtc/rtc_error.h b/src/core/libraries/rtc/rtc_error.h index 3af5a68fd..406c6fb56 100644 --- a/src/core/libraries/rtc/rtc_error.h +++ b/src/core/libraries/rtc/rtc_error.h @@ -3,6 +3,8 @@ #pragma once +#include "core/libraries/error_codes.h" + constexpr int ORBIS_RTC_ERROR_DATETIME_UNINITIALIZED = 0x7FFEF9FE; constexpr int ORBIS_RTC_ERROR_INVALID_PARAMETER = 0x80010602; constexpr int ORBIS_RTC_ERROR_INVALID_TICK_PARAMETER = 0x80010603; @@ -29,4 +31,4 @@ constexpr int ORBIS_RTC_ERROR_INVALID_DAY = 0x80B5000A; constexpr int ORBIS_RTC_ERROR_INVALID_HOUR = 0x80B5000B; constexpr int ORBIS_RTC_ERROR_INVALID_MINUTE = 0x80B5000C; constexpr int ORBIS_RTC_ERROR_INVALID_SECOND = 0x80B5000D; -constexpr int ORBIS_RTC_ERROR_INVALID_MICROSECOND = 0x80B5000E; \ No newline at end of file +constexpr int ORBIS_RTC_ERROR_INVALID_MICROSECOND = 0x80B5000E; diff --git a/src/core/libraries/system/systemservice.cpp b/src/core/libraries/system/systemservice.cpp index 4e7f9257a..ebb9f4392 100644 --- a/src/core/libraries/system/systemservice.cpp +++ b/src/core/libraries/system/systemservice.cpp @@ -3,9 +3,9 @@ #include "common/config.h" #include "common/logging/log.h" -#include "core/libraries/error_codes.h" #include "core/libraries/libs.h" #include "core/libraries/system/systemservice.h" +#include "core/libraries/system/systemservice_error.h" namespace Libraries::SystemService { @@ -1772,14 +1772,12 @@ s32 PS4_SYSV_ABI sceSystemServiceGetStatus(OrbisSystemServiceStatus* status) { LOG_ERROR(Lib_SystemService, "OrbisSystemServiceStatus is null"); return ORBIS_SYSTEM_SERVICE_ERROR_PARAMETER; } - OrbisSystemServiceStatus st = {}; - st.eventNum = 0; - st.isSystemUiOverlaid = false; - st.isInBackgroundExecution = false; - st.isCpuMode7CpuNormal = true; - st.isGameLiveStreamingOnAir = false; - st.isOutOfVrPlayArea = false; - *status = st; + status->event_num = 0; + status->is_system_ui_overlaid = false; + status->is_in_background_execution = false; + status->is_cpu_mode7_cpu_normal = true; + status->is_game_live_streaming_on_air = false; + status->is_out_of_vr_play_area = false; return ORBIS_OK; } @@ -1889,39 +1887,38 @@ int PS4_SYSV_ABI sceSystemServiceNavigateToGoHome() { return ORBIS_OK; } -s32 PS4_SYSV_ABI sceSystemServiceParamGetInt(int param_id, int* value) { +s32 PS4_SYSV_ABI sceSystemServiceParamGetInt(OrbisSystemServiceParamId param_id, int* value) { // TODO this probably should be stored in config for UI configuration - LOG_INFO(Lib_SystemService, "called param_id {}", param_id); + LOG_INFO(Lib_SystemService, "called param_id {}", u32(param_id)); if (value == nullptr) { LOG_ERROR(Lib_SystemService, "value is null"); return ORBIS_SYSTEM_SERVICE_ERROR_PARAMETER; } switch (param_id) { - case ORBIS_SYSTEM_SERVICE_PARAM_ID_LANG: + case OrbisSystemServiceParamId::Lang: *value = Config::GetLanguage(); break; - case ORBIS_SYSTEM_SERVICE_PARAM_ID_DATE_FORMAT: - *value = ORBIS_SYSTEM_PARAM_DATE_FORMAT_DDMMYYYY; + case OrbisSystemServiceParamId::DateFormat: + *value = u32(OrbisSystemParamDateFormat::FmtDDMMYYYY); break; - case ORBIS_SYSTEM_SERVICE_PARAM_ID_TIME_FORMAT: - *value = ORBIS_SYSTEM_PARAM_TIME_FORMAT_24HOUR; + case OrbisSystemServiceParamId::TimeFormat: + *value = u32(OrbisSystemParamTimeFormat::Fmt24Hour); break; - case ORBIS_SYSTEM_SERVICE_PARAM_ID_TIME_ZONE: + case OrbisSystemServiceParamId::TimeZone: *value = +120; break; - case ORBIS_SYSTEM_SERVICE_PARAM_ID_SUMMERTIME: + case OrbisSystemServiceParamId::Summertime: *value = 1; break; - case ORBIS_SYSTEM_SERVICE_PARAM_ID_GAME_PARENTAL_LEVEL: - *value = ORBIS_SYSTEM_PARAM_GAME_PARENTAL_OFF; + case OrbisSystemServiceParamId::GameParentalLevel: + *value = u32(OrbisSystemParamGameParentalLevel::Off); break; - case ORBIS_SYSTEM_SERVICE_PARAM_ID_ENTER_BUTTON_ASSIGN: - *value = ORBIS_SYSTEM_PARAM_ENTER_BUTTON_ASSIGN_CROSS; + case OrbisSystemServiceParamId::EnterButtonAssign: + *value = u32(OrbisSystemParamEnterButtonAssign::Cross); break; default: - LOG_ERROR(Lib_SystemService, "param_id {} unsupported!", - param_id); // shouldn't go there but log it - *value = 0; // return a dummy value + LOG_ERROR(Lib_SystemService, "param_id {} unsupported!", u32(param_id)); + *value = 0; } return ORBIS_OK; diff --git a/src/core/libraries/system/systemservice.h b/src/core/libraries/system/systemservice.h index 56583c97e..cdd3c15e8 100644 --- a/src/core/libraries/system/systemservice.h +++ b/src/core/libraries/system/systemservice.h @@ -12,114 +12,81 @@ class SymbolsResolver; namespace Libraries::SystemService { -enum OrbisSystemServiceParamId { - ORBIS_SYSTEM_SERVICE_PARAM_ID_LANG = 1, - ORBIS_SYSTEM_SERVICE_PARAM_ID_DATE_FORMAT = 2, - ORBIS_SYSTEM_SERVICE_PARAM_ID_TIME_FORMAT = 3, - ORBIS_SYSTEM_SERVICE_PARAM_ID_TIME_ZONE = 4, - ORBIS_SYSTEM_SERVICE_PARAM_ID_SUMMERTIME = 5, - ORBIS_SYSTEM_SERVICE_PARAM_ID_SYSTEM_NAME = 6, - ORBIS_SYSTEM_SERVICE_PARAM_ID_GAME_PARENTAL_LEVEL = 7, - ORBIS_SYSTEM_SERVICE_PARAM_ID_ENTER_BUTTON_ASSIGN = 1000 +enum class OrbisSystemServiceParamId { + Lang = 1, + DateFormat = 2, + TimeFormat = 3, + TimeZone = 4, + Summertime = 5, + SystemName = 6, + GameParentalLevel = 7, + EnterButtonAssign = 1000, }; -enum OrbisSystemParamDateFormat { - ORBIS_SYSTEM_PARAM_DATE_FORMAT_YYYYMMDD = 0, - ORBIS_SYSTEM_PARAM_DATE_FORMAT_DDMMYYYY = 1, - ORBIS_SYSTEM_PARAM_DATE_FORMAT_MMDDYYYY = 2 +enum class OrbisSystemParamDateFormat { + FmtYYYYMMDD = 0, + FmtDDMMYYYY = 1, + FmtMMDDYYYY = 2, }; -enum OrbisSystemParamTimeFormat { - ORBIS_SYSTEM_PARAM_TIME_FORMAT_12HOUR = 0, - ORBIS_SYSTEM_PARAM_TIME_FORMAT_24HOUR = 1 +enum class OrbisSystemParamTimeFormat { + Fmt12Hour = 0, + Fmt24Hour = 1, }; -enum OrbisSystemParamGameParentalLevel { - ORBIS_SYSTEM_PARAM_GAME_PARENTAL_OFF = 0, - ORBIS_SYSTEM_PARAM_GAME_PARENTAL_LEVEL01 = 1, - ORBIS_SYSTEM_PARAM_GAME_PARENTAL_LEVEL02 = 2, - ORBIS_SYSTEM_PARAM_GAME_PARENTAL_LEVEL03 = 3, - ORBIS_SYSTEM_PARAM_GAME_PARENTAL_LEVEL04 = 4, - ORBIS_SYSTEM_PARAM_GAME_PARENTAL_LEVEL05 = 5, - ORBIS_SYSTEM_PARAM_GAME_PARENTAL_LEVEL06 = 6, - ORBIS_SYSTEM_PARAM_GAME_PARENTAL_LEVEL07 = 7, - ORBIS_SYSTEM_PARAM_GAME_PARENTAL_LEVEL08 = 8, - ORBIS_SYSTEM_PARAM_GAME_PARENTAL_LEVEL09 = 9, - ORBIS_SYSTEM_PARAM_GAME_PARENTAL_LEVEL10 = 10, - ORBIS_SYSTEM_PARAM_GAME_PARENTAL_LEVEL11 = 11 +enum class OrbisSystemParamGameParentalLevel { + Off = 0, + Level01 = 1, + Level02 = 2, + Level03 = 3, + Level04 = 4, + Level05 = 5, + Level06 = 6, + Level07 = 7, + Level08 = 8, + Level09 = 9, + Level10 = 10, + Level11 = 11, }; -enum OrbisSystemParamEnterButtonAssign { - ORBIS_SYSTEM_PARAM_ENTER_BUTTON_ASSIGN_CIRCLE = 0, - ORBIS_SYSTEM_PARAM_ENTER_BUTTON_ASSIGN_CROSS = 1 +enum class OrbisSystemParamEnterButtonAssign { + Circle = 0, + Cross = 1, }; -enum OrbisSystemParamLanguage { - ORBIS_SYSTEM_PARAM_LANG_JAPANESE = 0, - ORBIS_SYSTEM_PARAM_LANG_ENGLISH_US = 1, - ORBIS_SYSTEM_PARAM_LANG_FRENCH = 2, - ORBIS_SYSTEM_PARAM_LANG_SPANISH = 3, - ORBIS_SYSTEM_PARAM_LANG_GERMAN = 4, - ORBIS_SYSTEM_PARAM_LANG_ITALIAN = 5, - ORBIS_SYSTEM_PARAM_LANG_DUTCH = 6, - ORBIS_SYSTEM_PARAM_LANG_PORTUGUESE_PT = 7, - ORBIS_SYSTEM_PARAM_LANG_RUSSIAN = 8, - ORBIS_SYSTEM_PARAM_LANG_KOREAN = 9, - ORBIS_SYSTEM_PARAM_LANG_CHINESE_T = 10, - ORBIS_SYSTEM_PARAM_LANG_CHINESE_S = 11, - ORBIS_SYSTEM_PARAM_LANG_FINNISH = 12, - ORBIS_SYSTEM_PARAM_LANG_SWEDISH = 13, - ORBIS_SYSTEM_PARAM_LANG_DANISH = 14, - ORBIS_SYSTEM_PARAM_LANG_NORWEGIAN = 15, - ORBIS_SYSTEM_PARAM_LANG_POLISH = 16, - ORBIS_SYSTEM_PARAM_LANG_PORTUGUESE_BR = 17, - ORBIS_SYSTEM_PARAM_LANG_ENGLISH_GB = 18, - ORBIS_SYSTEM_PARAM_LANG_TURKISH = 19, - ORBIS_SYSTEM_PARAM_LANG_SPANISH_LA = 20, - ORBIS_SYSTEM_PARAM_LANG_ARABIC = 21, - ORBIS_SYSTEM_PARAM_LANG_FRENCH_CA = 22, - ORBIS_SYSTEM_PARAM_LANG_CZECH = 23, - ORBIS_SYSTEM_PARAM_LANG_HUNGARIAN = 24, - ORBIS_SYSTEM_PARAM_LANG_GREEK = 25, - ORBIS_SYSTEM_PARAM_LANG_ROMANIAN = 26, - ORBIS_SYSTEM_PARAM_LANG_THAI = 27, - ORBIS_SYSTEM_PARAM_LANG_VIETNAMESE = 28, - ORBIS_SYSTEM_PARAM_LANG_INDONESIAN = 29 -}; - -enum OrbisSystemServiceEventType { - ORBIS_SYSTEM_SERVICE_EVENT_INVALID = -1, - ORBIS_SYSTEM_SERVICE_EVENT_ON_RESUME = 0x10000000, - ORBIS_SYSTEM_SERVICE_EVENT_GAME_LIVE_STREAMING_STATUS_UPDATE = 0x10000001, - ORBIS_SYSTEM_SERVICE_EVENT_SESSION_INVITATION = 0x10000002, - ORBIS_SYSTEM_SERVICE_EVENT_ENTITLEMENT_UPDATE = 0x10000003, - ORBIS_SYSTEM_SERVICE_EVENT_GAME_CUSTOM_DATA = 0x10000004, - ORBIS_SYSTEM_SERVICE_EVENT_DISPLAY_SAFE_AREA_UPDATE = 0x10000005, - ORBIS_SYSTEM_SERVICE_EVENT_URL_OPEN = 0x10000006, - ORBIS_SYSTEM_SERVICE_EVENT_LAUNCH_APP = 0x10000007, - ORBIS_SYSTEM_SERVICE_EVENT_APP_LAUNCH_LINK = 0x10000008, - ORBIS_SYSTEM_SERVICE_EVENT_ADDCONTENT_INSTALL = 0x10000009, - ORBIS_SYSTEM_SERVICE_EVENT_RESET_VR_POSITION = 0x1000000a, - ORBIS_SYSTEM_SERVICE_EVENT_JOIN_EVENT = 0x1000000b, - ORBIS_SYSTEM_SERVICE_EVENT_PLAYGO_LOCUS_UPDATE = 0x1000000c, - ORBIS_SYSTEM_SERVICE_EVENT_PLAY_TOGETHER_HOST = 0x1000000d, - ORBIS_SYSTEM_SERVICE_EVENT_SERVICE_ENTITLEMENT_UPDATE = 0x1000000e, - ORBIS_SYSTEM_SERVICE_EVENT_EYE_TO_EYE_DISTANCE_UPDATE = 0x1000000f, - ORBIS_SYSTEM_SERVICE_EVENT_JOIN_MATCH_EVENT = 0x10000010, - ORBIS_SYSTEM_SERVICE_EVENT_PLAY_TOGETHER_HOST_A = 0x10000011, - ORBIS_SYSTEM_SERVICE_EVENT_WEBBROWSER_CLOSED = 0x10000012, - ORBIS_SYSTEM_SERVICE_EVENT_CONTROLLER_SETTINGS_CLOSED = 0x10000013, - ORBIS_SYSTEM_SERVICE_EVENT_JOIN_TEAM_ON_TEAM_MATCH_EVENT = 0x10000014, - ORBIS_SYSTEM_SERVICE_EVENT_OPEN_SHARE_MENU = 0x30000000 +enum class OrbisSystemServiceEventType { + Invalid = -1, + OnResume = 0x10000000, + GameLiveStreamingStatusUpdate = 0x10000001, + SessionInvitation = 0x10000002, + EntitlementUpdate = 0x10000003, + GameCustomData = 0x10000004, + DisplaySafeAreaUpdate = 0x10000005, + UrlOpen = 0x10000006, + LaunchApp = 0x10000007, + AppLaunchLink = 0x10000008, + AddcontentInstall = 0x10000009, + ResetVrPosition = 0x1000000a, + JoinEvent = 0x1000000b, + PlaygoLocusUpdate = 0x1000000c, + PlayTogetherHost = 0x1000000d, + ServiceEntitlementUpdate = 0x1000000e, + EyeToEyeDistanceUpdate = 0x1000000f, + JoinMatchEvent = 0x10000010, + PlayTogetherHostA = 0x10000011, + WebBrowserClosed = 0x10000012, + ControllerSettingsClosed = 0x10000013, + JoinTeamOnTeamMatchEvent = 0x10000014, + OpenShareMenu = 0x30000000 }; struct OrbisSystemServiceStatus { - s32 eventNum; - bool isSystemUiOverlaid; - bool isInBackgroundExecution; - bool isCpuMode7CpuNormal; - bool isGameLiveStreamingOnAir; - bool isOutOfVrPlayArea; + s32 event_num; + bool is_system_ui_overlaid; + bool is_in_background_execution; + bool is_cpu_mode7_cpu_normal; + bool is_game_live_streaming_on_air; + bool is_out_of_vr_play_area; u8 reserved[]; }; @@ -129,36 +96,36 @@ struct OrbisSystemServiceDisplaySafeAreaInfo { }; struct OrbisSystemServiceEvent { - OrbisSystemServiceEventType eventType; + OrbisSystemServiceEventType event_type; union { char param[8192]; struct { char source[1024]; char url[4096]; - } urlOpen; + } url_open; struct { u32 size; u8 arg[8188]; - } launchApp; + } launch_app; struct { u32 size; u8 arg[2020]; - } appLaunchLink; + } app_launch_link; struct { - s32 userId; - char eventId[37]; - char bootArgument[7169]; - } joinEvent; + s32 user_id; + char event_id[37]; + char boot_argument[7169]; + } join_event; struct { - s32 userId; - u32 npServiceLabel; + s32 user_id; + u32 np_service_label; u8 reserved[8184]; - } serviceEntitlementUpdate; + } service_entitlement_update; struct { - s32 userId; - u32 npServiceLabel; + s32 user_id; + u32 np_service_label; u8 reserved[8184]; - } unifiedEntitlementUpdate; + } unified_entitlement_update; u8 reserved[8192]; }; }; @@ -537,7 +504,7 @@ int PS4_SYSV_ABI sceSystemServiceNavigateToAnotherApp(); int PS4_SYSV_ABI sceSystemServiceNavigateToGoBack(); int PS4_SYSV_ABI sceSystemServiceNavigateToGoBackWithValue(); int PS4_SYSV_ABI sceSystemServiceNavigateToGoHome(); -s32 PS4_SYSV_ABI sceSystemServiceParamGetInt(int param_id, int* value); +s32 PS4_SYSV_ABI sceSystemServiceParamGetInt(OrbisSystemServiceParamId param_id, int* value); int PS4_SYSV_ABI sceSystemServiceParamGetString(); int PS4_SYSV_ABI sceSystemServicePowerTick(); int PS4_SYSV_ABI sceSystemServiceRaiseExceptionLocalProcess(); diff --git a/src/core/libraries/system/systemservice_error.h b/src/core/libraries/system/systemservice_error.h new file mode 100644 index 000000000..ca59fab65 --- /dev/null +++ b/src/core/libraries/system/systemservice_error.h @@ -0,0 +1,10 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/libraries/error_codes.h" + +// SystemService library +constexpr int ORBIS_SYSTEM_SERVICE_ERROR_PARAMETER = 0x80A10003; +constexpr int ORBIS_SYSTEM_SERVICE_ERROR_NO_EVENT = 0x80A10004; diff --git a/src/core/libraries/system/userservice.cpp b/src/core/libraries/system/userservice.cpp index 140ca8921..e1f9f75e8 100644 --- a/src/core/libraries/system/userservice.cpp +++ b/src/core/libraries/system/userservice.cpp @@ -4,9 +4,9 @@ #include "common/config.h" #include "common/logging/log.h" -#include "core/libraries/error_codes.h" #include "core/libraries/libs.h" #include "core/libraries/system/userservice.h" +#include "core/libraries/system/userservice_error.h" namespace Libraries::UserService { @@ -112,7 +112,7 @@ s32 PS4_SYSV_ABI sceUserServiceGetEvent(OrbisUserServiceEvent* event) { if (!logged_in) { logged_in = true; - event->event = SCE_USER_SERVICE_EVENT_TYPE_LOGIN; + event->event = OrbisUserServiceEventType::Login; event->userId = 1; return ORBIS_OK; } @@ -1041,14 +1041,14 @@ int PS4_SYSV_ABI sceUserServiceGetTraditionalChineseInputType() { return ORBIS_OK; } -s32 PS4_SYSV_ABI sceUserServiceGetUserColor(int user_id, int* color) { +s32 PS4_SYSV_ABI sceUserServiceGetUserColor(int user_id, OrbisUserServiceUserColor* color) { // TODO fix me better LOG_INFO(Lib_UserService, "called user_id = {}", user_id); if (color == nullptr) { LOG_ERROR(Lib_UserService, "color is null"); return ORBIS_USER_SERVICE_ERROR_INVALID_ARGUMENT; } - *color = ORBIS_USER_SERVICE_USER_COLOR_BLUE; + *color = OrbisUserServiceUserColor::Blue; return ORBIS_OK; } diff --git a/src/core/libraries/system/userservice.h b/src/core/libraries/system/userservice.h index 5bb1fd043..66ac2b69d 100644 --- a/src/core/libraries/system/userservice.h +++ b/src/core/libraries/system/userservice.h @@ -40,16 +40,16 @@ struct OrbisUserServiceRegisteredUserIdList { OrbisUserServiceUserId userId[ORBIS_USER_SERVICE_MAX_REGISTER_USERS]; }; -enum OrbisUserServiceUserColor { - ORBIS_USER_SERVICE_USER_COLOR_BLUE = 0, - ORBIS_USER_SERVICE_USER_COLOR_RED = 1, - ORBIS_USER_SERVICE_USER_COLOR_GREEN = 2, - ORBIS_USER_SERVICE_USER_COLOR_PINK = 3, +enum class OrbisUserServiceUserColor { + Blue = 0, + Red = 1, + Green = 2, + Pink = 3, }; -enum OrbisUserServiceEventType { - SCE_USER_SERVICE_EVENT_TYPE_LOGIN = 0, // Login event - SCE_USER_SERVICE_EVENT_TYPE_LOGOUT = 1, // Logout event +enum class OrbisUserServiceEventType { + Login = 0, // Login event + Logout = 1, // Logout event }; struct OrbisUserServiceEvent { @@ -258,7 +258,7 @@ int PS4_SYSV_ABI sceUserServiceGetTopMenuLimitItem(); int PS4_SYSV_ABI sceUserServiceGetTopMenuNotificationFlag(); int PS4_SYSV_ABI sceUserServiceGetTopMenuTutorialFlag(); int PS4_SYSV_ABI sceUserServiceGetTraditionalChineseInputType(); -s32 PS4_SYSV_ABI sceUserServiceGetUserColor(int user_id, int* color); +s32 PS4_SYSV_ABI sceUserServiceGetUserColor(int user_id, OrbisUserServiceUserColor* color); int PS4_SYSV_ABI sceUserServiceGetUserGroupName(); int PS4_SYSV_ABI sceUserServiceGetUserGroupNameList(); int PS4_SYSV_ABI sceUserServiceGetUserGroupNum(); diff --git a/src/core/libraries/system/userservice_error.h b/src/core/libraries/system/userservice_error.h new file mode 100644 index 000000000..40921df9f --- /dev/null +++ b/src/core/libraries/system/userservice_error.h @@ -0,0 +1,17 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/libraries/error_codes.h" + +// UserService library +constexpr int ORBIS_USER_SERVICE_ERROR_INTERNAL = 0x80960001; +constexpr int ORBIS_USER_SERVICE_ERROR_NOT_INITIALIZED = 0x80960002; +constexpr int ORBIS_USER_SERVICE_ERROR_ALREADY_INITIALIZED = 0x80960003; +constexpr int ORBIS_USER_SERVICE_ERROR_NO_MEMORY = 0x80960004; +constexpr int ORBIS_USER_SERVICE_ERROR_INVALID_ARGUMENT = 0x80960005; +constexpr int ORBIS_USER_SERVICE_ERROR_OPERATION_NOT_SUPPORTED = 0x80960006; +constexpr int ORBIS_USER_SERVICE_ERROR_NO_EVENT = 0x80960007; +constexpr int ORBIS_USER_SERVICE_ERROR_NOT_LOGGED_IN = 0x80960009; +constexpr int ORBIS_USER_SERVICE_ERROR_BUFFER_TOO_SHORT = 0x8096000A; diff --git a/src/core/libraries/videodec/videodec.cpp b/src/core/libraries/videodec/videodec.cpp index 8d6ea4988..6c9a9b8c0 100644 --- a/src/core/libraries/videodec/videodec.cpp +++ b/src/core/libraries/videodec/videodec.cpp @@ -1,12 +1,11 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "videodec.h" - #include "common/logging/log.h" -#include "core/libraries/error_codes.h" #include "core/libraries/libs.h" -#include "videodec_impl.h" +#include "core/libraries/videodec/videodec.h" +#include "core/libraries/videodec/videodec_error.h" +#include "core/libraries/videodec/videodec_impl.h" namespace Libraries::Videodec { @@ -134,4 +133,4 @@ void RegisterlibSceVideodec(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("f8AgDv-1X8A", "libSceVideodec", 1, "libSceVideodec", 1, 1, sceVideodecReset); }; -} // namespace Libraries::Videodec \ No newline at end of file +} // namespace Libraries::Videodec diff --git a/src/core/libraries/videodec/videodec2.cpp b/src/core/libraries/videodec/videodec2.cpp index fe2b82bea..0bd68afbd 100644 --- a/src/core/libraries/videodec/videodec2.cpp +++ b/src/core/libraries/videodec/videodec2.cpp @@ -1,13 +1,12 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "videodec2.h" -#include "videodec2_impl.h" - #include "common/assert.h" #include "common/logging/log.h" -#include "core/libraries/error_codes.h" #include "core/libraries/libs.h" +#include "core/libraries/videodec/videodec2.h" +#include "core/libraries/videodec/videodec2_impl.h" +#include "core/libraries/videodec/videodec_error.h" namespace Libraries::Vdec2 { @@ -197,4 +196,4 @@ void RegisterlibSceVdec2(Core::Loader::SymbolsResolver* sym) { sceVideodec2GetPictureInfo); } -} // namespace Libraries::Vdec2 \ No newline at end of file +} // namespace Libraries::Vdec2 diff --git a/src/core/libraries/videodec/videodec2.h b/src/core/libraries/videodec/videodec2.h index 9b230cc54..4617e1c20 100644 --- a/src/core/libraries/videodec/videodec2.h +++ b/src/core/libraries/videodec/videodec2.h @@ -15,7 +15,7 @@ namespace Libraries::Vdec2 { class VdecDecoder; using OrbisVideodec2Decoder = VdecDecoder*; -typedef void* OrbisVideodec2ComputeQueue; +using OrbisVideodec2ComputeQueue = void*; struct OrbisVideodec2DecoderConfigInfo { u64 thisSize; diff --git a/src/core/libraries/videodec/videodec2_impl.cpp b/src/core/libraries/videodec/videodec2_impl.cpp index 37270fa8c..8daa48828 100644 --- a/src/core/libraries/videodec/videodec2_impl.cpp +++ b/src/core/libraries/videodec/videodec2_impl.cpp @@ -3,10 +3,9 @@ #include "videodec2_impl.h" -#include "common/alignment.h" #include "common/assert.h" #include "common/logging/log.h" -#include "core/libraries/error_codes.h" +#include "core/libraries/videodec/videodec_error.h" // The av_err2str macro in libavutil/error.h does not play nice with C++ #ifdef av_err2str diff --git a/src/core/libraries/videodec/videodec_error.h b/src/core/libraries/videodec/videodec_error.h new file mode 100644 index 000000000..4e0066e5e --- /dev/null +++ b/src/core/libraries/videodec/videodec_error.h @@ -0,0 +1,68 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/libraries/error_codes.h" + +// Videodec library +constexpr int ORBIS_VIDEODEC_ERROR_API_FAIL = 0x80C10000; +constexpr int ORBIS_VIDEODEC_ERROR_CODEC_TYPE = 0x80C10001; +constexpr int ORBIS_VIDEODEC_ERROR_STRUCT_SIZE = 0x80C10002; +constexpr int ORBIS_VIDEODEC_ERROR_HANDLE = 0x80C10003; +constexpr int ORBIS_VIDEODEC_ERROR_CPU_MEMORY_SIZE = 0x80C10004; +constexpr int ORBIS_VIDEODEC_ERROR_CPU_MEMORY_POINTER = 0x80C10005; +constexpr int ORBIS_VIDEODEC_ERROR_CPU_GPU_MEMORY_SIZE = 0x80C10006; +constexpr int ORBIS_VIDEODEC_ERROR_CPU_GPU_MEMORY_POINTER = 0x80C10007; +constexpr int ORBIS_VIDEODEC_ERROR_SHADER_CONTEXT_POINTER = 0x80C10008; +constexpr int ORBIS_VIDEODEC_ERROR_AU_SIZE = 0x80C10009; +constexpr int ORBIS_VIDEODEC_ERROR_AU_POINTER = 0x80C1000A; +constexpr int ORBIS_VIDEODEC_ERROR_FRAME_BUFFER_SIZE = 0x80C1000B; +constexpr int ORBIS_VIDEODEC_ERROR_FRAME_BUFFER_POINTER = 0x80C1000C; +constexpr int ORBIS_VIDEODEC_ERROR_FRAME_BUFFER_ALIGNMENT = 0x80C1000D; +constexpr int ORBIS_VIDEODEC_ERROR_CONFIG_INFO = 0x80C1000E; +constexpr int ORBIS_VIDEODEC_ERROR_ARGUMENT_POINTER = 0x80C1000F; +constexpr int ORBIS_VIDEODEC_ERROR_NEW_SEQUENCE = 0x80C10010; +constexpr int ORBIS_VIDEODEC_ERROR_DECODE_AU = 0x80C10011; +constexpr int ORBIS_VIDEODEC_ERROR_MISMATCH_SPEC = 0x80C10012; +constexpr int ORBIS_VIDEODEC_ERROR_INVALID_SEQUENCE = 0x80C10013; +constexpr int ORBIS_VIDEODEC_ERROR_FATAL_STREAM = 0x80C10014; +constexpr int ORBIS_VIDEODEC_ERROR_FATAL_STATE = 0x80C10015; + +// Videodec2 library +constexpr int ORBIS_VIDEODEC2_ERROR_API_FAIL = 0x811D0100; +constexpr int ORBIS_VIDEODEC2_ERROR_STRUCT_SIZE = 0x811D0101; +constexpr int ORBIS_VIDEODEC2_ERROR_ARGUMENT_POINTER = 0x811D0102; +constexpr int ORBIS_VIDEODEC2_ERROR_DECODER_INSTANCE = 0x811D0103; +constexpr int ORBIS_VIDEODEC2_ERROR_MEMORY_SIZE = 0x811D0104; +constexpr int ORBIS_VIDEODEC2_ERROR_MEMORY_POINTER = 0x811D0105; +constexpr int ORBIS_VIDEODEC2_ERROR_FRAME_BUFFER_SIZE = 0x811D0106; +constexpr int ORBIS_VIDEODEC2_ERROR_FRAME_BUFFER_POINTER = 0x811D0107; +constexpr int ORBIS_VIDEODEC2_ERROR_FRAME_BUFFER_ALIGNMENT = 0x811D0108; +constexpr int ORBIS_VIDEODEC2_ERROR_NOT_ONION_MEMORY = 0x811D0109; +constexpr int ORBIS_VIDEODEC2_ERROR_NOT_GARLIC_MEMORY = 0x811D010A; +constexpr int ORBIS_VIDEODEC2_ERROR_NOT_DIRECT_MEMORY = 0x811D010B; +constexpr int ORBIS_VIDEODEC2_ERROR_MEMORY_INFO = 0x811D010C; +constexpr int ORBIS_VIDEODEC2_ERROR_ACCESS_UNIT_SIZE = 0x811D010D; +constexpr int ORBIS_VIDEODEC2_ERROR_ACCESS_UNIT_POINTER = 0x811D010E; +constexpr int ORBIS_VIDEODEC2_ERROR_OUTPUT_INFO = 0x811D010F; +constexpr int ORBIS_VIDEODEC2_ERROR_COMPUTE_QUEUE = 0x811D0110; +constexpr int ORBIS_VIDEODEC2_ERROR_FATAL_STATE = 0x811D0111; +constexpr int ORBIS_VIDEODEC2_ERROR_PRESET_VALUE = 0x811D0112; +constexpr int ORBIS_VIDEODEC2_ERROR_CONFIG_INFO = 0x811D0200; +constexpr int ORBIS_VIDEODEC2_ERROR_COMPUTE_PIPE_ID = 0x811D0201; +constexpr int ORBIS_VIDEODEC2_ERROR_COMPUTE_QUEUE_ID = 0x811D0202; +constexpr int ORBIS_VIDEODEC2_ERROR_RESOURCE_TYPE = 0x811D0203; +constexpr int ORBIS_VIDEODEC2_ERROR_CODEC_TYPE = 0x811D0204; +constexpr int ORBIS_VIDEODEC2_ERROR_PROFILE_LEVEL = 0x811D0205; +constexpr int ORBIS_VIDEODEC2_ERROR_PIPELINE_DEPTH = 0x811D0206; +constexpr int ORBIS_VIDEODEC2_ERROR_AFFINITY_MASK = 0x811D0207; +constexpr int ORBIS_VIDEODEC2_ERROR_THREAD_PRIORITY = 0x811D0208; +constexpr int ORBIS_VIDEODEC2_ERROR_DPB_FRAME_COUNT = 0x811D0209; +constexpr int ORBIS_VIDEODEC2_ERROR_FRAME_WIDTH_HEIGHT = 0x811D020A; +constexpr int ORBIS_VIDEODEC2_ERROR_EXTRA_CONFIG_INFO = 0x811D020B; +constexpr int ORBIS_VIDEODEC2_ERROR_NEW_SEQUENCE = 0x811D0300; +constexpr int ORBIS_VIDEODEC2_ERROR_ACCESS_UNIT = 0x811D0301; +constexpr int ORBIS_VIDEODEC2_ERROR_OVERSIZE_DECODE = 0x811D0302; +constexpr int ORBIS_VIDEODEC2_ERROR_INVALID_SEQUENCE = 0x811D0303; +constexpr int ORBIS_VIDEODEC2_ERROR_FATAL_STREAM = 0x811D0304; diff --git a/src/core/libraries/videodec/videodec_impl.cpp b/src/core/libraries/videodec/videodec_impl.cpp index a244c4a61..cf4846971 100644 --- a/src/core/libraries/videodec/videodec_impl.cpp +++ b/src/core/libraries/videodec/videodec_impl.cpp @@ -6,7 +6,7 @@ #include "common/alignment.h" #include "common/assert.h" #include "common/logging/log.h" -#include "core/libraries/error_codes.h" +#include "core/libraries/videodec/videodec_error.h" // The av_err2str macro in libavutil/error.h does not play nice with C++ #ifdef av_err2str diff --git a/src/core/libraries/videoout/driver.cpp b/src/core/libraries/videoout/driver.cpp index d8013614c..f6c25afe3 100644 --- a/src/core/libraries/videoout/driver.cpp +++ b/src/core/libraries/videoout/driver.cpp @@ -8,10 +8,9 @@ #include "common/debug.h" #include "common/thread.h" #include "core/debug_state.h" -#include "core/libraries/error_codes.h" #include "core/libraries/kernel/time.h" #include "core/libraries/videoout/driver.h" -#include "core/platform.h" +#include "core/libraries/videoout/videoout_error.h" #include "video_core/renderer_vulkan/vk_presenter.h" extern std::unique_ptr presenter; @@ -42,10 +41,10 @@ constexpr u32 PixelFormatBpp(PixelFormat pixel_format) { } VideoOutDriver::VideoOutDriver(u32 width, u32 height) { - main_port.resolution.fullWidth = width; - main_port.resolution.fullHeight = height; - main_port.resolution.paneWidth = width; - main_port.resolution.paneHeight = height; + main_port.resolution.full_width = width; + main_port.resolution.full_height = height; + main_port.resolution.pane_width = width; + main_port.resolution.pane_height = height; present_thread = std::jthread([&](std::stop_token token) { PresentThread(token); }); } @@ -174,20 +173,21 @@ void VideoOutDriver::Flip(const Request& req) { std::unique_lock lock{port->port_mutex}; auto& flip_status = port->flip_status; flip_status.count++; - flip_status.processTime = Libraries::Kernel::sceKernelGetProcessTime(); + flip_status.process_time = Libraries::Kernel::sceKernelGetProcessTime(); flip_status.tsc = Libraries::Kernel::sceKernelReadTsc(); - flip_status.flipArg = req.flip_arg; - flip_status.currentBuffer = req.index; + flip_status.flip_arg = req.flip_arg; + flip_status.current_buffer = req.index; if (req.eop) { - --flip_status.gcQueueNum; + --flip_status.gc_queue_num; } - --flip_status.flipPendingNum; + --flip_status.flip_pending_num; } // Trigger flip events for the port. for (auto& event : port->flip_events) { if (event != nullptr) { - event->TriggerEvent(SCE_VIDEO_OUT_EVENT_FLIP, Kernel::SceKernelEvent::Filter::VideoOut, + event->TriggerEvent(u64(OrbisVideoOutEventId::Flip), + Kernel::SceKernelEvent::Filter::VideoOut, reinterpret_cast(req.flip_arg)); } } @@ -211,16 +211,16 @@ bool VideoOutDriver::SubmitFlip(VideoOutPort* port, s32 index, s64 flip_arg, bool is_eop /*= false*/) { { std::unique_lock lock{port->port_mutex}; - if (index != -1 && port->flip_status.flipPendingNum >= port->NumRegisteredBuffers()) { + if (index != -1 && port->flip_status.flip_pending_num >= port->NumRegisteredBuffers()) { LOG_ERROR(Lib_VideoOut, "Flip queue is full"); return false; } if (is_eop) { - ++port->flip_status.gcQueueNum; + ++port->flip_status.gc_queue_num; } - ++port->flip_status.flipPendingNum; // integral GPU and CPU pending flips counter - port->flip_status.submitTsc = Libraries::Kernel::sceKernelReadTsc(); + ++port->flip_status.flip_pending_num; // integral GPU and CPU pending flips counter + port->flip_status.submit_tsc = Libraries::Kernel::sceKernelReadTsc(); } if (!is_eop) { @@ -298,9 +298,9 @@ void VideoOutDriver::PresentThread(std::stop_token token) { { // Needs lock here as can be concurrently read by `sceVideoOutGetVblankStatus` - std::unique_lock lock{main_port.vo_mutex}; + std::scoped_lock lock{main_port.vo_mutex}; vblank_status.count++; - vblank_status.processTime = Libraries::Kernel::sceKernelGetProcessTime(); + vblank_status.process_time = Libraries::Kernel::sceKernelGetProcessTime(); vblank_status.tsc = Libraries::Kernel::sceKernelReadTsc(); main_port.vblank_cv.notify_all(); } @@ -308,7 +308,7 @@ void VideoOutDriver::PresentThread(std::stop_token token) { // Trigger flip events for the port. for (auto& event : main_port.vblank_events) { if (event != nullptr) { - event->TriggerEvent(SCE_VIDEO_OUT_EVENT_VBLANK, + event->TriggerEvent(u64(OrbisVideoOutEventId::Vblank), Kernel::SceKernelEvent::Filter::VideoOut, nullptr); } } diff --git a/src/core/libraries/videoout/video_out.cpp b/src/core/libraries/videoout/video_out.cpp index 0258074d3..ee4a89345 100644 --- a/src/core/libraries/videoout/video_out.cpp +++ b/src/core/libraries/videoout/video_out.cpp @@ -4,12 +4,11 @@ #include "common/assert.h" #include "common/config.h" #include "common/logging/log.h" -#include "core/libraries/error_codes.h" #include "core/libraries/libs.h" #include "core/libraries/system/userservice.h" #include "core/libraries/videoout/driver.h" #include "core/libraries/videoout/video_out.h" -#include "core/loader/symbols_resolver.h" +#include "core/libraries/videoout/videoout_error.h" #include "core/platform.h" #include "video_core/renderer_vulkan/vk_presenter.h" @@ -51,7 +50,7 @@ s32 PS4_SYSV_ABI sceVideoOutAddFlipEvent(Kernel::SceKernelEqueue eq, s32 handle, } Kernel::EqueueEvent event{}; - event.event.ident = SCE_VIDEO_OUT_EVENT_FLIP; + event.event.ident = u64(OrbisVideoOutEventId::Flip); event.event.filter = Kernel::SceKernelEvent::Filter::VideoOut; // The library only sets EV_ADD but kernel driver forces EV_CLEAR event.event.flags = Kernel::SceKernelEvent::Flags::Clear; @@ -78,7 +77,7 @@ s32 PS4_SYSV_ABI sceVideoOutAddVblankEvent(Kernel::SceKernelEqueue eq, s32 handl } Kernel::EqueueEvent event{}; - event.event.ident = SCE_VIDEO_OUT_EVENT_VBLANK; + event.event.ident = u64(OrbisVideoOutEventId::Vblank); event.event.filter = Kernel::SceKernelEvent::Filter::VideoOut; // The library only sets EV_ADD but kernel driver forces EV_CLEAR event.event.flags = Kernel::SceKernelEvent::Flags::Clear; @@ -118,7 +117,7 @@ s32 PS4_SYSV_ABI sceVideoOutIsFlipPending(s32 handle) { LOG_TRACE(Lib_VideoOut, "called"); auto* port = driver->GetPort(handle); std::unique_lock lock{port->port_mutex}; - s32 pending = port->flip_status.flipPendingNum; + s32 pending = port->flip_status.flip_pending_num; return pending; } @@ -156,7 +155,7 @@ s32 PS4_SYSV_ABI sceVideoOutSubmitFlip(s32 handle, s32 bufferIndex, s32 flipMode int PS4_SYSV_ABI sceVideoOutGetEventId(const Kernel::SceKernelEvent* ev) { if (ev == nullptr) { - return SCE_VIDEO_OUT_ERROR_INVALID_ADDRESS; + return ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS; } if (ev->filter != Kernel::SceKernelEvent::Filter::VideoOut) { return ORBIS_VIDEO_OUT_ERROR_INVALID_EVENT_QUEUE; @@ -166,7 +165,7 @@ int PS4_SYSV_ABI sceVideoOutGetEventId(const Kernel::SceKernelEvent* ev) { int PS4_SYSV_ABI sceVideoOutGetEventData(const Kernel::SceKernelEvent* ev, int64_t* data) { if (ev == nullptr || data == nullptr) { - return SCE_VIDEO_OUT_ERROR_INVALID_ADDRESS; + return ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS; } if (ev->filter != Kernel::SceKernelEvent::Filter::VideoOut) { return ORBIS_VIDEO_OUT_ERROR_INVALID_EVENT_QUEUE; @@ -204,7 +203,7 @@ s32 PS4_SYSV_ABI sceVideoOutGetFlipStatus(s32 handle, FlipStatus* status) { s32 PS4_SYSV_ABI sceVideoOutGetVblankStatus(int handle, SceVideoOutVblankStatus* status) { if (status == nullptr) { - return SCE_VIDEO_OUT_ERROR_INVALID_ADDRESS; + return ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS; } auto* port = driver->GetPort(handle); diff --git a/src/core/libraries/videoout/video_out.h b/src/core/libraries/videoout/video_out.h index 0680a8491..5af9d550d 100644 --- a/src/core/libraries/videoout/video_out.h +++ b/src/core/libraries/videoout/video_out.h @@ -40,36 +40,32 @@ constexpr int SCE_VIDEO_OUT_BUFFER_ATTRIBUTE_OPTION_NONE = 0; constexpr int SCE_VIDEO_OUT_BUFFER_ATTRIBUTE_OPTION_VR = 7; constexpr int SCE_VIDEO_OUT_BUFFER_ATTRIBUTE_OPTION_STRICT_COLORIMETRY = 8; -enum SceVideoOutEventId : s16 { - SCE_VIDEO_OUT_EVENT_FLIP = 0, - SCE_VIDEO_OUT_EVENT_VBLANK = 1, - SCE_VIDEO_OUT_EVENT_PRE_VBLANK_START = 2 -}; +enum class OrbisVideoOutEventId : s16 { Flip = 0, Vblank = 1, PreVblankStart = 2 }; -enum AspectRatioMode : s32 { - SCE_VIDEO_OUT_ASPECT_RATIO_16_9 = 0, +enum class AspectRatioMode : s32 { + Ratio16_9 = 0, }; struct FlipStatus { u64 count = 0; - u64 processTime = 0; + u64 process_time = 0; u64 tsc = 0; - s64 flipArg = -1; - u64 submitTsc = 0; + s64 flip_arg = -1; + u64 submit_tsc = 0; u64 reserved0 = 0; - s32 gcQueueNum = 0; - s32 flipPendingNum = 0; - s32 currentBuffer = -1; + s32 gc_queue_num = 0; + s32 flip_pending_num = 0; + s32 current_buffer = -1; u32 reserved1 = 0; }; struct SceVideoOutResolutionStatus { - s32 fullWidth = 1280; - s32 fullHeight = 720; - s32 paneWidth = 1280; - s32 paneHeight = 720; - u64 refreshRate = SCE_VIDEO_OUT_REFRESH_RATE_59_94HZ; - float screenSizeInInch = 50; + s32 full_width = 1280; + s32 full_height = 720; + s32 pane_width = 1280; + s32 pane_height = 720; + u64 refresh_rate = SCE_VIDEO_OUT_REFRESH_RATE_59_94HZ; + float screen_size_in_inch = 50; u16 flags = 0; u16 reserved0 = 0; u32 reserved1[3] = {0}; @@ -77,7 +73,7 @@ struct SceVideoOutResolutionStatus { struct SceVideoOutVblankStatus { u64 count = 0; - u64 processTime = 0; + u64 process_time = 0; u64 tsc = 0; u64 reserved[1] = {0}; u8 flags = 0; diff --git a/src/core/libraries/videoout/videoout_error.h b/src/core/libraries/videoout/videoout_error.h new file mode 100644 index 000000000..b1ed18c92 --- /dev/null +++ b/src/core/libraries/videoout/videoout_error.h @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/libraries/error_codes.h" + +// VideoOut library +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_VALUE = 0x80290001; +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_ADDRESS = 0x80290002; +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_PIXEL_FORMAT = 0x80290003; +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_PITCH = 0x80290004; +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_RESOLUTION = 0x80290005; +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_FLIP_MODE = 0x80290006; +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_TILING_MODE = 0x80290007; +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_ASPECT_RATIO = 0x80290008; +constexpr int ORBIS_VIDEO_OUT_ERROR_RESOURCE_BUSY = 0x80290009; +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_INDEX = 0x8029000A; +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_HANDLE = 0x8029000B; +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_EVENT_QUEUE = 0x8029000C; +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_EVENT = 0x8029000D; +constexpr int ORBIS_VIDEO_OUT_ERROR_NO_EMPTY_SLOT = 0x8029000F; +constexpr int ORBIS_VIDEO_OUT_ERROR_SLOT_OCCUPIED = 0x80290010; +constexpr int ORBIS_VIDEO_OUT_ERROR_FLIP_QUEUE_FULL = 0x80290012; +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_MEMORY = 0x80290013; +constexpr int ORBIS_VIDEO_OUT_ERROR_MEMORY_NOT_PHYSICALLY_CONTIGUOUS = 0x80290014; +constexpr int ORBIS_VIDEO_OUT_ERROR_MEMORY_INVALID_ALIGNMENT = 0x80290015; +constexpr int ORBIS_VIDEO_OUT_ERROR_UNSUPPORTED_OUTPUT_MODE = 0x80290016; +constexpr int ORBIS_VIDEO_OUT_ERROR_OVERFLOW = 0x80290017; +constexpr int ORBIS_VIDEO_OUT_ERROR_NO_DEVICE = 0x80290018; +constexpr int ORBIS_VIDEO_OUT_ERROR_UNAVAILABLE_OUTPUT_MODE = 0x80290019; +constexpr int ORBIS_VIDEO_OUT_ERROR_INVALID_OPTION = 0x8029001A; +constexpr int ORBIS_VIDEO_OUT_ERROR_UNKNOWN = 0x802900FE; +constexpr int ORBIS_VIDEO_OUT_ERROR_FATAL = 0x802900FF; +constexpr int ORBIS_VIDEO_OUT_ERROR_ENOMEM = 0x8029100C; diff --git a/src/core/linker.cpp b/src/core/linker.cpp index 9592bee0f..9cf4198ae 100644 --- a/src/core/linker.cpp +++ b/src/core/linker.cpp @@ -16,7 +16,6 @@ #include "core/linker.h" #include "core/memory.h" #include "core/tls.h" -#include "core/virtual_memory.h" namespace Core { @@ -211,7 +210,7 @@ void Linker::Relocate(Module* module) { } if (rel_is_resolved) { - VirtualMemory::memory_patch(rel_virtual_addr, rel_value); + std::memcpy(reinterpret_cast(rel_virtual_addr), &rel_value, sizeof(rel_value)); } else { LOG_INFO(Core_Linker, "Function not patched! {}", rel_name); } @@ -297,8 +296,6 @@ void* Linker::TlsGetAddr(u64 module_index, u64 offset) { u8* addr = dtv_table[module_index + 1].pointer; Module* module = m_modules[module_index - 1].get(); - // LOG_INFO(Core_Linker, "Got DTV addr {} from module index {} with name {}", - // fmt::ptr(addr), module_index, module->file.filename().string()); if (!addr) { // Module was just loaded by above code. Allocate TLS block for it. const u32 init_image_size = module->tls.init_image_size; diff --git a/src/core/memory.cpp b/src/core/memory.cpp index f638e5e1a..15fde2a57 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -5,10 +5,9 @@ #include "common/assert.h" #include "common/config.h" #include "common/debug.h" -#include "core/libraries/error_codes.h" #include "core/libraries/kernel/memory.h" +#include "core/libraries/kernel/orbis_error.h" #include "core/memory.h" -#include "video_core/renderer_vulkan/vk_instance.h" #include "video_core/renderer_vulkan/vk_rasterizer.h" namespace Core { @@ -268,7 +267,7 @@ int MemoryManager::MapMemory(void** out_addr, VAddr virtual_addr, size_t size, M // Certain games perform flexible mappings on loop to determine // the available flexible memory size. Questionable but we need to handle this. if (type == VMAType::Flexible && flexible_usage + size > total_flexible_size) { - return SCE_KERNEL_ERROR_ENOMEM; + return ORBIS_KERNEL_ERROR_ENOMEM; } // When virtual addr is zero, force it to virtual_base. The guest cannot pass Fixed diff --git a/src/core/virtual_memory.cpp b/src/core/virtual_memory.cpp deleted file mode 100644 index 8907622a4..000000000 --- a/src/core/virtual_memory.cpp +++ /dev/null @@ -1,180 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#include "common/assert.h" -#include "common/error.h" -#include "common/logging/log.h" -#include "core/virtual_memory.h" - -#ifdef _WIN64 -#include -#else -#include -#endif - -#if !defined(_WIN64) -enum PosixPageProtection { - PAGE_NOACCESS = 0, - PAGE_READONLY = PROT_READ, - PAGE_READWRITE = PROT_READ | PROT_WRITE, - PAGE_EXECUTE = PROT_EXEC, - PAGE_EXECUTE_READ = PROT_EXEC | PROT_READ, - PAGE_EXECUTE_READWRITE = PROT_EXEC | PROT_READ | PROT_WRITE -}; -#endif - -namespace VirtualMemory { -static u32 convertMemoryMode(MemoryMode mode) { - switch (mode) { - case MemoryMode::Read: - return PAGE_READONLY; - case MemoryMode::Write: - case MemoryMode::ReadWrite: - return PAGE_READWRITE; - - case MemoryMode::Execute: - return PAGE_EXECUTE; - case MemoryMode::ExecuteRead: - return PAGE_EXECUTE_READ; - case MemoryMode::ExecuteWrite: - case MemoryMode::ExecuteReadWrite: - return PAGE_EXECUTE_READWRITE; - - case MemoryMode::NoAccess: - return PAGE_NOACCESS; - default: - return PAGE_NOACCESS; - } -} -static MemoryMode convertMemoryMode(u32 mode) { - switch (mode) { - case PAGE_NOACCESS: - return MemoryMode::NoAccess; - case PAGE_READONLY: - return MemoryMode::Read; - case PAGE_READWRITE: - return MemoryMode::ReadWrite; - case PAGE_EXECUTE: - return MemoryMode::Execute; - case PAGE_EXECUTE_READ: - return MemoryMode::ExecuteRead; - case PAGE_EXECUTE_READWRITE: - return MemoryMode::ExecuteReadWrite; - default: - return MemoryMode::NoAccess; - } -} - -u64 memory_alloc(u64 address, u64 size, MemoryMode mode) { -#ifdef _WIN64 - auto ptr = reinterpret_cast(VirtualAlloc( - reinterpret_cast(static_cast(address)), size, - static_cast(MEM_COMMIT) | static_cast(MEM_RESERVE), convertMemoryMode(mode))); - - if (ptr == 0) { - auto err = static_cast(GetLastError()); - LOG_ERROR(Common_Memory, "VirtualAlloc() failed: 0x{:X}", err); - } -#else - auto ptr = reinterpret_cast( - mmap(reinterpret_cast(static_cast(address)), size, - PROT_EXEC | PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0)); - - if (ptr == reinterpret_cast MAP_FAILED) { - LOG_ERROR(Common_Memory, "mmap() failed: {}", std::strerror(errno)); - } -#endif - return ptr; -} -bool memory_protect(u64 address, u64 size, MemoryMode mode, MemoryMode* old_mode) { -#ifdef _WIN64 - DWORD old_protect = 0; - if (VirtualProtect(reinterpret_cast(static_cast(address)), size, - convertMemoryMode(mode), &old_protect) == 0) { - auto err = static_cast(GetLastError()); - LOG_ERROR(Common_Memory, "VirtualProtect() failed: 0x{:X}", err); - return false; - } - if (old_mode != nullptr) { - *old_mode = convertMemoryMode(old_protect); - } - return true; -#else - int ret = mprotect(reinterpret_cast(address), size, convertMemoryMode(mode)); - if (ret != 0) { - const auto error = Common::GetLastErrorMsg(); - ASSERT(false); - } - return true; -#endif -} - -bool memory_flush(u64 address, u64 size) { -#ifdef _WIN64 - if (::FlushInstructionCache(GetCurrentProcess(), - reinterpret_cast(static_cast(address)), - size) == 0) { - auto err = static_cast(GetLastError()); - LOG_ERROR(Common_Memory, "FlushInstructionCache() failed: 0x{:X}", err); - return false; - } - return true; -#else // linux probably doesn't have something similar - return true; -#endif -} -bool memory_patch(u64 vaddr, u64 value) { - MemoryMode old_mode{}; - // memory_protect(vaddr, 8, MemoryMode::ReadWrite, &old_mode); - - auto* ptr = reinterpret_cast(vaddr); - - bool ret = (*ptr != value); - - *ptr = value; - - // memory_protect(vaddr, 8, old_mode, nullptr); - - // if mode is executable flush it so insure that cpu finds it - if (containsExecuteMode(old_mode)) { - memory_flush(vaddr, 8); - } - - return ret; -} -static u64 AlignUp(u64 pos, u64 align) { - return (align != 0 ? (pos + (align - 1)) & ~(align - 1) : pos); -} - -u64 memory_alloc_aligned(u64 address, u64 size, MemoryMode mode, u64 alignment) { -#ifdef _WIN64 - // try allocate aligned address inside user area - MEM_ADDRESS_REQUIREMENTS req{}; - MEM_EXTENDED_PARAMETER param{}; - req.LowestStartingAddress = - (address == 0 ? reinterpret_cast(USER_MIN) - : reinterpret_cast(AlignUp(address, alignment))); - req.HighestEndingAddress = reinterpret_cast(USER_MAX); - req.Alignment = alignment; - param.Type = MemExtendedParameterAddressRequirements; - param.Pointer = &req; - - auto ptr = reinterpret_cast( - VirtualAlloc2(GetCurrentProcess(), nullptr, size, - static_cast(MEM_COMMIT) | static_cast(MEM_RESERVE), - convertMemoryMode(mode), ¶m, 1)); - - if (ptr == 0) { - auto err = static_cast(GetLastError()); - LOG_ERROR(Common_Memory, "VirtualAlloc2() failed: 0x{:X}", err); - } - return ptr; -#else - void* hint_address = address == 0 ? reinterpret_cast(USER_MIN) - : reinterpret_cast(AlignUp(address, alignment)); - void* ptr = mmap(hint_address, size, convertMemoryMode(mode), MAP_ANON | MAP_PRIVATE, -1, 0); - ASSERT(ptr != MAP_FAILED); - return reinterpret_cast(ptr); -#endif -} -} // namespace VirtualMemory diff --git a/src/core/virtual_memory.h b/src/core/virtual_memory.h deleted file mode 100644 index 953f35f79..000000000 --- a/src/core/virtual_memory.h +++ /dev/null @@ -1,47 +0,0 @@ -// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project -// SPDX-License-Identifier: GPL-2.0-or-later - -#pragma once - -#include "common/types.h" - -constexpr u64 SYSTEM_RESERVED = 0x800000000u; -constexpr u64 CODE_BASE_OFFSET = 0x100000000u; -constexpr u64 SYSTEM_MANAGED_MIN = 0x0000040000u; -constexpr u64 SYSTEM_MANAGED_MAX = 0x07FFFFBFFFu; -constexpr u64 USER_MIN = 0x1000000000u; -constexpr u64 USER_MAX = 0xFBFFFFFFFFu; - -namespace VirtualMemory { -enum class MemoryMode : u32 { - NoAccess = 0, - Read = 1, - Write = 2, - ReadWrite = 3, - Execute = 4, - ExecuteRead = 5, - ExecuteWrite = 6, - ExecuteReadWrite = 7, -}; -u64 memory_alloc(u64 address, u64 size, MemoryMode mode); -u64 memory_alloc_aligned(u64 address, u64 size, MemoryMode mode, u64 alignment); -bool memory_protect(u64 address, u64 size, MemoryMode mode, MemoryMode* old_mode); -bool memory_flush(u64 address, u64 size); -bool memory_patch(u64 vaddr, u64 value); - -inline bool containsExecuteMode(MemoryMode mode) { - switch (mode) { - case MemoryMode::Execute: - return true; - case MemoryMode::ExecuteRead: - return true; - case MemoryMode::ExecuteWrite: - return true; - case MemoryMode::ExecuteReadWrite: - return true; - default: - return false; - } -} - -} // namespace VirtualMemory diff --git a/src/emulator.cpp b/src/emulator.cpp index a01eb816b..4ab535a2c 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -257,9 +257,9 @@ void Emulator::Run(const std::filesystem::path& file) { linker->Execute(); - window->initTimers(); - while (window->isOpen()) { - window->waitEvent(); + window->InitTimers(); + while (window->IsOpen()) { + window->WaitEvent(); } #ifdef ENABLE_QT_GUI diff --git a/src/imgui/renderer/imgui_core.cpp b/src/imgui/renderer/imgui_core.cpp index 47f60e8e4..46391faef 100644 --- a/src/imgui/renderer/imgui_core.cpp +++ b/src/imgui/renderer/imgui_core.cpp @@ -49,7 +49,7 @@ void Initialize(const ::Vulkan::Instance& instance, const Frontend::WindowSDL& w io.ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; io.ConfigFlags |= ImGuiConfigFlags_NavEnableGamepad; io.ConfigFlags |= ImGuiConfigFlags_DockingEnable; - io.DisplaySize = ImVec2((float)window.getWidth(), (float)window.getHeight()); + io.DisplaySize = ImVec2((float)window.GetWidth(), (float)window.GetHeight()); PushStyleVar(ImGuiStyleVar_WindowRounding, 6.0f); // Makes the window edges rounded auto path = config_path.u8string(); @@ -83,7 +83,7 @@ void Initialize(const ::Vulkan::Instance& instance, const Frontend::WindowSDL& w StyleColorsDark(); ::Core::Devtools::Layer::SetupSettings(); - Sdl::Init(window.GetSdlWindow()); + Sdl::Init(window.GetSDLWindow()); const Vulkan::InitInfo vk_info{ .instance = instance.GetInstance(), @@ -108,7 +108,7 @@ void Initialize(const ::Vulkan::Instance& instance, const Frontend::WindowSDL& w ImFormatString(label, IM_ARRAYSIZE(label), "WindowOverViewport_%08X", GetMainViewport()->ID); dock_id = ImHashStr(label); - if (const auto dpi = SDL_GetWindowDisplayScale(window.GetSdlWindow()); dpi > 0.0f) { + if (const auto dpi = SDL_GetWindowDisplayScale(window.GetSDLWindow()); dpi > 0.0f) { GetIO().FontGlobalScale = dpi; } } diff --git a/src/input/controller.cpp b/src/input/controller.cpp index cd7d3d8af..3927b096f 100644 --- a/src/input/controller.cpp +++ b/src/input/controller.cpp @@ -1,13 +1,10 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later -#include "controller.h" - -#include "common/assert.h" +#include #include "core/libraries/kernel/time.h" #include "core/libraries/pad/pad.h" - -#include +#include "input/controller.h" namespace Input { @@ -59,9 +56,7 @@ State GameController::GetLastState() const { if (m_states_num == 0) { return m_last_state; } - - auto last = (m_first_state + m_states_num - 1) % MAX_STATES; - + const u32 last = (m_first_state + m_states_num - 1) % MAX_STATES; return m_states[last]; } @@ -71,19 +66,19 @@ void GameController::AddState(const State& state) { m_first_state = (m_first_state + 1) % MAX_STATES; } - auto index = (m_first_state + m_states_num) % MAX_STATES; - + const u32 index = (m_first_state + m_states_num) % MAX_STATES; m_states[index] = state; m_last_state = state; m_private[index].obtained = false; m_states_num++; } -void GameController::CheckButton(int id, u32 button, bool isPressed) { +void GameController::CheckButton(int id, Libraries::Pad::OrbisPadButtonDataOffset button, + bool is_pressed) { std::scoped_lock lock{m_mutex}; auto state = GetLastState(); state.time = Libraries::Kernel::sceKernelGetProcessTime(); - if (isPressed) { + if (is_pressed) { state.buttonsState |= button; } else { state.buttonsState &= ~button; @@ -93,28 +88,28 @@ void GameController::CheckButton(int id, u32 button, bool isPressed) { } void GameController::Axis(int id, Input::Axis axis, int value) { + using Libraries::Pad::OrbisPadButtonDataOffset; + std::scoped_lock lock{m_mutex}; auto state = GetLastState(); state.time = Libraries::Kernel::sceKernelGetProcessTime(); - int axis_id = static_cast(axis); - state.axes[axis_id] = value; if (axis == Input::Axis::TriggerLeft) { if (value > 0) { - state.buttonsState |= Libraries::Pad::OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_L2; + state.buttonsState |= OrbisPadButtonDataOffset::L2; } else { - state.buttonsState &= ~Libraries::Pad::OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_L2; + state.buttonsState &= ~OrbisPadButtonDataOffset::L2; } } if (axis == Input::Axis::TriggerRight) { if (value > 0) { - state.buttonsState |= Libraries::Pad::OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_R2; + state.buttonsState |= OrbisPadButtonDataOffset::R2; } else { - state.buttonsState &= ~Libraries::Pad::OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_R2; + state.buttonsState &= ~OrbisPadButtonDataOffset::R2; } } diff --git a/src/input/controller.h b/src/input/controller.h index 01ea21c0c..d425fb46c 100644 --- a/src/input/controller.h +++ b/src/input/controller.h @@ -5,6 +5,7 @@ #include #include "common/types.h" +#include "core/libraries/pad/pad.h" struct SDL_Gamepad; @@ -28,7 +29,7 @@ struct TouchpadEntry { }; struct State { - u32 buttonsState = 0; + Libraries::Pad::OrbisPadButtonDataOffset buttonsState{}; u64 time = 0; int axes[static_cast(Axis::AxisMax)] = {128, 128, 128, 128, 0, 0}; TouchpadEntry touchpad[2] = {{false, 0, 0}, {false, 0, 0}}; @@ -49,7 +50,7 @@ public: void ReadState(State* state, bool* isConnected, int* connectedCount); int ReadStates(State* states, int states_num, bool* isConnected, int* connectedCount); State GetLastState() const; - void CheckButton(int id, u32 button, bool isPressed); + void CheckButton(int id, Libraries::Pad::OrbisPadButtonDataOffset button, bool isPressed); void AddState(const State& state); void Axis(int id, Input::Axis axis, int value); void SetLightBarRGB(u8 r, u8 g, u8 b); diff --git a/src/sdl_window.cpp b/src/sdl_window.cpp index ad7d1b4a6..d95e8d634 100644 --- a/src/sdl_window.cpp +++ b/src/sdl_window.cpp @@ -6,9 +6,9 @@ #include #include #include + #include "common/assert.h" #include "common/config.h" -#include "common/version.h" #include "core/libraries/pad/pad.h" #include "imgui/renderer/imgui_core.h" #include "input/controller.h" @@ -21,6 +21,45 @@ namespace Frontend { +using namespace Libraries::Pad; + +static OrbisPadButtonDataOffset SDLGamepadToOrbisButton(u8 button) { + switch (button) { + case SDL_GAMEPAD_BUTTON_DPAD_DOWN: + return OrbisPadButtonDataOffset::Down; + case SDL_GAMEPAD_BUTTON_DPAD_UP: + return OrbisPadButtonDataOffset::Up; + case SDL_GAMEPAD_BUTTON_DPAD_LEFT: + return OrbisPadButtonDataOffset::Left; + case SDL_GAMEPAD_BUTTON_DPAD_RIGHT: + return OrbisPadButtonDataOffset::Right; + case SDL_GAMEPAD_BUTTON_SOUTH: + return OrbisPadButtonDataOffset::Cross; + case SDL_GAMEPAD_BUTTON_NORTH: + return OrbisPadButtonDataOffset::Triangle; + case SDL_GAMEPAD_BUTTON_WEST: + return OrbisPadButtonDataOffset::Square; + case SDL_GAMEPAD_BUTTON_EAST: + return OrbisPadButtonDataOffset::Circle; + case SDL_GAMEPAD_BUTTON_START: + return OrbisPadButtonDataOffset::Options; + case SDL_GAMEPAD_BUTTON_TOUCHPAD: + return OrbisPadButtonDataOffset::TouchPad; + case SDL_GAMEPAD_BUTTON_BACK: + return OrbisPadButtonDataOffset::TouchPad; + case SDL_GAMEPAD_BUTTON_LEFT_SHOULDER: + return OrbisPadButtonDataOffset::L1; + case SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER: + return OrbisPadButtonDataOffset::R1; + case SDL_GAMEPAD_BUTTON_LEFT_STICK: + return OrbisPadButtonDataOffset::L3; + case SDL_GAMEPAD_BUTTON_RIGHT_STICK: + return OrbisPadButtonDataOffset::R3; + default: + return OrbisPadButtonDataOffset::None; + } +} + static Uint32 SDLCALL PollController(void* userdata, SDL_TimerID timer_id, Uint32 interval) { auto* controller = reinterpret_cast(userdata); return controller->Poll(); @@ -80,7 +119,7 @@ WindowSDL::WindowSDL(s32 width_, s32 height_, Input::GameController* controller_ WindowSDL::~WindowSDL() = default; -void WindowSDL::waitEvent() { +void WindowSDL::WaitEvent() { // Called on main thread SDL_Event event; @@ -96,16 +135,16 @@ void WindowSDL::waitEvent() { case SDL_EVENT_WINDOW_RESIZED: case SDL_EVENT_WINDOW_MAXIMIZED: case SDL_EVENT_WINDOW_RESTORED: - onResize(); + OnResize(); break; case SDL_EVENT_WINDOW_MINIMIZED: case SDL_EVENT_WINDOW_EXPOSED: is_shown = event.type == SDL_EVENT_WINDOW_EXPOSED; - onResize(); + OnResize(); break; case SDL_EVENT_KEY_DOWN: case SDL_EVENT_KEY_UP: - onKeyPress(&event); + OnKeyPress(&event); break; case SDL_EVENT_GAMEPAD_BUTTON_DOWN: case SDL_EVENT_GAMEPAD_BUTTON_UP: @@ -115,7 +154,7 @@ void WindowSDL::waitEvent() { case SDL_EVENT_GAMEPAD_TOUCHPAD_DOWN: case SDL_EVENT_GAMEPAD_TOUCHPAD_UP: case SDL_EVENT_GAMEPAD_TOUCHPAD_MOTION: - onGamepadEvent(&event); + OnGamepadEvent(&event); break; case SDL_EVENT_QUIT: is_open = false; @@ -125,18 +164,16 @@ void WindowSDL::waitEvent() { } } -void WindowSDL::initTimers() { +void WindowSDL::InitTimers() { SDL_AddTimer(100, &PollController, controller); } -void WindowSDL::onResize() { +void WindowSDL::OnResize() { SDL_GetWindowSizeInPixels(window, &width, &height); ImGui::Core::OnResize(); } -void WindowSDL::onKeyPress(const SDL_Event* event) { - using Libraries::Pad::OrbisPadButtonDataOffset; - +void WindowSDL::OnKeyPress(const SDL_Event* event) { #ifdef __APPLE__ // Use keys that are more friendly for keyboards without a keypad. // Once there are key binding options this won't be necessary. @@ -151,38 +188,38 @@ void WindowSDL::onKeyPress(const SDL_Event* event) { constexpr SDL_Keycode TriangleKey = SDLK_KP_8; #endif - u32 button = 0; + auto button = OrbisPadButtonDataOffset::None; Input::Axis axis = Input::Axis::AxisMax; int axisvalue = 0; int ax = 0; std::string backButtonBehavior = Config::getBackButtonBehavior(); switch (event->key.key) { case SDLK_UP: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_UP; + button = OrbisPadButtonDataOffset::Up; break; case SDLK_DOWN: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_DOWN; + button = OrbisPadButtonDataOffset::Down; break; case SDLK_LEFT: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_LEFT; + button = OrbisPadButtonDataOffset::Left; break; case SDLK_RIGHT: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_RIGHT; + button = OrbisPadButtonDataOffset::Right; break; case TriangleKey: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_TRIANGLE; + button = OrbisPadButtonDataOffset::Triangle; break; case CircleKey: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_CIRCLE; + button = OrbisPadButtonDataOffset::Circle; break; case CrossKey: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_CROSS; + button = OrbisPadButtonDataOffset::Cross; break; case SquareKey: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_SQUARE; + button = OrbisPadButtonDataOffset::Square; break; case SDLK_RETURN: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_OPTIONS; + button = OrbisPadButtonDataOffset::Options; break; case SDLK_A: axis = Input::Axis::LeftX; @@ -257,19 +294,19 @@ void WindowSDL::onKeyPress(const SDL_Event* event) { ax = Input::GetAxis(-0x80, 0x80, axisvalue); break; case SDLK_X: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_L3; + button = OrbisPadButtonDataOffset::L3; break; case SDLK_M: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_R3; + button = OrbisPadButtonDataOffset::R3; break; case SDLK_Q: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_L1; + button = OrbisPadButtonDataOffset::L1; break; case SDLK_U: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_R1; + button = OrbisPadButtonDataOffset::R1; break; case SDLK_E: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_L2; + button = OrbisPadButtonDataOffset::L2; axis = Input::Axis::TriggerLeft; if (event->type == SDL_EVENT_KEY_DOWN) { axisvalue += 255; @@ -279,7 +316,7 @@ void WindowSDL::onKeyPress(const SDL_Event* event) { ax = Input::GetAxis(0, 0x80, axisvalue); break; case SDLK_O: - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_R2; + button = OrbisPadButtonDataOffset::R2; axis = Input::Axis::TriggerRight; if (event->type == SDL_EVENT_KEY_DOWN) { axisvalue += 255; @@ -294,9 +331,9 @@ void WindowSDL::onKeyPress(const SDL_Event* event) { : (backButtonBehavior == "right" ? 0.75f : 0.5f); // trigger a touchpad event so that the touchpad emulation for back button works controller->SetTouchpadState(0, true, x, 0.5f); - button = OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_TOUCH_PAD; + button = OrbisPadButtonDataOffset::TouchPad; } else { - button = 0; + button = {}; } break; case SDLK_F11: @@ -317,7 +354,7 @@ void WindowSDL::onKeyPress(const SDL_Event* event) { default: break; } - if (button != 0) { + if (button != OrbisPadButtonDataOffset::None) { controller->CheckButton(0, button, event->type == SDL_EVENT_KEY_DOWN); } if (axis != Input::Axis::AxisMax) { @@ -325,10 +362,8 @@ void WindowSDL::onKeyPress(const SDL_Event* event) { } } -void WindowSDL::onGamepadEvent(const SDL_Event* event) { - using Libraries::Pad::OrbisPadButtonDataOffset; - - u32 button = 0; +void WindowSDL::OnGamepadEvent(const SDL_Event* event) { + auto button = OrbisPadButtonDataOffset::None; Input::Axis axis = Input::Axis::AxisMax; switch (event->type) { case SDL_EVENT_GAMEPAD_ADDED: @@ -343,25 +378,25 @@ void WindowSDL::onGamepadEvent(const SDL_Event* event) { event->gtouchpad.x, event->gtouchpad.y); break; case SDL_EVENT_GAMEPAD_BUTTON_DOWN: - case SDL_EVENT_GAMEPAD_BUTTON_UP: - button = sdlGamepadToOrbisButton(event->gbutton.button); - if (button != 0) { - if (event->gbutton.button == SDL_GAMEPAD_BUTTON_BACK) { - std::string backButtonBehavior = Config::getBackButtonBehavior(); - if (backButtonBehavior != "none") { - float x = backButtonBehavior == "left" - ? 0.25f - : (backButtonBehavior == "right" ? 0.75f : 0.5f); - // trigger a touchpad event so that the touchpad emulation for back button works - controller->SetTouchpadState(0, true, x, 0.5f); - controller->CheckButton(0, button, - event->type == SDL_EVENT_GAMEPAD_BUTTON_DOWN); - } - } else { - controller->CheckButton(0, button, event->type == SDL_EVENT_GAMEPAD_BUTTON_DOWN); - } + case SDL_EVENT_GAMEPAD_BUTTON_UP: { + button = SDLGamepadToOrbisButton(event->gbutton.button); + if (button == OrbisPadButtonDataOffset::None) { + break; + } + if (event->gbutton.button != SDL_GAMEPAD_BUTTON_BACK) { + controller->CheckButton(0, button, event->type == SDL_EVENT_GAMEPAD_BUTTON_DOWN); + break; + } + const auto backButtonBehavior = Config::getBackButtonBehavior(); + if (backButtonBehavior != "none") { + float x = backButtonBehavior == "left" ? 0.25f + : (backButtonBehavior == "right" ? 0.75f : 0.5f); + // trigger a touchpad event so that the touchpad emulation for back button works + controller->SetTouchpadState(0, true, x, 0.5f); + controller->CheckButton(0, button, event->type == SDL_EVENT_GAMEPAD_BUTTON_DOWN); } break; + } case SDL_EVENT_GAMEPAD_AXIS_MOTION: axis = event->gaxis.axis == SDL_GAMEPAD_AXIS_LEFTX ? Input::Axis::LeftX : event->gaxis.axis == SDL_GAMEPAD_AXIS_LEFTY ? Input::Axis::LeftY @@ -383,43 +418,4 @@ void WindowSDL::onGamepadEvent(const SDL_Event* event) { } } -int WindowSDL::sdlGamepadToOrbisButton(u8 button) { - using Libraries::Pad::OrbisPadButtonDataOffset; - - switch (button) { - case SDL_GAMEPAD_BUTTON_DPAD_DOWN: - return OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_DOWN; - case SDL_GAMEPAD_BUTTON_DPAD_UP: - return OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_UP; - case SDL_GAMEPAD_BUTTON_DPAD_LEFT: - return OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_LEFT; - case SDL_GAMEPAD_BUTTON_DPAD_RIGHT: - return OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_RIGHT; - case SDL_GAMEPAD_BUTTON_SOUTH: - return OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_CROSS; - case SDL_GAMEPAD_BUTTON_NORTH: - return OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_TRIANGLE; - case SDL_GAMEPAD_BUTTON_WEST: - return OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_SQUARE; - case SDL_GAMEPAD_BUTTON_EAST: - return OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_CIRCLE; - case SDL_GAMEPAD_BUTTON_START: - return OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_OPTIONS; - case SDL_GAMEPAD_BUTTON_TOUCHPAD: - return OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_TOUCH_PAD; - case SDL_GAMEPAD_BUTTON_BACK: - return OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_TOUCH_PAD; - case SDL_GAMEPAD_BUTTON_LEFT_SHOULDER: - return OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_L1; - case SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER: - return OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_R1; - case SDL_GAMEPAD_BUTTON_LEFT_STICK: - return OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_L3; - case SDL_GAMEPAD_BUTTON_RIGHT_STICK: - return OrbisPadButtonDataOffset::ORBIS_PAD_BUTTON_R3; - default: - return 0; - } -} - } // namespace Frontend diff --git a/src/sdl_window.h b/src/sdl_window.h index ec8de354b..78d0e582f 100644 --- a/src/sdl_window.h +++ b/src/sdl_window.h @@ -46,36 +46,33 @@ public: std::string_view window_title); ~WindowSDL(); - s32 getWidth() const { + s32 GetWidth() const { return width; } - s32 getHeight() const { + s32 GetHeight() const { return height; } - bool isOpen() const { + bool IsOpen() const { return is_open; } - [[nodiscard]] SDL_Window* GetSdlWindow() const { + [[nodiscard]] SDL_Window* GetSDLWindow() const { return window; } - WindowSystemInfo getWindowInfo() const { + WindowSystemInfo GetWindowInfo() const { return window_info; } - void waitEvent(); - - void initTimers(); + void WaitEvent(); + void InitTimers(); private: - void onResize(); - void onKeyPress(const SDL_Event* event); - void onGamepadEvent(const SDL_Event* event); - - int sdlGamepadToOrbisButton(u8 button); + void OnResize(); + void OnKeyPress(const SDL_Event* event); + void OnGamepadEvent(const SDL_Event* event); private: s32 width; diff --git a/src/video_core/renderer_vulkan/vk_instance.cpp b/src/video_core/renderer_vulkan/vk_instance.cpp index a16f35ed7..580458e7e 100644 --- a/src/video_core/renderer_vulkan/vk_instance.cpp +++ b/src/video_core/renderer_vulkan/vk_instance.cpp @@ -95,7 +95,7 @@ Instance::Instance(bool enable_validation, bool enable_crash_diagnostic) Instance::Instance(Frontend::WindowSDL& window, s32 physical_device_index, bool enable_validation /*= false*/, bool enable_crash_diagnostic /*= false*/) - : instance{CreateInstance(window.getWindowInfo().type, enable_validation, + : instance{CreateInstance(window.GetWindowInfo().type, enable_validation, enable_crash_diagnostic)}, physical_devices{EnumeratePhysicalDevices(instance)} { if (enable_validation) { diff --git a/src/video_core/renderer_vulkan/vk_platform.cpp b/src/video_core/renderer_vulkan/vk_platform.cpp index 0eb7e0759..b2a50cd44 100644 --- a/src/video_core/renderer_vulkan/vk_platform.cpp +++ b/src/video_core/renderer_vulkan/vk_platform.cpp @@ -73,7 +73,7 @@ static VKAPI_ATTR VkBool32 VKAPI_CALL DebugUtilsCallback( } vk::SurfaceKHR CreateSurface(vk::Instance instance, const Frontend::WindowSDL& emu_window) { - const auto& window_info = emu_window.getWindowInfo(); + const auto& window_info = emu_window.GetWindowInfo(); vk::SurfaceKHR surface{}; #if defined(VK_USE_PLATFORM_WIN32_KHR) diff --git a/src/video_core/renderer_vulkan/vk_presenter.cpp b/src/video_core/renderer_vulkan/vk_presenter.cpp index 23d2981f5..b7d829316 100644 --- a/src/video_core/renderer_vulkan/vk_presenter.cpp +++ b/src/video_core/renderer_vulkan/vk_presenter.cpp @@ -629,9 +629,9 @@ Frame* Presenter::PrepareFrameInternal(VideoCore::ImageId image_id, bool is_eop) void Presenter::Present(Frame* frame) { // Recreate the swapchain if the window was resized. - if (window.getWidth() != swapchain.GetExtent().width || - window.getHeight() != swapchain.GetExtent().height) { - swapchain.Recreate(window.getWidth(), window.getHeight()); + if (window.GetWidth() != swapchain.GetExtent().width || + window.GetHeight() != swapchain.GetExtent().height) { + swapchain.Recreate(window.GetWidth(), window.GetHeight()); } ImGui::Core::NewFrame(); @@ -776,8 +776,8 @@ Frame* Presenter::GetRenderFrame() { device.resetFences(frame->present_done); // If the window dimensions changed, recreate this frame - if (frame->width != window.getWidth() || frame->height != window.getHeight()) { - RecreateFrame(frame, window.getWidth(), window.getHeight()); + if (frame->width != window.GetWidth() || frame->height != window.GetHeight()) { + RecreateFrame(frame, window.GetWidth(), window.GetHeight()); } return frame; diff --git a/src/video_core/renderer_vulkan/vk_swapchain.cpp b/src/video_core/renderer_vulkan/vk_swapchain.cpp index 86d7d5063..d0bc7ebdc 100644 --- a/src/video_core/renderer_vulkan/vk_swapchain.cpp +++ b/src/video_core/renderer_vulkan/vk_swapchain.cpp @@ -14,7 +14,7 @@ namespace Vulkan { Swapchain::Swapchain(const Instance& instance_, const Frontend::WindowSDL& window) : instance{instance_}, surface{CreateSurface(instance.GetInstance(), window)} { FindPresentFormat(); - Create(window.getWidth(), window.getHeight(), surface); + Create(window.GetWidth(), window.GetHeight(), surface); } Swapchain::~Swapchain() { From b0860d6e8c95cf585f28a5096135878b15e47931 Mon Sep 17 00:00:00 2001 From: Jamie Tong Date: Sun, 1 Dec 2024 04:39:11 +0800 Subject: [PATCH 17/32] implement DS_AND_B32, DS_OR_B32, DS_XOR_B32 (#1593) * implement DS_OR_B32 * implement DS_AND_B32, DS_XOR_B32 --- .../backend/spirv/emit_spirv_atomic.cpp | 12 +++++ .../backend/spirv/emit_spirv_instructions.h | 3 ++ .../frontend/translate/data_share.cpp | 49 +++++++++++++++++++ .../frontend/translate/translate.h | 3 ++ src/shader_recompiler/ir/ir_emitter.cpp | 12 +++++ src/shader_recompiler/ir/ir_emitter.h | 3 ++ src/shader_recompiler/ir/microinstruction.cpp | 3 ++ src/shader_recompiler/ir/opcodes.inc | 3 ++ 8 files changed, 88 insertions(+) diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp index a58b2778f..ce65a5ccb 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_atomic.cpp @@ -60,6 +60,18 @@ Id EmitSharedAtomicSMin32(EmitContext& ctx, Id offset, Id value) { return SharedAtomicU32(ctx, offset, value, &Sirit::Module::OpAtomicSMin); } +Id EmitSharedAtomicAnd32(EmitContext& ctx, Id offset, Id value) { + return SharedAtomicU32(ctx, offset, value, &Sirit::Module::OpAtomicAnd); +} + +Id EmitSharedAtomicOr32(EmitContext& ctx, Id offset, Id value) { + return SharedAtomicU32(ctx, offset, value, &Sirit::Module::OpAtomicOr); +} + +Id EmitSharedAtomicXor32(EmitContext& ctx, Id offset, Id value) { + return SharedAtomicU32(ctx, offset, value, &Sirit::Module::OpAtomicXor); +} + Id EmitBufferAtomicIAdd32(EmitContext& ctx, IR::Inst* inst, u32 handle, Id address, Id value) { return BufferAtomicU32(ctx, inst, handle, address, value, &Sirit::Module::OpAtomicIAdd); } diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h index 12361991a..cc3db880c 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h +++ b/src/shader_recompiler/backend/spirv/emit_spirv_instructions.h @@ -112,6 +112,9 @@ Id EmitSharedAtomicUMax32(EmitContext& ctx, Id offset, Id value); Id EmitSharedAtomicSMax32(EmitContext& ctx, Id offset, Id value); Id EmitSharedAtomicUMin32(EmitContext& ctx, Id offset, Id value); 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 EmitCompositeConstructU32x2(EmitContext& ctx, Id e1, Id e2); Id EmitCompositeConstructU32x3(EmitContext& ctx, Id e1, Id e2, Id e3); Id EmitCompositeConstructU32x4(EmitContext& ctx, Id e1, Id e2, Id e3, Id e4); diff --git a/src/shader_recompiler/frontend/translate/data_share.cpp b/src/shader_recompiler/frontend/translate/data_share.cpp index 2f5932f80..5914f9fe3 100644 --- a/src/shader_recompiler/frontend/translate/data_share.cpp +++ b/src/shader_recompiler/frontend/translate/data_share.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "shader_recompiler/frontend/translate/translate.h" +#include "shader_recompiler/ir/reg.h" namespace Shader::Gcn { @@ -18,6 +19,12 @@ void Translator::EmitDataShare(const GcnInst& inst) { return DS_MIN_U32(inst, false, false); case Opcode::DS_MAX_U32: return DS_MAX_U32(inst, false, false); + case Opcode::DS_AND_B32: + return DS_AND_B32(inst, false); + case Opcode::DS_OR_B32: + return DS_OR_B32(inst, false); + case Opcode::DS_XOR_B32: + return DS_XOR_B32(inst, false); case Opcode::DS_WRITE_B32: return DS_WRITE(32, false, false, false, inst); case Opcode::DS_WRITE2_B32: @@ -30,6 +37,12 @@ void Translator::EmitDataShare(const GcnInst& inst) { return DS_MIN_U32(inst, false, true); case Opcode::DS_MAX_RTN_U32: return DS_MAX_U32(inst, false, true); + case Opcode::DS_AND_RTN_B32: + return DS_AND_B32(inst, true); + case Opcode::DS_OR_RTN_B32: + return DS_OR_B32(inst, true); + case Opcode::DS_XOR_RTN_B32: + return DS_XOR_B32(inst, true); case Opcode::DS_SWIZZLE_B32: return DS_SWIZZLE_B32(inst); case Opcode::DS_READ_B32: @@ -119,6 +132,42 @@ void Translator::DS_MAX_U32(const GcnInst& inst, bool is_signed, bool rtn) { } } +void Translator::DS_AND_B32(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.SharedAtomicAnd(addr_offset, data); + if (rtn) { + SetDst(inst.dst[0], IR::U32{original_val}); + } +} + +void Translator::DS_OR_B32(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.SharedAtomicOr(addr_offset, data); + if (rtn) { + SetDst(inst.dst[0], IR::U32{original_val}); + } +} + +void Translator::DS_XOR_B32(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.SharedAtomicXor(addr_offset, data); + if (rtn) { + SetDst(inst.dst[0], IR::U32{original_val}); + } +} + void Translator::DS_WRITE(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))}; diff --git a/src/shader_recompiler/frontend/translate/translate.h b/src/shader_recompiler/frontend/translate/translate.h index f04038909..3b89372bd 100644 --- a/src/shader_recompiler/frontend/translate/translate.h +++ b/src/shader_recompiler/frontend/translate/translate.h @@ -250,6 +250,9 @@ public: void DS_MAX_U32(const GcnInst& inst, bool is_signed, bool rtn); void DS_WRITE(int bit_size, bool is_signed, bool is_pair, bool stride64, const GcnInst& inst); void DS_SWIZZLE_B32(const GcnInst& inst); + void DS_AND_B32(const GcnInst& inst, bool rtn); + void DS_OR_B32(const GcnInst& inst, bool rtn); + void DS_XOR_B32(const GcnInst& inst, bool rtn); 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); diff --git a/src/shader_recompiler/ir/ir_emitter.cpp b/src/shader_recompiler/ir/ir_emitter.cpp index 73b33432b..78e7f2289 100644 --- a/src/shader_recompiler/ir/ir_emitter.cpp +++ b/src/shader_recompiler/ir/ir_emitter.cpp @@ -326,6 +326,18 @@ U32 IREmitter::SharedAtomicIMax(const U32& address, const U32& data, bool is_sig : Inst(Opcode::SharedAtomicUMax32, address, data); } +U32 IREmitter::SharedAtomicAnd(const U32& address, const U32& data) { + return Inst(Opcode::SharedAtomicAnd32, address, data); +} + +U32 IREmitter::SharedAtomicOr(const U32& address, const U32& data) { + return Inst(Opcode::SharedAtomicOr32, address, data); +} + +U32 IREmitter::SharedAtomicXor(const U32& address, const U32& data) { + return Inst(Opcode::SharedAtomicXor32, address, data); +} + U32 IREmitter::ReadConst(const Value& base, const U32& offset) { return Inst(Opcode::ReadConst, base, offset); } diff --git a/src/shader_recompiler/ir/ir_emitter.h b/src/shader_recompiler/ir/ir_emitter.h index b3f513085..cbd3780de 100644 --- a/src/shader_recompiler/ir/ir_emitter.h +++ b/src/shader_recompiler/ir/ir_emitter.h @@ -90,6 +90,9 @@ public: [[nodiscard]] U32F32 SharedAtomicIAdd(const U32& address, const U32F32& data); [[nodiscard]] U32 SharedAtomicIMin(const U32& address, const U32& data, bool is_signed); [[nodiscard]] U32 SharedAtomicIMax(const U32& address, const U32& data, bool is_signed); + [[nodiscard]] U32 SharedAtomicAnd(const U32& address, const U32& data); + [[nodiscard]] U32 SharedAtomicOr(const U32& address, const U32& data); + [[nodiscard]] U32 SharedAtomicXor(const U32& address, const U32& data); [[nodiscard]] U32 ReadConst(const Value& base, const U32& offset); [[nodiscard]] U32 ReadConstBuffer(const Value& handle, const U32& index); diff --git a/src/shader_recompiler/ir/microinstruction.cpp b/src/shader_recompiler/ir/microinstruction.cpp index f0b4882b3..abd31a728 100644 --- a/src/shader_recompiler/ir/microinstruction.cpp +++ b/src/shader_recompiler/ir/microinstruction.cpp @@ -77,6 +77,9 @@ bool Inst::MayHaveSideEffects() const noexcept { case Opcode::SharedAtomicUMin32: case Opcode::SharedAtomicSMax32: case Opcode::SharedAtomicUMax32: + case Opcode::SharedAtomicAnd32: + case Opcode::SharedAtomicOr32: + case Opcode::SharedAtomicXor32: case Opcode::ImageWrite: case Opcode::ImageAtomicIAdd32: case Opcode::ImageAtomicSMin32: diff --git a/src/shader_recompiler/ir/opcodes.inc b/src/shader_recompiler/ir/opcodes.inc index 51e10fb38..0283ccd0f 100644 --- a/src/shader_recompiler/ir/opcodes.inc +++ b/src/shader_recompiler/ir/opcodes.inc @@ -43,6 +43,9 @@ OPCODE(SharedAtomicSMin32, U32, U32, OPCODE(SharedAtomicUMin32, U32, U32, U32, ) OPCODE(SharedAtomicSMax32, U32, U32, U32, ) OPCODE(SharedAtomicUMax32, U32, U32, U32, ) +OPCODE(SharedAtomicAnd32, U32, U32, U32, ) +OPCODE(SharedAtomicOr32, U32, U32, U32, ) +OPCODE(SharedAtomicXor32, U32, U32, U32, ) // Context getters/setters OPCODE(GetUserData, U32, ScalarReg, ) From 5f4d03172f0a56aee48566164e030980a39c3a50 Mon Sep 17 00:00:00 2001 From: Alexandre Bouvier Date: Sat, 30 Nov 2024 20:39:51 +0000 Subject: [PATCH 18/32] cmake: unbundle libpng (#1576) --- CMakeLists.txt | 5 +++-- cmake/Findzlib-ng.cmake | 15 --------------- externals/CMakeLists.txt | 31 ++++++++++++++++++------------- 3 files changed, 21 insertions(+), 30 deletions(-) delete mode 100644 cmake/Findzlib-ng.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index a8c3275f7..4ac1a6025 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -113,6 +113,7 @@ find_package(fmt 10.2.0 CONFIG) find_package(glslang 14.2.0 CONFIG) find_package(half 1.12.0 MODULE) find_package(magic_enum 0.9.6 CONFIG) +find_package(PNG 1.6 MODULE) find_package(RenderDoc 1.6.0 MODULE) find_package(SDL3 3.1.2 CONFIG) find_package(toml11 4.2.0 CONFIG) @@ -121,7 +122,7 @@ find_package(VulkanHeaders 1.3.289 CONFIG) find_package(VulkanMemoryAllocator 3.1.0 CONFIG) find_package(xbyak 7.07 CONFIG) find_package(xxHash 0.8.2 MODULE) -find_package(zlib-ng 2.1.7 MODULE) +find_package(ZLIB 1.3 MODULE) find_package(Zydis 5.0.0 CONFIG) find_package(pugixml 1.14 CONFIG) @@ -851,7 +852,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-ng::zlib png_static) +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::SPIRV glslang::glslang SDL3::SDL3 pugixml::pugixml) target_compile_definitions(shadps4 PRIVATE IMGUI_USER_CONFIG="imgui/imgui_config.h") diff --git a/cmake/Findzlib-ng.cmake b/cmake/Findzlib-ng.cmake deleted file mode 100644 index ec6f14b4a..000000000 --- a/cmake/Findzlib-ng.cmake +++ /dev/null @@ -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(ZLIB_NG QUIET IMPORTED_TARGET zlib-ng) - -include(FindPackageHandleStandardArgs) -find_package_handle_standard_args(zlib-ng - REQUIRED_VARS ZLIB_NG_LINK_LIBRARIES - VERSION_VAR ZLIB_NG_VERSION -) - -if (zlib-ng_FOUND AND NOT TARGET zlib-ng::zlib) - add_library(zlib-ng::zlib ALIAS PkgConfig::ZLIB_NG) -endif() diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index 8d080acc3..53802276e 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -52,15 +52,20 @@ file(GLOB LIBATRAC9_SOURCES LibAtrac9/C/src/*.c) add_library(LibAtrac9 STATIC ${LIBATRAC9_SOURCES}) target_include_directories(LibAtrac9 INTERFACE LibAtrac9/C/src) -# Zlib-Ng -if (NOT TARGET zlib-ng::zlib) +# zlib +if (NOT TARGET ZLIB::ZLIB) set(ZLIB_ENABLE_TESTS OFF) set(WITH_GTEST OFF) set(WITH_NEW_STRATEGIES ON) set(WITH_NATIVE_INSTRUCTIONS ON) set(ZLIB_COMPAT ON CACHE BOOL "" FORCE) - add_subdirectory(zlib-ng) - add_library(zlib-ng::zlib ALIAS zlib) + include(FetchContent) + FetchContent_Declare( + ZLIB + SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/zlib-ng" + OVERRIDE_FIND_PACKAGE + ) + FetchContent_MakeAvailable(ZLIB) add_library(ZLIB::ZLIB ALIAS zlib) endif() @@ -156,15 +161,15 @@ if (NOT TARGET half::half) endif() # libpng -set(PNG_SHARED OFF CACHE BOOL "" FORCE) -set(PNG_STATIC ON CACHE BOOL "" FORCE) -set(PNG_TESTS OFF CACHE BOOL "" FORCE) -set(PNG_TOOLS OFF CACHE BOOL "" FORCE) -set(SKIP_INSTALL_ALL OFF CACHE BOOL "" FORCE) -set(ZLIB_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/zlib-ng" CACHE STRING "" FORCE) -set(ZLIB_LIBRARY "${CMAKE_CURRENT_BINARY_DIR}/zlib-ng/zlibstatic-ngd" CACHE STRING "" FORCE) -file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/libpng/zlib.h" "#include \"../zlib-ng/zlib.h\"") -add_subdirectory(libpng) +if (NOT TARGET PNG::PNG) + set(PNG_SHARED OFF CACHE BOOL "" FORCE) + set(PNG_STATIC ON CACHE BOOL "" FORCE) + set(PNG_TESTS OFF CACHE BOOL "" FORCE) + set(PNG_TOOLS OFF CACHE BOOL "" FORCE) + set(SKIP_INSTALL_ALL OFF CACHE BOOL "" FORCE) + add_subdirectory(libpng) + add_library(PNG::PNG ALIAS png_static) +endif() if (APPLE) # date From 4ebb90c774cacacd89e24886e4bef595c5ca9e10 Mon Sep 17 00:00:00 2001 From: Alexandre Bouvier Date: Sun, 1 Dec 2024 09:16:01 +0000 Subject: [PATCH 19/32] cmake: hot fixes (#1638) --- CMakeLists.txt | 5 +++-- externals/CMakeLists.txt | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ac1a6025..82b85f2d2 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,8 @@ # SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project # SPDX-License-Identifier: GPL-2.0-or-later -cmake_minimum_required(VERSION 3.16.3) +# Version 3.24 needed for FetchContent OVERRIDE_FIND_PACKAGE +cmake_minimum_required(VERSION 3.24) set(CMAKE_CXX_STANDARD 23) set(CMAKE_CXX_STANDARD_REQUIRED True) @@ -110,7 +111,7 @@ configure_file("${CMAKE_CURRENT_SOURCE_DIR}/src/common/scm_rev.cpp.in" "${CMAKE_ find_package(Boost 1.84.0 CONFIG) find_package(FFmpeg 5.1.2 MODULE) find_package(fmt 10.2.0 CONFIG) -find_package(glslang 14.2.0 CONFIG) +find_package(glslang 15 CONFIG) find_package(half 1.12.0 MODULE) find_package(magic_enum 0.9.6 CONFIG) find_package(PNG 1.6 MODULE) diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index 53802276e..50eda0288 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -38,7 +38,8 @@ else() set(CRYPTOPP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/cryptopp/) add_subdirectory(cryptopp-cmake) file(COPY cryptopp DESTINATION cryptopp FILES_MATCHING PATTERN "*.h") - target_include_directories(cryptopp INTERFACE "${CMAKE_CURRENT_BINARY_DIR}/cryptopp") + # remove externals/cryptopp from include directories because it contains a conflicting zlib.h file + set_target_properties(cryptopp PROPERTIES INTERFACE_INCLUDE_DIRECTORIES "${CMAKE_CURRENT_BINARY_DIR}/cryptopp") endif() endif() @@ -67,6 +68,8 @@ if (NOT TARGET ZLIB::ZLIB) ) FetchContent_MakeAvailable(ZLIB) add_library(ZLIB::ZLIB ALIAS zlib) + # libpng expects this variable to exist after its find_package(ZLIB) + get_target_property(ZLIB_INCLUDE_DIRS zlib INTERFACE_INCLUDE_DIRECTORIES) endif() # SDL3 From 394a14626b4d691328e372e0cc9279597e7fbda8 Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Sun, 1 Dec 2024 03:44:15 -0800 Subject: [PATCH 20/32] libraries: Add stubs for libScePlayGoDialog (#1635) --- CMakeLists.txt | 2 + src/common/logging/filter.cpp | 1 + src/common/logging/types.h | 1 + src/core/libraries/libs.cpp | 2 + src/core/libraries/playgo/playgo_dialog.cpp | 78 +++++++++++++++++++++ src/core/libraries/playgo/playgo_dialog.h | 38 ++++++++++ 6 files changed, 122 insertions(+) create mode 100644 src/core/libraries/playgo/playgo_dialog.cpp create mode 100644 src/core/libraries/playgo/playgo_dialog.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 82b85f2d2..ed366a0b5 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -374,6 +374,8 @@ set(JPEG_LIB src/core/libraries/jpeg/jpeg_error.h set(PLAYGO_LIB src/core/libraries/playgo/playgo.cpp src/core/libraries/playgo/playgo.h + src/core/libraries/playgo/playgo_dialog.cpp + src/core/libraries/playgo/playgo_dialog.h src/core/libraries/playgo/playgo_types.h ) diff --git a/src/common/logging/filter.cpp b/src/common/logging/filter.cpp index 5f44658f0..632b2b329 100644 --- a/src/common/logging/filter.cpp +++ b/src/common/logging/filter.cpp @@ -107,6 +107,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) { SUB(Lib, Png) \ SUB(Lib, Jpeg) \ SUB(Lib, PlayGo) \ + SUB(Lib, PlayGoDialog) \ SUB(Lib, Random) \ SUB(Lib, Usbd) \ SUB(Lib, Ajm) \ diff --git a/src/common/logging/types.h b/src/common/logging/types.h index a373e8f1b..e7e91882a 100644 --- a/src/common/logging/types.h +++ b/src/common/logging/types.h @@ -74,6 +74,7 @@ enum class Class : u8 { Lib_Png, ///< The LibScePng implementation. Lib_Jpeg, ///< The LibSceJpeg implementation. Lib_PlayGo, ///< The LibScePlayGo implementation. + Lib_PlayGoDialog, ///< The LibScePlayGoDialog implementation. Lib_Random, ///< The libSceRandom implementation. Lib_Usbd, ///< The LibSceUsbd implementation. Lib_Ajm, ///< The LibSceAjm implementation. diff --git a/src/core/libraries/libs.cpp b/src/core/libraries/libs.cpp index 53b67b395..66cdd5b87 100644 --- a/src/core/libraries/libs.cpp +++ b/src/core/libraries/libs.cpp @@ -27,6 +27,7 @@ #include "core/libraries/np_trophy/np_trophy.h" #include "core/libraries/pad/pad.h" #include "core/libraries/playgo/playgo.h" +#include "core/libraries/playgo/playgo_dialog.h" #include "core/libraries/random/random.h" #include "core/libraries/razor_cpu/razor_cpu.h" #include "core/libraries/remote_play/remoteplay.h" @@ -74,6 +75,7 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) { Libraries::AppContent::RegisterlibSceAppContent(sym); Libraries::PngDec::RegisterlibScePngDec(sym); Libraries::PlayGo::RegisterlibScePlayGo(sym); + Libraries::PlayGo::Dialog::RegisterlibScePlayGoDialog(sym); Libraries::Random::RegisterlibSceRandom(sym); Libraries::Usbd::RegisterlibSceUsbd(sym); Libraries::Pad::RegisterlibScePad(sym); diff --git a/src/core/libraries/playgo/playgo_dialog.cpp b/src/core/libraries/playgo/playgo_dialog.cpp new file mode 100644 index 000000000..16f7aa05d --- /dev/null +++ b/src/core/libraries/playgo/playgo_dialog.cpp @@ -0,0 +1,78 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/assert.h" +#include "common/logging/log.h" +#include "core/libraries/libs.h" +#include "core/libraries/playgo/playgo_dialog.h" +#include "core/libraries/system/commondialog.h" + +namespace Libraries::PlayGo::Dialog { + +using CommonDialog::Error; +using CommonDialog::Result; +using CommonDialog::Status; + +Error PS4_SYSV_ABI scePlayGoDialogClose() { + LOG_ERROR(Lib_PlayGoDialog, "(DUMMY) called"); + return Error::OK; +} + +Error PS4_SYSV_ABI scePlayGoDialogGetResult(OrbisPlayGoDialogResult* result) { + LOG_ERROR(Lib_PlayGoDialog, "(DUMMY) called"); + if (result == nullptr) { + return Error::ARG_NULL; + } + // Result value 3 allows games to proceed. + result->result = static_cast(3); + return Error::OK; +} + +Status PS4_SYSV_ABI scePlayGoDialogGetStatus() { + LOG_ERROR(Lib_PlayGoDialog, "(DUMMY) called"); + return Status::FINISHED; +} + +Error PS4_SYSV_ABI scePlayGoDialogInitialize() { + LOG_ERROR(Lib_PlayGoDialog, "(DUMMY) called"); + return Error::OK; +} + +Error PS4_SYSV_ABI scePlayGoDialogOpen(const OrbisPlayGoDialogParam* param) { + LOG_ERROR(Lib_PlayGoDialog, "(DUMMY) called"); + if (param == nullptr) { + return Error::ARG_NULL; + } + ASSERT(param->size == sizeof(OrbisPlayGoDialogParam)); + ASSERT(param->baseParam.size == sizeof(CommonDialog::BaseParam)); + return Error::OK; +} + +Error PS4_SYSV_ABI scePlayGoDialogTerminate() { + LOG_ERROR(Lib_PlayGoDialog, "(DUMMY) called"); + return Error::OK; +} + +Status PS4_SYSV_ABI scePlayGoDialogUpdateStatus() { + LOG_ERROR(Lib_PlayGoDialog, "(DUMMY) called"); + return Status::FINISHED; +} + +void RegisterlibScePlayGoDialog(Core::Loader::SymbolsResolver* sym) { + LIB_FUNCTION("fbigNQiZpm0", "libScePlayGoDialog", 1, "libScePlayGoDialog", 1, 1, + scePlayGoDialogClose); + LIB_FUNCTION("wx9TDplJKB4", "libScePlayGoDialog", 1, "libScePlayGoDialog", 1, 1, + scePlayGoDialogGetResult); + LIB_FUNCTION("NOAMxY2EGS0", "libScePlayGoDialog", 1, "libScePlayGoDialog", 1, 1, + scePlayGoDialogGetStatus); + LIB_FUNCTION("fECamTJKpsM", "libScePlayGoDialog", 1, "libScePlayGoDialog", 1, 1, + scePlayGoDialogInitialize); + LIB_FUNCTION("kHd72ukqbxw", "libScePlayGoDialog", 1, "libScePlayGoDialog", 1, 1, + scePlayGoDialogOpen); + LIB_FUNCTION("okgIGdr5Iz0", "libScePlayGoDialog", 1, "libScePlayGoDialog", 1, 1, + scePlayGoDialogTerminate); + LIB_FUNCTION("Yb60K7BST48", "libScePlayGoDialog", 1, "libScePlayGoDialog", 1, 1, + scePlayGoDialogUpdateStatus); +}; + +} // namespace Libraries::PlayGo::Dialog diff --git a/src/core/libraries/playgo/playgo_dialog.h b/src/core/libraries/playgo/playgo_dialog.h new file mode 100644 index 000000000..fa9c64680 --- /dev/null +++ b/src/core/libraries/playgo/playgo_dialog.h @@ -0,0 +1,38 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "common/types.h" +#include "core/libraries/system/commondialog.h" + +namespace Core::Loader { +class SymbolsResolver; +} + +namespace Libraries::PlayGo::Dialog { + +struct OrbisPlayGoDialogParam { + CommonDialog::BaseParam baseParam; + s32 size; + u8 unk[0x30]; +}; +static_assert(sizeof(OrbisPlayGoDialogParam) == 0x68); + +struct OrbisPlayGoDialogResult { + u8 unk1[0x4]; + CommonDialog::Result result; + u8 unk2[0x20]; +}; +static_assert(sizeof(OrbisPlayGoDialogResult) == 0x28); + +CommonDialog::Error PS4_SYSV_ABI scePlayGoDialogClose(); +CommonDialog::Error PS4_SYSV_ABI scePlayGoDialogGetResult(OrbisPlayGoDialogResult* result); +CommonDialog::Status PS4_SYSV_ABI scePlayGoDialogGetStatus(); +CommonDialog::Error PS4_SYSV_ABI scePlayGoDialogInitialize(); +CommonDialog::Error PS4_SYSV_ABI scePlayGoDialogOpen(const OrbisPlayGoDialogParam* param); +CommonDialog::Error PS4_SYSV_ABI scePlayGoDialogTerminate(); +CommonDialog::Status PS4_SYSV_ABI scePlayGoDialogUpdateStatus(); + +void RegisterlibScePlayGoDialog(Core::Loader::SymbolsResolver* sym); +} // namespace Libraries::PlayGo::Dialog From b00a321b5e671007af936572223db3da374cbbf5 Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Sun, 1 Dec 2024 04:12:04 -0800 Subject: [PATCH 21/32] playgo: Fix loading PlayGo file. (#1639) --- src/core/file_format/playgo_chunk.h | 1 - src/core/libraries/playgo/playgo.cpp | 55 ++++++++++++++++------------ src/emulator.cpp | 7 ---- 3 files changed, 31 insertions(+), 32 deletions(-) diff --git a/src/core/file_format/playgo_chunk.h b/src/core/file_format/playgo_chunk.h index 2a234f5fe..12d8f022e 100644 --- a/src/core/file_format/playgo_chunk.h +++ b/src/core/file_format/playgo_chunk.h @@ -97,7 +97,6 @@ struct PlaygoChunk { class PlaygoFile { public: - bool initialized = false; OrbisPlayGoHandle handle = 0; OrbisPlayGoChunkId id = 0; OrbisPlayGoLocus locus = OrbisPlayGoLocus::NotDownloaded; diff --git a/src/core/libraries/playgo/playgo.cpp b/src/core/libraries/playgo/playgo.cpp index 6fcf875da..13d6f991f 100644 --- a/src/core/libraries/playgo/playgo.cpp +++ b/src/core/libraries/playgo/playgo.cpp @@ -2,7 +2,9 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "common/logging/log.h" +#include "common/singleton.h" #include "core/file_format/playgo_chunk.h" +#include "core/file_sys/fs.h" #include "core/libraries/error_codes.h" #include "core/libraries/libs.h" #include "core/libraries/system/systemservice.h" @@ -29,10 +31,9 @@ s32 PS4_SYSV_ABI scePlayGoClose(OrbisPlayGoHandle handle) { if (handle != PlaygoHandle) { return ORBIS_PLAYGO_ERROR_BAD_HANDLE; } - if (!playgo->initialized) { + if (!playgo) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; } - playgo.reset(); return ORBIS_OK; } @@ -98,7 +99,7 @@ s32 PS4_SYSV_ABI scePlayGoGetInstallSpeed(OrbisPlayGoHandle handle, if (outSpeed == nullptr) { return ORBIS_PLAYGO_ERROR_BAD_POINTER; } - if (!playgo->initialized) { + if (!playgo) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; } @@ -126,7 +127,7 @@ s32 PS4_SYSV_ABI scePlayGoGetLanguageMask(OrbisPlayGoHandle handle, if (outLanguageMask == nullptr) { return ORBIS_PLAYGO_ERROR_BAD_POINTER; } - if (!playgo->initialized) { + if (!playgo) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; } @@ -148,7 +149,7 @@ s32 PS4_SYSV_ABI scePlayGoGetLocus(OrbisPlayGoHandle handle, const OrbisPlayGoCh if (numberOfEntries == 0) { return ORBIS_PLAYGO_ERROR_BAD_SIZE; } - if (!playgo->initialized) { + if (!playgo) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; } if (playgo->GetPlaygoHeader().file_size == 0) { @@ -180,7 +181,7 @@ s32 PS4_SYSV_ABI scePlayGoGetProgress(OrbisPlayGoHandle handle, const OrbisPlayG if (numberOfEntries == 0) { return ORBIS_PLAYGO_ERROR_BAD_SIZE; } - if (!playgo->initialized) { + if (!playgo) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; } if (playgo->GetPlaygoHeader().file_size == 0) { @@ -219,7 +220,7 @@ s32 PS4_SYSV_ABI scePlayGoGetToDoList(OrbisPlayGoHandle handle, OrbisPlayGoToDo* if (numberOfEntries == 0) { return ORBIS_PLAYGO_ERROR_BAD_SIZE; } - if (!playgo->initialized) { + if (!playgo) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; } *outEntries = 0; // nothing to do @@ -242,17 +243,24 @@ s32 PS4_SYSV_ABI scePlayGoInitialize(OrbisPlayGoInitParams* param) { if (param->bufSize < 0x200000) { return ORBIS_PLAYGO_ERROR_BAD_SIZE; } - - playgo = std::make_unique(); - if (!playgo->initialized) { - using namespace SystemService; - s32 system_lang = 0; - sceSystemServiceParamGetInt(OrbisSystemServiceParamId::Lang, &system_lang); - playgo->langMask = scePlayGoConvertLanguage(system_lang); - playgo->initialized = true; - } else { + if (playgo) { return ORBIS_PLAYGO_ERROR_ALREADY_INITIALIZED; } + + using namespace SystemService; + + playgo = std::make_unique(); + + auto* mnt = Common::Singleton::Instance(); + const auto file_path = mnt->GetHostPath("/app0/sce_sys/playgo-chunk.dat"); + if (!playgo->Open(file_path)) { + LOG_WARNING(Lib_PlayGo, "Could not open PlayGo file"); + } + + s32 system_lang = 0; + sceSystemServiceParamGetInt(OrbisSystemServiceParamId::Lang, &system_lang); + playgo->langMask = scePlayGoConvertLanguage(system_lang); + return ORBIS_OK; } @@ -265,7 +273,7 @@ s32 PS4_SYSV_ABI scePlayGoOpen(OrbisPlayGoHandle* outHandle, const void* param) if (param) { return ORBIS_PLAYGO_ERROR_INVALID_ARGUMENT; } - if (!playgo->initialized) { + if (!playgo) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; } if (playgo->GetPlaygoHeader().file_size == 0) { @@ -289,7 +297,7 @@ s32 PS4_SYSV_ABI scePlayGoPrefetch(OrbisPlayGoHandle handle, const OrbisPlayGoCh if (numberOfEntries == 0) { return ORBIS_PLAYGO_ERROR_BAD_SIZE; } - if (!playgo->initialized) { + if (!playgo) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; } @@ -310,7 +318,7 @@ s32 PS4_SYSV_ABI scePlayGoSetInstallSpeed(OrbisPlayGoHandle handle, OrbisPlayGoI if (handle != PlaygoHandle) { return ORBIS_PLAYGO_ERROR_BAD_HANDLE; } - if (!playgo->initialized) { + if (!playgo) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; } @@ -339,7 +347,7 @@ s32 PS4_SYSV_ABI scePlayGoSetLanguageMask(OrbisPlayGoHandle handle, if (handle != 1) { return ORBIS_PLAYGO_ERROR_BAD_HANDLE; } - if (!playgo->initialized) { + if (!playgo) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; } @@ -360,7 +368,7 @@ s32 PS4_SYSV_ABI scePlayGoSetToDoList(OrbisPlayGoHandle handle, const OrbisPlayG if (numberOfEntries == 0) { return ORBIS_PLAYGO_ERROR_BAD_SIZE; } - if (!playgo->initialized) { + if (!playgo) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; } return ORBIS_OK; @@ -369,11 +377,10 @@ s32 PS4_SYSV_ABI scePlayGoSetToDoList(OrbisPlayGoHandle handle, const OrbisPlayG s32 PS4_SYSV_ABI scePlayGoTerminate() { LOG_INFO(Lib_PlayGo, "called"); - if (playgo->initialized) { - playgo->initialized = false; - } else { + if (!playgo) { return ORBIS_PLAYGO_ERROR_NOT_INITIALIZED; } + playgo.reset(); return ORBIS_OK; } diff --git a/src/emulator.cpp b/src/emulator.cpp index 4ab535a2c..1d2542d2b 100644 --- a/src/emulator.cpp +++ b/src/emulator.cpp @@ -22,7 +22,6 @@ #include "common/scm_rev.h" #include "common/singleton.h" #include "common/version.h" -#include "core/file_format/playgo_chunk.h" #include "core/file_format/psf.h" #include "core/file_format/splash.h" #include "core/file_format/trp.h" @@ -157,12 +156,6 @@ void Emulator::Run(const std::filesystem::path& file) { fw_version = param_sfo->GetInteger("SYSTEM_VER").value_or(0x4700000); app_version = param_sfo->GetString("APP_VER").value_or("Unknown version"); LOG_INFO(Loader, "Fw: {:#x} App Version: {}", fw_version, app_version); - } else if (entry.path().filename() == "playgo-chunk.dat") { - auto* playgo = Common::Singleton::Instance(); - auto filepath = sce_sys_folder / "playgo-chunk.dat"; - if (!playgo->Open(filepath)) { - LOG_ERROR(Loader, "PlayGo: unable to open file"); - } } else if (entry.path().filename() == "pic1.png") { auto* splash = Common::Singleton::Instance(); if (splash->IsLoaded()) { From 4a5850628eed4be35ad3f91aeea4ee27ccfa6c4f Mon Sep 17 00:00:00 2001 From: psucien Date: Sun, 1 Dec 2024 15:46:08 +0100 Subject: [PATCH 22/32] hot-fix: debug build fixed --- src/core/libraries/libpng/pngdec.cpp | 8 ++++---- src/core/libraries/videoout/video_out.cpp | 5 +++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/core/libraries/libpng/pngdec.cpp b/src/core/libraries/libpng/pngdec.cpp index d6f291a62..d9a324fc5 100644 --- a/src/core/libraries/libpng/pngdec.cpp +++ b/src/core/libraries/libpng/pngdec.cpp @@ -94,8 +94,8 @@ s32 PS4_SYSV_ABI scePngDecDecode(OrbisPngDecHandle handle, const OrbisPngDecDeco LOG_TRACE(Lib_Png, "pngMemSize = {} , imageMemSize = {} , pixelFormat = {} , alphaValue = {} , " "imagePitch = {}", - param->pngMemSize, param->imageMemSize, param->pixelFormat, param->alphaValue, - param->imagePitch); + param->png_mem_size, param->image_mem_size, int(param->pixel_format), + param->alpha_value, param->image_pitch); auto pngh = (PngHandler*)handle; @@ -240,8 +240,8 @@ s32 PS4_SYSV_ABI scePngDecParseHeader(const OrbisPngDecParseParam* param, LOG_TRACE( Lib_Png, "imageWidth = {} , imageHeight = {} , colorSpace = {} , bitDepth = {} , imageFlag = {}", - imageInfo->imageWidth, imageInfo->imageHeight, imageInfo->colorSpace, imageInfo->bitDepth, - imageInfo->imageFlag); + imageInfo->image_width, imageInfo->image_height, int(imageInfo->color_space), + imageInfo->bit_depth, int(imageInfo->image_flag)); return ORBIS_OK; } diff --git a/src/core/libraries/videoout/video_out.cpp b/src/core/libraries/videoout/video_out.cpp index ee4a89345..f36de6ade 100644 --- a/src/core/libraries/videoout/video_out.cpp +++ b/src/core/libraries/videoout/video_out.cpp @@ -195,8 +195,9 @@ s32 PS4_SYSV_ABI sceVideoOutGetFlipStatus(s32 handle, FlipStatus* status) { LOG_TRACE(Lib_VideoOut, "count = {}, processTime = {}, tsc = {}, submitTsc = {}, flipArg = {}, gcQueueNum = " "{}, flipPendingNum = {}, currentBuffer = {}", - status->count, status->processTime, status->tsc, status->submitTsc, status->flipArg, - status->gcQueueNum, status->flipPendingNum, status->currentBuffer); + status->count, status->process_time, status->tsc, status->submit_tsc, + status->flip_arg, status->gc_queue_num, status->flip_pending_num, + status->current_buffer); return ORBIS_OK; } From 0835dc71b3caf1f24352d19bd597bc56595675af Mon Sep 17 00:00:00 2001 From: Vinicius Rangel Date: Sun, 1 Dec 2024 15:34:29 -0300 Subject: [PATCH 23/32] More devtools stuff (#1637) * devtools: memory map viewer * devtools: batch highlight only for non-group viewer * devtools: fix not showing entire user data * devtools: shader debug viewer * devtools: add more reg naming --- CMakeLists.txt | 4 + src/common/config.cpp | 12 ++ src/common/config.h | 2 + src/core/debug_state.cpp | 11 +- src/core/debug_state.h | 48 ++++++- src/core/devtools/gcn/gcn_context_regs.cpp | 10 ++ src/core/devtools/layer.cpp | 45 +++++- src/core/devtools/options.cpp | 11 +- src/core/devtools/options.h | 3 +- src/core/devtools/widget/cmd_list.cpp | 4 +- src/core/devtools/widget/common.h | 57 ++++++++ src/core/devtools/widget/memory_map.cpp | 134 ++++++++++++++++++ src/core/devtools/widget/memory_map.h | 33 +++++ src/core/devtools/widget/reg_view.cpp | 49 +------ src/core/devtools/widget/shader_list.cpp | 95 +++++++++++++ src/core/devtools/widget/shader_list.h | 28 ++++ src/core/memory.h | 6 + .../renderer_vulkan/vk_pipeline_cache.cpp | 4 + 18 files changed, 491 insertions(+), 65 deletions(-) create mode 100644 src/core/devtools/widget/memory_map.cpp create mode 100644 src/core/devtools/widget/memory_map.h create mode 100644 src/core/devtools/widget/shader_list.cpp create mode 100644 src/core/devtools/widget/shader_list.h diff --git a/CMakeLists.txt b/CMakeLists.txt index ed366a0b5..2f503832c 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -435,10 +435,14 @@ set(DEV_TOOLS src/core/devtools/layer.cpp src/core/devtools/widget/frame_graph.cpp src/core/devtools/widget/frame_graph.h src/core/devtools/widget/imgui_memory_editor.h + src/core/devtools/widget/memory_map.cpp + src/core/devtools/widget/memory_map.h src/core/devtools/widget/reg_popup.cpp src/core/devtools/widget/reg_popup.h src/core/devtools/widget/reg_view.cpp src/core/devtools/widget/reg_view.h + src/core/devtools/widget/shader_list.cpp + src/core/devtools/widget/shader_list.h src/core/devtools/widget/text_editor.cpp src/core/devtools/widget/text_editor.h ) diff --git a/src/common/config.cpp b/src/common/config.cpp index 5c2c8cda6..eae8897c8 100644 --- a/src/common/config.cpp +++ b/src/common/config.cpp @@ -47,6 +47,7 @@ static std::string backButtonBehavior = "left"; static bool useSpecialPad = false; static int specialPadClass = 1; static bool isDebugDump = false; +static bool isShaderDebug = false; static bool isShowSplash = false; static bool isAutoUpdate = false; static bool isNullGpu = false; @@ -159,6 +160,10 @@ bool debugDump() { return isDebugDump; } +bool collectShadersForDebug() { + return isShaderDebug; +} + bool showSplash() { return isShowSplash; } @@ -235,6 +240,10 @@ void setDebugDump(bool enable) { isDebugDump = enable; } +void setCollectShaderForDebug(bool enable) { + isShaderDebug = enable; +} + void setShowSplash(bool enable) { isShowSplash = enable; } @@ -571,6 +580,7 @@ void load(const std::filesystem::path& path) { const toml::value& debug = data.at("Debug"); isDebugDump = toml::find_or(debug, "DebugDump", false); + isShaderDebug = toml::find_or(debug, "CollectShader", false); } if (data.contains("GUI")) { @@ -662,6 +672,7 @@ void save(const std::filesystem::path& path) { data["Vulkan"]["rdocMarkersEnable"] = vkMarkers; data["Vulkan"]["crashDiagnostic"] = vkCrashDiagnostic; data["Debug"]["DebugDump"] = isDebugDump; + data["Debug"]["CollectShader"] = isShaderDebug; data["GUI"]["theme"] = mw_themes; data["GUI"]["iconSize"] = m_icon_size; data["GUI"]["sliderPos"] = m_slider_pos; @@ -717,6 +728,7 @@ void setDefaultValues() { useSpecialPad = false; specialPadClass = 1; isDebugDump = false; + isShaderDebug = false; isShowSplash = false; isAutoUpdate = false; isNullGpu = false; diff --git a/src/common/config.h b/src/common/config.h index 400115745..d98c94480 100644 --- a/src/common/config.h +++ b/src/common/config.h @@ -37,6 +37,7 @@ u32 getScreenHeight(); s32 getGpuId(); bool debugDump(); +bool collectShadersForDebug(); bool showSplash(); bool autoUpdate(); bool nullGpu(); @@ -47,6 +48,7 @@ bool isRdocEnabled(); u32 vblankDiv(); void setDebugDump(bool enable); +void setCollectShaderForDebug(bool enable); void setShowSplash(bool enable); void setAutoUpdate(bool enable); void setNullGpu(bool enable); diff --git a/src/core/debug_state.cpp b/src/core/debug_state.cpp index 1dc4297c3..562cb62e8 100644 --- a/src/core/debug_state.cpp +++ b/src/core/debug_state.cpp @@ -157,7 +157,7 @@ void DebugStateImpl::PushRegsDump(uintptr_t base_addr, uintptr_t header_addr, if (is_compute) { dump.is_compute = true; const auto& cs = dump.regs.cs_program; - dump.cs_data = ComputerShaderDump{ + dump.cs_data = PipelineComputerProgramDump{ .cs_program = cs, .code = std::vector{cs.Code().begin(), cs.Code().end()}, }; @@ -167,7 +167,7 @@ void DebugStateImpl::PushRegsDump(uintptr_t base_addr, uintptr_t header_addr, auto stage = regs.ProgramForStage(i); if (stage->address_lo != 0) { auto code = stage->Code(); - dump.stages[i] = ShaderDump{ + dump.stages[i] = PipelineShaderProgramDump{ .user_data = *stage, .code = std::vector{code.begin(), code.end()}, }; @@ -176,3 +176,10 @@ void DebugStateImpl::PushRegsDump(uintptr_t base_addr, uintptr_t header_addr, } } } + +void DebugStateImpl::CollectShader(const std::string& name, std::span spv, + std::span raw_code) { + shader_dump_list.emplace_back(name, std::vector{spv.begin(), spv.end()}, + std::vector{raw_code.begin(), raw_code.end()}); + std::ranges::sort(shader_dump_list, {}, &ShaderDump::name); +} diff --git a/src/core/debug_state.h b/src/core/debug_state.h index cd1c6aa93..759755b52 100644 --- a/src/core/debug_state.h +++ b/src/core/debug_state.h @@ -30,7 +30,8 @@ namespace Core::Devtools { class Layer; namespace Widget { class FrameGraph; -} +class ShaderList; +} // namespace Widget } // namespace Core::Devtools namespace DebugStateType { @@ -49,12 +50,12 @@ struct QueueDump { uintptr_t base_addr; }; -struct ShaderDump { +struct PipelineShaderProgramDump { Vulkan::Liverpool::ShaderProgram user_data{}; std::vector code{}; }; -struct ComputerShaderDump { +struct PipelineComputerProgramDump { Vulkan::Liverpool::ComputeProgram cs_program{}; std::vector code{}; }; @@ -63,8 +64,8 @@ struct RegDump { bool is_compute{false}; static constexpr size_t MaxShaderStages = 5; Vulkan::Liverpool::Regs regs{}; - std::array stages{}; - ComputerShaderDump cs_data{}; + std::array stages{}; + PipelineComputerProgramDump cs_data{}; }; struct FrameDump { @@ -73,9 +74,41 @@ struct FrameDump { std::unordered_map regs; // address -> reg dump }; +struct ShaderDump { + std::string name; + std::vector spv; + std::vector raw_code; + + std::string cache_spv_disasm{}; + std::string cache_raw_disasm{}; + + ShaderDump(std::string name, std::vector spv, std::vector raw_code) + : name(std::move(name)), spv(std::move(spv)), raw_code(std::move(raw_code)) {} + + ShaderDump(const ShaderDump& other) = delete; + ShaderDump(ShaderDump&& other) noexcept + : name{std::move(other.name)}, spv{std::move(other.spv)}, + raw_code{std::move(other.raw_code)}, cache_spv_disasm{std::move(other.cache_spv_disasm)}, + cache_raw_disasm{std::move(other.cache_raw_disasm)} {} + ShaderDump& operator=(const ShaderDump& other) = delete; + ShaderDump& operator=(ShaderDump&& other) noexcept { + if (this == &other) + return *this; + name = std::move(other.name); + spv = std::move(other.spv); + raw_code = std::move(other.raw_code); + cache_spv_disasm = std::move(other.cache_spv_disasm); + cache_raw_disasm = std::move(other.cache_raw_disasm); + return *this; + } +}; + class DebugStateImpl { friend class Core::Devtools::Layer; friend class Core::Devtools::Widget::FrameGraph; + friend class Core::Devtools::Widget::ShaderList; + + std::queue debug_message_popup; std::mutex guest_threads_mutex{}; std::vector guest_threads{}; @@ -94,7 +127,7 @@ class DebugStateImpl { std::shared_mutex frame_dump_list_mutex; std::vector frame_dump_list{}; - std::queue debug_message_popup; + std::vector shader_dump_list{}; public: void ShowDebugMessage(std::string message) { @@ -152,6 +185,9 @@ public: void PushRegsDump(uintptr_t base_addr, uintptr_t header_addr, const AmdGpu::Liverpool::Regs& regs, bool is_compute = false); + + void CollectShader(const std::string& name, std::span spv, + std::span raw_code); }; } // namespace DebugStateType diff --git a/src/core/devtools/gcn/gcn_context_regs.cpp b/src/core/devtools/gcn/gcn_context_regs.cpp index 843ba9e65..5a591111e 100644 --- a/src/core/devtools/gcn/gcn_context_regs.cpp +++ b/src/core/devtools/gcn/gcn_context_regs.cpp @@ -289,6 +289,16 @@ const char* GetContextRegName(u32 reg_offset) { return "mmSPI_PS_INPUT_CNTL_2"; case mmSPI_PS_INPUT_CNTL_3: return "mmSPI_PS_INPUT_CNTL_3"; + case mmPA_SU_POLY_OFFSET_FRONT_SCALE: + return "mmPA_SU_POLY_OFFSET_FRONT_SCALE"; + case mmPA_SU_POLY_OFFSET_FRONT_OFFSET: + return "mmPA_SU_POLY_OFFSET_FRONT_OFFSET"; + case mmPA_SU_POLY_OFFSET_BACK_SCALE: + return "mmPA_SU_POLY_OFFSET_BACK_SCALE"; + case mmPA_SU_POLY_OFFSET_BACK_OFFSET: + return "mmPA_SU_POLY_OFFSET_BACK_OFFSET"; + case mmPA_SU_POLY_OFFSET_CLAMP: + return "mmPA_SU_POLY_OFFSET_CLAMP"; default: break; } diff --git a/src/core/devtools/layer.cpp b/src/core/devtools/layer.cpp index 2c4ce20b6..2c2099f4d 100644 --- a/src/core/devtools/layer.cpp +++ b/src/core/devtools/layer.cpp @@ -1,6 +1,8 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "layer.h" + #include #include "common/config.h" @@ -9,11 +11,12 @@ #include "core/debug_state.h" #include "imgui/imgui_std.h" #include "imgui_internal.h" -#include "layer.h" #include "options.h" #include "video_core/renderer_vulkan/vk_presenter.h" #include "widget/frame_dump.h" #include "widget/frame_graph.h" +#include "widget/memory_map.h" +#include "widget/shader_list.h" extern std::unique_ptr presenter; @@ -35,6 +38,9 @@ static float debug_popup_timing = 3.0f; static bool just_opened_options = false; +static Widget::MemoryMapViewer memory_map; +static Widget::ShaderList shader_list; + // clang-format off static std::string help_text = #include "help.txt" @@ -63,6 +69,7 @@ void L::DrawMenuBar() { } if (BeginMenu("GPU Tools")) { MenuItem("Show frame info", nullptr, &frame_graph.is_open); + MenuItem("Show loaded shaders", nullptr, &shader_list.open); if (BeginMenu("Dump frames")) { SliderInt("Count", &dump_frame_count, 1, 5); if (MenuItem("Dump", "Ctrl+Alt+F9", nullptr, !DebugState.DumpingCurrentFrame())) { @@ -81,6 +88,12 @@ void L::DrawMenuBar() { } ImGui::EndMenu(); } + if (BeginMenu("Debug")) { + if (MenuItem("Memory map")) { + memory_map.open = true; + } + ImGui::EndMenu(); + } EndMainMenuBar(); } @@ -175,19 +188,29 @@ void L::DrawAdvanced() { bool close_popup_options = true; if (BeginPopupModal("GPU Tools Options", &close_popup_options, ImGuiWindowFlags_AlwaysAutoResize | ImGuiWindowFlags_NoSavedSettings)) { - static char disassembly_cli[512]; + static char disassembler_cli_isa[512]; + static char disassembler_cli_spv[512]; static bool frame_dump_render_on_collapse; if (just_opened_options) { just_opened_options = false; - auto s = Options.disassembly_cli.copy(disassembly_cli, sizeof(disassembly_cli) - 1); - disassembly_cli[s] = '\0'; + auto s = Options.disassembler_cli_isa.copy(disassembler_cli_isa, + sizeof(disassembler_cli_isa) - 1); + disassembler_cli_isa[s] = '\0'; + s = Options.disassembler_cli_spv.copy(disassembler_cli_spv, + sizeof(disassembler_cli_spv) - 1); + disassembler_cli_spv[s] = '\0'; frame_dump_render_on_collapse = Options.frame_dump_render_on_collapse; } - InputText("Shader disassembler: ", disassembly_cli, sizeof(disassembly_cli)); + InputText("Shader isa disassembler: ", disassembler_cli_isa, sizeof(disassembler_cli_isa)); if (IsItemHovered()) { - SetTooltip(R"(Command to disassemble shaders. Example "dis.exe" --raw "{src}")"); + SetTooltip(R"(Command to disassemble shaders. Example: dis.exe --raw "{src}")"); + } + InputText("Shader SPIRV disassembler: ", disassembler_cli_spv, + sizeof(disassembler_cli_spv)); + if (IsItemHovered()) { + SetTooltip(R"(Command to disassemble shaders. Example: spirv-cross -V "{src}")"); } Checkbox("Show frame dump popups even when collapsed", &frame_dump_render_on_collapse); if (IsItemHovered()) { @@ -196,7 +219,8 @@ void L::DrawAdvanced() { } if (Button("Save")) { - Options.disassembly_cli = disassembly_cli; + Options.disassembler_cli_isa = disassembler_cli_isa; + Options.disassembler_cli_spv = disassembler_cli_spv; Options.frame_dump_render_on_collapse = frame_dump_render_on_collapse; SaveIniSettingsToDisk(io.IniFilename); CloseCurrentPopup(); @@ -219,6 +243,13 @@ void L::DrawAdvanced() { EndPopup(); } + + if (memory_map.open) { + memory_map.Draw(); + } + if (shader_list.open) { + shader_list.Draw(); + } } void L::DrawSimple() { diff --git a/src/core/devtools/options.cpp b/src/core/devtools/options.cpp index 1b49da76b..2def42071 100644 --- a/src/core/devtools/options.cpp +++ b/src/core/devtools/options.cpp @@ -12,8 +12,12 @@ TOptions Options; void LoadOptionsConfig(const char* line) { char str[512]; int i; - if (sscanf(line, "disassembly_cli=%511[^\n]", str) == 1) { - Options.disassembly_cli = str; + if (sscanf(line, "disassembler_cli_isa=%511[^\n]", str) == 1) { + Options.disassembler_cli_isa = str; + return; + } + if (sscanf(line, "disassembler_cli_spv=%511[^\n]", str) == 1) { + Options.disassembler_cli_spv = str; return; } if (sscanf(line, "frame_dump_render_on_collapse=%d", &i) == 1) { @@ -23,7 +27,8 @@ void LoadOptionsConfig(const char* line) { } void SerializeOptionsConfig(ImGuiTextBuffer* buf) { - buf->appendf("disassembly_cli=%s\n", Options.disassembly_cli.c_str()); + buf->appendf("disassembler_cli_isa=%s\n", Options.disassembler_cli_isa.c_str()); + buf->appendf("disassembler_cli_spv=%s\n", Options.disassembler_cli_spv.c_str()); buf->appendf("frame_dump_render_on_collapse=%d\n", Options.frame_dump_render_on_collapse); } diff --git a/src/core/devtools/options.h b/src/core/devtools/options.h index c3a8aaf31..70e1d137b 100644 --- a/src/core/devtools/options.h +++ b/src/core/devtools/options.h @@ -10,7 +10,8 @@ struct ImGuiTextBuffer; namespace Core::Devtools { struct TOptions { - std::string disassembly_cli{}; + std::string disassembler_cli_isa{"clrxdisasm --raw \"{src}\""}; + std::string disassembler_cli_spv{"spirv-cross -V \"{src}\""}; bool frame_dump_render_on_collapse{false}; }; diff --git a/src/core/devtools/widget/cmd_list.cpp b/src/core/devtools/widget/cmd_list.cpp index 219d25d6a..7c550cf2e 100644 --- a/src/core/devtools/widget/cmd_list.cpp +++ b/src/core/devtools/widget/cmd_list.cpp @@ -1306,7 +1306,7 @@ void CmdListViewer::Draw(bool only_batches_view) { if (batch.id == batch_bp) { // highlight batch at breakpoint PushStyleColor(ImGuiCol_Header, ImVec4{1.0f, 0.5f, 0.5f, 0.5f}); } - if (batch.id == highlight_batch) { + if (batch.id == highlight_batch && !group_batches) { PushStyleColor(ImGuiCol_Text, ImVec4{1.0f, 0.7f, 0.7f, 1.0f}); } @@ -1459,7 +1459,7 @@ void CmdListViewer::Draw(bool only_batches_view) { } } - if (batch.id == highlight_batch) { + if (batch.id == highlight_batch && !group_batches) { PopStyleColor(); } diff --git a/src/core/devtools/widget/common.h b/src/core/devtools/widget/common.h index e650f5fc7..4429f5581 100644 --- a/src/core/devtools/widget/common.h +++ b/src/core/devtools/widget/common.h @@ -3,6 +3,7 @@ #pragma once +#include #include #include #include @@ -10,9 +11,16 @@ #include #include "common/bit_field.h" +#include "common/io_file.h" #include "common/types.h" +#include "core/debug_state.h" #include "video_core/amdgpu/pm4_opcodes.h" +#if defined(_WIN32) +#define popen _popen +#define pclose _pclose +#endif + namespace Core::Devtools::Widget { /* * Generic PM4 header @@ -106,4 +114,53 @@ static bool IsDrawCall(AmdGpu::PM4ItOpcode opcode) { } } +inline std::optional exec_cli(const char* cli) { + std::array buffer{}; + std::string output; + const auto f = popen(cli, "r"); + if (!f) { + pclose(f); + return {}; + } + while (fgets(buffer.data(), buffer.size(), f)) { + output += buffer.data(); + } + pclose(f); + return output; +} + +inline std::string RunDisassembler(const std::string& disassembler_cli, + const std::vector& shader_code) { + std::string shader_dis; + + if (disassembler_cli.empty()) { + shader_dis = "No disassembler set"; + } else { + auto bin_path = std::filesystem::temp_directory_path() / "shadps4_tmp_shader.bin"; + + constexpr std::string_view src_arg = "{src}"; + std::string cli = disassembler_cli; + const auto pos = cli.find(src_arg); + if (pos == std::string::npos) { + DebugState.ShowDebugMessage("Disassembler CLI does not contain {src} argument\n" + + disassembler_cli); + } else { + cli.replace(pos, src_arg.size(), "\"" + bin_path.string() + "\""); + Common::FS::IOFile file(bin_path, Common::FS::FileAccessMode::Write); + file.Write(shader_code); + file.Close(); + + auto result = exec_cli(cli.c_str()); + shader_dis = result.value_or("Could not disassemble shader"); + if (shader_dis.empty()) { + shader_dis = "Disassembly empty or failed"; + } + + std::filesystem::remove(bin_path); + } + } + + return shader_dis; +} + } // namespace Core::Devtools::Widget \ No newline at end of file diff --git a/src/core/devtools/widget/memory_map.cpp b/src/core/devtools/widget/memory_map.cpp new file mode 100644 index 000000000..afafd2853 --- /dev/null +++ b/src/core/devtools/widget/memory_map.cpp @@ -0,0 +1,134 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include +#include + +#include "core/debug_state.h" +#include "core/memory.h" +#include "memory_map.h" + +using namespace ImGui; + +namespace Core::Devtools::Widget { + +bool MemoryMapViewer::Iterator::DrawLine() { + if (is_vma) { + if (vma.it == vma.end) { + return false; + } + auto m = vma.it->second; + if (m.type == VMAType::Free) { + ++vma.it; + return DrawLine(); + } + TableNextColumn(); + Text("%zX", m.base); + TableNextColumn(); + Text("%zX", m.size); + TableNextColumn(); + Text("%s", magic_enum::enum_name(m.type).data()); + TableNextColumn(); + Text("%s", magic_enum::enum_name(m.prot).data()); + TableNextColumn(); + if (m.is_exec) { + Text("X"); + } + TableNextColumn(); + Text("%s", m.name.c_str()); + ++vma.it; + return true; + } + if (dmem.it == dmem.end) { + return false; + } + auto m = dmem.it->second; + if (m.is_free) { + ++dmem.it; + return DrawLine(); + } + TableNextColumn(); + Text("%llX", m.base); + TableNextColumn(); + Text("%llX", m.size); + TableNextColumn(); + auto type = static_cast<::Libraries::Kernel::MemoryTypes>(m.memory_type); + Text("%s", magic_enum::enum_name(type).data()); + TableNextColumn(); + Text("%d", m.is_pooled); + ++dmem.it; + return true; +} + +void MemoryMapViewer::Draw() { + SetNextWindowSize({600.0f, 500.0f}, ImGuiCond_FirstUseEver); + if (!Begin("Memory map", &open)) { + End(); + return; + } + + auto mem = Memory::Instance(); + std::scoped_lock lck{mem->mutex}; + + { + bool next_showing_vma = showing_vma; + if (showing_vma) { + PushStyleColor(ImGuiCol_Button, ImVec4{1.0f, 0.7f, 0.7f, 1.0f}); + } + if (Button("VMem")) { + next_showing_vma = true; + } + if (showing_vma) { + PopStyleColor(); + } + SameLine(); + if (!showing_vma) { + PushStyleColor(ImGuiCol_Button, ImVec4{1.0f, 0.7f, 0.7f, 1.0f}); + } + if (Button("DMem")) { + next_showing_vma = false; + } + if (!showing_vma) { + PopStyleColor(); + } + showing_vma = next_showing_vma; + } + + Iterator it{}; + if (showing_vma) { + it.is_vma = true; + it.vma.it = mem->vma_map.begin(); + it.vma.end = mem->vma_map.end(); + } else { + it.is_vma = false; + it.dmem.it = mem->dmem_map.begin(); + it.dmem.end = mem->dmem_map.end(); + } + + if (BeginTable("memory_view_table", showing_vma ? 6 : 4, + ImGuiTableFlags_Resizable | ImGuiTableFlags_Reorderable | ImGuiTableFlags_RowBg | + ImGuiTableFlags_SizingFixedFit)) { + if (showing_vma) { + TableSetupColumn("Address"); + TableSetupColumn("Size"); + TableSetupColumn("Type"); + TableSetupColumn("Prot"); + TableSetupColumn("Is Exec"); + TableSetupColumn("Name"); + } else { + TableSetupColumn("Address"); + TableSetupColumn("Size"); + TableSetupColumn("Type"); + TableSetupColumn("Pooled"); + } + TableHeadersRow(); + + while (it.DrawLine()) + ; + EndTable(); + } + + End(); +} + +} // namespace Core::Devtools::Widget \ No newline at end of file diff --git a/src/core/devtools/widget/memory_map.h b/src/core/devtools/widget/memory_map.h new file mode 100644 index 000000000..cc7697c8c --- /dev/null +++ b/src/core/devtools/widget/memory_map.h @@ -0,0 +1,33 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/memory.h" + +namespace Core::Devtools::Widget { + +class MemoryMapViewer { + struct Iterator { + bool is_vma; + struct { + MemoryManager::DMemMap::iterator it; + MemoryManager::DMemMap::iterator end; + } dmem; + struct { + MemoryManager::VMAMap::iterator it; + MemoryManager::VMAMap::iterator end; + } vma; + + bool DrawLine(); + }; + + bool showing_vma = true; + +public: + bool open = false; + + void Draw(); +}; + +} // namespace Core::Devtools::Widget diff --git a/src/core/devtools/widget/reg_view.cpp b/src/core/devtools/widget/reg_view.cpp index 10cc88085..a60090a8c 100644 --- a/src/core/devtools/widget/reg_view.cpp +++ b/src/core/devtools/widget/reg_view.cpp @@ -25,21 +25,6 @@ using magic_enum::enum_name; constexpr auto depth_id = 0xF3; -static std::optional exec_cli(const char* cli) { - std::array buffer{}; - std::string output; - const auto f = popen(cli, "r"); - if (!f) { - pclose(f); - return {}; - } - while (fgets(buffer.data(), buffer.size(), f)) { - output += buffer.data(); - } - pclose(f); - return output; -} - namespace Core::Devtools::Widget { void RegView::ProcessShader(int shader_id) { @@ -54,38 +39,12 @@ void RegView::ProcessShader(int shader_id) { user_data = s.user_data.user_data; } - std::string shader_dis; - - if (Options.disassembly_cli.empty()) { - shader_dis = "No disassembler set"; - } else { - auto bin_path = std::filesystem::temp_directory_path() / "shadps4_tmp_shader.bin"; - - constexpr std::string_view src_arg = "{src}"; - std::string cli = Options.disassembly_cli; - const auto pos = cli.find(src_arg); - if (pos == std::string::npos) { - DebugState.ShowDebugMessage("Disassembler CLI does not contain {src} argument"); - } else { - cli.replace(pos, src_arg.size(), "\"" + bin_path.string() + "\""); - Common::FS::IOFile file(bin_path, Common::FS::FileAccessMode::Write); - file.Write(shader_code); - file.Close(); - - auto result = exec_cli(cli.c_str()); - shader_dis = result.value_or("Could not disassemble shader"); - if (shader_dis.empty()) { - shader_dis = "Disassembly empty or failed"; - } - - std::filesystem::remove(bin_path); - } - } + std::string shader_dis = RunDisassembler(Options.disassembler_cli_isa, shader_code); MemoryEditor hex_view; hex_view.Open = true; hex_view.ReadOnly = true; - hex_view.Cols = 8; + hex_view.Cols = 16; hex_view.OptShowAscii = false; hex_view.OptShowOptions = false; @@ -376,7 +335,9 @@ void RegView::Draw() { if (!shader) { Text("Stage not selected"); } else { - shader->hex_view.DrawContents(shader->user_data.data(), shader->user_data.size()); + shader->hex_view.DrawContents(shader->user_data.data(), + shader->user_data.size() * + sizeof(Vulkan::Liverpool::UserData::value_type)); } } End(); diff --git a/src/core/devtools/widget/shader_list.cpp b/src/core/devtools/widget/shader_list.cpp new file mode 100644 index 000000000..b056880dd --- /dev/null +++ b/src/core/devtools/widget/shader_list.cpp @@ -0,0 +1,95 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "shader_list.h" + +#include + +#include "common.h" +#include "common/config.h" +#include "core/debug_state.h" +#include "core/devtools/options.h" +#include "imgui/imgui_std.h" + +using namespace ImGui; + +namespace Core::Devtools::Widget { + +void ShaderList::DrawShader(DebugStateType::ShaderDump& value) { + if (!loaded_data) { + loaded_data = true; + if (value.cache_raw_disasm.empty()) { + value.cache_raw_disasm = RunDisassembler(Options.disassembler_cli_isa, value.raw_code); + } + isa_editor.SetText(value.cache_raw_disasm); + + if (value.cache_spv_disasm.empty()) { + value.cache_spv_disasm = RunDisassembler(Options.disassembler_cli_spv, value.spv); + } + spv_editor.SetText(value.cache_spv_disasm); + } + + if (SmallButton("<-")) { + selected_shader = -1; + } + SameLine(); + Text("%s", value.name.c_str()); + SameLine(0.0f, 7.0f); + if (BeginCombo("Shader type", showing_isa ? "ISA" : "SPIRV", ImGuiComboFlags_WidthFitPreview)) { + if (Selectable("SPIRV")) { + showing_isa = false; + } + if (Selectable("ISA")) { + showing_isa = true; + } + EndCombo(); + } + + if (showing_isa) { + isa_editor.Render("ISA", GetContentRegionAvail()); + } else { + spv_editor.Render("SPIRV", GetContentRegionAvail()); + } +} + +ShaderList::ShaderList() { + isa_editor.SetPalette(TextEditor::GetDarkPalette()); + isa_editor.SetReadOnly(true); + spv_editor.SetPalette(TextEditor::GetDarkPalette()); + spv_editor.SetReadOnly(true); + spv_editor.SetLanguageDefinition(TextEditor::LanguageDefinition::GLSL()); +} + +void ShaderList::Draw() { + SetNextWindowSize({500.0f, 600.0f}, ImGuiCond_FirstUseEver); + if (!Begin("Shader list", &open)) { + End(); + return; + } + + if (!Config::collectShadersForDebug()) { + DrawCenteredText("Enable 'CollectShader' in config to see shaders"); + End(); + return; + } + + if (selected_shader >= 0) { + DrawShader(DebugState.shader_dump_list[selected_shader]); + End(); + return; + } + + auto width = GetContentRegionAvail().x; + int i = 0; + for (const auto& shader : DebugState.shader_dump_list) { + if (ButtonEx(shader.name.c_str(), {width, 20.0f}, ImGuiButtonFlags_NoHoveredOnFocus)) { + selected_shader = i; + loaded_data = false; + } + i++; + } + + End(); +} + +} // namespace Core::Devtools::Widget \ No newline at end of file diff --git a/src/core/devtools/widget/shader_list.h b/src/core/devtools/widget/shader_list.h new file mode 100644 index 000000000..5a47f656d --- /dev/null +++ b/src/core/devtools/widget/shader_list.h @@ -0,0 +1,28 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include "core/debug_state.h" +#include "text_editor.h" + +namespace Core::Devtools::Widget { + +class ShaderList { + int selected_shader = -1; + TextEditor isa_editor{}; + TextEditor spv_editor{}; + bool loaded_data = false; + bool showing_isa = false; + + void DrawShader(DebugStateType::ShaderDump& value); + +public: + ShaderList(); + + bool open = false; + + void Draw(); +}; + +} // namespace Core::Devtools::Widget \ No newline at end of file diff --git a/src/core/memory.h b/src/core/memory.h index a9a42e1c2..2efa02763 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -20,6 +20,10 @@ namespace Libraries::Kernel { struct OrbisQueryInfo; } +namespace Core::Devtools::Widget { +class MemoryMapViewer; +} + namespace Core { enum class MemoryProt : u32 { @@ -257,6 +261,8 @@ private: size_t total_flexible_size{}; size_t flexible_usage{}; Vulkan::Rasterizer* rasterizer{}; + + friend class ::Core::Devtools::Widget::MemoryMapViewer; }; using Memory = Common::Singleton; diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index a4c213ca8..612e950bb 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -7,6 +7,7 @@ #include "common/hash.h" #include "common/io_file.h" #include "common/path_util.h" +#include "core/debug_state.h" #include "shader_recompiler/backend/spirv/emit_spirv.h" #include "shader_recompiler/info.h" #include "shader_recompiler/recompiler.h" @@ -416,6 +417,9 @@ vk::ShaderModule PipelineCache::CompileModule(Shader::Info& info, const auto module = CompileSPV(spv, instance.GetDevice()); const auto name = fmt::format("{}_{:#x}_{}", info.stage, info.pgm_hash, perm_idx); Vulkan::SetObjectName(instance.GetDevice(), module, name); + if (Config::collectShadersForDebug()) { + DebugState.CollectShader(name, spv, code); + } return module; } From 3dc0f6d831093b931ad5fac38ba714ed413db7f1 Mon Sep 17 00:00:00 2001 From: Alexandre Bouvier Date: Mon, 2 Dec 2024 03:04:44 +0000 Subject: [PATCH 24/32] cmake: fix build (#1645) --- externals/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/externals/CMakeLists.txt b/externals/CMakeLists.txt index 50eda0288..bc2d41bda 100644 --- a/externals/CMakeLists.txt +++ b/externals/CMakeLists.txt @@ -69,7 +69,7 @@ if (NOT TARGET ZLIB::ZLIB) FetchContent_MakeAvailable(ZLIB) add_library(ZLIB::ZLIB ALIAS zlib) # libpng expects this variable to exist after its find_package(ZLIB) - get_target_property(ZLIB_INCLUDE_DIRS zlib INTERFACE_INCLUDE_DIRECTORIES) + set(ZLIB_INCLUDE_DIRS "${FETCHCONTENT_BASE_DIR}/zlib-build") endif() # SDL3 From fda4f06518de074c8e8d1fbc99caec890b55875f Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Mon, 2 Dec 2024 11:46:51 -0800 Subject: [PATCH 25/32] devtools: More warning fixes (#1652) --- src/core/devtools/widget/memory_map.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/core/devtools/widget/memory_map.cpp b/src/core/devtools/widget/memory_map.cpp index afafd2853..dc8f5c2e9 100644 --- a/src/core/devtools/widget/memory_map.cpp +++ b/src/core/devtools/widget/memory_map.cpp @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include #include #include @@ -23,7 +24,7 @@ bool MemoryMapViewer::Iterator::DrawLine() { return DrawLine(); } TableNextColumn(); - Text("%zX", m.base); + Text("%" PRIXPTR, m.base); TableNextColumn(); Text("%zX", m.size); TableNextColumn(); @@ -48,9 +49,9 @@ bool MemoryMapViewer::Iterator::DrawLine() { return DrawLine(); } TableNextColumn(); - Text("%llX", m.base); + Text("%" PRIXPTR, m.base); TableNextColumn(); - Text("%llX", m.size); + Text("%zX", m.size); TableNextColumn(); auto type = static_cast<::Libraries::Kernel::MemoryTypes>(m.memory_type); Text("%s", magic_enum::enum_name(type).data()); From eb844b9b63bfddc70ef40665d5bffacd01f31a10 Mon Sep 17 00:00:00 2001 From: TheTurtle Date: Mon, 2 Dec 2024 23:20:54 +0200 Subject: [PATCH 26/32] shader_recompiler: Implement manual barycentric interpolation path (#1644) * shader_recompiler: Implement manual barycentric interpolation path * clang format * emit_spirv: Fix typo * emit_spirv: Simplify variable definition * spirv_emit: clang format --- .../backend/spirv/emit_spirv.cpp | 8 +- .../spirv/emit_spirv_context_get_set.cpp | 85 ++++++++++--------- .../backend/spirv/emit_spirv_special.cpp | 3 + .../backend/spirv/spirv_emit_context.cpp | 69 ++++++++++++--- .../backend/spirv/spirv_emit_context.h | 7 +- src/shader_recompiler/profile.h | 1 + .../renderer_vulkan/vk_instance.cpp | 7 ++ src/video_core/renderer_vulkan/vk_instance.h | 5 ++ .../renderer_vulkan/vk_pipeline_cache.cpp | 2 + 9 files changed, 129 insertions(+), 58 deletions(-) diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp index e84908a57..1e7032f10 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp @@ -206,7 +206,7 @@ Id DefineMain(EmitContext& ctx, const IR::Program& program) { return main; } -void SetupCapabilities(const Info& info, EmitContext& ctx) { +void SetupCapabilities(const Info& info, const Profile& profile, EmitContext& ctx) { ctx.AddCapability(spv::Capability::Image1D); ctx.AddCapability(spv::Capability::Sampled1D); ctx.AddCapability(spv::Capability::ImageQuery); @@ -251,6 +251,10 @@ void SetupCapabilities(const Info& info, EmitContext& ctx) { if (info.stage == Stage::Geometry) { ctx.AddCapability(spv::Capability::Geometry); } + if (info.stage == Stage::Fragment && profile.needs_manual_interpolation) { + ctx.AddExtension("SPV_KHR_fragment_shader_barycentric"); + ctx.AddCapability(spv::Capability::FragmentBarycentricKHR); + } } void DefineEntryPoint(const IR::Program& program, EmitContext& ctx, Id main) { @@ -342,7 +346,7 @@ std::vector EmitSPIRV(const Profile& profile, const RuntimeInfo& runtime_in EmitContext ctx{profile, runtime_info, program.info, binding}; const Id main{DefineMain(ctx, program)}; DefineEntryPoint(program, ctx, main); - SetupCapabilities(program.info, ctx); + SetupCapabilities(program.info, profile, ctx); SetupFloatMode(ctx, profile, runtime_info, main); PatchPhiNodes(program, ctx); binding.user_data += program.info.ud_mask.NumRegs(); diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp index 064200d99..d8c0a17bd 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_context_get_set.cpp @@ -171,54 +171,38 @@ Id EmitReadStepRate(EmitContext& ctx, int rate_idx) { rate_idx == 0 ? ctx.u32_zero_value : ctx.u32_one_value)); } +Id EmitGetAttributeForGeometry(EmitContext& ctx, IR::Attribute attr, u32 comp, u32 index) { + if (IR::IsPosition(attr)) { + ASSERT(attr == IR::Attribute::Position0); + const auto position_arr_ptr = ctx.TypePointer(spv::StorageClass::Input, ctx.F32[4]); + const auto pointer{ + ctx.OpAccessChain(position_arr_ptr, ctx.gl_in, ctx.ConstU32(index), ctx.ConstU32(0u))}; + const auto position_comp_ptr = ctx.TypePointer(spv::StorageClass::Input, ctx.F32[1]); + return ctx.OpLoad(ctx.F32[1], + ctx.OpAccessChain(position_comp_ptr, pointer, ctx.ConstU32(comp))); + } + + if (IR::IsParam(attr)) { + const u32 param_id{u32(attr) - u32(IR::Attribute::Param0)}; + const auto param = ctx.input_params.at(param_id).id; + const auto param_arr_ptr = ctx.TypePointer(spv::StorageClass::Input, ctx.F32[4]); + const auto pointer{ctx.OpAccessChain(param_arr_ptr, param, ctx.ConstU32(index))}; + const auto position_comp_ptr = ctx.TypePointer(spv::StorageClass::Input, ctx.F32[1]); + return ctx.OpLoad(ctx.F32[1], + ctx.OpAccessChain(position_comp_ptr, pointer, ctx.ConstU32(comp))); + } + UNREACHABLE(); +} + Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, u32 comp, u32 index) { if (ctx.info.stage == Stage::Geometry) { - if (IR::IsPosition(attr)) { - ASSERT(attr == IR::Attribute::Position0); - const auto position_arr_ptr = ctx.TypePointer(spv::StorageClass::Input, ctx.F32[4]); - const auto pointer{ctx.OpAccessChain(position_arr_ptr, ctx.gl_in, ctx.ConstU32(index), - ctx.ConstU32(0u))}; - const auto position_comp_ptr = ctx.TypePointer(spv::StorageClass::Input, ctx.F32[1]); - return ctx.OpLoad(ctx.F32[1], - ctx.OpAccessChain(position_comp_ptr, pointer, ctx.ConstU32(comp))); - } - - if (IR::IsParam(attr)) { - const u32 param_id{u32(attr) - u32(IR::Attribute::Param0)}; - const auto param = ctx.input_params.at(param_id).id; - const auto param_arr_ptr = ctx.TypePointer(spv::StorageClass::Input, ctx.F32[4]); - const auto pointer{ctx.OpAccessChain(param_arr_ptr, param, ctx.ConstU32(index))}; - const auto position_comp_ptr = ctx.TypePointer(spv::StorageClass::Input, ctx.F32[1]); - return ctx.OpLoad(ctx.F32[1], - ctx.OpAccessChain(position_comp_ptr, pointer, ctx.ConstU32(comp))); - } - UNREACHABLE(); + return EmitGetAttributeForGeometry(ctx, attr, comp, index); } if (IR::IsParam(attr)) { const u32 index{u32(attr) - u32(IR::Attribute::Param0)}; const auto& param{ctx.input_params.at(index)}; - if (param.buffer_handle < 0) { - if (!ValidId(param.id)) { - // Attribute is disabled or varying component is not written - return ctx.ConstF32(comp == 3 ? 1.0f : 0.0f); - } - - Id result; - if (param.is_default) { - result = ctx.OpCompositeExtract(param.component_type, param.id, comp); - } else if (param.num_components > 1) { - const Id pointer{ - ctx.OpAccessChain(param.pointer_type, param.id, ctx.ConstU32(comp))}; - result = ctx.OpLoad(param.component_type, pointer); - } else { - result = ctx.OpLoad(param.component_type, param.id); - } - if (param.is_integer) { - result = ctx.OpBitcast(ctx.F32[1], result); - } - return result; - } else { + if (param.buffer_handle >= 0) { const auto step_rate = EmitReadStepRate(ctx, param.id.value); const auto offset = ctx.OpIAdd( ctx.U32[1], @@ -229,7 +213,26 @@ Id EmitGetAttribute(EmitContext& ctx, IR::Attribute attr, u32 comp, u32 index) { ctx.ConstU32(comp)); return EmitReadConstBuffer(ctx, param.buffer_handle, offset); } + + Id result; + if (param.is_loaded) { + // Attribute is either default or manually interpolated. The id points to an already + // loaded vector. + result = ctx.OpCompositeExtract(param.component_type, param.id, comp); + } else if (param.num_components > 1) { + // Attribute is a vector and we need to access a specific component. + const Id pointer{ctx.OpAccessChain(param.pointer_type, param.id, ctx.ConstU32(comp))}; + result = ctx.OpLoad(param.component_type, pointer); + } else { + // Attribute is a single float or interger, simply load it. + result = ctx.OpLoad(param.component_type, param.id); + } + if (param.is_integer) { + result = ctx.OpBitcast(ctx.F32[1], result); + } + return result; } + switch (attr) { case IR::Attribute::FragCoord: { const Id coord = ctx.OpLoad( diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp index e9ffdcce8..4a22ba09f 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_special.cpp @@ -8,6 +8,9 @@ namespace Shader::Backend::SPIRV { void EmitPrologue(EmitContext& ctx) { + if (ctx.stage == Stage::Fragment) { + ctx.DefineInterpolatedAttribs(); + } ctx.DefineBufferOffsets(); } diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index dc404b121..6c8eb1236 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp @@ -222,6 +222,36 @@ void EmitContext::DefineBufferOffsets() { } } +void EmitContext::DefineInterpolatedAttribs() { + if (!profile.needs_manual_interpolation) { + return; + } + // Iterate all input attributes, load them and manually interpolate with barycentric + // coordinates. + for (s32 i = 0; i < runtime_info.fs_info.num_inputs; i++) { + const auto& input = runtime_info.fs_info.inputs[i]; + const u32 semantic = input.param_index; + auto& params = input_params[semantic]; + if (input.is_flat || params.is_loaded) { + continue; + } + const Id p_array{OpLoad(TypeArray(F32[4], ConstU32(3U)), params.id)}; + const Id p0{OpCompositeExtract(F32[4], p_array, 0U)}; + const Id p1{OpCompositeExtract(F32[4], p_array, 1U)}; + const Id p2{OpCompositeExtract(F32[4], p_array, 2U)}; + const Id p10{OpFSub(F32[4], p1, p0)}; + const Id p20{OpFSub(F32[4], p2, p0)}; + const Id bary_coord{OpLoad(F32[3], gl_bary_coord_id)}; + const Id bary_coord_y{OpCompositeExtract(F32[1], bary_coord, 1)}; + const Id bary_coord_z{OpCompositeExtract(F32[1], bary_coord, 2)}; + const Id p10_y{OpVectorTimesScalar(F32[4], p10, bary_coord_y)}; + const Id p20_z{OpVectorTimesScalar(F32[4], p20, bary_coord_z)}; + params.id = OpFAdd(F32[4], p0, OpFAdd(F32[4], p10_y, p20_z)); + Name(params.id, fmt::format("fs_in_attr{}", semantic)); + params.is_loaded = true; + } +} + Id MakeDefaultValue(EmitContext& ctx, u32 default_value) { switch (default_value) { case 0: @@ -260,14 +290,14 @@ void EmitContext::DefineInputs() { input.instance_step_rate == Info::VsInput::InstanceIdType::OverStepRate0 ? 0 : 1; // Note that we pass index rather than Id - input_params[input.binding] = { - rate_idx, - input_u32, - U32[1], - input.num_components, - true, - false, - input.instance_data_buf, + input_params[input.binding] = SpirvAttribute{ + .id = rate_idx, + .pointer_type = input_u32, + .component_type = U32[1], + .num_components = input.num_components, + .is_integer = true, + .is_loaded = false, + .buffer_handle = input.instance_data_buf, }; } else { Id id{DefineInput(type, input.binding)}; @@ -286,6 +316,10 @@ void EmitContext::DefineInputs() { frag_coord = DefineVariable(F32[4], spv::BuiltIn::FragCoord, spv::StorageClass::Input); frag_depth = DefineVariable(F32[1], spv::BuiltIn::FragDepth, spv::StorageClass::Output); front_facing = DefineVariable(U1[1], spv::BuiltIn::FrontFacing, spv::StorageClass::Input); + if (profile.needs_manual_interpolation) { + gl_bary_coord_id = + DefineVariable(F32[3], spv::BuiltIn::BaryCoordKHR, spv::StorageClass::Input); + } for (s32 i = 0; i < runtime_info.fs_info.num_inputs; i++) { const auto& input = runtime_info.fs_info.inputs[i]; const u32 semantic = input.param_index; @@ -299,14 +333,21 @@ void EmitContext::DefineInputs() { const IR::Attribute param{IR::Attribute::Param0 + input.param_index}; const u32 num_components = info.loads.NumComponents(param); const Id type{F32[num_components]}; - const Id id{DefineInput(type, semantic)}; - if (input.is_flat) { - Decorate(id, spv::Decoration::Flat); + Id attr_id{}; + if (profile.needs_manual_interpolation && !input.is_flat) { + attr_id = DefineInput(TypeArray(type, ConstU32(3U)), semantic); + Decorate(attr_id, spv::Decoration::PerVertexKHR); + Name(attr_id, fmt::format("fs_in_attr{}_p", semantic)); + } else { + attr_id = DefineInput(type, semantic); + Name(attr_id, fmt::format("fs_in_attr{}", semantic)); + } + if (input.is_flat) { + Decorate(attr_id, spv::Decoration::Flat); } - Name(id, fmt::format("fs_in_attr{}", semantic)); input_params[semantic] = - GetAttributeInfo(AmdGpu::NumberFormat::Float, id, num_components, false); - interfaces.push_back(id); + GetAttributeInfo(AmdGpu::NumberFormat::Float, attr_id, num_components, false); + interfaces.push_back(attr_id); } break; case Stage::Compute: diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.h b/src/shader_recompiler/backend/spirv/spirv_emit_context.h index fb30a5dd6..1c5da946d 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.h +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.h @@ -42,7 +42,9 @@ public: ~EmitContext(); Id Def(const IR::Value& value); + void DefineBufferOffsets(); + void DefineInterpolatedAttribs(); [[nodiscard]] Id DefineInput(Id type, u32 location) { const Id input_id{DefineVar(type, spv::StorageClass::Input)}; @@ -197,6 +199,9 @@ public: Id shared_memory_u32_type{}; + Id interpolate_func{}; + Id gl_bary_coord_id{}; + struct TextureDefinition { const VectorIds* data_types; Id id; @@ -241,7 +246,7 @@ public: Id component_type; u32 num_components; bool is_integer{}; - bool is_default{}; + bool is_loaded{}; s32 buffer_handle{-1}; }; std::array input_params{}; diff --git a/src/shader_recompiler/profile.h b/src/shader_recompiler/profile.h index bbda731e0..a868ab76c 100644 --- a/src/shader_recompiler/profile.h +++ b/src/shader_recompiler/profile.h @@ -24,6 +24,7 @@ struct Profile { bool support_explicit_workgroup_layout{}; bool has_broken_spirv_clamp{}; bool lower_left_origin_mode{}; + bool needs_manual_interpolation{}; u64 min_ssbo_alignment{}; }; diff --git a/src/video_core/renderer_vulkan/vk_instance.cpp b/src/video_core/renderer_vulkan/vk_instance.cpp index 580458e7e..1c150ce28 100644 --- a/src/video_core/renderer_vulkan/vk_instance.cpp +++ b/src/video_core/renderer_vulkan/vk_instance.cpp @@ -256,6 +256,7 @@ bool Instance::CreateDevice() { workgroup_memory_explicit_layout = add_extension(VK_KHR_WORKGROUP_MEMORY_EXPLICIT_LAYOUT_EXTENSION_NAME); vertex_input_dynamic_state = add_extension(VK_EXT_VERTEX_INPUT_DYNAMIC_STATE_EXTENSION_NAME); + fragment_shader_barycentric = add_extension(VK_KHR_FRAGMENT_SHADER_BARYCENTRIC_EXTENSION_NAME); // The next two extensions are required to be available together in order to support write masks color_write_en = add_extension(VK_EXT_COLOR_WRITE_ENABLE_EXTENSION_NAME); @@ -399,6 +400,9 @@ bool Instance::CreateDevice() { vk::PhysicalDevicePrimitiveTopologyListRestartFeaturesEXT{ .primitiveTopologyListRestart = true, }, + vk::PhysicalDeviceFragmentShaderBarycentricFeaturesKHR{ + .fragmentShaderBarycentric = true, + }, #ifdef __APPLE__ feature_chain.get(), #endif @@ -438,6 +442,9 @@ bool Instance::CreateDevice() { if (!vertex_input_dynamic_state) { device_chain.unlink(); } + if (!fragment_shader_barycentric) { + device_chain.unlink(); + } auto [device_result, dev] = physical_device.createDeviceUnique(device_chain.get()); if (device_result != vk::Result::eSuccess) { diff --git a/src/video_core/renderer_vulkan/vk_instance.h b/src/video_core/renderer_vulkan/vk_instance.h index 51c2c57c5..5a46ef6fe 100644 --- a/src/video_core/renderer_vulkan/vk_instance.h +++ b/src/video_core/renderer_vulkan/vk_instance.h @@ -143,6 +143,11 @@ public: return maintenance5; } + /// Returns true when VK_KHR_fragment_shader_barycentric is supported. + bool IsFragmentShaderBarycentricSupported() const { + return fragment_shader_barycentric; + } + bool IsListRestartSupported() const { return list_restart; } diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index 612e950bb..a1ed7edac 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -169,6 +169,8 @@ PipelineCache::PipelineCache(const Instance& instance_, Scheduler& scheduler_, .support_fp32_denorm_preserve = bool(vk12_props.shaderDenormPreserveFloat32), .support_fp32_denorm_flush = bool(vk12_props.shaderDenormFlushToZeroFloat32), .support_explicit_workgroup_layout = true, + .needs_manual_interpolation = instance.IsFragmentShaderBarycentricSupported() && + instance.GetDriverID() == vk::DriverId::eNvidiaProprietary, }; auto [cache_result, cache] = instance.GetDevice().createPipelineCacheUnique({}); ASSERT_MSG(cache_result == vk::Result::eSuccess, "Failed to create pipeline cache: {}", From f0b75289c8c810a53294c975453c7faba4f49ef2 Mon Sep 17 00:00:00 2001 From: psucien Date: Mon, 2 Dec 2024 22:24:54 +0100 Subject: [PATCH 27/32] video_core: few detiler formats added --- src/video_core/texture_cache/tile_manager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/video_core/texture_cache/tile_manager.cpp b/src/video_core/texture_cache/tile_manager.cpp index c4f24420d..7430168d0 100644 --- a/src/video_core/texture_cache/tile_manager.cpp +++ b/src/video_core/texture_cache/tile_manager.cpp @@ -182,12 +182,15 @@ vk::Format DemoteImageFormatForDetiling(vk::Format format) { case vk::Format::eB8G8R8A8Srgb: case vk::Format::eB8G8R8A8Unorm: case vk::Format::eR8G8B8A8Unorm: + case vk::Format::eR8G8B8A8Snorm: case vk::Format::eR8G8B8A8Uint: case vk::Format::eR32Sfloat: case vk::Format::eR32Uint: case vk::Format::eR16G16Sfloat: case vk::Format::eR16G16Unorm: + case vk::Format::eR16G16Snorm: case vk::Format::eB10G11R11UfloatPack32: + case vk::Format::eA2B10G10R10UnormPack32: return vk::Format::eR32Uint; case vk::Format::eBc1RgbaSrgbBlock: case vk::Format::eBc1RgbaUnormBlock: From c66db95378fb7ae9b68ea3980eae248da55d2250 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Tue, 3 Dec 2024 10:05:51 +0200 Subject: [PATCH 28/32] Misc Ime fixes continue (#1655) * core/libraries: Misc. Ime fixes * fixed issues --------- Co-authored-by: Daniel R <47796739+polybiusproxy@users.noreply.github.com> --- src/core/libraries/ime/ime.cpp | 95 +++++++++++++++++++---------- src/core/libraries/ime/ime.h | 26 ++++++-- src/core/libraries/ime/ime_common.h | 2 +- src/core/libraries/ime/ime_ui.cpp | 81 ++++++++++++------------ src/core/libraries/ime/ime_ui.h | 6 +- 5 files changed, 131 insertions(+), 79 deletions(-) diff --git a/src/core/libraries/ime/ime.cpp b/src/core/libraries/ime/ime.cpp index 700585ff3..dfd659db8 100644 --- a/src/core/libraries/ime/ime.cpp +++ b/src/core/libraries/ime/ime.cpp @@ -44,10 +44,14 @@ public: openEvent.param.rect.y = m_param.ime.posy; } else { openEvent.param.resource_id_array.userId = 1; - openEvent.param.resource_id_array.resource_id[0] = 1; + openEvent.param.resource_id_array.resourceId[0] = 1; } - Execute(nullptr, &openEvent, true); + // Are we supposed to call the event handler on init with + // ADD_OSK? + if (!ime_mode && False(m_param.key.option & OrbisImeKeyboardOption::AddOsk)) { + Execute(nullptr, &openEvent, true); + } if (ime_mode) { g_ime_state = ImeState(&m_param.ime); @@ -56,6 +60,11 @@ public: } s32 Update(OrbisImeEventHandler handler) { + if (!m_ime_mode) { + /* We don't handle any events for ImeKeyboard */ + return ORBIS_OK; + } + std::unique_lock lock{g_ime_state.queue_mutex}; while (!g_ime_state.event_queue.empty()) { @@ -85,6 +94,16 @@ public: } } + s32 SetText(const char16_t* text, u32 length) { + g_ime_state.SetText(text, length); + return ORBIS_OK; + } + + s32 SetCaret(const OrbisImeCaret* caret) { + g_ime_state.SetCaret(caret->index); + return ORBIS_OK; + } + bool IsIme() { return m_ime_mode; } @@ -98,6 +117,7 @@ private: }; static std::unique_ptr g_ime_handler; +static std::unique_ptr g_keyboard_handler; int PS4_SYSV_ABI FinalizeImeModule() { LOG_ERROR(Lib_Ime, "(STUBBED) called"); @@ -130,9 +150,6 @@ s32 PS4_SYSV_ABI sceImeClose() { if (!g_ime_handler) { return ORBIS_IME_ERROR_NOT_OPENED; } - if (!g_ime_handler->IsIme()) { - return ORBIS_IME_ERROR_NOT_OPENED; - } g_ime_handler.release(); g_ime_ui = ImeUi(); @@ -233,14 +250,11 @@ s32 PS4_SYSV_ABI sceImeGetPanelSize(const OrbisImeParam* param, u32* width, u32* s32 PS4_SYSV_ABI sceImeKeyboardClose(s32 userId) { LOG_INFO(Lib_Ime, "(STUBBED) called"); - if (!g_ime_handler) { - return ORBIS_IME_ERROR_NOT_OPENED; - } - if (g_ime_handler->IsIme()) { + if (!g_keyboard_handler) { return ORBIS_IME_ERROR_NOT_OPENED; } - g_ime_handler.release(); + g_keyboard_handler.release(); return ORBIS_OK; } @@ -255,18 +269,17 @@ int PS4_SYSV_ABI sceImeKeyboardGetResourceId() { } s32 PS4_SYSV_ABI sceImeKeyboardOpen(s32 userId, const OrbisImeKeyboardParam* param) { - LOG_ERROR(Lib_Ime, "(STUBBED) called"); + LOG_INFO(Lib_Ime, "called"); if (!param) { return ORBIS_IME_ERROR_INVALID_ADDRESS; } - if (g_ime_handler) { + if (g_keyboard_handler) { return ORBIS_IME_ERROR_BUSY; } - // g_ime_handler = std::make_unique(param); - // return ORBIS_OK; - return ORBIS_IME_ERROR_CONNECTION_FAILED; // Fixup + g_keyboard_handler = std::make_unique(param); + return ORBIS_OK; } int PS4_SYSV_ABI sceImeKeyboardOpenInternal() { @@ -287,16 +300,14 @@ int PS4_SYSV_ABI sceImeKeyboardUpdate() { s32 PS4_SYSV_ABI sceImeOpen(const OrbisImeParam* param, const void* extended) { LOG_INFO(Lib_Ime, "called"); - if (!g_ime_handler) { - g_ime_handler = std::make_unique(param); - } else { - if (g_ime_handler->IsIme()) { - return ORBIS_IME_ERROR_BUSY; - } - - g_ime_handler->Init((void*)param, true); + if (!param) { + return ORBIS_IME_ERROR_INVALID_ADDRESS; + } + if (g_ime_handler) { + return ORBIS_IME_ERROR_BUSY; } + g_ime_handler = std::make_unique(param); return ORBIS_OK; } @@ -322,13 +333,29 @@ int PS4_SYSV_ABI sceImeSetCandidateIndex() { } int PS4_SYSV_ABI sceImeSetCaret(const OrbisImeCaret* caret) { - LOG_ERROR(Lib_Ime, "(STUBBED) called"); - return ORBIS_OK; + LOG_TRACE(Lib_Ime, "called"); + + if (!g_ime_handler) { + return ORBIS_IME_ERROR_NOT_OPENED; + } + if (!caret) { + return ORBIS_IME_ERROR_INVALID_ADDRESS; + } + + return g_ime_handler->SetCaret(caret); } -int PS4_SYSV_ABI sceImeSetText() { - LOG_ERROR(Lib_Ime, "(STUBBED) called"); - return ORBIS_OK; +s32 PS4_SYSV_ABI sceImeSetText(const char16_t* text, u32 length) { + LOG_TRACE(Lib_Ime, "called"); + + if (!g_ime_handler) { + return ORBIS_IME_ERROR_NOT_OPENED; + } + if (!text) { + return ORBIS_IME_ERROR_INVALID_ADDRESS; + } + + return g_ime_handler->SetText(text, length); } int PS4_SYSV_ABI sceImeSetTextGeometry() { @@ -337,13 +364,19 @@ int PS4_SYSV_ABI sceImeSetTextGeometry() { } s32 PS4_SYSV_ABI sceImeUpdate(OrbisImeEventHandler handler) { - LOG_TRACE(Lib_Ime, "called"); + if (g_ime_handler) { + g_ime_handler->Update(handler); + } - if (!g_ime_handler) { + if (g_keyboard_handler) { + g_keyboard_handler->Update(handler); + } + + if (!g_ime_handler || !g_keyboard_handler) { return ORBIS_IME_ERROR_NOT_OPENED; } - return g_ime_handler->Update(handler); + return ORBIS_OK; } int PS4_SYSV_ABI sceImeVshClearPreedit() { diff --git a/src/core/libraries/ime/ime.h b/src/core/libraries/ime/ime.h index 2915b70da..448ee6896 100644 --- a/src/core/libraries/ime/ime.h +++ b/src/core/libraries/ime/ime.h @@ -26,6 +26,24 @@ enum class OrbisImeKeyboardOption : u32 { }; DECLARE_ENUM_FLAG_OPERATORS(OrbisImeKeyboardOption) +enum class OrbisImeOption : u32 { + DEFAULT = 0, + MULTILINE = 1, + NO_AUTO_CAPITALIZATION = 2, + PASSWORD = 4, + LANGUAGES_FORCED = 8, + EXT_KEYBOARD = 16, + NO_LEARNING = 32, + FIXED_POSITION = 64, + DISABLE_RESUME = 256, + DISABLE_AUTO_SPACE = 512, + DISABLE_POSITION_ADJUSTMENT = 2048, + EXPANDED_PREEDIT_BUFFER = 4096, + USE_JAPANESE_EISUU_KEY_AS_CAPSLOCK = 8192, + USE_2K_COORDINATES = 16384, +}; +DECLARE_ENUM_FLAG_OPERATORS(OrbisImeOption) + struct OrbisImeKeyboardParam { OrbisImeKeyboardOption option; s8 reserved1[4]; @@ -41,9 +59,9 @@ struct OrbisImeParam { OrbisImeEnterLabel enter_label; OrbisImeInputMethod input_method; OrbisImeTextFilter filter; - u32 option; - u32 max_text_length; - char16_t* input_text_buffer; + OrbisImeOption option; + u32 maxTextLength; + char16_t* inputTextBuffer; float posx; float posy; OrbisImeHorizontalAlignment horizontal_alignment; @@ -93,7 +111,7 @@ int PS4_SYSV_ABI sceImeOpenInternal(); void PS4_SYSV_ABI sceImeParamInit(OrbisImeParam* param); int PS4_SYSV_ABI sceImeSetCandidateIndex(); s32 PS4_SYSV_ABI sceImeSetCaret(const OrbisImeCaret* caret); -int PS4_SYSV_ABI sceImeSetText(); +s32 PS4_SYSV_ABI sceImeSetText(const char16_t* text, u32 length); int PS4_SYSV_ABI sceImeSetTextGeometry(); s32 PS4_SYSV_ABI sceImeUpdate(OrbisImeEventHandler handler); int PS4_SYSV_ABI sceImeVshClearPreedit(); diff --git a/src/core/libraries/ime/ime_common.h b/src/core/libraries/ime/ime_common.h index 77f23d91d..6d4afd81d 100644 --- a/src/core/libraries/ime/ime_common.h +++ b/src/core/libraries/ime/ime_common.h @@ -142,7 +142,7 @@ struct OrbisImeKeycode { struct OrbisImeKeyboardResourceIdArray { s32 userId; - u32 resource_id[6]; + u32 resourceId[5]; }; enum class OrbisImeCaretMovementDirection : u32 { diff --git a/src/core/libraries/ime/ime_ui.cpp b/src/core/libraries/ime/ime_ui.cpp index c5f41c5e8..8eaa48178 100644 --- a/src/core/libraries/ime/ime_ui.cpp +++ b/src/core/libraries/ime/ime_ui.cpp @@ -16,7 +16,7 @@ ImeState::ImeState(const OrbisImeParam* param) { } work_buffer = param->work; - text_buffer = param->input_text_buffer; + text_buffer = param->inputTextBuffer; std::size_t text_len = std::char_traits::length(text_buffer); if (!ConvertOrbisToUTF8(text_buffer, text_len, current_text.begin(), @@ -26,15 +26,13 @@ ImeState::ImeState(const OrbisImeParam* param) { } ImeState::ImeState(ImeState&& other) noexcept - : input_changed(other.input_changed), work_buffer(other.work_buffer), - text_buffer(other.text_buffer), current_text(std::move(other.current_text)), - event_queue(std::move(other.event_queue)) { + : work_buffer(other.work_buffer), text_buffer(other.text_buffer), + current_text(std::move(other.current_text)), event_queue(std::move(other.event_queue)) { other.text_buffer = nullptr; } ImeState& ImeState::operator=(ImeState&& other) noexcept { if (this != &other) { - input_changed = other.input_changed; work_buffer = other.work_buffer; text_buffer = other.text_buffer; current_text = std::move(other.current_text); @@ -63,6 +61,10 @@ void ImeState::SendCloseEvent() { SendEvent(&closeEvent); } +void ImeState::SetText(const char16_t* text, u32 length) {} + +void ImeState::SetCaret(u32 position) {} + bool ImeState::ConvertOrbisToUTF8(const char16_t* orbis_text, std::size_t orbis_text_len, char* utf8_text, std::size_t utf8_text_len) { std::fill(utf8_text, utf8_text + utf8_text_len, '\0'); @@ -180,9 +182,8 @@ void ImeUi::DrawInputText() { if (first_render) { SetKeyboardFocusHere(); } - if (InputTextEx("##ImeInput", nullptr, state->current_text.begin(), ime_param->max_text_length, + if (InputTextEx("##ImeInput", nullptr, state->current_text.begin(), ime_param->maxTextLength, input_size, ImGuiInputTextFlags_CallbackAlways, InputTextCallback, this)) { - state->input_changed = true; } } @@ -190,6 +191,39 @@ int ImeUi::InputTextCallback(ImGuiInputTextCallbackData* data) { ImeUi* ui = static_cast(data->UserData); ASSERT(ui); + static std::string lastText; + std::string currentText(data->Buf, data->BufTextLen); + if (currentText != lastText) { + OrbisImeEditText eventParam{}; + eventParam.str = reinterpret_cast(ui->ime_param->work); + eventParam.caret_index = data->CursorPos; + eventParam.area_num = 1; + + eventParam.text_area[0].mode = 1; // Edit mode + eventParam.text_area[0].index = data->CursorPos; + eventParam.text_area[0].length = data->BufTextLen; + + if (!ui->state->ConvertUTF8ToOrbis(data->Buf, data->BufTextLen, eventParam.str, + ui->ime_param->maxTextLength)) { + LOG_ERROR(Lib_ImeDialog, "Failed to convert Orbis char to UTF-8"); + return 0; + } + + if (!ui->state->ConvertUTF8ToOrbis(data->Buf, data->BufTextLen, + ui->ime_param->inputTextBuffer, + ui->ime_param->maxTextLength)) { + LOG_ERROR(Lib_ImeDialog, "Failed to convert Orbis char to UTF-8"); + return 0; + } + + OrbisImeEvent event{}; + event.id = OrbisImeEventId::UpdateText; + event.param.text = eventParam; + + lastText = currentText; + ui->state->SendEvent(&event); + } + static int lastCaretPos = -1; if (lastCaretPos == -1) { lastCaretPos = data->CursorPos; @@ -209,39 +243,6 @@ int ImeUi::InputTextCallback(ImGuiInputTextCallbackData* data) { ui->state->SendEvent(&event); } - static std::string lastText; - std::string currentText(data->Buf, data->BufTextLen); - if (currentText != lastText) { - OrbisImeEditText eventParam{}; - eventParam.str = reinterpret_cast(ui->ime_param->work); - eventParam.caret_index = data->CursorPos; - eventParam.area_num = 1; - - eventParam.text_area[0].mode = 1; // Edit mode - eventParam.text_area[0].index = data->CursorPos; - eventParam.text_area[0].length = data->BufTextLen; - - if (!ui->state->ConvertUTF8ToOrbis(data->Buf, data->BufTextLen, eventParam.str, - ui->ime_param->max_text_length)) { - LOG_ERROR(Lib_ImeDialog, "Failed to convert Orbis char to UTF-8"); - return 0; - } - - if (!ui->state->ConvertUTF8ToOrbis(data->Buf, data->BufTextLen, - ui->ime_param->input_text_buffer, - ui->ime_param->max_text_length)) { - LOG_ERROR(Lib_ImeDialog, "Failed to convert Orbis char to UTF-8"); - return 0; - } - - OrbisImeEvent event{}; - event.id = OrbisImeEventId::UpdateText; - event.param.text = eventParam; - - lastText = currentText; - ui->state->SendEvent(&event); - } - return 0; } diff --git a/src/core/libraries/ime/ime_ui.h b/src/core/libraries/ime/ime_ui.h index ebd70a7c8..a2a806bb9 100644 --- a/src/core/libraries/ime/ime_ui.h +++ b/src/core/libraries/ime/ime_ui.h @@ -22,10 +22,7 @@ class ImeState { friend class ImeHandler; friend class ImeUi; - bool input_changed = false; - void* work_buffer{}; - char16_t* text_buffer{}; // A character can hold up to 4 bytes in UTF-8 @@ -43,6 +40,9 @@ public: void SendEnterEvent(); void SendCloseEvent(); + void SetText(const char16_t* text, u32 length); + void SetCaret(u32 position); + private: bool ConvertOrbisToUTF8(const char16_t* orbis_text, std::size_t orbis_text_len, char* utf8_text, std::size_t native_text_len); From 6bf93071cf43f19b428fb1f4f34039a71cb315ee Mon Sep 17 00:00:00 2001 From: TheTurtle Date: Tue, 3 Dec 2024 14:15:08 +0200 Subject: [PATCH 29/32] hot-fix: Correct getpagesize Tested on my PS4 pro, returns 16KB instead of 4KB --- src/core/libraries/kernel/kernel.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/libraries/kernel/kernel.cpp b/src/core/libraries/kernel/kernel.cpp index b310c7be9..4028116ef 100644 --- a/src/core/libraries/kernel/kernel.cpp +++ b/src/core/libraries/kernel/kernel.cpp @@ -203,7 +203,7 @@ int PS4_SYSV_ABI _sigprocmask() { } int PS4_SYSV_ABI posix_getpagesize() { - return 4096; + return 16_KB; } void RegisterKernel(Core::Loader::SymbolsResolver* sym) { From 74b091fd0818894b19949a1a12d183e152f712ea Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Wed, 4 Dec 2024 01:15:58 -0800 Subject: [PATCH 30/32] renderer_vulkan: Add support for indexed QuadList draw. (#1661) --- src/video_core/buffer_cache/buffer_cache.cpp | 28 ++++++++++++++++++- .../renderer_vulkan/liverpool_to_vk.cpp | 13 --------- .../renderer_vulkan/liverpool_to_vk.h | 28 ++++++++++++++++++- 3 files changed, 54 insertions(+), 15 deletions(-) diff --git a/src/video_core/buffer_cache/buffer_cache.cpp b/src/video_core/buffer_cache/buffer_cache.cpp index 77b353c2f..1f05b16c8 100644 --- a/src/video_core/buffer_cache/buffer_cache.cpp +++ b/src/video_core/buffer_cache/buffer_cache.cpp @@ -236,7 +236,7 @@ bool BufferCache::BindVertexBuffers(const Shader::Info& vs_info) { u32 BufferCache::BindIndexBuffer(bool& is_indexed, u32 index_offset) { // Emulate QuadList primitive type with CPU made index buffer. const auto& regs = liverpool->regs; - if (regs.primitive_type == AmdGpu::PrimitiveType::QuadList) { + if (regs.primitive_type == AmdGpu::PrimitiveType::QuadList && !is_indexed) { is_indexed = true; // Emit indices. @@ -262,6 +262,32 @@ u32 BufferCache::BindIndexBuffer(bool& is_indexed, u32 index_offset) { VAddr index_address = regs.index_base_address.Address(); index_address += index_offset * index_size; + if (regs.primitive_type == AmdGpu::PrimitiveType::QuadList) { + // Convert indices. + const u32 new_index_size = regs.num_indices * index_size * 6 / 4; + const auto [data, offset] = stream_buffer.Map(new_index_size); + const auto index_ptr = reinterpret_cast(index_address); + switch (index_type) { + case vk::IndexType::eUint16: + Vulkan::LiverpoolToVK::ConvertQuadToTriangleListIndices(data, index_ptr, + regs.num_indices); + break; + case vk::IndexType::eUint32: + Vulkan::LiverpoolToVK::ConvertQuadToTriangleListIndices(data, index_ptr, + regs.num_indices); + break; + default: + UNREACHABLE_MSG("Unsupported QuadList index type {}", vk::to_string(index_type)); + break; + } + stream_buffer.Commit(); + + // Bind index buffer. + const auto cmdbuf = scheduler.CommandBuffer(); + cmdbuf.bindIndexBuffer(stream_buffer.Handle(), offset, index_type); + return new_index_size / index_size; + } + // Bind index buffer. const u32 index_buffer_size = regs.num_indices * index_size; const auto [vk_buffer, offset] = ObtainBuffer(index_address, index_buffer_size, false); diff --git a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp index 258e7f391..2262a429a 100644 --- a/src/video_core/renderer_vulkan/liverpool_to_vk.cpp +++ b/src/video_core/renderer_vulkan/liverpool_to_vk.cpp @@ -726,19 +726,6 @@ vk::Format DepthFormat(DepthBuffer::ZFormat z_format, DepthBuffer::StencilFormat return format->vk_format; } -void EmitQuadToTriangleListIndices(u8* out_ptr, u32 num_vertices) { - static constexpr u16 NumVerticesPerQuad = 4; - u16* out_data = reinterpret_cast(out_ptr); - for (u16 i = 0; i < num_vertices; i += NumVerticesPerQuad) { - *out_data++ = i; - *out_data++ = i + 1; - *out_data++ = i + 2; - *out_data++ = i; - *out_data++ = i + 2; - *out_data++ = i + 3; - } -} - vk::ClearValue ColorBufferClearValue(const AmdGpu::Liverpool::ColorBuffer& color_buffer) { const auto comp_swap = color_buffer.info.comp_swap.Value(); const auto format = color_buffer.info.format.Value(); diff --git a/src/video_core/renderer_vulkan/liverpool_to_vk.h b/src/video_core/renderer_vulkan/liverpool_to_vk.h index 70e707fad..287ba691e 100644 --- a/src/video_core/renderer_vulkan/liverpool_to_vk.h +++ b/src/video_core/renderer_vulkan/liverpool_to_vk.h @@ -68,7 +68,33 @@ vk::ClearValue ColorBufferClearValue(const AmdGpu::Liverpool::ColorBuffer& color vk::SampleCountFlagBits NumSamples(u32 num_samples, vk::SampleCountFlags supported_flags); -void EmitQuadToTriangleListIndices(u8* out_indices, u32 num_vertices); +static constexpr u16 NumVerticesPerQuad = 4; + +inline void EmitQuadToTriangleListIndices(u8* out_ptr, u32 num_vertices) { + u16* out_data = reinterpret_cast(out_ptr); + for (u16 i = 0; i < num_vertices; i += NumVerticesPerQuad) { + *out_data++ = i; + *out_data++ = i + 1; + *out_data++ = i + 2; + *out_data++ = i; + *out_data++ = i + 2; + *out_data++ = i + 3; + } +} + +template +void ConvertQuadToTriangleListIndices(u8* out_ptr, const u8* in_ptr, u32 num_vertices) { + T* out_data = reinterpret_cast(out_ptr); + const T* in_data = reinterpret_cast(in_ptr); + for (u16 i = 0; i < num_vertices; i += NumVerticesPerQuad) { + *out_data++ = in_data[i]; + *out_data++ = in_data[i + 1]; + *out_data++ = in_data[i + 2]; + *out_data++ = in_data[i]; + *out_data++ = in_data[i + 2]; + *out_data++ = in_data[i + 3]; + } +} static inline vk::Format PromoteFormatToDepth(vk::Format fmt) { if (fmt == vk::Format::eR32Sfloat) { From 920acb8d8b7524f32eafefccd5396f7c07f8c158 Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Wed, 4 Dec 2024 03:03:47 -0800 Subject: [PATCH 31/32] renderer_vulkan: Parse fetch shader per-pipeline (#1656) * shader_recompiler: Read image format info directly from sharps instead of storing in shader info. * renderer_vulkan: Parse fetch shader per-pipeline * Few minor fixes. * shader_recompiler: Specialize on vertex attribute number types. * shader_recompiler: Move GetDrawOffsets to fetch shader --- .../backend/spirv/emit_spirv_image.cpp | 3 +- .../backend/spirv/spirv_emit_context.cpp | 91 ++++++++++--------- .../frontend/fetch_shader.cpp | 12 ++- src/shader_recompiler/frontend/fetch_shader.h | 56 +++++++++++- .../frontend/translate/translate.cpp | 36 ++------ src/shader_recompiler/info.h | 47 ++-------- .../ir/passes/resource_tracking_pass.cpp | 4 - src/shader_recompiler/profile.h | 1 + src/shader_recompiler/specialization.h | 45 ++++++++- src/video_core/amdgpu/pixel_format.h | 19 +++- src/video_core/amdgpu/resource.h | 4 + src/video_core/buffer_cache/buffer_cache.cpp | 21 +++-- src/video_core/buffer_cache/buffer_cache.h | 8 +- .../renderer_vulkan/vk_graphics_pipeline.cpp | 32 ++++--- .../renderer_vulkan/vk_graphics_pipeline.h | 7 ++ .../renderer_vulkan/vk_instance.cpp | 7 ++ src/video_core/renderer_vulkan/vk_instance.h | 7 ++ .../renderer_vulkan/vk_pipeline_cache.cpp | 40 ++++---- .../renderer_vulkan/vk_pipeline_cache.h | 7 +- .../renderer_vulkan/vk_rasterizer.cpp | 14 +-- src/video_core/texture_cache/image_view.cpp | 7 +- 21 files changed, 286 insertions(+), 182 deletions(-) diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp index 40e5ea8b9..fe2660705 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp @@ -187,7 +187,8 @@ Id EmitImageFetch(EmitContext& ctx, IR::Inst* inst, u32 handle, Id coords, const Id EmitImageQueryDimensions(EmitContext& ctx, IR::Inst* inst, u32 handle, Id lod, bool has_mips) { const auto& texture = ctx.images[handle & 0xFFFF]; const Id image = ctx.OpLoad(texture.image_type, texture.id); - const auto type = ctx.info.images[handle & 0xFFFF].type; + const auto sharp = ctx.info.images[handle & 0xFFFF].GetSharp(ctx.info); + const auto type = sharp.GetBoundType(); const Id zero = ctx.u32_zero_value; const auto mips{[&] { return has_mips ? ctx.OpImageQueryLevels(ctx.U32[1], image) : zero; }}; const bool uses_lod{type != AmdGpu::ImageType::Color2DMsaa && !texture.is_storage}; diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index 6c8eb1236..4ce9f4221 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp @@ -4,6 +4,7 @@ #include "common/assert.h" #include "common/div_ceil.h" #include "shader_recompiler/backend/spirv/spirv_emit_context.h" +#include "shader_recompiler/frontend/fetch_shader.h" #include "shader_recompiler/ir/passes/srt.h" #include "video_core/amdgpu/types.h" @@ -155,18 +156,12 @@ void EmitContext::DefineInterfaces() { } const VectorIds& GetAttributeType(EmitContext& ctx, AmdGpu::NumberFormat fmt) { - switch (fmt) { - case AmdGpu::NumberFormat::Float: - case AmdGpu::NumberFormat::Unorm: - case AmdGpu::NumberFormat::Snorm: - case AmdGpu::NumberFormat::SnormNz: - case AmdGpu::NumberFormat::Sscaled: - case AmdGpu::NumberFormat::Uscaled: - case AmdGpu::NumberFormat::Srgb: + switch (GetNumberClass(fmt)) { + case AmdGpu::NumberClass::Float: return ctx.F32; - case AmdGpu::NumberFormat::Sint: + case AmdGpu::NumberClass::Sint: return ctx.S32; - case AmdGpu::NumberFormat::Uint: + case AmdGpu::NumberClass::Uint: return ctx.U32; default: break; @@ -176,18 +171,12 @@ const VectorIds& GetAttributeType(EmitContext& ctx, AmdGpu::NumberFormat fmt) { EmitContext::SpirvAttribute EmitContext::GetAttributeInfo(AmdGpu::NumberFormat fmt, Id id, u32 num_components, bool output) { - switch (fmt) { - case AmdGpu::NumberFormat::Float: - case AmdGpu::NumberFormat::Unorm: - case AmdGpu::NumberFormat::Snorm: - case AmdGpu::NumberFormat::SnormNz: - case AmdGpu::NumberFormat::Sscaled: - case AmdGpu::NumberFormat::Uscaled: - case AmdGpu::NumberFormat::Srgb: + switch (GetNumberClass(fmt)) { + case AmdGpu::NumberClass::Float: return {id, output ? output_f32 : input_f32, F32[1], num_components, false}; - case AmdGpu::NumberFormat::Uint: + case AmdGpu::NumberClass::Uint: return {id, output ? output_u32 : input_u32, U32[1], num_components, true}; - case AmdGpu::NumberFormat::Sint: + case AmdGpu::NumberClass::Sint: return {id, output ? output_s32 : input_s32, S32[1], num_components, true}; default: break; @@ -280,33 +269,42 @@ void EmitContext::DefineInputs() { base_vertex = DefineVariable(U32[1], spv::BuiltIn::BaseVertex, spv::StorageClass::Input); instance_id = DefineVariable(U32[1], spv::BuiltIn::InstanceIndex, spv::StorageClass::Input); - for (const auto& input : info.vs_inputs) { - ASSERT(input.binding < IR::NumParams); - const Id type{GetAttributeType(*this, input.fmt)[4]}; - if (input.instance_step_rate == Info::VsInput::InstanceIdType::OverStepRate0 || - input.instance_step_rate == Info::VsInput::InstanceIdType::OverStepRate1) { - + const auto fetch_shader = Gcn::ParseFetchShader(info); + if (!fetch_shader) { + break; + } + for (const auto& attrib : fetch_shader->attributes) { + ASSERT(attrib.semantic < IR::NumParams); + const auto sharp = attrib.GetSharp(info); + const Id type{GetAttributeType(*this, sharp.GetNumberFmt())[4]}; + if (attrib.UsesStepRates()) { const u32 rate_idx = - input.instance_step_rate == Info::VsInput::InstanceIdType::OverStepRate0 ? 0 - : 1; + attrib.GetStepRate() == Gcn::VertexAttribute::InstanceIdType::OverStepRate0 ? 0 + : 1; + const u32 num_components = AmdGpu::NumComponents(sharp.GetDataFmt()); + const auto buffer = + std::ranges::find_if(info.buffers, [&attrib](const auto& buffer) { + return buffer.instance_attrib == attrib.semantic; + }); // Note that we pass index rather than Id - input_params[input.binding] = SpirvAttribute{ + input_params[attrib.semantic] = SpirvAttribute{ .id = rate_idx, .pointer_type = input_u32, .component_type = U32[1], - .num_components = input.num_components, + .num_components = std::min(attrib.num_elements, num_components), .is_integer = true, .is_loaded = false, - .buffer_handle = input.instance_data_buf, + .buffer_handle = int(buffer - info.buffers.begin()), }; } else { - Id id{DefineInput(type, input.binding)}; - if (input.instance_step_rate == Info::VsInput::InstanceIdType::Plain) { - Name(id, fmt::format("vs_instance_attr{}", input.binding)); + Id id{DefineInput(type, attrib.semantic)}; + if (attrib.GetStepRate() == Gcn::VertexAttribute::InstanceIdType::Plain) { + Name(id, fmt::format("vs_instance_attr{}", attrib.semantic)); } else { - Name(id, fmt::format("vs_in_attr{}", input.binding)); + Name(id, fmt::format("vs_in_attr{}", attrib.semantic)); } - input_params[input.binding] = GetAttributeInfo(input.fmt, id, 4, false); + input_params[attrib.semantic] = + GetAttributeInfo(sharp.GetNumberFmt(), id, 4, false); interfaces.push_back(id); } } @@ -553,9 +551,10 @@ void EmitContext::DefineBuffers() { void EmitContext::DefineTextureBuffers() { for (const auto& desc : info.texture_buffers) { - const bool is_integer = - desc.nfmt == AmdGpu::NumberFormat::Uint || desc.nfmt == AmdGpu::NumberFormat::Sint; - const VectorIds& sampled_type{GetAttributeType(*this, desc.nfmt)}; + const auto sharp = desc.GetSharp(info); + const auto nfmt = sharp.GetNumberFmt(); + const bool is_integer = AmdGpu::IsInteger(nfmt); + const VectorIds& sampled_type{GetAttributeType(*this, nfmt)}; const u32 sampled = desc.is_written ? 2 : 1; const Id image_type{TypeImage(sampled_type[1], spv::Dim::Buffer, false, false, false, sampled, spv::ImageFormat::Unknown)}; @@ -650,10 +649,11 @@ spv::ImageFormat GetFormat(const AmdGpu::Image& image) { } Id ImageType(EmitContext& ctx, const ImageResource& desc, Id sampled_type) { - const auto image = ctx.info.ReadUdSharp(desc.sharp_idx); + const auto image = desc.GetSharp(ctx.info); const auto format = desc.is_atomic ? GetFormat(image) : spv::ImageFormat::Unknown; + const auto type = image.GetBoundType(); const u32 sampled = desc.is_storage ? 2 : 1; - switch (desc.type) { + switch (type) { case AmdGpu::ImageType::Color1D: return ctx.TypeImage(sampled_type, spv::Dim::Dim1D, false, false, false, sampled, format); case AmdGpu::ImageType::Color1DArray: @@ -672,14 +672,15 @@ Id ImageType(EmitContext& ctx, const ImageResource& desc, Id sampled_type) { default: break; } - throw InvalidArgument("Invalid texture type {}", desc.type); + throw InvalidArgument("Invalid texture type {}", type); } void EmitContext::DefineImagesAndSamplers() { for (const auto& image_desc : info.images) { - const bool is_integer = image_desc.nfmt == AmdGpu::NumberFormat::Uint || - image_desc.nfmt == AmdGpu::NumberFormat::Sint; - const VectorIds& data_types = GetAttributeType(*this, image_desc.nfmt); + const auto sharp = image_desc.GetSharp(info); + const auto nfmt = sharp.GetNumberFmt(); + const bool is_integer = AmdGpu::IsInteger(nfmt); + const VectorIds& data_types = GetAttributeType(*this, nfmt); const Id sampled_type = data_types[1]; const Id image_type{ImageType(*this, image_desc, sampled_type)}; const Id pointer_type{TypePointer(spv::StorageClass::UniformConstant, image_type)}; diff --git a/src/shader_recompiler/frontend/fetch_shader.cpp b/src/shader_recompiler/frontend/fetch_shader.cpp index 16938410c..8ae664d79 100644 --- a/src/shader_recompiler/frontend/fetch_shader.cpp +++ b/src/shader_recompiler/frontend/fetch_shader.cpp @@ -34,8 +34,14 @@ namespace Shader::Gcn { * We take the reverse way, extract the original input semantics from these instructions. **/ -FetchShaderData ParseFetchShader(const u32* code, u32* out_size) { - FetchShaderData data{}; +std::optional ParseFetchShader(const Shader::Info& info) { + if (!info.has_fetch_shader) { + return std::nullopt; + } + const u32* code; + std::memcpy(&code, &info.user_data[info.fetch_shader_sgpr_base], sizeof(code)); + + FetchShaderData data{.code = code}; GcnCodeSlice code_slice(code, code + std::numeric_limits::max()); GcnDecodeContext decoder; @@ -49,7 +55,7 @@ FetchShaderData ParseFetchShader(const u32* code, u32* out_size) { u32 semantic_index = 0; while (!code_slice.atEnd()) { const auto inst = decoder.decodeInstruction(code_slice); - *out_size += inst.length; + data.size += inst.length; if (inst.opcode == Opcode::S_SETPC_B64) { break; diff --git a/src/shader_recompiler/frontend/fetch_shader.h b/src/shader_recompiler/frontend/fetch_shader.h index 0e5d15419..ee9f5c805 100644 --- a/src/shader_recompiler/frontend/fetch_shader.h +++ b/src/shader_recompiler/frontend/fetch_shader.h @@ -3,26 +3,80 @@ #pragma once +#include #include #include "common/types.h" +#include "shader_recompiler/info.h" namespace Shader::Gcn { struct VertexAttribute { + enum InstanceIdType : u8 { + None = 0, + OverStepRate0 = 1, + OverStepRate1 = 2, + Plain = 3, + }; + u8 semantic; ///< Semantic index of the attribute u8 dest_vgpr; ///< Destination VGPR to load first component. u8 num_elements; ///< Number of components to load u8 sgpr_base; ///< SGPR that contains the pointer to the list of vertex V# u8 dword_offset; ///< The dword offset of the V# that describes this attribute. u8 instance_data; ///< Indicates that the buffer will be accessed in instance rate + + [[nodiscard]] InstanceIdType GetStepRate() const { + return static_cast(instance_data); + } + + [[nodiscard]] bool UsesStepRates() const { + const auto step_rate = GetStepRate(); + return step_rate == OverStepRate0 || step_rate == OverStepRate1; + } + + [[nodiscard]] constexpr AmdGpu::Buffer GetSharp(const Shader::Info& info) const noexcept { + return info.ReadUdReg(sgpr_base, dword_offset); + } + + bool operator==(const VertexAttribute& other) const { + return semantic == other.semantic && dest_vgpr == other.dest_vgpr && + num_elements == other.num_elements && sgpr_base == other.sgpr_base && + dword_offset == other.dword_offset && instance_data == other.instance_data; + } }; struct FetchShaderData { + const u32* code; + u32 size = 0; std::vector attributes; s8 vertex_offset_sgpr = -1; ///< SGPR of vertex offset from VADDR s8 instance_offset_sgpr = -1; ///< SGPR of instance offset from VADDR + + [[nodiscard]] bool UsesStepRates() const { + return std::ranges::find_if(attributes, [](const VertexAttribute& attribute) { + return attribute.UsesStepRates(); + }) != attributes.end(); + } + + [[nodiscard]] std::pair GetDrawOffsets(const AmdGpu::Liverpool::Regs& regs, + const Info& info) const { + u32 vertex_offset = regs.index_offset; + u32 instance_offset = 0; + if (vertex_offset == 0 && vertex_offset_sgpr != -1) { + vertex_offset = info.user_data[vertex_offset_sgpr]; + } + if (instance_offset_sgpr != -1) { + instance_offset = info.user_data[instance_offset_sgpr]; + } + return {vertex_offset, instance_offset}; + } + + bool operator==(const FetchShaderData& other) const { + return attributes == other.attributes && vertex_offset_sgpr == other.vertex_offset_sgpr && + instance_offset_sgpr == other.instance_offset_sgpr; + } }; -FetchShaderData ParseFetchShader(const u32* code, u32* out_size); +std::optional ParseFetchShader(const Shader::Info& info); } // namespace Shader::Gcn diff --git a/src/shader_recompiler/frontend/translate/translate.cpp b/src/shader_recompiler/frontend/translate/translate.cpp index 005c4a7ff..68625a12b 100644 --- a/src/shader_recompiler/frontend/translate/translate.cpp +++ b/src/shader_recompiler/frontend/translate/translate.cpp @@ -368,13 +368,11 @@ void Translator::SetDst64(const InstOperand& operand, const IR::U64F64& value_ra void Translator::EmitFetch(const GcnInst& inst) { // Read the pointer to the fetch shader assembly. - const u32 sgpr_base = inst.src[0].code; - const u32* code; - std::memcpy(&code, &info.user_data[sgpr_base], sizeof(code)); + info.has_fetch_shader = true; + info.fetch_shader_sgpr_base = inst.src[0].code; - // Parse the assembly to generate a list of attributes. - u32 fetch_size{}; - const auto fetch_data = ParseFetchShader(code, &fetch_size); + const auto fetch_data = ParseFetchShader(info); + ASSERT(fetch_data.has_value()); if (Config::dumpShaders()) { using namespace Common::FS; @@ -384,13 +382,10 @@ void Translator::EmitFetch(const GcnInst& inst) { } const auto filename = fmt::format("vs_{:#018x}.fetch.bin", info.pgm_hash); const auto file = IOFile{dump_dir / filename, FileAccessMode::Write}; - file.WriteRaw(code, fetch_size); + file.WriteRaw(fetch_data->code, fetch_data->size); } - info.vertex_offset_sgpr = fetch_data.vertex_offset_sgpr; - info.instance_offset_sgpr = fetch_data.instance_offset_sgpr; - - for (const auto& attrib : fetch_data.attributes) { + for (const auto& attrib : fetch_data->attributes) { const IR::Attribute attr{IR::Attribute::Param0 + attrib.semantic}; IR::VectorReg dst_reg{attrib.dest_vgpr}; @@ -420,29 +415,14 @@ void Translator::EmitFetch(const GcnInst& inst) { // In case of programmable step rates we need to fallback to instance data pulling in // shader, so VBs should be bound as regular data buffers - s32 instance_buf_handle = -1; - const auto step_rate = static_cast(attrib.instance_data); - if (step_rate == Info::VsInput::OverStepRate0 || - step_rate == Info::VsInput::OverStepRate1) { + if (attrib.UsesStepRates()) { info.buffers.push_back({ .sharp_idx = info.srt_info.ReserveSharp(attrib.sgpr_base, attrib.dword_offset, 4), .used_types = IR::Type::F32, .is_instance_data = true, + .instance_attrib = attrib.semantic, }); - instance_buf_handle = s32(info.buffers.size() - 1); - info.uses_step_rates = true; } - - const u32 num_components = AmdGpu::NumComponents(buffer.GetDataFmt()); - info.vs_inputs.push_back({ - .fmt = buffer.GetNumberFmt(), - .binding = attrib.semantic, - .num_components = std::min(attrib.num_elements, num_components), - .sgpr_base = attrib.sgpr_base, - .dword_offset = attrib.dword_offset, - .instance_step_rate = step_rate, - .instance_data_buf = instance_buf_handle, - }); } } diff --git a/src/shader_recompiler/info.h b/src/shader_recompiler/info.h index c7ae2a1e5..d382d0e7c 100644 --- a/src/shader_recompiler/info.h +++ b/src/shader_recompiler/info.h @@ -45,6 +45,7 @@ struct BufferResource { AmdGpu::Buffer inline_cbuf; bool is_gds_buffer{}; bool is_instance_data{}; + u8 instance_attrib{}; bool is_written{}; bool IsStorage(AmdGpu::Buffer buffer) const noexcept { @@ -57,7 +58,6 @@ using BufferResourceList = boost::container::small_vector; struct TextureBufferResource { u32 sharp_idx; - AmdGpu::NumberFormat nfmt; bool is_written{}; constexpr AmdGpu::Buffer GetSharp(const Info& info) const noexcept; @@ -66,8 +66,6 @@ using TextureBufferResourceList = boost::container::small_vector vs_inputs{}; - struct AttributeFlags { bool Get(IR::Attribute attrib, u32 comp = 0) const { return flags[Index(attrib)] & (1 << comp); @@ -179,9 +159,6 @@ struct Info { CopyShaderData gs_copy_data; - s8 vertex_offset_sgpr = -1; - s8 instance_offset_sgpr = -1; - BufferResourceList buffers; TextureBufferResourceList texture_buffers; ImageResourceList images; @@ -208,10 +185,11 @@ struct Info { bool uses_shared{}; bool uses_fp16{}; bool uses_fp64{}; - bool uses_step_rates{}; bool translation_failed{}; // indicates that shader has unsupported instructions bool has_readconst{}; u8 mrt_mask{0u}; + bool has_fetch_shader{false}; + u32 fetch_shader_sgpr_base{0u}; explicit Info(Stage stage_, ShaderParams params) : stage{stage_}, pgm_hash{params.hash}, pgm_base{params.Base()}, @@ -252,18 +230,6 @@ struct Info { bnd.user_data += ud_mask.NumRegs(); } - [[nodiscard]] std::pair GetDrawOffsets(const AmdGpu::Liverpool::Regs& regs) const { - u32 vertex_offset = regs.index_offset; - u32 instance_offset = 0; - if (vertex_offset == 0 && vertex_offset_sgpr != -1) { - vertex_offset = user_data[vertex_offset_sgpr]; - } - if (instance_offset_sgpr != -1) { - instance_offset = user_data[instance_offset_sgpr]; - } - return {vertex_offset, instance_offset}; - } - void RefreshFlatBuf() { flattened_ud_buf.resize(srt_info.flattened_bufsize_dw); ASSERT(user_data.size() <= NumUserDataRegs); @@ -284,7 +250,12 @@ constexpr AmdGpu::Buffer TextureBufferResource::GetSharp(const Info& info) const } constexpr AmdGpu::Image ImageResource::GetSharp(const Info& info) const noexcept { - return info.ReadUdSharp(sharp_idx); + const auto image = info.ReadUdSharp(sharp_idx); + if (!image.Valid()) { + // Fall back to null image if unbound. + return AmdGpu::Image::Null(); + } + return image; } constexpr AmdGpu::Sampler SamplerResource::GetSharp(const Info& info) const noexcept { diff --git a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp index 7d29c845d..c1ff3d2f2 100644 --- a/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp +++ b/src/shader_recompiler/ir/passes/resource_tracking_pass.cpp @@ -381,7 +381,6 @@ void PatchTextureBufferInstruction(IR::Block& block, IR::Inst& inst, Info& info, const auto buffer = info.ReadUdSharp(sharp); const s32 binding = descriptors.Add(TextureBufferResource{ .sharp_idx = sharp, - .nfmt = buffer.GetNumberFmt(), .is_written = inst.GetOpcode() == IR::Opcode::StoreBufferFormatF32, }); @@ -660,11 +659,8 @@ void PatchImageInstruction(IR::Block& block, IR::Inst& inst, Info& info, Descrip } } - const auto type = image.IsPartialCubemap() ? AmdGpu::ImageType::Color2DArray : image.GetType(); u32 image_binding = descriptors.Add(ImageResource{ .sharp_idx = tsharp, - .type = type, - .nfmt = image.GetNumberFmt(), .is_storage = is_storage, .is_depth = bool(inst_info.is_depth), .is_atomic = IsImageAtomicInstruction(inst), diff --git a/src/shader_recompiler/profile.h b/src/shader_recompiler/profile.h index a868ab76c..96c458d44 100644 --- a/src/shader_recompiler/profile.h +++ b/src/shader_recompiler/profile.h @@ -22,6 +22,7 @@ struct Profile { bool support_fp32_denorm_preserve{}; bool support_fp32_denorm_flush{}; bool support_explicit_workgroup_layout{}; + bool support_legacy_vertex_attributes{}; bool has_broken_spirv_clamp{}; bool lower_left_origin_mode{}; bool needs_manual_interpolation{}; diff --git a/src/shader_recompiler/specialization.h b/src/shader_recompiler/specialization.h index 225b164b5..740b89dda 100644 --- a/src/shader_recompiler/specialization.h +++ b/src/shader_recompiler/specialization.h @@ -6,12 +6,19 @@ #include #include "common/types.h" +#include "frontend/fetch_shader.h" #include "shader_recompiler/backend/bindings.h" #include "shader_recompiler/info.h" #include "shader_recompiler/ir/passes/srt.h" namespace Shader { +struct VsAttribSpecialization { + AmdGpu::NumberClass num_class{}; + + auto operator<=>(const VsAttribSpecialization&) const = default; +}; + struct BufferSpecialization { u16 stride : 14; u16 is_storage : 1; @@ -50,6 +57,8 @@ struct StageSpecialization { const Shader::Info* info; RuntimeInfo runtime_info; + Gcn::FetchShaderData fetch_shader_data{}; + boost::container::small_vector vs_attribs; std::bitset bitset{}; boost::container::small_vector buffers; boost::container::small_vector tex_buffers; @@ -57,9 +66,19 @@ struct StageSpecialization { boost::container::small_vector fmasks; Backend::Bindings start{}; - explicit StageSpecialization(const Shader::Info& info_, RuntimeInfo runtime_info_, - Backend::Bindings start_) + explicit StageSpecialization(const Info& info_, RuntimeInfo runtime_info_, + const Profile& profile_, Backend::Bindings start_) : info{&info_}, runtime_info{runtime_info_}, start{start_} { + if (const auto fetch_shader = Gcn::ParseFetchShader(info_)) { + fetch_shader_data = *fetch_shader; + if (info_.stage == Stage::Vertex && !profile_.support_legacy_vertex_attributes) { + // Specialize shader on VS input number types to follow spec. + ForEachSharp(vs_attribs, fetch_shader_data.attributes, + [](auto& spec, const auto& desc, AmdGpu::Buffer sharp) { + spec.num_class = AmdGpu::GetNumberClass(sharp.GetNumberFmt()); + }); + } + } u32 binding{}; if (info->has_readconst) { binding++; @@ -75,8 +94,7 @@ struct StageSpecialization { }); ForEachSharp(binding, images, info->images, [](auto& spec, const auto& desc, AmdGpu::Image sharp) { - spec.type = sharp.IsPartialCubemap() ? AmdGpu::ImageType::Color2DArray - : sharp.GetType(); + spec.type = sharp.GetBoundType(); spec.is_integer = AmdGpu::IsInteger(sharp.GetNumberFmt()); }); ForEachSharp(binding, fmasks, info->fmasks, @@ -86,6 +104,17 @@ struct StageSpecialization { }); } + void ForEachSharp(auto& spec_list, auto& desc_list, auto&& func) { + for (const auto& desc : desc_list) { + auto& spec = spec_list.emplace_back(); + const auto sharp = desc.GetSharp(*info); + if (!sharp) { + continue; + } + func(spec, desc, sharp); + } + } + void ForEachSharp(u32& binding, auto& spec_list, auto& desc_list, auto&& func) { for (const auto& desc : desc_list) { auto& spec = spec_list.emplace_back(); @@ -106,6 +135,14 @@ struct StageSpecialization { if (runtime_info != other.runtime_info) { return false; } + if (fetch_shader_data != other.fetch_shader_data) { + return false; + } + for (u32 i = 0; i < vs_attribs.size(); i++) { + if (vs_attribs[i] != other.vs_attribs[i]) { + return false; + } + } u32 binding{}; if (info->has_readconst != other.info->has_readconst) { return false; diff --git a/src/video_core/amdgpu/pixel_format.h b/src/video_core/amdgpu/pixel_format.h index e83313ea4..38c81ba5f 100644 --- a/src/video_core/amdgpu/pixel_format.h +++ b/src/video_core/amdgpu/pixel_format.h @@ -10,7 +10,24 @@ namespace AmdGpu { -[[nodiscard]] constexpr bool IsInteger(NumberFormat nfmt) { +enum NumberClass { + Float, + Sint, + Uint, +}; + +[[nodiscard]] constexpr NumberClass GetNumberClass(const NumberFormat nfmt) { + switch (nfmt) { + case NumberFormat::Sint: + return Sint; + case NumberFormat::Uint: + return Uint; + default: + return Float; + } +} + +[[nodiscard]] constexpr bool IsInteger(const NumberFormat nfmt) { return nfmt == AmdGpu::NumberFormat::Sint || nfmt == AmdGpu::NumberFormat::Uint; } diff --git a/src/video_core/amdgpu/resource.h b/src/video_core/amdgpu/resource.h index f43fc9800..a78a68391 100644 --- a/src/video_core/amdgpu/resource.h +++ b/src/video_core/amdgpu/resource.h @@ -304,6 +304,10 @@ struct Image { const auto viewed_slice = last_array - base_array + 1; return GetType() == ImageType::Cube && viewed_slice < 6; } + + ImageType GetBoundType() const noexcept { + return IsPartialCubemap() ? ImageType::Color2DArray : GetType(); + } }; static_assert(sizeof(Image) == 32); // 256bits diff --git a/src/video_core/buffer_cache/buffer_cache.cpp b/src/video_core/buffer_cache/buffer_cache.cpp index 1f05b16c8..1abdb230b 100644 --- a/src/video_core/buffer_cache/buffer_cache.cpp +++ b/src/video_core/buffer_cache/buffer_cache.cpp @@ -5,6 +5,7 @@ #include "common/alignment.h" #include "common/scope_exit.h" #include "common/types.h" +#include "shader_recompiler/frontend/fetch_shader.h" #include "shader_recompiler/info.h" #include "video_core/amdgpu/liverpool.h" #include "video_core/buffer_cache/buffer_cache.h" @@ -107,7 +108,8 @@ void BufferCache::DownloadBufferMemory(Buffer& buffer, VAddr device_addr, u64 si } } -bool BufferCache::BindVertexBuffers(const Shader::Info& vs_info) { +bool BufferCache::BindVertexBuffers( + const Shader::Info& vs_info, const std::optional& fetch_shader) { boost::container::small_vector attributes; boost::container::small_vector bindings; SCOPE_EXIT { @@ -126,7 +128,7 @@ bool BufferCache::BindVertexBuffers(const Shader::Info& vs_info) { } }; - if (vs_info.vs_inputs.empty()) { + if (!fetch_shader || fetch_shader->attributes.empty()) { return false; } @@ -150,30 +152,29 @@ bool BufferCache::BindVertexBuffers(const Shader::Info& vs_info) { // Calculate buffers memory overlaps bool has_step_rate = false; boost::container::static_vector ranges{}; - for (const auto& input : vs_info.vs_inputs) { - if (input.instance_step_rate == Shader::Info::VsInput::InstanceIdType::OverStepRate0 || - input.instance_step_rate == Shader::Info::VsInput::InstanceIdType::OverStepRate1) { + for (const auto& attrib : fetch_shader->attributes) { + if (attrib.UsesStepRates()) { has_step_rate = true; continue; } - const auto& buffer = vs_info.ReadUdReg(input.sgpr_base, input.dword_offset); + const auto& buffer = attrib.GetSharp(vs_info); if (buffer.GetSize() == 0) { continue; } guest_buffers.emplace_back(buffer); ranges.emplace_back(buffer.base_address, buffer.base_address + buffer.GetSize()); attributes.push_back({ - .location = input.binding, - .binding = input.binding, + .location = attrib.semantic, + .binding = attrib.semantic, .format = Vulkan::LiverpoolToVK::SurfaceFormat(buffer.GetDataFmt(), buffer.GetNumberFmt()), .offset = 0, }); bindings.push_back({ - .binding = input.binding, + .binding = attrib.semantic, .stride = buffer.GetStride(), - .inputRate = input.instance_step_rate == Shader::Info::VsInput::None + .inputRate = attrib.GetStepRate() == Shader::Gcn::VertexAttribute::InstanceIdType::None ? vk::VertexInputRate::eVertex : vk::VertexInputRate::eInstance, .divisor = 1, diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index e2519e942..b1bf77f8a 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h @@ -20,8 +20,11 @@ struct Liverpool; } namespace Shader { -struct Info; +namespace Gcn { +struct FetchShaderData; } +struct Info; +} // namespace Shader namespace VideoCore { @@ -76,7 +79,8 @@ public: void InvalidateMemory(VAddr device_addr, u64 size); /// Binds host vertex buffers for the current draw. - bool BindVertexBuffers(const Shader::Info& vs_info); + bool BindVertexBuffers(const Shader::Info& vs_info, + const std::optional& fetch_shader); /// Bind host index buffer for the current draw. u32 BindIndexBuffer(bool& is_indexed, u32 index_offset); diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp index d0d16ac75..d53204c77 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include +#include #include #include @@ -10,6 +11,8 @@ #include "video_core/amdgpu/resource.h" #include "video_core/buffer_cache/buffer_cache.h" #include "video_core/renderer_vulkan/vk_graphics_pipeline.h" + +#include "shader_recompiler/frontend/fetch_shader.h" #include "video_core/renderer_vulkan/vk_instance.h" #include "video_core/renderer_vulkan/vk_scheduler.h" #include "video_core/texture_cache/texture_cache.h" @@ -20,8 +23,10 @@ GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& schedul DescriptorHeap& desc_heap_, const GraphicsPipelineKey& key_, vk::PipelineCache pipeline_cache, std::span infos, + std::optional fetch_shader_, std::span modules) - : Pipeline{instance_, scheduler_, desc_heap_, pipeline_cache}, key{key_} { + : Pipeline{instance_, scheduler_, desc_heap_, pipeline_cache}, key{key_}, + fetch_shader{std::move(fetch_shader_)} { const vk::Device device = instance.GetDevice(); std::ranges::copy(infos, stages.begin()); BuildDescSetLayout(); @@ -46,32 +51,31 @@ GraphicsPipeline::GraphicsPipeline(const Instance& instance_, Scheduler& schedul boost::container::static_vector vertex_bindings; boost::container::static_vector vertex_attributes; - if (!instance.IsVertexInputDynamicState()) { - const auto& vs_info = stages[u32(Shader::Stage::Vertex)]; - for (const auto& input : vs_info->vs_inputs) { - if (input.instance_step_rate == Shader::Info::VsInput::InstanceIdType::OverStepRate0 || - input.instance_step_rate == Shader::Info::VsInput::InstanceIdType::OverStepRate1) { + if (fetch_shader && !instance.IsVertexInputDynamicState()) { + const auto& vs_info = GetStage(Shader::Stage::Vertex); + for (const auto& attrib : fetch_shader->attributes) { + if (attrib.UsesStepRates()) { // Skip attribute binding as the data will be pulled by shader continue; } - const auto buffer = - vs_info->ReadUdReg(input.sgpr_base, input.dword_offset); + const auto buffer = attrib.GetSharp(vs_info); if (buffer.GetSize() == 0) { continue; } vertex_attributes.push_back({ - .location = input.binding, - .binding = input.binding, + .location = attrib.semantic, + .binding = attrib.semantic, .format = LiverpoolToVK::SurfaceFormat(buffer.GetDataFmt(), buffer.GetNumberFmt()), .offset = 0, }); vertex_bindings.push_back({ - .binding = input.binding, + .binding = attrib.semantic, .stride = buffer.GetStride(), - .inputRate = input.instance_step_rate == Shader::Info::VsInput::None - ? vk::VertexInputRate::eVertex - : vk::VertexInputRate::eInstance, + .inputRate = + attrib.GetStepRate() == Shader::Gcn::VertexAttribute::InstanceIdType::None + ? vk::VertexInputRate::eVertex + : vk::VertexInputRate::eInstance, }); } } diff --git a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h index 4f4abfd16..91ffe4ea4 100644 --- a/src/video_core/renderer_vulkan/vk_graphics_pipeline.h +++ b/src/video_core/renderer_vulkan/vk_graphics_pipeline.h @@ -4,6 +4,7 @@ #include #include "common/types.h" +#include "shader_recompiler/frontend/fetch_shader.h" #include "video_core/renderer_vulkan/liverpool_to_vk.h" #include "video_core/renderer_vulkan/vk_common.h" #include "video_core/renderer_vulkan/vk_pipeline_common.h" @@ -59,9 +60,14 @@ public: GraphicsPipeline(const Instance& instance, Scheduler& scheduler, DescriptorHeap& desc_heap, const GraphicsPipelineKey& key, vk::PipelineCache pipeline_cache, std::span stages, + std::optional fetch_shader, std::span modules); ~GraphicsPipeline(); + const std::optional& GetFetchShader() const noexcept { + return fetch_shader; + } + bool IsEmbeddedVs() const noexcept { static constexpr size_t EmbeddedVsHash = 0x9b2da5cf47f8c29f; return key.stage_hashes[u32(Shader::Stage::Vertex)] == EmbeddedVsHash; @@ -94,6 +100,7 @@ private: private: GraphicsPipelineKey key; + std::optional fetch_shader{}; }; } // namespace Vulkan diff --git a/src/video_core/renderer_vulkan/vk_instance.cpp b/src/video_core/renderer_vulkan/vk_instance.cpp index 1c150ce28..49e4987db 100644 --- a/src/video_core/renderer_vulkan/vk_instance.cpp +++ b/src/video_core/renderer_vulkan/vk_instance.cpp @@ -265,6 +265,7 @@ bool Instance::CreateDevice() { const bool robustness = add_extension(VK_EXT_ROBUSTNESS_2_EXTENSION_NAME); list_restart = add_extension(VK_EXT_PRIMITIVE_TOPOLOGY_LIST_RESTART_EXTENSION_NAME); maintenance5 = add_extension(VK_KHR_MAINTENANCE_5_EXTENSION_NAME); + legacy_vertex_attributes = add_extension(VK_EXT_LEGACY_VERTEX_ATTRIBUTES_EXTENSION_NAME); // These extensions are promoted by Vulkan 1.3, but for greater compatibility we use Vulkan 1.2 // with extensions. @@ -403,6 +404,9 @@ bool Instance::CreateDevice() { vk::PhysicalDeviceFragmentShaderBarycentricFeaturesKHR{ .fragmentShaderBarycentric = true, }, + vk::PhysicalDeviceLegacyVertexAttributesFeaturesEXT{ + .legacyVertexAttributes = true, + }, #ifdef __APPLE__ feature_chain.get(), #endif @@ -445,6 +449,9 @@ bool Instance::CreateDevice() { if (!fragment_shader_barycentric) { device_chain.unlink(); } + if (!legacy_vertex_attributes) { + device_chain.unlink(); + } auto [device_result, dev] = physical_device.createDeviceUnique(device_chain.get()); if (device_result != vk::Result::eSuccess) { diff --git a/src/video_core/renderer_vulkan/vk_instance.h b/src/video_core/renderer_vulkan/vk_instance.h index 5a46ef6fe..81303c9cc 100644 --- a/src/video_core/renderer_vulkan/vk_instance.h +++ b/src/video_core/renderer_vulkan/vk_instance.h @@ -148,10 +148,16 @@ public: return fragment_shader_barycentric; } + /// Returns true when VK_EXT_primitive_topology_list_restart is supported. bool IsListRestartSupported() const { return list_restart; } + /// Returns true when VK_EXT_legacy_vertex_attributes is supported. + bool IsLegacyVertexAttributesSupported() const { + return legacy_vertex_attributes; + } + /// Returns true when geometry shaders are supported by the device bool IsGeometryStageSupported() const { return features.geometryShader; @@ -320,6 +326,7 @@ private: bool null_descriptor{}; bool maintenance5{}; bool list_restart{}; + bool legacy_vertex_attributes{}; u64 min_imported_host_pointer_alignment{}; u32 subgroup_size{}; bool tooling_info{}; diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp index a1ed7edac..47713f0ff 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.cpp @@ -169,6 +169,7 @@ PipelineCache::PipelineCache(const Instance& instance_, Scheduler& scheduler_, .support_fp32_denorm_preserve = bool(vk12_props.shaderDenormPreserveFloat32), .support_fp32_denorm_flush = bool(vk12_props.shaderDenormFlushToZeroFloat32), .support_explicit_workgroup_layout = true, + .support_legacy_vertex_attributes = instance_.IsLegacyVertexAttributesSupported(), .needs_manual_interpolation = instance.IsFragmentShaderBarycentricSupported() && instance.GetDriverID() == vk::DriverId::eNvidiaProprietary, }; @@ -187,7 +188,7 @@ const GraphicsPipeline* PipelineCache::GetGraphicsPipeline() { const auto [it, is_new] = graphics_pipelines.try_emplace(graphics_key); if (is_new) { it.value() = graphics_pipeline_pool.Create(instance, scheduler, desc_heap, graphics_key, - *pipeline_cache, infos, modules); + *pipeline_cache, infos, fetch_shader, modules); } return it->second; } @@ -304,8 +305,12 @@ bool PipelineCache::RefreshGraphicsKey() { } auto params = Liverpool::GetParams(*pgm); - std::tie(infos[stage_out_idx], modules[stage_out_idx], key.stage_hashes[stage_out_idx]) = - GetProgram(stage_in, params, binding); + std::optional fetch_shader_; + std::tie(infos[stage_out_idx], modules[stage_out_idx], fetch_shader_, + key.stage_hashes[stage_out_idx]) = GetProgram(stage_in, params, binding); + if (fetch_shader_) { + fetch_shader = fetch_shader_; + } return true; }; @@ -341,16 +346,14 @@ bool PipelineCache::RefreshGraphicsKey() { } } - const auto* vs_info = infos[static_cast(Shader::Stage::Vertex)]; - if (vs_info && !instance.IsVertexInputDynamicState()) { + const auto vs_info = infos[static_cast(Shader::Stage::Vertex)]; + if (vs_info && fetch_shader && !instance.IsVertexInputDynamicState()) { u32 vertex_binding = 0; - for (const auto& input : vs_info->vs_inputs) { - if (input.instance_step_rate == Shader::Info::VsInput::InstanceIdType::OverStepRate0 || - input.instance_step_rate == Shader::Info::VsInput::InstanceIdType::OverStepRate1) { + for (const auto& attrib : fetch_shader->attributes) { + if (attrib.UsesStepRates()) { continue; } - const auto& buffer = - vs_info->ReadUdReg(input.sgpr_base, input.dword_offset); + const auto& buffer = attrib.GetSharp(*vs_info); if (buffer.GetSize() == 0) { continue; } @@ -394,7 +397,7 @@ bool PipelineCache::RefreshComputeKey() { Shader::Backend::Bindings binding{}; const auto* cs_pgm = &liverpool->regs.cs_program; const auto cs_params = Liverpool::GetParams(*cs_pgm); - std::tie(infos[0], modules[0], compute_key) = + std::tie(infos[0], modules[0], fetch_shader, compute_key) = GetProgram(Shader::Stage::Compute, cs_params, binding); return true; } @@ -425,24 +428,26 @@ vk::ShaderModule PipelineCache::CompileModule(Shader::Info& info, return module; } -std::tuple PipelineCache::GetProgram( - Shader::Stage stage, Shader::ShaderParams params, Shader::Backend::Bindings& binding) { +std::tuple, u64> +PipelineCache::GetProgram(Shader::Stage stage, Shader::ShaderParams params, + Shader::Backend::Bindings& binding) { const auto runtime_info = BuildRuntimeInfo(stage); auto [it_pgm, new_program] = program_cache.try_emplace(params.hash); if (new_program) { Program* program = program_pool.Create(stage, params); auto start = binding; const auto module = CompileModule(program->info, runtime_info, params.code, 0, binding); - const auto spec = Shader::StageSpecialization(program->info, runtime_info, start); + const auto spec = Shader::StageSpecialization(program->info, runtime_info, profile, start); program->AddPermut(module, std::move(spec)); it_pgm.value() = program; - return std::make_tuple(&program->info, module, HashCombine(params.hash, 0)); + return std::make_tuple(&program->info, module, spec.fetch_shader_data, + HashCombine(params.hash, 0)); } Program* program = it_pgm->second; auto& info = program->info; info.RefreshFlatBuf(); - const auto spec = Shader::StageSpecialization(info, runtime_info, binding); + const auto spec = Shader::StageSpecialization(info, runtime_info, profile, binding); size_t perm_idx = program->modules.size(); vk::ShaderModule module{}; @@ -456,7 +461,8 @@ std::tuple PipelineCache::GetProgram module = it->module; perm_idx = std::distance(program->modules.begin(), it); } - return std::make_tuple(&info, module, HashCombine(params.hash, perm_idx)); + return std::make_tuple(&info, module, spec.fetch_shader_data, + HashCombine(params.hash, perm_idx)); } void PipelineCache::DumpShader(std::span code, u64 hash, Shader::Stage stage, diff --git a/src/video_core/renderer_vulkan/vk_pipeline_cache.h b/src/video_core/renderer_vulkan/vk_pipeline_cache.h index 662bcbd80..e4a8abd4f 100644 --- a/src/video_core/renderer_vulkan/vk_pipeline_cache.h +++ b/src/video_core/renderer_vulkan/vk_pipeline_cache.h @@ -47,8 +47,10 @@ public: const ComputePipeline* GetComputePipeline(); - std::tuple GetProgram( - Shader::Stage stage, Shader::ShaderParams params, Shader::Backend::Bindings& binding); + std::tuple, + u64> + GetProgram(Shader::Stage stage, Shader::ShaderParams params, + Shader::Backend::Bindings& binding); private: bool RefreshGraphicsKey(); @@ -80,6 +82,7 @@ private: tsl::robin_map graphics_pipelines; std::array infos{}; std::array modules{}; + std::optional fetch_shader{}; GraphicsPipelineKey graphics_key{}; u64 compute_key{}; }; diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp index ff5e88141..084b7c345 100644 --- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp +++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp @@ -187,13 +187,14 @@ void Rasterizer::Draw(bool is_indexed, u32 index_offset) { } const auto& vs_info = pipeline->GetStage(Shader::Stage::Vertex); - buffer_cache.BindVertexBuffers(vs_info); + const auto& fetch_shader = pipeline->GetFetchShader(); + buffer_cache.BindVertexBuffers(vs_info, fetch_shader); const u32 num_indices = buffer_cache.BindIndexBuffer(is_indexed, index_offset); BeginRendering(*pipeline, state); UpdateDynamicState(*pipeline); - const auto [vertex_offset, instance_offset] = vs_info.GetDrawOffsets(regs); + const auto [vertex_offset, instance_offset] = fetch_shader->GetDrawOffsets(regs, vs_info); const auto cmdbuf = scheduler.CommandBuffer(); cmdbuf.bindPipeline(vk::PipelineBindPoint::eGraphics, pipeline->Handle()); @@ -243,7 +244,8 @@ void Rasterizer::DrawIndirect(bool is_indexed, VAddr arg_address, u32 offset, u3 } const auto& vs_info = pipeline->GetStage(Shader::Stage::Vertex); - buffer_cache.BindVertexBuffers(vs_info); + const auto& fetch_shader = pipeline->GetFetchShader(); + buffer_cache.BindVertexBuffers(vs_info, fetch_shader); buffer_cache.BindIndexBuffer(is_indexed, 0); const auto& [buffer, base] = @@ -397,10 +399,8 @@ bool Rasterizer::BindResources(const Pipeline* pipeline) { if (!stage) { continue; } - if (stage->uses_step_rates) { - push_data.step0 = regs.vgt_instance_step_rate_0; - push_data.step1 = regs.vgt_instance_step_rate_1; - } + push_data.step0 = regs.vgt_instance_step_rate_0; + push_data.step1 = regs.vgt_instance_step_rate_1; stage->PushUd(binding, push_data); BindBuffers(*stage, binding, push_data, set_writes, buffer_barriers); diff --git a/src/video_core/texture_cache/image_view.cpp b/src/video_core/texture_cache/image_view.cpp index 488d44a7f..61cabdf11 100644 --- a/src/video_core/texture_cache/image_view.cpp +++ b/src/video_core/texture_cache/image_view.cpp @@ -87,12 +87,9 @@ ImageViewInfo::ImageViewInfo(const AmdGpu::Image& image, const Shader::ImageReso range.extent.levels = image.last_level - image.base_level + 1; } range.extent.layers = image.last_array - image.base_array + 1; - type = ConvertImageViewType(image.GetType()); + type = ConvertImageViewType(image.GetBoundType()); - // Adjust view type for partial cubemaps and arrays - if (image.IsPartialCubemap()) { - type = vk::ImageViewType::e2DArray; - } + // Adjust view type for arrays if (type == vk::ImageViewType::eCube) { if (desc.is_array) { type = vk::ImageViewType::eCubeArray; From c019b54fecff141bade82ef6efbbd1fdbc7d231a Mon Sep 17 00:00:00 2001 From: squidbus <175574877+squidbus@users.noreply.github.com> Date: Wed, 4 Dec 2024 10:21:03 -0800 Subject: [PATCH 32/32] thread: Configure stack and guard on POSIX hosts. (#1664) --- src/core/libraries/kernel/threads/pthread.cpp | 2 +- src/core/thread.cpp | 4 +++- src/core/thread.h | 6 +++++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/core/libraries/kernel/threads/pthread.cpp b/src/core/libraries/kernel/threads/pthread.cpp index 4629980c9..793ddd1fe 100644 --- a/src/core/libraries/kernel/threads/pthread.cpp +++ b/src/core/libraries/kernel/threads/pthread.cpp @@ -281,7 +281,7 @@ int PS4_SYSV_ABI posix_pthread_create_name_np(PthreadT* thread, const PthreadAtt /* Create thread */ new_thread->native_thr = Core::Thread(); - int ret = new_thread->native_thr.Create(RunThread, new_thread); + int ret = new_thread->native_thr.Create(RunThread, new_thread, &new_thread->attr); ASSERT_MSG(ret == 0, "Failed to create thread with error {}", ret); if (ret) { *thread = nullptr; diff --git a/src/core/thread.cpp b/src/core/thread.cpp index e9c46b522..a93f16c8d 100644 --- a/src/core/thread.cpp +++ b/src/core/thread.cpp @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project // SPDX-License-Identifier: GPL-2.0-or-later +#include "libraries/kernel/threads/pthread.h" #include "thread.h" #ifdef _WIN64 @@ -15,7 +16,7 @@ Thread::Thread() : native_handle{0} {} Thread::~Thread() {} -int Thread::Create(ThreadFunc func, void* arg) { +int Thread::Create(ThreadFunc func, void* arg, const ::Libraries::Kernel::PthreadAttr* attr) { #ifdef _WIN64 native_handle = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)func, arg, 0, nullptr); return native_handle ? 0 : -1; @@ -23,6 +24,7 @@ int Thread::Create(ThreadFunc func, void* arg) { pthread_t* pthr = reinterpret_cast(&native_handle); pthread_attr_t pattr; pthread_attr_init(&pattr); + pthread_attr_setstack(&pattr, attr->stackaddr_attr, attr->stacksize_attr); return pthread_create(pthr, &pattr, (PthreadFunc)func, arg); #endif } diff --git a/src/core/thread.h b/src/core/thread.h index 8665100af..cfb8b8309 100644 --- a/src/core/thread.h +++ b/src/core/thread.h @@ -5,6 +5,10 @@ #include "common/types.h" +namespace Libraries::Kernel { +struct PthreadAttr; +} // namespace Libraries::Kernel + namespace Core { class Thread { @@ -15,7 +19,7 @@ public: Thread(); ~Thread(); - int Create(ThreadFunc func, void* arg); + int Create(ThreadFunc func, void* arg, const ::Libraries::Kernel::PthreadAttr* attr); void Exit(); uintptr_t GetHandle() {