mirror of https://github.com/PCSX2/pcsx2.git
Lets go ahead and bring the changes to zzogl-pg in the GregMiscellaneous branch into trunk.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@3748 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
da9c955135
commit
a9281ecea0
|
@ -65,6 +65,7 @@ set(zzoglSources
|
||||||
ZZoglCreate.cpp
|
ZZoglCreate.cpp
|
||||||
ZZoglCRTC.cpp
|
ZZoglCRTC.cpp
|
||||||
ZZoglFlush.cpp
|
ZZoglFlush.cpp
|
||||||
|
ZZoglFlushHack.cpp
|
||||||
ZZoglSave.cpp
|
ZZoglSave.cpp
|
||||||
ZZoglShaders.cpp
|
ZZoglShaders.cpp
|
||||||
ZZoglShoots.cpp
|
ZZoglShoots.cpp
|
||||||
|
@ -154,9 +155,6 @@ target_link_libraries(${Output} ${OPENGL_LIBRARIES})
|
||||||
# link target with X11
|
# link target with X11
|
||||||
target_link_libraries(${Output} ${X11_LIBRARIES})
|
target_link_libraries(${Output} ${X11_LIBRARIES})
|
||||||
|
|
||||||
# link target with X11 videomod
|
|
||||||
target_link_libraries(${Output} ${X11_Xxf86vm_LIB})
|
|
||||||
|
|
||||||
# User flags options
|
# User flags options
|
||||||
if(NOT USER_CMAKE_LD_FLAGS STREQUAL "")
|
if(NOT USER_CMAKE_LD_FLAGS STREQUAL "")
|
||||||
target_link_libraries(${Output} "${USER_CMAKE_LD_FLAGS}")
|
target_link_libraries(${Output} "${USER_CMAKE_LD_FLAGS}")
|
||||||
|
|
|
@ -53,7 +53,8 @@ enum GAME_HACK_OPTIONS
|
||||||
GAME_PARTIALDEPTH = 0x04000000, // tries to save depth targets as much as possible across height changes
|
GAME_PARTIALDEPTH = 0x04000000, // tries to save depth targets as much as possible across height changes
|
||||||
GAME_REGETHACK = 0x08000000, // some sort of weirdness in ReGet() code
|
GAME_REGETHACK = 0x08000000, // some sort of weirdness in ReGet() code
|
||||||
GAME_GUSTHACK = 0x10000000, // Needed for Gustgames fast update.
|
GAME_GUSTHACK = 0x10000000, // Needed for Gustgames fast update.
|
||||||
GAME_NOLOGZ = 0x20000000 // Intended for linux -- not logarithmic Z.
|
GAME_NOLOGZ = 0x20000000, // Intended for linux -- not logarithmic Z.
|
||||||
|
GAME_AUTOSKIPDRAW = 0x40000000 // Remove blur effect on some games
|
||||||
};
|
};
|
||||||
|
|
||||||
#define USEALPHATESTING (!(conf.settings().no_alpha_test))
|
#define USEALPHATESTING (!(conf.settings().no_alpha_test))
|
||||||
|
|
|
@ -29,10 +29,6 @@
|
||||||
|
|
||||||
#undef CreateWindow // Undo Windows.h global namespace pollution
|
#undef CreateWindow // Undo Windows.h global namespace pollution
|
||||||
|
|
||||||
#ifdef GL_X11_WINDOW
|
|
||||||
#include <X11/extensions/xf86vmode.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class GLWindow
|
class GLWindow
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
|
@ -45,22 +41,23 @@ class GLWindow
|
||||||
Window glWindow;
|
Window glWindow;
|
||||||
XSetWindowAttributes attr;
|
XSetWindowAttributes attr;
|
||||||
|
|
||||||
// Original desktop video mode
|
|
||||||
XF86VidModeModeInfo deskMode;
|
|
||||||
|
|
||||||
bool CreateVisual();
|
bool CreateVisual();
|
||||||
void GetGLXVersion();
|
void GetGLXVersion();
|
||||||
void GetGLXVidModeVersion();
|
|
||||||
void GetWindowSize();
|
void GetWindowSize();
|
||||||
|
void UpdateGrabKey();
|
||||||
|
void Force43Ratio();
|
||||||
#endif
|
#endif
|
||||||
bool fullScreen, doubleBuffered;
|
bool fullScreen, doubleBuffered;
|
||||||
s32 x, y;
|
|
||||||
u32 width, height, depth;
|
u32 width, height, depth;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void SwapGLBuffers();
|
void SwapGLBuffers();
|
||||||
bool ReleaseContext();
|
bool ReleaseContext();
|
||||||
|
|
||||||
|
#ifdef GL_X11_WINDOW
|
||||||
|
void ToggleFullscreen();
|
||||||
|
#endif
|
||||||
|
|
||||||
bool CreateWindow(void *pDisplay);
|
bool CreateWindow(void *pDisplay);
|
||||||
void CloseWindow();
|
void CloseWindow();
|
||||||
bool DisplayWindow(int _width, int _height);
|
bool DisplayWindow(int _width, int _height);
|
||||||
|
@ -68,6 +65,7 @@ class GLWindow
|
||||||
void ResizeCheck();
|
void ResizeCheck();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
extern GLWindow GLWin;
|
extern GLWindow GLWin;
|
||||||
|
|
||||||
#endif // GLWIN_H_INCLUDED
|
#endif // GLWIN_H_INCLUDED
|
||||||
|
|
|
@ -24,9 +24,14 @@
|
||||||
#ifdef GL_X11_WINDOW
|
#ifdef GL_X11_WINDOW
|
||||||
|
|
||||||
#include <X11/Xlib.h>
|
#include <X11/Xlib.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
bool GLWindow::CreateWindow(void *pDisplay)
|
bool GLWindow::CreateWindow(void *pDisplay)
|
||||||
{
|
{
|
||||||
|
// init support of multi thread
|
||||||
|
if (!XInitThreads())
|
||||||
|
ZZLog::Error_Log("Failed to init the xlib concurent threads");
|
||||||
|
|
||||||
glDisplay = XOpenDisplay(0);
|
glDisplay = XOpenDisplay(0);
|
||||||
glScreen = DefaultScreen(glDisplay);
|
glScreen = DefaultScreen(glDisplay);
|
||||||
|
|
||||||
|
@ -39,42 +44,37 @@ bool GLWindow::CreateWindow(void *pDisplay)
|
||||||
|
|
||||||
bool GLWindow::ReleaseContext()
|
bool GLWindow::ReleaseContext()
|
||||||
{
|
{
|
||||||
if (context && (glDisplay != NULL))
|
bool status = true;
|
||||||
|
if (!glDisplay) return status;
|
||||||
|
|
||||||
|
// free the context
|
||||||
|
if (context)
|
||||||
{
|
{
|
||||||
if (!glXMakeCurrent(glDisplay, None, NULL))
|
if (!glXMakeCurrent(glDisplay, None, NULL)) {
|
||||||
{
|
|
||||||
ZZLog::Error_Log("Could not release drawing context.");
|
ZZLog::Error_Log("Could not release drawing context.");
|
||||||
}
|
status = false;
|
||||||
|
}
|
||||||
|
|
||||||
glXDestroyContext(glDisplay, context);
|
glXDestroyContext(glDisplay, context);
|
||||||
|
|
||||||
context = NULL;
|
context = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
// free the visual
|
||||||
|
if (vi) {
|
||||||
|
XFree(vi);
|
||||||
|
vi = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLWindow::CloseWindow()
|
void GLWindow::CloseWindow()
|
||||||
{
|
{
|
||||||
conf.x = x;
|
|
||||||
conf.y = y;
|
|
||||||
SaveConfig();
|
SaveConfig();
|
||||||
|
if (!glDisplay) return;
|
||||||
|
|
||||||
/* switch back to original desktop resolution if we were in fullscreen */
|
XCloseDisplay(glDisplay);
|
||||||
if (glDisplay != NULL)
|
glDisplay = NULL;
|
||||||
{
|
|
||||||
if (fullScreen)
|
|
||||||
{
|
|
||||||
XF86VidModeSwitchToMode(glDisplay, glScreen, &deskMode);
|
|
||||||
XF86VidModeSetViewPort(glDisplay, glScreen, 0, 0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (glDisplay != NULL)
|
|
||||||
{
|
|
||||||
XCloseDisplay(glDisplay);
|
|
||||||
glDisplay = NULL;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLWindow::CreateVisual()
|
bool GLWindow::CreateVisual()
|
||||||
|
@ -123,11 +123,21 @@ bool GLWindow::CreateVisual()
|
||||||
|
|
||||||
void GLWindow::GetWindowSize()
|
void GLWindow::GetWindowSize()
|
||||||
{
|
{
|
||||||
|
if (!glDisplay or !glWindow) return;
|
||||||
|
|
||||||
unsigned int borderDummy;
|
unsigned int borderDummy;
|
||||||
Window winDummy;
|
Window winDummy;
|
||||||
|
s32 xDummy;
|
||||||
|
s32 yDummy;
|
||||||
|
|
||||||
XGetGeometry(glDisplay, glWindow, &winDummy, &x, &y, &width, &height, &borderDummy, &depth);
|
XLockDisplay(glDisplay);
|
||||||
ZZLog::Error_Log("Depth %d", depth);
|
XGetGeometry(glDisplay, glWindow, &winDummy, &xDummy, &yDummy, &width, &height, &borderDummy, &depth);
|
||||||
|
XUnlockDisplay(glDisplay);
|
||||||
|
|
||||||
|
// update the gl buffer size
|
||||||
|
ZeroGS::ChangeWindowSize(width, height);
|
||||||
|
|
||||||
|
ZZLog::Error_Log("Resolution %dx%d. Depth %d bpp. Position (%d,%d)", width, height, depth, conf.x, conf.y);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLWindow::GetGLXVersion()
|
void GLWindow::GetGLXVersion()
|
||||||
|
@ -139,123 +149,148 @@ void GLWindow::GetGLXVersion()
|
||||||
ZZLog::Error_Log("glX-Version %d.%d", glxMajorVersion, glxMinorVersion);
|
ZZLog::Error_Log("glX-Version %d.%d", glxMajorVersion, glxMinorVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLWindow::GetGLXVidModeVersion()
|
void GLWindow::UpdateGrabKey()
|
||||||
{
|
{
|
||||||
int vidModeMajorVersion, vidModeMinorVersion;
|
// Do not stole the key in debug mode. It is not breakpoint friendly...
|
||||||
|
#ifndef _DEBUG
|
||||||
|
XLockDisplay(glDisplay);
|
||||||
|
if (fullScreen) {
|
||||||
|
XGrabPointer(glDisplay, glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, glWindow, None, CurrentTime);
|
||||||
|
XGrabKeyboard(glDisplay, glWindow, True, GrabModeAsync, GrabModeAsync, CurrentTime);
|
||||||
|
} else {
|
||||||
|
XUngrabPointer(glDisplay, CurrentTime);
|
||||||
|
XUngrabKeyboard(glDisplay, CurrentTime);
|
||||||
|
}
|
||||||
|
XUnlockDisplay(glDisplay);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
XF86VidModeQueryVersion(glDisplay, &vidModeMajorVersion, &vidModeMinorVersion);
|
void GLWindow::Force43Ratio()
|
||||||
|
{
|
||||||
|
// avoid black border in fullscreen
|
||||||
|
if (fullScreen && conf.isWideScreen) {
|
||||||
|
conf.width = width;
|
||||||
|
conf.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!fullScreen && !conf.isWideScreen) {
|
||||||
|
// Compute the width based on height
|
||||||
|
s32 new_width = (4*height)/3;
|
||||||
|
// do not bother to resize for 5 pixels. Avoid a loop
|
||||||
|
// due to round value
|
||||||
|
if ( abs(new_width - width) > 5) {
|
||||||
|
width = new_width;
|
||||||
|
conf.width = new_width;
|
||||||
|
// resize the window
|
||||||
|
XLockDisplay(glDisplay);
|
||||||
|
XResizeWindow(glDisplay, glWindow, new_width, height);
|
||||||
|
XSync(glDisplay, False);
|
||||||
|
XUnlockDisplay(glDisplay);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define _NET_WM_STATE_REMOVE 0
|
||||||
|
#define _NET_WM_STATE_ADD 1
|
||||||
|
#define _NET_WM_STATE_TOGGLE 2
|
||||||
|
|
||||||
|
void GLWindow::ToggleFullscreen()
|
||||||
|
{
|
||||||
|
if (!glDisplay or !glWindow) return;
|
||||||
|
|
||||||
|
Force43Ratio();
|
||||||
|
|
||||||
|
u32 mask = SubstructureRedirectMask | SubstructureNotifyMask;
|
||||||
|
// Setup a new event structure
|
||||||
|
XClientMessageEvent cme;
|
||||||
|
cme.type = ClientMessage;
|
||||||
|
cme.send_event = True;
|
||||||
|
cme.display = glDisplay;
|
||||||
|
cme.window = glWindow;
|
||||||
|
cme.message_type = XInternAtom(glDisplay, "_NET_WM_STATE", False);
|
||||||
|
cme.format = 32;
|
||||||
|
// Note: can not use _NET_WM_STATE_TOGGLE because the WM can change the fullscreen state
|
||||||
|
// and screw up the fullscreen variable... The test on fulscreen restore a sane configuration
|
||||||
|
cme.data.l[0] = fullScreen ? _NET_WM_STATE_REMOVE : _NET_WM_STATE_ADD;
|
||||||
|
cme.data.l[1] = (u32)XInternAtom(glDisplay, "_NET_WM_STATE_FULLSCREEN", False);
|
||||||
|
cme.data.l[2] = 0;
|
||||||
|
cme.data.l[3] = 0;
|
||||||
|
|
||||||
|
// send the event
|
||||||
|
XLockDisplay(glDisplay);
|
||||||
|
if (!XSendEvent(glDisplay, RootWindow(glDisplay, vi->screen), False, mask, (XEvent*)(&cme)))
|
||||||
|
ZZLog::Error_Log("Failed to send event: toggle fullscreen");
|
||||||
|
else {
|
||||||
|
fullScreen = (!fullScreen);
|
||||||
|
conf.setFullscreen(fullScreen);
|
||||||
|
}
|
||||||
|
XUnlockDisplay(glDisplay);
|
||||||
|
|
||||||
|
// Apply the change
|
||||||
|
XSync(glDisplay, False);
|
||||||
|
|
||||||
|
// update info structure
|
||||||
|
GetWindowSize();
|
||||||
|
|
||||||
|
UpdateGrabKey();
|
||||||
|
|
||||||
|
// avoid black border in widescreen fullscreen
|
||||||
|
if (fullScreen && conf.isWideScreen) {
|
||||||
|
conf.width = width;
|
||||||
|
conf.height = height;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hide the cursor in the right bottom corner
|
||||||
|
if(fullScreen)
|
||||||
|
XWarpPointer(glDisplay, None, glWindow, 0, 0, 0, 0, width, height);
|
||||||
|
|
||||||
ZZLog::Error_Log("XF86VidModeExtension-Version %d.%d.", vidModeMajorVersion, vidModeMinorVersion);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GLWindow::DisplayWindow(int _width, int _height)
|
bool GLWindow::DisplayWindow(int _width, int _height)
|
||||||
{
|
{
|
||||||
Colormap cmap;
|
|
||||||
|
|
||||||
x = conf.x;
|
|
||||||
y = conf.y;
|
|
||||||
fullScreen = (conf.fullscreen());
|
|
||||||
|
|
||||||
if (!CreateVisual()) return false;
|
if (!CreateVisual()) return false;
|
||||||
|
|
||||||
/* create a GLX context */
|
/* create a GLX context */
|
||||||
context = glXCreateContext(glDisplay, vi, NULL, GL_TRUE);
|
context = glXCreateContext(glDisplay, vi, NULL, GL_TRUE);
|
||||||
|
|
||||||
/* create a color map */
|
/* create a color map */
|
||||||
cmap = XCreateColormap(glDisplay, RootWindow(glDisplay, vi->screen),
|
attr.colormap = XCreateColormap(glDisplay, RootWindow(glDisplay, vi->screen),
|
||||||
vi->visual, AllocNone);
|
vi->visual, AllocNone);
|
||||||
|
|
||||||
attr.colormap = cmap;
|
|
||||||
attr.border_pixel = 0;
|
attr.border_pixel = 0;
|
||||||
attr.event_mask = ExposureMask | KeyPressMask | ButtonPressMask | StructureNotifyMask;
|
attr.event_mask = ExposureMask | KeyPressMask | KeyReleaseMask | ButtonPressMask |
|
||||||
|
StructureNotifyMask | SubstructureRedirectMask | SubstructureNotifyMask |
|
||||||
|
EnterWindowMask | LeaveWindowMask | FocusChangeMask ;
|
||||||
|
|
||||||
GetGLXVersion();
|
GetGLXVersion();
|
||||||
|
|
||||||
if (fullScreen)
|
// Create a window at the last position/size
|
||||||
{
|
glWindow = XCreateWindow(glDisplay, RootWindow(glDisplay, vi->screen),
|
||||||
int dpyWidth, dpyHeight;
|
conf.x , conf.y , _width, _height, 0, vi->depth, InputOutput, vi->visual,
|
||||||
int modeNum = 0, bestMode = 0;
|
CWBorderPixel | CWColormap | CWEventMask,
|
||||||
XF86VidModeModeInfo **modes = NULL;
|
&attr);
|
||||||
|
|
||||||
GetGLXVidModeVersion();
|
/* Allow to kill properly the window */
|
||||||
|
Atom wmDelete = XInternAtom(glDisplay, "WM_DELETE_WINDOW", True);
|
||||||
|
XSetWMProtocols(glDisplay, glWindow, &wmDelete, 1);
|
||||||
|
|
||||||
XF86VidModeGetAllModeLines(glDisplay, glScreen, &modeNum, &modes);
|
// Set icon name
|
||||||
|
XSetIconName(glDisplay, glWindow, "ZZogl-pg");
|
||||||
|
|
||||||
if (modeNum > 0 && modes != NULL)
|
// Draw the window
|
||||||
{
|
XMapRaised(glDisplay, glWindow);
|
||||||
/* save desktop-resolution before switching modes */
|
XSync(glDisplay, false);
|
||||||
deskMode = *modes[0];
|
|
||||||
|
|
||||||
/* look for mode with requested resolution */
|
|
||||||
|
|
||||||
for (int i = 0; i < modeNum; i++)
|
|
||||||
{
|
|
||||||
if ((modes[i]->hdisplay == _width) && (modes[i]->vdisplay == _height))
|
|
||||||
{
|
|
||||||
bestMode = i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
XF86VidModeSwitchToMode(glDisplay, glScreen, modes[bestMode]);
|
|
||||||
|
|
||||||
XF86VidModeSetViewPort(glDisplay, glScreen, 0, 0);
|
|
||||||
dpyWidth = modes[bestMode]->hdisplay;
|
|
||||||
dpyHeight = modes[bestMode]->vdisplay;
|
|
||||||
ZZLog::Error_Log("Resolution %dx%d.", dpyWidth, dpyHeight);
|
|
||||||
XFree(modes);
|
|
||||||
|
|
||||||
/* create a fullscreen window */
|
|
||||||
attr.override_redirect = True;
|
|
||||||
glWindow = XCreateWindow(glDisplay, RootWindow(glDisplay, vi->screen),
|
|
||||||
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);
|
|
||||||
XGrabPointer(glDisplay, glWindow, True, ButtonPressMask, GrabModeAsync, GrabModeAsync, glWindow, None, CurrentTime);
|
|
||||||
}
|
|
||||||
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)");
|
|
||||||
fullScreen = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!fullScreen)
|
|
||||||
{
|
|
||||||
// create a window in window mode
|
|
||||||
glWindow = XCreateWindow(glDisplay, RootWindow(glDisplay, vi->screen),
|
|
||||||
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
|
|
||||||
Atom wmDelete;
|
|
||||||
wmDelete = XInternAtom(glDisplay, "WM_DELETE_WINDOW", True);
|
|
||||||
XSetWMProtocols(glDisplay, glWindow, &wmDelete, 1);
|
|
||||||
|
|
||||||
XSetStandardProperties(glDisplay, glWindow, "ZZOgl-PG", "ZZOgl-PG", None, NULL, 0, NULL);
|
|
||||||
XMapRaised(glDisplay, glWindow);
|
|
||||||
XMoveWindow(glDisplay, glWindow, x, y);
|
|
||||||
}
|
|
||||||
|
|
||||||
// connect the glx-context to the window
|
// connect the glx-context to the window
|
||||||
glXMakeCurrent(glDisplay, glWindow, context);
|
glXMakeCurrent(glDisplay, glWindow, context);
|
||||||
|
|
||||||
GetWindowSize();
|
|
||||||
|
|
||||||
if (glXIsDirect(glDisplay, context))
|
if (glXIsDirect(glDisplay, context))
|
||||||
ZZLog::Error_Log("You have Direct Rendering!");
|
ZZLog::Error_Log("You have Direct Rendering!");
|
||||||
else
|
else
|
||||||
ZZLog::Error_Log("No Direct Rendering possible!");
|
ZZLog::Error_Log("No Direct Rendering possible!");
|
||||||
|
|
||||||
// better for pad plugin key input (thc)
|
// Always start in window mode
|
||||||
XSelectInput(glDisplay, glWindow, ExposureMask | KeyPressMask | KeyReleaseMask |
|
fullScreen = 0;
|
||||||
ButtonPressMask | StructureNotifyMask | EnterWindowMask | LeaveWindowMask |
|
GetWindowSize();
|
||||||
FocusChangeMask);
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -267,40 +302,49 @@ void GLWindow::SwapGLBuffers()
|
||||||
|
|
||||||
void GLWindow::SetTitle(char *strtitle)
|
void GLWindow::SetTitle(char *strtitle)
|
||||||
{
|
{
|
||||||
if (!conf.fullscreen())
|
if (!glDisplay or !glWindow) return;
|
||||||
{
|
if (fullScreen) return;
|
||||||
XTextProperty prop;
|
|
||||||
memset(&prop, 0, sizeof(prop));
|
|
||||||
char* ptitle = strtitle;
|
|
||||||
|
|
||||||
if (XStringListToTextProperty(&ptitle, 1, &prop))
|
XTextProperty prop;
|
||||||
XSetWMName(glDisplay, glWindow, &prop);
|
memset(&prop, 0, sizeof(prop));
|
||||||
|
|
||||||
XFree(prop.value);
|
char* ptitle = strtitle;
|
||||||
}
|
if (XStringListToTextProperty(&ptitle, 1, &prop)) {
|
||||||
|
XLockDisplay(glDisplay);
|
||||||
|
XSetWMName(glDisplay, glWindow, &prop);
|
||||||
|
XUnlockDisplay(glDisplay);
|
||||||
|
}
|
||||||
|
|
||||||
|
XFree(prop.value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GLWindow::ResizeCheck()
|
void GLWindow::ResizeCheck()
|
||||||
{
|
{
|
||||||
XEvent event;
|
XEvent event;
|
||||||
|
if (!glDisplay or !glWindow) return;
|
||||||
|
|
||||||
while (XCheckTypedEvent(glDisplay, ConfigureNotify, &event))
|
XLockDisplay(glDisplay);
|
||||||
|
while (XCheckTypedWindowEvent(glDisplay, glWindow, ConfigureNotify, &event))
|
||||||
{
|
{
|
||||||
if ((event.xconfigure.width != width) || (event.xconfigure.height != height))
|
if ((event.xconfigure.width != width) || (event.xconfigure.height != height))
|
||||||
{
|
{
|
||||||
ZeroGS::ChangeWindowSize(event.xconfigure.width, event.xconfigure.height);
|
|
||||||
width = event.xconfigure.width;
|
width = event.xconfigure.width;
|
||||||
height = event.xconfigure.height;
|
height = event.xconfigure.height;
|
||||||
|
Force43Ratio();
|
||||||
|
ZeroGS::ChangeWindowSize(width, height);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((event.xconfigure.x != x) || (event.xconfigure.y != y))
|
if (!fullScreen) {
|
||||||
{
|
if ((event.xconfigure.x != conf.x) || (event.xconfigure.y != conf.y))
|
||||||
// Fixme; x&y occassionally gives values near the top left corner rather then the real values,
|
{
|
||||||
// causing the window to change positions when adjusting ZZOgl's settings.
|
// Fixme; x&y occassionally gives values near the top left corner rather then the real values,
|
||||||
x = event.xconfigure.x;
|
// causing the window to change positions when adjusting ZZOgl's settings.
|
||||||
y = event.xconfigure.y;
|
conf.x = event.xconfigure.x;
|
||||||
}
|
conf.y = event.xconfigure.y;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
XUnlockDisplay(glDisplay);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -100,19 +100,19 @@ extern GSconf conf;
|
||||||
// PSM types == Texture Storage Format
|
// PSM types == Texture Storage Format
|
||||||
enum PSM_value
|
enum PSM_value
|
||||||
{
|
{
|
||||||
PSMCT32 = 0, // 000000
|
PSMCT32 = 0, // 00 0000
|
||||||
PSMCT24 = 1, // 000001
|
PSMCT24 = 1, // 00 0001
|
||||||
PSMCT16 = 2, // 000010
|
PSMCT16 = 2, // 00 0010
|
||||||
PSMCT16S = 10, // 001010
|
PSMCT16S = 10, // 00 1010
|
||||||
PSMT8 = 19, // 010011
|
PSMT8 = 19, // 01 0011
|
||||||
PSMT4 = 20, // 010100
|
PSMT4 = 20, // 01 0100
|
||||||
PSMT8H = 27, // 011011
|
PSMT8H = 27, // 01 1011
|
||||||
PSMT4HL = 36, // 100100
|
PSMT4HL = 36, // 10 0100
|
||||||
PSMT4HH = 44, // 101100
|
PSMT4HH = 44, // 10 1100
|
||||||
PSMT32Z = 48, // 110000
|
PSMT32Z = 48, // 11 0000
|
||||||
PSMT24Z = 49, // 110001
|
PSMT24Z = 49, // 11 0001
|
||||||
PSMT16Z = 50, // 110010
|
PSMT16Z = 50, // 11 0010
|
||||||
PSMT16SZ = 58, // 111010
|
PSMT16SZ = 58, // 11 1010
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check target bit mode. PSMCT32 and 32Z return 0, 24 and 24Z - 1
|
// Check target bit mode. PSMCT32 and 32Z return 0, 24 and 24Z - 1
|
||||||
|
@ -168,6 +168,25 @@ inline bool PSMT_IS16Z(int psm) {return ((psm & 0x32) == 0x32);}
|
||||||
// I'll have to look closer at it, because it'd seem like it'd return true for 24 bits.
|
// I'll have to look closer at it, because it'd seem like it'd return true for 24 bits.
|
||||||
inline bool PSMT_IS32BIT(int psm) {return !!(psm <= 1);}
|
inline bool PSMT_IS32BIT(int psm) {return !!(psm <= 1);}
|
||||||
|
|
||||||
|
// This function updates the 6th and 5th bit of psm
|
||||||
|
// 00 or 11 -> 00 ; 01 -> 10 ; 10 -> 01
|
||||||
|
inline int Switch_Top_Bytes (int X) {
|
||||||
|
if ( ( X & 0x30 ) == 0 )
|
||||||
|
return X;
|
||||||
|
else
|
||||||
|
return (X ^ 0x30);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some storage formats could share the same memory block (2 textures in 1 format). This include following combinations:
|
||||||
|
// PSMT24(24Z) with either 8H, 4HL, 4HH and PSMT4HL with PSMT4HH.
|
||||||
|
// We use slightly different versions of this function on comparison with GSDX, Storage format XOR 0x30 made Z-textures
|
||||||
|
// similar to normal ones and change higher bits on short (8 and 4 bits) textures.
|
||||||
|
inline bool PSMT_HAS_SHARED_BITS (int fpsm, int tpsm) {
|
||||||
|
int SUM = Switch_Top_Bytes(fpsm) + Switch_Top_Bytes(tpsm) ;
|
||||||
|
return (SUM == 0x15 || SUM == 0x1D || SUM == 0x2C || SUM == 0x30);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//----------------------- Data from registers -----------------------
|
//----------------------- Data from registers -----------------------
|
||||||
|
|
||||||
typedef union
|
typedef union
|
||||||
|
|
|
@ -37,6 +37,7 @@ using namespace std;
|
||||||
#include "zerogs.h"
|
#include "zerogs.h"
|
||||||
#include "targets.h"
|
#include "targets.h"
|
||||||
#include "ZeroGSShaders/zerogsshaders.h"
|
#include "ZeroGSShaders/zerogsshaders.h"
|
||||||
|
#include "ZZoglFlushHack.h"
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(disable:4244)
|
#pragma warning(disable:4244)
|
||||||
|
@ -49,6 +50,8 @@ GSconf conf;
|
||||||
|
|
||||||
int ppf, g_GSMultiThreaded, CurrentSavestate = 0;
|
int ppf, g_GSMultiThreaded, CurrentSavestate = 0;
|
||||||
int g_LastCRC = 0, g_TransferredToGPU = 0, s_frameskipping = 0;
|
int g_LastCRC = 0, g_TransferredToGPU = 0, s_frameskipping = 0;
|
||||||
|
int g_SkipFlushFrame = 0;
|
||||||
|
GetSkipCount GetSkipCount_Handler = 0;
|
||||||
|
|
||||||
int UPDATE_FRAMES = 16, g_nFrame = 0, g_nRealFrame = 0;
|
int UPDATE_FRAMES = 16, g_nFrame = 0, g_nRealFrame = 0;
|
||||||
float fFPS = 0;
|
float fFPS = 0;
|
||||||
|
@ -157,6 +160,7 @@ void ReportHacks(gameHacks hacks)
|
||||||
if (hacks.reget) ZZLog::WriteLn("Reget hack enabled.");
|
if (hacks.reget) ZZLog::WriteLn("Reget hack enabled.");
|
||||||
if (hacks.gust) ZZLog::WriteLn("Gust hack enabled.");
|
if (hacks.gust) ZZLog::WriteLn("Gust hack enabled.");
|
||||||
if (hacks.no_logz) ZZLog::WriteLn("'No logz' hack enabled.");
|
if (hacks.no_logz) ZZLog::WriteLn("'No logz' hack enabled.");
|
||||||
|
if (hacks.automatic_skip_draw) ZZLog::WriteLn("'Automatic skip draw' hack enabled.");
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListHacks()
|
void ListHacks()
|
||||||
|
@ -176,6 +180,54 @@ void ListHacks()
|
||||||
|
|
||||||
void CALLBACK GSsetGameCRC(int crc, int options)
|
void CALLBACK GSsetGameCRC(int crc, int options)
|
||||||
{
|
{
|
||||||
|
// build a list of function pointer for GetSkipCount (SkipDraw)
|
||||||
|
static GetSkipCount GSC_list[NUMBER_OF_TITLES];
|
||||||
|
static bool inited = false;
|
||||||
|
|
||||||
|
if (!inited)
|
||||||
|
{
|
||||||
|
inited = true;
|
||||||
|
|
||||||
|
memset(GSC_list, 0, sizeof(GSC_list));
|
||||||
|
// for(int i = 0; i < NUMBER_OF_TITLES; i++)
|
||||||
|
// {
|
||||||
|
// GSC_list[i] = GSC_Null;
|
||||||
|
// }
|
||||||
|
|
||||||
|
GSC_list[Okami] = GSC_Okami;
|
||||||
|
GSC_list[MetalGearSolid3] = GSC_MetalGearSolid3;
|
||||||
|
GSC_list[DBZBT2] = GSC_DBZBT2;
|
||||||
|
GSC_list[DBZBT3] = GSC_DBZBT3;
|
||||||
|
GSC_list[SFEX3] = GSC_SFEX3;
|
||||||
|
GSC_list[Bully] = GSC_Bully;
|
||||||
|
GSC_list[BullyCC] = GSC_BullyCC;
|
||||||
|
GSC_list[SoTC] = GSC_SoTC;
|
||||||
|
GSC_list[OnePieceGrandAdventure] = GSC_OnePieceGrandAdventure;
|
||||||
|
GSC_list[OnePieceGrandBattle] = GSC_OnePieceGrandBattle;
|
||||||
|
GSC_list[ICO] = GSC_ICO;
|
||||||
|
GSC_list[GT4] = GSC_GT4;
|
||||||
|
//FIXME GSC_list[WildArms4] = GSC_WildArms4;
|
||||||
|
GSC_list[WildArms5] = GSC_WildArms5;
|
||||||
|
GSC_list[Manhunt2] = GSC_Manhunt2;
|
||||||
|
GSC_list[CrashBandicootWoC] = GSC_CrashBandicootWoC;
|
||||||
|
GSC_list[ResidentEvil4] = GSC_ResidentEvil4;
|
||||||
|
GSC_list[Spartan] = GSC_Spartan;
|
||||||
|
GSC_list[AceCombat4] = GSC_AceCombat4;
|
||||||
|
GSC_list[Drakengard2] = GSC_Drakengard2;
|
||||||
|
GSC_list[Tekken5] = GSC_Tekken5;
|
||||||
|
GSC_list[IkkiTousen] = GSC_IkkiTousen;
|
||||||
|
GSC_list[GodOfWar] = GSC_GodOfWar;
|
||||||
|
GSC_list[GodOfWar2] = GSC_GodOfWar2;
|
||||||
|
GSC_list[GiTS] = GSC_GiTS;
|
||||||
|
GSC_list[Onimusha3] = GSC_Onimusha3;
|
||||||
|
GSC_list[TalesOfAbyss] = GSC_TalesOfAbyss;
|
||||||
|
GSC_list[SonicUnleashed] = GSC_SonicUnleashed;
|
||||||
|
GSC_list[Genji] = GSC_Genji;
|
||||||
|
GSC_list[StarOcean3] = GSC_StarOcean3;
|
||||||
|
GSC_list[ValkyrieProfile2] = GSC_ValkyrieProfile2;
|
||||||
|
GSC_list[RadiataStories] = GSC_RadiataStories;
|
||||||
|
}
|
||||||
|
|
||||||
// TEXDESTROY_THRESH starts out at 16.
|
// TEXDESTROY_THRESH starts out at 16.
|
||||||
VALIDATE_THRESH = 8;
|
VALIDATE_THRESH = 8;
|
||||||
conf.mrtdepth = (conf.settings().disable_mrt_depth != 0);
|
conf.mrtdepth = (conf.settings().disable_mrt_depth != 0);
|
||||||
|
@ -211,6 +263,9 @@ void CALLBACK GSsetGameCRC(int crc, int options)
|
||||||
ZZLog::WriteLn("Setting TEXDESTROY_THRESH to %d", TEXDESTROY_THRESH);
|
ZZLog::WriteLn("Setting TEXDESTROY_THRESH to %d", TEXDESTROY_THRESH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME need to check SkipDraw is positive (enabled by users)
|
||||||
|
GetSkipCount_Handler = GSC_list[crc_game_list[i].title];
|
||||||
|
|
||||||
conf.def_hacks._u32 |= crc_game_list[i].flags;
|
conf.def_hacks._u32 |= crc_game_list[i].flags;
|
||||||
ListHacks();
|
ListHacks();
|
||||||
return;
|
return;
|
||||||
|
@ -491,6 +546,7 @@ void CALLBACK GSvsync(int interlace)
|
||||||
g_nAlphaVars = 0;
|
g_nAlphaVars = 0;
|
||||||
g_nResolve = 0;
|
g_nResolve = 0;
|
||||||
g_nFramesSkipped = 0;
|
g_nFramesSkipped = 0;
|
||||||
|
g_SkipFlushFrame = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(ZEROGS_DEVBUILD)
|
#if defined(ZEROGS_DEVBUILD)
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
<Compiler>
|
<Compiler>
|
||||||
<Add option="-Wall" />
|
<Add option="-Wall" />
|
||||||
<Add option="-g" />
|
<Add option="-g" />
|
||||||
|
<Add option="-DZEROGS_DEVBUILD" />
|
||||||
<Add option="-D_DEBUG" />
|
<Add option="-D_DEBUG" />
|
||||||
</Compiler>
|
</Compiler>
|
||||||
<Linker>
|
<Linker>
|
||||||
|
@ -150,6 +151,8 @@
|
||||||
<Unit filename="../../ZZoglCRTC.h" />
|
<Unit filename="../../ZZoglCRTC.h" />
|
||||||
<Unit filename="../../ZZoglCreate.cpp" />
|
<Unit filename="../../ZZoglCreate.cpp" />
|
||||||
<Unit filename="../../ZZoglFlush.cpp" />
|
<Unit filename="../../ZZoglFlush.cpp" />
|
||||||
|
<Unit filename="../../ZZoglFlushHack.cpp" />
|
||||||
|
<Unit filename="../../ZZoglFlushHack.h" />
|
||||||
<Unit filename="../../ZZoglSave.cpp" />
|
<Unit filename="../../ZZoglSave.cpp" />
|
||||||
<Unit filename="../../ZZoglShaders.cpp" />
|
<Unit filename="../../ZZoglShaders.cpp" />
|
||||||
<Unit filename="../../ZZoglShoots.cpp" />
|
<Unit filename="../../ZZoglShoots.cpp" />
|
||||||
|
|
|
@ -173,7 +173,7 @@ typedef union
|
||||||
u32 reget : 1; // some sort of weirdness in ReGet() code
|
u32 reget : 1; // some sort of weirdness in ReGet() code
|
||||||
u32 gust : 1; // Needed for Gustgames fast update.
|
u32 gust : 1; // Needed for Gustgames fast update.
|
||||||
u32 no_logz : 1; // Intended for linux -- not logarithmic Z.
|
u32 no_logz : 1; // Intended for linux -- not logarithmic Z.
|
||||||
u32 reserved1 :1;
|
u32 automatic_skip_draw :1; // allow debug of the automatic skip draw option
|
||||||
u32 reserved2 :1;
|
u32 reserved2 :1;
|
||||||
};
|
};
|
||||||
u32 _u32;
|
u32 _u32;
|
||||||
|
@ -209,6 +209,7 @@ typedef struct
|
||||||
int width, height; // View target size, has no impact towards speed
|
int width, height; // View target size, has no impact towards speed
|
||||||
int x, y; // Lets try for a persistant window position.
|
int x, y; // Lets try for a persistant window position.
|
||||||
bool isWideScreen; // Widescreen support
|
bool isWideScreen; // Widescreen support
|
||||||
|
u32 SkipDraw;
|
||||||
u32 log;
|
u32 log;
|
||||||
|
|
||||||
void incAA() { aa++; if (aa > 4) aa = 0; }
|
void incAA() { aa++; if (aa > 4) aa = 0; }
|
||||||
|
@ -271,8 +272,8 @@ typedef struct
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
width = 640;
|
width = 800;
|
||||||
height = 480;
|
height = 600;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "Mem.h"
|
#include "Mem.h"
|
||||||
#include "zerogs.h"
|
#include "zerogs.h"
|
||||||
#include "targets.h"
|
#include "targets.h"
|
||||||
|
#include "ZZoglFlushHack.h"
|
||||||
|
|
||||||
using namespace ZeroGS;
|
using namespace ZeroGS;
|
||||||
|
|
||||||
|
@ -375,7 +376,7 @@ inline void FlushUpdateEffect()
|
||||||
// Check, maybe we cold skip flush
|
// Check, maybe we cold skip flush
|
||||||
inline bool IsFlushNoNeed(VB& curvb, const pixTest& curtest)
|
inline bool IsFlushNoNeed(VB& curvb, const pixTest& curtest)
|
||||||
{
|
{
|
||||||
if (curvb.nCount == 0 || (curtest.zte && curtest.ztst == 0))
|
if (curvb.nCount == 0 || (curtest.zte && curtest.ztst == 0) || IsBadFrame(curvb))
|
||||||
{
|
{
|
||||||
curvb.nCount = 0;
|
curvb.nCount = 0;
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -0,0 +1,531 @@
|
||||||
|
/* ZZ Open GL graphics plugin
|
||||||
|
* Copyright (c)2010 gregory.hainaut@gmail.com, zeydlitz@gmail.com
|
||||||
|
* Based on GSdx Copyright (C) 2007-2009 Gabest
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This file is a collection of hack for removing the blur effect on some games
|
||||||
|
* The blur renders very badly on high screen flat panel.
|
||||||
|
*
|
||||||
|
* To avoid severals combo-box, the hack detects the game based on crc
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ZZoglFlushHack.h"
|
||||||
|
|
||||||
|
inline bool GABEST_HAS_SHARED_BITS (int fbp, int fpsm, int tbp, int tpsm)
|
||||||
|
{
|
||||||
|
if ( !PSMT_HAS_SHARED_BITS (fpsm, tpsm) )
|
||||||
|
return ((fbp ^ tbp) == 0);
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// GSC_... function has been imported from GSdx
|
||||||
|
void GSC_Okami(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == 0x00e00 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x00000 && fi.TPSM == PSMCT32)
|
||||||
|
skip = 1000;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == 0x00e00 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x03800 && fi.TPSM == PSMT4)
|
||||||
|
skip = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_MetalGearSolid3(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == 0x02000 && fi.FPSM == PSMCT32 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01000) && fi.TPSM == PSMCT24)
|
||||||
|
skip = 1000; // 76, 79
|
||||||
|
else if(fi.TME && fi.FBP == 0x02800 && fi.FPSM == PSMCT24 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01000) && fi.TPSM == PSMCT32)
|
||||||
|
skip = 1000; // 69
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01000) && fi.FPSM == PSMCT32)
|
||||||
|
skip = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_DBZBT2(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && /*fi.FBP == 0x00000 && fi.FPSM == PSMCT16 &&*/ fi.TBP0 == 0x02000 && fi.TPSM == PSMT16Z)
|
||||||
|
skip = 27;
|
||||||
|
else if(!fi.TME && fi.FBP == 0x03000 && fi.FPSM == PSMCT16)
|
||||||
|
skip = 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_DBZBT3(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == 0x01c00 && fi.FPSM == PSMCT32 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x00e00) && fi.TPSM == PSMT8H)
|
||||||
|
skip = 24; // blur
|
||||||
|
else if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00e00) && fi.FPSM == PSMCT32 && fi.TPSM == PSMT8H)
|
||||||
|
skip = 28; // outline
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_SFEX3(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == 0x00500 && fi.FPSM == PSMCT16 && fi.TBP0 == 0x00f00 && fi.TPSM == PSMCT16)
|
||||||
|
skip = 2; // blur
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_Bully(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
// Test is useless !
|
||||||
|
// if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01180) && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01180) && fi.FBP == fi.TBP0 && fi.FPSM == PSMCT32 && fi.FPSM == fi.TPSM)
|
||||||
|
// return; // allowed
|
||||||
|
if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01180) && fi.FPSM == PSMCT16S && fi.TBP0 == 0x02300 && fi.TPSM == PSMT16SZ)
|
||||||
|
skip = 6;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01180) && fi.FPSM == PSMCT32)
|
||||||
|
skip = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_BullyCC(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
// Test is useless !
|
||||||
|
// if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01180) && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01180) && fi.FBP == fi.TBP0 && fi.FPSM == PSMCT32 && fi.FPSM == fi.TPSM)
|
||||||
|
// return; // allowed
|
||||||
|
|
||||||
|
if(!fi.TME && fi.FBP == 0x02800 && fi.FPSM == PSMCT24)
|
||||||
|
skip = 9;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_SoTC(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
// Not needed anymore? What did it fix anyway? (rama)
|
||||||
|
/*if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == 0x02b80 && fi.FPSM == PSMCT24 && fi.TBP0 == 0x01e80 && fi.TPSM == PSMCT24)
|
||||||
|
skip = 9;
|
||||||
|
else if(fi.TME && fi.FBP == 0x01c00 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x03800 && fi.TPSM == PSMCT32)
|
||||||
|
skip = 8;
|
||||||
|
else if(fi.TME && fi.FBP == 0x01e80 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x03880 && fi.TPSM == PSMCT32)
|
||||||
|
skip = 8;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_OnePieceGrandAdventure(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == 0x02d00 && fi.FPSM == PSMCT16 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x00e00 || fi.TBP0 == 0x00f00) && fi.TPSM == PSMCT16)
|
||||||
|
skip = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_OnePieceGrandBattle(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == 0x02d00 && fi.FPSM == PSMCT16 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x00f00) && fi.TPSM == PSMCT16)
|
||||||
|
skip = 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_ICO(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == 0x00800 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x03d00 && fi.TPSM == PSMCT32)
|
||||||
|
skip = 3;
|
||||||
|
else if(fi.TME && fi.FBP == 0x00800 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x02800 && fi.TPSM == PSMT8H)
|
||||||
|
skip = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.TBP0 == 0x00800 && fi.TPSM == PSMCT32)
|
||||||
|
skip = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_GT4(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && (fi.FBP == 0x03440 || fi.FBP >= 0x03e00) && fi.FPSM == PSMCT32 && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x01400) && fi.TPSM == PSMT8)
|
||||||
|
skip = 880;
|
||||||
|
else if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x01400) && fi.FPSM == PSMCT24 && fi.TBP0 >= 0x03420 && fi.TPSM == PSMT8)
|
||||||
|
{
|
||||||
|
// TODO: removes gfx from where it is not supposed to (garage)
|
||||||
|
// skip = 58;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_WildArms4(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == 0x03100 && fi.FPSM == PSMT32Z && fi.TBP0 == 0x01c00 && fi.TPSM == PSMT32Z)
|
||||||
|
skip = 100;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == 0x00e00 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x02a00 && fi.TPSM == PSMCT32)
|
||||||
|
skip = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_WildArms5(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == 0x03100 && fi.FPSM == PSMT32Z && fi.TBP0 == 0x01c00 && fi.TPSM == PSMT32Z)
|
||||||
|
skip = 100;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == 0x00e00 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x02a00 && fi.TPSM == PSMCT32)
|
||||||
|
skip = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_Manhunt2(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == 0x03c20 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x01400 && fi.TPSM == PSMT8)
|
||||||
|
skip = 640;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_CrashBandicootWoC(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
// Test is useless !
|
||||||
|
// if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00a00) && (fi.TBP0 == 0x00000 || fi.TBP0 == 0x00a00) && fi.FBP == fi.TBP0 && fi.FPSM == PSMCT32 && fi.FPSM == fi.TPSM)
|
||||||
|
// return false; // allowed
|
||||||
|
|
||||||
|
if(fi.TME && fi.FBP == 0x02200 && fi.FPSM == PSMT24Z && fi.TBP0 == 0x01400 && fi.TPSM == PSMT24Z)
|
||||||
|
skip = 41;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00a00) && fi.FPSM == PSMCT32 && fi.TBP0 == 0x03c00 && fi.TPSM == PSMCT32)
|
||||||
|
skip = 0;
|
||||||
|
else if(!fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00a00))
|
||||||
|
skip = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_ResidentEvil4(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == 0x03100 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x01c00 && fi.TPSM == PSMT24Z)
|
||||||
|
skip = 176;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_Spartan(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == 0x02000 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x00000 && fi.TPSM == PSMCT32)
|
||||||
|
skip = 107;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_AceCombat4(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == 0x02a00 && fi.FPSM == PSMT24Z && fi.TBP0 == 0x01600 && fi.TPSM == PSMT24Z)
|
||||||
|
skip = 71; // clouds (z, 16-bit)
|
||||||
|
else if(fi.TME && fi.FBP == 0x02900 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x00000 && fi.TPSM == PSMCT24)
|
||||||
|
skip = 28; // blur
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_Drakengard2(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == 0x026c0 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x00a00 && fi.TPSM == PSMCT32)
|
||||||
|
skip = 64;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_Tekken5(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == 0x02ea0 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x00000 && fi.TPSM == PSMCT32)
|
||||||
|
skip = 95;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_IkkiTousen(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == 0x00a80 && fi.FPSM == PSMT24Z && fi.TBP0 == 0x01180 && fi.TPSM == PSMT24Z)
|
||||||
|
skip = 1000; // shadow (result is broken without depth copy, also includes 16 bit)
|
||||||
|
else if(fi.TME && fi.FBP == 0x00700 && fi.FPSM == PSMT24Z && fi.TBP0 == 0x01180 && fi.TPSM == PSMT24Z)
|
||||||
|
skip = 11; // blur
|
||||||
|
}
|
||||||
|
else if(skip > 7)
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == 0x00700 && fi.FPSM == PSMCT16 && fi.TBP0 == 0x00700 && fi.TPSM == PSMCT16)
|
||||||
|
skip = 7; // the last steps of shadow drawing
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_GodOfWar(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == 0x00000 && fi.FPSM == PSMCT16 && fi.TBP0 == 0x00000 && fi.TPSM == PSMCT16)
|
||||||
|
{
|
||||||
|
// skip = 30; //GSdx
|
||||||
|
skip = 4; // 23 or 4 need more testing
|
||||||
|
}
|
||||||
|
else if(fi.TME && fi.FBP == 0x00000 && fi.FPSM == PSMCT32 && fi.TBP0 == 0x00000 && fi.TPSM == PSMCT32 && fi.FBMSK == 0xff000000)
|
||||||
|
skip = 1; // blur
|
||||||
|
else if(fi.FBP == 0x00000 && fi.FPSM == PSMCT32 && fi.TPSM == PSMT8
|
||||||
|
&& ((fi.TZTST == 2 && fi.FBMSK == 0x00FFFFFF) || (fi.TZTST == 1 && fi.FBMSK == 0x00FFFFFF) || (fi.TZTST == 3 && fi.FBMSK == 0xFF000000)))
|
||||||
|
skip = 1; // wall of fog
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_GodOfWar2(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME)
|
||||||
|
{
|
||||||
|
if((fi.FBP == 0x00100 && fi.FPSM == PSMCT16 && fi.TBP0 == 0x00100 && fi.TPSM == PSMCT16) // ntsc
|
||||||
|
|| (fi.FBP == 0x02100 && fi.FPSM == PSMCT16 && fi.TBP0 == 0x02100 && fi.TPSM == PSMCT16)) // pal
|
||||||
|
skip = 29; // shadows
|
||||||
|
if(fi.FBP == 0x00100 && fi.FPSM == PSMCT32 && (fi.TBP0 & 0x03000) == 0x03000
|
||||||
|
&& (fi.TPSM == PSMT8 || fi.TPSM == PSMT4)
|
||||||
|
&& ((fi.TZTST == 2 && fi.FBMSK == 0x00FFFFFF) || (fi.TZTST == 1 && fi.FBMSK == 0x00FFFFFF) || (fi.TZTST == 3 && fi.FBMSK == 0xFF000000)))
|
||||||
|
skip = 1; // wall of fog
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_GiTS(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == 0x01400 && fi.FPSM == PSMCT16 && fi.TBP0 == 0x02e40 && fi.TPSM == PSMCT16)
|
||||||
|
skip = 1315;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_Onimusha3(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(fi.TME /*&& (fi.FBP == 0x00000 || fi.FBP == 0x00700)*/ && (fi.TBP0 == 0x01180 || fi.TBP0 == 0x00e00 || fi.TBP0 == 0x01000 || fi.TBP0 == 0x01200) && (fi.TPSM == PSMCT32 || fi.TPSM == PSMCT24))
|
||||||
|
skip = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_TalesOfAbyss(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00e00) && fi.TBP0 == 0x01c00 && fi.TPSM == PSMT8) // copies the z buffer to the alpha channel of the fb
|
||||||
|
skip = 1000;
|
||||||
|
else if(fi.TME && (fi.FBP == 0x00000 || fi.FBP == 0x00e00) && (fi.TBP0 == 0x03560 || fi.TBP0 == 0x038e0) && fi.TPSM == PSMCT32)
|
||||||
|
skip = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.TPSM != PSMT8)
|
||||||
|
skip = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_SonicUnleashed(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == 0x02200 && fi.FPSM == PSMCT16S && fi.TBP0 == 0x00000 && fi.TPSM == PSMCT16)
|
||||||
|
skip = 1000; // shadow
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == 0x00000 && fi.FPSM == PSMCT16 && fi.TBP0 == 0x02200 && fi.TPSM == PSMCT16S)
|
||||||
|
skip = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_Genji(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == 0x01500 && fi.FPSM == PSMCT16 && fi.TBP0 == 0x00e00 && fi.TPSM == PSMT16Z)
|
||||||
|
skip = 6; //
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_StarOcean3(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSMCT32 && fi.TPSM == PSMT4HH)
|
||||||
|
skip = 1000; //
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSMCT32 && fi.TPSM == PSMT4HH))
|
||||||
|
skip = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_ValkyrieProfile2(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSMCT32 && fi.TPSM == PSMT4HH)
|
||||||
|
skip = 1000; //
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSMCT32 && fi.TPSM == PSMT4HH))
|
||||||
|
skip = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void GSC_RadiataStories(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSMCT32 && fi.TPSM == PSMT4HH)
|
||||||
|
skip = 1000; // Shadows
|
||||||
|
else if (fi.TME && fi.FBP == fi.TBP0 && (fi.TBP0 == 0x3700 || fi.TBP0 == 0x3400) && fi.TZTST == 1)
|
||||||
|
skip = 1; // Start manu issue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(!(fi.TME && fi.FBP == fi.TBP0 && fi.FPSM == PSMCT32 && fi.TPSM == PSMT4HH))
|
||||||
|
skip = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GSC_HauntingGround(const GSFrameInfo& fi, int& skip)
|
||||||
|
{
|
||||||
|
// Note GSdx seems to use invert somewhere FBMSK. So values were inverted
|
||||||
|
if(skip == 0)
|
||||||
|
{
|
||||||
|
if(fi.TME && fi.FPSM == fi.TPSM && fi.TPSM == PSMCT16S && fi.FBMSK == ~(0x03FFF))
|
||||||
|
skip = 1;
|
||||||
|
else if(fi.TME && fi.FBP == 0x3000 && fi.TBP0 == 0x3380)
|
||||||
|
skip = 1; // bloom
|
||||||
|
else if(fi.TME && fi.FBP == fi.TBP0 && fi.TBP0 == 0x3000 && fi.FBMSK == ~(0xFFFFFF) &&
|
||||||
|
GABEST_HAS_SHARED_BITS(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM))
|
||||||
|
skip = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Record skipped frame to allow better analysis
|
||||||
|
// #define FRAME_RECORDING_ON 1
|
||||||
|
#ifdef FRAME_RECORDING_ON
|
||||||
|
static const u32 MAX_FRAMES = 500;
|
||||||
|
static GSFrameInfo FrameAppear[MAX_FRAMES];
|
||||||
|
static u32 Rec_Numbers = 0;
|
||||||
|
|
||||||
|
void RecordNewFrames(ZeroGS::VB& curvb, GSFrameInfo fi) {
|
||||||
|
if (Rec_Numbers >= MAX_FRAMES)
|
||||||
|
return;
|
||||||
|
|
||||||
|
u32 i;
|
||||||
|
bool was_recorded = false;
|
||||||
|
for (i = 0; i < Rec_Numbers; i++ ) {
|
||||||
|
if (FrameAppear[i].FBP == fi.FBP && FrameAppear[i].FPSM == fi.FPSM
|
||||||
|
&& FrameAppear[i].TBP0 == fi.TBP0 && FrameAppear[i].TPSM == fi.TPSM) {
|
||||||
|
was_recorded = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!was_recorded) {
|
||||||
|
FrameAppear[Rec_Numbers] = fi;
|
||||||
|
Rec_Numbers++;
|
||||||
|
ZZLog::Print( "New frame %d, skip %d | fpb: %x fpsm: %d fpmsk: %x tme: %x tbp0: %x tpsm: %d tztst: %x | bits %d\n", \
|
||||||
|
Rec_Numbers, g_SkipFlushFrame, fi.FBP, fi.FPSM, fi.FBMSK, fi.TME, fi.TBP0, fi.TPSM, fi.TZTST, GABEST_HAS_SHARED_BITS(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM) );
|
||||||
|
|
||||||
|
// Dump a nice picture of the frame
|
||||||
|
char filename[255];
|
||||||
|
sprintf(filename, "SkipFlushFrame_%d__%d.tga", g_SkipFlushFrame, Rec_Numbers);
|
||||||
|
ZeroGS::SaveRenderTarget(filename, curvb.prndr->fbw, curvb.prndr->fbh, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
__forceinline bool IsBadFrame(ZeroGS::VB& curvb)
|
||||||
|
{
|
||||||
|
GSFrameInfo fi;
|
||||||
|
|
||||||
|
// Keep GSdx naming convention to ease sharing code
|
||||||
|
fi.FBP = curvb.frame.fbp;
|
||||||
|
fi.FPSM = curvb.frame.psm;
|
||||||
|
fi.FBMSK = ~curvb.frame.fbm;
|
||||||
|
fi.TME = curvb.curprim.tme;
|
||||||
|
fi.TBP0 = curvb.tex0.tbp0;
|
||||||
|
fi.TPSM = curvb.tex0.psm;
|
||||||
|
fi.TZTST = curvb.test.ztst;
|
||||||
|
|
||||||
|
if (GetSkipCount_Handler && conf.settings().automatic_skip_draw)
|
||||||
|
GetSkipCount_Handler(fi, g_SkipFlushFrame);
|
||||||
|
|
||||||
|
if(g_SkipFlushFrame == 0 && (conf.SkipDraw > 0))
|
||||||
|
{
|
||||||
|
if(fi.TME)
|
||||||
|
{
|
||||||
|
// depth textures (bully, mgs3s1 intro, Front Mission 5)
|
||||||
|
// Or General, often problematic post processing
|
||||||
|
if (PSMT_ISZTEX(fi.TPSM) || (GABEST_HAS_SHARED_BITS(fi.FBP, fi.FPSM, fi.TBP0, fi.TPSM)))
|
||||||
|
g_SkipFlushFrame = conf.SkipDraw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(g_SkipFlushFrame > 0)
|
||||||
|
{
|
||||||
|
#ifdef FRAME_RECORDING_ON
|
||||||
|
RecordNewFrames(curvb, fi);
|
||||||
|
#endif
|
||||||
|
g_SkipFlushFrame--;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
|
@ -0,0 +1,83 @@
|
||||||
|
/* ZZ Open GL graphics plugin
|
||||||
|
* Copyright (c)2010 gregory.hainaut@gmail.com
|
||||||
|
* Based on GSdx Copyright (C) 2007-2009 Gabest
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* This file is a collection of hack for removing the blur effect on some games
|
||||||
|
* The blur renders very badly on high screen flat panel.
|
||||||
|
*
|
||||||
|
* To avoid severals combo-box, the hack detects the game based on crc
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef ZZOGL_FLUSH_HACK_H_INCLUDED
|
||||||
|
#define ZZOGL_FLUSH_HACK_H_INCLUDED
|
||||||
|
|
||||||
|
#include "GS.h"
|
||||||
|
#include "zerogs.h"
|
||||||
|
|
||||||
|
extern int g_SkipFlushFrame;
|
||||||
|
|
||||||
|
struct GSFrameInfo
|
||||||
|
{
|
||||||
|
u32 FBP;
|
||||||
|
u32 FPSM;
|
||||||
|
u32 FBMSK;
|
||||||
|
u32 TBP0;
|
||||||
|
u32 TPSM;
|
||||||
|
u32 TZTST;
|
||||||
|
bool TME;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef void (*GetSkipCount)(const GSFrameInfo& fi, int& skip);
|
||||||
|
|
||||||
|
extern GetSkipCount GetSkipCount_Handler;
|
||||||
|
|
||||||
|
void GSC_Okami(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_MetalGearSolid3(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_DBZBT2(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_DBZBT3(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_SFEX3(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_Bully(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_BullyCC(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_SoTC(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_OnePieceGrandAdventure(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_OnePieceGrandBattle(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_ICO(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_GT4(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_WildArms4(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_WildArms5(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_Manhunt2(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_CrashBandicootWoC(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_ResidentEvil4(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_Spartan(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_AceCombat4(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_Drakengard2(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_Tekken5(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_IkkiTousen(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_GodOfWar(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_GodOfWar2(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_GiTS(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_Onimusha3(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_TalesOfAbyss(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_SonicUnleashed(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_Genji(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_StarOcean3(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_ValkyrieProfile2(const GSFrameInfo& fi, int& skip);
|
||||||
|
void GSC_RadiataStories(const GSFrameInfo& fi, int& skip);
|
||||||
|
|
||||||
|
extern bool IsBadFrame(ZeroGS::VB& curvb);
|
||||||
|
#endif
|
|
@ -420,6 +420,7 @@ union
|
||||||
CMemoryTarget* pmemtarg; // the current mem target set
|
CMemoryTarget* pmemtarg; // the current mem target set
|
||||||
CRenderTarget* prndr;
|
CRenderTarget* prndr;
|
||||||
CDepthTarget* pdepth;
|
CDepthTarget* pdepth;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Return, if tcc, aem or psm mode told us, than Alpha test should be used
|
// Return, if tcc, aem or psm mode told us, than Alpha test should be used
|
||||||
|
|
Loading…
Reference in New Issue