/[pcsx2_0.9.7]/trunk/plugins/zzogl-pg/opengl/GSmain.cpp
ViewVC logotype

Contents of /trunk/plugins/zzogl-pg/opengl/GSmain.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 280 - (show annotations) (download)
Thu Dec 23 12:02:12 2010 UTC (9 years, 2 months ago) by william
File size: 13073 byte(s)
re-commit (had local access denied errors when committing)
1 /* ZZ Open GL graphics plugin
2 * Copyright (c)2009-2010 zeydlitz@gmail.com, arcum42@gmail.com
3 * Based on Zerofrog's ZeroGS KOSMOS (c)2005-2008
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
18 */
19
20 #include "Util.h"
21 #include "GS.h"
22 #include "Profile.h"
23 #include "GLWin.h"
24 #include "ZZoglFlushHack.h"
25
26
27 using namespace std;
28
29 extern void SaveSnapshot(const char* filename);
30
31 #ifdef _MSC_VER
32 #pragma warning(disable:4244)
33 #endif
34
35 GLWindow GLWin;
36 GSinternal gs;
37 GSconf conf;
38
39 int ppf, g_GSMultiThreaded, CurrentSavestate = 0;
40 int g_LastCRC = 0, g_TransferredToGPU = 0, s_frameskipping = 0;
41 int g_SkipFlushFrame = 0;
42 GetSkipCount GetSkipCount_Handler = 0;
43
44 int UPDATE_FRAMES = 16, g_nFrame = 0, g_nRealFrame = 0;
45 float fFPS = 0;
46
47 void (*GSirq)();
48 u8* g_pBasePS2Mem = NULL;
49 string s_strIniPath("inis/"); // Air's new ini path (r2361)
50
51 bool SaveStateExists = true; // We could not know save slot status before first change occured
52 const char* SaveStateFile = NULL; // Name of SaveFile for access check.
53
54 extern const char* s_aa[5];
55 extern const char* pbilinear[];
56 // statistics
57 u32 g_nGenVars = 0, g_nTexVars = 0, g_nAlphaVars = 0, g_nResolve = 0;
58
59 #define VER 3
60 const unsigned char zgsversion = PS2E_GS_VERSION;
61 unsigned char zgsrevision = 0; // revision and build gives plugin version
62 unsigned char zgsbuild = VER;
63 unsigned char zgsminor = 0;
64
65 #ifdef _DEBUG
66 char *libraryName = "ZZ Ogl PG (Debug) ";
67 #elif defined(ZEROGS_DEVBUILD)
68 char *libraryName = "ZZ Ogl PG (Dev)";
69 #else
70 char *libraryName = "ZZ Ogl PG ";
71 #endif
72
73 extern int g_nPixelShaderVer, g_nFrameRender, g_nFramesSkipped;
74
75 extern void WriteAA();
76 extern void WriteBilinear();
77 extern void ZZDestroy();
78 extern bool ZZCreate(int width, int height);
79 extern void ZZGSStateReset();
80 extern int ZZSave(s8* pbydata);
81 extern bool ZZLoad(s8* pbydata);
82
83 // switches the render target to the real target, flushes the current render targets and renders the real image
84 extern void RenderCRTC(int interlace);
85
86 #if defined(_WIN32) && defined(_DEBUG)
87 HANDLE g_hCurrentThread = NULL;
88 #endif
89
90 extern int VALIDATE_THRESH;
91 extern u32 TEXDESTROY_THRESH;
92
93 u32 CALLBACK PS2EgetLibType()
94 {
95 return PS2E_LT_GS;
96 }
97
98 char* CALLBACK PS2EgetLibName()
99 {
100 return libraryName;
101 }
102
103 u32 CALLBACK PS2EgetLibVersion2(u32 type)
104 {
105 return (zgsversion << 16) | (zgsrevision << 8) | zgsbuild | (zgsminor << 24);
106 }
107
108 void CALLBACK GSsetBaseMem(void* pmem)
109 {
110 g_pBasePS2Mem = (u8*)pmem;
111 }
112
113 void CALLBACK GSsetSettingsDir(const char* dir)
114 {
115 s_strIniPath = (dir == NULL) ? "inis/" : dir;
116 }
117
118 void CALLBACK GSsetLogDir(const char* dir)
119 {
120 ZZLog::SetDir(dir);
121 }
122
123 void CALLBACK GSsetGameCRC(int crc, int options)
124 {
125 // build a list of function pointer for GetSkipCount (SkipDraw)
126 static GetSkipCount GSC_list[NUMBER_OF_TITLES];
127 static bool inited = false;
128
129 if (!inited)
130 {
131 inited = true;
132
133 memset(GSC_list, 0, sizeof(GSC_list));
134
135 GSC_list[Okami] = GSC_Okami;
136 GSC_list[MetalGearSolid3] = GSC_MetalGearSolid3;
137 GSC_list[DBZBT2] = GSC_DBZBT2;
138 GSC_list[DBZBT3] = GSC_DBZBT3;
139 GSC_list[SFEX3] = GSC_SFEX3;
140 GSC_list[Bully] = GSC_Bully;
141 GSC_list[BullyCC] = GSC_BullyCC;
142 GSC_list[SoTC] = GSC_SoTC;
143 GSC_list[OnePieceGrandAdventure] = GSC_OnePieceGrandAdventure;
144 GSC_list[OnePieceGrandBattle] = GSC_OnePieceGrandBattle;
145 GSC_list[ICO] = GSC_ICO;
146 GSC_list[GT4] = GSC_GT4;
147 GSC_list[WildArms4] = GSC_WildArms4;
148 GSC_list[WildArms5] = GSC_WildArms5;
149 GSC_list[Manhunt2] = GSC_Manhunt2;
150 GSC_list[CrashBandicootWoC] = GSC_CrashBandicootWoC;
151 GSC_list[ResidentEvil4] = GSC_ResidentEvil4;
152 GSC_list[Spartan] = GSC_Spartan;
153 GSC_list[AceCombat4] = GSC_AceCombat4;
154 GSC_list[Drakengard2] = GSC_Drakengard2;
155 GSC_list[Tekken5] = GSC_Tekken5;
156 GSC_list[IkkiTousen] = GSC_IkkiTousen;
157 GSC_list[GodOfWar] = GSC_GodOfWar;
158 GSC_list[GodOfWar2] = GSC_GodOfWar2;
159 GSC_list[GiTS] = GSC_GiTS;
160 GSC_list[Onimusha3] = GSC_Onimusha3;
161 GSC_list[TalesOfAbyss] = GSC_TalesOfAbyss;
162 GSC_list[SonicUnleashed] = GSC_SonicUnleashed;
163 GSC_list[Genji] = GSC_Genji;
164 GSC_list[StarOcean3] = GSC_StarOcean3;
165 GSC_list[ValkyrieProfile2] = GSC_ValkyrieProfile2;
166 GSC_list[RadiataStories] = GSC_RadiataStories;
167 }
168
169 // TEXDESTROY_THRESH starts out at 16.
170 VALIDATE_THRESH = 8;
171 conf.mrtdepth = (conf.settings().disable_mrt_depth != 0);
172
173 if (!conf.mrtdepth)
174 ZZLog::WriteLn("Disabling MRT depth writing.");
175 else
176 ZZLog::WriteLn("Enabling MRT depth writing.");
177
178 bool CRCValueChanged = (g_LastCRC != crc);
179
180 g_LastCRC = crc;
181
182 if (crc != 0) ZZLog::WriteLn("Current game CRC is %x.", crc);
183
184 if (CRCValueChanged && (crc != 0))
185 {
186 for (int i = 0; i < GAME_INFO_INDEX; i++)
187 {
188 if (crc_game_list[i].crc == crc)
189 {
190 ZZLog::WriteLn("Found CRC[%x] in crc game list.", crc);
191
192 if (crc_game_list[i].v_thresh > 0)
193 {
194 VALIDATE_THRESH = crc_game_list[i].v_thresh;
195 ZZLog::WriteLn("Setting VALIDATE_THRESH to %d", VALIDATE_THRESH);
196 }
197
198 if (crc_game_list[i].t_thresh > 0)
199 {
200 TEXDESTROY_THRESH = crc_game_list[i].t_thresh;
201 ZZLog::WriteLn("Setting TEXDESTROY_THRESH to %d", TEXDESTROY_THRESH);
202 }
203
204 // FIXME need to check SkipDraw is positive (enabled by users)
205 GetSkipCount_Handler = GSC_list[crc_game_list[i].title];
206
207 if (!conf.disableHacks)
208 {
209 conf.def_hacks._u32 |= crc_game_list[i].flags;
210 ListHacks();
211 }
212 return;
213 }
214 }
215 }
216 ListHacks();
217 }
218
219 void CALLBACK GSsetFrameSkip(int frameskip)
220 {
221 FUNCLOG
222 s_frameskipping |= frameskip;
223
224 if (frameskip && g_nFrameRender > 1)
225 {
226 SetFrameSkip(true);
227 }
228 else if (!frameskip && g_nFrameRender <= 0)
229 {
230 SetFrameSkip(false);
231 }
232 }
233
234 void CALLBACK GSreset()
235 {
236 FUNCLOG
237
238 memset(&gs, 0, sizeof(gs));
239
240 ZZGSStateReset();
241
242 gs.prac = 1;
243 prim = &gs._prim[0];
244 gs.imageTransfer = -1;
245 gs.q = 1;
246 }
247
248 void CALLBACK GSgifSoftReset(u32 mask)
249 {
250 FUNCLOG
251
252 if (mask & 1) memset(&gs.path[0], 0, sizeof(gs.path[0]));
253 if (mask & 2) memset(&gs.path[1], 0, sizeof(gs.path[1]));
254 if (mask & 4) memset(&gs.path[2], 0, sizeof(gs.path[2]));
255
256 gs.imageTransfer = -1;
257 gs.q = 1;
258 }
259
260 s32 CALLBACK GSinit()
261 {
262 FUNCLOG
263
264 ZZLog::Open();
265 ZZLog::WriteLn("Calling GSinit.");
266
267 WriteTempRegs();
268 GSreset();
269
270 ZZLog::WriteLn("GSinit finished.");
271 return 0;
272 }
273
274 __forceinline void InitMisc()
275 {
276 WriteBilinear();
277 WriteAA();
278 InitProfile();
279 InitPath();
280 ResetRegs();
281 }
282
283 s32 CALLBACK GSopen(void *pDsp, char *Title, int multithread)
284 {
285 FUNCLOG
286
287 g_GSMultiThreaded = multithread;
288
289 ZZLog::WriteLn("Calling GSopen.");
290
291 #if defined(_WIN32) && defined(_DEBUG)
292 g_hCurrentThread = GetCurrentThread();
293 #endif
294
295 LoadConfig();
296 strcpy(GLWin.title, Title);
297
298 ZZLog::GS_Log("Using %s:%d.%d.%d.", libraryName, zgsrevision, zgsbuild, zgsminor);
299
300 ZZLog::WriteLn("Creating ZZOgl window.");
301 if ((!GLWin.CreateWindow(pDsp)) || (!ZZCreate(conf.width, conf.height))) return -1;
302
303 ZZLog::WriteLn("Initialization successful.");
304
305 InitMisc();
306 ZZLog::GS_Log("GSopen finished.");
307 return 0;
308 }
309
310 #ifdef USE_GOPEN2
311 s32 CALLBACK GSopen2( void* pDsp, INT32 flags )
312 {
313 FUNCLOG
314
315 bool err;
316
317 g_GSMultiThreaded = true;
318
319 ZZLog::WriteLn("Calling GSopen2.");
320
321 #if defined(_WIN32) && defined(_DEBUG)
322 g_hCurrentThread = GetCurrentThread();
323 #endif
324
325 LoadConfig();
326
327 ZZLog::GS_Log("Using %s:%d.%d.%d.", libraryName, zgsrevision, zgsbuild, zgsminor);
328
329 ZZLog::WriteLn("Capturing ZZOgl window.");
330 if ((!GLWin.GetWindow(pDsp)) || (!ZZCreate2(conf.width, conf.height))) return -1;// Needs to be added.
331
332 ZZLog::WriteLn("Initialization successful.");
333
334 InitMisc();
335 ZZLog::GS_Log("GSopen2 finished.");
336 return 0;
337
338 }
339 #endif
340
341 void CALLBACK GSshutdown()
342 {
343 FUNCLOG
344
345 ZZLog::Close();
346 }
347 void CALLBACK GSclose()
348 {
349 FUNCLOG
350
351 ZZDestroy();
352 GLWin.CloseWindow();
353
354 SaveStateFile = NULL;
355 SaveStateExists = true; // default value
356 g_LastCRC = 0;
357 }
358
359 void CALLBACK GSirqCallback(void (*callback)())
360 {
361 FUNCLOG
362
363 GSirq = callback;
364 }
365
366 void CALLBACK GSwriteCSR(u32 write)
367 {
368 FUNCLOG
369
370 gs.CSRw = write;
371 }
372
373 #ifdef _WIN32
374 #define access _access
375 #endif
376
377 void CALLBACK GSchangeSaveState(int newstate, const char* filename)
378 {
379 FUNCLOG
380
381 char str[255];
382 sprintf(str, "save state %d", newstate);
383 ZZAddMessage(str);
384 CurrentSavestate = newstate;
385
386 SaveStateFile = filename;
387 SaveStateExists = (access(SaveStateFile, 0) == 0);
388 }
389
390 void CALLBACK GSmakeSnapshot(char *path)
391 {
392 FUNCLOG
393
394 FILE *bmpfile;
395 char filename[256];
396 u32 snapshotnr = 0;
397
398 // increment snapshot value & try to get filename
399
400 for (;;)
401 {
402 snapshotnr++;
403
404 sprintf(filename, "%s/snap%03ld.%s", path, snapshotnr, (conf.zz_options.tga_snap) ? "bmp" : "jpg");
405
406 bmpfile = fopen(filename, "rb");
407
408 if (bmpfile == NULL) break;
409
410 fclose(bmpfile);
411 }
412
413 // try opening new snapshot file
414 if ((bmpfile = fopen(filename, "wb")) == NULL)
415 {
416 char strdir[255];
417 sprintf(strdir, "%s", path);
418
419 #ifdef _WIN32
420 CreateDirectory(strdir, NULL);
421 #else
422 mkdir(path, 0777);
423 #endif
424
425 if ((bmpfile = fopen(filename, "wb")) == NULL) return;
426 }
427
428 fclose(bmpfile);
429
430 // get the bits
431 SaveSnapshot(filename);
432 }
433
434 // I'll probably move this somewhere else later, but it's got a ton of dependencies.
435 static __forceinline void SetGSTitle()
436 {
437 char strtitle[256];
438
439 #if !defined(ZEROGS_DEVBUILD)
440 const char* g_pShaders[4] = { "full", "reduced", "accurate", "accurate-reduced" };
441 const char* g_pInterlace[3] = { "interlace 0 |", "interlace 1 |", "" };
442 const char* g_pBilinear[3] = { "", "bilinear |", "forced bilinear |" };
443
444 if (SaveStateFile != NULL && !SaveStateExists)
445 SaveStateExists = (access(SaveStateFile, 0) == 0);
446 else
447 SaveStateExists = true;
448
449 sprintf(strtitle, "ZZ Open GL 0.%d.%d | %.1f fps | %s%s%s savestate %d%s | shaders %s | (%.1f)", zgsbuild, zgsminor, fFPS,
450 g_pInterlace[conf.interlace], g_pBilinear[conf.bilinear], (conf.aa ? s_aa[conf.aa] : ""),
451 CurrentSavestate, (SaveStateExists ? "" : "*"),
452 g_pShaders[g_nPixelShaderVer], (ppf&0xfffff) / (float)UPDATE_FRAMES);
453
454 #else
455 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,
456 100*g_nFramesSkipped / g_nFrame,
457 g_nGenVars / (float)UPDATE_FRAMES, g_nTexVars / (float)UPDATE_FRAMES, g_nAlphaVars / (float)UPDATE_FRAMES,
458 g_nResolve / (float)UPDATE_FRAMES, (ppf&0xfffff) / (float)UPDATE_FRAMES,
459 g_MemTargs.listTargets.size(), g_MemTargs.listClearedTargets.size(), g_TransferredToGPU >> 10);
460
461 //_snprintf(strtitle, 512, "%x %x", *(int*)(g_pbyGSMemory + 256 * 0x3e0c + 4), *(int*)(g_pbyGSMemory + 256 * 0x3e04 + 4));
462 #endif
463
464 // if( g_nFrame > 100 && fFPS > 60.0f ) {
465 // ZZLog::Debug_Log("Set profile.");
466 // g_bWriteProfile = 1;
467 // }
468 GLWin.SetTitle(strtitle);
469 }
470
471 void CALLBACK GSvsync(int interlace)
472 {
473 FUNCLOG
474
475 //ZZLog::GS_Log("Calling GSvsync.");
476
477 static u32 dwTime = timeGetTime();
478 static int nToNextUpdate = 1;
479
480 GL_REPORT_ERRORD();
481
482 g_nRealFrame++;
483
484 // !interlace? Hmmm... Fixme.
485 RenderCRTC(!interlace);
486
487 GLWin.ProcessEvents();
488
489 if (--nToNextUpdate <= 0)
490 {
491 u32 d = timeGetTime();
492 fFPS = UPDATE_FRAMES * 1000.0f / (float)max(d - dwTime, (u32)1);
493 dwTime = d;
494 g_nFrame += UPDATE_FRAMES;
495 SetGSTitle();
496
497 // if( g_nFrame > 100 && fFPS > 60.0f ) {
498 // ZZLog::Debug_Log("Set profile.");
499 // g_bWriteProfile = 1;
500 // }
501
502 if (fFPS < 16)
503 UPDATE_FRAMES = 4;
504 else if (fFPS < 32)
505 UPDATE_FRAMES = 8;
506 else
507 UPDATE_FRAMES = 16;
508
509 nToNextUpdate = UPDATE_FRAMES;
510
511 ppf = 0;
512 g_TransferredToGPU = 0;
513 g_nGenVars = 0;
514 g_nTexVars = 0;
515 g_nAlphaVars = 0;
516 g_nResolve = 0;
517 g_nFramesSkipped = 0;
518 g_SkipFlushFrame = 0;
519 }
520
521 #if defined(ZEROGS_DEVBUILD)
522 if (g_bWriteProfile)
523 {
524 //g_bWriteProfile = 0;
525 DVProfWrite("prof.txt", UPDATE_FRAMES);
526 DVProfClear();
527 }
528
529 #endif
530 GL_REPORT_ERRORD();
531 }
532
533 void CALLBACK GSreadFIFO(u64 *pMem)
534 {
535 FUNCLOG
536
537 //ZZLog::GS_Log("Calling GSreadFIFO.");
538
539 TransferLocalHost((u32*)pMem, 1);
540 }
541
542 void CALLBACK GSreadFIFO2(u64 *pMem, int qwc)
543 {
544 FUNCLOG
545
546 //ZZLog::GS_Log("Calling GSreadFIFO2.");
547
548 TransferLocalHost((u32*)pMem, qwc);
549 }
550
551 int CALLBACK GSsetupRecording(int start, void* pData)
552 {
553 FUNCLOG
554
555 if (start)
556 StartCapture();
557 else
558 StopCapture();
559
560 return 1;
561 }
562
563 s32 CALLBACK GSfreeze(int mode, freezeData *data)
564 {
565 FUNCLOG
566
567 switch (mode)
568 {
569 case FREEZE_LOAD:
570 if (!ZZLoad(data->data)) ZZLog::Error_Log("GS: Bad load format!");
571 g_nRealFrame += 100;
572 break;
573
574 case FREEZE_SAVE:
575 ZZSave(data->data);
576 break;
577
578 case FREEZE_SIZE:
579 data->size = ZZSave(NULL);
580 break;
581
582 default:
583 break;
584 }
585
586 return 0;
587 }

  ViewVC Help
Powered by ViewVC 1.1.22