Track hovering in GE debugger to show pixel value.

This works for texture, framebuffer, depth, and stencil.

Importantly, allows debugging the actual depth values present.
This commit is contained in:
Unknown W. Brackets 2015-08-23 09:25:05 -07:00
parent 14fd3136b1
commit ba15718db3
11 changed files with 408 additions and 92 deletions

View File

@ -1455,6 +1455,7 @@ add_library(GPU OBJECT
GPU/Common/DepalettizeShaderCommon.h
GPU/Common/FramebufferCommon.cpp
GPU/Common/FramebufferCommon.h
GPU/Common/GPUDebugInterface.cpp
GPU/Common/GPUDebugInterface.h
GPU/Common/DrawEngineCommon.cpp
GPU/Common/DrawEngineCommon.h

View File

@ -0,0 +1,98 @@
// Copyright (c) 2012- PPSSPP Project.
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, version 2.0 or later versions.
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License 2.0 for more details.
// A copy of the GPL 2.0 should have been included with the program.
// If not, see http://www.gnu.org/licenses/
// Official git repository and contact information can be found at
// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.
#include "GPUDebugInterface.h"
void GPUDebugBuffer::Allocate(u32 stride, u32 height, GEBufferFormat fmt, bool flipped, bool reversed) {
GPUDebugBufferFormat actualFmt = GPUDebugBufferFormat(fmt);
if (reversed && actualFmt < GPU_DBG_FORMAT_8888) {
actualFmt |= GPU_DBG_FORMAT_REVERSE_FLAG;
}
Allocate(stride, height, actualFmt, flipped);
}
void GPUDebugBuffer::Allocate(u32 stride, u32 height, GPUDebugBufferFormat fmt, bool flipped) {
if (alloc_ && stride_ == stride && height_ == height && fmt_ == fmt) {
// Already allocated the right size.
flipped_ = flipped;
return;
}
Free();
alloc_ = true;
height_ = height;
stride_ = stride;
fmt_ = fmt;
flipped_ = flipped;
u32 pixelSize = PixelSize(fmt);
data_ = new u8[pixelSize * stride * height];
}
void GPUDebugBuffer::Free() {
if (alloc_ && data_ != NULL) {
delete [] data_;
}
data_ = NULL;
}
u32 GPUDebugBuffer::PixelSize(GPUDebugBufferFormat fmt) const {
switch (fmt) {
case GPU_DBG_FORMAT_8888:
case GPU_DBG_FORMAT_8888_BGRA:
case GPU_DBG_FORMAT_FLOAT:
case GPU_DBG_FORMAT_24BIT_8X:
case GPU_DBG_FORMAT_24X_8BIT:
return 4;
case GPU_DBG_FORMAT_888_RGB:
return 3;
case GPU_DBG_FORMAT_8BIT:
return 1;
default:
return 2;
}
}
u32 GPUDebugBuffer::GetRawPixel(int x, int y) const {
if (data_ == nullptr) {
return 0;
}
if (flipped_) {
y = height_ - y - 1;
}
u32 pixelSize = PixelSize(fmt_);
u32 byteOffset = pixelSize * (stride_ * y + x);
const u8 *ptr = &data_[byteOffset];
switch (pixelSize) {
case 4:
return *(const u32 *)ptr;
case 3:
return ptr[0] | (ptr[1] << 8) | (ptr[2] << 16);
case 2:
return *(const u16 *)ptr;
case 1:
return *(const u8 *)ptr;
default:
return 0;
}
}

View File

@ -121,65 +121,16 @@ struct GPUDebugBuffer {
return *this;
}
void Allocate(u32 stride, u32 height, GEBufferFormat fmt, bool flipped = false, bool reversed = false) {
GPUDebugBufferFormat actualFmt = GPUDebugBufferFormat(fmt);
if (reversed && actualFmt < GPU_DBG_FORMAT_8888) {
actualFmt |= GPU_DBG_FORMAT_REVERSE_FLAG;
}
Allocate(stride, height, actualFmt, flipped);
}
void Allocate(u32 stride, u32 height, GPUDebugBufferFormat fmt, bool flipped = false) {
if (alloc_ && stride_ == stride && height_ == height && fmt_ == fmt) {
// Already allocated the right size.
flipped_ = flipped;
return;
}
Free();
alloc_ = true;
height_ = height;
stride_ = stride;
fmt_ = fmt;
flipped_ = flipped;
u32 pixelSize;
switch (fmt) {
case GPU_DBG_FORMAT_8888:
case GPU_DBG_FORMAT_8888_BGRA:
case GPU_DBG_FORMAT_FLOAT:
case GPU_DBG_FORMAT_24BIT_8X:
case GPU_DBG_FORMAT_24X_8BIT:
pixelSize = 4;
break;
case GPU_DBG_FORMAT_888_RGB:
pixelSize = 3;
break;
case GPU_DBG_FORMAT_8BIT:
pixelSize = 1;
break;
default:
pixelSize = 2;
break;
}
data_ = new u8[pixelSize * stride * height];
}
void Free() {
if (alloc_ && data_ != NULL) {
delete [] data_;
}
data_ = NULL;
}
void Allocate(u32 stride, u32 height, GEBufferFormat fmt, bool flipped = false, bool reversed = false);
void Allocate(u32 stride, u32 height, GPUDebugBufferFormat fmt, bool flipped = false);
void Free();
u8 *GetData() {
return data_;
}
u32 GetRawPixel(int x, int y) const;
const u8 *GetData() const {
return data_;
}
@ -201,6 +152,8 @@ struct GPUDebugBuffer {
}
private:
u32 PixelSize(GPUDebugBufferFormat fmt) const;
bool alloc_;
u8 *data_;
u32 stride_;

View File

@ -245,6 +245,7 @@
<ClCompile Include="Common\DepalettizeShaderCommon.cpp" />
<ClCompile Include="Common\DrawEngineCommon.cpp" />
<ClCompile Include="Common\FramebufferCommon.cpp" />
<ClCompile Include="Common\GPUDebugInterface.cpp" />
<ClCompile Include="Common\IndexGenerator.cpp" />
<ClCompile Include="Common\PostShader.cpp" />
<ClCompile Include="Common\SplineCommon.cpp" />
@ -318,9 +319,6 @@
<Project>{3fcdbae2-5103-4350-9a8e-848ce9c73195}</Project>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="CMakeLists.txt" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>

View File

@ -183,7 +183,9 @@
<ClInclude Include="Common\TextureScalerCommon.h">
<Filter>Common</Filter>
</ClInclude>
<ClInclude Include="GPU.h" />
<ClInclude Include="GPU.h">
<Filter>Common</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="Math3D.cpp">
@ -351,9 +353,11 @@
<ClCompile Include="Common\TextureScalerCommon.cpp">
<Filter>Common</Filter>
</ClCompile>
<ClCompile Include="GPU.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="CMakeLists.txt" />
<ClCompile Include="Common\GPUDebugInterface.cpp">
<Filter>Common</Filter>
</ClCompile>
<ClCompile Include="GPU.cpp">
<Filter>Common</Filter>
</ClCompile>
</ItemGroup>
</Project>

View File

@ -42,6 +42,7 @@ SOURCES += $$P/GPU/GeDisasm.cpp \ # GPU
$$P/GPU/Software/*.cpp \
$$P/GPU/Debugger/*.cpp \
$$P/GPU/Common/DepalettizeShaderCommon.cpp \
$$P/GPU/Common/GPUDebugInterface.cpp \
$$P/GPU/Common/IndexGenerator.cpp \
$$P/GPU/Common/TextureDecoder.cpp \
$$P/GPU/Common/TextureScalerCommon.cpp \

View File

@ -20,6 +20,7 @@
#include <set>
#include "base/functional.h"
#include "Common/ColorConv.h"
#include "Windows/GEDebugger/GEDebugger.h"
#include "Windows/GEDebugger/SimpleGLWindow.h"
#include "Windows/GEDebugger/CtrlDisplayListView.h"
@ -58,7 +59,8 @@ void CGEDebugger::Init() {
}
CGEDebugger::CGEDebugger(HINSTANCE _hInstance, HWND _hParent)
: Dialog((LPCSTR)IDD_GEDEBUGGER, _hInstance, _hParent), frameWindow(NULL), texWindow(NULL), textureLevel_(0) {
: Dialog((LPCSTR)IDD_GEDEBUGGER, _hInstance, _hParent), frameWindow(nullptr), texWindow(nullptr),
textureLevel_(0), primaryBuffer_(nullptr), texBuffer_(nullptr) {
GPUBreakpoints::Init();
Core_ListenShutdown(ForceUnpause);
@ -137,18 +139,46 @@ CGEDebugger::~CGEDebugger() {
}
void CGEDebugger::SetupPreviews() {
if (frameWindow == NULL) {
if (frameWindow == nullptr) {
frameWindow = SimpleGLWindow::GetFrom(GetDlgItem(m_hDlg, IDC_GEDBG_FRAME));
frameWindow->Initialize(SimpleGLWindow::ALPHA_IGNORE | SimpleGLWindow::RESIZE_SHRINK_CENTER);
frameWindow->SetHoverCallback([&] (int x, int y) {
PreviewFramebufHover(x, y);
});
frameWindow->Clear();
}
if (texWindow == NULL) {
if (texWindow == nullptr) {
texWindow = SimpleGLWindow::GetFrom(GetDlgItem(m_hDlg, IDC_GEDBG_TEX));
texWindow->Initialize(SimpleGLWindow::ALPHA_BLEND | SimpleGLWindow::RESIZE_SHRINK_CENTER);
texWindow->SetHoverCallback([&] (int x, int y) {
PreviewTextureHover(x, y);
});
texWindow->Clear();
}
}
void CGEDebugger::DescribeFramebufTab(const GPUgstate &state, wchar_t desc[256]) {
_assert_msg_(MASTER_LOG, primaryBuffer_ != nullptr, "Must have a valid primaryBuffer_");
switch (PrimaryDisplayType(fbTabs->CurrentTabIndex())) {
case PRIMARY_FRAMEBUF:
_snwprintf(desc, 256, L"Color: 0x%08x (%dx%d) fmt %i", state.getFrameBufRawAddress(), primaryBuffer_->GetStride(), primaryBuffer_->GetHeight(), state.FrameBufFormat());
break;
case PRIMARY_DEPTHBUF:
_snwprintf(desc, 256, L"Depth: 0x%08x (%dx%d)", state.getDepthBufRawAddress(), primaryBuffer_->GetStride(), primaryBuffer_->GetHeight());
break;
case PRIMARY_STENCILBUF:
_snwprintf(desc, 256, L"Stencil: 0x%08x (%dx%d)", state.getFrameBufRawAddress(), primaryBuffer_->GetStride(), primaryBuffer_->GetHeight());
break;
}
}
void CGEDebugger::DescribeTexture(const GPUgstate &state, wchar_t desc[256]) {
_snwprintf(desc, 256, L"Texture L%d: 0x%08x (%dx%d)", textureLevel_, state.getTextureAddress(textureLevel_), state.getTextureWidth(textureLevel_), state.getTextureHeight(textureLevel_));
}
void CGEDebugger::UpdatePreviews() {
auto memLock = Memory::Lock();
if (!PSP_IsInited()) {
@ -156,7 +186,6 @@ void CGEDebugger::UpdatePreviews() {
}
wchar_t desc[256];
const GPUDebugBuffer *primaryBuffer = NULL;
bool bufferResult = false;
GPUgstate state = {0};
@ -164,45 +193,41 @@ void CGEDebugger::UpdatePreviews() {
state = gpuDebug->GetGState();
}
primaryBuffer_ = nullptr;
switch (PrimaryDisplayType(fbTabs->CurrentTabIndex())) {
case PRIMARY_FRAMEBUF:
bufferResult = GPU_GetCurrentFramebuffer(primaryBuffer);
if (bufferResult) {
_snwprintf(desc, ARRAY_SIZE(desc), L"Color: 0x%08x (%dx%d) fmt %i", state.getFrameBufRawAddress(), primaryBuffer->GetStride(), primaryBuffer->GetHeight(), state.FrameBufFormat());
}
bufferResult = GPU_GetCurrentFramebuffer(primaryBuffer_);
break;
case PRIMARY_DEPTHBUF:
bufferResult = GPU_GetCurrentDepthbuffer(primaryBuffer);
if (bufferResult) {
_snwprintf(desc, ARRAY_SIZE(desc), L"Depth: 0x%08x (%dx%d)", state.getDepthBufRawAddress(), primaryBuffer->GetStride(), primaryBuffer->GetHeight());
}
bufferResult = GPU_GetCurrentDepthbuffer(primaryBuffer_);
break;
case PRIMARY_STENCILBUF:
bufferResult = GPU_GetCurrentStencilbuffer(primaryBuffer);
if (bufferResult) {
_snwprintf(desc, ARRAY_SIZE(desc), L"Stencil: 0x%08x (%dx%d)", state.getFrameBufRawAddress(), primaryBuffer->GetStride(), primaryBuffer->GetHeight());
}
bufferResult = GPU_GetCurrentStencilbuffer(primaryBuffer_);
break;
}
if (bufferResult && primaryBuffer != NULL) {
auto fmt = SimpleGLWindow::Format(primaryBuffer->GetFormat());
frameWindow->Draw(primaryBuffer->GetData(), primaryBuffer->GetStride(), primaryBuffer->GetHeight(), primaryBuffer->GetFlipped(), fmt);
if (bufferResult && primaryBuffer_ != nullptr) {
auto fmt = SimpleGLWindow::Format(primaryBuffer_->GetFormat());
frameWindow->Draw(primaryBuffer_->GetData(), primaryBuffer_->GetStride(), primaryBuffer_->GetHeight(), primaryBuffer_->GetFlipped(), fmt);
DescribeFramebufTab(state, desc);
SetDlgItemText(m_hDlg, IDC_GEDBG_FRAMEBUFADDR, desc);
} else if (frameWindow != NULL) {
frameWindow->Clear();
primaryBuffer_ = nullptr;
SetDlgItemText(m_hDlg, IDC_GEDBG_FRAMEBUFADDR, L"Failed");
}
const GPUDebugBuffer *bufferTex = NULL;
texBuffer_ = nullptr;
UpdateTextureLevel(textureLevel_);
bufferResult = GPU_GetCurrentTexture(bufferTex, textureLevel_);
bufferResult = GPU_GetCurrentTexture(texBuffer_, textureLevel_);
if (bufferResult) {
auto fmt = SimpleGLWindow::Format(bufferTex->GetFormat());
texWindow->Draw(bufferTex->GetData(), bufferTex->GetStride(), bufferTex->GetHeight(), bufferTex->GetFlipped(), fmt);
auto fmt = SimpleGLWindow::Format(texBuffer_->GetFormat());
texWindow->Draw(texBuffer_->GetData(), texBuffer_->GetStride(), texBuffer_->GetHeight(), texBuffer_->GetFlipped(), fmt);
if (gpuDebug != NULL) {
if (state.isTextureAlphaUsed()) {
@ -210,7 +235,7 @@ void CGEDebugger::UpdatePreviews() {
} else {
texWindow->SetFlags(SimpleGLWindow::RESIZE_SHRINK_CENTER);
}
_snwprintf(desc, ARRAY_SIZE(desc), L"Texture L%d: 0x%08x (%dx%d)", textureLevel_, state.getTextureAddress(textureLevel_), state.getTextureWidth(textureLevel_), state.getTextureHeight(textureLevel_));
DescribeTexture(state, desc);
SetDlgItemText(m_hDlg, IDC_GEDBG_TEXADDR, desc);
UpdateLastTexture(state.getTextureAddress(textureLevel_));
@ -219,6 +244,8 @@ void CGEDebugger::UpdatePreviews() {
}
} else if (texWindow != NULL) {
texWindow->Clear();
texBuffer_ = nullptr;
if (gpuDebug == NULL || state.isTextureMapEnabled()) {
SetDlgItemText(m_hDlg, IDC_GEDBG_TEXADDR, L"Texture: failed");
} else {
@ -248,6 +275,158 @@ void CGEDebugger::UpdatePreviews() {
lists->Update();
}
void CGEDebugger::PreviewFramebufHover(int x, int y) {
if (primaryBuffer_ == nullptr) {
return;
}
wchar_t desc[256] = {0};
if (x < 0 || y < 0) {
// This means they left the area.
GPUgstate state = {0};
if (gpuDebug != nullptr) {
state = gpuDebug->GetGState();
}
DescribeFramebufTab(state, desc);
} else {
// Coordinates are relative to actual framebuffer size.
u32 pix = primaryBuffer_->GetRawPixel(x, y);
DescribePixel(pix, primaryBuffer_->GetFormat(), x, y, desc);
}
SetDlgItemText(m_hDlg, IDC_GEDBG_FRAMEBUFADDR, desc);
}
void CGEDebugger::DescribePixel(u32 pix, GPUDebugBufferFormat fmt, int x, int y, wchar_t desc[256]) {
switch (fmt) {
case GPU_DBG_FORMAT_565:
case GPU_DBG_FORMAT_565_REV:
case GPU_DBG_FORMAT_5551:
case GPU_DBG_FORMAT_5551_REV:
case GPU_DBG_FORMAT_5551_BGRA:
case GPU_DBG_FORMAT_4444:
case GPU_DBG_FORMAT_4444_REV:
case GPU_DBG_FORMAT_4444_BGRA:
case GPU_DBG_FORMAT_8888:
case GPU_DBG_FORMAT_8888_BGRA:
DescribePixelRGBA(pix, fmt, x, y, desc);
break;
case GPU_DBG_FORMAT_16BIT:
_snwprintf(desc, 256, L"%d,%d: %d", x, y, pix);
break;
case GPU_DBG_FORMAT_8BIT:
_snwprintf(desc, 256, L"%d,%d: %d", x, y, pix);
break;
case GPU_DBG_FORMAT_24BIT_8X:
_snwprintf(desc, 256, L"%d,%d: %d", x, y, pix & 0x00FFFFFF);
break;
case GPU_DBG_FORMAT_24X_8BIT:
_snwprintf(desc, 256, L"%d,%d: %d", x, y, (pix >> 24) & 0xFF);
break;
case GPU_DBG_FORMAT_FLOAT:
_snwprintf(desc, 256, L"%d,%d: %f", x, y, *(float *)&pix);
break;
default:
_snwprintf(desc, 256, L"Unexpected format");
}
}
void CGEDebugger::DescribePixelRGBA(u32 pix, GPUDebugBufferFormat fmt, int x, int y, wchar_t desc[256]) {
u32 r = -1, g = -1, b = -1, a = -1;
switch (fmt) {
case GPU_DBG_FORMAT_565:
r = Convert5To8((pix >> 0) & 0x1F);
g = Convert6To8((pix >> 5) & 0x3F);
b = Convert5To8((pix >> 11) & 0x1F);
case GPU_DBG_FORMAT_565_REV:
b = Convert5To8((pix >> 0) & 0x1F);
g = Convert6To8((pix >> 5) & 0x3F);
r = Convert5To8((pix >> 11) & 0x1F);
case GPU_DBG_FORMAT_5551:
r = Convert5To8((pix >> 0) & 0x1F);
g = Convert5To8((pix >> 5) & 0x1F);
b = Convert5To8((pix >> 10) & 0x1F);
a = (pix >> 15) & 1 ? 255 : 0;
case GPU_DBG_FORMAT_5551_REV:
a = pix & 1 ? 255 : 0;
b = Convert5To8((pix >> 1) & 0x1F);
g = Convert5To8((pix >> 6) & 0x1F);
r = Convert5To8((pix >> 11) & 0x1F);
case GPU_DBG_FORMAT_5551_BGRA:
b = Convert5To8((pix >> 0) & 0x1F);
g = Convert5To8((pix >> 5) & 0x1F);
r = Convert5To8((pix >> 10) & 0x1F);
a = (pix >> 15) & 1 ? 255 : 0;
break;
case GPU_DBG_FORMAT_4444:
r = Convert4To8((pix >> 0) & 0x0F);
g = Convert4To8((pix >> 4) & 0x0F);
b = Convert4To8((pix >> 8) & 0x0F);
a = Convert4To8((pix >> 12) & 0x0F);
break;
case GPU_DBG_FORMAT_4444_REV:
a = Convert4To8((pix >> 0) & 0x0F);
b = Convert4To8((pix >> 4) & 0x0F);
g = Convert4To8((pix >> 8) & 0x0F);
r = Convert4To8((pix >> 12) & 0x0F);
break;
case GPU_DBG_FORMAT_4444_BGRA:
b = Convert4To8((pix >> 0) & 0x0F);
g = Convert4To8((pix >> 4) & 0x0F);
r = Convert4To8((pix >> 8) & 0x0F);
a = Convert4To8((pix >> 12) & 0x0F);
break;
case GPU_DBG_FORMAT_8888:
r = (pix >> 0) & 0xFF;
g = (pix >> 8) & 0xFF;
b = (pix >> 16) & 0xFF;
a = (pix >> 24) & 0xFF;
break;
case GPU_DBG_FORMAT_8888_BGRA:
b = (pix >> 0) & 0xFF;
g = (pix >> 8) & 0xFF;
r = (pix >> 16) & 0xFF;
a = (pix >> 24) & 0xFF;
break;
default:
_snwprintf(desc, 256, L"Unexpected format");
return;
}
_snwprintf(desc, 256, L"%d,%d: r=%d, g=%d, b=%d, a=%d", x, y, r, g, b, a);
}
void CGEDebugger::PreviewTextureHover(int x, int y) {
if (texBuffer_ == nullptr) {
return;
}
wchar_t desc[256] = {0};
if (x < 0 || y < 0) {
// This means they left the area.
GPUgstate state = {0};
if (gpuDebug != nullptr) {
state = gpuDebug->GetGState();
}
DescribeTexture(state, desc);
} else {
u32 pix = texBuffer_->GetRawPixel(x, y);
DescribePixel(pix, texBuffer_->GetFormat(), x, y, desc);
}
SetDlgItemText(m_hDlg, IDC_GEDBG_TEXADDR, desc);
}
void CGEDebugger::UpdateTextureLevel(int level) {
GPUgstate state = {0};
if (gpuDebug != NULL) {

View File

@ -18,6 +18,7 @@
#pragma once
#include "Common/CommonWindows.h"
#include "GPU/Common/GPUDebugInterface.h"
#include "Globals.h"
#include "Windows/resource.h"
#include "Windows/W32Util/DialogManager.h"
@ -51,6 +52,7 @@ class TabStateTexture;
class TabStateSettings;
class TabVertices;
class TabMatrices;
struct GPUgstate;
class CGEDebugger : public Dialog {
public:
@ -71,6 +73,14 @@ private:
void SavePosition();
void SetBreakNext(BreakNextType type);
void UpdateTextureLevel(int level);
void DescribeFramebufTab(const GPUgstate &state, wchar_t desc[256]);
void DescribeDepthbufPixel(int x, int y, wchar_t desc[256]);
void DescribeStencilbufPixel(int x, int y, wchar_t desc[256]);
void DescribeTexture(const GPUgstate &state, wchar_t desc[256]);
void PreviewFramebufHover(int x, int y);
void PreviewTextureHover(int x, int y);
void DescribePixel(u32 pix, GPUDebugBufferFormat fmt, int x, int y, wchar_t desc[256]);
void DescribePixelRGBA(u32 pix, GPUDebugBufferFormat fmt, int x, int y, wchar_t desc[256]);
CtrlDisplayListView *displayList;
TabDisplayLists *lists;
@ -85,6 +95,9 @@ private:
TabControl *tabs;
TabControl *fbTabs;
int textureLevel_;
// The most recent primary/framebuffer and texture buffers.
const GPUDebugBuffer *primaryBuffer_;
const GPUDebugBuffer *texBuffer_;
int minWidth,minHeight;
};

View File

@ -68,7 +68,7 @@ static const char basic_vs[] =
SimpleGLWindow::SimpleGLWindow(HWND wnd)
: hWnd_(wnd), valid_(false), drawProgram_(nullptr), tex_(0), flags_(0), zoom_(false),
dragging_(false), offsetX_(0), offsetY_(0), reformatBuf_(nullptr) {
dragging_(false), offsetX_(0), offsetY_(0), reformatBuf_(nullptr), hoverCallback_(nullptr) {
SetWindowLongPtr(wnd, GWLP_USERDATA, (LONG_PTR) this);
}
@ -434,6 +434,45 @@ bool SimpleGLWindow::ToggleZoom() {
return true;
}
bool SimpleGLWindow::Hover(int mouseX, int mouseY) {
if (hoverCallback_ == nullptr) {
return false;
}
float fw, fh;
float x, y;
GetContentSize(x, y, fw, fh);
if (mouseX < x || mouseX >= x + fw || mouseY < y || mouseY >= y + fh) {
// Outside of bounds.
hoverCallback_(-1, -1);
return true;
}
float tx = (mouseX - x) * (tw_ / fw);
float ty = (mouseY - y) * (th_ / fh);
hoverCallback_((int)tx, (int)ty);
// Find out when they are done.
TRACKMOUSEEVENT tracking = {0};
tracking.cbSize = sizeof(tracking);
tracking.dwFlags = TME_LEAVE;
tracking.hwndTrack = hWnd_;
TrackMouseEvent(&tracking);
return true;
}
bool SimpleGLWindow::Leave() {
if (hoverCallback_ == nullptr) {
return false;
}
hoverCallback_(-1, -1);
return true;
}
const u8 *SimpleGLWindow::Reformat(const u8 *data, Format fmt, u32 numPixels) {
if (!reformatBuf_ || reformatBufSize_ < numPixels) {
delete [] reformatBuf_;
@ -463,8 +502,19 @@ SimpleGLWindow *SimpleGLWindow::GetFrom(HWND hwnd) {
LRESULT CALLBACK SimpleGLWindow::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) {
SimpleGLWindow *win = SimpleGLWindow::GetFrom(hwnd);
switch(msg)
{
int mouseX = 0, mouseY = 0;
switch (msg) {
case WM_LBUTTONDOWN:
case WM_LBUTTONUP:
case WM_MOUSEMOVE:
mouseX = GET_X_LPARAM(lParam);
mouseY = GET_Y_LPARAM(lParam);
break;
default:
break;
}
switch (msg) {
case WM_NCCREATE:
win = new SimpleGLWindow(hwnd);
@ -482,19 +532,28 @@ LRESULT CALLBACK SimpleGLWindow::WndProc(HWND hwnd, UINT msg, WPARAM wParam, LPA
break;
case WM_LBUTTONDOWN:
if (win->DragStart(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))) {
if (win->DragStart(mouseX, mouseY)) {
return 0;
}
break;
case WM_LBUTTONUP:
if (win->DragEnd(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))) {
if (win->DragEnd(mouseX, mouseY)) {
return 0;
}
break;
case WM_MOUSEMOVE:
if (win->DragContinue(GET_X_LPARAM(lParam), GET_Y_LPARAM(lParam))) {
if (win->DragContinue(mouseX, mouseY)) {
return 0;
}
if (win->Hover(mouseX, mouseY)) {
return 0;
}
break;
case WM_MOUSELEAVE:
if (win->Leave()) {
return 0;
}
break;

View File

@ -17,6 +17,7 @@
#pragma once
#include "base/functional.h"
#include "gfx_es2/glsl_program.h"
#include "Common/CommonWindows.h"
#include "Globals.h"
@ -92,6 +93,10 @@ struct SimpleGLWindow {
void GetContentSize(float &x, float &y, float &fw, float &fh);
void SetHoverCallback(std::function<void(int, int)> hoverCallback) {
hoverCallback_ = hoverCallback;
}
static void RegisterClass();
protected:
void SetupGL();
@ -102,6 +107,8 @@ protected:
bool DragStart(int mouseX, int mouseY);
bool DragContinue(int mouseX, int mouseY);
bool DragEnd(int mouseX, int mouseY);
bool Hover(int mouseX, int mouseY);
bool Leave();
bool ToggleZoom();
const u8 *Reformat(const u8 *data, Format fmt, u32 numPixels);
@ -132,4 +139,6 @@ protected:
int offsetY_;
u32 *reformatBuf_;
u32 reformatBufSize_;
std::function<void(int, int)> hoverCallback_;
};

View File

@ -154,6 +154,7 @@ EXEC_AND_LIB_FILES := \
$(SRC)/GPU/GeDisasm.cpp \
$(SRC)/GPU/Common/DepalettizeShaderCommon.cpp \
$(SRC)/GPU/Common/FramebufferCommon.cpp \
$(SRC)/GPU/Common/GPUDebugInterface.cpp \
$(SRC)/GPU/Common/IndexGenerator.cpp.arm \
$(SRC)/GPU/Common/SoftwareTransformCommon.cpp.arm \
$(SRC)/GPU/Common/VertexDecoderCommon.cpp.arm \