From 04933ac863d4777fdbe21810e9cf5e050381aa37 Mon Sep 17 00:00:00 2001 From: psucien Date: Sat, 28 Dec 2024 11:44:11 +0100 Subject: [PATCH 01/15] hot-fix: handle ASC ring wrap --- src/core/libraries/gnmdriver/gnmdriver.cpp | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/core/libraries/gnmdriver/gnmdriver.cpp b/src/core/libraries/gnmdriver/gnmdriver.cpp index 566f8ce1f..91a1329e5 100644 --- a/src/core/libraries/gnmdriver/gnmdriver.cpp +++ b/src/core/libraries/gnmdriver/gnmdriver.cpp @@ -513,10 +513,14 @@ void PS4_SYSV_ABI sceGnmDingDong(u32 gnm_vqid, u32 next_offs_dw) { auto vqid = gnm_vqid - 1; auto& asc_queue = liverpool->asc_queues[{vqid}]; - const auto& offs_dw = asc_next_offs_dw[vqid]; + auto& offs_dw = asc_next_offs_dw[vqid]; - if (next_offs_dw < offs_dw) { - ASSERT_MSG(next_offs_dw == 0, "ACB submission is split at the end of ring buffer"); + if (next_offs_dw < offs_dw && next_offs_dw != 0) { + // For cases if a submission is split at the end of the ring buffer, we need to submit it in + // two parts to handle the wrap + liverpool->SubmitAsc(gnm_vqid, {reinterpret_cast(asc_queue.map_addr) + offs_dw, + asc_queue.ring_size_dw - offs_dw}); + offs_dw = 0; } const auto* acb_ptr = reinterpret_cast(asc_queue.map_addr) + offs_dw; From 9aabe98e4eb548b12ddbaeb6d60c81e14caf7dae Mon Sep 17 00:00:00 2001 From: DemoJameson Date: Sat, 28 Dec 2024 18:49:44 +0800 Subject: [PATCH 02/15] Fix a translation not working (#1947) --- src/qt_gui/gui_context_menus.h | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/qt_gui/gui_context_menus.h b/src/qt_gui/gui_context_menus.h index 6c96ab37f..bbc84c4fc 100644 --- a/src/qt_gui/gui_context_menus.h +++ b/src/qt_gui/gui_context_menus.h @@ -347,9 +347,8 @@ public: if (selected == deleteUpdate) { if (!std::filesystem::exists(Common::FS::PathFromQString(game_update_path))) { - QMessageBox::critical( - nullptr, tr("Error"), - QString(tr("This game has no separate update to delete!"))); + QMessageBox::critical(nullptr, tr("Error"), + QString(tr("This game has no update to delete!"))); error = true; } else { folder_path = game_update_path; From 55f78a0b94b508cc51ae23bd49079b680ac1a574 Mon Sep 17 00:00:00 2001 From: mailwl Date: Sat, 28 Dec 2024 13:58:37 +0300 Subject: [PATCH 03/15] libraries: Add libSceMove HLE skeleton (#1945) * libraries: Add libSceMove HLE skeleton * Fix clang-format issue --- CMakeLists.txt | 2 ++ src/common/logging/filter.cpp | 1 + src/common/logging/types.h | 3 ++- src/core/libraries/libs.cpp | 2 ++ src/core/libraries/move/move.cpp | 44 ++++++++++++++++++++++++++++++++ src/core/libraries/move/move.h | 21 +++++++++++++++ 6 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 src/core/libraries/move/move.cpp create mode 100644 src/core/libraries/move/move.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 43e8d7cab..cd3894719 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -425,6 +425,8 @@ set(NP_LIBS src/core/libraries/np_manager/np_manager.cpp set(MISC_LIBS src/core/libraries/screenshot/screenshot.cpp src/core/libraries/screenshot/screenshot.h + src/core/libraries/move/move.cpp + src/core/libraries/move/move.h ) set(DEV_TOOLS src/core/devtools/layer.cpp diff --git a/src/common/logging/filter.cpp b/src/common/logging/filter.cpp index 75c61a188..a2fd2c0a4 100644 --- a/src/common/logging/filter.cpp +++ b/src/common/logging/filter.cpp @@ -97,6 +97,7 @@ bool ParseFilterRule(Filter& instance, Iterator begin, Iterator end) { SUB(Lib, Http) \ SUB(Lib, Ssl) \ SUB(Lib, SysModule) \ + SUB(Lib, Move) \ SUB(Lib, NpManager) \ SUB(Lib, NpScore) \ SUB(Lib, NpTrophy) \ diff --git a/src/common/logging/types.h b/src/common/logging/types.h index a0e7d021f..5b496d175 100644 --- a/src/common/logging/types.h +++ b/src/common/logging/types.h @@ -57,8 +57,9 @@ enum class Class : u8 { Lib_MsgDlg, ///< The LibSceMsgDialog implementation. Lib_AudioOut, ///< The LibSceAudioOut implementation. Lib_AudioIn, ///< The LibSceAudioIn implementation. + Lib_Move, ///< The LibSceMove implementation. Lib_Net, ///< The LibSceNet implementation. - Lib_NetCtl, ///< The LibSecNetCtl implementation. + Lib_NetCtl, ///< The LibSceNetCtl implementation. Lib_SaveData, ///< The LibSceSaveData implementation. Lib_SaveDataDialog, ///< The LibSceSaveDataDialog implementation. Lib_Ssl, ///< The LibSceSsl implementation. diff --git a/src/core/libraries/libs.cpp b/src/core/libraries/libs.cpp index 66cdd5b87..c30c2d7c3 100644 --- a/src/core/libraries/libs.cpp +++ b/src/core/libraries/libs.cpp @@ -18,6 +18,7 @@ #include "core/libraries/libc_internal/libc_internal.h" #include "core/libraries/libpng/pngdec.h" #include "core/libraries/libs.h" +#include "core/libraries/move/move.h" #include "core/libraries/network/http.h" #include "core/libraries/network/net.h" #include "core/libraries/network/netctl.h" @@ -91,6 +92,7 @@ void InitHLELibs(Core::Loader::SymbolsResolver* sym) { Libraries::Remoteplay::RegisterlibSceRemoteplay(sym); Libraries::Videodec::RegisterlibSceVideodec(sym); Libraries::RazorCpu::RegisterlibSceRazorCpu(sym); + Libraries::Move::RegisterlibSceMove(sym); } } // namespace Libraries diff --git a/src/core/libraries/move/move.cpp b/src/core/libraries/move/move.cpp new file mode 100644 index 000000000..626fed9b4 --- /dev/null +++ b/src/core/libraries/move/move.cpp @@ -0,0 +1,44 @@ +// SPDX-FileCopyrightText: Copyright 2024 shadPS4 Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include "common/logging/log.h" +#include "core/libraries/error_codes.h" +#include "core/libraries/libs.h" +#include "move.h" + +namespace Libraries::Move { + +int PS4_SYSV_ABI sceMoveOpen() { + LOG_ERROR(Lib_Move, "(STUBBED) called"); + return ORBIS_FAIL; +} + +int PS4_SYSV_ABI sceMoveGetDeviceInfo() { + LOG_ERROR(Lib_Move, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceMoveReadStateRecent() { + LOG_TRACE(Lib_Move, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceMoveTerm() { + LOG_ERROR(Lib_Move, "(STUBBED) called"); + return ORBIS_OK; +} + +int PS4_SYSV_ABI sceMoveInit() { + LOG_ERROR(Lib_Move, "(STUBBED) called"); + return ORBIS_OK; +} + +void RegisterlibSceMove(Core::Loader::SymbolsResolver* sym) { + LIB_FUNCTION("HzC60MfjJxU", "libSceMove", 1, "libSceMove", 1, 1, sceMoveOpen); + LIB_FUNCTION("GWXTyxs4QbE", "libSceMove", 1, "libSceMove", 1, 1, sceMoveGetDeviceInfo); + LIB_FUNCTION("f2bcpK6kJfg", "libSceMove", 1, "libSceMove", 1, 1, sceMoveReadStateRecent); + LIB_FUNCTION("tsZi60H4ypY", "libSceMove", 1, "libSceMove", 1, 1, sceMoveTerm); + LIB_FUNCTION("j1ITE-EoJmE", "libSceMove", 1, "libSceMove", 1, 1, sceMoveInit); +}; + +} // namespace Libraries::Move \ No newline at end of file diff --git a/src/core/libraries/move/move.h b/src/core/libraries/move/move.h new file mode 100644 index 000000000..2d7adaba7 --- /dev/null +++ b/src/core/libraries/move/move.h @@ -0,0 +1,21 @@ +// 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::Move { + +int PS4_SYSV_ABI sceMoveOpen(); +int PS4_SYSV_ABI sceMoveGetDeviceInfo(); +int PS4_SYSV_ABI sceMoveReadStateRecent(); +int PS4_SYSV_ABI sceMoveTerm(); +int PS4_SYSV_ABI sceMoveInit(); + +void RegisterlibSceMove(Core::Loader::SymbolsResolver* sym); +} // namespace Libraries::Move \ No newline at end of file From 817a62468e9ecf041ba106cab5b1943127057fff Mon Sep 17 00:00:00 2001 From: polybiusproxy <47796739+polybiusproxy@users.noreply.github.com> Date: Sat, 28 Dec 2024 12:03:00 +0100 Subject: [PATCH 04/15] core: better memory configuration (#1896) --- src/core/address_space.cpp | 2 +- src/core/libraries/kernel/memory.h | 12 +++---- src/core/libraries/np_trophy/np_trophy.cpp | 7 ++-- src/core/linker.cpp | 41 ++++++++++++++++------ src/core/linker.h | 3 +- src/core/memory.cpp | 20 ++++++----- src/core/memory.h | 2 +- 7 files changed, 55 insertions(+), 32 deletions(-) diff --git a/src/core/address_space.cpp b/src/core/address_space.cpp index 24f5e9f87..2b7331cbd 100644 --- a/src/core/address_space.cpp +++ b/src/core/address_space.cpp @@ -26,7 +26,7 @@ asm(".zerofill GUEST_SYSTEM,GUEST_SYSTEM,__guest_system,0xFBFC00000"); namespace Core { -static constexpr size_t BackingSize = SCE_KERNEL_MAIN_DMEM_SIZE_PRO; +static constexpr size_t BackingSize = SCE_KERNEL_TOTAL_MEM_PRO; #ifdef _WIN32 diff --git a/src/core/libraries/kernel/memory.h b/src/core/libraries/kernel/memory.h index 2d19ceb49..400b6c3fc 100644 --- a/src/core/libraries/kernel/memory.h +++ b/src/core/libraries/kernel/memory.h @@ -6,9 +6,11 @@ #include "common/bit_field.h" #include "common/types.h" -constexpr u64 SCE_KERNEL_MAIN_DMEM_SIZE = 5056_MB; // ~ 5GB -// TODO: Confirm this value on hardware. -constexpr u64 SCE_KERNEL_MAIN_DMEM_SIZE_PRO = 5568_MB; // ~ 5.5GB +constexpr u64 SCE_KERNEL_TOTAL_MEM = 5248_MB; +constexpr u64 SCE_KERNEL_TOTAL_MEM_PRO = 5888_MB; + +constexpr u64 SCE_FLEXIBLE_MEMORY_BASE = 64_MB; +constexpr u64 SCE_FLEXIBLE_MEMORY_SIZE = 512_MB; namespace Core::Loader { class SymbolsResolver; @@ -129,10 +131,6 @@ s32 PS4_SYSV_ABI sceKernelMemoryPoolDecommit(void* addr, size_t len, int flags); int PS4_SYSV_ABI sceKernelMunmap(void* addr, size_t len); -void* Malloc(size_t size); - -void Free(void* ptr); - void RegisterMemory(Core::Loader::SymbolsResolver* sym); } // namespace Libraries::Kernel diff --git a/src/core/libraries/np_trophy/np_trophy.cpp b/src/core/libraries/np_trophy/np_trophy.cpp index 9324ed6bb..ccd8ab710 100644 --- a/src/core/libraries/np_trophy/np_trophy.cpp +++ b/src/core/libraries/np_trophy/np_trophy.cpp @@ -498,7 +498,7 @@ int PS4_SYSV_ABI sceNpTrophyGetTrophyInfo(OrbisNpTrophyContext context, OrbisNpT s32 PS4_SYSV_ABI sceNpTrophyGetTrophyUnlockState(OrbisNpTrophyContext context, OrbisNpTrophyHandle handle, OrbisNpTrophyFlagArray* flags, u32* count) { - LOG_INFO(Lib_NpTrophy, "GetTrophyUnlockState called"); + LOG_INFO(Lib_NpTrophy, "called"); if (context == ORBIS_NP_TROPHY_INVALID_CONTEXT) return ORBIS_NP_TROPHY_ERROR_INVALID_CONTEXT; @@ -519,8 +519,9 @@ s32 PS4_SYSV_ABI sceNpTrophyGetTrophyUnlockState(OrbisNpTrophyContext context, pugi::xml_parse_result result = doc.load_file(trophy_file.native().c_str()); if (!result) { - LOG_ERROR(Lib_NpTrophy, "Failed to open trophy xml : {}", result.description()); - return -1; + LOG_ERROR(Lib_NpTrophy, "Failed to open trophy XML: {}", result.description()); + *count = 0; + return ORBIS_OK; } int num_trophies = 0; diff --git a/src/core/linker.cpp b/src/core/linker.cpp index 9cf4198ae..28d2eea7b 100644 --- a/src/core/linker.cpp +++ b/src/core/linker.cpp @@ -5,6 +5,7 @@ #include "common/arch.h" #include "common/assert.h" #include "common/config.h" +#include "common/elf_info.h" #include "common/logging/log.h" #include "common/path_util.h" #include "common/string_util.h" @@ -65,21 +66,41 @@ void Linker::Execute() { Relocate(m.get()); } - // Configure used flexible memory size. - if (const auto* proc_param = GetProcParam()) { - if (proc_param->size >= - offsetof(OrbisProcParam, mem_param) + sizeof(OrbisKernelMemParam*)) { - if (const auto* mem_param = proc_param->mem_param) { - if (mem_param->size >= - offsetof(OrbisKernelMemParam, flexible_memory_size) + sizeof(u64*)) { - if (const auto* flexible_size = mem_param->flexible_memory_size) { - memory->SetupMemoryRegions(*flexible_size); - } + // Configure the direct and flexible memory regions. + u64 fmem_size = SCE_FLEXIBLE_MEMORY_SIZE; + bool use_extended_mem1 = true, use_extended_mem2 = true; + + const auto* proc_param = GetProcParam(); + ASSERT(proc_param); + + Core::OrbisKernelMemParam mem_param{}; + if (proc_param->size >= offsetof(OrbisProcParam, mem_param) + sizeof(OrbisKernelMemParam*)) { + if (proc_param->mem_param) { + mem_param = *proc_param->mem_param; + if (mem_param.size >= + offsetof(OrbisKernelMemParam, flexible_memory_size) + sizeof(u64*)) { + if (const auto* flexible_size = mem_param.flexible_memory_size) { + fmem_size = *flexible_size + SCE_FLEXIBLE_MEMORY_BASE; } } } } + if (mem_param.size < offsetof(OrbisKernelMemParam, extended_memory_1) + sizeof(u64*)) { + mem_param.extended_memory_1 = nullptr; + } + if (mem_param.size < offsetof(OrbisKernelMemParam, extended_memory_2) + sizeof(u64*)) { + mem_param.extended_memory_2 = nullptr; + } + + const u64 sdk_ver = proc_param->sdk_version; + if (sdk_ver < Common::ElfInfo::FW_50) { + use_extended_mem1 = mem_param.extended_memory_1 ? *mem_param.extended_memory_1 : false; + use_extended_mem2 = mem_param.extended_memory_2 ? *mem_param.extended_memory_2 : false; + } + + memory->SetupMemoryRegions(fmem_size, use_extended_mem1, use_extended_mem2); + main_thread.Run([this, module](std::stop_token) { Common::SetCurrentThreadName("GAME_MainThread"); LoadSharedLibraries(); diff --git a/src/core/linker.h b/src/core/linker.h index d6b5d648a..7ef13ae56 100644 --- a/src/core/linker.h +++ b/src/core/linker.h @@ -22,8 +22,9 @@ struct OrbisKernelMemParam { u8* extended_memory_1; u64* extended_gpu_page_table; u8* extended_memory_2; - u64* exnteded_cpu_page_table; + u64* extended_cpu_page_table; }; +static_assert(sizeof(OrbisKernelMemParam) == 0x38); struct OrbisProcParam { u64 size; diff --git a/src/core/memory.cpp b/src/core/memory.cpp index aa116fa3d..0a69ad773 100644 --- a/src/core/memory.cpp +++ b/src/core/memory.cpp @@ -12,12 +12,7 @@ namespace Core { -constexpr u64 SCE_DEFAULT_FLEXIBLE_MEMORY_SIZE = 448_MB; - MemoryManager::MemoryManager() { - // Set up the direct and flexible memory regions. - SetupMemoryRegions(SCE_DEFAULT_FLEXIBLE_MEMORY_SIZE); - // Insert a virtual memory area that covers the entire area we manage. const VAddr system_managed_base = impl.SystemManagedVirtualBase(); const size_t system_managed_size = impl.SystemManagedVirtualSize(); @@ -38,10 +33,17 @@ MemoryManager::MemoryManager() { MemoryManager::~MemoryManager() = default; -void MemoryManager::SetupMemoryRegions(u64 flexible_size) { - const auto total_size = - Config::isNeoMode() ? SCE_KERNEL_MAIN_DMEM_SIZE_PRO : SCE_KERNEL_MAIN_DMEM_SIZE; - total_flexible_size = flexible_size; +void MemoryManager::SetupMemoryRegions(u64 flexible_size, bool use_extended_mem1, + bool use_extended_mem2) { + const bool is_neo = Config::isNeoMode(); + auto total_size = is_neo ? SCE_KERNEL_TOTAL_MEM_PRO : SCE_KERNEL_TOTAL_MEM; + if (!use_extended_mem1 && is_neo) { + total_size -= 256_MB; + } + if (!use_extended_mem2 && !is_neo) { + total_size -= 128_MB; + } + total_flexible_size = flexible_size - SCE_FLEXIBLE_MEMORY_BASE; total_direct_size = total_size - flexible_size; // Insert an area that covers direct memory physical block. diff --git a/src/core/memory.h b/src/core/memory.h index a9f2df322..615ecc3eb 100644 --- a/src/core/memory.h +++ b/src/core/memory.h @@ -166,7 +166,7 @@ public: bool TryWriteBacking(void* address, const void* data, u32 num_bytes); - void SetupMemoryRegions(u64 flexible_size); + void SetupMemoryRegions(u64 flexible_size, bool use_extended_mem1, bool use_extended_mem2); PAddr PoolExpand(PAddr search_start, PAddr search_end, size_t size, u64 alignment); From fc2fd9fd3cd4ce584235590772d15904e0c1b9a4 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Sat, 28 Dec 2024 13:05:53 +0200 Subject: [PATCH 05/15] Update README.md with latest (not quite) addition to dev team --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 7ba13ad47..e68fb86f7 100644 --- a/README.md +++ b/README.md @@ -121,6 +121,10 @@ R3 | M | | - [**skmp**](https://github.com/skmp) - [**wheremyfoodat**](https://github.com/wheremyfoodat) - [**raziel1000**](https://github.com/raziel1000) +- [**viniciuslrangel**](https://github.com/viniciuslrangel) +- [**Roamic**](https://github.com/vladmikhalin) +- [**Poly**](https://github.com/polybiusproxy) +- [**squidbus**](https://github.com/squidbus) Logo is done by [**Xphalnos**](https://github.com/Xphalnos) From c8b704e4a364ce64d2f50cda2c7a240fec2f9aa1 Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Sat, 28 Dec 2024 13:06:51 +0200 Subject: [PATCH 06/15] Update README.md --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e68fb86f7..4fad47c3d 100644 --- a/README.md +++ b/README.md @@ -122,8 +122,8 @@ R3 | M | | - [**wheremyfoodat**](https://github.com/wheremyfoodat) - [**raziel1000**](https://github.com/raziel1000) - [**viniciuslrangel**](https://github.com/viniciuslrangel) -- [**Roamic**](https://github.com/vladmikhalin) -- [**Poly**](https://github.com/polybiusproxy) +- [**roamic**](https://github.com/vladmikhalin) +- [**poly**](https://github.com/polybiusproxy) - [**squidbus**](https://github.com/squidbus) Logo is done by [**Xphalnos**](https://github.com/Xphalnos) From f0352d2f7db0d64fec53fcb7214de9438285c6cb Mon Sep 17 00:00:00 2001 From: georgemoralis Date: Sat, 28 Dec 2024 13:16:25 +0200 Subject: [PATCH 07/15] Updated dev team (sorry frodo , the ring is yours) --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 4fad47c3d..fd40d2d63 100644 --- a/README.md +++ b/README.md @@ -125,6 +125,7 @@ R3 | M | | - [**roamic**](https://github.com/vladmikhalin) - [**poly**](https://github.com/polybiusproxy) - [**squidbus**](https://github.com/squidbus) +- [**frodo**](https://github.com/baggins183) Logo is done by [**Xphalnos**](https://github.com/Xphalnos) From 99e1e028c056de16966913d64efac7e7975df40f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Quang=20Ng=C3=B4?= Date: Sat, 28 Dec 2024 18:18:56 +0700 Subject: [PATCH 08/15] texture_cache: Don't read max ansio value if not aniso filter (#1942) Fix Sonic Forces. --- src/video_core/amdgpu/resource.h | 2 +- src/video_core/texture_cache/sampler.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/video_core/amdgpu/resource.h b/src/video_core/amdgpu/resource.h index 58b286e9c..6bbe1fb7e 100644 --- a/src/video_core/amdgpu/resource.h +++ b/src/video_core/amdgpu/resource.h @@ -447,7 +447,7 @@ struct Sampler { } float MaxAniso() const { - switch (max_aniso) { + switch (max_aniso.Value()) { case AnisoRatio::One: return 1.0f; case AnisoRatio::Two: diff --git a/src/video_core/texture_cache/sampler.cpp b/src/video_core/texture_cache/sampler.cpp index 5ce10ff0e..8dbdd2912 100644 --- a/src/video_core/texture_cache/sampler.cpp +++ b/src/video_core/texture_cache/sampler.cpp @@ -18,7 +18,8 @@ Sampler::Sampler(const Vulkan::Instance& instance, const AmdGpu::Sampler& sample (AmdGpu::IsAnisoFilter(sampler.xy_mag_filter) || AmdGpu::IsAnisoFilter(sampler.xy_min_filter)); const float maxAnisotropy = - std::clamp(sampler.MaxAniso(), 1.0f, instance.MaxSamplerAnisotropy()); + anisotropyEnable ? std::clamp(sampler.MaxAniso(), 1.0f, instance.MaxSamplerAnisotropy()) + : 1.0f; const vk::SamplerCreateInfo sampler_ci = { .magFilter = LiverpoolToVK::Filter(sampler.xy_mag_filter), .minFilter = LiverpoolToVK::Filter(sampler.xy_min_filter), From 668d5f65dcb1442ff14a5498a242231f36637b69 Mon Sep 17 00:00:00 2001 From: DemoJameson Date: Sat, 28 Dec 2024 19:19:16 +0800 Subject: [PATCH 09/15] Update zh_CN translation (#1946) --- src/qt_gui/translations/zh_CN.ts | 232 +++++++++++++++---------------- 1 file changed, 116 insertions(+), 116 deletions(-) diff --git a/src/qt_gui/translations/zh_CN.ts b/src/qt_gui/translations/zh_CN.ts index 4ceb91315..32b838fac 100644 --- a/src/qt_gui/translations/zh_CN.ts +++ b/src/qt_gui/translations/zh_CN.ts @@ -2,7 +2,7 @@ + SPDX-License-Identifier: GPL-2.0-or-later --> AboutDialog @@ -18,7 +18,7 @@ shadPS4 is an experimental open-source emulator for the PlayStation 4. - shadPS4 是一款实验性质的开源 PlayStation 4模拟器软件。 + shadPS4 是一款实验性质的开源 PlayStation 4 模拟器软件。 @@ -103,7 +103,7 @@ Cheats / Patches - 作弊码 / 补丁 + 作弊码/补丁 @@ -113,7 +113,7 @@ Trophy Viewer - Trophy 查看器 + 奖杯查看器 @@ -128,7 +128,7 @@ Open Save Data Folder - 打开保存数据文件夹 + 打开存档数据文件夹 @@ -173,27 +173,27 @@ Delete DLC - 删除DLC + 删除 DLC Compatibility... - Compatibility... + 兼容性... Update database - Update database + 更新数据库 View report - View report + 查看报告 Submit a report - Submit a report + 提交报告 @@ -203,7 +203,7 @@ Shortcut created successfully! - 创建快捷方式成功! + 创建快捷方式成功! @@ -213,7 +213,7 @@ Error creating shortcut! - 创建快捷方式出错! + 创建快捷方式出错! @@ -228,7 +228,7 @@ requiresEnableSeparateUpdateFolder_MSG - 这个功能需要‘启用单独的更新目录’配置选项才能正常运行,如果你想要使用这个功能,请启用它。 + 这个功能需要“启用单独的更新目录”配置选项才能正常运行,如果你想要使用这个功能,请启用它。 @@ -243,7 +243,7 @@ This game has no DLC to delete! - 这个游戏没有DLC可以删除! + 这个游戏没有 DLC 可以删除! @@ -258,7 +258,7 @@ Are you sure you want to delete %1's %2 directory? - 你确定要删除 %1 的 %2 目录? + 你确定要删除 %1 的%2目录? @@ -266,7 +266,7 @@ Open/Add Elf Folder - 打开/添加Elf文件夹 + 打开/添加 Elf 文件夹 @@ -316,7 +316,7 @@ Exit the application. - 退出应用程序. + 退出应用程序。 @@ -341,12 +341,12 @@ Medium - 中等 + Large - 巨大 + @@ -376,7 +376,7 @@ Dump Game List - 转储游戏列表 + 导出游戏列表 @@ -472,7 +472,7 @@ Trophy Viewer - Trophy 查看器 + 奖杯查看器 @@ -485,7 +485,7 @@ General - 通用 + 常规 @@ -520,12 +520,12 @@ Show Splash - 显示Splash + 显示启动画面 Is PS4 Pro - 是否是 PS4 Pro + 模拟 PS4 Pro @@ -570,17 +570,17 @@ Hide Cursor Idle Timeout - 光标空闲超时隐藏 + 光标隐藏闲置时长 s - s + Controller - 控制器 + 手柄 @@ -595,7 +595,7 @@ Graphics Device - 图像设备 + 图形设备 @@ -700,7 +700,7 @@ Disable Trophy Pop-ups - Disable Trophy Pop-ups + 禁止弹出奖杯 @@ -710,22 +710,22 @@ Update Compatibility Database On Startup - Update Compatibility Database On Startup + 启动时更新兼容性数据库 Game Compatibility - Game Compatibility + 游戏兼容性 Display Compatibility Data - Display Compatibility Data + 显示兼容性数据 Update Compatibility Database - Update Compatibility Database + 更新兼容性数据库 @@ -735,7 +735,7 @@ Audio Backend - Audio Backend + 音频后端 @@ -778,12 +778,12 @@ All Patches available for all games have been downloaded. - 所有游戏的所有补丁都已下载。 + 所有游戏的可用补丁都已下载。 Games: - 游戏: + 游戏: @@ -798,7 +798,7 @@ Game Boot - 游戏启动 + 启动游戏 @@ -818,7 +818,7 @@ PKG and Game versions match: - PKG 和游戏版本匹配: + PKG 和游戏版本匹配: @@ -828,17 +828,17 @@ PKG Version %1 is older than installed version: - PKG 版本 %1 比已安装版本更旧: + PKG 版本 %1 比已安装版本更旧: Game is installed: - 游戏已安装: + 游戏已安装: Would you like to install Patch: - 您想安装补丁吗: + 您想安装补丁吗: @@ -848,12 +848,12 @@ Would you like to install DLC: %1? - 您想安装 DLC: %1 吗? + 您想安装 DLC:%1 吗? DLC already installed: - DLC 已经安装: + DLC 已经安装: @@ -896,42 +896,42 @@ Cheats / Patches for - Cheats / Patches for + 作弊码/补丁: defaultTextEdit_MSG - 作弊/补丁是实验性的。\n请小心使用。\n\n通过选择存储库并点击下载按钮,单独下载作弊程序。\n在“补丁”选项卡中,您可以一次性下载所有补丁,选择要使用的补丁并保存选择。\n\n由于我们不开发作弊程序/补丁,\n请将问题报告给作弊程序的作者。\n\n创建了新的作弊程序?访问:\nhttps://github.com/shadps4-emu/ps4_cheats + 作弊码/补丁是实验性的。\n请小心使用。\n\n通过选择存储库并点击下载按钮,下载该游戏的作弊码。\n在“补丁”选项卡中,您可以一次性下载所有补丁,选择要使用的补丁并保存选择。\n\n由于我们不开发作弊码/补丁,\n请将问题报告给作弊码/补丁的作者。\n\n创建了新的作弊码/补丁?欢迎提交到我们的仓库:\nhttps://github.com/shadps4-emu/ps4_cheats No Image Available - 没有可用的图像 + 没有可用的图片 Serial: - 序列号: + 序列号: Version: - 版本: + 版本: Size: - 大小: + 大小: Select Cheat File: - 选择作弊码文件: + 选择作弊码文件: Repository: - 存储库: + 存储库: @@ -961,7 +961,7 @@ Select Patch File: - 选择补丁文件: + 选择补丁文件: @@ -1016,7 +1016,7 @@ Failed to parse XML: - 解析 XML 失败: + 解析 XML 失败: @@ -1046,17 +1046,17 @@ File already exists. Do you want to replace it? - 文件已存在。您要替换它吗? + 文件已存在,您要替换它吗? Failed to save file: - 保存文件失败: + 保存文件失败: Failed to download file: - 下载文件失败: + 下载文件失败: @@ -1076,17 +1076,17 @@ CheatsDownloadedSuccessfully_MSG - 您已成功下载了该游戏版本的作弊码 从所选存储库中。如果有,您还可以尝试从其他存储库下载,或通过从列表中选择文件来使用它们。 + 您已从所选存储库中成功下载了该游戏版本的作弊码。您还可以尝试从其他存储库下载,或通过从列表中选择文件来使用它们。 Failed to save: - 保存失败: + 保存失败: Failed to download: - 下载失败: + 下载失败: @@ -1096,7 +1096,7 @@ DownloadComplete_MSG - 补丁下载成功!所有可用的补丁已下载完成,无需像作弊码那样单独下载每个游戏的补丁。如果补丁没有出现,可能是该补丁不存在于特定的序列号和游戏版本中。 + 补丁下载成功!所有可用的补丁已下载完成,无需像作弊码那样单独下载每个游戏的补丁。如果补丁没有出现,可能是该补丁不适用于当前游戏的序列号和版本。 @@ -1111,12 +1111,12 @@ The game is in version: %1 - 游戏版本: %1 + 游戏版本:%1 The downloaded patch only works on version: %1 - 下载的补丁仅适用于版本: %1 + 下载的补丁仅适用于版本:%1 @@ -1131,12 +1131,12 @@ Failed to open file: - 无法打开文件: + 无法打开文件: XML ERROR: - XML 错误: + XML 错误: @@ -1146,12 +1146,12 @@ Author: - 作者: + 作者: Directory does not exist: - 目录不存在: + 目录不存在: @@ -1161,12 +1161,12 @@ Name: - 名称: + 名称: Can't apply cheats before the game is started - 在游戏开始之前无法应用作弊。 + 在游戏启动之前无法应用作弊码。 @@ -1199,17 +1199,17 @@ consoleLanguageGroupBox - 控制台语言:\n设置 PS4 游戏中使用的语言。\n建议设置为支持的语言,因为可能因地区而异。 + 主机语言:\n设置 PS4 游戏中使用的语言。\n建议设置为支持的语言,这将因地区而异。 emulatorLanguageGroupBox - 模拟器语言:\n设置模拟器用户界面的语言。 + 模拟器语言:\n设置模拟器用户界面的语言。 fullscreenCheckBox - 启用全屏模式:\n自动将游戏窗口设置为全屏模式。\n您可以按 F11 键禁用此选项。 + 启用全屏:\n以全屏模式启动游戏。\n您可以按 F11 键切换回窗口模式。 @@ -1219,77 +1219,77 @@ showSplashCheckBox - 显示启动画面:\n在游戏启动时显示游戏的启动画面(特殊图像)。 + 显示启动画面:\n在游戏启动时显示游戏的启动画面(特殊图像)。 ps4proCheckBox - 这是 PS4 Pro:\n使模拟器作为 PS4 PRO 运行,可以在支持的游戏中激活特殊功能。 + 模拟 PS4 Pro:\n使模拟器作为 PS4 Pro 运行,可以在支持的游戏中激活特殊功能。 discordRPCCheckbox - 启用 Discord Rich Presence:\n在您的 Discord 个人资料上显示仿真器图标和相关信息。 + 启用 Discord Rich Presence:\n在您的 Discord 个人资料上显示模拟器图标和相关信息。 userName - 用户名:\n设置 PS4 帐户的用户名。某些游戏中可能会显示此名称。 + 用户名:\n设置 PS4 帐户的用户名,某些游戏中可能会显示此名称。 logTypeGroupBox - 日志类型:\n设置是否同步日志窗口的输出以提高性能。这可能会对模拟产生负面影响。 + 日志类型:\n设置日志窗口输出的同步方式以提高性能。可能会对模拟产生不良影响。 logFilter - 日志过滤器:\n过滤日志,仅打印特定信息。\n例如:"Core:Trace" "Lib.Pad:Debug Common.Filesystem:Error" "*:Critical" 级别: Trace, Debug, Info, Warning, Error, Critical - 按此顺序,特定级别将静默列表中所有先前的级别,并记录所有后续级别。 + 日志过滤器:\n过滤日志,仅打印特定信息。\n例如:"Core:Trace" "Lib.Pad:Debug Common.Filesystem:Error" "*:Critical" 级别: Trace, Debug, Info, Warning, Error, Critical - 按此顺序,特定级别将静默列表中所有先前的级别,并记录所有后续级别。 updaterGroupBox - 更新:\nRelease: 官方版本,可能非常旧,并且每月发布,但更可靠且经过测试。\nNightly: 开发版本,包含所有最新功能和修复,但可能包含错误且不够稳定。 + 更新:\nRelease:每月发布的官方版本可能非常过时,但更可靠且经过测试。\nNightly:包含所有最新功能和修复的开发版本,但可能包含错误且稳定性较低。 GUIgroupBox - 播放标题音乐:\n如果游戏支持,在图形界面选择游戏时启用播放特殊音乐。 + 播放标题音乐:\n如果游戏支持,在图形界面选择游戏时播放特殊音乐。 disableTrophycheckBox - Disable Trophy Pop-ups:\nDisable in-game trophy notifications. Trophy progress can still be tracked using the Trophy Viewer (right-click the game in the main window). + 禁止弹出奖杯:\n禁用游戏内奖杯通知。可以在奖杯查看器中继续跟踪奖杯进度(在主窗口中右键点击游戏)。 hideCursorGroupBox - 隐藏光标:\n选择光标何时消失:\n从不: 您将始终看到鼠标。\n空闲: 设置光标在空闲后消失的时间。\n始终: 您将永远看不到鼠标。 + 隐藏光标:\n选择光标何时消失:\n从不: 始终显示光标。\闲置: 光标在闲置若干秒后消失。\n始终: 始终显示光标。 idleTimeoutGroupBox - 设置鼠标在空闲后消失的时间。 + 光标隐藏闲置时长:\n光标自动隐藏之前的闲置时长。 backButtonBehaviorGroupBox - 返回按钮行为:\n设置控制器的返回按钮以模拟在 PS4 触控板上指定位置的点击。 + 返回按钮行为:\n设置手柄的返回按钮模拟在 PS4 触控板上指定位置的点击。 enableCompatibilityCheckBox - Display Compatibility Data:\nDisplays game compatibility information in table view. Enable "Update Compatibility On Startup" to get up-to-date information. + 显示兼容性数据:\n在列表视图中显示游戏兼容性信息。启用“启动时更新兼容性数据库”以获取最新信息。 checkCompatibilityOnStartupCheckBox - Update Compatibility On Startup:\nAutomatically update the compatibility database when shadPS4 starts. + 启动时更新兼容性数据库:\n当 shadPS4 启动时自动更新兼容性数据库。 updateCompatibilityButton - Update Compatibility Database:\nImmediately update the compatibility database. + 更新兼容性数据库:\n立即更新兼容性数据库。 @@ -1299,7 +1299,7 @@ Idle - 空闲 + 闲置 @@ -1329,62 +1329,62 @@ graphicsAdapterGroupBox - 图形设备:\n在具有多个 GPU 的系统中,从下拉列表中选择要使用的 GPU,\n或者选择“自动检测”以自动确定。 + 图形设备:\n在具有多个 GPU 的系统中,从下拉列表中选择要使用的 GPU,\n或者选择“自动选择”由模拟器决定。 resolutionLayout - 宽度/高度:\n设置启动时模拟器的窗口大小,该大小可以在游戏中更改。\n这与游戏中的分辨率不同。 + 宽度/高度:\n设置启动游戏时的窗口大小,游戏过程中可以调整。\n这与游戏内的分辨率不同。 heightDivider - Vblank 除数:\n模拟器更新的帧速率乘以此数字。改变此项可能会导致游戏速度加快,或破坏游戏中不期望此变化的关键功能! + Vblank Divider:\n模拟器刷新的帧率会乘以此数字。改变此项可能会导致游戏速度加快,或破坏游戏中不期望此变化的关键功能! dumpShadersCheckBox - 启用着色器转储:\n为了技术调试,在渲染期间将游戏着色器保存到文件夹中。 + 启用着色器转储:\n用于技术调试,在渲染期间将游戏着色器保存到文件夹中。 nullGpuCheckBox - 启用空 GPU:\n为了技术调试,将游戏渲染禁用,仿佛没有图形卡。 + 启用 NULL GPU:\n用于技术调试,禁用游戏渲染,就像没有显卡一样。 gameFoldersBox - 游戏文件夹:\n检查已安装游戏的文件夹列表。 + 游戏文件夹:\n检查已安装游戏的文件夹列表。 addFolderButton - 添加:\n将文件夹添加到列表。 + 添加:\n将文件夹添加到列表。 removeFolderButton - 移除:\n从列表中移除文件夹。 + 移除:\n从列表中移除文件夹。 debugDump - 启用调试转储:\n将当前正在运行的 PS4 程序的导入和导出符号及文件头信息保存到目录中。 + 启用调试转储:\n将当前正在运行的 PS4 程序的导入和导出符号及文件头信息保存到目录中。 vkValidationCheckBox - 启用 Vulkan 验证层:\n启用验证 Vulkan 渲染器状态并记录内部状态信息的系统。这可能会降低性能,并可能更改模拟行为。 + 启用 Vulkan 验证层:\n启用一个系统来验证 Vulkan 渲染器的状态并记录其内部状态的信息。\n这将降低性能并可能改变模拟的行为。 vkSyncValidationCheckBox - 启用 Vulkan 同步验证:\n启用验证 Vulkan 渲染任务时间的系统。这可能会降低性能,并可能更改模拟行为。 + 启用 Vulkan 同步验证:\n启用一个系统来验证 Vulkan 渲染任务的时间。\n这将降低性能并可能改变模拟的行为。 rdocCheckBox - 启用 RenderDoc 调试:\n如果启用,模拟器将提供与 Renderdoc 的兼容性,允许在渲染过程中捕获和分析当前渲染的帧。 + 启用 RenderDoc 调试:\n启用后模拟器将提供与 Renderdoc 的兼容性,允许在渲染过程中捕获和分析当前渲染的帧。 @@ -1407,7 +1407,7 @@ Compatibility - Compatibility + 兼容性 @@ -1442,52 +1442,52 @@ Never Played - Never Played + 未玩过 h - h + 小时 m - m + 分钟 s - s + Compatibility is untested - Compatibility is untested + 兼容性未经测试 Game does not initialize properly / crashes the emulator - Game does not initialize properly / crashes the emulator + 游戏无法正确初始化/模拟器崩溃 Game boots, but only displays a blank screen - Game boots, but only displays a blank screen + 游戏启动,但只显示白屏 Game displays an image but does not go past the menu - Game displays an image but does not go past the menu + 游戏显示图像但无法通过菜单页面 Game has game-breaking glitches or unplayable performance - Game has game-breaking glitches or unplayable performance + 游戏有严重的 Bug 或太卡无法游玩 Game can be completed with playable performance and no major glitches - Game can be completed with playable performance and no major glitches + 游戏能在可玩的性能下完成且没有重大 Bug @@ -1525,7 +1525,7 @@ No download URL found for the specified asset. - 未找到指定资产的下载 URL。 + 未找到指定资源的下载地址。 @@ -1560,7 +1560,7 @@ Show Changelog - 显示变更日志 + 显示更新日志 @@ -1580,17 +1580,17 @@ Hide Changelog - 隐藏变更日志 + 隐藏更新日志 Changes - 变更 + 更新日志 Network error occurred while trying to access the URL - 尝试访问 URL 时发生网络错误 + 尝试访问网址时发生网络错误 @@ -1646,4 +1646,4 @@ TB - \ No newline at end of file + From 63d2d1ebe8467a58410e9eb82ff2ed5bafee0a4c Mon Sep 17 00:00:00 2001 From: jas0n098 Date: Sat, 28 Dec 2024 11:19:41 +0000 Subject: [PATCH 10/15] Handle RectList primitives in Geometry shaders (#1936) --- src/shader_recompiler/backend/spirv/emit_spirv.cpp | 1 + src/shader_recompiler/backend/spirv/spirv_emit_context.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/src/shader_recompiler/backend/spirv/emit_spirv.cpp b/src/shader_recompiler/backend/spirv/emit_spirv.cpp index 900d40472..f0cf15af0 100644 --- a/src/shader_recompiler/backend/spirv/emit_spirv.cpp +++ b/src/shader_recompiler/backend/spirv/emit_spirv.cpp @@ -28,6 +28,7 @@ static constexpr spv::ExecutionMode GetInputPrimitiveType(AmdGpu::PrimitiveType return spv::ExecutionMode::InputLines; case AmdGpu::PrimitiveType::TriangleList: case AmdGpu::PrimitiveType::TriangleStrip: + case AmdGpu::PrimitiveType::RectList: return spv::ExecutionMode::Triangles; case AmdGpu::PrimitiveType::AdjTriangleList: return spv::ExecutionMode::InputTrianglesAdjacency; diff --git a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp index 281c487af..575bf91f7 100644 --- a/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp +++ b/src/shader_recompiler/backend/spirv/spirv_emit_context.cpp @@ -47,6 +47,7 @@ static constexpr u32 NumVertices(AmdGpu::PrimitiveType type) { return 2u; case AmdGpu::PrimitiveType::TriangleList: case AmdGpu::PrimitiveType::TriangleStrip: + case AmdGpu::PrimitiveType::RectList: return 3u; case AmdGpu::PrimitiveType::AdjTriangleList: return 6u; From 8447d6ea1c6295b9e499f135a61cdb163a9c4b03 Mon Sep 17 00:00:00 2001 From: rainmakerv2 <30595646+rainmakerv3@users.noreply.github.com> Date: Sat, 28 Dec 2024 21:30:26 +0800 Subject: [PATCH 11/15] Remove PS4 pro mode from GUI, can still be edited in from config file (#1871) --- src/qt_gui/settings_dialog.cpp | 8 +------- src/qt_gui/settings_dialog.ui | 7 ------- 2 files changed, 1 insertion(+), 14 deletions(-) diff --git a/src/qt_gui/settings_dialog.cpp b/src/qt_gui/settings_dialog.cpp index df802901a..6d4de6603 100644 --- a/src/qt_gui/settings_dialog.cpp +++ b/src/qt_gui/settings_dialog.cpp @@ -199,7 +199,6 @@ SettingsDialog::SettingsDialog(std::span physical_devices, ui->fullscreenCheckBox->installEventFilter(this); ui->separateUpdatesCheckBox->installEventFilter(this); ui->showSplashCheckBox->installEventFilter(this); - ui->ps4proCheckBox->installEventFilter(this); ui->discordRPCCheckbox->installEventFilter(this); ui->userName->installEventFilter(this); ui->logTypeGroupBox->installEventFilter(this); @@ -291,7 +290,6 @@ void SettingsDialog::LoadValuesFromConfig() { ui->separateUpdatesCheckBox->setChecked( toml::find_or(data, "General", "separateUpdateEnabled", false)); ui->showSplashCheckBox->setChecked(toml::find_or(data, "General", "showSplash", false)); - ui->ps4proCheckBox->setChecked(toml::find_or(data, "General", "isPS4Pro", false)); ui->logTypeComboBox->setCurrentText( QString::fromStdString(toml::find_or(data, "General", "logType", "async"))); ui->logFilterLineEdit->setText( @@ -408,8 +406,6 @@ void SettingsDialog::updateNoteTextEdit(const QString& elementName) { text = tr("separateUpdatesCheckBox"); } else if (elementName == "showSplashCheckBox") { text = tr("showSplashCheckBox"); - } else if (elementName == "ps4proCheckBox") { - text = tr("ps4proCheckBox"); } else if (elementName == "discordRPCCheckbox") { text = tr("discordRPCCheckbox"); } else if (elementName == "userName") { @@ -520,11 +516,9 @@ void SettingsDialog::UpdateSettings() { const QVector TouchPadIndex = {"left", "center", "right", "none"}; Config::setBackButtonBehavior(TouchPadIndex[ui->backButtonBehaviorComboBox->currentIndex()]); - Config::setNeoMode(ui->ps4proCheckBox->isChecked()); Config::setFullscreenMode(ui->fullscreenCheckBox->isChecked()); Config::setisTrophyPopupDisabled(ui->disableTrophycheckBox->isChecked()); Config::setPlayBGM(ui->playBGMCheckBox->isChecked()); - Config::setNeoMode(ui->ps4proCheckBox->isChecked()); Config::setLogType(ui->logTypeComboBox->currentText().toStdString()); Config::setLogFilter(ui->logFilterLineEdit->text().toStdString()); Config::setUserName(ui->userNameLineEdit->text().toStdString()); @@ -590,4 +584,4 @@ void SettingsDialog::ResetInstallFolders() { } Config::setGameInstallDirs(settings_install_dirs_config); } -} +} \ No newline at end of file diff --git a/src/qt_gui/settings_dialog.ui b/src/qt_gui/settings_dialog.ui index c18b70497..f2d6b77d2 100644 --- a/src/qt_gui/settings_dialog.ui +++ b/src/qt_gui/settings_dialog.ui @@ -228,13 +228,6 @@ - - - - Is PS4 Pro - - - From a8b4e14bf526b4983eab8cc544263ee3d28412f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Quang=20Ng=C3=B4?= Date: Sat, 28 Dec 2024 21:35:12 +0700 Subject: [PATCH 12/15] Fix SDL version cannot launch game using game ID (#1650) * Fix SDL version cannot launch game using game ID Missing from https://github.com/shadps4-emu/shadPS4/pull/1507. * Added --add-game-folder argument Also added "treat the last argument as the game, if it isn't found already" option to the qt version --------- Co-authored-by: kalaposfos13 <153381648+kalaposfos13@users.noreply.github.com> --- src/main.cpp | 58 +++++++++++++++++++++++++++++++++++++++++---- src/qt_gui/main.cpp | 35 +++++++++++++++++++++++---- 2 files changed, 83 insertions(+), 10 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 17b5c11fe..bdbab89c9 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,11 +4,14 @@ #include "functional" #include "iostream" #include "string" +#include "system_error" #include "unordered_map" #include #include "common/config.h" #include "common/memory_patcher.h" +#include "common/path_util.h" +#include "core/file_sys/fs.h" #include "emulator.h" #ifdef _WIN32 @@ -20,6 +23,10 @@ int main(int argc, char* argv[]) { SetConsoleOutputCP(CP_UTF8); #endif + // Load configurations + const auto user_dir = Common::FS::GetUserPath(Common::FS::PathType::UserDir); + Config::load(user_dir / "config.toml"); + bool has_game_argument = false; std::string game_path; @@ -33,6 +40,7 @@ int main(int argc, char* argv[]) { " -p, --patch Apply specified patch file\n" " -f, --fullscreen Specify window initial fullscreen " "state. Does not overwrite the config file.\n" + " --add-game-folder Adds a new game folder to the config.\n" " -h, --help Display this help message\n"; exit(0); }}, @@ -81,6 +89,25 @@ int main(int argc, char* argv[]) { Config::setFullscreenMode(is_fullscreen); }}, {"--fullscreen", [&](int& i) { arg_map["-f"](i); }}, + {"--add-game-folder", + [&](int& i) { + if (++i >= argc) { + std::cerr << "Error: Missing argument for --add-game-folder\n"; + exit(1); + } + std::string config_dir(argv[i]); + std::filesystem::path config_path = std::filesystem::path(config_dir); + std::error_code discard; + if (!std::filesystem::exists(config_path, discard)) { + std::cerr << "Error: File does not exist: " << config_path << "\n"; + exit(1); + } + + Config::addGameInstallDir(config_path); + Config::save(Common::FS::GetUserPath(Common::FS::PathType::UserDir) / "config.toml"); + std::cout << "Game folder successfully saved.\n"; + exit(0); + }}, }; if (argc == 1) { @@ -105,20 +132,41 @@ int main(int argc, char* argv[]) { } } + // If no game directory is set and no command line argument, prompt for it + if (Config::getGameInstallDirs().empty()) { + std::cout << "Warning: No game folder set, please set it by calling shadps4" + " with the --add-game-folder argument"; + } + if (!has_game_argument) { std::cerr << "Error: Please provide a game path or ID.\n"; exit(1); } // Check if the game path or ID exists - if (!std::filesystem::exists(game_path)) { - std::cerr << "Error: Game file not found\n"; - return -1; + std::filesystem::path eboot_path(game_path); + + // Check if the provided path is a valid file + if (!std::filesystem::exists(eboot_path)) { + // If not a file, treat it as a game ID and search in install directories + bool game_found = false; + for (const auto& install_dir : Config::getGameInstallDirs()) { + const auto candidate_path = install_dir / game_path / "eboot.bin"; + if (std::filesystem::exists(candidate_path)) { + eboot_path = candidate_path; + game_found = true; + break; + } + } + if (!game_found) { + std::cerr << "Error: Game ID or file path not found: " << game_path << std::endl; + return 1; + } } - // Run the emulator with the specified game + // Run the emulator with the resolved eboot path Core::Emulator emulator; - emulator.Run(game_path); + emulator.Run(eboot_path); return 0; } diff --git a/src/qt_gui/main.cpp b/src/qt_gui/main.cpp index 318245053..ac731fdce 100644 --- a/src/qt_gui/main.cpp +++ b/src/qt_gui/main.cpp @@ -2,6 +2,7 @@ // SPDX-License-Identifier: GPL-2.0-or-later #include "iostream" +#include "system_error" #include "unordered_map" #include "common/config.h" @@ -31,7 +32,7 @@ int main(int argc, char* argv[]) { bool has_command_line_argument = argc > 1; bool show_gui = false, has_game_argument = false; - std::string gamePath; + std::string game_path; // Map of argument strings to lambda functions std::unordered_map> arg_map = { @@ -46,6 +47,7 @@ int main(int argc, char* argv[]) { " -s, --show-gui Show the GUI\n" " -f, --fullscreen Specify window initial fullscreen " "state. Does not overwrite the config file.\n" + " --add-game-folder Adds a new game folder to the config.\n" " -h, --help Display this help message\n"; exit(0); }}, @@ -57,7 +59,7 @@ int main(int argc, char* argv[]) { {"-g", [&](int& i) { if (i + 1 < argc) { - gamePath = argv[++i]; + game_path = argv[++i]; has_game_argument = true; } else { std::cerr << "Error: Missing argument for -g/--game\n"; @@ -98,6 +100,25 @@ int main(int argc, char* argv[]) { Config::setFullscreenMode(is_fullscreen); }}, {"--fullscreen", [&](int& i) { arg_map["-f"](i); }}, + {"--add-game-folder", + [&](int& i) { + if (++i >= argc) { + std::cerr << "Error: Missing argument for --add-game-folder\n"; + exit(1); + } + std::string config_dir(argv[i]); + std::filesystem::path config_path = std::filesystem::path(config_dir); + std::error_code discard; + if (!std::filesystem::is_directory(config_path, discard)) { + std::cerr << "Error: Directory does not exist: " << config_path << "\n"; + exit(1); + } + + Config::addGameInstallDir(config_path); + Config::save(Common::FS::GetUserPath(Common::FS::PathType::UserDir) / "config.toml"); + std::cout << "Game folder successfully saved.\n"; + exit(0); + }}, }; // Parse command-line arguments using the map @@ -106,6 +127,10 @@ int main(int argc, char* argv[]) { auto it = arg_map.find(cur_arg); if (it != arg_map.end()) { it->second(i); // Call the associated lambda function + } else if (i == argc - 1 && !has_game_argument) { + // Assume the last argument is the game file if not specified via -g/--game + game_path = argv[i]; + has_game_argument = true; } else { std::cerr << "Unknown argument: " << cur_arg << ", see --help for info.\n"; return 1; @@ -134,14 +159,14 @@ int main(int argc, char* argv[]) { // Process game path or ID if provided if (has_game_argument) { - std::filesystem::path game_file_path(gamePath); + std::filesystem::path game_file_path(game_path); // Check if the provided path is a valid file if (!std::filesystem::exists(game_file_path)) { // If not a file, treat it as a game ID and search in install directories bool game_found = false; for (const auto& install_dir : Config::getGameInstallDirs()) { - auto potential_game_path = install_dir / gamePath / "eboot.bin"; + auto potential_game_path = install_dir / game_path / "eboot.bin"; if (std::filesystem::exists(potential_game_path)) { game_file_path = potential_game_path; game_found = true; @@ -149,7 +174,7 @@ int main(int argc, char* argv[]) { } } if (!game_found) { - std::cerr << "Error: Game ID or file path not found: " << gamePath << std::endl; + std::cerr << "Error: Game ID or file path not found: " << game_path << std::endl; return 1; } } From e8b0fdd6cce138e83043843ad3289cf73684dcd2 Mon Sep 17 00:00:00 2001 From: tomboylover93 <95257311+tomboylover93@users.noreply.github.com> Date: Sat, 28 Dec 2024 12:09:33 -0300 Subject: [PATCH 13/15] style: add Tokyo Night theme (#1811) * style: add Tokyo Night theme * clang-format: Update main_window_themes.h --- src/qt_gui/main_window.cpp | 14 ++++++++++++++ src/qt_gui/main_window_themes.cpp | 22 ++++++++++++++++++++++ src/qt_gui/main_window_themes.h | 2 +- src/qt_gui/main_window_ui.h | 6 ++++++ 4 files changed, 43 insertions(+), 1 deletion(-) diff --git a/src/qt_gui/main_window.cpp b/src/qt_gui/main_window.cpp index 724e008ae..bd3c27809 100644 --- a/src/qt_gui/main_window.cpp +++ b/src/qt_gui/main_window.cpp @@ -112,6 +112,7 @@ void MainWindow::CreateActions() { m_theme_act_group->addAction(ui->setThemeBlue); m_theme_act_group->addAction(ui->setThemeViolet); m_theme_act_group->addAction(ui->setThemeGruvbox); + m_theme_act_group->addAction(ui->setThemeTokyoNight); } void MainWindow::AddUiWidgets() { @@ -559,6 +560,14 @@ void MainWindow::CreateConnects() { isIconBlack = false; } }); + connect(ui->setThemeTokyoNight, &QAction::triggered, &m_window_themes, [this]() { + m_window_themes.SetWindowTheme(Theme::TokyoNight, ui->mw_searchbar); + Config::setMainWindowTheme(static_cast(Theme::TokyoNight)); + if (isIconBlack) { + SetUiIcons(false); + isIconBlack = false; + } + }); } void MainWindow::StartGame() { @@ -934,6 +943,11 @@ void MainWindow::SetLastUsedTheme() { isIconBlack = false; SetUiIcons(false); break; + case Theme::TokyoNight: + ui->setThemeTokyoNight->setChecked(true); + isIconBlack = false; + SetUiIcons(false); + break; } } diff --git a/src/qt_gui/main_window_themes.cpp b/src/qt_gui/main_window_themes.cpp index a52b4466e..5fffd4c9e 100644 --- a/src/qt_gui/main_window_themes.cpp +++ b/src/qt_gui/main_window_themes.cpp @@ -143,5 +143,27 @@ void WindowThemes::SetWindowTheme(Theme theme, QLineEdit* mw_searchbar) { themePalette.setColor(QPalette::HighlightedText, Qt::black); qApp->setPalette(themePalette); break; + case Theme::TokyoNight: + mw_searchbar->setStyleSheet( + "QLineEdit {" + "background-color: #1a1b26; color: #9d7cd8; border: 1px solid #9d7cd8; " + "border-radius: 4px; padding: 5px; }" + "QLineEdit:focus {" + "border: 1px solid #7aa2f7; }"); + themePalette.setColor(QPalette::Window, QColor(31, 35, 53)); + themePalette.setColor(QPalette::WindowText, QColor(192, 202, 245)); + themePalette.setColor(QPalette::Base, QColor(25, 28, 39)); + themePalette.setColor(QPalette::AlternateBase, QColor(36, 40, 59)); + themePalette.setColor(QPalette::ToolTipBase, QColor(192, 202, 245)); + themePalette.setColor(QPalette::ToolTipText, QColor(192, 202, 245)); + themePalette.setColor(QPalette::Text, QColor(192, 202, 245)); + themePalette.setColor(QPalette::Button, QColor(30, 30, 41)); + themePalette.setColor(QPalette::ButtonText, QColor(192, 202, 245)); + themePalette.setColor(QPalette::BrightText, QColor(197, 59, 83)); + themePalette.setColor(QPalette::Link, QColor(79, 214, 190)); + themePalette.setColor(QPalette::Highlight, QColor(79, 214, 190)); + themePalette.setColor(QPalette::HighlightedText, Qt::black); + qApp->setPalette(themePalette); + break; } } \ No newline at end of file diff --git a/src/qt_gui/main_window_themes.h b/src/qt_gui/main_window_themes.h index d162da87b..0ec2cce58 100644 --- a/src/qt_gui/main_window_themes.h +++ b/src/qt_gui/main_window_themes.h @@ -7,7 +7,7 @@ #include #include -enum class Theme : int { Dark, Light, Green, Blue, Violet, Gruvbox }; +enum class Theme : int { Dark, Light, Green, Blue, Violet, Gruvbox, TokyoNight }; class WindowThemes : public QObject { Q_OBJECT diff --git a/src/qt_gui/main_window_ui.h b/src/qt_gui/main_window_ui.h index df64361fd..0d5038d7e 100644 --- a/src/qt_gui/main_window_ui.h +++ b/src/qt_gui/main_window_ui.h @@ -37,6 +37,7 @@ public: QAction* setThemeBlue; QAction* setThemeViolet; QAction* setThemeGruvbox; + QAction* setThemeTokyoNight; QWidget* centralWidget; QLineEdit* mw_searchbar; QPushButton* playButton; @@ -162,6 +163,9 @@ public: setThemeGruvbox = new QAction(MainWindow); setThemeGruvbox->setObjectName("setThemeGruvbox"); setThemeGruvbox->setCheckable(true); + setThemeTokyoNight = new QAction(MainWindow); + setThemeTokyoNight->setObjectName("setThemeTokyoNight"); + setThemeTokyoNight->setCheckable(true); centralWidget = new QWidget(MainWindow); centralWidget->setObjectName("centralWidget"); sizePolicy.setHeightForWidth(centralWidget->sizePolicy().hasHeightForWidth()); @@ -287,6 +291,7 @@ public: menuThemes->addAction(setThemeBlue); menuThemes->addAction(setThemeViolet); menuThemes->addAction(setThemeGruvbox); + menuThemes->addAction(setThemeTokyoNight); menuGame_List_Icons->addAction(setIconSizeTinyAct); menuGame_List_Icons->addAction(setIconSizeSmallAct); menuGame_List_Icons->addAction(setIconSizeMediumAct); @@ -374,6 +379,7 @@ public: setThemeBlue->setText(QCoreApplication::translate("MainWindow", "Blue", nullptr)); setThemeViolet->setText(QCoreApplication::translate("MainWindow", "Violet", nullptr)); setThemeGruvbox->setText("Gruvbox"); + setThemeTokyoNight->setText("Tokyo Night"); toolBar->setWindowTitle(QCoreApplication::translate("MainWindow", "toolBar", nullptr)); } // retranslateUi }; From 851995d4440b65f34b81995c638ce73b4ee92489 Mon Sep 17 00:00:00 2001 From: polybiusproxy <47796739+polybiusproxy@users.noreply.github.com> Date: Sat, 28 Dec 2024 17:33:40 +0100 Subject: [PATCH 14/15] libraries/fiber: implement context switching (#1950) --- src/core/libraries/fiber/fiber.cpp | 98 +++++++++++++++++++++++++++--- src/core/libraries/fiber/fiber.h | 2 + 2 files changed, 91 insertions(+), 9 deletions(-) diff --git a/src/core/libraries/fiber/fiber.cpp b/src/core/libraries/fiber/fiber.cpp index 7bb81b61e..6d3f546f2 100644 --- a/src/core/libraries/fiber/fiber.cpp +++ b/src/core/libraries/fiber/fiber.cpp @@ -41,6 +41,39 @@ void PS4_SYSV_ABI _sceFiberCheckStackOverflow(OrbisFiberContext* ctx) { } } +s32 PS4_SYSV_ABI _sceFiberAttachContext(OrbisFiber* fiber, void* addr_context, u64 size_context) { + if (size_context && size_context < ORBIS_FIBER_CONTEXT_MINIMUM_SIZE) { + return ORBIS_FIBER_ERROR_RANGE; + } + if (size_context & 15) { + return ORBIS_FIBER_ERROR_INVALID; + } + if (!addr_context || !size_context) { + return ORBIS_FIBER_ERROR_INVALID; + } + if (fiber->addr_context) { + return ORBIS_FIBER_ERROR_INVALID; + } + + fiber->addr_context = addr_context; + fiber->size_context = size_context; + fiber->context_start = addr_context; + fiber->context_end = reinterpret_cast(addr_context) + size_context; + + /* Apply signature to start of stack */ + *(u64*)addr_context = kFiberStackSignature; + + if (fiber->flags & FiberFlags::ContextSizeCheck) { + u64* stack_start = reinterpret_cast(fiber->context_start); + u64* stack_end = reinterpret_cast(fiber->context_end); + + u64* stack_ptr = stack_start + 1; + while (stack_ptr < stack_end) { + *stack_ptr++ = kFiberStackSizeCheck; + } + } +} + void PS4_SYSV_ABI _sceFiberSwitchToFiber(OrbisFiber* fiber, u64 arg_on_run_to, OrbisFiberContext* ctx) { OrbisFiberContext* fiber_ctx = fiber->context; @@ -62,8 +95,7 @@ void PS4_SYSV_ABI _sceFiberSwitchToFiber(OrbisFiber* fiber, u64 arg_on_run_to, data.entry = fiber->entry; data.arg_on_initialize = fiber->arg_on_initialize; data.arg_on_run_to = arg_on_run_to; - data.stack_addr = - reinterpret_cast(reinterpret_cast(fiber->addr_context) + fiber->size_context); + data.stack_addr = reinterpret_cast(fiber->addr_context) + fiber->size_context; if (fiber->flags & FiberFlags::SetFpuRegs) { data.fpucw = 0x037f; data.mxcsr = 0x9fc0; @@ -169,8 +201,7 @@ s32 PS4_SYSV_ABI sceFiberInitialize(OrbisFiber* fiber, const char* name, OrbisFi if (addr_context != nullptr) { fiber->context_start = addr_context; - fiber->context_end = - reinterpret_cast(reinterpret_cast(addr_context) + size_context); + fiber->context_end = reinterpret_cast(addr_context) + size_context; /* Apply signature to start of stack */ *(u64*)addr_context = kFiberStackSignature; @@ -221,11 +252,12 @@ s32 PS4_SYSV_ABI sceFiberFinalize(OrbisFiber* fiber) { return ORBIS_OK; } -s32 PS4_SYSV_ABI sceFiberRun(OrbisFiber* fiber, u64 arg_on_run_to, u64* arg_on_return) { +s32 PS4_SYSV_ABI sceFiberRunImpl(OrbisFiber* fiber, void* addr_context, u64 size_context, + u64 arg_on_run_to, u64* arg_on_return) { if (!fiber) { return ORBIS_FIBER_ERROR_NULL; } - if ((u64)fiber & 7) { + if ((u64)fiber & 7 || (u64)addr_context & 15) { return ORBIS_FIBER_ERROR_ALIGNMENT; } if (fiber->magic_start != kFiberSignature0 || fiber->magic_end != kFiberSignature1) { @@ -237,6 +269,14 @@ s32 PS4_SYSV_ABI sceFiberRun(OrbisFiber* fiber, u64 arg_on_run_to, u64* arg_on_r return ORBIS_FIBER_ERROR_PERMISSION; } + /* Caller wants to attach context and run. */ + if (addr_context != nullptr || size_context != 0) { + s32 res = _sceFiberAttachContext(fiber, addr_context, size_context); + if (res < 0) { + return res; + } + } + FiberState expected = FiberState::Idle; if (!fiber->state.compare_exchange_strong(expected, FiberState::Run)) { return ORBIS_FIBER_ERROR_STATE; @@ -288,11 +328,12 @@ s32 PS4_SYSV_ABI sceFiberRun(OrbisFiber* fiber, u64 arg_on_run_to, u64* arg_on_r return ORBIS_OK; } -s32 PS4_SYSV_ABI sceFiberSwitch(OrbisFiber* fiber, u64 arg_on_run_to, u64* arg_on_run) { +s32 PS4_SYSV_ABI sceFiberSwitchImpl(OrbisFiber* fiber, void* addr_context, u64 size_context, + u64 arg_on_run_to, u64* arg_on_run) { if (!fiber) { return ORBIS_FIBER_ERROR_NULL; } - if ((u64)fiber & 7) { + if ((u64)fiber & 7 || (u64)addr_context & 15) { return ORBIS_FIBER_ERROR_ALIGNMENT; } if (fiber->magic_start != kFiberSignature0 || fiber->magic_end != kFiberSignature1) { @@ -304,6 +345,14 @@ s32 PS4_SYSV_ABI sceFiberSwitch(OrbisFiber* fiber, u64 arg_on_run_to, u64* arg_o return ORBIS_FIBER_ERROR_PERMISSION; } + /* Caller wants to attach context and switch. */ + if (addr_context != nullptr || size_context != 0) { + s32 res = _sceFiberAttachContext(fiber, addr_context, size_context); + if (res < 0) { + return res; + } + } + FiberState expected = FiberState::Idle; if (!fiber->state.compare_exchange_strong(expected, FiberState::Run)) { return ORBIS_FIBER_ERROR_STATE; @@ -462,9 +511,32 @@ s32 PS4_SYSV_ABI sceFiberRename(OrbisFiber* fiber, const char* name) { return ORBIS_OK; } +s32 PS4_SYSV_ABI sceFiberGetThreadFramePointerAddress(u64* addr_frame_pointer) { + if (!addr_frame_pointer) { + return ORBIS_FIBER_ERROR_NULL; + } + + OrbisFiberContext* g_ctx = GetFiberContext(); + if (!g_ctx) { + return ORBIS_FIBER_ERROR_PERMISSION; + } + + *addr_frame_pointer = g_ctx->rbp; + return ORBIS_OK; +} + +s32 PS4_SYSV_ABI sceFiberRun(OrbisFiber* fiber, u64 arg_on_run_to, u64* arg_on_return) { + return sceFiberRunImpl(fiber, nullptr, 0, arg_on_run_to, arg_on_return); +} + +s32 PS4_SYSV_ABI sceFiberSwitch(OrbisFiber* fiber, u64 arg_on_run_to, u64* arg_on_run) { + return sceFiberSwitchImpl(fiber, nullptr, 0, arg_on_run_to, arg_on_run); +} + void RegisterlibSceFiber(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("hVYD7Ou2pCQ", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberInitialize); - LIB_FUNCTION("7+OJIpko9RY", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberInitialize); + LIB_FUNCTION("7+OJIpko9RY", "libSceFiber", 1, "libSceFiber", 1, 1, + sceFiberInitialize); // _sceFiberInitializeWithInternalOptionImpl LIB_FUNCTION("asjUJJ+aa8s", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberOptParamInitialize); LIB_FUNCTION("JeNX5F-NzQU", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberFinalize); @@ -473,12 +545,20 @@ void RegisterlibSceFiber(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("p+zLIOg27zU", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberGetSelf); LIB_FUNCTION("B0ZX2hx9DMw", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberReturnToThread); + LIB_FUNCTION("avfGJ94g36Q", "libSceFiber", 1, "libSceFiber", 1, 1, + sceFiberRunImpl); // _sceFiberAttachContextAndRun + LIB_FUNCTION("ZqhZFuzKT6U", "libSceFiber", 1, "libSceFiber", 1, 1, + sceFiberSwitchImpl); // _sceFiberAttachContextAndSwitch + LIB_FUNCTION("uq2Y5BFz0PE", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberGetInfo); LIB_FUNCTION("Lcqty+QNWFc", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberStartContextSizeCheck); LIB_FUNCTION("Kj4nXMpnM8Y", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberStopContextSizeCheck); LIB_FUNCTION("JzyT91ucGDc", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberRename); + + LIB_FUNCTION("0dy4JtMUcMQ", "libSceFiber", 1, "libSceFiber", 1, 1, + sceFiberGetThreadFramePointerAddress); } } // namespace Libraries::Fiber diff --git a/src/core/libraries/fiber/fiber.h b/src/core/libraries/fiber/fiber.h index 3c4e3b70e..edcd9afe8 100644 --- a/src/core/libraries/fiber/fiber.h +++ b/src/core/libraries/fiber/fiber.h @@ -114,5 +114,7 @@ s32 PS4_SYSV_ABI sceFiberStopContextSizeCheck(void); s32 PS4_SYSV_ABI sceFiberRename(OrbisFiber* fiber, const char* name); +s32 PS4_SYSV_ABI sceFiberGetThreadFramePointerAddress(u64* addr_frame_pointer); + void RegisterlibSceFiber(Core::Loader::SymbolsResolver* sym); } // namespace Libraries::Fiber \ No newline at end of file From ee974414d28b4da47fda57024987057c928e2872 Mon Sep 17 00:00:00 2001 From: polyproxy <47796739+polybiusproxy@users.noreply.github.com> Date: Sat, 28 Dec 2024 17:43:29 +0100 Subject: [PATCH 15/15] hotfix: fix fiber initialization --- src/common/elf_info.h | 1 + src/core/libraries/fiber/fiber.cpp | 29 ++++++++++++++++++++--------- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/src/common/elf_info.h b/src/common/elf_info.h index 5a2c914e0..6eb144e9a 100644 --- a/src/common/elf_info.h +++ b/src/common/elf_info.h @@ -34,6 +34,7 @@ public: static constexpr u32 FW_20 = 0x2000000; static constexpr u32 FW_25 = 0x2500000; static constexpr u32 FW_30 = 0x3000000; + static constexpr u32 FW_35 = 0x3500000; static constexpr u32 FW_40 = 0x4000000; static constexpr u32 FW_45 = 0x4500000; static constexpr u32 FW_50 = 0x5000000; diff --git a/src/core/libraries/fiber/fiber.cpp b/src/core/libraries/fiber/fiber.cpp index 6d3f546f2..b77b5b5b6 100644 --- a/src/core/libraries/fiber/fiber.cpp +++ b/src/core/libraries/fiber/fiber.cpp @@ -3,6 +3,7 @@ #include "fiber.h" +#include "common/elf_info.h" #include "common/logging/log.h" #include "core/libraries/fiber/fiber_error.h" #include "core/libraries/libs.h" @@ -72,6 +73,8 @@ s32 PS4_SYSV_ABI _sceFiberAttachContext(OrbisFiber* fiber, void* addr_context, u *stack_ptr++ = kFiberStackSizeCheck; } } + + return ORBIS_OK; } void PS4_SYSV_ABI _sceFiberSwitchToFiber(OrbisFiber* fiber, u64 arg_on_run_to, @@ -143,9 +146,10 @@ void PS4_SYSV_ABI _sceFiberTerminate(OrbisFiber* fiber, u64 arg_on_return, Orbis __builtin_trap(); } -s32 PS4_SYSV_ABI sceFiberInitialize(OrbisFiber* fiber, const char* name, OrbisFiberEntry entry, - u64 arg_on_initialize, void* addr_context, u64 size_context, - const OrbisFiberOptParam* opt_param, u32 build_ver) { +s32 PS4_SYSV_ABI sceFiberInitializeImpl(OrbisFiber* fiber, const char* name, OrbisFiberEntry entry, + u64 arg_on_initialize, void* addr_context, u64 size_context, + const OrbisFiberOptParam* opt_param, u32 flags, + u32 build_ver) { if (!fiber || !name || !entry) { return ORBIS_FIBER_ERROR_NULL; } @@ -171,12 +175,12 @@ s32 PS4_SYSV_ABI sceFiberInitialize(OrbisFiber* fiber, const char* name, OrbisFi return ORBIS_FIBER_ERROR_INVALID; } - u32 flags = FiberFlags::None; - if (build_ver >= 0x3500000) { - flags |= FiberFlags::SetFpuRegs; + u32 user_flags = flags; + if (build_ver >= Common::ElfInfo::FW_35) { + user_flags |= FiberFlags::SetFpuRegs; } if (context_size_check) { - flags |= FiberFlags::ContextSizeCheck; + user_flags |= FiberFlags::ContextSizeCheck; } strncpy(fiber->name, name, ORBIS_FIBER_MAX_NAME_LENGTH); @@ -186,7 +190,7 @@ s32 PS4_SYSV_ABI sceFiberInitialize(OrbisFiber* fiber, const char* name, OrbisFi fiber->addr_context = addr_context; fiber->size_context = size_context; fiber->context = nullptr; - fiber->flags = flags; + fiber->flags = user_flags; /* A low stack area is problematic, as we can easily @@ -525,6 +529,13 @@ s32 PS4_SYSV_ABI sceFiberGetThreadFramePointerAddress(u64* addr_frame_pointer) { return ORBIS_OK; } +s32 PS4_SYSV_ABI sceFiberInitialize(OrbisFiber* fiber, const char* name, OrbisFiberEntry entry, + u64 arg_on_initialize, void* addr_context, u64 size_context, + const OrbisFiberOptParam* opt_param, u32 build_ver) { + return sceFiberInitializeImpl(fiber, name, entry, arg_on_initialize, addr_context, size_context, + opt_param, 0, build_ver); +} + s32 PS4_SYSV_ABI sceFiberRun(OrbisFiber* fiber, u64 arg_on_run_to, u64* arg_on_return) { return sceFiberRunImpl(fiber, nullptr, 0, arg_on_run_to, arg_on_return); } @@ -536,7 +547,7 @@ s32 PS4_SYSV_ABI sceFiberSwitch(OrbisFiber* fiber, u64 arg_on_run_to, u64* arg_o void RegisterlibSceFiber(Core::Loader::SymbolsResolver* sym) { LIB_FUNCTION("hVYD7Ou2pCQ", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberInitialize); LIB_FUNCTION("7+OJIpko9RY", "libSceFiber", 1, "libSceFiber", 1, 1, - sceFiberInitialize); // _sceFiberInitializeWithInternalOptionImpl + sceFiberInitializeImpl); // _sceFiberInitializeWithInternalOptionImpl LIB_FUNCTION("asjUJJ+aa8s", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberOptParamInitialize); LIB_FUNCTION("JeNX5F-NzQU", "libSceFiber", 1, "libSceFiber", 1, 1, sceFiberFinalize);