diff --git a/Windows/BreakpointSmall.ico b/Windows/BreakpointSmall.ico new file mode 100644 index 0000000000..584cf5c253 Binary files /dev/null and b/Windows/BreakpointSmall.ico differ diff --git a/Windows/GEDebugger/TabState.cpp b/Windows/GEDebugger/TabState.cpp index 0a6e32e177..5cbcd46f52 100644 --- a/Windows/GEDebugger/TabState.cpp +++ b/Windows/GEDebugger/TabState.cpp @@ -15,6 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include "Common/CommonFuncs.h" #include "Common/CommonTypes.h" #include "Windows/resource.h" #include "Windows/InputBox.h" @@ -28,17 +29,22 @@ using namespace GPUBreakpoints; -// TODO: Show an icon or something for breakpoints, toggle. +// First column is the breakpoint icon. static const GenericListViewColumn stateValuesCols[] = { - { L"Name", 0.50f }, - { L"Value", 0.50f }, + { L"", 0.03f }, + { L"Name", 0.40f }, + { L"Value", 0.57f }, }; GenericListViewDef stateValuesListDef = { - stateValuesCols, ARRAY_SIZE(stateValuesCols), NULL, false + stateValuesCols, + ARRAY_SIZE(stateValuesCols), + nullptr, + false, }; enum StateValuesCols { + STATEVALUES_COL_BREAKPOINT, STATEVALUES_COL_NAME, STATEVALUES_COL_VALUE, }; @@ -279,9 +285,28 @@ static void ToggleWatchList(const TabStateRow &info) { watchList.push_back(info); } +static bool ToggleBreakpoint(const TabStateRow &info) { + if (IsCmdBreakpoint(info.cmd)) { + RemoveCmdBreakpoint(info.cmd); + RemoveCmdBreakpoint(info.otherCmd); + RemoveCmdBreakpoint(info.otherCmd2); + return false; + } + + AddCmdBreakpoint(info.cmd); + if (info.otherCmd) { + AddCmdBreakpoint(info.otherCmd); + } + if (info.otherCmd2) { + AddCmdBreakpoint(info.otherCmd2); + } + return true; +} + CtrlStateValues::CtrlStateValues(const TabStateRow *rows, int rowCount, HWND hwnd) : GenericListControl(hwnd, stateValuesListDef), rows_(rows), rowCount_(rowCount) { + SetIconList(12, 12, { (HICON)LoadIcon(GetModuleHandle(0), (LPCWSTR)IDI_BREAKPOINT_SMALL) }); Update(); } @@ -810,6 +835,10 @@ void CtrlStateValues::GetColumnText(wchar_t *dest, int row, int col) { } switch (col) { + case STATEVALUES_COL_BREAKPOINT: + wcscpy(dest, L" "); + break; + case STATEVALUES_COL_NAME: wcscpy(dest, rows_[row].title); break; @@ -835,11 +864,17 @@ void CtrlStateValues::GetColumnText(wchar_t *dest, int row, int col) { } void CtrlStateValues::OnDoubleClick(int row, int column) { - if (gpuDebug == NULL) { + if (gpuDebug == nullptr || row > rowCount_) { return; } const auto info = rows_[row]; + + if (column == STATEVALUES_COL_BREAKPOINT) { + SetItemState(row, ToggleBreakpoint(info) ? 1 : 0); + return; + } + switch (info.fmt) { case CMD_FMT_FLAG: { @@ -887,19 +922,7 @@ void CtrlStateValues::OnRightClick(int row, int column, const POINT &point) { switch (TriggerContextMenu(ContextMenuID::GEDBG_STATE, GetHandle(), ContextPoint::FromClient(point))) { case ID_DISASM_TOGGLEBREAKPOINT: - if (IsCmdBreakpoint(info.cmd)) { - RemoveCmdBreakpoint(info.cmd); - RemoveCmdBreakpoint(info.otherCmd); - RemoveCmdBreakpoint(info.otherCmd2); - } else { - AddCmdBreakpoint(info.cmd); - if (info.otherCmd) { - AddCmdBreakpoint(info.otherCmd); - } - if (info.otherCmd2) { - AddCmdBreakpoint(info.otherCmd2); - } - } + SetItemState(row, ToggleBreakpoint(info) ? 1 : 0); break; case ID_DISASM_COPYINSTRUCTIONHEX: { diff --git a/Windows/PPSSPP.vcxproj b/Windows/PPSSPP.vcxproj index efd5279466..63ecbc1691 100644 --- a/Windows/PPSSPP.vcxproj +++ b/Windows/PPSSPP.vcxproj @@ -1703,6 +1703,7 @@ + diff --git a/Windows/PPSSPP.vcxproj.filters b/Windows/PPSSPP.vcxproj.filters index 3179c6effe..0706f8fb9c 100644 --- a/Windows/PPSSPP.vcxproj.filters +++ b/Windows/PPSSPP.vcxproj.filters @@ -721,6 +721,9 @@ Resource Files + + Resource Files + diff --git a/Windows/W32Util/Misc.cpp b/Windows/W32Util/Misc.cpp index 261e05fe66..7aee7d98ec 100644 --- a/Windows/W32Util/Misc.cpp +++ b/Windows/W32Util/Misc.cpp @@ -203,6 +203,19 @@ GenericListControl::GenericListControl(HWND hwnd, const GenericListViewDef& def) valid = true; } +GenericListControl::~GenericListControl() { + if (images_ != nullptr) + ImageList_Destroy((HIMAGELIST)images_); +} + +void GenericListControl::SetIconList(int w, int h, const std::vector &icons) { + images_ = ImageList_Create(w, h, ILC_COLOR32 | ILC_MASK, 0, (int)icons.size()); + for (const HICON &icon : icons) + ImageList_AddIcon((HIMAGELIST)images_, icon); + + ListView_SetImageList(handle, (HIMAGELIST)images_, LVSIL_STATE); +} + void GenericListControl::HandleNotify(LPARAM lParam) { LPNMHDR mhdr = (LPNMHDR) lParam; @@ -234,6 +247,7 @@ void GenericListControl::HandleNotify(LPARAM lParam) wcscat(stringBuffer,L"Invalid"); dispInfo->item.pszText = stringBuffer; + dispInfo->item.mask |= LVIF_TEXT; return; } @@ -313,6 +327,13 @@ void GenericListControl::SetCheckState(int item, bool state) updating = false; } +void GenericListControl::SetItemState(int item, uint8_t state) { + updating = true; + ListView_SetItemState(handle, item, (state & 0xF) << 12, LVIS_STATEIMAGEMASK); + ListView_RedrawItems(handle, item, item); + updating = false; +} + void GenericListControl::ResizeColumns() { if (inResizeColumns) diff --git a/Windows/W32Util/Misc.h b/Windows/W32Util/Misc.h index 3ac282a6c5..c0ce2c33aa 100644 --- a/Windows/W32Util/Misc.h +++ b/Windows/W32Util/Misc.h @@ -1,6 +1,8 @@ #pragma once +#include #include +#include #include "Common/CommonWindows.h" namespace W32Util @@ -41,14 +43,17 @@ class GenericListControl { public: GenericListControl(HWND hwnd, const GenericListViewDef& def); - virtual ~GenericListControl() { }; + virtual ~GenericListControl(); void HandleNotify(LPARAM lParam); void Update(); int GetSelectedIndex(); HWND GetHandle() { return handle; }; void SetSendInvalidRows(bool enabled) { sendInvalidRows = enabled; }; protected: + void SetIconList(int w, int h, const std::vector &icons); void SetCheckState(int item, bool state); + void SetItemState(int item, uint8_t state); + virtual bool WindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT& returnValue) = 0; virtual void GetColumnText(wchar_t* dest, int row, int col) = 0; virtual int GetRowCount() = 0; @@ -66,6 +71,7 @@ private: HWND handle; WNDPROC oldProc; + void *images_ = nullptr; const GenericListViewColumn* columns; int columnCount; wchar_t stringBuffer[256]; diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index 05d72954fc..24603ba3b8 100644 --- a/Windows/ppsspp.rc +++ b/Windows/ppsspp.rc @@ -454,6 +454,7 @@ IDI_PPSSPP ICON "ppsspp.ico" #endif IDI_STOP ICON "icon1.ico" IDI_STOPDISABLE ICON "stop1.ico" +IDI_BREAKPOINT_SMALL ICON "BreakpointSmall.ico" ///////////////////////////////////////////////////////////////////////////// diff --git a/Windows/resource.h b/Windows/resource.h index 0f02787f64..98ecab1e1c 100644 --- a/Windows/resource.h +++ b/Windows/resource.h @@ -324,6 +324,7 @@ #define ID_GEDBG_BREAK_MENU 40211 #define IDC_GEDBG_FLUSH 40212 #define IDC_GEDBG_FLUSHAUTO 40213 +#define IDI_BREAKPOINT_SMALL 40214 // Dummy option to let the buffered rendering hotkey cycle through all the options. #define ID_OPTIONS_BUFFEREDRENDERINGDUMMY 40500 @@ -336,7 +337,7 @@ #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 256 -#define _APS_NEXT_COMMAND_VALUE 40214 +#define _APS_NEXT_COMMAND_VALUE 40215 #define _APS_NEXT_CONTROL_VALUE 1202 #define _APS_NEXT_SYMED_VALUE 101 #endif