mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Merge pull request #4062 from unknownbrackets/debugger
Show tabs for depth/stencil in ge debugger, other improvements
This commit is contained in:
commit
8f7a9656c8
19 changed files with 369 additions and 133 deletions
|
@ -38,9 +38,10 @@ enum GPUDebugBufferFormat {
|
|||
GPU_DBG_FORMAT_8888 = 3,
|
||||
GPU_DBG_FORMAT_INVALID = 0xFF,
|
||||
|
||||
// These don't, they're for depth buffers.
|
||||
// These don't, they're for depth/stencil buffers.
|
||||
GPU_DBG_FORMAT_FLOAT = 0x10,
|
||||
GPU_DBG_FORMAT_16BIT = 0x11,
|
||||
GPU_DBG_FORMAT_8BIT = 0x12,
|
||||
};
|
||||
|
||||
struct GPUDebugBuffer {
|
||||
|
@ -170,6 +171,9 @@ public:
|
|||
virtual u32 GetVertexAddress() = 0;
|
||||
virtual u32 GetIndexAddress() = 0;
|
||||
virtual GPUgstate GetGState() = 0;
|
||||
// Needs to be called from the GPU thread.
|
||||
// Calling from a separate thread (e.g. UI) may fail.
|
||||
virtual void SetCmdValue(u32 op) = 0;
|
||||
|
||||
// Needs to be called from the GPU thread, so on the same thread as a notification is fine.
|
||||
// Calling from a separate thread (e.g. UI) may fail.
|
||||
|
|
|
@ -386,10 +386,10 @@ void FramebufferManagerDX9::SetRenderFrameBuffer() {
|
|||
gstate_c.framebufChanged = false;
|
||||
|
||||
// Get parameters
|
||||
u32 fb_address = (gstate.fbptr & 0xFFFFFF) | ((gstate.fbwidth & 0xFF0000) << 8);
|
||||
u32 fb_address = gstate.getFrameBufRawAddress();
|
||||
int fb_stride = gstate.fbwidth & 0x3C0;
|
||||
|
||||
u32 z_address = (gstate.zbptr & 0xFFFFFF) | ((gstate.zbwidth & 0xFF0000) << 8);
|
||||
u32 z_address = gstate.getDepthBufRawAddress();
|
||||
int z_stride = gstate.zbwidth & 0x3C0;
|
||||
|
||||
// Yeah this is not completely right. but it'll do for now.
|
||||
|
|
|
@ -516,10 +516,10 @@ void FramebufferManager::SetRenderFrameBuffer() {
|
|||
gstate_c.framebufChanged = false;
|
||||
|
||||
// Get parameters
|
||||
u32 fb_address = (gstate.fbptr & 0xFFFFFF) | ((gstate.fbwidth & 0xFF0000) << 8);
|
||||
u32 fb_address = gstate.getFrameBufRawAddress();
|
||||
int fb_stride = gstate.fbwidth & 0x3C0;
|
||||
|
||||
u32 z_address = (gstate.zbptr & 0xFFFFFF) | ((gstate.zbwidth & 0xFF0000) << 8);
|
||||
u32 z_address = gstate.getDepthBufRawAddress();
|
||||
int z_stride = gstate.zbwidth & 0x3C0;
|
||||
|
||||
// Yeah this is not completely right. but it'll do for now.
|
||||
|
@ -1402,7 +1402,7 @@ void FramebufferManager::Resized() {
|
|||
}
|
||||
|
||||
bool FramebufferManager::GetCurrentFramebuffer(GPUDebugBuffer &buffer) {
|
||||
u32 fb_address = (gstate.fbptr & 0xFFFFFF) | ((gstate.fbwidth & 0xFF0000) << 8);
|
||||
u32 fb_address = gstate.getFrameBufRawAddress();
|
||||
int fb_stride = gstate.fbwidth & 0x3C0;
|
||||
|
||||
VirtualFramebuffer *vfb = currentRenderVfb_;
|
||||
|
@ -1429,10 +1429,10 @@ bool FramebufferManager::GetCurrentFramebuffer(GPUDebugBuffer &buffer) {
|
|||
}
|
||||
|
||||
bool FramebufferManager::GetCurrentDepthbuffer(GPUDebugBuffer &buffer) {
|
||||
u32 fb_address = (gstate.fbptr & 0xFFFFFF) | ((gstate.fbwidth & 0xFF0000) << 8);
|
||||
u32 fb_address = gstate.getFrameBufRawAddress();
|
||||
int fb_stride = gstate.fbwidth & 0x3C0;
|
||||
|
||||
u32 z_address = (gstate.zbptr & 0xFFFFFF) | ((gstate.zbwidth & 0xFF0000) << 8);
|
||||
u32 z_address = gstate.getDepthBufRawAddress();
|
||||
int z_stride = gstate.zbwidth & 0x3C0;
|
||||
|
||||
VirtualFramebuffer *vfb = currentRenderVfb_;
|
||||
|
@ -1462,7 +1462,7 @@ bool FramebufferManager::GetCurrentDepthbuffer(GPUDebugBuffer &buffer) {
|
|||
}
|
||||
|
||||
bool FramebufferManager::GetCurrentStencilbuffer(GPUDebugBuffer &buffer) {
|
||||
u32 fb_address = (gstate.fbptr & 0xFFFFFF) | ((gstate.fbwidth & 0xFF0000) << 8);
|
||||
u32 fb_address = gstate.getFrameBufRawAddress();
|
||||
int fb_stride = gstate.fbwidth & 0x3C0;
|
||||
|
||||
VirtualFramebuffer *vfb = currentRenderVfb_;
|
||||
|
@ -1478,7 +1478,7 @@ bool FramebufferManager::GetCurrentStencilbuffer(GPUDebugBuffer &buffer) {
|
|||
}
|
||||
|
||||
#ifndef USING_GLES2
|
||||
buffer.Allocate(vfb->renderWidth, vfb->renderHeight, GPU_DBG_FORMAT_16BIT, true);
|
||||
buffer.Allocate(vfb->renderWidth, vfb->renderHeight, GPU_DBG_FORMAT_8BIT, true);
|
||||
if (vfb->fbo)
|
||||
fbo_bind_for_read(vfb->fbo);
|
||||
glReadBuffer(GL_STENCIL_ATTACHMENT);
|
||||
|
|
|
@ -1100,9 +1100,10 @@ std::vector<GPUDebugOp> GPUCommon::DissassembleOpRange(u32 startpc, u32 endpc) {
|
|||
std::vector<GPUDebugOp> result;
|
||||
GPUDebugOp info;
|
||||
|
||||
u32 prev = Memory::Read_U32(startpc - 4);
|
||||
// Don't trigger a pause.
|
||||
u32 prev = Memory::IsValidAddress(startpc - 4) ? Memory::Read_U32(startpc - 4) : 0;
|
||||
for (u32 pc = startpc; pc < endpc; pc += 4) {
|
||||
u32 op = Memory::Read_U32(pc);
|
||||
u32 op = Memory::IsValidAddress(pc) ? Memory::Read_U32(pc) : 0;
|
||||
GeDisassembleOp(pc, op, prev, buffer);
|
||||
prev = op;
|
||||
|
||||
|
@ -1130,3 +1131,12 @@ u32 GPUCommon::GetIndexAddress() {
|
|||
GPUgstate GPUCommon::GetGState() {
|
||||
return gstate;
|
||||
}
|
||||
|
||||
void GPUCommon::SetCmdValue(u32 op) {
|
||||
u32 cmd = op >> 24;
|
||||
u32 diff = op ^ gstate.cmdmem[cmd];
|
||||
|
||||
PreExecuteOp(op, diff);
|
||||
gstate.cmdmem[cmd] = op;
|
||||
ExecuteOp(op, diff);
|
||||
}
|
||||
|
|
|
@ -152,6 +152,7 @@ public:
|
|||
virtual u32 GetVertexAddress();
|
||||
virtual u32 GetIndexAddress();
|
||||
virtual GPUgstate GetGState();
|
||||
virtual void SetCmdValue(u32 op);
|
||||
|
||||
virtual DisplayList* getList(int listid)
|
||||
{
|
||||
|
|
|
@ -212,8 +212,13 @@ struct GPUgstate
|
|||
float tgenMatrix[12];
|
||||
float boneMatrix[12 * 8]; // Eight bone matrices.
|
||||
|
||||
u32 getFrameBufRawAddress() const { return (fbptr & 0xFFFFFF) | ((fbwidth & 0xFF0000) << 8); }
|
||||
// 0x44000000 is uncached VRAM.
|
||||
u32 getFrameBufAddress() const { return 0x44000000 | getFrameBufRawAddress(); }
|
||||
GEBufferFormat FrameBufFormat() const { return static_cast<GEBufferFormat>(framebufpixformat & 3); }
|
||||
int FrameBufStride() const { return fbwidth&0x7C0; }
|
||||
u32 getDepthBufRawAddress() const { return (zbptr & 0xFFFFFF) | ((zbwidth & 0xFF0000) << 8); }
|
||||
u32 getDepthBufAddress() const { return 0x44000000 | getDepthBufRawAddress(); }
|
||||
int DepthBufStride() const { return zbwidth&0x7C0; }
|
||||
|
||||
// Pixel Pipeline
|
||||
|
|
|
@ -431,11 +431,11 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff)
|
|||
break;
|
||||
|
||||
case GE_CMD_FRAMEBUFPTR:
|
||||
fb.data = Memory::GetPointer(0x44000000 | (gstate.fbptr & 0xFFFFFF) | ((gstate.fbwidth & 0xFF0000) << 8));
|
||||
fb.data = Memory::GetPointer(gstate.getFrameBufAddress());
|
||||
break;
|
||||
|
||||
case GE_CMD_FRAMEBUFWIDTH:
|
||||
fb.data = Memory::GetPointer(0x44000000 | (gstate.fbptr & 0xFFFFFF) | ((gstate.fbwidth & 0xFF0000) << 8));
|
||||
fb.data = Memory::GetPointer(gstate.getFrameBufAddress());
|
||||
break;
|
||||
|
||||
case GE_CMD_FRAMEBUFPIXFORMAT:
|
||||
|
@ -532,11 +532,11 @@ void SoftGPU::ExecuteOp(u32 op, u32 diff)
|
|||
break;
|
||||
|
||||
case GE_CMD_ZBUFPTR:
|
||||
depthbuf.data = Memory::GetPointer(0x44000000 | (gstate.zbptr & 0xFFFFFF) | ((gstate.zbwidth & 0xFF0000) << 8));
|
||||
depthbuf.data = Memory::GetPointer(gstate.getDepthBufAddress());
|
||||
break;
|
||||
|
||||
case GE_CMD_ZBUFWIDTH:
|
||||
depthbuf.data = Memory::GetPointer(0x44000000 | (gstate.zbptr & 0xFFFFFF) | ((gstate.zbwidth & 0xFF0000) << 8));
|
||||
depthbuf.data = Memory::GetPointer(gstate.getDepthBufAddress());
|
||||
break;
|
||||
|
||||
case GE_CMD_AMBIENTCOLOR:
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
#include "Windows/GEDebugger/CtrlDisplayListView.h"
|
||||
#include "Core/Config.h"
|
||||
#include "Windows/GEDebugger/GEDebugger.h"
|
||||
#include "Windows/InputBox.h"
|
||||
#include "Windows/Main.h"
|
||||
#include "Core/Config.h"
|
||||
#include <algorithm>
|
||||
|
||||
const PTCHAR CtrlDisplayListView::windowClass = _T("CtrlDisplayListView");
|
||||
|
@ -166,6 +167,8 @@ void CtrlDisplayListView::onPaint(WPARAM wParam, LPARAM lParam)
|
|||
|
||||
HICON breakPoint = (HICON)LoadIcon(GetModuleHandle(0),(LPCWSTR)IDI_STOP);
|
||||
|
||||
auto disasm = gpuDebug->DissassembleOpRange(windowStart, windowStart + (visibleRows + 2) * instructionSize);
|
||||
|
||||
for (int i = 0; i < visibleRows+2; i++)
|
||||
{
|
||||
unsigned int address=windowStart + i*instructionSize;
|
||||
|
@ -210,7 +213,7 @@ void CtrlDisplayListView::onPaint(WPARAM wParam, LPARAM lParam)
|
|||
}
|
||||
SetTextColor(hdc,textColor);
|
||||
|
||||
GPUDebugOp op = gpuDebug->DissassembleOp(address);
|
||||
GPUDebugOp op = i < (int)disasm.size() ? disasm[i] : GPUDebugOp();
|
||||
|
||||
char addressText[64];
|
||||
sprintf(addressText,"%08X %08X",op.pc,op.op);
|
||||
|
@ -328,7 +331,7 @@ void CtrlDisplayListView::onMouseUp(WPARAM wParam, LPARAM lParam, int button)
|
|||
redraw();
|
||||
}
|
||||
break;
|
||||
case IDC_DEBUG_LIST_SETSTALL:
|
||||
case ID_GEDBG_SETSTALLADDR:
|
||||
{
|
||||
gpuDebug->ResetListStall(list.id,curAddress);
|
||||
list.stall = curAddress;
|
||||
|
@ -354,6 +357,24 @@ void CtrlDisplayListView::onMouseUp(WPARAM wParam, LPARAM lParam, int button)
|
|||
redraw();
|
||||
}
|
||||
break;
|
||||
case ID_GEDBG_GOTOPC:
|
||||
setCurAddress(list.pc);
|
||||
scrollAddressIntoView();
|
||||
redraw();
|
||||
break;
|
||||
case ID_GEDBG_GOTOADDR:
|
||||
{
|
||||
u32 newAddress = curAddress;
|
||||
if (!InputBox_GetHex(GetModuleHandle(NULL), wnd, L"Address", curAddress, newAddress)) {
|
||||
break;
|
||||
}
|
||||
if (Memory::IsValidAddress(newAddress)) {
|
||||
setCurAddress(newAddress);
|
||||
scrollAddressIntoView();
|
||||
redraw();
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -41,6 +41,7 @@ enum PauseAction {
|
|||
PAUSE_GETDEPTHBUF,
|
||||
PAUSE_GETSTENCILBUF,
|
||||
PAUSE_GETTEX,
|
||||
PAUSE_SETCMDVALUE,
|
||||
};
|
||||
|
||||
static bool attached = false;
|
||||
|
@ -65,6 +66,13 @@ static GPUDebugBuffer bufferFrame;
|
|||
static GPUDebugBuffer bufferDepth;
|
||||
static GPUDebugBuffer bufferStencil;
|
||||
static GPUDebugBuffer bufferTex;
|
||||
static u32 pauseSetCmdValue;
|
||||
|
||||
enum PrimaryDisplayType {
|
||||
PRIMARY_FRAMEBUF,
|
||||
PRIMARY_DEPTHBUF,
|
||||
PRIMARY_STENCILBUF,
|
||||
};
|
||||
|
||||
// TODO: Simplify and move out of windows stuff, just block in a common way for everyone.
|
||||
|
||||
|
@ -137,6 +145,13 @@ static void RunPauseAction() {
|
|||
case PAUSE_GETTEX:
|
||||
bufferResult = gpuDebug->GetCurrentTexture(bufferTex);
|
||||
break;
|
||||
|
||||
case PAUSE_SETCMDVALUE:
|
||||
gpuDebug->SetCmdValue(pauseSetCmdValue);
|
||||
break;
|
||||
|
||||
default:
|
||||
ERROR_LOG(HLE, "Unsupported pause action, forgot to add it to the switch.");
|
||||
}
|
||||
|
||||
actionWait.notify_one();
|
||||
|
@ -151,7 +166,7 @@ static void ForceUnpause() {
|
|||
}
|
||||
|
||||
CGEDebugger::CGEDebugger(HINSTANCE _hInstance, HWND _hParent)
|
||||
: Dialog((LPCSTR)IDD_GEDEBUGGER, _hInstance, _hParent), primaryDisplay(PRIMARY_FRAMEBUF), frameWindow(NULL), texWindow(NULL) {
|
||||
: Dialog((LPCSTR)IDD_GEDEBUGGER, _hInstance, _hParent), frameWindow(NULL), texWindow(NULL) {
|
||||
breakCmds.resize(256, false);
|
||||
Core_ListenShutdown(ForceUnpause);
|
||||
|
||||
|
@ -175,6 +190,14 @@ CGEDebugger::CGEDebugger(HINSTANCE _hInstance, HWND _hParent)
|
|||
HWND wnd = tabs->AddTabWindow(L"CtrlDisplayListView",L"Display List");
|
||||
displayList = CtrlDisplayListView::getFrom(wnd);
|
||||
|
||||
fbTabs = new TabControl(GetDlgItem(m_hDlg, IDC_GEDBG_FBTABS));
|
||||
fbTabs->SetMinTabWidth(50);
|
||||
// Must be in the same order as PrimaryDisplayType.
|
||||
fbTabs->AddTab(NULL, L"Color");
|
||||
fbTabs->AddTab(NULL, L"Depth");
|
||||
fbTabs->AddTab(NULL, L"Stencil");
|
||||
fbTabs->ShowTab(0, true);
|
||||
|
||||
flags = new TabStateFlags(_hInstance, m_hDlg);
|
||||
tabs->AddTabDialog(flags, L"Flags");
|
||||
|
||||
|
@ -201,28 +224,24 @@ CGEDebugger::CGEDebugger(HINSTANCE _hInstance, HWND _hParent)
|
|||
}
|
||||
|
||||
CGEDebugger::~CGEDebugger() {
|
||||
delete frameWindow;
|
||||
delete texWindow;
|
||||
|
||||
delete flags;
|
||||
delete lighting;
|
||||
delete textureState;
|
||||
delete settings;
|
||||
delete lists;
|
||||
delete tabs;
|
||||
delete fbTabs;
|
||||
}
|
||||
|
||||
void CGEDebugger::SetupPreviews() {
|
||||
if (frameWindow == NULL) {
|
||||
frameWindow = SimpleGLWindow::GetFrom(GetDlgItem(m_hDlg, IDC_GEDBG_FRAME));
|
||||
frameWindow->Initialize(SimpleGLWindow::ALPHA_IGNORE | SimpleGLWindow::RESIZE_SHRINK_CENTER);
|
||||
// TODO: Why doesn't this work?
|
||||
frameWindow->Clear();
|
||||
}
|
||||
if (texWindow == NULL) {
|
||||
texWindow = SimpleGLWindow::GetFrom(GetDlgItem(m_hDlg, IDC_GEDBG_TEX));
|
||||
texWindow->Initialize(SimpleGLWindow::ALPHA_BLEND | SimpleGLWindow::RESIZE_SHRINK_CENTER);
|
||||
// TODO: Why doesn't this work?
|
||||
texWindow->Clear();
|
||||
}
|
||||
}
|
||||
|
@ -230,31 +249,42 @@ void CGEDebugger::SetupPreviews() {
|
|||
void CGEDebugger::UpdatePreviews() {
|
||||
// TODO: Do something different if not paused?
|
||||
|
||||
wchar_t desc[256];
|
||||
GPUDebugBuffer *primaryBuffer = NULL;
|
||||
GPUgstate state;
|
||||
bufferResult = false;
|
||||
switch (primaryDisplay) {
|
||||
|
||||
if (gpuDebug != NULL) {
|
||||
state = gpuDebug->GetGState();
|
||||
}
|
||||
|
||||
switch (PrimaryDisplayType(fbTabs->CurrentTabIndex())) {
|
||||
case PRIMARY_FRAMEBUF:
|
||||
SetPauseAction(PAUSE_GETFRAMEBUF);
|
||||
primaryBuffer = &bufferFrame;
|
||||
_snwprintf(desc, ARRAY_SIZE(desc), L"Color: 0x%08x (%dx%d)", state.getFrameBufRawAddress(), primaryBuffer->GetStride(), primaryBuffer->GetHeight());
|
||||
break;
|
||||
|
||||
case PRIMARY_DEPTHBUF:
|
||||
SetPauseAction(PAUSE_GETDEPTHBUF);
|
||||
primaryBuffer = &bufferDepth;
|
||||
_snwprintf(desc, ARRAY_SIZE(desc), L"Depth: 0x%08x (%dx%d)", state.getDepthBufRawAddress(), primaryBuffer->GetStride(), primaryBuffer->GetHeight());
|
||||
break;
|
||||
|
||||
case PRIMARY_STENCILBUF:
|
||||
SetPauseAction(PAUSE_GETSTENCILBUF);
|
||||
primaryBuffer = &bufferStencil;
|
||||
_snwprintf(desc, ARRAY_SIZE(desc), L"Stencil: 0x%08x (%dx%d)", state.getFrameBufRawAddress(), primaryBuffer->GetStride(), primaryBuffer->GetHeight());
|
||||
break;
|
||||
}
|
||||
|
||||
if (bufferResult && primaryBuffer != NULL) {
|
||||
auto fmt = SimpleGLWindow::Format(primaryBuffer->GetFormat());
|
||||
frameWindow->Draw(primaryBuffer->GetData(), primaryBuffer->GetStride(), primaryBuffer->GetHeight(), primaryBuffer->GetFlipped(), fmt);
|
||||
SetDlgItemText(m_hDlg, IDC_GEDBG_FRAMEBUFADDR, desc);
|
||||
} else {
|
||||
ERROR_LOG(COMMON, "Unable to get buffer for main display.");
|
||||
frameWindow->Clear();
|
||||
SetDlgItemText(m_hDlg, IDC_GEDBG_FRAMEBUFADDR, L"Failed");
|
||||
}
|
||||
|
||||
bufferResult = false;
|
||||
|
@ -265,20 +295,25 @@ void CGEDebugger::UpdatePreviews() {
|
|||
texWindow->Draw(bufferTex.GetData(), bufferTex.GetStride(), bufferTex.GetHeight(), bufferTex.GetFlipped(), fmt);
|
||||
|
||||
if (gpuDebug != NULL) {
|
||||
auto state = gpuDebug->GetGState();
|
||||
if (state.isTextureAlphaUsed()) {
|
||||
texWindow->SetFlags(SimpleGLWindow::ALPHA_BLEND | SimpleGLWindow::RESIZE_SHRINK_CENTER);
|
||||
} else {
|
||||
texWindow->SetFlags(SimpleGLWindow::RESIZE_SHRINK_CENTER);
|
||||
}
|
||||
_snwprintf(desc, ARRAY_SIZE(desc), L"Texture: 0x%08x (%dx%d)", state.getTextureAddress(0), state.getTextureWidth(0), state.getTextureHeight(0));
|
||||
SetDlgItemText(m_hDlg, IDC_GEDBG_TEXADDR, desc);
|
||||
}
|
||||
} else {
|
||||
ERROR_LOG(COMMON, "Unable to get texture (may be no texture set.)");
|
||||
texWindow->Clear();
|
||||
if (gpuDebug == NULL || state.isTextureMapEnabled()) {
|
||||
SetDlgItemText(m_hDlg, IDC_GEDBG_TEXADDR, L"Texture: failed");
|
||||
} else {
|
||||
SetDlgItemText(m_hDlg, IDC_GEDBG_TEXADDR, L"Texture: disabled");
|
||||
}
|
||||
}
|
||||
|
||||
DisplayList list;
|
||||
if (gpuDebug->GetCurrentDisplayList(list)) {
|
||||
if (gpuDebug != NULL && gpuDebug->GetCurrentDisplayList(list)) {
|
||||
displayList->setDisplayList(list);
|
||||
}
|
||||
|
||||
|
@ -357,6 +392,13 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) {
|
|||
case IDC_GEDBG_MAINTAB:
|
||||
tabs->HandleNotify(lParam);
|
||||
break;
|
||||
case IDC_GEDBG_FBTABS:
|
||||
fbTabs->HandleNotify(lParam);
|
||||
// TODO: Move this somewhere...
|
||||
if (attached && gpuDebug != NULL) {
|
||||
UpdatePreviews();
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -378,6 +420,9 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) {
|
|||
case IDC_GEDBG_RESUME:
|
||||
frameWindow->Clear();
|
||||
texWindow->Clear();
|
||||
SetDlgItemText(m_hDlg, IDC_GEDBG_FRAMEBUFADDR, L"");
|
||||
SetDlgItemText(m_hDlg, IDC_GEDBG_TEXADDR, L"");
|
||||
|
||||
// TODO: detach? Should probably have separate UI, or just on activate?
|
||||
breakNextOp = false;
|
||||
breakNextDraw = false;
|
||||
|
@ -432,6 +477,13 @@ BOOL CGEDebugger::DlgProc(UINT message, WPARAM wParam, LPARAM lParam) {
|
|||
SendMessage(m_hDlg,WM_COMMAND,IDC_GEDBG_RESUME,0);
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_GEDBG_SETCMDWPARAM:
|
||||
{
|
||||
pauseSetCmdValue = (u32)wParam;
|
||||
SetPauseAction(PAUSE_SETCMDVALUE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
|
|
@ -29,7 +29,8 @@ enum {
|
|||
WM_GEDBG_BREAK_DRAW,
|
||||
WM_GEDBG_STEPDISPLAYLIST,
|
||||
WM_GEDBG_TOGGLEPCBREAKPOINT,
|
||||
WM_GEDBG_RUNTOWPARAM
|
||||
WM_GEDBG_RUNTOWPARAM,
|
||||
WM_GEDBG_SETCMDWPARAM,
|
||||
};
|
||||
|
||||
class CtrlDisplayListView;
|
||||
|
@ -61,13 +62,6 @@ private:
|
|||
void UpdateSize(WORD width, WORD height);
|
||||
void SavePosition();
|
||||
|
||||
enum PrimaryDisplayType {
|
||||
PRIMARY_FRAMEBUF,
|
||||
PRIMARY_DEPTHBUF,
|
||||
PRIMARY_STENCILBUF,
|
||||
};
|
||||
|
||||
PrimaryDisplayType primaryDisplay;
|
||||
CtrlDisplayListView *displayList;
|
||||
TabDisplayLists *lists;
|
||||
TabStateFlags *flags;
|
||||
|
@ -77,6 +71,7 @@ private:
|
|||
SimpleGLWindow *frameWindow;
|
||||
SimpleGLWindow *texWindow;
|
||||
TabControl *tabs;
|
||||
TabControl *fbTabs;
|
||||
|
||||
int minWidth,minHeight;
|
||||
};
|
||||
|
|
|
@ -227,6 +227,9 @@ void SimpleGLWindow::Draw(u8 *data, int w, int h, bool flipped, Format fmt) {
|
|||
} else if (fmt == FORMAT_16BIT) {
|
||||
glfmt = GL_UNSIGNED_SHORT;
|
||||
components = GL_RED;
|
||||
} else if (fmt == FORMAT_8BIT) {
|
||||
glfmt = GL_UNSIGNED_BYTE;
|
||||
components = GL_RED;
|
||||
} else {
|
||||
_dbg_assert_msg_(COMMON, false, "Invalid SimpleGLWindow format.");
|
||||
}
|
||||
|
@ -254,6 +257,11 @@ void SimpleGLWindow::Draw(u8 *data, int w, int h, bool flipped, Format fmt) {
|
|||
void SimpleGLWindow::Redraw() {
|
||||
DrawChecker();
|
||||
|
||||
if (tw_ == 0 && th_ == 0) {
|
||||
Swap();
|
||||
return;
|
||||
}
|
||||
|
||||
if (flags_ & ALPHA_BLEND) {
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
@ -306,8 +314,63 @@ void SimpleGLWindow::Redraw() {
|
|||
}
|
||||
|
||||
void SimpleGLWindow::Clear() {
|
||||
DrawChecker();
|
||||
Swap();
|
||||
tw_ = 0;
|
||||
th_ = 0;
|
||||
Redraw();
|
||||
}
|
||||
|
||||
bool SimpleGLWindow::DragStart(int mouseX, int mouseY) {
|
||||
// Only while zoomed in, otherwise it's shrink to fit mode or fixed.
|
||||
if (!zoom_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dragging_ = true;
|
||||
SetCapture(hWnd_);
|
||||
dragStartX_ = mouseX - offsetX_;
|
||||
dragStartY_ = mouseY - offsetY_;
|
||||
dragLastUpdate_ = GetTickCount();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SimpleGLWindow::DragContinue(int mouseX, int mouseY) {
|
||||
if (!dragging_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
offsetX_ = mouseX - dragStartX_;
|
||||
offsetY_ = mouseY - dragStartY_;
|
||||
|
||||
const u32 MS_BETWEEN_DRAG_REDRAWS = 5;
|
||||
if (GetTickCount() - dragLastUpdate_ > MS_BETWEEN_DRAG_REDRAWS) {
|
||||
Redraw();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SimpleGLWindow::DragEnd(int mouseX, int mouseY) {
|
||||
if (!dragging_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
dragging_ = false;
|
||||
ReleaseCapture();
|
||||
Redraw();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SimpleGLWindow::ToggleZoom() {
|
||||
// Reset the offset when zooming out (or in, doesn't matter.)
|
||||
offsetX_ = 0;
|
||||
offsetY_ = 0;
|
||||
|
||||
zoom_ = !zoom_;
|
||||
Redraw();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
SimpleGLWindow *SimpleGLWindow::GetFrom(HWND hwnd) {
|
||||
|
@ -320,48 +383,42 @@ LRESULT CALLBACK SimpleGLWindow::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPA
|
|||
switch(msg)
|
||||
{
|
||||
case WM_NCCREATE:
|
||||
// Allocate a new CustCtrl structure for this window.
|
||||
win = new SimpleGLWindow(hwnd);
|
||||
|
||||
// Continue with window creation.
|
||||
return win != NULL;
|
||||
return win != NULL ? TRUE : FALSE;
|
||||
|
||||
case WM_NCDESTROY:
|
||||
delete win;
|
||||
return 0;
|
||||
|
||||
case WM_LBUTTONDBLCLK:
|
||||
win->zoom_ = !win->zoom_;
|
||||
// Reset the offset when zooming out (or in, doesn't matter.)
|
||||
win->offsetX_ = 0;
|
||||
win->offsetY_ = 0;
|
||||
// Redrawn in WM_LBUTTONUP.
|
||||
return 0;
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
// Only while zoomed in, otherwise it's shrink to fit mode or fixed.
|
||||
if (win->zoom_) {
|
||||
win->dragging_ = true;
|
||||
win->dragStartX_ = GET_X_LPARAM(lParam) - win->offsetX_;
|
||||
win->dragStartY_ = GET_Y_LPARAM(lParam) - win->offsetY_;
|
||||
win->dragLastUpdate_ = GetTickCount();
|
||||
}
|
||||
return 0;
|
||||
|
||||
case WM_LBUTTONUP:
|
||||
win->dragging_ = false;
|
||||
win->Redraw();
|
||||
return 0;
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
if (win->dragging_) {
|
||||
int x = GET_X_LPARAM(lParam);
|
||||
int y = GET_Y_LPARAM(lParam);
|
||||
win->offsetX_ = x - win->dragStartX_;
|
||||
win->offsetY_ = y - win->dragStartY_;
|
||||
const u32 MS_BETWEEN_DRAG_REDRAWS = 5;
|
||||
if (GetTickCount() - win->dragLastUpdate_ > MS_BETWEEN_DRAG_REDRAWS) {
|
||||
win->Redraw();
|
||||
}
|
||||
if (win->ToggleZoom()) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_LBUTTONDOWN:
|
||||
if (win->DragStart(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_LBUTTONUP:
|
||||
if (win->DragEnd(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_MOUSEMOVE:
|
||||
if (win->DragContinue(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))) {
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case WM_PAINT:
|
||||
win->Redraw();
|
||||
break;
|
||||
}
|
||||
|
||||
return DefWindowProc(hwnd, msg, wParam, lParam);
|
||||
|
|
|
@ -32,6 +32,7 @@ struct SimpleGLWindow {
|
|||
|
||||
FORMAT_FLOAT = 0x10,
|
||||
FORMAT_16BIT = 0x11,
|
||||
FORMAT_8BIT = 0x12,
|
||||
};
|
||||
|
||||
enum Flags {
|
||||
|
@ -68,6 +69,10 @@ protected:
|
|||
void CreateProgram();
|
||||
void GenerateChecker();
|
||||
void DrawChecker();
|
||||
bool DragStart(int mouseX, int mouseY);
|
||||
bool DragContinue(int mouseX, int mouseY);
|
||||
bool DragEnd(int mouseX, int mouseY);
|
||||
bool ToggleZoom();
|
||||
|
||||
HWND hWnd_;
|
||||
HDC hDC_;
|
||||
|
|
|
@ -17,6 +17,8 @@
|
|||
|
||||
#include "base/basictypes.h"
|
||||
#include "Windows/resource.h"
|
||||
#include "Windows/InputBox.h"
|
||||
#include "Windows/GEDebugger/GEDebugger.h"
|
||||
#include "Windows/GEDebugger/TabState.h"
|
||||
#include "GPU/GPUState.h"
|
||||
#include "GPU/GeDisasm.h"
|
||||
|
@ -54,6 +56,7 @@ enum CmdFormatType {
|
|||
CMD_FMT_MATERIALUPDATE,
|
||||
CMD_FMT_STENCILOP,
|
||||
CMD_FMT_BLENDMODE,
|
||||
CMD_FMT_FLAG,
|
||||
};
|
||||
|
||||
struct TabStateRow {
|
||||
|
@ -66,25 +69,25 @@ struct TabStateRow {
|
|||
};
|
||||
|
||||
static const TabStateRow stateFlagsRows[] = {
|
||||
{ L"Lighting enable", GE_CMD_LIGHTINGENABLE, CMD_FMT_NUM },
|
||||
{ L"Light 0 enable", GE_CMD_LIGHTENABLE0, CMD_FMT_NUM },
|
||||
{ L"Light 1 enable", GE_CMD_LIGHTENABLE1, CMD_FMT_NUM },
|
||||
{ L"Light 2 enable", GE_CMD_LIGHTENABLE2, CMD_FMT_NUM },
|
||||
{ L"Light 3 enable", GE_CMD_LIGHTENABLE3, CMD_FMT_NUM },
|
||||
{ L"Clip enable", GE_CMD_CLIPENABLE, CMD_FMT_NUM },
|
||||
{ L"Cullface enable", GE_CMD_CULLFACEENABLE, CMD_FMT_NUM },
|
||||
{ L"Texture map enable", GE_CMD_TEXTUREMAPENABLE, CMD_FMT_NUM },
|
||||
{ L"Fog enable", GE_CMD_FOGENABLE, CMD_FMT_NUM },
|
||||
{ L"Dither enable", GE_CMD_DITHERENABLE, CMD_FMT_NUM },
|
||||
{ L"Alpha blend enable", GE_CMD_ALPHABLENDENABLE, CMD_FMT_NUM },
|
||||
{ L"Alpha test enable", GE_CMD_ALPHATESTENABLE, CMD_FMT_NUM },
|
||||
{ L"Depth test enable", GE_CMD_ZTESTENABLE, CMD_FMT_NUM },
|
||||
{ L"Stencil test enable", GE_CMD_STENCILTESTENABLE, CMD_FMT_NUM },
|
||||
{ L"Antialias enable", GE_CMD_ANTIALIASENABLE, CMD_FMT_NUM },
|
||||
{ L"Patch cull enable", GE_CMD_PATCHCULLENABLE, CMD_FMT_NUM },
|
||||
{ L"Color test enable", GE_CMD_COLORTESTENABLE, CMD_FMT_NUM },
|
||||
{ L"Logic op enable", GE_CMD_LOGICOPENABLE, CMD_FMT_NUM },
|
||||
{ L"Depth write disable", GE_CMD_ZWRITEDISABLE, CMD_FMT_NUM },
|
||||
{ L"Lighting enable", GE_CMD_LIGHTINGENABLE, CMD_FMT_FLAG },
|
||||
{ L"Light 0 enable", GE_CMD_LIGHTENABLE0, CMD_FMT_FLAG },
|
||||
{ L"Light 1 enable", GE_CMD_LIGHTENABLE1, CMD_FMT_FLAG },
|
||||
{ L"Light 2 enable", GE_CMD_LIGHTENABLE2, CMD_FMT_FLAG },
|
||||
{ L"Light 3 enable", GE_CMD_LIGHTENABLE3, CMD_FMT_FLAG },
|
||||
{ L"Clip enable", GE_CMD_CLIPENABLE, CMD_FMT_FLAG },
|
||||
{ L"Cullface enable", GE_CMD_CULLFACEENABLE, CMD_FMT_FLAG },
|
||||
{ L"Texture map enable", GE_CMD_TEXTUREMAPENABLE, CMD_FMT_FLAG },
|
||||
{ L"Fog enable", GE_CMD_FOGENABLE, CMD_FMT_FLAG },
|
||||
{ L"Dither enable", GE_CMD_DITHERENABLE, CMD_FMT_FLAG },
|
||||
{ L"Alpha blend enable", GE_CMD_ALPHABLENDENABLE, CMD_FMT_FLAG },
|
||||
{ L"Alpha test enable", GE_CMD_ALPHATESTENABLE, CMD_FMT_FLAG },
|
||||
{ L"Depth test enable", GE_CMD_ZTESTENABLE, CMD_FMT_FLAG },
|
||||
{ L"Stencil test enable", GE_CMD_STENCILTESTENABLE, CMD_FMT_FLAG },
|
||||
{ L"Antialias enable", GE_CMD_ANTIALIASENABLE, CMD_FMT_FLAG },
|
||||
{ L"Patch cull enable", GE_CMD_PATCHCULLENABLE, CMD_FMT_FLAG },
|
||||
{ L"Color test enable", GE_CMD_COLORTESTENABLE, CMD_FMT_FLAG },
|
||||
{ L"Logic op enable", GE_CMD_LOGICOPENABLE, CMD_FMT_FLAG },
|
||||
{ L"Depth write disable", GE_CMD_ZWRITEDISABLE, CMD_FMT_FLAG },
|
||||
};
|
||||
|
||||
static const TabStateRow stateLightingRows[] = {
|
||||
|
@ -97,7 +100,7 @@ static const TabStateRow stateLightingRows[] = {
|
|||
{ L"Material alpha", GE_CMD_MATERIALALPHA, CMD_FMT_HEX },
|
||||
{ L"Material specular", GE_CMD_MATERIALSPECULAR, CMD_FMT_HEX },
|
||||
{ L"Mat. specular coef", GE_CMD_MATERIALSPECULARCOEF, CMD_FMT_FLOAT24 },
|
||||
{ L"Reverse normals", GE_CMD_REVERSENORMAL, CMD_FMT_NUM },
|
||||
{ L"Reverse normals", GE_CMD_REVERSENORMAL, CMD_FMT_FLAG },
|
||||
// TODO: Format?
|
||||
{ L"Shade model", GE_CMD_SHADEMODE, CMD_FMT_NUM },
|
||||
// TODO: Format?
|
||||
|
@ -484,6 +487,14 @@ void FormatStateRow(wchar_t *dest, const TabStateRow &info, u32 value, bool enab
|
|||
}
|
||||
break;
|
||||
|
||||
case CMD_FMT_FLAG:
|
||||
if ((value & ~1) == 0) {
|
||||
swprintf(dest, L"%d", value);
|
||||
} else {
|
||||
swprintf(dest, L"%06x", value);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
swprintf(dest, L"BAD FORMAT %06x", value);
|
||||
}
|
||||
|
@ -518,7 +529,48 @@ void CtrlStateValues::GetColumnText(wchar_t *dest, int row, int col) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void CtrlStateValues::OnDoubleClick(int row, int column) {
|
||||
if (gpuDebug == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto info = rows_[row];
|
||||
switch (info.fmt) {
|
||||
case CMD_FMT_FLAG:
|
||||
{
|
||||
const auto state = gpuDebug->GetGState();
|
||||
u32 newValue = state.cmdmem[info.cmd] ^ 1;
|
||||
SetCmdValue(newValue);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
{
|
||||
// TODO: Floats/etc., and things with multiple cmds.
|
||||
const auto state = gpuDebug->GetGState();
|
||||
u32 newValue = state.cmdmem[info.cmd] & 0x00FFFFFF;
|
||||
if (InputBox_GetHex(GetModuleHandle(NULL), GetHandle(), L"New value", newValue, newValue)) {
|
||||
newValue |= state.cmdmem[info.cmd] & 0xFF000000;
|
||||
SetCmdValue(newValue);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CtrlStateValues::OnRightClick(int row, int column, const POINT& point) {
|
||||
if (gpuDebug == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO: Copy, break, watch... enable?
|
||||
}
|
||||
|
||||
void CtrlStateValues::SetCmdValue(u32 op) {
|
||||
SendMessage(GetParent(GetParent(GetHandle())), WM_GEDBG_SETCMDWPARAM, op, NULL);
|
||||
Update();
|
||||
}
|
||||
|
||||
TabStateValues::TabStateValues(const TabStateRow *rows, int rowCount, LPCSTR dialogID, HINSTANCE _hInstance, HWND _hParent)
|
||||
|
|
|
@ -30,8 +30,12 @@ protected:
|
|||
virtual bool WindowMessage(UINT msg, WPARAM wParam, LPARAM lParam, LRESULT& returnValue) { return false; };
|
||||
virtual void GetColumnText(wchar_t* dest, int row, int col);
|
||||
virtual int GetRowCount() { return rowCount_; }
|
||||
virtual void OnDoubleClick(int row, int column);
|
||||
virtual void OnRightClick(int row, int column, const POINT& point);
|
||||
|
||||
private:
|
||||
void SetCmdValue(u32 op);
|
||||
|
||||
const TabStateRow *rows_;
|
||||
int rowCount_;
|
||||
};
|
||||
|
|
|
@ -117,8 +117,11 @@ bool InputBox_GetHex(HINSTANCE hInst, HWND hParent, const wchar_t *title, u32 de
|
|||
|
||||
if (value == IDOK)
|
||||
{
|
||||
wscanf(out.c_str(),"%08x",&outvalue);
|
||||
return true;
|
||||
if (swscanf(out.c_str(), L"0x%08x", &outvalue) == 1)
|
||||
return true;
|
||||
if (swscanf(out.c_str(), L"%08x", &outvalue) == 1)
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -6,7 +6,8 @@
|
|||
|
||||
const DWORD tabControlStyleMask = ~(WS_POPUP | WS_TILEDWINDOW);
|
||||
|
||||
TabControl::TabControl(HWND handle): hwnd(handle), showTabTitles(true),currentTab(0),ignoreBottomMargin(false)
|
||||
TabControl::TabControl(HWND handle, bool noDisplayArea)
|
||||
: hwnd(handle), showTabTitles(true), currentTab(0), ignoreBottomMargin(false), noDisplayArea_(noDisplayArea)
|
||||
{
|
||||
SetWindowLongPtr(hwnd,GWLP_USERDATA,(LONG_PTR)this);
|
||||
oldProc = (WNDPROC) SetWindowLongPtr(hwnd,GWLP_WNDPROC,(LONG_PTR)wndProc);
|
||||
|
@ -60,26 +61,29 @@ void TabControl::AddTab(HWND handle, wchar_t* title)
|
|||
if (showTabTitles)
|
||||
AppendPageToControl(title);
|
||||
int index = tabs.size();
|
||||
|
||||
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);
|
||||
|
||||
TabInfo info;
|
||||
info.hasBorder = (style & WS_BORDER) != 0;
|
||||
info.hasClientEdge = (GetWindowLong(handle,GWL_EXSTYLE) & WS_EX_CLIENTEDGE) != 0;
|
||||
if (hasButtons == false)
|
||||
TabInfo info = {0};
|
||||
if (!noDisplayArea_)
|
||||
{
|
||||
style &= (~WS_BORDER);
|
||||
SetWindowLong(handle, GWL_EXSTYLE, GetWindowLong(handle,GWL_EXSTYLE) & (~WS_EX_CLIENTEDGE));
|
||||
}
|
||||
RECT tabRect;
|
||||
GetWindowRect(hwnd,&tabRect);
|
||||
MapWindowPoints(HWND_DESKTOP,GetParent(hwnd),(LPPOINT)&tabRect,2);
|
||||
TabCtrl_AdjustRect(hwnd, FALSE, &tabRect);
|
||||
|
||||
SetWindowLong(handle, GWL_STYLE, style & tabControlStyleMask);
|
||||
MoveWindow(handle,tabRect.left,tabRect.top,tabRect.right-tabRect.left,tabRect.bottom-tabRect.top,TRUE);
|
||||
SetParent(handle,GetParent(hwnd));
|
||||
DWORD style = (GetWindowLong(handle,GWL_STYLE) | WS_CHILD);
|
||||
|
||||
info.hasBorder = (style & WS_BORDER) != 0;
|
||||
info.hasClientEdge = (GetWindowLong(handle,GWL_EXSTYLE) & WS_EX_CLIENTEDGE) != 0;
|
||||
if (hasButtons == false)
|
||||
{
|
||||
style &= (~WS_BORDER);
|
||||
SetWindowLong(handle, GWL_EXSTYLE, GetWindowLong(handle,GWL_EXSTYLE) & (~WS_EX_CLIENTEDGE));
|
||||
}
|
||||
|
||||
SetWindowLong(handle, GWL_STYLE, style & tabControlStyleMask);
|
||||
MoveWindow(handle,tabRect.left,tabRect.top,tabRect.right-tabRect.left,tabRect.bottom-tabRect.top,TRUE);
|
||||
}
|
||||
|
||||
info.lastFocus = handle;
|
||||
info.pageHandle = handle;
|
||||
|
@ -133,7 +137,8 @@ void TabControl::ShowTab(int index, bool setControlIndex)
|
|||
{
|
||||
if (oldFocus && i == index)
|
||||
SetFocus(tabs[i].lastFocus);
|
||||
ShowWindow(tabs[i].pageHandle,i == index ? SW_NORMAL : SW_HIDE);
|
||||
if (!noDisplayArea_)
|
||||
ShowWindow(tabs[i].pageHandle,i == index ? SW_NORMAL : SW_HIDE);
|
||||
}
|
||||
|
||||
if (setControlIndex && showTabTitles)
|
||||
|
@ -156,7 +161,8 @@ void TabControl::ShowTab(HWND pageHandle)
|
|||
if (oldFocus)
|
||||
SetFocus(tabs[i].lastFocus);
|
||||
}
|
||||
ShowWindow(tabs[i].pageHandle,tabs[i].pageHandle == pageHandle ? SW_NORMAL : SW_HIDE);
|
||||
if (!noDisplayArea_)
|
||||
ShowWindow(tabs[i].pageHandle,tabs[i].pageHandle == pageHandle ? SW_NORMAL : SW_HIDE);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,7 +182,7 @@ void TabControl::SetShowTabTitles(bool enabled)
|
|||
{
|
||||
AppendPageToControl(tabs[i].title);
|
||||
|
||||
if (hasButtons == false)
|
||||
if (hasButtons == false && !noDisplayArea_)
|
||||
{
|
||||
DWORD style = GetWindowLong(tabs[i].pageHandle,GWL_STYLE) & (~WS_BORDER);
|
||||
SetWindowLong(tabs[i].pageHandle,GWL_STYLE,style);
|
||||
|
@ -186,7 +192,7 @@ void TabControl::SetShowTabTitles(bool enabled)
|
|||
}
|
||||
}
|
||||
TabCtrl_SetCurSel(hwnd,CurrentTabIndex());
|
||||
} else if (hasButtons == false)
|
||||
} else if (hasButtons == false && !noDisplayArea_)
|
||||
{
|
||||
for (int i = 0; i < (int) tabs.size(); i++)
|
||||
{
|
||||
|
@ -207,6 +213,11 @@ void TabControl::SetShowTabTitles(bool enabled)
|
|||
OnResize();
|
||||
}
|
||||
|
||||
void TabControl::SetMinTabWidth(int w)
|
||||
{
|
||||
TabCtrl_SetMinTabWidth(hwnd, w);
|
||||
}
|
||||
|
||||
void TabControl::NextTab(bool cycle)
|
||||
{
|
||||
int index = CurrentTabIndex()+1;
|
||||
|
@ -265,15 +276,18 @@ void TabControl::OnResize()
|
|||
|
||||
int current = CurrentTabIndex();
|
||||
|
||||
for (size_t i = 0; i < tabs.size(); i++)
|
||||
if (!noDisplayArea_)
|
||||
{
|
||||
InvalidateRect(tabs[i].pageHandle,NULL,FALSE);
|
||||
MoveWindow(tabs[i].pageHandle,tabRect.left,tabRect.top,tabRect.right-tabRect.left,tabRect.bottom-tabRect.top,TRUE);
|
||||
|
||||
if (i == current)
|
||||
for (size_t i = 0; i < tabs.size(); i++)
|
||||
{
|
||||
InvalidateRect(tabs[i].pageHandle,NULL,TRUE);
|
||||
UpdateWindow(tabs[i].pageHandle);
|
||||
InvalidateRect(tabs[i].pageHandle,NULL,FALSE);
|
||||
MoveWindow(tabs[i].pageHandle,tabRect.left,tabRect.top,tabRect.right-tabRect.left,tabRect.bottom-tabRect.top,TRUE);
|
||||
|
||||
if (i == current)
|
||||
{
|
||||
InvalidateRect(tabs[i].pageHandle,NULL,TRUE);
|
||||
UpdateWindow(tabs[i].pageHandle);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ class Dialog;
|
|||
class TabControl
|
||||
{
|
||||
public:
|
||||
TabControl(HWND handle);
|
||||
TabControl(HWND handle, bool noDisplayArea = false);
|
||||
void HandleNotify(LPARAM lParam);
|
||||
HWND AddTabWindow(wchar_t* className, wchar_t* title, DWORD style = 0);
|
||||
void AddTabDialog(Dialog* dialog, wchar_t* title);
|
||||
|
@ -21,6 +21,8 @@ public:
|
|||
void SetShowTabTitles(bool enabled);
|
||||
void SetIgnoreBottomMargin(bool enabled) { ignoreBottomMargin = enabled; };
|
||||
bool GetShowTabTitles() { return showTabTitles; };
|
||||
void SetMinTabWidth(int w);
|
||||
|
||||
private:
|
||||
static LRESULT CALLBACK wndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam);
|
||||
void OnResize();
|
||||
|
@ -42,4 +44,5 @@ private:
|
|||
bool ignoreBottomMargin;
|
||||
int currentTab;
|
||||
bool hasButtons;
|
||||
bool noDisplayArea_;
|
||||
};
|
|
@ -178,7 +178,10 @@ 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_MAINTAB,"SysTabControl32",TCS_TABS | TCS_FOCUSNEVER ,10,216,480,180
|
||||
CONTROL "",IDC_GEDBG_MAINTAB,"SysTabControl32",TCS_TABS | TCS_FOCUSNEVER,10,216,480,180
|
||||
EDITTEXT IDC_GEDBG_FRAMEBUFADDR,148,192,128,12,ES_READONLY | NOT WS_BORDER
|
||||
EDITTEXT IDC_GEDBG_TEXADDR,10,152,128,12,ES_READONLY | NOT WS_BORDER
|
||||
CONTROL "",IDC_GEDBG_FBTABS,"SysTabControl32",TCS_BUTTONS | TCS_FOCUSNEVER,384,192,110,12
|
||||
END
|
||||
|
||||
|
||||
|
@ -505,7 +508,7 @@ BEGIN
|
|||
MENUITEM "Copy Instruction (Disasm)", ID_DISASM_COPYINSTRUCTIONDISASM
|
||||
MENUITEM "Disassemble to File", ID_DISASM_DISASSEMBLETOFILE
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Assemble Ppcode", ID_DISASM_ASSEMBLE
|
||||
MENUITEM "Assemble Opcode", ID_DISASM_ASSEMBLE
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Run to Cursor", ID_DISASM_RUNTOHERE
|
||||
MENUITEM "Jump to Cursor", ID_DISASM_SETPCTOHERE
|
||||
|
@ -558,9 +561,11 @@ BEGIN
|
|||
MENUITEM SEPARATOR
|
||||
MENUITEM "Run to Cursor", ID_DISASM_RUNTOHERE
|
||||
MENUITEM "Jump to Cursor", ID_DISASM_SETPCTOHERE
|
||||
MENUITEM "Set Stall" IDC_DEBUG_LIST_SETSTALL
|
||||
MENUITEM "Set Stall" ID_GEDBG_SETSTALLADDR
|
||||
MENUITEM "Toggle Breakpoint", ID_DISASM_TOGGLEBREAKPOINT
|
||||
MENUITEM SEPARATOR
|
||||
MENUITEM "Go to Displaylist PC", ID_GEDBG_GOTOPC
|
||||
MENUITEM "Go to Address...", ID_GEDBG_GOTOADDR
|
||||
MENUITEM "Go to in Memory View", ID_DISASM_GOTOINMEMORYVIEW
|
||||
END
|
||||
END
|
||||
|
|
|
@ -155,6 +155,9 @@
|
|||
#define IDC_DUMP_SIZE 1188
|
||||
#define IDC_DUMP_FILENAME 1189
|
||||
#define IDC_DUMP_BROWSEFILENAME 1190
|
||||
#define IDC_GEDBG_FRAMEBUFADDR 1191
|
||||
#define IDC_GEDBG_TEXADDR 1192
|
||||
#define IDC_GEDBG_FBTABS 1193
|
||||
|
||||
// Don't define anything else in the 3000 range.
|
||||
// It's reserved for languages.
|
||||
|
@ -284,7 +287,9 @@
|
|||
#define IDC_DEBUG_BOTTOMTABS 40127
|
||||
#define ID_DEBUG_HIDEBOTTOMTABS 40128
|
||||
#define ID_DEBUG_TOGGLEBOTTOMTABTITLES 40129
|
||||
#define IDC_DEBUG_LIST_SETSTALL 40130
|
||||
#define ID_GEDBG_SETSTALLADDR 40130
|
||||
#define ID_GEDBG_GOTOPC 40131
|
||||
#define ID_GEDBG_GOTOADDR 40132
|
||||
|
||||
// Dummy option to let the buffered rendering hotkey cycle through all the options.
|
||||
#define ID_OPTIONS_BUFFEREDRENDERINGDUMMY 40500
|
||||
|
@ -297,8 +302,8 @@
|
|||
#ifdef APSTUDIO_INVOKED
|
||||
#ifndef APSTUDIO_READONLY_SYMBOLS
|
||||
#define _APS_NEXT_RESOURCE_VALUE 254
|
||||
#define _APS_NEXT_COMMAND_VALUE 40131
|
||||
#define _APS_NEXT_CONTROL_VALUE 1191
|
||||
#define _APS_NEXT_COMMAND_VALUE 40133
|
||||
#define _APS_NEXT_CONTROL_VALUE 1193
|
||||
#define _APS_NEXT_SYMED_VALUE 101
|
||||
#endif
|
||||
#endif
|
||||
|
|
Loading…
Add table
Reference in a new issue