diff --git a/Core/Config.cpp b/Core/Config.cpp index 8a084c5b5..9bb61f1e7 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -232,6 +232,10 @@ void Config::Load(const char *iniFileName, const char *controllerIniFilename) debugConfig->Get("DisasmWindowY", &iDisasmWindowY, -1); debugConfig->Get("DisasmWindowW", &iDisasmWindowW, -1); debugConfig->Get("DisasmWindowH", &iDisasmWindowH, -1); + debugConfig->Get("GEWindowX", &iGEWindowX, -1); + debugConfig->Get("GEWindowY", &iGEWindowY, -1); + debugConfig->Get("GEWindowW", &iGEWindowW, -1); + debugConfig->Get("GEWindowH", &iGEWindowH, -1); debugConfig->Get("ConsoleWindowX", &iConsoleWindowX, -1); debugConfig->Get("ConsoleWindowY", &iConsoleWindowY, -1); debugConfig->Get("FontWidth", &iFontWidth, 8); @@ -382,6 +386,10 @@ void Config::Save() { debugConfig->Set("DisasmWindowY", iDisasmWindowY); debugConfig->Set("DisasmWindowW", iDisasmWindowW); debugConfig->Set("DisasmWindowH", iDisasmWindowH); + debugConfig->Set("GEWindowX", iGEWindowX); + debugConfig->Set("GEWindowY", iGEWindowY); + debugConfig->Set("GEWindowW", iGEWindowW); + debugConfig->Set("GEWindowH", iGEWindowH); debugConfig->Set("ConsoleWindowX", iConsoleWindowX); debugConfig->Set("ConsoleWindowY", iConsoleWindowY); debugConfig->Set("FontWidth", iFontWidth); diff --git a/Core/Config.h b/Core/Config.h index e563c032a..cd04bbecf 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -157,6 +157,10 @@ public: int iDisasmWindowY; int iDisasmWindowW; int iDisasmWindowH; + int iGEWindowX; + int iGEWindowY; + int iGEWindowW; + int iGEWindowH; int iConsoleWindowX; int iConsoleWindowY; int iFontWidth; diff --git a/Windows/Debugger/Debugger_Disasm.cpp b/Windows/Debugger/Debugger_Disasm.cpp index db4f40f67..2029e2008 100644 --- a/Windows/Debugger/Debugger_Disasm.cpp +++ b/Windows/Debugger/Debugger_Disasm.cpp @@ -708,9 +708,7 @@ BOOL CDisasm::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) case WM_ACTIVATE: if (wParam == WA_ACTIVE || wParam == WA_CLICKACTIVE) { - g_debuggerActive = true; - } else { - g_debuggerActive = false; + g_activeWindow = WINDOW_CPUDEBUGGER; } break; } diff --git a/Windows/GEDebugger/CtrlDisplayListView.cpp b/Windows/GEDebugger/CtrlDisplayListView.cpp index 72f40b9d8..df701bcf3 100644 --- a/Windows/GEDebugger/CtrlDisplayListView.cpp +++ b/Windows/GEDebugger/CtrlDisplayListView.cpp @@ -1,5 +1,6 @@ #include "Windows/GEDebugger/CtrlDisplayListView.h" #include "Core/Config.h" +#include "Windows/GEDebugger/GEDebugger.h" const PTCHAR CtrlDisplayListView::windowClass = _T("CtrlDisplayListView"); @@ -98,8 +99,9 @@ LRESULT CALLBACK CtrlDisplayListView::wndProc(HWND hwnd, UINT msg, WPARAM wParam win->onMouseDown(wParam,lParam,1); break; case WM_KEYDOWN: + case WM_SYSKEYDOWN: win->onKeyDown(wParam,lParam); - break; + return 0; case WM_GETDLGCODE: if (lParam && ((MSG*)lParam)->message == WM_KEYDOWN) { @@ -290,6 +292,10 @@ void CtrlDisplayListView::onKeyDown(WPARAM wParam, LPARAM lParam) case VK_LEFT: gotoAddr(list.pc); return; + case VK_F10: + case VK_F11: + SendMessage(GetParent(wnd),WM_GEDBG_STEPDISPLAYLIST,0,0); + break; } redraw(); } diff --git a/Windows/GEDebugger/GEDebugger.cpp b/Windows/GEDebugger/GEDebugger.cpp index 00f5f4722..a9ac468e8 100644 --- a/Windows/GEDebugger/GEDebugger.cpp +++ b/Windows/GEDebugger/GEDebugger.cpp @@ -24,13 +24,14 @@ #include "Windows/GEDebugger/SimpleGLWindow.h" #include "Windows/GEDebugger/CtrlDisplayListView.h" #include "Windows/WindowsHost.h" +#include "Windows/WndMainWindow.h" #include "Windows/main.h" #include "GPU/GPUInterface.h" #include "GPU/Common/GPUDebugInterface.h" #include "GPU/GPUState.h" - -const UINT WM_GEDBG_BREAK_CMD = WM_USER + 200; -const UINT WM_GEDBG_BREAK_DRAW = WM_USER + 201; +#include "Core/Config.h" +#include +#include enum PauseAction { PAUSE_CONTINUE, @@ -108,6 +109,12 @@ CGEDebugger::CGEDebugger(HINSTANCE _hInstance, HWND _hParent) breakCmds.resize(256, false); Core_ListenShutdown(ForceUnpause); + // minimum size = a little more than the default + RECT windowRect; + GetWindowRect(m_hDlg,&windowRect); + minWidth = windowRect.right-windowRect.left+10; + minHeight = windowRect.bottom-windowRect.top+10; + // it's ugly, but .rc coordinates don't match actual pixels and it screws // up both the size and the aspect ratio // TODO: Could be scrollable in case the framebuf is larger? Also should be better positioned. @@ -117,6 +124,17 @@ CGEDebugger::CGEDebugger(HINSTANCE _hInstance, HWND _hParent) GetWindowRect(frameWnd,&frameRect); MapWindowPoints(HWND_DESKTOP,m_hDlg,(LPPOINT)&frameRect,2); MoveWindow(frameWnd,frameRect.left,frameRect.top,512,272,TRUE); + + tabs = new TabControl(GetDlgItem(m_hDlg,IDC_GEDBG_MAINTAB)); + HWND wnd = tabs->AddTabWindow(L"CtrlDisplayListView",L"Display List"); + displayList = CtrlDisplayListView::getFrom(wnd); + + // set window position + int x = g_Config.iGEWindowX == -1 ? windowRect.left : g_Config.iGEWindowX; + int y = g_Config.iGEWindowY == -1 ? windowRect.top : g_Config.iGEWindowY; + int w = g_Config.iGEWindowW == -1 ? minWidth : g_Config.iGEWindowW; + int h = g_Config.iGEWindowH == -1 ? minHeight : g_Config.iGEWindowH; + MoveWindow(m_hDlg,x,y,w,h,FALSE); } CGEDebugger::~CGEDebugger() { @@ -166,18 +184,56 @@ void CGEDebugger::UpdatePreviews() { DisplayList list; if (gpuDebug->GetCurrentDisplayList(list)) { - CtrlDisplayListView *displayList = CtrlDisplayListView::getFrom(GetDlgItem(m_hDlg, IDC_GEDBG_CURRENTDISPLAYLIST)); displayList->setDisplayList(list); } } +void CGEDebugger::UpdateSize(WORD width, WORD height) +{ + // only resize the tab for now + HWND tabControl = GetDlgItem(m_hDlg, IDC_GEDBG_MAINTAB); + + RECT tabRect; + GetWindowRect(tabControl,&tabRect); + MapWindowPoints(HWND_DESKTOP,m_hDlg,(LPPOINT)&tabRect,2); + + tabRect.right = tabRect.left + (width-tabRect.left*2); // assume same gap on both sides + tabRect.bottom = tabRect.top + (height-tabRect.top-tabRect.left); // assume same gap on bottom too + MoveWindow(tabControl,tabRect.left,tabRect.top,tabRect.right-tabRect.left,tabRect.bottom-tabRect.top,TRUE); +} + +void CGEDebugger::SavePosition() +{ + RECT rc; + if (GetWindowRect(m_hDlg, &rc)) + { + g_Config.iGEWindowX = rc.left; + g_Config.iGEWindowY = rc.top; + g_Config.iGEWindowW = rc.right - rc.left; + g_Config.iGEWindowH = rc.bottom - rc.top; + } +} + BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG: return TRUE; + case WM_GETMINMAXINFO: + { + MINMAXINFO* minmax = (MINMAXINFO*) lParam; + minmax->ptMinTrackSize.x = minWidth; + minmax->ptMinTrackSize.y = minHeight; + } + return TRUE; + case WM_SIZE: - // TODO + UpdateSize(LOWORD(lParam), HIWORD(lParam)); + SavePosition(); + return TRUE; + + case WM_MOVE: + SavePosition(); return TRUE; case WM_CLOSE: @@ -188,6 +244,21 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { SetupPreviews(); break; + case WM_ACTIVATE: + if (wParam == WA_ACTIVE || wParam == WA_CLICKACTIVE) { + g_activeWindow = WINDOW_GEDEBUGGER; + } + break; + + case WM_NOTIFY: + switch (wParam) + { + case IDC_GEDBG_MAINTAB: + tabs->HandleNotify(lParam); + break; + } + break; + case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_GEDBG_STEPDRAW: @@ -200,12 +271,7 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { break; case IDC_GEDBG_STEP: - attached = true; - SetupPreviews(); - - pauseWait.notify_one(); - breakNextOp = true; - breakNextDraw = false; + SendMessage(m_hDlg,WM_GEDBG_STEPDISPLAYLIST,0,0); break; case IDC_GEDBG_RESUME: @@ -234,6 +300,15 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) { UpdatePreviews(); } break; + + case WM_GEDBG_STEPDISPLAYLIST: + attached = true; + SetupPreviews(); + + pauseWait.notify_one(); + breakNextOp = true; + breakNextDraw = false; + break; } return FALSE; diff --git a/Windows/GEDebugger/GEDebugger.h b/Windows/GEDebugger/GEDebugger.h index 94abf33af..d50a273eb 100644 --- a/Windows/GEDebugger/GEDebugger.h +++ b/Windows/GEDebugger/GEDebugger.h @@ -21,8 +21,17 @@ #include "Globals.h" #include "Windows/resource.h" #include "Windows/W32Util/DialogManager.h" +#include "Windows/W32Util/TabControl.h" #include "Windows/GEDebugger/SimpleGLWindow.h" +enum { + WM_GEDBG_BREAK_CMD = WM_USER + 200, + WM_GEDBG_BREAK_DRAW, + WM_GEDBG_STEPDISPLAYLIST, +}; + +class CtrlDisplayListView; + class CGEDebugger : public Dialog { public: CGEDebugger(HINSTANCE _hInstance, HWND _hParent); @@ -35,7 +44,13 @@ protected: private: void SetupPreviews(); void UpdatePreviews(); + void UpdateSize(WORD width, WORD height); + void SavePosition(); + CtrlDisplayListView* displayList; SimpleGLWindow *frameWindow; SimpleGLWindow *texWindow; + TabControl* tabs; + + int minWidth,minHeight; }; diff --git a/Windows/Globals.cpp b/Windows/Globals.cpp index 36ed0137f..60d438b22 100644 --- a/Windows/Globals.cpp +++ b/Windows/Globals.cpp @@ -24,6 +24,6 @@ // Globals HMENU g_hPopupMenus; -bool g_debuggerActive = false; +int g_activeWindow = 0; #endif diff --git a/Windows/PPSSPP.vcxproj b/Windows/PPSSPP.vcxproj index f197d3f57..53d56b2f4 100644 --- a/Windows/PPSSPP.vcxproj +++ b/Windows/PPSSPP.vcxproj @@ -296,6 +296,7 @@ + @@ -334,6 +335,7 @@ + diff --git a/Windows/PPSSPP.vcxproj.filters b/Windows/PPSSPP.vcxproj.filters index caf6aae59..03023ca09 100644 --- a/Windows/PPSSPP.vcxproj.filters +++ b/Windows/PPSSPP.vcxproj.filters @@ -122,6 +122,9 @@ Windows\GE Debugger + + Windows\W32Util + @@ -218,6 +221,9 @@ Windows\GE Debugger + + Windows\W32Util + diff --git a/Windows/W32Util/TabControl.cpp b/Windows/W32Util/TabControl.cpp new file mode 100644 index 000000000..ff269ee65 --- /dev/null +++ b/Windows/W32Util/TabControl.cpp @@ -0,0 +1,162 @@ +#include "TabControl.h" +#include "DialogManager.h" +#include "Windows/WndMainWindow.h" +#include +#include + +TabControl::TabControl(HWND handle): hwnd(handle) +{ + SetWindowLongPtr(hwnd,GWLP_USERDATA,(LONG_PTR)this); + oldProc = (WNDPROC) SetWindowLongPtr(hwnd,GWLP_WNDPROC,(LONG_PTR)wndProc); + +} + +HWND TabControl::AddTabWindow(wchar_t* className, wchar_t* title, DWORD style) +{ + style |= WS_CHILD; + + TCITEM tcItem; + ZeroMemory (&tcItem,sizeof (tcItem)); + tcItem.mask = TCIF_TEXT; + tcItem.dwState = 0; + tcItem.pszText = title; + tcItem.cchTextMax = (int)wcslen(tcItem.pszText)+1; + tcItem.iImage = 0; + + int index = TabCtrl_GetItemCount(hwnd); + int result = TabCtrl_InsertItem(hwnd,index,&tcItem); + + RECT tabRect; + GetWindowRect(hwnd,&tabRect); + MapWindowPoints(HWND_DESKTOP,GetParent(hwnd),(LPPOINT)&tabRect,2); + TabCtrl_AdjustRect(hwnd, FALSE, &tabRect); + + HWND tabHandle = CreateWindowEx(0,className,title,style, + tabRect.left,tabRect.top,tabRect.right-tabRect.left,tabRect.bottom-tabRect.top, + GetParent(hwnd),0,MainWindow::GetHInstance(),0); + tabs.push_back(tabHandle); + + ShowTab(index); + return tabHandle; +} + +void TabControl::AddTabDialog(Dialog* dialog, wchar_t* title) +{ + HWND handle = dialog->GetDlgHandle(); + + TCITEM tcItem; + ZeroMemory (&tcItem,sizeof (tcItem)); + tcItem.mask = TCIF_TEXT; + tcItem.dwState = 0; + tcItem.pszText = title; + tcItem.cchTextMax = (int)wcslen(tcItem.pszText)+1; + tcItem.iImage = 0; + + int index = TabCtrl_GetItemCount(hwnd); + int result = TabCtrl_InsertItem(hwnd,index,&tcItem); + + RECT tabRect; + GetWindowRect(hwnd,&tabRect); + MapWindowPoints(HWND_DESKTOP,GetParent(hwnd),(LPPOINT)&tabRect,2); + TabCtrl_AdjustRect(hwnd, FALSE, &tabRect); + + SetParent(handle,GetParent(hwnd)); + DWORD style = (GetWindowLong(handle,GWL_STYLE) | WS_CHILD) & ~(WS_POPUP | WS_TILEDWINDOW); + SetWindowLong(handle, GWL_STYLE, style); + MoveWindow(handle,tabRect.left,tabRect.top,tabRect.right-tabRect.left,tabRect.bottom-tabRect.top,TRUE); + tabs.push_back(handle); + + ShowTab(index); +} + +void TabControl::ShowTab(int index, bool setControlIndex) +{ + for (size_t i = 0; i < tabs.size(); i++) + { + ShowWindow(tabs[i],i == index ? SW_NORMAL : SW_HIDE); + } + + if (setControlIndex) + { + TabCtrl_SetCurSel(hwnd,index); + } +} + +void TabControl::ShowTab(HWND pageHandle) +{ + for (size_t i = 0; i < tabs.size(); i++) + { + if (tabs[i] == pageHandle) + { + TabCtrl_SetCurSel(hwnd,i); + } + ShowWindow(tabs[i],tabs[i] == pageHandle ? SW_NORMAL : SW_HIDE); + } +} + +void TabControl::NextTab(bool cycle) +{ + int index = TabCtrl_GetCurSel(hwnd); + if (index == tabs.size()-1 && cycle) + index = 0; + ShowTab(index); +} + +void TabControl::PreviousTab(bool cycle) +{ + int index = TabCtrl_GetCurSel(hwnd); + if (index == 0 && cycle) + index = tabs.size()-1; + ShowTab(index); +} + +void TabControl::HandleNotify(LPARAM lParam) +{ + NMHDR* pNotifyMessage = NULL; + pNotifyMessage = (LPNMHDR)lParam; + if (pNotifyMessage->hwndFrom == hwnd) + { + int iPage = TabCtrl_GetCurSel(hwnd); + ShowTab(iPage,false); + } +} + +void TabControl::OnResize() +{ + RECT tabRect; + GetWindowRect(hwnd,&tabRect); + MapWindowPoints(HWND_DESKTOP,GetParent(hwnd),(LPPOINT)&tabRect,2); + + InvalidateRect(hwnd,NULL,FALSE); + UpdateWindow(hwnd); + + // now resize tab children + TabCtrl_AdjustRect(hwnd, FALSE, &tabRect); + int current = TabCtrl_GetCurSel(hwnd); + + for (size_t i = 0; i < tabs.size(); i++) + { + InvalidateRect(tabs[i],NULL,FALSE); + MoveWindow(tabs[i],tabRect.left,tabRect.top,tabRect.right-tabRect.left,tabRect.bottom-tabRect.top,FALSE); + + if (i == current) + { + InvalidateRect(tabs[i],NULL,FALSE); + UpdateWindow(tabs[i]); + } + } +} + +LRESULT CALLBACK TabControl::wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) +{ + TabControl* tabControl = (TabControl*) GetWindowLongPtr(hwnd,GWLP_USERDATA); + + switch (msg) + { + case WM_SIZE: + tabControl->OnResize(); + break; + } + + return (LRESULT)CallWindowProc((WNDPROC)tabControl->oldProc,hwnd,msg,wParam,lParam); +} \ No newline at end of file diff --git a/Windows/W32Util/TabControl.h b/Windows/W32Util/TabControl.h new file mode 100644 index 000000000..ba3557c04 --- /dev/null +++ b/Windows/W32Util/TabControl.h @@ -0,0 +1,24 @@ +#pragma once + +#include + +class Dialog; + +class TabControl +{ +public: + TabControl(HWND handle); + void HandleNotify(LPARAM lParam); + HWND AddTabWindow(wchar_t* className, wchar_t* title, DWORD style = 0); + void AddTabDialog(Dialog* dialog, wchar_t* title); + void ShowTab(int index, bool setControlIndex = true); + void ShowTab(HWND pageHandle); + void NextTab(bool cycle); + void PreviousTab(bool cycle); +private: + static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam); + void OnResize(); + HWND hwnd; + WNDPROC oldProc; + std::vector tabs; +}; \ No newline at end of file diff --git a/Windows/WndMainWindow.cpp b/Windows/WndMainWindow.cpp index 2fac8891a..aa44eeffa 100644 --- a/Windows/WndMainWindow.cpp +++ b/Windows/WndMainWindow.cpp @@ -838,6 +838,9 @@ namespace MainWindow switch (message) { case WM_ACTIVATE: + if (wParam == WA_ACTIVE || wParam == WA_CLICKACTIVE) { + g_activeWindow = WINDOW_MAINWINDOW; + } break; case WM_SETFOCUS: @@ -997,6 +1000,12 @@ namespace MainWindow switch (message) { case WM_CREATE: break; + + case WM_ACTIVATE: + if (wParam == WA_ACTIVE || wParam == WA_CLICKACTIVE) { + g_activeWindow = WINDOW_MAINWINDOW; + } + break; case WM_MOVE: SavePosition(); diff --git a/Windows/main.cpp b/Windows/main.cpp index d6d6b0328..e1385b049 100644 --- a/Windows/main.cpp +++ b/Windows/main.cpp @@ -224,12 +224,21 @@ int WINAPI WinMain(HINSTANCE _hInstance, HINSTANCE hPrevInstance, LPSTR szCmdLin //Translate accelerators and dialog messages... HWND wnd; HACCEL accel; - if (g_debuggerActive) { - wnd = disasmWindow[0]->GetDlgHandle(); - accel = hDebugAccelTable; - } else { + switch (g_activeWindow) + { + case WINDOW_MAINWINDOW: wnd = hwndMain; accel = hAccelTable; + break; + case WINDOW_CPUDEBUGGER: + wnd = disasmWindow[0]->GetDlgHandle(); + accel = hDebugAccelTable; + break; + case WINDOW_GEDEBUGGER: + default: + wnd = 0; + accel = 0; + break; } if (!TranslateAccelerator(wnd, accel, &msg)) diff --git a/Windows/main.h b/Windows/main.h index 70f6ca5b9..2990c9373 100644 --- a/Windows/main.h +++ b/Windows/main.h @@ -31,4 +31,6 @@ extern CGEDebugger *geDebuggerWindow ; extern CMemoryDlg *memoryWindow[MAX_CPUCOUNT]; extern HMENU g_hPopupMenus; -extern bool g_debuggerActive; \ No newline at end of file +extern int g_activeWindow; + +enum { WINDOW_MAINWINDOW, WINDOW_CPUDEBUGGER, WINDOW_GEDEBUGGER }; \ No newline at end of file diff --git a/Windows/ppsspp.rc b/Windows/ppsspp.rc index 1c666663c..64952cd5b 100644 --- a/Windows/ppsspp.rc +++ b/Windows/ppsspp.rc @@ -174,7 +174,7 @@ BEGIN PUSHBUTTON "Resume",IDC_GEDBG_RESUME,104,0,48,14 CONTROL "",IDC_GEDBG_TEX,"SimpleGLWindow",WS_CHILD | WS_VISIBLE,10,20,128,128 CONTROL "",IDC_GEDBG_FRAME,"SimpleGLWindow",WS_CHILD | WS_VISIBLE,148,20,256,136 - CONTROL "",IDC_GEDBG_CURRENTDISPLAYLIST,"CtrlDisplayListView",WS_BORDER | WS_VISIBLE,10,195,456,200 + CONTROL "",IDC_GEDBG_MAINTAB,"SysTabControl32",TCS_TABS ,10,216,480,180 END #include "aboutbox.rc" diff --git a/Windows/resource.h b/Windows/resource.h index f865f9174..b0de116ea 100644 --- a/Windows/resource.h +++ b/Windows/resource.h @@ -262,7 +262,7 @@ #define IDC_GEDBG_STEPDRAW 40117 #define IDC_GEDBG_RESUME 40118 #define IDC_GEDBG_FRAME 40119 -#define IDC_GEDBG_CURRENTDISPLAYLIST 40120 +#define IDC_GEDBG_MAINTAB 40120 #define IDC_GEDBG_TEX 40121 #define IDC_GEDBG_STEP 40122