OpenGL: Trying a new function to fix glScissor() and glViewport() when bpmem.copyTexSrcWH is not 640x480. It's only enabled with g_Config.bStretchToFit and without g_Config.bKeepAR to test how it works. Hopefully I have not broken all other modes.
git-svn-id: https://dolphin-emu.googlecode.com/svn/trunk@2310 8ced0084-cf51-0410-be5f-012b33b47a6e
This commit is contained in:
parent
14ab646978
commit
5746ed490c
|
@ -777,8 +777,8 @@ union UPE_Copy
|
||||||
struct BPMemory
|
struct BPMemory
|
||||||
{
|
{
|
||||||
GenMode genMode;
|
GenMode genMode;
|
||||||
u32 display_copy_filter[4]; //01-04
|
u32 display_copy_filter[4]; // 01-04
|
||||||
u32 unknown; //05
|
u32 unknown; // 05
|
||||||
// indirect matrices (set by GXSetIndTexMtx, selected by TevStageIndirect::mid)
|
// indirect matrices (set by GXSetIndTexMtx, selected by TevStageIndirect::mid)
|
||||||
// abc form a 2x3 offset matrix, there's 3 such matrices
|
// abc form a 2x3 offset matrix, there's 3 such matrices
|
||||||
// the 3 offset matrices can either be indirect type, S-type, or T-type
|
// the 3 offset matrices can either be indirect type, S-type, or T-type
|
||||||
|
@ -804,9 +804,9 @@ struct BPMemory
|
||||||
u32 drawdone; //45, bit1=1 if end of list
|
u32 drawdone; //45, bit1=1 if end of list
|
||||||
u32 unknown5; //46 clock?
|
u32 unknown5; //46 clock?
|
||||||
u32 petoken; //47
|
u32 petoken; //47
|
||||||
u32 petokenint; //48
|
u32 petokenint; // 48
|
||||||
X10Y10 copyTexSrcXY; //49
|
X10Y10 copyTexSrcXY; // 49
|
||||||
X10Y10 copyTexSrcWH; //4a
|
X10Y10 copyTexSrcWH; // 4a
|
||||||
u32 copyTexDest; //4b// 4b == CopyAddress (GXDispCopy and GXTexCopy use it)
|
u32 copyTexDest; //4b// 4b == CopyAddress (GXDispCopy and GXTexCopy use it)
|
||||||
u32 unknown6; //4c
|
u32 unknown6; //4c
|
||||||
u32 copyMipMapStrideChannels; // 4d usually set to 4 when dest is single channel, 8 when dest is 2 channel, 16 when dest is RGBA
|
u32 copyMipMapStrideChannels; // 4d usually set to 4 when dest is single channel, 8 when dest is 2 channel, 16 when dest is RGBA
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
#include "VertexShaderManager.h"
|
#include "VertexShaderManager.h"
|
||||||
#include "PixelShaderManager.h"
|
#include "PixelShaderManager.h"
|
||||||
#include "XFB.h"
|
#include "XFB.h"
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------
|
||||||
|
@ -56,14 +57,23 @@ void BPInit()
|
||||||
bpmem.bpMask = 0xFFFFFF;
|
bpmem.bpMask = 0xFFFFFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called at the end of every: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg
|
//////////////////////////////////////////////////////////////////////////////////////
|
||||||
// TODO - turn into function table. The (future) DL jit can then call the functions directly,
|
// Write to bpmem
|
||||||
// getting rid of dynamic dispatch.
|
/* ------------------
|
||||||
|
Called:
|
||||||
|
At the end of every: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg
|
||||||
|
TODO:
|
||||||
|
Turn into function table. The (future) DL jit can then call the functions directly,
|
||||||
|
getting rid of dynamic dispatch.
|
||||||
|
// ------------------ */
|
||||||
void BPWritten(int addr, int changes, int newval)
|
void BPWritten(int addr, int changes, int newval)
|
||||||
{
|
{
|
||||||
//static int count = 0;
|
//static int count = 0;
|
||||||
//ERROR_LOG("(%d) %x: %x\n", count++, addr, newval);
|
//ERROR_LOG("(%d) %x: %x\n", count++, addr, newval);
|
||||||
|
|
||||||
|
//Console::Print("BPWritten: 0x%02x %i %i %i\n", addr, changes, newval, (int)bpmem.copyTexSrcWH.y);
|
||||||
|
//if(addr == 0x49) PanicAlert("0x49");
|
||||||
|
|
||||||
switch (addr)
|
switch (addr)
|
||||||
{
|
{
|
||||||
case BPMEM_GENMODE:
|
case BPMEM_GENMODE:
|
||||||
|
@ -283,10 +293,12 @@ void BPWritten(int addr, int changes, int newval)
|
||||||
case BPMEM_SCISSORTL:
|
case BPMEM_SCISSORTL:
|
||||||
case BPMEM_SCISSORBR:
|
case BPMEM_SCISSORBR:
|
||||||
|
|
||||||
if (changes) {
|
if (changes)
|
||||||
|
{
|
||||||
VertexManager::Flush();
|
VertexManager::Flush();
|
||||||
((u32*)&bpmem)[addr] = newval;
|
((u32*)&bpmem)[addr] = newval;
|
||||||
if (!Renderer::SetScissorRect()) {
|
if (!Renderer::SetScissorRect())
|
||||||
|
{
|
||||||
if (addr == BPMEM_SCISSORBR) {
|
if (addr == BPMEM_SCISSORBR) {
|
||||||
ERROR_LOG("bad scissor!\n");
|
ERROR_LOG("bad scissor!\n");
|
||||||
}
|
}
|
||||||
|
@ -346,26 +358,29 @@ void BPWritten(int addr, int changes, int newval)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BPMEM_PE_TOKEN_ID:
|
case BPMEM_PE_TOKEN_ID: // 0x47
|
||||||
g_VideoInitialize.pSetPEToken(static_cast<u16>(newval & 0xFFFF), FALSE);
|
g_VideoInitialize.pSetPEToken(static_cast<u16>(newval & 0xFFFF), FALSE);
|
||||||
DebugLog("SetPEToken 0x%04x", (newval & 0xFFFF));
|
DebugLog("SetPEToken 0x%04x", (newval & 0xFFFF));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BPMEM_PE_TOKEN_INT_ID:
|
case BPMEM_PE_TOKEN_INT_ID: // 0x48
|
||||||
g_VideoInitialize.pSetPEToken(static_cast<u16>(newval & 0xFFFF), TRUE);
|
g_VideoInitialize.pSetPEToken(static_cast<u16>(newval & 0xFFFF), TRUE);
|
||||||
DebugLog("SetPEToken + INT 0x%04x", (newval & 0xFFFF));
|
DebugLog("SetPEToken + INT 0x%04x", (newval & 0xFFFF));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x67: // set gp metric?
|
// Set gp metric?
|
||||||
|
case 0x67:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// This case writes to bpmem.triggerEFBCopy and may apparently prompt us to update glScissor()
|
||||||
case 0x52:
|
case 0x52:
|
||||||
{
|
{
|
||||||
DVSTARTSUBPROFILE("LoadBPReg:swap");
|
DVSTARTSUBPROFILE("LoadBPReg:swap");
|
||||||
VertexManager::Flush();
|
VertexManager::Flush();
|
||||||
|
|
||||||
((u32*)&bpmem)[addr] = newval;
|
((u32*)&bpmem)[addr] = newval;
|
||||||
//The bottom right is within the rectangle.
|
// The bottom right is within the rectangle
|
||||||
|
// The values in bpmem.copyTexSrcXY and bpmem.copyTexSrcWH are updated in case 0x49 and 0x4a in this function
|
||||||
TRectangle rc = {
|
TRectangle rc = {
|
||||||
(int)(bpmem.copyTexSrcXY.x),
|
(int)(bpmem.copyTexSrcXY.x),
|
||||||
(int)(bpmem.copyTexSrcXY.y),
|
(int)(bpmem.copyTexSrcXY.y),
|
||||||
|
@ -374,8 +389,8 @@ void BPWritten(int addr, int changes, int newval)
|
||||||
};
|
};
|
||||||
float MValueX = OpenGL_GetXmax();
|
float MValueX = OpenGL_GetXmax();
|
||||||
float MValueY = OpenGL_GetYmax();
|
float MValueY = OpenGL_GetYmax();
|
||||||
//Need another rc here to get it to scale.
|
// Need another rc here to get it to scale.
|
||||||
//Here the bottom right is the out of the rectangle.
|
// Here the bottom right is the out of the rectangle.
|
||||||
TRectangle multirc = {
|
TRectangle multirc = {
|
||||||
(int)(bpmem.copyTexSrcXY.x * MValueX),
|
(int)(bpmem.copyTexSrcXY.x * MValueX),
|
||||||
(int)(bpmem.copyTexSrcXY.y * MValueY),
|
(int)(bpmem.copyTexSrcXY.y * MValueY),
|
||||||
|
@ -386,23 +401,31 @@ void BPWritten(int addr, int changes, int newval)
|
||||||
UPE_Copy PE_copy;
|
UPE_Copy PE_copy;
|
||||||
PE_copy.Hex = bpmem.triggerEFBCopy;
|
PE_copy.Hex = bpmem.triggerEFBCopy;
|
||||||
|
|
||||||
if (PE_copy.copy_to_xfb == 0) {
|
if (PE_copy.copy_to_xfb == 0)
|
||||||
|
{
|
||||||
// EFB to texture
|
// EFB to texture
|
||||||
// for some reason it sets bpmem.zcontrol.pixel_format to PIXELFMT_Z24 every time a zbuffer format is given as a dest to GXSetTexCopyDst
|
// for some reason it sets bpmem.zcontrol.pixel_format to PIXELFMT_Z24 every time a zbuffer format is given as a dest to GXSetTexCopyDst
|
||||||
if (g_Config.bEFBCopyDisable) {
|
if (g_Config.bEFBCopyDisable)
|
||||||
glViewport(rc.left,rc.bottom,rc.right,rc.top);
|
{
|
||||||
glScissor(rc.left,rc.bottom,rc.right,rc.top);
|
// We already have this in Render.cpp that we call when (PE_copy.clear) is true, why do we need this here to?
|
||||||
|
//glViewport(rc.left,rc.bottom, rc.right,rc.top);
|
||||||
|
//glScissor(rc.left,rc.bottom, rc.right,rc.top);
|
||||||
|
// Logging
|
||||||
|
//GLScissorX = rc.left; GLScissorY = rc.bottom; GLScissorW = rc.right; GLScissorH = rc.top;
|
||||||
}
|
}
|
||||||
else if (g_Config.bCopyEFBToRAM) {
|
else if (g_Config.bCopyEFBToRAM)
|
||||||
|
{
|
||||||
TextureConverter::EncodeToRam(bpmem.copyTexDest<<5, bpmem.zcontrol.pixel_format==PIXELFMT_Z24, PE_copy.intensity_fmt>0,
|
TextureConverter::EncodeToRam(bpmem.copyTexDest<<5, bpmem.zcontrol.pixel_format==PIXELFMT_Z24, PE_copy.intensity_fmt>0,
|
||||||
(PE_copy.target_pixel_format/2)+((PE_copy.target_pixel_format&1)*8), PE_copy.half_scale>0, rc);
|
(PE_copy.target_pixel_format/2)+((PE_copy.target_pixel_format&1)*8), PE_copy.half_scale>0, rc);
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
TextureMngr::CopyRenderTargetToTexture(bpmem.copyTexDest<<5, bpmem.zcontrol.pixel_format==PIXELFMT_Z24, PE_copy.intensity_fmt>0,
|
TextureMngr::CopyRenderTargetToTexture(bpmem.copyTexDest<<5, bpmem.zcontrol.pixel_format==PIXELFMT_Z24, PE_copy.intensity_fmt>0,
|
||||||
(PE_copy.target_pixel_format/2)+((PE_copy.target_pixel_format&1)*8), PE_copy.half_scale>0, &rc);
|
(PE_copy.target_pixel_format/2)+((PE_copy.target_pixel_format&1)*8), PE_copy.half_scale>0, &rc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
// EFB to XFB
|
// EFB to XFB
|
||||||
if (g_Config.bUseXFB)
|
if (g_Config.bUseXFB)
|
||||||
{
|
{
|
||||||
|
@ -429,17 +452,23 @@ void BPWritten(int addr, int changes, int newval)
|
||||||
}
|
}
|
||||||
|
|
||||||
// clearing
|
// clearing
|
||||||
if (PE_copy.clear) {
|
if (PE_copy.clear)
|
||||||
|
{
|
||||||
// clear color
|
// clear color
|
||||||
Renderer::SetRenderMode(Renderer::RM_Normal);
|
Renderer::SetRenderMode(Renderer::RM_Normal);
|
||||||
|
|
||||||
u32 nRestoreZBufferTarget = Renderer::GetZBufferTarget();
|
u32 nRestoreZBufferTarget = Renderer::GetZBufferTarget();
|
||||||
|
|
||||||
glViewport(0, 0, Renderer::GetTargetWidth(), Renderer::GetTargetHeight());
|
// Why do we have this here and in Render.cpp?
|
||||||
|
//glViewport(0, 0, Renderer::GetTargetWidth(), Renderer::GetTargetHeight());
|
||||||
|
|
||||||
// Always set the scissor in case it was set by the game and has not been reset
|
// Always set the scissor in case it was set by the game and has not been reset
|
||||||
glScissor(multirc.left, (Renderer::GetTargetHeight() - multirc.bottom),
|
// But we will do that at the end of this section, in SetScissorRect(), why would we do it twice in the same function?
|
||||||
(multirc.right - multirc.left), (multirc.bottom - multirc.top));
|
//glScissor(multirc.left, (Renderer::GetTargetHeight() - multirc.bottom),
|
||||||
|
// (multirc.right - multirc.left), (multirc.bottom - multirc.top));
|
||||||
|
// Logging
|
||||||
|
// GLScissorX = multirc.left; GLScissorY = (Renderer::GetTargetHeight() - multirc.bottom);
|
||||||
|
// GLScissorW = (multirc.right - multirc.left); GLScissorH = (multirc.bottom - multirc.top);
|
||||||
|
|
||||||
VertexShaderManager::SetViewportChanged();
|
VertexShaderManager::SetViewportChanged();
|
||||||
|
|
||||||
|
@ -457,7 +486,8 @@ void BPWritten(int addr, int changes, int newval)
|
||||||
((clearColor>>24) & 0xff)*(1/255.0f));
|
((clearColor>>24) & 0xff)*(1/255.0f));
|
||||||
bits |= GL_COLOR_BUFFER_BIT;
|
bits |= GL_COLOR_BUFFER_BIT;
|
||||||
}
|
}
|
||||||
if (bpmem.zmode.updateenable) {
|
if (bpmem.zmode.updateenable)
|
||||||
|
{
|
||||||
glClearDepth((float)(bpmem.clearZValue&0xFFFFFF) / float(0xFFFFFF));
|
glClearDepth((float)(bpmem.clearZValue&0xFFFFFF) / float(0xFFFFFF));
|
||||||
bits |= GL_DEPTH_BUFFER_BIT;
|
bits |= GL_DEPTH_BUFFER_BIT;
|
||||||
}
|
}
|
||||||
|
@ -635,6 +665,8 @@ void BPWritten(int addr, int changes, int newval)
|
||||||
case 0x90:
|
case 0x90:
|
||||||
case 0xA0:
|
case 0xA0:
|
||||||
case 0xB0:
|
case 0xB0:
|
||||||
|
|
||||||
|
// Just update the bpmem struct, don't do anything else.
|
||||||
default:
|
default:
|
||||||
if (changes)
|
if (changes)
|
||||||
{
|
{
|
||||||
|
@ -691,15 +723,16 @@ void BPWritten(int addr, int changes, int newval)
|
||||||
void LoadBPReg(u32 value0)
|
void LoadBPReg(u32 value0)
|
||||||
{
|
{
|
||||||
DVSTARTPROFILE();
|
DVSTARTPROFILE();
|
||||||
//handle the mask register
|
// Handle the mask register
|
||||||
int opcode = value0 >> 24;
|
int opcode = value0 >> 24;
|
||||||
int oldval = ((u32*)&bpmem)[opcode];
|
int oldval = ((u32*)&bpmem)[opcode];
|
||||||
int newval = (oldval & ~bpmem.bpMask) | (value0 & bpmem.bpMask);
|
int newval = (oldval & ~bpmem.bpMask) | (value0 & bpmem.bpMask);
|
||||||
|
// Check if it's a new value
|
||||||
int changes = (oldval ^ newval) & 0xFFFFFF;
|
int changes = (oldval ^ newval) & 0xFFFFFF;
|
||||||
//reset the mask register
|
//reset the mask register
|
||||||
if (opcode != 0xFE)
|
if (opcode != 0xFE)
|
||||||
bpmem.bpMask = 0xFFFFFF;
|
bpmem.bpMask = 0xFFFFFF;
|
||||||
//notify the video handling so it can update render states
|
// Notify the video handling so it can update render states
|
||||||
BPWritten(opcode, changes, newval);
|
BPWritten(opcode, changes, newval);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -117,6 +117,10 @@ void OpenGL_SetWindowText(const char *text)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// =======================================================================================
|
||||||
|
// Draw messages on top of the screen
|
||||||
|
// ------------------
|
||||||
unsigned int Callback_PeekMessages()
|
unsigned int Callback_PeekMessages()
|
||||||
{
|
{
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
|
@ -134,13 +138,14 @@ unsigned int Callback_PeekMessages()
|
||||||
return FALSE;
|
return FALSE;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
// Show the current FPS
|
||||||
void UpdateFPSDisplay(const char *text)
|
void UpdateFPSDisplay(const char *text)
|
||||||
{
|
{
|
||||||
char temp[512];
|
char temp[512];
|
||||||
sprintf(temp, "SVN R%s: GL: %s", SVN_REV_STR, text);
|
sprintf(temp, "SVN R%s: GL: %s", SVN_REV_STR, text);
|
||||||
OpenGL_SetWindowText(temp);
|
OpenGL_SetWindowText(temp);
|
||||||
}
|
}
|
||||||
|
// =========================
|
||||||
|
|
||||||
|
|
||||||
// =======================================================================================
|
// =======================================================================================
|
||||||
|
@ -171,7 +176,7 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight
|
||||||
{
|
{
|
||||||
sscanf(g_Config.iWindowedRes, "%dx%d", &_twidth, &_theight);
|
sscanf(g_Config.iWindowedRes, "%dx%d", &_twidth, &_theight);
|
||||||
}
|
}
|
||||||
else // No Window reso set, fall back to default
|
else // No Window resolution set, fall back to default
|
||||||
{
|
{
|
||||||
_twidth = _iwidth;
|
_twidth = _iwidth;
|
||||||
_theight = _iheight;
|
_theight = _iheight;
|
||||||
|
@ -262,15 +267,12 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight
|
||||||
// Create rendering window in Windows
|
// Create rendering window in Windows
|
||||||
// ----------------------
|
// ----------------------
|
||||||
|
|
||||||
// Create the window
|
// Create a separate window
|
||||||
if (!g_Config.renderToMainframe || g_VideoInitialize.pWindowHandle == NULL)
|
if (!g_Config.renderToMainframe || g_VideoInitialize.pWindowHandle == NULL)
|
||||||
{
|
|
||||||
g_VideoInitialize.pWindowHandle = (void*)EmuWindow::Create(NULL, g_hInstance, "Please wait...");
|
g_VideoInitialize.pWindowHandle = (void*)EmuWindow::Create(NULL, g_hInstance, "Please wait...");
|
||||||
}
|
// Create a child window
|
||||||
else
|
else
|
||||||
{
|
|
||||||
g_VideoInitialize.pWindowHandle = (void*)EmuWindow::Create((HWND)g_VideoInitialize.pWindowHandle, g_hInstance, "Please wait...");
|
g_VideoInitialize.pWindowHandle = (void*)EmuWindow::Create((HWND)g_VideoInitialize.pWindowHandle, g_hInstance, "Please wait...");
|
||||||
}
|
|
||||||
|
|
||||||
// Show the window
|
// Show the window
|
||||||
EmuWindow::Show();
|
EmuWindow::Show();
|
||||||
|
@ -311,12 +313,13 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// change to default resolution
|
// Change to default resolution
|
||||||
ChangeDisplaySettings(NULL, 0);
|
ChangeDisplaySettings(NULL, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (g_Config.bFullscreen && !g_Config.renderToMainframe)
|
if (g_Config.bFullscreen && !g_Config.renderToMainframe)
|
||||||
{
|
{
|
||||||
|
// Hide the cursor
|
||||||
ShowCursor(FALSE);
|
ShowCursor(FALSE);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -332,9 +335,10 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight
|
||||||
int X = (rcdesktop.right-rcdesktop.left)/2 - (rc.right-rc.left)/2;
|
int X = (rcdesktop.right-rcdesktop.left)/2 - (rc.right-rc.left)/2;
|
||||||
int Y = (rcdesktop.bottom-rcdesktop.top)/2 - (rc.bottom-rc.top)/2;
|
int Y = (rcdesktop.bottom-rcdesktop.top)/2 - (rc.bottom-rc.top)/2;
|
||||||
|
|
||||||
SetWindowPos(EmuWindow::GetWnd(), NULL, X, Y, rc.right-rc.left, rc.bottom-rc.top, SWP_NOREPOSITION|SWP_NOZORDER);
|
// EmuWindow::GetWnd() is either the new child window or the new separate window
|
||||||
|
SetWindowPos(EmuWindow::GetWnd(), NULL, X, Y, rc.right-rc.left, rc.bottom-rc.top, SWP_NOREPOSITION | SWP_NOZORDER);
|
||||||
|
|
||||||
PIXELFORMATDESCRIPTOR pfd= // pfd Tells Windows How We Want Things To Be
|
PIXELFORMATDESCRIPTOR pfd = // pfd Tells Windows How We Want Things To Be
|
||||||
{
|
{
|
||||||
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
|
sizeof(PIXELFORMATDESCRIPTOR), // Size Of This Pixel Format Descriptor
|
||||||
1, // Version Number
|
1, // Version Number
|
||||||
|
@ -361,7 +365,7 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd))) {
|
if (!(PixelFormat = ChoosePixelFormat(hDC,&pfd))) {
|
||||||
MessageBox(NULL,"(2) Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
|
MessageBox(NULL,"(2) Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -371,7 +375,7 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(hRC=wglCreateContext(hDC))) {
|
if (!(hRC = wglCreateContext(hDC))) {
|
||||||
MessageBox(NULL,"(4) Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
|
MessageBox(NULL,"(4) Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -605,9 +609,11 @@ void OpenGL_Update()
|
||||||
// TODO fill in
|
// TODO fill in
|
||||||
#elif defined(_WIN32)
|
#elif defined(_WIN32)
|
||||||
RECT rcWindow;
|
RECT rcWindow;
|
||||||
if (!EmuWindow::GetParentWnd()) {
|
// If we are not rendering to a child window
|
||||||
if (!g_Config.bStretchToFit)
|
if (!EmuWindow::GetParentWnd())
|
||||||
return;
|
{
|
||||||
|
// return if we don't stretch the picture
|
||||||
|
if (!g_Config.bStretchToFit) return;
|
||||||
GetWindowRect(EmuWindow::GetWnd(), &rcWindow);
|
GetWindowRect(EmuWindow::GetWnd(), &rcWindow);
|
||||||
rcWindow.top += 25;
|
rcWindow.top += 25;
|
||||||
}
|
}
|
||||||
|
@ -624,6 +630,7 @@ void OpenGL_Update()
|
||||||
int width = rcWindow.right - rcWindow.left;
|
int width = rcWindow.right - rcWindow.left;
|
||||||
int height = rcWindow.bottom - rcWindow.top;
|
int height = rcWindow.bottom - rcWindow.top;
|
||||||
|
|
||||||
|
// If we are rendering to a child window
|
||||||
if (EmuWindow::GetParentWnd() != 0)
|
if (EmuWindow::GetParentWnd() != 0)
|
||||||
::MoveWindow(EmuWindow::GetWnd(), 0, 0, width, height, FALSE);
|
::MoveWindow(EmuWindow::GetWnd(), 0, 0, width, height, FALSE);
|
||||||
|
|
||||||
|
@ -702,17 +709,16 @@ void OpenGL_Update()
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------------------
|
||||||
// Get the new window width and height
|
// Get the new window width and height
|
||||||
|
/* ------------------
|
||||||
|
nBackbufferWidth and nBackbufferHeight: Now the actual rendering window size
|
||||||
|
Max: The highest of w and h
|
||||||
|
nXoff and nYoff: Controls the picture's position inside the rendering window
|
||||||
|
MValueX and MValueY: Used for the picture resolution-change rescaling
|
||||||
// ------------------
|
// ------------------
|
||||||
// nBackbufferWidth and nBackbufferHeight = now the actual screen size
|
MValueX and MValueY: Used for the picture resolution-change rescaling. It will be used in
|
||||||
// Max = the highest of w and h
|
TextureMngr and VertexShaderManager: Rescale textures on resolution changes
|
||||||
// MValueX and MValueY = used for the picture resolution-change rescaling
|
BPStructs.cpp: Control glScissor()
|
||||||
// nXoff and nYoff = controls the picture's position inside the Dolphin window
|
// ------------------ */
|
||||||
// ------------------
|
|
||||||
/* MValueX and MValueY will be used in
|
|
||||||
TextureMngr and VertexShaderManager: Rescale textures on resolution changes
|
|
||||||
BPStructs.cpp: Control glScissor()
|
|
||||||
*/
|
|
||||||
// ------------------
|
|
||||||
float FactorW = 640.0f / (float)nBackbufferWidth;
|
float FactorW = 640.0f / (float)nBackbufferWidth;
|
||||||
float FactorH = 480.0f / (float)nBackbufferHeight;
|
float FactorH = 480.0f / (float)nBackbufferHeight;
|
||||||
float Max = (FactorW < FactorH) ? FactorH : FactorW;
|
float Max = (FactorW < FactorH) ? FactorH : FactorW;
|
||||||
|
@ -733,7 +739,7 @@ void OpenGL_Update()
|
||||||
nYoff = (int)((nBackbufferHeight - (480 * MValueY)) / 2);
|
nYoff = (int)((nBackbufferHeight - (480 * MValueY)) / 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// tell the debugger
|
// Tell the debugger
|
||||||
gleft = rcWindow.left; gright = rcWindow.right;
|
gleft = rcWindow.left; gright = rcWindow.right;
|
||||||
gtop = rcWindow.top; gbottom = rcWindow.bottom;
|
gtop = rcWindow.top; gbottom = rcWindow.bottom;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,13 +18,14 @@
|
||||||
#ifndef _GLOBALS_H
|
#ifndef _GLOBALS_H
|
||||||
#define _GLOBALS_H
|
#define _GLOBALS_H
|
||||||
|
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
|
|
||||||
#include "VideoCommon.h"
|
#include "VideoCommon.h"
|
||||||
#include "pluginspecs_video.h"
|
#include "pluginspecs_video.h"
|
||||||
|
|
||||||
|
#include "ConsoleWindow.h"
|
||||||
|
|
||||||
// Turns file logging on and off
|
// Turns file logging on and off
|
||||||
extern bool LocalLogFile;
|
extern bool LocalLogFile;
|
||||||
|
|
||||||
|
|
|
@ -263,7 +263,7 @@ namespace EmuWindow
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// This is called from
|
// This is called from Create()
|
||||||
HWND OpenWindow(HWND parent, HINSTANCE hInstance, int width, int height, const TCHAR *title)
|
HWND OpenWindow(HWND parent, HINSTANCE hInstance, int width, int height, const TCHAR *title)
|
||||||
{
|
{
|
||||||
wndClass.cbSize = sizeof( wndClass );
|
wndClass.cbSize = sizeof( wndClass );
|
||||||
|
@ -273,8 +273,9 @@ namespace EmuWindow
|
||||||
wndClass.cbWndExtra = 0;
|
wndClass.cbWndExtra = 0;
|
||||||
wndClass.hInstance = hInstance;
|
wndClass.hInstance = hInstance;
|
||||||
wndClass.hIcon = LoadIcon( NULL, IDI_APPLICATION );
|
wndClass.hIcon = LoadIcon( NULL, IDI_APPLICATION );
|
||||||
|
// To interfer less with SetCursor() later we set this to NULL
|
||||||
//wndClass.hCursor = LoadCursor( NULL, IDC_ARROW );
|
//wndClass.hCursor = LoadCursor( NULL, IDC_ARROW );
|
||||||
wndClass.hCursor = NULL; // To interfer less with SetCursor() later
|
wndClass.hCursor = NULL;
|
||||||
wndClass.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
|
wndClass.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
|
||||||
wndClass.lpszMenuName = NULL;
|
wndClass.lpszMenuName = NULL;
|
||||||
wndClass.lpszClassName = m_szClassName;
|
wndClass.lpszClassName = m_szClassName;
|
||||||
|
@ -357,7 +358,9 @@ namespace EmuWindow
|
||||||
UnregisterClass(m_szClassName, m_hInstance);
|
UnregisterClass(m_szClassName, m_hInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ------------------------------------------
|
||||||
|
// Set the size of the child or main window
|
||||||
|
// ------------------
|
||||||
void SetSize(int width, int height)
|
void SetSize(int width, int height)
|
||||||
{
|
{
|
||||||
RECT rc = {0, 0, width, height};
|
RECT rc = {0, 0, width, height};
|
||||||
|
@ -366,6 +369,7 @@ namespace EmuWindow
|
||||||
int w = rc.right - rc.left;
|
int w = rc.right - rc.left;
|
||||||
int h = rc.bottom - rc.top;
|
int h = rc.bottom - rc.top;
|
||||||
|
|
||||||
|
// Move and resize the window
|
||||||
rc.left = (1280 - w)/2;
|
rc.left = (1280 - w)/2;
|
||||||
rc.right = rc.left + w;
|
rc.right = rc.left + w;
|
||||||
rc.top = (1024 - h)/2;
|
rc.top = (1024 - h)/2;
|
||||||
|
|
|
@ -47,6 +47,11 @@
|
||||||
#include "XFB.h"
|
#include "XFB.h"
|
||||||
#include "Timer.h"
|
#include "Timer.h"
|
||||||
|
|
||||||
|
#include "main.h" // Local
|
||||||
|
#ifdef _WIN32
|
||||||
|
#include "OS/Win32.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(HAVE_WX) && HAVE_WX
|
#if defined(HAVE_WX) && HAVE_WX
|
||||||
#include "Debugger/Debugger.h" // for the CDebugger class
|
#include "Debugger/Debugger.h" // for the CDebugger class
|
||||||
#endif
|
#endif
|
||||||
|
@ -391,7 +396,8 @@ bool Renderer::InitializeGL()
|
||||||
|
|
||||||
glDisable(GL_STENCIL_TEST);
|
glDisable(GL_STENCIL_TEST);
|
||||||
glEnable(GL_SCISSOR_TEST);
|
glEnable(GL_SCISSOR_TEST);
|
||||||
glScissor(0, 0, (int)OpenGL_GetWidth(), (int)OpenGL_GetHeight());
|
// Do we really need to set this initial glScissor() value? Wont it be called all the time while the game is running?
|
||||||
|
//glScissor(0, 0, (int)OpenGL_GetWidth(), (int)OpenGL_GetHeight());
|
||||||
glBlendColorEXT(0, 0, 0, 0.5f);
|
glBlendColorEXT(0, 0, 0, 0.5f);
|
||||||
glClearDepth(1.0f);
|
glClearDepth(1.0f);
|
||||||
|
|
||||||
|
@ -504,6 +510,10 @@ void Renderer::ReinitView(int nNewWidth, int nNewHeight)
|
||||||
nNewHeight > 16 ? nNewHeight : 16);
|
nNewHeight > 16 ? nNewHeight : 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Return the rendering window width and height
|
||||||
|
// ------------------------
|
||||||
int Renderer::GetTargetWidth()
|
int Renderer::GetTargetWidth()
|
||||||
{
|
{
|
||||||
return (g_Config.bStretchToFit ? 640 : (int)OpenGL_GetWidth());
|
return (g_Config.bStretchToFit ? 640 : (int)OpenGL_GetWidth());
|
||||||
|
@ -513,6 +523,9 @@ int Renderer::GetTargetHeight()
|
||||||
{
|
{
|
||||||
return (g_Config.bStretchToFit ? 480 : (int)OpenGL_GetHeight());
|
return (g_Config.bStretchToFit ? 480 : (int)OpenGL_GetHeight());
|
||||||
}
|
}
|
||||||
|
/////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
void Renderer::SetRenderTarget(GLuint targ)
|
void Renderer::SetRenderTarget(GLuint targ)
|
||||||
{
|
{
|
||||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB,
|
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB,
|
||||||
|
@ -639,6 +652,7 @@ void Renderer::SetBlendMode(bool forceUpdate)
|
||||||
s_blendMode = newval;
|
s_blendMode = newval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Call browser: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg()
|
// Call browser: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg()
|
||||||
// case 0x52 > SetScissorRect()
|
// case 0x52 > SetScissorRect()
|
||||||
// ---------------
|
// ---------------
|
||||||
|
@ -649,6 +663,7 @@ void Renderer::SetBlendMode(bool forceUpdate)
|
||||||
// Renderer::GetTargetHeight() = the fixed ini file setting
|
// Renderer::GetTargetHeight() = the fixed ini file setting
|
||||||
// donkopunchstania - it appears scissorBR is the bottom right pixel inside the scissor box
|
// donkopunchstania - it appears scissorBR is the bottom right pixel inside the scissor box
|
||||||
// therefore the width and height are (scissorBR + 1) - scissorTL
|
// therefore the width and height are (scissorBR + 1) - scissorTL
|
||||||
|
// ---------------
|
||||||
bool Renderer::SetScissorRect()
|
bool Renderer::SetScissorRect()
|
||||||
{
|
{
|
||||||
int xoff = bpmem.scissorOffset.x * 2 - 342;
|
int xoff = bpmem.scissorOffset.x * 2 - 342;
|
||||||
|
@ -677,13 +692,30 @@ bool Renderer::SetScissorRect()
|
||||||
xoff, yoff
|
xoff, yoff
|
||||||
);*/
|
);*/
|
||||||
|
|
||||||
|
// Check that the coordinates are good
|
||||||
if (rc_right >= rc_left && rc_bottom >= rc_top)
|
if (rc_right >= rc_left && rc_bottom >= rc_top)
|
||||||
{
|
{
|
||||||
|
/* I don't know how this works with other options so I'm limiting it to this to test it, if you want to add support for other modes
|
||||||
|
or make this solution more general please do */
|
||||||
|
if(g_Config.bStretchToFit && !g_Config.bKeepAR)
|
||||||
|
{
|
||||||
|
int WidthDifference = 640 - (int)(rc_right - rc_left);
|
||||||
|
int HeightDifference = 480 - (int)(rc_bottom - rc_top);
|
||||||
|
|
||||||
|
GLScissorX = (int)rc_left; GLScissorY = -(Renderer::GetTargetHeight() - (int)(rc_bottom));
|
||||||
|
GLScissorW = Renderer::GetTargetWidth() + WidthDifference; GLScissorH = Renderer::GetTargetHeight() + HeightDifference;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
GLScissorX = (int)rc_left; GLScissorY = Renderer::GetTargetHeight() - (int)(rc_bottom);
|
||||||
|
GLScissorW = (int)(rc_right - rc_left); GLScissorH = (int)(rc_bottom - rc_top);
|
||||||
|
}
|
||||||
|
|
||||||
glScissor(
|
glScissor(
|
||||||
(int)rc_left, // x = 0
|
GLScissorX, // x = 0
|
||||||
Renderer::GetTargetHeight() - (int)(rc_bottom), // y = 0
|
GLScissorY, // y = 0
|
||||||
(int)(rc_right-rc_left), // y = 0
|
GLScissorW, // width = 640 for example
|
||||||
(int)(rc_bottom-rc_top) // y = 0
|
GLScissorH // height = 480 for example
|
||||||
);
|
);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1004,7 +1036,7 @@ void Renderer::SwapBuffers()
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// copy the rendered from to the real window
|
// Copy the rendered frame to the real window
|
||||||
OpenGL_SwapBuffers();
|
OpenGL_SwapBuffers();
|
||||||
|
|
||||||
glClearColor(0,0,0,0);
|
glClearColor(0,0,0,0);
|
||||||
|
@ -1012,7 +1044,7 @@ void Renderer::SwapBuffers()
|
||||||
|
|
||||||
GL_REPORT_ERRORD();
|
GL_REPORT_ERRORD();
|
||||||
|
|
||||||
//clean out old stuff from caches
|
// Clean out old stuff from caches
|
||||||
PixelShaderCache::Cleanup();
|
PixelShaderCache::Cleanup();
|
||||||
TextureMngr::Cleanup();
|
TextureMngr::Cleanup();
|
||||||
|
|
||||||
|
@ -1136,8 +1168,9 @@ void HandleCgError(CGcontext ctx, CGerror err, void* appdata)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////
|
||||||
// Called from VertexShaderManager
|
// Called from VertexShaderManager
|
||||||
|
// ----------------------
|
||||||
void UpdateViewport()
|
void UpdateViewport()
|
||||||
{
|
{
|
||||||
// reversed gxsetviewport(xorig, yorig, width, height, nearz, farz)
|
// reversed gxsetviewport(xorig, yorig, width, height, nearz, farz)
|
||||||
|
@ -1261,10 +1294,51 @@ void UpdateViewport()
|
||||||
}
|
}
|
||||||
// -------------------------------------
|
// -------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
// I'm limiting it to this modes to test it
|
||||||
|
if(g_Config.bStretchToFit && !g_Config.bKeepAR)
|
||||||
|
{
|
||||||
|
GLWidth = GLWidth + (GLScissorW - 640);
|
||||||
|
GLHeight = GLHeight + (GLScissorH - 480);
|
||||||
|
GLy = 0;
|
||||||
|
GLx = 0;
|
||||||
|
}
|
||||||
|
|
||||||
glViewport(
|
glViewport(
|
||||||
GLx, GLy,
|
GLx, GLy,
|
||||||
GLWidth, GLHeight
|
GLWidth, GLHeight
|
||||||
);
|
);
|
||||||
|
|
||||||
glDepthRange((xfregs.rawViewport[5]- xfregs.rawViewport[2])/16777215.0f, xfregs.rawViewport[5]/16777215.0f);
|
// -----------------------------------------------------------------------
|
||||||
|
// GLDepthRange
|
||||||
|
// ------------------
|
||||||
|
double GLNear = (xfregs.rawViewport[5] - xfregs.rawViewport[2]) / 16777215.0f;
|
||||||
|
double GLFar = xfregs.rawViewport[5] / 16777215.0f;
|
||||||
|
glDepthRange(GLNear, GLFar);
|
||||||
|
// -------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
// Logging
|
||||||
|
/*
|
||||||
|
RECT RcTop, RcParent, RcChild;
|
||||||
|
HWND Child = EmuWindow::GetWnd();
|
||||||
|
HWND Parent = GetParent(Child);
|
||||||
|
HWND Top = GetParent(Parent);
|
||||||
|
GetWindowRect(Top, &RcTop);
|
||||||
|
GetWindowRect(Parent, &RcParent);
|
||||||
|
GetWindowRect(Child, &RcChild);
|
||||||
|
|
||||||
|
|
||||||
|
Console::ClearScreen();
|
||||||
|
Console::Print("----------------------------------------------------------------\n");
|
||||||
|
Console::Print("Top window: X:%03i Y:%03i Width:%03i Height:%03i\n", RcTop.left, RcTop.top, RcTop.right - RcTop.left, RcTop.bottom - RcTop.top);
|
||||||
|
Console::Print("Parent window: X:%03i Y:%03i Width:%03i Height:%03i\n", RcParent.left, RcParent.top, RcParent.right - RcParent.left, RcParent.bottom - RcParent.top);
|
||||||
|
Console::Print("Child window: X:%03i Y:%03i Width:%03i Height:%03i\n", RcChild.left, RcChild.top, RcChild.right - RcChild.left, RcChild.bottom - RcChild.top);
|
||||||
|
Console::Print("----------------------------------------------------------------\n");
|
||||||
|
Console::Print("Res. MValue: X:%f Y:%f XOffs:%f YOffs:%f\n", OpenGL_GetXmax(), OpenGL_GetYmax(), OpenGL_GetXoff(), OpenGL_GetYoff());
|
||||||
|
Console::Print("GLViewPort: X:%03i Y:%03i Width:%03i Height:%03i\n", GLx, GLy, GLWidth, GLHeight);
|
||||||
|
Console::Print("GLDepthRange: Near:%f Far:%f\n", GLNear, GLFar);
|
||||||
|
Console::Print("GLScissor: X:%03i Y:%03i Width:%03i Height:%03i\n", GLScissorX, GLScissorY, GLScissorW, GLScissorH);
|
||||||
|
Console::Print("----------------------------------------------------------------\n");
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,9 @@
|
||||||
// Official SVN repository and contact information can be found at
|
// Official SVN repository and contact information can be found at
|
||||||
// http://code.google.com/p/dolphin-emu/
|
// http://code.google.com/p/dolphin-emu/
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Include
|
||||||
|
// --------------------------
|
||||||
#include "Globals.h"
|
#include "Globals.h"
|
||||||
|
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
|
@ -49,10 +52,20 @@
|
||||||
#include "TextureConverter.h"
|
#include "TextureConverter.h"
|
||||||
|
|
||||||
#include "VideoState.h"
|
#include "VideoState.h"
|
||||||
|
///////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// Definitions
|
||||||
|
// --------------------------
|
||||||
SVideoInitialize g_VideoInitialize;
|
SVideoInitialize g_VideoInitialize;
|
||||||
PLUGIN_GLOBALS* globals;
|
PLUGIN_GLOBALS* globals;
|
||||||
|
|
||||||
|
// Logging
|
||||||
|
int GLScissorX, GLScissorY, GLScissorW, GLScissorH;
|
||||||
|
///////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
/* Create debugging window. There's currently a strange crash that occurs whe a game is loaded
|
/* Create debugging window. There's currently a strange crash that occurs whe a game is loaded
|
||||||
if the OpenGL plugin was loaded before. I'll try to fix that. Currently you may have to
|
if the OpenGL plugin was loaded before. I'll try to fix that. Currently you may have to
|
||||||
clsoe the window if it has auto started, and then restart it after the dll has loaded
|
clsoe the window if it has auto started, and then restart it after the dll has loaded
|
||||||
|
@ -193,6 +206,8 @@ void DllConfig(HWND _hParent)
|
||||||
|
|
||||||
void Initialize(void *init)
|
void Initialize(void *init)
|
||||||
{
|
{
|
||||||
|
//Console::Open(130, 5000);
|
||||||
|
|
||||||
// --------------------------------------------------
|
// --------------------------------------------------
|
||||||
/* Dolphin currently crashes if the dll is loaded when a game is started so we close the
|
/* Dolphin currently crashes if the dll is loaded when a game is started so we close the
|
||||||
debugger and open it again after loading
|
debugger and open it again after loading
|
||||||
|
|
|
@ -22,4 +22,7 @@
|
||||||
|
|
||||||
extern SVideoInitialize g_VideoInitialize;
|
extern SVideoInitialize g_VideoInitialize;
|
||||||
|
|
||||||
|
// Logging
|
||||||
|
extern int GLScissorX, GLScissorY, GLScissorW, GLScissorH;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue