From 5746ed490c772cc6e853fa99988c1af7f3e12b24 Mon Sep 17 00:00:00 2001 From: John Peterson Date: Thu, 19 Feb 2009 06:52:01 +0000 Subject: [PATCH] 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 --- Source/Core/VideoCommon/Src/BPMemory.h | 10 +- .../Plugins/Plugin_VideoOGL/Src/BPStructs.cpp | 85 +++++++++++------ Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp | 58 ++++++------ Source/Plugins/Plugin_VideoOGL/Src/Globals.h | 3 +- .../Plugins/Plugin_VideoOGL/Src/OS/Win32.cpp | 12 ++- Source/Plugins/Plugin_VideoOGL/Src/Render.cpp | 92 +++++++++++++++++-- Source/Plugins/Plugin_VideoOGL/Src/main.cpp | 15 +++ Source/Plugins/Plugin_VideoOGL/Src/main.h | 3 + 8 files changed, 207 insertions(+), 71 deletions(-) diff --git a/Source/Core/VideoCommon/Src/BPMemory.h b/Source/Core/VideoCommon/Src/BPMemory.h index edba754015..47cf18bdd3 100644 --- a/Source/Core/VideoCommon/Src/BPMemory.h +++ b/Source/Core/VideoCommon/Src/BPMemory.h @@ -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 diff --git a/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.cpp b/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.cpp index dbb4587ac4..ffd8b339df 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/BPStructs.cpp @@ -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(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(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); } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp index 8d3a5dbb5d..0c22c97259 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/GLUtil.cpp @@ -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; } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Globals.h b/Source/Plugins/Plugin_VideoOGL/Src/Globals.h index 077908c113..c55236bf27 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Globals.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/Globals.h @@ -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; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/OS/Win32.cpp b/Source/Plugins/Plugin_VideoOGL/Src/OS/Win32.cpp index cedf48127a..0d81158040 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/OS/Win32.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/OS/Win32.cpp @@ -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; diff --git a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp index 0d2d454905..f73945d9b2 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/Render.cpp @@ -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"); + */ } diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp index 4a24ad52fe..7c1080dc24 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.cpp +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.cpp @@ -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 @@ -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 diff --git a/Source/Plugins/Plugin_VideoOGL/Src/main.h b/Source/Plugins/Plugin_VideoOGL/Src/main.h index 2c488e25d5..2e4980df1e 100644 --- a/Source/Plugins/Plugin_VideoOGL/Src/main.h +++ b/Source/Plugins/Plugin_VideoOGL/Src/main.h @@ -22,4 +22,7 @@ extern SVideoInitialize g_VideoInitialize; +// Logging +extern int GLScissorX, GLScissorY, GLScissorW, GLScissorH; + #endif