mirror of https://github.com/PCSX2/pcsx2.git
zzogl-pg: Ran a bunch of the files through AStyle, so I don't find myself messing with the source code formatting so much.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2931 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
7e8c22b4f5
commit
a6c4df49ea
|
@ -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,21 +109,22 @@ 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;
|
||||
|
||||
|
@ -129,8 +133,10 @@ bool GLWindow::CreateWindow(void *pDisplay)
|
|||
// 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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
@ -91,7 +94,8 @@ bool GLWindow::DisplayWindow(int _width, int _height)
|
|||
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
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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<int index> 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<int index> 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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<string, confOptsStruct>::iterator it = mapConfOpts.begin(); it != mapConfOpts.end(); ++it)
|
||||
for (map<string, confOptsStruct>::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<string, confOptsStruct>::iterator it = mapConfOpts.begin(); it != mapConfOpts.end(); ++it)
|
||||
|
||||
for (map<string, confOptsStruct>::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);
|
||||
return_value = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
|
||||
if (gtk_combo_box_get_active(GTK_COMBO_BOX(int_box)) != -1)
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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<T>(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<T>(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 <class T>
|
||||
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<T>(data, fun, alignedPt, endY, pbuf);
|
||||
|
||||
if (pbuf == NULL) return FinishTransfer(data, nLeftOver);
|
||||
|
||||
pbuf = TransferAligningToBlocks<T>(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<T>(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<u32>(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<u32>(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<u8>(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<u8>(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<u16>(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<u16>(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<u16>(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<u16>(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<u8>(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<u8>(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<u8>(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<u8>(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<u8>(data, fun, pbyMem, nQWordSize);
|
||||
|
@ -387,19 +398,25 @@ void BLOCK::FillBlocks(vector<char>& vBlockData, vector<char>& vBilinearData, in
|
|||
{
|
||||
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<char>& vBlockData, vector<char>& 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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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,6 +402,7 @@ void __fastcall GIFRegHandlerNull(u32* data)
|
|||
{
|
||||
FUNCLOG
|
||||
#ifdef _DEBUG
|
||||
|
||||
if ((((uptr)&data[2])&0xffff) == 0) return;
|
||||
|
||||
// 0x7f happens on a lot of games
|
||||
|
@ -382,23 +410,26 @@ void __fastcall GIFRegHandlerNull(u32* data)
|
|||
{
|
||||
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)
|
||||
{
|
||||
//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]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,40 +80,48 @@ extern vector<u32> 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<u32> 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<u32> 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,19 +140,20 @@ 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.
|
||||
|
@ -174,51 +183,67 @@ inline bool FrameSkippingHelper()
|
|||
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<<i)) ) {
|
||||
if (!(*(u32*)(PMODE) & (1 << i)))
|
||||
{
|
||||
dispinfo[i].tw = 0;
|
||||
dispinfo[i].th = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
GSRegDISPFB* pfb = i ? DISPFB2 : DISPFB1;
|
||||
|
||||
GSRegDISPLAY* pd = i ? DISPLAY2 : DISPLAY1;
|
||||
int magh = pd->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 ) {
|
||||
|
@ -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<<i);
|
||||
s_stencilmask = 1<<i;
|
||||
inline void RenderSetupStencil(int i)
|
||||
{
|
||||
glStencilMask(1 << i);
|
||||
s_stencilmask = 1 << i;
|
||||
GL_STENCILFUNC_SET();
|
||||
}
|
||||
|
||||
// do stencil check for each found target i -- texturig stage
|
||||
inline void RenderUpdateStencil(int i, bool* bUsingStencil) {
|
||||
if( !(*bUsingStencil) ) {
|
||||
inline void RenderUpdateStencil(int i, bool* bUsingStencil)
|
||||
{
|
||||
if (!(*bUsingStencil))
|
||||
{
|
||||
glClear(GL_STENCIL_BUFFER_BIT);
|
||||
}
|
||||
|
||||
*bUsingStencil = 1;
|
||||
|
||||
glEnable(GL_STENCIL_TEST);
|
||||
GL_STENCILFUNC(GL_NOTEQUAL, 3, 1<<i);
|
||||
GL_STENCILFUNC(GL_NOTEQUAL, 3, 1 << i);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
glStencilMask(1<<i);
|
||||
glStencilMask(1 << i);
|
||||
}
|
||||
|
||||
// CRTC24 could not be rendered
|
||||
inline void RenderCRTC24helper(u32 bInterlace, int interlace, int psm) {
|
||||
inline void RenderCRTC24helper(u32 bInterlace, int interlace, int psm)
|
||||
{
|
||||
ZZLog::Error_Log("ZZogl: CRTC24!!! I'm trying to show something.");
|
||||
SetShaderCaller("RenderCRTC24helper");
|
||||
// assume that data is already in ptexMem (do Resolve?)
|
||||
|
@ -406,43 +458,51 @@ inline int RenderGetBpp(int psm)
|
|||
|
||||
ZZLog::Debug_Log("ZZogl: 16S target.");
|
||||
}
|
||||
|
||||
if (PSMT_ISHALF(psm))
|
||||
return 2;
|
||||
|
||||
return 4;
|
||||
}
|
||||
|
||||
// We want to draw ptarg on screen, that could be disaligned to viewport.
|
||||
// So we do aligning it by height.
|
||||
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 ) {
|
||||
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)
|
||||
{
|
||||
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<CRenderTarget*>& listTargs, list<CRenderTarget*>::iterator& it) {
|
||||
inline bool RenderLookForABetterTarget(int fbp, int tbp, list<CRenderTarget*>& listTargs, list<CRenderTarget*>::iterator& it)
|
||||
{
|
||||
if (fbp == tbp)
|
||||
return false;
|
||||
|
||||
// look for a better target (metal slug 5)
|
||||
list<CRenderTarget*>::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<CRenderTarget*>& l
|
|||
}
|
||||
|
||||
// First try to draw frame from targets. It's
|
||||
inline bool RenderCheckForTargets(tex0Info& texframe, list<CRenderTarget*>& listTargs, int i, bool* bUsingStencil, int interlace, int bInterlace) {
|
||||
inline bool RenderCheckForTargets(tex0Info& texframe, list<CRenderTarget*>& 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<CRenderTarget*>& list
|
|||
// We need share list of targets beetween functions
|
||||
s_RTs.GetTargs(start, end, listTargs);
|
||||
|
||||
for(list<CRenderTarget*>::iterator it = listTargs.begin(); it != listTargs.end(); ) {
|
||||
for (list<CRenderTarget*>::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<CRenderTarget*>& 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<CRenderTarget*>& 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<CRenderTarget*>& listTargs, int interlace, int bInterlace)
|
||||
{
|
||||
|
||||
for(list<CRenderTarget*>::iterator it = listTargs.begin(); it != listTargs.end(); ++it)
|
||||
for (list<CRenderTarget*>::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<CRenderTarget*>& 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,71 +745,83 @@ 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)
|
||||
|
@ -730,10 +831,12 @@ inline void AfterRendererSwitchBackToTextures() {
|
|||
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<CRenderTarget*> 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -79,59 +79,60 @@
|
|||
#define VB_NUMBUFFERS 512
|
||||
|
||||
// ----------------- Types
|
||||
typedef void (APIENTRYP _PFNSWAPINTERVAL) (int);
|
||||
typedef void (APIENTRYP _PFNSWAPINTERVAL)(int);
|
||||
|
||||
map<string, GLbyte> 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<GLuint> g_vboBuffers; // VBOs for all drawing commands
|
||||
int g_nCurVBOIndex = 0;
|
||||
GLuint vboRect = 0;
|
||||
vector<GLuint> 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,33 +378,40 @@ 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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -431,15 +476,16 @@ bool ZeroGS::Create(int _width, int _height)
|
|||
|
||||
// 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<char> 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<VertexGPU> 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<u32> 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<u32> 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);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
@ -190,34 +214,39 @@ void SetupVertexProgramParameters(CGprogram prog, int context)
|
|||
|
||||
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;
|
||||
}
|
||||
|
@ -396,12 +462,14 @@ FRAGMENTSHADER* ZeroGS::LoadShadeEffect(int type, int texfilter, int fog, int te
|
|||
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;
|
||||
}
|
||||
|
|
|
@ -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<u32> 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<u32> 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<u32> 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<u32> 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
|
||||
|
|
|
@ -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) ;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#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);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -193,8 +193,8 @@ void __fastcall Frame16SwizzleBlock16Z##type##c(u16* dst, Vector_16F* src, int s
|
|||
} \
|
||||
|
||||
_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
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue