From c754da6491e90b5d736dea1e57fac03dfd86fdd1 Mon Sep 17 00:00:00 2001 From: Silent Date: Mon, 18 Nov 2019 21:46:51 +0100 Subject: [PATCH 01/35] Do not assert in Discord::Shutdown Discord::Shutdown runs on app exit unconditionally, and thus it's valid to try to call it even when Discord RPC is not running. --- UI/DiscordIntegration.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/UI/DiscordIntegration.cpp b/UI/DiscordIntegration.cpp index 442a14b763..5c49340c7e 100644 --- a/UI/DiscordIntegration.cpp +++ b/UI/DiscordIntegration.cpp @@ -64,11 +64,12 @@ void Discord::Init() { } void Discord::Shutdown() { - assert(initialized_); + if (initialized_) { #ifdef ENABLE_DISCORD - Discord_Shutdown(); + Discord_Shutdown(); #endif - initialized_ = false; + initialized_ = false; + } } void Discord::Update() { From f03417c08c885950aaa02c6abd70da276a239dd6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 26 Nov 2019 23:49:38 +0100 Subject: [PATCH 02/35] Update lang submodule --- assets/lang | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/lang b/assets/lang index a95fd4974c..d6fcde91c0 160000 --- a/assets/lang +++ b/assets/lang @@ -1 +1 @@ -Subproject commit a95fd4974c436a1a07455c5beef4a12f9f47b811 +Subproject commit d6fcde91c09456bb9e68b66a9c0df57d9825438a From 714205d699d7a79da1130e7ba8c48668dc73d540 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 3 Nov 2019 18:22:48 +0100 Subject: [PATCH 03/35] Vulkan: Enable renderpass merging for all games (was introduced in 1.9 for GoW games). A number of other games can also benefit. --- Core/Compatibility.cpp | 1 - Core/Compatibility.h | 1 - GPU/Vulkan/GPU_Vulkan.cpp | 5 +++-- assets/compat.ini | 36 ------------------------------------ 4 files changed, 3 insertions(+), 40 deletions(-) diff --git a/Core/Compatibility.cpp b/Core/Compatibility.cpp index b006447072..1d8c9d513a 100644 --- a/Core/Compatibility.cpp +++ b/Core/Compatibility.cpp @@ -59,7 +59,6 @@ void Compatibility::CheckSettings(IniFile &iniFile, const std::string &gameID) { CheckSetting(iniFile, gameID, "DisableAccurateDepth", &flags_.DisableAccurateDepth); CheckSetting(iniFile, gameID, "MGS2AcidHack", &flags_.MGS2AcidHack); CheckSetting(iniFile, gameID, "SonicRivalsHack", &flags_.SonicRivalsHack); - CheckSetting(iniFile, gameID, "RenderPassMerge", &flags_.RenderPassMerge); CheckSetting(iniFile, gameID, "BlockTransferAllowCreateFB", &flags_.BlockTransferAllowCreateFB); CheckSetting(iniFile, gameID, "YugiohSaveFix", &flags_.YugiohSaveFix); CheckSetting(iniFile, gameID, "ForceUMDDelay", &flags_.ForceUMDDelay); diff --git a/Core/Compatibility.h b/Core/Compatibility.h index 0baf9db5fa..460776a90a 100644 --- a/Core/Compatibility.h +++ b/Core/Compatibility.h @@ -59,7 +59,6 @@ struct CompatFlags { bool DisableAccurateDepth; bool MGS2AcidHack; bool SonicRivalsHack; - bool RenderPassMerge; bool BlockTransferAllowCreateFB; bool YugiohSaveFix; bool ForceUMDDelay; diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index 1a5e254e27..3f20ec0642 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -485,8 +485,9 @@ void GPU_Vulkan::InitDeviceObjects() { hacks |= QUEUE_HACK_MGS2_ACID; if (PSP_CoreParameter().compat.flags().SonicRivalsHack) hacks |= QUEUE_HACK_SONIC; - if (PSP_CoreParameter().compat.flags().RenderPassMerge) - hacks |= QUEUE_HACK_RENDERPASS_MERGE; + + // Always on. + hacks |= QUEUE_HACK_RENDERPASS_MERGE; if (hacks) { rm->GetQueueRunner()->EnableHacks(hacks); diff --git a/assets/compat.ini b/assets/compat.ini index c67f0b8360..55a47296eb 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -648,42 +648,6 @@ ULAS42214 = true ULJS19054 = true NPJH50184 = true -[RenderPassMerge] -UCJS10114 = true -UCKS45084 = true -# GOW : Ghost of Sparta -UCUS98737 = true -UCAS40323 = true -NPHG00092 = true -NPEG00044 = true -NPEG00045 = true -NPJG00120 = true -NPUG80508 = true -UCJS10114 = true -UCES01401 = true -UCES01473 = true -# GOW : Ghost of Sparta Demo -NPEG90035 = true -NPUG70125 = true -NPJG90095 = true -# GOW : Chains Of Olympus -UCAS40198 = true -UCUS98653 = true -UCES00842 = true -ULJM05438 = true -ULJM05348 = true -UCKS45084 = true -NPUG80325 = true -NPEG00023 = true -NPHG00027 = true -NPHG00028 = true -NPJH50170 = true -UCET00844 = true -# GOW: Chains of Olympus Demo -UCUS98705 = true -UCED00971 = true -UCUS98713 = true - [ForceSoftwareRenderer] # Darkstalkers ULES00016 = true From fc34a93ac2a21bd5ac5d0d6beff63c794e7630f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 30 Nov 2019 23:01:23 +0100 Subject: [PATCH 04/35] vulkan: ApplyRenderPassMerge; Add copy / blit destinations to touched buffers. --- ext/native/thin3d/VulkanQueueRunner.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index 3785b7d9b9..0b16b4bbc7 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -789,11 +789,13 @@ void VulkanQueueRunner::ApplyRenderPassMerge(std::vector &steps) { if (steps[j]->copy.src == fb || steps[j]->copy.dst == fb) { goto done_fb; } + touchedFramebuffers.insert(steps[j]->copy.dst); break; case VKRStepType::BLIT: if (steps[j]->blit.src == fb || steps[j]->blit.dst == fb) { goto done_fb; } + touchedFramebuffers.insert(steps[j]->blit.dst); break; case VKRStepType::READBACK: // Not sure this has much effect, when executed READBACK is always the last step From 26ab81c102ae9e7e56ca09fd2f4536f74e41c8ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 30 Nov 2019 23:03:30 +0100 Subject: [PATCH 05/35] vulkan: The GPU profiler could end up writing massive amounts of text, fix some bugs around that. --- ext/native/gfx_es2/draw_buffer.cpp | 14 +++++++++----- ext/native/thin3d/VulkanQueueRunner.cpp | 2 +- ext/native/thin3d/VulkanRenderManager.h | 8 ++++---- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/ext/native/gfx_es2/draw_buffer.cpp b/ext/native/gfx_es2/draw_buffer.cpp index 5d1bb88153..b329534a93 100644 --- a/ext/native/gfx_es2/draw_buffer.cpp +++ b/ext/native/gfx_es2/draw_buffer.cpp @@ -495,8 +495,12 @@ void DrawBuffer::DrawTextRect(int font, const char *text, float x, float y, floa // ROTATE_* doesn't yet work right. void DrawBuffer::DrawText(int font, const char *text, float x, float y, Color color, int align) { // rough estimate - if (count_ + strlen(text) * 6 > MAX_VERTS) { + size_t textLen = strlen(text); + if (count_ + textLen * 6 > MAX_VERTS) { Flush(true); + if (textLen * 6 >= MAX_VERTS) { + textLen = std::min(MAX_VERTS / 6 - 10, (int)textLen); + } } const AtlasFont &atlasfont = *atlas->fonts[font]; @@ -508,14 +512,14 @@ void DrawBuffer::DrawText(int font, const char *text, float x, float y, Color co } if (align & ROTATE_90DEG_LEFT) { - x -= atlasfont.ascend*fontscaley; + x -= atlasfont.ascend * fontscaley; // y += h; + } else { + y += atlasfont.ascend * fontscaley; } - else - y += atlasfont.ascend*fontscaley; float sx = x; UTF8 utf(text); - while (true) { + for (size_t i = 0; i < textLen; i++) { if (utf.end()) break; cval = utf.next(); diff --git a/ext/native/thin3d/VulkanQueueRunner.cpp b/ext/native/thin3d/VulkanQueueRunner.cpp index 0b16b4bbc7..8a7dcd8f4a 100644 --- a/ext/native/thin3d/VulkanQueueRunner.cpp +++ b/ext/native/thin3d/VulkanQueueRunner.cpp @@ -469,7 +469,7 @@ void VulkanQueueRunner::RunSteps(VkCommandBuffer cmd, std::vector &st break; } - if (profile) { + if (profile && profile->timestampDescriptions.size() + 1 < MAX_TIMESTAMP_QUERIES) { vkCmdWriteTimestamp(cmd, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, profile->queryPool, (uint32_t)profile->timestampDescriptions.size()); profile->timestampDescriptions.push_back(StepToString(step)); } diff --git a/ext/native/thin3d/VulkanRenderManager.h b/ext/native/thin3d/VulkanRenderManager.h index 4201d912ad..c14c894a72 100644 --- a/ext/native/thin3d/VulkanRenderManager.h +++ b/ext/native/thin3d/VulkanRenderManager.h @@ -85,6 +85,10 @@ enum class VKRRunType { SYNC, }; +enum { + MAX_TIMESTAMP_QUERIES = 128, +}; + class VulkanRenderManager { public: VulkanRenderManager(VulkanContext *vulkan); @@ -299,10 +303,6 @@ private: FrameData frameData_[VulkanContext::MAX_INFLIGHT_FRAMES]; - enum { - MAX_TIMESTAMP_QUERIES = 256, - }; - // Submission time state int curWidth_ = -1; int curHeight_ = -1; From a6d511d12357187356afa000bab843b6b1edd261 Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Fri, 13 Dec 2019 08:19:17 +0800 Subject: [PATCH 06/35] IO:Add an extra delay to simulate umd delay in file seek whence. Pangya(KS) seems want to check something base on this delay and system time.Anyhow, the game work now. --- Core/HLE/sceIo.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 5550411fcf..2baa398a7e 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -2531,6 +2531,10 @@ static int __IoIoctl(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, // TODO: Should probably move this to something common between ISOFileSystem and VirtualDiscSystem. INFO_LOG(SCEIO, "sceIoIoctl: Sector seek for file %i", id); // Even if the size is 4, it still actually reads a 16 byte struct, it seems. + + if (GetIOTimingMethod() == IOTIMING_REALISTIC) + usec = 15000;// Fantasy Golf Pangya Portable(KS) needs a delay over 15000us. + if (Memory::IsValidAddress(indataPtr) && inlen >= 4) { struct SeekInfo { u64 offset; From fd6b0554d6c6c356f6a9f29f87aebc9f87ee0fd4 Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Fri, 13 Dec 2019 11:15:58 +0800 Subject: [PATCH 07/35] IO:Re-grab SCE_KERNEL_ERROR_NOCWD. Fix issue#12492,the issue occur since commit e09296b9b10d6ee9997dcd86bc10d172a48a4b1b --- Core/FileSystems/MetaFileSystem.cpp | 47 ++++++++++++++++++++--------- Core/FileSystems/MetaFileSystem.h | 2 +- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/Core/FileSystems/MetaFileSystem.cpp b/Core/FileSystems/MetaFileSystem.cpp index 933f56f5b1..e7936014dc 100644 --- a/Core/FileSystems/MetaFileSystem.cpp +++ b/Core/FileSystems/MetaFileSystem.cpp @@ -226,7 +226,7 @@ int MetaFileSystem::MapFilePath(const std::string &_inpath, std::string &outpath currentDirectory = &(it->second); } - if ( RealPath(*currentDirectory, inpath, realpath) ) + if (RealPath(*currentDirectory, inpath, realpath)) { std::string prefix = realpath; size_t prefixPos = realpath.find(':'); @@ -243,7 +243,10 @@ int MetaFileSystem::MapFilePath(const std::string &_inpath, std::string &outpath VERBOSE_LOG(FILESYS, "MapFilePath: mapped \"%s\" to prefix: \"%s\", path: \"%s\"", inpath.c_str(), fileSystems[i].prefix.c_str(), outpath.c_str()); - return 0; + if (error == SCE_KERNEL_ERROR_NOCWD) + return error; + else + return 0; } } } @@ -339,9 +342,13 @@ int MetaFileSystem::OpenFile(std::string filename, FileAccess access, const char std::string of; MountPoint *mount; int error = MapFilePath(filename, of, &mount); - if (error == 0) - return mount->system->OpenFile(of, access, mount->prefix.c_str()); - else + if (error == 0 || error == SCE_KERNEL_ERROR_NOCWD) { + int h = mount->system->OpenFile(of, access, mount->prefix.c_str()); + if (h < 0 && error == SCE_KERNEL_ERROR_NOCWD) + return SCE_KERNEL_ERROR_NOCWD; + else + return h; + } else return error == -1 ? SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND : error; } @@ -350,7 +357,8 @@ PSPFileInfo MetaFileSystem::GetFileInfo(std::string filename) std::lock_guard guard(lock); std::string of; IFileSystem *system; - if (MapFilePath(filename, of, &system) == 0) + int error = MapFilePath(filename, of, &system); + if (error == 0 || error == SCE_KERNEL_ERROR_NOCWD) { return system->GetFileInfo(of); } @@ -366,7 +374,8 @@ bool MetaFileSystem::GetHostPath(const std::string &inpath, std::string &outpath std::lock_guard guard(lock); std::string of; IFileSystem *system; - if (MapFilePath(inpath, of, &system) == 0) { + int error = MapFilePath(inpath, of, &system); + if (error == 0 || error == SCE_KERNEL_ERROR_NOCWD) { return system->GetHostPath(of, outpath); } else { return false; @@ -378,7 +387,8 @@ std::vector MetaFileSystem::GetDirListing(std::string path) std::lock_guard guard(lock); std::string of; IFileSystem *system; - if (MapFilePath(path, of, &system) == 0) + int error = MapFilePath(path, of, &system); + if (error == 0 || error == SCE_KERNEL_ERROR_NOCWD) { return system->GetDirListing(of); } @@ -406,7 +416,8 @@ int MetaFileSystem::ChDir(const std::string &dir) std::string of; MountPoint *mountPoint; - if (MapFilePath(dir, of, &mountPoint) == 0) + int error = MapFilePath(dir, of, &mountPoint); + if (error == 0 || error == SCE_KERNEL_ERROR_NOCWD) { currentDir[curThread] = mountPoint->prefix + of; return 0; @@ -435,7 +446,8 @@ bool MetaFileSystem::MkDir(const std::string &dirname) std::lock_guard guard(lock); std::string of; IFileSystem *system; - if (MapFilePath(dirname, of, &system) == 0) + int error = MapFilePath(dirname, of, &system); + if (error == 0 || error == SCE_KERNEL_ERROR_NOCWD) { return system->MkDir(of); } @@ -450,7 +462,8 @@ bool MetaFileSystem::RmDir(const std::string &dirname) std::lock_guard guard(lock); std::string of; IFileSystem *system; - if (MapFilePath(dirname, of, &system) == 0) + int error = MapFilePath(dirname, of, &system); + if (error == 0 || error == SCE_KERNEL_ERROR_NOCWD) { return system->RmDir(of); } @@ -467,12 +480,14 @@ int MetaFileSystem::RenameFile(const std::string &from, const std::string &to) std::string rf; IFileSystem *osystem; IFileSystem *rsystem = NULL; - if (MapFilePath(from, of, &osystem) == 0) + int error = MapFilePath(from, of, &osystem); + if (error == 0 || error == SCE_KERNEL_ERROR_NOCWD) { // If it's a relative path, it seems to always use from's filesystem. if (to.find(":/") != to.npos) { - if (!MapFilePath(to, rf, &rsystem)) + error = MapFilePath(to, rf, &rsystem); + if (error != 0) return -1; } else @@ -497,7 +512,8 @@ bool MetaFileSystem::RemoveFile(const std::string &filename) std::lock_guard guard(lock); std::string of; IFileSystem *system; - if (MapFilePath(filename, of, &system) == 0) + int error = MapFilePath(filename, of, &system); + if (error == 0 || error == SCE_KERNEL_ERROR_NOCWD) { return system->RemoveFile(of); } @@ -604,7 +620,8 @@ u64 MetaFileSystem::FreeSpace(const std::string &path) std::lock_guard guard(lock); std::string of; IFileSystem *system; - if (MapFilePath(path, of, &system) == 0) + int error = MapFilePath(path, of, &system); + if (error == 0 || error == SCE_KERNEL_ERROR_NOCWD) return system->FreeSpace(of); else return 0; diff --git a/Core/FileSystems/MetaFileSystem.h b/Core/FileSystems/MetaFileSystem.h index cfc202b0d1..7335646170 100644 --- a/Core/FileSystems/MetaFileSystem.h +++ b/Core/FileSystems/MetaFileSystem.h @@ -79,7 +79,7 @@ public: inline int MapFilePath(const std::string &_inpath, std::string &outpath, IFileSystem **system) { MountPoint *mountPoint; int error = MapFilePath(_inpath, outpath, &mountPoint); - if (error == 0) { + if (error == 0 || error == SCE_KERNEL_ERROR_NOCWD) { *system = mountPoint->system; return error; } From c3a489fa90f7ea6d031ad931ec997f42474d1abf Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Fri, 13 Dec 2019 17:59:55 +0800 Subject: [PATCH 08/35] Don't ignore SCE_KERNEL_ERROR_NOCWD in many cases. Use a error 1 to mean the uccessful mapping but carry with SCE_KERNEL_ERROR_NOCWD error. --- Core/FileSystems/MetaFileSystem.cpp | 26 +++++++++++++------------- Core/FileSystems/MetaFileSystem.h | 2 +- Core/HLE/sceIo.cpp | 4 ++-- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/Core/FileSystems/MetaFileSystem.cpp b/Core/FileSystems/MetaFileSystem.cpp index e7936014dc..2c0fd58e5c 100644 --- a/Core/FileSystems/MetaFileSystem.cpp +++ b/Core/FileSystems/MetaFileSystem.cpp @@ -244,7 +244,7 @@ int MetaFileSystem::MapFilePath(const std::string &_inpath, std::string &outpath VERBOSE_LOG(FILESYS, "MapFilePath: mapped \"%s\" to prefix: \"%s\", path: \"%s\"", inpath.c_str(), fileSystems[i].prefix.c_str(), outpath.c_str()); if (error == SCE_KERNEL_ERROR_NOCWD) - return error; + return 1; // This means successful mapping but carry with SCE_KERNEL_ERROR_NOCWD error. else return 0; } @@ -342,9 +342,9 @@ int MetaFileSystem::OpenFile(std::string filename, FileAccess access, const char std::string of; MountPoint *mount; int error = MapFilePath(filename, of, &mount); - if (error == 0 || error == SCE_KERNEL_ERROR_NOCWD) { + if (error >= 0) { int h = mount->system->OpenFile(of, access, mount->prefix.c_str()); - if (h < 0 && error == SCE_KERNEL_ERROR_NOCWD) + if (h < 0 && error == 1) return SCE_KERNEL_ERROR_NOCWD; else return h; @@ -358,7 +358,7 @@ PSPFileInfo MetaFileSystem::GetFileInfo(std::string filename) std::string of; IFileSystem *system; int error = MapFilePath(filename, of, &system); - if (error == 0 || error == SCE_KERNEL_ERROR_NOCWD) + if (error >= 0) { return system->GetFileInfo(of); } @@ -375,7 +375,7 @@ bool MetaFileSystem::GetHostPath(const std::string &inpath, std::string &outpath std::string of; IFileSystem *system; int error = MapFilePath(inpath, of, &system); - if (error == 0 || error == SCE_KERNEL_ERROR_NOCWD) { + if (error >= 0) { return system->GetHostPath(of, outpath); } else { return false; @@ -388,7 +388,7 @@ std::vector MetaFileSystem::GetDirListing(std::string path) std::string of; IFileSystem *system; int error = MapFilePath(path, of, &system); - if (error == 0 || error == SCE_KERNEL_ERROR_NOCWD) + if (error >= 0) { return system->GetDirListing(of); } @@ -417,7 +417,7 @@ int MetaFileSystem::ChDir(const std::string &dir) std::string of; MountPoint *mountPoint; int error = MapFilePath(dir, of, &mountPoint); - if (error == 0 || error == SCE_KERNEL_ERROR_NOCWD) + if (error >= 0) { currentDir[curThread] = mountPoint->prefix + of; return 0; @@ -447,7 +447,7 @@ bool MetaFileSystem::MkDir(const std::string &dirname) std::string of; IFileSystem *system; int error = MapFilePath(dirname, of, &system); - if (error == 0 || error == SCE_KERNEL_ERROR_NOCWD) + if (error >= 0) { return system->MkDir(of); } @@ -463,7 +463,7 @@ bool MetaFileSystem::RmDir(const std::string &dirname) std::string of; IFileSystem *system; int error = MapFilePath(dirname, of, &system); - if (error == 0 || error == SCE_KERNEL_ERROR_NOCWD) + if (error >= 0) { return system->RmDir(of); } @@ -481,13 +481,13 @@ int MetaFileSystem::RenameFile(const std::string &from, const std::string &to) IFileSystem *osystem; IFileSystem *rsystem = NULL; int error = MapFilePath(from, of, &osystem); - if (error == 0 || error == SCE_KERNEL_ERROR_NOCWD) + if (error >= 0) { // If it's a relative path, it seems to always use from's filesystem. if (to.find(":/") != to.npos) { error = MapFilePath(to, rf, &rsystem); - if (error != 0) + if (error < 0) return -1; } else @@ -513,7 +513,7 @@ bool MetaFileSystem::RemoveFile(const std::string &filename) std::string of; IFileSystem *system; int error = MapFilePath(filename, of, &system); - if (error == 0 || error == SCE_KERNEL_ERROR_NOCWD) + if (error >= 0) { return system->RemoveFile(of); } @@ -621,7 +621,7 @@ u64 MetaFileSystem::FreeSpace(const std::string &path) std::string of; IFileSystem *system; int error = MapFilePath(path, of, &system); - if (error == 0 || error == SCE_KERNEL_ERROR_NOCWD) + if (error >= 0) return system->FreeSpace(of); else return 0; diff --git a/Core/FileSystems/MetaFileSystem.h b/Core/FileSystems/MetaFileSystem.h index 7335646170..ad9af8d2e8 100644 --- a/Core/FileSystems/MetaFileSystem.h +++ b/Core/FileSystems/MetaFileSystem.h @@ -79,7 +79,7 @@ public: inline int MapFilePath(const std::string &_inpath, std::string &outpath, IFileSystem **system) { MountPoint *mountPoint; int error = MapFilePath(_inpath, outpath, &mountPoint); - if (error == 0 || error == SCE_KERNEL_ERROR_NOCWD) { + if (error >= 0) { *system = mountPoint->system; return error; } diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 2baa398a7e..36166cf6bb 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -2532,8 +2532,8 @@ static int __IoIoctl(u32 id, u32 cmd, u32 indataPtr, u32 inlen, u32 outdataPtr, INFO_LOG(SCEIO, "sceIoIoctl: Sector seek for file %i", id); // Even if the size is 4, it still actually reads a 16 byte struct, it seems. - if (GetIOTimingMethod() == IOTIMING_REALISTIC) - usec = 15000;// Fantasy Golf Pangya Portable(KS) needs a delay over 15000us. + //if (GetIOTimingMethod() == IOTIMING_REALISTIC) // Need a check for io timing method? + usec = 15000;// Fantasy Golf Pangya Portable(KS) needs a delay over 15000us. if (Memory::IsValidAddress(indataPtr) && inlen >= 4) { struct SeekInfo { From 608d716413d517079781709793df01ab14e1c863 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 18 Dec 2019 00:04:07 +0100 Subject: [PATCH 09/35] Update build.gradle.. again. --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index c651082644..a9deb8ae96 100644 --- a/build.gradle +++ b/build.gradle @@ -5,7 +5,7 @@ buildscript { jcenter() } dependencies { - classpath 'com.android.tools.build:gradle:3.5.2' + classpath 'com.android.tools.build:gradle:3.5.3' } } From f99a651c6ae02fda9dc7e12a05d940832554fdd5 Mon Sep 17 00:00:00 2001 From: iota97 Date: Thu, 19 Dec 2019 00:41:32 +0100 Subject: [PATCH 10/35] Touch controll grid snap --- Core/Config.cpp | 4 ++++ Core/Config.h | 5 +++++ UI/TouchControlLayoutScreen.cpp | 15 +++++++++++++-- 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 73e529f59a..1fc75131f0 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -854,6 +854,10 @@ static ConfigSetting controlSettings[] = { ConfigSetting("TouchButtonHideSeconds", &g_Config.iTouchButtonHideSeconds, 20, true, true), ConfigSetting("AutoCenterTouchAnalog", &g_Config.bAutoCenterTouchAnalog, false, true, true), + // Snap touch control position + ConfigSetting("TouchSnapToGrid", &g_Config.bTouchSnapToGrid, false, true, true), + ConfigSetting("TouchSnapGridSize", &g_Config.iTouchSnapGridSize, 64, true, true), + // -1.0f means uninitialized, set in GamepadEmu::CreatePadLayout(). ConfigSetting("ActionButtonSpacing2", &g_Config.fActionButtonSpacing, 1.0f, true, true), ConfigSetting("ActionButtonCenterX", "ActionButtonCenterY", "ActionButtonScale", nullptr, &g_Config.touchActionButtonCenter, defaultTouchPosShow, true, true), diff --git a/Core/Config.h b/Core/Config.h index 0c58923417..2fe185fcd7 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -275,6 +275,11 @@ public: int iTouchButtonStyle; int iTouchButtonOpacity; int iTouchButtonHideSeconds; + + // Snap touch control position + bool bTouchSnapToGrid; + int iTouchSnapGridSize; + // Floating analog stick (recenters on thumb on press). bool bAutoCenterTouchAnalog; diff --git a/UI/TouchControlLayoutScreen.cpp b/UI/TouchControlLayoutScreen.cpp index 24574ed951..98b019b724 100644 --- a/UI/TouchControlLayoutScreen.cpp +++ b/UI/TouchControlLayoutScreen.cpp @@ -243,9 +243,15 @@ bool TouchControlLayoutScreen::touch(const TouchInput &touch) { // if the leftmost point of the control is ahead of the margin, // move it. Otherwise, don't. newX = touch.x; + // Snap to grid + if (g_Config.bTouchSnapToGrid) + newX -= (int)(touch.x-bounds.centerX()) % g_Config.iTouchSnapGridSize; } if (touch.y > minTouchY && touch.y < maxTouchY) { newY = touch.y; + // Snap to grid + if (g_Config.bTouchSnapToGrid) + newY -= (int)(touch.y-bounds.centerY()) % g_Config.iTouchSnapGridSize; } pickedControl_->ReplaceLayoutParams(new UI::AnchorLayoutParams(newX, newY, NONE, NONE, true)); } else if (mode == 1) { @@ -324,11 +330,14 @@ void TouchControlLayoutScreen::CreateViews() { Choice *reset = new Choice(di->T("Reset"), "", false, new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 84)); Choice *back = new Choice(di->T("Back"), "", false, new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 10)); - Choice *visibility = new Choice(co->T("Visibility"), "", false, new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 158)); + Choice *visibility = new Choice(co->T("Visibility"), "", false, new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 298)); // controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fButtonScale, 0.80, 2.0, co->T("Button Scaling"), screenManager())) // ->OnChange.Handle(this, &GameSettingsScreen::OnChangeControlScaling); - mode_ = new ChoiceStrip(ORIENT_VERTICAL, new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 158 + 64 + 10)); + CheckBox *snap = new CheckBox(&g_Config.bTouchSnapToGrid, di->T("Snap"), "", new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 228)); + PopupSliderChoice *gridSize = new PopupSliderChoice(&g_Config.iTouchSnapGridSize, 1, 256, di->T("Grid"), screenManager(), "", new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 158)); + + mode_ = new ChoiceStrip(ORIENT_VERTICAL, new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 140 + 158 + 64 + 10)); mode_->AddChoice(di->T("Move")); mode_->AddChoice(di->T("Resize")); mode_->SetSelection(0); @@ -338,6 +347,8 @@ void TouchControlLayoutScreen::CreateViews() { visibility->OnClick.Handle(this, &TouchControlLayoutScreen::OnVisibility); root_->Add(mode_); root_->Add(visibility); + root_->Add(snap); + root_->Add(gridSize); root_->Add(reset); root_->Add(back); From d7be4f883e1d46fdcc901fba059c5af0fb8955f9 Mon Sep 17 00:00:00 2001 From: iota97 Date: Thu, 19 Dec 2019 01:26:23 +0100 Subject: [PATCH 11/35] Fix --- UI/TouchControlLayoutScreen.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/UI/TouchControlLayoutScreen.cpp b/UI/TouchControlLayoutScreen.cpp index 98b019b724..3f8f27749c 100644 --- a/UI/TouchControlLayoutScreen.cpp +++ b/UI/TouchControlLayoutScreen.cpp @@ -245,13 +245,13 @@ bool TouchControlLayoutScreen::touch(const TouchInput &touch) { newX = touch.x; // Snap to grid if (g_Config.bTouchSnapToGrid) - newX -= (int)(touch.x-bounds.centerX()) % g_Config.iTouchSnapGridSize; + newX -= (int)(touch.x - bounds.w) % g_Config.iTouchSnapGridSize; } if (touch.y > minTouchY && touch.y < maxTouchY) { newY = touch.y; // Snap to grid if (g_Config.bTouchSnapToGrid) - newY -= (int)(touch.y-bounds.centerY()) % g_Config.iTouchSnapGridSize; + newY -= (int)(touch.y - bounds.h) % g_Config.iTouchSnapGridSize; } pickedControl_->ReplaceLayoutParams(new UI::AnchorLayoutParams(newX, newY, NONE, NONE, true)); } else if (mode == 1) { From 7a8c39d7bf7651a68ac35a1dcd1d02fa5ae7e712 Mon Sep 17 00:00:00 2001 From: iota97 Date: Thu, 19 Dec 2019 09:05:08 +0100 Subject: [PATCH 12/35] Disabled grid size if snap is disabled --- UI/TouchControlLayoutScreen.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/UI/TouchControlLayoutScreen.cpp b/UI/TouchControlLayoutScreen.cpp index 3f8f27749c..b317f9e5c8 100644 --- a/UI/TouchControlLayoutScreen.cpp +++ b/UI/TouchControlLayoutScreen.cpp @@ -336,6 +336,7 @@ void TouchControlLayoutScreen::CreateViews() { CheckBox *snap = new CheckBox(&g_Config.bTouchSnapToGrid, di->T("Snap"), "", new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 228)); PopupSliderChoice *gridSize = new PopupSliderChoice(&g_Config.iTouchSnapGridSize, 1, 256, di->T("Grid"), screenManager(), "", new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 158)); + gridSize->SetEnabledPtr(&g_Config.bTouchSnapToGrid); mode_ = new ChoiceStrip(ORIENT_VERTICAL, new AnchorLayoutParams(leftColumnWidth, WRAP_CONTENT, 10, NONE, NONE, 140 + 158 + 64 + 10)); mode_->AddChoice(di->T("Move")); From e53895f6879128d26db3a4c6fd1cd404d3e0e52f Mon Sep 17 00:00:00 2001 From: iota97 Date: Thu, 19 Dec 2019 11:56:42 +0100 Subject: [PATCH 13/35] Hide "Control" label on top --- UI/TouchControlLayoutScreen.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/UI/TouchControlLayoutScreen.cpp b/UI/TouchControlLayoutScreen.cpp index b317f9e5c8..65ebb654cf 100644 --- a/UI/TouchControlLayoutScreen.cpp +++ b/UI/TouchControlLayoutScreen.cpp @@ -364,7 +364,7 @@ void TouchControlLayoutScreen::CreateViews() { I18NCategory *ms = GetI18NCategory("MainSettings"); - tabHolder->AddTab(ms->T("Controls"), controlsHolder); + //tabHolder->AddTab(ms->T("Controls"), controlsHolder); if (!g_Config.bShowTouchControls) { // Shouldn't even be able to get here as the way into this dialog should be closed. From 072041a63dcc03fafa425caa4ddccf468abd102b Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Tue, 24 Dec 2019 11:05:15 -0800 Subject: [PATCH 14/35] SoftGPU: Convert from 16-bit if unsupported. Should help #12455, but not actually tested on an affected device. --- GPU/Software/SoftGpu.cpp | 86 ++++++++++++++++++++++++---------------- GPU/Software/SoftGpu.h | 3 +- 2 files changed, 53 insertions(+), 36 deletions(-) diff --git a/GPU/Software/SoftGpu.cpp b/GPU/Software/SoftGpu.cpp index 7254c2ce11..691a8756aa 100644 --- a/GPU/Software/SoftGpu.cpp +++ b/GPU/Software/SoftGpu.cpp @@ -158,6 +158,38 @@ void SoftGPU::SetDisplayFramebuffer(u32 framebuf, u32 stride, GEBufferFormat for bool g_DarkStalkerStretch; +void SoftGPU::ConvertTextureDescFrom16(Draw::TextureDesc &desc, int srcwidth, int srcheight) { + // TODO: This should probably be converted in a shader instead.. + fbTexBuffer_.resize(srcwidth * srcheight); + FormatBuffer displayBuffer; + displayBuffer.data = Memory::GetPointer(displayFramebuf_); + for (int y = 0; y < srcheight; ++y) { + u32 *buf_line = &fbTexBuffer_[y * srcwidth]; + const u16 *fb_line = &displayBuffer.as16[y * displayStride_]; + + switch (displayFormat_) { + case GE_FORMAT_565: + ConvertRGBA565ToRGBA8888(buf_line, fb_line, srcwidth); + break; + + case GE_FORMAT_5551: + ConvertRGBA5551ToRGBA8888(buf_line, fb_line, srcwidth); + break; + + case GE_FORMAT_4444: + ConvertRGBA4444ToRGBA8888(buf_line, fb_line, srcwidth); + break; + + default: + ERROR_LOG_REPORT(G3D, "Software: Unexpected framebuffer format: %d", displayFormat_); + } + } + + desc.width = srcwidth; + desc.height = srcheight; + desc.initData.push_back((uint8_t *)fbTexBuffer_.data()); +} + // Copies RGBA8 data from RAM to the currently bound render target. void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { if (!draw_) @@ -191,6 +223,7 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { Draw::Pipeline *pipeline = texColor; if (PSP_CoreParameter().compat.flags().DarkStalkersPresentHack && displayFormat_ == GE_FORMAT_5551 && g_DarkStalkerStretch) { u8 *data = Memory::GetPointer(0x04088000); + bool fillDesc = true; if (draw_->GetDataFormatSupport(Draw::DataFormat::A1B5G5R5_UNORM_PACK16) & Draw::FMT_TEXTURE) { // The perfect one. desc.format = Draw::DataFormat::A1B5G5R5_UNORM_PACK16; @@ -198,10 +231,15 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { // RB swapped, compensate with a shader. desc.format = Draw::DataFormat::A1R5G5B5_UNORM_PACK16; pipeline = texColorRBSwizzle; + } else { + ConvertTextureDescFrom16(desc, srcwidth, srcheight); + fillDesc = false; + } + if (fillDesc) { + desc.width = displayStride_ == 0 ? srcwidth : displayStride_; + desc.height = srcheight; + desc.initData.push_back(data); } - desc.width = displayStride_ == 0 ? srcwidth : displayStride_; - desc.height = srcheight; - desc.initData.push_back(data); u0 = 64.5f / 512.0f; u1 = 447.5f / 512.0f; v1 = 16.0f / 272.0f; @@ -217,6 +255,7 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { desc.format = Draw::DataFormat::R8G8B8A8_UNORM; } else if (displayFormat_ == GE_FORMAT_5551) { u8 *data = Memory::GetPointer(displayFramebuf_); + bool fillDesc = true; desc.format = Draw::DataFormat::A1R5G5B5_UNORM_PACK16; if (draw_->GetDataFormatSupport(Draw::DataFormat::A1B5G5R5_UNORM_PACK16) & Draw::FMT_TEXTURE) { // The perfect one. @@ -225,40 +264,17 @@ void SoftGPU::CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight) { // RB swapped, compensate with a shader. desc.format = Draw::DataFormat::A1R5G5B5_UNORM_PACK16; pipeline = texColorRBSwizzle; + } else { + ConvertTextureDescFrom16(desc, srcwidth, srcheight); + fillDesc = false; + } + if (fillDesc) { + desc.width = displayStride_ == 0 ? srcwidth : displayStride_; + desc.height = srcheight; + desc.initData.push_back(data); } - desc.width = displayStride_ == 0 ? srcwidth : displayStride_; - desc.height = srcheight; - desc.initData.push_back(data); } else { - // TODO: This should probably be converted in a shader instead.. - fbTexBuffer.resize(srcwidth * srcheight); - FormatBuffer displayBuffer; - displayBuffer.data = Memory::GetPointer(displayFramebuf_); - for (int y = 0; y < srcheight; ++y) { - u32 *buf_line = &fbTexBuffer[y * srcwidth]; - const u16 *fb_line = &displayBuffer.as16[y * displayStride_]; - - switch (displayFormat_) { - case GE_FORMAT_565: - ConvertRGBA565ToRGBA8888(buf_line, fb_line, srcwidth); - break; - - case GE_FORMAT_5551: - ConvertRGBA5551ToRGBA8888(buf_line, fb_line, srcwidth); - break; - - case GE_FORMAT_4444: - ConvertRGBA4444ToRGBA8888(buf_line, fb_line, srcwidth); - break; - - default: - ERROR_LOG_REPORT(G3D, "Software: Unexpected framebuffer format: %d", displayFormat_); - } - } - - desc.width = srcwidth; - desc.height = srcheight; - desc.initData.push_back((uint8_t *)fbTexBuffer.data()); + ConvertTextureDescFrom16(desc, srcwidth, srcheight); u1 = 1.0f; } if (!hasImage) { diff --git a/GPU/Software/SoftGpu.h b/GPU/Software/SoftGpu.h index 02660b5576..84626b31c2 100644 --- a/GPU/Software/SoftGpu.h +++ b/GPU/Software/SoftGpu.h @@ -101,6 +101,7 @@ public: protected: void FastRunLoop(DisplayList &list) override; void CopyToCurrentFboFromDisplayRam(int srcwidth, int srcheight); + void ConvertTextureDescFrom16(Draw::TextureDesc &desc, int srcwidth, int srcheight); private: bool framebufferDirty_; @@ -113,7 +114,7 @@ private: Draw::Texture *fbTex; Draw::Pipeline *texColor; Draw::Pipeline *texColorRBSwizzle; - std::vector fbTexBuffer; + std::vector fbTexBuffer_; Draw::SamplerState *samplerNearest = nullptr; Draw::SamplerState *samplerLinear = nullptr; From fb696f8a7126fe22eaa6c6baa2291b2733c6e115 Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Wed, 25 Dec 2019 11:16:56 +0800 Subject: [PATCH 15/35] Just return error if current directory not be setted. --- Core/FileSystems/MetaFileSystem.cpp | 33 ++++++++++++----------------- Core/FileSystems/MetaFileSystem.h | 2 +- 2 files changed, 14 insertions(+), 21 deletions(-) diff --git a/Core/FileSystems/MetaFileSystem.cpp b/Core/FileSystems/MetaFileSystem.cpp index 2c0fd58e5c..0cf66541e3 100644 --- a/Core/FileSystems/MetaFileSystem.cpp +++ b/Core/FileSystems/MetaFileSystem.cpp @@ -243,10 +243,7 @@ int MetaFileSystem::MapFilePath(const std::string &_inpath, std::string &outpath VERBOSE_LOG(FILESYS, "MapFilePath: mapped \"%s\" to prefix: \"%s\", path: \"%s\"", inpath.c_str(), fileSystems[i].prefix.c_str(), outpath.c_str()); - if (error == SCE_KERNEL_ERROR_NOCWD) - return 1; // This means successful mapping but carry with SCE_KERNEL_ERROR_NOCWD error. - else - return 0; + return error == SCE_KERNEL_ERROR_NOCWD ? error : 0; } } } @@ -342,13 +339,9 @@ int MetaFileSystem::OpenFile(std::string filename, FileAccess access, const char std::string of; MountPoint *mount; int error = MapFilePath(filename, of, &mount); - if (error >= 0) { - int h = mount->system->OpenFile(of, access, mount->prefix.c_str()); - if (h < 0 && error == 1) - return SCE_KERNEL_ERROR_NOCWD; - else - return h; - } else + if (error == 0) + return mount->system->OpenFile(of, access, mount->prefix.c_str()); + else return error == -1 ? SCE_KERNEL_ERROR_ERRNO_FILE_NOT_FOUND : error; } @@ -358,7 +351,7 @@ PSPFileInfo MetaFileSystem::GetFileInfo(std::string filename) std::string of; IFileSystem *system; int error = MapFilePath(filename, of, &system); - if (error >= 0) + if (error == 0) { return system->GetFileInfo(of); } @@ -375,7 +368,7 @@ bool MetaFileSystem::GetHostPath(const std::string &inpath, std::string &outpath std::string of; IFileSystem *system; int error = MapFilePath(inpath, of, &system); - if (error >= 0) { + if (error == 0) { return system->GetHostPath(of, outpath); } else { return false; @@ -388,7 +381,7 @@ std::vector MetaFileSystem::GetDirListing(std::string path) std::string of; IFileSystem *system; int error = MapFilePath(path, of, &system); - if (error >= 0) + if (error == 0) { return system->GetDirListing(of); } @@ -417,7 +410,7 @@ int MetaFileSystem::ChDir(const std::string &dir) std::string of; MountPoint *mountPoint; int error = MapFilePath(dir, of, &mountPoint); - if (error >= 0) + if (error == 0) { currentDir[curThread] = mountPoint->prefix + of; return 0; @@ -447,7 +440,7 @@ bool MetaFileSystem::MkDir(const std::string &dirname) std::string of; IFileSystem *system; int error = MapFilePath(dirname, of, &system); - if (error >= 0) + if (error == 0) { return system->MkDir(of); } @@ -463,7 +456,7 @@ bool MetaFileSystem::RmDir(const std::string &dirname) std::string of; IFileSystem *system; int error = MapFilePath(dirname, of, &system); - if (error >= 0) + if (error == 0) { return system->RmDir(of); } @@ -481,7 +474,7 @@ int MetaFileSystem::RenameFile(const std::string &from, const std::string &to) IFileSystem *osystem; IFileSystem *rsystem = NULL; int error = MapFilePath(from, of, &osystem); - if (error >= 0) + if (error == 0) { // If it's a relative path, it seems to always use from's filesystem. if (to.find(":/") != to.npos) @@ -513,7 +506,7 @@ bool MetaFileSystem::RemoveFile(const std::string &filename) std::string of; IFileSystem *system; int error = MapFilePath(filename, of, &system); - if (error >= 0) + if (error == 0) { return system->RemoveFile(of); } @@ -621,7 +614,7 @@ u64 MetaFileSystem::FreeSpace(const std::string &path) std::string of; IFileSystem *system; int error = MapFilePath(path, of, &system); - if (error >= 0) + if (error == 0) return system->FreeSpace(of); else return 0; diff --git a/Core/FileSystems/MetaFileSystem.h b/Core/FileSystems/MetaFileSystem.h index ad9af8d2e8..cfc202b0d1 100644 --- a/Core/FileSystems/MetaFileSystem.h +++ b/Core/FileSystems/MetaFileSystem.h @@ -79,7 +79,7 @@ public: inline int MapFilePath(const std::string &_inpath, std::string &outpath, IFileSystem **system) { MountPoint *mountPoint; int error = MapFilePath(_inpath, outpath, &mountPoint); - if (error >= 0) { + if (error == 0) { *system = mountPoint->system; return error; } From 499431c1ed94bcd81754d90626979f107ce394ef Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 26 Dec 2019 11:05:36 -0800 Subject: [PATCH 16/35] Io: Correct leak on save state. This was breaking things a bit more every time you saved state. --- Core/HLE/sceIo.cpp | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 5550411fcf..1f83b69ef6 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -697,29 +697,28 @@ void __IoDoState(PointerWrap &p) { } for (int i = 0; i < PSP_COUNT_FDS; ++i) { + auto clearThread = [&]() { + if (asyncThreads[i]) + asyncThreads[i]->Forget(); + delete asyncThreads[i]; + asyncThreads[i] = nullptr; + }; + if (s >= 4) { p.DoVoid(&asyncParams[i], (int)sizeof(IoAsyncParams)); bool hasThread = asyncThreads[i] != nullptr; p.Do(hasThread); if (hasThread) { - if (asyncThreads[i]) - asyncThreads[i]->Forget(); - delete asyncThreads[i]; - asyncThreads[i] = nullptr; + if (p.GetMode() == p.MODE_READ) + clearThread(); p.DoClass(asyncThreads[i]); } else if (!hasThread) { - if (asyncThreads[i]) - asyncThreads[i]->Forget(); - delete asyncThreads[i]; - asyncThreads[i] = nullptr; + clearThread(); } } else { asyncParams[i].op = IoAsyncOp::NONE; asyncParams[i].priority = -1; - if (asyncThreads[i]) - asyncThreads[i]->Forget(); - delete asyncThreads[i]; - asyncThreads[i] = nullptr; + clearThread(); } } } From 7e345dad113f56e7d9b82845155ca41edafc3191 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Thu, 26 Dec 2019 11:26:31 -0800 Subject: [PATCH 17/35] Io: Allow adjusting default async thread priority. --- Core/HLE/sceIo.cpp | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 36166cf6bb..872e7b03bc 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -199,6 +199,7 @@ struct IoAsyncParams { static IoAsyncParams asyncParams[PSP_COUNT_FDS]; static HLEHelperThread *asyncThreads[PSP_COUNT_FDS]{}; +static int asyncDefaultPriority = -1; class FileNode : public KernelObject { public: @@ -662,7 +663,7 @@ void __IoInit() { } void __IoDoState(PointerWrap &p) { - auto s = p.Section("sceIo", 1, 4); + auto s = p.Section("sceIo", 1, 5); if (!s) return; @@ -722,6 +723,12 @@ void __IoDoState(PointerWrap &p) { asyncThreads[i] = nullptr; } } + + if (s >= 5) { + p.Do(asyncDefaultPriority); + } else { + asyncDefaultPriority = -1; + } } void __IoShutdown() { @@ -739,6 +746,7 @@ void __IoShutdown() { delete asyncThreads[i]; asyncThreads[i] = nullptr; } + asyncDefaultPriority = -1; pspFileSystem.Unmount("ms0:", memstickSystem); pspFileSystem.Unmount("fatms0:", memstickSystem); @@ -772,7 +780,9 @@ u32 __IoGetFileHandleFromId(u32 id, u32 &outError) static void IoStartAsyncThread(int id, FileNode *f) { IoAsyncCleanupThread(id, true); - int priority = asyncParams[id].priority == -1 ? KernelCurThreadPriority() : asyncParams[id].priority; + int priority = asyncParams[id].priority == -1 ? asyncDefaultPriority : asyncParams[id].priority; + if (priority == -1) + priority = KernelCurThreadPriority(); asyncThreads[id] = new HLEHelperThread("SceIoAsync", "IoFileMgrForUser", "__IoAsyncFinish", priority, 0x200); asyncThreads[id]->Start(id, 0); f->pendingAsyncResult = true; @@ -1963,6 +1973,11 @@ static int sceIoChangeAsyncPriority(int id, int priority) { return hleLogError(SCEIO, SCE_KERNEL_ERROR_ILLEGAL_PRIORITY, "illegal priority %d", priority); } + if (id == -1) { + asyncDefaultPriority = priority; + return hleLogSuccessI(SCEIO, 0); + } + u32 error; FileNode *f = __IoGetFd(id, error); if (!f) { From 9989c51f21666ce3224621f045780cac896d6835 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Wed, 1 Jan 2020 07:47:26 -0800 Subject: [PATCH 18/35] SDL: Ignore audio switch events in first second. We get new device events right on start, which makes auto switch away from the preferred / most recent device otherwise. Fixes #12536. --- SDL/SDLMain.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/SDL/SDLMain.cpp b/SDL/SDLMain.cpp index f868592bd2..90db5d4195 100644 --- a/SDL/SDLMain.cpp +++ b/SDL/SDLMain.cpp @@ -910,7 +910,9 @@ int main(int argc, char *argv[]) { if (!name) { break; } - if (g_Config.bAutoAudioDevice || g_Config.sAudioDevice == name) { + // Don't start auto switching for a second, because some devices init on start. + bool doAutoSwitch = g_Config.bAutoAudioDevice && framecount > 60; + if (doAutoSwitch || g_Config.sAudioDevice == name) { StopSDLAudioDevice(); InitSDLAudioDevice(name ? name : ""); } From 2ec99ec47da4997b74cff6e2d75aa6fc0e331f39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Wed, 1 Jan 2020 17:41:19 +0100 Subject: [PATCH 19/35] compat.ini: Add Japanese Game ID for DarkStalkers (Vampire Chronicles) --- assets/compat.ini | 2 ++ 1 file changed, 2 insertions(+) diff --git a/assets/compat.ini b/assets/compat.ini index 55a47296eb..7bba442d39 100644 --- a/assets/compat.ini +++ b/assets/compat.ini @@ -652,8 +652,10 @@ NPJH50184 = true # Darkstalkers ULES00016 = true ULUS10005 = true +ULJM05005 = true [DarkStalkersPresentHack] # Darkstalkers ULES00016 = true ULUS10005 = true +ULJM05005 = true From d09543ebd70d1723f7c435ce09a3bee6d8e4c5a3 Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Thu, 2 Jan 2020 14:56:24 +0800 Subject: [PATCH 20/35] Move umd replace to loaders. --- Core/FileSystems/MetaFileSystem.cpp | 17 ++++++------ Core/FileSystems/MetaFileSystem.h | 2 +- Core/HLE/sceUmd.cpp | 40 ++++------------------------- Core/Loaders.cpp | 34 ++++++++++++++++++++++++ Core/Loaders.h | 2 ++ Core/PSPLoaders.cpp | 36 +++++++++++++++++++++++++- Core/PSPLoaders.h | 1 + 7 files changed, 87 insertions(+), 45 deletions(-) diff --git a/Core/FileSystems/MetaFileSystem.cpp b/Core/FileSystems/MetaFileSystem.cpp index 0cf66541e3..2a3ec02f7b 100644 --- a/Core/FileSystems/MetaFileSystem.cpp +++ b/Core/FileSystems/MetaFileSystem.cpp @@ -270,8 +270,7 @@ std::string MetaFileSystem::NormalizePrefix(std::string prefix) const { return prefix; } -void MetaFileSystem::Mount(std::string prefix, IFileSystem *system) -{ +void MetaFileSystem::Mount(std::string prefix, IFileSystem *system) { std::lock_guard guard(lock); MountPoint x; x.prefix = prefix; @@ -279,8 +278,7 @@ void MetaFileSystem::Mount(std::string prefix, IFileSystem *system) fileSystems.push_back(x); } -void MetaFileSystem::Unmount(std::string prefix, IFileSystem *system) -{ +void MetaFileSystem::Unmount(std::string prefix, IFileSystem *system) { std::lock_guard guard(lock); MountPoint x; x.prefix = prefix; @@ -288,10 +286,13 @@ void MetaFileSystem::Unmount(std::string prefix, IFileSystem *system) fileSystems.erase(std::remove(fileSystems.begin(), fileSystems.end(), x), fileSystems.end()); } -void MetaFileSystem::Remount(IFileSystem *oldSystem, IFileSystem *newSystem) { - for (auto it = fileSystems.begin(); it != fileSystems.end(); ++it) { - if (it->system == oldSystem) { - it->system = newSystem; +void MetaFileSystem::Remount(std::string prefix, IFileSystem *newSystem, bool delOldSystem) { + std::lock_guard guard(lock); + for (auto &it : fileSystems) { + if (it.prefix == prefix) { + if (delOldSystem) + delete it.system; + it.system = newSystem; } } } diff --git a/Core/FileSystems/MetaFileSystem.h b/Core/FileSystems/MetaFileSystem.h index cfc202b0d1..3fa2d16063 100644 --- a/Core/FileSystems/MetaFileSystem.h +++ b/Core/FileSystems/MetaFileSystem.h @@ -52,7 +52,7 @@ public: void Mount(std::string prefix, IFileSystem *system); void Unmount(std::string prefix, IFileSystem *system); - void Remount(IFileSystem *oldSystem, IFileSystem *newSystem); + void Remount(std::string prefix, IFileSystem *newSystem, bool delOldSystem = true); IFileSystem *GetSystem(const std::string &prefix); IFileSystem *GetSystemFromFilename(const std::string &filename); diff --git a/Core/HLE/sceUmd.cpp b/Core/HLE/sceUmd.cpp index bd4cb56d7b..2f61e739ec 100644 --- a/Core/HLE/sceUmd.cpp +++ b/Core/HLE/sceUmd.cpp @@ -425,7 +425,7 @@ static int sceUmdWaitDriveStatWithTimer(u32 stat, u32 timeout) DEBUG_LOG(SCEIO, "sceUmdWaitDriveStatWithTimer(stat = %08x, timeout = %d): waiting", stat, timeout); __UmdWaitStat(timeout); umdWaitingThreads.push_back(__KernelGetCurThread()); - __KernelWaitCurThread(WAITTYPE_UMD, 1, stat, 0, 0, "umd stat waited with timer"); + __KernelWaitCurThread(WAITTYPE_UMD, 1, stat, 0, false, "umd stat waited with timer"); return 0; } else { hleReSchedule("umd stat checked"); @@ -495,45 +495,15 @@ static u32 sceUmdGetErrorStat() } void __UmdReplace(std::string filepath) { - // TODO: This should really go through Loaders, no? What if it's an invalid file? + char *error = ""; + if (!UmdReplace(filepath, error)) + ERROR_LOG(SCEIO, "UMD Replace failed: %s", error); - // Only get system from disc0 seems have been enough. - IFileSystem* currentUMD = pspFileSystem.GetSystem("disc0:"); - IFileSystem* currentISOBlock = pspFileSystem.GetSystem("umd0:"); - if (!currentUMD) - return; - - FileLoader *loadedFile = ConstructFileLoader(filepath); - - IFileSystem* umd2; - if (!loadedFile->Exists()) { - delete loadedFile; - return; - } - UpdateLoadedFile(loadedFile); - - if (loadedFile->IsDirectory()) { - umd2 = new VirtualDiscFileSystem(&pspFileSystem, filepath); - } else { - auto bd = constructBlockDevice(loadedFile); - if (!bd) - return; - umd2 = new ISOFileSystem(&pspFileSystem, bd); - pspFileSystem.Remount(currentUMD, umd2); - - if (currentUMD != currentISOBlock) { - // We mounted an ISO block system separately. - IFileSystem *iso = new ISOBlockSystem(static_cast(umd2)); - pspFileSystem.Remount(currentISOBlock, iso); - delete currentISOBlock; - } - } - delete currentUMD; UMDInserted = false; CoreTiming::ScheduleEvent(usToCycles(200*1000), umdInsertChangeEvent, 0); // Wait sceUmdCheckMedium call // TODO Is this always correct if UMD was not activated? u32 notifyArg = PSP_UMD_PRESENT | PSP_UMD_READABLE | PSP_UMD_CHANGED; - if (driveCBId != -1) + if (driveCBId != 0) __KernelNotifyCallback(driveCBId, notifyArg); } diff --git a/Core/Loaders.cpp b/Core/Loaders.cpp index 14bc31973d..a07c7b8dd8 100644 --- a/Core/Loaders.cpp +++ b/Core/Loaders.cpp @@ -355,3 +355,37 @@ bool LoadFile(FileLoader **fileLoaderPtr, std::string *error_string) { coreState = CORE_ERROR; return false; } + +bool UmdReplace(std::string filepath, char *error) { + IFileSystem* currentUMD = pspFileSystem.GetSystem("disc0:"); + + if (!currentUMD) { + error = "has no disc"; + return false; + } + + FileLoader *loadedFile = ConstructFileLoader(filepath); + + if (!loadedFile->Exists()) { + delete loadedFile; + sprintf(error, "%s doesn't exist", loadedFile->Path().c_str()); + return false; + } + UpdateLoadedFile(loadedFile); + + loadedFile = ResolveFileLoaderTarget(loadedFile); + IdentifiedFileType type = Identify_File(loadedFile); + + switch (type) { + case IdentifiedFileType::PSP_ISO: + case IdentifiedFileType::PSP_ISO_NP: + case IdentifiedFileType::PSP_DISC_DIRECTORY: + ReInitMemoryForGameISO(loadedFile); + break; + default: + sprintf(error, "Unsupported file type: %i", type); + return false; + break; + } + return true; +} diff --git a/Core/Loaders.h b/Core/Loaders.h index 690376c73b..9d114b446d 100644 --- a/Core/Loaders.h +++ b/Core/Loaders.h @@ -158,3 +158,5 @@ void RegisterFileLoaderFactory(std::string name, std::unique_ptrIsDirectory()) { fileSystem = new VirtualDiscFileSystem(&pspFileSystem, fileLoader->Path()); blockSystem = fileSystem; @@ -144,6 +144,40 @@ void InitMemoryForGameISO(FileLoader *fileLoader) { } } +bool ReInitMemoryForGameISO(FileLoader *fileLoader) { + if (!fileLoader->Exists()) { + return false; + } + + IFileSystem *fileSystem = nullptr; + IFileSystem *blockSystem = nullptr; + + if (fileLoader->IsDirectory()) { + fileSystem = new VirtualDiscFileSystem(&pspFileSystem, fileLoader->Path()); + blockSystem = fileSystem; + } + else { + auto bd = constructBlockDevice(fileLoader); + if (!bd) + return false; + + ISOFileSystem *iso = new ISOFileSystem(&pspFileSystem, bd); + fileSystem = iso; + blockSystem = new ISOBlockSystem(iso); + } + + if (pspFileSystem.GetSystem("disc0:") != pspFileSystem.GetSystem("umd0:")) { + // We mounted an ISO block system separately. + pspFileSystem.Remount("umd0:", blockSystem, false); + pspFileSystem.Remount("umd1:", blockSystem, false); + pspFileSystem.Remount("umd:", blockSystem); + } + + pspFileSystem.Remount("disc0:", fileSystem); + + return true; +} + void InitMemoryForGamePBP(FileLoader *fileLoader) { if (!fileLoader->Exists()) { return; diff --git a/Core/PSPLoaders.h b/Core/PSPLoaders.h index f344008460..e9c089494e 100644 --- a/Core/PSPLoaders.h +++ b/Core/PSPLoaders.h @@ -25,5 +25,6 @@ bool Load_PSP_ISO(FileLoader *fileLoader, std::string *error_string); bool Load_PSP_ELF_PBP(FileLoader *fileLoader, std::string *error_string); bool Load_PSP_GE_Dump(FileLoader *fileLoader, std::string *error_string); void InitMemoryForGameISO(FileLoader *fileLoader); +bool ReInitMemoryForGameISO(FileLoader *fileLoader); void InitMemoryForGamePBP(FileLoader *fileLoader); void PSPLoaders_Shutdown(); From 28bfc4c05d19626a73dab7a11af6f774112ad5ef Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Thu, 2 Jan 2020 16:03:48 +0800 Subject: [PATCH 21/35] Avoid thread queue out of range by a offset. This case will happen if thread priority is -1. --- Core/HLE/ThreadQueueList.h | 39 +++++++++++++++++++++----------------- 1 file changed, 22 insertions(+), 17 deletions(-) diff --git a/Core/HLE/ThreadQueueList.h b/Core/HLE/ThreadQueueList.h index 9111fff41d..596abc74d9 100644 --- a/Core/HLE/ThreadQueueList.h +++ b/Core/HLE/ThreadQueueList.h @@ -21,8 +21,10 @@ #include "Common/ChunkFile.h" struct ThreadQueueList { + // + static const int INDEX_OFFSET = 1; // Number of queues (number of priority levels starting at 0.) - static const int NUM_QUEUES = 128; + static const int NUM_QUEUES = 128 + INDEX_OFFSET; // Initial number of threads a single queue can handle. static const int INITIAL_CAPACITY = 32; @@ -57,6 +59,9 @@ struct ThreadQueueList { ~ThreadQueueList() { clear(); } + inline int getQueueIdxwithOffset(u32 priority) { + return priority + INDEX_OFFSET; + } // Only for debugging, returns priority level. int contains(const SceUID uid) { @@ -67,7 +72,7 @@ struct ThreadQueueList { Queue *cur = &queues[i]; for (int j = cur->first; j < cur->end; ++j) { if (cur->data[j] == uid) - return i; + return i - INDEX_OFFSET; } } @@ -89,7 +94,7 @@ struct ThreadQueueList { inline SceUID pop_first_better(u32 priority) { Queue *cur = first; // Don't bother looking past (worse than) this priority. - Queue *stop = &queues[priority]; + Queue *stop = &queues[getQueueIdxwithOffset(priority)]; while (cur < stop) { if (cur->size() > 0) return cur->data[cur->first++]; @@ -111,7 +116,7 @@ struct ThreadQueueList { } inline void push_front(u32 priority, const SceUID threadID) { - Queue *cur = &queues[priority]; + Queue *cur = &queues[getQueueIdxwithOffset(priority)]; cur->data[--cur->first] = threadID; // If we ran out of room toward the front, add more room for next time. if (cur->first == 0) @@ -119,14 +124,14 @@ struct ThreadQueueList { } inline void push_back(u32 priority, const SceUID threadID) { - Queue *cur = &queues[priority]; + Queue *cur = &queues[getQueueIdxwithOffset(priority)]; cur->data[cur->end++] = threadID; if (cur->full()) rebalance(priority); } inline void remove(u32 priority, const SceUID threadID) { - Queue *cur = &queues[priority]; + Queue *cur = &queues[getQueueIdxwithOffset(priority)]; _dbg_assert_msg_(SCEKERNEL, cur->next != nullptr, "ThreadQueueList::Queue should already be linked up."); for (int i = cur->first; i < cur->end; ++i) { @@ -147,7 +152,7 @@ struct ThreadQueueList { } inline void rotate(u32 priority) { - Queue *cur = &queues[priority]; + Queue *cur = &queues[getQueueIdxwithOffset(priority)]; _dbg_assert_msg_(SCEKERNEL, cur->next != nullptr, "ThreadQueueList::Queue should already be linked up."); if (cur->size() > 1) { @@ -167,13 +172,13 @@ struct ThreadQueueList { first = invalid(); } - inline bool empty(u32 priority) const { - const Queue *cur = &queues[priority]; + inline bool empty(u32 priority) { + const Queue *cur = &queues[getQueueIdxwithOffset(priority)]; return cur->empty(); } inline void prepare(u32 priority) { - Queue *cur = &queues[priority]; + Queue *cur = &queues[getQueueIdxwithOffset(priority)]; if (cur->next == nullptr) link(priority, INITIAL_CAPACITY); } @@ -222,7 +227,7 @@ private: // Initialize a priority level and link to other queues. void link(u32 priority, int size) { - _dbg_assert_msg_(SCEKERNEL, queues[priority].data == nullptr, "ThreadQueueList::Queue should only be initialized once."); + _dbg_assert_msg_(SCEKERNEL, queues[getQueueIdxwithOffset(priority)].data == nullptr, "ThreadQueueList::Queue should only be initialized once."); // Make sure we stay a multiple of INITIAL_CAPACITY. if (size <= INITIAL_CAPACITY) @@ -235,19 +240,19 @@ private: } // Allocate the queue. - Queue *cur = &queues[priority]; + Queue *cur = &queues[getQueueIdxwithOffset(priority)]; cur->data = (SceUID *)malloc(sizeof(SceUID) * size); cur->capacity = size; // Start smack in the middle so it can move both directions. cur->first = size / 2; cur->end = size / 2; - for (int i = (int)priority - 1; i >= 0; --i) { + for (int i = (int)priority - 1; i >= -1; --i) { // This queue is before ours, and points past us. // We'll have it point to our new queue, inserting into the chain. - if (queues[i].next != nullptr) { - cur->next = queues[i].next; - queues[i].next = cur; + if (queues[getQueueIdxwithOffset(i)].next != nullptr) { + cur->next = queues[getQueueIdxwithOffset(i)].next; + queues[getQueueIdxwithOffset(i)].next = cur; return; } } @@ -260,7 +265,7 @@ private: // Move or allocate as necessary to maintain free space on both sides. void rebalance(u32 priority) { - Queue *cur = &queues[priority]; + Queue *cur = &queues[getQueueIdxwithOffset(priority)]; int size = cur->size(); // Basically full. Time for a larger queue? if (size >= cur->capacity - 2) { From 458f8cfac3cd3b76322b577b2d98b748c695de02 Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Thu, 2 Jan 2020 16:45:01 +0800 Subject: [PATCH 22/35] minor fix --- Core/HLE/sceUmd.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Core/HLE/sceUmd.cpp b/Core/HLE/sceUmd.cpp index 2f61e739ec..dcdfd88d93 100644 --- a/Core/HLE/sceUmd.cpp +++ b/Core/HLE/sceUmd.cpp @@ -496,8 +496,10 @@ static u32 sceUmdGetErrorStat() void __UmdReplace(std::string filepath) { char *error = ""; - if (!UmdReplace(filepath, error)) + if (!UmdReplace(filepath, error)) { ERROR_LOG(SCEIO, "UMD Replace failed: %s", error); + return; + } UMDInserted = false; CoreTiming::ScheduleEvent(usToCycles(200*1000), umdInsertChangeEvent, 0); // Wait sceUmdCheckMedium call From 44660bd9ae049c5c9df363c662a91ba10a363c9f Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Fri, 3 Jan 2020 14:33:32 +0800 Subject: [PATCH 23/35] Change async priority to current thread'priority if priority = -1. --- Core/HLE/ThreadQueueList.h | 39 +++++++++++++++++--------------------- Core/HLE/sceIo.cpp | 5 ++++- Core/Loaders.cpp | 6 +++++- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/Core/HLE/ThreadQueueList.h b/Core/HLE/ThreadQueueList.h index 596abc74d9..9111fff41d 100644 --- a/Core/HLE/ThreadQueueList.h +++ b/Core/HLE/ThreadQueueList.h @@ -21,10 +21,8 @@ #include "Common/ChunkFile.h" struct ThreadQueueList { - // - static const int INDEX_OFFSET = 1; // Number of queues (number of priority levels starting at 0.) - static const int NUM_QUEUES = 128 + INDEX_OFFSET; + static const int NUM_QUEUES = 128; // Initial number of threads a single queue can handle. static const int INITIAL_CAPACITY = 32; @@ -59,9 +57,6 @@ struct ThreadQueueList { ~ThreadQueueList() { clear(); } - inline int getQueueIdxwithOffset(u32 priority) { - return priority + INDEX_OFFSET; - } // Only for debugging, returns priority level. int contains(const SceUID uid) { @@ -72,7 +67,7 @@ struct ThreadQueueList { Queue *cur = &queues[i]; for (int j = cur->first; j < cur->end; ++j) { if (cur->data[j] == uid) - return i - INDEX_OFFSET; + return i; } } @@ -94,7 +89,7 @@ struct ThreadQueueList { inline SceUID pop_first_better(u32 priority) { Queue *cur = first; // Don't bother looking past (worse than) this priority. - Queue *stop = &queues[getQueueIdxwithOffset(priority)]; + Queue *stop = &queues[priority]; while (cur < stop) { if (cur->size() > 0) return cur->data[cur->first++]; @@ -116,7 +111,7 @@ struct ThreadQueueList { } inline void push_front(u32 priority, const SceUID threadID) { - Queue *cur = &queues[getQueueIdxwithOffset(priority)]; + Queue *cur = &queues[priority]; cur->data[--cur->first] = threadID; // If we ran out of room toward the front, add more room for next time. if (cur->first == 0) @@ -124,14 +119,14 @@ struct ThreadQueueList { } inline void push_back(u32 priority, const SceUID threadID) { - Queue *cur = &queues[getQueueIdxwithOffset(priority)]; + Queue *cur = &queues[priority]; cur->data[cur->end++] = threadID; if (cur->full()) rebalance(priority); } inline void remove(u32 priority, const SceUID threadID) { - Queue *cur = &queues[getQueueIdxwithOffset(priority)]; + Queue *cur = &queues[priority]; _dbg_assert_msg_(SCEKERNEL, cur->next != nullptr, "ThreadQueueList::Queue should already be linked up."); for (int i = cur->first; i < cur->end; ++i) { @@ -152,7 +147,7 @@ struct ThreadQueueList { } inline void rotate(u32 priority) { - Queue *cur = &queues[getQueueIdxwithOffset(priority)]; + Queue *cur = &queues[priority]; _dbg_assert_msg_(SCEKERNEL, cur->next != nullptr, "ThreadQueueList::Queue should already be linked up."); if (cur->size() > 1) { @@ -172,13 +167,13 @@ struct ThreadQueueList { first = invalid(); } - inline bool empty(u32 priority) { - const Queue *cur = &queues[getQueueIdxwithOffset(priority)]; + inline bool empty(u32 priority) const { + const Queue *cur = &queues[priority]; return cur->empty(); } inline void prepare(u32 priority) { - Queue *cur = &queues[getQueueIdxwithOffset(priority)]; + Queue *cur = &queues[priority]; if (cur->next == nullptr) link(priority, INITIAL_CAPACITY); } @@ -227,7 +222,7 @@ private: // Initialize a priority level and link to other queues. void link(u32 priority, int size) { - _dbg_assert_msg_(SCEKERNEL, queues[getQueueIdxwithOffset(priority)].data == nullptr, "ThreadQueueList::Queue should only be initialized once."); + _dbg_assert_msg_(SCEKERNEL, queues[priority].data == nullptr, "ThreadQueueList::Queue should only be initialized once."); // Make sure we stay a multiple of INITIAL_CAPACITY. if (size <= INITIAL_CAPACITY) @@ -240,19 +235,19 @@ private: } // Allocate the queue. - Queue *cur = &queues[getQueueIdxwithOffset(priority)]; + Queue *cur = &queues[priority]; cur->data = (SceUID *)malloc(sizeof(SceUID) * size); cur->capacity = size; // Start smack in the middle so it can move both directions. cur->first = size / 2; cur->end = size / 2; - for (int i = (int)priority - 1; i >= -1; --i) { + for (int i = (int)priority - 1; i >= 0; --i) { // This queue is before ours, and points past us. // We'll have it point to our new queue, inserting into the chain. - if (queues[getQueueIdxwithOffset(i)].next != nullptr) { - cur->next = queues[getQueueIdxwithOffset(i)].next; - queues[getQueueIdxwithOffset(i)].next = cur; + if (queues[i].next != nullptr) { + cur->next = queues[i].next; + queues[i].next = cur; return; } } @@ -265,7 +260,7 @@ private: // Move or allocate as necessary to maintain free space on both sides. void rebalance(u32 priority) { - Queue *cur = &queues[getQueueIdxwithOffset(priority)]; + Queue *cur = &queues[priority]; int size = cur->size(); // Basically full. Time for a larger queue? if (size >= cur->capacity - 2) { diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index f08d1d317b..ef4ca333e2 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -1967,7 +1967,7 @@ static u32 sceIoChdir(const char *dirname) { } static int sceIoChangeAsyncPriority(int id, int priority) { - // priority = -1 is valid + // priority = -1 is valid,means the current thread'priority if (priority != -1 && (priority < 0x08 || priority > 0x77)) { return hleLogError(SCEIO, SCE_KERNEL_ERROR_ILLEGAL_PRIORITY, "illegal priority %d", priority); } @@ -1977,6 +1977,9 @@ static int sceIoChangeAsyncPriority(int id, int priority) { return hleLogSuccessI(SCEIO, 0); } + if (priority == -1) + priority = KernelCurThreadPriority(); + u32 error; FileNode *f = __IoGetFd(id, error); if (!f) { diff --git a/Core/Loaders.cpp b/Core/Loaders.cpp index a07c7b8dd8..dd898f4ac9 100644 --- a/Core/Loaders.cpp +++ b/Core/Loaders.cpp @@ -380,7 +380,11 @@ bool UmdReplace(std::string filepath, char *error) { case IdentifiedFileType::PSP_ISO: case IdentifiedFileType::PSP_ISO_NP: case IdentifiedFileType::PSP_DISC_DIRECTORY: - ReInitMemoryForGameISO(loadedFile); + if (!ReInitMemoryForGameISO(loadedFile)) { + error = "reinit memory failed"; + return false; + } + break; default: sprintf(error, "Unsupported file type: %i", type); From 593e48b865dcbd77a0fab4d854e152a4e3276dd2 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 3 Jan 2020 13:09:58 -0800 Subject: [PATCH 24/35] Io: Update async priority more correctly. When an operation finishes, whether it uses the priority from the first operation or the current thread's priority depends on sdk version, it seems. This also makes it resolve the default priority on open, so that changing the default afterward doesn't affect already open descriptors. --- Core/HLE/HLEHelperThread.cpp | 9 ++++++++ Core/HLE/HLEHelperThread.h | 6 +++++ Core/HLE/sceIo.cpp | 43 ++++++++++++++++++++++-------------- Core/HLE/sceKernelThread.h | 2 +- 4 files changed, 42 insertions(+), 18 deletions(-) diff --git a/Core/HLE/HLEHelperThread.cpp b/Core/HLE/HLEHelperThread.cpp index 7f932c4a9c..36f9166813 100644 --- a/Core/HLE/HLEHelperThread.cpp +++ b/Core/HLE/HLEHelperThread.cpp @@ -16,9 +16,11 @@ // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. #include "Common/ChunkFile.h" +#include "Core/CoreTiming.h" #include "Core/MemMapHelpers.h" #include "Core/HLE/HLE.h" #include "Core/HLE/HLEHelperThread.h" +#include "Core/HLE/KernelWaitHelpers.h" #include "Core/HLE/sceKernelThread.h" #include "Core/HLE/sceKernelMemory.h" #include "Core/MIPS/MIPSCodeUtils.h" @@ -91,6 +93,13 @@ void HLEHelperThread::ChangePriority(u32 prio) { KernelChangeThreadPriority(id_, prio); } +void HLEHelperThread::Resume(WaitType waitType, SceUID uid, int result) { + bool res = HLEKernel::ResumeFromWait(id_, waitType, uid, result); + if (!res) { + ERROR_LOG(HLE, "Failed to wake helper thread from wait"); + } +} + void HLEHelperThread::Forget() { id_ = 0; entry_ = 0; diff --git a/Core/HLE/HLEHelperThread.h b/Core/HLE/HLEHelperThread.h index 1868d309b0..39df4c7402 100644 --- a/Core/HLE/HLEHelperThread.h +++ b/Core/HLE/HLEHelperThread.h @@ -19,6 +19,7 @@ #include "Core/HLE/sceKernel.h" class PointerWrap; +enum WaitType : int; class HLEHelperThread { public: @@ -33,10 +34,15 @@ public: void Terminate(); bool Stopped(); void ChangePriority(u32 prio); + void Resume(WaitType waitType, SceUID uid, int result); // For savestates. void Forget(); + u32 Entry() { + return entry_; + } + private: void AllocEntry(u32 size); void Create(const char *threadName, u32 prio, int stacksize); diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index f08d1d317b..1982eeab85 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -295,8 +295,11 @@ public: u64 __IoCompleteAsyncIO(FileNode *f); -static void IoAsyncCleanupThread(int fd, bool force = false) { - if (asyncThreads[fd] && (asyncThreads[fd]->Stopped() || force)) { +static void IoAsyncCleanupThread(int fd) { + if (asyncThreads[fd]) { + if (!asyncThreads[fd]->Stopped()) { + asyncThreads[fd]->Terminate(); + } delete asyncThreads[fd]; asyncThreads[fd] = nullptr; } @@ -438,8 +441,6 @@ static void __IoAsyncNotify(u64 userdata, int cyclesLate) { if (f->closePending) { __IoFreeFd(fd, error); } - - IoAsyncCleanupThread(fd); } } @@ -488,8 +489,6 @@ static void __IoSyncNotify(u64 userdata, int cyclesLate) { HLEKernel::ResumeFromWait(threadID, WAITTYPE_IO, fd, result); f->waitingSyncThreads.erase(std::remove(f->waitingSyncThreads.begin(), f->waitingSyncThreads.end(), threadID), f->waitingSyncThreads.end()); - - IoAsyncCleanupThread(fd); } static void __IoAsyncBeginCallback(SceUID threadID, SceUID prevCallbackId) { @@ -778,12 +777,20 @@ u32 __IoGetFileHandleFromId(u32 id, u32 &outError) } static void IoStartAsyncThread(int id, FileNode *f) { - IoAsyncCleanupThread(id, true); - int priority = asyncParams[id].priority == -1 ? asyncDefaultPriority : asyncParams[id].priority; - if (priority == -1) - priority = KernelCurThreadPriority(); - asyncThreads[id] = new HLEHelperThread("SceIoAsync", "IoFileMgrForUser", "__IoAsyncFinish", priority, 0x200); - asyncThreads[id]->Start(id, 0); + if (asyncThreads[id] && !asyncThreads[id]->Stopped()) { + // Wake the thread up. + if (asyncParams[id].priority == -1 && sceKernelGetCompiledSdkVersion() >= 0x04020000) { + asyncThreads[id]->ChangePriority(KernelCurThreadPriority()); + } + asyncThreads[id]->Resume(WAITTYPE_ASYNCIO, id, 0); + } else { + IoAsyncCleanupThread(id); + int priority = asyncParams[id].priority; + if (priority == -1) + priority = KernelCurThreadPriority(); + asyncThreads[id] = new HLEHelperThread("SceIoAsync", "IoFileMgrForUser", "__IoAsyncFinish", priority, 0x200); + asyncThreads[id]->Start(id, 0); + } f->pendingAsyncResult = true; } @@ -1491,7 +1498,7 @@ static u32 sceIoOpen(const char *filename, int flags, int mode) { return id; } else { DEBUG_LOG(SCEIO, "%i=sceIoOpen(%s, %08x, %08x)", id, filename, flags, mode); - asyncParams[id].priority = -1; + asyncParams[id].priority = asyncDefaultPriority; // Timing is not accurate, aiming low for now. return hleDelayResult(id, "file opened", 100); } @@ -1984,6 +1991,9 @@ static int sceIoChangeAsyncPriority(int id, int priority) { } if (asyncThreads[id] && !asyncThreads[id]->Stopped()) { + if (priority == -1) { + priority = KernelCurThreadPriority(); + } asyncThreads[id]->ChangePriority(priority); } @@ -2101,7 +2111,6 @@ static u32 sceIoGetAsyncStat(int id, u32 poll, u32 address) { DEBUG_LOG(SCEIO, "%lli = sceIoGetAsyncStat(%i, %i, %08x)", f->asyncResult, id, poll, address); Memory::Write_U64((u64) f->asyncResult, address); f->hasAsyncResult = false; - IoAsyncCleanupThread(id); if (f->closePending) { __IoFreeFd(id, error); @@ -2139,7 +2148,6 @@ static int sceIoWaitAsync(int id, u32 address) { } Memory::Write_U64((u64) f->asyncResult, address); f->hasAsyncResult = false; - IoAsyncCleanupThread(id); if (f->closePending) { __IoFreeFd(id, error); @@ -2173,7 +2181,6 @@ static int sceIoWaitAsyncCB(int id, u32 address) { } else if (f->hasAsyncResult) { Memory::Write_U64((u64) f->asyncResult, address); f->hasAsyncResult = false; - IoAsyncCleanupThread(id); if (f->closePending) { __IoFreeFd(id, error); @@ -2197,7 +2204,6 @@ static u32 sceIoPollAsync(int id, u32 address) { } else if (f->hasAsyncResult) { Memory::Write_U64((u64) f->asyncResult, address); f->hasAsyncResult = false; - IoAsyncCleanupThread(id); if (f->closePending) { __IoFreeFd(id, error); @@ -2671,6 +2677,8 @@ static int IoAsyncFinish(int id) { if (f) { // Reset this so the Io funcs don't reject the request. f->pendingAsyncResult = false; + // Reset the PC back so we will run again on resume. + currentMIPS->pc = asyncThreads[id]->Entry(); auto ¶ms = asyncParams[id]; @@ -2732,6 +2740,7 @@ static int IoAsyncFinish(int id) { __IoSchedAsync(f, id, us); __KernelWaitCurThread(WAITTYPE_ASYNCIO, id, 0, 0, false, "async io"); + hleSkipDeadbeef(); params.op = IoAsyncOp::NONE; return 0; diff --git a/Core/HLE/sceKernelThread.h b/Core/HLE/sceKernelThread.h index c89a373ee9..8b95396b97 100644 --- a/Core/HLE/sceKernelThread.h +++ b/Core/HLE/sceKernelThread.h @@ -80,7 +80,7 @@ struct SceKernelSysClock { // TODO: Map these to PSP wait types. Most of these are wrong. // remember to update the waitTypeNames array in sceKernelThread.cpp when changing these -enum WaitType +enum WaitType : int { WAITTYPE_NONE = 0, WAITTYPE_SLEEP = 1, From 507b01a93ec71398a0762e5aa7bf5f8bda3f5987 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 3 Jan 2020 13:35:04 -0800 Subject: [PATCH 25/35] Io: Return a better error code for sceIoCancel. This is very rarely used and doesn't seem to work. --- Core/HLE/sceIo.cpp | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index 1982eeab85..c2a55192b2 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -1265,17 +1265,14 @@ static u32 sceIoGetDevType(int id) { static u32 sceIoCancel(int id) { - ERROR_LOG_REPORT(SCEIO, "UNIMPL sceIoCancel(%d)", id); u32 error; FileNode *f = __IoGetFd(id, error); if (f) { - // TODO: Cancel the async operation if possible? + // It seems like this is unsupported for UMDs and memory sticks, based on tests. + return hleReportError(SCEIO, SCE_KERNEL_ERROR_UNSUP, "unimplemented or unsupported"); } else { - ERROR_LOG(SCEIO, "sceIoCancel: unknown id %d", id); - error = SCE_KERNEL_ERROR_BADF; + return hleLogError(SCEIO, SCE_KERNEL_ERROR_BADF, "invalid fd"); } - - return error; } static u32 npdrmLseek(FileNode *f, s32 where, FileMove whence) From 9fa4ae7b153cab319f5c4cf4a04475864087d77f Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Sat, 4 Jan 2020 09:11:15 +0800 Subject: [PATCH 26/35] fix --- Core/FileSystems/MetaFileSystem.cpp | 16 +++++++++++++--- Core/FileSystems/MetaFileSystem.h | 2 +- Core/HLE/sceIo.cpp | 3 --- Core/HLE/sceUmd.cpp | 2 +- Core/Loaders.cpp | 6 +++--- Core/Loaders.h | 2 +- Core/PSPLoaders.cpp | 17 ++++++----------- 7 files changed, 25 insertions(+), 23 deletions(-) diff --git a/Core/FileSystems/MetaFileSystem.cpp b/Core/FileSystems/MetaFileSystem.cpp index 2a3ec02f7b..19bddf251e 100644 --- a/Core/FileSystems/MetaFileSystem.cpp +++ b/Core/FileSystems/MetaFileSystem.cpp @@ -286,15 +286,25 @@ void MetaFileSystem::Unmount(std::string prefix, IFileSystem *system) { fileSystems.erase(std::remove(fileSystems.begin(), fileSystems.end(), x), fileSystems.end()); } -void MetaFileSystem::Remount(std::string prefix, IFileSystem *newSystem, bool delOldSystem) { +void MetaFileSystem::Remount(std::string prefix, IFileSystem *newSystem) { std::lock_guard guard(lock); + IFileSystem *oldSystem = nullptr; for (auto &it : fileSystems) { if (it.prefix == prefix) { - if (delOldSystem) - delete it.system; + oldSystem = it.system; it.system = newSystem; } } + + bool delOldSystem = true; + for (auto &it : fileSystems) { + if (it.system == oldSystem) { + delOldSystem = false; + } + } + + if (delOldSystem) + delete oldSystem; } IFileSystem *MetaFileSystem::GetSystemFromFilename(const std::string &filename) { diff --git a/Core/FileSystems/MetaFileSystem.h b/Core/FileSystems/MetaFileSystem.h index 3fa2d16063..c4bfd8d37f 100644 --- a/Core/FileSystems/MetaFileSystem.h +++ b/Core/FileSystems/MetaFileSystem.h @@ -52,7 +52,7 @@ public: void Mount(std::string prefix, IFileSystem *system); void Unmount(std::string prefix, IFileSystem *system); - void Remount(std::string prefix, IFileSystem *newSystem, bool delOldSystem = true); + void Remount(std::string prefix, IFileSystem *newSystem); IFileSystem *GetSystem(const std::string &prefix); IFileSystem *GetSystemFromFilename(const std::string &filename); diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index ef4ca333e2..d200bb4e0f 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -1977,9 +1977,6 @@ static int sceIoChangeAsyncPriority(int id, int priority) { return hleLogSuccessI(SCEIO, 0); } - if (priority == -1) - priority = KernelCurThreadPriority(); - u32 error; FileNode *f = __IoGetFd(id, error); if (!f) { diff --git a/Core/HLE/sceUmd.cpp b/Core/HLE/sceUmd.cpp index dcdfd88d93..3ebbaef092 100644 --- a/Core/HLE/sceUmd.cpp +++ b/Core/HLE/sceUmd.cpp @@ -495,7 +495,7 @@ static u32 sceUmdGetErrorStat() } void __UmdReplace(std::string filepath) { - char *error = ""; + std::string error = ""; if (!UmdReplace(filepath, error)) { ERROR_LOG(SCEIO, "UMD Replace failed: %s", error); return; diff --git a/Core/Loaders.cpp b/Core/Loaders.cpp index dd898f4ac9..a4d102e122 100644 --- a/Core/Loaders.cpp +++ b/Core/Loaders.cpp @@ -356,7 +356,7 @@ bool LoadFile(FileLoader **fileLoaderPtr, std::string *error_string) { return false; } -bool UmdReplace(std::string filepath, char *error) { +bool UmdReplace(std::string filepath, std::string &error) { IFileSystem* currentUMD = pspFileSystem.GetSystem("disc0:"); if (!currentUMD) { @@ -368,7 +368,7 @@ bool UmdReplace(std::string filepath, char *error) { if (!loadedFile->Exists()) { delete loadedFile; - sprintf(error, "%s doesn't exist", loadedFile->Path().c_str()); + error = loadedFile->Path() + " doesn't exist"; return false; } UpdateLoadedFile(loadedFile); @@ -387,7 +387,7 @@ bool UmdReplace(std::string filepath, char *error) { break; default: - sprintf(error, "Unsupported file type: %i", type); + error = "Unsupported file type:" + std::to_string((int)type); return false; break; } diff --git a/Core/Loaders.h b/Core/Loaders.h index 9d114b446d..a076cfa675 100644 --- a/Core/Loaders.h +++ b/Core/Loaders.h @@ -159,4 +159,4 @@ void RegisterFileLoaderFactory(std::string name, std::unique_ptrIsDirectory()) { fileSystem = new VirtualDiscFileSystem(&pspFileSystem, fileLoader->Path()); blockSystem = fileSystem; @@ -155,8 +155,7 @@ bool ReInitMemoryForGameISO(FileLoader *fileLoader) { if (fileLoader->IsDirectory()) { fileSystem = new VirtualDiscFileSystem(&pspFileSystem, fileLoader->Path()); blockSystem = fileSystem; - } - else { + } else { auto bd = constructBlockDevice(fileLoader); if (!bd) return false; @@ -166,15 +165,11 @@ bool ReInitMemoryForGameISO(FileLoader *fileLoader) { blockSystem = new ISOBlockSystem(iso); } - if (pspFileSystem.GetSystem("disc0:") != pspFileSystem.GetSystem("umd0:")) { - // We mounted an ISO block system separately. - pspFileSystem.Remount("umd0:", blockSystem, false); - pspFileSystem.Remount("umd1:", blockSystem, false); + pspFileSystem.Remount("umd0:", blockSystem); + pspFileSystem.Remount("umd1:", blockSystem); pspFileSystem.Remount("umd:", blockSystem); - } - - pspFileSystem.Remount("disc0:", fileSystem); - + pspFileSystem.Remount("disc0:", fileSystem); + return true; } From 9be8fc6c6917bbca50b0d55ec75614aa71995fa9 Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Sat, 4 Jan 2020 11:14:32 +0800 Subject: [PATCH 27/35] Oops. --- Core/HLE/sceUmd.cpp | 2 +- Core/PSPLoaders.cpp | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Core/HLE/sceUmd.cpp b/Core/HLE/sceUmd.cpp index 3ebbaef092..ab2d62a490 100644 --- a/Core/HLE/sceUmd.cpp +++ b/Core/HLE/sceUmd.cpp @@ -497,7 +497,7 @@ static u32 sceUmdGetErrorStat() void __UmdReplace(std::string filepath) { std::string error = ""; if (!UmdReplace(filepath, error)) { - ERROR_LOG(SCEIO, "UMD Replace failed: %s", error); + ERROR_LOG(SCEIO, "UMD Replace failed: %s", error.c_str()); return; } diff --git a/Core/PSPLoaders.cpp b/Core/PSPLoaders.cpp index 1f1425fe2c..6311485f7f 100644 --- a/Core/PSPLoaders.cpp +++ b/Core/PSPLoaders.cpp @@ -165,10 +165,10 @@ bool ReInitMemoryForGameISO(FileLoader *fileLoader) { blockSystem = new ISOBlockSystem(iso); } - pspFileSystem.Remount("umd0:", blockSystem); - pspFileSystem.Remount("umd1:", blockSystem); - pspFileSystem.Remount("umd:", blockSystem); - pspFileSystem.Remount("disc0:", fileSystem); + pspFileSystem.Remount("umd0:", blockSystem); + pspFileSystem.Remount("umd1:", blockSystem); + pspFileSystem.Remount("umd:", blockSystem); + pspFileSystem.Remount("disc0:", fileSystem); return true; } From 34743391095b8d6c605297aa7c91815ea884f3c6 Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Sat, 4 Jan 2020 08:48:04 -0800 Subject: [PATCH 28/35] Io: Correct async priority default on async open. --- Core/HLE/sceIo.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HLE/sceIo.cpp b/Core/HLE/sceIo.cpp index c2a55192b2..9e6a78028f 100644 --- a/Core/HLE/sceIo.cpp +++ b/Core/HLE/sceIo.cpp @@ -2062,7 +2062,7 @@ static u32 sceIoOpenAsync(const char *filename, int flags, int mode) auto ¶ms = asyncParams[fd]; params.op = IoAsyncOp::OPEN; - params.priority = -1; + params.priority = asyncDefaultPriority; params.open.filenameAddr = PARAM(0); params.open.flags = flags; params.open.mode = mode; From d9b6ab83cfc0fe0225a00e146c2d1bd59c5467a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 4 Jan 2020 21:00:15 +0100 Subject: [PATCH 29/35] Mac: MAP_32BIT is no longer supported in Catalina and breaks. We don't need it anymore anyway. Fixes #12495. --- Common/MemoryUtil.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Common/MemoryUtil.cpp b/Common/MemoryUtil.cpp index 36c7c74088..4694ef06e5 100644 --- a/Common/MemoryUtil.cpp +++ b/Common/MemoryUtil.cpp @@ -118,6 +118,10 @@ static void *SearchForFreeMem(size_t size) { // This is purposely not a full wrapper for virtualalloc/mmap, but it // provides exactly the primitive operations that PPSSPP needs. +#if PPSSPP_PLATFORM(MAC) +#undef MAP_32BIT +#endif + void *AllocateExecutableMemory(size_t size) { #if defined(_WIN32) void *ptr = nullptr; @@ -193,7 +197,7 @@ void *AllocateExecutableMemory(size_t size) { if (ptr == failed_result) { ptr = nullptr; - ERROR_LOG(MEMMAP, "Failed to allocate executable memory (%d)", (int)size); + ERROR_LOG(MEMMAP, "Failed to allocate executable memory (%d) errno=%d", (int)size, errno); PanicAlert("Failed to allocate executable memory\n%s", GetLastErrorMsg()); } #if defined(_M_X64) && !defined(_WIN32) && !defined(MAP_32BIT) From a04720e37e44ec0cb41e2b5e0c588a7c70c05959 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 4 Jan 2020 21:54:25 +0100 Subject: [PATCH 30/35] Don't use the MAP_32BIT flag on any platform. --- Common/MemoryUtil.cpp | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/Common/MemoryUtil.cpp b/Common/MemoryUtil.cpp index 4694ef06e5..4fef8c6f3e 100644 --- a/Common/MemoryUtil.cpp +++ b/Common/MemoryUtil.cpp @@ -117,11 +117,6 @@ static void *SearchForFreeMem(size_t size) { // This is purposely not a full wrapper for virtualalloc/mmap, but it // provides exactly the primitive operations that PPSSPP needs. - -#if PPSSPP_PLATFORM(MAC) -#undef MAP_32BIT -#endif - void *AllocateExecutableMemory(size_t size) { #if defined(_WIN32) void *ptr = nullptr; @@ -161,7 +156,7 @@ void *AllocateExecutableMemory(size_t size) { } #else static char *map_hint = 0; -#if defined(_M_X64) && !defined(MAP_32BIT) +#if defined(_M_X64) // Try to request one that is close to our memory location if we're in high memory. // We use a dummy global variable to give us a good location to start from. if (!map_hint) { @@ -169,9 +164,7 @@ void *AllocateExecutableMemory(size_t size) { map_hint = (char*)round_page(&hint_location) - 0x20000000; // 0.5gb lower than our approximate location else map_hint = (char*)0x20000000; // 0.5GB mark in memory - } - else if ((uintptr_t) map_hint > 0xFFFFFFFFULL) - { + } else if ((uintptr_t) map_hint > 0xFFFFFFFFULL) { map_hint -= round_page(size); /* round down to the next page if we're in high memory */ } #endif @@ -180,13 +173,7 @@ void *AllocateExecutableMemory(size_t size) { if (PlatformIsWXExclusive()) prot = PROT_READ | PROT_WRITE; // POST_EXEC is added later in this case. - void* ptr = mmap(map_hint, size, prot, - MAP_ANON | MAP_PRIVATE -#if defined(_M_X64) && defined(MAP_32BIT) - | MAP_32BIT -#endif - , -1, 0); - + void* ptr = mmap(map_hint, size, prot, MAP_ANON | MAP_PRIVATE, -1, 0); #endif /* defined(_WIN32) */ #if !defined(_WIN32) @@ -200,7 +187,8 @@ void *AllocateExecutableMemory(size_t size) { ERROR_LOG(MEMMAP, "Failed to allocate executable memory (%d) errno=%d", (int)size, errno); PanicAlert("Failed to allocate executable memory\n%s", GetLastErrorMsg()); } -#if defined(_M_X64) && !defined(_WIN32) && !defined(MAP_32BIT) + +#if defined(_M_X64) && !defined(_WIN32) else if ((uintptr_t)map_hint <= 0xFFFFFFFF) { // Round up if we're below 32-bit mark, probably allocating sequentially. map_hint += round_page(size); From 039fba0344eec368ab837b21c80708869e1eccdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 5 Jan 2020 10:57:09 +0800 Subject: [PATCH 31/35] Qt: don't return dangling pointer --- Qt/QtHost.cpp | 14 +++++++------- Qt/QtHost.h | 11 +++++------ 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/Qt/QtHost.cpp b/Qt/QtHost.cpp index c2ef7d2eac..e13f916c69 100644 --- a/Qt/QtHost.cpp +++ b/Qt/QtHost.cpp @@ -18,12 +18,12 @@ #include #include "Qt/QtHost.h" -const char* QtHost::SymbolMapFilename(std::string currentFilename) { - std::string result = currentFilename; - size_t dot = result.rfind('.'); - if (dot == result.npos) - return (result + ".map").c_str(); +std::string QtHost::SymbolMapFilename(std::string currentFilename) { + size_t dot = currentFilename.rfind('.'); + if (dot == std::string::npos) + currentFilename.append(".map"); + else + currentFilename.replace(dot, -1, ".map"); - result.replace(dot, result.npos, ".map"); - return result.c_str(); + return currentFilename; } diff --git a/Qt/QtHost.h b/Qt/QtHost.h index 846da1058f..1a15740806 100644 --- a/Qt/QtHost.h +++ b/Qt/QtHost.h @@ -64,13 +64,12 @@ public: #endif } virtual bool AttemptLoadSymbolMap() override { - return false; - // TODO: Make this work with Qt and threaded GL... not sure what's so broken. - // auto fn = SymbolMapFilename(PSP_CoreParameter().fileToStart); - // return g_symbolMap->LoadSymbolMap(fn); + auto fn = SymbolMapFilename(PSP_CoreParameter().fileToStart); + return g_symbolMap->LoadSymbolMap(fn.c_str()); } void PrepareShutdown() { - g_symbolMap->SaveSymbolMap(SymbolMapFilename(PSP_CoreParameter().fileToStart)); + auto fn = SymbolMapFilename(PSP_CoreParameter().fileToStart); + g_symbolMap->SaveSymbolMap(fn.c_str()); } void SetWindowTitle(const char *message) override { std::string title = std::string("PPSSPP ") + PPSSPP_GIT_VERSION; @@ -91,6 +90,6 @@ public: } private: - const char* SymbolMapFilename(std::string currentFilename); + std::string SymbolMapFilename(std::string currentFilename); MainWindow* mainWindow; }; From 19e03d7615074e6577ad385b87f6e863ae01a699 Mon Sep 17 00:00:00 2001 From: iota97 Date: Sun, 5 Jan 2020 12:21:19 +0100 Subject: [PATCH 32/35] Add headbar icon to Qt --- Qt/mainwindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Qt/mainwindow.cpp b/Qt/mainwindow.cpp index 502e22a0fd..4b4a6aaaf7 100644 --- a/Qt/mainwindow.cpp +++ b/Qt/mainwindow.cpp @@ -29,6 +29,8 @@ MainWindow::MainWindow(QWidget *parent, bool fullscreen) : QRect rect = desktop->screenGeometry(screenNum); move((rect.width()-frameGeometry().width()) / 4, (rect.height()-frameGeometry().height()) / 4); + setWindowIcon(QIcon(qApp->applicationDirPath() + "/assets/icon_regular_72.png")); + SetGameTitle(""); emugl = new MainUI(this); From f4b581025d4fa1cb7a76b61c10d56e32338d23dc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sun, 5 Jan 2020 14:41:17 +0100 Subject: [PATCH 33/35] Update submodules assets/lang, ffmpeg --- assets/lang | 2 +- ffmpeg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/assets/lang b/assets/lang index d6fcde91c0..6189eb455e 160000 --- a/assets/lang +++ b/assets/lang @@ -1 +1 @@ -Subproject commit d6fcde91c09456bb9e68b66a9c0df57d9825438a +Subproject commit 6189eb455e4b184ede558f7354e6ba31b485fd58 diff --git a/ffmpeg b/ffmpeg index 90701640c7..55147e5f33 160000 --- a/ffmpeg +++ b/ffmpeg @@ -1 +1 @@ -Subproject commit 90701640c7f458461310b54e7d4041230e2d5d5a +Subproject commit 55147e5f33f5ae4904f75ec082af809267122b94 From 4bc0274d53d0895602b9243eff61a28339f58ec2 Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Sun, 5 Jan 2020 22:11:43 +0800 Subject: [PATCH 34/35] Check invalid address in sceMpegAtracDecode. Fixes #11026. --- Core/HLE/sceMpeg.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index 43f30b9ce6..4f7e119e4e 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -1898,6 +1898,11 @@ static u32 sceMpegAtracDecode(u32 mpeg, u32 auAddr, u32 bufferAddr, int init) return -1; } + if (!Memory::IsValidAddress(bufferAddr) || !Memory::IsValidAddress(auAddr)) { + WARN_LOG(ME, "sceMpegAtracDecode(%08x, %08x, %08x, %i): invalid addresses", mpeg, auAddr, bufferAddr, init); + return -1; + } + DEBUG_LOG(ME, "sceMpegAtracDecode(%08x, %08x, %08x, %i)", mpeg, auAddr, bufferAddr, init); SceMpegAu atracAu; From 8ccc7996b038ae80ece65b60a18f619f46e45d56 Mon Sep 17 00:00:00 2001 From: shenweip <1037567878@qq.com> Date: Sun, 5 Jan 2020 22:37:29 +0800 Subject: [PATCH 35/35] Don't check auAddr. --- Core/HLE/sceMpeg.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Core/HLE/sceMpeg.cpp b/Core/HLE/sceMpeg.cpp index 4f7e119e4e..5243c76f03 100644 --- a/Core/HLE/sceMpeg.cpp +++ b/Core/HLE/sceMpeg.cpp @@ -1898,7 +1898,7 @@ static u32 sceMpegAtracDecode(u32 mpeg, u32 auAddr, u32 bufferAddr, int init) return -1; } - if (!Memory::IsValidAddress(bufferAddr) || !Memory::IsValidAddress(auAddr)) { + if (!Memory::IsValidAddress(bufferAddr)) { WARN_LOG(ME, "sceMpegAtracDecode(%08x, %08x, %08x, %i): invalid addresses", mpeg, auAddr, bufferAddr, init); return -1; }