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:
arcum42 2010-05-01 20:33:53 +00:00
parent 7e8c22b4f5
commit a6c4df49ea
23 changed files with 5863 additions and 3923 deletions

View File

@ -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;
}

View File

@ -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;

View File

@ -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]);
}

View File

@ -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

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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,

View File

@ -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]);
}
}

View File

@ -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;
}

View File

@ -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

View File

@ -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));
}

View File

@ -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;

View File

@ -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

View File

@ -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) ;
}

View File

@ -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

View File

@ -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

View File

@ -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;
}
}
}

View File

@ -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

View File

@ -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);
}