diff --git a/Windows/Debugger/CtrlDisAsmView.cpp b/Windows/Debugger/CtrlDisAsmView.cpp index ce5f37e98..5a0e336c9 100644 --- a/Windows/Debugger/CtrlDisAsmView.cpp +++ b/Windows/Debugger/CtrlDisAsmView.cpp @@ -441,19 +441,15 @@ void CtrlDisAsmView::onVScroll(WPARAM wParam, LPARAM lParam) { case SB_LINEDOWN: windowStart += instructionSize; - curAddress += instructionSize; break; case SB_LINEUP: windowStart -= instructionSize; - curAddress -= instructionSize; break; case SB_PAGEDOWN: windowStart += visibleRows*instructionSize; - curAddress += visibleRows*instructionSize; break; case SB_PAGEUP: windowStart -= visibleRows*instructionSize; - curAddress -= visibleRows*instructionSize; break; default: return; @@ -509,35 +505,29 @@ void CtrlDisAsmView::onKeyDown(WPARAM wParam, LPARAM lParam) switch (wParam & 0xFFFF) { case VK_DOWN: - if (curAddress == windowEnd-instructionSize) - { - windowStart += instructionSize; - } curAddress += instructionSize; + scrollAddressIntoView(); break; case VK_UP: - if (curAddress == windowStart) - { - windowStart -= instructionSize; - } curAddress-=instructionSize; + scrollAddressIntoView(); break; case VK_NEXT: - if (curAddress != windowEnd-instructionSize) - { + if (curAddress != windowEnd-instructionSize && curAddressIsVisible()) { curAddress = windowEnd-instructionSize; + scrollAddressIntoView(); } else { - windowStart += visibleRows*instructionSize; curAddress += visibleRows*instructionSize; + scrollAddressIntoView(); } break; case VK_PRIOR: - if (curAddress != windowStart) - { + if (curAddress != windowStart && curAddressIsVisible()) { curAddress = windowStart; + scrollAddressIntoView(); } else { - windowStart -= visibleRows*instructionSize; curAddress -= visibleRows*instructionSize; + scrollAddressIntoView(); } break; case VK_LEFT: @@ -591,6 +581,22 @@ void CtrlDisAsmView::onKeyUp(WPARAM wParam, LPARAM lParam) } } +void CtrlDisAsmView::scrollAddressIntoView() +{ + u32 windowEnd = windowStart + visibleRows * instructionSize; + + if (curAddress < windowStart) + windowStart = curAddress; + else if (curAddress >= windowEnd) + windowStart = curAddress - visibleRows * instructionSize + instructionSize; +} + +bool CtrlDisAsmView::curAddressIsVisible() +{ + u32 windowEnd = windowStart + visibleRows * instructionSize; + return curAddress >= windowStart && curAddress < windowEnd; +} + void CtrlDisAsmView::redraw() { if (dontRedraw == true) return; diff --git a/Windows/Debugger/CtrlDisAsmView.h b/Windows/Debugger/CtrlDisAsmView.h index 7baba6649..3790f7da1 100644 --- a/Windows/Debugger/CtrlDisAsmView.h +++ b/Windows/Debugger/CtrlDisAsmView.h @@ -82,6 +82,8 @@ public: void onMouseDown(WPARAM wParam, LPARAM lParam, int button); void onMouseUp(WPARAM wParam, LPARAM lParam, int button); void onMouseMove(WPARAM wParam, LPARAM lParam, int button); + void scrollAddressIntoView(); + bool curAddressIsVisible(); void redraw(); void getOpcodeText(u32 address, char* dest); @@ -134,7 +136,6 @@ public: void scrollWindow(int lines) { windowStart += lines*instructionSize; - curAddress += lines*instructionSize; redraw(); } }; \ No newline at end of file diff --git a/Windows/Debugger/DebuggerShared.h b/Windows/Debugger/DebuggerShared.h index be55ec8eb..b0d1ba6b3 100644 --- a/Windows/Debugger/DebuggerShared.h +++ b/Windows/Debugger/DebuggerShared.h @@ -2,6 +2,8 @@ #include #include "..\..\Core\Debugger\DebugInterface.h" +extern HMENU g_hPopupMenus; + enum { WM_DEB_RUNTOWPARAM = WM_USER+2, WM_DEB_GOTOWPARAM, WM_DEB_GOTOBREAKPOINT, diff --git a/Windows/Debugger/Debugger_Disasm.cpp b/Windows/Debugger/Debugger_Disasm.cpp index 20a3035cf..054f433c7 100644 --- a/Windows/Debugger/Debugger_Disasm.cpp +++ b/Windows/Debugger/Debugger_Disasm.cpp @@ -46,6 +46,8 @@ enum { BPL_TYPE, BPL_OFFSET, BPL_SIZELABEL, BPL_OPCODE, BPL_HITS, BPL_ENABLED, B // How long (max) to wait for Core to pause before clearing temp breakpoints. const int TEMP_BREAKPOINT_WAIT_MS = 100; +const int POPUP_SUBMENU_ID_BREAKPOINTLIST = 5; + static FAR WNDPROC DefBreakpointListProc; static LRESULT CALLBACK BreakpointListProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) @@ -332,20 +334,64 @@ void CDisasm::gotoBreakpointAddress(int itemIndex) } } +void CDisasm::showBreakpointMenu(int itemIndex, const POINT &pt) +{ + bool isMemory; + int index = getBreakpointIndex(itemIndex, isMemory); + if (index == -1) return; + + MemCheck mcPrev; + BreakPoint bpPrev; + if (isMemory) { + mcPrev = displayedMemChecks_[index]; + } else { + bpPrev = displayedBreakPoints_[index]; + } + + HWND wnd = GetDlgItem(m_hDlg, IDC_BREAKPOINTLIST); + POINT screenPt(pt); + ClientToScreen(wnd, &screenPt); + + HMENU subMenu = GetSubMenu(g_hPopupMenus, POPUP_SUBMENU_ID_BREAKPOINTLIST); + if (isMemory) { + CheckMenuItem(subMenu, ID_DISASM_DISABLEBREAKPOINT, MF_BYCOMMAND | (mcPrev.result & MEMCHECK_BREAK ? MF_CHECKED : MF_UNCHECKED)); + } else { + CheckMenuItem(subMenu, ID_DISASM_DISABLEBREAKPOINT, MF_BYCOMMAND | (bpPrev.enabled ? MF_CHECKED : MF_UNCHECKED)); + } + + switch (TrackPopupMenuEx(subMenu, TPM_RIGHTBUTTON | TPM_RETURNCMD, screenPt.x, screenPt.y, wnd, 0)) + { + case ID_DISASM_DISABLEBREAKPOINT: + if (isMemory) { + CBreakPoints::ChangeMemCheck(mcPrev.start, mcPrev.end, mcPrev.cond, MemCheckResult(mcPrev.result ^ MEMCHECK_BREAK)); + } else { + CBreakPoints::ChangeBreakPoint(bpPrev.addr, !bpPrev.enabled); + } + break; + } +} + static char breakpointText[256]; void CDisasm::handleBreakpointNotify(LPARAM lParam) { - if (((LPNMHDR)lParam)->code == NM_DBLCLK) + const LPNMHDR header = (LPNMHDR)lParam; + if (header->code == NM_DBLCLK) { - LPNMITEMACTIVATE item = (LPNMITEMACTIVATE) lParam; + const LPNMITEMACTIVATE item = (LPNMITEMACTIVATE) lParam; gotoBreakpointAddress(item->iItem); return; } - - if (((LPNMHDR)lParam)->code == LVN_GETDISPINFO) + if (header->code == NM_RCLICK) { - NMLVDISPINFO* dispInfo = (NMLVDISPINFO*)lParam; + const LPNMITEMACTIVATE item = (LPNMITEMACTIVATE)lParam; + showBreakpointMenu(item->iItem, item->ptAction); + return; + } + + if (header->code == LVN_GETDISPINFO) + { + NMLVDISPINFO *dispInfo = (NMLVDISPINFO *)lParam; bool isMemory; int index = getBreakpointIndex(dispInfo->item.iItem,isMemory); diff --git a/Windows/Debugger/Debugger_Disasm.h b/Windows/Debugger/Debugger_Disasm.h index a984068a7..3f2673140 100644 --- a/Windows/Debugger/Debugger_Disasm.h +++ b/Windows/Debugger/Debugger_Disasm.h @@ -42,6 +42,7 @@ private: int getTotalBreakpointCount(); int getBreakpointIndex(int itemIndex, bool& isMemory); void updateThreadLabel(bool clear); + void showBreakpointMenu(int itemIndex, const POINT &pt); public: int index; //helper diff --git a/Windows/Debugger/Debugger_Lists.cpp b/Windows/Debugger/Debugger_Lists.cpp index b328353b3..cc1d1f649 100644 --- a/Windows/Debugger/Debugger_Lists.cpp +++ b/Windows/Debugger/Debugger_Lists.cpp @@ -3,6 +3,7 @@ #include #include #include "DebuggerShared.h" +#include "Windows/resource.h" enum { TL_NAME, TL_PROGRAMCOUNTER, TL_ENTRYPOINT, TL_PRIORITY, TL_STATE, TL_WAITTYPE, TL_COLUMNCOUNT }; @@ -14,6 +15,8 @@ const float threadColumnSizes[] = { 0.20f, 0.15f, 0.15f, 0.15f, 0.15f, 0.20f }; +const int POPUP_SUBMENU_ID_THREADLIST = 6; + void CtrlThreadList::setDialogItem(HWND hwnd) { wnd = hwnd; @@ -76,6 +79,51 @@ LRESULT CALLBACK CtrlThreadList::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPA return (LRESULT)CallWindowProc((WNDPROC)tl->oldProc,hwnd,msg,wParam,lParam); } +void CtrlThreadList::showMenu(int itemIndex, const POINT &pt) +{ + auto threadInfo = threads[itemIndex]; + + // Can't do it, sorry. Needs to not be running. + if (Core_IsActive()) + return; + + POINT screenPt(pt); + ClientToScreen(wnd, &screenPt); + + HMENU subMenu = GetSubMenu(g_hPopupMenus, POPUP_SUBMENU_ID_THREADLIST); + switch (threadInfo.status) { + case THREADSTATUS_DEAD: + case THREADSTATUS_DORMANT: + case THREADSTATUS_RUNNING: + EnableMenuItem(subMenu, ID_DISASM_THREAD_FORCERUN, MF_BYCOMMAND | MF_DISABLED); + EnableMenuItem(subMenu, ID_DISASM_THREAD_KILL, MF_BYCOMMAND | MF_DISABLED); + break; + case THREADSTATUS_READY: + EnableMenuItem(subMenu, ID_DISASM_THREAD_FORCERUN, MF_BYCOMMAND | MF_DISABLED); + EnableMenuItem(subMenu, ID_DISASM_THREAD_KILL, MF_BYCOMMAND | MF_ENABLED); + break; + case THREADSTATUS_SUSPEND: + case THREADSTATUS_WAIT: + case THREADSTATUS_WAITSUSPEND: + default: + EnableMenuItem(subMenu, ID_DISASM_THREAD_FORCERUN, MF_BYCOMMAND | MF_ENABLED); + EnableMenuItem(subMenu, ID_DISASM_THREAD_KILL, MF_BYCOMMAND | MF_ENABLED); + break; + } + + switch (TrackPopupMenuEx(subMenu, TPM_RIGHTBUTTON | TPM_RETURNCMD, screenPt.x, screenPt.y, wnd, 0)) + { + case ID_DISASM_THREAD_FORCERUN: + __KernelResumeThreadFromWait(threadInfo.id, 0); + reloadThreads(); + break; + case ID_DISASM_THREAD_KILL: + sceKernelTerminateThread(threadInfo.id); + reloadThreads(); + break; + } +} + void CtrlThreadList::handleNotify(LPARAM lParam) { LPNMHDR mhdr = (LPNMHDR) lParam; @@ -99,6 +147,12 @@ void CtrlThreadList::handleNotify(LPARAM lParam) SendMessage(GetParent(wnd),WM_DEB_GOTOWPARAM,address,0); return; } + if (mhdr->code == NM_RCLICK) + { + const LPNMITEMACTIVATE item = (LPNMITEMACTIVATE)lParam; + showMenu(item->iItem, item->ptAction); + return; + } if (mhdr->code == LVN_GETDISPINFO) { @@ -188,7 +242,7 @@ void CtrlThreadList::reloadThreads() items++; } - while (items > threads.size()) + while (items > (int)threads.size()) { ListView_DeleteItem(wnd,--items); } @@ -199,7 +253,7 @@ void CtrlThreadList::reloadThreads() const char* CtrlThreadList::getCurrentThreadName() { - for (int i = 0; i < threads.size(); i++) + for (size_t i = 0; i < threads.size(); i++) { if (threads[i].isCurrent) return threads[i].name; } diff --git a/Windows/Debugger/Debugger_Lists.h b/Windows/Debugger/Debugger_Lists.h index ac8ffd5af..b9260604c 100644 --- a/Windows/Debugger/Debugger_Lists.h +++ b/Windows/Debugger/Debugger_Lists.h @@ -14,6 +14,7 @@ public: void setDialogItem(HWND hwnd); void reloadThreads(); void handleNotify(LPARAM lParam); + void showMenu(int itemIndex, const POINT &pt); static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); const char* getCurrentThreadName(); }; \ No newline at end of file diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index 062cb7aa7..359fa3106 100644 Binary files a/Windows/ppsspp.rc and b/Windows/ppsspp.rc differ diff --git a/Windows/resource.h b/Windows/resource.h index bed8c5514..032d62c03 100644 Binary files a/Windows/resource.h and b/Windows/resource.h differ