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
|
||||
{
|
||||
GenMode genMode;
|
||||
u32 display_copy_filter[4]; //01-04
|
||||
u32 unknown; //05
|
||||
u32 display_copy_filter[4]; // 01-04
|
||||
u32 unknown; // 05
|
||||
// indirect matrices (set by GXSetIndTexMtx, selected by TevStageIndirect::mid)
|
||||
// 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
|
||||
|
@ -804,9 +804,9 @@ struct BPMemory
|
|||
u32 drawdone; //45, bit1=1 if end of list
|
||||
u32 unknown5; //46 clock?
|
||||
u32 petoken; //47
|
||||
u32 petokenint; //48
|
||||
X10Y10 copyTexSrcXY; //49
|
||||
X10Y10 copyTexSrcWH; //4a
|
||||
u32 petokenint; // 48
|
||||
X10Y10 copyTexSrcXY; // 49
|
||||
X10Y10 copyTexSrcWH; // 4a
|
||||
u32 copyTexDest; //4b// 4b == CopyAddress (GXDispCopy and GXTexCopy use it)
|
||||
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
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
#include "VertexShaderManager.h"
|
||||
#include "PixelShaderManager.h"
|
||||
#include "XFB.h"
|
||||
#include "main.h"
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
|
@ -56,14 +57,23 @@ void BPInit()
|
|||
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,
|
||||
// getting rid of dynamic dispatch.
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Write to bpmem
|
||||
/* ------------------
|
||||
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)
|
||||
{
|
||||
//static int count = 0;
|
||||
//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)
|
||||
{
|
||||
case BPMEM_GENMODE:
|
||||
|
@ -283,10 +293,12 @@ void BPWritten(int addr, int changes, int newval)
|
|||
case BPMEM_SCISSORTL:
|
||||
case BPMEM_SCISSORBR:
|
||||
|
||||
if (changes) {
|
||||
if (changes)
|
||||
{
|
||||
VertexManager::Flush();
|
||||
((u32*)&bpmem)[addr] = newval;
|
||||
if (!Renderer::SetScissorRect()) {
|
||||
if (!Renderer::SetScissorRect())
|
||||
{
|
||||
if (addr == BPMEM_SCISSORBR) {
|
||||
ERROR_LOG("bad scissor!\n");
|
||||
}
|
||||
|
@ -346,26 +358,29 @@ void BPWritten(int addr, int changes, int newval)
|
|||
}
|
||||
break;
|
||||
|
||||
case BPMEM_PE_TOKEN_ID:
|
||||
case BPMEM_PE_TOKEN_ID: // 0x47
|
||||
g_VideoInitialize.pSetPEToken(static_cast<u16>(newval & 0xFFFF), FALSE);
|
||||
DebugLog("SetPEToken 0x%04x", (newval & 0xFFFF));
|
||||
break;
|
||||
|
||||
case BPMEM_PE_TOKEN_INT_ID:
|
||||
case BPMEM_PE_TOKEN_INT_ID: // 0x48
|
||||
g_VideoInitialize.pSetPEToken(static_cast<u16>(newval & 0xFFFF), TRUE);
|
||||
DebugLog("SetPEToken + INT 0x%04x", (newval & 0xFFFF));
|
||||
break;
|
||||
|
||||
case 0x67: // set gp metric?
|
||||
// Set gp metric?
|
||||
case 0x67:
|
||||
break;
|
||||
|
||||
// This case writes to bpmem.triggerEFBCopy and may apparently prompt us to update glScissor()
|
||||
case 0x52:
|
||||
{
|
||||
DVSTARTSUBPROFILE("LoadBPReg:swap");
|
||||
VertexManager::Flush();
|
||||
|
||||
((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 = {
|
||||
(int)(bpmem.copyTexSrcXY.x),
|
||||
(int)(bpmem.copyTexSrcXY.y),
|
||||
|
@ -374,8 +389,8 @@ void BPWritten(int addr, int changes, int newval)
|
|||
};
|
||||
float MValueX = OpenGL_GetXmax();
|
||||
float MValueY = OpenGL_GetYmax();
|
||||
//Need another rc here to get it to scale.
|
||||
//Here the bottom right is the out of the rectangle.
|
||||
// Need another rc here to get it to scale.
|
||||
// Here the bottom right is the out of the rectangle.
|
||||
TRectangle multirc = {
|
||||
(int)(bpmem.copyTexSrcXY.x * MValueX),
|
||||
(int)(bpmem.copyTexSrcXY.y * MValueY),
|
||||
|
@ -386,23 +401,31 @@ void BPWritten(int addr, int changes, int newval)
|
|||
UPE_Copy PE_copy;
|
||||
PE_copy.Hex = bpmem.triggerEFBCopy;
|
||||
|
||||
if (PE_copy.copy_to_xfb == 0) {
|
||||
if (PE_copy.copy_to_xfb == 0)
|
||||
{
|
||||
// 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
|
||||
if (g_Config.bEFBCopyDisable) {
|
||||
glViewport(rc.left,rc.bottom,rc.right,rc.top);
|
||||
glScissor(rc.left,rc.bottom,rc.right,rc.top);
|
||||
if (g_Config.bEFBCopyDisable)
|
||||
{
|
||||
// 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,
|
||||
(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,
|
||||
(PE_copy.target_pixel_format/2)+((PE_copy.target_pixel_format&1)*8), PE_copy.half_scale>0, &rc);
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
// EFB to XFB
|
||||
if (g_Config.bUseXFB)
|
||||
{
|
||||
|
@ -429,17 +452,23 @@ void BPWritten(int addr, int changes, int newval)
|
|||
}
|
||||
|
||||
// clearing
|
||||
if (PE_copy.clear) {
|
||||
if (PE_copy.clear)
|
||||
{
|
||||
// clear color
|
||||
Renderer::SetRenderMode(Renderer::RM_Normal);
|
||||
|
||||
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
|
||||
glScissor(multirc.left, (Renderer::GetTargetHeight() - multirc.bottom),
|
||||
(multirc.right - multirc.left), (multirc.bottom - multirc.top));
|
||||
// Always set the scissor in case it was set by the game and has not been reset
|
||||
// But we will do that at the end of this section, in SetScissorRect(), why would we do it twice in the same function?
|
||||
//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();
|
||||
|
||||
|
@ -457,7 +486,8 @@ void BPWritten(int addr, int changes, int newval)
|
|||
((clearColor>>24) & 0xff)*(1/255.0f));
|
||||
bits |= GL_COLOR_BUFFER_BIT;
|
||||
}
|
||||
if (bpmem.zmode.updateenable) {
|
||||
if (bpmem.zmode.updateenable)
|
||||
{
|
||||
glClearDepth((float)(bpmem.clearZValue&0xFFFFFF) / float(0xFFFFFF));
|
||||
bits |= GL_DEPTH_BUFFER_BIT;
|
||||
}
|
||||
|
@ -635,6 +665,8 @@ void BPWritten(int addr, int changes, int newval)
|
|||
case 0x90:
|
||||
case 0xA0:
|
||||
case 0xB0:
|
||||
|
||||
// Just update the bpmem struct, don't do anything else.
|
||||
default:
|
||||
if (changes)
|
||||
{
|
||||
|
@ -691,15 +723,16 @@ void BPWritten(int addr, int changes, int newval)
|
|||
void LoadBPReg(u32 value0)
|
||||
{
|
||||
DVSTARTPROFILE();
|
||||
//handle the mask register
|
||||
// Handle the mask register
|
||||
int opcode = value0 >> 24;
|
||||
int oldval = ((u32*)&bpmem)[opcode];
|
||||
int newval = (oldval & ~bpmem.bpMask) | (value0 & bpmem.bpMask);
|
||||
// Check if it's a new value
|
||||
int changes = (oldval ^ newval) & 0xFFFFFF;
|
||||
//reset the mask register
|
||||
if (opcode != 0xFE)
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -117,6 +117,10 @@ void OpenGL_SetWindowText(const char *text)
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
// =======================================================================================
|
||||
// Draw messages on top of the screen
|
||||
// ------------------
|
||||
unsigned int Callback_PeekMessages()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
@ -134,13 +138,14 @@ unsigned int Callback_PeekMessages()
|
|||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Show the current FPS
|
||||
void UpdateFPSDisplay(const char *text)
|
||||
{
|
||||
char temp[512];
|
||||
sprintf(temp, "SVN R%s: GL: %s", SVN_REV_STR, text);
|
||||
OpenGL_SetWindowText(temp);
|
||||
}
|
||||
// =========================
|
||||
|
||||
|
||||
// =======================================================================================
|
||||
|
@ -171,7 +176,7 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight
|
|||
{
|
||||
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;
|
||||
_theight = _iheight;
|
||||
|
@ -262,15 +267,12 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight
|
|||
// Create rendering window in Windows
|
||||
// ----------------------
|
||||
|
||||
// Create the window
|
||||
// Create a separate window
|
||||
if (!g_Config.renderToMainframe || g_VideoInitialize.pWindowHandle == NULL)
|
||||
{
|
||||
g_VideoInitialize.pWindowHandle = (void*)EmuWindow::Create(NULL, g_hInstance, "Please wait...");
|
||||
}
|
||||
// Create a child window
|
||||
else
|
||||
{
|
||||
g_VideoInitialize.pWindowHandle = (void*)EmuWindow::Create((HWND)g_VideoInitialize.pWindowHandle, g_hInstance, "Please wait...");
|
||||
}
|
||||
|
||||
// Show the window
|
||||
EmuWindow::Show();
|
||||
|
@ -311,12 +313,13 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight
|
|||
}
|
||||
else
|
||||
{
|
||||
// change to default resolution
|
||||
// Change to default resolution
|
||||
ChangeDisplaySettings(NULL, 0);
|
||||
}
|
||||
|
||||
if (g_Config.bFullscreen && !g_Config.renderToMainframe)
|
||||
{
|
||||
// Hide the cursor
|
||||
ShowCursor(FALSE);
|
||||
}
|
||||
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 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
|
||||
1, // Version Number
|
||||
|
@ -361,7 +365,7 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight
|
|||
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);
|
||||
return false;
|
||||
}
|
||||
|
@ -371,7 +375,7 @@ bool OpenGL_Create(SVideoInitialize &_VideoInitialize, int _iwidth, int _iheight
|
|||
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);
|
||||
return false;
|
||||
}
|
||||
|
@ -605,9 +609,11 @@ void OpenGL_Update()
|
|||
// TODO fill in
|
||||
#elif defined(_WIN32)
|
||||
RECT rcWindow;
|
||||
if (!EmuWindow::GetParentWnd()) {
|
||||
if (!g_Config.bStretchToFit)
|
||||
return;
|
||||
// If we are not rendering to a child window
|
||||
if (!EmuWindow::GetParentWnd())
|
||||
{
|
||||
// return if we don't stretch the picture
|
||||
if (!g_Config.bStretchToFit) return;
|
||||
GetWindowRect(EmuWindow::GetWnd(), &rcWindow);
|
||||
rcWindow.top += 25;
|
||||
}
|
||||
|
@ -624,6 +630,7 @@ void OpenGL_Update()
|
|||
int width = rcWindow.right - rcWindow.left;
|
||||
int height = rcWindow.bottom - rcWindow.top;
|
||||
|
||||
// If we are rendering to a child window
|
||||
if (EmuWindow::GetParentWnd() != 0)
|
||||
::MoveWindow(EmuWindow::GetWnd(), 0, 0, width, height, FALSE);
|
||||
|
||||
|
@ -702,17 +709,16 @@ void OpenGL_Update()
|
|||
|
||||
// ---------------------------------------------------------------------------------------
|
||||
// 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
|
||||
// Max = the highest of w and h
|
||||
// MValueX and MValueY = used for the picture resolution-change rescaling
|
||||
// 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()
|
||||
*/
|
||||
// ------------------
|
||||
MValueX and MValueY: Used for the picture resolution-change rescaling. It will be used in
|
||||
TextureMngr and VertexShaderManager: Rescale textures on resolution changes
|
||||
BPStructs.cpp: Control glScissor()
|
||||
// ------------------ */
|
||||
float FactorW = 640.0f / (float)nBackbufferWidth;
|
||||
float FactorH = 480.0f / (float)nBackbufferHeight;
|
||||
float Max = (FactorW < FactorH) ? FactorH : FactorW;
|
||||
|
@ -733,7 +739,7 @@ void OpenGL_Update()
|
|||
nYoff = (int)((nBackbufferHeight - (480 * MValueY)) / 2);
|
||||
}
|
||||
|
||||
// tell the debugger
|
||||
// Tell the debugger
|
||||
gleft = rcWindow.left; gright = rcWindow.right;
|
||||
gtop = rcWindow.top; gbottom = rcWindow.bottom;
|
||||
}
|
||||
|
|
|
@ -18,13 +18,14 @@
|
|||
#ifndef _GLOBALS_H
|
||||
#define _GLOBALS_H
|
||||
|
||||
|
||||
#include "Common.h"
|
||||
#include "Config.h"
|
||||
|
||||
#include "VideoCommon.h"
|
||||
#include "pluginspecs_video.h"
|
||||
|
||||
#include "ConsoleWindow.h"
|
||||
|
||||
// Turns file logging on and off
|
||||
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)
|
||||
{
|
||||
wndClass.cbSize = sizeof( wndClass );
|
||||
|
@ -273,8 +273,9 @@ namespace EmuWindow
|
|||
wndClass.cbWndExtra = 0;
|
||||
wndClass.hInstance = hInstance;
|
||||
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 = NULL; // To interfer less with SetCursor() later
|
||||
wndClass.hCursor = NULL;
|
||||
wndClass.hbrBackground = (HBRUSH)GetStockObject( BLACK_BRUSH );
|
||||
wndClass.lpszMenuName = NULL;
|
||||
wndClass.lpszClassName = m_szClassName;
|
||||
|
@ -295,7 +296,7 @@ namespace EmuWindow
|
|||
CW_USEDEFAULT, CW_USEDEFAULT,CW_USEDEFAULT, CW_USEDEFAULT,
|
||||
parent, NULL, hInstance, NULL );
|
||||
|
||||
ShowWindow(m_hWnd, SW_SHOWMAXIMIZED);
|
||||
ShowWindow(m_hWnd, SW_SHOWMAXIMIZED);
|
||||
}
|
||||
|
||||
// Create new separate window
|
||||
|
@ -357,7 +358,9 @@ namespace EmuWindow
|
|||
UnregisterClass(m_szClassName, m_hInstance);
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------
|
||||
// Set the size of the child or main window
|
||||
// ------------------
|
||||
void SetSize(int width, int height)
|
||||
{
|
||||
RECT rc = {0, 0, width, height};
|
||||
|
@ -366,6 +369,7 @@ namespace EmuWindow
|
|||
int w = rc.right - rc.left;
|
||||
int h = rc.bottom - rc.top;
|
||||
|
||||
// Move and resize the window
|
||||
rc.left = (1280 - w)/2;
|
||||
rc.right = rc.left + w;
|
||||
rc.top = (1024 - h)/2;
|
||||
|
|
|
@ -47,6 +47,11 @@
|
|||
#include "XFB.h"
|
||||
#include "Timer.h"
|
||||
|
||||
#include "main.h" // Local
|
||||
#ifdef _WIN32
|
||||
#include "OS/Win32.h"
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_WX) && HAVE_WX
|
||||
#include "Debugger/Debugger.h" // for the CDebugger class
|
||||
#endif
|
||||
|
@ -391,7 +396,8 @@ bool Renderer::InitializeGL()
|
|||
|
||||
glDisable(GL_STENCIL_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);
|
||||
glClearDepth(1.0f);
|
||||
|
||||
|
@ -504,6 +510,10 @@ void Renderer::ReinitView(int nNewWidth, int nNewHeight)
|
|||
nNewHeight > 16 ? nNewHeight : 16);
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Return the rendering window width and height
|
||||
// ------------------------
|
||||
int Renderer::GetTargetWidth()
|
||||
{
|
||||
return (g_Config.bStretchToFit ? 640 : (int)OpenGL_GetWidth());
|
||||
|
@ -513,6 +523,9 @@ int Renderer::GetTargetHeight()
|
|||
{
|
||||
return (g_Config.bStretchToFit ? 480 : (int)OpenGL_GetHeight());
|
||||
}
|
||||
/////////////////////////////
|
||||
|
||||
|
||||
void Renderer::SetRenderTarget(GLuint targ)
|
||||
{
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_ARB,
|
||||
|
@ -639,6 +652,7 @@ void Renderer::SetBlendMode(bool forceUpdate)
|
|||
s_blendMode = newval;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Call browser: OpcodeDecoding.cpp ExecuteDisplayList > Decode() > LoadBPReg()
|
||||
// case 0x52 > SetScissorRect()
|
||||
// ---------------
|
||||
|
@ -649,6 +663,7 @@ void Renderer::SetBlendMode(bool forceUpdate)
|
|||
// Renderer::GetTargetHeight() = the fixed ini file setting
|
||||
// donkopunchstania - it appears scissorBR is the bottom right pixel inside the scissor box
|
||||
// therefore the width and height are (scissorBR + 1) - scissorTL
|
||||
// ---------------
|
||||
bool Renderer::SetScissorRect()
|
||||
{
|
||||
int xoff = bpmem.scissorOffset.x * 2 - 342;
|
||||
|
@ -677,13 +692,30 @@ bool Renderer::SetScissorRect()
|
|||
xoff, yoff
|
||||
);*/
|
||||
|
||||
// Check that the coordinates are good
|
||||
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(
|
||||
(int)rc_left, // x = 0
|
||||
Renderer::GetTargetHeight() - (int)(rc_bottom), // y = 0
|
||||
(int)(rc_right-rc_left), // y = 0
|
||||
(int)(rc_bottom-rc_top) // y = 0
|
||||
GLScissorX, // x = 0
|
||||
GLScissorY, // y = 0
|
||||
GLScissorW, // width = 640 for example
|
||||
GLScissorH // height = 480 for example
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
@ -1004,7 +1036,7 @@ void Renderer::SwapBuffers()
|
|||
}
|
||||
#endif
|
||||
|
||||
// copy the rendered from to the real window
|
||||
// Copy the rendered frame to the real window
|
||||
OpenGL_SwapBuffers();
|
||||
|
||||
glClearColor(0,0,0,0);
|
||||
|
@ -1012,7 +1044,7 @@ void Renderer::SwapBuffers()
|
|||
|
||||
GL_REPORT_ERRORD();
|
||||
|
||||
//clean out old stuff from caches
|
||||
// Clean out old stuff from caches
|
||||
PixelShaderCache::Cleanup();
|
||||
TextureMngr::Cleanup();
|
||||
|
||||
|
@ -1136,8 +1168,9 @@ void HandleCgError(CGcontext ctx, CGerror err, void* appdata)
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////
|
||||
// Called from VertexShaderManager
|
||||
// ----------------------
|
||||
void UpdateViewport()
|
||||
{
|
||||
// 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(
|
||||
GLx, GLy,
|
||||
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
|
||||
// http://code.google.com/p/dolphin-emu/
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Include
|
||||
// --------------------------
|
||||
#include "Globals.h"
|
||||
|
||||
#include <cstdarg>
|
||||
|
@ -49,10 +52,20 @@
|
|||
#include "TextureConverter.h"
|
||||
|
||||
#include "VideoState.h"
|
||||
///////////////////////////////////////////////
|
||||
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Definitions
|
||||
// --------------------------
|
||||
SVideoInitialize g_VideoInitialize;
|
||||
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
|
||||
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
|
||||
|
@ -193,6 +206,8 @@ void DllConfig(HWND _hParent)
|
|||
|
||||
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
|
||||
debugger and open it again after loading
|
||||
|
|
|
@ -22,4 +22,7 @@
|
|||
|
||||
extern SVideoInitialize g_VideoInitialize;
|
||||
|
||||
// Logging
|
||||
extern int GLScissorX, GLScissorY, GLScissorW, GLScissorH;
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue