Merge pull request #3942 from Kingcom/GEDebugger

Add tab control to GEDebugger (and more)
This commit is contained in:
Henrik Rydgård 2013-09-28 12:08:27 -07:00
commit b0189b9557
16 changed files with 343 additions and 23 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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();
}

View File

@ -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 <windowsx.h>
#include <commctrl.h>
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;

View File

@ -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;
};

View File

@ -24,6 +24,6 @@
// Globals
HMENU g_hPopupMenus;
bool g_debuggerActive = false;
int g_activeWindow = 0;
#endif

View File

@ -296,6 +296,7 @@
<ClCompile Include="W32Util\PropertySheet.cpp" />
<ClCompile Include="W32Util\ShellUtil.cpp" />
<ClCompile Include="InputBox.cpp" />
<ClCompile Include="W32Util\TabControl.cpp" />
<ClCompile Include="WndMainWindow.cpp" />
<ClCompile Include="DSoundStream.cpp" />
<ClCompile Include="OpenGLBase.cpp" />
@ -334,6 +335,7 @@
<ClInclude Include="W32Util\Misc.h" />
<ClInclude Include="W32Util\PropertySheet.h" />
<ClInclude Include="W32Util\ShellUtil.h" />
<ClInclude Include="W32Util\TabControl.h" />
<ClInclude Include="W32Util\XPTheme.h" />
<ClInclude Include="InputBox.h" />
<ClInclude Include="WndMainWindow.h" />

View File

@ -122,6 +122,9 @@
<ClCompile Include="GEDebugger\CtrlDisplayListView.cpp">
<Filter>Windows\GE Debugger</Filter>
</ClCompile>
<ClCompile Include="W32Util\TabControl.cpp">
<Filter>Windows\W32Util</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="Debugger\CtrlDisAsmView.h">
@ -218,6 +221,9 @@
<ClInclude Include="GEDebugger\CtrlDisplayListView.h">
<Filter>Windows\GE Debugger</Filter>
</ClInclude>
<ClInclude Include="W32Util\TabControl.h">
<Filter>Windows\W32Util</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="icon1.ico">

View File

@ -0,0 +1,162 @@
#include "TabControl.h"
#include "DialogManager.h"
#include "Windows/WndMainWindow.h"
#include <windowsx.h>
#include <commctrl.h>
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);
}

View File

@ -0,0 +1,24 @@
#pragma once
#include <vector>
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<HWND> tabs;
};

View File

@ -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();

View File

@ -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))

View File

@ -31,4 +31,6 @@ extern CGEDebugger *geDebuggerWindow ;
extern CMemoryDlg *memoryWindow[MAX_CPUCOUNT];
extern HMENU g_hPopupMenus;
extern bool g_debuggerActive;
extern int g_activeWindow;
enum { WINDOW_MAINWINDOW, WINDOW_CPUDEBUGGER, WINDOW_GEDEBUGGER };

View File

@ -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"

View File

@ -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