mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-14 15:00:30 +02:00
Enable ImDebugger everywhere, on top of the regular UI.
This commit is contained in:
1 parent
ca3fc0fa9e
commit
db8ff4391e
7 files changed
+311
-263
No files matched your search
@@ -48,6 +48,9 @@ public:
|
|||||||
|
|
||||||
virtual bool AllowKeyboardNavigation() const { return true; }
|
virtual bool AllowKeyboardNavigation() const { return true; }
|
||||||
|
|
||||||
|
// Process keyboard shortcuts even outside the game.
|
||||||
|
virtual InputMode PassInputToMapper() const { return InputMode::Keyboard; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void CreateViews() = 0;
|
virtual void CreateViews() = 0;
|
||||||
virtual bool AllowFocusMovement() const { return true; }
|
virtual bool AllowFocusMovement() const { return true; }
|
||||||
|
|||||||
@@ -179,8 +179,12 @@ bool PortManager::Initialize(const unsigned int timeout) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Using Game ID & Player Name as default description for mapping
|
// Using Game ID & Player Name as default description for mapping
|
||||||
std::string gameID = g_paramSFO.GetDiscID();
|
if (PSP_IsInited()) {
|
||||||
m_defaultDesc = "PPSSPP:" + gameID + ":" + g_Config.sNickName; // Some routers may automatically prefixed it with "UPnP:"
|
std::string gameID = g_paramSFO.GetDiscID();
|
||||||
|
m_defaultDesc = "PPSSPP:" + gameID + ":" + g_Config.sNickName; // Some routers may automatically prefixed it with "UPnP:"
|
||||||
|
} else {
|
||||||
|
m_defaultDesc = "PPSSPP:at_menu:" + g_Config.sNickName;
|
||||||
|
}
|
||||||
|
|
||||||
freeUPNPDevlist(devlist);
|
freeUPNPDevlist(devlist);
|
||||||
|
|
||||||
|
|||||||
+4
-165
@@ -75,7 +75,6 @@ using namespace std::placeholders;
|
|||||||
#include "Core/RetroAchievements.h"
|
#include "Core/RetroAchievements.h"
|
||||||
#include "Core/SaveState.h"
|
#include "Core/SaveState.h"
|
||||||
#include "Core/Screenshot.h"
|
#include "Core/Screenshot.h"
|
||||||
#include "UI/ImDebugger/ImDebugger.h"
|
|
||||||
#include "Core/HLE/__sceAudio.h"
|
#include "Core/HLE/__sceAudio.h"
|
||||||
#include "Core/HW/Display.h"
|
#include "Core/HW/Display.h"
|
||||||
|
|
||||||
@@ -98,12 +97,6 @@ using namespace std::placeholders;
|
|||||||
#include "UI/ChatScreen.h"
|
#include "UI/ChatScreen.h"
|
||||||
#include "UI/DebugOverlay.h"
|
#include "UI/DebugOverlay.h"
|
||||||
|
|
||||||
#include "ext/imgui/imgui.h"
|
|
||||||
#include "ext/imgui/imgui_internal.h"
|
|
||||||
#include "ext/imgui/imgui_impl_thin3d.h"
|
|
||||||
#include "ext/imgui/imgui_impl_platform.h"
|
|
||||||
|
|
||||||
|
|
||||||
#if PPSSPP_PLATFORM(WINDOWS) && !PPSSPP_PLATFORM(UWP)
|
#if PPSSPP_PLATFORM(WINDOWS) && !PPSSPP_PLATFORM(UWP)
|
||||||
#include "Windows/MainWindow.h"
|
#include "Windows/MainWindow.h"
|
||||||
#endif
|
#endif
|
||||||
@@ -114,15 +107,6 @@ static AVIDump avi;
|
|||||||
|
|
||||||
extern bool g_TakeScreenshot;
|
extern bool g_TakeScreenshot;
|
||||||
|
|
||||||
static void AssertCancelCallback(const char *message, void *userdata) {
|
|
||||||
NOTICE_LOG(Log::CPU, "Broke after assert: %s", message);
|
|
||||||
Core_Break(BreakReason::AssertChoice);
|
|
||||||
g_Config.bShowImDebugger = true;
|
|
||||||
|
|
||||||
EmuScreen *emuScreen = (EmuScreen *)userdata;
|
|
||||||
emuScreen->SendImDebuggerCommand(ImCommand{ ImCmd::SHOW_IN_CPU_DISASM, currentMIPS->pc });
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handles control rotation due to internal screen rotation.
|
// Handles control rotation due to internal screen rotation.
|
||||||
void EmuScreen::UpdatePSPButtons(uint32_t bitsToSet, uint32_t bitsToClear) {
|
void EmuScreen::UpdatePSPButtons(uint32_t bitsToSet, uint32_t bitsToClear) {
|
||||||
if (!IsOnTop()) {
|
if (!IsOnTop()) {
|
||||||
@@ -283,8 +267,6 @@ void EmuScreen::ProcessGameBoot(const Path &filename) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
SetAssertCancelCallback(&AssertCancelCallback, this);
|
|
||||||
|
|
||||||
if (!g_Config.bShaderCache) {
|
if (!g_Config.bShaderCache) {
|
||||||
// Only developers should ever see this.
|
// Only developers should ever see this.
|
||||||
g_OSD.Show(OSDType::MESSAGE_WARNING, "Shader cache is disabled (developer)");
|
g_OSD.Show(OSDType::MESSAGE_WARNING, "Shader cache is disabled (developer)");
|
||||||
@@ -454,11 +436,6 @@ void EmuScreen::bootComplete() {
|
|||||||
EmuScreen::~EmuScreen() {
|
EmuScreen::~EmuScreen() {
|
||||||
g_controlMapper.RemoveListener(this);
|
g_controlMapper.RemoveListener(this);
|
||||||
|
|
||||||
if (imguiInited_) {
|
|
||||||
ImGui_ImplThin3d_Shutdown();
|
|
||||||
ImGui::DestroyContext(ctx_);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string gameID = g_paramSFO.GetValueString("DISC_ID");
|
std::string gameID = g_paramSFO.GetValueString("DISC_ID");
|
||||||
g_Config.TimeTracker().Stop(gameID);
|
g_Config.TimeTracker().Stop(gameID);
|
||||||
|
|
||||||
@@ -533,9 +510,6 @@ void EmuScreen::dialogFinished(const Screen *dialog, DialogResult result) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
SetExtraAssertInfo(extraAssertInfoStr_.c_str());
|
SetExtraAssertInfo(extraAssertInfoStr_.c_str());
|
||||||
|
|
||||||
// Make sure we re-enable keyboard mode if it was disabled by the dialog, and if needed.
|
|
||||||
lastImguiEnabled_ = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuScreen::focusChanged(ScreenFocusChange focusChange) {
|
void EmuScreen::focusChanged(ScreenFocusChange focusChange) {
|
||||||
@@ -771,11 +745,6 @@ void EmuScreen::ProcessVKey(VirtKey virtKey, bool down) {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case VIRTKEY_TOGGLE_DEBUGGER:
|
|
||||||
if (down) {
|
|
||||||
g_Config.bShowImDebugger = !g_Config.bShowImDebugger;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case VIRTKEY_TOGGLE_TILT:
|
case VIRTKEY_TOGGLE_TILT:
|
||||||
if (down) {
|
if (down) {
|
||||||
g_Config.bTiltInputEnabled = !g_Config.bTiltInputEnabled;
|
g_Config.bTiltInputEnabled = !g_Config.bTiltInputEnabled;
|
||||||
@@ -1160,27 +1129,12 @@ InputMode EmuScreen::PassInputToMapper() const {
|
|||||||
return InputMode::None;
|
return InputMode::None;
|
||||||
}
|
}
|
||||||
|
|
||||||
InputMode modes = InputMode::Keyboard | InputMode::Mouse | InputMode::Other | InputMode::ImDebuggerToggle;
|
return InputMode::Keyboard | InputMode::Mouse | InputMode::Other | InputMode::ImDebuggerToggle;
|
||||||
if (g_Config.bShowImDebugger && imguiInited_) {
|
|
||||||
if (ImGui::GetIO().WantCaptureKeyboard) {
|
|
||||||
modes &= ~InputMode::Keyboard;
|
|
||||||
}
|
|
||||||
if (ImGui::GetIO().WantCaptureMouse) {
|
|
||||||
modes &= ~InputMode::Mouse;
|
|
||||||
}
|
|
||||||
return modes;
|
|
||||||
}
|
|
||||||
|
|
||||||
return modes;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EmuScreen::key(const KeyInput &key) {
|
bool EmuScreen::key(const KeyInput &key) {
|
||||||
bool retval = UIScreen::key(key);
|
bool retval = UIScreen::key(key);
|
||||||
|
|
||||||
if (!retval && g_Config.bShowImDebugger && imguiInited_) {
|
|
||||||
ImGui_ImplPlatform_KeyEvent(key);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!retval && (key.flags & KeyInputFlags::DOWN) != 0 && UI::IsEscapeKey(key)) {
|
if (!retval && (key.flags & KeyInputFlags::DOWN) != 0 && UI::IsEscapeKey(key)) {
|
||||||
if (chatMenu_)
|
if (chatMenu_)
|
||||||
chatMenu_->Close();
|
chatMenu_->Close();
|
||||||
@@ -1206,18 +1160,13 @@ bool EmuScreen::touch(const TouchInput &touch) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (touch.flags & TouchInputFlags::DOWN) {
|
if (touch.flags & TouchInputFlags::DOWN) {
|
||||||
if (!(g_Config.bShowImDebugger && imguiInited_) && !ignoreGamepad) {
|
if (!g_Config.bShowImDebugger && !ignoreGamepad) {
|
||||||
// This just prevents the gamepad from timing out.
|
// This just prevents the gamepad from timing out.
|
||||||
GamepadTouch();
|
GamepadTouch();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_Config.bShowImDebugger && imguiInited_) {
|
if (g_Config.bMouseControl && !(touch.flags & TouchInputFlags::UP) && (touch.flags & TouchInputFlags::MOUSE)) {
|
||||||
ImGui_ImplPlatform_TouchEvent(touch);
|
|
||||||
if (!ImGui::GetIO().WantCaptureMouse) {
|
|
||||||
return UIScreen::touch(touch);
|
|
||||||
}
|
|
||||||
} else if (g_Config.bMouseControl && !(touch.flags & TouchInputFlags::UP) && (touch.flags & TouchInputFlags::MOUSE)) {
|
|
||||||
// don't do anything as the mouse pointer is hidden in this case.
|
// don't do anything as the mouse pointer is hidden in this case.
|
||||||
// But we let touch-up events through to avoid getting stuck if the user toggles mouse control.
|
// But we let touch-up events through to avoid getting stuck if the user toggles mouse control.
|
||||||
} else {
|
} else {
|
||||||
@@ -1385,20 +1334,10 @@ void EmuScreen::deviceLost() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
UIScreen::deviceLost();
|
UIScreen::deviceLost();
|
||||||
|
|
||||||
if (imguiInited_) {
|
|
||||||
if (imDebugger_) {
|
|
||||||
imDebugger_->DeviceLost();
|
|
||||||
}
|
|
||||||
ImGui_ImplThin3d_DestroyDeviceObjects();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuScreen::deviceRestored(Draw::DrawContext *draw) {
|
void EmuScreen::deviceRestored(Draw::DrawContext *draw) {
|
||||||
UIScreen::deviceRestored(draw);
|
UIScreen::deviceRestored(draw);
|
||||||
if (imguiInited_) {
|
|
||||||
ImGui_ImplThin3d_CreateDeviceObjects(draw);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuScreen::OnDevTools(UI::EventParams ¶ms) {
|
void EmuScreen::OnDevTools(UI::EventParams ¶ms) {
|
||||||
@@ -1707,7 +1646,6 @@ ScreenRenderFlags EmuScreen::render(ScreenRenderMode mode) {
|
|||||||
Draw::BackendState state = draw->GetCurrentBackendState();
|
Draw::BackendState state = draw->GetCurrentBackendState();
|
||||||
|
|
||||||
if (!(mode & ScreenRenderMode::TOP)) {
|
if (!(mode & ScreenRenderMode::TOP)) {
|
||||||
renderImDebugger();
|
|
||||||
// We're in run-behind mode, but we don't want to draw chat, debug UI and stuff. We do draw the imdebugger though.
|
// We're in run-behind mode, but we don't want to draw chat, debug UI and stuff. We do draw the imdebugger though.
|
||||||
// So, darken and bail here.
|
// So, darken and bail here.
|
||||||
// Reset viewport/scissor to be sure.
|
// Reset viewport/scissor to be sure.
|
||||||
@@ -1735,7 +1673,7 @@ ScreenRenderFlags EmuScreen::render(ScreenRenderMode mode) {
|
|||||||
SetVRAppMode(screenManager()->topScreen() == this ? VRAppMode::VR_GAME_MODE : VRAppMode::VR_DIALOG_MODE);
|
SetVRAppMode(screenManager()->topScreen() == this ? VRAppMode::VR_GAME_MODE : VRAppMode::VR_DIALOG_MODE);
|
||||||
}
|
}
|
||||||
|
|
||||||
renderImDebugger();
|
// renderImDebugger();
|
||||||
return screenRenderFlags;
|
return screenRenderFlags;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1859,108 +1797,9 @@ ScreenRenderFlags EmuScreen::RunEmulation(bool skipBufferEffects) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
runImDebugger();
|
|
||||||
|
|
||||||
return flags;
|
return flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EmuScreen::runImDebugger() {
|
|
||||||
if (!lastImguiEnabled_ && g_Config.bShowImDebugger) {
|
|
||||||
#if !defined(MOBILE_DEVICE)
|
|
||||||
// On mobile devices (specifically iOS) we don't want to pop the keyboard
|
|
||||||
// on activating imgui. Instead, we should do it when a text edit field in imgui gets focus,
|
|
||||||
// although we'll still have ugly overlap problems.
|
|
||||||
System_NotifyUIEvent(UIEventNotification::TEXT_GOTFOCUS);
|
|
||||||
#endif
|
|
||||||
VERBOSE_LOG(Log::System, "activating keyboard");
|
|
||||||
} else if (lastImguiEnabled_ && !g_Config.bShowImDebugger) {
|
|
||||||
System_NotifyUIEvent(UIEventNotification::TEXT_LOSTFOCUS);
|
|
||||||
VERBOSE_LOG(Log::System, "deactivating keyboard");
|
|
||||||
}
|
|
||||||
lastImguiEnabled_ = g_Config.bShowImDebugger;
|
|
||||||
if (g_Config.bShowImDebugger) {
|
|
||||||
Draw::DrawContext *draw = screenManager()->getDrawContext();
|
|
||||||
if (!imguiInited_) {
|
|
||||||
// TODO: Do this only on demand.
|
|
||||||
IMGUI_CHECKVERSION();
|
|
||||||
ctx_ = ImGui::CreateContext();
|
|
||||||
|
|
||||||
ImGui_ImplPlatform_Init(GetSysDirectory(DIRECTORY_SYSTEM) / "imgui.ini");
|
|
||||||
imDebugger_ = std::make_unique<ImDebugger>();
|
|
||||||
|
|
||||||
// Read the TTF font
|
|
||||||
size_t propSize = 0;
|
|
||||||
const uint8_t *propFontData = g_VFS.ReadFile("Roboto_Condensed-Regular.ttf", &propSize);
|
|
||||||
size_t fixedSize = 0;
|
|
||||||
const uint8_t *fixedFontData = g_VFS.ReadFile("Inconsolata-Regular.ttf", &fixedSize);
|
|
||||||
// This call works even if fontData is nullptr, in which case the font just won't get loaded.
|
|
||||||
// This takes ownership of the font array.
|
|
||||||
ImGui_ImplThin3d_Init(draw, propFontData, propSize, fixedFontData, fixedSize);
|
|
||||||
imguiInited_ = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (PSP_IsInited()) {
|
|
||||||
_dbg_assert_(imDebugger_);
|
|
||||||
|
|
||||||
ImGui_ImplPlatform_NewFrame();
|
|
||||||
ImGui_ImplThin3d_NewFrame(draw, ui_draw2d.GetDrawMatrix());
|
|
||||||
|
|
||||||
ImGui::NewFrame();
|
|
||||||
|
|
||||||
if (imCmd_.cmd != ImCmd::NONE) {
|
|
||||||
imDebugger_->PostCmd(imCmd_);
|
|
||||||
imCmd_.cmd = ImCmd::NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update keyboard modifiers.
|
|
||||||
auto &io = ImGui::GetIO();
|
|
||||||
|
|
||||||
KeyModifier modifiers = NativeGetKeyModifiers();
|
|
||||||
|
|
||||||
const bool keyCtrl = (modifiers & KeyModifier::LCTRL) || (modifiers & KeyModifier::RCTRL);
|
|
||||||
const bool keyShift = (modifiers & KeyModifier::LSHIFT) || (modifiers & KeyModifier::RSHIFT);
|
|
||||||
const bool keyAlt = (modifiers & KeyModifier::LALT) || (modifiers & KeyModifier::RALT);
|
|
||||||
io.AddKeyEvent(ImGuiMod_Ctrl, keyCtrl);
|
|
||||||
io.AddKeyEvent(ImGuiMod_Shift, keyShift);
|
|
||||||
io.AddKeyEvent(ImGuiMod_Alt, keyAlt);
|
|
||||||
// io.AddKeyEvent(ImGuiMod_Super, e.key.super);
|
|
||||||
|
|
||||||
ImGuiID dockID = ImGui::DockSpaceOverViewport(0, ImGui::GetMainViewport(), ImGuiDockNodeFlags_PassthruCentralNode | ImGuiDockNodeFlags_NoDockingOverCentralNode);
|
|
||||||
ImGuiDockNode* node = ImGui::DockBuilderGetCentralNode(dockID);
|
|
||||||
|
|
||||||
// Not elegant! But don't know how else to pass through the bounds, without making a mess.
|
|
||||||
Bounds centralNode(node->Pos.x, node->Pos.y, node->Size.x, node->Size.y);
|
|
||||||
SetOverrideScreenFrame(¢ralNode);
|
|
||||||
|
|
||||||
if (!io.WantCaptureKeyboard) {
|
|
||||||
// Draw a focus rectangle to indicate inputs will be passed through.
|
|
||||||
ImGui::GetBackgroundDrawList()->AddRect
|
|
||||||
(
|
|
||||||
node->Pos,
|
|
||||||
{ node->Pos.x + node->Size.x, node->Pos.y + node->Size.y },
|
|
||||||
IM_COL32(255, 255, 255, 90),
|
|
||||||
0.f,
|
|
||||||
ImDrawFlags_None,
|
|
||||||
1.f
|
|
||||||
);
|
|
||||||
}
|
|
||||||
imDebugger_->Frame(currentDebugMIPS, gpu, draw);
|
|
||||||
|
|
||||||
// Convert to drawlists.
|
|
||||||
ImGui::Render();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EmuScreen::renderImDebugger() {
|
|
||||||
if (g_Config.bShowImDebugger) {
|
|
||||||
Draw::DrawContext *draw = screenManager()->getDrawContext();
|
|
||||||
if (PSP_IsInited() && imDebugger_) {
|
|
||||||
ImGui_ImplThin3d_RenderDrawData(ImGui::GetDrawData(), draw);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EmuScreen::hasVisibleUI() {
|
bool EmuScreen::hasVisibleUI() {
|
||||||
// Regular but uncommon UI.
|
// Regular but uncommon UI.
|
||||||
if (saveStatePreview_->GetVisibility() != UI::V_GONE || loadingSpinner_->GetVisibility() == UI::V_VISIBLE)
|
if (saveStatePreview_->GetVisibility() != UI::V_GONE || loadingSpinner_->GetVisibility() == UI::V_VISIBLE)
|
||||||
|
|||||||
@@ -61,10 +61,6 @@ public:
|
|||||||
void deviceLost() override;
|
void deviceLost() override;
|
||||||
void deviceRestored(Draw::DrawContext *draw) override;
|
void deviceRestored(Draw::DrawContext *draw) override;
|
||||||
|
|
||||||
void SendImDebuggerCommand(const ImCommand &command) {
|
|
||||||
imCmd_ = command;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void darken();
|
void darken();
|
||||||
void focusChanged(ScreenFocusChange focusChange) override;
|
void focusChanged(ScreenFocusChange focusChange) override;
|
||||||
@@ -91,9 +87,6 @@ private:
|
|||||||
void bootComplete();
|
void bootComplete();
|
||||||
bool hasVisibleUI();
|
bool hasVisibleUI();
|
||||||
void renderUI();
|
void renderUI();
|
||||||
void runImDebugger();
|
|
||||||
void renderImDebugger();
|
|
||||||
|
|
||||||
|
|
||||||
void AutoLoadSaveState();
|
void AutoLoadSaveState();
|
||||||
bool checkPowerDown();
|
bool checkPowerDown();
|
||||||
@@ -141,18 +134,9 @@ private:
|
|||||||
|
|
||||||
std::string extraAssertInfoStr_;
|
std::string extraAssertInfoStr_;
|
||||||
|
|
||||||
std::unique_ptr<ImDebugger> imDebugger_;
|
|
||||||
ImCommand imCmd_{}; // needed to buffer commands in case imgui wasn't created yet.
|
|
||||||
|
|
||||||
bool imguiInited_ = false;
|
|
||||||
|
|
||||||
bool lastImguiEnabled_ = false;
|
|
||||||
|
|
||||||
std::mutex queuedVirtKeysLock_;
|
std::mutex queuedVirtKeysLock_;
|
||||||
std::vector<std::pair<VirtKey, bool>> queuedVirtKeys_;
|
std::vector<std::pair<VirtKey, bool>> queuedVirtKeys_;
|
||||||
|
|
||||||
ImGuiContext *ctx_ = nullptr;
|
|
||||||
|
|
||||||
bool frameStep_ = false;
|
bool frameStep_ = false;
|
||||||
#ifndef MOBILE_DEVICE
|
#ifndef MOBILE_DEVICE
|
||||||
bool startDumping_ = false;
|
bool startDumping_ = false;
|
||||||
|
|||||||
@@ -2363,19 +2363,21 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUCommon *gpuDebug, Draw:
|
|||||||
|
|
||||||
// Watch the step counters to figure out when to update things.
|
// Watch the step counters to figure out when to update things.
|
||||||
|
|
||||||
if (lastCpuStepCount_ != Core_GetSteppingCounter()) {
|
if (PSP_IsInited()) {
|
||||||
lastCpuStepCount_ = Core_GetSteppingCounter();
|
if (lastCpuStepCount_ != Core_GetSteppingCounter()) {
|
||||||
snapshot_ = newSnapshot_; // Compare against the previous snapshot.
|
lastCpuStepCount_ = Core_GetSteppingCounter();
|
||||||
Snapshot(currentMIPS);
|
snapshot_ = newSnapshot_; // Compare against the previous snapshot.
|
||||||
disasm_.NotifyStep();
|
Snapshot(currentMIPS);
|
||||||
}
|
disasm_.NotifyStep();
|
||||||
|
}
|
||||||
|
|
||||||
if (lastGpuStepCount_ != GPUStepping::GetSteppingCounter()) {
|
if (gpuDebug && lastGpuStepCount_ != GPUStepping::GetSteppingCounter()) {
|
||||||
// A GPU step has happened since last time. This means that we should re-center the cursor.
|
// A GPU step has happened since last time. This means that we should re-center the cursor.
|
||||||
// Snapshot();
|
// Snapshot();
|
||||||
lastGpuStepCount_ = GPUStepping::GetSteppingCounter();
|
lastGpuStepCount_ = GPUStepping::GetSteppingCounter();
|
||||||
SnapshotGPU(gpuDebug);
|
SnapshotGPU(gpuDebug);
|
||||||
geDebugger_.NotifyStep();
|
geDebugger_.NotifyStep();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ImControl control{};
|
ImControl control{};
|
||||||
@@ -2645,12 +2647,14 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUCommon *gpuDebug, Draw:
|
|||||||
atracToolWindow_.Draw(cfg_);
|
atracToolWindow_.Draw(cfg_);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cfg_.framebuffersOpen) {
|
if (gpuDebug) {
|
||||||
DrawFramebuffersWindow(cfg_, gpuDebug->GetFramebufferManagerCommon());
|
if (cfg_.framebuffersOpen) {
|
||||||
}
|
DrawFramebuffersWindow(cfg_, gpuDebug->GetFramebufferManagerCommon());
|
||||||
|
}
|
||||||
|
|
||||||
if (cfg_.texturesOpen) {
|
if (cfg_.texturesOpen) {
|
||||||
DrawTexturesWindow(cfg_, gpuDebug->GetTextureCacheCommon());
|
DrawTexturesWindow(cfg_, gpuDebug->GetTextureCacheCommon());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cfg_.logConfigOpen) {
|
if (cfg_.logConfigOpen) {
|
||||||
@@ -2661,78 +2665,82 @@ void ImDebugger::Frame(MIPSDebugInterface *mipsDebug, GPUCommon *gpuDebug, Draw:
|
|||||||
logWindow_.Draw(cfg_);
|
logWindow_.Draw(cfg_);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cfg_.jitViewerOpen) {
|
if (PSP_IsInited()) {
|
||||||
jitViewer_.Draw(cfg_, control);
|
if (cfg_.jitViewerOpen) {
|
||||||
}
|
jitViewer_.Draw(cfg_, control);
|
||||||
|
}
|
||||||
|
|
||||||
if (cfg_.displayOpen) {
|
if (cfg_.displayOpen) {
|
||||||
DrawDisplayWindow(cfg_, gpuDebug->GetFramebufferManagerCommon());
|
DrawDisplayWindow(cfg_, gpuDebug->GetFramebufferManagerCommon());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cfg_.debugStatsOpen) {
|
if (cfg_.debugStatsOpen) {
|
||||||
DrawDebugStatsWindow(cfg_);
|
DrawDebugStatsWindow(cfg_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cfg_.structViewerOpen) {
|
if (cfg_.structViewerOpen) {
|
||||||
structViewer_.Draw(cfg_, control, mipsDebug);
|
structViewer_.Draw(cfg_, control, mipsDebug);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cfg_.paramSFOOpen) {
|
if (PSP_IsInited()) {
|
||||||
DrawParamSFO(cfg_, control);
|
if (cfg_.paramSFOOpen) {
|
||||||
}
|
DrawParamSFO(cfg_, control);
|
||||||
|
|
||||||
if (cfg_.geDebuggerOpen) {
|
|
||||||
geDebugger_.Draw(cfg_, control, gpuDebug, draw);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cfg_.geStateOpen) {
|
|
||||||
geStateWindow_.Draw(cfg_, control, gpuDebug);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cfg_.geVertsOpen) {
|
|
||||||
DrawImGeVertsWindow(cfg_, control, gpuDebug);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cfg_.schedulerOpen) {
|
|
||||||
DrawSchedulerView(cfg_);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cfg_.timeOpen) {
|
|
||||||
DrawTimeView(cfg_);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cfg_.pixelViewerOpen) {
|
|
||||||
pixelViewer_.Draw(cfg_, control, gpuDebug, draw);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cfg_.memDumpOpen) {
|
|
||||||
memDumpWindow_.Draw(cfg_, mipsDebug);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cfg_.watchOpen) {
|
|
||||||
watchWindow_.Draw(cfg_, control, mipsDebug);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < 4; i++) {
|
|
||||||
if (cfg_.memViewOpen[i]) {
|
|
||||||
mem_[i].Draw(mipsDebug, cfg_, control, i);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (cfg_.socketsOpen) {
|
if (cfg_.geDebuggerOpen) {
|
||||||
DrawSockets(cfg_);
|
geDebugger_.Draw(cfg_, control, gpuDebug, draw);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cfg_.npOpen) {
|
if (cfg_.geStateOpen) {
|
||||||
DrawNp(cfg_);
|
geStateWindow_.Draw(cfg_, control, gpuDebug);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cfg_.adhocOpen) {
|
if (cfg_.geVertsOpen) {
|
||||||
DrawAdhoc(cfg_);
|
DrawImGeVertsWindow(cfg_, control, gpuDebug);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cfg_.apctlOpen) {
|
if (cfg_.schedulerOpen) {
|
||||||
DrawApctl(cfg_);
|
DrawSchedulerView(cfg_);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg_.timeOpen) {
|
||||||
|
DrawTimeView(cfg_);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg_.pixelViewerOpen) {
|
||||||
|
pixelViewer_.Draw(cfg_, control, gpuDebug, draw);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg_.memDumpOpen) {
|
||||||
|
memDumpWindow_.Draw(cfg_, mipsDebug);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg_.watchOpen) {
|
||||||
|
watchWindow_.Draw(cfg_, control, mipsDebug);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
if (cfg_.memViewOpen[i]) {
|
||||||
|
mem_[i].Draw(mipsDebug, cfg_, control, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg_.socketsOpen) {
|
||||||
|
DrawSockets(cfg_);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg_.npOpen) {
|
||||||
|
DrawNp(cfg_);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg_.adhocOpen) {
|
||||||
|
DrawAdhoc(cfg_);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cfg_.apctlOpen) {
|
||||||
|
DrawApctl(cfg_);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cfg_.internalsOpen) {
|
if (cfg_.internalsOpen) {
|
||||||
|
|||||||
+12
-2
@@ -436,14 +436,24 @@ void ViewSearch::ApplySearchFilter(UI::ViewGroup *viewGroup, bool setKeyboardFoc
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool IsSearchableChar(int unichar) {
|
||||||
|
// 127 gets produced from Ctrl+Backspace on Windows for some reason.
|
||||||
|
return unichar >= 0x20 && unichar != 127;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool IsFirstSearchableChar(int unichar) {
|
||||||
|
// Don't allow spaces as the first character, it looks confusing (empty search field)
|
||||||
|
return IsSearchableChar(unichar) && unichar != ' ' && unichar != '`' && unichar != '.' && unichar != ',';
|
||||||
|
}
|
||||||
|
|
||||||
bool ViewSearch::Key(UI::ViewGroup *viewGroup, const KeyInput &input) {
|
bool ViewSearch::Key(UI::ViewGroup *viewGroup, const KeyInput &input) {
|
||||||
bool retval = false;
|
bool retval = false;
|
||||||
// Only one is visible at a time, so we can just grab all Char input.
|
// Only one is visible at a time, so we can just grab all Char input.
|
||||||
if (input.flags & KeyInputFlags::CHAR) {
|
if (input.flags & KeyInputFlags::CHAR) {
|
||||||
const int unichar = input.keyCode;
|
const int unichar = input.keyCode;
|
||||||
if (unichar >= 0x20 && unichar != 127) { // 127 gets produced from Ctrl+Backspace on Windows for some reason.
|
if (IsSearchableChar(unichar)) {
|
||||||
// Don't allow spaces as the first character, it looks confusing (empty search field)
|
// Don't allow spaces as the first character, it looks confusing (empty search field)
|
||||||
if (searchFilter.empty() && unichar == ' ') {
|
if (searchFilter.empty() && !IsFirstSearchableChar(unichar)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+202
-2
@@ -38,6 +38,13 @@
|
|||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
|
||||||
|
#include "ext/imgui/imgui.h"
|
||||||
|
#include "ext/imgui/imgui_internal.h"
|
||||||
|
#include "ext/imgui/imgui_impl_thin3d.h"
|
||||||
|
#include "ext/imgui/imgui_impl_platform.h"
|
||||||
|
|
||||||
|
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
#include "Windows/WindowsAudio.h"
|
#include "Windows/WindowsAudio.h"
|
||||||
#include "Windows/MainWindow.h"
|
#include "Windows/MainWindow.h"
|
||||||
@@ -121,6 +128,7 @@
|
|||||||
|
|
||||||
#include "GPU/GPUCommon.h"
|
#include "GPU/GPUCommon.h"
|
||||||
#include "GPU/Common/PresentationCommon.h"
|
#include "GPU/Common/PresentationCommon.h"
|
||||||
|
#include "UI/ImDebugger/ImDebugger.h"
|
||||||
#include "UI/AudioCommon.h"
|
#include "UI/AudioCommon.h"
|
||||||
#include "UI/Background.h"
|
#include "UI/Background.h"
|
||||||
#include "UI/BackgroundAudio.h"
|
#include "UI/BackgroundAudio.h"
|
||||||
@@ -139,7 +147,6 @@
|
|||||||
#include "UI/Theme.h"
|
#include "UI/Theme.h"
|
||||||
#include "UI/PauseScreen.h"
|
#include "UI/PauseScreen.h"
|
||||||
#include "UI/UIAtlas.h"
|
#include "UI/UIAtlas.h"
|
||||||
|
|
||||||
#if PPSSPP_PLATFORM(UWP)
|
#if PPSSPP_PLATFORM(UWP)
|
||||||
#include <dwrite_3.h>
|
#include <dwrite_3.h>
|
||||||
#include "UWP/UWPHelpers/InputHelpers.h"
|
#include "UWP/UWPHelpers/InputHelpers.h"
|
||||||
@@ -202,6 +209,32 @@ static bool g_nativeMainThreadReady = false;
|
|||||||
static std::mutex g_inputEventQueueLock;
|
static std::mutex g_inputEventQueueLock;
|
||||||
static std::vector<QueuedEvent> g_inputEventQueue;
|
static std::vector<QueuedEvent> g_inputEventQueue;
|
||||||
|
|
||||||
|
static std::unique_ptr<ImDebugger> imDebugger_;
|
||||||
|
static ImCommand imCmd_{}; // needed to buffer commands in case imgui wasn't created yet.
|
||||||
|
static bool imguiInited_ = false;
|
||||||
|
static bool lastImguiEnabled_ = false;
|
||||||
|
static ImGuiContext *ctx_ = nullptr;
|
||||||
|
|
||||||
|
class GlobalListener : public ControlListener {
|
||||||
|
virtual void OnVKey(VirtKey vkey, bool down) {
|
||||||
|
switch (vkey) {
|
||||||
|
case VIRTKEY_TOGGLE_DEBUGGER:
|
||||||
|
if (down) {
|
||||||
|
g_Config.bShowImDebugger = !g_Config.bShowImDebugger;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
GlobalListener g_globalListener;
|
||||||
|
|
||||||
|
static void AssertCancelCallback(const char *message, void *userdata) {
|
||||||
|
NOTICE_LOG(Log::CPU, "Broke after assert: %s", message);
|
||||||
|
Core_Break(BreakReason::AssertChoice);
|
||||||
|
g_Config.bShowImDebugger = true;
|
||||||
|
imCmd_ = ImCommand{ImCmd::SHOW_IN_CPU_DISASM, currentMIPS->pc};
|
||||||
|
}
|
||||||
|
|
||||||
static void ApplyAchievementsRuntimeSettings() {
|
static void ApplyAchievementsRuntimeSettings() {
|
||||||
auto *client = Achievements::GetClient();
|
auto *client = Achievements::GetClient();
|
||||||
if (!client) {
|
if (!client) {
|
||||||
@@ -261,6 +294,101 @@ static void RunAchievementsOverrideUpdate(std::function<void()> func) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void runImDebugger(Draw::DrawContext *draw) {
|
||||||
|
bool lastImguiEnabled_ = false; // temp
|
||||||
|
if (lastImguiEnabled_ && g_Config.bShowImDebugger) {
|
||||||
|
#if !defined(MOBILE_DEVICE)
|
||||||
|
// On mobile devices (specifically iOS) we don't want to pop the keyboard
|
||||||
|
// on activating imgui. Instead, we should do it when a text edit field in imgui gets focus,
|
||||||
|
// although we'll still have ugly overlap problems.
|
||||||
|
System_NotifyUIEvent(UIEventNotification::TEXT_GOTFOCUS);
|
||||||
|
#endif
|
||||||
|
VERBOSE_LOG(Log::System, "activating keyboard");
|
||||||
|
} else if (lastImguiEnabled_ && !g_Config.bShowImDebugger) {
|
||||||
|
System_NotifyUIEvent(UIEventNotification::TEXT_LOSTFOCUS);
|
||||||
|
VERBOSE_LOG(Log::System, "deactivating keyboard");
|
||||||
|
}
|
||||||
|
lastImguiEnabled_ = g_Config.bShowImDebugger;
|
||||||
|
if (g_Config.bShowImDebugger) {
|
||||||
|
if (!imguiInited_) {
|
||||||
|
// TODO: Do this only on demand.
|
||||||
|
IMGUI_CHECKVERSION();
|
||||||
|
ctx_ = ImGui::CreateContext();
|
||||||
|
|
||||||
|
ImGui_ImplPlatform_Init(GetSysDirectory(DIRECTORY_SYSTEM) / "imgui.ini");
|
||||||
|
imDebugger_ = std::make_unique<ImDebugger>();
|
||||||
|
|
||||||
|
// Read the TTF font
|
||||||
|
size_t propSize = 0;
|
||||||
|
const uint8_t *propFontData = g_VFS.ReadFile("Roboto_Condensed-Regular.ttf", &propSize);
|
||||||
|
size_t fixedSize = 0;
|
||||||
|
const uint8_t *fixedFontData = g_VFS.ReadFile("Inconsolata-Regular.ttf", &fixedSize);
|
||||||
|
// This call works even if fontData is nullptr, in which case the font just won't get loaded.
|
||||||
|
// This takes ownership of the font array.
|
||||||
|
ImGui_ImplThin3d_Init(draw, propFontData, propSize, fixedFontData, fixedSize);
|
||||||
|
imguiInited_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_dbg_assert_(imDebugger_);
|
||||||
|
|
||||||
|
ImGui_ImplPlatform_NewFrame();
|
||||||
|
ImGui_ImplThin3d_NewFrame(draw, ui_draw2d.GetDrawMatrix());
|
||||||
|
|
||||||
|
ImGui::NewFrame();
|
||||||
|
|
||||||
|
if (imCmd_.cmd != ImCmd::NONE) {
|
||||||
|
imDebugger_->PostCmd(imCmd_);
|
||||||
|
imCmd_.cmd = ImCmd::NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update keyboard modifiers.
|
||||||
|
auto &io = ImGui::GetIO();
|
||||||
|
|
||||||
|
KeyModifier modifiers = NativeGetKeyModifiers();
|
||||||
|
|
||||||
|
const bool keyCtrl = (modifiers & KeyModifier::LCTRL) || (modifiers & KeyModifier::RCTRL);
|
||||||
|
const bool keyShift = (modifiers & KeyModifier::LSHIFT) || (modifiers & KeyModifier::RSHIFT);
|
||||||
|
const bool keyAlt = (modifiers & KeyModifier::LALT) || (modifiers & KeyModifier::RALT);
|
||||||
|
io.AddKeyEvent(ImGuiMod_Ctrl, keyCtrl);
|
||||||
|
io.AddKeyEvent(ImGuiMod_Shift, keyShift);
|
||||||
|
io.AddKeyEvent(ImGuiMod_Alt, keyAlt);
|
||||||
|
// io.AddKeyEvent(ImGuiMod_Super, e.key.super);
|
||||||
|
|
||||||
|
ImGuiID dockID = ImGui::DockSpaceOverViewport(0, ImGui::GetMainViewport(), ImGuiDockNodeFlags_PassthruCentralNode | ImGuiDockNodeFlags_NoDockingOverCentralNode);
|
||||||
|
ImGuiDockNode* node = ImGui::DockBuilderGetCentralNode(dockID);
|
||||||
|
|
||||||
|
// Not elegant! But don't know how else to pass through the bounds, without making a mess.
|
||||||
|
Bounds centralNode(node->Pos.x, node->Pos.y, node->Size.x, node->Size.y);
|
||||||
|
SetOverrideScreenFrame(¢ralNode);
|
||||||
|
|
||||||
|
if (!io.WantCaptureKeyboard) {
|
||||||
|
// Draw a focus rectangle to indicate inputs will be passed through.
|
||||||
|
ImGui::GetBackgroundDrawList()->AddRect
|
||||||
|
(
|
||||||
|
node->Pos,
|
||||||
|
{node->Pos.x + node->Size.x, node->Pos.y + node->Size.y},
|
||||||
|
IM_COL32(255, 255, 255, 90),
|
||||||
|
0.f,
|
||||||
|
ImDrawFlags_None,
|
||||||
|
1.f
|
||||||
|
);
|
||||||
|
}
|
||||||
|
imDebugger_->Frame(currentDebugMIPS, gpu, draw);
|
||||||
|
|
||||||
|
// Convert to drawlists.
|
||||||
|
ImGui::Render();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void renderImDebugger(Draw::DrawContext *draw) {
|
||||||
|
if (g_Config.bShowImDebugger) {
|
||||||
|
if (imDebugger_) {
|
||||||
|
ImGui_ImplThin3d_RenderDrawData(ImGui::GetDrawData(), draw);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
std::vector<std::function<void()>> g_pendingClosures;
|
std::vector<std::function<void()>> g_pendingClosures;
|
||||||
|
|
||||||
AudioBackend *g_audioBackend = nullptr;
|
AudioBackend *g_audioBackend = nullptr;
|
||||||
@@ -395,6 +523,10 @@ void NativeInit(int argc, const char *argv[], const CommandLineOptions &cmdLineO
|
|||||||
|
|
||||||
g_Config.Init();
|
g_Config.Init();
|
||||||
|
|
||||||
|
g_controlMapper.AddListener(&g_globalListener);
|
||||||
|
|
||||||
|
SetAssertCancelCallback(&AssertCancelCallback, nullptr);
|
||||||
|
|
||||||
IncrementDebugCounter(DebugCounter::APP_BOOT);
|
IncrementDebugCounter(DebugCounter::APP_BOOT);
|
||||||
|
|
||||||
// Probably an excessive timeout. it only causes delays on shutdown, though.
|
// Probably an excessive timeout. it only causes delays on shutdown, though.
|
||||||
@@ -851,6 +983,11 @@ bool NativeInitGraphics(GraphicsContext *graphicsContext) {
|
|||||||
gpu->DeviceRestore(g_draw);
|
gpu->DeviceRestore(g_draw);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (imguiInited_) {
|
||||||
|
ImGui_ImplThin3d_CreateDeviceObjects(g_draw);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
INFO_LOG(Log::System, "NativeInitGraphics completed");
|
INFO_LOG(Log::System, "NativeInitGraphics completed");
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -922,6 +1059,15 @@ void NativeShutdownGraphics(GraphicsContext *graphicsContext) {
|
|||||||
gpu->DeviceLost();
|
gpu->DeviceLost();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (imguiInited_) {
|
||||||
|
if (imDebugger_) {
|
||||||
|
imDebugger_->DeviceLost();
|
||||||
|
}
|
||||||
|
ImGui_ImplThin3d_DestroyDeviceObjects();
|
||||||
|
ImGui_ImplThin3d_Shutdown();
|
||||||
|
ImGui::DestroyContext(ctx_);
|
||||||
|
}
|
||||||
|
|
||||||
#if PPSSPP_PLATFORM(WINDOWS) && !PPSSPP_PLATFORM(UWP)
|
#if PPSSPP_PLATFORM(WINDOWS) && !PPSSPP_PLATFORM(UWP)
|
||||||
if (winCamera) {
|
if (winCamera) {
|
||||||
winCamera->waitShutDown();
|
winCamera->waitShutDown();
|
||||||
@@ -1038,8 +1184,47 @@ void NativeFrame(GraphicsContext *graphicsContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (auto &event : inputEvents) {
|
for (auto &event : inputEvents) {
|
||||||
g_screenManager->ProcessInputEvent(event);
|
bool filterTouch = false;
|
||||||
|
bool filterKey = false;
|
||||||
|
if (g_Config.bShowImDebugger && imguiInited_) {
|
||||||
|
// Let ImGui handle input if it's active.
|
||||||
|
if (ImGui::GetIO().WantCaptureMouse) {
|
||||||
|
filterTouch = true;
|
||||||
|
}
|
||||||
|
if (ImGui::GetIO().WantCaptureKeyboard) {
|
||||||
|
filterKey = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (event.type) {
|
||||||
|
case QueuedEventType::KEY:
|
||||||
|
// Let through up events to avoid stuck keys.
|
||||||
|
if (!filterKey || (event.key.flags & KeyInputFlags::UP)) {
|
||||||
|
g_screenManager->ProcessInputEvent(event);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case QueuedEventType::TOUCH:
|
||||||
|
if (!filterTouch) {
|
||||||
|
g_screenManager->ProcessInputEvent(event);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
g_screenManager->ProcessInputEvent(event);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (g_Config.bShowImDebugger && imguiInited_) {
|
||||||
|
switch (event.type) {
|
||||||
|
case QueuedEventType::KEY:
|
||||||
|
ImGui_ImplPlatform_KeyEvent(event.key);
|
||||||
|
break;
|
||||||
|
case QueuedEventType::TOUCH:
|
||||||
|
ImGui_ImplPlatform_TouchEvent(event.touch);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
g_screenManager->Update(); // This must happen *after* input event processing!
|
g_screenManager->Update(); // This must happen *after* input event processing!
|
||||||
|
|
||||||
// Do this after g_screenManager.update() so we can receive setting changes before rendering.
|
// Do this after g_screenManager.update() so we can receive setting changes before rendering.
|
||||||
@@ -1111,6 +1296,8 @@ void NativeFrame(GraphicsContext *graphicsContext) {
|
|||||||
|
|
||||||
ui_draw2d.PopDrawMatrix();
|
ui_draw2d.PopDrawMatrix();
|
||||||
|
|
||||||
|
runImDebugger(g_draw);
|
||||||
|
renderImDebugger(g_draw);
|
||||||
g_draw->EndFrame();
|
g_draw->EndFrame();
|
||||||
|
|
||||||
// This, between EndFrame and Present, is where we should actually wait to do present time management.
|
// This, between EndFrame and Present, is where we should actually wait to do present time management.
|
||||||
@@ -1379,6 +1566,16 @@ bool NativeKey(const KeyInput &key) {
|
|||||||
|
|
||||||
// Filtering, detailed rules needed for good imgui behavior without having to ask the screen about what to do.
|
// Filtering, detailed rules needed for good imgui behavior without having to ask the screen about what to do.
|
||||||
InputMode inputMode = g_screenManager->PassInputToMapper();
|
InputMode inputMode = g_screenManager->PassInputToMapper();
|
||||||
|
|
||||||
|
if (g_Config.bShowImDebugger && imguiInited_) {
|
||||||
|
if (ImGui::GetIO().WantCaptureKeyboard) {
|
||||||
|
inputMode &= ~InputMode::Keyboard;
|
||||||
|
}
|
||||||
|
if (ImGui::GetIO().WantCaptureMouse) {
|
||||||
|
inputMode &= ~InputMode::Mouse;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool passKeyThrough = false;
|
bool passKeyThrough = false;
|
||||||
if (inputMode != InputMode::None) {
|
if (inputMode != InputMode::None) {
|
||||||
if ((inputMode & InputMode::ImDebuggerToggle) && (key.flags & (KeyInputFlags::UP | KeyInputFlags::DOWN))) {
|
if ((inputMode & InputMode::ImDebuggerToggle) && (key.flags & (KeyInputFlags::UP | KeyInputFlags::DOWN))) {
|
||||||
@@ -1394,6 +1591,7 @@ bool NativeKey(const KeyInput &key) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key.deviceId == DEVICE_ID_MOUSE) {
|
if (key.deviceId == DEVICE_ID_MOUSE) {
|
||||||
if (inputMode & InputMode::Mouse) {
|
if (inputMode & InputMode::Mouse) {
|
||||||
passKeyThrough = true;
|
passKeyThrough = true;
|
||||||
@@ -1637,6 +1835,8 @@ void NativeShutdown() {
|
|||||||
ClearAchievementsHostOverride();
|
ClearAchievementsHostOverride();
|
||||||
g_nativeMainThreadReady = false;
|
g_nativeMainThreadReady = false;
|
||||||
|
|
||||||
|
g_controlMapper.RemoveListener(&g_globalListener);
|
||||||
|
|
||||||
Achievements::Shutdown();
|
Achievements::Shutdown();
|
||||||
|
|
||||||
if (g_Config.bAchievementsEnable) {
|
if (g_Config.bAchievementsEnable) {
|
||||||
|
|||||||
Reference in new issue
Block a user