Pickle's port for this emu
[pcsx_rearmed.git] / plugins / gpu-gles / gpuPlugin.c
CommitLineData
ce879073 1/***************************************************************************\r
2 gpu.c - description\r
3 -------------------\r
4 begin : Sun Mar 08 2009\r
5 copyright : (C) 1999-2009 by Pete Bernert\r
6 email : BlackDove@addcom.de\r
7 ***************************************************************************/\r
8\r
9/***************************************************************************\r
10 * *\r
11 * This program is free software; you can redistribute it and/or modify *\r
12 * it under the terms of the GNU General Public License as published by *\r
13 * the Free Software Foundation; either version 2 of the License, or *\r
14 * (at your option) any later version. See also the license.txt file for *\r
15 * additional informations. *\r
16 * *\r
17 ***************************************************************************/\r
18\r
19//*************************************************************************// \r
20// History of changes:\r
21//\r
22// 2009/03/08 - Pete \r
23// - generic cleanup for the Peops release\r
24//\r
25//*************************************************************************// \r
26\r
27//#include "gpuStdafx.h"\r
28\r
29//#include <mmsystem.h>\r
30\r
31#define _IN_GPU\r
32\r
33#ifdef _WINDOWS\r
34#include "stdafx.h"\r
35#include <stdlib.h>\r
36#include <stdio.h>\r
37#include <stdarg.h>\r
38#include <string.h>\r
39#include <mmsystem.h>\r
40\r
41#include "externals.h"\r
42#include "gpu.h"\r
43#include "draw.h"\r
44#include "prim.h"\r
45#include "texture.h"\r
46#include "fps.h"\r
47#include "resource.h"\r
48#else\r
49#include <stdlib.h>\r
50#include <stdio.h>\r
51#include <stdarg.h>\r
52#include <string.h>\r
53#include "gpuExternals.h"\r
54#include "gpuPlugin.h"\r
55#include "gpuDraw.h"\r
56#include "gpuTexture.h"\r
57#include "gpuFps.h"\r
58#include "gpuPrim.h"\r
59\r
60//#include "NoPic.h"\r
61\r
62#include "gpuStdafx.h"\r
63#endif\r
64\r
65extern void ProcessEvents();\r
66 \r
67short g_m1=255,g_m2=255,g_m3=255;\r
68short DrawSemiTrans=FALSE;\r
69short Ymin;\r
70short Ymax;\r
71\r
72short ly0,lx0,ly1,lx1,ly2,lx2,ly3,lx3; // global psx vertex coords\r
73long GlobalTextAddrX,GlobalTextAddrY,GlobalTextTP;\r
74long GlobalTextREST,GlobalTextABR,GlobalTextPAGE;\r
75\r
76unsigned long dwGPUVersion=0;\r
77int iGPUHeight=512;\r
78int iGPUHeightMask=511;\r
79int GlobalTextIL=0;\r
80int iTileCheat=0;\r
81\r
82////////////////////////////////////////////////////////////////////////\r
83// memory image of the PSX vram\r
84////////////////////////////////////////////////////////////////////////\r
85\r
86u8 *psxVSecure;\r
87u8 *psxVub;\r
88signed char *psxVsb;\r
89unsigned short *psxVuw;\r
90unsigned short *psxVuw_eom;\r
91signed short *psxVsw;\r
92unsigned long *psxVul;\r
93signed long *psxVsl;\r
94\r
95// macro for easy access to packet information\r
96#define GPUCOMMAND(x) ((x>>24) & 0xff)\r
97\r
98GLfloat gl_z=0.0f;\r
99BOOL bNeedInterlaceUpdate=FALSE;\r
100BOOL bNeedRGB24Update=FALSE;\r
101BOOL bChangeWinMode=FALSE;\r
102\r
103#ifdef _WINDOWS\r
104extern HGLRC GLCONTEXT;\r
105#endif\r
106\r
107unsigned long ulStatusControl[256];\r
108\r
109////////////////////////////////////////////////////////////////////////\r
110// global GPU vars\r
111////////////////////////////////////////////////////////////////////////\r
112\r
113static long GPUdataRet;\r
114long lGPUstatusRet;\r
115s8 szDispBuf[64];\r
116\r
117static unsigned long gpuDataM[256];\r
118static u8 gpuCommand = 0;\r
119static long gpuDataC = 0;\r
120static long gpuDataP = 0;\r
121\r
122VRAMLoad_t VRAMWrite;\r
123VRAMLoad_t VRAMRead;\r
124int iDataWriteMode;\r
125int iDataReadMode;\r
126\r
127long lClearOnSwap;\r
128long lClearOnSwapColor;\r
129BOOL bSkipNextFrame = FALSE;\r
130int iColDepth;\r
131BOOL bChangeRes;\r
132BOOL bWindowMode;\r
133int iWinSize;\r
134\r
135// possible psx display widths\r
136short dispWidths[8] = {256,320,512,640,368,384,512,640};\r
137\r
138PSXDisplay_t PSXDisplay;\r
139PSXDisplay_t PreviousPSXDisplay;\r
140TWin_t TWin;\r
141short imageX0,imageX1;\r
142short imageY0,imageY1;\r
143BOOL bDisplayNotSet = TRUE;\r
144GLuint uiScanLine=0;\r
145int iUseScanLines=0;\r
146long lSelectedSlot=0;\r
147u8 * pGfxCardScreen=0;\r
148int iBlurBuffer=0;\r
149int iScanBlend=0;\r
150int iRenderFVR=0;\r
151int iNoScreenSaver=0;\r
152unsigned long ulGPUInfoVals[16];\r
153int iFakePrimBusy = 0;\r
154int iRumbleVal = 0;\r
155int iRumbleTime = 0;\r
156\r
157////////////////////////////////////////////////////////////////////////\r
158// stuff to make this a true PDK module\r
159////////////////////////////////////////////////////////////////////////\r
160\r
161#ifdef _WINDOWS\r
162s8 * CALLBACK PSEgetLibName(void)\r
163{\r
164 return "name";\r
165}\r
166\r
167unsigned long CALLBACK PSEgetLibType(void)\r
168{\r
169 return 1;\r
170}\r
171\r
172unsigned long CALLBACK PSEgetLibVersion(void)\r
173{\r
174 return 1<<16|1<<8|1;\r
175}\r
176#endif\r
177\r
178////////////////////////////////////////////////////////////////////////\r
179// snapshot funcs (saves screen to bitmap / text infos into file)\r
180////////////////////////////////////////////////////////////////////////\r
181\r
182void ResizeWindow()\r
183{\r
184 rRatioRect.left = rRatioRect.top=0;\r
185 rRatioRect.right = iResX;\r
186 rRatioRect.bottom = iResY;\r
187 glViewport(rRatioRect.left, // init viewport by ratio rect\r
188 iResY-(rRatioRect.top+rRatioRect.bottom),\r
189 rRatioRect.right, \r
190 rRatioRect.bottom); \r
191 \r
192 glScissor(0, 0, iResX, iResY); // init clipping (fullscreen)\r
193 glEnable(GL_SCISSOR_TEST); \r
194\r
195#ifndef OWNSCALE\r
196 glMatrixMode(GL_TEXTURE); // init psx tex sow and tow if not "ownscale"\r
197 glLoadIdentity();\r
198 glScalef(1.0f/255.99f,1.0f/255.99f,1.0f); // geforce precision hack\r
199#endif \r
200\r
201 glMatrixMode(GL_PROJECTION); // init projection with psx resolution\r
202 glLoadIdentity();\r
203 glOrtho(0,PSXDisplay.DisplayMode.x,\r
204 PSXDisplay.DisplayMode.y, 0, -1, 1);\r
205 if (bKeepRatio)\r
206 SetAspectRatio();\r
207}\r
208\r
209s8 * GetConfigInfos(int hW)\r
210{\r
211#ifdef _WINDOWS\r
212 HDC hdc;HGLRC hglrc;\r
213#endif\r
214 s8 szO[2][4]={"off","on "};\r
215 s8 szTxt[256];\r
216 s8 * pB=(s8 *)malloc(32767);\r
217/*\r
218 if(!pB) return NULL;\r
219 *pB=0;\r
220 //----------------------------------------------------//\r
221 strcat(pB,szTxt);\r
222 strcat(pB,szTxt);\r
223#ifdef _WINDOWS\r
224 if(hW)\r
225 {\r
226 hdc = GetDC(hW);\r
227 bSetupPixelFormat(hdc);\r
228 hglrc = wglCreateContext(hdc);\r
229 wglMakeCurrent(hdc, hglrc);\r
230 }\r
231#endif\r
232 sprintf(szTxt,"Card vendor: %s\r\n",(char *)glGetString(GL_VENDOR));\r
233 strcat(pB,szTxt);\r
234 sprintf(szTxt,"GFX card: %s\r\n",(char *)glGetString(GL_RENDERER));\r
235 strcat(pB,szTxt);\r
236 sprintf(szTxt,"OGL version: %s\r\n\r\n",(char *)glGetString(GL_VERSION));\r
237 strcat(pB,szTxt);\r
238 //strcat(pB,(s8 *)glGetString(GL_EXTENSIONS));\r
239 //strcat(pB,"\r\n\r\n");\r
240\r
241#ifdef _WINDOWS\r
242 if(hW)\r
243 {\r
244 wglMakeCurrent(NULL, NULL);\r
245 wglDeleteContext(hglrc);\r
246 ReleaseDC(hW,hdc);\r
247 }\r
248 //----------------------------------------------------//\r
249#endif\r
250 if(hW && bWindowMode)\r
251 sprintf(szTxt,"Resolution/Color:\r\n- %dx%d ",LOWORD(iWinSize),HIWORD(iWinSize));\r
252 else\r
253 sprintf(szTxt,"Resolution/Color:\r\n- %dx%d ",iResX,iResY);\r
254 strcat(pB,szTxt);\r
255 if(bWindowMode) sprintf(szTxt,"Window mode\r\n");\r
256 else\r
257 {\r
258 sprintf(szTxt,"Fullscreen ");\r
259 strcat(pB,szTxt);\r
260 if(bChangeRes) sprintf(szTxt,"- Desktop changing [%d Bit]\r\n",iColDepth);\r
261 else sprintf(szTxt,"- NO desktop changing\r\n");\r
262 } \r
263 strcat(pB,szTxt);\r
264\r
265// if(iForceVSync>=0) sprintf(szTxt,"- V-Sync: %s\r\n",szO[iForceVSync]);\r
266// else strcpy(szTxt,"- V-Sync: Driver\r\n");\r
267 strcat(pB,szTxt); \r
268 sprintf(szTxt,"- Keep psx aspect ratio: %s\r\n\r\n",szO[bKeepRatio]);\r
269 strcat(pB,szTxt);\r
270 //----------------------------------------------------//\r
271 strcpy(szTxt,"Textures:\r\n- ");\r
272/*! if(iTexQuality==0) strcat(szTxt,"Default");\r
273 else if(iTexQuality==1) strcat(szTxt,"R4G4B4A4");\r
274 else if(iTexQuality==2) strcat(szTxt,"R5G5B5A1");\r
275 else if(iTexQuality==3) strcat(szTxt,"R8G8A8A8");\r
276 else if(iTexQuality==4) strcat(szTxt,"B8G8R8A8");\r
277 if(!hW && bGLExt) strcat(szTxt," (packed pixels)\r\n");\r
278 else strcat(szTxt,"\r\n");\r
279 strcat(pB,szTxt);\r
280 if(!hW)\r
281 {\r
282 sprintf(szTxt,"- Filtering: %d - edge clamping ",iFilterType);\r
283 if(iClampType==GL_TO_EDGE_CLAMP) strcat(szTxt,"supported\r\n");\r
284 else strcat(szTxt,"NOT supported\r\n");\r
285 }\r
286 else sprintf(szTxt,"- iFiltering: %d\r\n",iFilterType);\r
287 strcat(pB,szTxt);\r
288 sprintf(szTxt,"- Hi-Res textures: %d\r\n",iHiResTextures);\r
289 strcat(pB,szTxt); \r
290 if(!hW)\r
291 {\r
292 sprintf(szTxt,"- Palettized tex windows: %s\r\n",szO[iUsePalTextures]);\r
293 strcat(pB,szTxt); \r
294 }\r
295 !*/\r
296 /*sprintf(szTxt,"- VRam size: %d MBytes",iVRamSize);\r
297 if(!hW)\r
298 sprintf(szTxt+strlen(szTxt)," - %d textures usable\r\n\r\n",iSortTexCnt);\r
299 else strcat(szTxt,"\r\n\r\n");\r
300 strcat(pB,szTxt);\r
301 //----------------------------------------------------//\r
302 sprintf(szTxt,"Framerate:\r\n- FPS limitation: %s\r\n",szO[bUseFrameLimit]);\r
303 strcat(pB,szTxt);\r
304 sprintf(szTxt,"- Frame skipping: %s\r\n",szO[bUseFrameSkip]);\r
305 strcat(pB,szTxt);\r
306 if(iFrameLimit==2)\r
307 strcpy(szTxt,"- FPS limit: Auto\r\n\r\n");\r
308 else sprintf(szTxt,"- FPS limit: %.1f\r\n\r\n",fFrameRate);\r
309 strcat(pB,szTxt);\r
310 //----------------------------------------------------//\r
311 sprintf(szTxt,"Compatibility:\r\n- Offscreen drawing: %d\r\n",iOffscreenDrawing);\r
312 strcat(pB,szTxt);\r
313 sprintf(szTxt,"- Framebuffer texture: %d",iFrameTexType);\r
314 if(!hW && iFrameTexType==2)\r
315 {\r
316 if(gTexFrameName) strcat(szTxt," - texture created\r\n");\r
317 else strcat(szTxt," - not used yet\r\n");\r
318 }\r
319 else strcat(szTxt,"\r\n");\r
320 strcat(pB,szTxt);\r
321 sprintf(szTxt,"- Framebuffer access: %d\r\n",iFrameReadType);\r
322 strcat(pB,szTxt);\r
323// sprintf(szTxt,"- Alpha multipass: %s\r\n",szO[bOpaquePass]);\r
324 strcat(pB,szTxt);\r
325 sprintf(szTxt,"- Mask bit: %s\r\n",szO[iUseMask]);\r
326 strcat(pB,szTxt);\r
327 //sprintf(szTxt,"- Advanced blending: %s",szO[bAdvancedBlend]);\r
328 //if(!hW && bAdvancedBlend)\r
329// {\r
330// if(bGLBlend) strcat(szTxt," (hardware)\r\n");\r
331// else strcat(szTxt," (software)\r\n");\r
332// }\r
333 strcat(szTxt,"\r\n");\r
334 strcat(pB,szTxt);\r
335\r
336 if(!hW)\r
337 {\r
338 strcpy(szTxt,"- Subtractive blending: ");\r
339// if(glBlendEquationEXTEx)\r
340// {\r
341// if(bUseMultiPass) strcat(szTxt,"supported, but not used!");\r
342// else strcat(szTxt,"activated");\r
343// }\r
344 strcat(szTxt," NOT supported!");\r
345 strcat(szTxt,"\r\n\r\n");\r
346 }\r
347 else strcpy(szTxt,"\r\n");\r
348 \r
349 strcat(pB,szTxt); \r
350 //----------------------------------------------------//\r
351 sprintf(szTxt,"Misc:\r\n- Scanlines: %s",szO[iUseScanLines]);\r
352 strcat(pB,szTxt);\r
353 if(iUseScanLines) sprintf(szTxt," [%d]\r\n",iScanBlend);\r
354 else strcpy(szTxt,"\r\n");\r
355 strcat(pB,szTxt);\r
356// sprintf(szTxt,"- Line mode: %s\r\n",szO[bUseLines]);\r
357 strcat(pB,szTxt);\r
358// sprintf(szTxt,"- Line AA: %s\r\n",szO[bUseAntiAlias]);\r
359// fwrite(szTxt,lstrlen(szTxt),1,txtfile);\r
360 sprintf(szTxt,"- Unfiltered FB: %s\r\n",szO[bUseFastMdec]);\r
361 strcat(pB,szTxt);\r
362 sprintf(szTxt,"- 15 bit FB: %s\r\n",szO[bUse15bitMdec]);\r
363 strcat(pB,szTxt);\r
364 sprintf(szTxt,"- Dithering: %s\r\n",szO[bDrawDither]);\r
365 strcat(pB,szTxt);\r
366 sprintf(szTxt,"- Screen smoothing: %s",szO[iBlurBuffer]);\r
367 strcat(pB,szTxt);\r
368 if(!hW && iBlurBuffer) \r
369 {\r
370 if(gTexBlurName) strcat(pB," - supported\r\n");\r
371 else strcat(pB," - not supported\r\n");\r
372 }\r
373 else strcat(pB,"\r\n");\r
374 sprintf(szTxt,"- Game fixes: %s [%08lx]\r\n",szO[bUseFixes],dwCfgFixes);\r
375 strcat(pB,szTxt);\r
376 //----------------------------------------------------//\r
377*/ return pB;\r
378}\r
379\r
380////////////////////////////////////////////////////////////////////////\r
381// save text infos to file\r
382////////////////////////////////////////////////////////////////////////\r
383\r
384void DoTextSnapShot(int iNum)\r
385{\r
386}\r
387\r
388////////////////////////////////////////////////////////////////////////\r
389// saves screen bitmap to file\r
390////////////////////////////////////////////////////////////////////////\r
391\r
392void DoSnapShot(void)\r
393{\r
394} \r
395\r
396#ifdef _WINDOWS\r
397void CALLBACK GPUmakeSnapshot(void)\r
398#else\r
7eadbf88 399void CALLBACK GPUmakeSnapshot(void)\r
ce879073 400#endif\r
401{\r
402 //bSnapShot = TRUE;\r
403} \r
404\r
405////////////////////////////////////////////////////////////////////////\r
406// GPU INIT... here starts it all (first func called by emu)\r
407////////////////////////////////////////////////////////////////////////\r
408\r
409#ifdef _WINDOWS\r
410long CALLBACK GPUinit()\r
411#else\r
7eadbf88 412long CALLBACK GPUinit()\r
ce879073 413#endif\r
414{\r
415memset(ulStatusControl,0,256*sizeof(unsigned long));\r
416\r
417#ifdef _WINDOWS\r
418iResX=240;iResY=320;\r
419#endif\r
420bChangeRes=FALSE;\r
421#ifdef _WINDOWS\r
422bWindowMode=TRUE;\r
423#else\r
424bWindowMode=FALSE;\r
425#endif \r
426#ifdef _WINDOWS\r
427iWinSize=MAKELONG(iResX,iResY);\r
428#endif\r
429\r
430bKeepRatio = TRUE;\r
431// different ways of accessing PSX VRAM\r
432\r
433psxVSecure=(u8 *)malloc((iGPUHeight*2)*1024 + (1024*1024)); // always alloc one extra MB for soft drawing funcs security\r
434if(!psxVSecure) return -1;\r
435\r
436psxVub=psxVSecure+512*1024; // security offset into double sized psx vram!\r
437psxVsb=(signed char *)psxVub;\r
438psxVsw=(signed short *)psxVub;\r
439psxVsl=(signed long *)psxVub;\r
440psxVuw=(unsigned short *)psxVub;\r
441psxVul=(unsigned long *)psxVub;\r
442\r
443psxVuw_eom=psxVuw+1024*iGPUHeight; // pre-calc of end of vram\r
444\r
445memset(psxVSecure,0x00,(iGPUHeight*2)*1024 + (1024*1024));\r
446memset(ulGPUInfoVals,0x00,16*sizeof(unsigned long));\r
447\r
448InitFrameCap(); // init frame rate stuff\r
449\r
450PSXDisplay.RGB24 = 0; // init vars\r
451PreviousPSXDisplay.RGB24= 0;\r
452PSXDisplay.Interlaced = 0;\r
453PSXDisplay.InterlacedTest=0;\r
454PSXDisplay.DrawOffset.x = 0;\r
455PSXDisplay.DrawOffset.y = 0;\r
456PSXDisplay.DrawArea.x0 = 0;\r
457PSXDisplay.DrawArea.y0 = 0;\r
458PSXDisplay.DrawArea.x1 = 320;\r
459PSXDisplay.DrawArea.y1 = 240;\r
460PSXDisplay.DisplayMode.x= 320;\r
461PSXDisplay.DisplayMode.y= 240;\r
462PSXDisplay.Disabled = FALSE;\r
463PreviousPSXDisplay.Range.x0 =0;\r
464PreviousPSXDisplay.Range.x1 =0;\r
465PreviousPSXDisplay.Range.y0 =0;\r
466PreviousPSXDisplay.Range.y1 =0;\r
467PSXDisplay.Range.x0=0;\r
468PSXDisplay.Range.x1=0;\r
469PSXDisplay.Range.y0=0;\r
470PSXDisplay.Range.y1=0;\r
471PreviousPSXDisplay.DisplayPosition.x = 1;\r
472PreviousPSXDisplay.DisplayPosition.y = 1;\r
473PSXDisplay.DisplayPosition.x = 1;\r
474PSXDisplay.DisplayPosition.y = 1;\r
475PreviousPSXDisplay.DisplayModeNew.y=0;\r
476PSXDisplay.Double=1;\r
477GPUdataRet=0x400;\r
478\r
479PSXDisplay.DisplayModeNew.x=0;\r
480PSXDisplay.DisplayModeNew.y=0;\r
481\r
482//PreviousPSXDisplay.Height = PSXDisplay.Height = 239;\r
483\r
484iDataWriteMode = DR_NORMAL;\r
485\r
486// Reset transfer values, to prevent mis-transfer of data\r
487memset(&VRAMWrite,0,sizeof(VRAMLoad_t));\r
488memset(&VRAMRead,0,sizeof(VRAMLoad_t));\r
489\r
490// device initialised already !\r
491//lGPUstatusRet = 0x74000000;\r
492\r
493STATUSREG = 0x14802000;\r
494GPUIsIdle;\r
495GPUIsReadyForCommands;\r
496\r
497return 0;\r
498} \r
499\r
500\r
501////////////////////////////////////////////////////////////////////////\r
502// GPU OPEN: funcs to open up the gpu display (Windows)\r
503////////////////////////////////////////////////////////////////////////\r
504\r
505#ifdef _WINDOWS\r
506\r
507void ChangeDesktop() // change destop resolution\r
508{\r
509 DEVMODE dv;long lRes,iTry=0; \r
510\r
511 while(iTry<10) // keep on hammering...\r
512 {\r
513 memset(&dv,0,sizeof(DEVMODE));\r
514 dv.dmSize=sizeof(DEVMODE);\r
515 dv.dmBitsPerPel=iColDepth;\r
516 dv.dmPelsWidth=iResX;\r
517 dv.dmPelsHeight=iResY;\r
518\r
519 dv.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;\r
520\r
521 lRes=ChangeDisplaySettings(&dv,0); // ...hammering the anvil\r
522\r
523 if(lRes==DISP_CHANGE_SUCCESSFUL) return;\r
524 iTry++;Sleep(10);\r
525 }\r
526}\r
527\r
528////////////////////////////////////////////////////////////////////////\r
529// OPEN interface func: attention! \r
530// some emus are calling this func in their main Window thread,\r
531// but all other interface funcs (to draw stuff) in a different thread!\r
532// that's a problem, since OGL is thread safe! Therefore we cannot \r
533// initialize the OGL stuff right here, we simply set a "bIsFirstFrame = TRUE"\r
534// flag, to initialize OGL on the first real draw call.\r
535// btw, we also call this open func ourselfes, each time when the user \r
536// is changing between fullscreen/window mode (ENTER key)\r
537// btw part 2: in windows the plugin gets the window handle from the\r
538// main emu, and doesn't create it's own window (if it would do it,\r
539// some PAD or SPU plugins would not work anymore)\r
540////////////////////////////////////////////////////////////////////////\r
541\r
542HMENU hPSEMenu=NULL;\r
543\r
544long CALLBACK GPUopen(HWND hwndGPU) \r
545#else\r
7eadbf88 546long CALLBACK GPUopen(int hwndGPU)\r
ce879073 547#endif\r
548{\r
549 #ifdef _WINDOWS\r
550 HDC hdc;RECT r;DEVMODE dv;\r
551\r
552 hWWindow = hwndGPU; // store hwnd globally\r
553 #endif\r
554 // InitKeyHandler(); // init key handler (subclass window)\r
555\r
556\r
557\r
ce879073 558 #ifdef _WINDOWS\r
559 iResX=240;iResY=320;\r
560 #endif\r
7eadbf88 561#ifdef MAEMO_CHANGES\r
562 iResX=640;iResY=480;\r
563#endif\r
564 iColDepth=8;\r
ce879073 565 bChangeRes=FALSE;\r
566 #ifdef _WINDOWS\r
567 bWindowMode=TRUE;\r
568 #else\r
569 bWindowMode=FALSE;\r
570 #endif \r
571 bFullVRam=FALSE;\r
572 iFilterType=0;\r
573 // bAdvancedBlend=FALSE;\r
574 bDrawDither=FALSE;\r
575 // bUseLines=FALSE;\r
576 bUseFrameLimit=FALSE;\r
577 bUseFrameSkip=FALSE;\r
578 iFrameLimit=0;\r
579 fFrameRate=50.0f;\r
580 iOffscreenDrawing=0;\r
581 //bOpaquePass=FALSE;\r
582 //bUseAntiAlias=FALSE;\r
583 //iTexQuality=0;\r
584 #ifdef _WINDOWS\r
585 iWinSize=MAKELONG(iResX,iResY);\r
586 #endif\r
587 iUseMask=0;\r
588 iZBufferDepth=0;\r
589 bUseFastMdec=FALSE;\r
590 bUse15bitMdec=FALSE;\r
591 dwCfgFixes=0;\r
592 bUseFixes=FALSE;\r
593 // iUseScanLines=0;\r
594 iFrameTexType=0;\r
595 iFrameReadType=0;\r
596 //iShowFPS=0;\r
597 bKeepRatio=TRUE;\r
598 iScanBlend=0;\r
599 iVRamSize=0;\r
600 iTexGarbageCollection=0;\r
601 iBlurBuffer=0; \r
602 //iHiResTextures=0;\r
603 iNoScreenSaver=0;\r
604 //iForceVSync=0;\r
605\r
606\r
607\r
608#ifdef _WINDOWS\r
609 memset(&dv,0,sizeof(DEVMODE));\r
610 dv.dmSize=sizeof(DEVMODE);\r
611 EnumDisplaySettings(NULL,ENUM_CURRENT_SETTINGS,&dv);\r
612#endif\r
613 bIsFirstFrame = TRUE; // flag: we have to init OGL later in windows!\r
614\r
615#ifdef _WINDOWS\r
616 if(bWindowMode) // win mode?\r
617 {\r
618 DWORD dw=GetWindowLong(hWWindow, GWL_STYLE); // -> adjust wnd style (owndc needed by some stupid ogl drivers)\r
619 dw&=~WS_THICKFRAME;\r
620 dw|=WS_BORDER|WS_CAPTION|CS_OWNDC;\r
621 SetWindowLong(hWWindow, GWL_STYLE, dw);\r
622\r
623 hPSEMenu=GetMenu(hWWindow); // -> hide emu menu (if any)\r
624 if(hPSEMenu!=NULL) SetMenu(hWWindow,NULL);\r
625\r
626 iResX=LOWORD(iWinSize);iResY=HIWORD(iWinSize);\r
627 ShowWindow(hWWindow,SW_SHOWNORMAL);\r
628\r
629 MoveWindow(hWWindow, // -> center wnd\r
630 GetSystemMetrics(SM_CXFULLSCREEN)/2-iResX/2,\r
631 GetSystemMetrics(SM_CYFULLSCREEN)/2-iResY/2,\r
632 iResX+GetSystemMetrics(SM_CXFIXEDFRAME)+3,\r
633 iResY+GetSystemMetrics(SM_CYFIXEDFRAME)+GetSystemMetrics(SM_CYCAPTION)+3,\r
634 TRUE);\r
635 UpdateWindow(hWWindow); // -> let windows do some update\r
636\r
637 if(dv.dmBitsPerPel==16 || dv.dmBitsPerPel==32) // -> overwrite user color info with desktop color info\r
638 iColDepth=dv.dmBitsPerPel;\r
639 }\r
640 else // fullscreen mode:\r
641 {\r
642 if(dv.dmBitsPerPel!=(unsigned int)iColDepth || // -> check, if we have to change resolution\r
643 dv.dmPelsWidth !=(unsigned int)iResX ||\r
644 dv.dmPelsHeight!=(unsigned int)iResY)\r
645 bChangeRes=TRUE; else bChangeRes=FALSE;\r
646\r
647 if(bChangeRes) ChangeDesktop(); // -> change the res (had to do an own func because of some MS 'optimizations')\r
648\r
649 SetWindowLong(hWWindow, GWL_STYLE, CS_OWNDC); // -> adjust wnd style as well (to be sure)\r
650 \r
651 hPSEMenu=GetMenu(hWWindow); // -> hide menu\r
652 if(hPSEMenu!=NULL) SetMenu(hWWindow,NULL);\r
653 ShowWindow(hWWindow,SW_SHOWMAXIMIZED); // -> max mode\r
654 }\r
655#endif\r
656 rRatioRect.left = rRatioRect.top=0;\r
657 rRatioRect.right = iResX;\r
658 rRatioRect.bottom = iResY;\r
659\r
660#ifdef _WINDOWS\r
661 r.left=r.top=0;r.right=iResX;r.bottom=iResY; // hack for getting a clean black window until OGL gets initialized\r
662 hdc = GetDC(hWWindow);\r
663 FillRect(hdc,&r,(HBRUSH)GetStockObject(BLACK_BRUSH));\r
664 bSetupPixelFormat(hdc);\r
665 ReleaseDC(hWWindow,hdc);\r
666#endif\r
667 bDisplayNotSet = TRUE; \r
668 bSetClip=TRUE;\r
669\r
670 SetFixes(); // setup game fixes\r
671\r
672 InitializeTextureStore(); // init texture mem\r
673\r
674// lGPUstatusRet = 0x74000000;\r
675\r
676// with some emus, we could do the OGL init right here... oh my\r
677// if(bIsFirstFrame) GLinitialize();\r
678\r
679 return 0;\r
680}\r
681\r
682////////////////////////////////////////////////////////////////////////\r
683// close\r
684////////////////////////////////////////////////////////////////////////\r
685\r
686#ifdef _WINDOWS\r
687long CALLBACK GPUclose() // WINDOWS CLOSE\r
688{\r
689// ExitKeyHandler();\r
690\r
691 GLcleanup(); // close OGL\r
692\r
693 if(bChangeRes) // change res back\r
694 ChangeDisplaySettings(NULL,0);\r
695\r
696 if(hPSEMenu) // set menu again\r
697 SetMenu(hWWindow,hPSEMenu);\r
698\r
699 if(pGfxCardScreen) free(pGfxCardScreen); // free helper memory\r
700 pGfxCardScreen=0;\r
701\r
702// if(iNoScreenSaver) EnableScreenSaver(TRUE); // enable screen saver again\r
703\r
704 return 0;\r
705}\r
706\r
707#else\r
708\r
7eadbf88 709long GPUclose() // LINUX CLOSE\r
ce879073 710{\r
711 GLcleanup(); // close OGL\r
712\r
713 if(pGfxCardScreen) free(pGfxCardScreen); // free helper memory\r
714 pGfxCardScreen=0;\r
715\r
716// osd_close_display(); // destroy display\r
717\r
718 return 0;\r
719}\r
720#endif\r
721\r
722////////////////////////////////////////////////////////////////////////\r
723// I shot the sheriff... last function called from emu \r
724////////////////////////////////////////////////////////////////////////\r
725\r
726#ifdef _WINDOWS\r
727long CALLBACK GPUshutdown()\r
728#else\r
7eadbf88 729long CALLBACK GPUshutdown()\r
ce879073 730#endif\r
731{\r
732 if(psxVSecure) free(psxVSecure); // kill emulated vram memory\r
733 psxVSecure=0;\r
734\r
735 return 0;\r
736}\r
737\r
738////////////////////////////////////////////////////////////////////////\r
739// paint it black: simple func to clean up optical border garbage\r
740////////////////////////////////////////////////////////////////////////\r
741\r
742void PaintBlackBorders(void)\r
743{\r
744 short s;\r
745\r
746 glDisable(GL_SCISSOR_TEST);\r
747 if(bTexEnabled) {glDisable(GL_TEXTURE_2D);bTexEnabled=FALSE;}\r
748 if(bOldSmoothShaded) {glShadeModel(GL_FLAT);bOldSmoothShaded=FALSE;}\r
749 if(bBlendEnable) {glDisable(GL_BLEND);bBlendEnable=FALSE;}\r
750 glDisable(GL_ALPHA_TEST);\r
751\r
752 glEnable(GL_ALPHA_TEST);\r
753 glEnable(GL_SCISSOR_TEST);\r
754}\r
755\r
756////////////////////////////////////////////////////////////////////////\r
757// helper to draw scanlines\r
758////////////////////////////////////////////////////////////////////////\r
759\r
760__inline void XPRIMdrawTexturedQuad(OGLVertex* vertex1, OGLVertex* vertex2, \r
761 OGLVertex* vertex3, OGLVertex* vertex4) \r
762{\r
763\r
764}\r
765\r
766////////////////////////////////////////////////////////////////////////\r
767// scanlines\r
768////////////////////////////////////////////////////////////////////////\r
769\r
770void SetScanLines(void)\r
771{\r
772}\r
773\r
774////////////////////////////////////////////////////////////////////////\r
775// blur, babe, blur (heavy performance hit for a so-so fullscreen effect)\r
776////////////////////////////////////////////////////////////////////////\r
777\r
778\r
779////////////////////////////////////////////////////////////////////////\r
780// Update display (swap buffers)... called in interlaced mode on \r
781// every emulated vsync, otherwise whenever the displayed screen region\r
782// has been changed\r
783////////////////////////////////////////////////////////////////////////\r
784\r
785int iLastRGB24=0; // special vars for checking when to skip two display updates\r
786int iSkipTwo=0;\r
7eadbf88 787void GPUvSinc(void){\r
ce879073 788updateDisplay();\r
789}\r
790void updateDisplay(void) // UPDATE DISPLAY\r
791{\r
792BOOL bBlur=FALSE;\r
793\r
794#ifdef _WINDOWS\r
795HDC hdc=GetDC(hWWindow); // windows:\r
796wglMakeCurrent(hdc,GLCONTEXT); // -> make context current again\r
797#endif\r
798\r
799bFakeFrontBuffer=FALSE;\r
800bRenderFrontBuffer=FALSE;\r
801\r
802if(iRenderFVR) // frame buffer read fix mode still active?\r
803 {\r
804 iRenderFVR--; // -> if some frames in a row without read access: turn off mode\r
805 if(!iRenderFVR) bFullVRam=FALSE;\r
806 }\r
807\r
808if(iLastRGB24 && iLastRGB24!=PSXDisplay.RGB24+1) // (mdec) garbage check\r
809 {\r
810 iSkipTwo=2; // -> skip two frames to avoid garbage if color mode changes\r
811 }\r
812iLastRGB24=0;\r
813\r
814if(PSXDisplay.RGB24)// && !bNeedUploadAfter) // (mdec) upload wanted?\r
815 {\r
816 PrepareFullScreenUpload(-1);\r
817 UploadScreen(PSXDisplay.Interlaced); // -> upload whole screen from psx vram\r
818 bNeedUploadTest=FALSE;\r
819 bNeedInterlaceUpdate=FALSE;\r
820 bNeedUploadAfter=FALSE;\r
821 bNeedRGB24Update=FALSE;\r
822 }\r
823else\r
824if(bNeedInterlaceUpdate) // smaller upload?\r
825 {\r
826 bNeedInterlaceUpdate=FALSE;\r
827 xrUploadArea=xrUploadAreaIL; // -> upload this rect\r
828 UploadScreen(TRUE);\r
829 }\r
830\r
831if(dwActFixes&512) bCheckFF9G4(NULL); // special game fix for FF9 \r
832\r
833if(PreviousPSXDisplay.Range.x0|| // paint black borders around display area, if needed\r
834 PreviousPSXDisplay.Range.y0)\r
835 PaintBlackBorders();\r
836\r
837if(PSXDisplay.Disabled) // display disabled?\r
838 {\r
839 // moved here\r
840 glDisable(GL_SCISSOR_TEST); \r
841 glClearColor(0,0,0,128); // -> clear whole backbuffer\r
842 glClear(uiBufferBits);\r
843 glEnable(GL_SCISSOR_TEST); \r
844 gl_z=0.0f;\r
845 bDisplayNotSet = TRUE;\r
846 }\r
847\r
848if(iSkipTwo) // we are in skipping mood?\r
849 {\r
850 iSkipTwo--;\r
851 iDrawnSomething=0; // -> simply lie about something drawn\r
852 }\r
853\r
854//if(iBlurBuffer && !bSkipNextFrame) // "blur display" activated?\r
855// {BlurBackBuffer();bBlur=TRUE;} // -> blur it\r
856\r
857// if(iUseScanLines) SetScanLines(); // "scan lines" activated? do it\r
858\r
859// if(usCursorActive) ShowGunCursor(); // "gun cursor" wanted? show 'em\r
860\r
861if(dwActFixes&128) // special FPS limitation mode?\r
862 {\r
863 if(bUseFrameLimit) PCFrameCap(); // -> ok, do it\r
864// if(bUseFrameSkip || ulKeybits&KEY_SHOWFPS) \r
865 PCcalcfps(); \r
866 }\r
867\r
868// if(gTexPicName) DisplayPic(); // some gpu info picture active? display it\r
869\r
870// if(bSnapShot) DoSnapShot(); // snapshot key pressed? cheeeese :)\r
871\r
872// if(ulKeybits&KEY_SHOWFPS) // wanna see FPS?\r
873 {\r
874// sprintf(szDispBuf,"%06.1f",fps_cur);\r
875// DisplayText(); // -> show it\r
876 }\r
877\r
878//----------------------------------------------------//\r
879// main buffer swapping (well, or skip it)\r
880\r
881if(bUseFrameSkip) // frame skipping active ?\r
882 {\r
883 if(!bSkipNextFrame) \r
884 {\r
885 if(iDrawnSomething)\r
886#ifdef _WINDOWS\r
887 SwapBuffers(wglGetCurrentDC()); // -> to skip or not to skip\r
888#else\r
889 eglSwapBuffers(display,surface);\r
890#endif\r
891 }\r
892 if(dwActFixes&0x180) // -> special old frame skipping: skip max one in a row\r
893 {\r
894 if((fps_skip < fFrameRateHz) && !(bSkipNextFrame)) \r
895 {bSkipNextFrame = TRUE; fps_skip=fFrameRateHz;}\r
896 else bSkipNextFrame = FALSE;\r
897 }\r
898 else FrameSkip();\r
899 }\r
900else // no skip ?\r
901 {\r
902 if(iDrawnSomething)\r
903#ifdef _WINDOWS\r
904 SwapBuffers(wglGetCurrentDC()); // -> swap\r
905#else\r
906 eglSwapBuffers(display,surface);\r
907#endif\r
908 }\r
909\r
910iDrawnSomething=0;\r
911\r
912//----------------------------------------------------//\r
913\r
914if(lClearOnSwap) // clear buffer after swap?\r
915 {\r
916 GLclampf g,b,r;\r
917\r
918 if(bDisplayNotSet) // -> set new vals\r
919 SetOGLDisplaySettings(1);\r
920\r
921 g=((GLclampf)GREEN(lClearOnSwapColor))/255.0f; // -> get col\r
922 b=((GLclampf)BLUE(lClearOnSwapColor))/255.0f;\r
923 r=((GLclampf)RED(lClearOnSwapColor))/255.0f;\r
924 \r
925 glDisable(GL_SCISSOR_TEST); \r
926 glClearColor(r,g,b,128); // -> clear \r
927 glClear(uiBufferBits);\r
928 glEnable(GL_SCISSOR_TEST); \r
929 lClearOnSwap=0; // -> done\r
930 }\r
931else \r
932 {\r
933// if(bBlur) UnBlurBackBuffer(); // unblur buff, if blurred before\r
934\r
935 if(iZBufferDepth) // clear zbuffer as well (if activated)\r
936 {\r
937 glDisable(GL_SCISSOR_TEST); \r
938 glClear(GL_DEPTH_BUFFER_BIT);\r
939 glEnable(GL_SCISSOR_TEST); \r
940 }\r
941 }\r
942gl_z=0.0f;\r
943\r
944//----------------------------------------------------//\r
945// additional uploads immediatly after swapping\r
946\r
947if(bNeedUploadAfter) // upload wanted?\r
948 {\r
949 bNeedUploadAfter=FALSE; \r
950 bNeedUploadTest=FALSE;\r
951 UploadScreen(-1); // -> upload\r
952 }\r
953\r
954if(bNeedUploadTest)\r
955 {\r
956 bNeedUploadTest=FALSE;\r
957 if(PSXDisplay.InterlacedTest &&\r
958 //iOffscreenDrawing>2 &&\r
959 PreviousPSXDisplay.DisplayPosition.x==PSXDisplay.DisplayPosition.x &&\r
960 PreviousPSXDisplay.DisplayEnd.x==PSXDisplay.DisplayEnd.x &&\r
961 PreviousPSXDisplay.DisplayPosition.y==PSXDisplay.DisplayPosition.y &&\r
962 PreviousPSXDisplay.DisplayEnd.y==PSXDisplay.DisplayEnd.y)\r
963 {\r
964 PrepareFullScreenUpload(TRUE);\r
965 UploadScreen(TRUE);\r
966 }\r
967 }\r
968\r
969//----------------------------------------------------//\r
970// rumbling (main emu pad effect)\r
971\r
972if(iRumbleTime) // shake screen by modifying view port\r
973 {\r
974 int i1=0,i2=0,i3=0,i4=0;\r
975\r
976 iRumbleTime--;\r
977 if(iRumbleTime) \r
978 {\r
979 i1=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2); \r
980 i2=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2); \r
981 i3=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2); \r
982 i4=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2); \r
983 }\r
984\r
985 glViewport(rRatioRect.left+i1, \r
986 iResY-(rRatioRect.top+rRatioRect.bottom)+i2,\r
987 rRatioRect.right+i3, \r
988 rRatioRect.bottom+i4); \r
989 }\r
990\r
991//----------------------------------------------------//\r
992\r
993\r
994\r
995// if(ulKeybits&KEY_RESETTEXSTORE) ResetStuff(); // reset on gpu mode changes? do it before next frame is filled\r
996}\r
997\r
998////////////////////////////////////////////////////////////////////////\r
999// update front display: smaller update func, if something has changed \r
1000// in the frontbuffer... dirty, but hey... real men know no pain\r
1001////////////////////////////////////////////////////////////////////////\r
1002\r
1003void updateFrontDisplay(void)\r
1004{\r
1005if(PreviousPSXDisplay.Range.x0||\r
1006 PreviousPSXDisplay.Range.y0)\r
1007 PaintBlackBorders();\r
1008\r
1009//if(iBlurBuffer) BlurBackBuffer();\r
1010\r
1011//if(iUseScanLines) SetScanLines();\r
1012\r
1013// if(usCursorActive) ShowGunCursor();\r
1014\r
1015bFakeFrontBuffer=FALSE;\r
1016bRenderFrontBuffer=FALSE;\r
1017\r
1018// if(gTexPicName) DisplayPic();\r
1019// if(ulKeybits&KEY_SHOWFPS) DisplayText();\r
1020\r
1021#ifdef _WINDOWS\r
1022 { // windows: \r
1023 HDC hdc=GetDC(hWWindow);\r
1024 wglMakeCurrent(hdc,GLCONTEXT); // -> make current again\r
1025 if(iDrawnSomething)\r
1026 SwapBuffers(wglGetCurrentDC()); // -> swap\r
1027 ReleaseDC(hWWindow,hdc); // -> ! important !\r
1028 }\r
1029#else\r
1030if(iDrawnSomething) // linux:\r
1031 eglSwapBuffers(display,surface);\r
1032#endif\r
1033\r
1034//if(iBlurBuffer) UnBlurBackBuffer();\r
1035}\r
1036 \r
1037////////////////////////////////////////////////////////////////////////\r
1038// check if update needed\r
1039////////////////////////////////////////////////////////////////////////\r
1040void ChangeDispOffsetsX(void) // CENTER X\r
1041{\r
1042long lx,l;short sO;\r
1043\r
1044if(!PSXDisplay.Range.x1) return; // some range given?\r
1045\r
1046l=PSXDisplay.DisplayMode.x;\r
1047\r
1048l*=(long)PSXDisplay.Range.x1; // some funky calculation\r
1049l/=2560;lx=l;l&=0xfffffff8;\r
1050\r
1051if(l==PreviousPSXDisplay.Range.x1) return; // some change?\r
1052\r
1053sO=PreviousPSXDisplay.Range.x0; // store old\r
1054\r
1055if(lx>=PSXDisplay.DisplayMode.x) // range bigger?\r
1056 {\r
1057 PreviousPSXDisplay.Range.x1= // -> take display width\r
1058 PSXDisplay.DisplayMode.x;\r
1059 PreviousPSXDisplay.Range.x0=0; // -> start pos is 0\r
1060 }\r
1061else // range smaller? center it\r
1062 {\r
1063 PreviousPSXDisplay.Range.x1=l; // -> store width (8 pixel aligned)\r
1064 PreviousPSXDisplay.Range.x0= // -> calc start pos\r
1065 (PSXDisplay.Range.x0-500)/8;\r
1066 if(PreviousPSXDisplay.Range.x0<0) // -> we don't support neg. values yet\r
1067 PreviousPSXDisplay.Range.x0=0;\r
1068\r
1069 if((PreviousPSXDisplay.Range.x0+lx)> // -> uhuu... that's too much\r
1070 PSXDisplay.DisplayMode.x)\r
1071 {\r
1072 PreviousPSXDisplay.Range.x0= // -> adjust start\r
1073 PSXDisplay.DisplayMode.x-lx;\r
1074 PreviousPSXDisplay.Range.x1+=lx-l; // -> adjust width\r
1075 } \r
1076 }\r
1077\r
1078if(sO!=PreviousPSXDisplay.Range.x0) // something changed?\r
1079 {\r
1080 bDisplayNotSet=TRUE; // -> recalc display stuff\r
1081 }\r
1082}\r
1083\r
1084////////////////////////////////////////////////////////////////////////\r
1085\r
1086void ChangeDispOffsetsY(void) // CENTER Y\r
1087{\r
1088int iT;short sO; // store previous y size\r
1089\r
1090if(PSXDisplay.PAL) iT=48; else iT=28; // different offsets on PAL/NTSC\r
1091\r
1092if(PSXDisplay.Range.y0>=iT) // crossed the security line? :)\r
1093 {\r
1094 PreviousPSXDisplay.Range.y1= // -> store width\r
1095 PSXDisplay.DisplayModeNew.y;\r
1096 \r
1097 sO=(PSXDisplay.Range.y0-iT-4)*PSXDisplay.Double; // -> calc offset\r
1098 if(sO<0) sO=0;\r
1099\r
1100 PSXDisplay.DisplayModeNew.y+=sO; // -> add offset to y size, too\r
1101 }\r
1102else sO=0; // else no offset\r
1103\r
1104if(sO!=PreviousPSXDisplay.Range.y0) // something changed?\r
1105 {\r
1106 PreviousPSXDisplay.Range.y0=sO;\r
1107 bDisplayNotSet=TRUE; // -> recalc display stuff\r
1108 }\r
1109}\r
1110\r
1111////////////////////////////////////////////////////////////////////////\r
1112// Aspect ratio of ogl screen: simply adjusting ogl view port\r
1113////////////////////////////////////////////////////////////////////////\r
1114\r
1115void SetAspectRatio(void)\r
1116{\r
1117float xs,ys,s;RECT r;\r
1118\r
1119if(!PSXDisplay.DisplayModeNew.x) return;\r
1120if(!PSXDisplay.DisplayModeNew.y) return;\r
1121\r
1122xs=(float)iResX/(float)PSXDisplay.DisplayModeNew.x;\r
1123ys=(float)iResY/(float)PSXDisplay.DisplayModeNew.y;\r
1124\r
1125s=min(xs,ys);\r
1126r.right =(int)((float)PSXDisplay.DisplayModeNew.x*s);\r
1127r.bottom=(int)((float)PSXDisplay.DisplayModeNew.y*s);\r
1128if(r.right > iResX) r.right = iResX;\r
1129if(r.bottom > iResY) r.bottom = iResY;\r
1130if(r.right < 1) r.right = 1;\r
1131if(r.bottom < 1) r.bottom = 1;\r
1132\r
1133r.left = (iResX-r.right)/2;\r
1134r.top = (iResY-r.bottom)/2;\r
1135\r
1136if(r.bottom<rRatioRect.bottom ||\r
1137 r.right <rRatioRect.right)\r
1138 {\r
1139 RECT rC;\r
1140 glClearColor(0,0,0,128); \r
1141\r
1142 if(r.right <rRatioRect.right)\r
1143 {\r
1144 rC.left=0;\r
1145 rC.top=0;\r
1146 rC.right=r.left;\r
1147 rC.bottom=iResY;\r
1148 glScissor(rC.left,rC.top,rC.right,rC.bottom);\r
1149 glClear(uiBufferBits);\r
1150 rC.left=iResX-rC.right;\r
1151 glScissor(rC.left,rC.top,rC.right,rC.bottom);\r
1152 glClear(uiBufferBits);\r
1153 }\r
1154\r
1155 if(r.bottom <rRatioRect.bottom)\r
1156 {\r
1157 rC.left=0;\r
1158 rC.top=0;\r
1159 rC.right=iResX;\r
1160 rC.bottom=r.top;\r
1161 glScissor(rC.left,rC.top,rC.right,rC.bottom);\r
1162 glClear(uiBufferBits);\r
1163 rC.top=iResY-rC.bottom;\r
1164 glScissor(rC.left,rC.top,rC.right,rC.bottom);\r
1165 glClear(uiBufferBits);\r
1166 }\r
1167 \r
1168 bSetClip=TRUE;\r
1169 bDisplayNotSet=TRUE;\r
1170 }\r
1171\r
1172rRatioRect=r;\r
1173\r
1174\r
1175glViewport(rRatioRect.left,\r
1176 iResY-(rRatioRect.top+rRatioRect.bottom),\r
1177 rRatioRect.right,\r
1178 rRatioRect.bottom); // init viewport\r
1179}\r
1180\r
1181////////////////////////////////////////////////////////////////////////\r
1182// big ass check, if an ogl swap buffer is needed\r
1183////////////////////////////////////////////////////////////////////////\r
1184\r
1185void updateDisplayIfChanged(void)\r
1186{\r
1187BOOL bUp;\r
1188\r
1189if ((PSXDisplay.DisplayMode.y == PSXDisplay.DisplayModeNew.y) && \r
1190 (PSXDisplay.DisplayMode.x == PSXDisplay.DisplayModeNew.x))\r
1191 {\r
1192 if((PSXDisplay.RGB24 == PSXDisplay.RGB24New) && \r
1193 (PSXDisplay.Interlaced == PSXDisplay.InterlacedNew)) \r
1194 return; // nothing has changed? fine, no swap buffer needed\r
1195 }\r
1196else // some res change?\r
1197 {\r
1198 glLoadIdentity();\r
1199 glOrtho(0,PSXDisplay.DisplayModeNew.x, // -> new psx resolution\r
1200 PSXDisplay.DisplayModeNew.y, 0, -1, 1);\r
1201 if(bKeepRatio) SetAspectRatio();\r
1202 }\r
1203\r
1204bDisplayNotSet = TRUE; // re-calc offsets/display area\r
1205\r
1206bUp=FALSE;\r
1207if(PSXDisplay.RGB24!=PSXDisplay.RGB24New) // clean up textures, if rgb mode change (usually mdec on/off)\r
1208 {\r
1209 PreviousPSXDisplay.RGB24=0; // no full 24 frame uploaded yet\r
1210 ResetTextureArea(FALSE);\r
1211 bUp=TRUE;\r
1212 }\r
1213\r
1214PSXDisplay.RGB24 = PSXDisplay.RGB24New; // get new infos\r
1215PSXDisplay.DisplayMode.y = PSXDisplay.DisplayModeNew.y;\r
1216PSXDisplay.DisplayMode.x = PSXDisplay.DisplayModeNew.x;\r
1217PSXDisplay.Interlaced = PSXDisplay.InterlacedNew;\r
1218 \r
1219PSXDisplay.DisplayEnd.x= // calc new ends\r
1220 PSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;\r
1221PSXDisplay.DisplayEnd.y=\r
1222 PSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;\r
1223PreviousPSXDisplay.DisplayEnd.x=\r
1224 PreviousPSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;\r
1225PreviousPSXDisplay.DisplayEnd.y=\r
1226 PreviousPSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;\r
1227\r
1228ChangeDispOffsetsX();\r
1229\r
1230if(iFrameLimit==2) SetAutoFrameCap(); // set new fps limit vals (depends on interlace)\r
1231\r
1232if(bUp) updateDisplay(); // yeah, real update (swap buffer)\r
1233}\r
1234\r
1235////////////////////////////////////////////////////////////////////////\r
1236// window mode <-> fullscreen mode (windows)\r
1237////////////////////////////////////////////////////////////////////////\r
1238\r
1239#ifdef _WINDOWS\r
1240void ChangeWindowMode(void)\r
1241{\r
1242 GPUclose();\r
1243 bWindowMode=!bWindowMode;\r
1244 GPUopen(hWWindow);\r
1245 bChangeWinMode=FALSE;\r
1246}\r
1247#endif\r
1248\r
1249////////////////////////////////////////////////////////////////////////\r
1250// swap update check (called by psx vsync function)\r
1251////////////////////////////////////////////////////////////////////////\r
1252\r
1253BOOL bSwapCheck(void)\r
1254{\r
1255static int iPosCheck=0;\r
1256static PSXPoint_t pO;\r
1257static PSXPoint_t pD;\r
1258static int iDoAgain=0;\r
1259\r
1260if(PSXDisplay.DisplayPosition.x==pO.x &&\r
1261 PSXDisplay.DisplayPosition.y==pO.y &&\r
1262 PSXDisplay.DisplayEnd.x==pD.x &&\r
1263 PSXDisplay.DisplayEnd.y==pD.y)\r
1264 iPosCheck++;\r
1265else iPosCheck=0;\r
1266\r
1267pO=PSXDisplay.DisplayPosition;\r
1268pD=PSXDisplay.DisplayEnd;\r
1269\r
1270if(iPosCheck<=4) return FALSE;\r
1271\r
1272iPosCheck=4;\r
1273\r
1274if(PSXDisplay.Interlaced) return FALSE;\r
1275\r
1276if (bNeedInterlaceUpdate||\r
1277 bNeedRGB24Update ||\r
1278 bNeedUploadAfter|| \r
1279 bNeedUploadTest || \r
1280 iDoAgain\r
1281 )\r
1282 {\r
1283 iDoAgain=0;\r
1284 if(bNeedUploadAfter) \r
1285 iDoAgain=1;\r
1286 if(bNeedUploadTest && PSXDisplay.InterlacedTest)\r
1287 iDoAgain=1;\r
1288\r
1289 bDisplayNotSet = TRUE;\r
1290 updateDisplay();\r
1291\r
1292 PreviousPSXDisplay.DisplayPosition.x=PSXDisplay.DisplayPosition.x;\r
1293 PreviousPSXDisplay.DisplayPosition.y=PSXDisplay.DisplayPosition.y;\r
1294 PreviousPSXDisplay.DisplayEnd.x=PSXDisplay.DisplayEnd.x;\r
1295 PreviousPSXDisplay.DisplayEnd.y=PSXDisplay.DisplayEnd.y;\r
1296 pO=PSXDisplay.DisplayPosition;\r
1297 pD=PSXDisplay.DisplayEnd;\r
1298\r
1299 return TRUE;\r
1300 }\r
1301\r
1302return FALSE;\r
1303} \r
1304////////////////////////////////////////////////////////////////////////\r
1305// gun cursor func: player=0-7, x=0-511, y=0-255\r
1306////////////////////////////////////////////////////////////////////////\r
1307\r
1308////////////////////////////////////////////////////////////////////////\r
1309// update lace is called every VSync. Basically we limit frame rate \r
1310// here, and in interlaced mode we swap ogl display buffers.\r
1311////////////////////////////////////////////////////////////////////////\r
1312\r
1313static unsigned short usFirstPos=2;\r
1314\r
1315#ifdef _WINDOWS\r
1316void CALLBACK GPUupdateLace(void)\r
1317#else\r
7eadbf88 1318void CALLBACK GPUupdateLace(void)\r
ce879073 1319#endif\r
1320{\r
1321if(!(dwActFixes&0x1000)) \r
1322 STATUSREG^=0x80000000; // interlaced bit toggle, if the CC game fix is not active (see gpuReadStatus)\r
1323\r
1324if(!(dwActFixes&128)) // normal frame limit func\r
1325 CheckFrameRate();\r
1326\r
1327if(iOffscreenDrawing==4) // special check if high offscreen drawing is on\r
1328 {\r
1329 if(bSwapCheck()) return;\r
1330 }\r
1331\r
1332if(PSXDisplay.Interlaced) // interlaced mode?\r
1333 {\r
1334 if(PSXDisplay.DisplayMode.x>0 && PSXDisplay.DisplayMode.y>0)\r
1335 {\r
1336 updateDisplay(); // -> swap buffers (new frame)\r
1337 }\r
1338 }\r
1339else if(bRenderFrontBuffer) // no interlace mode? and some stuff in front has changed?\r
1340 {\r
1341 updateFrontDisplay(); // -> update front buffer\r
1342 }\r
1343else if(usFirstPos==1) // initial updates (after startup)\r
1344 {\r
1345 updateDisplay();\r
1346 }\r
1347\r
1348#ifdef _WINDOWS\r
1349if(bChangeWinMode) ChangeWindowMode();\r
1350#endif\r
1351}\r
1352\r
1353////////////////////////////////////////////////////////////////////////\r
1354// process read request from GPU status register\r
1355////////////////////////////////////////////////////////////////////////\r
1356\r
1357#ifdef _WINDOWS\r
1358unsigned long CALLBACK GPUreadStatus(void)\r
1359#else\r
7eadbf88 1360unsigned long CALLBACK GPUreadStatus(void)\r
ce879073 1361#endif\r
1362{\r
1363if(dwActFixes&0x1000) // CC game fix\r
1364 {\r
1365 static int iNumRead=0;\r
1366 if((iNumRead++)==2)\r
1367 {\r
1368 iNumRead=0;\r
1369 STATUSREG^=0x80000000; // interlaced bit toggle... we do it on every second read status... needed by some games (like ChronoCross)\r
1370 }\r
1371 }\r
1372\r
1373if(iFakePrimBusy) // 27.10.2007 - emulating some 'busy' while drawing... pfff... not perfect, but since our emulated dma is not done in an extra thread...\r
1374 {\r
1375 iFakePrimBusy--;\r
1376\r
1377 if(iFakePrimBusy&1) // we do a busy-idle-busy-idle sequence after/while drawing prims\r
1378 {\r
1379 GPUIsBusy;\r
1380 GPUIsNotReadyForCommands;\r
1381 }\r
1382 else\r
1383 {\r
1384 GPUIsIdle;\r
1385 GPUIsReadyForCommands;\r
1386 }\r
1387 }\r
1388\r
1389return STATUSREG;\r
1390}\r
1391\r
1392////////////////////////////////////////////////////////////////////////\r
1393// processes data send to GPU status register\r
1394// these are always single packet commands.\r
1395////////////////////////////////////////////////////////////////////////\r
1396\r
1397#ifdef _WINDOWS\r
1398void CALLBACK GPUwriteStatus(unsigned long gdata)\r
1399#else\r
7eadbf88 1400void CALLBACK GPUwriteStatus(unsigned long gdata)\r
ce879073 1401#endif\r
1402{\r
1403unsigned long lCommand=(gdata>>24)&0xff;\r
1404\r
1405#ifdef _WINDOWS\r
1406if(bIsFirstFrame) GLinitialize(); // real ogl startup (needed by some emus)\r
1407#endif\r
1408\r
1409ulStatusControl[lCommand]=gdata;\r
1410\r
1411switch(lCommand)\r
1412 {\r
1413 //--------------------------------------------------//\r
1414 // reset gpu\r
1415 case 0x00:\r
1416 memset(ulGPUInfoVals,0x00,16*sizeof(unsigned long));\r
1417 lGPUstatusRet=0x14802000;\r
1418 PSXDisplay.Disabled=1;\r
1419 iDataWriteMode=iDataReadMode=DR_NORMAL;\r
1420 PSXDisplay.DrawOffset.x=PSXDisplay.DrawOffset.y=0;\r
1421 drawX=drawY=0;drawW=drawH=0;\r
1422 sSetMask=0;lSetMask=0;bCheckMask=FALSE;iSetMask=0;\r
1423 usMirror=0;\r
1424 GlobalTextAddrX=0;GlobalTextAddrY=0;\r
1425 GlobalTextTP=0;GlobalTextABR=0;\r
1426 PSXDisplay.RGB24=FALSE;\r
1427 PSXDisplay.Interlaced=FALSE;\r
1428 bUsingTWin = FALSE;\r
1429 return;\r
1430\r
1431 // dis/enable display\r
1432 case 0x03: \r
1433 PreviousPSXDisplay.Disabled = PSXDisplay.Disabled;\r
1434 PSXDisplay.Disabled = (gdata & 1);\r
1435\r
1436 if(PSXDisplay.Disabled) \r
1437 STATUSREG|=GPUSTATUS_DISPLAYDISABLED;\r
1438 else STATUSREG&=~GPUSTATUS_DISPLAYDISABLED;\r
1439\r
1440 if (iOffscreenDrawing==4 &&\r
1441 PreviousPSXDisplay.Disabled && \r
1442 !(PSXDisplay.Disabled))\r
1443 {\r
1444\r
1445 if(!PSXDisplay.RGB24)\r
1446 {\r
1447 PrepareFullScreenUpload(TRUE);\r
1448 UploadScreen(TRUE); \r
1449 updateDisplay();\r
1450 }\r
1451 }\r
1452\r
1453 return;\r
1454\r
1455 // setting transfer mode\r
1456 case 0x04:\r
1457 gdata &= 0x03; // only want the lower two bits\r
1458\r
1459 iDataWriteMode=iDataReadMode=DR_NORMAL;\r
1460 if(gdata==0x02) iDataWriteMode=DR_VRAMTRANSFER;\r
1461 if(gdata==0x03) iDataReadMode =DR_VRAMTRANSFER;\r
1462\r
1463 STATUSREG&=~GPUSTATUS_DMABITS; // clear the current settings of the DMA bits\r
1464 STATUSREG|=(gdata << 29); // set the DMA bits according to the received data\r
1465\r
1466 return;\r
1467\r
1468 // setting display position\r
1469 case 0x05: \r
1470 {\r
1471 short sx=(short)(gdata & 0x3ff);\r
1472 short sy;\r
1473\r
1474 if(iGPUHeight==1024)\r
1475 {\r
1476 if(dwGPUVersion==2) \r
1477 sy = (short)((gdata>>12)&0x3ff);\r
1478 else sy = (short)((gdata>>10)&0x3ff);\r
1479 }\r
1480 else sy = (short)((gdata>>10)&0x3ff); // really: 0x1ff, but we adjust it later\r
1481\r
1482 if (sy & 0x200) \r
1483 {\r
1484 sy|=0xfc00;\r
1485 PreviousPSXDisplay.DisplayModeNew.y=sy/PSXDisplay.Double;\r
1486 sy=0;\r
1487 }\r
1488 else PreviousPSXDisplay.DisplayModeNew.y=0;\r
1489\r
1490 if(sx>1000) sx=0;\r
1491\r
1492 if(usFirstPos)\r
1493 {\r
1494 usFirstPos--;\r
1495 if(usFirstPos)\r
1496 {\r
1497 PreviousPSXDisplay.DisplayPosition.x = sx;\r
1498 PreviousPSXDisplay.DisplayPosition.y = sy;\r
1499 PSXDisplay.DisplayPosition.x = sx;\r
1500 PSXDisplay.DisplayPosition.y = sy;\r
1501 }\r
1502 }\r
1503\r
1504 if(dwActFixes&8) \r
1505 {\r
1506 if((!PSXDisplay.Interlaced) &&\r
1507 PreviousPSXDisplay.DisplayPosition.x == sx &&\r
1508 PreviousPSXDisplay.DisplayPosition.y == sy)\r
1509 return;\r
1510\r
1511 PSXDisplay.DisplayPosition.x = PreviousPSXDisplay.DisplayPosition.x;\r
1512 PSXDisplay.DisplayPosition.y = PreviousPSXDisplay.DisplayPosition.y;\r
1513 PreviousPSXDisplay.DisplayPosition.x = sx;\r
1514 PreviousPSXDisplay.DisplayPosition.y = sy;\r
1515 }\r
1516 else\r
1517 {\r
1518 if((!PSXDisplay.Interlaced) &&\r
1519 PSXDisplay.DisplayPosition.x == sx &&\r
1520 PSXDisplay.DisplayPosition.y == sy)\r
1521 return;\r
1522 PreviousPSXDisplay.DisplayPosition.x = PSXDisplay.DisplayPosition.x;\r
1523 PreviousPSXDisplay.DisplayPosition.y = PSXDisplay.DisplayPosition.y;\r
1524 PSXDisplay.DisplayPosition.x = sx;\r
1525 PSXDisplay.DisplayPosition.y = sy;\r
1526 }\r
1527\r
1528 PSXDisplay.DisplayEnd.x=\r
1529 PSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;\r
1530 PSXDisplay.DisplayEnd.y=\r
1531 PSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;\r
1532\r
1533 PreviousPSXDisplay.DisplayEnd.x=\r
1534 PreviousPSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;\r
1535 PreviousPSXDisplay.DisplayEnd.y=\r
1536 PreviousPSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;\r
1537\r
1538 bDisplayNotSet = TRUE;\r
1539\r
1540 if (!(PSXDisplay.Interlaced))\r
1541 {\r
1542 updateDisplay();\r
1543 }\r
1544 else\r
1545 if(PSXDisplay.InterlacedTest && \r
1546 ((PreviousPSXDisplay.DisplayPosition.x != PSXDisplay.DisplayPosition.x)||\r
1547 (PreviousPSXDisplay.DisplayPosition.y != PSXDisplay.DisplayPosition.y)))\r
1548 PSXDisplay.InterlacedTest--;\r
1549\r
1550 return;\r
1551 }\r
1552\r
1553 // setting width\r
1554 case 0x06:\r
1555\r
1556 PSXDisplay.Range.x0=gdata & 0x7ff; //0x3ff;\r
1557 PSXDisplay.Range.x1=(gdata>>12) & 0xfff;//0x7ff;\r
1558\r
1559 PSXDisplay.Range.x1-=PSXDisplay.Range.x0;\r
1560\r
1561 ChangeDispOffsetsX();\r
1562\r
1563 return;\r
1564\r
1565 // setting height\r
1566 case 0x07:\r
1567\r
1568 PreviousPSXDisplay.Height = PSXDisplay.Height;\r
1569\r
1570 PSXDisplay.Range.y0=gdata & 0x3ff;\r
1571 PSXDisplay.Range.y1=(gdata>>10) & 0x3ff;\r
1572\r
1573 PSXDisplay.Height = PSXDisplay.Range.y1 - \r
1574 PSXDisplay.Range.y0 +\r
1575 PreviousPSXDisplay.DisplayModeNew.y;\r
1576\r
1577 if (PreviousPSXDisplay.Height != PSXDisplay.Height)\r
1578 {\r
1579 PSXDisplay.DisplayModeNew.y=PSXDisplay.Height*PSXDisplay.Double;\r
1580 ChangeDispOffsetsY();\r
1581 updateDisplayIfChanged();\r
1582 }\r
1583 return;\r
1584\r
1585 // setting display infos\r
1586 case 0x08:\r
1587\r
1588 PSXDisplay.DisplayModeNew.x = dispWidths[(gdata & 0x03) | ((gdata & 0x40) >> 4)];\r
1589\r
1590 if (gdata&0x04) PSXDisplay.Double=2;\r
1591 else PSXDisplay.Double=1;\r
1592 PSXDisplay.DisplayModeNew.y = PSXDisplay.Height*PSXDisplay.Double;\r
1593\r
1594 ChangeDispOffsetsY();\r
1595 \r
1596 PSXDisplay.PAL = (gdata & 0x08)?TRUE:FALSE; // if 1 - PAL mode, else NTSC\r
1597 PSXDisplay.RGB24New = (gdata & 0x10)?TRUE:FALSE; // if 1 - TrueColor\r
1598 PSXDisplay.InterlacedNew = (gdata & 0x20)?TRUE:FALSE; // if 1 - Interlace\r
1599\r
1600 STATUSREG&=~GPUSTATUS_WIDTHBITS; // clear the width bits\r
1601\r
1602 STATUSREG|=\r
1603 (((gdata & 0x03) << 17) | \r
1604 ((gdata & 0x40) << 10)); // set the width bits\r
1605\r
1606 PreviousPSXDisplay.InterlacedNew=FALSE;\r
1607 if (PSXDisplay.InterlacedNew)\r
1608 {\r
1609 if(!PSXDisplay.Interlaced)\r
1610 {\r
1611 PSXDisplay.InterlacedTest=2;\r
1612 PreviousPSXDisplay.DisplayPosition.x = PSXDisplay.DisplayPosition.x;\r
1613 PreviousPSXDisplay.DisplayPosition.y = PSXDisplay.DisplayPosition.y;\r
1614 PreviousPSXDisplay.InterlacedNew=TRUE;\r
1615 }\r
1616\r
1617 STATUSREG|=GPUSTATUS_INTERLACED;\r
1618 }\r
1619 else \r
1620 {\r
1621 PSXDisplay.InterlacedTest=0;\r
1622 STATUSREG&=~GPUSTATUS_INTERLACED;\r
1623 }\r
1624\r
1625 if (PSXDisplay.PAL)\r
1626 STATUSREG|=GPUSTATUS_PAL;\r
1627 else STATUSREG&=~GPUSTATUS_PAL;\r
1628\r
1629 if (PSXDisplay.Double==2)\r
1630 STATUSREG|=GPUSTATUS_DOUBLEHEIGHT;\r
1631 else STATUSREG&=~GPUSTATUS_DOUBLEHEIGHT;\r
1632\r
1633 if (PSXDisplay.RGB24New)\r
1634 STATUSREG|=GPUSTATUS_RGB24;\r
1635 else STATUSREG&=~GPUSTATUS_RGB24;\r
1636\r
1637 updateDisplayIfChanged();\r
1638\r
1639 return;\r
1640\r
1641 //--------------------------------------------------//\r
1642 // ask about GPU version and other stuff\r
1643 case 0x10: \r
1644\r
1645 gdata&=0xff;\r
1646\r
1647 switch(gdata) \r
1648 {\r
1649 case 0x02:\r
1650 GPUdataRet=ulGPUInfoVals[INFO_TW]; // tw infos\r
1651 return;\r
1652 case 0x03:\r
1653 GPUdataRet=ulGPUInfoVals[INFO_DRAWSTART]; // draw start\r
1654 return;\r
1655 case 0x04:\r
1656 GPUdataRet=ulGPUInfoVals[INFO_DRAWEND]; // draw end\r
1657 return;\r
1658 case 0x05:\r
1659 case 0x06:\r
1660 GPUdataRet=ulGPUInfoVals[INFO_DRAWOFF]; // draw offset\r
1661 return;\r
1662 case 0x07:\r
1663 if(dwGPUVersion==2)\r
1664 GPUdataRet=0x01;\r
1665 else GPUdataRet=0x02; // gpu type\r
1666 return;\r
1667 case 0x08:\r
1668 case 0x0F: // some bios addr?\r
1669 GPUdataRet=0xBFC03720;\r
1670 return;\r
1671 }\r
1672 return;\r
1673 //--------------------------------------------------//\r
1674 }\r
1675}\r
1676\r
1677////////////////////////////////////////////////////////////////////////\r
1678// vram read/write helpers\r
1679////////////////////////////////////////////////////////////////////////\r
1680\r
1681BOOL bNeedWriteUpload=FALSE;\r
1682\r
1683__inline void FinishedVRAMWrite(void)\r
1684{\r
1685 if(bNeedWriteUpload)\r
1686 {\r
1687 bNeedWriteUpload=FALSE;\r
1688 CheckWriteUpdate();\r
1689 }\r
1690\r
1691 // set register to NORMAL operation\r
1692 iDataWriteMode = DR_NORMAL;\r
1693\r
1694 // reset transfer values, to prevent mis-transfer of data\r
1695 VRAMWrite.ColsRemaining = 0;\r
1696 VRAMWrite.RowsRemaining = 0;\r
1697}\r
1698\r
1699__inline void FinishedVRAMRead(void)\r
1700{\r
1701 // set register to NORMAL operation\r
1702 iDataReadMode = DR_NORMAL;\r
1703 // reset transfer values, to prevent mis-transfer of data\r
1704 VRAMRead.x = 0;\r
1705 VRAMRead.y = 0;\r
1706 VRAMRead.Width = 0;\r
1707 VRAMRead.Height = 0;\r
1708 VRAMRead.ColsRemaining = 0;\r
1709 VRAMRead.RowsRemaining = 0;\r
1710\r
1711 // indicate GPU is no longer ready for VRAM data in the STATUS REGISTER\r
1712 STATUSREG&=~GPUSTATUS_READYFORVRAM;\r
1713}\r
1714\r
1715////////////////////////////////////////////////////////////////////////\r
1716// vram read check ex (reading from card's back/frontbuffer if needed...\r
1717// slow!)\r
1718////////////////////////////////////////////////////////////////////////\r
1719\r
1720void CheckVRamReadEx(int x, int y, int dx, int dy)\r
1721{\r
1722 unsigned short sArea;\r
1723 int ux,uy,udx,udy,wx,wy;\r
1724 unsigned short * p1, *p2;\r
1725 float XS,YS;\r
1726 u8 * ps;\r
1727 u8 * px;\r
1728 unsigned short s,sx;\r
1729\r
1730 if(STATUSREG&GPUSTATUS_RGB24) return;\r
1731\r
1732 if(((dx > PSXDisplay.DisplayPosition.x) &&\r
1733 (x < PSXDisplay.DisplayEnd.x) &&\r
1734 (dy > PSXDisplay.DisplayPosition.y) &&\r
1735 (y < PSXDisplay.DisplayEnd.y)))\r
1736 sArea=0;\r
1737 else\r
1738 if((!(PSXDisplay.InterlacedTest) &&\r
1739 (dx > PreviousPSXDisplay.DisplayPosition.x) &&\r
1740 (x < PreviousPSXDisplay.DisplayEnd.x) &&\r
1741 (dy > PreviousPSXDisplay.DisplayPosition.y) &&\r
1742 (y < PreviousPSXDisplay.DisplayEnd.y)))\r
1743 sArea=1;\r
1744 else \r
1745 {\r
1746 return;\r
1747 }\r
1748\r
1749 //////////////\r
1750\r
1751 if(iRenderFVR)\r
1752 {\r
1753 bFullVRam=TRUE;iRenderFVR=2;return;\r
1754 }\r
1755 bFullVRam=TRUE;iRenderFVR=2;\r
1756\r
1757 //////////////\r
1758\r
1759 p2=0;\r
1760\r
1761 if(sArea==0)\r
1762 {\r
1763 ux=PSXDisplay.DisplayPosition.x;\r
1764 uy=PSXDisplay.DisplayPosition.y;\r
1765 udx=PSXDisplay.DisplayEnd.x-ux;\r
1766 udy=PSXDisplay.DisplayEnd.y-uy;\r
1767 if((PreviousPSXDisplay.DisplayEnd.x-\r
1768 PreviousPSXDisplay.DisplayPosition.x)==udx &&\r
1769 (PreviousPSXDisplay.DisplayEnd.y-\r
1770 PreviousPSXDisplay.DisplayPosition.y)==udy)\r
1771 p2=(psxVuw + (1024*PreviousPSXDisplay.DisplayPosition.y) + \r
1772 PreviousPSXDisplay.DisplayPosition.x);\r
1773 }\r
1774 else\r
1775 {\r
1776 ux=PreviousPSXDisplay.DisplayPosition.x;\r
1777 uy=PreviousPSXDisplay.DisplayPosition.y;\r
1778 udx=PreviousPSXDisplay.DisplayEnd.x-ux;\r
1779 udy=PreviousPSXDisplay.DisplayEnd.y-uy;\r
1780 if((PSXDisplay.DisplayEnd.x-\r
1781 PSXDisplay.DisplayPosition.x)==udx &&\r
1782 (PSXDisplay.DisplayEnd.y-\r
1783 PSXDisplay.DisplayPosition.y)==udy)\r
1784 p2=(psxVuw + (1024*PSXDisplay.DisplayPosition.y) + \r
1785 PSXDisplay.DisplayPosition.x);\r
1786 }\r
1787\r
1788 p1=(psxVuw + (1024*uy) + ux);\r
1789 if(p1==p2) p2=0;\r
1790\r
1791 x=0;y=0;\r
1792 wx=dx=udx;wy=dy=udy;\r
1793\r
1794 if(udx<=0) return;\r
1795 if(udy<=0) return;\r
1796 if(dx<=0) return;\r
1797 if(dy<=0) return;\r
1798 if(wx<=0) return;\r
1799 if(wy<=0) return;\r
1800\r
1801 XS=(float)rRatioRect.right/(float)wx;\r
1802 YS=(float)rRatioRect.bottom/(float)wy;\r
1803\r
1804 dx=(int)((float)(dx)*XS);\r
1805 dy=(int)((float)(dy)*YS);\r
1806\r
1807 if(dx>iResX) dx=iResX;\r
1808 if(dy>iResY) dy=iResY;\r
1809\r
1810 if(dx<=0) return;\r
1811 if(dy<=0) return;\r
1812\r
1813 // ogl y adjust\r
1814 y=iResY-y-dy;\r
1815\r
1816 x+=rRatioRect.left;\r
1817 y-=rRatioRect.top;\r
1818\r
1819 if(y<0) y=0; if((y+dy)>iResY) dy=iResY-y;\r
1820\r
1821 if(!pGfxCardScreen)\r
1822 {\r
1823 glPixelStorei(GL_PACK_ALIGNMENT,1);\r
1824 pGfxCardScreen=(u8 *)malloc(iResX*iResY*4);\r
1825 }\r
1826\r
1827 ps=pGfxCardScreen;\r
1828 \r
1829 //if(!sArea) glReadBuffer(GL_FRONT);\r
1830\r
1831 glReadPixels(x,y,dx,dy,GL_RGB,GL_UNSIGNED_BYTE,ps);\r
1832 \r
1833 //if(!sArea) glReadBuffer(GL_BACK);\r
1834\r
1835 s=0;\r
1836\r
1837 XS=(float)dx/(float)(udx);\r
1838 YS=(float)dy/(float)(udy+1);\r
1839 \r
1840 for(y=udy;y>0;y--)\r
1841 {\r
1842 for(x=0;x<udx;x++)\r
1843 {\r
1844 if(p1>=psxVuw && p1<psxVuw_eom)\r
1845 {\r
1846 px=ps+(3*((int)((float)x * XS))+\r
1847 (3*dx)*((int)((float)y*YS)));\r
1848 sx=(*px)>>3;px++;\r
1849 s=sx;\r
1850 sx=(*px)>>3;px++;\r
1851 s|=sx<<5;\r
1852 sx=(*px)>>3;\r
1853 s|=sx<<10;\r
1854 s&=~0x8000;\r
1855 *p1=s;\r
1856 }\r
1857 if(p2>=psxVuw && p2<psxVuw_eom) *p2=s;\r
1858\r
1859 p1++;\r
1860 if(p2) p2++;\r
1861 }\r
1862\r
1863 p1 += 1024 - udx;\r
1864 if(p2) p2 += 1024 - udx;\r
1865 }\r
1866}\r
1867\r
1868////////////////////////////////////////////////////////////////////////\r
1869// vram read check (reading from card's back/frontbuffer if needed... \r
1870// slow!)\r
1871////////////////////////////////////////////////////////////////////////\r
1872\r
1873void CheckVRamRead(int x, int y, int dx, int dy, bool bFront)\r
1874{\r
1875 unsigned short sArea;unsigned short * p;\r
1876 int ux,uy,udx,udy,wx,wy;float XS,YS;\r
1877 u8 * ps, * px;\r
1878 unsigned short s=0,sx;\r
1879\r
1880 if(STATUSREG&GPUSTATUS_RGB24) return;\r
1881\r
1882 if(((dx > PSXDisplay.DisplayPosition.x) &&\r
1883 (x < PSXDisplay.DisplayEnd.x) &&\r
1884 (dy > PSXDisplay.DisplayPosition.y) &&\r
1885 (y < PSXDisplay.DisplayEnd.y)))\r
1886 sArea=0;\r
1887 else\r
1888 if((!(PSXDisplay.InterlacedTest) &&\r
1889 (dx > PreviousPSXDisplay.DisplayPosition.x) &&\r
1890 (x < PreviousPSXDisplay.DisplayEnd.x) &&\r
1891 (dy > PreviousPSXDisplay.DisplayPosition.y) &&\r
1892 (y < PreviousPSXDisplay.DisplayEnd.y)))\r
1893 sArea=1;\r
1894 else \r
1895 {\r
1896 return;\r
1897 }\r
1898\r
1899 if(dwActFixes&0x40)\r
1900 {\r
1901 if(iRenderFVR)\r
1902 {\r
1903 bFullVRam=TRUE;iRenderFVR=2;return;\r
1904 }\r
1905 bFullVRam=TRUE;iRenderFVR=2;\r
1906 }\r
1907\r
1908 ux=x;uy=y;udx=dx;udy=dy;\r
1909\r
1910 if(sArea==0)\r
1911 {\r
1912 x -=PSXDisplay.DisplayPosition.x;\r
1913 dx-=PSXDisplay.DisplayPosition.x;\r
1914 y -=PSXDisplay.DisplayPosition.y;\r
1915 dy-=PSXDisplay.DisplayPosition.y;\r
1916 wx=PSXDisplay.DisplayEnd.x-PSXDisplay.DisplayPosition.x;\r
1917 wy=PSXDisplay.DisplayEnd.y-PSXDisplay.DisplayPosition.y;\r
1918 }\r
1919 else\r
1920 {\r
1921 x -=PreviousPSXDisplay.DisplayPosition.x;\r
1922 dx-=PreviousPSXDisplay.DisplayPosition.x;\r
1923 y -=PreviousPSXDisplay.DisplayPosition.y;\r
1924 dy-=PreviousPSXDisplay.DisplayPosition.y;\r
1925 wx=PreviousPSXDisplay.DisplayEnd.x-PreviousPSXDisplay.DisplayPosition.x;\r
1926 wy=PreviousPSXDisplay.DisplayEnd.y-PreviousPSXDisplay.DisplayPosition.y;\r
1927 }\r
1928 if(x<0) {ux-=x;x=0;}\r
1929 if(y<0) {uy-=y;y=0;}\r
1930 if(dx>wx) {udx-=(dx-wx);dx=wx;}\r
1931 if(dy>wy) {udy-=(dy-wy);dy=wy;}\r
1932 udx-=ux;\r
1933 udy-=uy;\r
1934 \r
1935 p=(psxVuw + (1024*uy) + ux);\r
1936\r
1937 if(udx<=0) return;\r
1938 if(udy<=0) return;\r
1939 if(dx<=0) return;\r
1940 if(dy<=0) return;\r
1941 if(wx<=0) return;\r
1942 if(wy<=0) return;\r
1943\r
1944 XS=(float)rRatioRect.right/(float)wx;\r
1945 YS=(float)rRatioRect.bottom/(float)wy;\r
1946\r
1947 dx=(int)((float)(dx)*XS);\r
1948 dy=(int)((float)(dy)*YS);\r
1949 x=(int)((float)x*XS);\r
1950 y=(int)((float)y*YS);\r
1951\r
1952 dx-=x;\r
1953 dy-=y;\r
1954\r
1955 if(dx>iResX) dx=iResX;\r
1956 if(dy>iResY) dy=iResY;\r
1957\r
1958 if(dx<=0) return;\r
1959 if(dy<=0) return;\r
1960\r
1961 // ogl y adjust\r
1962 y=iResY-y-dy;\r
1963\r
1964 x+=rRatioRect.left;\r
1965 y-=rRatioRect.top;\r
1966\r
1967 if(y<0) y=0; if((y+dy)>iResY) dy=iResY-y;\r
1968\r
1969 if(!pGfxCardScreen)\r
1970 {\r
1971 glPixelStorei(GL_PACK_ALIGNMENT,1);\r
1972 pGfxCardScreen=(u8 *)malloc(iResX*iResY*4);\r
1973 }\r
1974\r
1975 ps=pGfxCardScreen;\r
1976 \r
1977// if(bFront) glReadBuffer(GL_FRONT);\r
1978\r
1979 glReadPixels(x,y,dx,dy,GL_RGB,GL_UNSIGNED_BYTE,ps);\r
1980 \r
1981// if(bFront) glReadBuffer(GL_BACK);\r
1982\r
1983 XS=(float)dx/(float)(udx);\r
1984 YS=(float)dy/(float)(udy+1);\r
1985 \r
1986 for(y=udy;y>0;y--)\r
1987 {\r
1988 for(x=0;x<udx;x++)\r
1989 {\r
1990 if(p>=psxVuw && p<psxVuw_eom)\r
1991 {\r
1992 px=ps+(3*((int)((float)x * XS))+\r
1993 (3*dx)*((int)((float)y*YS)));\r
1994 sx=(*px)>>3;px++;\r
1995 s=sx;\r
1996 sx=(*px)>>3;px++;\r
1997 s|=sx<<5;\r
1998 sx=(*px)>>3;\r
1999 s|=sx<<10;\r
2000 s&=~0x8000;\r
2001 *p=s;\r
2002 }\r
2003 p++;\r
2004 }\r
2005 p += 1024 - udx;\r
2006 }\r
2007}\r
2008\r
2009////////////////////////////////////////////////////////////////////////\r
2010// core read from vram\r
2011////////////////////////////////////////////////////////////////////////\r
2012\r
2013#ifdef _WINDOWS\r
2014void CALLBACK GPUreadDataMem(unsigned int * pMem, int iSize)\r
2015#else\r
7eadbf88 2016void CALLBACK GPUreadDataMem(unsigned long * pMem, int iSize)\r
ce879073 2017#endif\r
2018{\r
2019int i;\r
2020\r
2021if(iDataReadMode!=DR_VRAMTRANSFER) return;\r
2022\r
2023GPUIsBusy;\r
2024\r
2025// adjust read ptr, if necessary\r
2026while(VRAMRead.ImagePtr>=psxVuw_eom)\r
2027 VRAMRead.ImagePtr-=iGPUHeight*1024;\r
2028while(VRAMRead.ImagePtr<psxVuw)\r
2029 VRAMRead.ImagePtr+=iGPUHeight*1024;\r
2030\r
2031if((iFrameReadType&1 && iSize>1) &&\r
2032 !(iDrawnSomething==2 &&\r
2033 VRAMRead.x == VRAMWrite.x &&\r
2034 VRAMRead.y == VRAMWrite.y &&\r
2035 VRAMRead.Width == VRAMWrite.Width &&\r
2036 VRAMRead.Height == VRAMWrite.Height))\r
2037 CheckVRamRead(VRAMRead.x,VRAMRead.y,\r
2038 VRAMRead.x+VRAMRead.RowsRemaining,\r
2039 VRAMRead.y+VRAMRead.ColsRemaining,\r
2040 TRUE);\r
2041\r
2042for(i=0;i<iSize;i++)\r
2043 {\r
2044 // do 2 seperate 16bit reads for compatibility (wrap issues)\r
2045 if ((VRAMRead.ColsRemaining > 0) && (VRAMRead.RowsRemaining > 0))\r
2046 {\r
2047 // lower 16 bit\r
2048 GPUdataRet=(unsigned long)*VRAMRead.ImagePtr;\r
2049\r
2050 VRAMRead.ImagePtr++;\r
2051 if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;\r
2052 VRAMRead.RowsRemaining --;\r
2053\r
2054 if(VRAMRead.RowsRemaining<=0)\r
2055 {\r
2056 VRAMRead.RowsRemaining = VRAMRead.Width;\r
2057 VRAMRead.ColsRemaining--;\r
2058 VRAMRead.ImagePtr += 1024 - VRAMRead.Width;\r
2059 if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;\r
2060 }\r
2061\r
2062 // higher 16 bit (always, even if it's an odd width)\r
2063 GPUdataRet|=(unsigned long)(*VRAMRead.ImagePtr)<<16;\r
2064 *pMem++=GPUdataRet;\r
2065\r
2066 if(VRAMRead.ColsRemaining <= 0)\r
2067 {FinishedVRAMRead();goto ENDREAD;}\r
2068\r
2069 VRAMRead.ImagePtr++;\r
2070 if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;\r
2071 VRAMRead.RowsRemaining--;\r
2072 if(VRAMRead.RowsRemaining<=0)\r
2073 {\r
2074 VRAMRead.RowsRemaining = VRAMRead.Width;\r
2075 VRAMRead.ColsRemaining--;\r
2076 VRAMRead.ImagePtr += 1024 - VRAMRead.Width;\r
2077 if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;\r
2078 }\r
2079 if(VRAMRead.ColsRemaining <= 0)\r
2080 {FinishedVRAMRead();goto ENDREAD;}\r
2081 }\r
2082 else {FinishedVRAMRead();goto ENDREAD;}\r
2083 }\r
2084\r
2085ENDREAD:\r
2086GPUIsIdle;\r
2087}\r
2088\r
2089#ifdef _WINDOWS\r
2090unsigned long CALLBACK GPUreadData(void)\r
2091#else\r
7eadbf88 2092unsigned long CALLBACK GPUreadData(void)\r
ce879073 2093#endif\r
2094{\r
2095 unsigned long l;\r
2096#ifdef _WINDOWS\r
2097 GPUreadDataMem(&l,1);\r
2098#else\r
7eadbf88 2099 GPUreadDataMem(&l,1);\r
ce879073 2100#endif \r
2101 return GPUdataRet;\r
2102}\r
2103\r
2104////////////////////////////////////////////////////////////////////////\r
2105// helper table to know how much data is used by drawing commands\r
2106////////////////////////////////////////////////////////////////////////\r
2107\r
2108const u8 primTableCX[256] =\r
2109{\r
2110 // 00\r
2111 0,0,3,0,0,0,0,0,\r
2112 // 08\r
2113 0,0,0,0,0,0,0,0,\r
2114 // 10\r
2115 0,0,0,0,0,0,0,0,\r
2116 // 18\r
2117 0,0,0,0,0,0,0,0,\r
2118 // 20\r
2119 4,4,4,4,7,7,7,7,\r
2120 // 28\r
2121 5,5,5,5,9,9,9,9,\r
2122 // 30\r
2123 6,6,6,6,9,9,9,9,\r
2124 // 38\r
2125 8,8,8,8,12,12,12,12,\r
2126 // 40\r
2127 3,3,3,3,0,0,0,0,\r
2128 // 48\r
2129// 5,5,5,5,6,6,6,6, //FLINE\r
2130 254,254,254,254,254,254,254,254,\r
2131 // 50\r
2132 4,4,4,4,0,0,0,0,\r
2133 // 58\r
2134// 7,7,7,7,9,9,9,9, // LINEG3 LINEG4\r
2135 255,255,255,255,255,255,255,255,\r
2136 // 60\r
2137 3,3,3,3,4,4,4,4, // TILE SPRT\r
2138 // 68\r
2139 2,2,2,2,3,3,3,3, // TILE1\r
2140 // 70\r
2141 2,2,2,2,3,3,3,3,\r
2142 // 78\r
2143 2,2,2,2,3,3,3,3,\r
2144 // 80\r
2145 4,0,0,0,0,0,0,0,\r
2146 // 88\r
2147 0,0,0,0,0,0,0,0,\r
2148 // 90\r
2149 0,0,0,0,0,0,0,0,\r
2150 // 98\r
2151 0,0,0,0,0,0,0,0,\r
2152 // a0\r
2153 3,0,0,0,0,0,0,0,\r
2154 // a8\r
2155 0,0,0,0,0,0,0,0,\r
2156 // b0\r
2157 0,0,0,0,0,0,0,0,\r
2158 // b8\r
2159 0,0,0,0,0,0,0,0,\r
2160 // c0\r
2161 3,0,0,0,0,0,0,0,\r
2162 // c8\r
2163 0,0,0,0,0,0,0,0,\r
2164 // d0\r
2165 0,0,0,0,0,0,0,0,\r
2166 // d8\r
2167 0,0,0,0,0,0,0,0,\r
2168 // e0\r
2169 0,1,1,1,1,1,1,0,\r
2170 // e8\r
2171 0,0,0,0,0,0,0,0,\r
2172 // f0\r
2173 0,0,0,0,0,0,0,0,\r
2174 // f8\r
2175 0,0,0,0,0,0,0,0\r
2176};\r
2177\r
2178////////////////////////////////////////////////////////////////////////\r
2179// processes data send to GPU data register\r
2180////////////////////////////////////////////////////////////////////////\r
2181\r
2182#ifdef _WINDOWS\r
2183void CALLBACK GPUwriteDataMem(unsigned long * pMem, int iSize)\r
2184#else\r
7eadbf88 2185void CALLBACK GPUwriteDataMem(unsigned long * pMem, int iSize)\r
ce879073 2186#endif\r
2187{\r
2188u8 command;\r
2189unsigned long gdata=0;\r
2190int i=0;\r
2191GPUIsBusy;\r
2192GPUIsNotReadyForCommands;\r
2193\r
2194STARTVRAM:\r
2195\r
2196if(iDataWriteMode==DR_VRAMTRANSFER)\r
2197 {\r
2198 // make sure we are in vram\r
2199 while(VRAMWrite.ImagePtr>=psxVuw_eom)\r
2200 VRAMWrite.ImagePtr-=iGPUHeight*1024;\r
2201 while(VRAMWrite.ImagePtr<psxVuw)\r
2202 VRAMWrite.ImagePtr+=iGPUHeight*1024;\r
2203\r
2204 // now do the loop\r
2205 while(VRAMWrite.ColsRemaining>0)\r
2206 {\r
2207 while(VRAMWrite.RowsRemaining>0)\r
2208 {\r
2209 if(i>=iSize) {goto ENDVRAM;}\r
2210 i++;\r
2211\r
2212 gdata=*pMem++;\r
2213\r
2214 *VRAMWrite.ImagePtr++ = (unsigned short)gdata;\r
2215 if(VRAMWrite.ImagePtr>=psxVuw_eom) VRAMWrite.ImagePtr-=iGPUHeight*1024;\r
2216 VRAMWrite.RowsRemaining --;\r
2217\r
2218 if(VRAMWrite.RowsRemaining <= 0)\r
2219 {\r
2220 VRAMWrite.ColsRemaining--;\r
2221 if (VRAMWrite.ColsRemaining <= 0) // last pixel is odd width\r
2222 {\r
2223 gdata=(gdata&0xFFFF)|(((unsigned long)(*VRAMWrite.ImagePtr))<<16);\r
2224 FinishedVRAMWrite();\r
2225 goto ENDVRAM;\r
2226 }\r
2227 VRAMWrite.RowsRemaining = VRAMWrite.Width;\r
2228 VRAMWrite.ImagePtr += 1024 - VRAMWrite.Width;\r
2229 }\r
2230\r
2231 *VRAMWrite.ImagePtr++ = (unsigned short)(gdata>>16);\r
2232 if(VRAMWrite.ImagePtr>=psxVuw_eom) VRAMWrite.ImagePtr-=iGPUHeight*1024;\r
2233 VRAMWrite.RowsRemaining --;\r
2234 }\r
2235\r
2236 VRAMWrite.RowsRemaining = VRAMWrite.Width;\r
2237 VRAMWrite.ColsRemaining--;\r
2238 VRAMWrite.ImagePtr += 1024 - VRAMWrite.Width;\r
2239 }\r
2240\r
2241 FinishedVRAMWrite();\r
2242 }\r
2243\r
2244ENDVRAM:\r
2245\r
2246if(iDataWriteMode==DR_NORMAL)\r
2247 {\r
2248 void (* *primFunc)(u8 *);\r
2249 if(bSkipNextFrame) primFunc=primTableSkip;\r
2250 else primFunc=primTableJ;\r
2251\r
2252 for(;i<iSize;)\r
2253 {\r
2254 if(iDataWriteMode==DR_VRAMTRANSFER) goto STARTVRAM;\r
2255\r
2256 gdata=*pMem++;i++;\r
2257\r
2258 if(gpuDataC == 0)\r
2259 {\r
2260 command = (u8)((gdata>>24) & 0xff);\r
2261\r
2262 if(primTableCX[command])\r
2263 {\r
2264 gpuDataC = primTableCX[command];\r
2265 gpuCommand = command;\r
2266 gpuDataM[0] = gdata;\r
2267 gpuDataP = 1;\r
2268 }\r
2269 else continue;\r
2270 }\r
2271 else\r
2272 {\r
2273 gpuDataM[gpuDataP] = gdata;\r
2274 if(gpuDataC>128)\r
2275 {\r
2276 if((gpuDataC==254 && gpuDataP>=3) ||\r
2277 (gpuDataC==255 && gpuDataP>=4 && !(gpuDataP&1)))\r
2278 {\r
2279 if((gpuDataM[gpuDataP] & 0xF000F000) == 0x50005000)\r
2280 gpuDataP=gpuDataC-1;\r
2281 }\r
2282 }\r
2283 gpuDataP++;\r
2284 }\r
2285\r
2286 if(gpuDataP == gpuDataC)\r
2287 {\r
2288 gpuDataC=gpuDataP=0;\r
2289 primFunc[gpuCommand]((u8 *)gpuDataM);\r
2290\r
2291 if(dwEmuFixes&0x0001 || dwActFixes&0x20000) // hack for emulating "gpu busy" in some games\r
2292 iFakePrimBusy=4;\r
2293 }\r
2294 } \r
2295 }\r
2296\r
2297GPUdataRet=gdata;\r
2298\r
2299GPUIsReadyForCommands;\r
2300GPUIsIdle; \r
2301}\r
2302\r
2303////////////////////////////////////////////////////////////////////////\r
2304\r
2305#ifdef _WINDOWS\r
2306void CALLBACK GPUwriteData(unsigned long gdata)\r
2307#else\r
7eadbf88 2308void CALLBACK GPUwriteData(unsigned long gdata)\r
ce879073 2309#endif\r
2310{\r
2311#ifdef _WINDOWS\r
2312 GPUwriteDataMem(&gdata,1);\r
2313#else\r
7eadbf88 2314 GPUwriteDataMem(&gdata,1);\r
ce879073 2315#endif \r
2316}\r
2317\r
2318////////////////////////////////////////////////////////////////////////\r
2319// this function will be removed soon (or 'soonish') (or never)\r
2320////////////////////////////////////////////////////////////////////////\r
2321\r
2322void CALLBACK GPUsetMode(unsigned int gdata)\r
2323{\r
2324 // ignore old psemu setmode:\r
2325\r
2326 // imageTransfer = gdata;\r
2327 // iDataWriteMode=(gdata&1)?DR_VRAMTRANSFER:DR_NORMAL;\r
2328 // iDataReadMode =(gdata&2)?DR_VRAMTRANSFER:DR_NORMAL;\r
2329}\r
2330\r
2331// and this function will be removed soon as well, hehehe...\r
2332long CALLBACK GPUgetMode(void)\r
2333{\r
2334 // ignore old psemu setmode\r
2335 // return imageTransfer;\r
2336\r
2337long iT=0;\r
2338\r
2339if(iDataWriteMode==DR_VRAMTRANSFER) iT|=0x1;\r
2340if(iDataReadMode ==DR_VRAMTRANSFER) iT|=0x2;\r
2341\r
2342return iT;\r
2343}\r
2344\r
2345////////////////////////////////////////////////////////////////////////\r
2346// call config dlg (Windows + Linux)\r
2347////////////////////////////////////////////////////////////////////////\r
2348\r
2349#ifndef _WINDOWS\r
2350\r
2351/*#include <unistd.h>\r
2352\r
2353void StartCfgTool(s8 * pCmdLine) // linux: start external cfg tool\r
2354{\r
2355 FILE * cf;s8 filename[255],t[255];\r
2356\r
2357 strcpy(filename,"cfg/cfgPeopsMesaGL"); // look in cfg sub folder first\r
2358 cf=fopen(filename,"rb");\r
2359 if(cf!=NULL)\r
2360 {\r
2361 fclose(cf);\r
2362 getcwd(t,255);\r
2363 chdir("cfg");\r
2364 sprintf(filename,"./cfgPeopsMesaGL %s",pCmdLine);\r
2365 system(filename);\r
2366 chdir(t);\r
2367 }\r
2368 else\r
2369 {\r
2370 strcpy(filename,"cfgPeopsMesaGL"); // look in current folder\r
2371 cf=fopen(filename,"rb");\r
2372 if(cf!=NULL)\r
2373 {\r
2374 fclose(cf);\r
2375 sprintf(filename,"./cfgPeopsMesaGL %s",pCmdLine);\r
2376 system(filename);\r
2377 }\r
2378 else\r
2379 {\r
2380 sprintf(filename,"%s/cfgPeopsMesaGL",getenv("HOME")); // look in home folder\r
2381 cf=fopen(filename,"rb");\r
2382 if(cf!=NULL)\r
2383 {\r
2384 fclose(cf);\r
2385 getcwd(t,255);\r
2386 chdir(getenv("HOME"));\r
2387 sprintf(filename,"./cfgPeopsMesaGL %s",pCmdLine);\r
2388 system(filename);\r
2389 chdir(t);\r
2390 }\r
2391 else printf("cfgPeopsMesaGL not found!\n");\r
2392 }\r
2393 }\r
2394}\r
2395*/\r
2396#endif\r
2397\r
2398\r
2399#ifdef _WINDOWS\r
2400long CALLBACK GPUconfigure(void)\r
2401#else\r
7eadbf88 2402long CALLBACK GPUconfigure(void)\r
ce879073 2403#endif\r
2404{\r
2405\r
2406#ifdef _WINDOWS\r
2407// HWND hWP=GetActiveWindow();\r
2408// DialogBox(hInst,MAKEINTRESOURCE(IDD_CFGDLG),\r
2409// hWP,(DLGPROC)CfgDlgProc);\r
2410#else\r
2411\r
2412// StartCfgTool("CFG");\r
2413\r
2414#endif\r
2415\r
2416 return 0;\r
2417}\r
2418\r
2419////////////////////////////////////////////////////////////////////////\r
2420// sets all kind of act fixes\r
2421////////////////////////////////////////////////////////////////////////\r
2422\r
2423void SetFixes(void)\r
2424{\r
2425 ReInitFrameCap();\r
2426\r
2427 if(dwActFixes & 0x2000) \r
2428 dispWidths[4]=384;\r
2429 else dispWidths[4]=368;\r
2430}\r
2431\r
2432////////////////////////////////////////////////////////////////////////\r
2433// Pete Special: make an 'intelligent' dma chain check (<-Tekken3)\r
2434////////////////////////////////////////////////////////////////////////\r
2435\r
2436unsigned long lUsedAddr[3];\r
2437\r
2438__inline BOOL CheckForEndlessLoop(unsigned long laddr)\r
2439{\r
2440if(laddr==lUsedAddr[1]) return TRUE;\r
2441if(laddr==lUsedAddr[2]) return TRUE;\r
2442\r
2443if(laddr<lUsedAddr[0]) lUsedAddr[1]=laddr;\r
2444else lUsedAddr[2]=laddr;\r
2445lUsedAddr[0]=laddr;\r
2446return FALSE;\r
2447}\r
2448\r
2449////////////////////////////////////////////////////////////////////////\r
2450// core gives a dma chain to gpu: same as the gpuwrite interface funcs\r
2451////////////////////////////////////////////////////////////////////////\r
2452\r
2453#ifdef _WINDOWS\r
2454long CALLBACK GPUdmaChain(unsigned long * baseAddrL, unsigned long addr)\r
2455#else\r
7eadbf88 2456long CALLBACK GPUdmaChain(unsigned long * baseAddrL, unsigned long addr)\r
ce879073 2457#endif\r
2458{\r
2459unsigned long dmaMem;\r
2460u8 * baseAddrB;\r
2461short count;unsigned int DMACommandCounter = 0;\r
2462\r
2463if(bIsFirstFrame) GLinitialize();\r
2464\r
2465GPUIsBusy;\r
2466\r
2467lUsedAddr[0]=lUsedAddr[1]=lUsedAddr[2]=0xffffff;\r
2468\r
2469baseAddrB = (u8*) baseAddrL;\r
2470\r
2471do\r
2472 {\r
2473 if(iGPUHeight==512) addr&=0x1FFFFC;\r
2474\r
2475 if(DMACommandCounter++ > 2000000) break;\r
2476 if(CheckForEndlessLoop(addr)) break;\r
2477\r
2478 count = baseAddrB[addr+3];\r
2479\r
2480 dmaMem=addr+4;\r
2481\r
2482#ifdef _WINDOWS\r
2483 if(count>0) GPUwriteDataMem(&baseAddrL[dmaMem>>2],count);\r
2484#else\r
7eadbf88 2485 if(count>0) GPUwriteDataMem(&baseAddrL[dmaMem>>2],count);\r
ce879073 2486#endif\r
2487 \r
2488 addr = baseAddrL[addr>>2]&0xffffff;\r
2489 }\r
2490while (addr != 0xffffff);\r
2491\r
2492GPUIsIdle;\r
2493\r
2494return 0;\r
2495}\r
2496 \r
2497////////////////////////////////////////////////////////////////////////\r
2498// show about dlg\r
2499////////////////////////////////////////////////////////////////////////\r
2500\r
2501#ifdef _WINDOWS\r
2502void CALLBACK GPUabout(void)\r
2503#else\r
7eadbf88 2504void CALLBACK GPUabout(void)\r
ce879073 2505#endif\r
2506{\r
2507\r
2508}\r
2509\r
2510////////////////////////////////////////////////////////////////////////\r
2511// We are ever fine ;)\r
2512////////////////////////////////////////////////////////////////////////\r
2513\r
2514#ifdef _WINDOWS\r
2515long CALLBACK GPUtest(void)\r
2516#else\r
7eadbf88 2517long CALLBACK GPUtest(void)\r
ce879073 2518#endif\r
2519{\r
2520 // if test fails this function should return negative value for error (unable to continue)\r
2521 // and positive value for warning (can continue but output might be crappy)\r
2522\r
2523 return 0;\r
2524}\r
2525\r
2526////////////////////////////////////////////////////////////////////////\r
2527// save state funcs\r
2528////////////////////////////////////////////////////////////////////////\r
2529\r
2530////////////////////////////////////////////////////////////////////////\r
2531\r
2532#ifdef _WINDOWS\r
2533long CALLBACK GPUfreeze(unsigned long ulGetFreezeData,GPUFreeze_t * pF)\r
2534#else\r
7eadbf88 2535long CALLBACK GPUfreeze(unsigned long ulGetFreezeData,GPUFreeze_t * pF)\r
ce879073 2536#endif\r
2537{\r
2538if(ulGetFreezeData==2) \r
2539 {\r
2540 long lSlotNum=*((long *)pF);\r
2541 if(lSlotNum<0) return 0;\r
2542 if(lSlotNum>8) return 0;\r
2543 lSelectedSlot=lSlotNum+1;\r
2544 return 1;\r
2545 }\r
2546\r
2547if(!pF) return 0; \r
2548if(pF->ulFreezeVersion!=1) return 0;\r
2549\r
2550if(ulGetFreezeData==1)\r
2551 {\r
2552 pF->ulStatus=STATUSREG;\r
2553 memcpy(pF->ulControl,ulStatusControl,256*sizeof(unsigned long));\r
2554 memcpy(pF->psxVRam, psxVub, 1024*iGPUHeight*2);\r
2555\r
2556 return 1;\r
2557 }\r
2558\r
2559if(ulGetFreezeData!=0) return 0;\r
2560\r
2561STATUSREG=pF->ulStatus;\r
2562memcpy(ulStatusControl,pF->ulControl,256*sizeof(unsigned long));\r
2563memcpy(psxVub, pF->psxVRam, 1024*iGPUHeight*2);\r
2564\r
2565ResetTextureArea(TRUE);\r
2566\r
2567#ifdef _WINDOWS\r
2568 GPUwriteStatus(ulStatusControl[0]);\r
2569 GPUwriteStatus(ulStatusControl[1]);\r
2570 GPUwriteStatus(ulStatusControl[2]);\r
2571 GPUwriteStatus(ulStatusControl[3]);\r
2572 GPUwriteStatus(ulStatusControl[8]);\r
2573 GPUwriteStatus(ulStatusControl[6]);\r
2574 GPUwriteStatus(ulStatusControl[7]);\r
2575 GPUwriteStatus(ulStatusControl[5]);\r
2576 GPUwriteStatus(ulStatusControl[4]);\r
2577#else\r
7eadbf88 2578 GPUwriteStatus(ulStatusControl[0]);\r
2579 GPUwriteStatus(ulStatusControl[1]);\r
2580 GPUwriteStatus(ulStatusControl[2]);\r
2581 GPUwriteStatus(ulStatusControl[3]);\r
2582 GPUwriteStatus(ulStatusControl[8]);\r
2583 GPUwriteStatus(ulStatusControl[6]);\r
2584 GPUwriteStatus(ulStatusControl[7]);\r
2585 GPUwriteStatus(ulStatusControl[5]);\r
2586 GPUwriteStatus(ulStatusControl[4]);\r
ce879073 2587#endif\r
2588 return 1;\r
2589}\r
2590\r
2591////////////////////////////////////////////////////////////////////////\r
2592// special "emu infos" / "emu effects" functions\r
2593////////////////////////////////////////////////////////////////////////\r
2594\r
2595//00 = black\r
2596//01 = white\r
2597//10 = red\r
2598//11 = transparent\r
2599\r
2600u8 cFont[10][120]=\r
2601{\r
2602// 0\r
2603{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
2604 0x80,0x00,0x00,0x00,0x00,0x00,\r
2605 0x80,0x00,0x00,0x00,0x00,0x00,\r
2606 0x80,0x00,0x00,0x00,0x00,0x00,\r
2607 0x80,0x00,0x00,0x00,0x00,0x00,\r
2608 0x80,0x00,0x05,0x54,0x00,0x00,\r
2609 0x80,0x00,0x14,0x05,0x00,0x00,\r
2610 0x80,0x00,0x14,0x05,0x00,0x00,\r
2611 0x80,0x00,0x14,0x05,0x00,0x00,\r
2612 0x80,0x00,0x14,0x05,0x00,0x00,\r
2613 0x80,0x00,0x14,0x05,0x00,0x00,\r
2614 0x80,0x00,0x14,0x05,0x00,0x00,\r
2615 0x80,0x00,0x14,0x05,0x00,0x00,\r
2616 0x80,0x00,0x14,0x05,0x00,0x00,\r
2617 0x80,0x00,0x05,0x54,0x00,0x00,\r
2618 0x80,0x00,0x00,0x00,0x00,0x00,\r
2619 0x80,0x00,0x00,0x00,0x00,0x00,\r
2620 0x80,0x00,0x00,0x00,0x00,0x00,\r
2621 0x80,0x00,0x00,0x00,0x00,0x00,\r
2622 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
2623},\r
2624// 1\r
2625{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
2626 0x80,0x00,0x00,0x00,0x00,0x00,\r
2627 0x80,0x00,0x00,0x00,0x00,0x00,\r
2628 0x80,0x00,0x00,0x00,0x00,0x00,\r
2629 0x80,0x00,0x00,0x00,0x00,0x00,\r
2630 0x80,0x00,0x00,0x50,0x00,0x00,\r
2631 0x80,0x00,0x05,0x50,0x00,0x00,\r
2632 0x80,0x00,0x00,0x50,0x00,0x00,\r
2633 0x80,0x00,0x00,0x50,0x00,0x00,\r
2634 0x80,0x00,0x00,0x50,0x00,0x00,\r
2635 0x80,0x00,0x00,0x50,0x00,0x00,\r
2636 0x80,0x00,0x00,0x50,0x00,0x00,\r
2637 0x80,0x00,0x00,0x50,0x00,0x00,\r
2638 0x80,0x00,0x00,0x50,0x00,0x00,\r
2639 0x80,0x00,0x05,0x55,0x00,0x00,\r
2640 0x80,0x00,0x00,0x00,0x00,0x00,\r
2641 0x80,0x00,0x00,0x00,0x00,0x00,\r
2642 0x80,0x00,0x00,0x00,0x00,0x00,\r
2643 0x80,0x00,0x00,0x00,0x00,0x00,\r
2644 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
2645},\r
2646// 2\r
2647{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
2648 0x80,0x00,0x00,0x00,0x00,0x00,\r
2649 0x80,0x00,0x00,0x00,0x00,0x00,\r
2650 0x80,0x00,0x00,0x00,0x00,0x00,\r
2651 0x80,0x00,0x00,0x00,0x00,0x00,\r
2652 0x80,0x00,0x05,0x54,0x00,0x00,\r
2653 0x80,0x00,0x14,0x05,0x00,0x00,\r
2654 0x80,0x00,0x00,0x05,0x00,0x00,\r
2655 0x80,0x00,0x00,0x05,0x00,0x00,\r
2656 0x80,0x00,0x00,0x14,0x00,0x00,\r
2657 0x80,0x00,0x00,0x50,0x00,0x00,\r
2658 0x80,0x00,0x01,0x40,0x00,0x00,\r
2659 0x80,0x00,0x05,0x00,0x00,0x00,\r
2660 0x80,0x00,0x14,0x00,0x00,0x00,\r
2661 0x80,0x00,0x15,0x55,0x00,0x00,\r
2662 0x80,0x00,0x00,0x00,0x00,0x00,\r
2663 0x80,0x00,0x00,0x00,0x00,0x00,\r
2664 0x80,0x00,0x00,0x00,0x00,0x00,\r
2665 0x80,0x00,0x00,0x00,0x00,0x00,\r
2666 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
2667},\r
2668// 3\r
2669{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
2670 0x80,0x00,0x00,0x00,0x00,0x00,\r
2671 0x80,0x00,0x00,0x00,0x00,0x00,\r
2672 0x80,0x00,0x00,0x00,0x00,0x00,\r
2673 0x80,0x00,0x00,0x00,0x00,0x00,\r
2674 0x80,0x00,0x05,0x54,0x00,0x00,\r
2675 0x80,0x00,0x14,0x05,0x00,0x00,\r
2676 0x80,0x00,0x00,0x05,0x00,0x00,\r
2677 0x80,0x00,0x00,0x05,0x00,0x00,\r
2678 0x80,0x00,0x01,0x54,0x00,0x00,\r
2679 0x80,0x00,0x00,0x05,0x00,0x00,\r
2680 0x80,0x00,0x00,0x05,0x00,0x00,\r
2681 0x80,0x00,0x00,0x05,0x00,0x00,\r
2682 0x80,0x00,0x14,0x05,0x00,0x00,\r
2683 0x80,0x00,0x05,0x54,0x00,0x00,\r
2684 0x80,0x00,0x00,0x00,0x00,0x00,\r
2685 0x80,0x00,0x00,0x00,0x00,0x00,\r
2686 0x80,0x00,0x00,0x00,0x00,0x00,\r
2687 0x80,0x00,0x00,0x00,0x00,0x00,\r
2688 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
2689},\r
2690// 4\r
2691{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
2692 0x80,0x00,0x00,0x00,0x00,0x00,\r
2693 0x80,0x00,0x00,0x00,0x00,0x00,\r
2694 0x80,0x00,0x00,0x00,0x00,0x00,\r
2695 0x80,0x00,0x00,0x00,0x00,0x00,\r
2696 0x80,0x00,0x00,0x14,0x00,0x00,\r
2697 0x80,0x00,0x00,0x54,0x00,0x00,\r
2698 0x80,0x00,0x01,0x54,0x00,0x00,\r
2699 0x80,0x00,0x01,0x54,0x00,0x00,\r
2700 0x80,0x00,0x05,0x14,0x00,0x00,\r
2701 0x80,0x00,0x14,0x14,0x00,0x00,\r
2702 0x80,0x00,0x15,0x55,0x00,0x00,\r
2703 0x80,0x00,0x00,0x14,0x00,0x00,\r
2704 0x80,0x00,0x00,0x14,0x00,0x00,\r
2705 0x80,0x00,0x00,0x55,0x00,0x00,\r
2706 0x80,0x00,0x00,0x00,0x00,0x00,\r
2707 0x80,0x00,0x00,0x00,0x00,0x00,\r
2708 0x80,0x00,0x00,0x00,0x00,0x00,\r
2709 0x80,0x00,0x00,0x00,0x00,0x00,\r
2710 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
2711},\r
2712// 5\r
2713{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
2714 0x80,0x00,0x00,0x00,0x00,0x00,\r
2715 0x80,0x00,0x00,0x00,0x00,0x00,\r
2716 0x80,0x00,0x00,0x00,0x00,0x00,\r
2717 0x80,0x00,0x00,0x00,0x00,0x00,\r
2718 0x80,0x00,0x15,0x55,0x00,0x00,\r
2719 0x80,0x00,0x14,0x00,0x00,0x00,\r
2720 0x80,0x00,0x14,0x00,0x00,0x00,\r
2721 0x80,0x00,0x14,0x00,0x00,0x00,\r
2722 0x80,0x00,0x15,0x54,0x00,0x00,\r
2723 0x80,0x00,0x00,0x05,0x00,0x00,\r
2724 0x80,0x00,0x00,0x05,0x00,0x00,\r
2725 0x80,0x00,0x00,0x05,0x00,0x00,\r
2726 0x80,0x00,0x14,0x05,0x00,0x00,\r
2727 0x80,0x00,0x05,0x54,0x00,0x00,\r
2728 0x80,0x00,0x00,0x00,0x00,0x00,\r
2729 0x80,0x00,0x00,0x00,0x00,0x00,\r
2730 0x80,0x00,0x00,0x00,0x00,0x00,\r
2731 0x80,0x00,0x00,0x00,0x00,0x00,\r
2732 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
2733},\r
2734// 6\r
2735{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
2736 0x80,0x00,0x00,0x00,0x00,0x00,\r
2737 0x80,0x00,0x00,0x00,0x00,0x00,\r
2738 0x80,0x00,0x00,0x00,0x00,0x00,\r
2739 0x80,0x00,0x00,0x00,0x00,0x00,\r
2740 0x80,0x00,0x01,0x54,0x00,0x00,\r
2741 0x80,0x00,0x05,0x00,0x00,0x00,\r
2742 0x80,0x00,0x14,0x00,0x00,0x00,\r
2743 0x80,0x00,0x14,0x00,0x00,0x00,\r
2744 0x80,0x00,0x15,0x54,0x00,0x00,\r
2745 0x80,0x00,0x15,0x05,0x00,0x00,\r
2746 0x80,0x00,0x14,0x05,0x00,0x00,\r
2747 0x80,0x00,0x14,0x05,0x00,0x00,\r
2748 0x80,0x00,0x14,0x05,0x00,0x00,\r
2749 0x80,0x00,0x05,0x54,0x00,0x00,\r
2750 0x80,0x00,0x00,0x00,0x00,0x00,\r
2751 0x80,0x00,0x00,0x00,0x00,0x00,\r
2752 0x80,0x00,0x00,0x00,0x00,0x00,\r
2753 0x80,0x00,0x00,0x00,0x00,0x00,\r
2754 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
2755},\r
2756// 7\r
2757{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
2758 0x80,0x00,0x00,0x00,0x00,0x00,\r
2759 0x80,0x00,0x00,0x00,0x00,0x00,\r
2760 0x80,0x00,0x00,0x00,0x00,0x00,\r
2761 0x80,0x00,0x00,0x00,0x00,0x00,\r
2762 0x80,0x00,0x15,0x55,0x00,0x00,\r
2763 0x80,0x00,0x14,0x05,0x00,0x00,\r
2764 0x80,0x00,0x00,0x14,0x00,0x00,\r
2765 0x80,0x00,0x00,0x14,0x00,0x00,\r
2766 0x80,0x00,0x00,0x50,0x00,0x00,\r
2767 0x80,0x00,0x00,0x50,0x00,0x00,\r
2768 0x80,0x00,0x01,0x40,0x00,0x00,\r
2769 0x80,0x00,0x01,0x40,0x00,0x00,\r
2770 0x80,0x00,0x05,0x00,0x00,0x00,\r
2771 0x80,0x00,0x05,0x00,0x00,0x00,\r
2772 0x80,0x00,0x00,0x00,0x00,0x00,\r
2773 0x80,0x00,0x00,0x00,0x00,0x00,\r
2774 0x80,0x00,0x00,0x00,0x00,0x00,\r
2775 0x80,0x00,0x00,0x00,0x00,0x00,\r
2776 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
2777},\r
2778// 8\r
2779{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
2780 0x80,0x00,0x00,0x00,0x00,0x00,\r
2781 0x80,0x00,0x00,0x00,0x00,0x00,\r
2782 0x80,0x00,0x00,0x00,0x00,0x00,\r
2783 0x80,0x00,0x00,0x00,0x00,0x00,\r
2784 0x80,0x00,0x05,0x54,0x00,0x00,\r
2785 0x80,0x00,0x14,0x05,0x00,0x00,\r
2786 0x80,0x00,0x14,0x05,0x00,0x00,\r
2787 0x80,0x00,0x14,0x05,0x00,0x00,\r
2788 0x80,0x00,0x05,0x54,0x00,0x00,\r
2789 0x80,0x00,0x14,0x05,0x00,0x00,\r
2790 0x80,0x00,0x14,0x05,0x00,0x00,\r
2791 0x80,0x00,0x14,0x05,0x00,0x00,\r
2792 0x80,0x00,0x14,0x05,0x00,0x00,\r
2793 0x80,0x00,0x05,0x54,0x00,0x00,\r
2794 0x80,0x00,0x00,0x00,0x00,0x00,\r
2795 0x80,0x00,0x00,0x00,0x00,0x00,\r
2796 0x80,0x00,0x00,0x00,0x00,0x00,\r
2797 0x80,0x00,0x00,0x00,0x00,0x00,\r
2798 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
2799},\r
2800// 9\r
2801{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
2802 0x80,0x00,0x00,0x00,0x00,0x00,\r
2803 0x80,0x00,0x00,0x00,0x00,0x00,\r
2804 0x80,0x00,0x00,0x00,0x00,0x00,\r
2805 0x80,0x00,0x00,0x00,0x00,0x00,\r
2806 0x80,0x00,0x05,0x54,0x00,0x00,\r
2807 0x80,0x00,0x14,0x05,0x00,0x00,\r
2808 0x80,0x00,0x14,0x05,0x00,0x00,\r
2809 0x80,0x00,0x14,0x05,0x00,0x00,\r
2810 0x80,0x00,0x14,0x15,0x00,0x00,\r
2811 0x80,0x00,0x05,0x55,0x00,0x00,\r
2812 0x80,0x00,0x00,0x05,0x00,0x00,\r
2813 0x80,0x00,0x00,0x05,0x00,0x00,\r
2814 0x80,0x00,0x00,0x14,0x00,0x00,\r
2815 0x80,0x00,0x05,0x50,0x00,0x00,\r
2816 0x80,0x00,0x00,0x00,0x00,0x00,\r
2817 0x80,0x00,0x00,0x00,0x00,0x00,\r
2818 0x80,0x00,0x00,0x00,0x00,0x00,\r
2819 0x80,0x00,0x00,0x00,0x00,0x00,\r
2820 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
2821}\r
2822};\r
2823\r
2824////////////////////////////////////////////////////////////////////////\r
2825\r
2826void PaintPicDot(u8 * p,u8 c)\r
2827{\r
2828 if(c==0) {*p++=0x00;*p++=0x00;*p=0x00;return;}\r
2829 if(c==1) {*p++=0xff;*p++=0xff;*p=0xff;return;}\r
2830 if(c==2) {*p++=0x00;*p++=0x00;*p=0xff;return;}\r
2831}\r
2832\r
2833////////////////////////////////////////////////////////////////////////\r
2834\r
2835#ifdef _WINDOWS\r
2836void CALLBACK GPUgetScreenPic(u8 * pMem)\r
2837#else\r
7eadbf88 2838long CALLBACK GPUgetScreenPic(u8 * pMem)\r
ce879073 2839#endif\r
2840{\r
2841 float XS,YS;int x,y,v;\r
2842 u8 * ps, * px, * pf;\r
2843 u8 c;\r
2844\r
2845 if(!pGfxCardScreen)\r
2846 {\r
2847 glPixelStorei(GL_PACK_ALIGNMENT,1);\r
2848 pGfxCardScreen=(u8 *)malloc(iResX*iResY*4);\r
2849 }\r
2850\r
2851 ps=pGfxCardScreen;\r
2852\r
2853// glReadBuffer(GL_FRONT);\r
2854\r
2855 glReadPixels(0,0,iResX,iResY,GL_RGB,GL_UNSIGNED_BYTE,ps);\r
2856 \r
2857// glReadBuffer(GL_BACK);\r
2858\r
2859 XS=(float)iResX/128;\r
2860 YS=(float)iResY/96;\r
2861 pf=pMem;\r
2862\r
2863 for(y=96;y>0;y--)\r
2864 {\r
2865 for(x=0;x<128;x++)\r
2866 {\r
2867 px=ps+(3*((int)((float)x * XS))+\r
2868 (3*iResX)*((int)((float)y*YS)));\r
2869 *(pf+0)=*(px+2);\r
2870 *(pf+1)=*(px+1);\r
2871 *(pf+2)=*(px+0);\r
2872 pf+=3;\r
2873 }\r
2874 }\r
2875\r
2876 /////////////////////////////////////////////////////////////////////\r
2877 // generic number/border painter\r
2878\r
2879 pf=pMem+(103*3);\r
2880\r
2881 for(y=0;y<20;y++)\r
2882 {\r
2883 for(x=0;x<6;x++)\r
2884 {\r
2885 c=cFont[lSelectedSlot][x+y*6];\r
2886 v=(c&0xc0)>>6;\r
2887 PaintPicDot(pf,(u8)v);pf+=3; // paint the dots into the rect\r
2888 v=(c&0x30)>>4;\r
2889 PaintPicDot(pf,(u8)v);pf+=3;\r
2890 v=(c&0x0c)>>2;\r
2891 PaintPicDot(pf,(u8)v);pf+=3;\r
2892 v=c&0x03;\r
2893 PaintPicDot(pf,(u8)v);pf+=3;\r
2894 }\r
2895 pf+=104*3;\r
2896 }\r
2897\r
2898 pf=pMem;\r
2899 for(x=0;x<128;x++)\r
2900 {\r
2901 *(pf+(95*128*3))=0x00;*pf++=0x00;\r
2902 *(pf+(95*128*3))=0x00;*pf++=0x00;\r
2903 *(pf+(95*128*3))=0xff;*pf++=0xff;\r
2904 }\r
2905 pf=pMem;\r
2906 for(y=0;y<96;y++)\r
2907 {\r
2908 *(pf+(127*3))=0x00;*pf++=0x00;\r
2909 *(pf+(127*3))=0x00;*pf++=0x00;\r
2910 *(pf+(127*3))=0xff;*pf++=0xff;\r
2911 pf+=127*3;\r
2912 }\r
2913\r
2914}\r
2915\r
2916////////////////////////////////////////////////////////////////////////\r
2917\r
2918#ifdef _WINDOWS\r
2919void CALLBACK GPUshowScreenPic(u8 * pMem)\r
2920#else\r
7eadbf88 2921long CALLBACK GPUshowScreenPic(u8 * pMem)\r
ce879073 2922#endif\r
2923{\r
2924// DestroyPic();\r
2925// if(pMem==0) return;\r
2926// CreatePic(pMem);\r
2927}\r
2928\r
2929////////////////////////////////////////////////////////////////////////\r
2930\r
2931void CALLBACK GPUsetfix(unsigned long dwFixBits)\r
2932{\r
2933 dwEmuFixes=dwFixBits;\r
2934}\r
2935\r
2936////////////////////////////////////////////////////////////////////////\r
2937 \r
2938void CALLBACK GPUvisualVibration(unsigned long iSmall, unsigned long iBig)\r
2939{\r
2940 int iVibVal;\r
2941\r
2942 if(PSXDisplay.DisplayModeNew.x) // calc min "shake pixel" from screen width\r
2943 iVibVal=max(1,iResX/PSXDisplay.DisplayModeNew.x);\r
2944 else iVibVal=1;\r
2945 // big rumble: 4...15 sp ; small rumble 1...3 sp\r
2946 if(iBig) iRumbleVal=max(4*iVibVal,min(15*iVibVal,((int)iBig *iVibVal)/10));\r
2947 else iRumbleVal=max(1*iVibVal,min( 3*iVibVal,((int)iSmall*iVibVal)/10));\r
2948\r
2949 srand(timeGetTime()); // init rand (will be used in BufferSwap)\r
2950\r
2951 iRumbleTime=15; // let the rumble last 16 buffer swaps\r
2952}\r
2953 \r
2954////////////////////////////////////////////////////////////////////////\r
2955// main emu can set display infos (A/M/G/D) \r
2956////////////////////////////////////////////////////////////////////////\r
2957\r
2958void CALLBACK GPUdisplayFlags(unsigned long dwFlags)\r
2959{\r
2960// dwCoreFlags=dwFlags;\r
2961}\r