2015-05-06 01:27:59 -04:00
|
|
|
#include "GsContextView.h"
|
|
|
|
#include "GsStateUtils.h"
|
|
|
|
#include "../../gs/GsPixelFormats.h"
|
|
|
|
#include "../GSH_Direct3D9.h"
|
|
|
|
#include "win32/VerticalSplitter.h"
|
|
|
|
|
|
|
|
#define WNDSTYLE (WS_CHILD | WS_VISIBLE | WS_CLIPSIBLINGS | WS_CLIPCHILDREN)
|
|
|
|
|
2016-08-27 12:47:37 +09:00
|
|
|
enum TAB_IDS
|
|
|
|
{
|
|
|
|
TAB_ID_FRAMEBUFFER,
|
|
|
|
TAB_ID_TEXTURE_BASE,
|
|
|
|
TAB_ID_TEXTURE_MIP1,
|
|
|
|
TAB_ID_TEXTURE_MIP2,
|
|
|
|
TAB_ID_TEXTURE_MIP3,
|
|
|
|
TAB_ID_TEXTURE_MIP4,
|
|
|
|
TAB_ID_TEXTURE_MIP5,
|
|
|
|
TAB_ID_TEXTURE_MIP6
|
|
|
|
};
|
|
|
|
|
2015-05-06 01:27:59 -04:00
|
|
|
CGsContextView::CGsContextView(HWND parent, const RECT& rect, CGSHandler* gs, unsigned int contextId)
|
|
|
|
: m_contextId(contextId)
|
|
|
|
, m_gs(gs)
|
|
|
|
{
|
|
|
|
Create(0, Framework::Win32::CDefaultWndClass::GetName(), NULL, WNDSTYLE, rect, parent, NULL);
|
|
|
|
SetClassPtr();
|
|
|
|
|
|
|
|
m_mainSplitter = std::make_unique<Framework::Win32::CVerticalSplitter>(m_hWnd, GetClientRect());
|
|
|
|
|
|
|
|
m_bufferSelectionTab = std::make_unique<Framework::Win32::CTab>(*m_mainSplitter, Framework::Win32::CRect(0, 0, 1, 1), TCS_BOTTOM);
|
2016-08-27 12:47:37 +09:00
|
|
|
m_bufferSelectionTab->SetTabData(
|
|
|
|
m_bufferSelectionTab->InsertTab(_T("Framebuffer")), TAB_ID_FRAMEBUFFER);
|
|
|
|
m_bufferSelectionTab->SetTabData(
|
|
|
|
m_bufferSelectionTab->InsertTab(_T("Texture (Base)")), TAB_ID_TEXTURE_BASE);
|
|
|
|
m_bufferSelectionTab->SetTabData(
|
|
|
|
m_bufferSelectionTab->InsertTab(_T("Texture (Mip 1)")), TAB_ID_TEXTURE_MIP1);
|
|
|
|
m_bufferSelectionTab->SetTabData(
|
|
|
|
m_bufferSelectionTab->InsertTab(_T("Texture (Mip 2)")), TAB_ID_TEXTURE_MIP2);
|
|
|
|
m_bufferSelectionTab->SetTabData(
|
|
|
|
m_bufferSelectionTab->InsertTab(_T("Texture (Mip 3)")), TAB_ID_TEXTURE_MIP3);
|
|
|
|
m_bufferSelectionTab->SetTabData(
|
|
|
|
m_bufferSelectionTab->InsertTab(_T("Texture (Mip 4)")), TAB_ID_TEXTURE_MIP4);
|
|
|
|
m_bufferSelectionTab->SetTabData(
|
|
|
|
m_bufferSelectionTab->InsertTab(_T("Texture (Mip 5)")), TAB_ID_TEXTURE_MIP5);
|
|
|
|
m_bufferSelectionTab->SetTabData(
|
|
|
|
m_bufferSelectionTab->InsertTab(_T("Texture (Mip 6)")), TAB_ID_TEXTURE_MIP6);
|
2015-05-06 01:27:59 -04:00
|
|
|
|
|
|
|
m_bufferView = std::make_unique<CPixelBufferView>(*m_bufferSelectionTab, Framework::Win32::CRect(0, 0, 1, 1));
|
|
|
|
|
|
|
|
m_stateView = std::make_unique<CGsContextStateView>(*m_mainSplitter, GetClientRect(), m_contextId);
|
|
|
|
m_stateView->Show(SW_SHOW);
|
|
|
|
|
|
|
|
m_mainSplitter->SetChild(0, *m_bufferSelectionTab);
|
|
|
|
m_mainSplitter->SetChild(1, *m_stateView);
|
|
|
|
m_mainSplitter->SetMasterChild(1);
|
|
|
|
m_mainSplitter->SetEdgePosition(0.5f);
|
|
|
|
}
|
|
|
|
|
|
|
|
CGsContextView::~CGsContextView()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void CGsContextView::SetFbDisplayMode(FB_DISPLAY_MODE fbDisplayMode)
|
|
|
|
{
|
|
|
|
m_fbDisplayMode = fbDisplayMode;
|
|
|
|
UpdateBufferView();
|
|
|
|
}
|
|
|
|
|
|
|
|
void CGsContextView::UpdateState(CGSHandler* gs, CGsPacketMetadata*, DRAWINGKICK_INFO* drawingKick)
|
|
|
|
{
|
|
|
|
assert(gs == m_gs);
|
|
|
|
m_drawingKick = (*drawingKick);
|
|
|
|
UpdateBufferView();
|
|
|
|
m_stateView->UpdateState(m_gs);
|
|
|
|
}
|
|
|
|
|
|
|
|
void CGsContextView::UpdateBufferView()
|
|
|
|
{
|
2016-08-27 12:47:37 +09:00
|
|
|
int selectionIndex = m_bufferSelectionTab->GetSelection();
|
|
|
|
uint32 selectedId = m_bufferSelectionTab->GetTabData(selectionIndex);
|
|
|
|
switch(selectedId)
|
2015-05-06 01:27:59 -04:00
|
|
|
{
|
2016-08-27 12:47:37 +09:00
|
|
|
case TAB_ID_FRAMEBUFFER:
|
2015-05-06 01:27:59 -04:00
|
|
|
{
|
2016-08-27 12:47:37 +09:00
|
|
|
uint64 frameReg = m_gs->GetRegisters()[GS_REG_FRAME_1 + m_contextId];
|
|
|
|
auto framebuffer = static_cast<CGSH_Direct3D9*>(m_gs)->GetFramebuffer(frameReg);
|
|
|
|
if(!framebuffer.IsEmpty())
|
2015-05-06 01:27:59 -04:00
|
|
|
{
|
2016-08-27 12:47:37 +09:00
|
|
|
RenderDrawKick(framebuffer);
|
|
|
|
if(m_fbDisplayMode == FB_DISPLAY_MODE_448P)
|
|
|
|
{
|
|
|
|
framebuffer = framebuffer.ResizeCanvas(640, 448);
|
|
|
|
}
|
|
|
|
else if(m_fbDisplayMode == FB_DISPLAY_MODE_448I)
|
|
|
|
{
|
|
|
|
framebuffer = framebuffer.ResizeCanvas(640, 224);
|
|
|
|
framebuffer = framebuffer.Resize(640, 448);
|
|
|
|
}
|
2015-05-06 01:27:59 -04:00
|
|
|
}
|
2016-10-28 18:39:46 -04:00
|
|
|
CPixelBufferView::PixelBufferArray pixelBuffers;
|
|
|
|
pixelBuffers.emplace_back("Raw", std::move(framebuffer));
|
|
|
|
m_bufferView->SetPixelBuffers(std::move(pixelBuffers));
|
2015-05-06 01:27:59 -04:00
|
|
|
}
|
2016-08-27 12:47:37 +09:00
|
|
|
break;
|
|
|
|
case TAB_ID_TEXTURE_BASE:
|
|
|
|
case TAB_ID_TEXTURE_MIP1:
|
|
|
|
case TAB_ID_TEXTURE_MIP2:
|
|
|
|
case TAB_ID_TEXTURE_MIP3:
|
|
|
|
case TAB_ID_TEXTURE_MIP4:
|
|
|
|
case TAB_ID_TEXTURE_MIP5:
|
|
|
|
case TAB_ID_TEXTURE_MIP6:
|
|
|
|
{
|
|
|
|
uint64 tex0Reg = m_gs->GetRegisters()[GS_REG_TEX0_1 + m_contextId];
|
|
|
|
uint64 tex1Reg = m_gs->GetRegisters()[GS_REG_TEX1_1 + m_contextId];
|
|
|
|
uint64 miptbp1Reg = m_gs->GetRegisters()[GS_REG_MIPTBP1_1 + m_contextId];
|
|
|
|
uint64 miptbp2Reg = m_gs->GetRegisters()[GS_REG_MIPTBP2_1 + m_contextId];
|
2016-10-17 20:01:03 -04:00
|
|
|
auto tex0 = make_convertible<CGSHandler::TEX0>(tex0Reg);
|
2016-08-27 12:47:37 +09:00
|
|
|
auto tex1 = make_convertible<CGSHandler::TEX1>(tex1Reg);
|
2015-05-06 01:27:59 -04:00
|
|
|
|
2016-08-27 12:47:37 +09:00
|
|
|
uint32 mipLevel = selectedId - TAB_ID_TEXTURE_BASE;
|
|
|
|
Framework::CBitmap texture;
|
2015-05-06 01:27:59 -04:00
|
|
|
|
2016-08-27 12:47:37 +09:00
|
|
|
if(mipLevel <= tex1.nMaxMip)
|
|
|
|
{
|
|
|
|
texture = static_cast<CGSH_Direct3D9*>(m_gs)->GetTexture(tex0Reg, tex1.nMaxMip, miptbp1Reg, miptbp2Reg, mipLevel);
|
2016-10-17 20:01:03 -04:00
|
|
|
|
|
|
|
if(CGsPixelFormats::IsPsmIDTEX4(tex0.nPsm))
|
|
|
|
{
|
|
|
|
//Too hard to see if pixel brightness is not boosted
|
|
|
|
BrightenBitmap(texture);
|
|
|
|
}
|
2016-08-27 12:47:37 +09:00
|
|
|
}
|
|
|
|
|
2016-10-28 18:39:46 -04:00
|
|
|
CPixelBufferView::PixelBufferArray pixelBuffers;
|
|
|
|
pixelBuffers.emplace_back("Raw", std::move(texture));
|
|
|
|
m_bufferView->SetPixelBuffers(std::move(pixelBuffers));
|
2016-08-27 12:47:37 +09:00
|
|
|
}
|
|
|
|
break;
|
2015-05-06 01:27:59 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CGsContextView::RenderDrawKick(Framework::CBitmap& bitmap)
|
|
|
|
{
|
|
|
|
if(m_drawingKick.primType == CGSHandler::PRIM_INVALID) return;
|
|
|
|
if(m_drawingKick.context != m_contextId) return;
|
|
|
|
|
|
|
|
auto primHighlightColor = Framework::CColor(0, 0xFF, 0, 0xFF);
|
|
|
|
|
|
|
|
switch(m_drawingKick.primType)
|
|
|
|
{
|
|
|
|
case CGSHandler::PRIM_TRIANGLE:
|
|
|
|
case CGSHandler::PRIM_TRIANGLESTRIP:
|
|
|
|
case CGSHandler::PRIM_TRIANGLEFAN:
|
|
|
|
{
|
|
|
|
int x1 = static_cast<int16>(m_drawingKick.vertex[0].x) / 16;
|
|
|
|
int y1 = static_cast<int16>(m_drawingKick.vertex[0].y) / 16;
|
|
|
|
int x2 = static_cast<int16>(m_drawingKick.vertex[1].x) / 16;
|
|
|
|
int y2 = static_cast<int16>(m_drawingKick.vertex[1].y) / 16;
|
|
|
|
int x3 = static_cast<int16>(m_drawingKick.vertex[2].x) / 16;
|
|
|
|
int y3 = static_cast<int16>(m_drawingKick.vertex[2].y) / 16;
|
|
|
|
bitmap.DrawLine(x1, y1, x2, y2, primHighlightColor);
|
|
|
|
bitmap.DrawLine(x1, y1, x3, y3, primHighlightColor);
|
|
|
|
bitmap.DrawLine(x2, y2, x3, y3, primHighlightColor);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case CGSHandler::PRIM_SPRITE:
|
|
|
|
{
|
|
|
|
int x1 = static_cast<int16>(m_drawingKick.vertex[0].x) / 16;
|
|
|
|
int y1 = static_cast<int16>(m_drawingKick.vertex[0].y) / 16;
|
|
|
|
int x2 = static_cast<int16>(m_drawingKick.vertex[1].x) / 16;
|
|
|
|
int y2 = static_cast<int16>(m_drawingKick.vertex[1].y) / 16;
|
|
|
|
bitmap.DrawLine(x1, y1, x1, y2, primHighlightColor);
|
|
|
|
bitmap.DrawLine(x1, y2, x2, y2, primHighlightColor);
|
|
|
|
bitmap.DrawLine(x2, y2, x2, y1, primHighlightColor);
|
|
|
|
bitmap.DrawLine(x2, y1, x1, y1, primHighlightColor);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-17 20:01:03 -04:00
|
|
|
void CGsContextView::BrightenBitmap(Framework::CBitmap& bitmap)
|
|
|
|
{
|
|
|
|
assert(!bitmap.IsEmpty());
|
|
|
|
assert(bitmap.GetBitsPerPixel() == 8);
|
|
|
|
auto pixels = reinterpret_cast<uint8*>(bitmap.GetPixels());
|
|
|
|
for(uint32 y = 0; y < bitmap.GetHeight(); y++)
|
|
|
|
{
|
|
|
|
for(uint32 x = 0; x < bitmap.GetWidth(); x++)
|
|
|
|
{
|
|
|
|
pixels[x] <<= 4;
|
|
|
|
}
|
|
|
|
pixels += bitmap.GetPitch();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-06 01:27:59 -04:00
|
|
|
long CGsContextView::OnSize(unsigned int, unsigned int, unsigned int)
|
|
|
|
{
|
|
|
|
m_mainSplitter->SetSizePosition(GetClientRect());
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
long CGsContextView::OnCommand(unsigned short, unsigned short, HWND hwndFrom)
|
|
|
|
{
|
|
|
|
if(CWindow::IsCommandSource(m_mainSplitter.get(), hwndFrom))
|
|
|
|
{
|
|
|
|
m_bufferView->SetSizePosition(m_bufferSelectionTab->GetDisplayAreaRect());
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
long CGsContextView::OnNotify(WPARAM wParam, NMHDR* hdr)
|
|
|
|
{
|
|
|
|
if(CWindow::IsNotifySource(m_bufferSelectionTab.get(), hdr))
|
|
|
|
{
|
|
|
|
if(hdr->code == TCN_SELCHANGE)
|
|
|
|
{
|
|
|
|
UpdateBufferView();
|
|
|
|
m_bufferView->FitBitmap();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|