diff --git a/Core/Core.cpp b/Core/Core.cpp index 8edff61a3c..cd8ac9db31 100644 --- a/Core/Core.cpp +++ b/Core/Core.cpp @@ -71,7 +71,6 @@ static std::mutex m_hInactiveMutex; static int steppingCounter = 0; static std::set lifecycleFuncs; -static std::set stopFuncs; // This can be read and written from ANYWHERE. volatile CoreState coreState = CORE_STEPPING_CPU; @@ -106,16 +105,9 @@ void Core_NotifyLifecycle(CoreLifecycle stage) { } } -void Core_ListenStopRequest(CoreStopRequestFunc func) { - stopFuncs.insert(func); -} - void Core_Stop() { Core_ResetException(); Core_UpdateState(CORE_POWERDOWN); - for (auto func : stopFuncs) { - func(); - } } void Core_UpdateState(CoreState newState) { diff --git a/Core/Core.h b/Core/Core.h index ebcc8c249c..9f6f56dbe3 100644 --- a/Core/Core.h +++ b/Core/Core.h @@ -107,10 +107,6 @@ typedef void (* CoreLifecycleFunc)(CoreLifecycle stage); void Core_ListenLifecycle(CoreLifecycleFunc func); void Core_NotifyLifecycle(CoreLifecycle stage); -// Callback is executed on requesting thread. -typedef void (* CoreStopRequestFunc)(); -void Core_ListenStopRequest(CoreStopRequestFunc callback); - bool Core_IsStepping(); bool Core_IsActive(); diff --git a/Core/HLE/sceHttp.cpp b/Core/HLE/sceHttp.cpp index 0281af67eb..01f2c89037 100644 --- a/Core/HLE/sceHttp.cpp +++ b/Core/HLE/sceHttp.cpp @@ -289,27 +289,7 @@ int HTTPRequest::sendRequest(u32 postDataPtr, u32 postDataSize) { return 0; } -static void __HttpNotifyLifecycle(CoreLifecycle stage) { - if (stage == CoreLifecycle::STOPPING) { - for (const auto& it : httpObjects) { - if (it->className() == name_HTTPRequest) - (static_cast(it.get()))->abortRequest(); - } - } -} - -static void __HttpRequestStop() { - // This can happen from a separate thread. - std::lock_guard guard(httpLock); - for (const auto& it : httpObjects) { - if (it->className() == name_HTTPRequest) - (static_cast(it.get()))->abortRequest(); - } -} - void __HttpInit() { - Core_ListenLifecycle(&__HttpNotifyLifecycle); - Core_ListenStopRequest(&__HttpRequestStop); } void __HttpShutdown() { @@ -317,6 +297,11 @@ void __HttpShutdown() { httpInited = false; httpsInited = false; httpCacheInited = false; + + for (const auto& it : httpObjects) { + if (it->className() == name_HTTPRequest) + (static_cast(it.get()))->abortRequest(); + } httpObjects.clear(); } diff --git a/GPU/Debugger/Playback.cpp b/GPU/Debugger/Playback.cpp index e9122e796d..0807a7aabd 100644 --- a/GPU/Debugger/Playback.cpp +++ b/GPU/Debugger/Playback.cpp @@ -822,16 +822,6 @@ static bool ReadCompressed(u32 fp, void *dest, size_t sz, uint32_t version) { return real_size == sz; } -static void ReplayStop() { - _dbg_assert_(!replayThread.joinable()); - - // This can happen from a separate thread. - lastExecFilename.clear(); - lastExecCommands.clear(); - lastExecPushbuf.clear(); - lastExecVersion = 0; -} - static u32 LoadReplay(const std::string &filename) { PROFILE_THIS_SCOPE("ReplayLoad"); u32 fp = pspFileSystem.OpenFile(filename, FILEACCESS_READ); @@ -911,8 +901,6 @@ void WriteRunDumpCode(u32 codeStart) { ReplayResult RunMountedReplay(const std::string &filename) { _assert_msg_(!gpuDebug->GetRecorder()->IsActivePending(), "Cannot run replay while recording."); - Core_ListenStopRequest(&ReplayStop); - uint32_t version = lastExecVersion; if (lastExecFilename != filename) { // Does this ever happen? Can the filename change, without going through core shutdown/startup? diff --git a/GPU/Debugger/Playback.h b/GPU/Debugger/Playback.h index fe0af7c636..fefd2f9217 100644 --- a/GPU/Debugger/Playback.h +++ b/GPU/Debugger/Playback.h @@ -30,5 +30,6 @@ enum class ReplayResult { void WriteRunDumpCode(u32 addr); ReplayResult RunMountedReplay(const std::string &filename); +void ReplayShutdown(); } // namespace GPURecord diff --git a/UI/ImDebugger/ImDebugger.cpp b/UI/ImDebugger/ImDebugger.cpp index 5c5acc7840..8155acbe7f 100644 --- a/UI/ImDebugger/ImDebugger.cpp +++ b/UI/ImDebugger/ImDebugger.cpp @@ -4,6 +4,7 @@ #include "ext/imgui/imgui_internal.h" #include "Common/StringUtils.h" +#include "Common/File/FileUtil.h" #include "Common/Data/Format/IniFile.h" #include "Core/Config.h" #include "Core/System.h" @@ -403,17 +404,40 @@ void DrawThreadView(ImConfig &cfg, ImControl &control) { } // TODO: Add popup menu, export file, export dir, etc... -static void RecurseFileSystem(IFileSystem *fs, std::string path) { +static void RecurseFileSystem(IFileSystem *fs, std::string path, RequesterToken token) { std::vector fileInfo = fs->GetDirListing(path); for (auto &file : fileInfo) { if (file.type == FileType::FILETYPE_DIRECTORY) { if (file.name != "." && file.name != ".." && ImGui::TreeNode(file.name.c_str())) { std::string fpath = path + "/" + file.name; - RecurseFileSystem(fs, fpath); + RecurseFileSystem(fs, fpath, token); ImGui::TreePop(); } } else { - ImGui::TextUnformatted(file.name.c_str()); + ImGui::Selectable(file.name.c_str()); + if (ImGui::BeginPopupContextItem()) { + if (ImGui::MenuItem("Copy Path")) { + System_CopyStringToClipboard(path + "/" + file.name); + } + if (ImGui::MenuItem("Save file...")) { + std::string fullPath = path + "/" + file.name; + int size = file.size; + // save dialog + System_BrowseForFileSave(token, "Save file", file.name, BrowseFileType::ANY, [fullPath, fs, size](const char *responseString, int) { + int fd = fs->OpenFile(fullPath, FILEACCESS_READ); + if (fd >= 0) { + std::string data; + data.resize(size); + fs->ReadFile(fd, (u8 *)data.data(), size); + fs->CloseFile(fd); + Path dest(responseString); + File::WriteDataToFile(false, data.data(), data.size(), dest); + } + }); + } + // your popup code + ImGui::EndPopup(); + } } } } @@ -433,7 +457,7 @@ static void DrawFilesystemBrowser(ImConfig &cfg) { snprintf(fsTitle, sizeof(fsTitle), "%s - %s", fs.prefix.c_str(), desc); if (ImGui::TreeNode(fsTitle)) { auto system = fs.system; - RecurseFileSystem(system.get(), path); + RecurseFileSystem(system.get(), path, cfg.requesterToken); ImGui::TreePop(); } } @@ -1764,6 +1788,8 @@ Path ImDebugger::ConfigPath() { // But, I don't really want Core to know about the ImDebugger.. void ImConfig::LoadConfig(const Path &iniFile) { + requesterToken = g_requestManager.GenerateRequesterToken(); + IniFile ini; ini.Load(iniFile); // Ignore return value, might not exist yet. In that case we'll end up loading defaults. SyncConfig(&ini, false); diff --git a/UI/ImDebugger/ImDebugger.h b/UI/ImDebugger/ImDebugger.h index 915fef7caf..80f7d204fb 100644 --- a/UI/ImDebugger/ImDebugger.h +++ b/UI/ImDebugger/ImDebugger.h @@ -164,6 +164,7 @@ struct ImConfig { int breakCount = 0; bool displayLatched = false; + int requesterToken; // We use a separate ini file from the main PPSSPP config. void LoadConfig(const Path &iniFile); diff --git a/UI/ImDebugger/ImGe.cpp b/UI/ImDebugger/ImGe.cpp index 977ed0a2a6..6216741fa1 100644 --- a/UI/ImDebugger/ImGe.cpp +++ b/UI/ImDebugger/ImGe.cpp @@ -174,7 +174,7 @@ void ImGePixelViewerWindow::Draw(ImConfig &cfg, ImControl &control, GPUDebugInte ImGui::SameLine(); if (ImGui::BeginChild("right")) { ImVec2 p0 = ImGui::GetCursorScreenPos(); - viewer_.Draw(gpuDebug, draw); + viewer_.Draw(gpuDebug, draw, 1.0f); if (ImGui::IsItemHovered()) { int x = (int)(ImGui::GetMousePos().x - p0.x); int y = (int)(ImGui::GetMousePos().y - p0.y); @@ -197,7 +197,7 @@ ImGePixelViewer::~ImGePixelViewer() { texture_->Release(); } -bool ImGePixelViewer::Draw(GPUDebugInterface *gpuDebug, Draw::DrawContext *draw) { +bool ImGePixelViewer::Draw(GPUDebugInterface *gpuDebug, Draw::DrawContext *draw, float zoom) { if (dirty_) { UpdateTexture(draw); dirty_ = false; @@ -206,7 +206,7 @@ bool ImGePixelViewer::Draw(GPUDebugInterface *gpuDebug, Draw::DrawContext *draw) if (Memory::IsValid4AlignedAddress(addr)) { if (texture_) { ImTextureID texId = ImGui_ImplThin3d_AddTextureTemp(texture_, useAlpha ? ImGuiPipeline::TexturedAlphaBlend : ImGuiPipeline::TexturedOpaque); - ImGui::Image(texId, ImVec2((float)width, (float)height)); + ImGui::Image(texId, ImVec2((float)width * zoom, (float)height * zoom)); return true; } else { ImGui::Text("(invalid params: %dx%d, %08x)", width, height, addr); @@ -375,7 +375,7 @@ ImGeReadbackViewer::~ImGeReadbackViewer() { delete[] data_; } -bool ImGeReadbackViewer::Draw(GPUDebugInterface *gpuDebug, Draw::DrawContext *draw) { +bool ImGeReadbackViewer::Draw(GPUDebugInterface *gpuDebug, Draw::DrawContext *draw, float zoom) { FramebufferManagerCommon *fbmanager = gpuDebug->GetFramebufferManagerCommon(); if (!vfb || !vfb->fbo || !fbmanager) { ImGui::TextUnformatted("(N/A)"); @@ -454,7 +454,7 @@ bool ImGeReadbackViewer::Draw(GPUDebugInterface *gpuDebug, Draw::DrawContext *dr } else { texId = ImGui_ImplThin3d_AddFBAsTextureTemp(vfb->fbo, Draw::Aspect::COLOR_BIT, ImGuiPipeline::TexturedOpaque); } - ImGui::Image(texId, ImVec2((float)vfb->fbo->Width(), (float)vfb->fbo->Height())); + ImGui::Image(texId, ImVec2((float)vfb->fbo->Width() * zoom, (float)vfb->fbo->Height() * zoom)); return true; } @@ -857,7 +857,6 @@ void ImGeDebuggerWindow::Draw(ImConfig &cfg, ImControl &control, GPUDebugInterfa ImGui::EndDisabled(); } - ImGui::SameLine(); ImGui::Text("%d/%d", gpuDebug->PrimsThisFrame(), gpuDebug->PrimsLastFrame()); if (disableStepButtons) { @@ -881,26 +880,13 @@ void ImGeDebuggerWindow::Draw(ImConfig &cfg, ImControl &control, GPUDebugInterfa ImGui::EndDisabled(); } - // Line break - if (ImGui::Button("Goto PC")) { - disasmView_.GotoPC(); - } - ImGui::SameLine(); - if (ImGui::Button("Settings")) { - ImGui::OpenPopup("disSettings"); - } - if (ImGui::BeginPopup("disSettings")) { - ImGui::Checkbox("Follow PC", &disasmView_.followPC_); - ImGui::EndPopup(); - } - // Display any pending step event. if (gpuDebug->GetBreakNext() != GPUDebug::BreakNext::NONE && gpuDebug->GetBreakNext() != GPUDebug::BreakNext::DEBUG_RUN) { if (showBannerInFrames_ > 0) { showBannerInFrames_--; } if (showBannerInFrames_ == 0) { - ImGui::Text("Step pending (waiting for CPU): %s", GPUDebug::BreakNextToString(gpuDebug->GetBreakNext())); + ImGui::Text("Step pending: %s", GPUDebug::BreakNextToString(gpuDebug->GetBreakNext())); ImGui::SameLine(); if (gpuDebug->GetBreakNext() == GPUDebug::BreakNext::COUNT) { ImGui::Text("(%d)", gpuDebug->GetBreakCount()); @@ -914,6 +900,19 @@ void ImGeDebuggerWindow::Draw(ImConfig &cfg, ImControl &control, GPUDebugInterfa showBannerInFrames_ = 2; } + // Line break + if (ImGui::Button("Goto PC")) { + disasmView_.GotoPC(); + } + ImGui::SameLine(); + if (ImGui::Button("Settings")) { + ImGui::OpenPopup("disSettings"); + } + if (ImGui::BeginPopup("disSettings")) { + ImGui::Checkbox("Follow PC", &disasmView_.followPC_); + ImGui::EndPopup(); + } + // First, let's list any active display lists in the left column, on top of the disassembly. ImGui::BeginChild("left pane", ImVec2(400, 0), ImGuiChildFlags_Borders | ImGuiChildFlags_ResizeX); @@ -980,7 +979,7 @@ void ImGeDebuggerWindow::Draw(ImConfig &cfg, ImControl &control, GPUDebugInterfa } - ImGui::BeginChild("texture/fb view"); // Leave room for 1 line below us + ImGui::BeginChild("texture/fb view"); ImDrawList *drawList = ImGui::GetWindowDrawList(); @@ -1001,7 +1000,10 @@ void ImGeDebuggerWindow::Draw(ImConfig &cfg, ImControl &control, GPUDebugInterfa } else { ImGui::Text("Framebuffer"); } + ImGui::SameLine(); } + ImGui::SetNextItemWidth(200.0f); + ImGui::SliderFloat("Zoom", &previewZoom_, 0.125f, 2.f, "%.3f", ImGuiSliderFlags_Logarithmic); // Use selectable instead of tab bar so we can get events (haven't figured that out). static const Draw::Aspect aspects[3] = { Draw::Aspect::COLOR_BIT, Draw::Aspect::DEPTH_BIT, Draw::Aspect::STENCIL_BIT, }; @@ -1020,7 +1022,7 @@ void ImGeDebuggerWindow::Draw(ImConfig &cfg, ImControl &control, GPUDebugInterfa float maximum = 256.0f; ImGui::SameLine(); ImGui::SetNextItemWidth(200.0f); - if (ImGui::DragFloat("Z scale", &rbViewer_.scale, 1.0f, 0.5f, 256.0f, "%0.2f", ImGuiSliderFlags_Logarithmic)) { + if (ImGui::DragFloat("Z value scale", &rbViewer_.scale, 1.0f, 0.5f, 256.0f, "%0.2f", ImGuiSliderFlags_Logarithmic)) { rbViewer_.Snapshot(); swViewer_.Snapshot(); } @@ -1031,7 +1033,7 @@ void ImGeDebuggerWindow::Draw(ImConfig &cfg, ImControl &control, GPUDebugInterfa float scale = 1.0f; if (vfb && vfb->fbo) { scale = vfb->renderScaleFactor; - p1 = ImVec2(p0.x + vfb->fbo->Width(), p0.y + vfb->fbo->Height()); + p1 = ImVec2(p0.x + vfb->fbo->Width() * previewZoom_, p0.y + vfb->fbo->Height() * previewZoom_); } else { // Guess p1 = ImVec2(p0.x + swViewer_.width, p0.y + swViewer_.height); @@ -1042,23 +1044,23 @@ void ImGeDebuggerWindow::Draw(ImConfig &cfg, ImControl &control, GPUDebugInterfa PixelLookup *lookup = nullptr; if (vfb) { - rbViewer_.Draw(gpuDebug, draw); + rbViewer_.Draw(gpuDebug, draw, previewZoom_); lookup = &rbViewer_; // ImTextureID texId = ImGui_ImplThin3d_AddFBAsTextureTemp(vfb->fbo, Draw::Aspect::COLOR_BIT, ImGuiPipeline::TexturedOpaque); // ImGui::Image(texId, ImVec2(vfb->width, vfb->height)); } else { - swViewer_.Draw(gpuDebug, draw); + swViewer_.Draw(gpuDebug, draw, previewZoom_); lookup = &swViewer_; } // Draw vertex preview on top! - DrawPreviewPrimitive(drawList, p0, previewPrim_, previewIndices_, previewVertices_, previewCount_, false, scale, scale); + DrawPreviewPrimitive(drawList, p0, previewPrim_, previewIndices_, previewVertices_, previewCount_, false, scale * previewZoom_, scale * previewZoom_); drawList->PopClipRect(); if (ImGui::IsItemHovered()) { - int x = (int)(ImGui::GetMousePos().x - p0.x); - int y = (int)(ImGui::GetMousePos().y - p0.y); + int x = (int)(ImGui::GetMousePos().x - p0.x) * previewZoom_; + int y = (int)(ImGui::GetMousePos().y - p0.y) * previewZoom_; char temp[128]; if (lookup->FormatValueAt(temp, sizeof(temp), x, y)) { ImGui::Text("(%d, %d): %s", x, y, temp); diff --git a/UI/ImDebugger/ImGe.h b/UI/ImDebugger/ImGe.h index 38ac0e6d52..a68f52eac4 100644 --- a/UI/ImDebugger/ImGe.h +++ b/UI/ImDebugger/ImGe.h @@ -65,7 +65,7 @@ public: struct ImGePixelViewer : public PixelLookup { ~ImGePixelViewer(); - bool Draw(GPUDebugInterface *gpuDebug, Draw::DrawContext *draw); + bool Draw(GPUDebugInterface *gpuDebug, Draw::DrawContext *draw, float zoom); void Snapshot() { dirty_ = true; } @@ -90,7 +90,7 @@ private: struct ImGeReadbackViewer : public PixelLookup { ImGeReadbackViewer(); ~ImGeReadbackViewer(); - bool Draw(GPUDebugInterface *gpuDebug, Draw::DrawContext *); + bool Draw(GPUDebugInterface *gpuDebug, Draw::DrawContext *draw, float zoom); void Snapshot() { dirty_ = true; } @@ -152,4 +152,5 @@ private: std::vector previewVertices_; int previewCount_ = 0; Draw::Aspect selectedAspect_; + float previewZoom_ = 1.0f; };