diff --git a/plugins/zzogl-pg/opengl/GLWin32.cpp b/plugins/zzogl-pg/opengl/GLWin32.cpp index 0bb5edf95d..f904cc9387 100644 --- a/plugins/zzogl-pg/opengl/GLWin32.cpp +++ b/plugins/zzogl-pg/opengl/GLWin32.cpp @@ -21,13 +21,15 @@ #ifdef GL_WIN32_WINDOW -LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) +LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { static int nWindowWidth = 0, nWindowHeight = 0; - switch( msg ) { + switch (msg) + { + case WM_DESTROY: - PostQuitMessage( 0 ); + PostQuitMessage(0); return 0; case WM_KEYDOWN: @@ -39,24 +41,23 @@ LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) break; case WM_ACTIVATE: - - if( wParam != WA_INACTIVE ) { + if (wParam != WA_INACTIVE) + { //ZZLog::Debug_Log("Restoring device."); ZeroGS::Restore(); } - break; case WM_SIZE: - nWindowWidth = lParam&0xffff; - nWindowHeight = lParam>>16; + nWindowWidth = lParam & 0xffff; + nWindowHeight = lParam >> 16; ZeroGS::ChangeWindowSize(nWindowWidth, nWindowHeight); - break; case WM_SIZING: // if button is 0, then just released so can resize - if( GetSystemMetrics(SM_SWAPBUTTON) ? !GetAsyncKeyState(VK_RBUTTON) : !GetAsyncKeyState(VK_LBUTTON) ) { + if (GetSystemMetrics(SM_SWAPBUTTON) ? !GetAsyncKeyState(VK_RBUTTON) : !GetAsyncKeyState(VK_LBUTTON)) + { ZeroGS::SetChangeDeviceSize(nWindowWidth, nWindowHeight); } break; @@ -66,14 +67,16 @@ LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ) break; } - return DefWindowProc( hWnd, msg, wParam, lParam ); + return DefWindowProc(hWnd, msg, wParam, lParam); } bool GLWindow::CreateWindow(void *pDisplay) { RECT rc, rcdesktop; - rc.left = 0; rc.top = 0; - rc.right = conf.width; rc.bottom = conf.height; + rc.left = 0; + rc.top = 0; + rc.right = conf.width; + rc.bottom = conf.height; WNDCLASSEX wc; HINSTANCE hInstance = GetModuleHandle(NULL); @@ -92,9 +95,9 @@ bool GLWindow::CreateWindow(void *pDisplay) wc.lpszMenuName = NULL; wc.lpszClassName = "PS2EMU_ZEROGS"; - RegisterClassEx( &wc ); + RegisterClassEx(&wc); - if( conf.options & GSOPTION_FULLSCREEN) + if (conf.options & GSOPTION_FULLSCREEN) { dwExStyle = WS_EX_APPWINDOW; dwStyle = WS_POPUP; @@ -106,31 +109,34 @@ bool GLWindow::CreateWindow(void *pDisplay) } AdjustWindowRectEx(&rc, dwStyle, FALSE, dwExStyle); + GetWindowRect(GetDesktopWindow(), &rcdesktop); GShwnd = CreateWindowEx( - dwExStyle, - "PS2EMU_ZEROGS", - "ZeroGS", - dwStyle, - (rcdesktop.right - (rc.right - rc.left)) / 2, - (rcdesktop.bottom - (rc.bottom - rc.top)) / 2, - rc.right - rc.left, - rc.bottom - rc.top, - NULL, - NULL, - hInstance, - NULL); + dwExStyle, + "PS2EMU_ZEROGS", + "ZeroGS", + dwStyle, + (rcdesktop.right - (rc.right - rc.left)) / 2, + (rcdesktop.bottom - (rc.bottom - rc.top)) / 2, + rc.right - rc.left, + rc.bottom - rc.top, + NULL, + NULL, + hInstance, + NULL); if (GShwnd == NULL) return false; if (pDisplay != NULL) *(HWND*)pDisplay = GShwnd; - + // set just in case SetWindowLongPtr(GShwnd, GWLP_WNDPROC, (LPARAM)(WNDPROC)MsgProc); - ShowWindow( GShwnd, SW_SHOWDEFAULT ); - UpdateWindow( GShwnd ); + ShowWindow(GShwnd, SW_SHOWDEFAULT); + + UpdateWindow(GShwnd); + SetFocus(GShwnd); return (pDisplay != NULL); @@ -140,22 +146,23 @@ bool GLWindow::ReleaseWindow() { if (hRC) // Do We Have A Rendering Context? { - if (!wglMakeCurrent(NULL,NULL)) // Are We Able To Release The DC And RC Contexts? + if (!wglMakeCurrent(NULL, NULL)) // Are We Able To Release The DC And RC Contexts? { - MessageBox(NULL,"Release Of DC And RC Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); + MessageBox(NULL, "Release Of DC And RC Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); } if (!wglDeleteContext(hRC)) // Are We Able To Delete The RC? { - MessageBox(NULL,"Release Rendering Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); + MessageBox(NULL, "Release Rendering Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); } - hRC=NULL; // Set RC To NULL + + hRC = NULL; // Set RC To NULL } - if (hDC && !ReleaseDC(GShwnd,hDC)) // Are We Able To Release The DC + if (hDC && !ReleaseDC(GShwnd, hDC)) // Are We Able To Release The DC { - MessageBox(NULL,"Release Device Context Failed.","SHUTDOWN ERROR",MB_OK | MB_ICONINFORMATION); - hDC=NULL; // Set DC To NULL + MessageBox(NULL, "Release Device Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION); + hDC = NULL; // Set DC To NULL } return true; @@ -163,7 +170,7 @@ bool GLWindow::ReleaseWindow() void GLWindow::CloseWindow() { - if( GShwnd != NULL ) + if (GShwnd != NULL) { DestroyWindow(GShwnd); GShwnd = NULL; @@ -179,55 +186,64 @@ bool GLWindow::DisplayWindow(int _width, int _height) RECT rcdesktop; GetWindowRect(GetDesktopWindow(), &rcdesktop); - if( conf.options & GSOPTION_FULLSCREEN) { + if (conf.options & GSOPTION_FULLSCREEN) + { nBackbufferWidth = rcdesktop.right - rcdesktop.left; nBackbufferHeight = rcdesktop.bottom - rcdesktop.top; - dwExStyle=WS_EX_APPWINDOW; - dwStyle=WS_POPUP; + dwExStyle = WS_EX_APPWINDOW; + dwStyle = WS_POPUP; ShowCursor(FALSE); } - else { - dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; - dwStyle=WS_OVERLAPPEDWINDOW; + else + { + dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; + dwStyle = WS_OVERLAPPEDWINDOW; } RECT rc; - rc.left = 0; rc.top = 0; - rc.right = nBackbufferWidth; rc.bottom = nBackbufferHeight; + + rc.left = 0; + rc.top = 0; + rc.right = nBackbufferWidth; + rc.bottom = nBackbufferHeight; AdjustWindowRectEx(&rc, dwStyle, FALSE, dwExStyle); - 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 X = (rcdesktop.right - rcdesktop.left) / 2 - (rc.right - rc.left) / 2; + int Y = (rcdesktop.bottom - rcdesktop.top) / 2 - (rc.bottom - rc.top) / 2; - SetWindowLong( GShwnd, GWL_STYLE, dwStyle ); - SetWindowLong( GShwnd, GWL_EXSTYLE, dwExStyle ); + SetWindowLong(GShwnd, GWL_STYLE, dwStyle); + SetWindowLong(GShwnd, GWL_EXSTYLE, dwExStyle); - SetWindowPos(GShwnd, HWND_TOP, X, Y, rc.right-rc.left, rc.bottom-rc.top, SWP_SHOWWINDOW); + SetWindowPos(GShwnd, HWND_TOP, X, Y, rc.right - rc.left, rc.bottom - rc.top, SWP_SHOWWINDOW); - if (conf.options & GSOPTION_FULLSCREEN) { + if (conf.options & GSOPTION_FULLSCREEN) + { DEVMODE dmScreenSettings; - memset(&dmScreenSettings,0,sizeof(dmScreenSettings)); - dmScreenSettings.dmSize=sizeof(dmScreenSettings); + memset(&dmScreenSettings, 0, sizeof(dmScreenSettings)); + dmScreenSettings.dmSize = sizeof(dmScreenSettings); dmScreenSettings.dmPelsWidth = nBackbufferWidth; dmScreenSettings.dmPelsHeight = nBackbufferHeight; dmScreenSettings.dmBitsPerPel = 32; - dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT; + dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; // Try To Set Selected Mode And Get Results. NOTE: CDS_FULLSCREEN Gets Rid Of Start Bar. - if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL) + + if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) { - if (MessageBox(NULL,"The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?","NeHe GL",MB_YESNO|MB_ICONEXCLAMATION)==IDYES) + if (MessageBox(NULL, "The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?", "NeHe GL", MB_YESNO | MB_ICONEXCLAMATION) == IDYES) conf.options &= ~GSOPTION_FULLSCREEN; else return false; } } - else { + else + { // change to default resolution ChangeDisplaySettings(NULL, 0); } - 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 @@ -249,32 +265,38 @@ bool GLWindow::DisplayWindow(int _width, int _height) 0, 0, 0 // Layer Masks Ignored }; - if (!(hDC=GetDC(GShwnd))) { - MessageBox(NULL,"(1) Can't Create A GL Device Context.","ERROR",MB_OK|MB_ICONEXCLAMATION); + if (!(hDC = GetDC(GShwnd))) + { + MessageBox(NULL, "(1) Can't Create A GL Device Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return false; } - if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd))) { - MessageBox(NULL,"(2) Can't Find A Suitable PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION); + if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd))) + { + MessageBox(NULL, "(2) Can't Find A Suitable PixelFormat.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return false; } - if(!SetPixelFormat(hDC,PixelFormat,&pfd)) { - MessageBox(NULL,"(3) Can't Set The PixelFormat.","ERROR",MB_OK|MB_ICONEXCLAMATION); + if (!SetPixelFormat(hDC, PixelFormat, &pfd)) + { + MessageBox(NULL, "(3) Can't Set The PixelFormat.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return false; } - if (!(hRC=wglCreateContext(hDC))) { - MessageBox(NULL,"(4) Can't Create A GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION); + if (!(hRC = wglCreateContext(hDC))) + { + MessageBox(NULL, "(4) Can't Create A GL Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return false; } - if(!wglMakeCurrent(hDC,hRC)) { - MessageBox(NULL,"(5) Can't Activate The GL Rendering Context.","ERROR",MB_OK|MB_ICONEXCLAMATION); + if (!wglMakeCurrent(hDC, hRC)) + { + MessageBox(NULL, "(5) Can't Activate The GL Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION); return false; } UpdateWindow(GShwnd); + return true; } diff --git a/plugins/zzogl-pg/opengl/GLWinX11.cpp b/plugins/zzogl-pg/opengl/GLWinX11.cpp index 18a169f3f8..1f5ebd2389 100644 --- a/plugins/zzogl-pg/opengl/GLWinX11.cpp +++ b/plugins/zzogl-pg/opengl/GLWinX11.cpp @@ -23,14 +23,14 @@ bool GLWindow::CreateWindow(void *pDisplay) { - glDisplay = XOpenDisplay(0); - glScreen = DefaultScreen(glDisplay); + glDisplay = XOpenDisplay(0); + glScreen = DefaultScreen(glDisplay); - if ( pDisplay == NULL ) return false; + if (pDisplay == NULL) return false; - *(Display**)pDisplay = glDisplay; + *(Display**)pDisplay = glDisplay; - return true; + return true; } bool GLWindow::ReleaseWindow() @@ -43,11 +43,12 @@ bool GLWindow::ReleaseWindow() } glXDestroyContext(glDisplay, context); + context = NULL; } /* switch back to original desktop resolution if we were in fullscreen */ - if ( glDisplay != NULL ) + if (glDisplay != NULL) { if (fullScreen) { @@ -55,6 +56,7 @@ bool GLWindow::ReleaseWindow() XF86VidModeSetViewPort(glDisplay, glScreen, 0, 0); } } + return true; } @@ -63,8 +65,9 @@ void GLWindow::CloseWindow() conf.x = x; conf.y = y; SaveConfig(); - if ( glDisplay != NULL ) - { + + if (glDisplay != NULL) + { XCloseDisplay(glDisplay); glDisplay = NULL; } @@ -84,14 +87,15 @@ bool GLWindow::DisplayWindow(int _width, int _height) x = conf.x; y = conf.y; - + // attributes for a single buffered visual in RGBA format with at least // 8 bits per color and a 24 bit depth buffer int attrListSgl[] = {GLX_RGBA, GLX_RED_SIZE, 8, GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_DEPTH_SIZE, 24, - None}; + None + }; // attributes for a double buffered visual in RGBA format with at least // 8 bits per color and a 24 bit depth buffer @@ -100,12 +104,14 @@ bool GLWindow::DisplayWindow(int _width, int _height) GLX_GREEN_SIZE, 8, GLX_BLUE_SIZE, 8, GLX_DEPTH_SIZE, 24, - None }; + None + }; GLWin.fullScreen = !!(conf.options & GSOPTION_FULLSCREEN); /* get an appropriate visual */ vi = glXChooseVisual(glDisplay, glScreen, attrListDbl); + if (vi == NULL) { vi = glXChooseVisual(glDisplay, glScreen, attrListSgl); @@ -117,6 +123,7 @@ bool GLWindow::DisplayWindow(int _width, int _height) doubleBuffered = true; ZZLog::Error_Log("Got Doublebuffered Visual!"); } + if (vi == NULL) { ZZLog::Error_Log("Failed to get buffered Visual!"); @@ -124,6 +131,7 @@ bool GLWindow::DisplayWindow(int _width, int _height) } glXQueryVersion(glDisplay, &glxMajorVersion, &glxMinorVersion); + ZZLog::Error_Log("glX-Version %d.%d", glxMajorVersion, glxMinorVersion); /* create a GLX context */ @@ -149,12 +157,13 @@ bool GLWindow::DisplayWindow(int _width, int _height) ZZLog::Error_Log("XF86VidModeExtension-Version %d.%d.", vidModeMajorVersion, vidModeMinorVersion); XF86VidModeGetAllModeLines(glDisplay, glScreen, &modeNum, &modes); - if( modeNum > 0 && modes != NULL ) + if (modeNum > 0 && modes != NULL) { /* save desktop-resolution before switching modes */ deskMode = *modes[0]; /* look for mode with requested resolution */ + for (i = 0; i < modeNum; i++) { if ((modes[i]->hdisplay == _width) && (modes[i]->vdisplay == _height)) @@ -164,6 +173,7 @@ bool GLWindow::DisplayWindow(int _width, int _height) } XF86VidModeSwitchToMode(glDisplay, glScreen, modes[bestMode]); + XF86VidModeSetViewPort(glDisplay, glScreen, 0, 0); dpyWidth = modes[bestMode]->hdisplay; dpyHeight = modes[bestMode]->vdisplay; @@ -174,9 +184,9 @@ bool GLWindow::DisplayWindow(int _width, int _height) attr.override_redirect = True; attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask; glWindow = XCreateWindow(glDisplay, RootWindow(glDisplay, vi->screen), - 0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual, - CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, - &attr); + 0, 0, dpyWidth, dpyHeight, 0, vi->depth, InputOutput, vi->visual, + CWBorderPixel | CWColormap | CWEventMask | CWOverrideRedirect, + &attr); XWarpPointer(glDisplay, None, glWindow, 0, 0, 0, 0, 0, 0); XMapRaised(glDisplay, glWindow); XGrabKeyboard(glDisplay, glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime); @@ -185,9 +195,9 @@ bool GLWindow::DisplayWindow(int _width, int _height) else { ZZLog::Error_Log("Failed to start fullscreen. If you received the \n" - "\"XFree86-VidModeExtension\" extension is missing, add\n" - "Load \"extmod\"\n" - "to your X configuration file (under the Module Section)"); + "\"XFree86-VidModeExtension\" extension is missing, add\n" + "Load \"extmod\"\n" + "to your X configuration file (under the Module Section)"); fullScreen = false; } } @@ -197,8 +207,8 @@ bool GLWindow::DisplayWindow(int _width, int _height) // create a window in window mode attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask; glWindow = XCreateWindow(glDisplay, RootWindow(glDisplay, vi->screen), - 0, 0, _width, _height, 0, vi->depth, InputOutput, vi->visual, - CWBorderPixel | CWColormap | CWEventMask, &attr); + 0, 0, _width, _height, 0, vi->depth, InputOutput, vi->visual, + CWBorderPixel | CWColormap | CWEventMask, &attr); // only set window title and handle wm_delete_events if in windowed mode wmDelete = XInternAtom(glDisplay, "WM_DELETE_WINDOW", True); @@ -211,8 +221,11 @@ bool GLWindow::DisplayWindow(int _width, int _height) // connect the glx-context to the window glXMakeCurrent(glDisplay, glWindow, context); + XGetGeometry(glDisplay, glWindow, &winDummy, &x, &y, &width, &height, &borderDummy, &depth); + ZZLog::Error_Log("Depth %d", depth); + if (glXIsDirect(glDisplay, context)) ZZLog::Error_Log("You have Direct Rendering!"); else @@ -221,14 +234,14 @@ bool GLWindow::DisplayWindow(int _width, int _height) // better for pad plugin key input (thc) XSelectInput(glDisplay, glWindow, ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask | StructureNotifyMask | EnterWindowMask | LeaveWindowMask | - FocusChangeMask ); + FocusChangeMask); return true; } void GLWindow::SwapGLBuffers() { - glXSwapBuffers(glDisplay, glWindow); + glXSwapBuffers(glDisplay, glWindow); } void GLWindow::SetTitle(char *strtitle) @@ -236,29 +249,32 @@ void GLWindow::SetTitle(char *strtitle) XTextProperty prop; memset(&prop, 0, sizeof(prop)); char* ptitle = strtitle; - if( XStringListToTextProperty(&ptitle, 1, &prop) ) + + if (XStringListToTextProperty(&ptitle, 1, &prop)) XSetWMName(glDisplay, glWindow, &prop); + XFree(prop.value); } void GLWindow::ResizeCheck() { - XEvent event; + XEvent event; - while(XCheckTypedEvent(glDisplay, ConfigureNotify, &event)) - { - if ((event.xconfigure.width != width) || (event.xconfigure.height != height)) - { - ZeroGS::ChangeWindowSize(event.xconfigure.width, event.xconfigure.height); - width = event.xconfigure.width; - height = event.xconfigure.height; - } - if ((event.xconfigure.x != x) || (event.xconfigure.y != y)) - { - x = event.xconfigure.x; - y = event.xconfigure.y; - } - } + while (XCheckTypedEvent(glDisplay, ConfigureNotify, &event)) + { + if ((event.xconfigure.width != width) || (event.xconfigure.height != height)) + { + ZeroGS::ChangeWindowSize(event.xconfigure.width, event.xconfigure.height); + width = event.xconfigure.width; + height = event.xconfigure.height; + } + + if ((event.xconfigure.x != x) || (event.xconfigure.y != y)) + { + x = event.xconfigure.x; + y = event.xconfigure.y; + } + } } #endif diff --git a/plugins/zzogl-pg/opengl/GSmain.cpp b/plugins/zzogl-pg/opengl/GSmain.cpp index 972e46f3ea..f45e62ab38 100644 --- a/plugins/zzogl-pg/opengl/GSmain.cpp +++ b/plugins/zzogl-pg/opengl/GSmain.cpp @@ -31,6 +31,7 @@ #include #include #include + using namespace std; #include "GS.h" @@ -98,16 +99,19 @@ BOOL g_bWriteProfile = 0; #endif int s_frameskipping = 0; -u32 CALLBACK PS2EgetLibType() { +u32 CALLBACK PS2EgetLibType() +{ return PS2E_LT_GS; } -char* CALLBACK PS2EgetLibName() { +char* CALLBACK PS2EgetLibName() +{ return libraryName; } -u32 CALLBACK PS2EgetLibVersion2(u32 type) { - return (zgsversion<<16) | (zgsrevision<<8) | zgsbuild | (zgsminor << 24); +u32 CALLBACK PS2EgetLibVersion2(u32 type) +{ + return (zgsversion << 16) | (zgsrevision << 8) | zgsbuild | (zgsminor << 24); } static u64 luPerfFreq; @@ -123,196 +127,220 @@ bool THR_bShift = false; namespace ZZLog { - bool IsLogging() - { - // gsLog can be null if the config dialog is used prior to Pcsx2 starting an emulation session. - // (GSinit won't have been called then) - return (gsLog != NULL && conf.log); - } - - void WriteToScreen(const char* pstr, u32 ms) - { - ZeroGS::AddMessage(pstr, ms); - } +bool IsLogging() +{ + // gsLog can be null if the config dialog is used prior to Pcsx2 starting an emulation session. + // (GSinit won't have been called then) + return (gsLog != NULL && conf.log); +} - void _Message(const char *str) - { - SysMessage(str); - } +void WriteToScreen(const char* pstr, u32 ms) +{ + ZeroGS::AddMessage(pstr, ms); +} - void _Log(const char *str) - { - if (IsLogging()) fprintf(gsLog, str); - } +void _Message(const char *str) +{ + SysMessage(str); +} - void _WriteToConsole(const char *str) - { - printf("ZZogl-PG: %s", str); - } +void _Log(const char *str) +{ + if (IsLogging()) fprintf(gsLog, str); +} - void _Print(const char *str) - { - printf("ZZogl-PG: %s", str); - if (IsLogging()) fprintf(gsLog, str); - } - - void Message(const char *fmt, ...) - { - va_list list; - char tmp[512]; +void _WriteToConsole(const char *str) +{ + printf("ZZogl-PG: %s", str); +} - va_start(list, fmt); - vsprintf(tmp, fmt, list); - va_end(list); - - SysMessage(tmp); - } +void _Print(const char *str) +{ + printf("ZZogl-PG: %s", str); - void Log(const char *fmt, ...) - { - va_list list; + if (IsLogging()) fprintf(gsLog, str); +} - va_start(list, fmt); - if (IsLogging()) vfprintf(gsLog, fmt, list); - va_end(list); - } +void Message(const char *fmt, ...) +{ + va_list list; + char tmp[512]; - void WriteToConsole(const char *fmt, ...) - { - va_list list; + va_start(list, fmt); + vsprintf(tmp, fmt, list); + va_end(list); - va_start(list, fmt); + SysMessage(tmp); +} - printf("ZZogl-PG: "); - vprintf(fmt, list); - va_end(list); - } +void Log(const char *fmt, ...) +{ + va_list list; - void Print(const char *fmt, ...) - { - va_list list; + va_start(list, fmt); - va_start(list, fmt); - if (IsLogging()) vfprintf(gsLog, fmt, list); - printf("ZZogl-PG: "); - vprintf(fmt, list); - va_end(list); - } + if (IsLogging()) vfprintf(gsLog, fmt, list); - void Greg_Log(const char *fmt, ...) - { - // Not currently used + va_end(list); +} + +void WriteToConsole(const char *fmt, ...) +{ + va_list list; + + va_start(list, fmt); + + printf("ZZogl-PG: "); + vprintf(fmt, list); + va_end(list); +} + +void Print(const char *fmt, ...) +{ + va_list list; + + va_start(list, fmt); + + if (IsLogging()) vfprintf(gsLog, fmt, list); + + printf("ZZogl-PG: "); + + vprintf(fmt, list); + + va_end(list); +} + +void Greg_Log(const char *fmt, ...) +{ + // Not currently used #if 0 - va_list list; - char tmp[512]; + va_list list; + char tmp[512]; + + va_start(list, fmt); + + if (IsLogging()) vfprintf(gsLog, fmt, list); + + va_end(list); - va_start(list, fmt); - if (IsLogging()) vfprintf(gsLog, fmt, list); - va_end(list); #endif - } - - void Prim_Log(const char *fmt, ...) - { +} + +void Prim_Log(const char *fmt, ...) +{ #if defined(ZEROGS_DEVBUILD) && defined(WRITE_PRIM_LOGS) - va_list list; - char tmp[512]; + va_list list; + char tmp[512]; - va_start(list, fmt); - - if (conf.log /*& 0x00000010*/) - { - if (IsLogging()) vfprintf(gsLog, fmt, list); - - printf("ZZogl-PG(PRIM): "); - vprintf(fmt, list); - } - va_end(list); - -#endif - } - - void GS_Log(const char *fmt, ...) + va_start(list, fmt); + + if (conf.log /*& 0x00000010*/) { -#ifdef ZEROGS_DEVBUILD - va_list list; + if (IsLogging()) vfprintf(gsLog, fmt, list); - va_start(list,fmt); - - if (IsLogging()) - { - vfprintf(gsLog, fmt, list); - fprintf(gsLog,"\n"); - } - printf("ZZogl-PG(GS): "); - vprintf(fmt,list); - printf("\n"); - va_end(list); -#endif - } - - void Warn_Log(const char *fmt, ...) - { -#ifdef ZEROGS_DEVBUILD - va_list list; + printf("ZZogl-PG(PRIM): "); - va_start(list,fmt); - if (IsLogging()) - { - vfprintf(gsLog, fmt, list); - fprintf(gsLog,"\n"); - } - printf("ZZogl-PG(Warning): "); vprintf(fmt, list); - va_end(list); - printf("\n"); -#endif } - - void Debug_Log(const char *fmt, ...) + + va_end(list); + +#endif +} + +void GS_Log(const char *fmt, ...) +{ +#ifdef ZEROGS_DEVBUILD + va_list list; + + va_start(list, fmt); + + if (IsLogging()) { + vfprintf(gsLog, fmt, list); + fprintf(gsLog, "\n"); + } + + printf("ZZogl-PG(GS): "); + + vprintf(fmt, list); + printf("\n"); + va_end(list); +#endif +} + +void Warn_Log(const char *fmt, ...) +{ +#ifdef ZEROGS_DEVBUILD + va_list list; + + va_start(list, fmt); + + if (IsLogging()) + { + vfprintf(gsLog, fmt, list); + fprintf(gsLog, "\n"); + } + + printf("ZZogl-PG(Warning): "); + + vprintf(fmt, list); + va_end(list); + printf("\n"); +#endif +} + +void Debug_Log(const char *fmt, ...) +{ #if _DEBUG - va_list list; + va_list list; - va_start(list,fmt); - if (IsLogging()) - { - vfprintf(gsLog, fmt, list); - fprintf(gsLog,"\n"); - } - printf("ZZogl-PG(Debug): "); - vprintf(fmt, list); - printf("\n"); - va_end(list); - - -#endif - } - - void Error_Log(const char *fmt, ...) + va_start(list, fmt); + + if (IsLogging()) { - va_list list; - - va_start(list,fmt); - - if (IsLogging()) - { - vfprintf(gsLog, fmt, list); - fprintf(gsLog,"\n"); - } - printf("ZZogl-PG(Error): "); - vprintf(fmt,list); - printf("\n"); - va_end(list); + vfprintf(gsLog, fmt, list); + fprintf(gsLog, "\n"); } + + printf("ZZogl-PG(Debug): "); + + vprintf(fmt, list); + printf("\n"); + va_end(list); + + +#endif +} + +void Error_Log(const char *fmt, ...) +{ + va_list list; + + va_start(list, fmt); + + if (IsLogging()) + { + vfprintf(gsLog, fmt, list); + fprintf(gsLog, "\n"); + } + + printf("ZZogl-PG(Error): "); + + vprintf(fmt, list); + printf("\n"); + va_end(list); +} }; -void CALLBACK GSsetBaseMem(void* pmem) { +void CALLBACK GSsetBaseMem(void* pmem) +{ g_pBasePS2Mem = (u8*)pmem; } -void CALLBACK GSsetSettingsDir(const char* dir) { - s_strIniPath = (dir==NULL) ? "inis/" : dir; +void CALLBACK GSsetSettingsDir(const char* dir) +{ + s_strIniPath = (dir == NULL) ? "inis/" : dir; } extern int VALIDATE_THRESH; @@ -334,36 +362,44 @@ void CALLBACK GSsetGameCRC(int crc, int options) g_GameSettings |= GAME_PATH3HACK; bool CRCValueChanged = (g_LastCRC != crc); + g_LastCRC = crc; - + ZZLog::Error_Log("CRC = %x", crc); - if (CRCValueChanged && (crc != 0)) + + if (CRCValueChanged && (crc != 0)) { for (int i = 0; i < GAME_INFO_INDEX; i++) { if (crc_game_list[i].crc == crc) { if (crc_game_list[i].v_thresh > 0) VALIDATE_THRESH = crc_game_list[i].v_thresh; + if (crc_game_list[i].t_thresh > 0) TEXDESTROY_THRESH = crc_game_list[i].t_thresh; - + conf.gamesettings |= crc_game_list[i].flags; + g_GameSettings = conf.gamesettings | options; + ZZLog::Error_Log("Found CRC[%x] in crc game list.", crc); + return; } } } - g_GameSettings = conf.gamesettings|options; + g_GameSettings = conf.gamesettings | options; } void CALLBACK GSsetFrameSkip(int frameskip) { FUNCLOG s_frameskipping |= frameskip; - if( frameskip && g_nFrameRender > 1 ) { - for(int i = 0; i < 16; ++i) { + if (frameskip && g_nFrameRender > 1) + { + for (int i = 0; i < 16; ++i) + { g_GIFPackedRegHandlers[i] = GIFPackedRegHandlerNOP; } @@ -371,7 +407,7 @@ void CALLBACK GSsetFrameSkip(int frameskip) g_GIFPackedRegHandlers[6] = GIFRegHandlerTEX0_1; g_GIFPackedRegHandlers[7] = GIFRegHandlerTEX0_2; g_GIFPackedRegHandlers[14] = GIFPackedRegHandlerA_D; - + g_GIFRegHandlers[0] = GIFRegHandlerNOP; g_GIFRegHandlers[1] = GIFRegHandlerNOP; g_GIFRegHandlers[2] = GIFRegHandlerNOP; @@ -382,12 +418,14 @@ void CALLBACK GSsetFrameSkip(int frameskip) g_GIFRegHandlers[13] = GIFRegHandlerNOP; g_GIFRegHandlers[26] = GIFRegHandlerNOP; g_GIFRegHandlers[27] = GIFRegHandlerNOP; + g_nFrameRender = 0; } - else if( !frameskip && g_nFrameRender <= 0 ) { + else if (!frameskip && g_nFrameRender <= 0) + { g_nFrameRender = 1; - if( g_GIFTempRegHandlers[0] == NULL ) return; // not init yet + if (g_GIFTempRegHandlers[0] == NULL) return; // not init yet // restore memcpy(g_GIFPackedRegHandlers, g_GIFTempRegHandlers, sizeof(g_GIFTempRegHandlers)); @@ -405,7 +443,8 @@ void CALLBACK GSsetFrameSkip(int frameskip) } } -void CALLBACK GSreset() { +void CALLBACK GSreset() +{ FUNCLOG memset(&gs, 0, sizeof(gs)); @@ -423,9 +462,10 @@ void CALLBACK GSgifSoftReset(u32 mask) { FUNCLOG - if( mask & 1 ) memset(&gs.path[0], 0, sizeof(gs.path[0])); - if( mask & 2 ) memset(&gs.path[1], 0, sizeof(gs.path[1])); - if( mask & 4 ) memset(&gs.path[2], 0, sizeof(gs.path[2])); + if (mask & 1) memset(&gs.path[0], 0, sizeof(gs.path[0])); + if (mask & 2) memset(&gs.path[1], 0, sizeof(gs.path[1])); + if (mask & 4) memset(&gs.path[2], 0, sizeof(gs.path[2])); + gs.imageTransfer = -1; gs.q = 1; gs.nTriFanVert = -1; @@ -438,17 +478,20 @@ s32 CALLBACK GSinit() memcpy(g_GIFTempRegHandlers, g_GIFPackedRegHandlers, sizeof(g_GIFTempRegHandlers)); gsLog = fopen("logs/gsLog.txt", "w"); - if (gsLog == NULL) + + if (gsLog == NULL) { gsLog = fopen("gsLog.txt", "w"); - if (gsLog == NULL) + + if (gsLog == NULL) { - SysMessage("Can't create gsLog.txt"); + SysMessage("Can't create gsLog.txt"); return -1; } } - + setvbuf(gsLog, NULL, _IONBF, 0); + ZZLog::GS_Log("Calling GSinit."); GSreset(); @@ -469,24 +512,34 @@ void OnKeyboardF5(int shift) FUNCLOG char strtitle[256]; - if( shift ) { - if( g_nPixelShaderVer == SHADER_REDUCED ) { + + if (shift) + { + if (g_nPixelShaderVer == SHADER_REDUCED) + { conf.bilinear = 0; sprintf(strtitle, "reduced shaders don't support bilinear filtering"); } - else { - conf.bilinear = (conf.bilinear+1)%3; + else + { + conf.bilinear = (conf.bilinear + 1) % 3; sprintf(strtitle, "bilinear filtering - %s", pbilinear[conf.bilinear]); } } - else { + else + { conf.interlace++; - if( conf.interlace > 2 ) conf.interlace = 0; - if( conf.interlace < 2 ) sprintf(strtitle, "interlace on - mode %d", conf.interlace); - else sprintf(strtitle, "interlace off"); + + if (conf.interlace > 2) conf.interlace = 0; + + if (conf.interlace < 2) + sprintf(strtitle, "interlace on - mode %d", conf.interlace); + else + sprintf(strtitle, "interlace off"); } ZeroGS::AddMessage(strtitle); + SaveConfig(); } @@ -495,20 +548,24 @@ void OnKeyboardF6(int shift) FUNCLOG char strtitle[256]; - if( shift ) { + + if (shift) + { conf.aa--; // -1 - if( conf.aa > 4 ) conf.aa = 4; // u8 in unsigned, so negative value is 255. + if (conf.aa > 4) conf.aa = 4; // u8 in unsigned, so negative value is 255. sprintf(strtitle, "anti-aliasing - %s", s_aa[conf.aa]); ZeroGS::SetAA(conf.aa); } - else { + else + { conf.aa++; - if( conf.aa > 4 ) conf.aa = 0; + if (conf.aa > 4) conf.aa = 0; sprintf(strtitle, "anti-aliasing - %s", s_aa[conf.aa]); ZeroGS::SetAA(conf.aa); } ZeroGS::AddMessage(strtitle); + SaveConfig(); } @@ -517,30 +574,37 @@ void OnKeyboardF7(int shift) FUNCLOG char strtitle[256]; - if( !shift ) { + + if (!shift) + { extern BOOL g_bDisplayFPS; g_bDisplayFPS ^= 1; } - else { + else + { conf.options ^= GSOPTION_WIREFRAME; - glPolygonMode(GL_FRONT_AND_BACK, (conf.options&GSOPTION_WIREFRAME)?GL_LINE:GL_FILL); - sprintf(strtitle, "wireframe rendering - %s", (conf.options&GSOPTION_WIREFRAME)?"on":"off"); + glPolygonMode(GL_FRONT_AND_BACK, (conf.options&GSOPTION_WIREFRAME) ? GL_LINE : GL_FILL); + sprintf(strtitle, "wireframe rendering - %s", (conf.options&GSOPTION_WIREFRAME) ? "on" : "off"); } } -void OnKeyboardF61(int shift) { +void OnKeyboardF61(int shift) +{ FUNCLOG char strtitle[256]; - if( shift ) { + + if (shift) + { conf.negaa--; // -1 - if( conf.negaa > 2 ) conf.negaa = 2; // u8 in unsigned, so negative value is 255. + if (conf.negaa > 2) conf.negaa = 2; // u8 in unsigned, so negative value is 255. sprintf(strtitle, "down resolution - %s", s_naa[conf.negaa]); ZeroGS::SetNegAA(conf.negaa); } - else { + else + { conf.negaa++; - if( conf.negaa > 2 ) conf.negaa = 0; + if (conf.negaa > 2) conf.negaa = 0; sprintf(strtitle, "down resolution - %s", s_naa[conf.negaa]); ZeroGS::SetNegAA(conf.negaa); } @@ -549,13 +613,16 @@ void OnKeyboardF61(int shift) { SaveConfig(); } -typedef struct GameHackStruct { +typedef struct GameHackStruct +{ const char HackName[40]; u32 HackMask; } GameHack; + #define HACK_NUMBER 30 -GameHack HackinshTable[HACK_NUMBER] = { +GameHack HackinshTable[HACK_NUMBER] = +{ {"*** 0 No Hack", 0}, {"*** 1 TexTargets Check", GAME_TEXTURETARGS}, {"*** 2 Autoreset Targets", GAME_AUTORESET}, @@ -573,7 +640,7 @@ GameHack HackinshTable[HACK_NUMBER] = { {"***14 No Stencil", GAME_NOSTENCIL}, {"***15 No Depth resolve", GAME_NODEPTHRESOLVE}, {"***16 Full 16 bit", GAME_FULL16BITRES}, - {"***17 Resolve promoted", GAME_RESOLVEPROMOTED}, + {"***17 Resolve promoted", GAME_RESOLVEPROMOTED}, {"***18 Fast Update", GAME_FASTUPDATE}, {"***19 No Alpha Test", GAME_NOALPHATEST}, {"***20 Disable MRT deprh", GAME_DISABLEMRTDEPTH}, @@ -591,28 +658,35 @@ GameHack HackinshTable[HACK_NUMBER] = { int CurrentHackSetting = 0; -void OnKeyboardF9(int shift) { +void OnKeyboardF9(int shift) +{ FUNCLOG // printf ("A %d\n", HackinshTable[CurrentHackSetting].HackMask); conf.gamesettings &= !(HackinshTable[CurrentHackSetting].HackMask); - if( shift ) { + + if (shift) + { CurrentHackSetting--; - if (CurrentHackSetting == -1) - CurrentHackSetting = HACK_NUMBER-1; + + if (CurrentHackSetting == -1) CurrentHackSetting = HACK_NUMBER - 1; } - else { + else + { CurrentHackSetting++; - if (CurrentHackSetting == HACK_NUMBER) - CurrentHackSetting = 0; + + if (CurrentHackSetting == HACK_NUMBER) CurrentHackSetting = 0; } + conf.gamesettings |= HackinshTable[CurrentHackSetting].HackMask; + g_GameSettings = conf.gamesettings; ZeroGS::AddMessage(HackinshTable[CurrentHackSetting].HackName); SaveConfig(); } -void OnKeyboardF1(int shift) { +void OnKeyboardF1(int shift) +{ FUNCLOG char strtitle[256]; sprintf(strtitle, "Saving in savestate %d", CurrentSavestate); @@ -627,7 +701,7 @@ HANDLE g_hCurrentThread = NULL; #endif -extern LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam ); +extern LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam); extern HINSTANCE hInst; #endif @@ -635,7 +709,7 @@ extern HINSTANCE hInst; s32 CALLBACK GSopen(void *pDsp, char *Title, int multithread) { FUNCLOG - + bool err; g_GSMultiThreaded = multithread; @@ -647,27 +721,25 @@ s32 CALLBACK GSopen(void *pDsp, char *Title, int multithread) g_hCurrentThread = GetCurrentThread(); #endif #endif - + LoadConfig(); - strcpy(GStitle, Title); - + err = GLWin.CreateWindow(pDsp); - if (!err) { ZZLog::GS_Log("Failed to create window. Exiting..."); return -1; } - + ZZLog::Error_Log("Using %s:%d.%d.%d.", libraryName, zgsrevision, zgsbuild, zgsminor); ZZLog::Error_Log("Creating ZZOgl window."); - + if (!ZeroGS::Create(conf.width, conf.height)) return -1; ZZLog::Error_Log("Initialization successful."); - switch(conf.bilinear) + switch (conf.bilinear) { case 2: ZeroGS::AddMessage("bilinear filtering - forced", 1000); @@ -680,17 +752,18 @@ s32 CALLBACK GSopen(void *pDsp, char *Title, int multithread) default: break; } - + if (conf.aa) { char strtitle[64]; sprintf(strtitle, "anti-aliasing - %s", s_aa[conf.aa]); - ZeroGS::AddMessage(strtitle,1000); + ZeroGS::AddMessage(strtitle, 1000); } luPerfFreq = GetCPUTicks(); + gs.path[0].mode = gs.path[1].mode = gs.path[2].mode = 0; - + ZZLog::GS_Log("GSopen finished."); return 0; @@ -700,35 +773,42 @@ s32 CALLBACK GSopen(void *pDsp, char *Title, int multithread) void ProcessMessages() { MSG msg; - - ZeroMemory( &msg, sizeof(msg) ); - - while( 1 ) + + ZeroMemory(&msg, sizeof(msg)); + + while (1) { - if (PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE)) + if (PeekMessage(&msg, NULL, 0U, 0U, PM_REMOVE)) { - switch( msg.message ) + switch (msg.message) { + case WM_KEYDOWN : int my_KeyEvent = msg.wParam; bool my_bShift = !!(GetKeyState(VK_SHIFT) & 0x8000); - + switch (msg.wParam) { + case VK_F5: OnKeyboardF5(my_bShift); break; + case VK_F6: OnKeyboardF6(my_bShift); break; + case VK_F7: OnKeyboardF7(my_bShift); break; + case VK_F9: OnKeyboardF9(my_bShift); break; + case VK_ESCAPE: - if (conf.options & GSOPTION_FULLSCREEN) + + if (conf.options & GSOPTION_FULLSCREEN) { // destroy that msg conf.options &= ~GSOPTION_FULLSCREEN; @@ -736,19 +816,21 @@ void ProcessMessages() UpdateWindow(GShwnd); continue; // so that msg doesn't get sent } - else + else { SendMessage(GShwnd, WM_DESTROY, 0, 0); //g_bHidden = 1; return; } + break; } + break; } - TranslateMessage( &msg ); - DispatchMessage( &msg ); + TranslateMessage(&msg); + DispatchMessage(&msg); } else { @@ -775,20 +857,26 @@ void ProcessMessages() // check resizing GLWin.ResizeCheck(); - if ( THR_KeyEvent ) { // This values was passed from GSKeyEvents which could be in another thread + if (THR_KeyEvent) // This values was passed from GSKeyEvents which could be in another thread + { int my_KeyEvent = THR_KeyEvent; bool my_bShift = THR_bShift; THR_KeyEvent = 0; - switch ( my_KeyEvent ) { - case XK_F5: - OnKeyboardF5(my_bShift); + + switch (my_KeyEvent) + { + case XK_F5: + OnKeyboardF5(my_bShift); break; + case XK_F6: OnKeyboardF6(my_bShift); break; + case XK_F7: OnKeyboardF7(my_bShift); break; + case XK_F9: OnKeyboardF9(my_bShift); break; @@ -798,7 +886,8 @@ void ProcessMessages() #endif // linux -void CALLBACK GSclose() { +void CALLBACK GSclose() +{ FUNCLOG ZeroGS::Destroy(1); @@ -809,7 +898,8 @@ void CALLBACK GSclose() { SaveStateExists = true; // default value } -void CALLBACK GSirqCallback(void (*callback)()) { +void CALLBACK GSirqCallback(void (*callback)()) +{ FUNCLOG GSirq = callback; @@ -844,18 +934,23 @@ void CALLBACK GSmakeSnapshot(char *path) u32 snapshotnr = 0; // increment snapshot value & try to get filename - for (;;) { + + for (;;) + { snapshotnr++; - sprintf(filename,"%ssnap%03ld.%s", path, snapshotnr, (conf.options&GSOPTION_TGASNAP)?"bmp":"jpg"); + sprintf(filename, "%ssnap%03ld.%s", path, snapshotnr, (conf.options&GSOPTION_TGASNAP) ? "bmp" : "jpg"); + + bmpfile = fopen(filename, "rb"); - bmpfile=fopen(filename,"rb"); if (bmpfile == NULL) break; + fclose(bmpfile); } // try opening new snapshot file - if((bmpfile=fopen(filename,"wb"))==NULL) { + if ((bmpfile = fopen(filename, "wb")) == NULL) + { char strdir[255]; #ifdef _WIN32 @@ -866,7 +961,7 @@ void CALLBACK GSmakeSnapshot(char *path) system(strdir); #endif - if((bmpfile=fopen(filename,"wb"))==NULL) return; + if ((bmpfile = fopen(filename, "wb")) == NULL) return; } fclose(bmpfile); @@ -899,10 +994,11 @@ void CALLBACK GSvsync(int interlace) ProcessMessages(); - if( --nToNextUpdate <= 0 ) { + if (--nToNextUpdate <= 0) + { u32 d = timeGetTime(); - fFPS = UPDATE_FRAMES * 1000.0f / (float)max(d-dwTime,1); + fFPS = UPDATE_FRAMES * 1000.0f / (float)max(d - dwTime, 1); dwTime = d; g_nFrame += UPDATE_FRAMES; @@ -910,22 +1006,25 @@ void CALLBACK GSvsync(int interlace) const char* g_pShaders[4] = { "full", "reduced", "accurate", "accurate-reduced" }; const char* g_pInterlace[3] = { "interlace 0 |", "interlace 1 |", "" }; const char* g_pBilinear[3] = { "", "bilinear |", "forced bilinear |" }; + if (SaveStateFile != NULL && !SaveStateExists) SaveStateExists = (access(SaveStateFile, 0) == 0); else SaveStateExists = true; sprintf(strtitle, "ZZ Open GL 0.%d.%d | %.1f fps | %s%s%s savestate %d%s | shaders %s | (%.1f)", zgsbuild, zgsminor, fFPS, - g_pInterlace[conf.interlace], g_pBilinear[conf.bilinear], - (conf.aa >= conf.negaa) ? (conf.aa ? s_aa[conf.aa - conf.negaa] : "") : (conf.negaa ? s_naa[conf.negaa - conf.aa] : ""), - CurrentSavestate, (SaveStateExists ? "": "*" ), - g_pShaders[g_nPixelShaderVer], (ppf&0xfffff)/(float)UPDATE_FRAMES); + g_pInterlace[conf.interlace], g_pBilinear[conf.bilinear], + (conf.aa >= conf.negaa) ? (conf.aa ? s_aa[conf.aa - conf.negaa] : "") : (conf.negaa ? s_naa[conf.negaa - conf.aa] : ""), + CurrentSavestate, (SaveStateExists ? "" : "*"), + g_pShaders[g_nPixelShaderVer], (ppf&0xfffff) / (float)UPDATE_FRAMES); + #else sprintf(strtitle, "%d | %.1f fps (sk:%d%%) | g: %.1f, t: %.1f, a: %.1f, r: %.1f | p: %.1f | tex: %d %d (%d kbpf)", g_nFrame, fFPS, - 100*g_nFramesSkipped/g_nFrame, - g_nGenVars/(float)UPDATE_FRAMES, g_nTexVars/(float)UPDATE_FRAMES, g_nAlphaVars/(float)UPDATE_FRAMES, - g_nResolve/(float)UPDATE_FRAMES, (ppf&0xfffff)/(float)UPDATE_FRAMES, - ZeroGS::g_MemTargs.listTargets.size(), ZeroGS::g_MemTargs.listClearedTargets.size(), g_TransferredToGPU>>10); + 100*g_nFramesSkipped / g_nFrame, + g_nGenVars / (float)UPDATE_FRAMES, g_nTexVars / (float)UPDATE_FRAMES, g_nAlphaVars / (float)UPDATE_FRAMES, + g_nResolve / (float)UPDATE_FRAMES, (ppf&0xfffff) / (float)UPDATE_FRAMES, + ZeroGS::g_MemTargs.listTargets.size(), ZeroGS::g_MemTargs.listClearedTargets.size(), g_TransferredToGPU >> 10); + //_snprintf(strtitle, 512, "%x %x", *(int*)(g_pbyGSMemory + 256 * 0x3e0c + 4), *(int*)(g_pbyGSMemory + 256 * 0x3e04 + 4)); #endif @@ -936,8 +1035,8 @@ void CALLBACK GSvsync(int interlace) // } if (!(conf.options & GSOPTION_FULLSCREEN)) GLWin.SetTitle(strtitle); - if( fFPS < 16 ) UPDATE_FRAMES = 4; - else if( fFPS < 32 ) UPDATE_FRAMES = 8; + if (fFPS < 16) UPDATE_FRAMES = 4; + else if (fFPS < 32) UPDATE_FRAMES = 8; else UPDATE_FRAMES = 16; nToNextUpdate = UPDATE_FRAMES; @@ -947,16 +1046,20 @@ void CALLBACK GSvsync(int interlace) g_nTexVars = 0; g_nAlphaVars = 0; g_nResolve = 0; + ppf = 0; + g_nFramesSkipped = 0; } #if defined(ZEROGS_DEVBUILD) - if( g_bWriteProfile ) { + if (g_bWriteProfile) + { //g_bWriteProfile = 0; DVProfWrite("prof.txt", UPDATE_FRAMES); DVProfClear(); } + #endif GL_REPORT_ERRORD(); } @@ -983,18 +1086,24 @@ int CALLBACK GSsetupRecording(int start, void* pData) { FUNCLOG - if( start ) { - if( conf.options & GSOPTION_CAPTUREAVI ) - return 1; + if (start) + { + if (conf.options & GSOPTION_CAPTUREAVI) return 1; + ZeroGS::StartCapture(); + conf.options |= GSOPTION_CAPTUREAVI; + ZZLog::Warn_Log("Started recording zerogs.avi."); } - else { - if( !(conf.options & GSOPTION_CAPTUREAVI) ) - return 1; + else + { + if (!(conf.options & GSOPTION_CAPTUREAVI)) return 1; + conf.options &= ~GSOPTION_CAPTUREAVI; + ZeroGS::StopCapture(); + ZZLog::Warn_Log("Stopped recording."); } @@ -1011,12 +1120,15 @@ s32 CALLBACK GSfreeze(int mode, freezeData *data) if (!ZeroGS::Load(data->data)) ZZLog::Error_Log("GS: Bad load format!"); g_nRealFrame += 100; break; + case FREEZE_SAVE: ZeroGS::Save(data->data); break; + case FREEZE_SIZE: data->size = ZeroGS::Save(NULL); break; + default: break; } @@ -1030,6 +1142,7 @@ s32 CALLBACK GSfreeze(int mode, freezeData *data) #include #include #include + using namespace std; #define GET_PROFILE_TIME() GetCPUTicks() @@ -1038,26 +1151,31 @@ struct DVPROFSTRUCT; struct DVPROFSTRUCT { + struct DATA { DATA(u64 time, u32 user = 0) : dwTime(time), dwUserData(user) {} + DATA() : dwTime(0), dwUserData(0) {} u64 dwTime; u32 dwUserData; }; - ~DVPROFSTRUCT() { + ~DVPROFSTRUCT() + { list::iterator it = listpChild.begin(); - while(it != listpChild.end() ) { + + while (it != listpChild.end()) + { SAFE_DELETE(*it); ++it; } } list listTimes; // before DVProfEnd is called, contains the global time it started - // after DVProfEnd is called, contains the time it lasted - // the list contains all the tracked times + // after DVProfEnd is called, contains the time it lasted + // the list contains all the tracked times char pname[256]; list listpChild; // other profilers called during this profiler period @@ -1071,16 +1189,16 @@ struct DVPROFTRACK }; list g_listCurTracking; // the current profiling functions, the back element is the - // one that will first get popped off the list when DVProfEnd is called - // the pointer is an element in DVPROFSTRUCT::listTimes +// one that will first get popped off the list when DVProfEnd is called +// the pointer is an element in DVPROFSTRUCT::listTimes list g_listProfilers; // the current profilers, note that these are the parents - // any profiler started during the time of another is held in - // DVPROFSTRUCT::listpChild +// any profiler started during the time of another is held in +// DVPROFSTRUCT::listpChild list g_listAllProfilers; // ignores the hierarchy, pointer to elements in g_listProfilers void DVProfRegister(char* pname) { - if( !g_bWriteProfile ) + if (!g_bWriteProfile) return; list::iterator it = g_listAllProfilers.begin(); @@ -1102,12 +1220,14 @@ void DVProfRegister(char* pname) // else add in a new profiler to the appropriate parent profiler DVPROFSTRUCT* pprof = NULL; - if( g_listCurTracking.size() > 0 ) { - assert( g_listCurTracking.back().pprof != NULL ); + if (g_listCurTracking.size() > 0) + { + assert(g_listCurTracking.back().pprof != NULL); g_listCurTracking.back().pprof->listpChild.push_back(new DVPROFSTRUCT()); pprof = g_listCurTracking.back().pprof->listpChild.back(); } - else { + else + { g_listProfilers.push_back(DVPROFSTRUCT()); pprof = &g_listProfilers.back(); } @@ -1130,16 +1250,18 @@ void DVProfRegister(char* pname) void DVProfEnd(u32 dwUserData) { - if( !g_bWriteProfile ) + if (!g_bWriteProfile) return; - B_RETURN( g_listCurTracking.size() > 0 ); + + B_RETURN(g_listCurTracking.size() > 0); DVPROFTRACK dvtrack = g_listCurTracking.back(); - assert( dvtrack.pdwTime != NULL && dvtrack.pprof != NULL ); + assert(dvtrack.pdwTime != NULL && dvtrack.pprof != NULL); - dvtrack.pdwTime->dwTime = 1000000 * (GET_PROFILE_TIME()- dvtrack.pdwTime->dwTime) / luPerfFreq; - dvtrack.pdwTime->dwUserData= dwUserData; + dvtrack.pdwTime->dwTime = 1000000 * (GET_PROFILE_TIME() - dvtrack.pdwTime->dwTime) / luPerfFreq; + + dvtrack.pdwTime->dwUserData = dwUserData; g_listCurTracking.pop_back(); } @@ -1147,6 +1269,7 @@ void DVProfEnd(u32 dwUserData) struct DVTIMEINFO { DVTIMEINFO() : uInclusive(0), uExclusive(0) {} + u64 uInclusive, uExclusive; }; @@ -1160,13 +1283,15 @@ u64 DVProfWriteStruct(FILE* f, DVPROFSTRUCT* p, int ident) u32 utime = 0; - while(ittime != p->listTimes.end() ) { + while (ittime != p->listTimes.end()) + { utime += (u32)ittime->dwTime; - if( ittime->dwUserData ) + if (ittime->dwUserData) fprintf(f, "time: %d, user: 0x%8.8x", (u32)ittime->dwTime, ittime->dwUserData); else fprintf(f, "time: %d", (u32)ittime->dwTime); + ++ittime; } @@ -1177,25 +1302,29 @@ u64 DVProfWriteStruct(FILE* f, DVPROFSTRUCT* p, int ident) list::iterator itprof = p->listpChild.begin(); u32 uex = utime; - while(itprof != p->listpChild.end() ) { - uex -= DVProfWriteStruct(f, *itprof, ident+4); + while (itprof != p->listpChild.end()) + { + + uex -= DVProfWriteStruct(f, *itprof, ident + 4); ++itprof; } mapAggregateTimes[p->pname].uExclusive += uex; + return utime; } void DVProfWrite(char* pfilename, u32 frames) { - assert( pfilename != NULL ); + assert(pfilename != NULL); FILE* f = fopen(pfilename, "wb"); mapAggregateTimes.clear(); list::iterator it = g_listProfilers.begin(); - while(it != g_listProfilers.end() ) { + while (it != g_listProfilers.end()) + { DVProfWriteStruct(f, &(*it), 0); ++it; } @@ -1207,21 +1336,25 @@ void DVProfWrite(char* pfilename, u32 frames) u64 uTotal[2] = {0}; double fiTotalTime[2]; - for(it = mapAggregateTimes.begin(); it != mapAggregateTimes.end(); ++it) { + for (it = mapAggregateTimes.begin(); it != mapAggregateTimes.end(); ++it) + { uTotal[0] += it->second.uExclusive; uTotal[1] += it->second.uInclusive; } - fprintf(f, "total times (%d): ex: %Lu ", frames, uTotal[0]/frames); - fprintf(f, "inc: %Lu\n", uTotal[1]/frames); + fprintf(f, "total times (%d): ex: %Lu ", frames, uTotal[0] / frames); + + fprintf(f, "inc: %Lu\n", uTotal[1] / frames); fiTotalTime[0] = 1.0 / (double)uTotal[0]; fiTotalTime[1] = 1.0 / (double)uTotal[1]; // output the combined times - for(it = mapAggregateTimes.begin(); it != mapAggregateTimes.end(); ++it) { + + for (it = mapAggregateTimes.begin(); it != mapAggregateTimes.end(); ++it) + { fprintf(f, "%s - ex: %f inc: %f\n", it->first.c_str(), (double)it->second.uExclusive * fiTotalTime[0], - (double)it->second.uInclusive * fiTotalTime[1]); + (double)it->second.uInclusive * fiTotalTime[1]); } } diff --git a/plugins/zzogl-pg/opengl/GifTransfer.cpp b/plugins/zzogl-pg/opengl/GifTransfer.cpp index 7eaa4ec036..8a2c9ec5d9 100644 --- a/plugins/zzogl-pg/opengl/GifTransfer.cpp +++ b/plugins/zzogl-pg/opengl/GifTransfer.cpp @@ -74,18 +74,22 @@ extern HANDLE g_hCurrentThread; __forceinline void gifTransferLog(int index, u32 *pMem, u32 size) { #ifdef _DEBUG - if( conf.log /*& 0x20*/ ) + + if (conf.log /*& 0x20*/) { static int nSaveIndex = 0; ZZLog::GS_Log("%d: p:%d %x", nSaveIndex++, index + 1, size); int vals[4] = {0}; - for(u32 i = 0; i < size; i++) + + for (u32 i = 0; i < size; i++) { - for(u32 j = 0; j < 4; ++j ) + for (u32 j = 0; j < 4; ++j) vals[j] ^= pMem[4*i+j]; } + ZZLog::GS_Log("%x %x %x %x", vals[0], vals[1], vals[2], vals[3]); } + #endif } @@ -94,151 +98,157 @@ extern int g_GSMultiThreaded; template void _GSgifTransfer(u32 *pMem, u32 size) { - FUNCLOG + FUNCLOG - pathInfo *path = &gs.path[index]; + pathInfo *path = &gs.path[index]; #ifdef _WIN32 - assert( g_hCurrentThread == GetCurrentThread() ); + assert(g_hCurrentThread == GetCurrentThread()); #endif #ifdef _DEBUG - gifTransferLog(index, pMem, size); + gifTransferLog(index, pMem, size); #endif - while(size > 0) - { - //LOG(_T("Transfer(%08x, %d) START\n"), pMem, size); - if (path->nloop == 0) + while (size > 0) + { + //LOG(_T("Transfer(%08x, %d) START\n"), pMem, size); + if (path->nloop == 0) + { + path->setTag(pMem); + pMem += 4; + size--; + + if ((g_GameSettings & GAME_PATH3HACK) && (index == 2) && path->eop) nPath3Hack = 1; + + // eeuser 7.2.2. GIFtag: "... when NLOOP is 0, the GIF does not output anything, and + // values other than the EOP field are disregarded." + if (path->nloop > 0) { - path->setTag(pMem); - pMem += 4; - size--; + gs.q = 1.0f; - if ((g_GameSettings & GAME_PATH3HACK) && (index == 2) && path->eop) nPath3Hack = 1; - - // eeuser 7.2.2. GIFtag: "... when NLOOP is 0, the GIF does not output anything, and - // values other than the EOP field are disregarded." - if (path->nloop > 0) + if (path->tag.PRE && (path->tag.FLG == GIF_FLG_PACKED)) { - gs.q = 1.0f; - - if(path->tag.PRE && (path->tag.FLG == GIF_FLG_PACKED)) - { - u32 tagprim = path->tag.PRIM; - GIFRegHandlerPRIM((u32*)&tagprim); - } + u32 tagprim = path->tag.PRIM; + GIFRegHandlerPRIM((u32*)&tagprim); } } - else + } + else + { + switch (path->mode) { - switch(path->mode) + case GIF_FLG_PACKED: { - case GIF_FLG_PACKED: + // Needs to be looked at. + + // first try a shortcut for a very common case + + /*if(path.adonly && size >= path.nloop) { - // Needs to be looked at. - - // first try a shortcut for a very common case - - /*if(path.adonly && size >= path.nloop) - { - size -= path.nloop; - - do - { - GIFPackedRegHandlerA_D(pMem); - - mem += sizeof(GIFPackedReg); - } - while(--path.nloop > 0);*/ + size -= path.nloop; do { - g_GIFPackedRegHandlers[path->GetReg()](pMem); + GIFPackedRegHandlerA_D(pMem); - pMem += 4; - size--; + mem += sizeof(GIFPackedReg); } - while (path->StepReg() && (size > 0)); + while(--path.nloop > 0);*/ - break; - } - case GIF_FLG_REGLIST: + do { - // Needs to be looked at. - //ZZLog::GS_Log("%8.8x%8.8x %d L", ((u32*)&gs.regs)[1], *(u32*)&gs.regs, path->tag.nreg/4); + g_GIFPackedRegHandlers[path->GetReg()](pMem); - size *= 2; - - do - { - g_GIFRegHandlers[path->GetReg()](pMem); - - pMem += 2; - size--; - } - while(path->StepReg() && (size > 0)); - - if(size & 1) pMem += 2; - - size /= 2; - break; + pMem += 4; + size--; } + while (path->StepReg() && (size > 0)); - case GIF_FLG_IMAGE: // FROM_VFRAM - case GIF_FLG_IMAGE2: // Used in the DirectX version, so we'll use it here too. - { - int len = min(size, path->nloop); - //ZZLog::Error_Log("GIF_FLG_IMAGE(%d)=%d", gs.imageTransfer, len); - - switch(gs.imageTransfer) - { - case 0: - ZeroGS::TransferHostLocal(pMem, len * 4); - break; - case 1: - ZeroGS::TransferLocalHost(pMem, len); - break; - case 2: - //Move(); - //ZZLog::Error_Log("GIF_FLG_IMAGE MOVE"); - break; - case 3: - //assert(0); - break; - default: - //assert(0); - break; - } - - pMem += len * 4; - path->nloop -= len; - size -= len; - - break; - } - default: // GIF_IMAGE - ZZLog::GS_Log("*** WARNING **** Unexpected GIFTag flag."); - assert(0); - path->nloop = 0; - break; - } - } - - if (index == 0) - { - if(path->tag.EOP && path->nloop == 0) - { break; } + + case GIF_FLG_REGLIST: + { + // Needs to be looked at. + //ZZLog::GS_Log("%8.8x%8.8x %d L", ((u32*)&gs.regs)[1], *(u32*)&gs.regs, path->tag.nreg/4); + + size *= 2; + + do + { + g_GIFRegHandlers[path->GetReg()](pMem); + + pMem += 2; + size--; + } + while (path->StepReg() && (size > 0)); + + if (size & 1) pMem += 2; + size /= 2; + break; + } + + case GIF_FLG_IMAGE: // FROM_VFRAM + case GIF_FLG_IMAGE2: // Used in the DirectX version, so we'll use it here too. + { + int len = min(size, path->nloop); + //ZZLog::Error_Log("GIF_FLG_IMAGE(%d)=%d", gs.imageTransfer, len); + + switch (gs.imageTransfer) + { + case 0: + ZeroGS::TransferHostLocal(pMem, len * 4); + break; + + case 1: + ZeroGS::TransferLocalHost(pMem, len); + break; + + case 2: + //Move(); + //ZZLog::Error_Log("GIF_FLG_IMAGE MOVE"); + break; + + case 3: + //assert(0); + break; + + default: + //assert(0); + break; + } + + pMem += len * 4; + + path->nloop -= len; + size -= len; + + break; + } + + default: // GIF_IMAGE + ZZLog::GS_Log("*** WARNING **** Unexpected GIFTag flag."); + assert(0); + path->nloop = 0; + break; } - } + } + + if (index == 0) + { + if (path->tag.EOP && path->nloop == 0) + { + break; + } + } + } // This is the case when not all data was readed from one try: VU1 has too much data. // So we should redo reading from the start. if (index == 0) { - if(size == 0 && path->nloop > 0) + if (size == 0 && path->nloop > 0) { if (g_GSMultiThreaded) { @@ -263,7 +273,7 @@ void CALLBACK GSgifTransfer1(u32 *pMem, u32 addr) count++; #endif - _GSgifTransfer<0>((u32*)((u8*)pMem + addr), (0x4000 - addr)/16); + _GSgifTransfer<0>((u32*)((u8*)pMem + addr), (0x4000 - addr) / 16); } void CALLBACK GSgifTransfer2(u32 *pMem, u32 size) @@ -283,180 +293,194 @@ void CALLBACK GSgifTransfer3(u32 *pMem, u32 size) _GSgifTransfer<2>(pMem, size); } + #else template void _GSgifTransfer(u32 *pMem, u32 size) { - FUNCLOG + FUNCLOG - pathInfo *path = &gs.path[index]; + pathInfo *path = &gs.path[index]; #ifdef _WIN32 - assert( g_hCurrentThread == GetCurrentThread() ); + assert(g_hCurrentThread == GetCurrentThread()); #endif #ifdef _DEBUG - gifTransferLog(index, pMem, size); + gifTransferLog(index, pMem, size); #endif - while(size > 0) - { - //LOG(_T("Transfer(%08x, %d) START\n"), pMem, size); - if (path->nloop == 0) - { - path->setTag(pMem); - gs.q = 1; - pMem += 4; - size--; + while (size > 0) + { + //LOG(_T("Transfer(%08x, %d) START\n"), pMem, size); + if (path->nloop == 0) + { + path->setTag(pMem); + gs.q = 1; + pMem += 4; + size--; - if ((g_GameSettings & GAME_PATH3HACK) && (index == 2) && path->eop) nPath3Hack = 1; + if ((g_GameSettings & GAME_PATH3HACK) && (index == 2) && path->eop) nPath3Hack = 1; - if (index == 0) - { - if (path->mode == GIF_FLG_PACKED) - { - // check if 0xb is in any reg, if yes, exit (kh2) - for(int i = 0; i < path->nreg; i += 4) - { - if (((path->regs >> i) & 0xf) == 11) - { - ERROR_LOG_SPAM("Invalid unpack type\n"); - path->nloop = 0; - return; - } - } - } - } + if (index == 0) + { + if (path->mode == GIF_FLG_PACKED) + { + // check if 0xb is in any reg, if yes, exit (kh2) + for (int i = 0; i < path->nreg; i += 4) + { + if (((path->regs >> i) & 0xf) == 11) + { + ERROR_LOG_SPAM("Invalid unpack type\n"); + path->nloop = 0; + return; + } + } + } + } - if(path->nloop == 0 ) - { - if (index == 0) - { - // ffx hack - if( path->eop ) return; - continue; - } + if (path->nloop == 0) + { + if (index == 0) + { + // ffx hack + if (path->eop) return; - /*if( !path->eop ) - { - //ZZLog::Debug_Log("Continuing from eop."); - continue; - }*/ + continue; + } - // Issue 174 fix! - continue; - } - } + /*if( !path->eop ) + { + //ZZLog::Debug_Log("Continuing from eop."); + continue; + }*/ - switch(path->mode) - { - case GIF_FLG_PACKED: - { - assert( path->nloop > 0 ); - for(; size > 0; size--, pMem += 4) - { - int reg = (int)((path->regs >> path->regn) & 0xf); + // Issue 174 fix! + continue; + } + } - g_GIFPackedRegHandlers[reg](pMem); + switch (path->mode) + { - path->regn += 4; + case GIF_FLG_PACKED: + { + assert(path->nloop > 0); - if (path->nreg == path->regn) - { - path->regn = 0; + for (; size > 0; size--, pMem += 4) + { + int reg = (int)((path->regs >> path->regn) & 0xf); - if( path->nloop-- <= 1 ) - { - size--; - pMem += 4; - break; - } - } - } - break; - } - case GIF_FLG_REGLIST: - { - //GS_LOG("%8.8x%8.8x %d L", ((u32*)&gs.regs)[1], *(u32*)&gs.regs, path->tag.nreg/4); - assert( path->nloop > 0 ); - size *= 2; + g_GIFPackedRegHandlers[reg](pMem); - for(; size > 0; pMem+= 2, size--) - { - int reg = (int)((path->regs >> path->regn) & 0xf); + path->regn += 4; - g_GIFRegHandlers[reg](pMem); + if (path->nreg == path->regn) + { + path->regn = 0; - path->regn += 4; + if (path->nloop-- <= 1) + { + size--; + pMem += 4; + break; + } + } + } - if (path->nreg == path->regn) - { - path->regn = 0; - if( path->nloop-- <= 1 ) - { - size--; - pMem += 2; - break; - } - } - } + break; + } - if( size & 1 ) pMem += 2; - size /= 2; - break; - } - case GIF_FLG_IMAGE: // FROM_VFRAM - case GIF_FLG_IMAGE2: // Used in the DirectX version, so we'll use it here too. - { - if(gs.imageTransfer >= 0 && gs.imageTransfer <= 1) - { - int process = min((int)size, path->nloop); + case GIF_FLG_REGLIST: + { + //GS_LOG("%8.8x%8.8x %d L", ((u32*)&gs.regs)[1], *(u32*)&gs.regs, path->tag.nreg/4); + assert(path->nloop > 0); + size *= 2; - if( process > 0 ) - { - if ( gs.imageTransfer ) - ZeroGS::TransferLocalHost(pMem, process); - else - ZeroGS::TransferHostLocal(pMem, process*4); + for (; size > 0; pMem += 2, size--) + { + int reg = (int)((path->regs >> path->regn) & 0xf); - path->nloop -= process; - pMem += process*4; - size -= process; + g_GIFRegHandlers[reg](pMem); - assert( size == 0 || path->nloop == 0 ); - } - break; - } - else - { - // simulate - int process = min((int)size, path->nloop); + path->regn += 4; - path->nloop -= process; - pMem += process*4; - size -= process; - } + if (path->nreg == path->regn) + { + path->regn = 0; - break; - } - default: // GIF_IMAGE - ZZLog::GS_Log("*** WARNING **** Unexpected GIFTag flag."); - assert(0); - path->nloop = 0; - break; - } + if (path->nloop-- <= 1) + { + size--; + pMem += 2; + break; + } + } + } - if ((index == 0) && path->eop) return; - } + if (size & 1) pMem += 2; - // This is the case when not all data was readed from one try: VU1 has too much data. - // So we should redo reading from the start. - if ((index == 0) && size == 0 && path->nloop > 0) - { - ERROR_LOG_SPAMA("VU1 too much data, ignore if gfx are fine %d\n", path->nloop) - // TODO: this code is not working correctly. Anyway, ringing work only in single-threaded mode. - // _GSgifTransfer(&gs.path[0], (u32*)((u8*)pMem-0x4000), (0x4000)/16); - } + size /= 2; + + break; + } + + case GIF_FLG_IMAGE: // FROM_VFRAM + case GIF_FLG_IMAGE2: // Used in the DirectX version, so we'll use it here too. + { + if (gs.imageTransfer >= 0 && gs.imageTransfer <= 1) + { + int process = min((int)size, path->nloop); + + if (process > 0) + { + if (gs.imageTransfer) + ZeroGS::TransferLocalHost(pMem, process); + else + ZeroGS::TransferHostLocal(pMem, process*4); + + path->nloop -= process; + + pMem += process * 4; + + size -= process; + + assert(size == 0 || path->nloop == 0); + } + + break; + } + else + { + // simulate + int process = min((int)size, path->nloop); + + path->nloop -= process; + pMem += process * 4; + size -= process; + } + + break; + } + + default: // GIF_IMAGE + ZZLog::GS_Log("*** WARNING **** Unexpected GIFTag flag."); + assert(0); + path->nloop = 0; + break; + } + + if ((index == 0) && path->eop) return; + } + + // This is the case when not all data was readed from one try: VU1 has too much data. + // So we should redo reading from the start. + if ((index == 0) && size == 0 && path->nloop > 0) + { + ERROR_LOG_SPAMA("VU1 too much data, ignore if gfx are fine %d\n", path->nloop) + // TODO: this code is not working correctly. Anyway, ringing work only in single-threaded mode. + // _GSgifTransfer(&gs.path[0], (u32*)((u8*)pMem-0x4000), (0x4000)/16); + } } void CALLBACK GSgifTransfer1(u32 *pMem, u32 addr) @@ -476,11 +500,11 @@ void CALLBACK GSgifTransfer1(u32 *pMem, u32 addr) path->nloop = 0; path->eop = 0; - _GSgifTransfer<0>((u32*)((u8*)pMem + addr), (0x4000 - addr)/16); + _GSgifTransfer<0>((u32*)((u8*)pMem + addr), (0x4000 - addr) / 16); if (!path->eop && (path->nloop > 0)) { - assert( (addr&0xf) == 0 ); //BUG + assert((addr&0xf) == 0); //BUG path->nloop = 0; ZZLog::Error_Log("Transfer1 - 2."); return; @@ -505,4 +529,5 @@ void CALLBACK GSgifTransfer3(u32 *pMem, u32 size) nPath3Hack = 0; _GSgifTransfer<2>(pMem, size); } + #endif diff --git a/plugins/zzogl-pg/opengl/Linux/Conf.cpp b/plugins/zzogl-pg/opengl/Linux/Conf.cpp index 4b4b975cd2..94835ae69d 100644 --- a/plugins/zzogl-pg/opengl/Linux/Conf.cpp +++ b/plugins/zzogl-pg/opengl/Linux/Conf.cpp @@ -26,8 +26,8 @@ void SaveConfig() { - const std::string iniFile( s_strIniPath + "zzogl-pg.ini" ); - FILE* f = fopen(iniFile.c_str(),"w"); + const std::string iniFile(s_strIniPath + "zzogl-pg.ini"); + FILE* f = fopen(iniFile.c_str(), "w"); if (f == NULL) { @@ -36,6 +36,7 @@ void SaveConfig() } fprintf(f, "interlace = %hhx\n", conf.interlace); + fprintf(f, "mrtdepth = %hhx\n", conf.mrtdepth); fprintf(f, "options = %x\n", conf.options); //u32 fprintf(f, "bilinear = %hhx\n", conf.bilinear); @@ -64,15 +65,18 @@ void LoadConfig() conf.aa = 0; conf.log = 1; - const std::string iniFile( s_strIniPath + "zzogl-pg.ini" ); + const std::string iniFile(s_strIniPath + "zzogl-pg.ini"); FILE* f = fopen(iniFile.c_str(), "r"); + if (f == NULL) { printf("failed to open %s\n", iniFile.c_str()); SaveConfig();//save and return return; } + err = fscanf(f, "interlace = %hhx\n", &conf.interlace); + err = fscanf(f, "mrtdepth = %hhx\n", &conf.mrtdepth); err = fscanf(f, "options = %x\n", &conf.options);//u32 err = fscanf(f, "bilinear = %hhx\n", &conf.bilinear); @@ -86,23 +90,29 @@ void LoadConfig() fclose(f); // filter bad files + if ((conf.aa < 0) || (conf.aa > 4)) conf.aa = 0; conf.isWideScreen = conf.options & GSOPTION_WIDESCREEN; - switch(conf.options & GSOPTION_WINDIMS) + + switch (conf.options & GSOPTION_WINDIMS) { + case GSOPTION_WIN640: conf.width = 640; conf.height = conf.isWideScreen ? 360 : 480; break; + case GSOPTION_WIN800: conf.width = 800; conf.height = conf.isWideScreen ? 450 : 600; break; + case GSOPTION_WIN1024: conf.width = 1024; conf.height = conf.isWideScreen ? 576 : 768; break; + case GSOPTION_WIN1280: conf.width = 1280; conf.height = conf.isWideScreen ? 720 : 960; @@ -111,14 +121,16 @@ void LoadConfig() // turn off all hacks by default conf.options &= ~(GSOPTION_WIREFRAME | GSOPTION_CAPTUREAVI); + conf.options |= GSOPTION_LOADED; - if( conf.width <= 0 || conf.height <= 0 ) + if (conf.width <= 0 || conf.height <= 0) { conf.width = 640; conf.height = 480; } - if( conf.x <= 0 || conf.y <= 0 ) + + if (conf.x <= 0 || conf.y <= 0) { conf.x = 0; conf.y = 0; diff --git a/plugins/zzogl-pg/opengl/Linux/Linux.cpp b/plugins/zzogl-pg/opengl/Linux/Linux.cpp index 32a6bec8db..d55a5ad615 100644 --- a/plugins/zzogl-pg/opengl/Linux/Linux.cpp +++ b/plugins/zzogl-pg/opengl/Linux/Linux.cpp @@ -35,37 +35,44 @@ void CALLBACK GSkeyEvent(keyEvent *ev) //static bool bShift = false; static bool bAlt = false; - switch(ev->evt) { + switch (ev->evt) + { case KEYPRESS: - switch(ev->key) { + switch (ev->key) + { case XK_F5: case XK_F6: case XK_F7: case XK_F9: THR_KeyEvent = ev->key ; break; + case XK_Escape: - if (conf.options & GSOPTION_FULLSCREEN) - GSclose(); + if (conf.options & GSOPTION_FULLSCREEN) GSclose(); break; + case XK_Shift_L: case XK_Shift_R: //bShift = true; THR_bShift = true; break; + case XK_Alt_L: case XK_Alt_R: bAlt = true; break; - } + } break; + case KEYRELEASE: - switch(ev->key) { + switch (ev->key) + { case XK_Shift_L: case XK_Shift_R: //bShift = false; THR_bShift = false; break; + case XK_Alt_L: case XK_Alt_R: bAlt = false; @@ -91,7 +98,7 @@ void CreateGameHackTable(GtkWidget *treeview) GtkTreeViewColumn *treecol; //--------- Let's build a treeview for our advanced options! --------// - treestore = gtk_list_store_new(2,G_TYPE_BOOLEAN, G_TYPE_STRING); + treestore = gtk_list_store_new(2, G_TYPE_BOOLEAN, G_TYPE_STRING); //setup columns in treeview //COLUMN 0 is the checkboxes @@ -139,15 +146,16 @@ void CreateGameHackTable(GtkWidget *treeview) add_map_entry(GAME_NOLOGZ, "20000000", "No logarithmic Z, could decrease number of Z-artefacts - 20000000"); add_map_entry(GAME_INTERLACE2X, "00000004", "Interlace 2X - 00000004\nFixes 2x bigger screen (Gradius 3)."); - for(map::iterator it = mapConfOpts.begin(); it != mapConfOpts.end(); ++it) + for (map::iterator it = mapConfOpts.begin(); it != mapConfOpts.end(); ++it) { gtk_list_store_append(treestore, &treeiter);//new row - itval = (conf.gamesettings&it->second.value)?TRUE:FALSE; + itval = (conf.gamesettings & it->second.value) ? TRUE : FALSE; snprintf(descbuf, 254, "%s", it->second.desc); gtk_list_store_set(treestore, &treeiter, 0, itval, 1, descbuf, -1); } gtk_tree_view_set_model(GTK_TREE_VIEW(treeview), GTK_TREE_MODEL(treestore));//NB: store is cast as tree model. + g_object_unref(treestore);//allow model to be destroyed when the tree is destroyed. //don't select/highlight rows @@ -166,17 +174,19 @@ void SaveGameHackTable(GtkWidget *treeview) gtk_tree_model_get_iter_first(treemodel, &treeiter); conf.gamesettings = 0; - for(map::iterator it = mapConfOpts.begin(); it != mapConfOpts.end(); ++it) + + for (map::iterator it = mapConfOpts.begin(); it != mapConfOpts.end(); ++it) { treeoptval = FALSE; gtk_tree_model_get(treemodel, &treeiter, 0, &treeoptval, -1); - if(treeoptval) conf.gamesettings |= it->second.value; + if (treeoptval) conf.gamesettings |= it->second.value; - gtk_tree_model_iter_next(treemodel,&treeiter); + gtk_tree_model_iter_next(treemodel, &treeiter); } GSsetGameCRC(0, conf.gamesettings); + //---------- done getting advanced options ---------// } @@ -193,94 +203,105 @@ void OnToggle_advopts(GtkCellRendererToggle *cell, gchar *path, gpointer user_da void DisplayDialog() { - int return_value; + int return_value; - GtkWidget *dialog; - GtkWidget *main_frame, *main_box; + GtkWidget *dialog; + GtkWidget *main_frame, *main_box; - GtkWidget *option_frame, *option_box; - GtkWidget *log_check; - GtkWidget *int_label, *int_box; - GtkWidget *bilinear_check, *bilinear_label; - GtkWidget *aa_label, *aa_box; - GtkWidget *wireframe_check, *avi_check; - GtkWidget *snap_label, *snap_box; - GtkWidget *size_label, *size_box; - GtkWidget *fullscreen_check, *widescreen_check; + GtkWidget *option_frame, *option_box; + GtkWidget *log_check; + GtkWidget *int_label, *int_box; + GtkWidget *bilinear_check, *bilinear_label; + GtkWidget *aa_label, *aa_box; + GtkWidget *wireframe_check, *avi_check; + GtkWidget *snap_label, *snap_box; + GtkWidget *size_label, *size_box; + GtkWidget *fullscreen_check, *widescreen_check; - GtkWidget *advanced_frame, *advanced_box; - GtkWidget *advanced_scroll; - GtkWidget *tree; + GtkWidget *advanced_frame, *advanced_box; + GtkWidget *advanced_scroll; + GtkWidget *tree; if (!(conf.options & GSOPTION_LOADED)) LoadConfig(); - /* Create the widgets */ - dialog = gtk_dialog_new_with_buttons ( - "ZZOgl PG Config", - NULL, /* parent window*/ - (GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), - GTK_STOCK_CANCEL, - GTK_RESPONSE_REJECT, - GTK_STOCK_OK, - GTK_RESPONSE_ACCEPT, - NULL); + /* Create the widgets */ + dialog = gtk_dialog_new_with_buttons( + "ZZOgl PG Config", + NULL, /* parent window*/ + (GtkDialogFlags)(GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT), + GTK_STOCK_CANCEL, + GTK_RESPONSE_REJECT, + GTK_STOCK_OK, + GTK_RESPONSE_ACCEPT, + NULL); - log_check = gtk_check_button_new_with_label("Logging (For Debugging):"); - int_label = gtk_label_new ("Interlacing: (F5 to toggle)"); - int_box = gtk_combo_box_new_text (); - gtk_combo_box_append_text(GTK_COMBO_BOX(int_box), "No Interlacing"); - gtk_combo_box_append_text(GTK_COMBO_BOX(int_box), "Interlace 0"); - gtk_combo_box_append_text(GTK_COMBO_BOX(int_box), "Interlace 1"); - gtk_combo_box_set_active(GTK_COMBO_BOX(int_box), conf.interlace); + log_check = gtk_check_button_new_with_label("Logging (For Debugging):"); + + int_label = gtk_label_new("Interlacing: (F5 to toggle)"); + + int_box = gtk_combo_box_new_text(); + + gtk_combo_box_append_text(GTK_COMBO_BOX(int_box), "No Interlacing"); + gtk_combo_box_append_text(GTK_COMBO_BOX(int_box), "Interlace 0"); + gtk_combo_box_append_text(GTK_COMBO_BOX(int_box), "Interlace 1"); + gtk_combo_box_set_active(GTK_COMBO_BOX(int_box), conf.interlace); - bilinear_check = gtk_check_button_new_with_label("Bilinear Filtering (Shift + F5)"); - bilinear_label = gtk_label_new ("Best quality is off. Turn on for speed."); + bilinear_check = gtk_check_button_new_with_label("Bilinear Filtering (Shift + F5)"); + bilinear_label = gtk_label_new("Best quality is off. Turn on for speed."); - aa_label = gtk_label_new ("Anti-Aliasing for Higher Quality(F6)"); - aa_box = gtk_combo_box_new_text (); - gtk_combo_box_append_text(GTK_COMBO_BOX(aa_box), "1X - No Anti-Aliasing"); - gtk_combo_box_append_text(GTK_COMBO_BOX(aa_box), "2X - Anti-Aliasing x 2"); - gtk_combo_box_append_text(GTK_COMBO_BOX(aa_box), "4X - Anti-Aliasing x 4"); - gtk_combo_box_append_text(GTK_COMBO_BOX(aa_box), "8X - Anti-Aliasing x 8"); - gtk_combo_box_append_text(GTK_COMBO_BOX(aa_box), "16X - Anti-Aliasing x 16"); - gtk_combo_box_set_active(GTK_COMBO_BOX(aa_box), conf.aa); + aa_label = gtk_label_new("Anti-Aliasing for Higher Quality(F6)"); + aa_box = gtk_combo_box_new_text(); - wireframe_check = gtk_check_button_new_with_label("Wireframe Rendering(Shift + F6)"); - avi_check = gtk_check_button_new_with_label("Capture Avi (as zerogs.avi)(F7)"); + gtk_combo_box_append_text(GTK_COMBO_BOX(aa_box), "1X - No Anti-Aliasing"); + gtk_combo_box_append_text(GTK_COMBO_BOX(aa_box), "2X - Anti-Aliasing x 2"); + gtk_combo_box_append_text(GTK_COMBO_BOX(aa_box), "4X - Anti-Aliasing x 4"); + gtk_combo_box_append_text(GTK_COMBO_BOX(aa_box), "8X - Anti-Aliasing x 8"); + gtk_combo_box_append_text(GTK_COMBO_BOX(aa_box), "16X - Anti-Aliasing x 16"); + gtk_combo_box_set_active(GTK_COMBO_BOX(aa_box), conf.aa); - snap_label = gtk_label_new ("Snapshot format:"); - snap_box = gtk_combo_box_new_text (); - gtk_combo_box_append_text(GTK_COMBO_BOX(snap_box), "JPEG"); - gtk_combo_box_append_text(GTK_COMBO_BOX(snap_box), "TIFF"); - gtk_combo_box_set_active(GTK_COMBO_BOX(snap_box), conf.options&GSOPTION_TGASNAP); + wireframe_check = gtk_check_button_new_with_label("Wireframe Rendering(Shift + F6)"); + avi_check = gtk_check_button_new_with_label("Capture Avi (as zerogs.avi)(F7)"); - fullscreen_check = gtk_check_button_new_with_label("Fullscreen (Alt + Enter)"); + snap_label = gtk_label_new("Snapshot format:"); + snap_box = gtk_combo_box_new_text(); + gtk_combo_box_append_text(GTK_COMBO_BOX(snap_box), "JPEG"); + gtk_combo_box_append_text(GTK_COMBO_BOX(snap_box), "TIFF"); + gtk_combo_box_set_active(GTK_COMBO_BOX(snap_box), conf.options & GSOPTION_TGASNAP); + + fullscreen_check = gtk_check_button_new_with_label("Fullscreen (Alt + Enter)"); widescreen_check = gtk_check_button_new_with_label("Widescreen"); - size_label = gtk_label_new ("Default Window Size: (no speed impact)"); - size_box = gtk_combo_box_new_text (); - gtk_combo_box_append_text(GTK_COMBO_BOX(size_box), "640x480"); - gtk_combo_box_append_text(GTK_COMBO_BOX(size_box), "800x600"); - gtk_combo_box_append_text(GTK_COMBO_BOX(size_box), "1024x768"); - gtk_combo_box_append_text(GTK_COMBO_BOX(size_box), "1280x960"); - gtk_combo_box_set_active(GTK_COMBO_BOX(size_box), (conf.options&GSOPTION_WINDIMS)>>4); + size_label = gtk_label_new("Default Window Size: (no speed impact)"); - main_box = gtk_hbox_new(false, 5); - main_frame = gtk_frame_new ("ZZOgl PG Config"); - gtk_container_add (GTK_CONTAINER(main_frame), main_box); + size_box = gtk_combo_box_new_text(); - option_box = gtk_vbox_new(false, 5); - option_frame = gtk_frame_new (""); - gtk_container_add (GTK_CONTAINER(option_frame), option_box); + gtk_combo_box_append_text(GTK_COMBO_BOX(size_box), "640x480"); + gtk_combo_box_append_text(GTK_COMBO_BOX(size_box), "800x600"); + gtk_combo_box_append_text(GTK_COMBO_BOX(size_box), "1024x768"); + gtk_combo_box_append_text(GTK_COMBO_BOX(size_box), "1280x960"); - advanced_box = gtk_vbox_new(false, 5); - advanced_frame = gtk_frame_new ("Advanced Settings:"); - gtk_container_add (GTK_CONTAINER(advanced_frame), advanced_box); + gtk_combo_box_set_active(GTK_COMBO_BOX(size_box), (conf.options&GSOPTION_WINDIMS) >> 4); + + main_box = gtk_hbox_new(false, 5); + main_frame = gtk_frame_new("ZZOgl PG Config"); + + gtk_container_add(GTK_CONTAINER(main_frame), main_box); + + option_box = gtk_vbox_new(false, 5); + option_frame = gtk_frame_new(""); + gtk_container_add(GTK_CONTAINER(option_frame), option_box); + + advanced_box = gtk_vbox_new(false, 5); + advanced_frame = gtk_frame_new("Advanced Settings:"); + gtk_container_add(GTK_CONTAINER(advanced_frame), advanced_box); tree = gtk_tree_view_new(); + CreateGameHackTable(tree); + advanced_scroll = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(advanced_scroll), tree); gtk_box_pack_start(GTK_BOX(option_box), log_check, false, false, 2); @@ -298,68 +319,80 @@ void DisplayDialog() gtk_box_pack_start(GTK_BOX(option_box), widescreen_check, false, false, 2); gtk_box_pack_start(GTK_BOX(option_box), size_label, false, false, 2); gtk_box_pack_start(GTK_BOX(option_box), size_box, false, false, 2); - gtk_box_pack_start(GTK_BOX(advanced_box), advanced_scroll, true, true, 2); - gtk_box_pack_start(GTK_BOX(main_box), option_frame, false, false, 2); gtk_box_pack_start(GTK_BOX(main_box), advanced_frame, true, true, 2); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(log_check), conf.log); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bilinear_check), conf.bilinear); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(wireframe_check), (conf.options & GSOPTION_WIREFRAME)); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(avi_check), (conf.options & GSOPTION_CAPTUREAVI)); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fullscreen_check), (conf.options & GSOPTION_FULLSCREEN)); - gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widescreen_check), (conf.options & GSOPTION_WIDESCREEN)); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(log_check), conf.log); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(bilinear_check), conf.bilinear); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(wireframe_check), (conf.options & GSOPTION_WIREFRAME)); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(avi_check), (conf.options & GSOPTION_CAPTUREAVI)); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(fullscreen_check), (conf.options & GSOPTION_FULLSCREEN)); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widescreen_check), (conf.options & GSOPTION_WIDESCREEN)); - gtk_container_add (GTK_CONTAINER (GTK_DIALOG(dialog)->vbox), main_frame); - gtk_widget_show_all (dialog); + gtk_container_add(GTK_CONTAINER(GTK_DIALOG(dialog)->vbox), main_frame); - return_value = gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_show_all(dialog); - if (return_value == GTK_RESPONSE_ACCEPT) - { - int fake_options = 0; - SaveGameHackTable(tree); - - if (gtk_combo_box_get_active(GTK_COMBO_BOX(int_box)) != -1) + return_value = gtk_dialog_run(GTK_DIALOG(dialog)); + + if (return_value == GTK_RESPONSE_ACCEPT) + { + int fake_options = 0; + SaveGameHackTable(tree); + + if (gtk_combo_box_get_active(GTK_COMBO_BOX(int_box)) != -1) conf.interlace = gtk_combo_box_get_active(GTK_COMBO_BOX(int_box)); - if (gtk_combo_box_get_active(GTK_COMBO_BOX(aa_box)) != -1) + if (gtk_combo_box_get_active(GTK_COMBO_BOX(aa_box)) != -1) conf.aa = gtk_combo_box_get_active(GTK_COMBO_BOX(aa_box)); conf.negaa = 0; - switch(gtk_combo_box_get_active(GTK_COMBO_BOX(size_box))) + switch (gtk_combo_box_get_active(GTK_COMBO_BOX(size_box))) { - case 0: fake_options |= GSOPTION_WIN640; break; - case 1: fake_options |= GSOPTION_WIN800; break; - case 2: fake_options |= GSOPTION_WIN1024; break; - case 3: fake_options |= GSOPTION_WIN1280; break; + case 0: + fake_options |= GSOPTION_WIN640; + break; + + case 1: + fake_options |= GSOPTION_WIN800; + break; + + case 2: + fake_options |= GSOPTION_WIN1024; + break; + + case 3: + fake_options |= GSOPTION_WIN1280; + break; } conf.log = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(log_check)); + conf.bilinear = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(bilinear_check)); - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wireframe_check))) + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(wireframe_check))) fake_options |= GSOPTION_WIREFRAME; - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(avi_check))) + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(avi_check))) fake_options |= GSOPTION_CAPTUREAVI; - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fullscreen_check))) + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(fullscreen_check))) fake_options |= GSOPTION_FULLSCREEN; - if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widescreen_check))) + if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widescreen_check))) fake_options |= GSOPTION_WIDESCREEN; - if (gtk_combo_box_get_active(GTK_COMBO_BOX(snap_box)) == 1) + if (gtk_combo_box_get_active(GTK_COMBO_BOX(snap_box)) == 1) fake_options |= GSOPTION_TGASNAP; conf.options = fake_options; - SaveConfig(); - } - gtk_widget_destroy (dialog); + SaveConfig(); + } + + gtk_widget_destroy(dialog); } void CALLBACK GSconfigure() @@ -374,23 +407,26 @@ void CALLBACK GSconfigure() void SysMessage(const char *fmt, ...) { - va_list list; - char msg[512]; + va_list list; + char msg[512]; - va_start(list, fmt); - vsprintf(msg, fmt, list); - va_end(list); + va_start(list, fmt); + vsprintf(msg, fmt, list); + va_end(list); - if (msg[strlen(msg)-1] == '\n') msg[strlen(msg)-1] = 0; + if (msg[strlen(msg)-1] == '\n') msg[strlen(msg)-1] = 0; - GtkWidget *dialog; - dialog = gtk_message_dialog_new (NULL, - GTK_DIALOG_DESTROY_WITH_PARENT, - GTK_MESSAGE_INFO, - GTK_BUTTONS_OK, - "%s", msg); - gtk_dialog_run (GTK_DIALOG (dialog)); - gtk_widget_destroy (dialog); + GtkWidget *dialog; + + dialog = gtk_message_dialog_new(NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_INFO, + GTK_BUTTONS_OK, + "%s", msg); + + gtk_dialog_run(GTK_DIALOG(dialog)); + + gtk_widget_destroy(dialog); } void CALLBACK GSabout() @@ -411,7 +447,9 @@ void *SysLoadLibrary(char *lib) void *SysLoadSym(void *lib, char *sym) { void *ret = dlsym(lib, sym); + if (ret == NULL) printf("null: %s\n", sym); + return dlsym(lib, sym); } diff --git a/plugins/zzogl-pg/opengl/Mem.cpp b/plugins/zzogl-pg/opengl/Mem.cpp index c01d3ec0ea..174b7cf68d 100644 --- a/plugins/zzogl-pg/opengl/Mem.cpp +++ b/plugins/zzogl-pg/opengl/Mem.cpp @@ -57,8 +57,8 @@ static __forceinline const T* AlignOnBlockBoundry(TransferData data, TransferFun { /* hack */ int testwidth = (int)nSize - - (gs.imageEndY - gs.imageY) * (gs.imageEndX - gs.trxpos.dx) - + (gs.imageX - gs.trxpos.dx); + (gs.imageEndY - gs.imageY) * (gs.imageEndX - gs.trxpos.dx) + + (gs.imageX - gs.trxpos.dx); if ((testwidth <= data.widthlimit) && (testwidth >= -data.widthlimit)) { @@ -67,17 +67,19 @@ static __forceinline const T* AlignOnBlockBoundry(TransferData data, TransferFun //ZZLog::Error_Log("Bad texture: testwidth = %d; data.widthlimit = %d", testwidth, data.widthlimit); gs.imageTransfer = -1; } + bCanAlign = false; } + /* first align on block boundary */ - if ( MOD_POW2(gs.imageY, data.blockheight) || !bCanAlign ) + if (MOD_POW2(gs.imageY, data.blockheight) || !bCanAlign) { u32 transwidth; - if( !bCanAlign ) + if (!bCanAlign) endY = gs.imageEndY; /* transfer the whole image */ else - assert( endY < gs.imageEndY); /* part of alignment condition */ + assert(endY < gs.imageEndY); /* part of alignment condition */ if (((gs.imageEndX - gs.trxpos.dx) % data.widthlimit) || ((gs.imageEndX - gs.imageX) % data.widthlimit)) { @@ -90,10 +92,12 @@ static __forceinline const T* AlignOnBlockBoundry(TransferData data, TransferFun } pbuf = TransmitHostLocalY(data, fun.wp, transwidth, endY, pbuf); + if (pbuf == NULL) return NULL; - if( nSize == 0 || tempY == gs.imageEndY ) return NULL; + if (nSize == 0 || tempY == gs.imageEndY) return NULL; } + return pbuf; } @@ -112,43 +116,45 @@ static __forceinline const T* TransferAligningToBlocks(TransferData data, Transf /* on top of checking whether pbuf is aligned, make sure that the width is at least aligned to its limits (due to bugs in pcsx2) */ bAligned = !((uptr)pbuf & 0xf) && (TransPitch(pitch, data.transfersize) & 0xf) == 0; - if ( bAligned || ((DSTPSM==PSMCT24) || (DSTPSM==PSMT8H) || (DSTPSM==PSMT4HH) || (DSTPSM==PSMT4HL))) + if (bAligned || ((DSTPSM == PSMCT24) || (DSTPSM == PSMT8H) || (DSTPSM == PSMT4HH) || (DSTPSM == PSMT4HL))) swizzle = (fun.Swizzle); else swizzle = (fun.Swizzle_u); //Transfer aligning to blocks. - for(; tempY < alignedPt.y && nSize >= area; tempY += data.blockheight, nSize -= area) + for (; tempY < alignedPt.y && nSize >= area; tempY += data.blockheight, nSize -= area) { - for(int tempj = gs.trxpos.dx; tempj < alignedPt.x; tempj += data.blockwidth, pbuf += TransPitch(data.blockwidth, data.transfersize)/TSize) + for (int tempj = gs.trxpos.dx; tempj < alignedPt.x; tempj += data.blockwidth, pbuf += TransPitch(data.blockwidth, data.transfersize) / TSize) { - u8 *temp = pstart + fun.gp(tempj, tempY, gs.dstbuf.bw) * data.blockbits/8; - swizzle(temp, (u8*)pbuf, TransPitch(pitch, data.transfersize), 0xffffffff); + u8 *temp = pstart + fun.gp(tempj, tempY, gs.dstbuf.bw) * data.blockbits / 8; + swizzle(temp, (u8*)pbuf, TransPitch(pitch, data.transfersize), 0xffffffff); } /* transfer the rest */ if (alignedPt.x < gs.imageEndX) { pbuf = TransmitHostLocalX(data, fun.wp, data.widthlimit, data.blockheight, alignedPt.x, pbuf); + if (pbuf == NULL) return NULL; - pbuf -= TransPitch((alignedPt.x - gs.trxpos.dx), data.transfersize)/TSize; + pbuf -= TransPitch((alignedPt.x - gs.trxpos.dx), data.transfersize) / TSize; } else { - pbuf += (data.blockheight - 1)* TransPitch(pitch, data.transfersize)/TSize; + pbuf += (data.blockheight - 1) * TransPitch(pitch, data.transfersize) / TSize; } tempX = gs.trxpos.dx; } + return pbuf; } static __forceinline int FinishTransfer(TransferData data, int nLeftOver) { - if( tempY >= gs.imageEndY ) + if (tempY >= gs.imageEndY) { - assert( gs.imageTransfer == -1 || tempY == gs.imageEndY ); + assert(gs.imageTransfer == -1 || tempY == gs.imageEndY); gs.imageTransfer = -1; /*int start, end; ZeroGS::GetRectMemAddress(start, end, gs.dstbuf.psm, gs.trxpos.dx, gs.trxpos.dy, gs.imageWnew, gs.imageHnew, gs.dstbuf.bp, gs.dstbuf.bw); @@ -161,22 +167,23 @@ static __forceinline int FinishTransfer(TransferData data, int nLeftOver) gs.imageX = tempX; } - return (nSize * TransPitch(2, data.transfersize) + nLeftOver)/2; + return (nSize * TransPitch(2, data.transfersize) + nLeftOver) / 2; } template static __forceinline int RealTransfer(TransferData data, TransferFuncts fun, const void* pbyMem, u32 nQWordSize) { - assert( gs.imageTransfer == 0 ); + assert(gs.imageTransfer == 0); - pstart = g_pbyGSMemory + gs.dstbuf.bp*256; + pstart = g_pbyGSMemory + gs.dstbuf.bp * 256; const T* pbuf = (const T*)pbyMem; const int tp2 = TransPitch(2, data.transfersize); - int nLeftOver = (nQWordSize*4*2)%tp2; - tempY = gs.imageY; tempX = gs.imageX; + int nLeftOver = (nQWordSize * 4 * 2) % tp2; + tempY = gs.imageY; + tempX = gs.imageX; Point alignedPt; - nSize = (nQWordSize*4*2)/tp2; + nSize = (nQWordSize * 4 * 2) / tp2; nSize = min(nSize, gs.imageWnew * gs.imageHnew); int endY = ROUND_UPPOW2(gs.imageY, data.blockheight); @@ -184,17 +191,21 @@ static __forceinline int RealTransfer(TransferData data, TransferFuncts fun, con alignedPt.x = ROUND_DOWNPOW2(gs.imageEndX, data.blockwidth); pbuf = AlignOnBlockBoundry(data, fun, alignedPt, endY, pbuf); + if (pbuf == NULL) return FinishTransfer(data, nLeftOver); pbuf = TransferAligningToBlocks(data, fun, alignedPt, pbuf); + if (pbuf == NULL) return FinishTransfer(data, nLeftOver); - if (TransPitch(nSize, data.transfersize)/4 > 0) + if (TransPitch(nSize, data.transfersize) / 4 > 0) { pbuf = TransmitHostLocalY(data, fun.wp, data.widthlimit, gs.imageEndY, pbuf); + if (pbuf == NULL) return FinishTransfer(data, nLeftOver); + /* sometimes wrong sizes are sent (tekken tag) */ - assert( gs.imageTransfer == -1 || TransPitch(nSize, data.transfersize)/4 <= 2 ); + assert(gs.imageTransfer == -1 || TransPitch(nSize, data.transfersize) / 4 <= 2); } return FinishTransfer(data, nLeftOver); @@ -203,7 +214,7 @@ static __forceinline int RealTransfer(TransferData data, TransferFuncts fun, con //DEFINE_TRANSFERLOCAL(32, u32, 2, 32, 8, 8, _, SwizzleBlock32); int TransferHostLocal32(const void* pbyMem, u32 nQWordSize) { - TransferData data(2,32,8,8,32, PSM_); + TransferData data(2, 32, 8, 8, 32, PSM_); TransferFuncts fun(writePixel32_0, getPixelAddress32_0, SwizzleBlock32, SwizzleBlock32u); return RealTransfer(data, fun, pbyMem, nQWordSize); @@ -212,7 +223,7 @@ int TransferHostLocal32(const void* pbyMem, u32 nQWordSize) //DEFINE_TRANSFERLOCAL(32Z, u32, 2, 32, 8, 8, _, SwizzleBlock32); int TransferHostLocal32Z(const void* pbyMem, u32 nQWordSize) { - TransferData data(2,32,8,8,32, PSM_); + TransferData data(2, 32, 8, 8, 32, PSM_); TransferFuncts fun(writePixel32Z_0, getPixelAddress32Z_0, SwizzleBlock32, SwizzleBlock32u); return RealTransfer(data, fun, pbyMem, nQWordSize); @@ -221,7 +232,7 @@ int TransferHostLocal32Z(const void* pbyMem, u32 nQWordSize) //DEFINE_TRANSFERLOCAL(24, u8, 8, 32, 8, 8, _24, SwizzleBlock24); int TransferHostLocal24(const void* pbyMem, u32 nQWordSize) { - TransferData data(8,32,8,8,24, PSM_24_); + TransferData data(8, 32, 8, 8, 24, PSM_24_); TransferFuncts fun(writePixel24_0, getPixelAddress24_0, SwizzleBlock24, SwizzleBlock24u); return RealTransfer(data, fun, pbyMem, nQWordSize); @@ -230,7 +241,7 @@ int TransferHostLocal24(const void* pbyMem, u32 nQWordSize) //DEFINE_TRANSFERLOCAL(24Z, u8, 8, 32, 8, 8, _24, SwizzleBlock24); int TransferHostLocal24Z(const void* pbyMem, u32 nQWordSize) { - TransferData data(8,32,8,8,24, PSM_24_); + TransferData data(8, 32, 8, 8, 24, PSM_24_); TransferFuncts fun(writePixel24Z_0, getPixelAddress24Z_0, SwizzleBlock24, SwizzleBlock24u); return RealTransfer(data, fun, pbyMem, nQWordSize); @@ -239,7 +250,7 @@ int TransferHostLocal24Z(const void* pbyMem, u32 nQWordSize) //DEFINE_TRANSFERLOCAL(16, u16, 4, 16, 16, 8, _, SwizzleBlock16); int TransferHostLocal16(const void* pbyMem, u32 nQWordSize) { - TransferData data(4,16,16,8,16, PSM_); + TransferData data(4, 16, 16, 8, 16, PSM_); TransferFuncts fun(writePixel16_0, getPixelAddress16_0, SwizzleBlock16, SwizzleBlock16u); return RealTransfer(data, fun, pbyMem, nQWordSize); @@ -248,7 +259,7 @@ int TransferHostLocal16(const void* pbyMem, u32 nQWordSize) //DEFINE_TRANSFERLOCAL(16S, u16, 4, 16, 16, 8, _, SwizzleBlock16); int TransferHostLocal16S(const void* pbyMem, u32 nQWordSize) { - TransferData data(4,16,16,8,16, PSM_); + TransferData data(4, 16, 16, 8, 16, PSM_); TransferFuncts fun(writePixel16S_0, getPixelAddress16S_0, SwizzleBlock16, SwizzleBlock16u); return RealTransfer(data, fun, pbyMem, nQWordSize); @@ -257,7 +268,7 @@ int TransferHostLocal16S(const void* pbyMem, u32 nQWordSize) //DEFINE_TRANSFERLOCAL(16Z, u16, 4, 16, 16, 8, _, SwizzleBlock16); int TransferHostLocal16Z(const void* pbyMem, u32 nQWordSize) { - TransferData data(4,16,16,8,16, PSM_); + TransferData data(4, 16, 16, 8, 16, PSM_); TransferFuncts fun(writePixel16Z_0, getPixelAddress16Z_0, SwizzleBlock16, SwizzleBlock16u); return RealTransfer(data, fun, pbyMem, nQWordSize); @@ -266,7 +277,7 @@ int TransferHostLocal16Z(const void* pbyMem, u32 nQWordSize) //DEFINE_TRANSFERLOCAL(16SZ, u16, 4, 16, 16, 8, _, SwizzleBlock16); int TransferHostLocal16SZ(const void* pbyMem, u32 nQWordSize) { - TransferData data(4,16,16,8,16, PSM_); + TransferData data(4, 16, 16, 8, 16, PSM_); TransferFuncts fun(writePixel16SZ_0, getPixelAddress16SZ_0, SwizzleBlock16, SwizzleBlock16u); return RealTransfer(data, fun, pbyMem, nQWordSize); @@ -275,7 +286,7 @@ int TransferHostLocal16SZ(const void* pbyMem, u32 nQWordSize) //DEFINE_TRANSFERLOCAL(8, u8, 4, 8, 16, 16, _, SwizzleBlock8); int TransferHostLocal8(const void* pbyMem, u32 nQWordSize) { - TransferData data(4,8,16,16,8, PSM_); + TransferData data(4, 8, 16, 16, 8, PSM_); TransferFuncts fun(writePixel8_0, getPixelAddress8_0, SwizzleBlock8, SwizzleBlock8u); return RealTransfer(data, fun, pbyMem, nQWordSize); @@ -284,7 +295,7 @@ int TransferHostLocal8(const void* pbyMem, u32 nQWordSize) //DEFINE_TRANSFERLOCAL(4, u8, 8, 4, 32, 16, _4, SwizzleBlock4); int TransferHostLocal4(const void* pbyMem, u32 nQWordSize) { - TransferData data(8,4,32,16,4, PSM_4_); + TransferData data(8, 4, 32, 16, 4, PSM_4_); TransferFuncts fun(writePixel4_0, getPixelAddress4_0, SwizzleBlock4, SwizzleBlock4u); return RealTransfer(data, fun, pbyMem, nQWordSize); @@ -293,7 +304,7 @@ int TransferHostLocal4(const void* pbyMem, u32 nQWordSize) //DEFINE_TRANSFERLOCAL(8H, u8, 4, 32, 8, 8, _, SwizzleBlock8H); int TransferHostLocal8H(const void* pbyMem, u32 nQWordSize) { - TransferData data(4,32,8,8,8, PSM_); + TransferData data(4, 32, 8, 8, 8, PSM_); TransferFuncts fun(writePixel8H_0, getPixelAddress8H_0, SwizzleBlock8H, SwizzleBlock8Hu); return RealTransfer(data, fun, pbyMem, nQWordSize); @@ -302,7 +313,7 @@ int TransferHostLocal8H(const void* pbyMem, u32 nQWordSize) //DEFINE_TRANSFERLOCAL(4HL, u8, 8, 32, 8, 8, _4, SwizzleBlock4HL); int TransferHostLocal4HL(const void* pbyMem, u32 nQWordSize) { - TransferData data(8,32,8,8,4, PSM_4_); + TransferData data(8, 32, 8, 8, 4, PSM_4_); TransferFuncts fun(writePixel4HL_0, getPixelAddress4HL_0, SwizzleBlock4HL, SwizzleBlock4HLu); return RealTransfer(data, fun, pbyMem, nQWordSize); @@ -311,7 +322,7 @@ int TransferHostLocal4HL(const void* pbyMem, u32 nQWordSize) //DEFINE_TRANSFERLOCAL(4HH, u8, 8, 32, 8, 8, _4, SwizzleBlock4HH); int TransferHostLocal4HH(const void* pbyMem, u32 nQWordSize) { - TransferData data(8,32,8,8,4, PSM_4_); + TransferData data(8, 32, 8, 8, 4, PSM_4_); TransferFuncts fun(writePixel4HH_0, getPixelAddress4HH_0, SwizzleBlock4HH, SwizzleBlock4HHu); return RealTransfer(data, fun, pbyMem, nQWordSize); @@ -382,24 +393,30 @@ void TransferLocalHost16SZ(void* pbyMem, u32 nQWordSize) {FUNCLOG} b.TransferHostLocal = TransferHostLocal##psm; \ b.TransferLocalHost = TransferLocalHost##psm; \ } \ - + void BLOCK::FillBlocks(vector& vBlockData, vector& vBilinearData, int floatfmt) { FUNCLOG vBlockData.resize(BLOCK_TEXWIDTH * BLOCK_TEXHEIGHT * (floatfmt ? 4 : 2)); - if( floatfmt ) + + if (floatfmt) vBilinearData.resize(BLOCK_TEXWIDTH * BLOCK_TEXHEIGHT * sizeof(Vector)); int i, j; + BLOCK b; + float* psrcf = NULL; + u16* psrcw = NULL; + Vector* psrcv = NULL; memset(m_Blocks, 0, sizeof(m_Blocks)); // 32 FILL_BLOCK(64, 32, 0, 0, 1, 32, 32); + m_Blocks[PSMCT32] = b; // 24 (same as 32 except write/readPixel are different) @@ -427,8 +444,8 @@ void BLOCK::FillBlocks(vector& vBlockData, vector& vBilinearData, in m_Blocks[PSMT4HL].readPixel_0 = readPixel4HL_0; m_Blocks[PSMT4HL].TransferHostLocal = TransferHostLocal4HL; m_Blocks[PSMT4HL].TransferLocalHost = TransferLocalHost4HL; - m_Blocks[PSMT4HH] = b; + m_Blocks[PSMT4HH].writePixel = writePixel4HH; m_Blocks[PSMT4HH].writePixel_0 = writePixel4HH_0; m_Blocks[PSMT4HH].readPixel = readPixel4HH; diff --git a/plugins/zzogl-pg/opengl/Mem_Swizzle.cpp b/plugins/zzogl-pg/opengl/Mem_Swizzle.cpp index 2aad5a291b..94b7a68bea 100644 --- a/plugins/zzogl-pg/opengl/Mem_Swizzle.cpp +++ b/plugins/zzogl-pg/opengl/Mem_Swizzle.cpp @@ -32,30 +32,37 @@ __forceinline void SwizzleBlock16(u8 *dst, u8 *src, int pitch, u32 WriteMask) { SwizzleBlock16_sse2(dst, src, pitch/*, WriteMask*/); } + __forceinline void SwizzleBlock8(u8 *dst, u8 *src, int pitch, u32 WriteMask) { SwizzleBlock8_sse2(dst, src, pitch/*, WriteMask*/); } + __forceinline void SwizzleBlock4(u8 *dst, u8 *src, int pitch, u32 WriteMask) { SwizzleBlock4_sse2(dst, src, pitch/*, WriteMask*/); } + __forceinline void SwizzleBlock32u(u8 *dst, u8 *src, int pitch, u32 WriteMask) { SwizzleBlock32u_sse2(dst, src, pitch, WriteMask); } + __forceinline void SwizzleBlock16u(u8 *dst, u8 *src, int pitch, u32 WriteMask) { SwizzleBlock16u_sse2(dst, src, pitch/*, WriteMask*/); } + __forceinline void SwizzleBlock8u(u8 *dst, u8 *src, int pitch, u32 WriteMask) { SwizzleBlock8u_sse2(dst, src, pitch/*, WriteMask*/); } + __forceinline void SwizzleBlock4u(u8 *dst, u8 *src, int pitch, u32 WriteMask) { SwizzleBlock4u_sse2(dst, src, pitch/*, WriteMask*/); } + #else __forceinline void SwizzleBlock32(u8 *dst, u8 *src, int pitch, u32 WriteMask) @@ -67,26 +74,32 @@ __forceinline void SwizzleBlock16(u8 *dst, u8 *src, int pitch, u32 WriteMask) { SwizzleBlock16_c(dst, src, pitch/*, WriteMask*/); } + __forceinline void SwizzleBlock8(u8 *dst, u8 *src, int pitch, u32 WriteMask) { SwizzleBlock8_c(dst, src, pitch/*, WriteMask*/); } + __forceinline void SwizzleBlock4(u8 *dst, u8 *src, int pitch, u32 WriteMask) { SwizzleBlock4_c(dst, src, pitch/*, WriteMask*/); } + __forceinline void SwizzleBlock32u(u8 *dst, u8 *src, int pitch, u32 WriteMask) { SwizzleBlock32_c(dst, src, pitch, WriteMask); } + __forceinline void SwizzleBlock16u(u8 *dst, u8 *src, int pitch, u32 WriteMask) { SwizzleBlock16_c(dst, src, pitch/*, WriteMask*/); } + __forceinline void SwizzleBlock8u(u8 *dst, u8 *src, int pitch, u32 WriteMask) { SwizzleBlock8_c(dst, src, pitch/*, WriteMask*/); } + __forceinline void SwizzleBlock4u(u8 *dst, u8 *src, int pitch, u32 WriteMask) { SwizzleBlock4_c(dst, src, pitch/*, WriteMask*/); @@ -96,16 +109,16 @@ __forceinline void __fastcall SwizzleBlock32_c(u8* dst, u8* src, int srcpitch, u { u32* d = &g_columnTable32[0][0]; - if(WriteMask == 0xffffffff) + if (WriteMask == 0xffffffff) { - for(int j = 0; j < 8; j++, d += 8, src += srcpitch) - for(int i = 0; i < 8; i++) + for (int j = 0; j < 8; j++, d += 8, src += srcpitch) + for (int i = 0; i < 8; i++) ((u32*)dst)[d[i]] = ((u32*)src)[i]; } else { - for(int j = 0; j < 8; j++, d += 8, src += srcpitch) - for(int i = 0; i < 8; i++) + for (int j = 0; j < 8; j++, d += 8, src += srcpitch) + for (int i = 0; i < 8; i++) ((u32*)dst)[d[i]] = (((u32*)dst)[d[i]] & ~WriteMask) | (((u32*)src)[i] & WriteMask); } } @@ -115,16 +128,16 @@ __forceinline void __fastcall SwizzleBlock24_c(u8* dst, u8* src, int srcpitch, u { u32* d = &g_columnTable32[0][0]; - if(WriteMask == 0x00ffffff) + if (WriteMask == 0x00ffffff) { - for(int j = 0; j < 8; j++, d += 8, src += srcpitch) - for(int i = 0; i < 8; i++) + for (int j = 0; j < 8; j++, d += 8, src += srcpitch) + for (int i = 0; i < 8; i++) ((u32*)dst)[d[i]] = ((u32*)src)[i]; } else { - for(int j = 0; j < 8; j++, d += 8, src += srcpitch) - for(int i = 0; i < 8; i++) + for (int j = 0; j < 8; j++, d += 8, src += srcpitch) + for (int i = 0; i < 8; i++) ((u32*)dst)[d[i]] = (((u32*)dst)[d[i]] & ~WriteMask) | (((u32*)src)[i] & WriteMask); } } @@ -133,8 +146,8 @@ __forceinline void __fastcall SwizzleBlock16_c(u8* dst, u8* src, int srcpitch, u { u32* d = &g_columnTable16[0][0]; - for(int j = 0; j < 8; j++, d += 16, src += srcpitch) - for(int i = 0; i < 16; i++) + for (int j = 0; j < 8; j++, d += 16, src += srcpitch) + for (int i = 0; i < 16; i++) ((u16*)dst)[d[i]] = ((u16*)src)[i]; } @@ -142,8 +155,8 @@ __forceinline void __fastcall SwizzleBlock8_c(u8* dst, u8* src, int srcpitch, u3 { u32* d = &g_columnTable8[0][0]; - for(int j = 0; j < 16; j++, d += 16, src += srcpitch) - for(int i = 0; i < 16; i++) + for (int j = 0; j < 16; j++, d += 16, src += srcpitch) + for (int i = 0; i < 16; i++) dst[d[i]] = src[i]; } @@ -151,41 +164,45 @@ __forceinline void __fastcall SwizzleBlock4_c(u8* dst, u8* src, int srcpitch, u3 { u32* d = &g_columnTable4[0][0]; - for(int j = 0; j < 16; j++, d += 32, src += srcpitch) + for (int j = 0; j < 16; j++, d += 32, src += srcpitch) { - for(int i = 0; i < 32; i++) + for (int i = 0; i < 32; i++) { u32 addr = d[i]; - u8 c = (src[i>>1] >> ((i&1) << 2)) & 0x0f; - u32 shift = (addr&1) << 2; + u8 c = (src[i>>1] >> ((i & 1) << 2)) & 0x0f; + u32 shift = (addr & 1) << 2; dst[addr >> 1] = (dst[addr >> 1] & (0xf0 >> shift)) | (c << shift); } } } + #endif __forceinline void SwizzleBlock24(u8 *dst, u8 *src, int pitch, u32 WriteMask) { u8* pnewsrc = src; u32* pblock = tempblock; - for(int by = 0; by < 7; ++by, pblock += 8, pnewsrc += pitch-24) + for (int by = 0; by < 7; ++by, pblock += 8, pnewsrc += pitch - 24) { - for(int bx = 0; bx < 8; ++bx, pnewsrc += 3) + for (int bx = 0; bx < 8; ++bx, pnewsrc += 3) { pblock[bx] = *(u32*)pnewsrc; } } - for(int bx = 0; bx < 7; ++bx, pnewsrc += 3) + for (int bx = 0; bx < 7; ++bx, pnewsrc += 3) { /* might be 1 byte out of bounds of GS memory */ pblock[bx] = *(u32*)pnewsrc; } /* do 3 bytes for the last copy */ - *((u8*)pblock+28) = pnewsrc[0]; - *((u8*)pblock+29) = pnewsrc[1]; - *((u8*)pblock+30) = pnewsrc[2]; + *((u8*)pblock + 28) = pnewsrc[0]; + + *((u8*)pblock + 29) = pnewsrc[1]; + + *((u8*)pblock + 30) = pnewsrc[2]; + SwizzleBlock32((u8*)dst, (u8*)tempblock, 32, 0x00ffffff); } @@ -194,19 +211,20 @@ __forceinline void SwizzleBlock8H(u8 *dst, u8 *src, int pitch, u32 WriteMask) u8* pnewsrc = src; u32* pblock = tempblock; - for(int by = 0; by < 8; ++by, pblock += 8, pnewsrc += pitch) + for (int by = 0; by < 8; ++by, pblock += 8, pnewsrc += pitch) { u32 u = *(u32*)pnewsrc; - pblock[0] = u<<24; - pblock[1] = u<<16; - pblock[2] = u<<8; + pblock[0] = u << 24; + pblock[1] = u << 16; + pblock[2] = u << 8; pblock[3] = u; - u = *(u32*)(pnewsrc+4); - pblock[4] = u<<24; - pblock[5] = u<<16; - pblock[6] = u<<8; + u = *(u32*)(pnewsrc + 4); + pblock[4] = u << 24; + pblock[5] = u << 16; + pblock[6] = u << 8; pblock[7] = u; } + SwizzleBlock32((u8*)dst, (u8*)tempblock, 32, 0xff000000); } @@ -215,18 +233,19 @@ __forceinline void SwizzleBlock4HH(u8 *dst, u8 *src, int pitch, u32 WriteMask) u8* pnewsrc = src; u32* pblock = tempblock; - for(int by = 0; by < 8; ++by, pblock += 8, pnewsrc += pitch) + for (int by = 0; by < 8; ++by, pblock += 8, pnewsrc += pitch) { u32 u = *(u32*)pnewsrc; - pblock[0] = u<<28; - pblock[1] = u<<24; - pblock[2] = u<<20; - pblock[3] = u<<16; - pblock[4] = u<<12; - pblock[5] = u<<8; - pblock[6] = u<<4; + pblock[0] = u << 28; + pblock[1] = u << 24; + pblock[2] = u << 20; + pblock[3] = u << 16; + pblock[4] = u << 12; + pblock[5] = u << 8; + pblock[6] = u << 4; pblock[7] = u; } + SwizzleBlock32((u8*)dst, (u8*)tempblock, 32, 0xf0000000); } @@ -235,17 +254,18 @@ __forceinline void SwizzleBlock4HL(u8 *dst, u8 *src, int pitch, u32 WriteMask) u8* pnewsrc = src; u32* pblock = tempblock; - for(int by = 0; by < 8; ++by, pblock += 8, pnewsrc += pitch) + for (int by = 0; by < 8; ++by, pblock += 8, pnewsrc += pitch) { u32 u = *(u32*)pnewsrc; - pblock[0] = u<<24; - pblock[1] = u<<20; - pblock[2] = u<<16; - pblock[3] = u<<12; - pblock[4] = u<<8; - pblock[5] = u<<4; + pblock[0] = u << 24; + pblock[1] = u << 20; + pblock[2] = u << 16; + pblock[3] = u << 12; + pblock[4] = u << 8; + pblock[5] = u << 4; pblock[6] = u; - pblock[7] = u>>4; + pblock[7] = u >> 4; } + SwizzleBlock32((u8*)dst, (u8*)tempblock, 32, 0x0f000000); } diff --git a/plugins/zzogl-pg/opengl/Mem_Tables.cpp b/plugins/zzogl-pg/opengl/Mem_Tables.cpp index d903c78a66..4b056727f7 100644 --- a/plugins/zzogl-pg/opengl/Mem_Tables.cpp +++ b/plugins/zzogl-pg/opengl/Mem_Tables.cpp @@ -18,212 +18,224 @@ #include "GS.h" -u32 g_blockTable32[4][8] = { - { 0, 1, 4, 5, 16, 17, 20, 21}, - { 2, 3, 6, 7, 18, 19, 22, 23}, - { 8, 9, 12, 13, 24, 25, 28, 29}, - { 10, 11, 14, 15, 26, 27, 30, 31} +u32 g_blockTable32[4][8] = +{ + { 0, 1, 4, 5, 16, 17, 20, 21}, + { 2, 3, 6, 7, 18, 19, 22, 23}, + { 8, 9, 12, 13, 24, 25, 28, 29}, + { 10, 11, 14, 15, 26, 27, 30, 31} }; -u32 g_blockTable32Z[4][8] = { - { 24, 25, 28, 29, 8, 9, 12, 13}, - { 26, 27, 30, 31, 10, 11, 14, 15}, - { 16, 17, 20, 21, 0, 1, 4, 5}, - { 18, 19, 22, 23, 2, 3, 6, 7} +u32 g_blockTable32Z[4][8] = +{ + { 24, 25, 28, 29, 8, 9, 12, 13}, + { 26, 27, 30, 31, 10, 11, 14, 15}, + { 16, 17, 20, 21, 0, 1, 4, 5}, + { 18, 19, 22, 23, 2, 3, 6, 7} }; -u32 g_blockTable16[8][4] = { - { 0, 2, 8, 10 }, - { 1, 3, 9, 11 }, - { 4, 6, 12, 14 }, - { 5, 7, 13, 15 }, - { 16, 18, 24, 26 }, - { 17, 19, 25, 27 }, - { 20, 22, 28, 30 }, - { 21, 23, 29, 31 } +u32 g_blockTable16[8][4] = +{ + { 0, 2, 8, 10 }, + { 1, 3, 9, 11 }, + { 4, 6, 12, 14 }, + { 5, 7, 13, 15 }, + { 16, 18, 24, 26 }, + { 17, 19, 25, 27 }, + { 20, 22, 28, 30 }, + { 21, 23, 29, 31 } }; -u32 g_blockTable16S[8][4] = { - { 0, 2, 16, 18 }, - { 1, 3, 17, 19 }, - { 8, 10, 24, 26 }, - { 9, 11, 25, 27 }, - { 4, 6, 20, 22 }, - { 5, 7, 21, 23 }, - { 12, 14, 28, 30 }, - { 13, 15, 29, 31 } +u32 g_blockTable16S[8][4] = +{ + { 0, 2, 16, 18 }, + { 1, 3, 17, 19 }, + { 8, 10, 24, 26 }, + { 9, 11, 25, 27 }, + { 4, 6, 20, 22 }, + { 5, 7, 21, 23 }, + { 12, 14, 28, 30 }, + { 13, 15, 29, 31 } }; -u32 g_blockTable16Z[8][4] = { - { 24, 26, 16, 18 }, - { 25, 27, 17, 19 }, - { 28, 30, 20, 22 }, - { 29, 31, 21, 23 }, - { 8, 10, 0, 2 }, - { 9, 11, 1, 3 }, - { 12, 14, 4, 6 }, - { 13, 15, 5, 7 } +u32 g_blockTable16Z[8][4] = +{ + { 24, 26, 16, 18 }, + { 25, 27, 17, 19 }, + { 28, 30, 20, 22 }, + { 29, 31, 21, 23 }, + { 8, 10, 0, 2 }, + { 9, 11, 1, 3 }, + { 12, 14, 4, 6 }, + { 13, 15, 5, 7 } }; -u32 g_blockTable16SZ[8][4] = { - { 24, 26, 8, 10 }, - { 25, 27, 9, 11 }, - { 16, 18, 0, 2 }, - { 17, 19, 1, 3 }, - { 28, 30, 12, 14 }, - { 29, 31, 13, 15 }, - { 20, 22, 4, 6 }, - { 21, 23, 5, 7 } +u32 g_blockTable16SZ[8][4] = +{ + { 24, 26, 8, 10 }, + { 25, 27, 9, 11 }, + { 16, 18, 0, 2 }, + { 17, 19, 1, 3 }, + { 28, 30, 12, 14 }, + { 29, 31, 13, 15 }, + { 20, 22, 4, 6 }, + { 21, 23, 5, 7 } }; -u32 g_blockTable8[4][8] = { - { 0, 1, 4, 5, 16, 17, 20, 21}, - { 2, 3, 6, 7, 18, 19, 22, 23}, - { 8, 9, 12, 13, 24, 25, 28, 29}, - { 10, 11, 14, 15, 26, 27, 30, 31} +u32 g_blockTable8[4][8] = +{ + { 0, 1, 4, 5, 16, 17, 20, 21}, + { 2, 3, 6, 7, 18, 19, 22, 23}, + { 8, 9, 12, 13, 24, 25, 28, 29}, + { 10, 11, 14, 15, 26, 27, 30, 31} }; -u32 g_blockTable4[8][4] = { - { 0, 2, 8, 10 }, - { 1, 3, 9, 11 }, - { 4, 6, 12, 14 }, - { 5, 7, 13, 15 }, - { 16, 18, 24, 26 }, - { 17, 19, 25, 27 }, - { 20, 22, 28, 30 }, - { 21, 23, 29, 31 } +u32 g_blockTable4[8][4] = +{ + { 0, 2, 8, 10 }, + { 1, 3, 9, 11 }, + { 4, 6, 12, 14 }, + { 5, 7, 13, 15 }, + { 16, 18, 24, 26 }, + { 17, 19, 25, 27 }, + { 20, 22, 28, 30 }, + { 21, 23, 29, 31 } }; -u32 g_columnTable32[8][8] = { - { 0, 1, 4, 5, 8, 9, 12, 13 }, - { 2, 3, 6, 7, 10, 11, 14, 15 }, - { 16, 17, 20, 21, 24, 25, 28, 29 }, - { 18, 19, 22, 23, 26, 27, 30, 31 }, - { 32, 33, 36, 37, 40, 41, 44, 45 }, - { 34, 35, 38, 39, 42, 43, 46, 47 }, - { 48, 49, 52, 53, 56, 57, 60, 61 }, - { 50, 51, 54, 55, 58, 59, 62, 63 }, +u32 g_columnTable32[8][8] = +{ + { 0, 1, 4, 5, 8, 9, 12, 13 }, + { 2, 3, 6, 7, 10, 11, 14, 15 }, + { 16, 17, 20, 21, 24, 25, 28, 29 }, + { 18, 19, 22, 23, 26, 27, 30, 31 }, + { 32, 33, 36, 37, 40, 41, 44, 45 }, + { 34, 35, 38, 39, 42, 43, 46, 47 }, + { 48, 49, 52, 53, 56, 57, 60, 61 }, + { 50, 51, 54, 55, 58, 59, 62, 63 }, }; -u32 g_columnTable16[8][16] = { - { 0, 2, 8, 10, 16, 18, 24, 26, - 1, 3, 9, 11, 17, 19, 25, 27 }, - { 4, 6, 12, 14, 20, 22, 28, 30, - 5, 7, 13, 15, 21, 23, 29, 31 }, - { 32, 34, 40, 42, 48, 50, 56, 58, - 33, 35, 41, 43, 49, 51, 57, 59 }, - { 36, 38, 44, 46, 52, 54, 60, 62, - 37, 39, 45, 47, 53, 55, 61, 63 }, - { 64, 66, 72, 74, 80, 82, 88, 90, - 65, 67, 73, 75, 81, 83, 89, 91 }, - { 68, 70, 76, 78, 84, 86, 92, 94, - 69, 71, 77, 79, 85, 87, 93, 95 }, - { 96, 98, 104, 106, 112, 114, 120, 122, - 97, 99, 105, 107, 113, 115, 121, 123 }, - { 100, 102, 108, 110, 116, 118, 124, 126, - 101, 103, 109, 111, 117, 119, 125, 127 }, +u32 g_columnTable16[8][16] = +{ + { 0, 2, 8, 10, 16, 18, 24, 26, + 1, 3, 9, 11, 17, 19, 25, 27 }, + { 4, 6, 12, 14, 20, 22, 28, 30, + 5, 7, 13, 15, 21, 23, 29, 31 }, + { 32, 34, 40, 42, 48, 50, 56, 58, + 33, 35, 41, 43, 49, 51, 57, 59 }, + { 36, 38, 44, 46, 52, 54, 60, 62, + 37, 39, 45, 47, 53, 55, 61, 63 }, + { 64, 66, 72, 74, 80, 82, 88, 90, + 65, 67, 73, 75, 81, 83, 89, 91 }, + { 68, 70, 76, 78, 84, 86, 92, 94, + 69, 71, 77, 79, 85, 87, 93, 95 }, + { 96, 98, 104, 106, 112, 114, 120, 122, + 97, 99, 105, 107, 113, 115, 121, 123 }, + { 100, 102, 108, 110, 116, 118, 124, 126, + 101, 103, 109, 111, 117, 119, 125, 127 }, }; -u32 g_columnTable8[16][16] = { +u32 g_columnTable8[16][16] = +{ { 0, 4, 16, 20, 32, 36, 48, 52, // column 0 - 2, 6, 18, 22, 34, 38, 50, 54 }, - { 8, 12, 24, 28, 40, 44, 56, 60, - 10, 14, 26, 30, 42, 46, 58, 62 }, - { 33, 37, 49, 53, 1, 5, 17, 21, - 35, 39, 51, 55, 3, 7, 19, 23 }, - { 41, 45, 57, 61, 9, 13, 25, 29, - 43, 47, 59, 63, 11, 15, 27, 31 }, + 2, 6, 18, 22, 34, 38, 50, 54 }, + { 8, 12, 24, 28, 40, 44, 56, 60, + 10, 14, 26, 30, 42, 46, 58, 62 }, + { 33, 37, 49, 53, 1, 5, 17, 21, + 35, 39, 51, 55, 3, 7, 19, 23 }, + { 41, 45, 57, 61, 9, 13, 25, 29, + 43, 47, 59, 63, 11, 15, 27, 31 }, { 96, 100, 112, 116, 64, 68, 80, 84, // column 1 - 98, 102, 114, 118, 66, 70, 82, 86 }, - { 104, 108, 120, 124, 72, 76, 88, 92, - 106, 110, 122, 126, 74, 78, 90, 94 }, - { 65, 69, 81, 85, 97, 101, 113, 117, - 67, 71, 83, 87, 99, 103, 115, 119 }, - { 73, 77, 89, 93, 105, 109, 121, 125, - 75, 79, 91, 95, 107, 111, 123, 127 }, + 98, 102, 114, 118, 66, 70, 82, 86 }, + { 104, 108, 120, 124, 72, 76, 88, 92, + 106, 110, 122, 126, 74, 78, 90, 94 }, + { 65, 69, 81, 85, 97, 101, 113, 117, + 67, 71, 83, 87, 99, 103, 115, 119 }, + { 73, 77, 89, 93, 105, 109, 121, 125, + 75, 79, 91, 95, 107, 111, 123, 127 }, { 128, 132, 144, 148, 160, 164, 176, 180, // column 2 - 130, 134, 146, 150, 162, 166, 178, 182 }, - { 136, 140, 152, 156, 168, 172, 184, 188, - 138, 142, 154, 158, 170, 174, 186, 190 }, - { 161, 165, 177, 181, 129, 133, 145, 149, - 163, 167, 179, 183, 131, 135, 147, 151 }, - { 169, 173, 185, 189, 137, 141, 153, 157, - 171, 175, 187, 191, 139, 143, 155, 159 }, + 130, 134, 146, 150, 162, 166, 178, 182 }, + { 136, 140, 152, 156, 168, 172, 184, 188, + 138, 142, 154, 158, 170, 174, 186, 190 }, + { 161, 165, 177, 181, 129, 133, 145, 149, + 163, 167, 179, 183, 131, 135, 147, 151 }, + { 169, 173, 185, 189, 137, 141, 153, 157, + 171, 175, 187, 191, 139, 143, 155, 159 }, { 224, 228, 240, 244, 192, 196, 208, 212, // column 3 - 226, 230, 242, 246, 194, 198, 210, 214 }, - { 232, 236, 248, 252, 200, 204, 216, 220, - 234, 238, 250, 254, 202, 206, 218, 222 }, - { 193, 197, 209, 213, 225, 229, 241, 245, - 195, 199, 211, 215, 227, 231, 243, 247 }, - { 201, 205, 217, 221, 233, 237, 249, 253, - 203, 207, 219, 223, 235, 239, 251, 255 }, + 226, 230, 242, 246, 194, 198, 210, 214 }, + { 232, 236, 248, 252, 200, 204, 216, 220, + 234, 238, 250, 254, 202, 206, 218, 222 }, + { 193, 197, 209, 213, 225, 229, 241, 245, + 195, 199, 211, 215, 227, 231, 243, 247 }, + { 201, 205, 217, 221, 233, 237, 249, 253, + 203, 207, 219, 223, 235, 239, 251, 255 }, }; -u32 g_columnTable4[16][32] = { +u32 g_columnTable4[16][32] = +{ { 0, 8, 32, 40, 64, 72, 96, 104, // column 0 - 2, 10, 34, 42, 66, 74, 98, 106, - 4, 12, 36, 44, 68, 76, 100, 108, - 6, 14, 38, 46, 70, 78, 102, 110 }, - { 16, 24, 48, 56, 80, 88, 112, 120, - 18, 26, 50, 58, 82, 90, 114, 122, - 20, 28, 52, 60, 84, 92, 116, 124, - 22, 30, 54, 62, 86, 94, 118, 126 }, - { 65, 73, 97, 105, 1, 9, 33, 41, - 67, 75, 99, 107, 3, 11, 35, 43, - 69, 77, 101, 109, 5, 13, 37, 45, - 71, 79, 103, 111, 7, 15, 39, 47 }, - { 81, 89, 113, 121, 17, 25, 49, 57, - 83, 91, 115, 123, 19, 27, 51, 59, - 85, 93, 117, 125, 21, 29, 53, 61, - 87, 95, 119, 127, 23, 31, 55, 63 }, + 2, 10, 34, 42, 66, 74, 98, 106, + 4, 12, 36, 44, 68, 76, 100, 108, + 6, 14, 38, 46, 70, 78, 102, 110 }, + { 16, 24, 48, 56, 80, 88, 112, 120, + 18, 26, 50, 58, 82, 90, 114, 122, + 20, 28, 52, 60, 84, 92, 116, 124, + 22, 30, 54, 62, 86, 94, 118, 126 }, + { 65, 73, 97, 105, 1, 9, 33, 41, + 67, 75, 99, 107, 3, 11, 35, 43, + 69, 77, 101, 109, 5, 13, 37, 45, + 71, 79, 103, 111, 7, 15, 39, 47 }, + { 81, 89, 113, 121, 17, 25, 49, 57, + 83, 91, 115, 123, 19, 27, 51, 59, + 85, 93, 117, 125, 21, 29, 53, 61, + 87, 95, 119, 127, 23, 31, 55, 63 }, { 192, 200, 224, 232, 128, 136, 160, 168, // column 1 - 194, 202, 226, 234, 130, 138, 162, 170, - 196, 204, 228, 236, 132, 140, 164, 172, - 198, 206, 230, 238, 134, 142, 166, 174 }, - { 208, 216, 240, 248, 144, 152, 176, 184, - 210, 218, 242, 250, 146, 154, 178, 186, - 212, 220, 244, 252, 148, 156, 180, 188, - 214, 222, 246, 254, 150, 158, 182, 190 }, - { 129, 137, 161, 169, 193, 201, 225, 233, - 131, 139, 163, 171, 195, 203, 227, 235, - 133, 141, 165, 173, 197, 205, 229, 237, - 135, 143, 167, 175, 199, 207, 231, 239 }, - { 145, 153, 177, 185, 209, 217, 241, 249, - 147, 155, 179, 187, 211, 219, 243, 251, - 149, 157, 181, 189, 213, 221, 245, 253, - 151, 159, 183, 191, 215, 223, 247, 255 }, + 194, 202, 226, 234, 130, 138, 162, 170, + 196, 204, 228, 236, 132, 140, 164, 172, + 198, 206, 230, 238, 134, 142, 166, 174 }, + { 208, 216, 240, 248, 144, 152, 176, 184, + 210, 218, 242, 250, 146, 154, 178, 186, + 212, 220, 244, 252, 148, 156, 180, 188, + 214, 222, 246, 254, 150, 158, 182, 190 }, + { 129, 137, 161, 169, 193, 201, 225, 233, + 131, 139, 163, 171, 195, 203, 227, 235, + 133, 141, 165, 173, 197, 205, 229, 237, + 135, 143, 167, 175, 199, 207, 231, 239 }, + { 145, 153, 177, 185, 209, 217, 241, 249, + 147, 155, 179, 187, 211, 219, 243, 251, + 149, 157, 181, 189, 213, 221, 245, 253, + 151, 159, 183, 191, 215, 223, 247, 255 }, { 256, 264, 288, 296, 320, 328, 352, 360, // column 2 - 258, 266, 290, 298, 322, 330, 354, 362, - 260, 268, 292, 300, 324, 332, 356, 364, - 262, 270, 294, 302, 326, 334, 358, 366 }, - { 272, 280, 304, 312, 336, 344, 368, 376, - 274, 282, 306, 314, 338, 346, 370, 378, - 276, 284, 308, 316, 340, 348, 372, 380, - 278, 286, 310, 318, 342, 350, 374, 382 }, - { 321, 329, 353, 361, 257, 265, 289, 297, - 323, 331, 355, 363, 259, 267, 291, 299, - 325, 333, 357, 365, 261, 269, 293, 301, - 327, 335, 359, 367, 263, 271, 295, 303 }, - { 337, 345, 369, 377, 273, 281, 305, 313, - 339, 347, 371, 379, 275, 283, 307, 315, - 341, 349, 373, 381, 277, 285, 309, 317, - 343, 351, 375, 383, 279, 287, 311, 319 }, + 258, 266, 290, 298, 322, 330, 354, 362, + 260, 268, 292, 300, 324, 332, 356, 364, + 262, 270, 294, 302, 326, 334, 358, 366 }, + { 272, 280, 304, 312, 336, 344, 368, 376, + 274, 282, 306, 314, 338, 346, 370, 378, + 276, 284, 308, 316, 340, 348, 372, 380, + 278, 286, 310, 318, 342, 350, 374, 382 }, + { 321, 329, 353, 361, 257, 265, 289, 297, + 323, 331, 355, 363, 259, 267, 291, 299, + 325, 333, 357, 365, 261, 269, 293, 301, + 327, 335, 359, 367, 263, 271, 295, 303 }, + { 337, 345, 369, 377, 273, 281, 305, 313, + 339, 347, 371, 379, 275, 283, 307, 315, + 341, 349, 373, 381, 277, 285, 309, 317, + 343, 351, 375, 383, 279, 287, 311, 319 }, { 448, 456, 480, 488, 384, 392, 416, 424, // column 3 - 450, 458, 482, 490, 386, 394, 418, 426, - 452, 460, 484, 492, 388, 396, 420, 428, - 454, 462, 486, 494, 390, 398, 422, 430 }, - { 464, 472, 496, 504, 400, 408, 432, 440, - 466, 474, 498, 506, 402, 410, 434, 442, - 468, 476, 500, 508, 404, 412, 436, 444, - 470, 478, 502, 510, 406, 414, 438, 446 }, - { 385, 393, 417, 425, 449, 457, 481, 489, - 387, 395, 419, 427, 451, 459, 483, 491, - 389, 397, 421, 429, 453, 461, 485, 493, - 391, 399, 423, 431, 455, 463, 487, 495 }, - { 401, 409, 433, 441, 465, 473, 497, 505, - 403, 411, 435, 443, 467, 475, 499, 507, - 405, 413, 437, 445, 469, 477, 501, 509, - 407, 415, 439, 447, 471, 479, 503, 511 }, + 450, 458, 482, 490, 386, 394, 418, 426, + 452, 460, 484, 492, 388, 396, 420, 428, + 454, 462, 486, 494, 390, 398, 422, 430 }, + { 464, 472, 496, 504, 400, 408, 432, 440, + 466, 474, 498, 506, 402, 410, 434, 442, + 468, 476, 500, 508, 404, 412, 436, 444, + 470, 478, 502, 510, 406, 414, 438, 446 }, + { 385, 393, 417, 425, 449, 457, 481, 489, + 387, 395, 419, 427, 451, 459, 483, 491, + 389, 397, 421, 429, 453, 461, 485, 493, + 391, 399, 423, 431, 455, 463, 487, 495 }, + { 401, 409, 433, 441, 465, 473, 497, 505, + 403, 411, 435, 443, 467, 475, 499, 507, + 405, 413, 437, 445, 469, 477, 501, 509, + 407, 415, 439, 447, 471, 479, 503, 511 }, }; u32 g_pageTable32[32][64]; diff --git a/plugins/zzogl-pg/opengl/Regs.cpp b/plugins/zzogl-pg/opengl/Regs.cpp index ec32cd40f9..97627f6deb 100644 --- a/plugins/zzogl-pg/opengl/Regs.cpp +++ b/plugins/zzogl-pg/opengl/Regs.cpp @@ -36,20 +36,23 @@ const u32 g_primsub[8] = { 1, 2, 1, 3, 1, 1, 2, 0 }; #pragma warning(disable:4244) #endif -GIFRegHandler g_GIFPackedRegHandlers[16] = { +GIFRegHandler g_GIFPackedRegHandlers[16] = +{ GIFRegHandlerPRIM, GIFPackedRegHandlerRGBA, GIFPackedRegHandlerSTQ, GIFPackedRegHandlerUV, GIFPackedRegHandlerXYZF2, GIFPackedRegHandlerXYZ2, GIFRegHandlerTEX0_1, GIFRegHandlerTEX0_2, GIFRegHandlerCLAMP_1, GIFRegHandlerCLAMP_2, GIFPackedRegHandlerFOG, GIFPackedRegHandlerNull, - GIFRegHandlerXYZF3, GIFRegHandlerXYZ3, GIFPackedRegHandlerA_D, GIFPackedRegHandlerNOP }; + GIFRegHandlerXYZF3, GIFRegHandlerXYZ3, GIFPackedRegHandlerA_D, GIFPackedRegHandlerNOP +}; -GIFRegHandler g_GIFRegHandlers[] = { +GIFRegHandler g_GIFRegHandlers[] = +{ GIFRegHandlerPRIM, GIFRegHandlerRGBAQ, GIFRegHandlerST, GIFRegHandlerUV, GIFRegHandlerXYZF2, GIFRegHandlerXYZ2, GIFRegHandlerTEX0_1, GIFRegHandlerTEX0_2, GIFRegHandlerCLAMP_1, GIFRegHandlerCLAMP_2, GIFRegHandlerFOG, GIFRegHandlerNull, GIFRegHandlerXYZF3, GIFRegHandlerXYZ3, GIFRegHandlerNOP, GIFRegHandlerNOP, GIFRegHandlerNull, GIFRegHandlerNull, GIFRegHandlerNull, GIFRegHandlerNull, GIFRegHandlerTEX1_1, GIFRegHandlerTEX1_2, GIFRegHandlerTEX2_1, GIFRegHandlerTEX2_2, - GIFRegHandlerXYOFFSET_1,GIFRegHandlerXYOFFSET_2,GIFRegHandlerPRMODECONT,GIFRegHandlerPRMODE, + GIFRegHandlerXYOFFSET_1, GIFRegHandlerXYOFFSET_2, GIFRegHandlerPRMODECONT, GIFRegHandlerPRMODE, GIFRegHandlerTEXCLUT, GIFRegHandlerNull, GIFRegHandlerNull, GIFRegHandlerNull, GIFRegHandlerNull, GIFRegHandlerNull, GIFRegHandlerSCANMSK, GIFRegHandlerNull, GIFRegHandlerNull, GIFRegHandlerNull, GIFRegHandlerNull, GIFRegHandlerNull, @@ -67,23 +70,25 @@ GIFRegHandler g_GIFRegHandlers[] = { GIFRegHandlerHWREG, GIFRegHandlerNull, GIFRegHandlerNull, GIFRegHandlerNull, GIFRegHandlerNull, GIFRegHandlerNull, GIFRegHandlerNull, GIFRegHandlerNull, GIFRegHandlerNull, GIFRegHandlerNull, GIFRegHandlerNull, GIFRegHandlerNull, - GIFRegHandlerSIGNAL, GIFRegHandlerFINISH, GIFRegHandlerLABEL, GIFRegHandlerNull }; + GIFRegHandlerSIGNAL, GIFRegHandlerFINISH, GIFRegHandlerLABEL, GIFRegHandlerNull +}; -C_ASSERT(sizeof(g_GIFRegHandlers)/sizeof(g_GIFRegHandlers[0]) == 100 ); +C_ASSERT(sizeof(g_GIFRegHandlers) / sizeof(g_GIFRegHandlers[0]) == 100); // values for keeping track of changes -u32 s_uTex1Data[2][2] = {{0,}}; -u32 s_uClampData[2] = {0,}; +u32 s_uTex1Data[2][2] = {{0, }}; +u32 s_uClampData[2] = {0, }; -u32 results[65535] = {0,}; +u32 results[65535] = {0, }; // return true if triangle SHOULD be painted. -inline bool NoHighlights(int i) { +inline bool NoHighlights(int i) +{ // This is hack-code, I still in search of correct reason, why some triangles should not be drawn. // I'd have thought we could just test prim->_val and ZeroGS::vb[i].zbuf.psm directly... - int resultA = prim->iip + ((prim->tme) << 1) + ((prim->fge) << 2) + ((prim->abe) << 3) + ((prim->aa1) << 4) + ((prim->fst) << 5) + ((prim->ctxt) << 6) + ((prim->fix)<< 7) + - ((ZeroGS::vb[i].zbuf.psm ) << 8); + int resultA = prim->iip + ((prim->tme) << 1) + ((prim->fge) << 2) + ((prim->abe) << 3) + ((prim->aa1) << 4) + ((prim->fst) << 5) + ((prim->ctxt) << 6) + ((prim->fix) << 7) + + ((ZeroGS::vb[i].zbuf.psm) << 8); // if ( results[resultA] == 0 ) { // results[resultA] = 1; // ZZLog::Error_Log("%x = %d %d %d %d %d %d %d %d psm: %x", resultA, prim->iip, (prim->tme), (prim->fge), (prim->abe) , (prim->aa1) ,(prim->fst), (prim->ctxt), (prim->fix), ZeroGS::vb[i].zbuf.psm) ; @@ -92,7 +97,7 @@ inline bool NoHighlights(int i) { const pixTest curtest = ZeroGS::vb[i].test; // Again, couldn't we just test curtest._val? - int result = curtest.ate + ((curtest.atst) << 1) +((curtest.afail) << 4) + ((curtest.date) << 6) + ((curtest.datm) << 7) + ((curtest.zte) << 8) + ((curtest.ztst)<< 9); + int result = curtest.ate + ((curtest.atst) << 1) + ((curtest.afail) << 4) + ((curtest.date) << 6) + ((curtest.datm) << 7) + ((curtest.zte) << 8) + ((curtest.ztst) << 9); // if (resultA == 0xb) // if ( results[result] == 0) { // results[result] = 1; @@ -102,6 +107,7 @@ inline bool NoHighlights(int i) { // if (result == 0x50b && ZeroGS::vb[i].zbuf.zmsk ) return false; //ATF // if psm is 16S or 24, tme, abe, & fst are true, the rest are false, result is 0x302 or 0x700, and there is a mask. + if ((resultA == 0x3a2a || resultA == 0x312a) && (result == 0x302 || result == 0x700) && (ZeroGS::vb[i].zbuf.zmsk)) return false; // Silent Hill:SM and Front Mission 5, result != 0x300 // if psm is 24, abe is true, tme doesn't matter, the rest are false, result is 0x54c or 0x50c and there is a mask. @@ -109,12 +115,14 @@ inline bool NoHighlights(int i) { // if psm is 24, abe & tme are true, the rest are false, and no result. if ((resultA == 0x310a) && (result == 0x0)) return false; // Radiata Stories + // if psm is 16S, tme, abe, fst, and ctxt are true, the rest are false, result is 0x330 or 0x500, and there is a mask. - if (resultA == 0x3a6a && (result == 0x300 || result == 0x500)&& ZeroGS::vb[i].zbuf.zmsk) return false; // Okami, result != 0x30d + if (resultA == 0x3a6a && (result == 0x300 || result == 0x500) && ZeroGS::vb[i].zbuf.zmsk) return false; // Okami, result != 0x30d + // if ((resultA == 0x300b) && (result == 0x300) && ZeroGS::vb[i].zbuf.zmsk) return false; // ATF, but no Melty Blood // Old code - return (!(g_GameSettings&GAME_XENOSPECHACK) || !ZeroGS::vb[i].zbuf.zmsk || prim->iip ) ; + return (!(g_GameSettings&GAME_XENOSPECHACK) || !ZeroGS::vb[i].zbuf.zmsk || prim->iip) ; } void __fastcall GIFPackedRegHandlerNull(u32* data) @@ -127,9 +135,9 @@ void __fastcall GIFPackedRegHandlerRGBA(u32* data) { FUNCLOG gs.rgba = (data[0] & 0xff) | - ((data[1] & 0xff) << 8) | - ((data[2] & 0xff) << 16) | - ((data[3] & 0xff) << 24); + ((data[1] & 0xff) << 8) | + ((data[2] & 0xff) << 16) | + ((data[3] & 0xff) << 24); gs.vertexregs.rgba = gs.rgba; gs.vertexregs.q = gs.q; } @@ -137,8 +145,8 @@ void __fastcall GIFPackedRegHandlerRGBA(u32* data) void __fastcall GIFPackedRegHandlerSTQ(u32* data) { FUNCLOG - *(u32*)&gs.vertexregs.s = data[0]&0xffffff00; - *(u32*)&gs.vertexregs.t = data[1]&0xffffff00; + *(u32*)&gs.vertexregs.s = data[0] & 0xffffff00; + *(u32*)&gs.vertexregs.t = data[1] & 0xffffff00; *(u32*)&gs.q = data[2]; } @@ -152,10 +160,11 @@ void __fastcall GIFPackedRegHandlerUV(u32* data) void __forceinline KICK_VERTEX2() { FUNCLOG + if (++gs.primC >= (int)g_primmult[prim->prim]) { - if ( NoHighlights(prim->ctxt) ) - (*ZeroGS::drawfn[prim->prim])(); + if (NoHighlights(prim->ctxt)) (*ZeroGS::drawfn[prim->prim])(); + gs.primC -= g_primsub[prim->prim]; } } @@ -163,14 +172,16 @@ void __forceinline KICK_VERTEX2() void __forceinline KICK_VERTEX3() { FUNCLOG + if (++gs.primC >= (int)g_primmult[prim->prim]) { gs.primC -= g_primsub[prim->prim]; + if (prim->prim == 5) { /* tri fans need special processing */ if (gs.nTriFanVert == gs.primIndex) - gs.primIndex = (gs.primIndex+1)%ArraySize(gs.gsvertex); + gs.primIndex = (gs.primIndex + 1) % ArraySize(gs.gsvertex); } } } @@ -183,12 +194,14 @@ void __fastcall GIFPackedRegHandlerXYZF2(u32* data) gs.vertexregs.z = (data[2] >> 4) & 0xffffff; gs.vertexregs.f = (data[3] >> 4) & 0xff; gs.gsvertex[gs.primIndex] = gs.vertexregs; - gs.primIndex = (gs.primIndex+1)%ArraySize(gs.gsvertex); + gs.primIndex = (gs.primIndex + 1) % ArraySize(gs.gsvertex); - if( data[3] & 0x8000 ) { + if (data[3] & 0x8000) + { KICK_VERTEX3(); } - else { + else + { KICK_VERTEX2(); } } @@ -200,12 +213,14 @@ void __fastcall GIFPackedRegHandlerXYZ2(u32* data) gs.vertexregs.y = (data[1] >> 0) & 0xffff; gs.vertexregs.z = data[2]; gs.gsvertex[gs.primIndex] = gs.vertexregs; - gs.primIndex = (gs.primIndex+1)%ArraySize(gs.gsvertex); + gs.primIndex = (gs.primIndex + 1) % ArraySize(gs.gsvertex); - if( data[3] & 0x8000 ) { + if (data[3] & 0x8000) + { KICK_VERTEX3(); } - else { + else + { KICK_VERTEX2(); } } @@ -213,20 +228,22 @@ void __fastcall GIFPackedRegHandlerXYZ2(u32* data) void __fastcall GIFPackedRegHandlerFOG(u32* data) { FUNCLOG - gs.vertexregs.f = (data[3]&0xff0)>>4; + gs.vertexregs.f = (data[3] & 0xff0) >> 4; } void __fastcall GIFPackedRegHandlerA_D(u32* data) { FUNCLOG - if((data[2] & 0xff) < 100) + + if ((data[2] & 0xff) < 100) g_GIFRegHandlers[data[2] & 0xff](data); else GIFRegHandlerNull(data); } void __fastcall GIFPackedRegHandlerNOP(u32* data) -{FUNCLOG +{ + FUNCLOG } extern int g_PrevBitwiseTexX, g_PrevBitwiseTexY; @@ -236,17 +253,19 @@ void tex0Write(int i, u32 *data) FUNCLOG u32 psm = ZZOglGet_psm_TexBitsFix(data[0]); - if ( m_Blocks[psm].bpp == 0 ) + if (m_Blocks[psm].bpp == 0) { // kh and others return; } ZeroGS::vb[i].uNextTex0Data[0] = data[0]; + ZeroGS::vb[i].uNextTex0Data[1] = data[1]; ZeroGS::vb[i].bNeedTexCheck = 1; // don't update unless necessary + if (PSMT_ISCLUT(psm)) { if (ZeroGS::CheckChangeInClut(data[1], psm)) @@ -254,6 +273,7 @@ void tex0Write(int i, u32 *data) // loading clut, so flush whole texture ZeroGS::vb[i].FlushTexData(); } + // check if csa is the same!! (ffx bisaid island, grass) else if ((data[1] & 0x1f780000) != (ZeroGS::vb[i].uCurTex0Data[1] & 0x1f780000)) { @@ -262,11 +282,12 @@ void tex0Write(int i, u32 *data) } } -void tex2Write(int i, u32 *data) { +void tex2Write(int i, u32 *data) +{ FUNCLOG tex0Info& tex0 = ZeroGS::vb[i].tex0; - if( ZeroGS::vb[i].bNeedTexCheck ) + if (ZeroGS::vb[i].bNeedTexCheck) ZeroGS::vb[i].FlushTexData(); u32 psm = ZZOglGet_psm_TexBitsFix(data[0]); @@ -275,43 +296,48 @@ void tex2Write(int i, u32 *data) { // don't update unless necessary // if( ZZOglGet_psm_TexBitsFix(*s_uTex0Data) == ZZOglGet_psm_TexBitsFix(data[0]) ) { // psm is the same - if (ZZOglAllExceptClutIsSame(s_uTex0Data, data)) { - if (!PSMT_ISCLUT(psm)) - return; + if (ZZOglAllExceptClutIsSame(s_uTex0Data, data)) + { + if (!PSMT_ISCLUT(psm)) return; // have to write the CLUT again if changed - if (ZZOglClutMinusCLDunchanged(s_uTex0Data, data)) { + if (ZZOglClutMinusCLDunchanged(s_uTex0Data, data)) + { tex0.cld = ZZOglGet_cld_TexBits(data[1]); - if (tex0.cld != 0) { + + if (tex0.cld != 0) + { ZeroGS::texClutWrite(i); // invalidate to make sure target didn't change! ZeroGS::vb[i].bVarsTexSync = FALSE; } + return; } } ZeroGS::Flush(i); + ZeroGS::vb[i].bVarsTexSync = FALSE; ZeroGS::vb[i].bTexConstsSync = FALSE; - s_uTex0Data[0] = (s_uTex0Data[0]&~0x03f00000)|(psm<<20); - s_uTex0Data[1] = (s_uTex0Data[1]&0x1f)|(data[1]&~0x1f); + s_uTex0Data[0] = (s_uTex0Data[0] & ~0x03f00000) | (psm << 20); + s_uTex0Data[1] = (s_uTex0Data[1] & 0x1f) | (data[1] & ~0x1f); - tex0.psm = ZZOglGet_psm_TexBitsFix(data[0]); + tex0.psm = ZZOglGet_psm_TexBitsFix(data[0]); - if( PSMT_ISCLUT(tex0.psm) ) - ZeroGS::CluttingForFlushedTex(&tex0, data[1], i); + if (PSMT_ISCLUT(tex0.psm)) ZeroGS::CluttingForFlushedTex(&tex0, data[1], i); } -__forceinline void frameWrite(int i, u32 *data) { +__forceinline void frameWrite(int i, u32 *data) +{ FUNCLOG frameInfo& gsfb = ZeroGS::vb[i].gsfb; if ((gsfb.fbp == ZZOglGet_fbp_FrameBitsMult(data[0])) && - (gsfb.fbw == ZZOglGet_fbw_FrameBitsMult(data[0])) && - (gsfb.psm == ZZOglGet_psm_FrameBits(data[0])) && - (gsfb.fbm == ZZOglGet_fbm_FrameBits(data[0])) ) + (gsfb.fbw == ZZOglGet_fbw_FrameBitsMult(data[0])) && + (gsfb.psm == ZZOglGet_psm_FrameBits(data[0])) && + (gsfb.fbm == ZZOglGet_fbm_FrameBits(data[0]))) { return; } @@ -322,7 +348,7 @@ __forceinline void frameWrite(int i, u32 *data) { gsfb.fbp = ZZOglGet_fbp_FrameBitsMult(data[0]); gsfb.fbw = ZZOglGet_fbw_FrameBitsMult(data[0]); gsfb.psm = ZZOglGet_psm_FrameBits(data[0]); - gsfb.fbm = ZZOglGet_fbm_FrameBitsFix(data[0],data[1]); + gsfb.fbm = ZZOglGet_fbm_FrameBitsFix(data[0], data[1]); gsfb.fbh = ZZOglGet_fbh_FrameBitsCalc(data[0]); // gsfb.fbhCalc = gsfb.fbh; @@ -334,10 +360,10 @@ __forceinline void testWrite(int i, u32 *data) FUNCLOG pixTest* test = &ZeroGS::vb[i].test; - if( (*(u32*)test & 0x0007ffff) == (data[0] & 0x0007ffff) ) - return; + if ((*(u32*)test & 0x0007ffff) == (data[0] & 0x0007ffff)) return; ZeroGS::Flush(i); + *(u32*)test = data[0]; // test.ate = (data[0] ) & 0x1; @@ -355,16 +381,17 @@ __forceinline void clampWrite(int i, u32 *data) FUNCLOG clampInfo& clamp = ZeroGS::vb[i].clamp; - if ((s_uClampData[i] != data[0]) || (((clamp.minv>>8) | (clamp.maxv<<2)) != (data[1]&0x0fff))) { + if ((s_uClampData[i] != data[0]) || (((clamp.minv >> 8) | (clamp.maxv << 2)) != (data[1]&0x0fff))) + { ZeroGS::Flush(i); s_uClampData[i] = data[0]; - clamp.wms = (data[0] ) & 0x3; + clamp.wms = (data[0]) & 0x3; clamp.wmt = (data[0] >> 2) & 0x3; clamp.minu = (data[0] >> 4) & 0x3ff; clamp.maxu = (data[0] >> 14) & 0x3ff; - clamp.minv =((data[0] >> 24) & 0xff) | ((data[1] & 0x3) << 8); + clamp.minv = ((data[0] >> 24) & 0xff) | ((data[1] & 0x3) << 8); clamp.maxv = (data[1] >> 2) & 0x3ff; ZeroGS::vb[i].bTexConstsSync = FALSE; @@ -375,30 +402,34 @@ void __fastcall GIFRegHandlerNull(u32* data) { FUNCLOG #ifdef _DEBUG + if ((((uptr)&data[2])&0xffff) == 0) return; // 0x7f happens on a lot of games - if (data[2] != 0x7f && (data[0] || data[1])) + if (data[2] != 0x7f && (data[0] || data[1])) { ZZLog::Debug_Log("Unexpected reg handler %x %x %x.", data[0], data[1], data[2]); } + #endif } void __fastcall GIFRegHandlerPRIM(u32 *data) { FUNCLOG - if (data[0] & ~0x3ff) + + if (data[0] & ~0x3ff) { //ZZLog::Warn_Log("Warning: unknown bits in prim %8.8lx_%8.8lx", data[1], data[0]); } gs.nTriFanVert = gs.primIndex; + gs.primC = 0; prim->prim = (data[0]) & 0x7; gs._prim[0].prim = (data[0]) & 0x7; gs._prim[1].prim = (data[0]) & 0x7; - gs._prim[1]._val = (data[0]>>3)&0xff; + gs._prim[1]._val = (data[0] >> 3) & 0xff; ZeroGS::Prim(); } @@ -414,8 +445,8 @@ void __fastcall GIFRegHandlerRGBAQ(u32* data) void __fastcall GIFRegHandlerST(u32* data) { FUNCLOG - *(u32*)&gs.vertexregs.s = data[0]&0xffffff00; - *(u32*)&gs.vertexregs.t = data[1]&0xffffff00; + *(u32*)&gs.vertexregs.s = data[0] & 0xffffff00; + *(u32*)&gs.vertexregs.t = data[1] & 0xffffff00; //*(u32*)&gs.q = data[2]; } @@ -434,7 +465,7 @@ void __fastcall GIFRegHandlerXYZF2(u32* data) gs.vertexregs.z = data[1] & 0xffffff; gs.vertexregs.f = data[1] >> 24; gs.gsvertex[gs.primIndex] = gs.vertexregs; - gs.primIndex = (gs.primIndex+1)%ARRAY_SIZE(gs.gsvertex); + gs.primIndex = (gs.primIndex + 1) % ARRAY_SIZE(gs.gsvertex); KICK_VERTEX2(); } @@ -446,7 +477,7 @@ void __fastcall GIFRegHandlerXYZ2(u32* data) gs.vertexregs.y = (data[0] >> (16)) & 0xffff; gs.vertexregs.z = data[1]; gs.gsvertex[gs.primIndex] = gs.vertexregs; - gs.primIndex = (gs.primIndex+1)%ARRAY_SIZE(gs.gsvertex); + gs.primIndex = (gs.primIndex + 1) % ARRAY_SIZE(gs.gsvertex); KICK_VERTEX2(); } @@ -454,36 +485,36 @@ void __fastcall GIFRegHandlerXYZ2(u32* data) void __fastcall GIFRegHandlerTEX0_1(u32* data) { FUNCLOG - if( !NoHighlights(0)) { - return; - } + + if (!NoHighlights(0)) return; + tex0Write(0, data); } void __fastcall GIFRegHandlerTEX0_2(u32* data) { FUNCLOG - if( !NoHighlights(1) ) { - return; - } + + if (!NoHighlights(1)) return; + tex0Write(1, data); } void __fastcall GIFRegHandlerCLAMP_1(u32* data) { FUNCLOG - if( !NoHighlights(0) ) { - return; - } + + if (!NoHighlights(0)) return; + clampWrite(0, data); } void __fastcall GIFRegHandlerCLAMP_2(u32* data) { FUNCLOG - if( !NoHighlights(1) ) { - return; - } + + if (!NoHighlights(1)) return; + clampWrite(1, data); } @@ -491,7 +522,7 @@ void __fastcall GIFRegHandlerFOG(u32* data) { FUNCLOG //gs.gsvertex[gs.primIndex].f = (data[1] >> 24); // shift to upper bits - gs.vertexregs.f = data[1]>>24; + gs.vertexregs.f = data[1] >> 24; } void __fastcall GIFRegHandlerXYZF3(u32* data) @@ -502,7 +533,7 @@ void __fastcall GIFRegHandlerXYZF3(u32* data) gs.vertexregs.z = data[1] & 0xffffff; gs.vertexregs.f = data[1] >> 24; gs.gsvertex[gs.primIndex] = gs.vertexregs; - gs.primIndex = (gs.primIndex+1)%ARRAY_SIZE(gs.gsvertex); + gs.primIndex = (gs.primIndex + 1) % ARRAY_SIZE(gs.gsvertex); KICK_VERTEX3(); } @@ -514,7 +545,7 @@ void __fastcall GIFRegHandlerXYZ3(u32* data) gs.vertexregs.y = (data[0] >> (16)) & 0xffff; gs.vertexregs.z = data[1]; gs.gsvertex[gs.primIndex] = gs.vertexregs; - gs.primIndex = (gs.primIndex+1)%ARRAY_SIZE(gs.gsvertex); + gs.primIndex = (gs.primIndex + 1) % ARRAY_SIZE(gs.gsvertex); KICK_VERTEX3(); } @@ -529,11 +560,14 @@ void tex1Write(int i, u32* data) FUNCLOG tex1Info& tex1 = ZeroGS::vb[i].tex1; - if( conf.bilinear == 1 && (tex1.mmag != ((data[0] >> 5) & 0x1) || tex1.mmin != ((data[0] >> 6) & 0x7)) ) { + if (conf.bilinear == 1 && (tex1.mmag != ((data[0] >> 5) & 0x1) || tex1.mmin != ((data[0] >> 6) & 0x7))) + { ZeroGS::Flush(i); ZeroGS::vb[i].bVarsTexSync = FALSE; } - tex1.lcm = (data[0] ) & 0x1; + + tex1.lcm = (data[0]) & 0x1; + tex1.mxl = (data[0] >> 2) & 0x7; tex1.mmag = (data[0] >> 5) & 0x1; tex1.mmin = (data[0] >> 6) & 0x7; @@ -546,9 +580,7 @@ void __fastcall GIFRegHandlerTEX1_1(u32* data) { FUNCLOG - if( !NoHighlights(0)) { - return; - } + if (!NoHighlights(0)) return; tex1Write(0, data); } @@ -556,8 +588,8 @@ void __fastcall GIFRegHandlerTEX1_1(u32* data) void __fastcall GIFRegHandlerTEX1_2(u32* data) { FUNCLOG - if( !NoHighlights(1) ) - return; + + if (!NoHighlights(1)) return; tex1Write(1, data); } @@ -611,7 +643,7 @@ void __fastcall GIFRegHandlerPRMODECONT(u32* data) void __fastcall GIFRegHandlerPRMODE(u32* data) { FUNCLOG - gs._prim[0]._val = (data[0]>>3)&0xff; + gs._prim[0]._val = (data[0] >> 3) & 0xff; if (gs.prac == 0) ZeroGS::Prim(); @@ -620,11 +652,11 @@ void __fastcall GIFRegHandlerPRMODE(u32* data) void __fastcall GIFRegHandlerTEXCLUT(u32* data) { FUNCLOG - if( ZeroGS::vb[0].bNeedTexCheck ) - ZeroGS::vb[0].FlushTexData(); - if( ZeroGS::vb[1].bNeedTexCheck ) - ZeroGS::vb[1].FlushTexData(); - gs.clut.cbw = ((data[0] ) & 0x3f) * 64; + + if (ZeroGS::vb[0].bNeedTexCheck) ZeroGS::vb[0].FlushTexData(); + if (ZeroGS::vb[1].bNeedTexCheck) ZeroGS::vb[1].FlushTexData(); + + gs.clut.cbw = ((data[0]) & 0x3f) * 64; gs.clut.cou = ((data[0] >> 6) & 0x3f) * 16; gs.clut.cov = (data[0] >> 12) & 0x3ff; } @@ -644,7 +676,7 @@ void __fastcall GIFRegHandlerMIPTBP1_1(u32* data) { FUNCLOG miptbpInfo& miptbp0 = ZeroGS::vb[0].miptbp0; - miptbp0.tbp[0] = (data[0] ) & 0x3fff; + miptbp0.tbp[0] = (data[0]) & 0x3fff; miptbp0.tbw[0] = (data[0] >> 14) & 0x3f; miptbp0.tbp[1] = ((data[0] >> 20) & 0xfff) | ((data[1] & 0x3) << 12); miptbp0.tbw[1] = (data[1] >> 2) & 0x3f; @@ -656,7 +688,7 @@ void __fastcall GIFRegHandlerMIPTBP1_2(u32* data) { FUNCLOG miptbpInfo& miptbp0 = ZeroGS::vb[1].miptbp0; - miptbp0.tbp[0] = (data[0] ) & 0x3fff; + miptbp0.tbp[0] = (data[0]) & 0x3fff; miptbp0.tbw[0] = (data[0] >> 14) & 0x3f; miptbp0.tbp[1] = ((data[0] >> 20) & 0xfff) | ((data[1] & 0x3) << 12); miptbp0.tbw[1] = (data[1] >> 2) & 0x3f; @@ -668,7 +700,7 @@ void __fastcall GIFRegHandlerMIPTBP2_1(u32* data) { FUNCLOG miptbpInfo& miptbp1 = ZeroGS::vb[0].miptbp1; - miptbp1.tbp[0] = (data[0] ) & 0x3fff; + miptbp1.tbp[0] = (data[0]) & 0x3fff; miptbp1.tbw[0] = (data[0] >> 14) & 0x3f; miptbp1.tbp[1] = ((data[0] >> 20) & 0xfff) | ((data[1] & 0x3) << 12); miptbp1.tbw[1] = (data[1] >> 2) & 0x3f; @@ -680,7 +712,7 @@ void __fastcall GIFRegHandlerMIPTBP2_2(u32* data) { FUNCLOG miptbpInfo& miptbp1 = ZeroGS::vb[1].miptbp1; - miptbp1.tbp[0] = (data[0] ) & 0x3fff; + miptbp1.tbp[0] = (data[0]) & 0x3fff; miptbp1.tbw[0] = (data[0] >> 14) & 0x3f; miptbp1.tbp[1] = ((data[0] >> 20) & 0xfff) | ((data[1] & 0x3) << 12); miptbp1.tbw[1] = (data[1] >> 2) & 0x3f; @@ -696,12 +728,13 @@ void __fastcall GIFRegHandlerTEXA(u32* data) newinfo.ta[0] = data[0] & 0xff; newinfo.ta[1] = data[1] & 0xff; - if( *(u32*)&newinfo != *(u32*)&gs.texa ) { + if (*(u32*)&newinfo != *(u32*)&gs.texa) + { ZeroGS::Flush(0); ZeroGS::Flush(1); - *(u32*)&gs.texa = *(u32*)&newinfo; - gs.texa.fta[0] = newinfo.ta[0]/255.0f; - gs.texa.fta[1] = newinfo.ta[1]/255.0f; + *(u32*)&gs.texa = *(u32*) & newinfo; + gs.texa.fta[0] = newinfo.ta[0] / 255.0f; + gs.texa.fta[1] = newinfo.ta[1] / 255.0f; ZeroGS::vb[0].bTexConstsSync = FALSE; ZeroGS::vb[1].bTexConstsSync = FALSE; @@ -727,13 +760,14 @@ void __fastcall GIFRegHandlerSCISSOR_1(u32* data) Rect2 newscissor; - newscissor.x0 = ((data[0] ) & 0x7ff) << 3; + newscissor.x0 = ((data[0]) & 0x7ff) << 3; newscissor.x1 = ((data[0] >> 16) & 0x7ff) << 3; - newscissor.y0 = ((data[1] ) & 0x7ff) << 3; + newscissor.y0 = ((data[1]) & 0x7ff) << 3; newscissor.y1 = ((data[1] >> 16) & 0x7ff) << 3; - if( newscissor.x1 != scissor.x1 || newscissor.y1 != scissor.y1 || - newscissor.x0 != scissor.x0 || newscissor.y0 != scissor.y0 ) { + if (newscissor.x1 != scissor.x1 || newscissor.y1 != scissor.y1 || + newscissor.x0 != scissor.x0 || newscissor.y0 != scissor.y0) + { ZeroGS::Flush(0); scissor = newscissor; @@ -749,13 +783,14 @@ void __fastcall GIFRegHandlerSCISSOR_2(u32* data) Rect2 newscissor; - newscissor.x0 = ((data[0] ) & 0x7ff) << 3; + newscissor.x0 = ((data[0]) & 0x7ff) << 3; newscissor.x1 = ((data[0] >> 16) & 0x7ff) << 3; - newscissor.y0 = ((data[1] ) & 0x7ff) << 3; + newscissor.y0 = ((data[1]) & 0x7ff) << 3; newscissor.y1 = ((data[1] >> 16) & 0x7ff) << 3; - if( newscissor.x1 != scissor.x1 || newscissor.y1 != scissor.y1 || - newscissor.x0 != scissor.x0 || newscissor.y0 != scissor.y0 ) { + if (newscissor.x1 != scissor.x1 || newscissor.y1 != scissor.y1 || + newscissor.x0 != scissor.x0 || newscissor.y0 != scissor.y0) + { ZeroGS::Flush(1); scissor = newscissor; @@ -770,17 +805,18 @@ void __fastcall GIFRegHandlerALPHA_1(u32* data) FUNCLOG alphaInfo newalpha; newalpha.abcd = *(u8*)data; - newalpha.fix = *(u8*)(data+1); + newalpha.fix = *(u8*)(data + 1); - if( *(u16*)&newalpha != *(u16*)&ZeroGS::vb[0].alpha ) { + if (*(u16*)&newalpha != *(u16*)&ZeroGS::vb[0].alpha) + { ZeroGS::Flush(0); - if( newalpha.a == 3 ) newalpha.a = 0; - if( newalpha.b == 3 ) newalpha.b = 0; - if( newalpha.c == 3 ) newalpha.c = 0; - if( newalpha.d == 3 ) newalpha.d = 0; + if (newalpha.a == 3) newalpha.a = 0; + if (newalpha.b == 3) newalpha.b = 0; + if (newalpha.c == 3) newalpha.c = 0; + if (newalpha.d == 3) newalpha.d = 0; - *(u16*)&ZeroGS::vb[0].alpha = *(u16*)&newalpha; + *(u16*)&ZeroGS::vb[0].alpha = *(u16*) & newalpha; } } @@ -789,17 +825,18 @@ void __fastcall GIFRegHandlerALPHA_2(u32* data) FUNCLOG alphaInfo newalpha; newalpha.abcd = *(u8*)data; - newalpha.fix = *(u8*)(data+1); + newalpha.fix = *(u8*)(data + 1); - if( *(u16*)&newalpha != *(u16*)&ZeroGS::vb[1].alpha ) { + if (*(u16*)&newalpha != *(u16*)&ZeroGS::vb[1].alpha) + { ZeroGS::Flush(1); - if( newalpha.a == 3 ) newalpha.a = 0; - if( newalpha.b == 3 ) newalpha.b = 0; - if( newalpha.c == 3 ) newalpha.c = 0; - if( newalpha.d == 3 ) newalpha.d = 0; + if (newalpha.a == 3) newalpha.a = 0; + if (newalpha.b == 3) newalpha.b = 0; + if (newalpha.c == 3) newalpha.c = 0; + if (newalpha.d == 3) newalpha.d = 0; - *(u16*)&ZeroGS::vb[1].alpha = *(u16*)&newalpha; + *(u16*)&ZeroGS::vb[1].alpha = *(u16*) & newalpha; } } @@ -876,26 +913,28 @@ void __fastcall GIFRegHandlerZBUF_1(u32* data) FUNCLOG zbufInfo& zbuf = ZeroGS::vb[0].zbuf; - int psm = (0x30|((data[0] >> 24) & 0xf)); - if( zbuf.zbp == (data[0] & 0x1ff) * 32 && - zbuf.psm == psm && - zbuf.zmsk == (data[1] & 0x1) ) { + int psm = (0x30 | ((data[0] >> 24) & 0xf)); + + if (zbuf.zbp == (data[0] & 0x1ff) * 32 && + zbuf.psm == psm && + zbuf.zmsk == (data[1] & 0x1)) + { return; } // error detection - if( m_Blocks[psm].bpp == 0 ) - return; + if (m_Blocks[psm].bpp == 0) return; ZeroGS::Flush(0); ZeroGS::Flush(1); zbuf.zbp = (data[0] & 0x1ff) * 32; - zbuf.psm = 0x30|((data[0] >> 24) & 0xf); + zbuf.psm = 0x30 | ((data[0] >> 24) & 0xf); zbuf.zmsk = data[1] & 0x1; ZeroGS::vb[0].zprimmask = 0xffffffff; - if( zbuf.psm > 0x31 ) ZeroGS::vb[0].zprimmask = 0xffff; + + if (zbuf.psm > 0x31) ZeroGS::vb[0].zprimmask = 0xffff; ZeroGS::vb[0].bNeedZCheck = 1; } @@ -905,39 +944,43 @@ void __fastcall GIFRegHandlerZBUF_2(u32* data) FUNCLOG zbufInfo& zbuf = ZeroGS::vb[1].zbuf; - int psm = (0x30|((data[0] >> 24) & 0xf)); - if( zbuf.zbp == (data[0] & 0x1ff) * 32 && - zbuf.psm == psm && - zbuf.zmsk == (data[1] & 0x1) ) { + int psm = (0x30 | ((data[0] >> 24) & 0xf)); + + if (zbuf.zbp == (data[0] & 0x1ff) * 32 && + zbuf.psm == psm && + zbuf.zmsk == (data[1] & 0x1)) + { return; } // error detection - if( m_Blocks[psm].bpp == 0 ) + if (m_Blocks[psm].bpp == 0) return; ZeroGS::Flush(0); ZeroGS::Flush(1); zbuf.zbp = (data[0] & 0x1ff) * 32; - zbuf.psm = 0x30|((data[0] >> 24) & 0xf); + + zbuf.psm = 0x30 | ((data[0] >> 24) & 0xf); + zbuf.zmsk = data[1] & 0x1; ZeroGS::vb[1].bNeedZCheck = 1; - ZeroGS::vb[1].zprimmask = 0xffffffff; - if( zbuf.psm > 0x31 ) ZeroGS::vb[1].zprimmask = 0xffff; + + if (zbuf.psm > 0x31) ZeroGS::vb[1].zprimmask = 0xffff; } void __fastcall GIFRegHandlerBITBLTBUF(u32* data) { FUNCLOG - gs.srcbufnew.bp = ((data[0] ) & 0x3fff);// * 64; + gs.srcbufnew.bp = ((data[0]) & 0x3fff); // * 64; gs.srcbufnew.bw = ((data[0] >> 16) & 0x3f) * 64; - gs.srcbufnew.psm = (data[0] >> 24) & 0x3f; - gs.dstbufnew.bp = ((data[1] ) & 0x3fff);// * 64; + gs.srcbufnew.psm = (data[0] >> 24) & 0x3f; + gs.dstbufnew.bp = ((data[1]) & 0x3fff); // * 64; gs.dstbufnew.bw = ((data[1] >> 16) & 0x3f) * 64; - gs.dstbufnew.psm = (data[1] >> 24) & 0x3f; + gs.dstbufnew.psm = (data[1] >> 24) & 0x3f; if (gs.dstbufnew.bw == 0) gs.dstbufnew.bw = 64; } @@ -945,9 +988,9 @@ void __fastcall GIFRegHandlerBITBLTBUF(u32* data) void __fastcall GIFRegHandlerTRXPOS(u32* data) { FUNCLOG - gs.trxposnew.sx = (data[0] ) & 0x7ff; + gs.trxposnew.sx = (data[0]) & 0x7ff; gs.trxposnew.sy = (data[0] >> 16) & 0x7ff; - gs.trxposnew.dx = (data[1] ) & 0x7ff; + gs.trxposnew.dx = (data[1]) & 0x7ff; gs.trxposnew.dy = (data[1] >> 16) & 0x7ff; gs.trxposnew.dir = (data[1] >> 27) & 0x3; } @@ -955,42 +998,48 @@ void __fastcall GIFRegHandlerTRXPOS(u32* data) void __fastcall GIFRegHandlerTRXREG(u32* data) { FUNCLOG - gs.imageWtemp = data[0]&0xfff; - gs.imageHtemp = data[1]&0xfff; + gs.imageWtemp = data[0] & 0xfff; + gs.imageHtemp = data[1] & 0xfff; } void __fastcall GIFRegHandlerTRXDIR(u32* data) { FUNCLOG // terminate any previous transfers - switch( gs.imageTransfer ) { + + switch (gs.imageTransfer) + { + case 0: // host->loc gs.imageTransfer = -1; break; + case 1: // loc->host ZeroGS::TerminateLocalHost(); break; } gs.srcbuf = gs.srcbufnew; + gs.dstbuf = gs.dstbufnew; gs.trxpos = gs.trxposnew; gs.imageTransfer = data[0] & 0x3; gs.imageWnew = gs.imageWtemp; gs.imageHnew = gs.imageHtemp; - if( gs.imageWnew > 0 && gs.imageHnew > 0 ) { - switch(gs.imageTransfer) { + if (gs.imageWnew > 0 && gs.imageHnew > 0) + { + switch (gs.imageTransfer) + { case 0: // host->loc ZeroGS::InitTransferHostLocal(); break; case 1: // loc->host - ZeroGS::InitTransferLocalHost(); break; - case 2: + case 2: ZeroGS::TransferLocalLocal(); break; @@ -998,10 +1047,12 @@ void __fastcall GIFRegHandlerTRXDIR(u32* data) gs.imageTransfer = -1; break; - default: assert(0); + default: + assert(0); } } - else { + else + { #if defined(ZEROGS_DEVBUILD) ZZLog::Warn_Log("Dummy transfer."); #endif @@ -1012,10 +1063,13 @@ void __fastcall GIFRegHandlerTRXDIR(u32* data) void __fastcall GIFRegHandlerHWREG(u32* data) { FUNCLOG - if( gs.imageTransfer == 0 ) { + + if (gs.imageTransfer == 0) + { ZeroGS::TransferHostLocal(data, 2); } - else { + else + { #if defined(ZEROGS_DEVBUILD) ZZLog::Error_Log("ZeroGS: HWREG!? %8.8x_%8.8x", data[0], data[1]); //assert(0); @@ -1028,31 +1082,34 @@ extern int g_GSMultiThreaded; void __fastcall GIFRegHandlerSIGNAL(u32* data) { FUNCLOG - if(!g_GSMultiThreaded) { - SIGLBLID->SIGID = (SIGLBLID->SIGID&~data[1])|(data[0]&data[1]); + + if (!g_GSMultiThreaded) + { + SIGLBLID->SIGID = (SIGLBLID->SIGID & ~data[1]) | (data[0] & data[1]); // if (gs.CSRw & 0x1) CSR->SIGNAL = 1; // if (!IMR->SIGMSK && GSirq) // GSirq(); - if (gs.CSRw & 0x1) { + if (gs.CSRw & 0x1) + { CSR->SIGNAL = 1; //gs.CSRw &= ~1; } - if (!IMR->SIGMSK && GSirq) - GSirq(); + + if (!IMR->SIGMSK && GSirq) GSirq(); } } void __fastcall GIFRegHandlerFINISH(u32* data) { FUNCLOG - if(!g_GSMultiThreaded) { - if (gs.CSRw & 0x2) - CSR->FINISH = 1; - if (!IMR->FINISHMSK && GSirq) - GSirq(); + if (!g_GSMultiThreaded) + { + if (gs.CSRw & 0x2) CSR->FINISH = 1; + + if (!IMR->FINISHMSK && GSirq) GSirq(); // if( gs.CSRw & 2 ) { // //gs.CSRw &= ~2; @@ -1070,7 +1127,9 @@ void __fastcall GIFRegHandlerFINISH(u32* data) void __fastcall GIFRegHandlerLABEL(u32* data) { FUNCLOG - if(!g_GSMultiThreaded) { - SIGLBLID->LBLID = (SIGLBLID->LBLID&~data[1])|(data[0]&data[1]); + + if (!g_GSMultiThreaded) + { + SIGLBLID->LBLID = (SIGLBLID->LBLID & ~data[1]) | (data[0] & data[1]); } } diff --git a/plugins/zzogl-pg/opengl/ZZoglCRTC.cpp b/plugins/zzogl-pg/opengl/ZZoglCRTC.cpp index a432a482e7..be9bb3fee3 100644 --- a/plugins/zzogl-pg/opengl/ZZoglCRTC.cpp +++ b/plugins/zzogl-pg/opengl/ZZoglCRTC.cpp @@ -32,7 +32,7 @@ using namespace ZeroGS; #if !defined(ZEROGS_DEVBUILD) #define g_bSaveFrame 0 #define g_bSaveFinalFrame 0 -#else +#else BOOL g_bSaveFrame = 0; // saves the current psurfTarget BOOL g_bSaveFinalFrame = 0; // saves the input to the CRTC #endif // !defined(ZEROGS_DEVBUILD) @@ -80,40 +80,48 @@ extern vector s_vecTempTextures; // temporary textures, released at the //------------------ Namespace -namespace ZeroGS { - extern int s_nNewWidth, s_nNewHeight; +namespace ZeroGS +{ +extern int s_nNewWidth, s_nNewHeight; - extern CRangeManager s_RangeMngr; // manages overwritten memory - extern void FlushTransferRanges(const tex0Info* ptex); - extern void ProcessMessages(); - void AdjustTransToAspect(Vector& v); +extern CRangeManager s_RangeMngr; // manages overwritten memory +extern void FlushTransferRanges(const tex0Info* ptex); +extern void ProcessMessages(); +void AdjustTransToAspect(Vector& v); - // Interlace texture is lazy 1*(height) array of 1 and 0. - // It height (it named s_nInterlaceTexWidth here) hanging we must redone - // the texture. - // FIXME: If this function would spammed to often, we could use - // width < s_nInterlaceTexWidth as correct for old texture - static int s_nInterlaceTexWidth = 0; // width of texture - inline u32 CreateInterlaceTex(int width) { - if (width == s_nInterlaceTexWidth && s_ptexInterlace != 0) - return s_ptexInterlace; +// Interlace texture is lazy 1*(height) array of 1 and 0. +// If its height (named s_nInterlaceTexWidth here) is hanging we must redo +// the texture. +// FIXME: If this function were spammed too often, we could use +// width < s_nInterlaceTexWidth as correct for old texture +static int s_nInterlaceTexWidth = 0; // width of texture - SAFE_RELEASE_TEX(s_ptexInterlace); - s_nInterlaceTexWidth = width; +inline u32 CreateInterlaceTex(int width) +{ + if (width == s_nInterlaceTexWidth && s_ptexInterlace != 0) return s_ptexInterlace; - vector data(width); - for (int i = 0; i < width; ++i) - data[i] = (i & 1) ? 0xffffffff : 0; + SAFE_RELEASE_TEX(s_ptexInterlace); - glGenTextures(1, &s_ptexInterlace); - glBindTexture(GL_TEXTURE_RECTANGLE_NV, s_ptexInterlace); - glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, 4, width, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); - glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - GL_REPORT_ERRORD(); - return s_ptexInterlace; + s_nInterlaceTexWidth = width; + + vector data(width); + + for (int i = 0; i < width; ++i) + { + data[i] = (i & 1) ? 0xffffffff : 0; } + + glGenTextures(1, &s_ptexInterlace); + glBindTexture(GL_TEXTURE_RECTANGLE_NV, s_ptexInterlace); + glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, 4, width, 1, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); + glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + GL_REPORT_ERRORD(); + + return s_ptexInterlace; } +} + //------------------ Code // Adjusts vertex shader BitBltPos vector v to preserve aspect ratio. It used to emulate 4:3 or 16:9. @@ -132,93 +140,110 @@ void ZeroGS::AdjustTransToAspect(Vector& v) v.w *= f; // scanlines mess up when not aligned right - v.y += (1-(float)modf(v.y*(float)nBackbufferHeight*0.5f+0.05f, &temp))*2.0f/(float)nBackbufferHeight; - v.w += (1-(float)modf(v.w*(float)nBackbufferHeight*0.5f+0.05f, &temp))*2.0f/(float)nBackbufferHeight; + v.y += (1 - (float)modf(v.y * (float)nBackbufferHeight * 0.5f + 0.05f, &temp)) * 2.0f / (float)nBackbufferHeight; + v.w += (1 - (float)modf(v.w * (float)nBackbufferHeight * 0.5f + 0.05f, &temp)) * 2.0f / (float)nBackbufferHeight; } else { // limited by height f = ((float)nBackbufferHeight / (float)conf.height) / ((float)nBackbufferWidth / (float)conf.width); - f -= (float)modf(f*nBackbufferWidth, &temp)/(float)nBackbufferWidth; + f -= (float)modf(f * nBackbufferWidth, &temp) / (float)nBackbufferWidth; v.x *= f; v.z *= f; } - v *= 1/32767.0f; + + v *= 1 / 32767.0f; } // Helper for skip frames. int TimeLastSkip = 0; -inline bool FrameSkippingHelper() +inline bool FrameSkippingHelper() { bool ShouldSkip = false; - - if (g_nFrameRender > 0) + + if (g_nFrameRender > 0) { - if (g_nFrameRender < 8) + if (g_nFrameRender < 8) { g_nFrameRender++; - - if (g_nFrameRender <= 3) + + if (g_nFrameRender <= 3) { g_nFramesSkipped++; ShouldSkip = true; } } } - else + else { - if (g_nFrameRender < -1) + if (g_nFrameRender < -1) { g_nFramesSkipped++; ShouldSkip = true; } + g_nFrameRender--; } #if defined _DEBUG - if (timeGetTime() - TimeLastSkip > 15000 && ShouldSkip) { + if (timeGetTime() - TimeLastSkip > 15000 && ShouldSkip) + { ZZLog::Debug_Log("ZZogl Skipped frames."); TimeLastSkip = timeGetTime(); } + #endif return ShouldSkip; } // helper function for save frame in picture. -inline void FrameSavingHelper() { - if( g_bSaveFrame ) { - if( vb[0].prndr != NULL ) { +inline void FrameSavingHelper() +{ + if (g_bSaveFrame) + { + if (vb[0].prndr != NULL) + { SaveTexture("frame1.tga", GL_TEXTURE_RECTANGLE_NV, vb[0].prndr->ptex, RW(vb[0].prndr->fbw), RH(vb[0].prndr->fbh)); } - if( vb[1].prndr != NULL && vb[0].prndr != vb[1].prndr ) { + if (vb[1].prndr != NULL && vb[0].prndr != vb[1].prndr) + { SaveTexture("frame2.tga", GL_TEXTURE_RECTANGLE_NV, vb[1].prndr->ptex, RW(vb[1].prndr->fbw), RH(vb[1].prndr->fbh)); } + #ifdef _WIN32 - else DeleteFile("frame2.tga"); + else + { + DeleteFile("frame2.tga"); + } #endif } + g_SaveFrameNum = 0; g_bSaveFlushedFrame = 1; } // Function populated tex0Info[2] array -inline void FrameObtainDispinfo(u32 bInterlace, tex0Info* dispinfo) { - for(int i = 0; i < 2; ++i) { +inline void FrameObtainDispinfo(u32 bInterlace, tex0Info* dispinfo) +{ + for (int i = 0; i < 2; ++i) + { - if( !(*(u32*)(PMODE) & (1<MAGH+1; - int magv = pd->MAGV+1; + int magh = pd->MAGH + 1; + int magv = pd->MAGV + 1; dispinfo[i].tbp0 = pfb->FBP << 5; dispinfo[i].tbw = pfb->FBW << 6; @@ -228,7 +253,9 @@ inline void FrameObtainDispinfo(u32 bInterlace, tex0Info* dispinfo) { // hack!! // 2 * dispinfo[i].tw / dispinfo[i].th <= 1, metal slug 4 - if( bInterlace && 2 * dispinfo[i].tw / dispinfo[i].th <= 1 && !(g_GameSettings&GAME_INTERLACE2X) ) { + + if (bInterlace && 2 * dispinfo[i].tw / dispinfo[i].th <= 1 && !(g_GameSettings&GAME_INTERLACE2X)) + { dispinfo[i].th >>= 1; } } @@ -236,7 +263,8 @@ inline void FrameObtainDispinfo(u32 bInterlace, tex0Info* dispinfo) { // Something should be done before Renderer the picture. -inline void RenderStartHelper(u32 bInterlace){ +inline void RenderStartHelper(u32 bInterlace) +{ // Crashes Final Fantasy X at startup if uncommented. --arcum42 //#ifdef !defined(ZEROGS_DEVBUILD) // if(g_nRealFrame < 80 ) { @@ -247,7 +275,7 @@ inline void RenderStartHelper(u32 bInterlace){ // return; // } //#endif - if (conf.mrtdepth && pvs[8] == NULL) + if (conf.mrtdepth && pvs[8] == NULL) { conf.mrtdepth = 0; s_bWriteDepth = FALSE; @@ -261,36 +289,39 @@ inline void RenderStartHelper(u32 bInterlace){ FrameSavingHelper(); - if( s_RangeMngr.ranges.size() > 0 ) + if (s_RangeMngr.ranges.size() > 0) FlushTransferRanges(NULL); SetShaderCaller("RenderStartHelper"); + // reset fba after every frame vb[0].fba.fba = 0; vb[1].fba.fba = 0; - glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); // switch to the backbuffer + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the backbuffer + glViewport(0, 0, nBackbufferWidth, nBackbufferHeight); // if interlace, only clear every other vsync - if(!bInterlace ) + if (!bInterlace) { //u32 color = COLOR_ARGB(0, BGCOLOR->R, BGCOLOR->G, BGCOLOR->B); - glClear(GL_COLOR_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); } SETVERTEXSHADER(pvsBitBlt.prog); + glBindBuffer(GL_ARRAY_BUFFER, vboRect); SET_STREAM(); GL_REPORT_ERRORD(); - if( conf.options & GSOPTION_WIREFRAME ) - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + if (conf.options & GSOPTION_WIREFRAME) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); DisableAllgl() ; + GL_REPORT_ERRORD(); - if( bInterlace ) g_PrevBitwiseTexX = -1; // reset since will be using + if (bInterlace) g_PrevBitwiseTexX = -1; // reset since will be using } // It is setting for intrelace texture multiplied vector; @@ -298,95 +329,116 @@ inline void RenderStartHelper(u32 bInterlace){ // on image y coord. So it we write valpha.z * F + valpha.w + 0.5 it would be swicthig odd // and even strings at each frame // valpha.x and y used for image blending. -inline Vector RenderGetForClip(u32 bInterlace, int interlace, int psm, FRAGMENTSHADER* prog){ +inline Vector RenderGetForClip(u32 bInterlace, int interlace, int psm, FRAGMENTSHADER* prog) +{ SetShaderCaller("RenderGetForClip"); Vector valpha; // first render the current render targets, then from ptexMem - if( psm == 1 ) { + + if (psm == 1) + { valpha.x = 1; valpha.y = 0; } - else { + else + { valpha.x = 0; valpha.y = 1; } - if (bInterlace) { - if( interlace == (conf.interlace&1) ) { + if (bInterlace) + { + if (interlace == (conf.interlace&1)) + { // pass if odd valpha.z = 1.0f; valpha.w = -0.4999f; } - else { + else + { // pass if even valpha.z = -1.0f; valpha.w = 0.5001f; } } - else { + else + { // always pass interlace test valpha.z = 0; valpha.w = 1; } ZZcgSetParameter4fv(prog->sOneColor, valpha, "g_fOneColor"); + return valpha; } // Put interlaced texture in use for shader prog. // Note: if frame interlaced it's th is halved, so we should x2 it. -inline void RenderCreateInterlaceTex(u32 bInterlace, int th, FRAGMENTSHADER* prog) { +inline void RenderCreateInterlaceTex(u32 bInterlace, int th, FRAGMENTSHADER* prog) +{ if (!bInterlace) return; - int interlacetex = CreateInterlaceTex(2*th); + int interlacetex = CreateInterlaceTex(2 * th); + cgGLSetTextureParameter(prog->sInterlace, interlacetex); cgGLEnableTextureParameter(prog->sInterlace); } // Well, do blending setup prior to second pass of half-frame drawing -inline void RenderSetupBlending() { +inline void RenderSetupBlending() +{ // setup right blending glEnable(GL_BLEND); zgsBlendEquationSeparateEXT(GL_FUNC_ADD, GL_FUNC_ADD); - if (PMODE->MMOD) { - glBlendColorEXT(PMODE->ALP*(1/255.0f), PMODE->ALP*(1/255.0f), PMODE->ALP*(1/255.0f), 0.5f); + if (PMODE->MMOD) + { + glBlendColorEXT(PMODE->ALP*(1 / 255.0f), PMODE->ALP*(1 / 255.0f), PMODE->ALP*(1 / 255.0f), 0.5f); s_srcrgb = GL_CONSTANT_COLOR_EXT; s_dstrgb = GL_ONE_MINUS_CONSTANT_COLOR_EXT; } - else { + else + { s_srcrgb = GL_SRC_ALPHA; s_dstrgb = GL_ONE_MINUS_SRC_ALPHA; } s_srcalpha = PMODE->AMOD ? GL_ZERO : GL_ONE; - s_dstalpha = PMODE->AMOD? GL_ONE : GL_ZERO; + + s_dstalpha = PMODE->AMOD ? GL_ONE : GL_ZERO; zgsBlendFuncSeparateEXT(s_srcrgb, s_dstrgb, s_srcalpha, s_dstalpha); } // each frame could be drawed in two stages, so blending should be different for them -inline void RenderSetupStencil(int i) { - glStencilMask(1<fbp)/texframe.tbw; - if( *dby < 0 ) { +inline int RenderGetOffsets(int* dby, int* movy, tex0Info& texframe, CRenderTarget* ptarg, int bpp) +{ + *dby += (256 / bpp) * (texframe.tbp0 - ptarg->fbp) / texframe.tbw; + + if (*dby < 0) + { *movy = -*dby; *dby = 0; } + return min(ptarg->fbh - *dby, texframe.th - *movy); } // BltBit shader calculate vertex (4 coord's pixel) position at the viewport. -inline Vector RenderSetTargetBitPos(int dh, int th, int movy, bool isInterlace) { +inline Vector RenderSetTargetBitPos(int dh, int th, int movy, bool isInterlace) +{ SetShaderCaller("RenderSetTargetBitPos"); Vector v; // dest rect v.x = 1; - v.y = dh/(float)th; + v.y = dh / (float)th; v.z = 0; - v.w = 1-v.y; + v.w = 1 - v.y; - if( movy > 0 ) - v.w -= movy/(float)th; + if (movy > 0) v.w -= movy / (float)th; AdjustTransToAspect(v); - if (isInterlace) { + if (isInterlace) + { // move down by 1 pixel v.w += 1.0f / (float)dh ; } ZZcgSetParameter4fv(pvsBitBlt.sBitBltPos, v, "g_fBitBltPos"); + return v; } @@ -450,62 +510,73 @@ inline Vector RenderSetTargetBitPos(int dh, int th, int movy, bool isInterlace) // For example use tw / X and tw / X magnify the vieport. // Interlaced output is little out of VB, it could be see as evil blinking line on top // and bottom, so we try to remove it -inline Vector RenderSetTargetBitTex(float th, float tw, float dh, float dw, bool isInterlace) { +inline Vector RenderSetTargetBitTex(float th, float tw, float dh, float dw, bool isInterlace) +{ SetShaderCaller("RenderSetTargetBitTex"); Vector v; v = Vector(th, tw, dh, dw); // Incorrect Aspect ratio on interlaced frames - if (isInterlace) + + if (isInterlace) { - v.y -= 1.0f/conf.height; - v.w += 1.0f/conf.height; + v.y -= 1.0f / conf.height; + v.w += 1.0f / conf.height; } ZZcgSetParameter4fv(pvsBitBlt.sBitBltTex, v, "g_fBitBltTex"); + return v; } // Translator for POSITION coordinats (-1.0:+1.0f at x axis, +1.0f:-1.0y at y) into target frame ones // We don't need x coordinate, bvecause interlacing is y-axis only. -inline Vector RenderSetTargetBitTrans(int th) { +inline Vector RenderSetTargetBitTrans(int th) +{ SetShaderCaller("RenderSetTargetBitTrans"); - Vector v = Vector( float(th), -float(th), float(th), float(th)); + Vector v = Vector(float(th), -float(th), float(th), float(th)); ZZcgSetParameter4fv(pvsBitBlt.fBitBltTrans, v, "g_fBitBltTrans"); return v; } // use g_fInvTexDims to store inverse texture dims // Seems, that Targ shader does not use it -inline Vector RenderSetTargetInvTex(int bInterlace, int tw, int th, FRAGMENTSHADER* prog) { +inline Vector RenderSetTargetInvTex(int bInterlace, int tw, int th, FRAGMENTSHADER* prog) +{ SetShaderCaller("RenderSetTargetInvTex"); Vector v = Vector(0, 0, 0, 0); - if (prog->sInvTexDims) { + + if (prog->sInvTexDims) + { v.x = 1.0f / (float)tw; v.y = 1.0f / (float)th; v.z = (float)0.0; v.w = -0.5f / (float)th; ZZcgSetParameter4fv(prog->sInvTexDims, v, "g_fInvTexDims"); } + return v; } // Metal Slug 5 hack (as was written). If tarhet tbp not equal to framed fbp, than we look for better possibility, // Note, than after true result iterator it could not be use. -inline bool RenderLookForABetterTarget(int fbp, int tbp, list& listTargs, list::iterator& it) { +inline bool RenderLookForABetterTarget(int fbp, int tbp, list& listTargs, list::iterator& it) +{ if (fbp == tbp) return false; // look for a better target (metal slug 5) list::iterator itbetter; - for(itbetter = listTargs.begin(); itbetter != listTargs.end(); ++itbetter ) { - if( (*itbetter)->fbp == tbp ) - break; + + for (itbetter = listTargs.begin(); itbetter != listTargs.end(); ++itbetter) + { + if ((*itbetter)->fbp == tbp) break; } - if( itbetter != listTargs.end() ) { + if (itbetter != listTargs.end()) + { it = listTargs.erase(it); return true; } @@ -514,7 +585,8 @@ inline bool RenderLookForABetterTarget(int fbp, int tbp, list& l } // First try to draw frame from targets. It's -inline bool RenderCheckForTargets(tex0Info& texframe, list& listTargs, int i, bool* bUsingStencil, int interlace, int bInterlace) { +inline bool RenderCheckForTargets(tex0Info& texframe, list& listTargs, int i, bool* bUsingStencil, int interlace, int bInterlace) +{ // get the start and end addresses of the buffer int bpp = RenderGetBpp(texframe.psm); GSRegDISPFB* pfb = i ? DISPFB2 : DISPFB1; @@ -525,30 +597,33 @@ inline bool RenderCheckForTargets(tex0Info& texframe, list& list // We need share list of targets beetween functions s_RTs.GetTargs(start, end, listTargs); - for(list::iterator it = listTargs.begin(); it != listTargs.end(); ) { + for (list::iterator it = listTargs.begin(); it != listTargs.end();) + { CRenderTarget* ptarg = *it; - if( ptarg->fbw == texframe.tbw && !(ptarg->status&CRenderTarget::TS_NeedUpdate) && ((256/bpp)*(texframe.tbp0-ptarg->fbp))%texframe.tbw == 0 ) { - if (RenderLookForABetterTarget(ptarg->fbp, texframe.tbp0, listTargs, it)) - continue; + if (ptarg->fbw == texframe.tbw && !(ptarg->status&CRenderTarget::TS_NeedUpdate) && ((256 / bpp)*(texframe.tbp0 - ptarg->fbp)) % texframe.tbw == 0) + { + if (RenderLookForABetterTarget(ptarg->fbp, texframe.tbp0, listTargs, it)) continue; - if( g_bSaveFinalFrame ) - SaveTexture("frame1.tga", GL_TEXTURE_RECTANGLE_NV, ptarg->ptex, RW(ptarg->fbw), RH(ptarg->fbh)); + if (g_bSaveFinalFrame) SaveTexture("frame1.tga", GL_TEXTURE_RECTANGLE_NV, ptarg->ptex, RW(ptarg->fbw), RH(ptarg->fbh)); // determine the rectangle to render int dby = pfb->DBY; int movy = 0; int dh = RenderGetOffsets(&dby, &movy, texframe, ptarg, bpp); - if( dh >= 64 ) { + if (dh >= 64) + { - if( ptarg->fbh - dby < texframe.th - movy && !(*bUsingStencil) ) + if (ptarg->fbh - dby < texframe.th - movy && !(*bUsingStencil)) RenderUpdateStencil(i, bUsingStencil); SetShaderCaller("RenderCheckForTargets"); + // Texture - Vector v = RenderSetTargetBitTex((float)RW(texframe.tw), (float)RH(dh), (float)RW(pfb->DBX), (float)RH(dby), INTERLACE_COUNT ); + Vector v = RenderSetTargetBitTex((float)RW(texframe.tw), (float)RH(dh), (float)RW(pfb->DBX), (float)RH(dby), INTERLACE_COUNT); + // dest rect v = RenderSetTargetBitPos(dh, texframe.th, movy, INTERLACE_COUNT); v = RenderSetTargetBitTrans(ptarg->fbh); @@ -559,37 +634,45 @@ inline bool RenderCheckForTargets(tex0Info& texframe, list& list // inside vb[0]'s target area, so render that region only cgGLSetTextureParameter(ppsCRTCTarg[bInterlace].sFinal, ptarg->ptex); cgGLEnableTextureParameter(ppsCRTCTarg[bInterlace].sFinal); - RenderCreateInterlaceTex(bInterlace, texframe.th, &ppsCRTCTarg[bInterlace]); SETPIXELSHADER(ppsCRTCTarg[bInterlace].prog); + GL_REPORT_ERRORD(); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - if( abs(dh - (int)texframe.th) <= 1 ) - return true; + if (abs(dh - (int)texframe.th) <= 1) return true; - if( abs(dh - (int)ptarg->fbh) <= 1 ) { + if (abs(dh - (int)ptarg->fbh) <= 1) + { it = listTargs.erase(it); continue; } } } + ++it; } + return false; } -// The same of the previous, but from memory -inline void RenderCheckForMemory(tex0Info& texframe, list& listTargs, int interlace, int bInterlace) { +// The same as the previous, but from memory. +// If you ever wondered why a picture from a minute ago suddenly flashes on the screen (say, in Mana Khemia), +// this is the function that does it. +inline void RenderCheckForMemory(tex0Info& texframe, list& listTargs, int interlace, int bInterlace) +{ - for(list::iterator it = listTargs.begin(); it != listTargs.end(); ++it) + for (list::iterator it = listTargs.begin(); it != listTargs.end(); ++it) + { (*it)->Resolve(); + } // context has to be 0 CMemoryTarget* pmemtarg = g_MemTargs.GetMemoryTarget(texframe, 1); + if ((pmemtarg == NULL) || (bInterlace >= 2)) ZZLog::Error_Log("CRCR Check for memory shader fault."); @@ -599,56 +682,62 @@ inline void RenderCheckForMemory(tex0Info& texframe, list& listT cgGLSetTextureParameter(ppsCRTC[bInterlace].sMemory, pmemtarg->ptex->tex); cgGLEnableTextureParameter(ppsCRTC[bInterlace].sMemory); - if( g_bSaveFinalFrame ) - SaveTex(&texframe, g_bSaveFinalFrame - 1 > 0); + if (g_bSaveFinalFrame) SaveTex(&texframe, g_bSaveFinalFrame - 1 > 0); // finally render from the memory (note that the stencil buffer will keep previous regions) Vector v = RenderSetTargetBitPos(1, 1, 0, INTERLACE_COUNT); - // Fixme: Why this if here? - if( g_bCRTCBilinear ) - ZZcgSetParameter4fv(pvsBitBlt.sBitBltTex, Vector(texframe.tw,texframe.th,-0.5f,-0.5f), "g_fBitBltTex"); + // Fixme: Why is this here? + // We should probably call RenderSetTargetBitTex instead. + if (g_bCRTCBilinear) + ZZcgSetParameter4fv(pvsBitBlt.sBitBltTex, Vector(texframe.tw, texframe.th, -0.5f, -0.5f), "g_fBitBltTex"); else - ZZcgSetParameter4fv(pvsBitBlt.sBitBltTex, Vector(1,1,-0.5f/(float)texframe.tw,-0.5f/(float)texframe.th), "g_fBitBltTex"); + ZZcgSetParameter4fv(pvsBitBlt.sBitBltTex, Vector(1, 1, -0.5f / (float)texframe.tw, -0.5f / (float)texframe.th), "g_fBitBltTex"); v = RenderSetTargetBitTrans(texframe.th); + v = RenderSetTargetInvTex(bInterlace, texframe.tw, texframe.th, &ppsCRTC[bInterlace]); Vector valpha = RenderGetForClip(bInterlace, interlace, texframe.psm, &ppsCRTC[bInterlace]); + RenderCreateInterlaceTex(bInterlace, texframe.th, &ppsCRTC[bInterlace]); SETPIXELSHADER(ppsCRTC[bInterlace].prog); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); } // Put FPS counter on scren (not in window title) -inline void AfterRenderDisplayFPS() { +inline void AfterRenderDisplayFPS() +{ char str[64]; int left = 10, top = 15; sprintf(str, "%.1f fps", fFPS); - DrawText(str, left+1, top+1, 0xff000000); + DrawText(str, left + 1, top + 1, 0xff000000); DrawText(str, left, top, 0xffc0ffff); } -// Swaping buffers, so we could use another windows -inline void AfterRenderSwapBuffers() { - if (glGetError() != GL_NO_ERROR) - ZZLog::Debug_Log("glError before swap!"); +// Swapping buffers, so we could use another windows +inline void AfterRenderSwapBuffers() +{ + if (glGetError() != GL_NO_ERROR) ZZLog::Debug_Log("glError before swap!"); GLWin.SwapGLBuffers(); } // SnapeShoot helper -inline void AfterRenderMadeSnapshoot() { +inline void AfterRenderMadeSnapshoot() +{ char str[64]; int left = 200, top = 15; - sprintf(str, "ZeroGS %d.%d.%d - %.1f fps %s", zgsrevision, zgsbuild, zgsminor, fFPS, s_frameskipping?" - frameskipping":""); + sprintf(str, "ZeroGS %d.%d.%d - %.1f fps %s", zgsrevision, zgsbuild, zgsminor, fFPS, s_frameskipping ? " - frameskipping" : ""); - DrawText(str, left+1, top+1, 0xff000000); + DrawText(str, left + 1, top + 1, 0xff000000); DrawText(str, left, top, 0xffc0ffff); - if( SaveRenderTarget(strSnapshot != ""?strSnapshot.c_str():"temp.jpg", nBackbufferWidth, -nBackbufferHeight, 0)) {//(conf.options&GSOPTION_TGASNAP)?0:1) ) { + if (SaveRenderTarget(strSnapshot != "" ? strSnapshot.c_str() : "temp.jpg", nBackbufferWidth, -nBackbufferHeight, 0)) //(conf.options&GSOPTION_TGASNAP)?0:1) ) { + { char str[255]; sprintf(str, "saved %s\n", strSnapshot.c_str()); AddMessage(str, 500); @@ -656,84 +745,98 @@ inline void AfterRenderMadeSnapshoot() { } // If needed reset -inline void AfterRendererResizeWindow() { +inline void AfterRendererResizeWindow() +{ Reset(); ChangeDeviceSize(s_nNewWidth, s_nNewHeight); s_nNewWidth = s_nNewHeight = -1; } // Put new values on statistic variable -inline void AfterRenderCountStatistics() { - if( s_nWriteDepthCount > 0 ) { - assert( conf.mrtdepth ); - if( --s_nWriteDepthCount <= 0 ) { +inline void AfterRenderCountStatistics() +{ + if (s_nWriteDepthCount > 0) + { + assert(conf.mrtdepth); + + if (--s_nWriteDepthCount <= 0) + { s_bWriteDepth = FALSE; } } - if( s_nWriteDestAlphaTest > 0 ) { - if( --s_nWriteDestAlphaTest <= 0 ) { + if (s_nWriteDestAlphaTest > 0) + { + if (--s_nWriteDestAlphaTest <= 0) + { s_bDestAlphaTest = FALSE; } } - if( g_nDepthUsed > 0 ) --g_nDepthUsed; + if (g_nDepthUsed > 0) --g_nDepthUsed; s_ClutResolve = 0; + g_nDepthUpdateCount = 0; } // This all could be easily forefeit -inline void AfterRendererUnimportantJob() { +inline void AfterRendererUnimportantJob() +{ ProcessMessages(); - if( g_bDisplayFPS ) - AfterRenderDisplayFPS(); + if (g_bDisplayFPS) AfterRenderDisplayFPS(); AfterRenderSwapBuffers(); - if( conf.options & GSOPTION_WIREFRAME ) { + if (conf.options & GSOPTION_WIREFRAME) + { // clear all targets s_nWireframeCount = 1; } - if( g_bMakeSnapshot ) { + if (g_bMakeSnapshot) + { AfterRenderMadeSnapshoot(); g_bMakeSnapshot = 0; } - if( s_avicapturing ) + if (s_avicapturing) CaptureFrame(); AfterRenderCountStatistics(); - if( s_nNewWidth >= 0 && s_nNewHeight >= 0 && !g_bIsLost ) + if (s_nNewWidth >= 0 && s_nNewHeight >= 0 && !g_bIsLost) AfterRendererResizeWindow(); maxmin = 608; } // Swich Frabuffers -inline void AfterRendererSwitchBackToTextures() { - glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, s_uFramebuffer ); +inline void AfterRendererSwitchBackToTextures() +{ + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, s_uFramebuffer); g_MemTargs.DestroyCleared(); - if( s_vecTempTextures.size() > 0 ) + if (s_vecTempTextures.size() > 0) glDeleteTextures((GLsizei)s_vecTempTextures.size(), &s_vecTempTextures[0]); + s_vecTempTextures.clear(); - if (EXTWRITE->WRITE & 1) + if (EXTWRITE->WRITE & 1) { ZZLog::Warn_Log("EXTWRITE!"); ExtWrite(); EXTWRITE->WRITE = 0; } - if( conf.options & GSOPTION_WIREFRAME ) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + if (conf.options & GSOPTION_WIREFRAME) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glEnable(GL_SCISSOR_TEST); - if( icurctx >= 0 ) { + if (icurctx >= 0) + { vb[icurctx].bVarsSetTarg = FALSE; vb[icurctx].bVarsTexSync = FALSE; vb[0].bVarsTexSync = FALSE; @@ -741,70 +844,81 @@ inline void AfterRendererSwitchBackToTextures() { } // Reset Targets Helper, for hack. -inline void AfterRendererAutoresetTargets() { - if( g_GameSettings & GAME_AUTORESET ) { +inline void AfterRendererAutoresetTargets() +{ + if (g_GameSettings & GAME_AUTORESET) + { s_nResolveCounts[s_nCurResolveIndex] = s_nResolved; - s_nCurResolveIndex = (s_nCurResolveIndex+1)%ARRAY_SIZE(s_nResolveCounts); + s_nCurResolveIndex = (s_nCurResolveIndex + 1) % ARRAY_SIZE(s_nResolveCounts); int total = 0; - for(int i = 0; i < ARRAY_SIZE(s_nResolveCounts); ++i) total += s_nResolveCounts[i]; - if( total / ARRAY_SIZE(s_nResolveCounts) > 3 ) { - if( s_nLastResolveReset > (int)(fFPS * 8) ) { + for (int i = 0; i < ARRAY_SIZE(s_nResolveCounts); ++i) total += s_nResolveCounts[i]; + + if (total / ARRAY_SIZE(s_nResolveCounts) > 3) + { + if (s_nLastResolveReset > (int)(fFPS * 8)) + { // reset ZZLog::Error_Log("Video memory reset."); s_nLastResolveReset = 0; memset(s_nResolveCounts, 0, sizeof(s_nResolveCounts)); s_RTs.ResolveAll(); - return; + return; s_RTs.Destroy(); s_DepthRTs.ResolveAll(); s_DepthRTs.Destroy(); - vb[0].prndr = NULL; vb[0].pdepth = NULL; vb[0].bNeedFrameCheck = 1; vb[0].bNeedZCheck = 1; - vb[1].prndr = NULL; vb[1].pdepth = NULL; vb[1].bNeedFrameCheck = 1; vb[1].bNeedZCheck = 1; + vb[0].prndr = NULL; + vb[0].pdepth = NULL; + vb[0].bNeedFrameCheck = 1; + vb[0].bNeedZCheck = 1; + vb[1].prndr = NULL; + vb[1].pdepth = NULL; + vb[1].bNeedFrameCheck = 1; + vb[1].bNeedZCheck = 1; } } s_nLastResolveReset++; } - if( s_nResolved > 8 ) s_nResolved = 2; - else if( s_nResolved > 0 ) --s_nResolved; + if (s_nResolved > 8) + s_nResolved = 2; + else if (s_nResolved > 0) + --s_nResolved; } int count = 0; // The main renderer function void ZeroGS::RenderCRTC(int interlace) { - if( g_bIsLost ) return; + if (g_bIsLost) return; if (FrameSkippingHelper()) return; u32 bInterlace = SMODE2->INT && SMODE2->FFMD && (conf.interlace < 2); - RenderStartHelper(bInterlace); - bool bUsingStencil = 0; + RenderStartHelper(bInterlace); + + bool bUsingStencil = 0; tex0Info dispinfo[2]; - FrameObtainDispinfo(bInterlace, dispinfo); + + FrameObtainDispinfo(bInterlace, dispinfo); // start from the last circuit - for(int i = !PMODE->SLBG; i >= 0; --i) { + for (int i = !PMODE->SLBG; i >= 0; --i) + { tex0Info& texframe = dispinfo[i]; - if( texframe.th <= 1 ) - continue; - if (SMODE2->INT && SMODE2->FFMD) - texframe.th >>= 1; + if (texframe.th <= 1) continue; + if (SMODE2->INT && SMODE2->FFMD) texframe.th >>= 1; + if (i == 0) RenderSetupBlending(); + if (bUsingStencil) RenderSetupStencil(i); - if( i == 0 ) - RenderSetupBlending(); - - if( bUsingStencil ) - RenderSetupStencil(i); - - if( texframe.psm == 0x12 ) { + if (texframe.psm == 0x12) + { RenderCRTC24helper(bInterlace, interlace, texframe.psm); continue; } @@ -813,7 +927,7 @@ void ZeroGS::RenderCRTC(int interlace) list listTargs; // if we could not draw image from target's do it from memory - if ( !RenderCheckForTargets(texframe, listTargs, i, &bUsingStencil, interlace, bInterlace) ) + if (!RenderCheckForTargets(texframe, listTargs, i, &bUsingStencil, interlace, bInterlace)) RenderCheckForMemory(texframe, listTargs, interlace, bInterlace); } diff --git a/plugins/zzogl-pg/opengl/ZZoglCreate.cpp b/plugins/zzogl-pg/opengl/ZZoglCreate.cpp index 4a361e653d..85fa4af53c 100644 --- a/plugins/zzogl-pg/opengl/ZZoglCreate.cpp +++ b/plugins/zzogl-pg/opengl/ZZoglCreate.cpp @@ -79,59 +79,60 @@ #define VB_NUMBUFFERS 512 // ----------------- Types -typedef void (APIENTRYP _PFNSWAPINTERVAL) (int); +typedef void (APIENTRYP _PFNSWAPINTERVAL)(int); map mapGLExtensions; -namespace ZeroGS{ - RenderFormatType g_RenderFormatType = RFT_float16; +namespace ZeroGS +{ +RenderFormatType g_RenderFormatType = RFT_float16; - extern void KickPoint(); - extern void KickLine(); - extern void KickTriangle(); - extern void KickTriangleFan(); - extern void KickSprite(); - extern void KickDummy(); - extern bool LoadEffects(); - extern bool LoadExtraEffects(); - extern FRAGMENTSHADER* LoadShadeEffect(int type, int texfilter, int fog, int testaem, int exactcolor, const clampInfo& clamp, int context, bool* pbFailed); - VERTEXSHADER pvsBitBlt; +extern void KickPoint(); +extern void KickLine(); +extern void KickTriangle(); +extern void KickTriangleFan(); +extern void KickSprite(); +extern void KickDummy(); +extern bool LoadEffects(); +extern bool LoadExtraEffects(); +extern FRAGMENTSHADER* LoadShadeEffect(int type, int texfilter, int fog, int testaem, int exactcolor, const clampInfo& clamp, int context, bool* pbFailed); +VERTEXSHADER pvsBitBlt; - GLuint vboRect = 0; - vector g_vboBuffers; // VBOs for all drawing commands - int g_nCurVBOIndex = 0; +GLuint vboRect = 0; +vector g_vboBuffers; // VBOs for all drawing commands +int g_nCurVBOIndex = 0; - inline bool CreateImportantCheck(); - inline void CreateOtherCheck(); - inline bool CreateOpenShadersFile(); +inline bool CreateImportantCheck(); +inline void CreateOtherCheck(); +inline bool CreateOpenShadersFile(); } //------------------ Dummies #ifdef _WIN32 - void __stdcall glBlendFuncSeparateDummy(GLenum e1, GLenum e2, GLenum e3, GLenum e4) +void __stdcall glBlendFuncSeparateDummy(GLenum e1, GLenum e2, GLenum e3, GLenum e4) #else - void APIENTRY glBlendFuncSeparateDummy(GLenum e1, GLenum e2, GLenum e3, GLenum e4) +void APIENTRY glBlendFuncSeparateDummy(GLenum e1, GLenum e2, GLenum e3, GLenum e4) #endif - { - glBlendFunc(e1, e2); - } +{ + glBlendFunc(e1, e2); +} #ifdef _WIN32 - void __stdcall glBlendEquationSeparateDummy(GLenum e1, GLenum e2) +void __stdcall glBlendEquationSeparateDummy(GLenum e1, GLenum e2) #else - void APIENTRY glBlendEquationSeparateDummy(GLenum e1, GLenum e2) +void APIENTRY glBlendEquationSeparateDummy(GLenum e1, GLenum e2) #endif - { - glBlendEquation(e1); - } +{ + glBlendEquation(e1); +} #ifdef _WIN32 - extern HINSTANCE hInst; - void (__stdcall *zgsBlendEquationSeparateEXT)(GLenum, GLenum) = NULL; - void (__stdcall *zgsBlendFuncSeparateEXT)(GLenum, GLenum, GLenum, GLenum) = NULL; +extern HINSTANCE hInst; +void (__stdcall *zgsBlendEquationSeparateEXT)(GLenum, GLenum) = NULL; +void (__stdcall *zgsBlendFuncSeparateEXT)(GLenum, GLenum, GLenum, GLenum) = NULL; #else - void (APIENTRY *zgsBlendEquationSeparateEXT)(GLenum, GLenum) = NULL; - void (APIENTRY *zgsBlendFuncSeparateEXT)(GLenum, GLenum, GLenum, GLenum) = NULL; +void (APIENTRY *zgsBlendEquationSeparateEXT)(GLenum, GLenum) = NULL; +void (APIENTRY *zgsBlendFuncSeparateEXT)(GLenum, GLenum, GLenum, GLenum) = NULL; #endif //------------------ variables @@ -144,8 +145,8 @@ CGprogram pvs[16] = {NULL}; // String's for shader file in developer mode #ifdef DEVBUILD -char* EFFECT_NAME=""; -char* EFFECT_DIR=""; +char* EFFECT_NAME = ""; +char* EFFECT_DIR = ""; #endif ///////////////////// @@ -183,52 +184,64 @@ BOOL g_bSaveFlushedFrame = 0; //------------------ Code -bool ZeroGS::IsGLExt( const char* szTargetExtension ) +bool ZeroGS::IsGLExt(const char* szTargetExtension) { return mapGLExtensions.find(string(szTargetExtension)) != mapGLExtensions.end(); } inline bool -ZeroGS::Create_Window(int _width, int _height) { +ZeroGS::Create_Window(int _width, int _height) +{ nBackbufferWidth = _width; nBackbufferHeight = _height; fiRendWidth = 1.0f / nBackbufferWidth; fiRendHeight = 1.0f / nBackbufferHeight; + if (!GLWin.DisplayWindow(_width, _height)) return false; s_nFullscreen = (conf.options & GSOPTION_FULLSCREEN) ? 1 : 0; + conf.mrtdepth = 0; // for now return true; } // Function asks about different OGL extensions, that are required to setup accordingly. Return false if checks failed -inline bool ZeroGS::CreateImportantCheck() { +inline bool ZeroGS::CreateImportantCheck() +{ bool bSuccess = true; #ifndef _WIN32 int const glew_ok = glewInit(); - if( glew_ok != GLEW_OK ) { + + if (glew_ok != GLEW_OK) + { ZZLog::Error_Log("glewInit() is not ok!"); bSuccess = false; } + #endif - if( !IsGLExt("GL_EXT_framebuffer_object") ) { + if (!IsGLExt("GL_EXT_framebuffer_object")) + { ZZLog::Error_Log("*********\nZZogl: ERROR: Need GL_EXT_framebufer_object for multiple render targets\nZZogl: *********"); bSuccess = false; } - if( !IsGLExt("GL_EXT_secondary_color") ) { + if (!IsGLExt("GL_EXT_secondary_color")) + { ZZLog::Error_Log("*********\nZZogl: OGL WARNING: Need GL_EXT_secondary_color\nZZogl: *********"); bSuccess = false; } // load the effect & find the best profiles (if any) - if( cgGLIsProfileSupported(CG_PROFILE_ARBVP1) != CG_TRUE ) { + if (cgGLIsProfileSupported(CG_PROFILE_ARBVP1) != CG_TRUE) + { ZZLog::Error_Log("arbvp1 not supported."); bSuccess = false; } - if( cgGLIsProfileSupported(CG_PROFILE_ARBFP1) != CG_TRUE ) { + + if (cgGLIsProfileSupported(CG_PROFILE_ARBFP1) != CG_TRUE) + { ZZLog::Error_Log("arbfp1 not supported."); bSuccess = false; } @@ -237,43 +250,51 @@ inline bool ZeroGS::CreateImportantCheck() { } // This is a check for less important open gl extensions. -inline void ZeroGS::CreateOtherCheck() { - if( !IsGLExt("GL_EXT_blend_equation_separate") || glBlendEquationSeparateEXT == NULL ) { +inline void ZeroGS::CreateOtherCheck() +{ + if (!IsGLExt("GL_EXT_blend_equation_separate") || glBlendEquationSeparateEXT == NULL) + { ZZLog::Error_Log("*********\nZZogl: OGL WARNING: Need GL_EXT_blend_equation_separate\nZZogl: *********"); zgsBlendEquationSeparateEXT = glBlendEquationSeparateDummy; } else zgsBlendEquationSeparateEXT = glBlendEquationSeparateEXT; - if( !IsGLExt("GL_EXT_blend_func_separate") || glBlendFuncSeparateEXT == NULL ) { + if (!IsGLExt("GL_EXT_blend_func_separate") || glBlendFuncSeparateEXT == NULL) + { ZZLog::Error_Log("*********\nZZogl: OGL WARNING: Need GL_EXT_blend_func_separate\nZZogl: *********"); zgsBlendFuncSeparateEXT = glBlendFuncSeparateDummy; } else zgsBlendFuncSeparateEXT = glBlendFuncSeparateEXT; - if( !IsGLExt("GL_ARB_draw_buffers") && !IsGLExt("GL_ATI_draw_buffers") ) { + if (!IsGLExt("GL_ARB_draw_buffers") && !IsGLExt("GL_ATI_draw_buffers")) + { ZZLog::Error_Log("*********\nZZogl: OGL WARNING: multiple render targets not supported, some effects might look bad\nZZogl: *********"); conf.mrtdepth = 0; } - if( IsGLExt("GL_ARB_draw_buffers") ) + if (IsGLExt("GL_ARB_draw_buffers")) glDrawBuffers = (PFNGLDRAWBUFFERSPROC)wglGetProcAddress("glDrawBuffers"); - else if( IsGLExt("GL_ATI_draw_buffers") ) + else if (IsGLExt("GL_ATI_draw_buffers")) glDrawBuffers = (PFNGLDRAWBUFFERSPROC)wglGetProcAddress("glDrawBuffersATI"); - if (!IsGLExt("GL_ARB_multitexture")) + if (!IsGLExt("GL_ARB_multitexture")) ZZLog::Error_Log("No multitexturing."); else ZZLog::Error_Log("Using multitexturing."); GLint Max_Texture_Size_NV = 0; + GLint Max_Texture_Size_2d = 0; glGetIntegerv(GL_MAX_RECTANGLE_TEXTURE_SIZE_NV, &Max_Texture_Size_NV); + glGetIntegerv(GL_MAX_TEXTURE_SIZE, &Max_Texture_Size_2d); + ZZLog::Error_Log("Maximum texture size is %d for Tex_2d and %d for Tex_NV.", Max_Texture_Size_2d, Max_Texture_Size_NV); + if (Max_Texture_Size_NV < 1024) ZZLog::Error_Log("Could not properly make bitmasks, so some textures will be missed."); @@ -291,44 +312,56 @@ inline void ZeroGS::CreateOtherCheck() { g_RenderFormatType = RFT_byte8; #ifdef _WIN32 - if( IsGLExt("WGL_EXT_swap_control") || IsGLExt("EXT_swap_control") ) + if (IsGLExt("WGL_EXT_swap_control") || IsGLExt("EXT_swap_control")) wglSwapIntervalEXT(0); + #else - if( IsGLExt("GLX_SGI_swap_control") ) { + if (IsGLExt("GLX_SGI_swap_control")) + { _PFNSWAPINTERVAL swapinterval = (_PFNSWAPINTERVAL)wglGetProcAddress("glXSwapInterval"); - if( !swapinterval ) + + if (!swapinterval) swapinterval = (_PFNSWAPINTERVAL)wglGetProcAddress("glXSwapIntervalSGI"); - if( !swapinterval ) + + if (!swapinterval) swapinterval = (_PFNSWAPINTERVAL)wglGetProcAddress("glXSwapIntervalEXT"); - if( swapinterval ) + if (swapinterval) swapinterval(0); else ZZLog::Error_Log("No support for SwapInterval (framerate clamped to monitor refresh rate),"); } + #endif } // open shader file according to build target -inline bool ZeroGS::CreateOpenShadersFile() { +inline bool ZeroGS::CreateOpenShadersFile() +{ #ifndef DEVBUILD # ifdef _WIN32 HRSRC hShaderSrc = FindResource(hInst, MAKEINTRESOURCE(IDR_SHADERS), RT_RCDATA); - assert( hShaderSrc != NULL ); + assert(hShaderSrc != NULL); HGLOBAL hShaderGlob = LoadResource(hInst, hShaderSrc); - assert( hShaderGlob != NULL ); + assert(hShaderGlob != NULL); s_lpShaderResources = (u8*)LockResource(hShaderGlob); # else // not _WIN32 FILE* fres = fopen("ps2hw.dat", "rb"); - if( fres == NULL ) { + + if (fres == NULL) + { fres = fopen("plugins/ps2hw.dat", "rb"); - if( fres == NULL ) { + + if (fres == NULL) + { ZZLog::Error_Log("Cannot find ps2hw.dat in working directory. Exiting."); return false; } } + fseek(fres, 0, SEEK_END); + size_t s = ftell(fres); s_lpShaderResources = new u8[s+1]; fseek(fres, 0, SEEK_SET); @@ -345,42 +378,49 @@ inline bool ZeroGS::CreateOpenShadersFile() { strcpy(tempstr, "/plugins/"); sprintf(EFFECT_NAME, "%sps2hw.fx", tempstr); FILE* f = fopen(EFFECT_NAME, "r"); - if( f == NULL ) { + + if (f == NULL) + { strcpy(tempstr, "../../plugins/zzogl-pg/opengl/"); sprintf(EFFECT_NAME, "%sps2hw.fx", tempstr); f = fopen(EFFECT_NAME, "r"); - if( f == NULL ) { + if (f == NULL) + { ZZLog::Error_Log("Failed to find %s, try compiling a non-devbuild.", EFFECT_NAME); return false; } } + fclose(f); sprintf(EFFECT_DIR, "%s/%s", curwd, tempstr); sprintf(EFFECT_NAME, "%sps2hw.fx", EFFECT_DIR); - #endif +#endif #endif // !defined(ZEROGS_DEVBUILD) return true; } // Read all extensions name and fill mapGLExtensions -inline bool CreateFillExtensionsMap(){ +inline bool CreateFillExtensionsMap() +{ // fill the opengl extension map - const char* ptoken = (const char*)glGetString( GL_EXTENSIONS ); - if( ptoken == NULL ) return false; + const char* ptoken = (const char*)glGetString(GL_EXTENSIONS); + + if (ptoken == NULL) return false; int prevlog = conf.log; + conf.log = 1; - + ZZLog::GS_Log("Supported OpenGL Extensions:\n%s\n", ptoken); // write to the log file - + // Probably a better way to do it, but seems to crash. /*int n; glGetIntegerv(GL_NUM_EXTENSIONS, &n); ZZLog::GS_Log("Supported OpenGL Extensions:\n"); - for (int i = 0; i < n; i++) + for (int i = 0; i < n; i++) { ZZLog::GS_Log("%s/n", (const char*)glGetStringi(GL_EXTENSIONS, i)); }*/ @@ -391,20 +431,25 @@ inline bool CreateFillExtensionsMap(){ const char* pend = NULL; - while(ptoken != NULL ) { + while (ptoken != NULL) + { pend = strchr(ptoken, ' '); - if( pend != NULL ) { + if (pend != NULL) + { mapGLExtensions[string(ptoken, pend-ptoken)]; } - else { + else + { mapGLExtensions[string(ptoken)]; break; } ptoken = pend; - while(*ptoken == ' ') ++ptoken; + + while (*ptoken == ' ') ++ptoken; } + return true; } @@ -426,20 +471,21 @@ bool ZeroGS::Create(int _width, int _height) if (!Create_Window(_width, _height)) return false; if (!CreateFillExtensionsMap()) return false; if (!CreateImportantCheck()) return false; - + ZeroGS::CreateOtherCheck(); // check the max texture width and height glGetIntegerv(GL_MAX_TEXTURE_SIZE, &g_MaxTexWidth); - g_MaxTexHeight = g_MaxTexWidth/4; - GPU_TEXWIDTH = g_MaxTexWidth/8; + + g_MaxTexHeight = g_MaxTexWidth / 4; + GPU_TEXWIDTH = g_MaxTexWidth / 8; g_fiGPU_TEXWIDTH = 1.0f / GPU_TEXWIDTH; - if (!CreateOpenShadersFile()) - return false; + if (!CreateOpenShadersFile()) return false; GL_REPORT_ERROR(); - if( err != GL_NO_ERROR ) bSuccess = false; + + if (err != GL_NO_ERROR) bSuccess = false; s_srcrgb = s_dstrgb = s_srcalpha = s_dstalpha = GL_ONE; @@ -461,28 +507,31 @@ bool ZeroGS::Create(int _width, int _height) GL_LOADFN(glGetFramebufferAttachmentParameterivEXT); GL_LOADFN(glGenerateMipmapEXT); - glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); - + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); GL_REPORT_ERROR(); - if( err != GL_NO_ERROR ) bSuccess = false; - glGenFramebuffersEXT( 1, &s_uFramebuffer); - if( s_uFramebuffer == 0 ) { + if (err != GL_NO_ERROR) bSuccess = false; + + glGenFramebuffersEXT(1, &s_uFramebuffer); + + if (s_uFramebuffer == 0) + { ZZLog::Error_Log("Failed to create the renderbuffer."); } - assert( glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT ); - glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, s_uFramebuffer ); + assert(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT); - if( glDrawBuffers != NULL ) - glDrawBuffers(1, s_drawbuffers); + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, s_uFramebuffer); + + if (glDrawBuffers != NULL) glDrawBuffers(1, s_drawbuffers); GL_REPORT_ERROR(); - if( err != GL_NO_ERROR ) bSuccess = false; + + if (err != GL_NO_ERROR) bSuccess = false; font_p = new RasterFont(); - GL_REPORT_ERROR(); - if( err != GL_NO_ERROR ) bSuccess = false; + + if (err != GL_NO_ERROR) bSuccess = false; // init draw fns drawfn[0] = KickPoint; @@ -495,64 +544,76 @@ bool ZeroGS::Create(int _width, int _height) drawfn[7] = KickDummy; SetAA(conf.aa); + GSsetGameCRC(g_LastCRC, g_GameSettings); + GL_STENCILFUNC(GL_ALWAYS, 0, 0); //g_GameSettings |= 0;//GAME_VSSHACK|GAME_FULL16BITRES|GAME_NODEPTHRESOLVE|GAME_FASTUPDATE; //s_bWriteDepth = TRUE; GL_BLEND_ALL(GL_ONE, GL_ONE, GL_ONE, GL_ONE); - - glViewport(0,0,nBackbufferWidth,nBackbufferHeight); // Reset The Current Viewport - + glViewport(0, 0, nBackbufferWidth, nBackbufferHeight); // Reset The Current Viewport + glMatrixMode(GL_PROJECTION); glLoadIdentity(); + glMatrixMode(GL_MODELVIEW); glLoadIdentity(); - + glShadeModel(GL_SMOOTH); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClearDepth(1.0f); + glEnable(GL_DEPTH_TEST); glDisable(GL_LIGHTING); + glDepthFunc(GL_LEQUAL); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations - glGenTextures(1, &ptexLogo); glBindTexture(GL_TEXTURE_RECTANGLE_NV, ptexLogo); #ifdef _WIN32 HRSRC hBitmapSrc = FindResource(hInst, MAKEINTRESOURCE(IDB_ZEROGSLOGO), RT_BITMAP); - assert( hBitmapSrc != NULL ); + assert(hBitmapSrc != NULL); + HGLOBAL hBitmapGlob = LoadResource(hInst, hBitmapSrc); - assert( hBitmapGlob != NULL ); + assert(hBitmapGlob != NULL); + PBITMAPINFO pinfo = (PBITMAPINFO)LockResource(hBitmapGlob); - glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, 4, pinfo->bmiHeader.biWidth, pinfo->bmiHeader.biHeight, 0, pinfo->bmiHeader.biBitCount==32?GL_RGBA:GL_RGB, GL_UNSIGNED_BYTE, (u8*)pinfo+pinfo->bmiHeader.biSize); + glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, 4, pinfo->bmiHeader.biWidth, pinfo->bmiHeader.biHeight, 0, pinfo->bmiHeader.biBitCount == 32 ? GL_RGBA : GL_RGB, GL_UNSIGNED_BYTE, (u8*)pinfo + pinfo->bmiHeader.biSize); + nLogoWidth = pinfo->bmiHeader.biWidth; nLogoHeight = pinfo->bmiHeader.biHeight; + glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + #else #endif GL_REPORT_ERROR(); g_nCurVBOIndex = 0; + g_vboBuffers.resize(VB_NUMBUFFERS); glGenBuffers((GLsizei)g_vboBuffers.size(), &g_vboBuffers[0]); - for(i = 0; i < (int)g_vboBuffers.size(); ++i) { + + for (i = 0; i < (int)g_vboBuffers.size(); ++i) + { glBindBuffer(GL_ARRAY_BUFFER, g_vboBuffers[i]); glBufferData(GL_ARRAY_BUFFER, 0x100*sizeof(VertexGPU), NULL, GL_STREAM_DRAW); } GL_REPORT_ERROR(); - if( err != GL_NO_ERROR ) bSuccess = false; + if (err != GL_NO_ERROR) bSuccess = false; // create the blocks texture g_fBlockMult = 1; vector vBlockData, vBilinearData; + BLOCK::FillBlocks(vBlockData, vBilinearData, 1); glGenTextures(1, &ptexBlocks); @@ -564,7 +625,8 @@ bool ZeroGS::Create(int _width, int _height) glTexImage2D(GL_TEXTURE_2D, 0, g_internalFloatFmt, BLOCK_TEXWIDTH, BLOCK_TEXHEIGHT, 0, GL_ALPHA, GL_FLOAT, &vBlockData[0]); - if( glGetError() != GL_NO_ERROR ) { + if (glGetError() != GL_NO_ERROR) + { // try different internal format g_internalFloatFmt = GL_FLOAT_R32_NV; glTexImage2D(GL_TEXTURE_2D, 0, g_internalFloatFmt, BLOCK_TEXWIDTH, BLOCK_TEXHEIGHT, 0, GL_RED, GL_FLOAT, &vBlockData[0]); @@ -575,26 +637,31 @@ bool ZeroGS::Create(int _width, int _height) glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); - if( glGetError() != GL_NO_ERROR ) { - + if (glGetError() != GL_NO_ERROR) + { // error, resort to 16bit - g_fBlockMult = 65535.0f*(float)g_fiGPU_TEXWIDTH / 32.0f; + g_fBlockMult = 65535.0f * (float)g_fiGPU_TEXWIDTH / 32.0f; BLOCK::FillBlocks(vBlockData, vBilinearData, 0); glTexImage2D(GL_TEXTURE_2D, 0, 2, BLOCK_TEXWIDTH, BLOCK_TEXHEIGHT, 0, GL_R, GL_UNSIGNED_SHORT, &vBlockData[0]); - if( glGetError() != GL_NO_ERROR ) { + + if (glGetError() != GL_NO_ERROR) + { ZZLog::Error_Log("Could not fill blocks."); return false; } + ZZLog::Error_Log("Using non-bilinear fill."); } - else { + else + { // fill in the bilinear blocks glGenTextures(1, &ptexBilinearBlocks); glBindTexture(GL_TEXTURE_2D, ptexBilinearBlocks); glTexImage2D(GL_TEXTURE_2D, 0, g_internalRGBAFloatFmt, BLOCK_TEXWIDTH, BLOCK_TEXHEIGHT, 0, GL_RGBA, GL_FLOAT, &vBilinearData[0]); - if( glGetError() != GL_NO_ERROR ) { + if (glGetError() != GL_NO_ERROR) + { g_internalRGBAFloatFmt = GL_FLOAT_RGBA32_NV; g_internalRGBAFloat16Fmt = GL_FLOAT_RGBA16_NV; glTexImage2D(GL_TEXTURE_2D, 0, g_internalRGBAFloatFmt, BLOCK_TEXWIDTH, BLOCK_TEXHEIGHT, 0, GL_RGBA, GL_FLOAT, &vBilinearData[0]); @@ -603,7 +670,8 @@ bool ZeroGS::Create(int _width, int _height) } else { - ZZLog::Error_Log("Fill bilinear blocks failed!"); + // No, they failed on the first clause of the if statement, not the second. + //ZZLog::Error_Log("Fill bilinear blocks failed!"); } glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); @@ -613,9 +681,10 @@ bool ZeroGS::Create(int _width, int _height) } float fpri = 1; + glPrioritizeTextures(1, &ptexBlocks, &fpri); - if( ptexBilinearBlocks != 0 ) - glPrioritizeTextures(1, &ptexBilinearBlocks, &fpri); + + if (ptexBilinearBlocks != 0) glPrioritizeTextures(1, &ptexBilinearBlocks, &fpri); GL_REPORT_ERROR(); @@ -624,11 +693,37 @@ bool ZeroGS::Create(int _width, int _height) glBindBuffer(GL_ARRAY_BUFFER, vboRect); vector verts(4); + VertexGPU* pvert = &verts[0]; - pvert->x = -0x7fff; pvert->y = 0x7fff; pvert->z = 0; pvert->s = 0; pvert->t = 0; pvert++; - pvert->x = 0x7fff; pvert->y = 0x7fff; pvert->z = 0; pvert->s = 1; pvert->t = 0; pvert++; - pvert->x = -0x7fff; pvert->y = -0x7fff; pvert->z = 0; pvert->s = 0; pvert->t = 1; pvert++; - pvert->x = 0x7fff; pvert->y = -0x7fff; pvert->z = 0; pvert->s = 1; pvert->t = 1; pvert++; + + pvert->x = -0x7fff; + pvert->y = 0x7fff; + pvert->z = 0; + pvert->s = 0; + pvert->t = 0; + pvert++; + + pvert->x = 0x7fff; + pvert->y = 0x7fff; + pvert->z = 0; + pvert->s = 1; + pvert->t = 0; + pvert++; + + pvert->x = -0x7fff; + pvert->y = -0x7fff; + pvert->z = 0; + pvert->s = 0; + pvert->t = 1; + pvert++; + + pvert->x = 0x7fff; + pvert->y = -0x7fff; + pvert->z = 0; + pvert->s = 1; + pvert->t = 1; + pvert++; + glBufferDataARB(GL_ARRAY_BUFFER, 4*sizeof(VertexGPU), &verts[0], GL_STATIC_DRAW); // setup the default vertex declaration @@ -649,33 +744,45 @@ bool ZeroGS::Create(int _width, int _height) glBindTexture(GL_TEXTURE_2D, ptexConv16to32); vector conv16to32data(256*256); - for(i = 0; i < 256*256; ++i) { + + for (i = 0; i < 256*256; ++i) + { u32 tempcol = RGBA16to32(i); // have to flip r and b - conv16to32data[i] = (tempcol&0xff00ff00)|((tempcol&0xff)<<16)|((tempcol&0xff0000)>>16); + conv16to32data[i] = (tempcol & 0xff00ff00) | ((tempcol & 0xff) << 16) | ((tempcol & 0xff0000) >> 16); } + glTexImage2D(GL_TEXTURE_2D, 0, 4, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, &conv16to32data[0]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); GL_REPORT_ERROR(); - if( err != GL_NO_ERROR ) bSuccess = false; + + if (err != GL_NO_ERROR) bSuccess = false; vector conv32to16data(32*32*32); glGenTextures(1, &ptexConv32to16); + glBindTexture(GL_TEXTURE_3D, ptexConv32to16); + u32* dst = &conv32to16data[0]; - for(i = 0; i < 32; ++i) { - for(int j = 0; j < 32; ++j) { - for(int k = 0; k < 32; ++k) { - u32 col = (i<<10)|(j<<5)|k; - *dst++ = ((col&0xff)<<16)|(col&0xff00); + + for (i = 0; i < 32; ++i) + { + for (int j = 0; j < 32; ++j) + { + for (int k = 0; k < 32; ++k) + { + u32 col = (i << 10) | (j << 5) | k; + *dst++ = ((col & 0xff) << 16) | (col & 0xff00); } } } + glTexImage3D(GL_TEXTURE_3D, 0, 4, 32, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, &conv32to16data[0]); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); @@ -683,18 +790,22 @@ bool ZeroGS::Create(int _width, int _height) glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP); GL_REPORT_ERROR(); - if( err != GL_NO_ERROR ) bSuccess = false; + + if (err != GL_NO_ERROR) bSuccess = false; g_cgcontext = cgCreateContext(); cgvProf = CG_PROFILE_ARBVP1; cgfProf = CG_PROFILE_ARBFP1; + cgGLEnableProfile(cgvProf); cgGLEnableProfile(cgfProf); + cgGLSetOptimalOptions(cgvProf); cgGLSetOptimalOptions(cgfProf); cgGLSetManageTextureParameters(g_cgcontext, CG_FALSE); + //cgSetAutoCompile(g_cgcontext, CG_COMPILE_IMMEDIATE); g_fparamFogColor = cgCreateParameter(g_cgcontext, CG_FLOAT4); @@ -702,6 +813,7 @@ bool ZeroGS::Create(int _width, int _height) g_vparamPosXY[1] = cgCreateParameter(g_cgcontext, CG_FLOAT4); ZZLog::Error_Log("Creating effects."); + B_G(LoadEffects(), return false); g_bDisplayMsg = 0; @@ -709,41 +821,54 @@ bool ZeroGS::Create(int _width, int _height) // create a sample shader clampInfo temp; + memset(&temp, 0, sizeof(temp)); - temp.wms = 3; temp.wmt = 3; + + temp.wms = 3; + temp.wmt = 3; g_nPixelShaderVer = 0;//SHADER_ACCURATE; + // test bool bFailed; + FRAGMENTSHADER* pfrag = LoadShadeEffect(0, 1, 1, 1, 1, temp, 0, &bFailed); - if( bFailed || pfrag == NULL ) { - g_nPixelShaderVer = SHADER_ACCURATE|SHADER_REDUCED; + + if (bFailed || pfrag == NULL) + { + g_nPixelShaderVer = SHADER_ACCURATE | SHADER_REDUCED; pfrag = LoadShadeEffect(0, 0, 1, 1, 0, temp, 0, &bFailed); - if( pfrag != NULL ) + + if (pfrag != NULL) cgGLLoadProgram(pfrag->prog); - if( bFailed || pfrag == NULL || cgGetError() != CG_NO_ERROR ) { + + if (bFailed || pfrag == NULL || cgGetError() != CG_NO_ERROR) + { g_nPixelShaderVer = SHADER_REDUCED; ZZLog::Error_Log("Basic shader test failed."); } } g_bDisplayMsg = 1; - if( g_nPixelShaderVer & SHADER_REDUCED ) - conf.bilinear = 0; + + if (g_nPixelShaderVer & SHADER_REDUCED) conf.bilinear = 0; ZZLog::Error_Log("Creating extra effects."); + B_G(LoadExtraEffects(), return false); ZZLog::Error_Log("Using %s shaders.", g_pShaders[g_nPixelShaderVer]); GL_REPORT_ERROR(); - if( err != GL_NO_ERROR ) bSuccess = false; + + if (err != GL_NO_ERROR) bSuccess = false; glDisable(GL_STENCIL_TEST); glEnable(GL_SCISSOR_TEST); GL_BLEND_ALPHA(GL_ONE, GL_ZERO); + glBlendColorEXT(0, 0, 0, 0.5f); glDisable(GL_CULL_FACE); @@ -751,20 +876,27 @@ bool ZeroGS::Create(int _width, int _height) // points // This was changed in SetAA - should we be changing it back? glPointSize(1.0f); + g_nDepthBias = 0; + glEnable(GL_POLYGON_OFFSET_FILL); glEnable(GL_POLYGON_OFFSET_LINE); + glPolygonOffset(0, 1); vb[0].Init(VB_BUFFERSIZE); vb[1].Init(VB_BUFFERSIZE); + g_bSaveFlushedFrame = 1; g_vsprog = g_psprog = 0; if (glGetError() == GL_NO_ERROR) + { return bSuccess; - else { + } + else + { ZZLog::Error_Log("In final init!"); return false; } @@ -772,7 +904,8 @@ bool ZeroGS::Create(int _width, int _height) void ZeroGS::Destroy(BOOL bD3D) { - if( s_aviinit ) { + if (s_aviinit) + { StopCapture(); Stop_Avi(); ZZLog::Error_Log("zerogs.avi stopped."); @@ -780,6 +913,7 @@ void ZeroGS::Destroy(BOOL bD3D) } g_MemTargs.Destroy(); + s_RTs.Destroy(); s_DepthRTs.Destroy(); s_BitwiseTextures.Destroy(); @@ -793,28 +927,40 @@ void ZeroGS::Destroy(BOOL bD3D) vb[0].Destroy(); vb[1].Destroy(); - if( g_vboBuffers.size() > 0 ) { + if (g_vboBuffers.size() > 0) + { glDeleteBuffers((GLsizei)g_vboBuffers.size(), &g_vboBuffers[0]); g_vboBuffers.clear(); } + g_nCurVBOIndex = 0; - for(int i = 0; i < ARRAY_SIZE(pvs); ++i) { + for (int i = 0; i < ARRAY_SIZE(pvs); ++i) + { SAFE_RELEASE_PROG(pvs[i]); } - for(int i = 0; i < ARRAY_SIZE(ppsRegular); ++i) { + + for (int i = 0; i < ARRAY_SIZE(ppsRegular); ++i) + { SAFE_RELEASE_PROG(ppsRegular[i].prog); } - for(int i = 0; i < ARRAY_SIZE(ppsTexture); ++i) { + + for (int i = 0; i < ARRAY_SIZE(ppsTexture); ++i) + { SAFE_RELEASE_PROG(ppsTexture[i].prog); } SAFE_RELEASE_PROG(pvsBitBlt.prog); - SAFE_RELEASE_PROG(ppsBitBlt[0].prog); SAFE_RELEASE_PROG(ppsBitBlt[1].prog); + + SAFE_RELEASE_PROG(ppsBitBlt[0].prog); + SAFE_RELEASE_PROG(ppsBitBlt[1].prog); SAFE_RELEASE_PROG(ppsBitBltDepth.prog); - SAFE_RELEASE_PROG(ppsCRTCTarg[0].prog); SAFE_RELEASE_PROG(ppsCRTCTarg[1].prog); - SAFE_RELEASE_PROG(ppsCRTC[0].prog); SAFE_RELEASE_PROG(ppsCRTC[1].prog); - SAFE_RELEASE_PROG(ppsCRTC24[0].prog); SAFE_RELEASE_PROG(ppsCRTC24[1].prog); + SAFE_RELEASE_PROG(ppsCRTCTarg[0].prog); + SAFE_RELEASE_PROG(ppsCRTCTarg[1].prog); + SAFE_RELEASE_PROG(ppsCRTC[0].prog); + SAFE_RELEASE_PROG(ppsCRTC[1].prog); + SAFE_RELEASE_PROG(ppsCRTC24[0].prog); + SAFE_RELEASE_PROG(ppsCRTC24[1].prog); SAFE_RELEASE_PROG(ppsOne.prog); SAFE_DELETE(font_p); diff --git a/plugins/zzogl-pg/opengl/ZZoglFlush.cpp b/plugins/zzogl-pg/opengl/ZZoglFlush.cpp index bd85d2f382..cb32174dde 100644 --- a/plugins/zzogl-pg/opengl/ZZoglFlush.cpp +++ b/plugins/zzogl-pg/opengl/ZZoglFlush.cpp @@ -119,7 +119,7 @@ bool g_bUpdateStencil = 1; u32 g_SaveFrameNum = 0; // ZZ int GPU_TEXWIDTH = 512; -float g_fiGPU_TEXWIDTH = 1/512.0f; +float g_fiGPU_TEXWIDTH = 1 / 512.0f; extern CGprogram g_psprog; // 2 -- ZZ @@ -158,14 +158,18 @@ static Vector vAlphaBlendColor; // used for GPU_COLOR static u8 bNeedBlendFactorInAlpha; // set if the output source alpha is different from the real source alpha (only when blend factor > 0x80) static u32 s_dwColorWrite = 0xf; // the color write mask of the current target -union { - struct { +union +{ + + struct + { u8 _bNeedAlphaColor; // set if vAlphaBlendColor needs to be set u8 _b2XAlphaTest; // Only valid when bNeedAlphaColor is set. if 1st bit set set, double all alpha testing values - // otherwise alpha testing needs to be done separately. + // otherwise alpha testing needs to be done separately. u8 _bDestAlphaColor; // set to 1 if blending with dest color (process only one tri at a time). If 2, dest alpha is always 1. u8 _bAlphaClamping; // if first bit is set, do min; if second bit, do max }; + u32 _bAlphaState; } g_vars; @@ -182,68 +186,80 @@ extern u8* g_pbyGSClut; //------------------ Namespace -namespace ZeroGS { +namespace ZeroGS +{ - VB vb[2]; - float fiTexWidth[2], fiTexHeight[2]; // current tex width and height +VB vb[2]; +float fiTexWidth[2], fiTexHeight[2]; // current tex width and height - u8 s_AAx = 0, s_AAy = 0; // if AAy is set, then AAx has to be set - u8 s_AAz = 0, s_AAw = 0; // if AAy is set, then AAx has to be set +u8 s_AAx = 0, s_AAy = 0; // if AAy is set, then AAx has to be set +u8 s_AAz = 0, s_AAw = 0; // if AAy is set, then AAx has to be set - int icurctx = -1; +int icurctx = -1; - extern CRangeManager s_RangeMngr; // manages overwritten memory // zz - void FlushTransferRanges(const tex0Info* ptex); //zz +extern CRangeManager s_RangeMngr; // manages overwritten memory // zz +void FlushTransferRanges(const tex0Info* ptex); //zz - RenderFormatType GetRenderFormat() { return g_RenderFormatType; } //zz +RenderFormatType GetRenderFormat() { return g_RenderFormatType; } //zz - // use to update the state - void SetTexVariables(int context, FRAGMENTSHADER* pfragment); // zz - void SetTexInt(int context, FRAGMENTSHADER* pfragment, int settexint); // zz - void SetAlphaVariables(const alphaInfo& ainfo); // zzz - void ResetAlphaVariables(); +// use to update the state +void SetTexVariables(int context, FRAGMENTSHADER* pfragment); // zz +void SetTexInt(int context, FRAGMENTSHADER* pfragment, int settexint); // zz +void SetAlphaVariables(const alphaInfo& ainfo); // zzz +void ResetAlphaVariables(); - inline void SetAlphaTestInt(pixTest curtest); +inline void SetAlphaTestInt(pixTest curtest); - inline void RenderAlphaTest(const VB& curvb, CGparameter sOneColor); - inline void RenderStencil(const VB& curvb, u32 dwUsingSpecialTesting); - inline void ProcessStencil(const VB& curvb); - inline void RenderFBA(const VB& curvb, CGparameter sOneColor); - inline void ProcessFBA(const VB& curvb, CGparameter sOneColor); // zz +inline void RenderAlphaTest(const VB& curvb, CGparameter sOneColor); +inline void RenderStencil(const VB& curvb, u32 dwUsingSpecialTesting); +inline void ProcessStencil(const VB& curvb); +inline void RenderFBA(const VB& curvb, CGparameter sOneColor); +inline void ProcessFBA(const VB& curvb, CGparameter sOneColor); // zz } + //------------------ Code -inline float AlphaReferedValue(int aref) { - return b2XAlphaTest ? min (1.0f, (float)aref / 127.5f) : (float)aref /255.0f ; +inline float AlphaReferedValue(int aref) +{ + return b2XAlphaTest ? min(1.0f, (float)aref / 127.5f) : (float)aref / 255.0f ; } -inline void SetAlphaTest(const pixTest& curtest) { +inline void SetAlphaTest(const pixTest& curtest) +{ // if s_dwColorWrite is nontrivial, than we should not off alphatest. // This fix GOW and Okami. - if( !curtest.ate && USEALPHATESTING && (s_dwColorWrite != 2 && s_dwColorWrite != 14 )) { + if (!curtest.ate && USEALPHATESTING && (s_dwColorWrite != 2 && s_dwColorWrite != 14)) + { glDisable(GL_ALPHA_TEST); } - else { + else + { glEnable(GL_ALPHA_TEST); glAlphaFunc(g_dwAlphaCmp[curtest.atst], AlphaReferedValue(curtest.aref)); } } // Switch wireframe rendering off for first flush, so it's draw few solid primitives -inline void SwitchWireframeOff() { - if( conf.options & GSOPTION_WIREFRAME ) { - if( s_nWireframeCount > 0 ) { +inline void SwitchWireframeOff() +{ + if (conf.options & GSOPTION_WIREFRAME) + { + if (s_nWireframeCount > 0) + { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } } } // Switch wireframe rendering on, look at previous function -inline void SwitchWireframeOn() { - if( conf.options & GSOPTION_WIREFRAME ) { - if( s_nWireframeCount > 0 ) { +inline void SwitchWireframeOn() +{ + if (conf.options & GSOPTION_WIREFRAME) + { + if (s_nWireframeCount > 0) + { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); --s_nWireframeCount; } @@ -253,28 +269,34 @@ inline void SwitchWireframeOn() { int GetTexFilter(const tex1Info& tex1) { // always force - if( conf.bilinear == 2 ) - return 1; + if (conf.bilinear == 2) return 1; int texfilter = 0; - if( conf.bilinear && ptexBilinearBlocks != 0 ) { - if( tex1.mmin <= 1 ) - texfilter = tex1.mmin|tex1.mmag; + + if (conf.bilinear && ptexBilinearBlocks != 0) + { + if (tex1.mmin <= 1) + texfilter = tex1.mmin | tex1.mmag; else - texfilter = tex1.mmag ? ((tex1.mmin+2)&5) : tex1.mmin; + texfilter = tex1.mmag ? ((tex1.mmin + 2) & 5) : tex1.mmin; texfilter = texfilter == 1 || texfilter == 4 || texfilter == 5; } + return texfilter; } void ZeroGS::ReloadEffects() { #ifdef ZEROGS_DEVBUILD - for(int i = 0; i < ARRAY_SIZE(ppsTexture); ++i) { + + for (int i = 0; i < ARRAY_SIZE(ppsTexture); ++i) + { SAFE_RELEASE_PROG(ppsTexture[i].prog); } + memset(ppsTexture, 0, sizeof(ppsTexture)); + LoadExtraEffects(); #endif } @@ -282,8 +304,8 @@ void ZeroGS::ReloadEffects() long BufferNumber = 0; // This is a debug function. It prints all buffer info and save current texture into the file, then prints the file name. -inline void -VisualBufferMessage(int context) { +inline void VisualBufferMessage(int context) +{ #if defined(WRITE_PRIM_LOGS) && defined(_DEBUG) BufferNumber++; ZeroGS::VB& curvb = vb[context]; @@ -292,59 +314,72 @@ VisualBufferMessage(int context) { static const char* pafail[4] = { "KEEP", "FB_ONLY", "ZB_ONLY", "RGB_ONLY" }; ZZLog::Error_Log("**Drawing ctx %d, num %d, fbp: 0x%x, zbp: 0x%x, fpsm: %d, zpsm: %d, fbw: %d", context, vb[context].nCount, curvb.prndr->fbp, curvb.zbuf.zbp, curvb.prndr->psm, curvb.zbuf.psm, curvb.prndr->fbw); ZZLog::Error_Log("prim: prim=%x iip=%x tme=%x fge=%x abe=%x aa1=%x fst=%x ctxt=%x fix=%x", - curvb.curprim.prim, curvb.curprim.iip, curvb.curprim.tme, curvb.curprim.fge, curvb.curprim.abe, curvb.curprim.aa1, curvb.curprim.fst, curvb.curprim.ctxt, curvb.curprim.fix); + curvb.curprim.prim, curvb.curprim.iip, curvb.curprim.tme, curvb.curprim.fge, curvb.curprim.abe, curvb.curprim.aa1, curvb.curprim.fst, curvb.curprim.ctxt, curvb.curprim.fix); ZZLog::Error_Log("test: ate:%d, atst: %s, aref: %d, afail: %s, date: %d, datm: %d, zte: %d, ztst: %s, fba: %d", - curvb.test.ate, patst[curvb.test.atst], curvb.test.aref, pafail[curvb.test.afail], curvb.test.date, curvb.test.datm, curvb.test.zte, pztst[curvb.test.ztst], curvb.fba.fba); + curvb.test.ate, patst[curvb.test.atst], curvb.test.aref, pafail[curvb.test.afail], curvb.test.date, curvb.test.datm, curvb.test.zte, pztst[curvb.test.ztst], curvb.fba.fba); ZZLog::Error_Log("alpha: A%d B%d C%d D%d FIX:%d pabe: %d; aem: %d, ta0: %d, ta1: %d\n", curvb.alpha.a, curvb.alpha.b, curvb.alpha.c, curvb.alpha.d, curvb.alpha.fix, gs.pabe, gs.texa.aem, gs.texa.ta[0], gs.texa.ta[1]); ZZLog::Error_Log("tex0: tbp0=0x%x, tbw=%d, psm=0x%x, tw=%d, th=%d, tcc=%d, tfx=%d, cbp=0x%x, cpsm=0x%x, csm=%d, csa=%d, cld=%d", - curvb.tex0.tbp0, curvb.tex0.tbw, curvb.tex0.psm, curvb.tex0.tw, - curvb.tex0.th, curvb.tex0.tcc, curvb.tex0.tfx, curvb.tex0.cbp, - curvb.tex0.cpsm, curvb.tex0.csm, curvb.tex0.csa, curvb.tex0.cld); + curvb.tex0.tbp0, curvb.tex0.tbw, curvb.tex0.psm, curvb.tex0.tw, + curvb.tex0.th, curvb.tex0.tcc, curvb.tex0.tfx, curvb.tex0.cbp, + curvb.tex0.cpsm, curvb.tex0.csm, curvb.tex0.csa, curvb.tex0.cld); char* Name; // if (g_bSaveTex) { // if (g_bSaveTex == 1) - Name = NamedSaveTex(&curvb.tex0, 1); + Name = NamedSaveTex(&curvb.tex0, 1); // else // Name = NamedSaveTex(&curvb.tex0, 0); - ZZLog::Error_Log("TGA name '%s'.", Name); - free(Name); + ZZLog::Error_Log("TGA name '%s'.", Name); + free(Name); // } ZZLog::Error_Log("frame: %d, buffer %ld.\n", g_SaveFrameNum, BufferNumber); #endif } -inline void SaveRendererTarget(VB& curvb) { +inline void SaveRendererTarget(VB& curvb) +{ #ifdef _DEBUG - if( g_bSaveFlushedFrame & 0x80000000 ) { + + if (g_bSaveFlushedFrame & 0x80000000) + { char str[255]; sprintf(str, "rndr.tga", g_SaveFrameNum); SaveRenderTarget(str, curvb.prndr->fbw, curvb.prndr->fbh, 0); } + #endif } // Stop effects in Developers mode -inline void FlushUpdateEffect() { +inline void FlushUpdateEffect() +{ #if defined(DEVBUILD) - if( g_bUpdateEffect ) { + + if (g_bUpdateEffect) + { ReloadEffects(); g_bUpdateEffect = 0; } + #endif } // Check, maybe we cold skip flush -inline bool IsFlushNoNeed(VB& curvb, const pixTest& curtest ) { - if (curvb.nCount == 0 || (curtest.zte && curtest.ztst == 0) || g_bIsLost) { +inline bool IsFlushNoNeed(VB& curvb, const pixTest& curtest) +{ + if (curvb.nCount == 0 || (curtest.zte && curtest.ztst == 0) || g_bIsLost) + { curvb.nCount = 0; return true; } + return false; } // Transfer targets, that are located in current texture. -inline void FlushTransferRangesHelper(VB& curvb) { - if( s_RangeMngr.ranges.size() > 0 ) { +inline void FlushTransferRangesHelper(VB& curvb) +{ + if (s_RangeMngr.ranges.size() > 0) + { // don't want infinite loop, so set nCount to 0. u32 prevcount = curvb.nCount; curvb.nCount = 0; @@ -356,73 +391,83 @@ inline void FlushTransferRangesHelper(VB& curvb) { } // If set bit for texture cheking, do it. Maybe it's all. -inline bool FushTexDataHelper(VB& curvb){ - if( curvb.bNeedFrameCheck || curvb.bNeedZCheck ) { +inline bool FushTexDataHelper(VB& curvb) +{ + if (curvb.bNeedFrameCheck || curvb.bNeedZCheck) + { curvb.CheckFrame(curvb.curprim.tme ? curvb.tex0.tbp0 : 0); } - if( curvb.bNeedTexCheck ) { // Zeydlitz want to try this + if (curvb.bNeedTexCheck) // Zeydlitz want to try this + { curvb.FlushTexData(); - if (curvb.nCount == 0) - return true; + if (curvb.nCount == 0) return true; } + return false; } // Null target mean that we do something really bad. -inline bool FlushCheckForNULLTarget(VB& curvb, int context){ - if ((curvb.prndr == NULL) || (curvb.pdepth == NULL)) { +inline bool FlushCheckForNULLTarget(VB& curvb, int context) +{ + if ((curvb.prndr == NULL) || (curvb.pdepth == NULL)) + { ERROR_LOG_SPAMA("Current render target NULL (ctx: %d)", context); curvb.nCount = 0; return true; } + return false; } // O.k. A set of resolutions, we do before real flush. We do RangeManager, FrameCheck and // ZCheck before this. -inline bool FlushInitialTest(VB& curvb, const pixTest& curtest, int context) { +inline bool FlushInitialTest(VB& curvb, const pixTest& curtest, int context) +{ GL_REPORT_ERRORD(); - assert( context >= 0 && context <= 1 ); + assert(context >= 0 && context <= 1); FlushUpdateEffect(); - if (IsFlushNoNeed(curvb, curtest)) - return true; + if (IsFlushNoNeed(curvb, curtest)) return true; FlushTransferRangesHelper(curvb); - if (FushTexDataHelper(curvb)) - return true; + if (FushTexDataHelper(curvb)) return true; GL_REPORT_ERRORD(); - if (FlushCheckForNULLTarget(curvb, context)) - return true; + if (FlushCheckForNULLTarget(curvb, context)) return true; return false; } // Try to different approach if texture target was not found -inline CRenderTarget* FlushReGetTarget(int& tbw, int& tbp0, int& tpsm, VB& curvb) { +inline CRenderTarget* FlushReGetTarget(int& tbw, int& tbp0, int& tpsm, VB& curvb) +{ // This was incorrect code CRenderTarget* ptextarg = NULL; - if (ptextarg == NULL && tpsm == PSMT8 && (g_GameSettings & GAME_REGETHACK) ) { + if (ptextarg == NULL && tpsm == PSMT8 && (g_GameSettings & GAME_REGETHACK)) + { // check for targets with half the width. Break Valkyrie Chronicles - ptextarg = s_RTs.GetTarg(tbp0, tbw/2, curvb); - if( ptextarg == NULL ) { - tbp0 &= ~0x7ff; - ptextarg = s_RTs.GetTarg(tbp0, tbw/2, curvb); // mgs3 hack + ptextarg = s_RTs.GetTarg(tbp0, tbw / 2, curvb); - if( ptextarg == NULL ) { + if (ptextarg == NULL) + { + tbp0 &= ~0x7ff; + ptextarg = s_RTs.GetTarg(tbp0, tbw / 2, curvb); // mgs3 hack + + if (ptextarg == NULL) + { // check the next level (mgs3) tbp0 &= ~0xfff; - ptextarg = s_RTs.GetTarg(tbp0, tbw/2, curvb); // mgs3 hack + ptextarg = s_RTs.GetTarg(tbp0, tbw / 2, curvb); // mgs3 hack } - if( ptextarg != NULL && ptextarg->start > tbp0*256 ) { + if (ptextarg != NULL && ptextarg->start > tbp0*256) + { // target beyond range, so ignore ptextarg = NULL; } @@ -430,82 +475,103 @@ inline CRenderTarget* FlushReGetTarget(int& tbw, int& tbp0, int& tpsm, VB& curvb } - if( PSMT_ISZTEX(tpsm) && (ptextarg == NULL) ) { + if (PSMT_ISZTEX(tpsm) && (ptextarg == NULL)) + { // try depth ptextarg = s_DepthRTs.GetTarg(tbp0, tbw, curvb); } - if ((ptextarg == NULL) && (g_GameSettings & GAME_TEXTURETARGS) ) { + if ((ptextarg == NULL) && (g_GameSettings & GAME_TEXTURETARGS)) + { // check if any part of the texture intersects the current target - if( !PSMT_ISCLUT(tpsm) && (curvb.tex0.tbp0 >= curvb.frame.fbp) && ((curvb.tex0.tbp0 ) < curvb.prndr->end)) { + if (!PSMT_ISCLUT(tpsm) && (curvb.tex0.tbp0 >= curvb.frame.fbp) && ((curvb.tex0.tbp0) < curvb.prndr->end)) + { ptextarg = curvb.prndr; } } #ifdef DEBUG - if (tbp0 == 0x3600 && tbw == 0x100) { - if (ptextarg == NULL) { - printf ("Miss %x 0x%x %d\n", tbw, tbp0, tpsm); + if (tbp0 == 0x3600 && tbw == 0x100) + { + if (ptextarg == NULL) + { + printf("Miss %x 0x%x %d\n", tbw, tbp0, tpsm); - typedef map MAPTARGETS; - for(MAPTARGETS::iterator itnew = s_RTs.mapTargets.begin(); itnew != s_RTs.mapTargets.end(); ++itnew) { - printf("\tRender %x 0x%x %x\n", itnew->second->fbw, itnew->second->fbp, itnew->second->psm); - } - for(MAPTARGETS::iterator itnew = s_DepthRTs.mapTargets.begin(); itnew != s_DepthRTs.mapTargets.end(); ++itnew) { - printf("\tDepth %x 0x%x %x\n", itnew->second->fbw, itnew->second->fbp, itnew->second->psm); - } + typedef map MAPTARGETS; - printf ("\tCurvb 0x%x 0x%x 0x%x %x\n", curvb.frame.fbp, curvb.prndr->end, curvb.prndr->fbp, curvb.prndr->fbw); - } - else - printf ("Hit %x 0x%x %x\n", tbw, tbp0, tpsm); + for (MAPTARGETS::iterator itnew = s_RTs.mapTargets.begin(); itnew != s_RTs.mapTargets.end(); ++itnew) + { + printf("\tRender %x 0x%x %x\n", itnew->second->fbw, itnew->second->fbp, itnew->second->psm); + } + + for (MAPTARGETS::iterator itnew = s_DepthRTs.mapTargets.begin(); itnew != s_DepthRTs.mapTargets.end(); ++itnew) + { + printf("\tDepth %x 0x%x %x\n", itnew->second->fbw, itnew->second->fbp, itnew->second->psm); + } + + printf("\tCurvb 0x%x 0x%x 0x%x %x\n", curvb.frame.fbp, curvb.prndr->end, curvb.prndr->fbp, curvb.prndr->fbw); + } + else + printf("Hit %x 0x%x %x\n", tbw, tbp0, tpsm); } + #endif return ptextarg; } // Find target to draw a texture, it's highly p -inline CRenderTarget* FlushGetTarget(VB& curvb) { +inline CRenderTarget* FlushGetTarget(VB& curvb) +{ int tbw, tbp0, tpsm; CRenderTarget* ptextarg = NULL; - if (!curvb.curprim.tme) - return ptextarg; - if (curvb.bNeedTexCheck) { - printf ("How it is possible?\n"); + if (!curvb.curprim.tme) return ptextarg; + + if (curvb.bNeedTexCheck) + { + printf("How it is possible?\n"); // not yet initied, but still need to get correct target! (xeno3 ingame) tbp0 = ZZOglGet_tbp0_TexBits(curvb.uNextTex0Data[0]); tbw = ZZOglGet_tbw_TexBitsMult(curvb.uNextTex0Data[0]); tpsm = ZZOglGet_psm_TexBitsFix(curvb.uNextTex0Data[0]); } - else{ + else + { tbw = curvb.tex0.tbw; tbp0 = curvb.tex0.tbp0; tpsm = curvb.tex0.psm; } ptextarg = s_RTs.GetTarg(tbp0, tbw, curvb); - if (ptextarg == NULL) - ptextarg = FlushReGetTarget(tbw, tbp0, tpsm, curvb); - if ((ptextarg != NULL) && !(ptextarg->status & CRenderTarget::TS_NeedUpdate)) { - if (PSMT_BITMODE(tpsm) == 4) { // handle 8h cluts + if (ptextarg == NULL) + ptextarg = FlushReGetTarget(tbw, tbp0, tpsm, curvb); + + if ((ptextarg != NULL) && !(ptextarg->status & CRenderTarget::TS_NeedUpdate)) + { + if (PSMT_BITMODE(tpsm) == 4) // handle 8h cluts + { // don't support clut targets, read from mem // 4hl - kh2 check - from dx version -- arcum42 - if ( tpsm == PSMT4 && s_ClutResolve <= 1 ) - { // xenosaga requires 2 resolves + + if (tpsm == PSMT4 && s_ClutResolve <= 1) + { + // xenosaga requires 2 resolves u32 prevcount = curvb.nCount; curvb.nCount = 0; ptextarg->Resolve(); s_ClutResolve++; curvb.nCount += prevcount; } + ptextarg = NULL; } - else { - if (ptextarg == curvb.prndr) { + else + { + if (ptextarg == curvb.prndr) + { // need feedback curvb.prndr->CreateFeedback(); @@ -516,45 +582,60 @@ inline CRenderTarget* FlushGetTarget(VB& curvb) { } } } - else ptextarg = NULL; + else + { + ptextarg = NULL; + } return ptextarg; } // Set target for current context -inline void FlushSetContextTarget(VB& curvb, int context) { - if( !curvb.bVarsSetTarg ) +inline void FlushSetContextTarget(VB& curvb, int context) +{ + if (!curvb.bVarsSetTarg) + { SetContextTarget(context); - else { - assert( curvb.pdepth != NULL ); + } + else + { + assert(curvb.pdepth != NULL); - if( curvb.pdepth->status & CRenderTarget::TS_Virtual) { - - if( !curvb.zbuf.zmsk ) { + if (curvb.pdepth->status & CRenderTarget::TS_Virtual) + { + if (!curvb.zbuf.zmsk) + { CRenderTarget* ptemp = s_DepthRTs.Promote(GetFrameKey(curvb.pdepth)); - assert( ptemp == curvb.pdepth ); + assert(ptemp == curvb.pdepth); } else + { curvb.pdepth->status &= ~CRenderTarget::TS_NeedUpdate; + } } - if( (curvb.pdepth->status & CRenderTarget::TS_NeedUpdate) || (curvb.prndr->status & CRenderTarget::TS_NeedUpdate) ) + if ((curvb.pdepth->status & CRenderTarget::TS_NeedUpdate) || (curvb.prndr->status & CRenderTarget::TS_NeedUpdate)) SetContextTarget(context); } - assert( !(curvb.prndr->status&CRenderTarget::TS_NeedUpdate) ); + assert(!(curvb.prndr->status&CRenderTarget::TS_NeedUpdate)); + curvb.prndr->status = 0; - if( curvb.pdepth != NULL ) { - assert( !(curvb.pdepth->status&CRenderTarget::TS_NeedUpdate) ); - if( !curvb.zbuf.zmsk ) { - assert( !(curvb.pdepth->status & CRenderTarget::TS_Virtual) ); + if (curvb.pdepth != NULL) + { + assert(!(curvb.pdepth->status&CRenderTarget::TS_NeedUpdate)); + + if (!curvb.zbuf.zmsk) + { + assert(!(curvb.pdepth->status & CRenderTarget::TS_Virtual)); curvb.pdepth->status = 0; } } } -inline void FlushSetStream(VB& curvb) { +inline void FlushSetStream(VB& curvb) +{ glBindBuffer(GL_ARRAY_BUFFER, g_vboBuffers[g_nCurVBOIndex]); g_nCurVBOIndex = (g_nCurVBOIndex + 1) % g_vboBuffers.size(); glBufferData(GL_ARRAY_BUFFER, curvb.nCount * sizeof(VertexGPU), curvb.pBufferData, GL_STREAM_DRAW); @@ -564,27 +645,28 @@ inline void FlushSetStream(VB& curvb) { SET_STREAM(); #ifdef _DEBUG GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - assert( glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT ); + assert(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT); #endif } -int SetMaskR = 0x0; int SetMaskG = 0x0; int SetMaskB = 0x0; -// Set color mask. Really it's not as good as PS2 one. -inline void FlushSetColorMask(VB& curvb) { - s_dwColorWrite = (PSMT_BITMODE(curvb.prndr->psm) == 1) ? (COLORMASK_BLUE|COLORMASK_GREEN|COLORMASK_RED) : 0xf; +int SetMaskR = 0x0; +int SetMaskG = 0x0; +int SetMaskB = 0x0; +// Set color mask. Really, it's not as good as PS2 one. +inline void FlushSetColorMask(VB& curvb) +{ + s_dwColorWrite = (PSMT_BITMODE(curvb.prndr->psm) == 1) ? (COLORMASK_BLUE | COLORMASK_GREEN | COLORMASK_RED) : 0xf; int maskR = ZZOglGet_fbmRed_FrameBits(curvb.frame.fbm); int maskG = ZZOglGet_fbmGreen_FrameBits(curvb.frame.fbm); int maskB = ZZOglGet_fbmBlue_FrameBits(curvb.frame.fbm); int maskA = ZZOglGet_fbmAlpha_FrameBits(curvb.frame.fbm); - if (maskR == 0xff) - s_dwColorWrite &= ~COLORMASK_RED; - if (maskG == 0xff) - s_dwColorWrite &= ~COLORMASK_GREEN; - if (maskB == 0xff) - s_dwColorWrite &= ~COLORMASK_BLUE; + if (maskR == 0xff) s_dwColorWrite &= ~COLORMASK_RED; + if (maskG == 0xff) s_dwColorWrite &= ~COLORMASK_GREEN; + if (maskB == 0xff) s_dwColorWrite &= ~COLORMASK_BLUE; + if ((maskA == 0xff) || (curvb.curprim.abe && (curvb.test.atst == 2 && curvb.test.aref == 128))) s_dwColorWrite &= ~COLORMASK_ALPHA; @@ -592,13 +674,15 @@ inline void FlushSetColorMask(VB& curvb) { } // Set Scissors for scissor test. -inline void FlushSetScissorRect(VB& curvb) { +inline void FlushSetScissorRect(VB& curvb) +{ Rect& scissor = curvb.prndr->scissorrect; glScissor(scissor.x, scissor.y, scissor.w, scissor.h); } // Prior really doing something check context -inline void FlushDoContextJob(VB& curvb, int context) { +inline void FlushDoContextJob(VB& curvb, int context) +{ SaveRendererTarget(curvb); FlushSetContextTarget(curvb, context); @@ -610,56 +694,68 @@ inline void FlushDoContextJob(VB& curvb, int context) { } // Set 1 is Alpha test is EQUAL and alpha should be proceed with care. -inline int FlushGetExactcolor(const pixTest curtest) { +inline int FlushGetExactcolor(const pixTest curtest) +{ if (!(g_nPixelShaderVer&SHADER_REDUCED)) // ffx2 breaks when ==7 - return ((curtest.ate && curtest.aref <= 128) && (curtest.atst==4));//||curtest.atst==7); + return ((curtest.ate && curtest.aref <= 128) && (curtest.atst == 4));//||curtest.atst==7); return 0; } // fill the buffer by decoding the clut -inline void FlushDecodeClut(VB& curvb, GLuint& ptexclut) { +inline void FlushDecodeClut(VB& curvb, GLuint& ptexclut) +{ glGenTextures(1, &ptexclut); glBindTexture(GL_TEXTURE_2D, ptexclut); vector data(PSMT_ISHALF_STORAGE(curvb.tex0) ? 512 : 1024); - if( ptexclut != 0 ) { + if (ptexclut != 0) + { int nClutOffset = 0, clutsize; int entries = PSMT_IS8CLUT(curvb.tex0.psm) ? 256 : 16; - if (curvb.tex0.csm && curvb.tex0.csa ) - printf ("ERROR, csm1\n"); + if (curvb.tex0.csm && curvb.tex0.csa) + printf("ERROR, csm1\n"); - if (PSMT_IS32BIT(curvb.tex0.cpsm)) { // 32 bit + if (PSMT_IS32BIT(curvb.tex0.cpsm)) // 32 bit + { nClutOffset = 64 * curvb.tex0.csa; clutsize = min(entries, 256 - curvb.tex0.csa * 16) * 4; } - else { + else + { nClutOffset = 64 * (curvb.tex0.csa & 15) + (curvb.tex0.csa >= 16 ? 2 : 0); clutsize = min(entries, 512 - curvb.tex0.csa * 16) * 2; } - if (PSMT_IS32BIT(curvb.tex0.cpsm)) { // 32 bit - memcpy_amd(&data[0], g_pbyGSClut+nClutOffset, clutsize); + if (PSMT_IS32BIT(curvb.tex0.cpsm)) // 32 bit + { + memcpy_amd(&data[0], g_pbyGSClut + nClutOffset, clutsize); } - else { + else + { u16* pClutBuffer = (u16*)(g_pbyGSClut + nClutOffset); - u16* pclut = (u16*)&data[0]; - int left = ((u32)nClutOffset & 2) ? 0 : ((nClutOffset&0x3ff)/2)+clutsize-512; - if( left > 0 ) clutsize -= left; + u16* pclut = (u16*) & data[0]; + int left = ((u32)nClutOffset & 2) ? 0 : ((nClutOffset & 0x3ff) / 2) + clutsize - 512; - while(clutsize > 0) { + if (left > 0) clutsize -= left; + + while (clutsize > 0) + { pclut[0] = pClutBuffer[0]; pclut++; - pClutBuffer+=2; + pClutBuffer += 2; clutsize -= 2; } - if( left > 0) { + if (left > 0) + { pClutBuffer = (u16*)(g_pbyGSClut + 2); - while(left > 0) { + + while (left > 0) + { pclut[0] = pClutBuffer[0]; left -= 2; pClutBuffer += 2; @@ -668,11 +764,11 @@ inline void FlushDecodeClut(VB& curvb, GLuint& ptexclut) { } } - glTexImage2D(GL_TEXTURE_2D, 0, 4, 256, 1, 0, GL_RGBA, PSMT_ISHALF_STORAGE(curvb.tex0)?GL_UNSIGNED_SHORT_5_5_5_1:GL_UNSIGNED_BYTE, &data[0]); + glTexImage2D(GL_TEXTURE_2D, 0, 4, 256, 1, 0, GL_RGBA, PSMT_ISHALF_STORAGE(curvb.tex0) ? GL_UNSIGNED_SHORT_5_5_5_1 : GL_UNSIGNED_BYTE, &data[0]); + s_vecTempTextures.push_back(ptexclut); - if (g_bSaveTex) - SaveTexture("clut.tga", GL_TEXTURE_2D, ptexclut, 256, 1); + if (g_bSaveTex) SaveTexture("clut.tga", GL_TEXTURE_2D, ptexclut, 256, 1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); @@ -681,68 +777,84 @@ inline void FlushDecodeClut(VB& curvb, GLuint& ptexclut) { } } -inline int FlushGetShaderType(VB& curvb, CRenderTarget* ptextarg, GLuint& ptexclut) { - if( PSMT_ISCLUT(curvb.tex0.psm) && !(g_GameSettings&GAME_NOTARGETCLUT) ) { +inline int FlushGetShaderType(VB& curvb, CRenderTarget* ptextarg, GLuint& ptexclut) +{ + if (PSMT_ISCLUT(curvb.tex0.psm) && !(g_GameSettings&GAME_NOTARGETCLUT)) + { FlushDecodeClut(curvb, ptexclut); - if( !(g_nPixelShaderVer&SHADER_REDUCED) && PSMT_ISHALF(ptextarg->psm) ) { + + if (!(g_nPixelShaderVer&SHADER_REDUCED) && PSMT_ISHALF(ptextarg->psm)) + { return 4; } - else { + else + { // Valkyrie return 2; } } - if (PSMT_ISHALF_STORAGE(curvb.tex0) != PSMT_ISHALF(ptextarg->psm) && (!(g_nPixelShaderVer&SHADER_REDUCED) || !curvb.curprim.fge) ) { - if (PSMT_ISHALF_STORAGE(curvb.tex0)) { + if (PSMT_ISHALF_STORAGE(curvb.tex0) != PSMT_ISHALF(ptextarg->psm) && (!(g_nPixelShaderVer&SHADER_REDUCED) || !curvb.curprim.fge)) + { + if (PSMT_ISHALF_STORAGE(curvb.tex0)) + { // converting from 32->16 // Radiata Chronicles return 3; } - else { + else + { // converting from 16->32 // Star Ward: Force return 0; } } + return 1; } //Set page offsets depends omn shader type. -inline Vector FlushSetPageOffset(FRAGMENTSHADER* pfragment, int shadertype, CRenderTarget* ptextarg) { +inline Vector FlushSetPageOffset(FRAGMENTSHADER* pfragment, int shadertype, CRenderTarget* ptextarg) +{ SetShaderCaller("FlushSetPageOffset"); Vector vpageoffset; vpageoffset.w = 0; - switch (shadertype) { - case 3: - vpageoffset.x = -0.1f / 256.0f; - vpageoffset.y = -0.001f / 256.0f; - vpageoffset.z = -0.1f / (ptextarg->fbh); - vpageoffset.w = 0.0f; - break; - case 4: - vpageoffset.x = 2; - vpageoffset.y = 1; - vpageoffset.z = 0; - vpageoffset.w = 0.0001f; - break; + switch (shadertype) + { + case 3: + vpageoffset.x = -0.1f / 256.0f; + vpageoffset.y = -0.001f / 256.0f; + vpageoffset.z = -0.1f / (ptextarg->fbh); + vpageoffset.w = 0.0f; + break; + + case 4: + vpageoffset.x = 2; + vpageoffset.y = 1; + vpageoffset.z = 0; + vpageoffset.w = 0.0001f; + break; } + // zoe2 - if (PSMT_ISZTEX(ptextarg->psm)) - vpageoffset.w = -1.0f; + if (PSMT_ISZTEX(ptextarg->psm)) vpageoffset.w = -1.0f; ZZcgSetParameter4fv(pfragment->fPageOffset, vpageoffset, "g_fPageOffset"); + return vpageoffset; } //Set texture offsets depends omn shader type. -inline Vector FlushSetTexOffset(FRAGMENTSHADER* pfragment, int shadertype, VB& curvb, CRenderTarget* ptextarg) { +inline Vector FlushSetTexOffset(FRAGMENTSHADER* pfragment, int shadertype, VB& curvb, CRenderTarget* ptextarg) +{ SetShaderCaller("FlushSetTexOffset"); Vector v; - if( shadertype == 3 ) { + + if (shadertype == 3) + { Vector v; v.x = 16.0f / (float)curvb.tex0.tw; v.y = 16.0f / (float)curvb.tex0.th; @@ -750,7 +862,8 @@ inline Vector FlushSetTexOffset(FRAGMENTSHADER* pfragment, int shadertype, VB& c v.w = 0.5f * v.y; ZZcgSetParameter4fv(pfragment->fTexOffset, v, "g_fTexOffset"); } - else if( shadertype == 4 ) { + else if (shadertype == 4) + { Vector v; v.x = 16.0f / (float)ptextarg->fbw; v.y = 16.0f / (float)ptextarg->fbh; @@ -758,22 +871,27 @@ inline Vector FlushSetTexOffset(FRAGMENTSHADER* pfragment, int shadertype, VB& c v.w = 8.0f / (float)ptextarg->fbh; ZZcgSetParameter4fv(pfragment->fTexOffset, v, "g_fTexOffset"); } + return v; } // Set dimension (Real!) of texture. z and w -inline Vector FlushTextureDims(FRAGMENTSHADER* pfragment, int shadertype, VB& curvb, CRenderTarget* ptextarg) { +inline Vector FlushTextureDims(FRAGMENTSHADER* pfragment, int shadertype, VB& curvb, CRenderTarget* ptextarg) +{ SetShaderCaller("FlushTextureDims"); Vector vTexDims; vTexDims.x = (float)RW(curvb.tex0.tw) ; vTexDims.y = (float)RH(curvb.tex0.th) ; // look at the offset of tbp0 from fbp - if( curvb.tex0.tbp0 <= ptextarg->fbp ) { + + if (curvb.tex0.tbp0 <= ptextarg->fbp) + { vTexDims.z = 0;//-0.5f/(float)ptextarg->fbw; vTexDims.w = 0;//0.2f/(float)ptextarg->fbh; } - else { + else + { //u32 tbp0 = curvb.tex0.tbp0 >> 5; // align to a page int blockheight = PSMT_ISHALF(ptextarg->psm) ? 64 : 32; int ycoord = ((curvb.tex0.tbp0 - ptextarg->fbp) / (32 * (ptextarg->fbw >> 6))) * blockheight; @@ -786,24 +904,28 @@ inline Vector FlushTextureDims(FRAGMENTSHADER* pfragment, int shadertype, VB& cu vTexDims.z += 8.0f; ZZcgSetParameter4fv(pfragment->fTexDims, vTexDims, "g_fTexDims"); + return vTexDims; } // Apply TEX1 mmag and mmin -- filter for expanding/reducing texture // We ignore all settings, only NEAREST (0) is used -inline void FlushApplyResizeFilter(VB& curvb, u32& dwFilterOpts, CRenderTarget* ptextarg, int context) { +inline void FlushApplyResizeFilter(VB& curvb, u32& dwFilterOpts, CRenderTarget* ptextarg, int context) +{ u32 ptexset = (ptextarg == curvb.prndr) ? ptextarg->ptexFeedback : ptextarg->ptex; s_ptexCurSet[context] = ptexset; if ((!curvb.tex1.mmag) || (!curvb.tex1.mmin)) glBindTexture(GL_TEXTURE_RECTANGLE_NV, ptexset); - if( !curvb.tex1.mmag ) { + if (!curvb.tex1.mmag) + { glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST); dwFilterOpts |= 1; } - if( !curvb.tex1.mmin ) { + if (!curvb.tex1.mmin) + { glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST); dwFilterOpts |= 2; } @@ -811,48 +933,61 @@ inline void FlushApplyResizeFilter(VB& curvb, u32& dwFilterOpts, CRenderTarget* // Usage existing targets depends on several tricks, 32-16 conversion and CLUTing, so we need handle it. -inline FRAGMENTSHADER* FlushUseExistRenderTaget(VB& curvb, CRenderTarget* ptextarg, u32& dwFilterOpts, int exactcolor, int context) { +inline FRAGMENTSHADER* FlushUseExistRenderTaget(VB& curvb, CRenderTarget* ptextarg, u32& dwFilterOpts, int exactcolor, int context) +{ if (ptextarg->IsDepth()) SetWriteDepth(); GLuint ptexclut = 0; + //int psm = GetTexCPSM(curvb.tex0); int shadertype = FlushGetShaderType(curvb, ptextarg, ptexclut); FRAGMENTSHADER* pfragment = LoadShadeEffect(shadertype, 0, curvb.curprim.fge, - IsAlphaTestExpansion(curvb), exactcolor, curvb.clamp, context, NULL); + IsAlphaTestExpansion(curvb), exactcolor, curvb.clamp, context, NULL); Vector vpageoffset = FlushSetPageOffset(pfragment, shadertype, ptextarg); + Vector v = FlushSetTexOffset(pfragment, shadertype, curvb, ptextarg); + Vector vTexDims = FlushTextureDims(pfragment, shadertype, curvb, ptextarg); - if( pfragment->sCLUT != NULL && ptexclut != 0 ) { + if (pfragment->sCLUT != NULL && ptexclut != 0) + { cgGLSetTextureParameter(pfragment->sCLUT, ptexclut); cgGLEnableTextureParameter(pfragment->sCLUT); } FlushApplyResizeFilter(curvb, dwFilterOpts, ptextarg, context); - if( g_bSaveTex ) + if (g_bSaveTex) SaveTexture("tex.tga", GL_TEXTURE_RECTANGLE_NV, - ptextarg == curvb.prndr ? ptextarg->ptexFeedback : ptextarg->ptex, RW(ptextarg->fbw), RH(ptextarg->fbh)); + ptextarg == curvb.prndr ? ptextarg->ptexFeedback : ptextarg->ptex, RW(ptextarg->fbw), RH(ptextarg->fbh)); return pfragment; } // Usage most major shader. -inline FRAGMENTSHADER* FlushMadeNewTarget(VB& curvb, int exactcolor, int context) { +inline FRAGMENTSHADER* FlushMadeNewTarget(VB& curvb, int exactcolor, int context) +{ // save the texture - if( g_bSaveTex ) { - if( g_bSaveTex == 1 ) { + if (g_bSaveTex) + { + if (g_bSaveTex == 1) + { SaveTex(&curvb.tex0, 1); - /*CMemoryTarget* pmemtarg = */g_MemTargs.GetMemoryTarget(curvb.tex0, 0); + /*CMemoryTarget* pmemtarg = */ + g_MemTargs.GetMemoryTarget(curvb.tex0, 0); + } + else + { + SaveTex(&curvb.tex0, 0); } - else SaveTex(&curvb.tex0, 0); } FRAGMENTSHADER* pfragment = LoadShadeEffect(0, GetTexFilter(curvb.tex1), curvb.curprim.fge, - IsAlphaTestExpansion(curvb), exactcolor, curvb.clamp, context, NULL); + + IsAlphaTestExpansion(curvb), exactcolor, curvb.clamp, context, NULL); if (pfragment == NULL) ZZLog::Error_Log("Could not find memory target shader."); @@ -861,27 +996,35 @@ inline FRAGMENTSHADER* FlushMadeNewTarget(VB& curvb, int exactcolor, int context } // We made an shader, so now need to put all common variables. -inline void FlushSetTexture(VB& curvb, FRAGMENTSHADER* pfragment, CRenderTarget* ptextarg, int context) { +inline void FlushSetTexture(VB& curvb, FRAGMENTSHADER* pfragment, CRenderTarget* ptextarg, int context) +{ SetTexVariables(context, pfragment); SetTexInt(context, pfragment, ptextarg == NULL); // have to enable the texture parameters(curtest.atst= - if( curvb.ptexClamp[0] != 0 ) { + + if (curvb.ptexClamp[0] != 0) + { cgGLSetTextureParameter(pfragment->sBitwiseANDX, curvb.ptexClamp[0]); cgGLEnableTextureParameter(pfragment->sBitwiseANDX); } - if( curvb.ptexClamp[1] != 0 ) { + + if (curvb.ptexClamp[1] != 0) + { cgGLSetTextureParameter(pfragment->sBitwiseANDY, curvb.ptexClamp[1]); cgGLEnableTextureParameter(pfragment->sBitwiseANDY); } - if( pfragment->sMemory != NULL && s_ptexCurSet[context] != 0) { + + if (pfragment->sMemory != NULL && s_ptexCurSet[context] != 0) + { cgGLSetTextureParameter(pfragment->sMemory, s_ptexCurSet[context]); cgGLEnableTextureParameter(pfragment->sMemory); } } // Reset programm and texture variables; -inline void FlushBindProgramm( FRAGMENTSHADER* pfragment, int context) { +inline void FlushBindProgramm(FRAGMENTSHADER* pfragment, int context) +{ vb[context].bTexConstsSync = 0; vb[context].bVarsTexSync = 0; @@ -889,24 +1032,30 @@ inline void FlushBindProgramm( FRAGMENTSHADER* pfragment, int context) { g_psprog = pfragment->prog; } -inline FRAGMENTSHADER* FlushRendererStage(VB& curvb, u32& dwFilterOpts, CRenderTarget* ptextarg, int exactcolor, int context) { +inline FRAGMENTSHADER* FlushRendererStage(VB& curvb, u32& dwFilterOpts, CRenderTarget* ptextarg, int exactcolor, int context) +{ FRAGMENTSHADER* pfragment = NULL; // set the correct pixel shaders - if (curvb.curprim.tme) { + + if (curvb.curprim.tme) + { if (ptextarg != NULL) pfragment = FlushUseExistRenderTaget(curvb, ptextarg, dwFilterOpts, exactcolor, context); else pfragment = FlushMadeNewTarget(curvb, exactcolor, context); - if (pfragment == NULL) { + if (pfragment == NULL) + { ZZLog::Error_Log("Shader is not found."); // return NULL; } + FlushSetTexture(curvb, pfragment, ptextarg, context); } - else { + else + { pfragment = &ppsRegular[curvb.curprim.fge + 2 * s_bWriteDepth]; } @@ -914,20 +1063,23 @@ inline FRAGMENTSHADER* FlushRendererStage(VB& curvb, u32& dwFilterOpts, CRenderT // set the shaders SetShaderCaller("FlushRendererStage") ; - SETVERTEXSHADER(pvs[2 * ((curvb.curprim._val >> 1) & 3) + 8 * s_bWriteDepth + context] ); + SETVERTEXSHADER(pvs[2 * ((curvb.curprim._val >> 1) & 3) + 8 * s_bWriteDepth + context]); FlushBindProgramm(pfragment, context); GL_REPORT_ERRORD(); return pfragment; } -inline bool AlphaCanRenderStencil(VB& curvb) { +inline bool AlphaCanRenderStencil(VB& curvb) +{ return g_bUpdateStencil && (PSMT_BITMODE(curvb.prndr->psm) != 1) && - !ZZOglGet_fbmHighByte(curvb.frame.fbm) && !(g_GameSettings & GAME_NOSTENCIL); + !ZZOglGet_fbmHighByte(curvb.frame.fbm) && !(g_GameSettings & GAME_NOSTENCIL); } -inline void AlphaSetStencil (bool DoIt) { - if (DoIt) { +inline void AlphaSetStencil(bool DoIt) +{ + if (DoIt) + { glEnable(GL_STENCIL_TEST); GL_STENCILFUNC(GL_ALWAYS, 0, 0); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); @@ -935,59 +1087,75 @@ inline void AlphaSetStencil (bool DoIt) { else glDisable(GL_STENCIL_TEST); } -inline void AlphaSetDepthTest(VB& curvb, const pixTest curtest, FRAGMENTSHADER* pfragment) { +inline void AlphaSetDepthTest(VB& curvb, const pixTest curtest, FRAGMENTSHADER* pfragment) +{ glDepthMask(!curvb.zbuf.zmsk && curtest.zte); - // && curtest.zte && (curtest.ztst > 1) ); + // && curtest.zte && (curtest.ztst > 1) ); - if (curtest.zte) { + if (curtest.zte) + { if (curtest.ztst > 1) g_nDepthUsed = 2; - if ((curtest.ztst == 2) ^ (g_nDepthBias != 0) ) { + if ((curtest.ztst == 2) ^(g_nDepthBias != 0)) + { g_nDepthBias = (curtest.ztst == 2); //SETRS(D3DRS_DEPTHBIAS, g_nDepthBias?FtoDW(0.0003f):FtoDW(0.000015f)); } + glDepthFunc(g_dwZCmp[curtest.ztst]); } + GL_ZTEST(curtest.zte); // glEnable (GL_POLYGON_OFFSET_FILL); // glPolygonOffset (-1., -1.); - if (s_bWriteDepth) { - if(!curvb.zbuf.zmsk) + if (s_bWriteDepth) + { + if (!curvb.zbuf.zmsk) curvb.pdepth->SetRenderTarget(1); else ResetRenderTarget(1); } } -inline u32 AlphaSetupBlendTest(VB& curvb) { +inline u32 AlphaSetupBlendTest(VB& curvb) +{ if (curvb.curprim.abe) SetAlphaVariables(curvb.alpha); else glDisable(GL_BLEND); u32 oldabe = curvb.curprim.abe; - if (gs.pabe) { + + if (gs.pabe) + { //ZZLog::Error_Log("PABE!"); curvb.curprim.abe = 1; glEnable(GL_BLEND); } + return oldabe; } -inline void AlphaRenderFBA(VB& curvb, FRAGMENTSHADER* pfragment, bool s_bDestAlphaTest, bool bCanRenderStencil) { +inline void AlphaRenderFBA(VB& curvb, FRAGMENTSHADER* pfragment, bool s_bDestAlphaTest, bool bCanRenderStencil) +{ // needs to be before RenderAlphaTest - if ((gs.pabe) || (curvb.fba.fba && !ZZOglGet_fbmHighByte(curvb.frame.fbm)) || (s_bDestAlphaTest && bCanRenderStencil)) { - RenderFBA(curvb, pfragment->sOneColor); + if ((gs.pabe) || (curvb.fba.fba && !ZZOglGet_fbmHighByte(curvb.frame.fbm)) || (s_bDestAlphaTest && bCanRenderStencil)) + { + RenderFBA(curvb, pfragment->sOneColor); } } -inline u32 AlphaRenderAlpha(VB& curvb, const pixTest curtest, FRAGMENTSHADER* pfragment, int exactcolor) { +inline u32 AlphaRenderAlpha(VB& curvb, const pixTest curtest, FRAGMENTSHADER* pfragment, int exactcolor) +{ SetShaderCaller("AlphaRenderAlpha"); u32 dwUsingSpecialTesting = 0; - if (curvb.curprim.abe) { - if ((bNeedBlendFactorInAlpha || ((curtest.ate && curtest.atst > 1) && (curtest.aref > 0x80)))) { + + if (curvb.curprim.abe) + { + if ((bNeedBlendFactorInAlpha || ((curtest.ate && curtest.atst > 1) && (curtest.aref > 0x80)))) + { // need special stencil processing for the alpha RenderAlphaTest(curvb, pfragment->sOneColor); dwUsingSpecialTesting = 1; @@ -995,107 +1163,131 @@ inline u32 AlphaRenderAlpha(VB& curvb, const pixTest curtest, FRAGMENTSHADER* pf // harvest fishing Vector v = vAlphaBlendColor; - if (exactcolor) { + + if (exactcolor) + { v.y *= 255; v.w *= 255; } + ZZcgSetParameter4fv(pfragment->sOneColor, v, "g_fOneColor"); } - else { + else + { // not using blending so set to defaults - Vector v = exactcolor ? Vector(1, 510*255.0f/256.0f, 0, 0) : Vector(1,2*255.0f/256.0f,0,0); + Vector v = exactcolor ? Vector(1, 510 * 255.0f / 256.0f, 0, 0) : Vector(1, 2 * 255.0f / 256.0f, 0, 0); ZZcgSetParameter4fv(pfragment->sOneColor, v, "g_fOneColor"); } + return dwUsingSpecialTesting; } -inline void AlphaRenderStencil(VB& curvb, bool s_bDestAlphaTest, bool bCanRenderStencil, u32 dwUsingSpecialTesting) { - if (s_bDestAlphaTest && bCanRenderStencil) { +inline void AlphaRenderStencil(VB& curvb, bool s_bDestAlphaTest, bool bCanRenderStencil, u32 dwUsingSpecialTesting) +{ + if (s_bDestAlphaTest && bCanRenderStencil) + { // if not 24bit and can write to high alpha bit RenderStencil(curvb, dwUsingSpecialTesting); } - else { + else + { s_stencilref = STENCIL_SPECIAL; s_stencilmask = STENCIL_SPECIAL; // setup the stencil to only accept the test pixels - if (dwUsingSpecialTesting) { + + if (dwUsingSpecialTesting) + { glEnable(GL_STENCIL_TEST); glStencilMask(STENCIL_PIXELWRITE); - GL_STENCILFUNC(GL_EQUAL, STENCIL_SPECIAL|STENCIL_PIXELWRITE, STENCIL_SPECIAL); + GL_STENCILFUNC(GL_EQUAL, STENCIL_SPECIAL | STENCIL_PIXELWRITE, STENCIL_SPECIAL); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); } } #ifdef _DEBUG - if (bDestAlphaColor == 1) + if (bDestAlphaColor == 1) { ZZLog::Debug_Log("Dest alpha blending! Manipulate alpha here."); } + #endif - if( bCanRenderStencil && gs.pabe ) { + if (bCanRenderStencil && gs.pabe) + { // only render the pixels with alpha values >= 0x80 - GL_STENCILFUNC(GL_EQUAL, s_stencilref|STENCIL_FBA, s_stencilmask|STENCIL_FBA); + GL_STENCILFUNC(GL_EQUAL, s_stencilref | STENCIL_FBA, s_stencilmask | STENCIL_FBA); } GL_REPORT_ERRORD(); } -inline void AlphaTest(VB& curvb) { +inline void AlphaTest(VB& curvb) +{ // printf ("%d %d %d %d %d\n", curvb.test.date, curvb.test.datm, gs.texa.aem, curvb.test.ate, curvb.test.atst ); // return; - // Zeydlitz change this with a reason! It's "Alpha more than 1 hack." - if (curvb.test.ate == 1 && curvb.test.atst == 1 && curvb.test.date == 1) { + // Zeydlitz changed this with a reason! It's an "Alpha more than 1 hack." + if (curvb.test.ate == 1 && curvb.test.atst == 1 && curvb.test.date == 1) + { if (curvb.test.datm == 1) + { glAlphaFunc(GL_GREATER, 1.0f); - else { + } + else + { glAlphaFunc(GL_LESS, 1.0f); - printf ("%d %d %d\n", curvb.test.date, curvb.test.datm, gs.texa.aem); + printf("%d %d %d\n", curvb.test.date, curvb.test.datm, gs.texa.aem); } } - if (!curvb.test.ate || curvb.test.atst > 0) { + if (!curvb.test.ate || curvb.test.atst > 0) + { DRAW(); } GL_REPORT_ERRORD(); } -inline void AlphaPabe(VB& curvb, FRAGMENTSHADER* pfragment, int exactcolor) { - if( gs.pabe ) { +inline void AlphaPabe(VB& curvb, FRAGMENTSHADER* pfragment, int exactcolor) +{ + if (gs.pabe) + { SetShaderCaller("AlphaPabe"); // only render the pixels with alpha values < 0x80 glDisable(GL_BLEND); GL_STENCILFUNC_SET(); Vector v; - v.x = 1; v.y = 2; v.z = 0; v.w = 0; - if( exactcolor ) v.y *= 255; + v.x = 1; + v.y = 2; + v.z = 0; + v.w = 0; + + if (exactcolor) v.y *= 255; + ZZcgSetParameter4fv(pfragment->sOneColor, v, "g_fOneColor"); DRAW(); // reset - if (!s_stencilmask) - s_stencilfunc = GL_ALWAYS; + if (!s_stencilmask) s_stencilfunc = GL_ALWAYS; + GL_STENCILFUNC_SET(); } GL_REPORT_ERRORD(); } -// Alfa Failure does not work properly on this cases. True means that no failure job should be done -// First three cases are trivail manual -inline bool AlphaFailureIgnore(const pixTest curtest) { - if (!curtest.ate) - return true; - if (curtest.atst == 1) - return true; - if (curtest.afail == 0) - return true; +// Alpha Failure does not work properly on this cases. True means that no failure job should be done. +// First three cases are trivial manual. +inline bool AlphaFailureIgnore(const pixTest curtest) +{ + if (!curtest.ate) return true; + if (curtest.atst == 1) return true; + if (curtest.afail == 0) return true; + if (g_GameSettings & GAME_NOALPHAFAIL && ((s_dwColorWrite < 8) || (s_dwColorWrite == 15 && curtest.atst == 5 && (curtest.aref == 64)))) return true; @@ -1108,15 +1300,15 @@ inline bool AlphaFailureIgnore(const pixTest curtest) { } // more work on alpha failure case -inline void AlphaFailureTestJob(VB& curvb, const pixTest curtest, FRAGMENTSHADER* pfragment, int exactcolor, bool bCanRenderStencil, int oldabe) { +inline void AlphaFailureTestJob(VB& curvb, const pixTest curtest, FRAGMENTSHADER* pfragment, int exactcolor, bool bCanRenderStencil, int oldabe) +{ // Note, case when ate == 1, atst == 0 and afail > 0 in documentation wrote as failure case. But it seems that - // either doc's are incorrect nor this case have some issues. - if (AlphaFailureIgnore(curtest)) { - return; - } + // either doc's are incorrect or this case has some issues. + if (AlphaFailureIgnore(curtest)) return; #ifdef NOALFAFAIL ZZLog::Error_Log("Alpha job here %d %d %d %d %d %d", s_dwColorWrite, curtest.atst, curtest.afail, curtest.aref, gs.pabe, s_bWriteDepth); + // return; #endif @@ -1125,87 +1317,103 @@ inline void AlphaFailureTestJob(VB& curvb, const pixTest curtest, FRAGMENTSHADE // need to reverse the test and disable some targets glAlphaFunc(g_dwReverseAlphaCmp[curtest.atst], AlphaReferedValue(curtest.aref)); - if (curtest.afail & 1) { // front buffer update only - - if( curtest.afail == 3 ) // disable alpha - glColorMask(1,1,1,0); + if (curtest.afail & 1) // front buffer update only + { + if (curtest.afail == 3) glColorMask(1, 1, 1, 0);// disable alpha glDepthMask(0); - if (s_bWriteDepth) - ResetRenderTarget(1); + if (s_bWriteDepth) ResetRenderTarget(1); } - else { + else + { // zbuffer update only - glColorMask(0,0,0,0); + glColorMask(0, 0, 0, 0); } - if( gs.pabe && bCanRenderStencil ) { + if (gs.pabe && bCanRenderStencil) + { // only render the pixels with alpha values >= 0x80 Vector v = vAlphaBlendColor; - if( exactcolor ) { v.y *= 255; v.w *= 255; } + + if (exactcolor) { v.y *= 255; v.w *= 255; } + ZZcgSetParameter4fv(pfragment->sOneColor, v, "g_fOneColor"); + glEnable(GL_BLEND); - GL_STENCILFUNC(GL_EQUAL, s_stencilref|STENCIL_FBA, s_stencilmask|STENCIL_FBA); + GL_STENCILFUNC(GL_EQUAL, s_stencilref | STENCIL_FBA, s_stencilmask | STENCIL_FBA); } DRAW(); + GL_REPORT_ERRORD(); - if (gs.pabe) { + if (gs.pabe) + { // only render the pixels with alpha values < 0x80 glDisable(GL_BLEND); GL_STENCILFUNC_SET(); Vector v; - v.x = 1; v.y = 2; v.z = 0; v.w = 0; + v.x = 1; + v.y = 2; + v.z = 0; + v.w = 0; + if (exactcolor) v.y *= 255; - ZZcgSetParameter4fv(pfragment->sOneColor, v, "g_fOneColor"); + + ZZcgSetParameter4fv(pfragment->sOneColor, v, "g_fOneColor"); DRAW(); // reset - if (oldabe) - glEnable(GL_BLEND); - if (!s_stencilmask) - s_stencilfunc = GL_ALWAYS; + if (oldabe) glEnable(GL_BLEND); + + if (!s_stencilmask) s_stencilfunc = GL_ALWAYS; + GL_STENCILFUNC_SET(); } // restore - if ((curtest.afail & 1) && !curvb.zbuf.zmsk ) { + if ((curtest.afail & 1) && !curvb.zbuf.zmsk) + { glDepthMask(1); - if( s_bWriteDepth ) { - assert( curvb.pdepth != NULL); + if (s_bWriteDepth) + { + assert(curvb.pdepth != NULL); curvb.pdepth->SetRenderTarget(1); } } GL_COLORMASK(s_dwColorWrite); + // not needed anymore since rest of ops concentrate on image processing GL_REPORT_ERRORD(); } -inline void AlphaSpecialTesting(VB& curvb, FRAGMENTSHADER* pfragment, u32 dwUsingSpecialTesting, int exactcolor) { - if (dwUsingSpecialTesting) { +inline void AlphaSpecialTesting(VB& curvb, FRAGMENTSHADER* pfragment, u32 dwUsingSpecialTesting, int exactcolor) +{ + if (dwUsingSpecialTesting) + { SetShaderCaller("AlphaSpecialTesting"); // render the real alpha glDisable(GL_ALPHA_TEST); - glColorMask(0,0,0,1); + glColorMask(0, 0, 0, 1); - if (s_bWriteDepth) { + if (s_bWriteDepth) + { ResetRenderTarget(1); } glDepthMask(0); - glStencilFunc(GL_EQUAL, STENCIL_SPECIAL|STENCIL_PIXELWRITE, STENCIL_SPECIAL|STENCIL_PIXELWRITE); + glStencilFunc(GL_EQUAL, STENCIL_SPECIAL | STENCIL_PIXELWRITE, STENCIL_SPECIAL | STENCIL_PIXELWRITE); glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - Vector v = Vector(0,exactcolor ? 510.0f : 2.0f,0,0); + Vector v = Vector(0, exactcolor ? 510.0f : 2.0f, 0, 0); ZZcgSetParameter4fv(pfragment->sOneColor, v, "g_fOneColor"); DRAW(); @@ -1215,10 +1423,13 @@ inline void AlphaSpecialTesting(VB& curvb, FRAGMENTSHADER* pfragment, u32 dwUsin GL_REPORT_ERRORD(); } -inline void AlphaDestinationTest(VB& curvb, FRAGMENTSHADER* pfragment, bool s_bDestAlphaTest, bool bCanRenderStencil) { - if (s_bDestAlphaTest) { - if( (s_dwColorWrite & COLORMASK_ALPHA) ) { - if( curvb.fba.fba ) +inline void AlphaDestinationTest(VB& curvb, FRAGMENTSHADER* pfragment, bool s_bDestAlphaTest, bool bCanRenderStencil) +{ + if (s_bDestAlphaTest) + { + if ((s_dwColorWrite & COLORMASK_ALPHA)) + { + if (curvb.fba.fba) ProcessFBA(curvb, pfragment->sOneColor); else if (bCanRenderStencil) // finally make sure all entries are 1 when the dest alpha >= 0x80 (if fba is 1, this is already the case) @@ -1228,13 +1439,15 @@ inline void AlphaDestinationTest(VB& curvb, FRAGMENTSHADER* pfragment, bool s_bD else if ((s_dwColorWrite & COLORMASK_ALPHA) && curvb.fba.fba) ProcessFBA(curvb, pfragment->sOneColor); - if( bDestAlphaColor == 1 ) { + if (bDestAlphaColor == 1) + { // need to reset the dest colors to their original counter parts //WARN_LOG("Need to reset dest alpha color\n"); } } -inline void AlphaSaveTarget(VB& curvb) { +inline void AlphaSaveTarget(VB& curvb) +{ #ifdef _DEBUG return; // Do nothing @@ -1258,10 +1471,11 @@ inline void AlphaSaveTarget(VB& curvb) { #endif } -inline void AlphaColorClamping (VB& curvb, const pixTest curtest) { +inline void AlphaColorClamping(VB& curvb, const pixTest curtest) +{ // clamp the final colors, when enabled ffx2 credits mess up - if (curvb.curprim.abe && bAlphaClamping && GetRenderFormat() != RFT_byte8 && !(g_GameSettings&GAME_NOCOLORCLAMP)) { // if !colclamp, skip - + if (curvb.curprim.abe && bAlphaClamping && GetRenderFormat() != RFT_byte8 && !(g_GameSettings&GAME_NOCOLORCLAMP)) // if !colclamp, skip + { ResetAlphaVariables(); // if processing the clamping case, make sure can write to the front buffer @@ -1270,18 +1484,19 @@ inline void AlphaColorClamping (VB& curvb, const pixTest curtest) { glDisable(GL_ALPHA_TEST); glDisable(GL_DEPTH_TEST); glDepthMask(0); - glColorMask(1,1,1,0); + glColorMask(1, 1, 1, 0); + + if (s_bWriteDepth) ResetRenderTarget(1); - if( s_bWriteDepth ) { - ResetRenderTarget(1); - } SetShaderCaller("AlphaColorClamping"); SETPIXELSHADER(ppsOne.prog); GL_BLEND_RGB(GL_ONE, GL_ONE); float f; - if( bAlphaClamping & 1 ) { // min + + if (bAlphaClamping & 1) // min + { f = 0; ZZcgSetParameter4fv(ppsOne.sOneColor, &f, "g_fOneColor"); GL_BLENDEQ_RGB(GL_MAX_EXT); @@ -1289,51 +1504,54 @@ inline void AlphaColorClamping (VB& curvb, const pixTest curtest) { } // bios shows white screen - if( bAlphaClamping & 2 ) { // max + if (bAlphaClamping & 2) // max + { f = 1; ZZcgSetParameter4fv(ppsOne.sOneColor, &f, "g_fOneColor"); GL_BLENDEQ_RGB(GL_MIN_EXT); DRAW(); } - if( !curvb.zbuf.zmsk ) { + if (!curvb.zbuf.zmsk) + { glDepthMask(1); - if( s_bWriteDepth ) { - assert( curvb.pdepth != NULL ); + if (s_bWriteDepth) + { + assert(curvb.pdepth != NULL); curvb.pdepth->SetRenderTarget(1); } } - if( curvb.test.ate && USEALPHATESTING ) - glEnable(GL_ALPHA_TEST); + if (curvb.test.ate && USEALPHATESTING) glEnable(GL_ALPHA_TEST); GL_ZTEST(curtest.zte); } } -inline void FlushUndoFiter(u32 dwFilterOpts) { - if( dwFilterOpts ) { +inline void FlushUndoFiter(u32 dwFilterOpts) +{ + if (dwFilterOpts) + { // undo filter changes (binding didn't change) - if( dwFilterOpts & 1 ) glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - if( dwFilterOpts & 2 ) glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + if (dwFilterOpts & 1) glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + if (dwFilterOpts & 2) glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } } -// This is the most important function! it's draw all collected info oncscreen. -void -ZeroGS::Flush(int context) +// This is the most important function! It draws all collected info onscreen. +void ZeroGS::Flush(int context) { FUNCLOG VB& curvb = vb[context]; const pixTest curtest = curvb.test; - if (FlushInitialTest(curvb, curtest, context)) - return; + if (FlushInitialTest(curvb, curtest, context)) return; VisualBufferMessage(context); GL_REPORT_ERRORD(); + CRenderTarget* ptextarg = FlushGetTarget(curvb); SwitchWireframeOff(); @@ -1342,19 +1560,22 @@ ZeroGS::Flush(int context) u32 dwUsingSpecialTesting = 0; u32 dwFilterOpts = 0; int exactcolor = FlushGetExactcolor(curtest); + FRAGMENTSHADER* pfragment = FlushRendererStage(curvb, dwFilterOpts, ptextarg, exactcolor, context); bool bCanRenderStencil = AlphaCanRenderStencil(curvb); - if (curtest.date || gs.pabe) - SetDestAlphaTest(); + + if (curtest.date || gs.pabe) SetDestAlphaTest(); AlphaSetStencil(s_bDestAlphaTest && bCanRenderStencil); AlphaSetDepthTest(curvb, curtest, pfragment); // Error! SetAlphaTest(curtest); + u32 oldabe = AlphaSetupBlendTest(curvb); // Unavoidable // needs to be before RenderAlphaTest AlphaRenderFBA(curvb, pfragment, s_bDestAlphaTest, bCanRenderStencil); + dwUsingSpecialTesting = AlphaRenderAlpha(curvb, curtest, pfragment, exactcolor); // Unavoidable AlphaRenderStencil(curvb, s_bDestAlphaTest, bCanRenderStencil, dwUsingSpecialTesting); AlphaTest(curvb); // Unavoidable @@ -1363,16 +1584,19 @@ ZeroGS::Flush(int context) AlphaSpecialTesting(curvb, pfragment, dwUsingSpecialTesting, exactcolor); AlphaDestinationTest(curvb, pfragment, s_bDestAlphaTest, bCanRenderStencil); AlphaSaveTarget(curvb); - + GL_REPORT_ERRORD(); - AlphaColorClamping (curvb, curtest); + AlphaColorClamping(curvb, curtest); FlushUndoFiter(dwFilterOpts); - ppf += curvb.nCount+0x100000; + + ppf += curvb.nCount + 0x100000; curvb.nCount = 0; curvb.curprim.abe = oldabe; + SwitchWireframeOn(); + GL_REPORT_ERRORD(); } @@ -1385,17 +1609,18 @@ inline void ZeroGS::RenderFBA(const VB& curvb, CGparameter sOneColor) glDisable(GL_DEPTH_TEST); glDepthMask(0); - glColorMask(0,0,0,0); + glColorMask(0, 0, 0, 0); - if( s_bWriteDepth ) - ResetRenderTarget(1); + if (s_bWriteDepth) ResetRenderTarget(1); SetShaderCaller("RenderFBA"); + glEnable(GL_ALPHA_TEST); + glAlphaFunc(GL_GEQUAL, 1); - Vector v; - v.x = 1; v.y = 2; v.z = 0; v.w = 0; + Vector v(1,2,0,0); + ZZcgSetParameter4fv(sOneColor, v, "g_fOneColor"); DRAW(); @@ -1404,45 +1629,47 @@ inline void ZeroGS::RenderFBA(const VB& curvb, CGparameter sOneColor) // reset (not necessary) GL_COLORMASK(s_dwColorWrite); + glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - if( !curvb.zbuf.zmsk ) + if (!curvb.zbuf.zmsk) { glDepthMask(1); - assert( curvb.pdepth != NULL ); - if( s_bWriteDepth ) - curvb.pdepth->SetRenderTarget(1); + assert(curvb.pdepth != NULL); + + if (s_bWriteDepth) curvb.pdepth->SetRenderTarget(1); } + GL_ZTEST(curvb.test.zte); } __forceinline void ZeroGS::RenderAlphaTest(const VB& curvb, CGparameter sOneColor) { - if( !g_bUpdateStencil ) return; + if (!g_bUpdateStencil) return; - if( (curvb.test.ate) && (curvb.test.afail == 1)) - glDisable(GL_ALPHA_TEST); + if ((curvb.test.ate) && (curvb.test.afail == 1)) glDisable(GL_ALPHA_TEST); glDepthMask(0); - glColorMask(0,0,0,0); - if (s_bWriteDepth) - ResetRenderTarget(1); + glColorMask(0, 0, 0, 0); + + if (s_bWriteDepth) ResetRenderTarget(1); SetShaderCaller("RenderAlphaTest"); - Vector v; - v.x = 1; v.y = 2; v.z = 0; v.w = 0; + Vector v(1,2,0,0); + ZZcgSetParameter4fv(sOneColor, v, "g_fOneColor"); // or a 1 to the stencil buffer wherever alpha passes glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); + s_stencilfunc = GL_ALWAYS; glEnable(GL_STENCIL_TEST); - if( !s_bDestAlphaTest ) + if (!s_bDestAlphaTest) { // clear everything s_stencilref = 0; @@ -1451,34 +1678,36 @@ __forceinline void ZeroGS::RenderAlphaTest(const VB& curvb, CGparameter sOneColo GL_STENCILFUNC_SET(); DRAW(); - if( curvb.test.ate && curvb.test.afail != 1 && USEALPHATESTING ) - glEnable(GL_ALPHA_TEST); + if (curvb.test.ate && curvb.test.afail != 1 && USEALPHATESTING) glEnable(GL_ALPHA_TEST); } - if( curvb.test.ate && curvb.test.atst>1 && curvb.test.aref > 0x80) + if (curvb.test.ate && curvb.test.atst > 1 && curvb.test.aref > 0x80) { - v.x = 1; v.y = 1; v.z = 0; v.w = 0; + v = Vector(1,1,0,0); ZZcgSetParameter4fv(sOneColor, v, "g_fOneColor"); glAlphaFunc(g_dwAlphaCmp[curvb.test.atst], AlphaReferedValue(curvb.test.aref)); } s_stencilref = STENCIL_SPECIAL; + glStencilMask(STENCIL_SPECIAL); GL_STENCILFUNC_SET(); glDisable(GL_DEPTH_TEST); DRAW(); - if( curvb.test.zte ) - glEnable(GL_DEPTH_TEST); + if (curvb.test.zte) glEnable(GL_DEPTH_TEST); + GL_ALPHATEST(0); + GL_COLORMASK(s_dwColorWrite); - if( !curvb.zbuf.zmsk ) + if (!curvb.zbuf.zmsk) { glDepthMask(1); // set rt next level + if (s_bWriteDepth) curvb.pdepth->SetRenderTarget(1); } } @@ -1493,80 +1722,81 @@ inline void ZeroGS::RenderStencil(const VB& curvb, u32 dwUsingSpecialTesting) glStencilMask(STENCIL_PIXELWRITE); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - s_stencilmask = (curvb.test.date?STENCIL_ALPHABIT:0)|(dwUsingSpecialTesting?STENCIL_SPECIAL:0); + s_stencilmask = (curvb.test.date ? STENCIL_ALPHABIT : 0) | (dwUsingSpecialTesting ? STENCIL_SPECIAL : 0); s_stencilfunc = s_stencilmask ? GL_EQUAL : GL_ALWAYS; - s_stencilref = curvb.test.date*curvb.test.datm|STENCIL_PIXELWRITE|(dwUsingSpecialTesting?STENCIL_SPECIAL:0); + s_stencilref = curvb.test.date * curvb.test.datm | STENCIL_PIXELWRITE | (dwUsingSpecialTesting ? STENCIL_SPECIAL : 0); GL_STENCILFUNC_SET(); } inline void ZeroGS::ProcessStencil(const VB& curvb) { - assert( !curvb.fba.fba ); + assert(!curvb.fba.fba); // set new alpha bit glStencilMask(STENCIL_ALPHABIT); - GL_STENCILFUNC(GL_EQUAL, STENCIL_PIXELWRITE, STENCIL_PIXELWRITE|STENCIL_FBA); + GL_STENCILFUNC(GL_EQUAL, STENCIL_PIXELWRITE, STENCIL_PIXELWRITE | STENCIL_FBA); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); glDisable(GL_DEPTH_TEST); glDepthMask(0); - glColorMask(0,0,0,0); + glColorMask(0, 0, 0, 0); if (s_bWriteDepth) ResetRenderTarget(1); GL_ALPHATEST(0); + SetShaderCaller("ProcessStencil"); SETPIXELSHADER(ppsOne.prog); DRAW(); // process when alpha >= 0xff - GL_STENCILFUNC(GL_EQUAL, STENCIL_PIXELWRITE|STENCIL_FBA|STENCIL_ALPHABIT, STENCIL_PIXELWRITE|STENCIL_FBA); + GL_STENCILFUNC(GL_EQUAL, STENCIL_PIXELWRITE | STENCIL_FBA | STENCIL_ALPHABIT, STENCIL_PIXELWRITE | STENCIL_FBA); DRAW(); // clear STENCIL_PIXELWRITE bit glStencilMask(STENCIL_CLEAR); - GL_STENCILFUNC(GL_ALWAYS, 0, STENCIL_PIXELWRITE|STENCIL_FBA); + GL_STENCILFUNC(GL_ALWAYS, 0, STENCIL_PIXELWRITE | STENCIL_FBA); DRAW(); // restore state GL_COLORMASK(s_dwColorWrite); - if( curvb.test.ate && USEALPHATESTING) - glEnable(GL_ALPHA_TEST); + if (curvb.test.ate && USEALPHATESTING) glEnable(GL_ALPHA_TEST); - if( !curvb.zbuf.zmsk ) { + if (!curvb.zbuf.zmsk) + { glDepthMask(1); - if( s_bWriteDepth ) { - assert( curvb.pdepth != NULL ); + if (s_bWriteDepth) + { + assert(curvb.pdepth != NULL); curvb.pdepth->SetRenderTarget(1); } } GL_ZTEST(curvb.test.zte); + glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); } __forceinline void ZeroGS::ProcessFBA(const VB& curvb, CGparameter sOneColor) { - if( (curvb.frame.fbm&0x80000000) ) return; + if ((curvb.frame.fbm&0x80000000)) return; // add fba to all pixels that were written and alpha was less than 0xff glStencilMask(STENCIL_ALPHABIT); glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - - GL_STENCILFUNC(GL_EQUAL, STENCIL_FBA|STENCIL_PIXELWRITE|STENCIL_ALPHABIT, STENCIL_PIXELWRITE|STENCIL_FBA); - + GL_STENCILFUNC(GL_EQUAL, STENCIL_FBA | STENCIL_PIXELWRITE | STENCIL_ALPHABIT, STENCIL_PIXELWRITE | STENCIL_FBA); glDisable(GL_DEPTH_TEST); - glDepthMask(0); - glColorMask(0,0,0,1); - if( s_bWriteDepth ) { - ResetRenderTarget(1); - } + glDepthMask(0); + glColorMask(0, 0, 0, 1); + + if (s_bWriteDepth) ResetRenderTarget(1); + SetShaderCaller("ProcessFBA"); // processes the pixels with ALPHA < 0x80*2 @@ -1580,35 +1810,36 @@ __forceinline void ZeroGS::ProcessFBA(const VB& curvb, CGparameter sOneColor) float f = 1; ZZcgSetParameter4fv(sOneColor, &f, "g_fOneColor"); SETPIXELSHADER(ppsOne.prog); - DRAW(); - glDisable(GL_ALPHA_TEST); // reset bits glStencilMask(STENCIL_CLEAR); - GL_STENCILFUNC(GL_GREATER, 0, STENCIL_PIXELWRITE|STENCIL_FBA); + GL_STENCILFUNC(GL_GREATER, 0, STENCIL_PIXELWRITE | STENCIL_FBA); glStencilOp(GL_KEEP, GL_KEEP, GL_ZERO); - DRAW(); - if( curvb.test.atst && USEALPHATESTING) { + if (curvb.test.atst && USEALPHATESTING) + { glEnable(GL_ALPHA_TEST); glAlphaFunc(g_dwAlphaCmp[curvb.test.atst], AlphaReferedValue(curvb.test.aref)); } // restore (SetAlphaVariables) GL_BLEND_ALPHA(GL_ONE, GL_ZERO); - if(vAlphaBlendColor.y<0) GL_BLENDEQ_ALPHA(GL_FUNC_REVERSE_SUBTRACT); + + if (vAlphaBlendColor.y < 0) GL_BLENDEQ_ALPHA(GL_FUNC_REVERSE_SUBTRACT); // reset (not necessary) GL_COLORMASK(s_dwColorWrite); - if( !curvb.zbuf.zmsk ) { + if (!curvb.zbuf.zmsk) + { glDepthMask(1); if (s_bWriteDepth) curvb.pdepth->SetRenderTarget(1); } + GL_ZTEST(curvb.test.zte); } @@ -1618,38 +1849,45 @@ void ZeroGS::SetContextTarget(int context) VB& curvb = vb[context]; GL_REPORT_ERRORD(); - if( curvb.prndr == NULL ) + if (curvb.prndr == NULL) curvb.prndr = s_RTs.GetTarg(curvb.frame, 0, get_maxheight(curvb.gsfb.fbp, curvb.gsfb.fbw, curvb.gsfb.psm)); // make sure targets are valid - if( curvb.pdepth == NULL ) { + if (curvb.pdepth == NULL) + { frameInfo f; f.fbp = curvb.zbuf.zbp; f.fbw = curvb.frame.fbw; f.fbh = curvb.prndr->fbh; f.psm = curvb.zbuf.psm; f.fbm = 0; - curvb.pdepth = (CDepthTarget*)s_DepthRTs.GetTarg(f, CRenderTargetMngr::TO_DepthBuffer|CRenderTargetMngr::TO_StrictHeight| - (curvb.zbuf.zmsk?CRenderTargetMngr::TO_Virtual:0), get_maxheight(curvb.zbuf.zbp, curvb.gsfb.fbw, 0)); + curvb.pdepth = (CDepthTarget*)s_DepthRTs.GetTarg(f, CRenderTargetMngr::TO_DepthBuffer | CRenderTargetMngr::TO_StrictHeight | + (curvb.zbuf.zmsk ? CRenderTargetMngr::TO_Virtual : 0), get_maxheight(curvb.zbuf.zbp, curvb.gsfb.fbw, 0)); } - assert( curvb.prndr != NULL && curvb.pdepth != NULL ); - assert( curvb.pdepth->fbh == curvb.prndr->fbh ); + assert(curvb.prndr != NULL && curvb.pdepth != NULL); - if( curvb.pdepth->status & CRenderTarget::TS_Virtual) { + assert(curvb.pdepth->fbh == curvb.prndr->fbh); - if( !curvb.zbuf.zmsk ) { - CRenderTarget* ptemp = s_DepthRTs.Promote(curvb.pdepth->fbp|(curvb.pdepth->fbw<<16)); - assert( ptemp == curvb.pdepth ); + if (curvb.pdepth->status & CRenderTarget::TS_Virtual) + { + + if (!curvb.zbuf.zmsk) + { + CRenderTarget* ptemp = s_DepthRTs.Promote(curvb.pdepth->fbp | (curvb.pdepth->fbw << 16)); + assert(ptemp == curvb.pdepth); } else + { curvb.pdepth->status &= ~CRenderTarget::TS_NeedUpdate; + } } bool bSetTarg = 1; - if( curvb.pdepth->status & CRenderTarget::TS_NeedUpdate ) { - assert( !(curvb.pdepth->status & CRenderTarget::TS_Virtual) ); + if (curvb.pdepth->status & CRenderTarget::TS_NeedUpdate) + { + assert(!(curvb.pdepth->status & CRenderTarget::TS_Virtual)); // don't update if virtual curvb.pdepth->Update(context, curvb.prndr); @@ -1657,19 +1895,22 @@ void ZeroGS::SetContextTarget(int context) } GL_REPORT_ERRORD(); - if( curvb.prndr->status & CRenderTarget::TS_NeedUpdate ) { -/* if(bSetTarg) { -* printf ( " Here\n "); -* if(s_bWriteDepth) { -* curvb.pdepth->SetRenderTarget(1); -* curvb.pdepth->SetDepthStencilSurface(); -* } -* else -* curvb.pdepth->SetDepthStencilSurface(); -* }*/ + + if (curvb.prndr->status & CRenderTarget::TS_NeedUpdate) + { + /* if(bSetTarg) { + * printf ( " Here\n "); + * if(s_bWriteDepth) { + * curvb.pdepth->SetRenderTarget(1); + * curvb.pdepth->SetDepthStencilSurface(); + * } + * else + * curvb.pdepth->SetDepthStencilSurface(); + * }*/ curvb.prndr->Update(context, curvb.pdepth); } - else { + else + { //if( (vb[0].prndr != vb[1].prndr && vb[!context].bVarsSetTarg) || !vb[context].bVarsSetTarg ) curvb.prndr->SetRenderTarget(0); @@ -1677,7 +1918,6 @@ void ZeroGS::SetContextTarget(int context) curvb.pdepth->SetDepthStencilSurface(); if (conf.mrtdepth && ZeroGS::IsWriteDepth()) curvb.pdepth->SetRenderTarget(1); - if (s_ptexCurSet[0] == curvb.prndr->ptex) s_ptexCurSet[0] = 0; if (s_ptexCurSet[1] == curvb.prndr->ptex) s_ptexCurSet[1] = 0; @@ -1686,44 +1926,55 @@ void ZeroGS::SetContextTarget(int context) curvb.prndr->SetTarget(curvb.frame.fbp, curvb.scissor, context); - if ((curvb.zbuf.zbp-curvb.pdepth->fbp) != (curvb.frame.fbp - curvb.prndr->fbp) && curvb.test.zte) + if ((curvb.zbuf.zbp - curvb.pdepth->fbp) != (curvb.frame.fbp - curvb.prndr->fbp) && curvb.test.zte) ZZLog::Warn_Log("Frame and zbuf not aligned."); curvb.bVarsSetTarg = TRUE; - if( vb[!context].prndr != curvb.prndr ) vb[!context].bVarsSetTarg = FALSE; - assert( !(curvb.prndr->status&CRenderTarget::TS_NeedUpdate) ); - assert( curvb.pdepth == NULL || !(curvb.pdepth->status&CRenderTarget::TS_NeedUpdate) ); + if (vb[!context].prndr != curvb.prndr) vb[!context].bVarsSetTarg = FALSE; + + assert(!(curvb.prndr->status&CRenderTarget::TS_NeedUpdate)); + assert(curvb.pdepth == NULL || !(curvb.pdepth->status&CRenderTarget::TS_NeedUpdate)); + GL_REPORT_ERRORD(); } -void ZeroGS::SetTexInt (int context, FRAGMENTSHADER* pfragment, int settexint ) { +void ZeroGS::SetTexInt(int context, FRAGMENTSHADER* pfragment, int settexint) +{ FUNCLOG - if (settexint) { + + if (settexint) + { tex0Info& tex0 = vb[context].tex0; CMemoryTarget* pmemtarg = g_MemTargs.GetMemoryTarget(tex0, 1); - if (vb[context].bVarsTexSync) { - if (vb[context].pmemtarg != pmemtarg) { + + if (vb[context].bVarsTexSync) + { + if (vb[context].pmemtarg != pmemtarg) + { SetTexVariablesInt(context, GetTexFilter(vb[context].tex1), tex0, pmemtarg, pfragment, s_bForceTexFlush); vb[context].bVarsTexSync = TRUE; } } - else { + else + { SetTexVariablesInt(context, GetTexFilter(vb[context].tex1), tex0, pmemtarg, pfragment, s_bForceTexFlush); vb[context].bVarsTexSync = TRUE; INC_TEXVARS(); } } - else { + else + { vb[context].bVarsTexSync = FALSE; } } // clamp relies on texture width -void ZeroGS::SetTexClamping(int context, FRAGMENTSHADER* pfragment ) { +void ZeroGS::SetTexClamping(int context, FRAGMENTSHADER* pfragment) +{ FUNCLOG SetShaderCaller("SetTexClamping"); clampInfo* pclamp = &ZeroGS::vb[context].clamp; @@ -1735,16 +1986,22 @@ void ZeroGS::SetTexClamping(int context, FRAGMENTSHADER* pfragment ) { float fw = ZeroGS::vb[context].tex0.tw ; float fh = ZeroGS::vb[context].tex0.th ; - switch(pclamp->wms) { + switch (pclamp->wms) + { case 0: - v2.x = -1e10; v2.z = 1e10; + v2.x = -1e10; + v2.z = 1e10; break; + case 1: // pclamp // suikoden5 movie text - v2.x = 0; v2.z = 1-0.5f/fw; + v2.x = 0; + v2.z = 1 - 0.5f / fw; break; + case 2: // reg pclamp - v2.x = (pclamp->minu+0.5f)/fw; v2.z = (pclamp->maxu-0.5f)/fw; + v2.x = (pclamp->minu + 0.5f) / fw; + v2.z = (pclamp->maxu - 0.5f) / fw; break; case 3: // region rep x @@ -1754,23 +2011,32 @@ void ZeroGS::SetTexClamping(int context, FRAGMENTSHADER* pfragment ) { v2.z = pclamp->maxu / fw; int correctMinu = pclamp->minu & (~pclamp->maxu); // (A && B) || C == (A && (B && !C)) + C - if( correctMinu != g_PrevBitwiseTexX ) { + if (correctMinu != g_PrevBitwiseTexX) + { g_PrevBitwiseTexX = correctMinu; ptex[0] = ZeroGS::s_BitwiseTextures.GetTex(correctMinu, 0); - } + } + break; } - switch(pclamp->wmt) { + switch (pclamp->wmt) + { + case 0: - v2.y = -1e10; v2.w = 1e10; + v2.y = -1e10; + v2.w = 1e10; break; + case 1: // pclamp // suikoden5 movie text - v2.y = 0; v2.w = 1-0.5f/fh; + v2.y = 0; + v2.w = 1 - 0.5f / fh; break; + case 2: // reg pclamp - v2.y = (pclamp->minv+0.5f)/fh; v2.w = (pclamp->maxv-0.5f)/fh; + v2.y = (pclamp->minv + 0.5f) / fh; + v2.w = (pclamp->maxv - 0.5f) / fh; break; case 3: // region rep y @@ -1780,42 +2046,50 @@ void ZeroGS::SetTexClamping(int context, FRAGMENTSHADER* pfragment ) { v2.w = pclamp->maxv / fh; int correctMinv = pclamp->minv & (~pclamp->maxv); // (A && B) || C == (A && (B && !C)) + C - if( correctMinv != g_PrevBitwiseTexY ) { + if (correctMinv != g_PrevBitwiseTexY) + { g_PrevBitwiseTexY = correctMinv; ptex[1] = ZeroGS::s_BitwiseTextures.GetTex(correctMinv, ptex[0]); } break; - } + } - if( pfragment->fTexWrapMode != 0 ) + if (pfragment->fTexWrapMode != 0) ZZcgSetParameter4fv(pfragment->fTexWrapMode, v, "g_fTexWrapMode"); - if( pfragment->fClampExts != 0 ) + + if (pfragment->fClampExts != 0) ZZcgSetParameter4fv(pfragment->fClampExts, v2, "g_fClampExts"); } // Fixme should be in Vector lib -inline bool equal_vectors( Vector a, Vector b){ - if ( abs(a.x - b.x) + abs(a.y - b.y) + abs(a.z - b.z) + abs(a.w - b.w) < 0.01 ) +inline bool equal_vectors(Vector a, Vector b) +{ + if (abs(a.x - b.x) + abs(a.y - b.y) + abs(a.z - b.z) + abs(a.w - b.w) < 0.01) return true; else return false; } -int CheckTexArray[4][2][2][2] = {{{{0,}}}}; -void ZeroGS::SetTexVariables(int context, FRAGMENTSHADER* pfragment ) { +int CheckTexArray[4][2][2][2] = {{{{0, }}}}; +void ZeroGS::SetTexVariables(int context, FRAGMENTSHADER* pfragment) +{ FUNCLOG + if (!vb[context].curprim.tme) return; - assert( !vb[context].bNeedTexCheck ); + + assert(!vb[context].bNeedTexCheck); Vector v, v2; + tex0Info& tex0 = vb[context].tex0; //float fw = (float)tex0.tw; //float fh = (float)tex0.th; - if( !vb[context].bTexConstsSync ) { + if (!vb[context].bTexConstsSync) + { SetShaderCaller("SetTexVariables"); // alpha and texture highlighting @@ -1829,153 +2103,162 @@ void ZeroGS::SetTexVariables(int context, FRAGMENTSHADER* pfragment ) { Vector vblack; vblack.x = vblack.y = vblack.z = vblack.w = 10; -/* tcc -- Tecture Color Component 0=RGB, 1=RGBA + use Alpha from TEXA reg when not in PSM - * tfx -- Texture Function (0=modulate, 1=decal, 2=hilight, 3=hilight2) - * - * valpha2 = 0 0 2 1 0 0 2 1 - * 1 0 0 0 1 1 0 0 - * 0 0 2 0 0 1 2 0 - * 0 0 2 0 0 1 2 0 - * - * 0 1,!nNeed 1, psm=2, 10 1, psm=1 - * valpha = 0 0 0 1 0 2 0 0 2ta0 2ta1-2ta0 0 0 2ta0 0 0 0 - * 0 0 0 1 0 1 0 0 ta0 ta1-ta0 0 0 ta0 0 0 0 - * 0 0 1 1 0 1 1 1 1 1 ta0 0 1 1 - * 0 0 1 1 0 1 1 0 1 0 ta0 0 1 0 -*/ + /* tcc -- Tecture Color Component 0=RGB, 1=RGBA + use Alpha from TEXA reg when not in PSM + * tfx -- Texture Function (0=modulate, 1=decal, 2=hilight, 3=hilight2) + * + * valpha2 = 0 0 2 1 0 0 2 1 + * 1 0 0 0 1 1 0 0 + * 0 0 2 0 0 1 2 0 + * 0 0 2 0 0 1 2 0 + * + * 0 1,!nNeed 1, psm=2, 10 1, psm=1 + * valpha = 0 0 0 1 0 2 0 0 2ta0 2ta1-2ta0 0 0 2ta0 0 0 0 + * 0 0 0 1 0 1 0 0 ta0 ta1-ta0 0 0 ta0 0 0 0 + * 0 0 1 1 0 1 1 1 1 1 ta0 0 1 1 + * 0 0 1 1 0 1 1 0 1 0 ta0 0 1 0 + */ - valpha2.x = ( tex0.tfx == 1 ) ; - valpha2.y = ( tex0.tcc == 1 ) && ( tex0.tfx != 0 ) ; - valpha2.z = ( tex0.tfx != 1 ) * 2 ; - valpha2.w = ( tex0.tfx == 0 ) ; + valpha2.x = (tex0.tfx == 1) ; + valpha2.y = (tex0.tcc == 1) && (tex0.tfx != 0) ; + valpha2.z = (tex0.tfx != 1) * 2 ; + valpha2.w = (tex0.tfx == 0) ; - if ( tex0.tcc == 0 || !nNeedAlpha(psm) ) { + if (tex0.tcc == 0 || !nNeedAlpha(psm)) + { valpha.x = 0 ; - valpha.y = ( !!tex0.tcc ) * ( 1 + ( tex0.tfx == 0) ) ; } - else { - valpha.x = ( gs.texa.fta[0] ) * ( 1 + ( tex0.tfx == 0) ) ; - valpha.y = ( gs.texa.fta[psm!=1] - gs.texa.fta[0] ) * ( 1 + ( tex0.tfx == 0) ) ; + valpha.y = (!!tex0.tcc) * (1 + (tex0.tfx == 0)) ; + } + else + { + valpha.x = (gs.texa.fta[0]) * (1 + (tex0.tfx == 0)) ; + valpha.y = (gs.texa.fta[psm!=1] - gs.texa.fta[0]) * (1 + (tex0.tfx == 0)) ; } - valpha.z = ( tex0.tfx >= 3 ) ; - valpha.w = ( tex0.tcc == 0 ) || ( tex0.tcc == 1 && tex0.tfx == 2 ) ; + valpha.z = (tex0.tfx >= 3) ; - if( tex0.tcc && gs.texa.aem && psm == PSMCT24 ) + valpha.w = (tex0.tcc == 0) || (tex0.tcc == 1 && tex0.tfx == 2) ; + + if (tex0.tcc && gs.texa.aem && psm == PSMCT24) vblack.w = 0; -/* -// Test, old code. - Vector valpha3, valpha4; - switch(tex0.tfx) { - case 0: - valpha3.z = 0; valpha3.w = 0; - valpha4.x = 0; valpha4.y = 0; - valpha4.z = 2; valpha4.w = 1; - break; - case 1: - valpha3.z = 0; valpha3.w = 1; - valpha4.x = 1; valpha4.y = 0; - valpha4.z = 0; valpha4.w = 0; + /* + // Test, old code. + Vector valpha3, valpha4; + switch(tex0.tfx) { + case 0: + valpha3.z = 0; valpha3.w = 0; + valpha4.x = 0; valpha4.y = 0; + valpha4.z = 2; valpha4.w = 1; - break; - case 2: - valpha3.z = 1; valpha3.w = 1.0f; - valpha4.x = 0; valpha4.y = tex0.tcc ? 1.0f : 0.0f; - valpha4.z = 2; valpha4.w = 0; + break; + case 1: + valpha3.z = 0; valpha3.w = 1; + valpha4.x = 1; valpha4.y = 0; + valpha4.z = 0; valpha4.w = 0; - break; + break; + case 2: + valpha3.z = 1; valpha3.w = 1.0f; + valpha4.x = 0; valpha4.y = tex0.tcc ? 1.0f : 0.0f; + valpha4.z = 2; valpha4.w = 0; - case 3: - valpha3.z = 1; valpha3.w = tex0.tcc ? 0.0f : 1.0f; - valpha4.x = 0; valpha4.y = tex0.tcc ? 1.0f : 0.0f; - valpha4.z = 2; valpha4.w = 0; + break; - break; - } - if( tex0.tcc ) { + case 3: + valpha3.z = 1; valpha3.w = tex0.tcc ? 0.0f : 1.0f; + valpha4.x = 0; valpha4.y = tex0.tcc ? 1.0f : 0.0f; + valpha4.z = 2; valpha4.w = 0; - if( tex0.tfx == 1 ) { - //mode.x = 10; - valpha3.z = 0; valpha3.w = 0; - valpha4.x = 1; valpha4.y = 1; - valpha4.z = 0; valpha4.w = 0; - } + break; + } + if( tex0.tcc ) { - if( nNeedAlpha(psm) ) { + if( tex0.tfx == 1 ) { + //mode.x = 10; + valpha3.z = 0; valpha3.w = 0; + valpha4.x = 1; valpha4.y = 1; + valpha4.z = 0; valpha4.w = 0; + } - if( tex0.tfx == 0 ) { - // make sure alpha is mult by two when the output is Cv = Ct*Cf - valpha3.x = 2*gs.texa.fta[0]; - // if 24bit, always choose ta[0] - valpha3.y = 2*gs.texa.fta[psm != 1]; - valpha3.y -= valpha.x; + if( nNeedAlpha(psm) ) { + + if( tex0.tfx == 0 ) { + // make sure alpha is mult by two when the output is Cv = Ct*Cf + valpha3.x = 2*gs.texa.fta[0]; + // if 24bit, always choose ta[0] + valpha3.y = 2*gs.texa.fta[psm != 1]; + valpha3.y -= valpha.x; + } + else { + valpha3.x = gs.texa.fta[0]; + // if 24bit, always choose ta[0] + valpha3.y = gs.texa.fta[psm != 1]; + valpha3.y -= valpha.x; + } + } + else { + if( tex0.tfx == 0 ) { + valpha3.x = 0; + valpha3.y = 2; + } + else { + valpha3.x = 0; + valpha3.y = 1; + } + } } else { - valpha3.x = gs.texa.fta[0]; - // if 24bit, always choose ta[0] - valpha3.y = gs.texa.fta[psm != 1]; - valpha3.y -= valpha.x; - } - } - else { - if( tex0.tfx == 0 ) { - valpha3.x = 0; - valpha3.y = 2; - } - else { - valpha3.x = 0; - valpha3.y = 1; - } - } - } - else { - // reset alpha to color - valpha3.x = valpha3.y = 0; - valpha3.w = 1; - } + // reset alpha to color + valpha3.x = valpha3.y = 0; + valpha3.w = 1; + } - if ( equal_vectors(valpha, valpha3) && equal_vectors(valpha2, valpha4) ) { - if (CheckTexArray[tex0.tfx][tex0.tcc][psm!=1][nNeedAlpha(psm)] == 0) { - printf ( "Good issue %d %d %d %d\n", tex0.tfx, tex0.tcc, psm, nNeedAlpha(psm) ); - CheckTexArray[tex0.tfx][tex0.tcc][psm!=1][nNeedAlpha(psm) ] = 1; - } - } - else if (CheckTexArray[tex0.tfx][tex0.tcc][psm!=1][nNeedAlpha(psm)] == -1) { - printf ("Bad array, %d %d %d %d\n\tolf valpha %f, %f, %f, %f : valpha2 %f %f %f %f\n\tnew valpha %f, %f, %f, %f : valpha2 %f %f %f %f\n", - tex0.tfx, tex0.tcc, psm, nNeedAlpha(psm), - valpha3.x, valpha3.y, valpha3.z, valpha3.w, valpha4.x, valpha4.y, valpha4.z, valpha4.w, - valpha.x, valpha.y, valpha.z, valpha.w, valpha2.x, valpha2.y, valpha2.z, valpha2.w); - CheckTexArray[tex0.tfx][tex0.tcc][psm!=1][nNeedAlpha(psm)] = -1 ; - } + if ( equal_vectors(valpha, valpha3) && equal_vectors(valpha2, valpha4) ) { + if (CheckTexArray[tex0.tfx][tex0.tcc][psm!=1][nNeedAlpha(psm)] == 0) { + printf ( "Good issue %d %d %d %d\n", tex0.tfx, tex0.tcc, psm, nNeedAlpha(psm) ); + CheckTexArray[tex0.tfx][tex0.tcc][psm!=1][nNeedAlpha(psm) ] = 1; + } + } + else if (CheckTexArray[tex0.tfx][tex0.tcc][psm!=1][nNeedAlpha(psm)] == -1) { + printf ("Bad array, %d %d %d %d\n\tolf valpha %f, %f, %f, %f : valpha2 %f %f %f %f\n\tnew valpha %f, %f, %f, %f : valpha2 %f %f %f %f\n", + tex0.tfx, tex0.tcc, psm, nNeedAlpha(psm), + valpha3.x, valpha3.y, valpha3.z, valpha3.w, valpha4.x, valpha4.y, valpha4.z, valpha4.w, + valpha.x, valpha.y, valpha.z, valpha.w, valpha2.x, valpha2.y, valpha2.z, valpha2.w); + CheckTexArray[tex0.tfx][tex0.tcc][psm!=1][nNeedAlpha(psm)] = -1 ; + } -// Test;*/ + // Test;*/ ZZcgSetParameter4fv(pfragment->fTexAlpha, valpha, "g_fTexAlpha"); ZZcgSetParameter4fv(pfragment->fTexAlpha2, valpha2, "g_fTexAlpha2"); - if(tex0.tcc && gs.texa.aem && nNeedAlpha(psm)) + + if (tex0.tcc && gs.texa.aem && nNeedAlpha(psm)) ZZcgSetParameter4fv(pfragment->fTestBlack, vblack, "g_fTestBlack"); SetTexClamping(context, pfragment); + vb[context].bTexConstsSync = TRUE; } - if(s_bTexFlush ) { - if( PSMT_ISCLUT(tex0.psm) ) + if (s_bTexFlush) + { + if (PSMT_ISCLUT(tex0.psm)) texClutWrite(context); else s_bTexFlush = FALSE; } } -void ZeroGS::SetTexVariablesInt(int context, int bilinear, const tex0Info& tex0, CMemoryTarget* pmemtarg, FRAGMENTSHADER* pfragment, int force) { +void ZeroGS::SetTexVariablesInt(int context, int bilinear, const tex0Info& tex0, CMemoryTarget* pmemtarg, FRAGMENTSHADER* pfragment, int force) +{ FUNCLOG Vector v; - assert( pmemtarg != NULL && pfragment != NULL && pmemtarg->ptex != NULL); + assert(pmemtarg != NULL && pfragment != NULL && pmemtarg->ptex != NULL); - if (pmemtarg == NULL || pfragment == NULL || pmemtarg->ptex == NULL ) + if (pmemtarg == NULL || pfragment == NULL || pmemtarg->ptex == NULL) { - printf ("SetTexVariablesInt error\n"); + printf("SetTexVariablesInt error\n"); return; } @@ -1985,18 +2268,22 @@ void ZeroGS::SetTexVariablesInt(int context, int bilinear, const tex0Info& tex0, float fh = (float)tex0.th; bool bUseBilinear = bilinear > 1 || (bilinear && conf.bilinear); - if( bUseBilinear ) { + + if (bUseBilinear) + { v.x = (float)fw; v.y = (float)fh; v.z = 1.0f / (float)fw; v.w = 1.0f / (float)fh; - if (pfragment->fRealTexDims) - ZZcgSetParameter4fv(pfragment->fRealTexDims, v, "g_fRealTexDims"); - else - ZZcgSetParameter4fv(cgGetNamedParameter(pfragment->prog,"g_fRealTexDims"),v, "g_fRealTexDims"); + + if (pfragment->fRealTexDims) + ZZcgSetParameter4fv(pfragment->fRealTexDims, v, "g_fRealTexDims"); + else + ZZcgSetParameter4fv(cgGetNamedParameter(pfragment->prog, "g_fRealTexDims"), v, "g_fRealTexDims"); } - if( m_Blocks[tex0.psm].bpp == 0 ) { + if (m_Blocks[tex0.psm].bpp == 0) + { ZZLog::Error_Log("Undefined tex psm 0x%x!", tex0.psm); return; } @@ -2006,73 +2293,79 @@ void ZeroGS::SetTexVariablesInt(int context, int bilinear, const tex0Info& tex0, float fbw = (float)tex0.tbw; Vector vTexDims; + vTexDims.x = b.vTexDims.x * (fw); vTexDims.y = b.vTexDims.y * (fh); vTexDims.z = (float)BLOCK_TEXWIDTH * (0.002f / 64.0f + 0.01f / 128.0f); vTexDims.w = (float)BLOCK_TEXHEIGHT * 0.1f / 512.0f; - if (bUseBilinear) { - vTexDims.x *= 1/128.0f; - vTexDims.y *= 1/512.0f; - vTexDims.z *= 1/128.0f; - vTexDims.w *= 1/512.0f; + if (bUseBilinear) + { + vTexDims.x *= 1 / 128.0f; + vTexDims.y *= 1 / 512.0f; + vTexDims.z *= 1 / 128.0f; + vTexDims.w *= 1 / 512.0f; } - float g_fitexwidth = g_fiGPU_TEXWIDTH/(float)pmemtarg->widthmult; + float g_fitexwidth = g_fiGPU_TEXWIDTH / (float)pmemtarg->widthmult; + //float g_texwidth = GPU_TEXWIDTH*(float)pmemtarg->widthmult; - float fpage = tex0.tbp0*(64.0f*g_fitexwidth);// + 0.05f * g_fitexwidth; + float fpage = tex0.tbp0 * (64.0f * g_fitexwidth);// + 0.05f * g_fitexwidth; float fpageint = floorf(fpage); //int starttbp = (int)fpage; // 2048 is number of words to span one page //float fblockstride = (2048.0f /(float)(g_texwidth*BLOCK_TEXWIDTH)) * b.vTexDims.x * fbw; - float fblockstride = (2048.0f /(float)(GPU_TEXWIDTH*(float)pmemtarg->widthmult*BLOCK_TEXWIDTH)) * b.vTexDims.x * fbw; + float fblockstride = (2048.0f / (float)(GPU_TEXWIDTH * (float)pmemtarg->widthmult * BLOCK_TEXWIDTH)) * b.vTexDims.x * fbw; - assert( fblockstride >= 1.0f ); + assert(fblockstride >= 1.0f); v.x = (float)(2048 * g_fitexwidth); v.y = fblockstride; - v.z = g_fBlockMult/(float)pmemtarg->widthmult; - v.w = fpage-fpageint ; + v.z = g_fBlockMult / (float)pmemtarg->widthmult; + v.w = fpage - fpageint ; - if( g_fBlockMult > 1 ) { + if (g_fBlockMult > 1) + { // make sure to divide by mult (since the G16R16 texture loses info) - v.z *= b.bpp * (1/32.0f); + v.z *= b.bpp * (1 / 32.0f); } ZZcgSetParameter4fv(pfragment->fTexDims, vTexDims, "g_fTexDims"); + // ZZcgSetParameter4fv(pfragment->fTexBlock, b.vTexBlock, "g_fTexBlock"); // I change it, and it's working. Seems casting from Vector to float[4] is ok. ZZcgSetParameter4fv(pfragment->fTexBlock, &b.vTexBlock.x, "g_fTexBlock"); ZZcgSetParameter4fv(pfragment->fTexOffset, v, "g_fTexOffset"); // get hardware texture dims //int texheight = (pmemtarg->realheight+pmemtarg->widthmult-1)/pmemtarg->widthmult; - int texwidth = GPU_TEXWIDTH*pmemtarg->widthmult*pmemtarg->channels; + int texwidth = GPU_TEXWIDTH * pmemtarg->widthmult * pmemtarg->channels; v.y = 1.0f; - v.x = (fpageint-(float)pmemtarg->realy/(float)pmemtarg->widthmult+0.5f);//*v.y; + v.x = (fpageint - (float)pmemtarg->realy / (float)pmemtarg->widthmult + 0.5f);//*v.y; v.z = (float)texwidth; -/* if( !(g_nPixelShaderVer & SHADER_ACCURATE) || bUseBilinear ) { - if (tex0.psm == PSMT4 ) - v.w = 0.0f; + /* if( !(g_nPixelShaderVer & SHADER_ACCURATE) || bUseBilinear ) { + if (tex0.psm == PSMT4 ) + v.w = 0.0f; + else + v.w = 0.25f; + } else - v.w = 0.25f; - } - else - v.w = 0.5f;*/ + v.w = 0.5f;*/ v.w = 0.5f; ZZcgSetParameter4fv(pfragment->fPageOffset, v, "g_fPageOffset"); - if( force ) + if (force) s_ptexCurSet[context] = pmemtarg->ptex->tex; else s_ptexNextSet[context] = pmemtarg->ptex->tex; vb[context].pmemtarg = pmemtarg; + vb[context].bVarsTexSync = FALSE; } @@ -2110,7 +2403,7 @@ void ZeroGS::SetTexVariablesInt(int context, int bilinear, const tex0Info& tex0, break; \ } \ } \ - + //if( a.fix <= 0x80 ) { \ // dwTemp = (a.fix*2)>255?255:(a.fix*2); \ // dwTemp = dwTemp|(dwTemp<<8)|(dwTemp<<16)|0x80000000; \ @@ -2123,9 +2416,11 @@ void ZeroGS::ResetAlphaVariables() { FUNCLOG } -inline void ZeroGS::NeedFactor( int w ) { - if (bDestAlphaColor == 2){ - bNeedBlendFactorInAlpha = (w+1) ? 1 : 0; +inline void ZeroGS::NeedFactor(int w) +{ + if (bDestAlphaColor == 2) + { + bNeedBlendFactorInAlpha = (w + 1) ? 1 : 0; vAlphaBlendColor.y = 0; vAlphaBlendColor.w = (float)w; } @@ -2152,50 +2447,50 @@ void ZeroGS::SetAlphaVariables(const alphaInfo& a) s_rgbeq = 1; s_alphaInfo = a; - vAlphaBlendColor = Vector(1,2*255.0f/256.0f,0,0); + vAlphaBlendColor = Vector(1, 2 * 255.0f / 256.0f, 0, 0); u32 usec = a.c; -/* - * Alpha table - * a + b + d - * S D - * 0 a -a 1 | 0 0 0 - * 1 0 0 0 | a -a 1 - * 2 0 0 0 | 0 0 0 - * - * d = 0 Cs - * a b 0 Cs 1 Cd 2 0 - * | | - * 0 000: a+-a+ 1 | 0+ 0+ 0 = 1 | 010: a+ 0+ 1 | 0+-a+ 0 = 1-(-a)(+)(-a) | 020: a+ 0+ 1 | 0+ 0+ 0 = 1-(-a) (+) 0 - * 1 100: 0+-a+ 1 | a+ 0+ 0 = 1-a (+) a | 110: 0+ 0+ 1 | a+-a+ 0 = 1 | 120: 0+ 0+ 1 | a+ 0+ 0 = 1 (+) a - * 2 200: 0+-a+ 1 | 0+ 0+ 0 = 1-a (+) 0 | 210: 0+ 0+ 1 | 0+-a+ 0 = 1 (-) a | 220: 0+ 0+ 1 | 0+ 0+ 0 = 1 - * - * d = 1 Cd - * 0 | 1 | 2 - * 0 001: a+-a+ 0 | 0+ 0+ 1 = 0 (+) 1 | 011: a+ 0+ 0 | 0+-a+ 1 = a (+) 1-a | 021: a+ 0+ 0 | 0+ 0+ 1 = a (+) 1 - * 1 101: 0+-a+ 0 | a+ 0+ 1 = (-a)(+) 1-(-a) | 111: 0+ 0+ 0 | a+-a+ 1 = 0 (+) 1 | 121: 0+ 0+ 0 | a+ 0+ 1 = 0 (+) 1-(-a) - * 2 201: 0+-a+ 0 | 0+ 0+ 1 = a (R-)1 | 211: 0+ 0+ 0 | 0+-a+ 1 = 0 (+) 1-a | 221: 0+ 0+ 0 | 0+ 0+ 1 = 0 (+) 1 - * - * d = 2 0 - * 0 | 1 | 2 - * 0 002: a+-a+ 0 | 0+ 0+ 0 = 0 | 012: a+ 0+ 0 | 0+-a+ 0 = a (-) a | 022: a+ 0+ 0 | 0+ 0+ 0 = a (+) 0 - * 1 102: 0+-a+ 0 | a+ 0+ 0 = a (R-) a | 112: 0+ 0+ 0 | a+-a+ 0 = 0 | 122: 0+ 0+ 0 | a+ 0+ 0 = 0 (+) a - * 2 202: 0+-a+ 0 | 0+ 0+ 0 = a (R-) 0 | 212: 0+ 0+ 0 | 0+-a+ 0 = 0 (-) a | 222: 0+ 0+ 0 | 0+ 0+ 0 = 0 - * - * Formulae is: (a-b) * (c /32) + d - * 0 1 2 - * a Cs Cd 0 - * b Cs Cd 0 - * c As Ad ALPHA.FIX - * d Cs Cd 0 - * - * We want to emulate Cs * F1(alpha) + Cd * F2(alpha) by OpenGl blending: (Cs * Ss (+,-,R-) Cd * Sd) - * SET_ALPHA_COLOR_FACTOR(sign) set Set A (as As>>7, Ad>>7 or FIX>>7) with sign. - * So we could use 1+a as one_minus_alpha and -a as alpha. - * - */ - int code = ( a.a * 16 ) + ( a.b * 4 ) + a.d ; + /* + * Alpha table + * a + b + d + * S D + * 0 a -a 1 | 0 0 0 + * 1 0 0 0 | a -a 1 + * 2 0 0 0 | 0 0 0 + * + * d = 0 Cs + * a b 0 Cs 1 Cd 2 0 + * | | + * 0 000: a+-a+ 1 | 0+ 0+ 0 = 1 | 010: a+ 0+ 1 | 0+-a+ 0 = 1-(-a)(+)(-a) | 020: a+ 0+ 1 | 0+ 0+ 0 = 1-(-a) (+) 0 + * 1 100: 0+-a+ 1 | a+ 0+ 0 = 1-a (+) a | 110: 0+ 0+ 1 | a+-a+ 0 = 1 | 120: 0+ 0+ 1 | a+ 0+ 0 = 1 (+) a + * 2 200: 0+-a+ 1 | 0+ 0+ 0 = 1-a (+) 0 | 210: 0+ 0+ 1 | 0+-a+ 0 = 1 (-) a | 220: 0+ 0+ 1 | 0+ 0+ 0 = 1 + * + * d = 1 Cd + * 0 | 1 | 2 + * 0 001: a+-a+ 0 | 0+ 0+ 1 = 0 (+) 1 | 011: a+ 0+ 0 | 0+-a+ 1 = a (+) 1-a | 021: a+ 0+ 0 | 0+ 0+ 1 = a (+) 1 + * 1 101: 0+-a+ 0 | a+ 0+ 1 = (-a)(+) 1-(-a) | 111: 0+ 0+ 0 | a+-a+ 1 = 0 (+) 1 | 121: 0+ 0+ 0 | a+ 0+ 1 = 0 (+) 1-(-a) + * 2 201: 0+-a+ 0 | 0+ 0+ 1 = a (R-)1 | 211: 0+ 0+ 0 | 0+-a+ 1 = 0 (+) 1-a | 221: 0+ 0+ 0 | 0+ 0+ 1 = 0 (+) 1 + * + * d = 2 0 + * 0 | 1 | 2 + * 0 002: a+-a+ 0 | 0+ 0+ 0 = 0 | 012: a+ 0+ 0 | 0+-a+ 0 = a (-) a | 022: a+ 0+ 0 | 0+ 0+ 0 = a (+) 0 + * 1 102: 0+-a+ 0 | a+ 0+ 0 = a (R-) a | 112: 0+ 0+ 0 | a+-a+ 0 = 0 | 122: 0+ 0+ 0 | a+ 0+ 0 = 0 (+) a + * 2 202: 0+-a+ 0 | 0+ 0+ 0 = a (R-) 0 | 212: 0+ 0+ 0 | 0+-a+ 0 = 0 (-) a | 222: 0+ 0+ 0 | 0+ 0+ 0 = 0 + * + * Formulae is: (a-b) * (c /32) + d + * 0 1 2 + * a Cs Cd 0 + * b Cs Cd 0 + * c As Ad ALPHA.FIX + * d Cs Cd 0 + * + * We want to emulate Cs * F1(alpha) + Cd * F2(alpha) by OpenGl blending: (Cs * Ss (+,-,R-) Cd * Sd) + * SET_ALPHA_COLOR_FACTOR(sign) set Set A (as As>>7, Ad>>7 or FIX>>7) with sign. + * So we could use 1+a as one_minus_alpha and -a as alpha. + * + */ + int code = (a.a * 16) + (a.b * 4) + a.d ; #define one_minus_alpha (bDestAlphaColor == 2) ? GL_ONE_MINUS_SRC_ALPHA : blendinvalpha[usec] #define alpha (bDestAlphaColor == 2) ? GL_SRC_ALPHA : blendalpha[usec] @@ -2203,41 +2498,51 @@ void ZeroGS::SetAlphaVariables(const alphaInfo& a) #define zero (bDestAlphaColor == 2) ? GL_ZERO : blendinvalpha[usec] switch (code) - { + { + case 0: // 000 // Cs -- nothing changed case 20: // 110 = 16+4=20 // Cs - case 40: { // 220 = 32+8=40 // Cs - alphaenable = false; - break; - } + case 40: // 220 = 32+8=40 // Cs + { + alphaenable = false; + break; + } + case 2: //002 // 0 -- should be zero case 22: //112 // 0 - case 42: { //222 = 32+8+2 =42 // 0 - s_rgbeq = GL_FUNC_ADD; - s_srcrgb = GL_ZERO; - s_dstrgb = GL_ZERO; - break; - } + case 42: //222 = 32+8+2 =42 // 0 + { + s_rgbeq = GL_FUNC_ADD; + s_srcrgb = GL_ZERO; + s_dstrgb = GL_ZERO; + break; + } + case 1: //001 // Cd -- Should be destination alpha case 21: //111, // Cd -- 0*Source + 1*Desrinarion - case 41: { //221 = 32+8+1=41 // Cd -- - s_rgbeq = GL_FUNC_ADD; - s_srcrgb = GL_ZERO; - s_dstrgb = GL_ONE; - break; - } - case 4: { // 010 // (Cs-Cd)*A+Cs = Cs * (A + 1) - Cd * A - bAlphaClamping = 3; - SET_ALPHA_COLOR_FACTOR(0); // a = -A + case 41: //221 = 32+8+1=41 // Cd -- + { + s_rgbeq = GL_FUNC_ADD; + s_srcrgb = GL_ZERO; + s_dstrgb = GL_ONE; + break; + } - s_rgbeq = GL_FUNC_ADD; // Cs*(1-a)+Cd*a - s_srcrgb = one_minus_alpha ; - s_dstrgb = alpha; + case 4: // 010 // (Cs-Cd)*A+Cs = Cs * (A + 1) - Cd * A + { + bAlphaClamping = 3; + SET_ALPHA_COLOR_FACTOR(0); // a = -A - NeedFactor(-1); - break; - } - case 5: { // 011 // (Cs-Cd)*A+Cs = Cs * A + Cd * (1-A) + s_rgbeq = GL_FUNC_ADD; // Cs*(1-a)+Cd*a + s_srcrgb = one_minus_alpha ; + s_dstrgb = alpha; + + NeedFactor(-1); + break; + } + + case 5: // 011 // (Cs-Cd)*A+Cs = Cs * A + Cd * (1-A) + { bAlphaClamping = 3; // all testing SET_ALPHA_COLOR_FACTOR(1); @@ -2247,364 +2552,407 @@ void ZeroGS::SetAlphaVariables(const alphaInfo& a) NeedFactor(1); break; - } - case 6: { //012 // (Cs-Cd)*FIX + } + + case 6: //012 // (Cs-Cd)*FIX + { bAlphaClamping = 3; SET_ALPHA_COLOR_FACTOR(1); - s_rgbeq = GL_FUNC_SUBTRACT; + s_rgbeq = GL_FUNC_SUBTRACT; s_srcrgb = alpha; s_dstrgb = alpha; break; - } - case 8: { //020 // Cs*A+Cs = Cs * (1+A) + } + + case 8: //020 // Cs*A+Cs = Cs * (1+A) + { bAlphaClamping = 2; // max testing SET_ALPHA_COLOR_FACTOR(0); // Zeyflitz change this! a = -A - - s_rgbeq = GL_FUNC_ADD; + + s_rgbeq = GL_FUNC_ADD; s_srcrgb = one_minus_alpha; // Cs*(1-a). s_dstrgb = GL_ZERO; // NeedFactor(1); break; - } - case 9: { //021 // Cs*A+Cd - bAlphaClamping = 2; // max testing - SET_ALPHA_COLOR_FACTOR(1); + } - s_rgbeq = GL_FUNC_ADD; + case 9: //021 // Cs*A+Cd + { + bAlphaClamping = 2; // max testing + SET_ALPHA_COLOR_FACTOR(1); + + s_rgbeq = GL_FUNC_ADD; s_srcrgb = alpha; // ZZ change it to. s_dstrgb = GL_ONE; break; - } - case 10: { //022 // Cs*A - bAlphaClamping = 2; // max testing - SET_ALPHA_COLOR_FACTOR(1); + } - s_rgbeq = GL_FUNC_ADD; - s_srcrgb = alpha; - s_dstrgb = GL_ZERO; - break; - } - case 16: { //100 - bAlphaClamping = 3; - SET_ALPHA_COLOR_FACTOR(1); + case 10: //022 // Cs*A + { + bAlphaClamping = 2; // max testing + SET_ALPHA_COLOR_FACTOR(1); - s_rgbeq = GL_FUNC_ADD; - s_srcrgb = one_minus_alpha; - s_dstrgb = alpha; + s_rgbeq = GL_FUNC_ADD; + s_srcrgb = alpha; + s_dstrgb = GL_ZERO; + break; + } - NeedFactor(1); - break; - } - case 17: { //101 - bAlphaClamping = 3; // all testing - SET_ALPHA_COLOR_FACTOR(0); + case 16: //100 + { + bAlphaClamping = 3; + SET_ALPHA_COLOR_FACTOR(1); - s_rgbeq = GL_FUNC_ADD; - s_srcrgb = alpha; - s_dstrgb = one_minus_alpha; + s_rgbeq = GL_FUNC_ADD; + s_srcrgb = one_minus_alpha; + s_dstrgb = alpha; - NeedFactor(-1); - break; - } - case 18: { //102 - bAlphaClamping = 3; - SET_ALPHA_COLOR_FACTOR(1); + NeedFactor(1); + break; + } - s_rgbeq = GL_FUNC_REVERSE_SUBTRACT; - s_srcrgb = alpha; - s_dstrgb = alpha; + case 17: //101 + { + bAlphaClamping = 3; // all testing + SET_ALPHA_COLOR_FACTOR(0); - break; - } - case 24: { //120 = 16+8 - bAlphaClamping = 2; // max testing - SET_ALPHA_COLOR_FACTOR(1); + s_rgbeq = GL_FUNC_ADD; + s_srcrgb = alpha; + s_dstrgb = one_minus_alpha; - s_rgbeq = GL_FUNC_ADD; - s_srcrgb = GL_ONE; - s_dstrgb = alpha; - break; - } - case 25: { //121 // Cd*(1+A) - bAlphaClamping = 2; // max testing - SET_ALPHA_COLOR_FACTOR(0); + NeedFactor(-1); + break; + } - s_rgbeq = GL_FUNC_ADD; - s_srcrgb = GL_ZERO; - s_dstrgb = one_minus_alpha; + case 18: //102 + { + bAlphaClamping = 3; + SET_ALPHA_COLOR_FACTOR(1); + + s_rgbeq = GL_FUNC_REVERSE_SUBTRACT; + s_srcrgb = alpha; + s_dstrgb = alpha; + + break; + } + + case 24: //120 = 16+8 + { + bAlphaClamping = 2; // max testing + SET_ALPHA_COLOR_FACTOR(1); + + s_rgbeq = GL_FUNC_ADD; + s_srcrgb = GL_ONE; + s_dstrgb = alpha; + break; + } + + case 25: //121 // Cd*(1+A) + { + bAlphaClamping = 2; // max testing + SET_ALPHA_COLOR_FACTOR(0); + + s_rgbeq = GL_FUNC_ADD; + s_srcrgb = GL_ZERO; + s_dstrgb = one_minus_alpha; // NeedFactor(-1); - break; - } - case 26: { //122 - bAlphaClamping = 2; - SET_ALPHA_COLOR_FACTOR(1); + break; + } - s_rgbeq = GL_FUNC_ADD; - s_srcrgb = GL_ZERO; - s_dstrgb = alpha; - break; - } - case 32: {// 200 = 32 - bAlphaClamping = 1; // min testing - SET_ALPHA_COLOR_FACTOR(1); + case 26: //122 + { + bAlphaClamping = 2; + SET_ALPHA_COLOR_FACTOR(1); - s_rgbeq = GL_FUNC_ADD; - s_srcrgb = one_minus_alpha; - s_dstrgb = GL_ZERO; - break; - } - case 33: {//201 // -Cs*A + Cd - bAlphaClamping = 1; // min testing - SET_ALPHA_COLOR_FACTOR(1); + s_rgbeq = GL_FUNC_ADD; + s_srcrgb = GL_ZERO; + s_dstrgb = alpha; + break; + } + + case 32: // 200 = 32 + { + bAlphaClamping = 1; // min testing + SET_ALPHA_COLOR_FACTOR(1); + + s_rgbeq = GL_FUNC_ADD; + s_srcrgb = one_minus_alpha; + s_dstrgb = GL_ZERO; + break; + } + + case 33: //201 // -Cs*A + Cd + { + bAlphaClamping = 1; // min testing + SET_ALPHA_COLOR_FACTOR(1); + + s_rgbeq = GL_FUNC_REVERSE_SUBTRACT; + s_srcrgb = alpha; + s_dstrgb = GL_ONE; + break; + } - s_rgbeq = GL_FUNC_REVERSE_SUBTRACT; - s_srcrgb = alpha; - s_dstrgb = GL_ONE; - break; - } case 34: //202 - case 38: {//212 - bAlphaClamping = 1; // min testing -- negative values + case 38: //212 + { + bAlphaClamping = 1; // min testing -- negative values - s_rgbeq = GL_FUNC_ADD; - s_srcrgb = GL_ZERO; - s_dstrgb = GL_ZERO; - break; - } - case 36: {//210 - bAlphaClamping = 1; // min testing - SET_ALPHA_COLOR_FACTOR(1); + s_rgbeq = GL_FUNC_ADD; + s_srcrgb = GL_ZERO; + s_dstrgb = GL_ZERO; + break; + } - s_rgbeq = GL_FUNC_SUBTRACT; - s_srcrgb = GL_ONE; - s_dstrgb = alpha; - break; - } - case 37: {//211 - bAlphaClamping = 1; // min testing - SET_ALPHA_COLOR_FACTOR(1); + case 36: //210 + { + bAlphaClamping = 1; // min testing + SET_ALPHA_COLOR_FACTOR(1); - s_rgbeq = GL_FUNC_ADD; - s_srcrgb = GL_ZERO; - s_dstrgb = one_minus_alpha; - break; - } - default: { + s_rgbeq = GL_FUNC_SUBTRACT; + s_srcrgb = GL_ONE; + s_dstrgb = alpha; + break; + } + + case 37: //211 + { + bAlphaClamping = 1; // min testing + SET_ALPHA_COLOR_FACTOR(1); + + s_rgbeq = GL_FUNC_ADD; + s_srcrgb = GL_ZERO; + s_dstrgb = one_minus_alpha; + break; + } + + default: + { ZZLog::Error_Log("Bad alpha code %d | %d %d %d", code, a.a, a.b, a.d); } } -/* - int t_rgbeq = GL_FUNC_ADD; - int t_srcrgb = GL_ONE; - int t_dstrgb = GL_ZERO; - int tAlphaClamping = 0; - if( a.a == a.b ) - { // just d remains - if( a.d == 0 ) {} - else - { - t_dstrgb = a.d == 1 ? GL_ONE : GL_ZERO; - t_srcrgb = GL_ZERO; - t_rgbeq = GL_FUNC_ADD; //a) (001) (111) (221) b) (002) (112) (222) + /* + int t_rgbeq = GL_FUNC_ADD; + int t_srcrgb = GL_ONE; + int t_dstrgb = GL_ZERO; + int tAlphaClamping = 0; + + if( a.a == a.b ) + { // just d remains + if( a.d == 0 ) {} + else + { + t_dstrgb = a.d == 1 ? GL_ONE : GL_ZERO; + t_srcrgb = GL_ZERO; + t_rgbeq = GL_FUNC_ADD; //a) (001) (111) (221) b) (002) (112) (222) + } + goto EndSetAlpha; } - goto EndSetAlpha; - } - else if( a.d == 2 ) - { // zero - if( a.a == 2 ) - { - // zero all color - t_srcrgb = GL_ZERO; - t_dstrgb = GL_ZERO; - goto EndSetAlpha; // (202) (212) + else if( a.d == 2 ) + { // zero + if( a.a == 2 ) + { + // zero all color + t_srcrgb = GL_ZERO; + t_dstrgb = GL_ZERO; + goto EndSetAlpha; // (202) (212) + } + else if( a.b == 2 ) + { + //b2XAlphaTest = 1; // a) (022) // b) (122) + SET_ALPHA_COLOR_FACTOR(1); + + if( bDestAlphaColor == 2 ) + { + t_rgbeq = GL_FUNC_ADD; + t_srcrgb = a.a == 0 ? GL_ONE : GL_ZERO; + t_dstrgb = a.a == 0 ? GL_ZERO : GL_ONE; + } + else + { + tAlphaClamping = 2; + t_rgbeq = GL_FUNC_ADD; + t_srcrgb = a.a == 0 ? blendalpha[usec] : GL_ZERO; + t_dstrgb = a.a == 0 ? GL_ZERO : blendalpha[usec]; + } + + goto EndSetAlpha; + } + + // nothing is zero, so must do some real blending //b2XAlphaTest = 1; //a) (012) //b) (102) + tAlphaClamping = 3; + + SET_ALPHA_COLOR_FACTOR(1); + + t_rgbeq = a.a == 0 ? GL_FUNC_SUBTRACT : GL_FUNC_REVERSE_SUBTRACT; + t_srcrgb = bDestAlphaColor == 2 ? GL_ONE : blendalpha[usec]; + t_dstrgb = bDestAlphaColor == 2 ? GL_ONE : blendalpha[usec]; + } + else if( a.a == 2 ) + { // zero + + //b2XAlphaTest = 1; + tAlphaClamping = 1; // min testing + + SET_ALPHA_COLOR_FACTOR(1); + + if( a.b == a.d ) + { + // can get away with 1-A + // a.a == a.d == 2!! (200) (211) + t_rgbeq = GL_FUNC_ADD; + t_srcrgb = (a.b == 0 && bDestAlphaColor != 2) ? blendinvalpha[usec] : GL_ZERO; + t_dstrgb = (a.b == 0 || bDestAlphaColor == 2) ? GL_ZERO : blendinvalpha[usec]; + } + else + { + // a) (201) b)(210) + t_rgbeq = a.b==0 ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_SUBTRACT; + t_srcrgb = (a.b == 0 && bDestAlphaColor != 2) ? blendalpha[usec] : GL_ONE; + t_dstrgb = (a.b == 0 || bDestAlphaColor == 2 ) ? GL_ONE : blendalpha[usec]; + } } else if( a.b == 2 ) { - //b2XAlphaTest = 1; // a) (022) // b) (122) - SET_ALPHA_COLOR_FACTOR(1); + tAlphaClamping = 2; // max testing - if( bDestAlphaColor == 2 ) + SET_ALPHA_COLOR_FACTOR(a.a!=a.d); + + if( a.a == a.d ) { + // can get away with 1+A, but need to set alpha to negative + // a)(020) + // b)(121) t_rgbeq = GL_FUNC_ADD; - t_srcrgb = a.a == 0 ? GL_ONE : GL_ZERO; - t_dstrgb = a.a == 0 ? GL_ZERO : GL_ONE; + + if( bDestAlphaColor == 2 ) + { + t_srcrgb = (a.a == 0) ? GL_ONE_MINUS_SRC_ALPHA : GL_ZERO; + t_dstrgb = (a.a == 0) ? GL_ZERO : GL_ONE_MINUS_SRC_ALPHA; + } + else + { + t_srcrgb = a.a == 0 ? blendinvalpha[usec] : GL_ZERO; + t_dstrgb = a.a == 0 ? GL_ZERO : blendinvalpha[usec]; + } } else { - tAlphaClamping = 2; + //a)(021) //b)(120) //b2XAlphaTest = 1; t_rgbeq = GL_FUNC_ADD; - t_srcrgb = a.a == 0 ? blendalpha[usec] : GL_ZERO; - t_dstrgb = a.a == 0 ? GL_ZERO : blendalpha[usec]; + t_srcrgb = (a.a == 0 && bDestAlphaColor != 2) ? blendalpha[usec] : GL_ONE; + t_dstrgb = (a.a == 0 || bDestAlphaColor == 2) ? GL_ONE : blendalpha[usec]; } - - goto EndSetAlpha; - } - - // nothing is zero, so must do some real blending //b2XAlphaTest = 1; //a) (012) //b) (102) - tAlphaClamping = 3; - - SET_ALPHA_COLOR_FACTOR(1); - - t_rgbeq = a.a == 0 ? GL_FUNC_SUBTRACT : GL_FUNC_REVERSE_SUBTRACT; - t_srcrgb = bDestAlphaColor == 2 ? GL_ONE : blendalpha[usec]; - t_dstrgb = bDestAlphaColor == 2 ? GL_ONE : blendalpha[usec]; - } - else if( a.a == 2 ) - { // zero - - //b2XAlphaTest = 1; - tAlphaClamping = 1; // min testing - - SET_ALPHA_COLOR_FACTOR(1); - - if( a.b == a.d ) - { - // can get away with 1-A - // a.a == a.d == 2!! (200) (211) - t_rgbeq = GL_FUNC_ADD; - t_srcrgb = (a.b == 0 && bDestAlphaColor != 2) ? blendinvalpha[usec] : GL_ZERO; - t_dstrgb = (a.b == 0 || bDestAlphaColor == 2) ? GL_ZERO : blendinvalpha[usec]; } else { - // a) (201) b)(210) - t_rgbeq = a.b==0 ? GL_FUNC_REVERSE_SUBTRACT : GL_FUNC_SUBTRACT; - t_srcrgb = (a.b == 0 && bDestAlphaColor != 2) ? blendalpha[usec] : GL_ONE; - t_dstrgb = (a.b == 0 || bDestAlphaColor == 2 ) ? GL_ONE : blendalpha[usec]; + // all 3 components are valid! + tAlphaClamping = 3; // all testing + SET_ALPHA_COLOR_FACTOR(a.a!=a.d); + + if( a.a == a.d ) + { + // can get away with 1+A, but need to set alpha to negative // a) 010, // b) 101 + t_rgbeq = GL_FUNC_ADD; + + if( bDestAlphaColor == 2 ) + { + // all ones + t_srcrgb = a.a == 0 ? GL_ONE_MINUS_SRC_ALPHA : GL_SRC_ALPHA; + t_dstrgb = a.a == 0 ? GL_SRC_ALPHA : GL_ONE_MINUS_SRC_ALPHA; + } + else + { + t_srcrgb = a.a == 0 ? blendinvalpha[usec] : blendalpha[usec]; + t_dstrgb = a.a == 0 ? blendalpha[usec] : blendinvalpha[usec]; + } + } + else + { + t_rgbeq = GL_FUNC_ADD; // a) 011 // b) 100 // + if( bDestAlphaColor == 2 ) + { + // all ones + t_srcrgb = a.a != 0 ? GL_ONE_MINUS_SRC_ALPHA : GL_SRC_ALPHA; + t_dstrgb = a.a != 0 ? GL_SRC_ALPHA : GL_ONE_MINUS_SRC_ALPHA; + } + else + { + //b2XAlphaTest = 1; + t_srcrgb = a.a != 0 ? blendinvalpha[usec] : blendalpha[usec]; + t_dstrgb = a.a != 0 ? blendalpha[usec] : blendinvalpha[usec]; + } + } } - } - else if( a.b == 2 ) + EndSetAlpha: + + + if ( alphaenable && (t_rgbeq != s_rgbeq || s_srcrgb != t_srcrgb || t_dstrgb != s_dstrgb || tAlphaClamping != bAlphaClamping)) { + if (CheckArray[code][(bDestAlphaColor==2)] != -1) { + printf ( "A code %d, 0x%x, 0x%x, 0x%x, 0x%x %d\n", code, alpha, one_minus_alpha, one, zero, bDestAlphaColor ); + printf ( " Difference %d %d %d %d | 0x%x 0x%x | 0x%x 0x%x | 0x%x 0x%x | %d %d\n", + code, a.a, a.b, a.d, + t_rgbeq, s_rgbeq, t_srcrgb, s_srcrgb, t_dstrgb, s_dstrgb, tAlphaClamping, bAlphaClamping); + CheckArray[code][(bDestAlphaColor==2)] = -1; + } + } + else + if (CheckArray[code][(bDestAlphaColor==2)] == 0){ + printf ( "Add good code %d %d, psm %d destA %d\n", code, a.c, vb[icurctx].prndr->psm, bDestAlphaColor); + CheckArray[code][(bDestAlphaColor==2)] = 1; + }*/ + + + if (alphaenable) { - tAlphaClamping = 2; // max testing - - SET_ALPHA_COLOR_FACTOR(a.a!=a.d); - - if( a.a == a.d ) - { - // can get away with 1+A, but need to set alpha to negative - // a)(020) - // b)(121) - t_rgbeq = GL_FUNC_ADD; - - if( bDestAlphaColor == 2 ) - { - t_srcrgb = (a.a == 0) ? GL_ONE_MINUS_SRC_ALPHA : GL_ZERO; - t_dstrgb = (a.a == 0) ? GL_ZERO : GL_ONE_MINUS_SRC_ALPHA; - } - else - { - t_srcrgb = a.a == 0 ? blendinvalpha[usec] : GL_ZERO; - t_dstrgb = a.a == 0 ? GL_ZERO : blendinvalpha[usec]; - } - } - else - { - //a)(021) //b)(120) //b2XAlphaTest = 1; - t_rgbeq = GL_FUNC_ADD; - t_srcrgb = (a.a == 0 && bDestAlphaColor != 2) ? blendalpha[usec] : GL_ONE; - t_dstrgb = (a.a == 0 || bDestAlphaColor == 2) ? GL_ONE : blendalpha[usec]; - } - } - else - { - // all 3 components are valid! - tAlphaClamping = 3; // all testing - SET_ALPHA_COLOR_FACTOR(a.a!=a.d); - - if( a.a == a.d ) - { - // can get away with 1+A, but need to set alpha to negative // a) 010, // b) 101 - t_rgbeq = GL_FUNC_ADD; - - if( bDestAlphaColor == 2 ) - { - // all ones - t_srcrgb = a.a == 0 ? GL_ONE_MINUS_SRC_ALPHA : GL_SRC_ALPHA; - t_dstrgb = a.a == 0 ? GL_SRC_ALPHA : GL_ONE_MINUS_SRC_ALPHA; - } - else - { - t_srcrgb = a.a == 0 ? blendinvalpha[usec] : blendalpha[usec]; - t_dstrgb = a.a == 0 ? blendalpha[usec] : blendinvalpha[usec]; - } - } - else - { - t_rgbeq = GL_FUNC_ADD; // a) 011 // b) 100 // - if( bDestAlphaColor == 2 ) - { - // all ones - t_srcrgb = a.a != 0 ? GL_ONE_MINUS_SRC_ALPHA : GL_SRC_ALPHA; - t_dstrgb = a.a != 0 ? GL_SRC_ALPHA : GL_ONE_MINUS_SRC_ALPHA; - } - else - { - //b2XAlphaTest = 1; - t_srcrgb = a.a != 0 ? blendinvalpha[usec] : blendalpha[usec]; - t_dstrgb = a.a != 0 ? blendalpha[usec] : blendinvalpha[usec]; - } - } - } - EndSetAlpha: - - - if ( alphaenable && (t_rgbeq != s_rgbeq || s_srcrgb != t_srcrgb || t_dstrgb != s_dstrgb || tAlphaClamping != bAlphaClamping)) { - if (CheckArray[code][(bDestAlphaColor==2)] != -1) { - printf ( "A code %d, 0x%x, 0x%x, 0x%x, 0x%x %d\n", code, alpha, one_minus_alpha, one, zero, bDestAlphaColor ); - printf ( " Difference %d %d %d %d | 0x%x 0x%x | 0x%x 0x%x | 0x%x 0x%x | %d %d\n", - code, a.a, a.b, a.d, - t_rgbeq, s_rgbeq, t_srcrgb, s_srcrgb, t_dstrgb, s_dstrgb, tAlphaClamping, bAlphaClamping); - CheckArray[code][(bDestAlphaColor==2)] = -1; - } - } - else - if (CheckArray[code][(bDestAlphaColor==2)] == 0){ - printf ( "Add good code %d %d, psm %d destA %d\n", code, a.c, vb[icurctx].prndr->psm, bDestAlphaColor); - CheckArray[code][(bDestAlphaColor==2)] = 1; - }*/ - - - if( alphaenable ) { zgsBlendFuncSeparateEXT(s_srcrgb, s_dstrgb, s_srcalpha, s_dstalpha); zgsBlendEquationSeparateEXT(s_rgbeq, s_alphaeq); glEnable(GL_BLEND); // always set } else + { glDisable(GL_BLEND); + } INC_ALPHAVARS(); } -void ZeroGS::SetWriteDepth() { +void ZeroGS::SetWriteDepth() +{ FUNCLOG - if( conf.mrtdepth ) { + + if (conf.mrtdepth) + { s_bWriteDepth = TRUE; s_nWriteDepthCount = 4; } } -bool ZeroGS::IsWriteDepth() { +bool ZeroGS::IsWriteDepth() +{ FUNCLOG return s_bWriteDepth; } -bool ZeroGS::IsWriteDestAlphaTest() { +bool ZeroGS::IsWriteDestAlphaTest() +{ FUNCLOG return s_bDestAlphaTest; } -void ZeroGS::SetDestAlphaTest() { +void ZeroGS::SetDestAlphaTest() +{ FUNCLOG s_bDestAlphaTest = TRUE; s_nWriteDestAlphaTest = 4; } -void ZeroGS::SetTexFlush() { +void ZeroGS::SetTexFlush() +{ FUNCLOG s_bTexFlush = TRUE; @@ -2613,7 +2961,7 @@ void ZeroGS::SetTexFlush() { // if( PSMT_ISCLUT(vb[1].tex0.psm) ) // texClutWrite(1); - if( !s_bForceTexFlush ) + if (!s_bForceTexFlush) { if (s_ptexCurSet[0] != s_ptexNextSet[0]) s_ptexCurSet[0] = s_ptexNextSet[0]; if (s_ptexCurSet[1] != s_ptexNextSet[1]) s_ptexCurSet[1] = s_ptexNextSet[1]; diff --git a/plugins/zzogl-pg/opengl/ZZoglSave.cpp b/plugins/zzogl-pg/opengl/ZZoglSave.cpp index ee3d15b372..e5ae6aa914 100644 --- a/plugins/zzogl-pg/opengl/ZZoglSave.cpp +++ b/plugins/zzogl-pg/opengl/ZZoglSave.cpp @@ -46,31 +46,38 @@ extern u32 s_uTex1Data[2][2], s_uClampData[2]; int ZeroGS::Save(s8* pbydata) { - if( pbydata == NULL ) + if (pbydata == NULL) return 40 + 0x00400000 + sizeof(gs) + 2*VBSAVELIMIT + 2*sizeof(frameInfo) + 4 + 256*4; s_RTs.ResolveAll(); s_DepthRTs.ResolveAll(); strcpy((char*)pbydata, libraryNameX); - *(u32*)(pbydata+16) = ZEROGS_SAVEVER; - pbydata += 32; - *(int*)pbydata = icurctx; pbydata += 4; - *(int*)pbydata = VBSAVELIMIT; pbydata += 4; + *(u32*)(pbydata + 16) = ZEROGS_SAVEVER; + + pbydata += 32; + *(int*)pbydata = icurctx; + + pbydata += 4; + *(int*)pbydata = VBSAVELIMIT; + + pbydata += 4; memcpy(pbydata, g_pbyGSMemory, 0x00400000); pbydata += 0x00400000; memcpy(pbydata, g_pbyGSClut, 256*4); - pbydata += 256*4; + pbydata += 256 * 4; *(int*)pbydata = sizeof(gs); pbydata += 4; + memcpy(pbydata, &gs, sizeof(gs)); pbydata += sizeof(gs); - for(int i = 0; i < 2; ++i) { + for (int i = 0; i < 2; ++i) + { memcpy(pbydata, &vb[i], VBSAVELIMIT); pbydata += VBSAVELIMIT; } @@ -86,10 +93,10 @@ bool ZeroGS::Load(s8* pbydata) g_nCurVBOIndex = 0; // first 32 bytes are the id - u32 savever = *(u32*)(pbydata+16); - - if( strncmp((char*)pbydata, libraryNameX, 6) == 0 && (savever == ZEROGS_SAVEVER || savever == 0xaa000004) ) { + u32 savever = *(u32*)(pbydata + 16); + if (strncmp((char*)pbydata, libraryNameX, 6) == 0 && (savever == ZEROGS_SAVEVER || savever == 0xaa000004)) + { g_MemTargs.Destroy(); GSStateReset(); @@ -99,25 +106,31 @@ bool ZeroGS::Load(s8* pbydata) pbydata += 4; u32 savelimit = VBSAVELIMIT; - savelimit = *(u32*)pbydata; pbydata += 4; + savelimit = *(u32*)pbydata; + pbydata += 4; memcpy(g_pbyGSMemory, pbydata, 0x00400000); pbydata += 0x00400000; memcpy(g_pbyGSClut, pbydata, 256*4); - pbydata += 256*4; + pbydata += 256 * 4; memset(&gs, 0, sizeof(gs)); int savedgssize; - if( savever == 0xaa000004 ) + + if (savever == 0xaa000004) + { savedgssize = 0x1d0; - else { + } + else + { savedgssize = *(int*)pbydata; pbydata += 4; } memcpy(&gs, pbydata, savedgssize); + pbydata += savedgssize; prim = &gs._prim[gs.prac]; @@ -131,17 +144,19 @@ bool ZeroGS::Load(s8* pbydata) pbydata += savelimit; vb[1].pBufferData = NULL; - for(int i = 0; i < 2; ++i) { + for (int i = 0; i < 2; ++i) + { vb[i].Init(VB_BUFFERSIZE); vb[i].bNeedZCheck = vb[i].bNeedFrameCheck = 1; - vb[i].bSyncVars = 0; vb[i].bNeedTexCheck = 1; + vb[i].bSyncVars = 0; + vb[i].bNeedTexCheck = 1; memset(vb[i].uCurTex0Data, 0, sizeof(vb[i].uCurTex0Data)); } icurctx = -1; - glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, s_uFramebuffer ); // switch to the backbuffer + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, s_uFramebuffer); // switch to the backbuffer SetFogColor(gs.fogcol); GL_REPORT_ERRORD(); diff --git a/plugins/zzogl-pg/opengl/ZZoglShaders.cpp b/plugins/zzogl-pg/opengl/ZZoglShaders.cpp index 38af07500f..55d2d75121 100644 --- a/plugins/zzogl-pg/opengl/ZZoglShaders.cpp +++ b/plugins/zzogl-pg/opengl/ZZoglShaders.cpp @@ -30,9 +30,11 @@ using namespace ZeroGS; //------------------ Constants // ----------------- Global Variables -namespace ZeroGS { - FRAGMENTSHADER ppsBitBlt[2], ppsBitBltDepth, ppsOne; - FRAGMENTSHADER ppsBaseTexture, ppsConvert16to32, ppsConvert32to16; + +namespace ZeroGS +{ +FRAGMENTSHADER ppsBitBlt[2], ppsBitBltDepth, ppsOne; +FRAGMENTSHADER ppsBaseTexture, ppsConvert16to32, ppsConvert32to16; } // Debug variable, store name of the function that call the shader. @@ -46,8 +48,8 @@ void HandleCgError(CGcontext ctx, CGerror err, void* appdata) { ZZLog::Error_Log("%s->%s: %s", ShaderCallerName, ShaderHandleName, cgGetErrorString(err)); const char* listing = cgGetLastListing(g_cgcontext); - if (listing != NULL) - ZZLog::Debug_Log(" Last listing: %s", listing); + + if (listing != NULL) ZZLog::Debug_Log(" Last listing: %s", listing); } // This is a helper of cgGLSetParameter4fv, made for debugging purposes. @@ -82,14 +84,24 @@ void SetupFragmentProgramParameters(FRAGMENTSHADER* pf, int context, int type) pf->set_texture(ptexBlocks, "g_sBlocks"); // cg parameter usage is wrong, so do it manually - switch(type) + + switch (type) { - case 3: pf->set_texture(ptexConv16to32, "g_sConv16to32"); break; - case 4: pf->set_texture(ptexConv32to16, "g_sConv32to16"); break; - default: pf->set_texture(ptexBilinearBlocks, "g_sBilinearBlocks"); break; + case 3: + pf->set_texture(ptexConv16to32, "g_sConv16to32"); + break; + + case 4: + pf->set_texture(ptexConv32to16, "g_sConv32to16"); + break; + + default: + pf->set_texture(ptexBilinearBlocks, "g_sBilinearBlocks"); + break; } pf->set_texture(pf->sMemory, "g_sMemory"); + pf->set_texture(pf->sFinal, "g_sSrcFinal"); pf->set_texture(pf->sBitwiseANDX, "g_sBitwiseANDX"); pf->set_texture(pf->sBitwiseANDY, "g_sBitwiseANDY"); @@ -97,11 +109,11 @@ void SetupFragmentProgramParameters(FRAGMENTSHADER* pf, int context, int type) pf->set_texture(pf->sInterlace, "g_sInterlace"); // set global shader constants - pf->set_shader_const(Vector(0.5f, (g_GameSettings&GAME_EXACTCOLOR)?0.9f/256.0f:0.5f/256.0f, 0,1/255.0f), "g_fExactColor"); - pf->set_shader_const(Vector(-0.2f, -0.65f, 0.9f, 1.0f / 32767.0f ), "g_fBilinear"); - pf->set_shader_const(Vector(1.0f/256.0f, 1.0004f, 1, 0.5f), "g_fZBias"); - pf->set_shader_const(Vector(0,1, 0.001f, 0.5f), "g_fc0"); - pf->set_shader_const(Vector(1/1024.0f, 0.2f/1024.0f, 1/128.0f, 1/512.0f), "g_fMult"); + pf->set_shader_const(Vector(0.5f, (g_GameSettings&GAME_EXACTCOLOR) ? 0.9f / 256.0f : 0.5f / 256.0f, 0, 1 / 255.0f), "g_fExactColor"); + pf->set_shader_const(Vector(-0.2f, -0.65f, 0.9f, 1.0f / 32767.0f), "g_fBilinear"); + pf->set_shader_const(Vector(1.0f / 256.0f, 1.0004f, 1, 0.5f), "g_fZBias"); + pf->set_shader_const(Vector(0, 1, 0.001f, 0.5f), "g_fc0"); + pf->set_shader_const(Vector(1 / 1024.0f, 0.2f / 1024.0f, 1 / 128.0f, 1 / 512.0f), "g_fMult"); } void SetupVertexProgramParameters(CGprogram prog, int context) @@ -109,50 +121,62 @@ void SetupVertexProgramParameters(CGprogram prog, int context) CGparameter p; p = cgGetNamedParameter(prog, "g_fPosXY"); - if( p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE ) + + if (p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE) cgConnectParameter(g_vparamPosXY[context], p); // Set Z-test, log or no log; if (g_GameSettings&GAME_NOLOGZ) { - g_vdepth = Vector( 255.0 /256.0f, 255.0/65536.0f, 255.0f/(65535.0f*256.0f), 1.0f/(65536.0f*65536.0f)); - vlogz = Vector( 1.0f, 0.0f, 0.0f, 0.0f); + g_vdepth = Vector(255.0 / 256.0f, 255.0 / 65536.0f, 255.0f / (65535.0f * 256.0f), 1.0f / (65536.0f * 65536.0f)); + vlogz = Vector(1.0f, 0.0f, 0.0f, 0.0f); } else { - g_vdepth = Vector( 256.0f*65536.0f, 65536.0f, 256.0f, 65536.0f*65536.0f); - vlogz = Vector( 0.0f, 1.0f, 0.0f, 0.0f); + g_vdepth = Vector(256.0f * 65536.0f, 65536.0f, 256.0f, 65536.0f * 65536.0f); + vlogz = Vector(0.0f, 1.0f, 0.0f, 0.0f); } p = cgGetNamedParameter(prog, "g_fZ"); - if( p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE ) { + + if (p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE) + { cgGLSetParameter4fv(p, g_vdepth); p = cgGetNamedParameter(prog, "g_fZMin"); // Switch to flat-z when needed - if( p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE ) { + + if (p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE) + { //ZZLog::Error_Log("Use flat-z"); cgGLSetParameter4fv(p, vlogz); } else + { ZZLog::Error_Log("Shader file version is outdated! Only log-Z is possible."); + } } - Vector vnorm = Vector(g_filog32, 0, 0,0); + Vector vnorm = Vector(g_filog32, 0, 0, 0); + p = cgGetNamedParameter(prog, "g_fZNorm"); - if( p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE ) + + if (p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE) cgGLSetParameter4fv(p, vnorm); p = cgGetNamedParameter(prog, "g_fBilinear"); - if( p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE ) - cgGLSetParameter4fv(p, Vector(-0.2f, -0.65f, 0.9f, 1.0f / 32767.0f )); + + if (p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE) + cgGLSetParameter4fv(p, Vector(-0.2f, -0.65f, 0.9f, 1.0f / 32767.0f)); p = cgGetNamedParameter(prog, "g_fZBias"); - if( p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE ) - cgGLSetParameter4fv(p, Vector(1.0f/256.0f, 1.0004f, 1, 0.5f)); + + if (p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE) + cgGLSetParameter4fv(p, Vector(1.0f / 256.0f, 1.0004f, 1, 0.5f)); p = cgGetNamedParameter(prog, "g_fc0"); - if( p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE ) - cgGLSetParameter4fv(p, Vector(0,1, 0.001f, 0.5f)); + + if (p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE) + cgGLSetParameter4fv(p, Vector(0, 1, 0.001f, 0.5f)); } #ifndef DEVBUILD @@ -170,7 +194,7 @@ void SetupVertexProgramParameters(CGprogram prog, int context) if( cgGetError() != CG_NO_ERROR ) ZZLog::Error_Log("failed to load program %d.", Index); \ SetupVertexProgramParameters(prog, !!(Index&SH_CONTEXT1)); \ } \ - + #define LOAD_PS(Index, fragment) { \ bLoadSuccess = true; \ assert( mapShaderResources.find(Index) != mapShaderResources.end() ); \ @@ -187,37 +211,42 @@ void SetupVertexProgramParameters(CGprogram prog, int context) } \ SetupFragmentProgramParameters(&fragment, !!(Index&SH_CONTEXT1), 0); \ } \ - + bool ZeroGS::LoadEffects() { - assert( s_lpShaderResources != NULL ); + assert(s_lpShaderResources != NULL); // process the header u32 num = *(u32*)s_lpShaderResources; - int compressed_size = *(int*)(s_lpShaderResources+4); - int real_size = *(int*)(s_lpShaderResources+8); + int compressed_size = *(int*)(s_lpShaderResources + 4); + int real_size = *(int*)(s_lpShaderResources + 8); int out; char* pbuffer = (char*)malloc(real_size); - inf((char*)s_lpShaderResources+12, &pbuffer[0], compressed_size, real_size, &out); + inf((char*)s_lpShaderResources + 12, &pbuffer[0], compressed_size, real_size, &out); assert(out == real_size); s_lpShaderResources = (u8*)pbuffer; SHADERHEADER* header = (SHADERHEADER*)s_lpShaderResources; mapShaderResources.clear(); - while(num-- > 0 ) { + + while (num-- > 0) + { mapShaderResources[header->index] = header; ++header; } // clear the textures - for(int i = 0; i < ARRAY_SIZE(ppsTexture); ++i) { + for (int i = 0; i < ARRAY_SIZE(ppsTexture); ++i) + { SAFE_RELEASE_PROG(ppsTexture[i].prog); ppsTexture[i].prog = NULL; } + #ifndef _DEBUG memset(ppsTexture, 0, sizeof(ppsTexture)); + #endif return true; @@ -231,12 +260,13 @@ bool ZeroGS::LoadExtraEffects() const int vsshaders[4] = { SH_REGULARVS, SH_TEXTUREVS, SH_REGULARFOGVS, SH_TEXTUREFOGVS }; - for(int i = 0; i < 4; ++i) { + for (int i = 0; i < 4; ++i) + { LOAD_VS(vsshaders[i], pvs[2*i]); LOAD_VS((vsshaders[i] | SH_CONTEXT1), pvs[2*i+1]); //if( conf.mrtdepth ) { - LOAD_VS((vsshaders[i] | SH_WRITEDEPTH), pvs[2*i+8]); - LOAD_VS((vsshaders[i] | SH_WRITEDEPTH | SH_CONTEXT1), pvs[2*i+8+1]); + LOAD_VS((vsshaders[i] | SH_WRITEDEPTH), pvs[2*i+8]); + LOAD_VS((vsshaders[i] | SH_WRITEDEPTH | SH_CONTEXT1), pvs[2*i+8+1]); // } // else { // pvs[2*i+8] = pvs[2*i+8+1] = NULL; @@ -244,6 +274,7 @@ bool ZeroGS::LoadExtraEffects() } LOAD_VS(SH_BITBLTVS, pvsBitBlt.prog); + pvsBitBlt.sBitBltPos = cgGetNamedParameter(pvsBitBlt.prog, "g_fBitBltPos"); pvsBitBlt.sBitBltTex = cgGetNamedParameter(pvsBitBlt.prog, "g_fBitBltTex"); pvsBitBlt.fBitBltTrans = cgGetNamedParameter(pvsBitBlt.prog, "g_fBitBltTrans"); @@ -251,38 +282,50 @@ bool ZeroGS::LoadExtraEffects() LOAD_PS(SH_REGULARPS, ppsRegular[0]); LOAD_PS(SH_REGULARFOGPS, ppsRegular[1]); - if( conf.mrtdepth ) { + if (conf.mrtdepth) + { LOAD_PS(SH_REGULARPS, ppsRegular[2]); - if( !bLoadSuccess ) + + if (!bLoadSuccess) conf.mrtdepth = 0; + LOAD_PS(SH_REGULARFOGPS, ppsRegular[3]); - if( !bLoadSuccess ) + + if (!bLoadSuccess) conf.mrtdepth = 0; } LOAD_PS(SH_BITBLTPS, ppsBitBlt[0]); + LOAD_PS(SH_BITBLTAAPS, ppsBitBlt[1]); - if( !bLoadSuccess ) { + + if (!bLoadSuccess) + { ZZLog::Error_Log("Failed to load BitBltAAPS, using BitBltPS."); LOAD_PS(SH_BITBLTPS, ppsBitBlt[1]); } + LOAD_PS(SH_BITBLTDEPTHPS, ppsBitBltDepth); + LOAD_PS(SH_CRTCTARGPS, ppsCRTCTarg[0]); LOAD_PS(SH_CRTCTARGINTERPS, ppsCRTCTarg[1]); g_bCRTCBilinear = TRUE; LOAD_PS(SH_CRTCPS, ppsCRTC[0]); - if( !bLoadSuccess ) { + + if (!bLoadSuccess) + { // switch to simpler g_bCRTCBilinear = FALSE; LOAD_PS(SH_CRTC_NEARESTPS, ppsCRTC[0]); LOAD_PS(SH_CRTCINTER_NEARESTPS, ppsCRTC[0]); } - else { + else + { LOAD_PS(SH_CRTCINTERPS, ppsCRTC[1]); } - if( !bLoadSuccess ) + if (!bLoadSuccess) ZZLog::Error_Log("Failed to create CRTC shaders."); LOAD_PS(SH_CRTC24PS, ppsCRTC24[0]); @@ -298,62 +341,85 @@ bool ZeroGS::LoadExtraEffects() FRAGMENTSHADER* ZeroGS::LoadShadeEffect(int type, int texfilter, int fog, int testaem, int exactcolor, const clampInfo& clamp, int context, bool* pbFailed) { int texwrap; - assert( texfilter < NUM_FILTERS ); + assert(texfilter < NUM_FILTERS); - if(g_nPixelShaderVer&SHADER_REDUCED) - texfilter = 0; - assert(!(g_nPixelShaderVer&SHADER_REDUCED) || !exactcolor); + if (g_nPixelShaderVer & SHADER_REDUCED) texfilter = 0; - if( clamp.wms == clamp.wmt ) { - switch( clamp.wms ) { - case 0: texwrap = TEXWRAP_REPEAT; break; - case 1: texwrap = TEXWRAP_CLAMP; break; - case 2: texwrap = TEXWRAP_CLAMP; break; - default: texwrap = TEXWRAP_REGION_REPEAT; break; + assert(!(g_nPixelShaderVer & SHADER_REDUCED) || !exactcolor); + + if (clamp.wms == clamp.wmt) + { + switch (clamp.wms) + { + case 0: + texwrap = TEXWRAP_REPEAT; + break; + + case 1: + texwrap = TEXWRAP_CLAMP; + break; + + case 2: + texwrap = TEXWRAP_CLAMP; + break; + + default: + texwrap = TEXWRAP_REGION_REPEAT; + break; } } - else if( clamp.wms==3||clamp.wmt==3) + else if (clamp.wms == 3 || clamp.wmt == 3) texwrap = TEXWRAP_REGION_REPEAT; else texwrap = TEXWRAP_REPEAT_CLAMP; int index = GET_SHADER_INDEX(type, texfilter, texwrap, fog, s_bWriteDepth, testaem, exactcolor, context, 0); - assert( index < ARRAY_SIZE(ppsTexture) ); - FRAGMENTSHADER* pf = ppsTexture+index; + assert(index < ARRAY_SIZE(ppsTexture)); - if( pbFailed != NULL ) *pbFailed = false; + FRAGMENTSHADER* pf = ppsTexture + index; - if( pf->prog != NULL ) - return pf; + if (pbFailed != NULL) *pbFailed = false; - if( (g_nPixelShaderVer & SHADER_ACCURATE) && mapShaderResources.find(index+NUM_SHADERS*SHADER_ACCURATE) != mapShaderResources.end() ) - index += NUM_SHADERS*SHADER_ACCURATE; + if (pf->prog != NULL) return pf; + + if ((g_nPixelShaderVer & SHADER_ACCURATE) && mapShaderResources.find(index + NUM_SHADERS*SHADER_ACCURATE) != mapShaderResources.end()) + index += NUM_SHADERS * SHADER_ACCURATE; + + assert(mapShaderResources.find(index) != mapShaderResources.end()); - assert( mapShaderResources.find(index) != mapShaderResources.end() ); SHADERHEADER* header = mapShaderResources[index]; - if( header == NULL ) - ZZLog::Error_Log("%d %d", index, g_nPixelShaderVer); - assert( header != NULL ); + + if (header == NULL) ZZLog::Error_Log("%d %d", index, g_nPixelShaderVer); + + assert(header != NULL); //ZZLog::Debug_Log("Shader:\n%s.", (char*)(s_lpShaderResources + (header)->offset)); pf->prog = cgCreateProgram(g_cgcontext, CG_OBJECT, (char*)(s_lpShaderResources + (header)->offset), cgfProf, NULL, NULL); - if( pf->prog != NULL && cgIsProgram(pf->prog) && cgGetError() == CG_NO_ERROR ) { + + if (pf->prog != NULL && cgIsProgram(pf->prog) && cgGetError() == CG_NO_ERROR) + { SetupFragmentProgramParameters(pf, context, type); cgGLLoadProgram(pf->prog); - if( cgGetError() != CG_NO_ERROR ) { + + if (cgGetError() != CG_NO_ERROR) + { // cgGLLoadProgram(pf->prog); // if( cgGetError() != CG_NO_ERROR ) { - ZZLog::Error_Log("Failed to load shader %d,%d,%d,%d.", type, fog, texfilter, 4*clamp.wms+clamp.wmt); - if( pbFailed != NULL ) *pbFailed = true; - return pf; + ZZLog::Error_Log("Failed to load shader %d,%d,%d,%d.", type, fog, texfilter, 4*clamp.wms + clamp.wmt); + + if (pbFailed != NULL) *pbFailed = true; + + return pf; + // } } return pf; } - ZZLog::Error_Log("Failed to create shader %d,%d,%d,%d", type, fog, texfilter, 4*clamp.wms+clamp.wmt); - if( pbFailed != NULL ) *pbFailed = true; + ZZLog::Error_Log("Failed to create shader %d,%d,%d,%d", type, fog, texfilter, 4*clamp.wms + clamp.wmt); + + if (pbFailed != NULL) *pbFailed = true; return NULL; } @@ -370,7 +436,7 @@ FRAGMENTSHADER* ZeroGS::LoadShadeEffect(int type, int texfilter, int fog, int te if( cgGetError() != CG_NO_ERROR ) ZZLog::Error_Log("failed to load program %s.", name); \ SetupVertexProgramParameters(prog, args[0]==context1); \ } \ - + #ifdef _DEBUG #define SET_PSFILENAME(frag, name) frag.filename = name #else @@ -392,16 +458,18 @@ FRAGMENTSHADER* ZeroGS::LoadShadeEffect(int type, int texfilter, int fog, int te SetupFragmentProgramParameters(&fragment, args[0]==context1, 0); \ SET_PSFILENAME(fragment, name); \ } \ - + bool ZeroGS::LoadEffects() { // clear the textures - for(int i = 0; i < ARRAY_SIZE(ppsTexture); ++i) { + for (int i = 0; i < ARRAY_SIZE(ppsTexture); ++i) + { SAFE_RELEASE_PROG(ppsTexture[i].prog); } #ifndef _DEBUG memset(ppsTexture, 0, sizeof(ppsTexture)); + #endif return true; @@ -418,7 +486,8 @@ bool ZeroGS::LoadExtraEffects() const char* pvsshaders[4] = { "RegularVS", "TextureVS", "RegularFogVS", "TextureFogVS" }; - for(int i = 0; i < 4; ++i) { + for (int i = 0; i < 4; ++i) + { args[0] = context0; args[1] = NULL; LOAD_VS(pvsshaders[i], pvs[2*i], cgvProf); @@ -426,11 +495,11 @@ bool ZeroGS::LoadExtraEffects() LOAD_VS(pvsshaders[i], pvs[2*i+1], cgvProf); //if( conf.mrtdepth ) { - args[0] = context0; - args[1] = write_depth; - LOAD_VS(pvsshaders[i], pvs[2*i+8], cgvProf); - args[0] = context1; - LOAD_VS(pvsshaders[i], pvs[2*i+8+1], cgvProf); + args[0] = context0; + args[1] = write_depth; + LOAD_VS(pvsshaders[i], pvs[2*i+8], cgvProf); + args[0] = context1; + LOAD_VS(pvsshaders[i], pvs[2*i+8+1], cgvProf); // } // else { // pvs[2*i+8] = pvs[2*i+8+1] = NULL; @@ -438,6 +507,7 @@ bool ZeroGS::LoadExtraEffects() } args[0] = context0; + args[1] = NULL; LOAD_VS("BitBltVS", pvsBitBlt.prog, cgvProf); pvsBitBlt.sBitBltPos = cgGetNamedParameter(pvsBitBlt.prog, "g_fBitBltPos"); @@ -447,20 +517,24 @@ bool ZeroGS::LoadExtraEffects() LOAD_PS("RegularPS", ppsRegular[0], cgfProf); LOAD_PS("RegularFogPS", ppsRegular[1], cgfProf); - if( conf.mrtdepth ) { + if (conf.mrtdepth) + { args[0] = context0; args[1] = write_depth; LOAD_PS("RegularPS", ppsRegular[2], cgfProf); - if( !bLoadSuccess ) - conf.mrtdepth = 0; + + if (!bLoadSuccess) conf.mrtdepth = 0; + LOAD_PS("RegularFogPS", ppsRegular[3], cgfProf); - if( !bLoadSuccess ) - conf.mrtdepth = 0; + + if (!bLoadSuccess) conf.mrtdepth = 0; } LOAD_PS("BitBltPS", ppsBitBlt[0], cgfProf); LOAD_PS("BitBltAAPS", ppsBitBlt[1], cgfProf); - if( !bLoadSuccess ) { + + if (!bLoadSuccess) + { ZZLog::Error_Log("Failed to load BitBltAAPS, using BitBltPS."); LOAD_PS("BitBltPS", ppsBitBlt[1], cgfProf); } @@ -471,19 +545,23 @@ bool ZeroGS::LoadExtraEffects() g_bCRTCBilinear = TRUE; LOAD_PS("CRTCPS", ppsCRTC[0], cgfProf); - if( !bLoadSuccess ) { + + if (!bLoadSuccess) + { // switch to simpler g_bCRTCBilinear = FALSE; LOAD_PS("CRTCPS_Nearest", ppsCRTC[0], cgfProf); LOAD_PS("CRTCInterPS_Nearest", ppsCRTC[0], cgfProf); } - else { + else + { LOAD_PS("CRTCInterPS", ppsCRTC[1], cgfProf); } if (!bLoadSuccess) ZZLog::Error_Log("Failed to create CRTC shaders."); - LOAD_PS("CRTC24PS", ppsCRTC24[0], cgfProf); LOAD_PS("CRTC24InterPS", ppsCRTC24[1], cgfProf); + LOAD_PS("CRTC24PS", ppsCRTC24[0], cgfProf); + LOAD_PS("CRTC24InterPS", ppsCRTC24[1], cgfProf); LOAD_PS("ZeroPS", ppsOne, cgfProf); LOAD_PS("BaseTexturePS", ppsBaseTexture, cgfProf); LOAD_PS("Convert16to32PS", ppsConvert16to32, cgfProf); @@ -501,57 +579,77 @@ FRAGMENTSHADER* ZeroGS::LoadShadeEffect(int type, int texfilter, int fog, int te { int texwrap; - assert( texfilter < NUM_FILTERS ); + assert(texfilter < NUM_FILTERS); //assert( g_nPixelShaderVer == SHADER_30 ); - if( clamp.wms == clamp.wmt ) { - switch( clamp.wms ) { - case 0: texwrap = TEXWRAP_REPEAT; break; - case 1: texwrap = TEXWRAP_CLAMP; break; - case 2: texwrap = TEXWRAP_CLAMP; break; + + if (clamp.wms == clamp.wmt) + { + switch (clamp.wms) + { + case 0: + texwrap = TEXWRAP_REPEAT; + break; + + case 1: + texwrap = TEXWRAP_CLAMP; + break; + + case 2: + texwrap = TEXWRAP_CLAMP; + break; + default: - texwrap = TEXWRAP_REGION_REPEAT; break; + texwrap = TEXWRAP_REGION_REPEAT; + break; } } - else if( clamp.wms==3||clamp.wmt==3) + else if (clamp.wms == 3 || clamp.wmt == 3) texwrap = TEXWRAP_REGION_REPEAT; else texwrap = TEXWRAP_REPEAT_CLAMP; int index = GET_SHADER_INDEX(type, texfilter, texwrap, fog, s_bWriteDepth, testaem, exactcolor, context, 0); - if( pbFailed != NULL ) *pbFailed = false; + if (pbFailed != NULL) *pbFailed = false; - FRAGMENTSHADER* pf = ppsTexture+index; + FRAGMENTSHADER* pf = ppsTexture + index; - if( pf->prog != NULL ) - return pf; + if (pf->prog != NULL) return pf; pf->prog = LoadShaderFromType(EFFECT_DIR, EFFECT_NAME, type, texfilter, texwrap, fog, s_bWriteDepth, testaem, exactcolor, g_nPixelShaderVer, context); - if( pf->prog != NULL ) { + if (pf->prog != NULL) + { #ifdef _DEBUG char str[255]; - sprintf(str, "Texture%s%d_%sPS", fog?"Fog":"", texfilter, g_pTexTypes[type]); + sprintf(str, "Texture%s%d_%sPS", fog ? "Fog" : "", texfilter, g_pTexTypes[type]); pf->filename = str; #endif SetupFragmentProgramParameters(pf, context, type); cgGLLoadProgram(pf->prog); - if( cgGetError() != CG_NO_ERROR ) { + + if (cgGetError() != CG_NO_ERROR) + { // try again // cgGLLoadProgram(pf->prog); // if( cgGetError() != CG_NO_ERROR ) { - ZZLog::Error_Log("Failed to load shader %d,%d,%d,%d.", type, fog, texfilter, 4*clamp.wms+clamp.wmt); - if( pbFailed != NULL ) *pbFailed = true; - //assert(0); - // NULL makes things crash - return pf; + ZZLog::Error_Log("Failed to load shader %d,%d,%d,%d.", type, fog, texfilter, 4*clamp.wms + clamp.wmt); + + if (pbFailed != NULL) *pbFailed = true; + + //assert(0); + // NULL makes things crash + return pf; + // } } + return pf; } - ZZLog::Error_Log("Failed to create shader %d,%d,%d,%d.", type, fog, texfilter, 4*clamp.wms+clamp.wmt); - if( pbFailed != NULL ) *pbFailed = true; + ZZLog::Error_Log("Failed to create shader %d,%d,%d,%d.", type, fog, texfilter, 4*clamp.wms + clamp.wmt); + + if (pbFailed != NULL) *pbFailed = true; return NULL; } diff --git a/plugins/zzogl-pg/opengl/ZZoglShoots.cpp b/plugins/zzogl-pg/opengl/ZZoglShoots.cpp index 4a3787f408..9ab0bfbdf2 100644 --- a/plugins/zzogl-pg/opengl/ZZoglShoots.cpp +++ b/plugins/zzogl-pg/opengl/ZZoglShoots.cpp @@ -32,7 +32,8 @@ #include "Mem.h" -extern "C" { +extern "C" +{ #ifdef _WIN32 # define XMD_H # undef FAR @@ -59,64 +60,65 @@ int s_aviinit = 0; //------------------ Code // Set variables need to made a snapshoot when it's possible -void -ZeroGS::SaveSnapshot(const char* filename) +void ZeroGS::SaveSnapshot(const char* filename) { g_bMakeSnapshot = 1; strSnapshot = filename; } // Save curent renderer in jpeg or TGA format -bool -ZeroGS::SaveRenderTarget(const char* filename, int width, int height, int jpeg) +bool ZeroGS::SaveRenderTarget(const char* filename, int width, int height, int jpeg) { bool bflip = height < 0; height = abs(height); vector data(width*height); glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); - if (glGetError() != GL_NO_ERROR) - return false; - if (bflip) { + if (glGetError() != GL_NO_ERROR) return false; + + if (bflip) + { // swap scanlines vector scanline(width); - for (int i = 0; i < height/2; ++i) { + + for (int i = 0; i < height / 2; ++i) + { memcpy(&scanline[0], &data[i * width], width * 4); memcpy(&data[i * width], &data[(height - i - 1) * width], width * 4); memcpy(&data[(height - i - 1) * width], &scanline[0], width * 4); } } - if (jpeg) - return SaveJPEG(filename, width, height, &data[0], 70); + if (jpeg) return SaveJPEG(filename, width, height, &data[0], 70); return SaveTGA(filename, width, height, &data[0]); } // Save selected texture as TGA -bool -ZeroGS::SaveTexture(const char* filename, u32 textarget, u32 tex, int width, int height) +bool ZeroGS::SaveTexture(const char* filename, u32 textarget, u32 tex, int width, int height) { vector data(width*height); glBindTexture(textarget, tex); glGetTexImage(textarget, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); - if (glGetError() != GL_NO_ERROR) - return false; + + if (glGetError() != GL_NO_ERROR) return false; return SaveTGA(filename, width, height, &data[0]); } // save image as JPEG -bool -ZeroGS::SaveJPEG(const char* filename, int image_width, int image_height, const void* pdata, int quality) +bool ZeroGS::SaveJPEG(const char* filename, int image_width, int image_height, const void* pdata, int quality) { u8* image_buffer = new u8[image_width * image_height * 3]; u8* psrc = (u8*)pdata; // input data is rgba format, so convert to rgb u8* p = image_buffer; - for(int i = 0; i < image_height; ++i) { - for(int j = 0; j < image_width; ++j) { + + for (int i = 0; i < image_height; ++i) + { + for (int j = 0; j < image_width; ++j) + { p[0] = psrc[0]; p[1] = psrc[1]; p[2] = psrc[2]; @@ -131,7 +133,9 @@ ZeroGS::SaveJPEG(const char* filename, int image_width, int image_height, const * compression/decompression processes, in existence at once. We refer * to any one struct (and its associated working data) as a "JPEG object". */ + struct jpeg_compress_struct cinfo; + /* This struct represents a JPEG error handler. It is declared separately * because applications often want to supply a specialized error handler * (see the second half of this file for an example). But here we just @@ -140,10 +144,14 @@ ZeroGS::SaveJPEG(const char* filename, int image_width, int image_height, const * Note that this struct must live as long as the main JPEG parameter * struct, to avoid dangling-pointer problems. */ + struct jpeg_error_mgr jerr; + /* More stuff */ FILE * outfile; /* target file */ + JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ + int row_stride; /* physical row width in image buffer */ /* Step 1: allocate and initialize JPEG compression object */ @@ -154,6 +162,7 @@ ZeroGS::SaveJPEG(const char* filename, int image_width, int image_height, const * address which we place into the link field in cinfo. */ cinfo.err = jpeg_std_error(&jerr); + /* Now we can initialize the JPEG compression object. */ jpeg_create_compress(&cinfo); @@ -165,10 +174,12 @@ ZeroGS::SaveJPEG(const char* filename, int image_width, int image_height, const * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that * requires it in order to write binary files. */ - if ((outfile = fopen(filename, "wb")) == NULL) { + if ((outfile = fopen(filename, "wb")) == NULL) + { fprintf(stderr, "can't open %s\n", filename); exit(1); } + jpeg_stdio_dest(&cinfo, outfile); /* Step 3: set parameters for compression */ @@ -207,8 +218,9 @@ ZeroGS::SaveJPEG(const char* filename, int image_width, int image_height, const */ row_stride = image_width * 3; /* JSAMPLEs per row in image_buffer */ - while (cinfo.next_scanline < cinfo.image_height) { - /* jpeg_write_scanlines expects an array of pointers to scanlines. + while (cinfo.next_scanline < cinfo.image_height) + { + /* jpeg_write_scanlines expects an array of pointers to scanlines. * Here the array is only one element long, but you could pass * more than one scanline at a time if that's more convenient. */ @@ -219,6 +231,7 @@ ZeroGS::SaveJPEG(const char* filename, int image_width, int image_height, const /* Step 6: Finish compression */ jpeg_finish_compress(&cinfo); + /* After finish_compress, we can close the output file. */ fclose(outfile); @@ -228,6 +241,7 @@ ZeroGS::SaveJPEG(const char* filename, int image_width, int image_height, const jpeg_destroy_compress(&cinfo); delete image_buffer; + /* And we're done! */ return true; } @@ -237,6 +251,7 @@ ZeroGS::SaveJPEG(const char* filename, int image_width, int image_height, const #endif // This is the defenition of TGA header. We need it to function bellow + struct TGA_HEADER { u8 identsize; // size of ID field that follows 18 u8 header (0 usually) @@ -254,36 +269,41 @@ struct TGA_HEADER u8 bits; // image bits per pixel 8,16,24,32 u8 descriptor; // image descriptor bits (vh flip bits) - // pixel data follows header + // pixel data follows header #if defined(_MSC_VER) }; + # pragma pack(pop) # else -} __attribute__((packed)); +} + +__attribute__((packed)); #endif // Save image as TGA -bool -ZeroGS::SaveTGA(const char* filename, int width, int height, void* pdata) +bool ZeroGS::SaveTGA(const char* filename, int width, int height, void* pdata) { int err = 0; TGA_HEADER hdr; FILE* f = fopen(filename, "wb"); - if (f == NULL) - return false; - assert( sizeof(TGA_HEADER) == 18 && sizeof(hdr) == 18 ); + if (f == NULL) return false; + + assert(sizeof(TGA_HEADER) == 18 && sizeof(hdr) == 18); memset(&hdr, 0, sizeof(hdr)); + hdr.imagetype = 2; hdr.bits = 32; hdr.width = width; hdr.height = height; - hdr.descriptor |= 8|(1<<5); // 8bit alpha, flip vertical + hdr.descriptor |= 8 | (1 << 5); // 8bit alpha, flip vertical err = fwrite(&hdr, sizeof(hdr), 1, f); err = fwrite(pdata, width * height * 4, 1, f); + fclose(f); + return true; } @@ -291,8 +311,8 @@ ZeroGS::SaveTGA(const char* filename, int width, int height, void* pdata) // AVI start -- set needed glabal variables void ZeroGS::StartCapture() { - if( !s_aviinit ) { - + if (!s_aviinit) + { #ifdef _WIN32 START_AVI("zerogs.avi"); #else // linux @@ -300,7 +320,8 @@ void ZeroGS::StartCapture() #endif s_aviinit = 1; } - else { + else + { ZZLog::Error_Log("Continuing from previous capture."); } @@ -317,10 +338,11 @@ void ZeroGS::StopCapture() // Does not work on linux void ZeroGS::CaptureFrame() { - assert( s_avicapturing && s_aviinit ); + assert(s_avicapturing && s_aviinit); vector data(nBackbufferWidth*nBackbufferHeight); glReadPixels(0, 0, nBackbufferWidth, nBackbufferHeight, GL_RGBA, GL_UNSIGNED_BYTE, &data[0]); + if (glGetError() != GL_NO_ERROR) return; #ifdef _WIN32 @@ -328,12 +350,14 @@ void ZeroGS::CaptureFrame() bool bSuccess = ADD_FRAME_FROM_DIB_TO_AVI("AAAA", fps, nBackbufferWidth, nBackbufferHeight, 32, &data[0]); - if( !bSuccess ) { + if (!bSuccess) + { s_avicapturing = 0; STOP_AVI(); ZeroGS::AddMessage("Failed to create avi"); return; } + #else // linux //TODO #endif // _WIN32 @@ -351,10 +375,10 @@ ZeroGS::SaveTex(tex0Info* ptex, int usevid) CMemoryTarget* pmemtarg = NULL; - if (usevid) { - + if (usevid) + { pmemtarg = g_MemTargs.GetMemoryTarget(*ptex, 0); - assert( pmemtarg != NULL ); + assert(pmemtarg != NULL); glBindTexture(GL_TEXTURE_RECTANGLE_NV, pmemtarg->ptex->tex); srcdata.resize(pmemtarg->realheight * GPU_TEXWIDTH * pmemtarg->widthmult * 4 * 8); // max of 8 cannels @@ -371,11 +395,15 @@ ZeroGS::SaveTex(tex0Info* ptex, int usevid) psrc = &srcdata[0] - offset; } - for (int i = 0; i < ptex->th; ++i) { - for (int j = 0; j < ptex->tw; ++j) { + for (int i = 0; i < ptex->th; ++i) + { + for (int j = 0; j < ptex->tw; ++j) + { u32 u = 0; - u32 addr; - switch (ptex->psm) { + u32 addr; + + switch (ptex->psm) + { case PSMCT32: addr = getPixelAddress32(j, i, ptex->tbp0, ptex->tbw); if (addr * 4 < 0x00400000) @@ -383,6 +411,7 @@ ZeroGS::SaveTex(tex0Info* ptex, int usevid) else u = 0; break; + case PSMCT24: addr = getPixelAddress24(j, i, ptex->tbp0, ptex->tbw); if (addr * 4 < 0x00400000) @@ -390,135 +419,174 @@ ZeroGS::SaveTex(tex0Info* ptex, int usevid) else u = 0; break; + case PSMCT16: addr = getPixelAddress16(j, i, ptex->tbp0, ptex->tbw); - if (addr * 2 < 0x00400000) { + if (addr * 2 < 0x00400000) + { u = readPixel16(psrc, j, i, ptex->tbp0, ptex->tbw); u = RGBA16to32(u); } else + { u = 0; + } break; + case PSMCT16S: addr = getPixelAddress16(j, i, ptex->tbp0, ptex->tbw); - if (addr * 2 < 0x00400000) { + if (addr * 2 < 0x00400000) + { u = readPixel16S(psrc, j, i, ptex->tbp0, ptex->tbw); u = RGBA16to32(u); } - else u = 0; + else + { + u = 0; + } break; case PSMT8: addr = getPixelAddress8(j, i, ptex->tbp0, ptex->tbw); - if (addr < 0x00400000) { - if (usevid) { + if (addr < 0x00400000) + { + if (usevid) + { if (PSMT_IS32BIT(ptex->cpsm)) - u = *(u32*)(psrc+4*addr); + u = *(u32*)(psrc + 4 * addr); else - u = RGBA16to32(*(u16*)(psrc+2*addr)); + u = RGBA16to32(*(u16*)(psrc + 2 * addr)); } else + { u = readPixel8(psrc, j, i, ptex->tbp0, ptex->tbw); + } } else + { u = 0; + } break; case PSMT4: addr = getPixelAddress4(j, i, ptex->tbp0, ptex->tbw); - - if( addr < 2*0x00400000 ) { - if( usevid ) { + if (addr < 2*0x00400000) + { + if (usevid) + { if (PSMT_IS32BIT(ptex->cpsm)) - u = *(u32*)(psrc+4*addr); + u = *(u32*)(psrc + 4 * addr); else - u = RGBA16to32(*(u16*)(psrc+2*addr)); + u = RGBA16to32(*(u16*)(psrc + 2 * addr)); } else + { u = readPixel4(psrc, j, i, ptex->tbp0, ptex->tbw); + } } - else u = 0; + else + { + u = 0; + } + break; case PSMT8H: addr = getPixelAddress8H(j, i, ptex->tbp0, ptex->tbw); - - if( 4*addr < 0x00400000 ) { - if( usevid ) { + if (4*addr < 0x00400000) + { + if (usevid) + { if (PSMT_IS32BIT(ptex->cpsm)) - u = *(u32*)(psrc+4*addr); + u = *(u32*)(psrc + 4 * addr); else - u = RGBA16to32(*(u16*)(psrc+2*addr)); + u = RGBA16to32(*(u16*)(psrc + 2 * addr)); } else + { u = readPixel8H(psrc, j, i, ptex->tbp0, ptex->tbw); + } + } + else + { + u = 0; } - else u = 0; - break; case PSMT4HL: addr = getPixelAddress4HL(j, i, ptex->tbp0, ptex->tbw); - - if( 4*addr < 0x00400000 ) { - if( usevid ) { + if (4*addr < 0x00400000) + { + if (usevid) + { if (PSMT_IS32BIT(ptex->cpsm)) - u = *(u32*)(psrc+4*addr); + u = *(u32*)(psrc + 4 * addr); else - u = RGBA16to32(*(u16*)(psrc+2*addr)); + u = RGBA16to32(*(u16*)(psrc + 2 * addr)); } else + { u = readPixel4HL(psrc, j, i, ptex->tbp0, ptex->tbw); + } + } + else + { + u = 0; } - else u = 0; break; case PSMT4HH: addr = getPixelAddress4HH(j, i, ptex->tbp0, ptex->tbw); - - if( 4*addr < 0x00400000 ) { - if( usevid ) { + if (4*addr < 0x00400000) + { + if (usevid) + { if (PSMT_IS32BIT(ptex->cpsm)) - u = *(u32*)(psrc+4*addr); + u = *(u32*)(psrc + 4 * addr); else - u = RGBA16to32(*(u16*)(psrc+2*addr)); + u = RGBA16to32(*(u16*)(psrc + 2 * addr)); } else + { u = readPixel4HH(psrc, j, i, ptex->tbp0, ptex->tbw); + } + } + else + { + u = 0; } - else u = 0; break; case PSMT32Z: addr = getPixelAddress32Z(j, i, ptex->tbp0, ptex->tbw); - - if( 4*addr < 0x00400000 ) + if (4*addr < 0x00400000) u = readPixel32Z(psrc, j, i, ptex->tbp0, ptex->tbw); - else u = 0; + else + u = 0; break; case PSMT24Z: addr = getPixelAddress24Z(j, i, ptex->tbp0, ptex->tbw); - - if( 4*addr < 0x00400000 ) + if (4*addr < 0x00400000) u = readPixel24Z(psrc, j, i, ptex->tbp0, ptex->tbw); - else u = 0; + else + u = 0; break; case PSMT16Z: addr = getPixelAddress16Z(j, i, ptex->tbp0, ptex->tbw); - - if( 2*addr < 0x00400000 ) + if (2*addr < 0x00400000) u = readPixel16Z(psrc, j, i, ptex->tbp0, ptex->tbw); - else u = 0; + else + u = 0; break; case PSMT16SZ: addr = getPixelAddress16SZ(j, i, ptex->tbp0, ptex->tbw); - - if( 2*addr < 0x00400000 ) + if (2*addr < 0x00400000) u = readPixel16SZ(psrc, j, i, ptex->tbp0, ptex->tbw); - else u = 0; + else + u = 0; break; default: @@ -530,29 +598,30 @@ ZeroGS::SaveTex(tex0Info* ptex, int usevid) } char Name[TGA_FILE_NAME_MAX_LENGTH]; - snprintf( Name, TGA_FILE_NAME_MAX_LENGTH, "Tex.%d.tga", TexNumber ); + + snprintf(Name, TGA_FILE_NAME_MAX_LENGTH, "Tex.%d.tga", TexNumber); SaveTGA(Name, ptex->tw, ptex->th, &data[0]); } // Do the save texture and return file name of it // Do not forget to call free(), other wise there would be memory leak! -char* -ZeroGS::NamedSaveTex(tex0Info* ptex, int usevid){ +char* ZeroGS::NamedSaveTex(tex0Info* ptex, int usevid) +{ SaveTex(ptex, usevid); char* Name = (char*)malloc(TGA_FILE_NAME_MAX_LENGTH); - snprintf( Name, TGA_FILE_NAME_MAX_LENGTH, "Tex.%d.tga", TexNumber ); + snprintf(Name, TGA_FILE_NAME_MAX_LENGTH, "Tex.%d.tga", TexNumber); TexNumber++; - if (TexNumber > MAX_NUMBER_SAVED_TGA) - TexNumber = 0; + + if (TexNumber > MAX_NUMBER_SAVED_TGA) TexNumber = 0; return Name; } -// Special function, wich is safe to call from any other file, without aviutils problems. -void -ZeroGS::Stop_Avi(){ +// Special function, which is safe to call from any other file, without aviutils problems. +void ZeroGS::Stop_Avi() +{ #ifdef _WIN32 STOP_AVI(); #else diff --git a/plugins/zzogl-pg/opengl/ZZoglVB.cpp b/plugins/zzogl-pg/opengl/ZZoglVB.cpp index a82a3bf1ee..08f6250f92 100644 --- a/plugins/zzogl-pg/opengl/ZZoglVB.cpp +++ b/plugins/zzogl-pg/opengl/ZZoglVB.cpp @@ -52,104 +52,123 @@ ZeroGS::VB::~VB() void ZeroGS::VB::Destroy() { - _aligned_free(pBufferData); pBufferData = NULL; nNumVertices = 0; + _aligned_free(pBufferData); + pBufferData = NULL; + nNumVertices = 0; prndr = NULL; pdepth = NULL; } -int ConstraintReson; +int ConstraintReason; // Return number of 64-pixels block, that guaranted could be hold in memory // from gsfb.fbp and tbp (textrure pase), zbuf.zbp (Z-buffer), frame.fbp // (previous frame). -inline int -ZeroGS::VB::FindMinimalMemoryConstrain(int tbp, int maxpos) { +inline int ZeroGS::VB::FindMinimalMemoryConstrain(int tbp, int maxpos) +{ int MinConstraint = maxpos; // make sure texture is far away from tbp { int Constraint = tbp - gsfb.fbp; - if ((0 < Constraint) && (Constraint < MinConstraint)) { + + if ((0 < Constraint) && (Constraint < MinConstraint)) + { MinConstraint = Constraint; - ConstraintReson = 1; + ConstraintReason = 1; } } // offroad uses 0x80 fbp which messes up targets // special case when double buffering (hamsterball) // Suikoden 3 require e00 have this issue too. P3 - 0x1000. - if (prndr != NULL) { + + if (prndr != NULL) + { int Constraint = frame.fbp - gsfb.fbp; - if ((0x0 < Constraint) && (Constraint < MinConstraint)) { + + if ((0x0 < Constraint) && (Constraint < MinConstraint)) + { MinConstraint = Constraint; - ConstraintReson = 2; + ConstraintReason = 2; } } // old caching method // zmsk necessary for KH movie - if (!zbuf.zmsk){ + if (!zbuf.zmsk) + { int Constraint = zbuf.zbp - gsfb.fbp; - if ((0 < Constraint) && (Constraint < MinConstraint)) { + + if ((0 < Constraint) && (Constraint < MinConstraint)) + { MinConstraint = Constraint; - ConstraintReson = 3; + ConstraintReason = 3; } } - // In 16Bit mode in one Word freame stored 2 pixels - if (PSMT_ISHALF(gsfb.psm)) - MinConstraint *= 2; + // In 16Bit mode in one Word frame stored 2 pixels + if (PSMT_ISHALF(gsfb.psm)) MinConstraint *= 2; return MinConstraint ; } // Return number of 64 pizel words that could be placed in Z-Buffer // If no Z-buffer present return old constraint -inline int -ZeroGS::VB::FindZbufferMemoryConstrain(int tbp, int maxpos) { +inline int ZeroGS::VB::FindZbufferMemoryConstrain(int tbp, int maxpos) +{ int MinConstraint = maxpos; // Check tbp / zbuffer constraint - if (!zbuf.zmsk) { - int Constraint = (tbp - zbuf.zbp) * (PSMT_ISHALF(zbuf.psm) ? 2 : 1 ); - if ((0 < Constraint) && (Constraint < MinConstraint)) { + if (!zbuf.zmsk) + { + int Constraint = (tbp - zbuf.zbp) * (PSMT_ISHALF(zbuf.psm) ? 2 : 1); + + if ((0 < Constraint) && (Constraint < MinConstraint)) + { MinConstraint = Constraint; - ConstraintReson = 4; + ConstraintReason = 4; } } return MinConstraint; } -// Return heights limiter form scissor. . -inline int -GetScissorY(int y) { +// Return heights limiter from scissor... +inline int GetScissorY(int y) +{ int fbh = (y >> MINMAX_SHIFT) + 1; - if ( fbh > 2 && ( fbh & 1 ) ) fbh -= 1; + + if (fbh > 2 && (fbh & 1)) fbh -= 1; + return fbh; } -//There is several reason to limit a height of frame: maximum buffer size, calculated size +//There is several reasons to limit a height of frame: maximum buffer size, calculated size //from fbw and fbh and scissoring. -inline int -ZeroGS::VB::FindMinimalHeightConstrain(int maxpos) { +inline int ZeroGS::VB::FindMinimalHeightConstrain(int maxpos) +{ int MinConstraint = maxpos; - if (maxmin < MinConstraint) { + if (maxmin < MinConstraint) + { MinConstraint = maxmin; - ConstraintReson = 5; + ConstraintReason = 5; } - if (gsfb.fbh < MinConstraint) { + if (gsfb.fbh < MinConstraint) + { MinConstraint = gsfb.fbh; - ConstraintReson = 6; + ConstraintReason = 6; } int ScissorConstraint = GetScissorY(scissor.y1) ; - if (ScissorConstraint < MinConstraint) { + + if (ScissorConstraint < MinConstraint) + { MinConstraint = ScissorConstraint; - ConstraintReson = 7; + ConstraintReason = 7; } return MinConstraint; @@ -157,32 +176,36 @@ ZeroGS::VB::FindMinimalHeightConstrain(int maxpos) { // 32 bit frames have additional constraints to frame // maxpos was maximum length of frame at normal constraints -inline void -ZeroGS::VB::CheckFrame32bitRes(int maxpos) +inline void ZeroGS::VB::CheckFrame32bitRes(int maxpos) { int fbh = frame.fbh; - if ( frame.fbh >= 512 ) { + if (frame.fbh >= 512) + { // neopets hack maxmin = min(maxmin, frame.fbh); frame.fbh = maxmin; - ConstraintReson = 8; + ConstraintReason = 8; } // ffxii hack to stop resolving - if( frame.fbp >= 0x3000 && fbh >= 0x1a0 ) { + if (frame.fbp >= 0x3000 && fbh >= 0x1a0) + { int endfbp = frame.fbp + frame.fbw * fbh / (PSMT_ISHALF(gsfb.psm) ? 128 : 64); // see if there is a previous render target in the way, reduce - for (CRenderTargetMngr::MAPTARGETS::iterator itnew = s_RTs.mapTargets.begin(); itnew != s_RTs.mapTargets.end(); ++itnew) { - if ( itnew->second->fbp > frame.fbp && endfbp > itnew->second->fbp ) { + + for (CRenderTargetMngr::MAPTARGETS::iterator itnew = s_RTs.mapTargets.begin(); itnew != s_RTs.mapTargets.end(); ++itnew) + { + if (itnew->second->fbp > frame.fbp && endfbp > itnew->second->fbp) + { endfbp = itnew->second->fbp; } } - frame.fbh = (endfbp - frame.fbp) * ( PSMT_ISHALF(gsfb.psm) ? 128: 64 ) / frame.fbw; - if (frame.fbh < fbh) - ConstraintReson = 9; + frame.fbh = (endfbp - frame.fbp) * (PSMT_ISHALF(gsfb.psm) ? 128 : 64) / frame.fbw; + + if (frame.fbh < fbh) ConstraintReason = 9; } } @@ -192,30 +215,33 @@ ZeroGS::VB::CheckFrame32bitRes(int maxpos) // 4Mb memory in 64 bit (4 bytes) words. // |------------------------|---------------------|----------|----------|---------------------| // 0 gsfb.fbp zbuff.zpb tbp frame.fbp 2^20/64 -inline int -ZeroGS::VB::CheckFrameAddConstraints(int tbp) +inline int ZeroGS::VB::CheckFrameAddConstraints(int tbp) { - if ( gsfb.fbw <= 0 ) { + if (gsfb.fbw <= 0) + { ERROR_LOG_SPAM("render target null, no constraints. Ignoring\n"); return -1; } // Memory region after fbp int maxmemorypos = 0x4000 - gsfb.fbp; - ConstraintReson = 0; + + ConstraintReason = 0; maxmemorypos = FindMinimalMemoryConstrain(tbp, maxmemorypos); maxmemorypos = FindZbufferMemoryConstrain(tbp, maxmemorypos); int maxpos = 64 * maxmemorypos ; + maxpos /= gsfb.fbw; + //? atelier iris crashes without it - if( maxpos > 256 ) - maxpos &= ~0x1f; + if (maxpos > 256) maxpos &= ~0x1f; #ifdef DEVBUILD int noscissorpos = maxpos; - int ConstrainR1 = ConstraintReson; + + int ConstrainR1 = ConstraintReason; #endif maxpos = FindMinimalHeightConstrain(maxpos); @@ -223,12 +249,13 @@ ZeroGS::VB::CheckFrameAddConstraints(int tbp) frame = gsfb; frame.fbh = maxpos; - if( !PSMT_ISHALF(frame.psm) || !(g_GameSettings&GAME_FULL16BITRES) ) - CheckFrame32bitRes( maxpos ) ; + if (!PSMT_ISHALF(frame.psm) || !(g_GameSettings&GAME_FULL16BITRES)) + CheckFrame32bitRes(maxpos); #ifdef DEVBUILD if (frame.fbh == 0xe2) - ZZLog::Error_Log ("Const: %x %x %d| %x %d %x %x", frame.fbh, frame.fbw, ConstraintReson, noscissorpos, ConstrainR1, tbp, frame.fbp); + ZZLog::Error_Log("Const: %x %x %d| %x %d %x %x", frame.fbh, frame.fbw, ConstraintReason, noscissorpos, ConstrainR1, tbp, frame.fbp); + #endif // Fixme: Reserved psm for framebuffers @@ -237,11 +264,9 @@ ZeroGS::VB::CheckFrameAddConstraints(int tbp) return 0 ; } -// Check if after resising new depth target is need to be used. -// it return 2 if new deapth target used. bool Chose is used to proprely check -// renderer target status -inline int -ZeroGS::VB::CheckFrameResolveDepth(int tbp) +// Check if after resizing new depth target is needed to be used. +// it returns 2 if a new depth target is used. +inline int ZeroGS::VB::CheckFrameResolveDepth(int tbp) { int result = 0 ; CDepthTarget* pprevdepth = pdepth; @@ -250,13 +275,13 @@ ZeroGS::VB::CheckFrameResolveDepth(int tbp) // just z changed frameInfo f = CreateFrame(zbuf.zbp, prndr->fbw, prndr->fbh, zbuf.psm, (zbuf.psm == 0x31) ? 0xff000000 : 0); - CDepthTarget* pnewdepth = (CDepthTarget*)s_DepthRTs.GetTarg(f, CRenderTargetMngr::TO_DepthBuffer|CRenderTargetMngr::TO_StrictHeight| - (zbuf.zmsk?CRenderTargetMngr::TO_Virtual:0), get_maxheight(zbuf.zbp, gsfb.fbw, 0)); + CDepthTarget* pnewdepth = (CDepthTarget*)s_DepthRTs.GetTarg(f, CRenderTargetMngr::TO_DepthBuffer | CRenderTargetMngr::TO_StrictHeight | + (zbuf.zmsk ? CRenderTargetMngr::TO_Virtual : 0), get_maxheight(zbuf.zbp, gsfb.fbw, 0)); - assert( pnewdepth != NULL && prndr != NULL ); - assert( pnewdepth->fbh == prndr->fbh ); + assert(pnewdepth != NULL && prndr != NULL); + assert(pnewdepth->fbh == prndr->fbh); - if( (pprevdepth != pnewdepth) || (pprevdepth != NULL && (pprevdepth->status & CRenderTarget::TS_NeedUpdate)) ) + if ((pprevdepth != pnewdepth) || (pprevdepth != NULL && (pprevdepth->status & CRenderTarget::TS_NeedUpdate))) result = 2; pdepth = pnewdepth; @@ -264,11 +289,11 @@ ZeroGS::VB::CheckFrameResolveDepth(int tbp) return result ; } -// Check if after resings new render target is need to be used. Also perform deptaget check -// Return 1 if only render target is changed and 3 -- if both. -inline int -ZeroGS::VB::CheckFrameResolveRender(int tbp) { - int result = 0 ; +// Check if after resizing, a new render target is needed to be used. Also perform deptarget check. +// Returns 1 if only 1 render target is changed and 3 -- if both. +inline int ZeroGS::VB::CheckFrameResolveRender(int tbp) +{ + int result = 0; CRenderTarget* pprevrndr = prndr; prndr = NULL; @@ -277,98 +302,115 @@ ZeroGS::VB::CheckFrameResolveRender(int tbp) { // Set renderes to NULL to prevent Flushing. CRenderTarget* pnewtarg = s_RTs.GetTarg(frame, 0, maxmin); - assert( pnewtarg != NULL ); + assert(pnewtarg != NULL); // pnewtarg->fbh >= 0x1c0 needed for ffx - if( (pnewtarg->fbh >= 0x1c0) && pnewtarg->fbh > frame.fbh && zbuf.zbp < tbp && !zbuf.zmsk ) { + + if ((pnewtarg->fbh >= 0x1c0) && pnewtarg->fbh > frame.fbh && zbuf.zbp < tbp && !zbuf.zmsk) + { // check if zbuf is in the way of the texture (suikoden5) - int maxallowedfbh = (tbp-zbuf.zbp)*(PSMT_ISHALF(zbuf.psm)?128:64) / gsfb.fbw; + int maxallowedfbh = (tbp - zbuf.zbp) * (PSMT_ISHALF(zbuf.psm) ? 128 : 64) / gsfb.fbw; + if (PSMT_ISHALF(gsfb.psm)) maxallowedfbh *= 2; - if (pnewtarg->fbh > maxallowedfbh + 32) { // +32 needed for ffx2 + if (pnewtarg->fbh > maxallowedfbh + 32) // +32 needed for ffx2 + { // destroy and recreate s_RTs.DestroyAllTargs(0, 0x100, pnewtarg->fbw); pnewtarg = s_RTs.GetTarg(frame, 0, maxmin); - assert( pnewtarg != NULL ); + assert(pnewtarg != NULL); } } ZZLog::Prim_Log("frame_%d: fbp=0x%x fbw=%d fbh=%d(%d) psm=0x%x fbm=0x%x\n", ictx, gsfb.fbp, gsfb.fbw, gsfb.fbh, pnewtarg->fbh, gsfb.psm, gsfb.fbm); - if( (pprevrndr != pnewtarg) || (pprevrndr != NULL && (pprevrndr->status & CRenderTarget::TS_NeedUpdate)) ) + if ((pprevrndr != pnewtarg) || (pprevrndr != NULL && (pprevrndr->status & CRenderTarget::TS_NeedUpdate))) result = 1; prndr = pnewtarg; + pdepth = pprevdepth ; result |= CheckFrameResolveDepth(tbp) ; + return result ; } -// After frame resetting it is possible that 16 to 32 or 32 to 16 (color bits) conversion should be made. -inline void -ZeroGS::VB::CheckFrame16vs32Convesion() +// After frame resetting, it is possible that 16 to 32 or 32 to 16 (color bits) conversion should be made. +inline void ZeroGS::VB::CheckFrame16vs32Convesion() { - if( prndr->status & CRenderTarget::TS_NeedConvert32) { - if( pdepth->pdepth != 0 ) - pdepth->SetDepthStencilSurface(); + if (prndr->status & CRenderTarget::TS_NeedConvert32) + { + if (pdepth->pdepth != 0) pdepth->SetDepthStencilSurface(); + prndr->fbh *= 2; prndr->ConvertTo32(); prndr->status &= ~CRenderTarget::TS_NeedConvert32; } - else if( prndr->status & CRenderTarget::TS_NeedConvert16 ) { - if( pdepth->pdepth != 0 ) - pdepth->SetDepthStencilSurface(); + else if (prndr->status & CRenderTarget::TS_NeedConvert16) + { + if (pdepth->pdepth != 0) pdepth->SetDepthStencilSurface(); + prndr->fbh /= 2; prndr->ConvertTo16(); prndr->status &= ~CRenderTarget::TS_NeedConvert16; } } -// a lot of times, target is too big and overwrites the texture using, -// if tbp != 0, use it to bound +// A lot of times, the target is too big and overwrites the texture. +// If tbp != 0, use it to bound. void ZeroGS::VB::CheckFrame(int tbp) { static int bChanged; - if( bNeedZCheck ) { + + if (bNeedZCheck) + { ZZLog::Prim_Log("zbuf_%d: zbp=0x%x psm=0x%x, zmsk=%d\n", ictx, zbuf.zbp, zbuf.psm, zbuf.zmsk); //zbuf = *zb; } - if( m_Blocks[gsfb.psm].bpp == 0 ) { + if (m_Blocks[gsfb.psm].bpp == 0) + { ZZLog::Error_Log("CheckFrame invalid bpp %d.", gsfb.psm); return; } bChanged = 0; - if( bNeedFrameCheck ) { - + if (bNeedFrameCheck) + { // important to set before calling GetTarg bNeedFrameCheck = 0; bNeedZCheck = 0; - if ( CheckFrameAddConstraints(tbp) == -1 ) return ; - if ( ( prndr != NULL ) && ( prndr->psm != gsfb.psm ) ) { + if (CheckFrameAddConstraints(tbp) == -1) return ; + + if ((prndr != NULL) && (prndr->psm != gsfb.psm)) + { // behavior for dest alpha varies ResetAlphaVariables(); - } + } + + bChanged = CheckFrameResolveRender(tbp); - bChanged = CheckFrameResolveRender(tbp) ; CheckFrame16vs32Convesion(); } - else if (bNeedZCheck) { + else if (bNeedZCheck) + { bNeedZCheck = 0; - if (prndr != NULL && gsfb.fbw > 0 ) + + if (prndr != NULL && gsfb.fbw > 0) CheckFrameResolveDepth(tbp); } - if( prndr != NULL ) SetContextTarget(ictx); + if (prndr != NULL) SetContextTarget(ictx); } // This is the case, most easy to perform, when nothinh was changed -inline void ZeroGS::VB::FlushTexUnchangedClutDontUpdate() { - if (ZZOglGet_cld_TexBits(uNextTex0Data[1])) { +inline void ZeroGS::VB::FlushTexUnchangedClutDontUpdate() +{ + if (ZZOglGet_cld_TexBits(uNextTex0Data[1])) + { ZeroGS::texClutWrite(ictx); // invalidate to make sure target didn't change! bVarsTexSync = FALSE; @@ -377,7 +419,8 @@ inline void ZeroGS::VB::FlushTexUnchangedClutDontUpdate() { // The second of easy branch. We does not change storage model, so we don't need to // update anything except texture itself -inline void ZeroGS::VB::FlushTexClutDontUpdate() { +inline void ZeroGS::VB::FlushTexClutDontUpdate() +{ if (!ZZOglClutStorageUnchanged(uCurTex0Data, uNextTex0Data)) ZeroGS::Flush(ictx); @@ -388,12 +431,14 @@ inline void ZeroGS::VB::FlushTexClutDontUpdate() { tex0.cpsm = ZZOglGet_cpsm_TexBits(uNextTex0Data[1]); ZeroGS::texClutWrite(ictx); + bVarsTexSync = FALSE; } // Set texture variables after big change -inline void ZeroGS::VB::FlushTexSetNewVars(u32 psm) { +inline void ZeroGS::VB::FlushTexSetNewVars(u32 psm) +{ tex0.tbp0 = ZZOglGet_tbp0_TexBits(uNextTex0Data[0]); tex0.tbw = ZZOglGet_tbw_TexBitsMult(uNextTex0Data[0]); tex0.psm = psm; @@ -403,34 +448,37 @@ inline void ZeroGS::VB::FlushTexSetNewVars(u32 psm) { tex0.tcc = ZZOglGet_tcc_TexBits(uNextTex0Data[1]); tex0.tfx = ZZOglGet_tfx_TexBits(uNextTex0Data[1]); - ZeroGS::fiTexWidth[ictx] = (1/16.0f)/ tex0.tw; - ZeroGS::fiTexHeight[ictx] = (1/16.0f) / tex0.th; + ZeroGS::fiTexWidth[ictx] = (1 / 16.0f) / tex0.tw; + ZeroGS::fiTexHeight[ictx] = (1 / 16.0f) / tex0.th; } // Flush == draw on screen // This function made VB state consistant before real Flush. void ZeroGS::VB::FlushTexData() { - assert( bNeedTexCheck ); + assert(bNeedTexCheck); bNeedTexCheck = 0; u32 psm = ZZOglGet_psm_TexBitsFix(uNextTex0Data[0]); // don't update unless necessary - if (ZZOglAllExceptClutIsSame(uCurTex0Data, uNextTex0Data)) { + + if (ZZOglAllExceptClutIsSame(uCurTex0Data, uNextTex0Data)) + { // Don't need to do anything if there is no clutting and VB tex data was not changed - if( !PSMT_ISCLUT(psm) ) - return ; + if (!PSMT_ISCLUT(psm)) return ; // have to write the CLUT again if only CLD was changed - if( ZZOglClutMinusCLDunchanged(uCurTex0Data, uNextTex0Data) ) { + if (ZZOglClutMinusCLDunchanged(uCurTex0Data, uNextTex0Data)) + { FlushTexUnchangedClutDontUpdate(); return; } // Cld bit is 0 means that clut buffer stay unchanged - if( ZZOglGet_cld_TexBits(uNextTex0Data[1]) == 0 ) { + if (ZZOglGet_cld_TexBits(uNextTex0Data[1]) == 0) + { FlushTexClutDontUpdate(); return; } @@ -438,6 +486,7 @@ void ZeroGS::VB::FlushTexData() // Made the full update ZeroGS::Flush(ictx); + bVarsTexSync = FALSE; bTexConstsSync = FALSE; @@ -446,8 +495,5 @@ void ZeroGS::VB::FlushTexData() FlushTexSetNewVars(psm); - if( PSMT_ISCLUT(psm) ) - ZeroGS::CluttingForFlushedTex(&tex0, uNextTex0Data[1], ictx ) ; + if (PSMT_ISCLUT(psm)) ZeroGS::CluttingForFlushedTex(&tex0, uNextTex0Data[1], ictx) ; } - - diff --git a/plugins/zzogl-pg/opengl/rasterfont.cpp b/plugins/zzogl-pg/opengl/rasterfont.cpp index 969c47463f..71a330e995 100644 --- a/plugins/zzogl-pg/opengl/rasterfont.cpp +++ b/plugins/zzogl-pg/opengl/rasterfont.cpp @@ -1,4 +1,3 @@ - #ifdef _WIN32 #include #endif @@ -9,7 +8,8 @@ #include "rasterfont.h" // globals -GLubyte rasters[][13] = { +GLubyte rasters[][13] = +{ {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, {0x00, 0x00, 0x18, 0x18, 0x00, 0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18}, {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x36, 0x36, 0x36}, @@ -113,9 +113,11 @@ RasterFont::RasterFont() glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // create the raster font - fontOffset = glGenLists (128); - for (int i = 32; i < 127; i++) { - glNewList(i+fontOffset, GL_COMPILE); + fontOffset = glGenLists(128); + + for (int i = 32; i < 127; i++) + { + glNewList(i + fontOffset, GL_COMPILE); glBitmap(8, 13, 0.0f, 2.0f, 10.0f, 0.0f, rasters[i-32]); glEndList(); } @@ -131,16 +133,16 @@ void RasterFont::printString(const char *s, double x, double y, double z) // go to the right spot glRasterPos3d(x, y, z); - glPushAttrib (GL_LIST_BIT); + glPushAttrib(GL_LIST_BIT); glListBase(fontOffset); glCallLists(strlen(s), GL_UNSIGNED_BYTE, (GLubyte *) s); - glPopAttrib (); + glPopAttrib(); } void RasterFont::printCenteredString(const char *s, double y, int screen_width, double z) { int length = strlen(s); - int x = int(screen_width/2.0 - (length/2.0)*char_width); + int x = int(screen_width / 2.0 - (length / 2.0) * char_width); printString(s, x, y, z); } diff --git a/plugins/zzogl-pg/opengl/targets.cpp b/plugins/zzogl-pg/opengl/targets.cpp index 51fcac131e..ad211acee4 100644 --- a/plugins/zzogl-pg/opengl/targets.cpp +++ b/plugins/zzogl-pg/opengl/targets.cpp @@ -36,6 +36,7 @@ //#define RW extern int g_GameSettings; + using namespace ZeroGS; extern int g_TransferredToGPU; extern bool g_bIsLost; @@ -56,10 +57,11 @@ extern int s_nResolved; extern u32 g_nResolve; extern bool g_bSaveTrans; -namespace ZeroGS { - CRenderTargetMngr s_RTs, s_DepthRTs; - CBitwiseTextureMngr s_BitwiseTextures; - CMemoryTargetMngr g_MemTargs; +namespace ZeroGS +{ +CRenderTargetMngr s_RTs, s_DepthRTs; +CBitwiseTextureMngr s_BitwiseTextures; +CMemoryTargetMngr g_MemTargs; } extern u32 s_ptexCurSet[2]; @@ -71,25 +73,26 @@ BOOL g_bSaveZUpdate = 0; // memory size for one row of texture. It's depends of windth of texture and number of bytes // per pixel -inline u32 Pitch( int fbw ) { return (RW(fbw) * (GetRenderFormat() == RFT_float16 ? 8 : 4)) ; } +inline u32 Pitch(int fbw) { return (RW(fbw) * (GetRenderFormat() == RFT_float16 ? 8 : 4)) ; } // memory size of whole texture. It is number of rows multiplied by memory size of row -inline u32 Tex_Memory_Size ( int fbw, int fbh ) { return (RH(fbh) * Pitch(fbw)); } +inline u32 Tex_Memory_Size(int fbw, int fbh) { return (RH(fbh) * Pitch(fbw)); } // Oftenly called for several reasons // Call flush if renderer or depther target is equal to ptr -inline void FlushIfNecesary ( void* ptr ) { - if( vb[0].prndr == ptr || vb[0].pdepth == ptr ) - Flush(0); - if( vb[1].prndr == ptr || vb[1].pdepth == ptr ) - Flush(1); +inline void FlushIfNecesary(void* ptr) +{ + if (vb[0].prndr == ptr || vb[0].pdepth == ptr) Flush(0); + if (vb[1].prndr == ptr || vb[1].pdepth == ptr) Flush(1); } // This block was repreaded several times, so I inlined it. -inline void DestroyAllTargetsHelper( void* ptr ) { - for(int i = 0; i < 2; ++i) { - if( ptr == vb[i].prndr ) { vb[i].prndr = NULL; vb[i].bNeedFrameCheck = 1; } - if( ptr == vb[i].pdepth ) { vb[i].pdepth = NULL; vb[i].bNeedZCheck = 1; } +inline void DestroyAllTargetsHelper(void* ptr) +{ + for (int i = 0; i < 2; ++i) + { + if (ptr == vb[i].prndr) { vb[i].prndr = NULL; vb[i].bNeedFrameCheck = 1; } + if (ptr == vb[i].pdepth) { vb[i].pdepth = NULL; vb[i].bNeedZCheck = 1; } } } @@ -97,11 +100,12 @@ inline void DestroyAllTargetsHelper( void* ptr ) { // return false if creating texture was uncuccessfull // fbh and fdb should be properly shifter before calling this!. // We should ignore framebuffer trouble here, we put textures of dufferent sized to it. -inline bool ZeroGS::CRenderTarget::InitialiseDefaultTexture ( u32 *ptr_p, int fbw, int fbh ) { +inline bool ZeroGS::CRenderTarget::InitialiseDefaultTexture(u32 *ptr_p, int fbw, int fbh) +{ glGenTextures(1, ptr_p); glBindTexture(GL_TEXTURE_RECTANGLE_NV, *ptr_p); // initialize to default - glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GetRenderTargetFormat(), fbw, fbh, 0, GL_RGBA, GetRenderFormat()==RFT_float16?GL_FLOAT:GL_UNSIGNED_BYTE, NULL); + glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GetRenderTargetFormat(), fbw, fbh, 0, GL_RGBA, GetRenderFormat() == RFT_float16 ? GL_FLOAT : GL_UNSIGNED_BYTE, NULL); glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_T, GL_CLAMP); @@ -113,9 +117,11 @@ inline bool ZeroGS::CRenderTarget::InitialiseDefaultTexture ( u32 *ptr_p, int fb } // Draw 4 triangles from binded array using only stenclil buffer -inline void FillOnlyStencilBuffer() { - if( ZeroGS::IsWriteDestAlphaTest() && !(g_GameSettings&GAME_NOSTENCIL)) { - glColorMask(0,0,0,0); +inline void FillOnlyStencilBuffer() +{ + if (ZeroGS::IsWriteDestAlphaTest() && !(g_GameSettings&GAME_NOSTENCIL)) + { + glColorMask(0, 0, 0, 0); glEnable(GL_ALPHA_TEST); glAlphaFunc(GL_GEQUAL, 1.0f); @@ -123,30 +129,33 @@ inline void FillOnlyStencilBuffer() { glStencilFunc(GL_ALWAYS, 1, 0xff); glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); - glColorMask(1,1,1,1); + glColorMask(1, 1, 1, 1); } } // used for transformation from vertex position in GS window.coords (I hope) // to view coordinates (in range 0, 1). -inline Vector ZeroGS::CRenderTarget::DefaultBitBltPos() { - Vector v = Vector (1, -1, 0.5f/(float)RW(fbw), 0.5f/(float)RH(fbh) ); - v *= 1.0f/32767.0f; +inline Vector ZeroGS::CRenderTarget::DefaultBitBltPos() +{ + Vector v = Vector(1, -1, 0.5f / (float)RW(fbw), 0.5f / (float)RH(fbh)); + v *= 1.0f / 32767.0f; ZZcgSetParameter4fv(pvsBitBlt.sBitBltPos, v, "g_sBitBltPos"); - return v ; + return v; } // Used to transform texture coordinates from GS (when 0,0 is upper left) to // OpenGL (0,0 - lower left). -inline Vector ZeroGS::CRenderTarget::DefaultBitBltTex() { +inline Vector ZeroGS::CRenderTarget::DefaultBitBltTex() +{ // I really sure that -0.5 is correct, because OpenGL have no half-offset // issue, DirectX known for. - Vector v = Vector (1, -1, 0.5f/(float)RW(fbw), -0.5f/(float)RH(fbh) ); + Vector v = Vector(1, -1, 0.5f / (float)RW(fbw), -0.5f / (float)RH(fbh)); ZZcgSetParameter4fv(pvsBitBlt.sBitBltTex, v, "g_sBitBltTex"); - return v ; + return v; } -inline void BindToSample ( u32 *p_ptr ) { +inline void BindToSample(u32 *p_ptr) +{ glBindTexture(GL_TEXTURE_RECTANGLE_NV, *p_ptr); glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_MIN_FILTER, GL_NEAREST); @@ -183,24 +192,27 @@ bool ZeroGS::CRenderTarget::Create(const frameInfo& frame) vposxy.x = 2.0f * (1.0f / 8.0f) / (float)fbw; vposxy.y = 2.0f * (1.0f / 8.0f) / (float)fbh; - vposxy.z = -1-0.5f/(float)fbw; - vposxy.w = -1+0.5f/(float)fbh; + vposxy.z = -1 - 0.5f / (float)fbw; + vposxy.w = -1 + 0.5f / (float)fbh; status = 0; - if( fbw > 0 && fbh > 0 ) { + if (fbw > 0 && fbh > 0) + { GetRectMemAddress(start, end, psm, 0, 0, fbw, fbh, fbp, fbw); - psys = _aligned_malloc( Tex_Memory_Size ( fbw, fbh ), 16 ); + psys = _aligned_malloc(Tex_Memory_Size(fbw, fbh), 16); GL_REPORT_ERRORD(); - if ( !InitialiseDefaultTexture( &ptex, RW(fbw), RH(fbh) )) { + if (!InitialiseDefaultTexture(&ptex, RW(fbw), RH(fbh))) + { Destroy(); return false; } status = TS_NeedUpdate; } - else { + else + { start = end = 0; } @@ -211,7 +223,8 @@ void ZeroGS::CRenderTarget::Destroy() { FUNCLOG created = 1; - _aligned_free(psys); psys = NULL; + _aligned_free(psys); + psys = NULL; SAFE_RELEASE_TEX(ptex); SAFE_RELEASE_TEX(ptexFeedback); } @@ -221,30 +234,34 @@ void ZeroGS::CRenderTarget::SetTarget(int fbplocal, const Rect2& scissor, int co FUNCLOG int dy = 0; - if( fbplocal != fbp ) { + if (fbplocal != fbp) + { Vector v; // will be rendering to a subregion u32 bpp = PSMT_ISHALF(psm) ? 2 : 4; - assert( ((256/bpp)*(fbplocal-fbp)) % fbw == 0 ); - assert( fbplocal >= fbp ); + assert(((256 / bpp)*(fbplocal - fbp)) % fbw == 0); + assert(fbplocal >= fbp); - dy = ((256/bpp)*(fbplocal-fbp)) / fbw; + dy = ((256 / bpp) * (fbplocal - fbp)) / fbw; v.x = vposxy.x; v.y = vposxy.y; v.z = vposxy.z; - v.w = vposxy.w - dy*2.0f/(float)fbh; + v.w = vposxy.w - dy * 2.0f / (float)fbh; ZZcgSetParameter4fv(g_vparamPosXY[context], v, "g_fPosXY"); } else + { ZZcgSetParameter4fv(g_vparamPosXY[context], vposxy, "g_fPosXY"); + } // set render states - scissorrect.x = scissor.x0>>3; - scissorrect.y = (scissor.y0>>3) + dy; - scissorrect.w = (scissor.x1>>3)+1; - scissorrect.h = (scissor.y1>>3)+1+dy; + scissorrect.x = scissor.x0 >> 3; + scissorrect.y = (scissor.y0 >> 3) + dy; + scissorrect.w = (scissor.x1 >> 3) + 1; + scissorrect.h = (scissor.y1 >> 3) + 1 + dy; + scissorrect.w = min(scissorrect.w, fbw) - scissorrect.x; scissorrect.h = min(scissorrect.h, fbh) - scissorrect.y; @@ -260,7 +277,8 @@ void ZeroGS::CRenderTarget::SetViewport() glViewport(0, 0, RW(fbw), RH(fbh)); } -inline bool NotResolveHelper() { +inline bool NotResolveHelper() +{ return ((s_nResolved > 8 && (2 * s_nResolved > fFPS - 10)) || (g_GameSettings&GAME_NOTARGETRESOLVE)); } @@ -268,18 +286,20 @@ void ZeroGS::CRenderTarget::Resolve() { FUNCLOG - if( ptex != 0 && !(status&TS_Resolved) && !(status&TS_NeedUpdate) ) { - + if (ptex != 0 && !(status&TS_Resolved) && !(status&TS_NeedUpdate)) + { // flush if necessary - FlushIfNecesary ( this ) ; + FlushIfNecesary(this) ; - if ((IsDepth() && !ZeroGS::IsWriteDepth()) || NotResolveHelper()) { + if ((IsDepth() && !ZeroGS::IsWriteDepth()) || NotResolveHelper()) + { // don't resolve if depths aren't used status = TS_Resolved; return; } glBindTexture(GL_TEXTURE_RECTANGLE_NV, ptex); + GL_REPORT_ERRORD(); // This code extremely slow on DC1. // _aligned_free(psys); @@ -290,12 +310,16 @@ void ZeroGS::CRenderTarget::Resolve() GL_REPORT_ERRORD(); #if defined(DEVBUILD) - if( g_bSaveResolved ) { + + if (g_bSaveResolved) + { SaveTexture("resolved.tga", GL_TEXTURE_RECTANGLE_NV, ptex, RW(fbw), RH(fbh)); g_bSaveResolved = 0; } + #endif _Resolve(psys, fbp, fbw, fbh, psm, fbm, true); + status = TS_Resolved; } } @@ -304,46 +328,53 @@ void ZeroGS::CRenderTarget::Resolve(int startrange, int endrange) { FUNCLOG - assert( startrange < end && endrange > start ); // make sure it at least intersects - - if( ptex != 0 && !(status&TS_Resolved) && !(status&TS_NeedUpdate) ) { + assert(startrange < end && endrange > start); // make sure it at least intersects + if (ptex != 0 && !(status&TS_Resolved) && !(status&TS_NeedUpdate)) + { // flush if necessary - FlushIfNecesary ( this ) ; + FlushIfNecesary(this) ; #if defined(DEVBUILD) - if( g_bSaveResolved ) { + if (g_bSaveResolved) + { SaveTexture("resolved.tga", GL_TEXTURE_RECTANGLE_NV, ptex, RW(fbw), RH(fbh)); g_bSaveResolved = 0; } #endif - - if(g_GameSettings&GAME_NOTARGETRESOLVE) { + if (g_GameSettings&GAME_NOTARGETRESOLVE) + { status = TS_Resolved; return; } int blockheight = PSMT_ISHALF(psm) ? 64 : 32; int resolvefbp = fbp, resolveheight = fbh; + int scanlinewidth = 0x2000 * (fbw >> 6); - int scanlinewidth = 0x2000*(fbw>>6); + // in no way should data be overwritten!, instead resolve less - // in now way should data be overwritten!, instead resolve less - if( endrange < end ) { + if (endrange < end) + { // round down to nearest block and scanline - resolveheight = ((endrange-start)/(0x2000*(fbw>>6))) * blockheight; - if( resolveheight <= 32 ) { + resolveheight = ((endrange - start) / (0x2000 * (fbw >> 6))) * blockheight; + + if (resolveheight <= 32) + { status = TS_Resolved; return; } } - else if( startrange > start ) { + else if (startrange > start) + { // round up to nearest block and scanline resolvefbp = startrange + scanlinewidth - 1; resolvefbp -= resolvefbp % scanlinewidth; - resolveheight = fbh-((resolvefbp-fbp)*blockheight/scanlinewidth); - if( resolveheight <= 64 ) { // this is a total hack, but kh doesn't resolve now + resolveheight = fbh - ((resolvefbp - fbp) * blockheight / scanlinewidth); + + if (resolveheight <= 64) // this is a total hack, but kh doesn't resolve now + { status = TS_Resolved; return; } @@ -352,14 +383,16 @@ void ZeroGS::CRenderTarget::Resolve(int startrange, int endrange) } glBindTexture(GL_TEXTURE_RECTANGLE_NV, ptex); + glGetTexImage(GL_TEXTURE_RECTANGLE_NV, 0, GL_RGBA, GL_UNSIGNED_BYTE, psys); GL_REPORT_ERRORD(); u8* pbits = (u8*)psys; - if( fbp != resolvefbp ) - pbits += ((resolvefbp-fbp)*256/scanlinewidth)*blockheight*Pitch( fbw ); + + if (fbp != resolvefbp) pbits += ((resolvefbp - fbp) * 256 / scanlinewidth) * blockheight * Pitch(fbw); _Resolve(pbits, resolvefbp, fbw, resolveheight, psm, fbm, true); + status = TS_Resolved; } } @@ -377,25 +410,32 @@ void ZeroGS::CRenderTarget::Update(int context, ZeroGS::CRenderTarget* pdepth) //pd3dDevice->SetDepthStencilSurface(psurfDepth); ResetRenderTarget(1); SetRenderTarget(0); - assert( pdepth != NULL ); + assert(pdepth != NULL); ((CDepthTarget*)pdepth)->SetDepthStencilSurface(); SetShaderCaller("CRenderTarget::Update"); Vector v = DefaultBitBltPos(); CRenderTargetMngr::MAPTARGETS::iterator ittarg; - if( nUpdateTarg ) { + + if (nUpdateTarg) + { ittarg = s_RTs.mapTargets.find(nUpdateTarg); - if( ittarg == s_RTs.mapTargets.end() ) { + + if (ittarg == s_RTs.mapTargets.end()) + { ittarg = s_DepthRTs.mapTargets.find(nUpdateTarg); - if( ittarg == s_DepthRTs.mapTargets.end() ) + + if (ittarg == s_DepthRTs.mapTargets.end()) nUpdateTarg = 0; - else if( ittarg->second == this ) { + else if (ittarg->second == this) + { ZZLog::Error_Log("Updating self."); nUpdateTarg = 0; } } - else if( ittarg->second == this ) { + else if (ittarg->second == this) + { ZZLog::Error_Log("Updating self."); nUpdateTarg = 0; } @@ -403,13 +443,15 @@ void ZeroGS::CRenderTarget::Update(int context, ZeroGS::CRenderTarget* pdepth) SetViewport(); - if( nUpdateTarg ) { + if (nUpdateTarg) + { cgGLSetTextureParameter(ppsBaseTexture.sFinal, ittarg->second->ptex); cgGLEnableTextureParameter(ppsBaseTexture.sFinal); //assert( ittarg->second->fbw == fbw ); - int offset = (fbp-ittarg->second->fbp)*64/fbw; + int offset = (fbp - ittarg->second->fbp) * 64 / fbw; + if (PSMT_ISHALF(psm)) // 16 bit offset *= 2; @@ -417,14 +459,18 @@ void ZeroGS::CRenderTarget::Update(int context, ZeroGS::CRenderTarget* pdepth) v.y = (float)RH(fbh); v.z = 0.25f; v.w = (float)RH(offset) + 0.25f; + ZZcgSetParameter4fv(pvsBitBlt.sBitBltTex, v, "g_fBitBltTex"); + // v = DefaultBitBltTex(); Maybe? - v = DefaultOneColor ( ppsBaseTexture ) ; + v = DefaultOneColor(ppsBaseTexture) ; SETPIXELSHADER(ppsBaseTexture.prog); + nUpdateTarg = 0; } - else { + else + { // align the rect to the nearest page // note that fbp is always aligned on page boundaries tex0Info texframe; @@ -438,22 +484,23 @@ void ZeroGS::CRenderTarget::Update(int context, ZeroGS::CRenderTarget* pdepth) // write color and zero out stencil buf, always 0 context! // force bilinear if using AA // Fix in r133 -- FFX movies and Gust backgrounds! - SetTexVariablesInt(0, 0*(s_AAx || s_AAy)?2:0, texframe, pmemtarg, &ppsBitBlt[!!s_AAx], 1); + SetTexVariablesInt(0, 0*(s_AAx || s_AAy) ? 2 : 0, texframe, pmemtarg, &ppsBitBlt[!!s_AAx], 1); cgGLSetTextureParameter(ppsBitBlt[!!s_AAx].sMemory, pmemtarg->ptex->tex); cgGLEnableTextureParameter(ppsBitBlt[!!s_AAx].sMemory); - v = Vector(1,1,0.0f,0.0f); + v = Vector(1, 1, 0.0f, 0.0f); ZZcgSetParameter4fv(pvsBitBlt.sBitBltTex, v, "g_fBitBltTex"); v.x = 1; v.y = 2; ZZcgSetParameter4fv(ppsBitBlt[!!s_AAx].sOneColor, v, "g_fOneColor"); - assert( ptex != 0 ); + assert(ptex != 0); - if( conf.options & GSOPTION_WIREFRAME ) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + if (conf.options & GSOPTION_WIREFRAME) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - if( ZeroGS::IsWriteDestAlphaTest() ) { + if (ZeroGS::IsWriteDestAlphaTest()) + { glEnable(GL_STENCIL_TEST); glStencilFunc(GL_ALWAYS, 0, 0xff); glStencilMask(0xff); @@ -473,15 +520,14 @@ void ZeroGS::CRenderTarget::Update(int context, ZeroGS::CRenderTarget* pdepth) FillOnlyStencilBuffer(); glEnable(GL_SCISSOR_TEST); - if( conf.options & GSOPTION_WIREFRAME ) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - - if( conf.mrtdepth && pdepth != NULL && ZeroGS::IsWriteDepth() ) - pdepth->SetRenderTarget(1); + if (conf.options & GSOPTION_WIREFRAME) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + if (conf.mrtdepth && pdepth != NULL && ZeroGS::IsWriteDepth()) pdepth->SetRenderTarget(1); status = TS_Resolved; // reset since settings changed vb[0].bVarsTexSync = 0; + ZeroGS::ResetAlphaVariables(); } @@ -492,12 +538,15 @@ void ZeroGS::CRenderTarget::ConvertTo32() u32 ptexConv; // ZZLog::Error_Log("Convert to 32, report if something missing."); // create new target - if ( ! InitialiseDefaultTexture ( &ptexConv, RW(fbw), RH(fbh)/2 ) ) { - ZZLog::Error_Log("Failed to create target for ConvertTo32 %dx%d.", RW(fbw), RH(fbh)/2); + + if (! InitialiseDefaultTexture(&ptexConv, RW(fbw), RH(fbh) / 2)) + { + ZZLog::Error_Log("Failed to create target for ConvertTo32 %dx%d.", RW(fbw), RH(fbh) / 2); return; } DisableAllgl(); + SetShaderCaller("CRenderTarget::ConvertTo32"); // tex coords, test ffx bikanel island when changing these @@ -529,11 +578,11 @@ void ZeroGS::CRenderTarget::ConvertTo32() SET_STREAM(); // assume depth already set !? - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_NV, ptexConv, 0 ); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_NV, ptexConv, 0); ZeroGS::ResetRenderTarget(1); - assert( glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT ); + assert(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT); - BindToSample( &ptex ) ; + BindToSample(&ptex) ; cgGLSetTextureParameter(ppsConvert16to32.sFinal, ptex); cgGLEnableTextureParameter(ppsBitBlt[!!s_AAx].sMemory); @@ -541,44 +590,53 @@ void ZeroGS::CRenderTarget::ConvertTo32() fbh /= 2; // have 16 bit surfaces are usually 2x higher SetViewport(); - if( conf.options & GSOPTION_WIREFRAME ) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + if (conf.options & GSOPTION_WIREFRAME) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // render with an AA shader if possible (bilinearly interpolates data) SETVERTEXSHADER(pvsBitBlt.prog); + SETPIXELSHADER(ppsConvert16to32.prog); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); #ifdef _DEBUG - if( g_bSaveZUpdate ) { + if (g_bSaveZUpdate) + { // buggy SaveTexture("tex1.tga", GL_TEXTURE_RECTANGLE_NV, ptex, RW(fbw), RH(fbh)*2); SaveTexture("tex3.tga", GL_TEXTURE_RECTANGLE_NV, ptexConv, RW(fbw), RH(fbh)); } + #endif vposxy.y = -2.0f * (32767.0f / 8.0f) / (float)fbh; - vposxy.w = 1+0.5f/fbh; + vposxy.w = 1 + 0.5f / fbh; // restore SAFE_RELEASE_TEX(ptex); + SAFE_RELEASE_TEX(ptexFeedback); + ptex = ptexConv; // no need to free psys since the render target is getting shrunk - if( conf.options & GSOPTION_WIREFRAME ) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + if (conf.options & GSOPTION_WIREFRAME) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // reset textures - BindToSample ( &ptex ) ; + BindToSample(&ptex) ; glEnable(GL_SCISSOR_TEST); + status = TS_Resolved; // TODO, reset depth? - if( ZeroGS::icurctx >= 0 ) { + if (ZeroGS::icurctx >= 0) + { // reset since settings changed vb[icurctx].bVarsTexSync = 0; vb[icurctx].bVarsSetTarg = 0; } + vb[0].bVarsTexSync = 0; } @@ -590,12 +648,15 @@ void ZeroGS::CRenderTarget::ConvertTo16() // ZZLog::Error_Log("Convert to 16, report if something missing."); // create new target - if ( ! InitialiseDefaultTexture ( &ptexConv, RW(fbw), RH(fbh)*2 ) ) { + + if (! InitialiseDefaultTexture(&ptexConv, RW(fbw), RH(fbh)*2)) + { ZZLog::Error_Log("Failed to create target for ConvertTo16 %dx%d.", RW(fbw), RH(fbh)*2); return; } DisableAllgl(); + SetShaderCaller("CRenderTarget::ConvertTo16"); // tex coords, test ffx bikanel island when changing these @@ -617,7 +678,7 @@ void ZeroGS::CRenderTarget::ConvertTo16() v.x = (float)RW(fbw); v.y = (float)RH(2 * fbh); v.z = 0; - v.w = -0.1f/RH(fbh); + v.w = -0.1f / RH(fbh); ZZcgSetParameter4fv(ppsConvert32to16.fTexDims, v, "g_fTexDims"); glBindBuffer(GL_ARRAY_BUFFER, vboRect); @@ -625,11 +686,11 @@ void ZeroGS::CRenderTarget::ConvertTo16() // assume depth already set !? // assume depth already set !? - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_NV, ptexConv, 0 ); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_NV, ptexConv, 0); ZeroGS::ResetRenderTarget(1); - assert( glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT ); + assert(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT); - BindToSample ( &ptex ) ; + BindToSample(&ptex) ; cgGLSetTextureParameter(ppsConvert32to16.sFinal, ptex); cgGLEnableTextureParameter(ppsConvert32to16.sFinal); @@ -638,45 +699,55 @@ void ZeroGS::CRenderTarget::ConvertTo16() SetViewport(); - if( conf.options & GSOPTION_WIREFRAME ) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + if (conf.options & GSOPTION_WIREFRAME) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // render with an AA shader if possible (bilinearly interpolates data) SETVERTEXSHADER(pvsBitBlt.prog); + SETPIXELSHADER(ppsConvert32to16.prog); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); #ifdef _DEBUG //g_bSaveZUpdate = 1; - if( g_bSaveZUpdate ) { + if (g_bSaveZUpdate) + { SaveTexture("tex1.tga", GL_TEXTURE_RECTANGLE_NV, ptexConv, RW(fbw), RH(fbh)); } + #endif vposxy.y = -2.0f * (32767.0f / 8.0f) / (float)fbh; - vposxy.w = 1+0.5f/fbh; + + vposxy.w = 1 + 0.5f / fbh; // restore SAFE_RELEASE_TEX(ptex); SAFE_RELEASE_TEX(ptexFeedback); + ptex = ptexConv; _aligned_free(psys); - psys = _aligned_malloc( Tex_Memory_Size ( fbw, fbh ), 16 ); - if( conf.options & GSOPTION_WIREFRAME ) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + psys = _aligned_malloc(Tex_Memory_Size(fbw, fbh), 16); + + if (conf.options & GSOPTION_WIREFRAME) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); // reset textures - BindToSample ( &ptex ) ; + BindToSample(&ptex) ; + glEnable(GL_SCISSOR_TEST); status = TS_Resolved; // TODO, reset depth? - if( ZeroGS::icurctx >= 0 ) { + if (ZeroGS::icurctx >= 0) + { // reset since settings changed vb[icurctx].bVarsTexSync = 0; vb[icurctx].bVarsSetTarg = 0; } + vb[0].bVarsTexSync = 0; } @@ -684,24 +755,27 @@ void ZeroGS::CRenderTarget::_CreateFeedback() { FUNCLOG - if( ptexFeedback == 0 ) { + if (ptexFeedback == 0) + { // create - if ( ! InitialiseDefaultTexture( &ptexFeedback, RW(fbw), RH(fbh) ) ) { + if (! InitialiseDefaultTexture(&ptexFeedback, RW(fbw), RH(fbh))) + { ZZLog::Error_Log("Failed to create feedback %dx%d.", RW(fbw), RH(fbh)); return; } } DisableAllgl(); + SetShaderCaller("CRenderTarget::_CreateFeedback"); // assume depth already set ResetRenderTarget(1); // tex coords, test ffx bikanel island when changing these -/* Vector v = DefaultBitBltPos(); - v = Vector ((float)(RW(fbw+4)), (float)(RH(fbh+4)), +0.25f, -0.25f); - ZZcgSetParameter4fv(pvsBitBlt.sBitBltTex, v, "BitBltTex");*/ + /* Vector v = DefaultBitBltPos(); + v = Vector ((float)(RW(fbw+4)), (float)(RH(fbh+4)), +0.25f, -0.25f); + ZZcgSetParameter4fv(pvsBitBlt.sBitBltTex, v, "BitBltTex");*/ // tex coords, test ffx bikanel island when changing these @@ -720,44 +794,47 @@ void ZeroGS::CRenderTarget::_CreateFeedback() glBindBuffer(GL_ARRAY_BUFFER, vboRect); SET_STREAM(); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_NV, ptexFeedback, 0 ); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_NV, ptexFeedback, 0); glBindTexture(GL_TEXTURE_RECTANGLE_NV, ptex); - assert( glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT ); + assert(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT); cgGLSetTextureParameter(ppsBaseTexture.sFinal, ptex); cgGLEnableTextureParameter(ppsBaseTexture.sFinal); SetViewport(); - if( conf.options & GSOPTION_WIREFRAME ) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + if (conf.options & GSOPTION_WIREFRAME) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // render with an AA shader if possible (bilinearly interpolates data) SETVERTEXSHADER(pvsBitBlt.prog); SETPIXELSHADER(ppsBaseTexture.prog); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // restore swap(ptex, ptexFeedback); - if( conf.options & GSOPTION_WIREFRAME ) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + if (conf.options & GSOPTION_WIREFRAME) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); glEnable(GL_SCISSOR_TEST); + status |= TS_FeedbackReady; // TODO, reset depth? - if( ZeroGS::icurctx >= 0 ) { + if (ZeroGS::icurctx >= 0) + { // reset since settings changed vb[icurctx].bVarsTexSync = 0; } - assert( glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT ); + assert(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT); } void ZeroGS::CRenderTarget::SetRenderTarget(int targ) { FUNCLOG - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+targ, GL_TEXTURE_RECTANGLE_NV, ptex, 0 ); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + targ, GL_TEXTURE_RECTANGLE_NV, ptex, 0); // if (glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT) // ERROR_LOG_SPAM("Too bad Framebuffer not compele, glitches could appear onscreen!\n"); @@ -776,34 +853,42 @@ bool ZeroGS::CDepthTarget::Create(const frameInfo& frame) { FUNCLOG - if( !CRenderTarget::Create(frame) ) + if (!CRenderTarget::Create(frame)) return false; GL_REPORT_ERROR(); - glGenRenderbuffersEXT( 1, &pdepth ); + glGenRenderbuffersEXT(1, &pdepth); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, pdepth); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, RW(fbw), RH(fbh)); - if (glGetError() != GL_NO_ERROR) { + if (glGetError() != GL_NO_ERROR) + { // try a separate depth and stencil buffer glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, pdepth); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24, RW(fbw), RH(fbh)); - if (g_bUpdateStencil) { - glGenRenderbuffersEXT( 1, &pstencil ); + if (g_bUpdateStencil) + { + glGenRenderbuffersEXT(1, &pstencil); glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, pstencil); glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_STENCIL_INDEX8_EXT, RW(fbw), RH(fbh)); - if( glGetError() != GL_NO_ERROR ) { + if (glGetError() != GL_NO_ERROR) + { ZZLog::Error_Log("Failed to create depth buffer %dx%d.", RW(fbw), RH(fbh)); return false; } } - else pstencil = 0; + else + { + pstencil = 0; + } } else + { pstencil = pdepth; + } status = TS_NeedUpdate; @@ -814,22 +899,25 @@ void ZeroGS::CDepthTarget::Destroy() { FUNCLOG - if ( status ) { // In this case Framebuffer extension is off-use and lead to segfault + if (status) // In this case Framebuffer extension is off-use and lead to segfault + { ResetRenderTarget(1); - glFramebufferRenderbufferEXT( GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0 ); - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0 ); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0); GL_REPORT_ERRORD(); - if( pstencil != 0 ) { - if( pstencil != pdepth ) - glDeleteRenderbuffersEXT( 1, &pstencil ); - pstencil = 0; + if (pstencil != 0) + { + if (pstencil != pdepth) glDeleteRenderbuffersEXT(1, &pstencil); + pstencil = 0; } - if( pdepth != 0 ) { - glDeleteRenderbuffersEXT( 1, &pdepth ); - pdepth = 0; + if (pdepth != 0) + { + glDeleteRenderbuffersEXT(1, &pdepth); + pdepth = 0; } + GL_REPORT_ERRORD(); } @@ -843,16 +931,18 @@ void ZeroGS::CDepthTarget::Resolve() { FUNCLOG - if( g_nDepthUsed > 0 && conf.mrtdepth && !(status&TS_Virtual) && ZeroGS::IsWriteDepth() && !(g_GameSettings&GAME_NODEPTHRESOLVE) ) + if (g_nDepthUsed > 0 && conf.mrtdepth && !(status&TS_Virtual) && ZeroGS::IsWriteDepth() && !(g_GameSettings&GAME_NODEPTHRESOLVE)) CRenderTarget::Resolve(); - else { + else + { // flush if necessary - FlushIfNecesary ( this ) ; - if( !(status & TS_Virtual) ) - status |= TS_Resolved; + FlushIfNecesary(this) ; + + if (!(status & TS_Virtual)) status |= TS_Resolved; } - if( !(status&TS_Virtual) ) { + if (!(status&TS_Virtual)) + { ZeroGS::SetWriteDepth(); } } @@ -861,16 +951,21 @@ void ZeroGS::CDepthTarget::Resolve(int startrange, int endrange) { FUNCLOG - if( g_nDepthUsed > 0 && conf.mrtdepth && !(status&TS_Virtual) && ZeroGS::IsWriteDepth() ) + if (g_nDepthUsed > 0 && conf.mrtdepth && !(status&TS_Virtual) && ZeroGS::IsWriteDepth()) + { CRenderTarget::Resolve(startrange, endrange); - else { + } + else + { // flush if necessary - FlushIfNecesary ( this ) ; - if( !(status & TS_Virtual) ) + FlushIfNecesary(this) ; + + if (!(status & TS_Virtual)) status |= TS_Resolved; } - if( !(status&TS_Virtual) ) { + if (!(status&TS_Virtual)) + { ZeroGS::SetWriteDepth(); } } @@ -881,7 +976,7 @@ void ZeroGS::CDepthTarget::Update(int context, ZeroGS::CRenderTarget* prndr) { FUNCLOG - assert( !(status & TS_Virtual) ); + assert(!(status & TS_Virtual)); // align the rect to the nearest page // note that fbp is always aligned on page boundaries @@ -893,60 +988,73 @@ void ZeroGS::CDepthTarget::Update(int context, ZeroGS::CRenderTarget* prndr) texframe.psm = psm; CMemoryTarget* pmemtarg = g_MemTargs.GetMemoryTarget(texframe, 1); - DisableAllgl () ; + DisableAllgl(); ZeroGS::VB& curvb = vb[context]; - if (curvb.test.zte == 0) - return; + + if (curvb.test.zte == 0) return; SetShaderCaller("CDepthTarget::Update"); + glEnable(GL_DEPTH_TEST); + glDepthMask(!curvb.zbuf.zmsk); static const u32 g_dwZCmp[] = { GL_NEVER, GL_ALWAYS, GL_GEQUAL, GL_GREATER }; + glDepthFunc(g_dwZCmp[curvb.test.ztst]); // write color and zero out stencil buf, always 0 context! SetTexVariablesInt(0, 0, texframe, pmemtarg, &ppsBitBltDepth, 1); + cgGLSetTextureParameter(ppsBitBltDepth.sMemory, pmemtarg->ptex->tex); cgGLEnableTextureParameter(ppsBaseTexture.sFinal); Vector v = DefaultBitBltPos() ; + v = DefaultBitBltTex() ; v.x = 1; v.y = 2; - v.z = PSMT_IS16Z(psm)?1.0f:0.0f; + v.z = PSMT_IS16Z(psm) ? 1.0f : 0.0f; v.w = g_filog32; ZZcgSetParameter4fv(ppsBitBltDepth.sOneColor, v, "g_fOneColor"); Vector vdepth = g_vdepth; + if (psm == PSMT24Z) + { vdepth.w = 0; - else if (psm != PSMT32Z) { + } + else if (psm != PSMT32Z) + { vdepth.z = vdepth.w = 0; } - assert( ppsBitBltDepth.sBitBltZ != 0 ); - ZZcgSetParameter4fv(ppsBitBltDepth.sBitBltZ, ((255.0f/256.0f)*vdepth), "g_fBitBltZ"); + assert(ppsBitBltDepth.sBitBltZ != 0); - assert( pdepth != 0 ); + ZZcgSetParameter4fv(ppsBitBltDepth.sBitBltZ, ((255.0f / 256.0f)*vdepth), "g_fBitBltZ"); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_NV, ptex, 0 ); + assert(pdepth != 0); + + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_NV, ptex, 0); SetDepthStencilSurface(); - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_NV, 0, 0 ); + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_NV, 0, 0); GLenum buffer = GL_COLOR_ATTACHMENT0_EXT; - if( glDrawBuffers != NULL ) - glDrawBuffers(1, &buffer); + + if (glDrawBuffers != NULL) glDrawBuffers(1, &buffer); + int stat = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - assert( glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT ); + + assert(glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT) == GL_FRAMEBUFFER_COMPLETE_EXT); SetViewport(); - if( conf.options & GSOPTION_WIREFRAME ) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + + if (conf.options & GSOPTION_WIREFRAME) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glBindBuffer(GL_ARRAY_BUFFER, vboRect); - SET_STREAM(); + SET_STREAM(); SETVERTEXSHADER(pvsBitBlt.prog); SETPIXELSHADER(ppsBitBltDepth.prog); @@ -954,15 +1062,18 @@ void ZeroGS::CDepthTarget::Update(int context, ZeroGS::CRenderTarget* prndr) status = TS_Resolved; - if( !ZeroGS::IsWriteDepth() ) { + if (!ZeroGS::IsWriteDepth()) + { ResetRenderTarget(1); } - if( conf.options & GSOPTION_WIREFRAME ) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + if (conf.options & GSOPTION_WIREFRAME) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + glEnable(GL_SCISSOR_TEST); #ifdef _DEBUG - if( g_bSaveZUpdate ) { + if (g_bSaveZUpdate) + { SaveTex(&texframe, 1); SaveTexture("frame1.tga", GL_TEXTURE_RECTANGLE_NV, ptex, RW(fbw), RH(fbh)); } @@ -972,120 +1083,166 @@ void ZeroGS::CDepthTarget::Update(int context, ZeroGS::CRenderTarget* prndr) void ZeroGS::CDepthTarget::SetDepthStencilSurface() { FUNCLOG - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, pdepth ); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, pdepth); - if( pstencil ) { + if (pstencil) + { // there's a bug with attaching stencil and depth buffers - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, pstencil ); + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, pstencil); - if( icount++ < 8 ) { // not going to fail if succeeded 4 times + if (icount++ < 8) // not going to fail if succeeded 4 times + { GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - if( status != GL_FRAMEBUFFER_COMPLETE_EXT ) { - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0 ); - if( pstencil != pdepth ) + + if (status != GL_FRAMEBUFFER_COMPLETE_EXT) + { + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0); + + if (pstencil != pdepth) glDeleteRenderbuffersEXT(1, &pstencil); + pstencil = 0; + g_bUpdateStencil = 0; } } } else - glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0 ); + { + glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, 0); + } } void ZeroGS::CRenderTargetMngr::Destroy() { FUNCLOG - for(MAPTARGETS::iterator it = mapTargets.begin(); it != mapTargets.end(); ++it) + + for (MAPTARGETS::iterator it = mapTargets.begin(); it != mapTargets.end(); ++it) + { delete it->second; + } + mapTargets.clear(); - for(MAPTARGETS::iterator it = mapDummyTargs.begin(); it != mapDummyTargs.end(); ++it) + + for (MAPTARGETS::iterator it = mapDummyTargs.begin(); it != mapDummyTargs.end(); ++it) + { delete it->second; + } + mapDummyTargs.clear(); } void ZeroGS::CRenderTargetMngr::DestroyAllTargs(int start, int end, int fbw) { FUNCLOG - for(MAPTARGETS::iterator it = mapTargets.begin(); it != mapTargets.end();) { - if( it->second->start < end && start < it->second->end ) { + + for (MAPTARGETS::iterator it = mapTargets.begin(); it != mapTargets.end();) + { + if (it->second->start < end && start < it->second->end) + { // if is depth, only resolve if fbw is the same - if( !it->second->IsDepth() ) { + if (!it->second->IsDepth()) + { // only resolve if the widths are the same or it->second has bit outside the range // shadow of colossus swaps between fbw=256,fbh=256 and fbw=512,fbh=448. This kills the game if doing || it->second->end > end // kh hack, sometimes kh movies do this to clear the target, so have a static count that periodically checks end static int count = 0; - if( it->second->fbw == fbw || (it->second->fbw != fbw && (it->second->start < start || ((count++&0xf)?0:it->second->end > end) )) ) + if (it->second->fbw == fbw || (it->second->fbw != fbw && (it->second->start < start || ((count++&0xf) ? 0 : it->second->end > end)))) + { it->second->Resolve(); - else { - FlushIfNecesary ( it->second ) ; + } + else + { + FlushIfNecesary(it->second) ; it->second->status |= CRenderTarget::TS_Resolved; } } - else { - if( it->second->fbw == fbw ) + else + { + if (it->second->fbw == fbw) + { it->second->Resolve(); - else { - FlushIfNecesary ( it->second ) ; + } + else + { + FlushIfNecesary(it->second) ; it->second->status |= CRenderTarget::TS_Resolved; } } - DestroyAllTargetsHelper( it->second ) ; + DestroyAllTargetsHelper(it->second) ; u32 dummykey = GetFrameKeyDummy(it->second); - if( mapDummyTargs.find(dummykey) == mapDummyTargs.end() ) { + + if (mapDummyTargs.find(dummykey) == mapDummyTargs.end()) + { mapDummyTargs[dummykey] = it->second; } else + { delete it->second; + } + mapTargets.erase(it++); } - else ++it; + else + { + ++it; + } } } void ZeroGS::CRenderTargetMngr::DestroyTarg(CRenderTarget* ptarg) { FUNCLOG - DestroyAllTargetsHelper ( ptarg ) ; + DestroyAllTargetsHelper(ptarg) ; delete ptarg; } void ZeroGS::CRenderTargetMngr::DestroyIntersecting(CRenderTarget* prndr) { FUNCLOG - assert( prndr != NULL ); + assert(prndr != NULL); int start, end; GetRectMemAddress(start, end, prndr->psm, 0, 0, prndr->fbw, prndr->fbh, prndr->fbp, prndr->fbw); - for(MAPTARGETS::iterator it = mapTargets.begin(); it != mapTargets.end();) { - if( it->second != prndr && it->second->start < end && start < it->second->end ) { + for (MAPTARGETS::iterator it = mapTargets.begin(); it != mapTargets.end();) + { + if (it->second != prndr && it->second->start < end && start < it->second->end) + { it->second->Resolve(); - - DestroyAllTargetsHelper( it->second ) ; - + DestroyAllTargetsHelper(it->second) ; u32 dummykey = GetFrameKeyDummy(it->second); - if( mapDummyTargs.find(dummykey) == mapDummyTargs.end() ) { + + if (mapDummyTargs.find(dummykey) == mapDummyTargs.end()) + { mapDummyTargs[dummykey] = it->second; } else + { delete it->second; + } + mapTargets.erase(it++); } - else ++it; + else + { + ++it; + } } } //-------------------------------------------------- -inline bool CheckWidthIsSame (const frameInfo& frame, CRenderTarget* ptarg) { +inline bool CheckWidthIsSame(const frameInfo& frame, CRenderTarget* ptarg) +{ if (PSMT_ISHALF(frame.psm) == PSMT_ISHALF(ptarg->psm)) return (frame.fbw == ptarg->fbw); + if (PSMT_ISHALF(frame.psm)) return (frame.fbw == 2 * ptarg->fbw); else @@ -1095,23 +1252,30 @@ inline bool CheckWidthIsSame (const frameInfo& frame, CRenderTarget* ptarg) { CRenderTarget* ZeroGS::CRenderTargetMngr::GetTarg(const frameInfo& frame, u32 opts, int maxposheight) { FUNCLOG - if( frame.fbw <= 0 || frame.fbh <= 0 ) - return NULL; + + if (frame.fbw <= 0 || frame.fbh <= 0) return NULL; GL_REPORT_ERRORD(); u32 key = GetFrameKey(frame); + MAPTARGETS::iterator it = mapTargets.find(key); // only enforce height if frame.fbh <= 0x1c0 bool bfound = it != mapTargets.end(); - if( bfound ) { - if( opts&TO_StrictHeight ) { + + if (bfound) + { + if (opts&TO_StrictHeight) + { bfound = it->second->fbh == frame.fbh; - if( (g_GameSettings&GAME_PARTIALDEPTH) && !bfound ) { - MAPTARGETS::iterator itnew = mapTargets.find(key+1); - if( itnew != mapTargets.end() && itnew->second->fbh == frame.fbh ) { + if ((g_GameSettings&GAME_PARTIALDEPTH) && !bfound) + { + MAPTARGETS::iterator itnew = mapTargets.find(key + 1); + + if (itnew != mapTargets.end() && itnew->second->fbh == frame.fbh) + { // found! delete the previous and restore delete it->second; mapTargets.erase(it); @@ -1123,40 +1287,51 @@ CRenderTarget* ZeroGS::CRenderTargetMngr::GetTarg(const frameInfo& frame, u32 op } } } - else { - if( PSMT_ISHALF(frame.psm)==PSMT_ISHALF(it->second->psm) && !(g_GameSettings & GAME_FULL16BITRES) ) + else + { + if (PSMT_ISHALF(frame.psm) == PSMT_ISHALF(it->second->psm) && !(g_GameSettings & GAME_FULL16BITRES)) bfound = (frame.fbh > 0x1c0 || it->second->fbh >= frame.fbh) && it->second->fbh <= maxposheight; } } - if( !bfound ) { + if (!bfound) + { // might be a virtual target - it = mapTargets.find(key|TARGET_VIRTUAL_KEY); - bfound = it != mapTargets.end() && ((opts&TO_StrictHeight) ? it->second->fbh == frame.fbh : it->second->fbh >= frame.fbh) && it->second->fbh <= maxposheight; + it = mapTargets.find(key | TARGET_VIRTUAL_KEY); + bfound = it != mapTargets.end() && ((opts & TO_StrictHeight) ? it->second->fbh == frame.fbh : it->second->fbh >= frame.fbh) && it->second->fbh <= maxposheight; } - if( bfound && PSMT_ISHALF(frame.psm) && PSMT_ISHALF(it->second->psm) && (g_GameSettings&GAME_FULL16BITRES) ) { + if (bfound && PSMT_ISHALF(frame.psm) && PSMT_ISHALF(it->second->psm) && (g_GameSettings&GAME_FULL16BITRES)) + { // mgs3 - if( frame.fbh > it->second->fbh ) { + if (frame.fbh > it->second->fbh) + { bfound = false; } } - if( bfound ) { + if (bfound) + { // can be both 16bit and 32bit - if( PSMT_ISHALF(frame.psm) != PSMT_ISHALF(it->second->psm) ) { + if (PSMT_ISHALF(frame.psm) != PSMT_ISHALF(it->second->psm)) + { // a lot of games do this, actually... ZZLog::Debug_Log("Really bad formats! %d %d", frame.psm, it->second->psm); // This code SHOULD be commented, until I redo the _Resolve function - if( !(opts&TO_StrictHeight) ) { - if( (g_GameSettings & GAME_VSSHACKOFF) ) { - if (PSMT_ISHALF(it->second->psm)) { + + if (!(opts & TO_StrictHeight)) + { + if ((g_GameSettings & GAME_VSSHACKOFF)) + { + if (PSMT_ISHALF(it->second->psm)) + { it->second->status |= CRenderTarget::TS_NeedConvert32; it->second->fbh /= 2; } - else { + else + { it->second->status |= CRenderTarget::TS_NeedConvert16; it->second->fbh *= 2; } @@ -1166,9 +1341,11 @@ CRenderTarget* ZeroGS::CRenderTargetMngr::GetTarg(const frameInfo& frame, u32 op // recalc extents GetRectMemAddress(it->second->start, it->second->end, frame.psm, 0, 0, frame.fbw, it->second->fbh, it->second->fbp, frame.fbw); } - else { + else + { // certain variables have to be reset every time - if( (it->second->psm&~1) != (frame.psm&~1) ) { + if ((it->second->psm & ~1) != (frame.psm & ~1)) + { #if defined(ZEROGS_DEVBUILD) ZZLog::Warn_Log("Bad formats 2: %d %d", frame.psm, it->second->psm); #endif @@ -1179,14 +1356,16 @@ CRenderTarget* ZeroGS::CRenderTargetMngr::GetTarg(const frameInfo& frame, u32 op } } - if( it->second->fbm != frame.fbm ) { + if (it->second->fbm != frame.fbm) + { //ZZLog::Warn_Log("Bad fbm: 0x%8.8x 0x%8.8x, psm: %d", frame.fbm, it->second->fbm, frame.psm); } it->second->fbm &= frame.fbm; it->second->psm = frame.psm; // have to convert (ffx2) - if( (it->first & TARGET_VIRTUAL_KEY) && !(opts&TO_Virtual) ) { + if ((it->first & TARGET_VIRTUAL_KEY) && !(opts&TO_Virtual)) + { // switch it->second->lastused = timeGetTime(); return Promote(it->first&~TARGET_VIRTUAL_KEY); @@ -1194,21 +1373,25 @@ CRenderTarget* ZeroGS::CRenderTargetMngr::GetTarg(const frameInfo& frame, u32 op // check if there exists a more recent target that this target could update from // only update if target isn't mirrored - bool bCheckHalfCovering = (g_GameSettings&GAME_FULL16BITRES) && PSMT_ISHALF(it->second->psm) && it->second->fbh +32 < frame.fbh; + bool bCheckHalfCovering = (g_GameSettings & GAME_FULL16BITRES) && PSMT_ISHALF(it->second->psm) && it->second->fbh + 32 < frame.fbh; - for(MAPTARGETS::iterator itnew = mapTargets.begin(); itnew != mapTargets.end(); ++itnew) { - if( itnew->second != it->second && itnew->second->ptex != it->second->ptex && itnew->second->ptexFeedback != it->second->ptex && - itnew->second->lastused > it->second->lastused && !(itnew->second->status & CRenderTarget::TS_NeedUpdate) ) { + for (MAPTARGETS::iterator itnew = mapTargets.begin(); itnew != mapTargets.end(); ++itnew) + { + if (itnew->second != it->second && itnew->second->ptex != it->second->ptex && itnew->second->ptexFeedback != it->second->ptex && + itnew->second->lastused > it->second->lastused && !(itnew->second->status & CRenderTarget::TS_NeedUpdate)) + { // if new target totally encompasses the current one - if( itnew->second->start <= it->second->start && itnew->second->end >= it->second->end ) { + if (itnew->second->start <= it->second->start && itnew->second->end >= it->second->end) + { it->second->status |= CRenderTarget::TS_NeedUpdate; it->second->nUpdateTarg = itnew->first; break; } // if 16bit, then check for half encompassing targets - if( bCheckHalfCovering && itnew->second->start > it->second->start && itnew->second->start < it->second->end && itnew->second->end <= it->second->end+0x2000 ) { + if (bCheckHalfCovering && itnew->second->start > it->second->start && itnew->second->start < it->second->end && itnew->second->end <= it->second->end + 0x2000) + { it->second->status |= CRenderTarget::TS_NeedUpdate; it->second->nUpdateTarg = itnew->first; break; @@ -1230,49 +1413,58 @@ CRenderTarget* ZeroGS::CRenderTargetMngr::GetTarg(const frameInfo& frame, u32 op // have to change, so recreate (find all intersecting targets and Resolve) u32 besttarg = 0; - if( !(opts & CRenderTargetMngr::TO_Virtual) ) { + if (!(opts & CRenderTargetMngr::TO_Virtual)) + { int start, end; GetRectMemAddress(start, end, frame.psm, 0, 0, frame.fbw, frame.fbh, frame.fbp, frame.fbw); CRenderTarget* pbesttarg = NULL; - if( besttarg == 0 ) { + if (besttarg == 0) + { // if there is only one intersecting target and it encompasses the current one, update the new render target with // its data instead of resolving then updating (ffx2). Do not change the original target. - for(MAPTARGETS::iterator it = mapTargets.begin(); it != mapTargets.end(); ++it) { - if( it->second->start < end && start < it->second->end ) { - if ((g_GameSettings&GAME_FASTUPDATE) || + for (MAPTARGETS::iterator it = mapTargets.begin(); it != mapTargets.end(); ++it) + { + if (it->second->start < end && start < it->second->end) + { + if ((g_GameSettings&GAME_FASTUPDATE) || ((frame.fbw == it->second->fbw) && - // check depth targets only if partialdepth option - ((it->second->fbp != frame.fbp) || ((g_GameSettings & GAME_PARTIALDEPTH) && (opts & CRenderTargetMngr::TO_DepthBuffer))))) + // check depth targets only if partialdepth option + ((it->second->fbp != frame.fbp) || ((g_GameSettings & GAME_PARTIALDEPTH) && (opts & CRenderTargetMngr::TO_DepthBuffer))))) + { + if (besttarg != 0) { - if( besttarg != 0 ) { - besttarg = 0; - break; - } - - if( start >= it->second->start && end <= it->second->end ) { - besttarg = it->first; - pbesttarg = it->second; - } + besttarg = 0; + break; } + + if (start >= it->second->start && end <= it->second->end) + { + besttarg = it->first; + pbesttarg = it->second; + } + } } } } - if (besttarg != 0 && pbesttarg->fbw != frame.fbw) { + if (besttarg != 0 && pbesttarg->fbw != frame.fbw) + { // printf ("A %d %d %d %d\n", frame.psm, frame.fbw, pbesttarg->psm, pbesttarg->fbw); vb[0].frame.fbw = pbesttarg->fbw; // Something should be here, but what? } - if( besttarg == 0 ) { + if (besttarg == 0) + { // if none found, resolve all DestroyAllTargs(start, end, frame.fbw); } - else if( key == besttarg && pbesttarg != NULL ) { + else if (key == besttarg && pbesttarg != NULL) + { // add one and store in a different location until best targ is processed mapTargets.erase(besttarg); besttarg++; @@ -1280,22 +1472,27 @@ CRenderTarget* ZeroGS::CRenderTargetMngr::GetTarg(const frameInfo& frame, u32 op } } - if( mapTargets.size() > 8 ) { + if (mapTargets.size() > 8) + { // release some resources it = GetOldestTarg(mapTargets); // if more than 5s passed since target used, destroy - if( it->second != vb[0].prndr && it->second != vb[1].prndr && it->second != vb[0].pdepth && it->second != vb[1].pdepth && - timeGetTime()-it->second->lastused > 5000 ) { + + if (it->second != vb[0].prndr && it->second != vb[1].prndr && it->second != vb[0].pdepth && it->second != vb[1].pdepth && + timeGetTime() - it->second->lastused > 5000) + { delete it->second; mapTargets.erase(it); } } - if( ptarg == NULL ) { + if (ptarg == NULL) + { // not found yet, so create - if( mapDummyTargs.size() > 8 ) { + if (mapDummyTargs.size() > 8) + { it = GetOldestTarg(mapDummyTargs); delete it->second; @@ -1304,69 +1501,86 @@ CRenderTarget* ZeroGS::CRenderTargetMngr::GetTarg(const frameInfo& frame, u32 op it = mapDummyTargs.find(GetFrameKeyDummy(frame)); - if (it != mapDummyTargs.end()) { + if (it != mapDummyTargs.end()) + { #ifdef DEBUG - printf ("A %x %x %x %x\n", frame.fbw, frame.fbh, frame.psm, frame.fbp); - for(MAPTARGETS::iterator it1 = mapDummyTargs.begin(); it1 != mapDummyTargs.end(); ++it1) - printf ("\t %x %x %x %x\n", it1->second->fbw, it1->second->fbh, it1->second->psm, it1->second->fbp); - for(MAPTARGETS::iterator it1 = mapTargets.begin(); it1 != mapTargets.end(); ++it1) - printf ("\t ! %x %x %x %x\n", it1->second->fbw, it1->second->fbh, it1->second->psm, it1->second->fbp); - printf ("\t\t %x %x %x %x\n", it->second->fbw, it->second->fbh, it->second->psm, it->second->fbp); + printf("A %x %x %x %x\n", frame.fbw, frame.fbh, frame.psm, frame.fbp); + + for (MAPTARGETS::iterator it1 = mapDummyTargs.begin(); it1 != mapDummyTargs.end(); ++it1) + printf("\t %x %x %x %x\n", it1->second->fbw, it1->second->fbh, it1->second->psm, it1->second->fbp); + + for (MAPTARGETS::iterator it1 = mapTargets.begin(); it1 != mapTargets.end(); ++it1) + printf("\t ! %x %x %x %x\n", it1->second->fbw, it1->second->fbh, it1->second->psm, it1->second->fbp); + + printf("\t\t %x %x %x %x\n", it->second->fbw, it->second->fbh, it->second->psm, it->second->fbp); + #endif ptarg = it->second; + mapDummyTargs.erase(it); // restore all setttings ptarg->psm = frame.psm; ptarg->fbm = frame.fbm; ptarg->fbp = frame.fbp; + GetRectMemAddress(ptarg->start, ptarg->end, frame.psm, 0, 0, frame.fbw, frame.fbh, frame.fbp, frame.fbw); ptarg->status = CRenderTarget::TS_NeedUpdate; } - else { + else + { #ifdef DEBUG - printf ("A %x %x %x %x\n", frame.fbw, frame.fbh, frame.psm, frame.fbp); - for(MAPTARGETS::iterator it1 = mapDummyTargs.begin(); it1 != mapDummyTargs.end(); ++it1) - printf ("\t %x %x %x %x\n", it1->second->fbw, it1->second->fbh, it1->second->psm, it1->second->fbp); - for(MAPTARGETS::iterator it1 = mapTargets.begin(); it1 != mapTargets.end(); ++it1) - printf ("\t ! %x %x %x %x\n", it1->second->fbw, it1->second->fbh, it1->second->psm, it1->second->fbp); + printf("A %x %x %x %x\n", frame.fbw, frame.fbh, frame.psm, frame.fbp); + + for (MAPTARGETS::iterator it1 = mapDummyTargs.begin(); it1 != mapDummyTargs.end(); ++it1) + printf("\t %x %x %x %x\n", it1->second->fbw, it1->second->fbh, it1->second->psm, it1->second->fbp); + + for (MAPTARGETS::iterator it1 = mapTargets.begin(); it1 != mapTargets.end(); ++it1) + printf("\t ! %x %x %x %x\n", it1->second->fbw, it1->second->fbh, it1->second->psm, it1->second->fbp); + #endif // create anew - ptarg = (opts&TO_DepthBuffer) ? new CDepthTarget : new CRenderTarget; + ptarg = (opts & TO_DepthBuffer) ? new CDepthTarget : new CRenderTarget; CRenderTargetMngr* pmngrs[2] = { &s_DepthRTs, this == &s_RTs ? &s_RTs : NULL }; int cur = 0; - while( !ptarg->Create(frame) ) { + while (!ptarg->Create(frame)) + { // destroy unused targets - if( mapDummyTargs.size() > 0 ) { + if (mapDummyTargs.size() > 0) + { it = mapDummyTargs.begin(); delete it->second; mapDummyTargs.erase(it); continue; } - if( g_MemTargs.listClearedTargets.size() > 0 ) { + if (g_MemTargs.listClearedTargets.size() > 0) + { g_MemTargs.DestroyCleared(); continue; } - else - if( g_MemTargs.listTargets.size() > 32 ) { - g_MemTargs.DestroyOldest(); - continue; - } + else if (g_MemTargs.listTargets.size() > 32) + { + g_MemTargs.DestroyOldest(); + continue; + } - if( pmngrs[cur] == NULL ) { + if (pmngrs[cur] == NULL) + { cur = !cur; - if( pmngrs[cur] == NULL ) { + + if (pmngrs[cur] == NULL) + { ZZLog::Warn_Log("Out of memory!"); delete ptarg; return NULL; } } - if( pmngrs[cur]->mapTargets.size() == 0 ) + if (pmngrs[cur]->mapTargets.size() == 0) { pmngrs[cur] = NULL; cur = !cur; @@ -1382,11 +1596,13 @@ CRenderTarget* ZeroGS::CRenderTargetMngr::GetTarg(const frameInfo& frame, u32 op } } - if( (opts & CRenderTargetMngr::TO_Virtual) ) { + if ((opts & CRenderTargetMngr::TO_Virtual)) + { ptarg->status = CRenderTarget::TS_Virtual; key |= TARGET_VIRTUAL_KEY; - if( (it = mapTargets.find(key)) != mapTargets.end() ) { + if ((it = mapTargets.find(key)) != mapTargets.end()) + { DestroyTarg(it->second); it->second = ptarg; @@ -1395,25 +1611,34 @@ CRenderTarget* ZeroGS::CRenderTargetMngr::GetTarg(const frameInfo& frame, u32 op } } else - assert( mapTargets.find(key) == mapTargets.end()); + { + assert(mapTargets.find(key) == mapTargets.end()); + } ptarg->nUpdateTarg = besttarg; + mapTargets[key] = ptarg; + return ptarg; } ZeroGS::CRenderTargetMngr::MAPTARGETS::iterator ZeroGS::CRenderTargetMngr::GetOldestTarg(MAPTARGETS& m) { FUNCLOG - if( m.size() == 0 ) { + + if (m.size() == 0) + { return m.end(); } // release some resources u32 curtime = timeGetTime(); + MAPTARGETS::iterator itmaxtarg = m.begin(); - for(MAPTARGETS::iterator it = ++m.begin(); it != m.end(); ++it) { - if( itmaxtarg->second->lastused-curtime < it->second->lastused-curtime ) itmaxtarg = it; + + for (MAPTARGETS::iterator it = ++m.begin(); it != m.end(); ++it) + { + if (itmaxtarg->second->lastused - curtime < it->second->lastused - curtime) itmaxtarg = it; } return itmaxtarg; @@ -1422,16 +1647,20 @@ ZeroGS::CRenderTargetMngr::MAPTARGETS::iterator ZeroGS::CRenderTargetMngr::GetOl void ZeroGS::CRenderTargetMngr::GetTargs(int start, int end, list& listTargets) const { FUNCLOG - for(MAPTARGETS::const_iterator it = mapTargets.begin(); it != mapTargets.end(); ++it) { - if( it->second->start < end && start < it->second->end ) listTargets.push_back(it->second); + + for (MAPTARGETS::const_iterator it = mapTargets.begin(); it != mapTargets.end(); ++it) + { + if (it->second->start < end && start < it->second->end) listTargets.push_back(it->second); } } void ZeroGS::CRenderTargetMngr::Resolve(int start, int end) { FUNCLOG - for(MAPTARGETS::const_iterator it = mapTargets.begin(); it != mapTargets.end(); ++it) { - if( it->second->start < end && start < it->second->end ) + + for (MAPTARGETS::const_iterator it = mapTargets.begin(); it != mapTargets.end(); ++it) + { + if (it->second->start < end && start < it->second->end) it->second->Resolve(); } } @@ -1446,33 +1675,39 @@ void ZeroGS::CMemoryTargetMngr::Destroy() int memcmp_clut16(u16* pSavedBuffer, u16* pClutBuffer, int clutsize) { FUNCLOG - assert( (clutsize&31) == 0 ); + assert((clutsize&31) == 0); // left > 0 only when csa < 16 - int left = ((u32)(uptr)pClutBuffer & 2) ? 0 : (((u32)(uptr)pClutBuffer & 0x3ff)/2) + clutsize - 512; - if( left > 0 ) clutsize -= left; + int left = ((u32)(uptr)pClutBuffer & 2) ? 0 : (((u32)(uptr)pClutBuffer & 0x3ff) / 2) + clutsize - 512; - while(clutsize > 0) { - for(int i = 0; i < 16; ++i) { - if( pSavedBuffer[i] != pClutBuffer[2*i] ) - return 1; + if (left > 0) clutsize -= left; + + while (clutsize > 0) + { + for (int i = 0; i < 16; ++i) + { + if (pSavedBuffer[i] != pClutBuffer[2*i]) return 1; } clutsize -= 32; + pSavedBuffer += 16; pClutBuffer += 32; } - if( left > 0 ) { + if (left > 0) + { pClutBuffer = (u16*)(g_pbyGSClut + 2); - while(left > 0) { - for(int i = 0; i < 16; ++i) { - if( pSavedBuffer[i] != pClutBuffer[2*i] ) - return 1; + while (left > 0) + { + for (int i = 0; i < 16; ++i) + { + if (pSavedBuffer[i] != pClutBuffer[2*i]) return 1; } left -= 32; + pSavedBuffer += 16; pClutBuffer += 32; } @@ -1484,30 +1719,32 @@ int memcmp_clut16(u16* pSavedBuffer, u16* pClutBuffer, int clutsize) bool ZeroGS::CMemoryTarget::ValidateClut(const tex0Info& tex0) { FUNCLOG - assert( tex0.psm == psm && PSMT_ISCLUT(psm) && cpsm == tex0.cpsm ); + assert(tex0.psm == psm && PSMT_ISCLUT(psm) && cpsm == tex0.cpsm); int nClutOffset = 0; int clutsize = 0; - int entries = PSMT_IS8CLUT(tex0.psm) ? 256 : 16; - if (PSMT_IS32BIT(tex0.cpsm)) { // 32 bit + + if (PSMT_IS32BIT(tex0.cpsm)) // 32 bit + { nClutOffset = 64 * tex0.csa; - clutsize = min(entries, 256-tex0.csa*16)*4; + clutsize = min(entries, 256 - tex0.csa * 16) * 4; } - else { - nClutOffset = 32 * (tex0.csa&15) + (tex0.csa>=16?2:0); - clutsize = min(entries, 512-tex0.csa*16)*2; + else + { + nClutOffset = 32 * (tex0.csa & 15) + (tex0.csa >= 16 ? 2 : 0); + clutsize = min(entries, 512 - tex0.csa * 16) * 2; } - assert( clutsize == clut.size() ); + assert(clutsize == clut.size()); - if( PSMT_IS32BIT(cpsm)) { - if( memcmp_mmx(&clut[0], g_pbyGSClut+nClutOffset, clutsize) ) - return false; + if (PSMT_IS32BIT(cpsm)) + { + if (memcmp_mmx(&clut[0], g_pbyGSClut + nClutOffset, clutsize)) return false; } - else { - if( memcmp_clut16((u16*)&clut[0], (u16*)(g_pbyGSClut+nClutOffset), clutsize) ) - return false; + else + { + if (memcmp_clut16((u16*)&clut[0], (u16*)(g_pbyGSClut + nClutOffset), clutsize)) return false; } return true; @@ -1519,50 +1756,59 @@ u32 TEXDESTROY_THRESH = 16; bool ZeroGS::CMemoryTarget::ValidateTex(const tex0Info& tex0, int starttex, int endtex, bool bDeleteBadTex) { FUNCLOG - if( clearmaxy == 0 ) + + if (clearmaxy == 0) return true; int checkstarty = max(starttex, clearminy); int checkendy = min(endtex, clearmaxy); - if( checkstarty >= checkendy ) - return true; - if( validatecount++ > VALIDATE_THRESH ) { + if (checkstarty >= checkendy) return true; + + if (validatecount++ > VALIDATE_THRESH) + { height = 0; return false; } // lock and compare - assert( ptex != NULL && ptex->memptr != NULL); + assert(ptex != NULL && ptex->memptr != NULL); - int result = memcmp_mmx(ptex->memptr + (checkstarty-realy)*4*GPU_TEXWIDTH, g_pbyGSMemory+checkstarty*4*GPU_TEXWIDTH, (checkendy-checkstarty)*4*GPU_TEXWIDTH); + int result = memcmp_mmx(ptex->memptr + (checkstarty - realy) * 4 * GPU_TEXWIDTH, g_pbyGSMemory + checkstarty * 4 * GPU_TEXWIDTH, (checkendy - checkstarty) * 4 * GPU_TEXWIDTH); + + if (result == 0 || !bDeleteBadTex) + { + if (result == 0) clearmaxy = 0; - if( result == 0 || !bDeleteBadTex ) { - if( result == 0 ) clearmaxy = 0; return result == 0; } // delete clearminy, clearmaxy range (not the checkstarty, checkendy range) //int newstarty = 0; - if( clearminy <= starty ) { - if( clearmaxy < starty + height) { + if (clearminy <= starty) + { + if (clearmaxy < starty + height) + { // preserve end height = starty + height - clearmaxy; starty = clearmaxy; assert(height > 0); } - else { + else + { // destroy height = 0; } } - else { + else + { // beginning can be preserved - height = clearminy-starty; + height = clearminy - starty; } clearmaxy = 0; - assert( starty >= realy && starty+height<=realy+realheight ); + + assert(starty >= realy && starty + height <= realy + realheight); return false; } @@ -1571,12 +1817,12 @@ bool ZeroGS::CMemoryTarget::ValidateTex(const tex0Info& tex0, int starttex, int template static __forceinline void BuildClut(u32 psm, u32 height, T* pclut, u8* psrc, T* pdst) { - switch(psm) + switch (psm) { case PSMT8: - for(u32 i = 0; i < height; ++i) + for (u32 i = 0; i < height; ++i) { - for(int j = 0; j < GPU_TEXWIDTH/2; ++j) + for (int j = 0; j < GPU_TEXWIDTH / 2; ++j) { pdst[0] = pclut[psrc[0]]; pdst[1] = pclut[psrc[1]]; @@ -1593,18 +1839,18 @@ static __forceinline void BuildClut(u32 psm, u32 height, T* pclut, u8* psrc, T* break; case PSMT4: - for(u32 i = 0; i < height; ++i) + for (u32 i = 0; i < height; ++i) { - for(int j = 0; j < GPU_TEXWIDTH; ++j) + for (int j = 0; j < GPU_TEXWIDTH; ++j) { - pdst[0] = pclut[psrc[0]&15]; - pdst[1] = pclut[psrc[0]>>4]; - pdst[2] = pclut[psrc[1]&15]; - pdst[3] = pclut[psrc[1]>>4]; - pdst[4] = pclut[psrc[2]&15]; - pdst[5] = pclut[psrc[2]>>4]; - pdst[6] = pclut[psrc[3]&15]; - pdst[7] = pclut[psrc[3]>>4]; + pdst[0] = pclut[psrc[0] & 15]; + pdst[1] = pclut[psrc[0] >> 4]; + pdst[2] = pclut[psrc[1] & 15]; + pdst[3] = pclut[psrc[1] >> 4]; + pdst[4] = pclut[psrc[2] & 15]; + pdst[5] = pclut[psrc[2] >> 4]; + pdst[6] = pclut[psrc[3] & 15]; + pdst[7] = pclut[psrc[3] >> 4]; pdst += 8; psrc += 4; @@ -1613,9 +1859,9 @@ static __forceinline void BuildClut(u32 psm, u32 height, T* pclut, u8* psrc, T* break; case PSMT8H: - for(u32 i = 0; i < height; ++i) + for (u32 i = 0; i < height; ++i) { - for(int j = 0; j < GPU_TEXWIDTH/8; ++j) + for (int j = 0; j < GPU_TEXWIDTH / 8; ++j) { pdst[0] = pclut[psrc[3]]; pdst[1] = pclut[psrc[7]]; @@ -1632,18 +1878,18 @@ static __forceinline void BuildClut(u32 psm, u32 height, T* pclut, u8* psrc, T* break; case PSMT4HH: - for(u32 i = 0; i < height; ++i) + for (u32 i = 0; i < height; ++i) { - for(int j = 0; j < GPU_TEXWIDTH/8; ++j) + for (int j = 0; j < GPU_TEXWIDTH / 8; ++j) { - pdst[0] = pclut[psrc[3]>>4]; - pdst[1] = pclut[psrc[7]>>4]; - pdst[2] = pclut[psrc[11]>>4]; - pdst[3] = pclut[psrc[15]>>4]; - pdst[4] = pclut[psrc[19]>>4]; - pdst[5] = pclut[psrc[23]>>4]; - pdst[6] = pclut[psrc[27]>>4]; - pdst[7] = pclut[psrc[31]>>4]; + pdst[0] = pclut[psrc[3] >> 4]; + pdst[1] = pclut[psrc[7] >> 4]; + pdst[2] = pclut[psrc[11] >> 4]; + pdst[3] = pclut[psrc[15] >> 4]; + pdst[4] = pclut[psrc[19] >> 4]; + pdst[5] = pclut[psrc[23] >> 4]; + pdst[6] = pclut[psrc[27] >> 4]; + pdst[7] = pclut[psrc[31] >> 4]; pdst += 8; psrc += 32; } @@ -1651,18 +1897,18 @@ static __forceinline void BuildClut(u32 psm, u32 height, T* pclut, u8* psrc, T* break; case PSMT4HL: - for(u32 i = 0; i < height; ++i) + for (u32 i = 0; i < height; ++i) { - for(int j = 0; j < GPU_TEXWIDTH/8; ++j) + for (int j = 0; j < GPU_TEXWIDTH / 8; ++j) { - pdst[0] = pclut[psrc[3]&15]; - pdst[1] = pclut[psrc[7]&15]; - pdst[2] = pclut[psrc[11]&15]; - pdst[3] = pclut[psrc[15]&15]; - pdst[4] = pclut[psrc[19]&15]; - pdst[5] = pclut[psrc[23]&15]; - pdst[6] = pclut[psrc[27]&15]; - pdst[7] = pclut[psrc[31]&15]; + pdst[0] = pclut[psrc[3] & 15]; + pdst[1] = pclut[psrc[7] & 15]; + pdst[2] = pclut[psrc[11] & 15]; + pdst[3] = pclut[psrc[15] & 15]; + pdst[4] = pclut[psrc[19] & 15]; + pdst[5] = pclut[psrc[23] & 15]; + pdst[6] = pclut[psrc[27] & 15]; + pdst[7] = pclut[psrc[31] & 15]; pdst += 8; psrc += 32; } @@ -1682,125 +1928,162 @@ extern int g_MaxTexWidth, g_MaxTexHeight; inline list::iterator ZeroGS::CMemoryTargetMngr::DestroyTargetIter(list::iterator& it) { // find the target and destroy - list::iterator itprev = it; ++it; + list::iterator itprev = it; + ++it; listClearedTargets.splice(listClearedTargets.end(), listTargets, itprev); - if( listClearedTargets.size() > TEXDESTROY_THRESH ) { + if (listClearedTargets.size() > TEXDESTROY_THRESH) + { listClearedTargets.pop_front(); } return it; } -int MemoryTarget_CompareTarget (list::iterator& it, const tex0Info& tex0, int clutsize, int nClutOffset) { - if( PSMT_ISCLUT(it->psm) != PSMT_ISCLUT(tex0.psm) ) { +int MemoryTarget_CompareTarget(list::iterator& it, const tex0Info& tex0, int clutsize, int nClutOffset) +{ + if (PSMT_ISCLUT(it->psm) != PSMT_ISCLUT(tex0.psm)) + { return 1; } - if( PSMT_ISCLUT(tex0.psm) ) { - assert( it->clut.size() > 0 ); + if (PSMT_ISCLUT(tex0.psm)) + { + assert(it->clut.size() > 0); - if( it->psm != tex0.psm || it->cpsm != tex0.cpsm || it->clut.size() != clutsize ) { + if (it->psm != tex0.psm || it->cpsm != tex0.cpsm || it->clut.size() != clutsize) + { return 1; } - if (PSMT_IS32BIT(tex0.cpsm)) { - if (memcmp_mmx(&it->clut[0], g_pbyGSClut+nClutOffset, clutsize)) { + if (PSMT_IS32BIT(tex0.cpsm)) + { + if (memcmp_mmx(&it->clut[0], g_pbyGSClut + nClutOffset, clutsize)) + { return 2; } } - else { - if (memcmp_clut16((u16*)&it->clut[0], (u16*)(g_pbyGSClut+nClutOffset), clutsize)) { + else + { + if (memcmp_clut16((u16*)&it->clut[0], (u16*)(g_pbyGSClut + nClutOffset), clutsize)) + { return 2; } } } else - if ( PSMT_IS16BIT(tex0.psm) != PSMT_IS16BIT(it->psm) ) { + if (PSMT_IS16BIT(tex0.psm) != PSMT_IS16BIT(it->psm)) + { return 1; } + return 0; } -void MemoryTarget_GetClutVariables (int& nClutOffset, int& clutsize, const tex0Info& tex0) { +void MemoryTarget_GetClutVariables(int& nClutOffset, int& clutsize, const tex0Info& tex0) +{ nClutOffset = 0; clutsize = 0; - if( PSMT_ISCLUT(tex0.psm) ) { + if (PSMT_ISCLUT(tex0.psm)) + { int entries = PSMT_IS8CLUT(tex0.psm) ? 256 : 16; - if (PSMT_IS32BIT(tex0.cpsm)) { + + if (PSMT_IS32BIT(tex0.cpsm)) + { nClutOffset = 64 * tex0.csa; - clutsize = min(entries, 256-tex0.csa*16)*4; + clutsize = min(entries, 256 - tex0.csa * 16) * 4; } - else { - nClutOffset = 64 * (tex0.csa&15) + (tex0.csa>=16?2:0); - clutsize = min(entries, 512-tex0.csa*16)*2; + else + { + nClutOffset = 64 * (tex0.csa & 15) + (tex0.csa >= 16 ? 2 : 0); + clutsize = min(entries, 512 - tex0.csa * 16) * 2; } } } -void MemoryTarget_GetMemAddress(int& start, int& end, const tex0Info& tex0) { +void MemoryTarget_GetMemAddress(int& start, int& end, const tex0Info& tex0) +{ int nbStart, nbEnd; GetRectMemAddress(nbStart, nbEnd, tex0.psm, 0, 0, tex0.tw, tex0.th, tex0.tbp0, tex0.tbw); - assert( nbStart < nbEnd ); + assert(nbStart < nbEnd); nbEnd = min(nbEnd, 0x00400000); - start = nbStart / (4*GPU_TEXWIDTH); - end = (nbEnd + GPU_TEXWIDTH*4 - 1) / (4*GPU_TEXWIDTH); - assert( start < end ); + start = nbStart / (4 * GPU_TEXWIDTH); + end = (nbEnd + GPU_TEXWIDTH * 4 - 1) / (4 * GPU_TEXWIDTH); + assert(start < end); } -ZeroGS::CMemoryTarget* ZeroGS::CMemoryTargetMngr::MemoryTarget_SearchExistTarget (int start, int end, int nClutOffset, int clutsize, const tex0Info& tex0, int forcevalidate) { - for(list::iterator it = listTargets.begin(); it != listTargets.end(); ) { +ZeroGS::CMemoryTarget* ZeroGS::CMemoryTargetMngr::MemoryTarget_SearchExistTarget(int start, int end, int nClutOffset, int clutsize, const tex0Info& tex0, int forcevalidate) +{ + for (list::iterator it = listTargets.begin(); it != listTargets.end();) + { - if( it->starty <= start && it->starty+it->height >= end ) { + if (it->starty <= start && it->starty + it->height >= end) + { - int res = MemoryTarget_CompareTarget (it, tex0, clutsize, nClutOffset); + int res = MemoryTarget_CompareTarget(it, tex0, clutsize, nClutOffset); - if (res == 1) { - if( it->validatecount++ > VALIDATE_THRESH ) { + if (res == 1) + { + if (it->validatecount++ > VALIDATE_THRESH) + { it = DestroyTargetIter(it); - if( listTargets.size() == 0 ) - break; + + if (listTargets.size() == 0) break; } else + { ++it; + } continue; } - else if (res == 2) { + else if (res == 2) + { ++it; continue; } - if( forcevalidate ) {//&& listTargets.size() < TARGET_THRESH ) { + if (forcevalidate) //&& listTargets.size() < TARGET_THRESH ) { + { // do more validation checking. delete if not been used for a while - if( !it->ValidateTex(tex0, start, end, curstamp > it->usedstamp + 3) ) { - if( it->height <= 0 ) { + if (!it->ValidateTex(tex0, start, end, curstamp > it->usedstamp + 3)) + { + + if (it->height <= 0) + { it = DestroyTargetIter(it); - if( listTargets.size() == 0 ) + + if (listTargets.size() == 0) break; } else + { ++it; + } + continue; } } it->usedstamp = curstamp; + it->validatecount = 0; return &(*it); } + #ifdef SORT_TARGETS - else if( it->starty >= end ) - break; + else if (it->starty >= end) break; + #endif ++it; } + return NULL; } @@ -1835,7 +2118,7 @@ ZeroGS::CMemoryTarget* ZeroGS::CMemoryTargetMngr::MemoryTarget_ClearedTargetsSea { list::iterator itbest = listClearedTargets.begin(); - while(itbest != listClearedTargets.end()) + while (itbest != listClearedTargets.end()) { if ((height <= itbest->realheight) && (itbest->fmt == fmt) && (itbest->widthmult == widthmult) && (itbest->channels == channels)) { @@ -1844,6 +2127,7 @@ ZeroGS::CMemoryTarget* ZeroGS::CMemoryTargetMngr::MemoryTarget_ClearedTargetsSea if (targchannels == channels) break; } + ++itbest; } @@ -1874,10 +2158,11 @@ ZeroGS::CMemoryTarget* ZeroGS::CMemoryTargetMngr::GetMemoryTarget(const tex0Info FUNCLOG int start, end, nClutOffset, clutsize; - MemoryTarget_GetClutVariables (nClutOffset, clutsize, tex0); + MemoryTarget_GetClutVariables(nClutOffset, clutsize, tex0); MemoryTarget_GetMemAddress(start, end, tex0); - ZeroGS::CMemoryTarget* it = MemoryTarget_SearchExistTarget (start, end, nClutOffset, clutsize, tex0, forcevalidate); + ZeroGS::CMemoryTarget* it = MemoryTarget_SearchExistTarget(start, end, nClutOffset, clutsize, tex0, forcevalidate); + if (it != NULL) return it; // couldn't find so create @@ -1888,9 +2173,11 @@ ZeroGS::CMemoryTarget* ZeroGS::CMemoryTargetMngr::GetMemoryTarget(const tex0Info if (PSMT_ISHALF_STORAGE(tex0)) fmt = GL_UNSIGNED_SHORT_1_5_5_5_REV; int widthmult = 1; - if ((g_MaxTexHeight < 4096) && (end-start > g_MaxTexHeight)) widthmult = 2; + + if ((g_MaxTexHeight < 4096) && (end - start > g_MaxTexHeight)) widthmult = 2; int channels = 1; + channels = NumberOfChannels(tex0.psm); targ = MemoryTarget_ClearedTargetsSearch(fmt, widthmult, channels, end - start); @@ -1898,7 +2185,7 @@ ZeroGS::CMemoryTarget* ZeroGS::CMemoryTargetMngr::GetMemoryTarget(const tex0Info // fill local clut if (PSMT_ISCLUT(tex0.psm)) { - assert( clutsize > 0 ); + assert(clutsize > 0); targ->cpsm = tex0.cpsm; targ->clut.reserve(256*4); // no matter what @@ -1906,28 +2193,29 @@ ZeroGS::CMemoryTarget* ZeroGS::CMemoryTargetMngr::GetMemoryTarget(const tex0Info if (PSMT_IS32BIT(tex0.cpsm)) { - memcpy_amd(&targ->clut[0], g_pbyGSClut+nClutOffset, clutsize); + memcpy_amd(&targ->clut[0], g_pbyGSClut + nClutOffset, clutsize); } else { u16* pClutBuffer = (u16*)(g_pbyGSClut + nClutOffset); - u16* pclut = (u16*)&targ->clut[0]; - int left = ((u32)nClutOffset & 2) ? 0 : ((nClutOffset&0x3ff)/2)+clutsize-512; - if( left > 0 ) clutsize -= left; + u16* pclut = (u16*) & targ->clut[0]; + int left = ((u32)nClutOffset & 2) ? 0 : ((nClutOffset & 0x3ff) / 2) + clutsize - 512; - while(clutsize > 0) + if (left > 0) clutsize -= left; + + while (clutsize > 0) { pclut[0] = pClutBuffer[0]; pclut++; - pClutBuffer+=2; + pClutBuffer += 2; clutsize -= 2; } - if( left > 0) + if (left > 0) { pClutBuffer = (u16*)(g_pbyGSClut + 2); - while(left > 0) + while (left > 0) { pclut[0] = pClutBuffer[0]; left -= 2; @@ -1938,16 +2226,16 @@ ZeroGS::CMemoryTarget* ZeroGS::CMemoryTargetMngr::GetMemoryTarget(const tex0Info } } - if( targ->ptex != NULL ) + if (targ->ptex != NULL) { - assert( end-start <= targ->realheight && targ->fmt == fmt && targ->widthmult == widthmult ); + assert(end - start <= targ->realheight && targ->fmt == fmt && targ->widthmult == widthmult); // good enough, so init targ->realy = targ->starty = start; targ->usedstamp = curstamp; targ->psm = tex0.psm; targ->cpsm = tex0.cpsm; - targ->height = end-start; + targ->height = end - start; } if (targ->ptex == NULL) @@ -1955,7 +2243,7 @@ ZeroGS::CMemoryTarget* ZeroGS::CMemoryTargetMngr::GetMemoryTarget(const tex0Info // not initialized yet targ->fmt = fmt; targ->realy = targ->starty = start; - targ->realheight = targ->height = end-start; + targ->realheight = targ->height = end - start; targ->usedstamp = curstamp; targ->psm = tex0.psm; targ->cpsm = tex0.cpsm; @@ -1969,36 +2257,38 @@ ZeroGS::CMemoryTarget* ZeroGS::CMemoryTargetMngr::GetMemoryTarget(const tex0Info #if defined(ZEROGS_DEVBUILD) g_TransferredToGPU += GPU_TEXWIDTH * channels * 4 * targ->height; + #endif // fill with data - if( targ->ptex->memptr == NULL ) + if (targ->ptex->memptr == NULL) { targ->ptex->memptr = (u8*)_aligned_malloc(4 * GPU_TEXWIDTH * targ->realheight, 16); - assert(targ->ptex->ref > 0 ); + assert(targ->ptex->ref > 0); } memcpy_amd(targ->ptex->memptr, g_pbyGSMemory + 4 * GPU_TEXWIDTH * targ->realy, 4 * GPU_TEXWIDTH * targ->height); + vector texdata; u8* ptexdata = NULL; if (PSMT_ISCLUT(tex0.psm)) { - texdata.resize( (tex0.cpsm <= 1?4:2) *GPU_TEXWIDTH*channels*widthmult*(targ->realheight+widthmult-1)/widthmult); + texdata.resize((tex0.cpsm <= 1 ? 4 : 2) *GPU_TEXWIDTH*channels*widthmult*(targ->realheight + widthmult - 1) / widthmult); ptexdata = &texdata[0]; u8* psrc = (u8*)(g_pbyGSMemory + 4 * GPU_TEXWIDTH * targ->realy); if (PSMT_IS32BIT(tex0.cpsm)) { - u32* pclut = (u32*)&targ->clut[0]; + u32* pclut = (u32*) & targ->clut[0]; u32* pdst = (u32*)ptexdata; BuildClut(tex0.psm, targ->height, pclut, psrc, pdst); } else { - u16* pclut = (u16*)&targ->clut[0]; + u16* pclut = (u16*) & targ->clut[0]; u16* pdst = (u16*)ptexdata; BuildClut(tex0.psm, targ->height, pclut, psrc, pdst); @@ -2008,12 +2298,12 @@ ZeroGS::CMemoryTarget* ZeroGS::CMemoryTargetMngr::GetMemoryTarget(const tex0Info { if (tex0.psm == PSMT16Z || tex0.psm == PSMT16SZ) { - texdata.resize(4*GPU_TEXWIDTH*channels*widthmult*(targ->realheight+widthmult-1)/widthmult + texdata.resize(4*GPU_TEXWIDTH*channels*widthmult*(targ->realheight + widthmult - 1) / widthmult #if defined(ZEROGS_SSE2) - + 15 // reserve additional elements for alignment if SSE2 used. - // better do it now, so less resizing would be needed + + 15 // reserve additional elements for alignment if SSE2 used. + // better do it now, so less resizing would be needed #endif - ); + ); ptexdata = &texdata[0]; @@ -2022,34 +2312,40 @@ ZeroGS::CMemoryTarget* ZeroGS::CMemoryTargetMngr::GetMemoryTarget(const tex0Info u16* src = (u16*)(g_pbyGSMemory + 4 * GPU_TEXWIDTH * targ->realy); #if defined(ZEROGS_SSE2) - if (((u32)(uptr)dst)%16 != 0) + + if (((u32)(uptr)dst) % 16 != 0) { - // This is not unusual situation, when vector does not 16bit alignment, that is destructive for SSE2 - // instruction movdqa [%eax], xmm0 - // The idea would be resise vector to 15 elements, that set ptxedata to aligned position. - // Later we would move eax by 16, so only we should verify is first element align - // FIXME. As I see, texdata used only once here, it does not have any impact on other code. - // Probably, usage of _aligned_maloc() would be preferable. - int disalignment = 16 - ((u32)(uptr)dst)%16 ; // This is value of shift. It could be 0 < disalignment <= 15 + // This is not unusual situation, when vector does not 16bit alignment, that is destructive for SSE2 + // instruction movdqa [%eax], xmm0 + // The idea would be resise vector to 15 elements, that set ptxedata to aligned position. + // Later we would move eax by 16, so only we should verify is first element align + // FIXME. As I see, texdata used only once here, it does not have any impact on other code. + // Probably, usage of _aligned_maloc() would be preferable. + int disalignment = 16 - ((u32)(uptr)dst) % 16 ; // This is value of shift. It could be 0 < disalignment <= 15 ptexdata = &texdata[disalignment]; // Set pointer to aligned element dst = (u16*)ptexdata; - ZZLog::GS_Log("Made alignment for texdata, 0x%x", dst ); - assert( ((u32)(uptr)dst)%16 == 0 ); // Assert, because at future could be vectors with uncontigious spaces + ZZLog::GS_Log("Made alignment for texdata, 0x%x", dst); + assert(((u32)(uptr)dst) % 16 == 0); // Assert, because at future could be vectors with uncontigious spaces } - int iters = targ->height*GPU_TEXWIDTH/16; - SSE2_UnswizzleZ16Target( dst, src, iters ) ; + int iters = targ->height * GPU_TEXWIDTH / 16; + + SSE2_UnswizzleZ16Target(dst, src, iters) ; #else // ZEROGS_SSE2 - for(int i = 0; i < targ->height; ++i) + + for (int i = 0; i < targ->height; ++i) { - for(int j = 0; j < GPU_TEXWIDTH; ++j) + for (int j = 0; j < GPU_TEXWIDTH; ++j) { - dst[0] = src[0]; dst[1] = 0; - dst[2] = src[1]; dst[3] = 0; + dst[0] = src[0]; + dst[1] = 0; + dst[2] = src[1]; + dst[3] = 0; dst += 4; src += 2; } } + #endif // ZEROGS_SSE2 } else @@ -2060,16 +2356,19 @@ ZeroGS::CMemoryTarget* ZeroGS::CMemoryTargetMngr::GetMemoryTarget(const tex0Info // create the texture GL_REPORT_ERRORD(); + assert(ptexdata != NULL); if (targ->ptex->tex == 0) glGenTextures(1, &targ->ptex->tex); glBindTexture(GL_TEXTURE_RECTANGLE_NV, targ->ptex->tex); - glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, fmt==GL_UNSIGNED_BYTE?4:GL_RGB5_A1, GPU_TEXWIDTH*channels*widthmult, - (targ->realheight+widthmult-1)/widthmult, 0, GL_RGBA, fmt, ptexdata); + + glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, fmt == GL_UNSIGNED_BYTE ? 4 : GL_RGB5_A1, GPU_TEXWIDTH*channels*widthmult, + (targ->realheight + widthmult - 1) / widthmult, 0, GL_RGBA, fmt, ptexdata); int realheight = targ->realheight; - while(glGetError() != GL_NO_ERROR) + + while (glGetError() != GL_NO_ERROR) { // release resources until can create if (listClearedTargets.size() > 0) @@ -2080,21 +2379,23 @@ ZeroGS::CMemoryTarget* ZeroGS::CMemoryTargetMngr::GetMemoryTarget(const tex0Info { if (listTargets.size() == 0) { - ZZLog::Error_Log("Failed to create %dx%x texture.", GPU_TEXWIDTH*channels*widthmult, (realheight+widthmult-1)/widthmult); + ZZLog::Error_Log("Failed to create %dx%x texture.", GPU_TEXWIDTH*channels*widthmult, (realheight + widthmult - 1) / widthmult); channels = 1; return NULL; } + DestroyOldest(); } - glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, 4, GPU_TEXWIDTH*channels*widthmult, (targ->realheight+widthmult-1)/widthmult, 0, GL_RGBA, fmt, ptexdata); + glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, 4, GPU_TEXWIDTH*channels*widthmult, (targ->realheight + widthmult - 1) / widthmult, 0, GL_RGBA, fmt, ptexdata); } glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_RECTANGLE_NV, GL_TEXTURE_WRAP_T, GL_CLAMP); - assert( tex0.psm != 0xd ); - if (PSMT_ISCLUT(tex0.psm)) assert( targ->clut.size() > 0 ); + assert(tex0.psm != 0xd); + + if (PSMT_ISCLUT(tex0.psm)) assert(targ->clut.size() > 0); return targ; } @@ -2102,33 +2403,39 @@ ZeroGS::CMemoryTarget* ZeroGS::CMemoryTargetMngr::GetMemoryTarget(const tex0Info void ZeroGS::CMemoryTargetMngr::ClearRange(int nbStartY, int nbEndY) { FUNCLOG - int starty = nbStartY / (4*GPU_TEXWIDTH); - int endy = (nbEndY+4*GPU_TEXWIDTH-1) / (4*GPU_TEXWIDTH); + int starty = nbStartY / (4 * GPU_TEXWIDTH); + int endy = (nbEndY + 4 * GPU_TEXWIDTH - 1) / (4 * GPU_TEXWIDTH); //int endy = (nbEndY+4096-1) / 4096; //if( listTargets.size() < TARGET_THRESH ) { - for(list::iterator it = listTargets.begin(); it != listTargets.end(); ) { - if( it->starty < endy && (it->starty+it->height) > starty ) { + for (list::iterator it = listTargets.begin(); it != listTargets.end();) + { - // intersects, reduce valid texture mem (or totally delete texture) - // there are 4 cases - int miny = max(it->starty, starty); - int maxy = min(it->starty+it->height, endy); - assert(miny < maxy); + if (it->starty < endy && (it->starty + it->height) > starty) + { - if( it->clearmaxy == 0 ) { - it->clearminy = miny; - it->clearmaxy = maxy; - } - else { - if( it->clearminy > miny ) it->clearminy = miny; - if( it->clearmaxy < maxy ) it->clearmaxy = maxy; - } + // intersects, reduce valid texture mem (or totally delete texture) + // there are 4 cases + int miny = max(it->starty, starty); + int maxy = min(it->starty + it->height, endy); + assert(miny < maxy); + + if (it->clearmaxy == 0) + { + it->clearminy = miny; + it->clearmaxy = maxy; + } + else + { + if (it->clearminy > miny) it->clearminy = miny; + if (it->clearmaxy < maxy) it->clearmaxy = maxy; } - - ++it; } + + ++it; + } + // } // else { // for(list::iterator it = listTargets.begin(); it != listTargets.end(); ) { @@ -2168,8 +2475,11 @@ void ZeroGS::CMemoryTargetMngr::ClearRange(int nbStartY, int nbEndY) void ZeroGS::CMemoryTargetMngr::DestroyCleared() { FUNCLOG - for(list::iterator it = listClearedTargets.begin(); it != listClearedTargets.end(); ) { - if( it->usedstamp < curstamp - 2 ) { + + for (list::iterator it = listClearedTargets.begin(); it != listClearedTargets.end();) + { + if (it->usedstamp < curstamp - 2) + { it = listClearedTargets.erase(it); continue; } @@ -2177,10 +2487,13 @@ void ZeroGS::CMemoryTargetMngr::DestroyCleared() ++it; } - if( (curstamp % 3) == 0 ) { + if ((curstamp % 3) == 0) + { // purge old targets every 3 frames - for(list::iterator it = listTargets.begin(); it != listTargets.end(); ) { - if( it->usedstamp < curstamp - 3 ) { + for (list::iterator it = listTargets.begin(); it != listTargets.end();) + { + if (it->usedstamp < curstamp - 3) + { it = listTargets.erase(it); continue; } @@ -2195,15 +2508,17 @@ void ZeroGS::CMemoryTargetMngr::DestroyCleared() void ZeroGS::CMemoryTargetMngr::DestroyOldest() { FUNCLOG - if( listTargets.size() == 0 ) + + if (listTargets.size() == 0) return; list::iterator it, itbest; + it = itbest = listTargets.begin(); - while(it != listTargets.end()) { - if( it->usedstamp < itbest->usedstamp ) - itbest = it; + while (it != listTargets.end()) + { + if (it->usedstamp < itbest->usedstamp) itbest = it; ++it; } @@ -2216,22 +2531,33 @@ void ZeroGS::CMemoryTargetMngr::DestroyOldest() void ZeroGS::CBitwiseTextureMngr::Destroy() { FUNCLOG - for(map::iterator it = mapTextures.begin(); it != mapTextures.end(); ++it) - glDeleteTextures(1, &it->second); + + for (map::iterator it = mapTextures.begin(); it != mapTextures.end(); ++it) + { + glDeleteTextures(1, &it->second); + } + mapTextures.clear(); } u32 ZeroGS::CBitwiseTextureMngr::GetTexInt(u32 bitvalue, u32 ptexDoNotDelete) { FUNCLOG - if( mapTextures.size() > 32 ) { + + if (mapTextures.size() > 32) + { // randomly delete 8 - for(map::iterator it = mapTextures.begin(); it != mapTextures.end();) { - if( !(rand()&3) && it->second != ptexDoNotDelete) { + for (map::iterator it = mapTextures.begin(); it != mapTextures.end();) + { + if (!(rand()&3) && it->second != ptexDoNotDelete) + { glDeleteTextures(1, &it->second); mapTextures.erase(it++); } - else ++it; + else + { + ++it; + } } } @@ -2239,22 +2565,25 @@ u32 ZeroGS::CBitwiseTextureMngr::GetTexInt(u32 bitvalue, u32 ptexDoNotDelete) // create a new tex u32 ptex; + glGenTextures(1, &ptex); if (glGetError() != GL_NO_ERROR) ZZLog::Error_Log("Error on generation of bitmask texture."); - vector data(GPU_TEXMASKWIDTH+1); - for(u32 i = 0; i < GPU_TEXMASKWIDTH; ++i) - data[i] = (((i << MASKDIVISOR) & bitvalue)<<6); // add the 1/2 offset so that + vector data(GPU_TEXMASKWIDTH + 1); + + for (u32 i = 0; i < GPU_TEXMASKWIDTH; ++i) + { + data[i] = (((i << MASKDIVISOR) & bitvalue) << 6); // add the 1/2 offset so that + } + data[GPU_TEXMASKWIDTH] = 0; glBindTexture(GL_TEXTURE_RECTANGLE_NV, ptex); + if (glGetError() != GL_NO_ERROR) ZZLog::Error_Log("Error on binding bitmask texture."); - if (glGetError() != GL_NO_ERROR ) ZZLog::Error_Log("Error on binding bitmask texture."); - - glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_LUMINANCE16, GPU_TEXMASKWIDTH+1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_SHORT, &data[0]); - - if (glGetError() != GL_NO_ERROR ) ZZLog::Error_Log("Error on applying bitmask texture."); + glTexImage2D(GL_TEXTURE_RECTANGLE_NV, 0, GL_LUMINANCE16, GPU_TEXMASKWIDTH + 1, 1, 0, GL_LUMINANCE, GL_UNSIGNED_SHORT, &data[0]); + if (glGetError() != GL_NO_ERROR) ZZLog::Error_Log("Error on applying bitmask texture."); // Removing clamping, as it seems lead to numerous troubles at some drivers // Need to observe, may be clamping is not really needed. @@ -2277,6 +2606,7 @@ u32 ZeroGS::CBitwiseTextureMngr::GetTexInt(u32 bitvalue, u32 ptexDoNotDelete) }*/ mapTextures[bitvalue] = ptex; + return ptex; } @@ -2284,10 +2614,12 @@ void ZeroGS::CRangeManager::RangeSanityCheck() { #ifdef _DEBUG // sanity check - for(int i = 0; i < (int)ranges.size()-1; ++i) + + for (int i = 0; i < (int)ranges.size() - 1; ++i) { - assert( ranges[i].end < ranges[i+1].start ); + assert(ranges[i].end < ranges[i+1].start); } + #endif } @@ -2298,8 +2630,9 @@ void ZeroGS::CRangeManager::Insert(int start, int end) RangeSanityCheck(); - switch(ranges.size()) + switch (ranges.size()) { + case 0: ranges.push_back(RANGE(start, end)); return; @@ -2323,11 +2656,11 @@ void ZeroGS::CRangeManager::Insert(int start, int end) } // find where start is - while(imin < imax) + while (imin < imax) { - imid = (imin+imax)>>1; + imid = (imin + imax) >> 1; - assert( imid < (int)ranges.size() ); + assert(imid < (int)ranges.size()); if ((ranges[imid].end >= start) && ((imid == 0) || (ranges[imid-1].end < start))) { @@ -2349,10 +2682,11 @@ void ZeroGS::CRangeManager::Insert(int start, int end) if (startindex >= (int)ranges.size()) { // non intersecting - assert( start > ranges.back().end ); + assert(start > ranges.back().end); ranges.push_back(RANGE(start, end)); return; } + if (startindex == 0 && end < ranges.front().start) { ranges.insert(ranges.begin(), RANGE(start, end)); @@ -2364,7 +2698,8 @@ void ZeroGS::CRangeManager::Insert(int start, int end) imax = (int)ranges.size(); // find where end is - while(imin < imax) + + while (imin < imax) { imid = (imin + imax) >> 1; @@ -2401,24 +2736,29 @@ void ZeroGS::CRangeManager::Insert(int start, int end) int lastend = ranges.back().end; int numpop = (int)ranges.size() - startindex - 1; - while(numpop-- > 0 ) + while (numpop-- > 0) { ranges.pop_back(); } - assert( start <= ranges.back().end ); + assert(start <= ranges.back().end); + if (start < ranges.back().start) ranges.back().start = start; if (lastend > ranges.back().end) ranges.back().end = lastend; if (end > ranges.back().end) ranges.back().end = end; + RangeSanityCheck(); + return; } - if( endindex == 0 ) + if (endindex == 0) { - assert( end >= ranges.front().start ); + assert(end >= ranges.front().start); + if (start < ranges.front().start) ranges.front().start = start; if (end > ranges.front().end) ranges.front().end = end; + RangeSanityCheck(); } @@ -2427,7 +2767,7 @@ void ZeroGS::CRangeManager::Insert(int start, int end) if (startindex < endindex) { - ranges.erase(ranges.begin() + startindex, ranges.begin() + endindex ); + ranges.erase(ranges.begin() + startindex, ranges.begin() + endindex); } if (start < ranges[startindex].start) ranges[startindex].start = start; @@ -2436,7 +2776,8 @@ void ZeroGS::CRangeManager::Insert(int start, int end) RangeSanityCheck(); } -namespace ZeroGS { +namespace ZeroGS +{ CRangeManager s_RangeMngr; // manages overwritten memory static int gs_imageEnd = 0; @@ -2445,21 +2786,24 @@ void ResolveInRange(int start, int end) { FUNCLOG list listTargs = CreateTargetsList(start, end); -/* s_DepthRTs.GetTargs(start, end, listTargs); - s_RTs.GetTargs(start, end, listTargs);*/ - if( listTargs.size() > 0 ) { + /* s_DepthRTs.GetTargs(start, end, listTargs); + s_RTs.GetTargs(start, end, listTargs);*/ + + if (listTargs.size() > 0) + { Flush(0); Flush(1); // We need another list, because old one could be brocken by Flush(). listTargs.clear(); listTargs = CreateTargetsList(start, end); -/* s_DepthRTs.GetTargs(start, end, listTargs_1); - s_RTs.GetTargs(start, end, listTargs_1);*/ + /* s_DepthRTs.GetTargs(start, end, listTargs_1); + s_RTs.GetTargs(start, end, listTargs_1);*/ - for(list::iterator it = listTargs.begin(); it != listTargs.end(); ++it) { + for (list::iterator it = listTargs.begin(); it != listTargs.end(); ++it) + { // only resolve if not completely covered - if ((*it)->created == 123 ) + if ((*it)->created == 123) (*it)->Resolve(); else ZZLog::Error_Log("Resolving non-existing object! Destroy code %d.", (*it)->created); @@ -2473,16 +2817,19 @@ void ResolveInRange(int start, int end) void FlushTransferRanges(const tex0Info* ptex) { FUNCLOG - assert( s_RangeMngr.ranges.size() > 0 ); + assert(s_RangeMngr.ranges.size() > 0); //bool bHasFlushed = false; list listTransmissionUpdateTargs; int texstart = -1, texend = -1; - if( ptex != NULL ) { + + if (ptex != NULL) + { GetRectMemAddress(texstart, texend, ptex->psm, 0, 0, ptex->tw, ptex->th, ptex->tbp0, ptex->tbw); } - for(vector::iterator itrange = s_RangeMngr.ranges.begin(); itrange != s_RangeMngr.ranges.end(); ++itrange ) { + for (vector::iterator itrange = s_RangeMngr.ranges.begin(); itrange != s_RangeMngr.ranges.end(); ++itrange) + { int start = itrange->start; int end = itrange->end; @@ -2490,8 +2837,8 @@ void FlushTransferRanges(const tex0Info* ptex) listTransmissionUpdateTargs.clear(); listTransmissionUpdateTargs = CreateTargetsList(start, end); -/* s_DepthRTs.GetTargs(start, end, listTransmissionUpdateTargs); - s_RTs.GetTargs(start, end, listTransmissionUpdateTargs);*/ + /* s_DepthRTs.GetTargs(start, end, listTransmissionUpdateTargs); + s_RTs.GetTargs(start, end, listTransmissionUpdateTargs);*/ // if( !bHasFlushed && listTransmissionUpdateTargs.size() > 0 ) { // Flush(0); @@ -2520,33 +2867,38 @@ void FlushTransferRanges(const tex0Info* ptex) //#endif // } - for(list::iterator it = listTransmissionUpdateTargs.begin(); it != listTransmissionUpdateTargs.end(); ++it) { + for (list::iterator it = listTransmissionUpdateTargs.begin(); it != listTransmissionUpdateTargs.end(); ++it) + { CRenderTarget* ptarg = *it; - if( (ptarg->status & CRenderTarget::TS_Virtual) ) - continue; + if ((ptarg->status & CRenderTarget::TS_Virtual)) continue; - if( !(ptarg->start < texend && ptarg->end > texstart) ) { - // chekc if target is currently being used + if (!(ptarg->start < texend && ptarg->end > texstart)) + { + // check if target is currently being used - if( !(g_GameSettings & GAME_NOQUICKRESOLVE) ) { - if( ptarg->fbp != vb[0].gsfb.fbp ) {//&& (vb[0].prndr == NULL || ptarg->fbp != vb[0].prndr->fbp) ) { - - if( ptarg->fbp != vb[1].gsfb.fbp ) { //&& (vb[1].prndr == NULL || ptarg->fbp != vb[1].prndr->fbp) ) { + if (!(g_GameSettings & GAME_NOQUICKRESOLVE)) + { + if (ptarg->fbp != vb[0].gsfb.fbp) //&& (vb[0].prndr == NULL || ptarg->fbp != vb[0].prndr->fbp) ) { + { + if (ptarg->fbp != vb[1].gsfb.fbp) //&& (vb[1].prndr == NULL || ptarg->fbp != vb[1].prndr->fbp) ) { + { // this render target currently isn't used and is not in the texture's way, so can safely ignore // resolving it. Also the range has to be big enough compared to the target to really call it resolved // (ffx changing screens, shadowhearts) // start == ptarg->start, used for kh to transfer text - if( ptarg->IsDepth() || end-start > 0x50000 || ((g_GameSettings&GAME_QUICKRESOLVE1)&&start == ptarg->start) ) - ptarg->status |= CRenderTarget::TS_NeedUpdate|CRenderTarget::TS_Resolved; + + if (ptarg->IsDepth() || end - start > 0x50000 || ((g_GameSettings&GAME_QUICKRESOLVE1) && start == ptarg->start)) + ptarg->status |= CRenderTarget::TS_NeedUpdate | CRenderTarget::TS_Resolved; continue; } } } } - else { + else + { // if( start <= texstart && end >= texend ) { // // texture taken care of so can skip!? // continue; @@ -2555,25 +2907,27 @@ void FlushTransferRanges(const tex0Info* ptex) // the first range check was very rough; some games (dragonball z) have the zbuf in the same page as textures (but not overlapping) // so detect that condition - if( ptarg->fbh % m_Blocks[ptarg->psm].height ) { + if (ptarg->fbh % m_Blocks[ptarg->psm].height) + { // get start of left-most boundry page int targstart, targend; - ZeroGS::GetRectMemAddress(targstart, targend, ptarg->psm, 0, 0, ptarg->fbw, ptarg->fbh & ~(m_Blocks[ptarg->psm].height-1), ptarg->fbp, ptarg->fbw); - - if( start >= targend ) { + ZeroGS::GetRectMemAddress(targstart, targend, ptarg->psm, 0, 0, ptarg->fbw, ptarg->fbh & ~(m_Blocks[ptarg->psm].height - 1), ptarg->fbp, ptarg->fbw); + if (start >= targend) + { // don't bother - if( (ptarg->fbh % m_Blocks[ptarg->psm].height) <= 2 ) - continue; + if ((ptarg->fbh % m_Blocks[ptarg->psm].height) <= 2) continue; // calc how many bytes of the block that the page spans } } - if( !(ptarg->status & CRenderTarget::TS_Virtual) ) { + if (!(ptarg->status & CRenderTarget::TS_Virtual)) + { - if( start < ptarg->end && end > ptarg->start ) { + if (start < ptarg->end && end > ptarg->start) + { // suikoden5 is faster with check, but too big of a value and kh screens mess up /* Zeydlitz remove this check, it does not do anything good @@ -2591,7 +2945,8 @@ void FlushTransferRanges(const tex0Info* ptex) }*/ ptarg->status |= CRenderTarget::TS_Resolved; - if( (!ptarg->IsDepth() || (!(g_GameSettings & GAME_NODEPTHUPDATE) || end-start > 0x1000)) && ((end-start > 0x40000) || !(g_GameSettings & GAME_GUSTHACK))) + + if ((!ptarg->IsDepth() || (!(g_GameSettings & GAME_NODEPTHUPDATE) || end - start > 0x1000)) && ((end - start > 0x40000) || !(g_GameSettings & GAME_GUSTHACK))) ptarg->status |= CRenderTarget::TS_NeedUpdate; } } @@ -2608,31 +2963,35 @@ static vector s_vTempBuffer, s_vTransferCache; void InitTransferHostLocal() { FUNCLOG - if( g_bIsLost ) + + if (g_bIsLost) return; #if defined(ZEROGS_DEVBUILD) - if( gs.trxpos.dx+gs.imageWnew > gs.dstbuf.bw ) + if (gs.trxpos.dx + gs.imageWnew > gs.dstbuf.bw) ZZLog::Warn_Log("Transfer error, width exceeded."); + #endif //bool bHasFlushed = false; gs.imageX = gs.trxpos.dx; gs.imageY = gs.trxpos.dy; + gs.imageEndX = gs.imageX + gs.imageWnew; gs.imageEndY = gs.imageY + gs.imageHnew; - assert( gs.imageEndX < 2048 && gs.imageEndY < 2048 ); + assert(gs.imageEndX < 2048 && gs.imageEndY < 2048); // hack! viewful joe - if( gs.dstbuf.psm == 63 ) - gs.dstbuf.psm = 0; + if (gs.dstbuf.psm == 63) gs.dstbuf.psm = 0; int start, end; + GetRectMemAddress(start, end, gs.dstbuf.psm, gs.trxpos.dx, gs.trxpos.dy, gs.imageWnew, gs.imageHnew, gs.dstbuf.bp, gs.dstbuf.bw); - if( end > 0x00400000 ) { + if (end > 0x00400000) + { ZZLog::Warn_Log("Host local out of bounds!"); //gs.imageTransfer = -1; end = 0x00400000; @@ -2640,10 +2999,8 @@ void InitTransferHostLocal() gs_imageEnd = end; - if( vb[0].nCount > 0 ) - Flush(0); - if( vb[1].nCount > 0 ) - Flush(1); + if (vb[0].nCount > 0) Flush(0); + if (vb[1].nCount > 0) Flush(1); //ZZLog::Prim_Log("trans: bp:%x x:%x y:%x w:%x h:%x\n", gs.dstbuf.bp, gs.trxpos.dx, gs.trxpos.dy, gs.imageWnew, gs.imageHnew); @@ -2684,49 +3041,54 @@ void InitTransferHostLocal() void TransferHostLocal(const void* pbyMem, u32 nQWordSize) { FUNCLOG - if( g_bIsLost ) - return; + + if (g_bIsLost) return; int start, end; + GetRectMemAddress(start, end, gs.dstbuf.psm, gs.imageX, gs.imageY, gs.imageWnew, gs.imageHnew, gs.dstbuf.bp, gs.dstbuf.bw); - assert( start < gs_imageEnd ); + + assert(start < gs_imageEnd); end = gs_imageEnd; // sometimes games can decompress to alpha channel of render target only, in this case // do a resolve right away. wolverine x2 - if ((gs.dstbuf.psm == PSMT8H || gs.dstbuf.psm == PSMT4HL || gs.dstbuf.psm == PSMT4HH) && !(g_GameSettings & GAME_GUSTHACK)) { + if ((gs.dstbuf.psm == PSMT8H || gs.dstbuf.psm == PSMT4HL || gs.dstbuf.psm == PSMT4HH) && !(g_GameSettings & GAME_GUSTHACK)) + { list listTransmissionUpdateTargs; s_RTs.GetTargs(start, end, listTransmissionUpdateTargs); - for(list::iterator it = listTransmissionUpdateTargs.begin(); it != listTransmissionUpdateTargs.end(); ++it) { - + for (list::iterator it = listTransmissionUpdateTargs.begin(); it != listTransmissionUpdateTargs.end(); ++it) + { CRenderTarget* ptarg = *it; - if( (ptarg->status & CRenderTarget::TS_Virtual) ) - continue; + if ((ptarg->status & CRenderTarget::TS_Virtual)) continue; //ZZLog::Error_Log("Resolving to alpha channel."); ptarg->Resolve(); } } - s_RangeMngr.Insert(start, min(end, start+(int)nQWordSize*16)); + s_RangeMngr.Insert(start, min(end, start + (int)nQWordSize*16)); const u8* porgend = (const u8*)pbyMem + 4 * nQWordSize; - if( s_vTransferCache.size() > 0 ) { + if (s_vTransferCache.size() > 0) + { int imagecache = s_vTransferCache.size(); s_vTempBuffer.resize(imagecache + nQWordSize*4); memcpy(&s_vTempBuffer[0], &s_vTransferCache[0], imagecache); memcpy(&s_vTempBuffer[imagecache], pbyMem, nQWordSize*4); - pbyMem = (const void*)&s_vTempBuffer[0]; - porgend = &s_vTempBuffer[0]+s_vTempBuffer.size(); + pbyMem = (const void*) & s_vTempBuffer[0]; + porgend = &s_vTempBuffer[0] + s_vTempBuffer.size(); int wordinc = imagecache / 4; - if( (nQWordSize * 4 + imagecache)/3 == ((nQWordSize+wordinc) * 4) / 3 ) { + + if ((nQWordSize * 4 + imagecache) / 3 == ((nQWordSize + wordinc) * 4) / 3) + { // can use the data nQWordSize += wordinc; } @@ -2734,15 +3096,20 @@ void TransferHostLocal(const void* pbyMem, u32 nQWordSize) int leftover = m_Blocks[gs.dstbuf.psm].TransferHostLocal(pbyMem, nQWordSize); - if( leftover > 0 ) { + if (leftover > 0) + { // copy the last gs.image24bitOffset to the cache s_vTransferCache.resize(leftover); memcpy(&s_vTransferCache[0], porgend - leftover, leftover); } - else s_vTransferCache.resize(0); + else + { + s_vTransferCache.resize(0); + } #if defined(_DEBUG) - if( g_bSaveTrans ) { + if (g_bSaveTrans) + { tex0Info t; t.tbp0 = gs.dstbuf.bp; t.tw = gs.imageWnew; @@ -2751,6 +3118,7 @@ void TransferHostLocal(const void* pbyMem, u32 nQWordSize) t.psm = gs.dstbuf.psm; SaveTex(&t, 0); } + #endif } @@ -2882,21 +3250,27 @@ void TransferHostLocal(const void* pbyMem, u32 nQWordSize) void InitTransferLocalHost() { FUNCLOG - assert( gs.trxpos.sx+gs.imageWnew <= 2048 && gs.trxpos.sy+gs.imageHnew <= 2048 ); + assert(gs.trxpos.sx + gs.imageWnew <= 2048 && gs.trxpos.sy + gs.imageHnew <= 2048); #if defined(ZEROGS_DEVBUILD) - if( gs.trxpos.sx+gs.imageWnew > gs.srcbuf.bw ) + + if (gs.trxpos.sx + gs.imageWnew > gs.srcbuf.bw) ZZLog::Warn_Log("Transfer error, width exceeded."); + #endif gs.imageX = gs.trxpos.sx; gs.imageY = gs.trxpos.sy; + gs.imageEndX = gs.imageX + gs.imageWnew; gs.imageEndY = gs.imageY + gs.imageHnew; + s_vTransferCache.resize(0); int start, end; + GetRectMemAddress(start, end, gs.srcbuf.psm, gs.trxpos.sx, gs.trxpos.sy, gs.imageWnew, gs.imageHnew, gs.srcbuf.bp, gs.srcbuf.bw); + ResolveInRange(start, end); } @@ -2905,23 +3279,23 @@ void TransferLocalHost(void* pbyMem, u32 nQWordSize, int& x, int& y, u8 *pstart, { int i = x, j = y; T* pbuf = (T*)pbyMem; - u32 nSize = nQWordSize*16/sizeof(T); + u32 nSize = nQWordSize * 16 / sizeof(T); - for(; i < gs.imageEndY; ++i) + for (; i < gs.imageEndY; ++i) { - for(; j < gs.imageEndX && nSize > 0; ++j, --nSize) + for (; j < gs.imageEndX && nSize > 0; ++j, --nSize) { - *pbuf++ = rp(pstart, j%2048, i%2048, gs.srcbuf.bw); + *pbuf++ = rp(pstart, j % 2048, i % 2048, gs.srcbuf.bw); } - if( j >= gs.imageEndX ) + if (j >= gs.imageEndX) { - assert( j == gs.imageEndX); + assert(j == gs.imageEndX); j = gs.trxpos.sx; } else { - assert( nSize == 0 ); + assert(nSize == 0); break; } } @@ -2932,29 +3306,29 @@ void TransferLocalHost_24(void* pbyMem, u32 nQWordSize, int& x, int& y, u8 *psta { int i = x, j = y; u8* pbuf = (u8*)pbyMem; - u32 nSize = nQWordSize*16/3; + u32 nSize = nQWordSize * 16 / 3; - for(; i < gs.imageEndY; ++i) + for (; i < gs.imageEndY; ++i) { - for(; j < gs.imageEndX && nSize > 0; ++j, --nSize) + for (; j < gs.imageEndX && nSize > 0; ++j, --nSize) { - u32 p = rp(pstart, j%2048, i%2048, gs.srcbuf.bw); + u32 p = rp(pstart, j % 2048, i % 2048, gs.srcbuf.bw); pbuf[0] = (u8)p; - pbuf[1] = (u8)(p>>8); - pbuf[2] = (u8)(p>>16); + pbuf[1] = (u8)(p >> 8); + pbuf[2] = (u8)(p >> 16); pbuf += 3; } - if( j >= gs.imageEndX ) - { - assert( j == gs.imageEndX); - j = gs.trxpos.sx; - } + if (j >= gs.imageEndX) + { + assert(j == gs.imageEndX); + j = gs.trxpos.sx; + } else - { - assert( nSize == 0 ); - break; - } + { + assert(nSize == 0); + break; + } } } @@ -2962,30 +3336,64 @@ void TransferLocalHost_24(void* pbyMem, u32 nQWordSize, int& x, int& y, u8 *psta void TransferLocalHost(void* pbyMem, u32 nQWordSize) { FUNCLOG - assert( gs.imageTransfer == 1 ); + assert(gs.imageTransfer == 1); - u8* pstart = g_pbyGSMemory + 256*gs.srcbuf.bp; + u8* pstart = g_pbyGSMemory + 256 * gs.srcbuf.bp; int i = gs.imageY, j = gs.imageX; - switch (gs.srcbuf.psm) { - case PSMCT32: TransferLocalHost(pbyMem, nQWordSize, i, j, pstart, readPixel32_0); break; - case PSMCT24: TransferLocalHost_24(pbyMem, nQWordSize, i, j, pstart, readPixel24_0); break; - case PSMCT16: TransferLocalHost(pbyMem, nQWordSize, i, j, pstart, readPixel16_0); break; - case PSMCT16S: TransferLocalHost(pbyMem, nQWordSize, i, j, pstart, readPixel16S_0); break; - case PSMT8: TransferLocalHost(pbyMem, nQWordSize, i, j, pstart, readPixel8_0); break; - case PSMT8H: TransferLocalHost(pbyMem, nQWordSize, i, j, pstart, readPixel8H_0); break; - case PSMT32Z: TransferLocalHost(pbyMem, nQWordSize, i, j, pstart, readPixel32Z_0); break; - case PSMT24Z: TransferLocalHost_24(pbyMem, nQWordSize, i, j, pstart, readPixel24Z_0); break; - case PSMT16Z: TransferLocalHost(pbyMem, nQWordSize, i, j, pstart, readPixel16Z_0); break; - case PSMT16SZ: TransferLocalHost(pbyMem, nQWordSize, i, j, pstart, readPixel16SZ_0); break; - default: assert(0); + switch (gs.srcbuf.psm) + { + + case PSMCT32: + TransferLocalHost(pbyMem, nQWordSize, i, j, pstart, readPixel32_0); + break; + + case PSMCT24: + TransferLocalHost_24(pbyMem, nQWordSize, i, j, pstart, readPixel24_0); + break; + + case PSMCT16: + TransferLocalHost(pbyMem, nQWordSize, i, j, pstart, readPixel16_0); + break; + + case PSMCT16S: + TransferLocalHost(pbyMem, nQWordSize, i, j, pstart, readPixel16S_0); + break; + + case PSMT8: + TransferLocalHost(pbyMem, nQWordSize, i, j, pstart, readPixel8_0); + break; + + case PSMT8H: + TransferLocalHost(pbyMem, nQWordSize, i, j, pstart, readPixel8H_0); + break; + + case PSMT32Z: + TransferLocalHost(pbyMem, nQWordSize, i, j, pstart, readPixel32Z_0); + break; + + case PSMT24Z: + TransferLocalHost_24(pbyMem, nQWordSize, i, j, pstart, readPixel24Z_0); + break; + + case PSMT16Z: + TransferLocalHost(pbyMem, nQWordSize, i, j, pstart, readPixel16Z_0); + break; + + case PSMT16SZ: + TransferLocalHost(pbyMem, nQWordSize, i, j, pstart, readPixel16SZ_0); + break; + + default: + assert(0); } gs.imageY = i; gs.imageX = j; - if( gs.imageY >= gs.imageEndY ) { - assert( gs.imageY == gs.imageEndY ); + if (gs.imageY >= gs.imageEndY) + { + assert(gs.imageY == gs.imageEndY); gs.imageTransfer = -1; } } @@ -2994,13 +3402,15 @@ void TransferLocalHost(void* pbyMem, u32 nQWordSize) void TransferLocalLocal() { FUNCLOG - assert( gs.imageTransfer == 2 ); - assert( gs.trxpos.sx+gs.imageWnew < 2048 && gs.trxpos.sy+gs.imageHnew < 2048 ); - assert( gs.trxpos.dx+gs.imageWnew < 2048 && gs.trxpos.dy+gs.imageHnew < 2048 ); - assert( (gs.srcbuf.psm&0x7) == (gs.dstbuf.psm&0x7) ); - if (gs.trxpos.sx+gs.imageWnew > gs.srcbuf.bw) + assert(gs.imageTransfer == 2); + assert(gs.trxpos.sx + gs.imageWnew < 2048 && gs.trxpos.sy + gs.imageHnew < 2048); + assert(gs.trxpos.dx + gs.imageWnew < 2048 && gs.trxpos.dy + gs.imageHnew < 2048); + assert((gs.srcbuf.psm&0x7) == (gs.dstbuf.psm&0x7)); + + if (gs.trxpos.sx + gs.imageWnew > gs.srcbuf.bw) ZZLog::Warn_Log("Transfer error, src width exceeded."); - if (gs.trxpos.dx+gs.imageWnew > gs.dstbuf.bw) + + if (gs.trxpos.dx + gs.imageWnew > gs.dstbuf.bw) ZZLog::Warn_Log("Transfer error, dst width exceeded."); int srcstart, srcend, dststart, dstend; @@ -3012,16 +3422,20 @@ void TransferLocalLocal() ResolveInRange(srcstart, srcend); list listTargs; + s_RTs.GetTargs(dststart, dstend, listTargs); - for(list::iterator it = listTargs.begin(); it != listTargs.end(); ++it) { - if( !((*it)->status & CRenderTarget::TS_Virtual) ) { + + for (list::iterator it = listTargs.begin(); it != listTargs.end(); ++it) + { + if (!((*it)->status & CRenderTarget::TS_Virtual)) + { (*it)->Resolve(); //(*it)->status |= CRenderTarget::TS_NeedUpdate; } } - u8* pSrcBuf = g_pbyGSMemory + gs.srcbuf.bp*256; - u8* pDstBuf = g_pbyGSMemory + gs.dstbuf.bp*256; + u8* pSrcBuf = g_pbyGSMemory + gs.srcbuf.bp * 256; + u8* pDstBuf = g_pbyGSMemory + gs.dstbuf.bp * 256; #define TRANSFERLOCALLOCAL(srcpsm, dstpsm, widthlimit) { \ if( (gs.imageWnew&widthlimit)!=0 ) break; \ @@ -3049,7 +3463,7 @@ void TransferLocalLocal() } \ } \ } \ - + #define TRANSFERLOCALLOCAL_4(srcpsm, dstpsm) { \ assert( (gs.imageWnew%8) == 0 ); \ for(int i = gs.trxpos.sy, i2 = gs.trxpos.dy; i < gs.trxpos.sy+gs.imageHnew; ++i, ++i2) { \ @@ -3089,119 +3503,208 @@ void TransferLocalLocal() } \ } \ } \ - - switch (gs.srcbuf.psm) { + + switch (gs.srcbuf.psm) + { case PSMCT32: - if( gs.dstbuf.psm == PSMCT32 ) { + if (gs.dstbuf.psm == PSMCT32) + { TRANSFERLOCALLOCAL(32, 32, 2); } - else { + else + { TRANSFERLOCALLOCAL(32, 32Z, 2); } break; case PSMCT24: - if( gs.dstbuf.psm == PSMCT24 ) { + if (gs.dstbuf.psm == PSMCT24) + { TRANSFERLOCALLOCAL(24, 24, 4); } - else { + else + { TRANSFERLOCALLOCAL(24, 24Z, 4); } break; case PSMCT16: - switch(gs.dstbuf.psm) { - case PSMCT16: TRANSFERLOCALLOCAL(16, 16, 4); break; - case PSMCT16S: TRANSFERLOCALLOCAL(16, 16S, 4); break; - case PSMT16Z: TRANSFERLOCALLOCAL(16, 16Z, 4); break; - case PSMT16SZ: TRANSFERLOCALLOCAL(16, 16SZ, 4); break; + switch (gs.dstbuf.psm) + { + case PSMCT16: + TRANSFERLOCALLOCAL(16, 16, 4); + break; + + case PSMCT16S: + TRANSFERLOCALLOCAL(16, 16S, 4); + break; + + case PSMT16Z: + TRANSFERLOCALLOCAL(16, 16Z, 4); + break; + + case PSMT16SZ: + TRANSFERLOCALLOCAL(16, 16SZ, 4); + break; } break; case PSMCT16S: - switch(gs.dstbuf.psm) { - case PSMCT16: TRANSFERLOCALLOCAL(16S, 16, 4); break; - case PSMCT16S: TRANSFERLOCALLOCAL(16S, 16S, 4); break; - case PSMT16Z: TRANSFERLOCALLOCAL(16S, 16Z, 4); break; - case PSMT16SZ: TRANSFERLOCALLOCAL(16S, 16SZ, 4); break; + switch (gs.dstbuf.psm) + { + case PSMCT16: + TRANSFERLOCALLOCAL(16S, 16, 4); + break; + + case PSMCT16S: + TRANSFERLOCALLOCAL(16S, 16S, 4); + break; + + case PSMT16Z: + TRANSFERLOCALLOCAL(16S, 16Z, 4); + break; + + case PSMT16SZ: + TRANSFERLOCALLOCAL(16S, 16SZ, 4); + break; } break; case PSMT8: - if( gs.dstbuf.psm == PSMT8 ) { + if (gs.dstbuf.psm == PSMT8) + { TRANSFERLOCALLOCAL(8, 8, 4); } - else { + else + { TRANSFERLOCALLOCAL(8, 8H, 4); } break; case PSMT4: + switch (gs.dstbuf.psm) + { - switch(gs.dstbuf.psm ) { - case PSMT4: TRANSFERLOCALLOCAL_4(4, 4); break; - case PSMT4HL: TRANSFERLOCALLOCAL_4(4, 4HL); break; - case PSMT4HH: TRANSFERLOCALLOCAL_4(4, 4HH); break; + case PSMT4: + TRANSFERLOCALLOCAL_4(4, 4); + break; + + case PSMT4HL: + TRANSFERLOCALLOCAL_4(4, 4HL); + break; + + case PSMT4HH: + TRANSFERLOCALLOCAL_4(4, 4HH); + break; } break; case PSMT8H: - if( gs.dstbuf.psm == PSMT8 ) { + if (gs.dstbuf.psm == PSMT8) + { TRANSFERLOCALLOCAL(8H, 8, 4); } - else { + else + { TRANSFERLOCALLOCAL(8H, 8H, 4); } break; case PSMT4HL: - switch(gs.dstbuf.psm ) { - case PSMT4: TRANSFERLOCALLOCAL_4(4HL, 4); break; - case PSMT4HL: TRANSFERLOCALLOCAL_4(4HL, 4HL); break; - case PSMT4HH: TRANSFERLOCALLOCAL_4(4HL, 4HH); break; + switch (gs.dstbuf.psm) + { + case PSMT4: + TRANSFERLOCALLOCAL_4(4HL, 4); + break; + + case PSMT4HL: + TRANSFERLOCALLOCAL_4(4HL, 4HL); + break; + + case PSMT4HH: + TRANSFERLOCALLOCAL_4(4HL, 4HH); + break; } break; + case PSMT4HH: - switch(gs.dstbuf.psm ) { - case PSMT4: TRANSFERLOCALLOCAL_4(4HH, 4); break; - case PSMT4HL: TRANSFERLOCALLOCAL_4(4HH, 4HL); break; - case PSMT4HH: TRANSFERLOCALLOCAL_4(4HH, 4HH); break; + switch (gs.dstbuf.psm) + { + case PSMT4: + TRANSFERLOCALLOCAL_4(4HH, 4); + break; + + case PSMT4HL: + TRANSFERLOCALLOCAL_4(4HH, 4HL); + break; + + case PSMT4HH: + TRANSFERLOCALLOCAL_4(4HH, 4HH); + break; } break; case PSMT32Z: - if( gs.dstbuf.psm == PSMCT32 ) { + if (gs.dstbuf.psm == PSMCT32) + { TRANSFERLOCALLOCAL(32Z, 32, 2); } - else { + else + { TRANSFERLOCALLOCAL(32Z, 32Z, 2); } break; case PSMT24Z: - if( gs.dstbuf.psm == PSMCT24 ) { + if (gs.dstbuf.psm == PSMCT24) + { TRANSFERLOCALLOCAL(24Z, 24, 4); } - else { + else + { TRANSFERLOCALLOCAL(24Z, 24Z, 4); } break; case PSMT16Z: - switch(gs.dstbuf.psm) { - case PSMCT16: TRANSFERLOCALLOCAL(16Z, 16, 4); break; - case PSMCT16S: TRANSFERLOCALLOCAL(16Z, 16S, 4); break; - case PSMT16Z: TRANSFERLOCALLOCAL(16Z, 16Z, 4); break; - case PSMT16SZ: TRANSFERLOCALLOCAL(16Z, 16SZ, 4); break; + switch (gs.dstbuf.psm) + { + case PSMCT16: + TRANSFERLOCALLOCAL(16Z, 16, 4); + break; + + case PSMCT16S: + TRANSFERLOCALLOCAL(16Z, 16S, 4); + break; + + case PSMT16Z: + TRANSFERLOCALLOCAL(16Z, 16Z, 4); + break; + + case PSMT16SZ: + TRANSFERLOCALLOCAL(16Z, 16SZ, 4); + break; } break; case PSMT16SZ: - switch(gs.dstbuf.psm) { - case PSMCT16: TRANSFERLOCALLOCAL(16SZ, 16, 4); break; - case PSMCT16S: TRANSFERLOCALLOCAL(16SZ, 16S, 4); break; - case PSMT16Z: TRANSFERLOCALLOCAL(16SZ, 16Z, 4); break; - case PSMT16SZ: TRANSFERLOCALLOCAL(16SZ, 16SZ, 4); break; + switch (gs.dstbuf.psm) + { + case PSMCT16: + TRANSFERLOCALLOCAL(16SZ, 16, 4); + break; + + case PSMCT16S: + TRANSFERLOCALLOCAL(16SZ, 16S, 4); + break; + + case PSMT16Z: + TRANSFERLOCALLOCAL(16SZ, 16Z, 4); + break; + + case PSMT16SZ: + TRANSFERLOCALLOCAL(16SZ, 16SZ, 4); + break; } break; } @@ -3209,7 +3712,9 @@ void TransferLocalLocal() g_MemTargs.ClearRange(dststart, dstend); #ifdef DEVBUILD - if( g_bSaveTrans ) { + + if (g_bSaveTrans) + { tex0Info t; t.tbp0 = gs.dstbuf.bp; t.tw = gs.imageWnew; @@ -3225,52 +3730,61 @@ void TransferLocalLocal() t.psm = gs.srcbuf.psm; SaveTex(&t, 0); } + #endif } void GetRectMemAddress(int& start, int& end, int psm, int x, int y, int w, int h, int bp, int bw) { FUNCLOG - if( m_Blocks[psm].bpp == 0 ) { + + if (m_Blocks[psm].bpp == 0) + { ZZLog::Error_Log("ZeroGS: Bad psm 0x%x.", psm); start = 0; end = 0x00400000; return; } - if( PSMT_ISZTEX(psm) || psm == PSMCT16S ) { + if (PSMT_ISZTEX(psm) || psm == PSMCT16S) + { const BLOCK& b = m_Blocks[psm]; - bw = (bw + b.width - 1)/b.width; - start = bp*256 + ((y/b.height) * bw + (x/b.width) )*0x2000; - end = bp*256 + (((y+h-1)/b.height) * bw + (x + w + b.width - 1)/b.width)*0x2000; + bw = (bw + b.width - 1) / b.width; + start = bp * 256 + ((y / b.height) * bw + (x / b.width)) * 0x2000; + end = bp * 256 + (((y + h - 1) / b.height) * bw + (x + w + b.width - 1) / b.width) * 0x2000; } - else { + else + { // just take the addresses - switch(psm) { + switch (psm) + { case PSMCT32: case PSMCT24: case PSMT8H: case PSMT4HL: case PSMT4HH: - start = 4*getPixelAddress32(x, y, bp, bw); - end = 4*getPixelAddress32(x+w-1, y+h-1, bp, bw) + 4; + start = 4 * getPixelAddress32(x, y, bp, bw); + end = 4 * getPixelAddress32(x + w - 1, y + h - 1, bp, bw) + 4; break; + case PSMCT16: - start = 2*getPixelAddress16(x, y, bp, bw); - end = 2*getPixelAddress16(x+w-1, y+h-1, bp, bw)+2; + start = 2 * getPixelAddress16(x, y, bp, bw); + end = 2 * getPixelAddress16(x + w - 1, y + h - 1, bp, bw) + 2; break; + case PSMT8: start = getPixelAddress8(x, y, bp, bw); - end = getPixelAddress8(x+w-1, y+h-1, bp, bw)+1; + end = getPixelAddress8(x + w - 1, y + h - 1, bp, bw) + 1; break; + case PSMT4: { - start = getPixelAddress4(x, y, bp, bw)/2; - int newx = ((x+w-1+31)&~31)-1; - int newy = ((y+h-1+15)&~15)-1; - end = (getPixelAddress4(max(newx,x), max(newy,y), bp, bw)+2)/2; + start = getPixelAddress4(x, y, bp, bw) / 2; + int newx = ((x + w - 1 + 31) & ~31) - 1; + int newy = ((y + h - 1 + 15) & ~15) - 1; + end = (getPixelAddress4(max(newx, x), max(newy, y), bp, bw) + 2) / 2; break; } } @@ -3308,7 +3822,7 @@ void GetRectMemAddress(int& start, int& end, int psm, int x, int y, int w, int h src += RH(Pitch(fbw))/sizeof(Tsrc); \ } \ } \ - + void _Resolve(const void* psrc, int fbp, int fbw, int fbh, int psm, u32 fbm, bool mode = true) { FUNCLOG @@ -3324,9 +3838,11 @@ void _Resolve(const void* psrc, int fbp, int fbw, int fbh, int psm, u32 fbm, boo if (GetRenderFormat() == RFT_byte8) { // start the conversion process A8R8G8B8 -> psm - switch(psm) + switch (psm) { + case PSMCT32: + case PSMCT24: RESOLVE_32_BIT(32, u32, u32, (u32)); break; @@ -3340,6 +3856,7 @@ void _Resolve(const void* psrc, int fbp, int fbw, int fbh, int psm, u32 fbm, boo break; case PSMT32Z: + case PSMT24Z: RESOLVE_32_BIT(32Z, u32, u32, (u32)); break; @@ -3355,9 +3872,11 @@ void _Resolve(const void* psrc, int fbp, int fbw, int fbh, int psm, u32 fbm, boo } else // float16 { - switch(psm) + switch (psm) { + case PSMCT32: + case PSMCT24: RESOLVE_32_BIT(32, u32, Vector_16F, Float16ToARGB); break; @@ -3371,6 +3890,7 @@ void _Resolve(const void* psrc, int fbp, int fbw, int fbh, int psm, u32 fbm, boo break; case PSMT32Z: + case PSMT24Z: RESOLVE_32_BIT(32Z, u32, Vector_16F, Float16ToARGB_Z); break; @@ -3386,6 +3906,7 @@ void _Resolve(const void* psrc, int fbp, int fbw, int fbh, int psm, u32 fbm, boo } g_MemTargs.ClearRange(start, end); + INC_RESOLVE(); } @@ -3407,16 +3928,19 @@ void _Resolve(const void* psrc, int fbp, int fbw, int fbh, int psm, u32 fbm, boo //short smask2 = gs.smask&2; u32 mask, imask; - if (PSMT_ISHALF(psm)) { // 16 bit + if (PSMT_ISHALF(psm)) // 16 bit + { // mask is shifted imask = RGBA32to16(fbm); - mask = (~imask)&0xffff; + mask = (~imask) & 0xffff; } - else { + else + { mask = ~fbm; imask = fbm; - if( (psm&0xf)>0 && 0) { + if ((psm&0xf) > 0 && 0) + { // preserve the alpha? mask &= 0x00ffffff; imask |= 0xff000000; @@ -3425,6 +3949,7 @@ void _Resolve(const void* psrc, int fbp, int fbw, int fbh, int psm, u32 fbm, boo // Targets over 2000 should be shuffle. FFX and KH2 (0x2100) int X = (psm == 0) ? 0 : 0; + //if (X == 1) //ZZLog::Error_Log("resolve: %x %x %x %x (%x-%x).", psm, fbp, fbw, fbh, start, end); @@ -3454,157 +3979,225 @@ void _Resolve(const void* psrc, int fbp, int fbw, int fbh, int psm, u32 fbm, boo src += RH(Pitch(fbw))/sizeof(Tsrc); \ } \ } \ - + if( GetRenderFormat() == RFT_byte8 ) { // start the conversion process A8R8G8B8 -> psm - switch(psm) { + switch (psm) + { + case PSMCT32: + case PSMCT24: - if( s_AAy ) { + + if (s_AAy) + { RESOLVE_32BIT(32, u32, u32, 32A4, 8, 8, (u32), Frame, s_AAx, s_AAy); } - else if( s_AAx ) { + else if (s_AAx) + { RESOLVE_32BIT(32, u32, u32, 32A2, 8, 8, (u32), Frame, 1, 0); } - else { + else + { RESOLVE_32BIT(32, u32, u32, 32, 8, 8, (u32), Frame, 0, 0); } + break; + case PSMCT16: - if( s_AAy ) { + + if (s_AAy) + { RESOLVE_32BIT(16, u16, u32, 16A4, 16, 8, RGBA32to16, Frame, s_AAx, s_AAy); } - else if( s_AAx ) { + else if (s_AAx) + { RESOLVE_32BIT(16, u16, u32, 16A2, 16, 8, RGBA32to16, Frame, 1, 0); } - else { + else + { RESOLVE_32BIT(16, u16, u32, 16, 16, 8, RGBA32to16, Frame, 0, 0); } break; + case PSMCT16S: - if( s_AAy ) { + + if (s_AAy) + { RESOLVE_32BIT(16S, u16, u32, 16A4, 16, 8, RGBA32to16, Frame, s_AAx, s_AAy); } - else if( s_AAx ) { + else if (s_AAx) + { RESOLVE_32BIT(16S, u16, u32, 16A2, 16, 8, RGBA32to16, Frame, 1, 0); } - else { + else + { RESOLVE_32BIT(16S, u16, u32, 16, 16, 8, RGBA32to16, Frame, 0, 0); } break; + case PSMT32Z: + case PSMT24Z: - if( s_AAy ) { + + if (s_AAy) + { RESOLVE_32BIT(32Z, u32, u32, 32A4, 8, 8, (u32), Frame, s_AAx, s_AAy); } - else if( s_AAx ) { + else if (s_AAx) + { RESOLVE_32BIT(32Z, u32, u32, 32A2, 8, 8, (u32), Frame, 1, 0); } - else { + else + { RESOLVE_32BIT(32Z, u32, u32, 32, 8, 8, (u32), Frame, 0, 0); } break; + case PSMT16Z: - if( s_AAy ) { + + if (s_AAy) + { RESOLVE_32BIT(16Z, u16, u32, 16A4, 16, 8, (u16), Frame, s_AAx, s_AAy); } - else if( s_AAx ) { + else if (s_AAx) + { RESOLVE_32BIT(16Z, u16, u32, 16A2, 16, 8, (u16), Frame, 1, 0); } - else { + else + { RESOLVE_32BIT(16Z, u16, u32, 16, 16, 8, (u16), Frame, 0, 0); } break; + case PSMT16SZ: - if( s_AAy ) { + + if (s_AAy) + { RESOLVE_32BIT(16SZ, u16, u32, 16A4, 16, 8, (u16), Frame, s_AAx, s_AAy); } - else if( s_AAx ) { + else if (s_AAx) + { RESOLVE_32BIT(16SZ, u16, u32, 16A2, 16, 8, (u16), Frame, 1, 0); } - else { + else + { RESOLVE_32BIT(16SZ, u16, u32, 16, 16, 8, (u16), Frame, 0, 0); } break; } } - else { // float16 - switch(psm) { + else // float16 + { + switch (psm) + { + case PSMCT32: + case PSMCT24: - if( s_AAy ) { + + if (s_AAy) + { RESOLVE_32BIT(32, u32, Vector_16F, 32A4, 8, 8, Float16ToARGB, Frame16, 1, 1); } - else if( s_AAx ) { + else if (s_AAx) + { RESOLVE_32BIT(32, u32, Vector_16F, 32A2, 8, 8, Float16ToARGB, Frame16, 1, 0); } - else { + else + { RESOLVE_32BIT(32, u32, Vector_16F, 32, 8, 8, Float16ToARGB, Frame16, 0, 0); } break; + case PSMCT16: - if( s_AAy ) { + + if (s_AAy) + { RESOLVE_32BIT(16, u16, Vector_16F, 16A4, 16, 8, Float16ToARGB16, Frame16, 1, 1); } - else if( s_AAx ) { + else if (s_AAx) + { RESOLVE_32BIT(16, u16, Vector_16F, 16A2, 16, 8, Float16ToARGB16, Frame16, 1, 0); } - else { + else + { RESOLVE_32BIT(16, u16, Vector_16F, 16, 16, 8, Float16ToARGB16, Frame16, 0, 0); } break; + case PSMCT16S: - if( s_AAy ) { + + if (s_AAy) + { RESOLVE_32BIT(16S, u16, Vector_16F, 16A4, 16, 8, Float16ToARGB16, Frame16, 1, 1); } - else if( s_AAx ) { + else if (s_AAx) + { RESOLVE_32BIT(16S, u16, Vector_16F, 16A2, 16, 8, Float16ToARGB16, Frame16, 1, 0); } - else { + else + { RESOLVE_32BIT(16S, u16, Vector_16F, 16, 16, 8, Float16ToARGB16, Frame16, 0, 0); } break; + case PSMT32Z: + case PSMT24Z: - if( s_AAy ) { + + if (s_AAy) + { RESOLVE_32BIT(32Z, u32, Vector_16F, 32ZA4, 8, 8, Float16ToARGB_Z, Frame16, 1, 1); } - else if( s_AAx ) { + else if (s_AAx) + { RESOLVE_32BIT(32Z, u32, Vector_16F, 32ZA2, 8, 8, Float16ToARGB_Z, Frame16, 1, 0); } - else { + else + { RESOLVE_32BIT(32Z, u32, Vector_16F, 32Z, 8, 8, Float16ToARGB_Z, Frame16, 0, 0); } break; + case PSMT16Z: - if( s_AAy ) { + + if (s_AAy) + { RESOLVE_32BIT(16Z, u16, Vector_16F, 16ZA4, 16, 8, Float16ToARGB16_Z, Frame16, 1, 1); } - else if( s_AAx ) { + else if (s_AAx) + { RESOLVE_32BIT(16Z, u16, Vector_16F, 16ZA2, 16, 8, Float16ToARGB16_Z, Frame16, 1, 0); } - else { + else + { RESOLVE_32BIT(16Z, u16, Vector_16F, 16Z, 16, 8, Float16ToARGB16_Z, Frame16, 0, 0); } break; + case PSMT16SZ: - if( s_AAy ) { + + if (s_AAy) + { RESOLVE_32BIT(16SZ, u16, Vector_16F, 16ZA4, 16, 8, Float16ToARGB16_Z, Frame16, 1, 1); } - else if( s_AAx ) { + else if (s_AAx) + { RESOLVE_32BIT(16SZ, u16, Vector_16F, 16ZA2, 16, 8, Float16ToARGB16_Z, Frame16, 1, 0); } - else { + else + { RESOLVE_32BIT(16SZ, u16, Vector_16F, 16Z, 16, 8, Float16ToARGB16_Z, Frame16, 0, 0); } @@ -3613,8 +4206,10 @@ void _Resolve(const void* psrc, int fbp, int fbw, int fbh, int psm, u32 fbm, boo } g_MemTargs.ClearRange(start, end); + INC_RESOLVE(); } + #endif } // End of namespece ZeroGS diff --git a/plugins/zzogl-pg/opengl/x86.cpp b/plugins/zzogl-pg/opengl/x86.cpp index f41a8dd0bb..a094412381 100644 --- a/plugins/zzogl-pg/opengl/x86.cpp +++ b/plugins/zzogl-pg/opengl/x86.cpp @@ -191,10 +191,10 @@ void __fastcall Frame16SwizzleBlock16Z##type##c(u16* dst, Vector_16F* src, int s src += srcpitch << incsrc; \ } \ } \ - + _FrameSwizzleBlock(_, src[j], src[j], 0); -_FrameSwizzleBlock(A2_, (src[2*j]+src[2*j+1])>>1, src[2*j], 0); -_FrameSwizzleBlock(A4_, (src[2*j]+src[2*j+1]+src[2*j+srcpitch]+src[2*j+srcpitch+1])>>2, src[2*j], 1); +_FrameSwizzleBlock(A2_, (src[2*j] + src[2*j+1]) >> 1, src[2*j], 0); +_FrameSwizzleBlock(A4_, (src[2*j] + src[2*j+1] + src[2*j+srcpitch] + src[2*j+srcpitch+1]) >> 2, src[2*j], 1); #ifdef ZEROGS_SSE2 @@ -266,9 +266,9 @@ extern "C" void __fastcall WriteCLUT_T32_I8_CSM1_sse2(u32* vm, u32* clut) __m128i* src = (__m128i*)vm; __m128i* dst = (__m128i*)clut; - for(int j = 0; j < 64; j += 32, src += 32, dst += 32) + for (int j = 0; j < 64; j += 32, src += 32, dst += 32) { - for(int i = 0; i < 16; i += 4) + for (int i = 0; i < 16; i += 4) { __m128i r0 = _mm_load_si128(&src[i+0]); __m128i r1 = _mm_load_si128(&src[i+1]); @@ -310,16 +310,19 @@ extern "C" void __fastcall WriteCLUT_T32_I4_CSM1_sse2(u32* vm, u32* clut) } -extern "C" { -PCSX2_ALIGNED16(int s_clut16mask2[4]) = { 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff }; -PCSX2_ALIGNED16(int s_clut16mask[8]) = { 0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000, - 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff}; +extern "C" +{ + PCSX2_ALIGNED16(int s_clut16mask2[4]) = { 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff }; + PCSX2_ALIGNED16(int s_clut16mask[8]) = { 0xffff0000, 0xffff0000, 0xffff0000, 0xffff0000, + 0x0000ffff, 0x0000ffff, 0x0000ffff, 0x0000ffff + }; } extern "C" void __fastcall WriteCLUT_T16_I4_CSM1_sse2(u32* vm, u32* clut) { #if defined(_MSC_VER) - __asm { + __asm + { mov eax, vm mov ecx, clut movdqa xmm0, qword ptr [eax] @@ -428,122 +431,125 @@ WriteUnaligned: movdqa [ecx+16], xmm2 movdqa [ecx+48], xmm3 + End: } #else __asm__(".intel_syntax noprefix\n" - "movdqa xmm0, xmmword ptr [ecx]\n" - "movdqa xmm1, xmmword ptr [ecx+16]\n" - "movdqa xmm2, xmmword ptr [ecx+32]\n" - "movdqa xmm3, xmmword ptr [ecx+48]\n" + "movdqa xmm0, xmmword ptr [ecx]\n" + "movdqa xmm1, xmmword ptr [ecx+16]\n" + "movdqa xmm2, xmmword ptr [ecx+32]\n" + "movdqa xmm3, xmmword ptr [ecx+48]\n" - // rearrange - "pshuflw xmm0, xmm0, 0x88\n" - "pshufhw xmm0, xmm0, 0x88\n" - "pshuflw xmm1, xmm1, 0x88\n" - "pshufhw xmm1, xmm1, 0x88\n" - "pshuflw xmm2, xmm2, 0x88\n" - "pshufhw xmm2, xmm2, 0x88\n" - "pshuflw xmm3, xmm3, 0x88\n" - "pshufhw xmm3, xmm3, 0x88\n" + // rearrange + "pshuflw xmm0, xmm0, 0x88\n" + "pshufhw xmm0, xmm0, 0x88\n" + "pshuflw xmm1, xmm1, 0x88\n" + "pshufhw xmm1, xmm1, 0x88\n" + "pshuflw xmm2, xmm2, 0x88\n" + "pshufhw xmm2, xmm2, 0x88\n" + "pshuflw xmm3, xmm3, 0x88\n" + "pshufhw xmm3, xmm3, 0x88\n" - "shufps xmm0, xmm1, 0x88\n" - "shufps xmm2, xmm3, 0x88\n" + "shufps xmm0, xmm1, 0x88\n" + "shufps xmm2, xmm3, 0x88\n" - "pshufd xmm0, xmm0, 0xd8\n" - "pshufd xmm2, xmm2, 0xd8\n" + "pshufd xmm0, xmm0, 0xd8\n" + "pshufd xmm2, xmm2, 0xd8\n" - "pxor xmm6, xmm6\n" + "pxor xmm6, xmm6\n" - "test edx, 15\n" - "jnz WriteUnaligned\n" + "test edx, 15\n" + "jnz WriteUnaligned\n" - "movdqa xmm7, [%[s_clut16mask]]\n" // saves upper 16 bits + "movdqa xmm7, [%[s_clut16mask]]\n" // saves upper 16 bits - // have to save interlaced with the old data - "movdqa xmm4, [edx]\n" - "movdqa xmm5, [edx+32]\n" - "movhlps xmm1, xmm0\n" - "movlhps xmm0, xmm2\n"// lower 8 colors + // have to save interlaced with the old data + "movdqa xmm4, [edx]\n" + "movdqa xmm5, [edx+32]\n" + "movhlps xmm1, xmm0\n" + "movlhps xmm0, xmm2\n"// lower 8 colors - "pand xmm4, xmm7\n" - "pand xmm5, xmm7\n" + "pand xmm4, xmm7\n" + "pand xmm5, xmm7\n" - "shufps xmm1, xmm2, 0xe4\n" // upper 8 colors - "movdqa xmm2, xmm0\n" - "movdqa xmm3, xmm1\n" + "shufps xmm1, xmm2, 0xe4\n" // upper 8 colors + "movdqa xmm2, xmm0\n" + "movdqa xmm3, xmm1\n" - "punpcklwd xmm0, xmm6\n" - "punpcklwd xmm1, xmm6\n" - "por xmm0, xmm4\n" - "por xmm1, xmm5\n" + "punpcklwd xmm0, xmm6\n" + "punpcklwd xmm1, xmm6\n" + "por xmm0, xmm4\n" + "por xmm1, xmm5\n" - "punpckhwd xmm2, xmm6\n" - "punpckhwd xmm3, xmm6\n" + "punpckhwd xmm2, xmm6\n" + "punpckhwd xmm3, xmm6\n" - "movdqa [edx], xmm0\n" - "movdqa [edx+32], xmm1\n" + "movdqa [edx], xmm0\n" + "movdqa [edx+32], xmm1\n" - "movdqa xmm5, xmm7\n" - "pand xmm7, [edx+16]\n" - "pand xmm5, [edx+48]\n" + "movdqa xmm5, xmm7\n" + "pand xmm7, [edx+16]\n" + "pand xmm5, [edx+48]\n" - "por xmm2, xmm7\n" - "por xmm3, xmm5\n" + "por xmm2, xmm7\n" + "por xmm3, xmm5\n" - "movdqa [edx+16], xmm2\n" - "movdqa [edx+48], xmm3\n" - "jmp WriteCLUT_T16_I4_CSM1_End\n" + "movdqa [edx+16], xmm2\n" + "movdqa [edx+48], xmm3\n" + "jmp WriteCLUT_T16_I4_CSM1_End\n" -"WriteUnaligned:\n" - // %edx is offset by 2 - "sub edx, 2\n" + "WriteUnaligned:\n" + // %edx is offset by 2 + "sub edx, 2\n" - "movdqa xmm7, [%[s_clut16mask2]]\n" // saves lower 16 bits + "movdqa xmm7, [%[s_clut16mask2]]\n" // saves lower 16 bits - // have to save interlaced with the old data - "movdqa xmm4, [edx]\n" - "movdqa xmm5, [edx+32]\n" - "movhlps xmm1, xmm0\n" - "movlhps xmm0, xmm2\n" // lower 8 colors + // have to save interlaced with the old data + "movdqa xmm4, [edx]\n" + "movdqa xmm5, [edx+32]\n" + "movhlps xmm1, xmm0\n" + "movlhps xmm0, xmm2\n" // lower 8 colors - "pand xmm4, xmm7\n" - "pand xmm5, xmm7\n" + "pand xmm4, xmm7\n" + "pand xmm5, xmm7\n" - "shufps xmm1, xmm2, 0xe4\n" // upper 8 colors - "movdqa xmm2, xmm0\n" - "movdqa xmm3, xmm1\n" + "shufps xmm1, xmm2, 0xe4\n" // upper 8 colors + "movdqa xmm2, xmm0\n" + "movdqa xmm3, xmm1\n" - "punpcklwd xmm0, xmm6\n" - "punpcklwd xmm1, xmm6\n" - "pslld xmm0, 16\n" - "pslld xmm1, 16\n" - "por xmm0, xmm4\n" - "por xmm1, xmm5\n" + "punpcklwd xmm0, xmm6\n" + "punpcklwd xmm1, xmm6\n" + "pslld xmm0, 16\n" + "pslld xmm1, 16\n" + "por xmm0, xmm4\n" + "por xmm1, xmm5\n" - "punpckhwd xmm2, xmm6\n" - "punpckhwd xmm3, xmm6\n" - "pslld xmm2, 16\n" - "pslld xmm3, 16\n" + "punpckhwd xmm2, xmm6\n" + "punpckhwd xmm3, xmm6\n" + "pslld xmm2, 16\n" + "pslld xmm3, 16\n" - "movdqa [edx], xmm0\n" - "movdqa [edx+32], xmm1\n" + "movdqa [edx], xmm0\n" + "movdqa [edx+32], xmm1\n" - "movdqa xmm5, xmm7\n" - "pand xmm7, [edx+16]\n" - "pand xmm5, [edx+48]\n" + "movdqa xmm5, xmm7\n" + "pand xmm7, [edx+16]\n" + "pand xmm5, [edx+48]\n" - "por xmm2, xmm7\n" - "por xmm3, xmm5\n" + "por xmm2, xmm7\n" + "por xmm3, xmm5\n" - "movdqa [edx+16], xmm2\n" - "movdqa [edx+48], xmm3\n" -"WriteCLUT_T16_I4_CSM1_End:\n" - ".att_syntax\n" - : [s_clut16mask]"=m"(s_clut16mask), [s_clut16mask2]"=m"(s_clut16mask2) - ); + "movdqa [edx+16], xmm2\n" + "movdqa [edx+48], xmm3\n" + "WriteCLUT_T16_I4_CSM1_End:\n" + ".att_syntax\n" + +: [s_clut16mask]"=m"(s_clut16mask), [s_clut16mask2]"=m"(s_clut16mask2) + ); #endif // _MSC_VER } + #endif // ZEROGS_SSE2 void __fastcall WriteCLUT_T16_I8_CSM1_c(u32* _vm, u32* _clut) @@ -559,27 +565,31 @@ void __fastcall WriteCLUT_T16_I8_CSM1_c(u32* _vm, u32* _clut) u16* vm = (u16*)_vm; u16* clut = (u16*)_clut; - int left = ((u32)(uptr)clut&2) ? 512 : 512-(((u32)(uptr)clut)&0x3ff)/2; + int left = ((u32)(uptr)clut & 2) ? 512 : 512 - (((u32)(uptr)clut) & 0x3ff) / 2; - for(int j = 0; j < 8; j++, vm += 32, clut += 64, left -= 32) + for (int j = 0; j < 8; j++, vm += 32, clut += 64, left -= 32) { - if(left == 32) { - assert( left == 32 ); - for(int i = 0; i < 16; i++) + if (left == 32) + { + assert(left == 32); + + for (int i = 0; i < 16; i++) clut[2*i] = vm[map[i]]; clut = (u16*)((uptr)clut & ~0x3ff) + 1; - for(int i = 16; i < 32; i++) + for (int i = 16; i < 32; i++) clut[2*i] = vm[map[i]]; } - else { - if( left == 0 ) { + else + { + if (left == 0) + { clut = (u16*)((uptr)clut & ~0x3ff) + 1; left = -1; } - for(int i = 0; i < 32; i++) + for (int i = 0; i < 32; i++) clut[2*i] = vm[map[i]]; } } @@ -590,8 +600,9 @@ void __fastcall WriteCLUT_T32_I8_CSM1_c(u32* vm, u32* clut) u64* src = (u64*)vm; u64* dst = (u64*)clut; - for(int j = 0; j < 2; j++, src += 32) { - for(int i = 0; i < 4; i++, dst+=16, src+=8) + for (int j = 0; j < 2; j++, src += 32) + { + for (int i = 0; i < 4; i++, dst += 16, src += 8) { dst[0] = src[0]; dst[1] = src[2]; @@ -619,14 +630,22 @@ void __fastcall WriteCLUT_T16_I4_CSM1_c(u32* _vm, u32* _clut) u16* dst = (u16*)_clut; u16* src = (u16*)_vm; - dst[0] = src[0]; dst[2] = src[2]; - dst[4] = src[8]; dst[6] = src[10]; - dst[8] = src[16]; dst[10] = src[18]; - dst[12] = src[24]; dst[14] = src[26]; - dst[16] = src[4]; dst[18] = src[6]; - dst[20] = src[12]; dst[22] = src[14]; - dst[24] = src[20]; dst[26] = src[22]; - dst[28] = src[28]; dst[30] = src[30]; + dst[0] = src[0]; + dst[2] = src[2]; + dst[4] = src[8]; + dst[6] = src[10]; + dst[8] = src[16]; + dst[10] = src[18]; + dst[12] = src[24]; + dst[14] = src[26]; + dst[16] = src[4]; + dst[18] = src[6]; + dst[20] = src[12]; + dst[22] = src[14]; + dst[24] = src[20]; + dst[26] = src[22]; + dst[28] = src[28]; + dst[30] = src[30]; } void __fastcall WriteCLUT_T32_I4_CSM1_c(u32* vm, u32* clut) @@ -644,10 +663,12 @@ void __fastcall WriteCLUT_T32_I4_CSM1_c(u32* vm, u32* clut) dst[7] = src[7]; } -void SSE2_UnswizzleZ16Target( u16* dst, u16* src, int iters ) { +void SSE2_UnswizzleZ16Target(u16* dst, u16* src, int iters) +{ #if defined(_MSC_VER) - __asm { + __asm + { mov edx, iters pxor xmm7, xmm7 mov eax, dst @@ -698,51 +719,52 @@ Z16Loop: #else // _MSC_VER __asm__(".intel_syntax\n" - "pxor %%xmm7, %%xmm7\n" + "pxor %%xmm7, %%xmm7\n" - "Z16Loop:\n" - // unpack 64 bytes at a time - "movdqa %%xmm0, [%0]\n" - "movdqa %%xmm2, [%0+16]\n" - "movdqa %%xmm4, [%0+32]\n" - "movdqa %%xmm6, [%0+48]\n" + "Z16Loop:\n" + // unpack 64 bytes at a time + "movdqa %%xmm0, [%0]\n" + "movdqa %%xmm2, [%0+16]\n" + "movdqa %%xmm4, [%0+32]\n" + "movdqa %%xmm6, [%0+48]\n" - "movdqa %%xmm1, %%xmm0\n" - "movdqa %%xmm3, %%xmm2\n" - "movdqa %%xmm5, %%xmm4\n" + "movdqa %%xmm1, %%xmm0\n" + "movdqa %%xmm3, %%xmm2\n" + "movdqa %%xmm5, %%xmm4\n" - "punpcklwd %%xmm0, %%xmm7\n" - "punpckhwd %%xmm1, %%xmm7\n" - "punpcklwd %%xmm2, %%xmm7\n" - "punpckhwd %%xmm3, %%xmm7\n" + "punpcklwd %%xmm0, %%xmm7\n" + "punpckhwd %%xmm1, %%xmm7\n" + "punpcklwd %%xmm2, %%xmm7\n" + "punpckhwd %%xmm3, %%xmm7\n" - // start saving - "movdqa [%1], %%xmm0\n" - "movdqa [%1+16], %%xmm1\n" + // start saving + "movdqa [%1], %%xmm0\n" + "movdqa [%1+16], %%xmm1\n" - "punpcklwd %%xmm4, %%xmm7\n" - "punpckhwd %%xmm5, %%xmm7\n" + "punpcklwd %%xmm4, %%xmm7\n" + "punpckhwd %%xmm5, %%xmm7\n" - "movdqa [%1+32], %%xmm2\n" - "movdqa [%1+48], %%xmm3\n" + "movdqa [%1+32], %%xmm2\n" + "movdqa [%1+48], %%xmm3\n" - "movdqa %%xmm0, %%xmm6\n" - "punpcklwd %%xmm6, %%xmm7\n" + "movdqa %%xmm0, %%xmm6\n" + "punpcklwd %%xmm6, %%xmm7\n" - "movdqa [%1+64], %%xmm4\n" - "movdqa [%1+80], %%xmm5\n" + "movdqa [%1+64], %%xmm4\n" + "movdqa [%1+80], %%xmm5\n" - "punpckhwd %%xmm0, %%xmm7\n" + "punpckhwd %%xmm0, %%xmm7\n" - "movdqa [%1+96], %%xmm6\n" - "movdqa [%1+112], %%xmm0\n" + "movdqa [%1+96], %%xmm6\n" + "movdqa [%1+112], %%xmm0\n" - "add %0, 64\n" - "add %1, 128\n" - "sub %2, 1\n" - "jne Z16Loop\n" - ".att_syntax\n" : "=r"(src), "=r"(dst), "=r"(iters) : "0"(src), "1"(dst), "2"(iters) - ); + "add %0, 64\n" + "add %1, 128\n" + "sub %2, 1\n" + "jne Z16Loop\n" + +".att_syntax\n" : "=r"(src), "=r"(dst), "=r"(iters) : "0"(src), "1"(dst), "2"(iters) + ); #endif // _MSC_VER } diff --git a/plugins/zzogl-pg/opengl/zerogs.cpp b/plugins/zzogl-pg/opengl/zerogs.cpp index 562bd7b5db..44eaa5e133 100644 --- a/plugins/zzogl-pg/opengl/zerogs.cpp +++ b/plugins/zzogl-pg/opengl/zerogs.cpp @@ -42,9 +42,10 @@ //----------------------- Defines //-------------------------- Typedefs -typedef void (APIENTRYP _PFNSWAPINTERVAL) (int); +typedef void (APIENTRYP _PFNSWAPINTERVAL)(int); //-------------------------- Extern variables + using namespace ZeroGS; extern u32 g_nGenVars, g_nTexVars, g_nAlphaVars, g_nResolve; @@ -54,8 +55,8 @@ extern int g_nFrame, g_nRealFrame; //-------------------------- Variables #ifdef _WIN32 -HDC hDC=NULL; // Private GDI Device Context -HGLRC hRC=NULL; // Permanent Rendering Context +HDC hDC = NULL; // Private GDI Device Context +HGLRC hRC = NULL; // Permanent Rendering Context #endif bool g_bIsLost = 0; // ZZ @@ -115,79 +116,91 @@ u8* g_pbyGSClut = NULL; // ZZ namespace ZeroGS { - Vector g_vdepth, vlogz; +Vector g_vdepth, vlogz; // = Vector( 255.0 /256.0f, 255.0/65536.0f, 255.0f/(65535.0f*256.0f), 1.0f/(65536.0f*65536.0f)); // Vector g_vdepth = Vector( 65536.0f*65536.0f, 256.0f*65536.0f, 65536.0f, 256.0f); - extern CRangeManager s_RangeMngr; // manages overwritten memory - GLenum GetRenderTargetFormat() { return GetRenderFormat()==RFT_byte8?4:g_internalRGBAFloat16Fmt; } +extern CRangeManager s_RangeMngr; // manages overwritten memory +GLenum GetRenderTargetFormat() { return GetRenderFormat() == RFT_byte8 ? 4 : g_internalRGBAFloat16Fmt; } - // returns the first and last addresses aligned to a page that cover - void GetRectMemAddress(int& start, int& end, int psm, int x, int y, int w, int h, int bp, int bw); +// returns the first and last addresses aligned to a page that cover +void GetRectMemAddress(int& start, int& end, int psm, int x, int y, int w, int h, int bp, int bw); // bool LoadEffects(); // bool LoadExtraEffects(); // FRAGMENTSHADER* LoadShadeEffect(int type, int texfilter, int fog, int testaem, int exactcolor, const clampInfo& clamp, int context, bool* pbFailed); - int s_nNewWidth = -1, s_nNewHeight = -1; - void ChangeDeviceSize(int nNewWidth, int nNewHeight); +int s_nNewWidth = -1, s_nNewHeight = -1; +void ChangeDeviceSize(int nNewWidth, int nNewHeight); - void ProcessMessages(); - void RenderCustom(float fAlpha); // intro anim +void ProcessMessages(); +void RenderCustom(float fAlpha); // intro anim - struct MESSAGE - { - MESSAGE() {} - MESSAGE(const char* p, u32 dw) { strcpy(str, p); dwTimeStamp = dw; } - char str[255]; - u32 dwTimeStamp; - }; +struct MESSAGE +{ + MESSAGE() {} - static list listMsgs; + MESSAGE(const char* p, u32 dw) { strcpy(str, p); dwTimeStamp = dw; } - /////////////////////// - // Method Prototypes // - /////////////////////// + char str[255]; + u32 dwTimeStamp; +}; - void KickPoint(); - void KickLine(); - void KickTriangle(); - void KickTriangleFan(); - void KickSprite(); - void KickDummy(); +static list listMsgs; - void ResolveInRange(int start, int end); +/////////////////////// +// Method Prototypes // +/////////////////////// - void ExtWrite(); +void KickPoint(); +void KickLine(); +void KickTriangle(); +void KickTriangleFan(); +void KickSprite(); +void KickDummy(); - void ResetRenderTarget(int index) { - glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT+index, GL_TEXTURE_RECTANGLE_NV, 0, 0 ); - } +void ResolveInRange(int start, int end); - DrawFn drawfn[8] = { KickDummy, KickDummy, KickDummy, KickDummy, - KickDummy, KickDummy, KickDummy, KickDummy }; +void ExtWrite(); + +void ResetRenderTarget(int index) +{ + glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + index, GL_TEXTURE_RECTANGLE_NV, 0, 0); +} + +DrawFn drawfn[8] = { KickDummy, KickDummy, KickDummy, KickDummy, + KickDummy, KickDummy, KickDummy, KickDummy + }; }; // end namespace // does one time only initializing/destruction + class ZeroGSInit { -public: - ZeroGSInit() { - // clear - g_pbyGSMemory = (u8*)_aligned_malloc(0x00410000, 1024); // leave some room for out of range accesses (saves on the checks) - memset(g_pbyGSMemory, 0, 0x00410000); - g_pbyGSClut = (u8*)_aligned_malloc(256*8, 1024); // need 512 alignment! - memset(g_pbyGSClut, 0, 256*8); + public: + ZeroGSInit() + { + const u32 mem_size = 0x00400000 + 0x10000; // leave some room for out of range accesses (saves on the checks) + // clear + g_pbyGSMemory = (u8*)_aligned_malloc(mem_size, 1024); + memset(g_pbyGSMemory, 0, mem_size); - memset(&GLWin, 0, sizeof(GLWin)); - } - ~ZeroGSInit() { - _aligned_free(g_pbyGSMemory); g_pbyGSMemory = NULL; - _aligned_free(g_pbyGSClut); g_pbyGSClut = NULL; - } + g_pbyGSClut = (u8*)_aligned_malloc(256 * 8, 1024); // need 512 alignment! + memset(g_pbyGSClut, 0, 256*8); + memset(&GLWin, 0, sizeof(GLWin)); + } + + ~ZeroGSInit() + { + _aligned_free(g_pbyGSMemory); + g_pbyGSMemory = NULL; + + _aligned_free(g_pbyGSClut); + g_pbyGSClut = NULL; + } }; static ZeroGSInit s_ZeroGSInit; @@ -203,41 +216,52 @@ void ZeroGS::HandleGLError() GLenum error = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); // if error != GL_FRAMEBUFFER_COMPLETE_EXT, there's an error of some sort - if( error != 0 ) { + + if (error != 0) + { int w, h; GLint fmt; glGetRenderbufferParameterivEXT(GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_INTERNAL_FORMAT_EXT, &fmt); glGetRenderbufferParameterivEXT(GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_WIDTH_EXT, &w); glGetRenderbufferParameterivEXT(GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_HEIGHT_EXT, &h); - switch(error) + switch (error) { case GL_FRAMEBUFFER_COMPLETE_EXT: break; + case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: ZZLog::Error_Log("Error! missing a required image/buffer attachment!"); break; + case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: ZZLog::Error_Log("Error! has no images/buffers attached!"); break; + // case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT: // ZZLog::Error_Log("Error! has an image/buffer attached in multiple locations!"); // break; + case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: ZZLog::Error_Log("Error! has mismatched image/buffer dimensions!"); break; + case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: ZZLog::Error_Log("Error! colorbuffer attachments have different types!"); break; + case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: ZZLog::Error_Log("Error! trying to draw to non-attached color buffer!"); break; + case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: ZZLog::Error_Log("Error! trying to read from a non-attached color buffer!"); break; + case GL_FRAMEBUFFER_UNSUPPORTED_EXT: ZZLog::Error_Log("Error! format is not supported by current graphics card/driver!"); break; + default: ZZLog::Error_Log("*UNKNOWN ERROR* reported from glCheckFramebufferStatusEXT() for %s!"); break; @@ -251,7 +275,8 @@ void ZeroGS::GSStateReset() FUNCLOG icurctx = -1; - for(int i = 0; i < 2; ++i) { + for (int i = 0; i < 2; ++i) + { vb[i].Destroy(); memset(&vb[i], 0, sizeof(ZeroGS::VB)); @@ -264,6 +289,7 @@ void ZeroGS::GSStateReset() } s_RangeMngr.Clear(); + g_MemTargs.Destroy(); s_RTs.Destroy(); s_DepthRTs.Destroy(); @@ -276,7 +302,8 @@ void ZeroGS::GSStateReset() void ZeroGS::AddMessage(const char* pstr, u32 ms) { FUNCLOG - listMsgs.push_back(MESSAGE(pstr, timeGetTime()+ms)); + listMsgs.push_back(MESSAGE(pstr, timeGetTime() + ms)); + ZZLog::Log("%s\n", pstr); } void ZeroGS::DrawText(const char* pstr, int left, int top, u32 color) @@ -285,9 +312,12 @@ void ZeroGS::DrawText(const char* pstr, int left, int top, u32 color) cgGLDisableProfile(cgvProf); cgGLDisableProfile(cgfProf); - glColor3f(((color>>16)&0xff)/255.0f, ((color>>8)&0xff)/255.0f, (color&0xff)/255.0f); + Vector v; + v.SetColor(color); + glColor3f(v.z, v.y, v.x); + //glColor3f(((color >> 16) & 0xff) / 255.0f, ((color >> 8) & 0xff)/ 255.0f, (color & 0xff) / 255.0f); - font_p->printString(pstr, left * 2.0f / (float)nBackbufferWidth - 1, 1 - top * 2.0f / (float)nBackbufferHeight,0); + font_p->printString(pstr, left * 2.0f / (float)nBackbufferWidth - 1, 1 - top * 2.0f / (float)nBackbufferHeight, 0); cgGLEnableProfile(cgvProf); cgGLEnableProfile(cgfProf); } @@ -295,10 +325,11 @@ void ZeroGS::DrawText(const char* pstr, int left, int top, u32 color) void ZeroGS::ChangeWindowSize(int nNewWidth, int nNewHeight) { FUNCLOG - nBackbufferWidth = nNewWidth > 16 ? nNewWidth : 16; - nBackbufferHeight = nNewHeight > 16 ? nNewHeight : 16; + nBackbufferWidth = max(nNewWidth, 16); + nBackbufferHeight = max(nNewHeight, 16); - if( !(conf.options & GSOPTION_FULLSCREEN) ) { + if (!(conf.options & GSOPTION_FULLSCREEN)) + { conf.width = nNewWidth; conf.height = nNewHeight; //SaveConfig(); @@ -311,7 +342,8 @@ void ZeroGS::SetChangeDeviceSize(int nNewWidth, int nNewHeight) s_nNewWidth = nNewWidth; s_nNewHeight = nNewHeight; - if( !(conf.options & GSOPTION_FULLSCREEN) ) { + if (!(conf.options & GSOPTION_FULLSCREEN)) + { conf.width = nNewWidth; conf.height = nNewHeight; //SaveConfig(); @@ -352,26 +384,30 @@ void ZeroGS::ChangeDeviceSize(int nNewWidth, int nNewHeight) //int oldscreen = s_nFullscreen; int oldwidth = nBackbufferWidth, oldheight = nBackbufferHeight; - if (!Create(nNewWidth&~7, nNewHeight&~7)) + + if (!Create(nNewWidth&~7, nNewHeight&~7)) { ZZLog::Error_Log("Failed to recreate, changing to old device."); - if ( Create(oldwidth, oldheight)) + + if (Create(oldwidth, oldheight)) { SysMessage("Failed to create device, exiting..."); exit(0); } } - for(int i = 0; i < 2; ++i) { + for (int i = 0; i < 2; ++i) + { vb[i].bNeedFrameCheck = vb[i].bNeedZCheck = 1; vb[i].CheckFrame(0); } - assert( vb[0].pBufferData != NULL && vb[1].pBufferData != NULL ); + assert(vb[0].pBufferData != NULL && vb[1].pBufferData != NULL); } -void ZeroGS::SetNegAA(int mode) { +void ZeroGS::SetNegAA(int mode) +{ FUNCLOG // need to flush all targets s_RTs.ResolveAll(); @@ -380,17 +416,25 @@ void ZeroGS::SetNegAA(int mode) { s_DepthRTs.Destroy(); s_AAz = s_AAw = 0; // This is code for x0, x2, x4, x8 and x16 anti-aliasing. + if (mode > 0) { - s_AAz = (mode+1) / 2; // ( 1, 0 ) ; ( 1, 1 ) -- it's used as binary shift, so x << s_AAz, y << s_AAw + s_AAz = (mode + 1) / 2; // ( 1, 0 ) ; ( 1, 1 ) -- it's used as binary shift, so x << s_AAz, y << s_AAw s_AAw = mode / 2; } memset(s_nResolveCounts, 0, sizeof(s_nResolveCounts)); + s_nLastResolveReset = 0; - vb[0].prndr = NULL; vb[0].pdepth = NULL; vb[0].bNeedFrameCheck = 1; vb[0].bNeedZCheck = 1; - vb[1].prndr = NULL; vb[1].pdepth = NULL; vb[1].bNeedFrameCheck = 1; vb[1].bNeedZCheck = 1; + vb[0].prndr = NULL; + vb[0].pdepth = NULL; + vb[0].bNeedFrameCheck = 1; + vb[0].bNeedZCheck = 1; + vb[1].prndr = NULL; + vb[1].pdepth = NULL; + vb[1].bNeedFrameCheck = 1; + vb[1].bNeedZCheck = 1; } void ZeroGS::SetAA(int mode) @@ -405,32 +449,40 @@ void ZeroGS::SetAA(int mode) s_DepthRTs.Destroy(); s_AAx = s_AAy = 0; // This is code for x0, x2, x4, x8 and x16 anti-aliasing. + if (mode > 0) { - s_AAx = (mode+1) / 2; // ( 1, 0 ) ; ( 1, 1 ) ; ( 2, 1 ) ; ( 2, 2 ) -- it's used as binary shift, so x >> s_AAx, y >> s_AAy + s_AAx = (mode + 1) / 2; // ( 1, 0 ) ; ( 1, 1 ) ; ( 2, 1 ) ; ( 2, 2 ) -- it's used as binary shift, so x >> s_AAx, y >> s_AAy s_AAy = mode / 2; } memset(s_nResolveCounts, 0, sizeof(s_nResolveCounts)); + s_nLastResolveReset = 0; - vb[0].prndr = NULL; vb[0].pdepth = NULL; vb[0].bNeedFrameCheck = 1; vb[0].bNeedZCheck = 1; - vb[1].prndr = NULL; vb[1].pdepth = NULL; vb[1].bNeedFrameCheck = 1; vb[1].bNeedZCheck = 1; + vb[0].prndr = NULL; + vb[0].pdepth = NULL; + vb[0].bNeedFrameCheck = 1; + vb[0].bNeedZCheck = 1; + vb[1].prndr = NULL; + vb[1].pdepth = NULL; + vb[1].bNeedFrameCheck = 1; + vb[1].bNeedZCheck = 1; f = mode > 0 ? 2.0f : 1.0f; glPointSize(f); } -void ZeroGS::Prim(){ +void ZeroGS::Prim() +{ FUNCLOG - if( g_bIsLost ) - return; + + if (g_bIsLost) return; VB& curvb = vb[prim->ctxt]; - if( curvb.CheckPrim() ){ - Flush(prim->ctxt); - } + if (curvb.CheckPrim()) Flush(prim->ctxt); + curvb.curprim._val = prim->_val; // flush the other pipe if sharing the same buffer @@ -446,16 +498,19 @@ void ZeroGS::Prim(){ void ZeroGS::ProcessMessages() { FUNCLOG - if( listMsgs.size() > 0 ) { + + if (listMsgs.size() > 0) + { int left = 25, top = 15; list::iterator it = listMsgs.begin(); - while( it != listMsgs.end() ) { - DrawText(it->str, left+1, top+1, 0xff000000); + while (it != listMsgs.end()) + { + DrawText(it->str, left + 1, top + 1, 0xff000000); DrawText(it->str, left, top, 0xffffff30); top += 15; - if( (int)(it->dwTimeStamp - timeGetTime()) < 0 ) + if ((int)(it->dwTimeStamp - timeGetTime()) < 0) it = listMsgs.erase(it); else ++it; } @@ -468,7 +523,7 @@ void ZeroGS::RenderCustom(float fAlpha) GL_REPORT_ERROR(); fAlpha = 1; - glBindFramebufferEXT( GL_FRAMEBUFFER_EXT, 0 ); // switch to the backbuffer + glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); // switch to the backbuffer DisableAllgl() ; SetShaderCaller("RenderCustom"); @@ -476,10 +531,10 @@ void ZeroGS::RenderCustom(float fAlpha) glViewport(0, 0, nBackbufferWidth, nBackbufferHeight); // play custom animation - glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT|GL_STENCIL_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); // tex coords - Vector v = Vector(1/32767.0f, 1/32767.0f, 0, 0); + Vector v = Vector(1 / 32767.0f, 1 / 32767.0f, 0, 0); ZZcgSetParameter4fv(pvsBitBlt.sBitBltPos, v, "g_fBitBltPos"); v.x = (float)nLogoWidth; v.y = (float)nLogoHeight; @@ -488,25 +543,26 @@ void ZeroGS::RenderCustom(float fAlpha) v.x = v.y = v.z = v.w = fAlpha; ZZcgSetParameter4fv(ppsBaseTexture.sOneColor, v, "g_fOneColor"); - if( conf.options & GSOPTION_WIREFRAME ) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + if (conf.options & GSOPTION_WIREFRAME) glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); // inside vhDCb[0]'s target area, so render that region only cgGLSetTextureParameter(ppsBaseTexture.sFinal, ptexLogo); cgGLEnableTextureParameter(ppsBaseTexture.sFinal); - glBindBuffer(GL_ARRAY_BUFFER, vboRect); + SET_STREAM(); SETVERTEXSHADER(pvsBitBlt.prog); SETPIXELSHADER(ppsBaseTexture.prog); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); // restore - if( conf.options & GSOPTION_WIREFRAME ) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); + if (conf.options & GSOPTION_WIREFRAME) glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); ProcessMessages(); - GLWin.SwapGLBuffers(); + GLWin.SwapGLBuffers(); glEnable(GL_SCISSOR_TEST); glEnable(GL_STENCIL_TEST); @@ -515,20 +571,24 @@ void ZeroGS::RenderCustom(float fAlpha) vb[1].bSyncVars = 0; GL_REPORT_ERROR(); + GLint status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); - assert( status == GL_FRAMEBUFFER_COMPLETE_EXT || status == GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT ); + + assert(status == GL_FRAMEBUFFER_COMPLETE_EXT || status == GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT); } void ZeroGS::Restore() { FUNCLOG - if( !g_bIsLost ) - return; + + if (!g_bIsLost) return; //if( SUCCEEDED(pd3dDevice->Reset(&d3dpp)) ) { - g_bIsLost = 0; - // handle lost states - ZeroGS::ChangeDeviceSize(nBackbufferWidth, nBackbufferHeight); + g_bIsLost = 0; + + // handle lost states + ZeroGS::ChangeDeviceSize(nBackbufferWidth, nBackbufferHeight); + //} } @@ -539,48 +599,51 @@ void ZeroGS::Restore() __forceinline void MOVZ(VertexGPU *p, u32 gsz, const VB& curvb) { - p->z = (curvb.zprimmask==0xffff) ? min((u32)0xffff, gsz) : gsz; + p->z = (curvb.zprimmask == 0xffff) ? min((u32)0xffff, gsz) : gsz; } __forceinline void MOVFOG(VertexGPU *p, Vertex gsf) { - p->f = ((s16)(gsf).f<<7)|0x7f; + p->f = ((s16)(gsf).f << 7) | 0x7f; } -int Values[100]={0,}; +int Values[100] = {0, }; __forceinline void SET_VERTEX(VertexGPU *p, int Index, const VB& curvb) { int index = Index; p->x = ((((int)gs.gsvertex[index].x - curvb.offset.x) >> 1) & 0xffff); p->y = ((((int)gs.gsvertex[index].y - curvb.offset.y) >> 1) & 0xffff); - + #ifdef LSD_MODE int diffX = (int)gs.gsvertex[index].x - curvb.offset.x; int diffY = (int)gs.gsvertex[index].y - curvb.offset.y; - + if (diffX < 0) { p->x = - p->x; } if (diffY < 0) { p->y = - p->y; } #endif - p->f = ((s16)gs.gsvertex[index].f<<7)|0x7f; + p->f = ((s16)gs.gsvertex[index].f << 7) | 0x7f; + MOVZ(p, gs.gsvertex[index].z, curvb); + p->rgba = prim->iip ? gs.gsvertex[index].rgba : gs.rgba; // This code is somehow incorrect // if ((gs.texa.aem) && ((p->rgba & 0xffffff ) == 0)) // p->rgba = 0; - if (g_GameSettings & GAME_TEXAHACK) { - u32 B = (( p->rgba & 0xfe000000 ) >> 1) + - (0x01000000 * curvb.fba.fba) ; - p->rgba = ( p->rgba & 0xffffff ) + B; + if (g_GameSettings & GAME_TEXAHACK) + { + u32 B = ((p->rgba & 0xfe000000) >> 1) + + (0x01000000 * curvb.fba.fba) ; + p->rgba = (p->rgba & 0xffffff) + B; } - if (prim->tme ) + if (prim->tme) { - if( prim->fst ) + if (prim->fst) { p->s = (float)gs.gsvertex[index].u * fiTexWidth[prim->ctxt]; p->t = (float)gs.gsvertex[index].v * fiTexHeight[prim->ctxt]; @@ -598,31 +661,32 @@ __forceinline void SET_VERTEX(VertexGPU *p, int Index, const VB& curvb) static __forceinline void OUTPUT_VERT(VertexGPU vert, u32 id) { #ifdef WRITE_PRIM_LOGS - ZZLog::Prim_Log("%c%d(%d): xyzf=(%4d,%4d,0x%x,%3d), rgba=0x%8.8x, stq = (%2.5f,%2.5f,%2.5f)\n", - id==0?'*':' ', id, prim->prim, vert.x/8, vert.y/8, vert.z, vert.f/128, - vert.rgba, Clamp(vert.s, -10, 10), Clamp(vert.t, -10, 10), Clamp(vert.q, -10, 10)); + ZZLog::Prim_Log("%c%d(%d): xyzf=(%4d,%4d,0x%x,%3d), rgba=0x%8.8x, stq = (%2.5f,%2.5f,%2.5f)\n", + id == 0 ? '*' : ' ', id, prim->prim, vert.x / 8, vert.y / 8, vert.z, vert.f / 128, + vert.rgba, Clamp(vert.s, -10, 10), Clamp(vert.t, -10, 10), Clamp(vert.q, -10, 10)); #endif } void ZeroGS::KickPoint() { FUNCLOG - assert( gs.primC >= 1 ); + assert(gs.primC >= 1); VB& curvb = vb[prim->ctxt]; + if (curvb.bNeedTexCheck) curvb.FlushTexData(); if ((vb[!prim->ctxt].nCount > 0) && (vb[prim->ctxt].gsfb.fbp == vb[!prim->ctxt].gsfb.fbp)) { - assert( vb[prim->ctxt].nCount == 0 ); + assert(vb[prim->ctxt].nCount == 0); Flush(!prim->ctxt); } curvb.NotifyWrite(1); - int last = (gs.primIndex+2)%ARRAY_SIZE(gs.gsvertex); + int last = (gs.primIndex + 2) % ARRAY_SIZE(gs.gsvertex); - VertexGPU* p = curvb.pBufferData+curvb.nCount; + VertexGPU* p = curvb.pBufferData + curvb.nCount; SET_VERTEX(&p[0], last, curvb); curvb.nCount++; @@ -632,23 +696,23 @@ void ZeroGS::KickPoint() void ZeroGS::KickLine() { FUNCLOG - assert( gs.primC >= 2 ); + assert(gs.primC >= 2); VB& curvb = vb[prim->ctxt]; - if( curvb.bNeedTexCheck ) - curvb.FlushTexData(); - if( vb[!prim->ctxt].nCount > 0 && vb[prim->ctxt].gsfb.fbp == vb[!prim->ctxt].gsfb.fbp ) + if (curvb.bNeedTexCheck) curvb.FlushTexData(); + + if ((vb[!prim->ctxt].nCount > 0) && (vb[prim->ctxt].gsfb.fbp == vb[!prim->ctxt].gsfb.fbp)) { - assert( vb[prim->ctxt].nCount == 0 ); + assert(vb[prim->ctxt].nCount == 0); Flush(!prim->ctxt); } curvb.NotifyWrite(2); - int next = (gs.primIndex+1)%ARRAY_SIZE(gs.gsvertex); - int last = (gs.primIndex+2)%ARRAY_SIZE(gs.gsvertex); + int next = (gs.primIndex + 1) % ARRAY_SIZE(gs.gsvertex); + int last = (gs.primIndex + 2) % ARRAY_SIZE(gs.gsvertex); - VertexGPU* p = curvb.pBufferData+curvb.nCount; + VertexGPU* p = curvb.pBufferData + curvb.nCount; SET_VERTEX(&p[0], next, curvb); SET_VERTEX(&p[1], last, curvb); @@ -661,19 +725,20 @@ void ZeroGS::KickLine() void ZeroGS::KickTriangle() { FUNCLOG - assert( gs.primC >= 3 ); + assert(gs.primC >= 3); VB& curvb = vb[prim->ctxt]; + if (curvb.bNeedTexCheck) curvb.FlushTexData(); if ((vb[!prim->ctxt].nCount > 0) && (vb[prim->ctxt].gsfb.fbp == vb[!prim->ctxt].gsfb.fbp)) { - assert( vb[prim->ctxt].nCount == 0 ); + assert(vb[prim->ctxt].nCount == 0); Flush(!prim->ctxt); } curvb.NotifyWrite(3); - VertexGPU* p = curvb.pBufferData+curvb.nCount; + VertexGPU* p = curvb.pBufferData + curvb.nCount; SET_VERTEX(&p[0], 0, curvb); SET_VERTEX(&p[1], 1, curvb); SET_VERTEX(&p[2], 2, curvb); @@ -688,19 +753,20 @@ void ZeroGS::KickTriangle() void ZeroGS::KickTriangleFan() { FUNCLOG - assert( gs.primC >= 3 ); + assert(gs.primC >= 3); VB& curvb = vb[prim->ctxt]; + if (curvb.bNeedTexCheck) curvb.FlushTexData(); if ((vb[!prim->ctxt].nCount > 0) && (vb[prim->ctxt].gsfb.fbp == vb[!prim->ctxt].gsfb.fbp)) { - assert( vb[prim->ctxt].nCount == 0 ); + assert(vb[prim->ctxt].nCount == 0); Flush(!prim->ctxt); } curvb.NotifyWrite(3); - VertexGPU* p = curvb.pBufferData+curvb.nCount; + VertexGPU* p = curvb.pBufferData + curvb.nCount; SET_VERTEX(&p[0], 0, curvb); SET_VERTEX(&p[1], 1, curvb); SET_VERTEX(&p[2], 2, curvb); @@ -708,8 +774,8 @@ void ZeroGS::KickTriangleFan() curvb.nCount += 3; // add 1 to skip the first vertex - if (gs.primIndex == gs.nTriFanVert) - gs.primIndex = (gs.primIndex+1)%ARRAY_SIZE(gs.gsvertex); + + if (gs.primIndex == gs.nTriFanVert) gs.primIndex = (gs.primIndex + 1) % ARRAY_SIZE(gs.gsvertex); OUTPUT_VERT(p[0], 0); OUTPUT_VERT(p[1], 1); @@ -726,34 +792,36 @@ __forceinline void SetKickVertex(VertexGPU *p, Vertex v, int next, const VB& cur void ZeroGS::KickSprite() { FUNCLOG - assert( gs.primC >= 2 ); + assert(gs.primC >= 2); VB& curvb = vb[prim->ctxt]; if (curvb.bNeedTexCheck) curvb.FlushTexData(); if ((vb[!prim->ctxt].nCount > 0) && (vb[prim->ctxt].gsfb.fbp == vb[!prim->ctxt].gsfb.fbp)) { - assert( vb[prim->ctxt].nCount == 0 ); + assert(vb[prim->ctxt].nCount == 0); Flush(!prim->ctxt); } curvb.NotifyWrite(6); - int next = (gs.primIndex+1)%ARRAY_SIZE(gs.gsvertex); - int last = (gs.primIndex+2)%ARRAY_SIZE(gs.gsvertex); + int next = (gs.primIndex + 1) % ARRAY_SIZE(gs.gsvertex); + int last = (gs.primIndex + 2) % ARRAY_SIZE(gs.gsvertex); // sprite is too small and AA shows lines (tek4) - if ( s_AAx ) + + if (s_AAx) { gs.gsvertex[last].x += 4; - if( s_AAy ) gs.gsvertex[last].y += 4; + + if (s_AAy) gs.gsvertex[last].y += 4; } // might be bad sprite (KH dialog text) //if( gs.gsvertex[next].x == gs.gsvertex[last].x || gs.gsvertex[next].y == gs.gsvertex[last].y ) - //return; + //return; - VertexGPU* p = curvb.pBufferData+curvb.nCount; + VertexGPU* p = curvb.pBufferData + curvb.nCount; SetKickVertex(&p[0], gs.gsvertex[last], next, curvb); SetKickVertex(&p[3], gs.gsvertex[last], next, curvb); @@ -765,6 +833,7 @@ void ZeroGS::KickSprite() p[2].x = p[1].x; SetKickVertex(&p[5], gs.gsvertex[last], last, curvb); + p[5].s = p[0].s; p[5].x = p[0].x; @@ -783,26 +852,28 @@ void ZeroGS::KickDummy() void ZeroGS::SetFogColor(u32 fog) { FUNCLOG - + // Always set the fog color, even if it was already set. -// if (gs.fogcol != fog) +// if (gs.fogcol != fog) // { - gs.fogcol = fog; + gs.fogcol = fog; - ZeroGS::Flush(0); - ZeroGS::Flush(1); + ZeroGS::Flush(0); + ZeroGS::Flush(1); - if (!g_bIsLost) - { - SetShaderCaller("SetFogColor"); - Vector v; + if (!g_bIsLost) + { + SetShaderCaller("SetFogColor"); + Vector v; + + // set it immediately +// v.x = (gs.fogcol & 0xff) / 255.0f; +// v.y = ((gs.fogcol >> 8) & 0xff) / 255.0f; +// v.z = ((gs.fogcol >> 16) & 0xff) / 255.0f; + v.SetColor(gs.fogcol); + ZZcgSetParameter4fv(g_fparamFogColor, v, "g_fParamFogColor"); + } - // set it immediately - v.x = (gs.fogcol&0xff)/255.0f; - v.y = ((gs.fogcol>>8)&0xff)/255.0f; - v.z = ((gs.fogcol>>16)&0xff)/255.0f; - ZZcgSetParameter4fv(g_fparamFogColor, v, "g_fParamFogColor"); - } // } } @@ -862,7 +933,8 @@ bool IsDirty(u32 highdword, u32 psm, int cld, int cbp) // do a fast test with MMX #ifdef _MSC_VER int storeebx; - __asm { + __asm + { mov storeebx, ebx mov edx, dst mov ecx, src @@ -910,12 +982,14 @@ Continue: test ebx, 0x10 jz AddEcx sub ecx, 448 // go back and down one column, + AddEcx: add ecx, 256 // go to the right block jne Continue1 add ecx, 256 // skip whole block + Continue1: add edx, 64 sub ebx, 16 @@ -930,7 +1004,7 @@ Return: // do a fast test with MMX __asm__( ".intel_syntax\n" -"Start:\n" + "Start:\n" "movq %%mm0, [%%ecx]\n" "movq %%mm1, [%%ecx+8]\n" "pcmpeqd %%mm0, [%%edx]\n" @@ -961,27 +1035,28 @@ Return: "movb $1, %0\n" ".intel_syntax\n" "jmp Return\n" -"Continue:\n" + "Continue:\n" "cmp %%ebx, 16\n" "jle Return\n" "test %%ebx, 0x10\n" "jz AddEcx\n" "sub %%edx, 448\n" // go back and down one column -"AddEcx:\n" + "AddEcx:\n" "add %%edx, 256\n" // go to the right block "cmp %%ebx, 0x90\n" "jne Continue1\n" "add %%edx, 256\n" // skip whole block -"Continue1:\n" + "Continue1:\n" "add %%ecx, 64\n" "sub %%ebx, 16\n" "jmp Start\n" -"Return:\n" + "Return:\n" "emms\n" - ".att_syntax\n" : "=m"(bRet) : "c"(dst), "d"(src), "b"(entries) : "eax", "memory"); + + ".att_syntax\n" : "=m"(bRet) : "c"(dst), "d"(src), "b"(entries) : "eax", "memory"); #endif // _WIN32 -return bRet; + return bRet; } // cld state: @@ -1001,19 +1076,36 @@ bool ZeroGS::CheckChangeInClut(u32 highdword, u32 psm) // processing the CLUT after tex0/2 are written //ZZLog::Error_Log("high == 0x%x; cld == %d", highdword, cld); - switch(cld) { - case 0: return false; - case 1: break; - case 2: break; - case 3: break; - case 4: if (gs.cbp[0] == cbp) return false; break; - case 5: if (gs.cbp[1] == cbp) return false; break; - //case 4: return gs.cbp[0] != cbp; - //case 5: return gs.cbp[1] != cbp; + switch (cld) + { + case 0: + return false; - // default: load - default: break; + case 1: + break; + + case 2: + break; + + case 3: + break; + + case 4: + if (gs.cbp[0] == cbp) return false; + break; + + case 5: + if (gs.cbp[1] == cbp) return false; + break; + + //case 4: return gs.cbp[0] != cbp; + //case 5: return gs.cbp[1] != cbp; + + // default: load + + default: + break; } return IsDirty(highdword, psm, cld, cbp); @@ -1023,26 +1115,40 @@ void ZeroGS::texClutWrite(int ctx) { FUNCLOG s_bTexFlush = 0; + if (g_bIsLost) return; tex0Info& tex0 = vb[ctx].tex0; - assert( PSMT_ISCLUT(tex0.psm) ); + + assert(PSMT_ISCLUT(tex0.psm)); // processing the CLUT after tex0/2 are written - switch(tex0.cld) + switch (tex0.cld) { - case 0: return; - case 1: break; // tex0.cld is usually 1. - case 2: gs.cbp[0] = tex0.cbp; break; - case 3: gs.cbp[1] = tex0.cbp; break; + case 0: + return; + + case 1: + break; // tex0.cld is usually 1. + + case 2: + gs.cbp[0] = tex0.cbp; + break; + + case 3: + gs.cbp[1] = tex0.cbp; + break; + case 4: if (gs.cbp[0] == tex0.cbp) return; gs.cbp[0] = tex0.cbp; break; + case 5: if (gs.cbp[1] == tex0.cbp) return; gs.cbp[1] = tex0.cbp; break; + default: //ZZLog::Debug_Log("cld isn't 0-5!"); break; } @@ -1055,12 +1161,13 @@ void ZeroGS::texClutWrite(int ctx) { switch (tex0.cpsm) { - // 16bit psm - // eggomania uses non16bit textures for csm2 + // 16bit psm + // eggomania uses non16bit textures for csm2 + case PSMCT16: { - u16* src = (u16*)g_pbyGSMemory + tex0.cbp*128; - u16 *dst = (u16*)(g_pbyGSClut+32*(tex0.csa&15)+(tex0.csa>=16?2:0)); + u16* src = (u16*)g_pbyGSMemory + tex0.cbp * 128; + u16 *dst = (u16*)(g_pbyGSClut + 32 * (tex0.csa & 15) + (tex0.csa >= 16 ? 2 : 0)); for (int i = 0; i < entries; ++i) { @@ -1068,15 +1175,16 @@ void ZeroGS::texClutWrite(int ctx) dst += 2; // check for wrapping - if (((u32)(uptr)dst & 0x3ff) == 0) dst = (u16*)(g_pbyGSClut+2); + + if (((u32)(uptr)dst & 0x3ff) == 0) dst = (u16*)(g_pbyGSClut + 2); } break; } case PSMCT16S: { - u16* src = (u16*)g_pbyGSMemory + tex0.cbp*128; - u16 *dst = (u16*)(g_pbyGSClut+32*(tex0.csa&15)+(tex0.csa>=16?2:0)); + u16* src = (u16*)g_pbyGSMemory + tex0.cbp * 128; + u16 *dst = (u16*)(g_pbyGSClut + 32 * (tex0.csa & 15) + (tex0.csa >= 16 ? 2 : 0)); for (int i = 0; i < entries; ++i) { @@ -1084,27 +1192,29 @@ void ZeroGS::texClutWrite(int ctx) dst += 2; // check for wrapping - if (((u32)(uptr)dst & 0x3ff) == 0) dst = (u16*)(g_pbyGSClut+2); + + if (((u32)(uptr)dst & 0x3ff) == 0) dst = (u16*)(g_pbyGSClut + 2); } - break; + break; } case PSMCT32: case PSMCT24: { - u32* src = (u32*)g_pbyGSMemory + tex0.cbp*64; - u32 *dst = (u32*)(g_pbyGSClut+64*tex0.csa); + u32* src = (u32*)g_pbyGSMemory + tex0.cbp * 64; + u32 *dst = (u32*)(g_pbyGSClut + 64 * tex0.csa); // check if address exceeds src - if( src+getPixelAddress32_0(gs.clut.cou+entries-1, gs.clut.cov, gs.clut.cbw) >= (u32*)g_pbyGSMemory + 0x00100000 ) + + if (src + getPixelAddress32_0(gs.clut.cou + entries - 1, gs.clut.cov, gs.clut.cbw) >= (u32*)g_pbyGSMemory + 0x00100000) ZZLog::Error_Log("texClutWrite out of bounds."); else - for(int i = 0; i < entries; ++i) + for (int i = 0; i < entries; ++i) { *dst = src[getPixelAddress32_0(gs.clut.cou+i, gs.clut.cov, gs.clut.cbw)]; dst++; } - break; + break; } default: @@ -1120,19 +1230,18 @@ void ZeroGS::texClutWrite(int ctx) { case PSMCT24: case PSMCT32: - if( entries == 16 ) - WriteCLUT_T32_I4_CSM1((u32*)(g_pbyGSMemory + tex0.cbp*256), (u32*)(g_pbyGSClut+64*tex0.csa)); + if (entries == 16) + WriteCLUT_T32_I4_CSM1((u32*)(g_pbyGSMemory + tex0.cbp*256), (u32*)(g_pbyGSClut + 64*tex0.csa)); else - WriteCLUT_T32_I8_CSM1((u32*)(g_pbyGSMemory + tex0.cbp*256), (u32*)(g_pbyGSClut+64*tex0.csa)); + WriteCLUT_T32_I8_CSM1((u32*)(g_pbyGSMemory + tex0.cbp*256), (u32*)(g_pbyGSClut + 64*tex0.csa)); break; default: - if( entries == 16 ) - WriteCLUT_T16_I4_CSM1((u32*)(g_pbyGSMemory + 256 * tex0.cbp), (u32*)(g_pbyGSClut+32*(tex0.csa&15)+(tex0.csa>=16?2:0))); + if (entries == 16) + WriteCLUT_T16_I4_CSM1((u32*)(g_pbyGSMemory + 256 * tex0.cbp), (u32*)(g_pbyGSClut + 32*(tex0.csa&15) + (tex0.csa >= 16 ? 2 : 0))); else // sse2 for 256 is more complicated, so use regular - WriteCLUT_T16_I8_CSM1_c((u32*)(g_pbyGSMemory + 256 * tex0.cbp), (u32*)(g_pbyGSClut+32*(tex0.csa&15)+(tex0.csa>=16?2:0))); + WriteCLUT_T16_I8_CSM1_c((u32*)(g_pbyGSMemory + 256 * tex0.cbp), (u32*)(g_pbyGSClut + 32*(tex0.csa&15) + (tex0.csa >= 16 ? 2 : 0))); break; - } } } diff --git a/plugins/zzogl-pg/opengl/zerogsmath.h b/plugins/zzogl-pg/opengl/zerogsmath.h index dbfef2085b..8cf5392c6d 100644 --- a/plugins/zzogl-pg/opengl/zerogsmath.h +++ b/plugins/zzogl-pg/opengl/zerogsmath.h @@ -59,6 +59,12 @@ public: inline void Set3(const float* pvals) { x = pvals[0]; y = pvals[1]; z = pvals[2]; } inline void Set4(const float* pvals) { x = pvals[0]; y = pvals[1]; z = pvals[2]; w = pvals[3]; } + inline void SetColor(u32 color) + { + x = (color & 0xff) / 255.0f; + y = ((color >> 8) & 0xff) / 255.0f; + z = ((color >> 16) & 0xff) / 255.0f; + } // 3 dim cross product, w is not touched /// this = this x v diff --git a/plugins/zzogl-pg/opengl/zpipe.cpp b/plugins/zzogl-pg/opengl/zpipe.cpp index 15eb93f16a..ac604780f7 100644 --- a/plugins/zzogl-pg/opengl/zpipe.cpp +++ b/plugins/zzogl-pg/opengl/zpipe.cpp @@ -25,23 +25,28 @@ int def(char *src, char *dst, int bytes_to_compress, int *bytes_after_compressed strm.zfree = Z_NULL; strm.opaque = Z_NULL; ret = deflateInit(&strm, Z_DEFAULT_COMPRESSION) ; + if (ret != Z_OK) return ret; /* compress */ strm.avail_in = bytes_to_compress ; strm.avail_out = bytes_to_compress ; + strm.next_in = (Bytef *)src ; strm.next_out = (Bytef *)dst ; ret = deflate(&strm, Z_FINISH) ; + have = bytes_to_compress - strm.avail_out ; + *bytes_after_compressed = have ; assert(ret == Z_STREAM_END); /* stream will be complete */ /* clean up and return */ (void)deflateEnd(&strm); + return Z_OK; } @@ -59,8 +64,8 @@ int inf(char *src, char *dst, int bytes_to_decompress, int maximum_after_decompr strm.avail_in = 0; strm.next_in = Z_NULL; ret = inflateInit(&strm); - if (ret != Z_OK) - return ret; + + if (ret != Z_OK) return ret; /* decompress */ strm.avail_in = bytes_to_decompress ; @@ -69,23 +74,29 @@ int inf(char *src, char *dst, int bytes_to_decompress, int maximum_after_decompr strm.avail_out = maximum_after_decompress ; ret = inflate(&strm, Z_NO_FLUSH) ; + assert(ret != Z_STREAM_ERROR); /* state not clobbered */ - switch (ret) { - case Z_NEED_DICT: - ret = Z_DATA_ERROR; /* and fall through */ - case Z_DATA_ERROR: - case Z_MEM_ERROR: - (void)inflateEnd(&strm); - return ret; + + switch (ret) + { + + case Z_NEED_DICT: + ret = Z_DATA_ERROR; /* and fall through */ + + case Z_DATA_ERROR: + + case Z_MEM_ERROR: + (void)inflateEnd(&strm); + return ret; } assert(strm.avail_in == 0); /* all input will be used */ - if( outbytes != NULL ) - *outbytes = strm.total_out; + if (outbytes != NULL) *outbytes = strm.total_out; /* clean up and return */ (void)inflateEnd(&strm); + return ret == Z_STREAM_END ? Z_OK : Z_DATA_ERROR; } @@ -93,23 +104,28 @@ int inf(char *src, char *dst, int bytes_to_decompress, int maximum_after_decompr void zerr(int ret) { fputs("zpipe: ", stderr); - switch (ret) { - case Z_ERRNO: - if (ferror(stdin)) - fputs("error reading stdin\n", stderr); - if (ferror(stdout)) - fputs("error writing stdout\n", stderr); - break; - case Z_STREAM_ERROR: - fputs("invalid compression level\n", stderr); - break; - case Z_DATA_ERROR: - fputs("invalid or incomplete deflate data\n", stderr); - break; - case Z_MEM_ERROR: - fputs("out of memory\n", stderr); - break; - case Z_VERSION_ERROR: - fputs("zlib version mismatch!\n", stderr); + + switch (ret) + { + + case Z_ERRNO: + if (ferror(stdin)) fputs("error reading stdin\n", stderr); + if (ferror(stdout)) fputs("error writing stdout\n", stderr); + break; + + case Z_STREAM_ERROR: + fputs("invalid compression level\n", stderr); + break; + + case Z_DATA_ERROR: + fputs("invalid or incomplete deflate data\n", stderr); + break; + + case Z_MEM_ERROR: + fputs("out of memory\n", stderr); + break; + + case Z_VERSION_ERROR: + fputs("zlib version mismatch!\n", stderr); } }