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
|
@ -25,7 +25,9 @@ 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);
|
||||
return 0;
|
||||
|
@ -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;
|
||||
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;
|
||||
|
@ -72,8 +73,10 @@ LRESULT WINAPI MsgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM 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);
|
||||
|
@ -106,6 +109,7 @@ bool GLWindow::CreateWindow(void *pDisplay)
|
|||
}
|
||||
|
||||
AdjustWindowRectEx(&rc, dwStyle, FALSE, dwExStyle);
|
||||
|
||||
GetWindowRect(GetDesktopWindow(), &rcdesktop);
|
||||
|
||||
GShwnd = CreateWindowEx(
|
||||
|
@ -130,7 +134,9 @@ bool GLWindow::CreateWindow(void *pDisplay)
|
|||
SetWindowLongPtr(GShwnd, GWLP_WNDPROC, (LPARAM)(WNDPROC)MsgProc);
|
||||
|
||||
ShowWindow(GShwnd, SW_SHOWDEFAULT);
|
||||
|
||||
UpdateWindow(GShwnd);
|
||||
|
||||
SetFocus(GShwnd);
|
||||
|
||||
return (pDisplay != NULL);
|
||||
|
@ -149,6 +155,7 @@ bool GLWindow::ReleaseWindow()
|
|||
{
|
||||
MessageBox(NULL, "Release Rendering Context Failed.", "SHUTDOWN ERROR", MB_OK | MB_ICONINFORMATION);
|
||||
}
|
||||
|
||||
hRC = NULL; // Set RC To NULL
|
||||
}
|
||||
|
||||
|
@ -179,7 +186,8 @@ 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;
|
||||
|
||||
|
@ -187,14 +195,18 @@ bool GLWindow::DisplayWindow(int _width, int _height)
|
|||
dwStyle = WS_POPUP;
|
||||
ShowCursor(FALSE);
|
||||
}
|
||||
else {
|
||||
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;
|
||||
|
@ -204,7 +216,8 @@ bool GLWindow::DisplayWindow(int _width, int _height)
|
|||
|
||||
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);
|
||||
|
@ -214,6 +227,7 @@ bool GLWindow::DisplayWindow(int _width, int _height)
|
|||
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 (MessageBox(NULL, "The Requested Fullscreen Mode Is Not Supported By\nYour Video Card. Use Windowed Mode Instead?", "NeHe GL", MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
|
||||
|
@ -222,12 +236,14 @@ bool GLWindow::DisplayWindow(int _width, int _height)
|
|||
return false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
// change to default resolution
|
||||
ChangeDisplaySettings(NULL, 0);
|
||||
}
|
||||
|
||||
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))) {
|
||||
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))) {
|
||||
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)) {
|
||||
if (!SetPixelFormat(hDC, PixelFormat, &pfd))
|
||||
{
|
||||
MessageBox(NULL, "(3) Can't Set The PixelFormat.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!(hRC=wglCreateContext(hDC))) {
|
||||
if (!(hRC = wglCreateContext(hDC)))
|
||||
{
|
||||
MessageBox(NULL, "(4) Can't Create A GL Rendering Context.", "ERROR", MB_OK | MB_ICONEXCLAMATION);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!wglMakeCurrent(hDC,hRC)) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,6 +43,7 @@ bool GLWindow::ReleaseWindow()
|
|||
}
|
||||
|
||||
glXDestroyContext(glDisplay, context);
|
||||
|
||||
context = NULL;
|
||||
}
|
||||
|
||||
|
@ -55,6 +56,7 @@ bool GLWindow::ReleaseWindow()
|
|||
XF86VidModeSetViewPort(glDisplay, glScreen, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -63,6 +65,7 @@ void GLWindow::CloseWindow()
|
|||
conf.x = x;
|
||||
conf.y = y;
|
||||
SaveConfig();
|
||||
|
||||
if (glDisplay != NULL)
|
||||
{
|
||||
XCloseDisplay(glDisplay);
|
||||
|
@ -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 */
|
||||
|
@ -155,6 +163,7 @@ bool GLWindow::DisplayWindow(int _width, int _height)
|
|||
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;
|
||||
|
@ -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
|
||||
|
@ -236,8 +249,10 @@ void GLWindow::SetTitle(char *strtitle)
|
|||
XTextProperty prop;
|
||||
memset(&prop, 0, sizeof(prop));
|
||||
char* ptitle = strtitle;
|
||||
|
||||
if (XStringListToTextProperty(&ptitle, 1, &prop))
|
||||
XSetWMName(glDisplay, glWindow, &prop);
|
||||
|
||||
XFree(prop.value);
|
||||
}
|
||||
|
||||
|
@ -253,6 +268,7 @@ void GLWindow::ResizeCheck()
|
|||
width = event.xconfigure.width;
|
||||
height = event.xconfigure.height;
|
||||
}
|
||||
|
||||
if ((event.xconfigure.x != x) || (event.xconfigure.y != y))
|
||||
{
|
||||
x = event.xconfigure.x;
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "GS.h"
|
||||
|
@ -98,15 +99,18 @@ BOOL g_bWriteProfile = 0;
|
|||
#endif
|
||||
|
||||
int s_frameskipping = 0;
|
||||
u32 CALLBACK PS2EgetLibType() {
|
||||
u32 CALLBACK PS2EgetLibType()
|
||||
{
|
||||
return PS2E_LT_GS;
|
||||
}
|
||||
|
||||
char* CALLBACK PS2EgetLibName() {
|
||||
char* CALLBACK PS2EgetLibName()
|
||||
{
|
||||
return libraryName;
|
||||
}
|
||||
|
||||
u32 CALLBACK PS2EgetLibVersion2(u32 type) {
|
||||
u32 CALLBACK PS2EgetLibVersion2(u32 type)
|
||||
{
|
||||
return (zgsversion << 16) | (zgsrevision << 8) | zgsbuild | (zgsminor << 24);
|
||||
}
|
||||
|
||||
|
@ -153,6 +157,7 @@ namespace ZZLog
|
|||
void _Print(const char *str)
|
||||
{
|
||||
printf("ZZogl-PG: %s", str);
|
||||
|
||||
if (IsLogging()) fprintf(gsLog, str);
|
||||
}
|
||||
|
||||
|
@ -173,7 +178,9 @@ namespace ZZLog
|
|||
va_list list;
|
||||
|
||||
va_start(list, fmt);
|
||||
|
||||
if (IsLogging()) vfprintf(gsLog, fmt, list);
|
||||
|
||||
va_end(list);
|
||||
}
|
||||
|
||||
|
@ -193,9 +200,13 @@ namespace ZZLog
|
|||
va_list list;
|
||||
|
||||
va_start(list, fmt);
|
||||
|
||||
if (IsLogging()) vfprintf(gsLog, fmt, list);
|
||||
|
||||
printf("ZZogl-PG: ");
|
||||
|
||||
vprintf(fmt, list);
|
||||
|
||||
va_end(list);
|
||||
}
|
||||
|
||||
|
@ -207,8 +218,11 @@ namespace ZZLog
|
|||
char tmp[512];
|
||||
|
||||
va_start(list, fmt);
|
||||
|
||||
if (IsLogging()) vfprintf(gsLog, fmt, list);
|
||||
|
||||
va_end(list);
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -225,8 +239,10 @@ namespace ZZLog
|
|||
if (IsLogging()) vfprintf(gsLog, fmt, list);
|
||||
|
||||
printf("ZZogl-PG(PRIM): ");
|
||||
|
||||
vprintf(fmt, list);
|
||||
}
|
||||
|
||||
va_end(list);
|
||||
|
||||
#endif
|
||||
|
@ -244,7 +260,9 @@ namespace ZZLog
|
|||
vfprintf(gsLog, fmt, list);
|
||||
fprintf(gsLog, "\n");
|
||||
}
|
||||
|
||||
printf("ZZogl-PG(GS): ");
|
||||
|
||||
vprintf(fmt, list);
|
||||
printf("\n");
|
||||
va_end(list);
|
||||
|
@ -257,12 +275,15 @@ namespace ZZLog
|
|||
va_list list;
|
||||
|
||||
va_start(list, fmt);
|
||||
|
||||
if (IsLogging())
|
||||
{
|
||||
vfprintf(gsLog, fmt, list);
|
||||
fprintf(gsLog, "\n");
|
||||
}
|
||||
|
||||
printf("ZZogl-PG(Warning): ");
|
||||
|
||||
vprintf(fmt, list);
|
||||
va_end(list);
|
||||
printf("\n");
|
||||
|
@ -275,12 +296,15 @@ namespace ZZLog
|
|||
va_list list;
|
||||
|
||||
va_start(list, fmt);
|
||||
|
||||
if (IsLogging())
|
||||
{
|
||||
vfprintf(gsLog, fmt, list);
|
||||
fprintf(gsLog, "\n");
|
||||
}
|
||||
|
||||
printf("ZZogl-PG(Debug): ");
|
||||
|
||||
vprintf(fmt, list);
|
||||
printf("\n");
|
||||
va_end(list);
|
||||
|
@ -300,18 +324,22 @@ namespace ZZLog
|
|||
vfprintf(gsLog, fmt, list);
|
||||
fprintf(gsLog, "\n");
|
||||
}
|
||||
|
||||
printf("ZZogl-PG(Error): ");
|
||||
|
||||
vprintf(fmt, list);
|
||||
printf("\n");
|
||||
va_end(list);
|
||||
}
|
||||
};
|
||||
|
||||
void CALLBACK GSsetBaseMem(void* pmem) {
|
||||
void CALLBACK GSsetBaseMem(void* pmem)
|
||||
{
|
||||
g_pBasePS2Mem = (u8*)pmem;
|
||||
}
|
||||
|
||||
void CALLBACK GSsetSettingsDir(const char* dir) {
|
||||
void CALLBACK GSsetSettingsDir(const char* dir)
|
||||
{
|
||||
s_strIniPath = (dir == NULL) ? "inis/" : dir;
|
||||
}
|
||||
|
||||
|
@ -334,9 +362,11 @@ void CALLBACK GSsetGameCRC(int crc, int options)
|
|||
g_GameSettings |= GAME_PATH3HACK;
|
||||
|
||||
bool CRCValueChanged = (g_LastCRC != crc);
|
||||
|
||||
g_LastCRC = crc;
|
||||
|
||||
ZZLog::Error_Log("CRC = %x", crc);
|
||||
|
||||
if (CRCValueChanged && (crc != 0))
|
||||
{
|
||||
for (int i = 0; i < GAME_INFO_INDEX; i++)
|
||||
|
@ -344,11 +374,15 @@ void CALLBACK GSsetGameCRC(int crc, int options)
|
|||
if (crc_game_list[i].crc == crc)
|
||||
{
|
||||
if (crc_game_list[i].v_thresh > 0) VALIDATE_THRESH = crc_game_list[i].v_thresh;
|
||||
|
||||
if (crc_game_list[i].t_thresh > 0) TEXDESTROY_THRESH = crc_game_list[i].t_thresh;
|
||||
|
||||
conf.gamesettings |= crc_game_list[i].flags;
|
||||
|
||||
g_GameSettings = conf.gamesettings | options;
|
||||
|
||||
ZZLog::Error_Log("Found CRC[%x] in crc game list.", crc);
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -361,9 +395,11 @@ void CALLBACK GSsetFrameSkip(int frameskip)
|
|||
{
|
||||
FUNCLOG
|
||||
s_frameskipping |= frameskip;
|
||||
if( frameskip && g_nFrameRender > 1 ) {
|
||||
|
||||
for(int i = 0; i < 16; ++i) {
|
||||
if (frameskip && g_nFrameRender > 1)
|
||||
{
|
||||
for (int i = 0; i < 16; ++i)
|
||||
{
|
||||
g_GIFPackedRegHandlers[i] = GIFPackedRegHandlerNOP;
|
||||
}
|
||||
|
||||
|
@ -382,9 +418,11 @@ void CALLBACK GSsetFrameSkip(int frameskip)
|
|||
g_GIFRegHandlers[13] = GIFRegHandlerNOP;
|
||||
g_GIFRegHandlers[26] = GIFRegHandlerNOP;
|
||||
g_GIFRegHandlers[27] = GIFRegHandlerNOP;
|
||||
|
||||
g_nFrameRender = 0;
|
||||
}
|
||||
else if( !frameskip && g_nFrameRender <= 0 ) {
|
||||
else if (!frameskip && g_nFrameRender <= 0)
|
||||
{
|
||||
g_nFrameRender = 1;
|
||||
|
||||
if (g_GIFTempRegHandlers[0] == NULL) return; // not init yet
|
||||
|
@ -405,7 +443,8 @@ void CALLBACK GSsetFrameSkip(int frameskip)
|
|||
}
|
||||
}
|
||||
|
||||
void CALLBACK GSreset() {
|
||||
void CALLBACK GSreset()
|
||||
{
|
||||
FUNCLOG
|
||||
|
||||
memset(&gs, 0, sizeof(gs));
|
||||
|
@ -426,6 +465,7 @@ void CALLBACK GSgifSoftReset(u32 mask)
|
|||
if (mask & 1) memset(&gs.path[0], 0, sizeof(gs.path[0]));
|
||||
if (mask & 2) memset(&gs.path[1], 0, sizeof(gs.path[1]));
|
||||
if (mask & 4) memset(&gs.path[2], 0, sizeof(gs.path[2]));
|
||||
|
||||
gs.imageTransfer = -1;
|
||||
gs.q = 1;
|
||||
gs.nTriFanVert = -1;
|
||||
|
@ -438,9 +478,11 @@ s32 CALLBACK GSinit()
|
|||
memcpy(g_GIFTempRegHandlers, g_GIFPackedRegHandlers, sizeof(g_GIFTempRegHandlers));
|
||||
|
||||
gsLog = fopen("logs/gsLog.txt", "w");
|
||||
|
||||
if (gsLog == NULL)
|
||||
{
|
||||
gsLog = fopen("gsLog.txt", "w");
|
||||
|
||||
if (gsLog == NULL)
|
||||
{
|
||||
SysMessage("Can't create gsLog.txt");
|
||||
|
@ -449,6 +491,7 @@ s32 CALLBACK GSinit()
|
|||
}
|
||||
|
||||
setvbuf(gsLog, NULL, _IONBF, 0);
|
||||
|
||||
ZZLog::GS_Log("Calling GSinit.");
|
||||
|
||||
GSreset();
|
||||
|
@ -469,24 +512,34 @@ void OnKeyboardF5(int shift)
|
|||
FUNCLOG
|
||||
|
||||
char strtitle[256];
|
||||
if( shift ) {
|
||||
if( g_nPixelShaderVer == SHADER_REDUCED ) {
|
||||
|
||||
if (shift)
|
||||
{
|
||||
if (g_nPixelShaderVer == SHADER_REDUCED)
|
||||
{
|
||||
conf.bilinear = 0;
|
||||
sprintf(strtitle, "reduced shaders don't support bilinear filtering");
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
conf.bilinear = (conf.bilinear + 1) % 3;
|
||||
sprintf(strtitle, "bilinear filtering - %s", pbilinear[conf.bilinear]);
|
||||
}
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
conf.interlace++;
|
||||
|
||||
if (conf.interlace > 2) conf.interlace = 0;
|
||||
if( conf.interlace < 2 ) sprintf(strtitle, "interlace on - mode %d", conf.interlace);
|
||||
else sprintf(strtitle, "interlace off");
|
||||
|
||||
if (conf.interlace < 2)
|
||||
sprintf(strtitle, "interlace on - mode %d", conf.interlace);
|
||||
else
|
||||
sprintf(strtitle, "interlace off");
|
||||
}
|
||||
|
||||
ZeroGS::AddMessage(strtitle);
|
||||
|
||||
SaveConfig();
|
||||
}
|
||||
|
||||
|
@ -495,13 +548,16 @@ void OnKeyboardF6(int shift)
|
|||
FUNCLOG
|
||||
|
||||
char strtitle[256];
|
||||
if( shift ) {
|
||||
|
||||
if (shift)
|
||||
{
|
||||
conf.aa--; // -1
|
||||
if (conf.aa > 4) conf.aa = 4; // u8 in unsigned, so negative value is 255.
|
||||
sprintf(strtitle, "anti-aliasing - %s", s_aa[conf.aa]);
|
||||
ZeroGS::SetAA(conf.aa);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
conf.aa++;
|
||||
if (conf.aa > 4) conf.aa = 0;
|
||||
sprintf(strtitle, "anti-aliasing - %s", s_aa[conf.aa]);
|
||||
|
@ -509,6 +565,7 @@ void OnKeyboardF6(int shift)
|
|||
}
|
||||
|
||||
ZeroGS::AddMessage(strtitle);
|
||||
|
||||
SaveConfig();
|
||||
}
|
||||
|
||||
|
@ -517,28 +574,35 @@ void OnKeyboardF7(int shift)
|
|||
FUNCLOG
|
||||
|
||||
char strtitle[256];
|
||||
if( !shift ) {
|
||||
|
||||
if (!shift)
|
||||
{
|
||||
extern BOOL g_bDisplayFPS;
|
||||
g_bDisplayFPS ^= 1;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
conf.options ^= GSOPTION_WIREFRAME;
|
||||
glPolygonMode(GL_FRONT_AND_BACK, (conf.options&GSOPTION_WIREFRAME) ? GL_LINE : GL_FILL);
|
||||
sprintf(strtitle, "wireframe rendering - %s", (conf.options&GSOPTION_WIREFRAME) ? "on" : "off");
|
||||
}
|
||||
}
|
||||
|
||||
void OnKeyboardF61(int shift) {
|
||||
void OnKeyboardF61(int shift)
|
||||
{
|
||||
FUNCLOG
|
||||
|
||||
char strtitle[256];
|
||||
if( shift ) {
|
||||
|
||||
if (shift)
|
||||
{
|
||||
conf.negaa--; // -1
|
||||
if (conf.negaa > 2) conf.negaa = 2; // u8 in unsigned, so negative value is 255.
|
||||
sprintf(strtitle, "down resolution - %s", s_naa[conf.negaa]);
|
||||
ZeroGS::SetNegAA(conf.negaa);
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
conf.negaa++;
|
||||
if (conf.negaa > 2) conf.negaa = 0;
|
||||
sprintf(strtitle, "down resolution - %s", s_naa[conf.negaa]);
|
||||
|
@ -549,13 +613,16 @@ void OnKeyboardF61(int shift) {
|
|||
SaveConfig();
|
||||
}
|
||||
|
||||
typedef struct GameHackStruct {
|
||||
typedef struct GameHackStruct
|
||||
{
|
||||
const char HackName[40];
|
||||
u32 HackMask;
|
||||
} GameHack;
|
||||
|
||||
#define HACK_NUMBER 30
|
||||
|
||||
GameHack HackinshTable[HACK_NUMBER] = {
|
||||
GameHack HackinshTable[HACK_NUMBER] =
|
||||
{
|
||||
{"*** 0 No Hack", 0},
|
||||
{"*** 1 TexTargets Check", GAME_TEXTURETARGS},
|
||||
{"*** 2 Autoreset Targets", GAME_AUTORESET},
|
||||
|
@ -591,28 +658,35 @@ GameHack HackinshTable[HACK_NUMBER] = {
|
|||
|
||||
int CurrentHackSetting = 0;
|
||||
|
||||
void OnKeyboardF9(int shift) {
|
||||
void OnKeyboardF9(int shift)
|
||||
{
|
||||
FUNCLOG
|
||||
|
||||
// printf ("A %d\n", HackinshTable[CurrentHackSetting].HackMask);
|
||||
conf.gamesettings &= !(HackinshTable[CurrentHackSetting].HackMask);
|
||||
if( shift ) {
|
||||
|
||||
if (shift)
|
||||
{
|
||||
CurrentHackSetting--;
|
||||
if (CurrentHackSetting == -1)
|
||||
CurrentHackSetting = HACK_NUMBER-1;
|
||||
|
||||
if (CurrentHackSetting == -1) CurrentHackSetting = HACK_NUMBER - 1;
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
CurrentHackSetting++;
|
||||
if (CurrentHackSetting == HACK_NUMBER)
|
||||
CurrentHackSetting = 0;
|
||||
|
||||
if (CurrentHackSetting == HACK_NUMBER) CurrentHackSetting = 0;
|
||||
}
|
||||
|
||||
conf.gamesettings |= HackinshTable[CurrentHackSetting].HackMask;
|
||||
|
||||
g_GameSettings = conf.gamesettings;
|
||||
ZeroGS::AddMessage(HackinshTable[CurrentHackSetting].HackName);
|
||||
SaveConfig();
|
||||
}
|
||||
|
||||
void OnKeyboardF1(int shift) {
|
||||
void OnKeyboardF1(int shift)
|
||||
{
|
||||
FUNCLOG
|
||||
char strtitle[256];
|
||||
sprintf(strtitle, "Saving in savestate %d", CurrentSavestate);
|
||||
|
@ -649,11 +723,9 @@ s32 CALLBACK GSopen(void *pDsp, char *Title, int multithread)
|
|||
#endif
|
||||
|
||||
LoadConfig();
|
||||
|
||||
strcpy(GStitle, Title);
|
||||
|
||||
err = GLWin.CreateWindow(pDsp);
|
||||
|
||||
if (!err)
|
||||
{
|
||||
ZZLog::GS_Log("Failed to create window. Exiting...");
|
||||
|
@ -689,6 +761,7 @@ s32 CALLBACK GSopen(void *pDsp, char *Title, int multithread)
|
|||
}
|
||||
|
||||
luPerfFreq = GetCPUTicks();
|
||||
|
||||
gs.path[0].mode = gs.path[1].mode = gs.path[2].mode = 0;
|
||||
|
||||
ZZLog::GS_Log("GSopen finished.");
|
||||
|
@ -709,25 +782,32 @@ void ProcessMessages()
|
|||
{
|
||||
switch (msg.message)
|
||||
{
|
||||
|
||||
case WM_KEYDOWN :
|
||||
int my_KeyEvent = msg.wParam;
|
||||
bool my_bShift = !!(GetKeyState(VK_SHIFT) & 0x8000);
|
||||
|
||||
switch (msg.wParam)
|
||||
{
|
||||
|
||||
case VK_F5:
|
||||
OnKeyboardF5(my_bShift);
|
||||
break;
|
||||
|
||||
case VK_F6:
|
||||
OnKeyboardF6(my_bShift);
|
||||
break;
|
||||
|
||||
case VK_F7:
|
||||
OnKeyboardF7(my_bShift);
|
||||
break;
|
||||
|
||||
case VK_F9:
|
||||
OnKeyboardF9(my_bShift);
|
||||
break;
|
||||
|
||||
case VK_ESCAPE:
|
||||
|
||||
if (conf.options & GSOPTION_FULLSCREEN)
|
||||
{
|
||||
// destroy that msg
|
||||
|
@ -742,8 +822,10 @@ void ProcessMessages()
|
|||
//g_bHidden = 1;
|
||||
return;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -775,20 +857,26 @@ void ProcessMessages()
|
|||
// check resizing
|
||||
GLWin.ResizeCheck();
|
||||
|
||||
if ( THR_KeyEvent ) { // This values was passed from GSKeyEvents which could be in another thread
|
||||
if (THR_KeyEvent) // This values was passed from GSKeyEvents which could be in another thread
|
||||
{
|
||||
int my_KeyEvent = THR_KeyEvent;
|
||||
bool my_bShift = THR_bShift;
|
||||
THR_KeyEvent = 0;
|
||||
switch ( my_KeyEvent ) {
|
||||
|
||||
switch (my_KeyEvent)
|
||||
{
|
||||
case XK_F5:
|
||||
OnKeyboardF5(my_bShift);
|
||||
break;
|
||||
|
||||
case XK_F6:
|
||||
OnKeyboardF6(my_bShift);
|
||||
break;
|
||||
|
||||
case XK_F7:
|
||||
OnKeyboardF7(my_bShift);
|
||||
break;
|
||||
|
||||
case XK_F9:
|
||||
OnKeyboardF9(my_bShift);
|
||||
break;
|
||||
|
@ -798,7 +886,8 @@ void ProcessMessages()
|
|||
|
||||
#endif // linux
|
||||
|
||||
void CALLBACK GSclose() {
|
||||
void CALLBACK GSclose()
|
||||
{
|
||||
FUNCLOG
|
||||
|
||||
ZeroGS::Destroy(1);
|
||||
|
@ -809,7 +898,8 @@ void CALLBACK GSclose() {
|
|||
SaveStateExists = true; // default value
|
||||
}
|
||||
|
||||
void CALLBACK GSirqCallback(void (*callback)()) {
|
||||
void CALLBACK GSirqCallback(void (*callback)())
|
||||
{
|
||||
FUNCLOG
|
||||
|
||||
GSirq = callback;
|
||||
|
@ -844,18 +934,23 @@ void CALLBACK GSmakeSnapshot(char *path)
|
|||
u32 snapshotnr = 0;
|
||||
|
||||
// increment snapshot value & try to get filename
|
||||
for (;;) {
|
||||
|
||||
for (;;)
|
||||
{
|
||||
snapshotnr++;
|
||||
|
||||
sprintf(filename, "%ssnap%03ld.%s", path, snapshotnr, (conf.options&GSOPTION_TGASNAP) ? "bmp" : "jpg");
|
||||
|
||||
bmpfile = fopen(filename, "rb");
|
||||
|
||||
if (bmpfile == NULL) break;
|
||||
|
||||
fclose(bmpfile);
|
||||
}
|
||||
|
||||
// try opening new snapshot file
|
||||
if((bmpfile=fopen(filename,"wb"))==NULL) {
|
||||
if ((bmpfile = fopen(filename, "wb")) == NULL)
|
||||
{
|
||||
char strdir[255];
|
||||
|
||||
#ifdef _WIN32
|
||||
|
@ -899,7 +994,8 @@ void CALLBACK GSvsync(int interlace)
|
|||
|
||||
ProcessMessages();
|
||||
|
||||
if( --nToNextUpdate <= 0 ) {
|
||||
if (--nToNextUpdate <= 0)
|
||||
{
|
||||
|
||||
u32 d = timeGetTime();
|
||||
fFPS = UPDATE_FRAMES * 1000.0f / (float)max(d - dwTime, 1);
|
||||
|
@ -910,6 +1006,7 @@ void CALLBACK GSvsync(int interlace)
|
|||
const char* g_pShaders[4] = { "full", "reduced", "accurate", "accurate-reduced" };
|
||||
const char* g_pInterlace[3] = { "interlace 0 |", "interlace 1 |", "" };
|
||||
const char* g_pBilinear[3] = { "", "bilinear |", "forced bilinear |" };
|
||||
|
||||
if (SaveStateFile != NULL && !SaveStateExists)
|
||||
SaveStateExists = (access(SaveStateFile, 0) == 0);
|
||||
else
|
||||
|
@ -920,12 +1017,14 @@ void CALLBACK GSvsync(int interlace)
|
|||
(conf.aa >= conf.negaa) ? (conf.aa ? s_aa[conf.aa - conf.negaa] : "") : (conf.negaa ? s_naa[conf.negaa - conf.aa] : ""),
|
||||
CurrentSavestate, (SaveStateExists ? "" : "*"),
|
||||
g_pShaders[g_nPixelShaderVer], (ppf&0xfffff) / (float)UPDATE_FRAMES);
|
||||
|
||||
#else
|
||||
sprintf(strtitle, "%d | %.1f fps (sk:%d%%) | g: %.1f, t: %.1f, a: %.1f, r: %.1f | p: %.1f | tex: %d %d (%d kbpf)", g_nFrame, fFPS,
|
||||
100*g_nFramesSkipped / g_nFrame,
|
||||
g_nGenVars / (float)UPDATE_FRAMES, g_nTexVars / (float)UPDATE_FRAMES, g_nAlphaVars / (float)UPDATE_FRAMES,
|
||||
g_nResolve / (float)UPDATE_FRAMES, (ppf&0xfffff) / (float)UPDATE_FRAMES,
|
||||
ZeroGS::g_MemTargs.listTargets.size(), ZeroGS::g_MemTargs.listClearedTargets.size(), g_TransferredToGPU >> 10);
|
||||
|
||||
//_snprintf(strtitle, 512, "%x %x", *(int*)(g_pbyGSMemory + 256 * 0x3e0c + 4), *(int*)(g_pbyGSMemory + 256 * 0x3e04 + 4));
|
||||
|
||||
#endif
|
||||
|
@ -947,16 +1046,20 @@ void CALLBACK GSvsync(int interlace)
|
|||
g_nTexVars = 0;
|
||||
g_nAlphaVars = 0;
|
||||
g_nResolve = 0;
|
||||
|
||||
ppf = 0;
|
||||
|
||||
g_nFramesSkipped = 0;
|
||||
}
|
||||
|
||||
#if defined(ZEROGS_DEVBUILD)
|
||||
if( g_bWriteProfile ) {
|
||||
if (g_bWriteProfile)
|
||||
{
|
||||
//g_bWriteProfile = 0;
|
||||
DVProfWrite("prof.txt", UPDATE_FRAMES);
|
||||
DVProfClear();
|
||||
}
|
||||
|
||||
#endif
|
||||
GL_REPORT_ERRORD();
|
||||
}
|
||||
|
@ -983,18 +1086,24 @@ int CALLBACK GSsetupRecording(int start, void* pData)
|
|||
{
|
||||
FUNCLOG
|
||||
|
||||
if( start ) {
|
||||
if( conf.options & GSOPTION_CAPTUREAVI )
|
||||
return 1;
|
||||
if (start)
|
||||
{
|
||||
if (conf.options & GSOPTION_CAPTUREAVI) return 1;
|
||||
|
||||
ZeroGS::StartCapture();
|
||||
|
||||
conf.options |= GSOPTION_CAPTUREAVI;
|
||||
|
||||
ZZLog::Warn_Log("Started recording zerogs.avi.");
|
||||
}
|
||||
else {
|
||||
if( !(conf.options & GSOPTION_CAPTUREAVI) )
|
||||
return 1;
|
||||
else
|
||||
{
|
||||
if (!(conf.options & GSOPTION_CAPTUREAVI)) return 1;
|
||||
|
||||
conf.options &= ~GSOPTION_CAPTUREAVI;
|
||||
|
||||
ZeroGS::StopCapture();
|
||||
|
||||
ZZLog::Warn_Log("Stopped recording.");
|
||||
}
|
||||
|
||||
|
@ -1011,12 +1120,15 @@ s32 CALLBACK GSfreeze(int mode, freezeData *data)
|
|||
if (!ZeroGS::Load(data->data)) ZZLog::Error_Log("GS: Bad load format!");
|
||||
g_nRealFrame += 100;
|
||||
break;
|
||||
|
||||
case FREEZE_SAVE:
|
||||
ZeroGS::Save(data->data);
|
||||
break;
|
||||
|
||||
case FREEZE_SIZE:
|
||||
data->size = ZeroGS::Save(NULL);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -1030,6 +1142,7 @@ s32 CALLBACK GSfreeze(int mode, freezeData *data)
|
|||
#include <list>
|
||||
#include <string>
|
||||
#include <map>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define GET_PROFILE_TIME() GetCPUTicks()
|
||||
|
@ -1038,18 +1151,23 @@ struct DVPROFSTRUCT;
|
|||
|
||||
struct DVPROFSTRUCT
|
||||
{
|
||||
|
||||
struct DATA
|
||||
{
|
||||
DATA(u64 time, u32 user = 0) : dwTime(time), dwUserData(user) {}
|
||||
|
||||
DATA() : dwTime(0), dwUserData(0) {}
|
||||
|
||||
u64 dwTime;
|
||||
u32 dwUserData;
|
||||
};
|
||||
|
||||
~DVPROFSTRUCT() {
|
||||
~DVPROFSTRUCT()
|
||||
{
|
||||
list<DVPROFSTRUCT*>::iterator it = listpChild.begin();
|
||||
while(it != listpChild.end() ) {
|
||||
|
||||
while (it != listpChild.end())
|
||||
{
|
||||
SAFE_DELETE(*it);
|
||||
++it;
|
||||
}
|
||||
|
@ -1102,12 +1220,14 @@ void DVProfRegister(char* pname)
|
|||
// else add in a new profiler to the appropriate parent profiler
|
||||
DVPROFSTRUCT* pprof = NULL;
|
||||
|
||||
if( g_listCurTracking.size() > 0 ) {
|
||||
if (g_listCurTracking.size() > 0)
|
||||
{
|
||||
assert(g_listCurTracking.back().pprof != NULL);
|
||||
g_listCurTracking.back().pprof->listpChild.push_back(new DVPROFSTRUCT());
|
||||
pprof = g_listCurTracking.back().pprof->listpChild.back();
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
g_listProfilers.push_back(DVPROFSTRUCT());
|
||||
pprof = &g_listProfilers.back();
|
||||
}
|
||||
|
@ -1132,6 +1252,7 @@ void DVProfEnd(u32 dwUserData)
|
|||
{
|
||||
if (!g_bWriteProfile)
|
||||
return;
|
||||
|
||||
B_RETURN(g_listCurTracking.size() > 0);
|
||||
|
||||
DVPROFTRACK dvtrack = g_listCurTracking.back();
|
||||
|
@ -1139,6 +1260,7 @@ void DVProfEnd(u32 dwUserData)
|
|||
assert(dvtrack.pdwTime != NULL && dvtrack.pprof != NULL);
|
||||
|
||||
dvtrack.pdwTime->dwTime = 1000000 * (GET_PROFILE_TIME() - dvtrack.pdwTime->dwTime) / luPerfFreq;
|
||||
|
||||
dvtrack.pdwTime->dwUserData = dwUserData;
|
||||
|
||||
g_listCurTracking.pop_back();
|
||||
|
@ -1147,6 +1269,7 @@ void DVProfEnd(u32 dwUserData)
|
|||
struct DVTIMEINFO
|
||||
{
|
||||
DVTIMEINFO() : uInclusive(0), uExclusive(0) {}
|
||||
|
||||
u64 uInclusive, uExclusive;
|
||||
};
|
||||
|
||||
|
@ -1160,13 +1283,15 @@ u64 DVProfWriteStruct(FILE* f, DVPROFSTRUCT* p, int ident)
|
|||
|
||||
u32 utime = 0;
|
||||
|
||||
while(ittime != p->listTimes.end() ) {
|
||||
while (ittime != p->listTimes.end())
|
||||
{
|
||||
utime += (u32)ittime->dwTime;
|
||||
|
||||
if (ittime->dwUserData)
|
||||
fprintf(f, "time: %d, user: 0x%8.8x", (u32)ittime->dwTime, ittime->dwUserData);
|
||||
else
|
||||
fprintf(f, "time: %d", (u32)ittime->dwTime);
|
||||
|
||||
++ittime;
|
||||
}
|
||||
|
||||
|
@ -1177,13 +1302,16 @@ u64 DVProfWriteStruct(FILE* f, DVPROFSTRUCT* p, int ident)
|
|||
list<DVPROFSTRUCT*>::iterator itprof = p->listpChild.begin();
|
||||
|
||||
u32 uex = utime;
|
||||
while(itprof != p->listpChild.end() ) {
|
||||
|
||||
while (itprof != p->listpChild.end())
|
||||
{
|
||||
|
||||
uex -= DVProfWriteStruct(f, *itprof, ident + 4);
|
||||
++itprof;
|
||||
}
|
||||
|
||||
mapAggregateTimes[p->pname].uExclusive += uex;
|
||||
|
||||
return utime;
|
||||
}
|
||||
|
||||
|
@ -1195,7 +1323,8 @@ void DVProfWrite(char* pfilename, u32 frames)
|
|||
mapAggregateTimes.clear();
|
||||
list<DVPROFSTRUCT>::iterator it = g_listProfilers.begin();
|
||||
|
||||
while(it != g_listProfilers.end() ) {
|
||||
while (it != g_listProfilers.end())
|
||||
{
|
||||
DVProfWriteStruct(f, &(*it), 0);
|
||||
++it;
|
||||
}
|
||||
|
@ -1207,19 +1336,23 @@ void DVProfWrite(char* pfilename, u32 frames)
|
|||
u64 uTotal[2] = {0};
|
||||
double fiTotalTime[2];
|
||||
|
||||
for(it = mapAggregateTimes.begin(); it != mapAggregateTimes.end(); ++it) {
|
||||
for (it = mapAggregateTimes.begin(); it != mapAggregateTimes.end(); ++it)
|
||||
{
|
||||
uTotal[0] += it->second.uExclusive;
|
||||
uTotal[1] += it->second.uInclusive;
|
||||
}
|
||||
|
||||
fprintf(f, "total times (%d): ex: %Lu ", frames, uTotal[0] / frames);
|
||||
|
||||
fprintf(f, "inc: %Lu\n", uTotal[1] / frames);
|
||||
|
||||
fiTotalTime[0] = 1.0 / (double)uTotal[0];
|
||||
fiTotalTime[1] = 1.0 / (double)uTotal[1];
|
||||
|
||||
// output the combined times
|
||||
for(it = mapAggregateTimes.begin(); it != mapAggregateTimes.end(); ++it) {
|
||||
|
||||
for (it = mapAggregateTimes.begin(); it != mapAggregateTimes.end(); ++it)
|
||||
{
|
||||
fprintf(f, "%s - ex: %f inc: %f\n", it->first.c_str(), (double)it->second.uExclusive * fiTotalTime[0],
|
||||
(double)it->second.uInclusive * fiTotalTime[1]);
|
||||
}
|
||||
|
|
|
@ -74,18 +74,22 @@ extern HANDLE g_hCurrentThread;
|
|||
__forceinline void gifTransferLog(int index, u32 *pMem, u32 size)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
|
||||
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 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
|
||||
}
|
||||
|
||||
|
@ -163,6 +167,7 @@ template<int index> void _GSgifTransfer(u32 *pMem, u32 size)
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
case GIF_FLG_REGLIST:
|
||||
{
|
||||
// Needs to be looked at.
|
||||
|
@ -180,7 +185,6 @@ template<int index> void _GSgifTransfer(u32 *pMem, u32 size)
|
|||
while (path->StepReg() && (size > 0));
|
||||
|
||||
if (size & 1) pMem += 2;
|
||||
|
||||
size /= 2;
|
||||
break;
|
||||
}
|
||||
|
@ -196,27 +200,33 @@ template<int index> void _GSgifTransfer(u32 *pMem, u32 size)
|
|||
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);
|
||||
|
@ -283,6 +293,7 @@ void CALLBACK GSgifTransfer3(u32 *pMem, u32 size)
|
|||
|
||||
_GSgifTransfer<2>(pMem, size);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
template<int index> void _GSgifTransfer(u32 *pMem, u32 size)
|
||||
|
@ -334,6 +345,7 @@ template<int index> void _GSgifTransfer(u32 *pMem, u32 size)
|
|||
{
|
||||
// ffx hack
|
||||
if (path->eop) return;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -350,9 +362,11 @@ template<int index> void _GSgifTransfer(u32 *pMem, u32 size)
|
|||
|
||||
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);
|
||||
|
@ -373,8 +387,10 @@ template<int index> void _GSgifTransfer(u32 *pMem, u32 size)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case GIF_FLG_REGLIST:
|
||||
{
|
||||
//GS_LOG("%8.8x%8.8x %d L", ((u32*)&gs.regs)[1], *(u32*)&gs.regs, path->tag.nreg/4);
|
||||
|
@ -392,6 +408,7 @@ template<int index> void _GSgifTransfer(u32 *pMem, u32 size)
|
|||
if (path->nreg == path->regn)
|
||||
{
|
||||
path->regn = 0;
|
||||
|
||||
if (path->nloop-- <= 1)
|
||||
{
|
||||
size--;
|
||||
|
@ -402,9 +419,12 @@ template<int index> void _GSgifTransfer(u32 *pMem, u32 size)
|
|||
}
|
||||
|
||||
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.
|
||||
{
|
||||
|
@ -420,11 +440,14 @@ template<int index> void _GSgifTransfer(u32 *pMem, u32 size)
|
|||
ZeroGS::TransferHostLocal(pMem, process*4);
|
||||
|
||||
path->nloop -= process;
|
||||
|
||||
pMem += process * 4;
|
||||
|
||||
size -= process;
|
||||
|
||||
assert(size == 0 || path->nloop == 0);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
else
|
||||
|
@ -439,6 +462,7 @@ template<int index> void _GSgifTransfer(u32 *pMem, u32 size)
|
|||
|
||||
break;
|
||||
}
|
||||
|
||||
default: // GIF_IMAGE
|
||||
ZZLog::GS_Log("*** WARNING **** Unexpected GIFTag flag.");
|
||||
assert(0);
|
||||
|
@ -505,4 +529,5 @@ void CALLBACK GSgifTransfer3(u32 *pMem, u32 size)
|
|||
nPath3Hack = 0;
|
||||
_GSgifTransfer<2>(pMem, size);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -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);
|
||||
|
@ -66,13 +67,16 @@ void LoadConfig()
|
|||
|
||||
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)
|
||||
{
|
||||
|
||||
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,6 +121,7 @@ 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)
|
||||
|
@ -118,6 +129,7 @@ void LoadConfig()
|
|||
conf.width = 640;
|
||||
conf.height = 480;
|
||||
}
|
||||
|
||||
if (conf.x <= 0 || conf.y <= 0)
|
||||
{
|
||||
conf.x = 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;
|
||||
|
@ -148,6 +155,7 @@ void CreateGameHackTable(GtkWidget *treeview)
|
|||
}
|
||||
|
||||
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,6 +174,7 @@ 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)
|
||||
{
|
||||
treeoptval = FALSE;
|
||||
|
@ -177,6 +186,7 @@ void SaveGameHackTable(GtkWidget *treeview)
|
|||
}
|
||||
|
||||
GSsetGameCRC(0, conf.gamesettings);
|
||||
|
||||
//---------- done getting advanced options ---------//
|
||||
}
|
||||
|
||||
|
@ -226,8 +236,11 @@ void DisplayDialog()
|
|||
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");
|
||||
|
@ -239,6 +252,7 @@ void DisplayDialog()
|
|||
|
||||
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");
|
||||
|
@ -259,15 +273,19 @@ void DisplayDialog()
|
|||
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);
|
||||
|
||||
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);
|
||||
|
@ -279,8 +297,11 @@ void DisplayDialog()
|
|||
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,9 +319,7 @@ 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);
|
||||
|
||||
|
@ -312,6 +331,7 @@ void DisplayDialog()
|
|||
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);
|
||||
|
||||
return_value = gtk_dialog_run(GTK_DIALOG(dialog));
|
||||
|
@ -331,13 +351,25 @@ void DisplayDialog()
|
|||
|
||||
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)))
|
||||
|
@ -356,6 +388,7 @@ void DisplayDialog()
|
|||
fake_options |= GSOPTION_TGASNAP;
|
||||
|
||||
conf.options = fake_options;
|
||||
|
||||
SaveConfig();
|
||||
}
|
||||
|
||||
|
@ -384,12 +417,15 @@ void SysMessage(const char *fmt, ...)
|
|||
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);
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -67,8 +67,10 @@ 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)
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
return pbuf;
|
||||
}
|
||||
|
||||
|
@ -130,6 +134,7 @@ static __forceinline const T* TransferAligningToBlocks(TransferData data, Transf
|
|||
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;
|
||||
|
@ -141,6 +146,7 @@ static __forceinline const T* TransferAligningToBlocks(TransferData data, Transf
|
|||
|
||||
tempX = gs.trxpos.dx;
|
||||
}
|
||||
|
||||
return pbuf;
|
||||
}
|
||||
|
||||
|
@ -173,7 +179,8 @@ static __forceinline int RealTransfer(TransferData data, TransferFuncts fun, con
|
|||
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;
|
||||
tempY = gs.imageY;
|
||||
tempX = gs.imageX;
|
||||
Point alignedPt;
|
||||
|
||||
nSize = (nQWordSize * 4 * 2) / tp2;
|
||||
|
@ -184,15 +191,19 @@ 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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
@ -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)
|
||||
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*/);
|
||||
|
@ -162,6 +175,7 @@ __forceinline void __fastcall SwizzleBlock4_c(u8* dst, u8* src, int srcpitch, u3
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
__forceinline void SwizzleBlock24(u8 *dst, u8 *src, int pitch, u32 WriteMask)
|
||||
{
|
||||
|
@ -184,8 +198,11 @@ __forceinline void SwizzleBlock24(u8 *dst, u8 *src, int pitch, u32 WriteMask)
|
|||
|
||||
/* do 3 bytes for the last copy */
|
||||
*((u8*)pblock + 28) = pnewsrc[0];
|
||||
|
||||
*((u8*)pblock + 29) = pnewsrc[1];
|
||||
|
||||
*((u8*)pblock + 30) = pnewsrc[2];
|
||||
|
||||
SwizzleBlock32((u8*)dst, (u8*)tempblock, 32, 0x00ffffff);
|
||||
}
|
||||
|
||||
|
@ -207,6 +224,7 @@ __forceinline void SwizzleBlock8H(u8 *dst, u8 *src, int pitch, u32 WriteMask)
|
|||
pblock[6] = u << 8;
|
||||
pblock[7] = u;
|
||||
}
|
||||
|
||||
SwizzleBlock32((u8*)dst, (u8*)tempblock, 32, 0xff000000);
|
||||
}
|
||||
|
||||
|
@ -227,6 +245,7 @@ __forceinline void SwizzleBlock4HH(u8 *dst, u8 *src, int pitch, u32 WriteMask)
|
|||
pblock[6] = u << 4;
|
||||
pblock[7] = u;
|
||||
}
|
||||
|
||||
SwizzleBlock32((u8*)dst, (u8*)tempblock, 32, 0xf0000000);
|
||||
}
|
||||
|
||||
|
@ -247,5 +266,6 @@ __forceinline void SwizzleBlock4HL(u8 *dst, u8 *src, int pitch, u32 WriteMask)
|
|||
pblock[6] = u;
|
||||
pblock[7] = u >> 4;
|
||||
}
|
||||
|
||||
SwizzleBlock32((u8*)dst, (u8*)tempblock, 32, 0x0f000000);
|
||||
}
|
||||
|
|
|
@ -18,21 +18,24 @@
|
|||
|
||||
#include "GS.h"
|
||||
|
||||
u32 g_blockTable32[4][8] = {
|
||||
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] = {
|
||||
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] = {
|
||||
u32 g_blockTable16[8][4] =
|
||||
{
|
||||
{ 0, 2, 8, 10 },
|
||||
{ 1, 3, 9, 11 },
|
||||
{ 4, 6, 12, 14 },
|
||||
|
@ -43,7 +46,8 @@ u32 g_blockTable16[8][4] = {
|
|||
{ 21, 23, 29, 31 }
|
||||
};
|
||||
|
||||
u32 g_blockTable16S[8][4] = {
|
||||
u32 g_blockTable16S[8][4] =
|
||||
{
|
||||
{ 0, 2, 16, 18 },
|
||||
{ 1, 3, 17, 19 },
|
||||
{ 8, 10, 24, 26 },
|
||||
|
@ -54,7 +58,8 @@ u32 g_blockTable16S[8][4] = {
|
|||
{ 13, 15, 29, 31 }
|
||||
};
|
||||
|
||||
u32 g_blockTable16Z[8][4] = {
|
||||
u32 g_blockTable16Z[8][4] =
|
||||
{
|
||||
{ 24, 26, 16, 18 },
|
||||
{ 25, 27, 17, 19 },
|
||||
{ 28, 30, 20, 22 },
|
||||
|
@ -65,7 +70,8 @@ u32 g_blockTable16Z[8][4] = {
|
|||
{ 13, 15, 5, 7 }
|
||||
};
|
||||
|
||||
u32 g_blockTable16SZ[8][4] = {
|
||||
u32 g_blockTable16SZ[8][4] =
|
||||
{
|
||||
{ 24, 26, 8, 10 },
|
||||
{ 25, 27, 9, 11 },
|
||||
{ 16, 18, 0, 2 },
|
||||
|
@ -76,14 +82,16 @@ u32 g_blockTable16SZ[8][4] = {
|
|||
{ 21, 23, 5, 7 }
|
||||
};
|
||||
|
||||
u32 g_blockTable8[4][8] = {
|
||||
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] = {
|
||||
u32 g_blockTable4[8][4] =
|
||||
{
|
||||
{ 0, 2, 8, 10 },
|
||||
{ 1, 3, 9, 11 },
|
||||
{ 4, 6, 12, 14 },
|
||||
|
@ -94,7 +102,8 @@ u32 g_blockTable4[8][4] = {
|
|||
{ 21, 23, 29, 31 }
|
||||
};
|
||||
|
||||
u32 g_columnTable32[8][8] = {
|
||||
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 },
|
||||
|
@ -105,7 +114,8 @@ u32 g_columnTable32[8][8] = {
|
|||
{ 50, 51, 54, 55, 58, 59, 62, 63 },
|
||||
};
|
||||
|
||||
u32 g_columnTable16[8][16] = {
|
||||
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,
|
||||
|
@ -124,7 +134,8 @@ u32 g_columnTable16[8][16] = {
|
|||
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,
|
||||
|
@ -159,7 +170,8 @@ u32 g_columnTable8[16][16] = {
|
|||
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,
|
||||
|
|
|
@ -36,13 +36,16 @@ 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,
|
||||
|
@ -67,7 +70,8 @@ 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);
|
||||
|
||||
|
@ -78,7 +82,8 @@ u32 s_uClampData[2] = {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...
|
||||
|
@ -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,8 +115,10 @@ 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 == 0x300b) && (result == 0x300) && ZeroGS::vb[i].zbuf.zmsk) return false; // ATF, but no Melty Blood
|
||||
|
||||
// Old code
|
||||
|
@ -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,9 +172,11 @@ 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 */
|
||||
|
@ -185,10 +196,12 @@ void __fastcall GIFPackedRegHandlerXYZF2(u32* data)
|
|||
gs.gsvertex[gs.primIndex] = gs.vertexregs;
|
||||
gs.primIndex = (gs.primIndex + 1) % ArraySize(gs.gsvertex);
|
||||
|
||||
if( data[3] & 0x8000 ) {
|
||||
if (data[3] & 0x8000)
|
||||
{
|
||||
KICK_VERTEX3();
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
KICK_VERTEX2();
|
||||
}
|
||||
}
|
||||
|
@ -202,10 +215,12 @@ void __fastcall GIFPackedRegHandlerXYZ2(u32* data)
|
|||
gs.gsvertex[gs.primIndex] = gs.vertexregs;
|
||||
gs.primIndex = (gs.primIndex + 1) % ArraySize(gs.gsvertex);
|
||||
|
||||
if( data[3] & 0x8000 ) {
|
||||
if (data[3] & 0x8000)
|
||||
{
|
||||
KICK_VERTEX3();
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
KICK_VERTEX2();
|
||||
}
|
||||
}
|
||||
|
@ -219,6 +234,7 @@ void __fastcall GIFPackedRegHandlerFOG(u32* data)
|
|||
void __fastcall GIFPackedRegHandlerA_D(u32* data)
|
||||
{
|
||||
FUNCLOG
|
||||
|
||||
if ((data[2] & 0xff) < 100)
|
||||
g_GIFRegHandlers[data[2] & 0xff](data);
|
||||
else
|
||||
|
@ -226,7 +242,8 @@ void __fastcall GIFPackedRegHandlerA_D(u32* data)
|
|||
}
|
||||
|
||||
void __fastcall GIFPackedRegHandlerNOP(u32* data)
|
||||
{FUNCLOG
|
||||
{
|
||||
FUNCLOG
|
||||
}
|
||||
|
||||
extern int g_PrevBitwiseTexX, g_PrevBitwiseTexY;
|
||||
|
@ -243,10 +260,12 @@ void tex0Write(int i, u32 *data)
|
|||
}
|
||||
|
||||
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,7 +282,8 @@ 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;
|
||||
|
||||
|
@ -275,23 +296,28 @@ 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;
|
||||
|
||||
|
@ -300,11 +326,11 @@ void tex2Write(int i, u32 *data) {
|
|||
|
||||
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;
|
||||
|
||||
|
@ -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,7 +381,8 @@ __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];
|
||||
|
@ -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,18 +410,21 @@ 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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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.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);
|
||||
}
|
||||
|
@ -620,10 +652,10 @@ 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();
|
||||
|
||||
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;
|
||||
|
@ -696,7 +728,8 @@ 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;
|
||||
|
@ -733,7 +766,8 @@ void __fastcall GIFRegHandlerSCISSOR_1(u32* data)
|
|||
newscissor.y1 = ((data[1] >> 16) & 0x7ff) << 3;
|
||||
|
||||
if (newscissor.x1 != scissor.x1 || newscissor.y1 != scissor.y1 ||
|
||||
newscissor.x0 != scissor.x0 || newscissor.y0 != scissor.y0 ) {
|
||||
newscissor.x0 != scissor.x0 || newscissor.y0 != scissor.y0)
|
||||
{
|
||||
|
||||
ZeroGS::Flush(0);
|
||||
scissor = newscissor;
|
||||
|
@ -755,7 +789,8 @@ void __fastcall GIFRegHandlerSCISSOR_2(u32* data)
|
|||
newscissor.y1 = ((data[1] >> 16) & 0x7ff) << 3;
|
||||
|
||||
if (newscissor.x1 != scissor.x1 || newscissor.y1 != scissor.y1 ||
|
||||
newscissor.x0 != scissor.x0 || newscissor.y0 != scissor.y0 ) {
|
||||
newscissor.x0 != scissor.x0 || newscissor.y0 != scissor.y0)
|
||||
{
|
||||
|
||||
ZeroGS::Flush(1);
|
||||
scissor = newscissor;
|
||||
|
@ -772,7 +807,8 @@ void __fastcall GIFRegHandlerALPHA_1(u32* data)
|
|||
newalpha.abcd = *(u8*)data;
|
||||
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;
|
||||
|
@ -791,7 +827,8 @@ void __fastcall GIFRegHandlerALPHA_2(u32* data)
|
|||
newalpha.abcd = *(u8*)data;
|
||||
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;
|
||||
|
@ -877,15 +914,16 @@ void __fastcall GIFRegHandlerZBUF_1(u32* data)
|
|||
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) ) {
|
||||
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);
|
||||
|
@ -895,6 +933,7 @@ void __fastcall GIFRegHandlerZBUF_1(u32* data)
|
|||
zbuf.zmsk = data[1] & 0x1;
|
||||
|
||||
ZeroGS::vb[0].zprimmask = 0xffffffff;
|
||||
|
||||
if (zbuf.psm > 0x31) ZeroGS::vb[0].zprimmask = 0xffff;
|
||||
|
||||
ZeroGS::vb[0].bNeedZCheck = 1;
|
||||
|
@ -906,9 +945,11 @@ void __fastcall GIFRegHandlerZBUF_2(u32* data)
|
|||
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) ) {
|
||||
zbuf.zmsk == (data[1] & 0x1))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -920,12 +961,14 @@ void __fastcall GIFRegHandlerZBUF_2(u32* data)
|
|||
ZeroGS::Flush(1);
|
||||
|
||||
zbuf.zbp = (data[0] & 0x1ff) * 32;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -963,34 +1006,40 @@ 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) {
|
||||
|
||||
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) {
|
||||
|
||||
if (!g_GSMultiThreaded)
|
||||
{
|
||||
SIGLBLID->LBLID = (SIGLBLID->LBLID & ~data[1]) | (data[0] & data[1]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -80,7 +80,8 @@ extern vector<u32> s_vecTempTextures; // temporary textures, released at the
|
|||
|
||||
//------------------ Namespace
|
||||
|
||||
namespace ZeroGS {
|
||||
namespace ZeroGS
|
||||
{
|
||||
extern int s_nNewWidth, s_nNewHeight;
|
||||
|
||||
extern CRangeManager s_RangeMngr; // manages overwritten memory
|
||||
|
@ -89,21 +90,26 @@ namespace ZeroGS {
|
|||
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
|
||||
// If its height (named s_nInterlaceTexWidth here) is hanging we must redo
|
||||
// the texture.
|
||||
// FIXME: If this function would spammed to often, we could use
|
||||
// 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
|
||||
inline u32 CreateInterlaceTex(int width) {
|
||||
if (width == s_nInterlaceTexWidth && s_ptexInterlace != 0)
|
||||
return s_ptexInterlace;
|
||||
|
||||
inline u32 CreateInterlaceTex(int width)
|
||||
{
|
||||
if (width == s_nInterlaceTexWidth && s_ptexInterlace != 0) return s_ptexInterlace;
|
||||
|
||||
SAFE_RELEASE_TEX(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);
|
||||
|
@ -111,9 +117,11 @@ namespace ZeroGS {
|
|||
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.
|
||||
|
@ -144,6 +152,7 @@ void ZeroGS::AdjustTransToAspect(Vector& v)
|
|||
v.x *= f;
|
||||
v.z *= f;
|
||||
}
|
||||
|
||||
v *= 1 / 32767.0f;
|
||||
}
|
||||
|
||||
|
@ -174,48 +183,64 @@ 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;
|
||||
|
@ -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 ) {
|
||||
|
@ -265,11 +293,13 @@ inline void RenderStartHelper(u32 bInterlace){
|
|||
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
|
||||
|
||||
glViewport(0, 0, nBackbufferWidth, nBackbufferHeight);
|
||||
|
||||
// if interlace, only clear every other vsync
|
||||
|
@ -280,14 +310,15 @@ inline void RenderStartHelper(u32 bInterlace){
|
|||
}
|
||||
|
||||
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
|
||||
|
@ -298,87 +329,107 @@ 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);
|
||||
|
||||
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) {
|
||||
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;
|
||||
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) {
|
||||
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);
|
||||
glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE);
|
||||
|
@ -386,7 +437,8 @@ inline void RenderUpdateStencil(int i, bool* bUsingStencil) {
|
|||
}
|
||||
|
||||
// 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,24 +458,31 @@ 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) {
|
||||
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 ) {
|
||||
|
||||
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
|
||||
|
@ -432,17 +491,18 @@ inline Vector RenderSetTargetBitPos(int dh, int th, int movy, bool isInterlace)
|
|||
v.z = 0;
|
||||
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,13 +510,15 @@ 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;
|
||||
|
@ -464,12 +526,14 @@ inline Vector RenderSetTargetBitTex(float th, float tw, float dh, float dw, bool
|
|||
}
|
||||
|
||||
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));
|
||||
ZZcgSetParameter4fv(pvsBitBlt.fBitBltTrans, v, "g_fBitBltTrans");
|
||||
|
@ -478,34 +542,41 @@ inline Vector RenderSetTargetBitTrans(int th) {
|
|||
|
||||
// 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))
|
||||
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);
|
||||
|
||||
// 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)
|
||||
{
|
||||
(*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,30 +682,34 @@ 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?
|
||||
// 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");
|
||||
|
||||
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);
|
||||
|
@ -631,16 +718,17 @@ inline void AfterRenderDisplayFPS() {
|
|||
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" : "");
|
||||
|
@ -648,7 +736,8 @@ inline void AfterRenderMadeSnapshoot() {
|
|||
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,23 +745,30 @@ 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 ) {
|
||||
inline void AfterRenderCountStatistics()
|
||||
{
|
||||
if (s_nWriteDepthCount > 0)
|
||||
{
|
||||
assert(conf.mrtdepth);
|
||||
if( --s_nWriteDepthCount <= 0 ) {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -680,24 +776,27 @@ inline void AfterRenderCountStatistics() {
|
|||
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;
|
||||
}
|
||||
|
@ -714,13 +813,15 @@ inline void AfterRendererUnimportantJob() {
|
|||
}
|
||||
|
||||
// Swich Frabuffers
|
||||
inline void AfterRendererSwitchBackToTextures() {
|
||||
inline void AfterRendererSwitchBackToTextures()
|
||||
{
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, s_uFramebuffer);
|
||||
|
||||
g_MemTargs.DestroyCleared();
|
||||
|
||||
if (s_vecTempTextures.size() > 0)
|
||||
glDeleteTextures((GLsizei)s_vecTempTextures.size(), &s_vecTempTextures[0]);
|
||||
|
||||
s_vecTempTextures.clear();
|
||||
|
||||
if (EXTWRITE->WRITE & 1)
|
||||
|
@ -731,9 +832,11 @@ inline void AfterRendererSwitchBackToTextures() {
|
|||
}
|
||||
|
||||
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,16 +844,21 @@ 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);
|
||||
|
||||
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) ) {
|
||||
if (total / ARRAY_SIZE(s_nResolveCounts) > 3)
|
||||
{
|
||||
if (s_nLastResolveReset > (int)(fFPS * 8))
|
||||
{
|
||||
// reset
|
||||
ZZLog::Error_Log("Video memory reset.");
|
||||
s_nLastResolveReset = 0;
|
||||
|
@ -762,16 +870,24 @@ inline void AfterRendererAutoresetTargets() {
|
|||
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;
|
||||
|
@ -782,29 +898,27 @@ void ZeroGS::RenderCRTC(int interlace)
|
|||
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);
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
|
|
@ -83,7 +83,8 @@ typedef void (APIENTRYP _PFNSWAPINTERVAL) (int);
|
|||
|
||||
map<string, GLbyte> mapGLExtensions;
|
||||
|
||||
namespace ZeroGS{
|
||||
namespace ZeroGS
|
||||
{
|
||||
RenderFormatType g_RenderFormatType = RFT_float16;
|
||||
|
||||
extern void KickPoint();
|
||||
|
@ -189,46 +190,58 @@ bool ZeroGS::IsGLExt( const char* szTargetExtension )
|
|||
}
|
||||
|
||||
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,22 +250,26 @@ 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;
|
||||
}
|
||||
|
@ -269,11 +286,15 @@ inline void ZeroGS::CreateOtherCheck() {
|
|||
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.");
|
||||
|
||||
|
@ -293,11 +314,15 @@ inline void ZeroGS::CreateOtherCheck() {
|
|||
#ifdef _WIN32
|
||||
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)
|
||||
swapinterval = (_PFNSWAPINTERVAL)wglGetProcAddress("glXSwapIntervalSGI");
|
||||
|
||||
if (!swapinterval)
|
||||
swapinterval = (_PFNSWAPINTERVAL)wglGetProcAddress("glXSwapIntervalEXT");
|
||||
|
||||
|
@ -306,12 +331,14 @@ inline void ZeroGS::CreateOtherCheck() {
|
|||
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);
|
||||
|
@ -321,14 +348,20 @@ inline bool ZeroGS::CreateOpenShadersFile() {
|
|||
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,17 +378,21 @@ 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);
|
||||
|
@ -366,12 +403,15 @@ inline bool ZeroGS::CreateOpenShadersFile() {
|
|||
}
|
||||
|
||||
// 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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -431,14 +476,15 @@ 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_fiGPU_TEXWIDTH = 1.0f / GPU_TEXWIDTH;
|
||||
|
||||
if (!CreateOpenShadersFile())
|
||||
return false;
|
||||
if (!CreateOpenShadersFile()) return false;
|
||||
|
||||
GL_REPORT_ERROR();
|
||||
|
||||
if (err != GL_NO_ERROR) bSuccess = false;
|
||||
|
||||
s_srcrgb = s_dstrgb = s_srcalpha = s_dstalpha = GL_ONE;
|
||||
|
@ -462,26 +508,29 @@ bool ZeroGS::Create(int _width, int _height)
|
|||
GL_LOADFN(glGenerateMipmapEXT);
|
||||
|
||||
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 (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);
|
||||
|
||||
if( glDrawBuffers != NULL )
|
||||
glDrawBuffers(1, s_drawbuffers);
|
||||
if (glDrawBuffers != NULL) glDrawBuffers(1, s_drawbuffers);
|
||||
GL_REPORT_ERROR();
|
||||
|
||||
if (err != GL_NO_ERROR) bSuccess = false;
|
||||
|
||||
font_p = new RasterFont();
|
||||
|
||||
GL_REPORT_ERROR();
|
||||
|
||||
if (err != GL_NO_ERROR) bSuccess = false;
|
||||
|
||||
// init draw fns
|
||||
|
@ -495,53 +544,64 @@ 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
|
||||
|
||||
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);
|
||||
|
||||
HGLOBAL hBitmapGlob = LoadResource(hInst, hBitmapSrc);
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
|
@ -553,6 +613,7 @@ bool ZeroGS::Create(int _width, int _height)
|
|||
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;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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) {
|
||||
|
||||
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;
|
||||
|
||||
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 ) {
|
||||
|
||||
if (bFailed || pfrag == NULL)
|
||||
{
|
||||
g_nPixelShaderVer = SHADER_ACCURATE | SHADER_REDUCED;
|
||||
|
||||
pfrag = LoadShadeEffect(0, 0, 1, 1, 0, temp, 0, &bFailed);
|
||||
|
||||
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;
|
||||
|
||||
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
|
@ -53,11 +53,16 @@ int ZeroGS::Save(s8* pbydata)
|
|||
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;
|
||||
|
@ -67,10 +72,12 @@ int ZeroGS::Save(s8* pbydata)
|
|||
|
||||
*(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;
|
||||
}
|
||||
|
@ -88,8 +95,8 @@ bool ZeroGS::Load(s8* pbydata)
|
|||
// first 32 bytes are the id
|
||||
u32 savever = *(u32*)(pbydata + 16);
|
||||
|
||||
if( strncmp((char*)pbydata, libraryNameX, 6) == 0 && (savever == ZEROGS_SAVEVER || savever == 0xaa000004) ) {
|
||||
|
||||
if (strncmp((char*)pbydata, libraryNameX, 6) == 0 && (savever == ZEROGS_SAVEVER || savever == 0xaa000004))
|
||||
{
|
||||
g_MemTargs.Destroy();
|
||||
|
||||
GSStateReset();
|
||||
|
@ -99,7 +106,8 @@ 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;
|
||||
|
@ -110,14 +118,19 @@ bool ZeroGS::Load(s8* pbydata)
|
|||
memset(&gs, 0, sizeof(gs));
|
||||
|
||||
int savedgssize;
|
||||
|
||||
if (savever == 0xaa000004)
|
||||
{
|
||||
savedgssize = 0x1d0;
|
||||
else {
|
||||
}
|
||||
else
|
||||
{
|
||||
savedgssize = *(int*)pbydata;
|
||||
pbydata += 4;
|
||||
}
|
||||
|
||||
memcpy(&gs, pbydata, savedgssize);
|
||||
|
||||
pbydata += savedgssize;
|
||||
prim = &gs._prim[gs.prac];
|
||||
|
||||
|
@ -131,11 +144,13 @@ 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));
|
||||
}
|
||||
|
||||
|
|
|
@ -30,7 +30,9 @@ using namespace ZeroGS;
|
|||
//------------------ Constants
|
||||
|
||||
// ----------------- Global Variables
|
||||
namespace ZeroGS {
|
||||
|
||||
namespace ZeroGS
|
||||
{
|
||||
FRAGMENTSHADER ppsBitBlt[2], ppsBitBltDepth, ppsOne;
|
||||
FRAGMENTSHADER ppsBaseTexture, ppsConvert16to32, ppsConvert32to16;
|
||||
}
|
||||
|
@ -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)
|
||||
{
|
||||
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");
|
||||
|
@ -109,6 +121,7 @@ void SetupVertexProgramParameters(CGprogram prog, int context)
|
|||
CGparameter p;
|
||||
|
||||
p = cgGetNamedParameter(prog, "g_fPosXY");
|
||||
|
||||
if (p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE)
|
||||
cgConnectParameter(g_vparamPosXY[context], p);
|
||||
|
||||
|
@ -125,32 +138,43 @@ void SetupVertexProgramParameters(CGprogram prog, int context)
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
p = cgGetNamedParameter(prog, "g_fZNorm");
|
||||
|
||||
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));
|
||||
|
||||
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));
|
||||
|
||||
p = cgGetNamedParameter(prog, "g_fc0");
|
||||
|
||||
if (p != NULL && cgIsParameterUsed(p, prog) == CG_TRUE)
|
||||
cgGLSetParameter4fv(p, Vector(0, 1, 0.001f, 0.5f));
|
||||
}
|
||||
|
@ -206,18 +230,23 @@ bool ZeroGS::LoadEffects()
|
|||
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,7 +260,8 @@ 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 ) {
|
||||
|
@ -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,34 +282,46 @@ 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)
|
||||
conf.mrtdepth = 0;
|
||||
|
||||
LOAD_PS(SH_REGULARFOGPS, ppsRegular[3]);
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
|
@ -300,16 +343,29 @@ FRAGMENTSHADER* ZeroGS::LoadShadeEffect(int type, int texfilter, int fog, int te
|
|||
int texwrap;
|
||||
assert(texfilter < NUM_FILTERS);
|
||||
|
||||
if(g_nPixelShaderVer&SHADER_REDUCED)
|
||||
texfilter = 0;
|
||||
if (g_nPixelShaderVer & SHADER_REDUCED) texfilter = 0;
|
||||
|
||||
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;
|
||||
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)
|
||||
|
@ -320,39 +376,49 @@ FRAGMENTSHADER* ZeroGS::LoadShadeEffect(int type, int texfilter, int fog, int te
|
|||
int index = GET_SHADER_INDEX(type, texfilter, texwrap, fog, s_bWriteDepth, testaem, exactcolor, context, 0);
|
||||
|
||||
assert(index < ARRAY_SIZE(ppsTexture));
|
||||
|
||||
FRAGMENTSHADER* pf = ppsTexture + index;
|
||||
|
||||
if (pbFailed != NULL) *pbFailed = false;
|
||||
|
||||
if( pf->prog != NULL )
|
||||
return pf;
|
||||
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());
|
||||
|
||||
SHADERHEADER* header = mapShaderResources[index];
|
||||
if( header == NULL )
|
||||
ZZLog::Error_Log("%d %d", index, g_nPixelShaderVer);
|
||||
|
||||
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;
|
||||
|
||||
// }
|
||||
}
|
||||
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;
|
||||
|
||||
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);
|
||||
|
@ -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);
|
||||
|
@ -503,13 +581,26 @@ FRAGMENTSHADER* ZeroGS::LoadShadeEffect(int type, int texfilter, int fog, int te
|
|||
|
||||
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)
|
||||
|
@ -523,12 +614,12 @@ FRAGMENTSHADER* ZeroGS::LoadShadeEffect(int type, int texfilter, int fog, int te
|
|||
|
||||
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]);
|
||||
|
@ -536,21 +627,28 @@ FRAGMENTSHADER* ZeroGS::LoadShadeEffect(int type, int texfilter, int fog, int te
|
|||
#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;
|
||||
|
||||
// }
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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,7 +218,8 @@ 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) {
|
||||
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)
|
||||
|
@ -257,24 +272,27 @@ struct TGA_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;
|
||||
|
||||
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;
|
||||
|
@ -283,7 +301,9 @@ ZeroGS::SaveTGA(const char* filename, int width, int height, void* pdata)
|
|||
|
||||
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.");
|
||||
}
|
||||
|
||||
|
@ -321,6 +342,7 @@ void ZeroGS::CaptureFrame()
|
|||
|
||||
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,8 +375,8 @@ ZeroGS::SaveTex(tex0Info* ptex, int usevid)
|
|||
|
||||
CMemoryTarget* pmemtarg = NULL;
|
||||
|
||||
if (usevid) {
|
||||
|
||||
if (usevid)
|
||||
{
|
||||
pmemtarg = g_MemTargs.GetMemoryTarget(*ptex, 0);
|
||||
assert(pmemtarg != NULL);
|
||||
|
||||
|
@ -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) {
|
||||
|
||||
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);
|
||||
else
|
||||
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);
|
||||
else
|
||||
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);
|
||||
else
|
||||
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);
|
||||
else
|
||||
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);
|
||||
else
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
u = readPixel16SZ(psrc, j, i, ptex->tbp0, ptex->tbw);
|
||||
else u = 0;
|
||||
else
|
||||
u = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -530,6 +598,7 @@ ZeroGS::SaveTex(tex0Info* ptex, int usevid)
|
|||
}
|
||||
|
||||
char Name[TGA_FILE_NAME_MAX_LENGTH];
|
||||
|
||||
snprintf(Name, TGA_FILE_NAME_MAX_LENGTH, "Tex.%d.tga", TexNumber);
|
||||
SaveTGA(Name, ptex->tw, ptex->th, &data[0]);
|
||||
}
|
||||
|
@ -537,22 +606,22 @@ ZeroGS::SaveTex(tex0Info* ptex, int usevid)
|
|||
|
||||
// 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);
|
||||
|
||||
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) {
|
||||
if (!zbuf.zmsk)
|
||||
{
|
||||
int Constraint = (tbp - zbuf.zbp) * (PSMT_ISHALF(zbuf.psm) ? 2 : 1);
|
||||
if ((0 < Constraint) && (Constraint < MinConstraint)) {
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
|
||||
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);
|
||||
|
@ -228,7 +254,8 @@ ZeroGS::VB::CheckFrameAddConstraints(int tbp)
|
|||
|
||||
#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;
|
||||
|
@ -264,10 +289,10 @@ 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) {
|
||||
// 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;
|
||||
|
@ -280,12 +305,16 @@ ZeroGS::VB::CheckFrameResolveRender(int tbp) {
|
|||
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;
|
||||
|
||||
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);
|
||||
|
@ -299,66 +328,77 @@ ZeroGS::VB::CheckFrameResolveRender(int tbp) {
|
|||
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 ((prndr != NULL) && (prndr->psm != gsfb.psm))
|
||||
{
|
||||
// behavior for dest alpha varies
|
||||
ResetAlphaVariables();
|
||||
}
|
||||
|
||||
bChanged = CheckFrameResolveRender(tbp);
|
||||
|
||||
CheckFrame16vs32Convesion();
|
||||
}
|
||||
else if (bNeedZCheck) {
|
||||
else if (bNeedZCheck)
|
||||
{
|
||||
bNeedZCheck = 0;
|
||||
|
||||
if (prndr != NULL && gsfb.fbw > 0)
|
||||
CheckFrameResolveDepth(tbp);
|
||||
}
|
||||
|
@ -367,8 +407,10 @@ void ZeroGS::VB::CheckFrame(int tbp)
|
|||
}
|
||||
|
||||
// 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;
|
||||
|
@ -418,19 +463,22 @@ void ZeroGS::VB::FlushTexData()
|
|||
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},
|
||||
|
@ -114,7 +114,9 @@ RasterFont::RasterFont()
|
|||
|
||||
// create the raster font
|
||||
fontOffset = glGenLists(128);
|
||||
for (int i = 32; i < 127; i++) {
|
||||
|
||||
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();
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -310,16 +310,19 @@ extern "C" void __fastcall WriteCLUT_T32_I4_CSM1_sse2(u32* vm, u32* clut)
|
|||
}
|
||||
|
||||
|
||||
extern "C" {
|
||||
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};
|
||||
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,6 +431,7 @@ WriteUnaligned:
|
|||
|
||||
movdqa [ecx+16], xmm2
|
||||
movdqa [ecx+48], xmm3
|
||||
|
||||
End:
|
||||
}
|
||||
#else
|
||||
|
@ -540,10 +544,12 @@ End:
|
|||
"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)
|
||||
|
@ -563,8 +569,10 @@ void __fastcall WriteCLUT_T16_I8_CSM1_c(u32* _vm, u32* _clut)
|
|||
|
||||
for (int j = 0; j < 8; j++, vm += 32, clut += 64, left -= 32)
|
||||
{
|
||||
if(left == 32) {
|
||||
if (left == 32)
|
||||
{
|
||||
assert(left == 32);
|
||||
|
||||
for (int i = 0; i < 16; i++)
|
||||
clut[2*i] = vm[map[i]];
|
||||
|
||||
|
@ -573,8 +581,10 @@ void __fastcall WriteCLUT_T16_I8_CSM1_c(u32* _vm, u32* _clut)
|
|||
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;
|
||||
}
|
||||
|
@ -590,7 +600,8 @@ 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 j = 0; j < 2; j++, src += 32)
|
||||
{
|
||||
for (int i = 0; i < 4; i++, dst += 16, src += 8)
|
||||
{
|
||||
dst[0] = src[0];
|
||||
|
@ -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
|
||||
|
@ -741,6 +762,7 @@ Z16Loop:
|
|||
"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
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
typedef void (APIENTRYP _PFNSWAPINTERVAL)(int);
|
||||
|
||||
//-------------------------- Extern variables
|
||||
|
||||
using namespace ZeroGS;
|
||||
|
||||
extern u32 g_nGenVars, g_nTexVars, g_nAlphaVars, g_nResolve;
|
||||
|
@ -139,7 +140,9 @@ namespace ZeroGS
|
|||
struct MESSAGE
|
||||
{
|
||||
MESSAGE() {}
|
||||
|
||||
MESSAGE(const char* p, u32 dw) { strcpy(str, p); dwTimeStamp = dw; }
|
||||
|
||||
char str[255];
|
||||
u32 dwTimeStamp;
|
||||
};
|
||||
|
@ -161,32 +164,42 @@ namespace ZeroGS
|
|||
|
||||
void ExtWrite();
|
||||
|
||||
void ResetRenderTarget(int index) {
|
||||
void ResetRenderTarget(int index)
|
||||
{
|
||||
glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + index, GL_TEXTURE_RECTANGLE_NV, 0, 0);
|
||||
}
|
||||
|
||||
DrawFn drawfn[8] = { KickDummy, KickDummy, KickDummy, KickDummy,
|
||||
KickDummy, KickDummy, KickDummy, KickDummy };
|
||||
KickDummy, KickDummy, KickDummy, KickDummy
|
||||
};
|
||||
|
||||
}; // end namespace
|
||||
|
||||
// does one time only initializing/destruction
|
||||
|
||||
class ZeroGSInit
|
||||
{
|
||||
|
||||
public:
|
||||
ZeroGSInit() {
|
||||
ZeroGSInit()
|
||||
{
|
||||
const u32 mem_size = 0x00400000 + 0x10000; // leave some room for out of range accesses (saves on the checks)
|
||||
// clear
|
||||
g_pbyGSMemory = (u8*)_aligned_malloc(0x00410000, 1024); // leave some room for out of range accesses (saves on the checks)
|
||||
memset(g_pbyGSMemory, 0, 0x00410000);
|
||||
g_pbyGSMemory = (u8*)_aligned_malloc(mem_size, 1024);
|
||||
memset(g_pbyGSMemory, 0, mem_size);
|
||||
|
||||
g_pbyGSClut = (u8*)_aligned_malloc(256 * 8, 1024); // need 512 alignment!
|
||||
memset(g_pbyGSClut, 0, 256*8);
|
||||
|
||||
memset(&GLWin, 0, sizeof(GLWin));
|
||||
}
|
||||
~ZeroGSInit() {
|
||||
_aligned_free(g_pbyGSMemory); g_pbyGSMemory = NULL;
|
||||
_aligned_free(g_pbyGSClut); g_pbyGSClut = NULL;
|
||||
|
||||
~ZeroGSInit()
|
||||
{
|
||||
_aligned_free(g_pbyGSMemory);
|
||||
g_pbyGSMemory = NULL;
|
||||
|
||||
_aligned_free(g_pbyGSClut);
|
||||
g_pbyGSClut = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -203,7 +216,9 @@ void ZeroGS::HandleGLError()
|
|||
GLenum error = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
|
||||
// if error != GL_FRAMEBUFFER_COMPLETE_EXT, there's an error of some sort
|
||||
if( error != 0 ) {
|
||||
|
||||
if (error != 0)
|
||||
{
|
||||
int w, h;
|
||||
GLint fmt;
|
||||
glGetRenderbufferParameterivEXT(GL_COLOR_ATTACHMENT0_EXT, GL_RENDERBUFFER_INTERNAL_FORMAT_EXT, &fmt);
|
||||
|
@ -214,30 +229,39 @@ void ZeroGS::HandleGLError()
|
|||
{
|
||||
case GL_FRAMEBUFFER_COMPLETE_EXT:
|
||||
break;
|
||||
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
|
||||
ZZLog::Error_Log("Error! missing a required image/buffer attachment!");
|
||||
break;
|
||||
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
|
||||
ZZLog::Error_Log("Error! has no images/buffers attached!");
|
||||
break;
|
||||
|
||||
// case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT_EXT:
|
||||
// ZZLog::Error_Log("Error! has an image/buffer attached in multiple locations!");
|
||||
// break;
|
||||
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
|
||||
ZZLog::Error_Log("Error! has mismatched image/buffer dimensions!");
|
||||
break;
|
||||
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT:
|
||||
ZZLog::Error_Log("Error! colorbuffer attachments have different types!");
|
||||
break;
|
||||
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
|
||||
ZZLog::Error_Log("Error! trying to draw to non-attached color buffer!");
|
||||
break;
|
||||
|
||||
case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
|
||||
ZZLog::Error_Log("Error! trying to read from a non-attached color buffer!");
|
||||
break;
|
||||
|
||||
case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
|
||||
ZZLog::Error_Log("Error! format is not supported by current graphics card/driver!");
|
||||
break;
|
||||
|
||||
default:
|
||||
ZZLog::Error_Log("*UNKNOWN ERROR* reported from glCheckFramebufferStatusEXT() for %s!");
|
||||
break;
|
||||
|
@ -251,7 +275,8 @@ void ZeroGS::GSStateReset()
|
|||
FUNCLOG
|
||||
icurctx = -1;
|
||||
|
||||
for(int i = 0; i < 2; ++i) {
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
vb[i].Destroy();
|
||||
memset(&vb[i], 0, sizeof(ZeroGS::VB));
|
||||
|
||||
|
@ -264,6 +289,7 @@ void ZeroGS::GSStateReset()
|
|||
}
|
||||
|
||||
s_RangeMngr.Clear();
|
||||
|
||||
g_MemTargs.Destroy();
|
||||
s_RTs.Destroy();
|
||||
s_DepthRTs.Destroy();
|
||||
|
@ -277,6 +303,7 @@ void ZeroGS::AddMessage(const char* pstr, u32 ms)
|
|||
{
|
||||
FUNCLOG
|
||||
listMsgs.push_back(MESSAGE(pstr, timeGetTime() + ms));
|
||||
ZZLog::Log("%s\n", pstr);
|
||||
}
|
||||
|
||||
void ZeroGS::DrawText(const char* pstr, int left, int top, u32 color)
|
||||
|
@ -285,7 +312,10 @@ void ZeroGS::DrawText(const char* pstr, int left, int top, u32 color)
|
|||
cgGLDisableProfile(cgvProf);
|
||||
cgGLDisableProfile(cgfProf);
|
||||
|
||||
glColor3f(((color>>16)&0xff)/255.0f, ((color>>8)&0xff)/255.0f, (color&0xff)/255.0f);
|
||||
Vector v;
|
||||
v.SetColor(color);
|
||||
glColor3f(v.z, v.y, v.x);
|
||||
//glColor3f(((color >> 16) & 0xff) / 255.0f, ((color >> 8) & 0xff)/ 255.0f, (color & 0xff) / 255.0f);
|
||||
|
||||
font_p->printString(pstr, left * 2.0f / (float)nBackbufferWidth - 1, 1 - top * 2.0f / (float)nBackbufferHeight, 0);
|
||||
cgGLEnableProfile(cgvProf);
|
||||
|
@ -295,10 +325,11 @@ void ZeroGS::DrawText(const char* pstr, int left, int top, u32 color)
|
|||
void ZeroGS::ChangeWindowSize(int nNewWidth, int nNewHeight)
|
||||
{
|
||||
FUNCLOG
|
||||
nBackbufferWidth = nNewWidth > 16 ? nNewWidth : 16;
|
||||
nBackbufferHeight = nNewHeight > 16 ? nNewHeight : 16;
|
||||
nBackbufferWidth = max(nNewWidth, 16);
|
||||
nBackbufferHeight = max(nNewHeight, 16);
|
||||
|
||||
if( !(conf.options & GSOPTION_FULLSCREEN) ) {
|
||||
if (!(conf.options & GSOPTION_FULLSCREEN))
|
||||
{
|
||||
conf.width = nNewWidth;
|
||||
conf.height = nNewHeight;
|
||||
//SaveConfig();
|
||||
|
@ -311,7 +342,8 @@ void ZeroGS::SetChangeDeviceSize(int nNewWidth, int nNewHeight)
|
|||
s_nNewWidth = nNewWidth;
|
||||
s_nNewHeight = nNewHeight;
|
||||
|
||||
if( !(conf.options & GSOPTION_FULLSCREEN) ) {
|
||||
if (!(conf.options & GSOPTION_FULLSCREEN))
|
||||
{
|
||||
conf.width = nNewWidth;
|
||||
conf.height = nNewHeight;
|
||||
//SaveConfig();
|
||||
|
@ -352,9 +384,11 @@ void ZeroGS::ChangeDeviceSize(int nNewWidth, int nNewHeight)
|
|||
//int oldscreen = s_nFullscreen;
|
||||
|
||||
int oldwidth = nBackbufferWidth, oldheight = nBackbufferHeight;
|
||||
|
||||
if (!Create(nNewWidth&~7, nNewHeight&~7))
|
||||
{
|
||||
ZZLog::Error_Log("Failed to recreate, changing to old device.");
|
||||
|
||||
if (Create(oldwidth, oldheight))
|
||||
{
|
||||
SysMessage("Failed to create device, exiting...");
|
||||
|
@ -362,7 +396,8 @@ void ZeroGS::ChangeDeviceSize(int nNewWidth, int nNewHeight)
|
|||
}
|
||||
}
|
||||
|
||||
for(int i = 0; i < 2; ++i) {
|
||||
for (int i = 0; i < 2; ++i)
|
||||
{
|
||||
vb[i].bNeedFrameCheck = vb[i].bNeedZCheck = 1;
|
||||
vb[i].CheckFrame(0);
|
||||
}
|
||||
|
@ -371,7 +406,8 @@ void ZeroGS::ChangeDeviceSize(int nNewWidth, int nNewHeight)
|
|||
}
|
||||
|
||||
|
||||
void ZeroGS::SetNegAA(int mode) {
|
||||
void ZeroGS::SetNegAA(int mode)
|
||||
{
|
||||
FUNCLOG
|
||||
// need to flush all targets
|
||||
s_RTs.ResolveAll();
|
||||
|
@ -380,6 +416,7 @@ void ZeroGS::SetNegAA(int mode) {
|
|||
s_DepthRTs.Destroy();
|
||||
|
||||
s_AAz = s_AAw = 0; // This is code for x0, x2, x4, x8 and x16 anti-aliasing.
|
||||
|
||||
if (mode > 0)
|
||||
{
|
||||
s_AAz = (mode + 1) / 2; // ( 1, 0 ) ; ( 1, 1 ) -- it's used as binary shift, so x << s_AAz, y << s_AAw
|
||||
|
@ -387,10 +424,17 @@ void ZeroGS::SetNegAA(int mode) {
|
|||
}
|
||||
|
||||
memset(s_nResolveCounts, 0, sizeof(s_nResolveCounts));
|
||||
|
||||
s_nLastResolveReset = 0;
|
||||
|
||||
vb[0].prndr = NULL; vb[0].pdepth = NULL; vb[0].bNeedFrameCheck = 1; vb[0].bNeedZCheck = 1;
|
||||
vb[1].prndr = NULL; vb[1].pdepth = NULL; vb[1].bNeedFrameCheck = 1; vb[1].bNeedZCheck = 1;
|
||||
vb[0].prndr = NULL;
|
||||
vb[0].pdepth = NULL;
|
||||
vb[0].bNeedFrameCheck = 1;
|
||||
vb[0].bNeedZCheck = 1;
|
||||
vb[1].prndr = NULL;
|
||||
vb[1].pdepth = NULL;
|
||||
vb[1].bNeedFrameCheck = 1;
|
||||
vb[1].bNeedZCheck = 1;
|
||||
}
|
||||
|
||||
void ZeroGS::SetAA(int mode)
|
||||
|
@ -405,6 +449,7 @@ void ZeroGS::SetAA(int mode)
|
|||
s_DepthRTs.Destroy();
|
||||
|
||||
s_AAx = s_AAy = 0; // This is code for x0, x2, x4, x8 and x16 anti-aliasing.
|
||||
|
||||
if (mode > 0)
|
||||
{
|
||||
s_AAx = (mode + 1) / 2; // ( 1, 0 ) ; ( 1, 1 ) ; ( 2, 1 ) ; ( 2, 2 ) -- it's used as binary shift, so x >> s_AAx, y >> s_AAy
|
||||
|
@ -412,25 +457,32 @@ void ZeroGS::SetAA(int mode)
|
|||
}
|
||||
|
||||
memset(s_nResolveCounts, 0, sizeof(s_nResolveCounts));
|
||||
|
||||
s_nLastResolveReset = 0;
|
||||
|
||||
vb[0].prndr = NULL; vb[0].pdepth = NULL; vb[0].bNeedFrameCheck = 1; vb[0].bNeedZCheck = 1;
|
||||
vb[1].prndr = NULL; vb[1].pdepth = NULL; vb[1].bNeedFrameCheck = 1; vb[1].bNeedZCheck = 1;
|
||||
vb[0].prndr = NULL;
|
||||
vb[0].pdepth = NULL;
|
||||
vb[0].bNeedFrameCheck = 1;
|
||||
vb[0].bNeedZCheck = 1;
|
||||
vb[1].prndr = NULL;
|
||||
vb[1].pdepth = NULL;
|
||||
vb[1].bNeedFrameCheck = 1;
|
||||
vb[1].bNeedZCheck = 1;
|
||||
|
||||
f = mode > 0 ? 2.0f : 1.0f;
|
||||
glPointSize(f);
|
||||
}
|
||||
|
||||
void ZeroGS::Prim(){
|
||||
void ZeroGS::Prim()
|
||||
{
|
||||
FUNCLOG
|
||||
if( g_bIsLost )
|
||||
return;
|
||||
|
||||
if (g_bIsLost) return;
|
||||
|
||||
VB& curvb = vb[prim->ctxt];
|
||||
|
||||
if( curvb.CheckPrim() ){
|
||||
Flush(prim->ctxt);
|
||||
}
|
||||
if (curvb.CheckPrim()) Flush(prim->ctxt);
|
||||
|
||||
curvb.curprim._val = prim->_val;
|
||||
|
||||
// flush the other pipe if sharing the same buffer
|
||||
|
@ -446,11 +498,14 @@ void ZeroGS::Prim(){
|
|||
void ZeroGS::ProcessMessages()
|
||||
{
|
||||
FUNCLOG
|
||||
if( listMsgs.size() > 0 ) {
|
||||
|
||||
if (listMsgs.size() > 0)
|
||||
{
|
||||
int left = 25, top = 15;
|
||||
list<MESSAGE>::iterator it = listMsgs.begin();
|
||||
|
||||
while( it != listMsgs.end() ) {
|
||||
while (it != listMsgs.end())
|
||||
{
|
||||
DrawText(it->str, left + 1, top + 1, 0xff000000);
|
||||
DrawText(it->str, left, top, 0xffffff30);
|
||||
top += 15;
|
||||
|
@ -493,12 +548,13 @@ void ZeroGS::RenderCustom(float fAlpha)
|
|||
// inside vhDCb[0]'s target area, so render that region only
|
||||
cgGLSetTextureParameter(ppsBaseTexture.sFinal, ptexLogo);
|
||||
cgGLEnableTextureParameter(ppsBaseTexture.sFinal);
|
||||
|
||||
glBindBuffer(GL_ARRAY_BUFFER, vboRect);
|
||||
|
||||
SET_STREAM();
|
||||
|
||||
SETVERTEXSHADER(pvsBitBlt.prog);
|
||||
SETPIXELSHADER(ppsBaseTexture.prog);
|
||||
|
||||
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
|
||||
|
||||
// restore
|
||||
|
@ -515,20 +571,24 @@ void ZeroGS::RenderCustom(float fAlpha)
|
|||
vb[1].bSyncVars = 0;
|
||||
|
||||
GL_REPORT_ERROR();
|
||||
|
||||
GLint status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
|
||||
|
||||
assert(status == GL_FRAMEBUFFER_COMPLETE_EXT || status == GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT);
|
||||
}
|
||||
|
||||
void ZeroGS::Restore()
|
||||
{
|
||||
FUNCLOG
|
||||
if( !g_bIsLost )
|
||||
return;
|
||||
|
||||
if (!g_bIsLost) return;
|
||||
|
||||
//if( SUCCEEDED(pd3dDevice->Reset(&d3dpp)) ) {
|
||||
g_bIsLost = 0;
|
||||
|
||||
// handle lost states
|
||||
ZeroGS::ChangeDeviceSize(nBackbufferWidth, nBackbufferHeight);
|
||||
|
||||
//}
|
||||
}
|
||||
|
||||
|
@ -565,14 +625,17 @@ __forceinline void SET_VERTEX(VertexGPU *p, int Index, const VB& curvb)
|
|||
|
||||
|
||||
p->f = ((s16)gs.gsvertex[index].f << 7) | 0x7f;
|
||||
|
||||
MOVZ(p, gs.gsvertex[index].z, curvb);
|
||||
|
||||
p->rgba = prim->iip ? gs.gsvertex[index].rgba : gs.rgba;
|
||||
|
||||
// This code is somehow incorrect
|
||||
// if ((gs.texa.aem) && ((p->rgba & 0xffffff ) == 0))
|
||||
// p->rgba = 0;
|
||||
|
||||
if (g_GameSettings & GAME_TEXAHACK) {
|
||||
if (g_GameSettings & GAME_TEXAHACK)
|
||||
{
|
||||
u32 B = ((p->rgba & 0xfe000000) >> 1) +
|
||||
(0x01000000 * curvb.fba.fba) ;
|
||||
p->rgba = (p->rgba & 0xffffff) + B;
|
||||
|
@ -610,6 +673,7 @@ void ZeroGS::KickPoint()
|
|||
assert(gs.primC >= 1);
|
||||
|
||||
VB& curvb = vb[prim->ctxt];
|
||||
|
||||
if (curvb.bNeedTexCheck) curvb.FlushTexData();
|
||||
|
||||
if ((vb[!prim->ctxt].nCount > 0) && (vb[prim->ctxt].gsfb.fbp == vb[!prim->ctxt].gsfb.fbp))
|
||||
|
@ -634,10 +698,10 @@ void ZeroGS::KickLine()
|
|||
FUNCLOG
|
||||
assert(gs.primC >= 2);
|
||||
VB& curvb = vb[prim->ctxt];
|
||||
if( curvb.bNeedTexCheck )
|
||||
curvb.FlushTexData();
|
||||
|
||||
if( vb[!prim->ctxt].nCount > 0 && vb[prim->ctxt].gsfb.fbp == vb[!prim->ctxt].gsfb.fbp )
|
||||
if (curvb.bNeedTexCheck) curvb.FlushTexData();
|
||||
|
||||
if ((vb[!prim->ctxt].nCount > 0) && (vb[prim->ctxt].gsfb.fbp == vb[!prim->ctxt].gsfb.fbp))
|
||||
{
|
||||
assert(vb[prim->ctxt].nCount == 0);
|
||||
Flush(!prim->ctxt);
|
||||
|
@ -663,6 +727,7 @@ void ZeroGS::KickTriangle()
|
|||
FUNCLOG
|
||||
assert(gs.primC >= 3);
|
||||
VB& curvb = vb[prim->ctxt];
|
||||
|
||||
if (curvb.bNeedTexCheck) curvb.FlushTexData();
|
||||
|
||||
if ((vb[!prim->ctxt].nCount > 0) && (vb[prim->ctxt].gsfb.fbp == vb[!prim->ctxt].gsfb.fbp))
|
||||
|
@ -690,6 +755,7 @@ void ZeroGS::KickTriangleFan()
|
|||
FUNCLOG
|
||||
assert(gs.primC >= 3);
|
||||
VB& curvb = vb[prim->ctxt];
|
||||
|
||||
if (curvb.bNeedTexCheck) curvb.FlushTexData();
|
||||
|
||||
if ((vb[!prim->ctxt].nCount > 0) && (vb[prim->ctxt].gsfb.fbp == vb[!prim->ctxt].gsfb.fbp))
|
||||
|
@ -708,8 +774,8 @@ void ZeroGS::KickTriangleFan()
|
|||
curvb.nCount += 3;
|
||||
|
||||
// add 1 to skip the first vertex
|
||||
if (gs.primIndex == gs.nTriFanVert)
|
||||
gs.primIndex = (gs.primIndex+1)%ARRAY_SIZE(gs.gsvertex);
|
||||
|
||||
if (gs.primIndex == gs.nTriFanVert) gs.primIndex = (gs.primIndex + 1) % ARRAY_SIZE(gs.gsvertex);
|
||||
|
||||
OUTPUT_VERT(p[0], 0);
|
||||
OUTPUT_VERT(p[1], 1);
|
||||
|
@ -743,9 +809,11 @@ void ZeroGS::KickSprite()
|
|||
int last = (gs.primIndex + 2) % ARRAY_SIZE(gs.gsvertex);
|
||||
|
||||
// sprite is too small and AA shows lines (tek4)
|
||||
|
||||
if (s_AAx)
|
||||
{
|
||||
gs.gsvertex[last].x += 4;
|
||||
|
||||
if (s_AAy) gs.gsvertex[last].y += 4;
|
||||
}
|
||||
|
||||
|
@ -765,6 +833,7 @@ void ZeroGS::KickSprite()
|
|||
p[2].x = p[1].x;
|
||||
|
||||
SetKickVertex(&p[5], gs.gsvertex[last], last, curvb);
|
||||
|
||||
p[5].s = p[0].s;
|
||||
p[5].x = p[0].x;
|
||||
|
||||
|
@ -798,11 +867,13 @@ void ZeroGS::SetFogColor(u32 fog)
|
|||
Vector v;
|
||||
|
||||
// set it immediately
|
||||
v.x = (gs.fogcol&0xff)/255.0f;
|
||||
v.y = ((gs.fogcol>>8)&0xff)/255.0f;
|
||||
v.z = ((gs.fogcol>>16)&0xff)/255.0f;
|
||||
// v.x = (gs.fogcol & 0xff) / 255.0f;
|
||||
// v.y = ((gs.fogcol >> 8) & 0xff) / 255.0f;
|
||||
// v.z = ((gs.fogcol >> 16) & 0xff) / 255.0f;
|
||||
v.SetColor(gs.fogcol);
|
||||
ZZcgSetParameter4fv(g_fparamFogColor, v, "g_fParamFogColor");
|
||||
}
|
||||
|
||||
// }
|
||||
}
|
||||
|
||||
|
@ -862,7 +933,8 @@ bool IsDirty(u32 highdword, u32 psm, int cld, int cbp)
|
|||
// do a fast test with MMX
|
||||
#ifdef _MSC_VER
|
||||
int storeebx;
|
||||
__asm {
|
||||
__asm
|
||||
{
|
||||
mov storeebx, ebx
|
||||
mov edx, dst
|
||||
mov ecx, src
|
||||
|
@ -910,12 +982,14 @@ Continue:
|
|||
test ebx, 0x10
|
||||
jz AddEcx
|
||||
sub ecx, 448 // go back and down one column,
|
||||
|
||||
AddEcx:
|
||||
add ecx, 256 // go to the right block
|
||||
|
||||
|
||||
jne Continue1
|
||||
add ecx, 256 // skip whole block
|
||||
|
||||
Continue1:
|
||||
add edx, 64
|
||||
sub ebx, 16
|
||||
|
@ -978,6 +1052,7 @@ Return:
|
|||
"jmp Start\n"
|
||||
"Return:\n"
|
||||
"emms\n"
|
||||
|
||||
".att_syntax\n" : "=m"(bRet) : "c"(dst), "d"(src), "b"(entries) : "eax", "memory");
|
||||
|
||||
#endif // _WIN32
|
||||
|
@ -1001,19 +1076,36 @@ bool ZeroGS::CheckChangeInClut(u32 highdword, u32 psm)
|
|||
|
||||
// processing the CLUT after tex0/2 are written
|
||||
//ZZLog::Error_Log("high == 0x%x; cld == %d", highdword, cld);
|
||||
switch(cld) {
|
||||
case 0: return false;
|
||||
case 1: break;
|
||||
case 2: break;
|
||||
case 3: break;
|
||||
case 4: if (gs.cbp[0] == cbp) return false; break;
|
||||
case 5: if (gs.cbp[1] == cbp) return false; break;
|
||||
|
||||
switch (cld)
|
||||
{
|
||||
case 0:
|
||||
return false;
|
||||
|
||||
case 1:
|
||||
break;
|
||||
|
||||
case 2:
|
||||
break;
|
||||
|
||||
case 3:
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (gs.cbp[0] == cbp) return false;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
if (gs.cbp[1] == cbp) return false;
|
||||
break;
|
||||
|
||||
//case 4: return gs.cbp[0] != cbp;
|
||||
//case 5: return gs.cbp[1] != cbp;
|
||||
|
||||
// default: load
|
||||
default: break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return IsDirty(highdword, psm, cld, cbp);
|
||||
|
@ -1023,26 +1115,40 @@ void ZeroGS::texClutWrite(int ctx)
|
|||
{
|
||||
FUNCLOG
|
||||
s_bTexFlush = 0;
|
||||
|
||||
if (g_bIsLost) return;
|
||||
|
||||
tex0Info& tex0 = vb[ctx].tex0;
|
||||
|
||||
assert(PSMT_ISCLUT(tex0.psm));
|
||||
|
||||
// processing the CLUT after tex0/2 are written
|
||||
switch (tex0.cld)
|
||||
{
|
||||
case 0: return;
|
||||
case 1: break; // tex0.cld is usually 1.
|
||||
case 2: gs.cbp[0] = tex0.cbp; break;
|
||||
case 3: gs.cbp[1] = tex0.cbp; break;
|
||||
case 0:
|
||||
return;
|
||||
|
||||
case 1:
|
||||
break; // tex0.cld is usually 1.
|
||||
|
||||
case 2:
|
||||
gs.cbp[0] = tex0.cbp;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
gs.cbp[1] = tex0.cbp;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
if (gs.cbp[0] == tex0.cbp) return;
|
||||
gs.cbp[0] = tex0.cbp;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
if (gs.cbp[1] == tex0.cbp) return;
|
||||
gs.cbp[1] = tex0.cbp;
|
||||
break;
|
||||
|
||||
default: //ZZLog::Debug_Log("cld isn't 0-5!");
|
||||
break;
|
||||
}
|
||||
|
@ -1057,6 +1163,7 @@ void ZeroGS::texClutWrite(int ctx)
|
|||
{
|
||||
// 16bit psm
|
||||
// eggomania uses non16bit textures for csm2
|
||||
|
||||
case PSMCT16:
|
||||
{
|
||||
u16* src = (u16*)g_pbyGSMemory + tex0.cbp * 128;
|
||||
|
@ -1068,6 +1175,7 @@ void ZeroGS::texClutWrite(int ctx)
|
|||
dst += 2;
|
||||
|
||||
// check for wrapping
|
||||
|
||||
if (((u32)(uptr)dst & 0x3ff) == 0) dst = (u16*)(g_pbyGSClut + 2);
|
||||
}
|
||||
break;
|
||||
|
@ -1084,6 +1192,7 @@ void ZeroGS::texClutWrite(int ctx)
|
|||
dst += 2;
|
||||
|
||||
// check for wrapping
|
||||
|
||||
if (((u32)(uptr)dst & 0x3ff) == 0) dst = (u16*)(g_pbyGSClut + 2);
|
||||
}
|
||||
break;
|
||||
|
@ -1096,6 +1205,7 @@ void ZeroGS::texClutWrite(int ctx)
|
|||
u32 *dst = (u32*)(g_pbyGSClut + 64 * tex0.csa);
|
||||
|
||||
// check if address exceeds src
|
||||
|
||||
if (src + getPixelAddress32_0(gs.clut.cou + entries - 1, gs.clut.cov, gs.clut.cbw) >= (u32*)g_pbyGSMemory + 0x00100000)
|
||||
ZZLog::Error_Log("texClutWrite out of bounds.");
|
||||
else
|
||||
|
@ -1132,7 +1242,6 @@ void ZeroGS::texClutWrite(int ctx)
|
|||
else // sse2 for 256 is more complicated, so use regular
|
||||
WriteCLUT_T16_I8_CSM1_c((u32*)(g_pbyGSMemory + 256 * tex0.cbp), (u32*)(g_pbyGSClut + 32*(tex0.csa&15) + (tex0.csa >= 16 ? 2 : 0)));
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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,11 +74,17 @@ 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) {
|
||||
|
||||
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;
|
||||
|
@ -81,11 +92,11 @@ int inf(char *src, char *dst, int bytes_to_decompress, int maximum_after_decompr
|
|||
|
||||
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,22 +104,27 @@ int inf(char *src, char *dst, int bytes_to_decompress, int maximum_after_decompr
|
|||
void zerr(int ret)
|
||||
{
|
||||
fputs("zpipe: ", stderr);
|
||||
switch (ret) {
|
||||
|
||||
switch (ret)
|
||||
{
|
||||
|
||||
case Z_ERRNO:
|
||||
if (ferror(stdin))
|
||||
fputs("error reading stdin\n", stderr);
|
||||
if (ferror(stdout))
|
||||
fputs("error writing stdout\n", stderr);
|
||||
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