gpu-gles: clean up headers and stuff
[pcsx_rearmed.git] / plugins / gpu-gles / gpuPlugin.c
... / ...
CommitLineData
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
86unsigned char *psxVSecure;\r
87unsigned char *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
115char szDispBuf[64];\r
116\r
117static unsigned long gpuDataM[256];\r
118static unsigned char 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
147unsigned char * 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
157static void (*rearmed_get_layer_pos)(int *x, int *y, int *w, int *h);\r
158\r
159////////////////////////////////////////////////////////////////////////\r
160// stuff to make this a true PDK module\r
161////////////////////////////////////////////////////////////////////////\r
162\r
163#ifdef _WINDOWS\r
164char * CALLBACK PSEgetLibName(void)\r
165{\r
166 return "name";\r
167}\r
168\r
169unsigned long CALLBACK PSEgetLibType(void)\r
170{\r
171 return 1;\r
172}\r
173\r
174unsigned long CALLBACK PSEgetLibVersion(void)\r
175{\r
176 return 1<<16|1<<8|1;\r
177}\r
178#endif\r
179\r
180////////////////////////////////////////////////////////////////////////\r
181// snapshot funcs (saves screen to bitmap / text infos into file)\r
182////////////////////////////////////////////////////////////////////////\r
183\r
184void ResizeWindow()\r
185{\r
186 rRatioRect.left = rRatioRect.top=0;\r
187 rRatioRect.right = iResX;\r
188 rRatioRect.bottom = iResY;\r
189 glViewport(rRatioRect.left, // init viewport by ratio rect\r
190 iResY-(rRatioRect.top+rRatioRect.bottom),\r
191 rRatioRect.right, \r
192 rRatioRect.bottom); \r
193 \r
194 glScissor(0, 0, iResX, iResY); // init clipping (fullscreen)\r
195 glEnable(GL_SCISSOR_TEST); \r
196\r
197#ifndef OWNSCALE\r
198 glMatrixMode(GL_TEXTURE); // init psx tex sow and tow if not "ownscale"\r
199 glLoadIdentity();\r
200 glScalef(1.0f/255.99f,1.0f/255.99f,1.0f); // geforce precision hack\r
201#endif \r
202\r
203 glMatrixMode(GL_PROJECTION); // init projection with psx resolution\r
204 glLoadIdentity();\r
205 glOrtho(0,PSXDisplay.DisplayMode.x,\r
206 PSXDisplay.DisplayMode.y, 0, -1, 1);\r
207 if (bKeepRatio)\r
208 SetAspectRatio();\r
209}\r
210\r
211char * GetConfigInfos(int hW)\r
212{\r
213#ifdef _WINDOWS\r
214 HDC hdc;HGLRC hglrc;\r
215#endif\r
216 char szO[2][4]={"off","on "};\r
217 char szTxt[256];\r
218 char * pB=(char *)malloc(32767);\r
219/*\r
220 if(!pB) return NULL;\r
221 *pB=0;\r
222 //----------------------------------------------------//\r
223 strcat(pB,szTxt);\r
224 strcat(pB,szTxt);\r
225#ifdef _WINDOWS\r
226 if(hW)\r
227 {\r
228 hdc = GetDC(hW);\r
229 bSetupPixelFormat(hdc);\r
230 hglrc = wglCreateContext(hdc);\r
231 wglMakeCurrent(hdc, hglrc);\r
232 }\r
233#endif\r
234 sprintf(szTxt,"Card vendor: %s\r\n",(char *)glGetString(GL_VENDOR));\r
235 strcat(pB,szTxt);\r
236 sprintf(szTxt,"GFX card: %s\r\n",(char *)glGetString(GL_RENDERER));\r
237 strcat(pB,szTxt);\r
238 sprintf(szTxt,"OGL version: %s\r\n\r\n",(char *)glGetString(GL_VERSION));\r
239 strcat(pB,szTxt);\r
240 //strcat(pB,(char *)glGetString(GL_EXTENSIONS));\r
241 //strcat(pB,"\r\n\r\n");\r
242\r
243#ifdef _WINDOWS\r
244 if(hW)\r
245 {\r
246 wglMakeCurrent(NULL, NULL);\r
247 wglDeleteContext(hglrc);\r
248 ReleaseDC(hW,hdc);\r
249 }\r
250 //----------------------------------------------------//\r
251#endif\r
252 if(hW && bWindowMode)\r
253 sprintf(szTxt,"Resolution/Color:\r\n- %dx%d ",LOWORD(iWinSize),HIWORD(iWinSize));\r
254 else\r
255 sprintf(szTxt,"Resolution/Color:\r\n- %dx%d ",iResX,iResY);\r
256 strcat(pB,szTxt);\r
257 if(bWindowMode) sprintf(szTxt,"Window mode\r\n");\r
258 else\r
259 {\r
260 sprintf(szTxt,"Fullscreen ");\r
261 strcat(pB,szTxt);\r
262 if(bChangeRes) sprintf(szTxt,"- Desktop changing [%d Bit]\r\n",iColDepth);\r
263 else sprintf(szTxt,"- NO desktop changing\r\n");\r
264 } \r
265 strcat(pB,szTxt);\r
266\r
267// if(iForceVSync>=0) sprintf(szTxt,"- V-Sync: %s\r\n",szO[iForceVSync]);\r
268// else strcpy(szTxt,"- V-Sync: Driver\r\n");\r
269 strcat(pB,szTxt); \r
270 sprintf(szTxt,"- Keep psx aspect ratio: %s\r\n\r\n",szO[bKeepRatio]);\r
271 strcat(pB,szTxt);\r
272 //----------------------------------------------------//\r
273 strcpy(szTxt,"Textures:\r\n- ");\r
274/*! if(iTexQuality==0) strcat(szTxt,"Default");\r
275 else if(iTexQuality==1) strcat(szTxt,"R4G4B4A4");\r
276 else if(iTexQuality==2) strcat(szTxt,"R5G5B5A1");\r
277 else if(iTexQuality==3) strcat(szTxt,"R8G8A8A8");\r
278 else if(iTexQuality==4) strcat(szTxt,"B8G8R8A8");\r
279 if(!hW && bGLExt) strcat(szTxt," (packed pixels)\r\n");\r
280 else strcat(szTxt,"\r\n");\r
281 strcat(pB,szTxt);\r
282 if(!hW)\r
283 {\r
284 sprintf(szTxt,"- Filtering: %d - edge clamping ",iFilterType);\r
285 if(iClampType==GL_TO_EDGE_CLAMP) strcat(szTxt,"supported\r\n");\r
286 else strcat(szTxt,"NOT supported\r\n");\r
287 }\r
288 else sprintf(szTxt,"- iFiltering: %d\r\n",iFilterType);\r
289 strcat(pB,szTxt);\r
290 sprintf(szTxt,"- Hi-Res textures: %d\r\n",iHiResTextures);\r
291 strcat(pB,szTxt); \r
292 if(!hW)\r
293 {\r
294 sprintf(szTxt,"- Palettized tex windows: %s\r\n",szO[iUsePalTextures]);\r
295 strcat(pB,szTxt); \r
296 }\r
297 !*/\r
298 /*sprintf(szTxt,"- VRam size: %d MBytes",iVRamSize);\r
299 if(!hW)\r
300 sprintf(szTxt+strlen(szTxt)," - %d textures usable\r\n\r\n",iSortTexCnt);\r
301 else strcat(szTxt,"\r\n\r\n");\r
302 strcat(pB,szTxt);\r
303 //----------------------------------------------------//\r
304 sprintf(szTxt,"Framerate:\r\n- FPS limitation: %s\r\n",szO[bUseFrameLimit]);\r
305 strcat(pB,szTxt);\r
306 sprintf(szTxt,"- Frame skipping: %s\r\n",szO[bUseFrameSkip]);\r
307 strcat(pB,szTxt);\r
308 if(iFrameLimit==2)\r
309 strcpy(szTxt,"- FPS limit: Auto\r\n\r\n");\r
310 else sprintf(szTxt,"- FPS limit: %.1f\r\n\r\n",fFrameRate);\r
311 strcat(pB,szTxt);\r
312 //----------------------------------------------------//\r
313 sprintf(szTxt,"Compatibility:\r\n- Offscreen drawing: %d\r\n",iOffscreenDrawing);\r
314 strcat(pB,szTxt);\r
315 sprintf(szTxt,"- Framebuffer texture: %d",iFrameTexType);\r
316 if(!hW && iFrameTexType==2)\r
317 {\r
318 if(gTexFrameName) strcat(szTxt," - texture created\r\n");\r
319 else strcat(szTxt," - not used yet\r\n");\r
320 }\r
321 else strcat(szTxt,"\r\n");\r
322 strcat(pB,szTxt);\r
323 sprintf(szTxt,"- Framebuffer access: %d\r\n",iFrameReadType);\r
324 strcat(pB,szTxt);\r
325// sprintf(szTxt,"- Alpha multipass: %s\r\n",szO[bOpaquePass]);\r
326 strcat(pB,szTxt);\r
327 sprintf(szTxt,"- Mask bit: %s\r\n",szO[iUseMask]);\r
328 strcat(pB,szTxt);\r
329 //sprintf(szTxt,"- Advanced blending: %s",szO[bAdvancedBlend]);\r
330 //if(!hW && bAdvancedBlend)\r
331// {\r
332// if(bGLBlend) strcat(szTxt," (hardware)\r\n");\r
333// else strcat(szTxt," (software)\r\n");\r
334// }\r
335 strcat(szTxt,"\r\n");\r
336 strcat(pB,szTxt);\r
337\r
338 if(!hW)\r
339 {\r
340 strcpy(szTxt,"- Subtractive blending: ");\r
341// if(glBlendEquationEXTEx)\r
342// {\r
343// if(bUseMultiPass) strcat(szTxt,"supported, but not used!");\r
344// else strcat(szTxt,"activated");\r
345// }\r
346 strcat(szTxt," NOT supported!");\r
347 strcat(szTxt,"\r\n\r\n");\r
348 }\r
349 else strcpy(szTxt,"\r\n");\r
350 \r
351 strcat(pB,szTxt); \r
352 //----------------------------------------------------//\r
353 sprintf(szTxt,"Misc:\r\n- Scanlines: %s",szO[iUseScanLines]);\r
354 strcat(pB,szTxt);\r
355 if(iUseScanLines) sprintf(szTxt," [%d]\r\n",iScanBlend);\r
356 else strcpy(szTxt,"\r\n");\r
357 strcat(pB,szTxt);\r
358// sprintf(szTxt,"- Line mode: %s\r\n",szO[bUseLines]);\r
359 strcat(pB,szTxt);\r
360// sprintf(szTxt,"- Line AA: %s\r\n",szO[bUseAntiAlias]);\r
361// fwrite(szTxt,lstrlen(szTxt),1,txtfile);\r
362 sprintf(szTxt,"- Unfiltered FB: %s\r\n",szO[bUseFastMdec]);\r
363 strcat(pB,szTxt);\r
364 sprintf(szTxt,"- 15 bit FB: %s\r\n",szO[bUse15bitMdec]);\r
365 strcat(pB,szTxt);\r
366 sprintf(szTxt,"- Dithering: %s\r\n",szO[bDrawDither]);\r
367 strcat(pB,szTxt);\r
368 sprintf(szTxt,"- Screen smoothing: %s",szO[iBlurBuffer]);\r
369 strcat(pB,szTxt);\r
370 if(!hW && iBlurBuffer) \r
371 {\r
372 if(gTexBlurName) strcat(pB," - supported\r\n");\r
373 else strcat(pB," - not supported\r\n");\r
374 }\r
375 else strcat(pB,"\r\n");\r
376 sprintf(szTxt,"- Game fixes: %s [%08lx]\r\n",szO[bUseFixes],dwCfgFixes);\r
377 strcat(pB,szTxt);\r
378 //----------------------------------------------------//\r
379*/ return pB;\r
380}\r
381\r
382////////////////////////////////////////////////////////////////////////\r
383// save text infos to file\r
384////////////////////////////////////////////////////////////////////////\r
385\r
386void DoTextSnapShot(int iNum)\r
387{\r
388}\r
389\r
390////////////////////////////////////////////////////////////////////////\r
391// saves screen bitmap to file\r
392////////////////////////////////////////////////////////////////////////\r
393\r
394void DoSnapShot(void)\r
395{\r
396} \r
397\r
398#ifdef _WINDOWS\r
399void CALLBACK GPUmakeSnapshot(void)\r
400#else\r
401void CALLBACK GPUmakeSnapshot(void)\r
402#endif\r
403{\r
404 //bSnapShot = TRUE;\r
405} \r
406\r
407////////////////////////////////////////////////////////////////////////\r
408// GPU INIT... here starts it all (first func called by emu)\r
409////////////////////////////////////////////////////////////////////////\r
410\r
411#ifdef _WINDOWS\r
412long CALLBACK GPUinit()\r
413#else\r
414long CALLBACK GPUinit()\r
415#endif\r
416{\r
417memset(ulStatusControl,0,256*sizeof(unsigned long));\r
418\r
419#ifdef _WINDOWS\r
420iResX=240;iResY=320;\r
421#endif\r
422bChangeRes=FALSE;\r
423#ifdef _WINDOWS\r
424bWindowMode=TRUE;\r
425#else\r
426bWindowMode=FALSE;\r
427#endif \r
428#ifdef _WINDOWS\r
429iWinSize=MAKELONG(iResX,iResY);\r
430#endif\r
431\r
432bKeepRatio = TRUE;\r
433// different ways of accessing PSX VRAM\r
434\r
435psxVSecure=(unsigned char *)malloc((iGPUHeight*2)*1024 + (1024*1024)); // always alloc one extra MB for soft drawing funcs security\r
436if(!psxVSecure) return -1;\r
437\r
438psxVub=psxVSecure+512*1024; // security offset into double sized psx vram!\r
439psxVsb=(signed char *)psxVub;\r
440psxVsw=(signed short *)psxVub;\r
441psxVsl=(signed long *)psxVub;\r
442psxVuw=(unsigned short *)psxVub;\r
443psxVul=(unsigned long *)psxVub;\r
444\r
445psxVuw_eom=psxVuw+1024*iGPUHeight; // pre-calc of end of vram\r
446\r
447memset(psxVSecure,0x00,(iGPUHeight*2)*1024 + (1024*1024));\r
448memset(ulGPUInfoVals,0x00,16*sizeof(unsigned long));\r
449\r
450InitFrameCap(); // init frame rate stuff\r
451\r
452PSXDisplay.RGB24 = 0; // init vars\r
453PreviousPSXDisplay.RGB24= 0;\r
454PSXDisplay.Interlaced = 0;\r
455PSXDisplay.InterlacedTest=0;\r
456PSXDisplay.DrawOffset.x = 0;\r
457PSXDisplay.DrawOffset.y = 0;\r
458PSXDisplay.DrawArea.x0 = 0;\r
459PSXDisplay.DrawArea.y0 = 0;\r
460PSXDisplay.DrawArea.x1 = 320;\r
461PSXDisplay.DrawArea.y1 = 240;\r
462PSXDisplay.DisplayMode.x= 320;\r
463PSXDisplay.DisplayMode.y= 240;\r
464PSXDisplay.Disabled = FALSE;\r
465PreviousPSXDisplay.Range.x0 =0;\r
466PreviousPSXDisplay.Range.x1 =0;\r
467PreviousPSXDisplay.Range.y0 =0;\r
468PreviousPSXDisplay.Range.y1 =0;\r
469PSXDisplay.Range.x0=0;\r
470PSXDisplay.Range.x1=0;\r
471PSXDisplay.Range.y0=0;\r
472PSXDisplay.Range.y1=0;\r
473PreviousPSXDisplay.DisplayPosition.x = 1;\r
474PreviousPSXDisplay.DisplayPosition.y = 1;\r
475PSXDisplay.DisplayPosition.x = 1;\r
476PSXDisplay.DisplayPosition.y = 1;\r
477PreviousPSXDisplay.DisplayModeNew.y=0;\r
478PSXDisplay.Double=1;\r
479GPUdataRet=0x400;\r
480\r
481PSXDisplay.DisplayModeNew.x=0;\r
482PSXDisplay.DisplayModeNew.y=0;\r
483\r
484//PreviousPSXDisplay.Height = PSXDisplay.Height = 239;\r
485\r
486iDataWriteMode = DR_NORMAL;\r
487\r
488// Reset transfer values, to prevent mis-transfer of data\r
489memset(&VRAMWrite,0,sizeof(VRAMLoad_t));\r
490memset(&VRAMRead,0,sizeof(VRAMLoad_t));\r
491\r
492// device initialised already !\r
493//lGPUstatusRet = 0x74000000;\r
494\r
495STATUSREG = 0x14802000;\r
496GPUIsIdle;\r
497GPUIsReadyForCommands;\r
498\r
499return 0;\r
500} \r
501\r
502\r
503////////////////////////////////////////////////////////////////////////\r
504// GPU OPEN: funcs to open up the gpu display (Windows)\r
505////////////////////////////////////////////////////////////////////////\r
506\r
507#ifdef _WINDOWS\r
508\r
509void ChangeDesktop() // change destop resolution\r
510{\r
511 DEVMODE dv;long lRes,iTry=0; \r
512\r
513 while(iTry<10) // keep on hammering...\r
514 {\r
515 memset(&dv,0,sizeof(DEVMODE));\r
516 dv.dmSize=sizeof(DEVMODE);\r
517 dv.dmBitsPerPel=iColDepth;\r
518 dv.dmPelsWidth=iResX;\r
519 dv.dmPelsHeight=iResY;\r
520\r
521 dv.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;\r
522\r
523 lRes=ChangeDisplaySettings(&dv,0); // ...hammering the anvil\r
524\r
525 if(lRes==DISP_CHANGE_SUCCESSFUL) return;\r
526 iTry++;Sleep(10);\r
527 }\r
528}\r
529\r
530////////////////////////////////////////////////////////////////////////\r
531// OPEN interface func: attention! \r
532// some emus are calling this func in their main Window thread,\r
533// but all other interface funcs (to draw stuff) in a different thread!\r
534// that's a problem, since OGL is thread safe! Therefore we cannot \r
535// initialize the OGL stuff right here, we simply set a "bIsFirstFrame = TRUE"\r
536// flag, to initialize OGL on the first real draw call.\r
537// btw, we also call this open func ourselfes, each time when the user \r
538// is changing between fullscreen/window mode (ENTER key)\r
539// btw part 2: in windows the plugin gets the window handle from the\r
540// main emu, and doesn't create it's own window (if it would do it,\r
541// some PAD or SPU plugins would not work anymore)\r
542////////////////////////////////////////////////////////////////////////\r
543\r
544HMENU hPSEMenu=NULL;\r
545\r
546long CALLBACK GPUopen(HWND hwndGPU) \r
547#else\r
548long CALLBACK GPUopen(int hwndGPU)\r
549#endif\r
550{\r
551 #ifdef _WINDOWS\r
552 HDC hdc;RECT r;DEVMODE dv;\r
553\r
554 hWWindow = hwndGPU; // store hwnd globally\r
555 #endif\r
556 // InitKeyHandler(); // init key handler (subclass window)\r
557\r
558\r
559\r
560 #ifdef _WINDOWS\r
561 iResX=240;iResY=320;\r
562 #endif\r
563 iResX=800;iResY=480;\r
564 iColDepth=8;\r
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
709long GPUclose() // LINUX CLOSE\r
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
729long CALLBACK GPUshutdown()\r
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
787void GPUvSinc(void){\r
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
1122#if 0\r
1123xs=(float)iResX/(float)PSXDisplay.DisplayModeNew.x;\r
1124ys=(float)iResY/(float)PSXDisplay.DisplayModeNew.y;\r
1125\r
1126s=min(xs,ys);\r
1127r.right =(int)((float)PSXDisplay.DisplayModeNew.x*s);\r
1128r.bottom=(int)((float)PSXDisplay.DisplayModeNew.y*s);\r
1129if(r.right > iResX) r.right = iResX;\r
1130if(r.bottom > iResY) r.bottom = iResY;\r
1131if(r.right < 1) r.right = 1;\r
1132if(r.bottom < 1) r.bottom = 1;\r
1133\r
1134r.left = (iResX-r.right)/2;\r
1135r.top = (iResY-r.bottom)/2;\r
1136\r
1137if(r.bottom<rRatioRect.bottom ||\r
1138 r.right <rRatioRect.right)\r
1139 {\r
1140 RECT rC;\r
1141 glClearColor(0,0,0,128); \r
1142\r
1143 if(r.right <rRatioRect.right)\r
1144 {\r
1145 rC.left=0;\r
1146 rC.top=0;\r
1147 rC.right=r.left;\r
1148 rC.bottom=iResY;\r
1149 glScissor(rC.left,rC.top,rC.right,rC.bottom);\r
1150 glClear(uiBufferBits);\r
1151 rC.left=iResX-rC.right;\r
1152 glScissor(rC.left,rC.top,rC.right,rC.bottom);\r
1153 glClear(uiBufferBits);\r
1154 }\r
1155\r
1156 if(r.bottom <rRatioRect.bottom)\r
1157 {\r
1158 rC.left=0;\r
1159 rC.top=0;\r
1160 rC.right=iResX;\r
1161 rC.bottom=r.top;\r
1162 glScissor(rC.left,rC.top,rC.right,rC.bottom);\r
1163 glClear(uiBufferBits);\r
1164 rC.top=iResY-rC.bottom;\r
1165 glScissor(rC.left,rC.top,rC.right,rC.bottom);\r
1166 glClear(uiBufferBits);\r
1167 }\r
1168 \r
1169 bSetClip=TRUE;\r
1170 bDisplayNotSet=TRUE;\r
1171 }\r
1172\r
1173rRatioRect=r;\r
1174#else\r
1175 // pcsx-rearmed hack\r
1176 if (rearmed_get_layer_pos != NULL)\r
1177 rearmed_get_layer_pos(&rRatioRect.left, &rRatioRect.top, &rRatioRect.right, &rRatioRect.bottom);\r
1178#endif\r
1179\r
1180glViewport(rRatioRect.left,\r
1181 iResY-(rRatioRect.top+rRatioRect.bottom),\r
1182 rRatioRect.right,\r
1183 rRatioRect.bottom); // init viewport\r
1184}\r
1185\r
1186////////////////////////////////////////////////////////////////////////\r
1187// big ass check, if an ogl swap buffer is needed\r
1188////////////////////////////////////////////////////////////////////////\r
1189\r
1190void updateDisplayIfChanged(void)\r
1191{\r
1192BOOL bUp;\r
1193\r
1194if ((PSXDisplay.DisplayMode.y == PSXDisplay.DisplayModeNew.y) && \r
1195 (PSXDisplay.DisplayMode.x == PSXDisplay.DisplayModeNew.x))\r
1196 {\r
1197 if((PSXDisplay.RGB24 == PSXDisplay.RGB24New) && \r
1198 (PSXDisplay.Interlaced == PSXDisplay.InterlacedNew)) \r
1199 return; // nothing has changed? fine, no swap buffer needed\r
1200 }\r
1201else // some res change?\r
1202 {\r
1203 glLoadIdentity();\r
1204 glOrtho(0,PSXDisplay.DisplayModeNew.x, // -> new psx resolution\r
1205 PSXDisplay.DisplayModeNew.y, 0, -1, 1);\r
1206 if(bKeepRatio) SetAspectRatio();\r
1207 }\r
1208\r
1209bDisplayNotSet = TRUE; // re-calc offsets/display area\r
1210\r
1211bUp=FALSE;\r
1212if(PSXDisplay.RGB24!=PSXDisplay.RGB24New) // clean up textures, if rgb mode change (usually mdec on/off)\r
1213 {\r
1214 PreviousPSXDisplay.RGB24=0; // no full 24 frame uploaded yet\r
1215 ResetTextureArea(FALSE);\r
1216 bUp=TRUE;\r
1217 }\r
1218\r
1219PSXDisplay.RGB24 = PSXDisplay.RGB24New; // get new infos\r
1220PSXDisplay.DisplayMode.y = PSXDisplay.DisplayModeNew.y;\r
1221PSXDisplay.DisplayMode.x = PSXDisplay.DisplayModeNew.x;\r
1222PSXDisplay.Interlaced = PSXDisplay.InterlacedNew;\r
1223 \r
1224PSXDisplay.DisplayEnd.x= // calc new ends\r
1225 PSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;\r
1226PSXDisplay.DisplayEnd.y=\r
1227 PSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;\r
1228PreviousPSXDisplay.DisplayEnd.x=\r
1229 PreviousPSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;\r
1230PreviousPSXDisplay.DisplayEnd.y=\r
1231 PreviousPSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;\r
1232\r
1233ChangeDispOffsetsX();\r
1234\r
1235if(iFrameLimit==2) SetAutoFrameCap(); // set new fps limit vals (depends on interlace)\r
1236\r
1237if(bUp) updateDisplay(); // yeah, real update (swap buffer)\r
1238}\r
1239\r
1240////////////////////////////////////////////////////////////////////////\r
1241// window mode <-> fullscreen mode (windows)\r
1242////////////////////////////////////////////////////////////////////////\r
1243\r
1244#ifdef _WINDOWS\r
1245void ChangeWindowMode(void)\r
1246{\r
1247 GPUclose();\r
1248 bWindowMode=!bWindowMode;\r
1249 GPUopen(hWWindow);\r
1250 bChangeWinMode=FALSE;\r
1251}\r
1252#endif\r
1253\r
1254////////////////////////////////////////////////////////////////////////\r
1255// swap update check (called by psx vsync function)\r
1256////////////////////////////////////////////////////////////////////////\r
1257\r
1258BOOL bSwapCheck(void)\r
1259{\r
1260static int iPosCheck=0;\r
1261static PSXPoint_t pO;\r
1262static PSXPoint_t pD;\r
1263static int iDoAgain=0;\r
1264\r
1265if(PSXDisplay.DisplayPosition.x==pO.x &&\r
1266 PSXDisplay.DisplayPosition.y==pO.y &&\r
1267 PSXDisplay.DisplayEnd.x==pD.x &&\r
1268 PSXDisplay.DisplayEnd.y==pD.y)\r
1269 iPosCheck++;\r
1270else iPosCheck=0;\r
1271\r
1272pO=PSXDisplay.DisplayPosition;\r
1273pD=PSXDisplay.DisplayEnd;\r
1274\r
1275if(iPosCheck<=4) return FALSE;\r
1276\r
1277iPosCheck=4;\r
1278\r
1279if(PSXDisplay.Interlaced) return FALSE;\r
1280\r
1281if (bNeedInterlaceUpdate||\r
1282 bNeedRGB24Update ||\r
1283 bNeedUploadAfter|| \r
1284 bNeedUploadTest || \r
1285 iDoAgain\r
1286 )\r
1287 {\r
1288 iDoAgain=0;\r
1289 if(bNeedUploadAfter) \r
1290 iDoAgain=1;\r
1291 if(bNeedUploadTest && PSXDisplay.InterlacedTest)\r
1292 iDoAgain=1;\r
1293\r
1294 bDisplayNotSet = TRUE;\r
1295 updateDisplay();\r
1296\r
1297 PreviousPSXDisplay.DisplayPosition.x=PSXDisplay.DisplayPosition.x;\r
1298 PreviousPSXDisplay.DisplayPosition.y=PSXDisplay.DisplayPosition.y;\r
1299 PreviousPSXDisplay.DisplayEnd.x=PSXDisplay.DisplayEnd.x;\r
1300 PreviousPSXDisplay.DisplayEnd.y=PSXDisplay.DisplayEnd.y;\r
1301 pO=PSXDisplay.DisplayPosition;\r
1302 pD=PSXDisplay.DisplayEnd;\r
1303\r
1304 return TRUE;\r
1305 }\r
1306\r
1307return FALSE;\r
1308} \r
1309////////////////////////////////////////////////////////////////////////\r
1310// gun cursor func: player=0-7, x=0-511, y=0-255\r
1311////////////////////////////////////////////////////////////////////////\r
1312\r
1313////////////////////////////////////////////////////////////////////////\r
1314// update lace is called every VSync. Basically we limit frame rate \r
1315// here, and in interlaced mode we swap ogl display buffers.\r
1316////////////////////////////////////////////////////////////////////////\r
1317\r
1318static unsigned short usFirstPos=2;\r
1319\r
1320#ifdef _WINDOWS\r
1321void CALLBACK GPUupdateLace(void)\r
1322#else\r
1323void CALLBACK GPUupdateLace(void)\r
1324#endif\r
1325{\r
1326if(!(dwActFixes&0x1000)) \r
1327 STATUSREG^=0x80000000; // interlaced bit toggle, if the CC game fix is not active (see gpuReadStatus)\r
1328\r
1329if(!(dwActFixes&128)) // normal frame limit func\r
1330 CheckFrameRate();\r
1331\r
1332if(iOffscreenDrawing==4) // special check if high offscreen drawing is on\r
1333 {\r
1334 if(bSwapCheck()) return;\r
1335 }\r
1336\r
1337if(PSXDisplay.Interlaced) // interlaced mode?\r
1338 {\r
1339 if(PSXDisplay.DisplayMode.x>0 && PSXDisplay.DisplayMode.y>0)\r
1340 {\r
1341 updateDisplay(); // -> swap buffers (new frame)\r
1342 }\r
1343 }\r
1344else if(bRenderFrontBuffer) // no interlace mode? and some stuff in front has changed?\r
1345 {\r
1346 updateFrontDisplay(); // -> update front buffer\r
1347 }\r
1348else if(usFirstPos==1) // initial updates (after startup)\r
1349 {\r
1350 updateDisplay();\r
1351 }\r
1352\r
1353#ifdef _WINDOWS\r
1354if(bChangeWinMode) ChangeWindowMode();\r
1355#endif\r
1356}\r
1357\r
1358////////////////////////////////////////////////////////////////////////\r
1359// process read request from GPU status register\r
1360////////////////////////////////////////////////////////////////////////\r
1361\r
1362#ifdef _WINDOWS\r
1363unsigned long CALLBACK GPUreadStatus(void)\r
1364#else\r
1365unsigned long CALLBACK GPUreadStatus(void)\r
1366#endif\r
1367{\r
1368if(dwActFixes&0x1000) // CC game fix\r
1369 {\r
1370 static int iNumRead=0;\r
1371 if((iNumRead++)==2)\r
1372 {\r
1373 iNumRead=0;\r
1374 STATUSREG^=0x80000000; // interlaced bit toggle... we do it on every second read status... needed by some games (like ChronoCross)\r
1375 }\r
1376 }\r
1377\r
1378if(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
1379 {\r
1380 iFakePrimBusy--;\r
1381\r
1382 if(iFakePrimBusy&1) // we do a busy-idle-busy-idle sequence after/while drawing prims\r
1383 {\r
1384 GPUIsBusy;\r
1385 GPUIsNotReadyForCommands;\r
1386 }\r
1387 else\r
1388 {\r
1389 GPUIsIdle;\r
1390 GPUIsReadyForCommands;\r
1391 }\r
1392 }\r
1393\r
1394return STATUSREG;\r
1395}\r
1396\r
1397////////////////////////////////////////////////////////////////////////\r
1398// processes data send to GPU status register\r
1399// these are always single packet commands.\r
1400////////////////////////////////////////////////////////////////////////\r
1401\r
1402#ifdef _WINDOWS\r
1403void CALLBACK GPUwriteStatus(unsigned long gdata)\r
1404#else\r
1405void CALLBACK GPUwriteStatus(unsigned long gdata)\r
1406#endif\r
1407{\r
1408unsigned long lCommand=(gdata>>24)&0xff;\r
1409\r
1410#ifdef _WINDOWS\r
1411if(bIsFirstFrame) GLinitialize(); // real ogl startup (needed by some emus)\r
1412#endif\r
1413\r
1414ulStatusControl[lCommand]=gdata;\r
1415\r
1416switch(lCommand)\r
1417 {\r
1418 //--------------------------------------------------//\r
1419 // reset gpu\r
1420 case 0x00:\r
1421 memset(ulGPUInfoVals,0x00,16*sizeof(unsigned long));\r
1422 lGPUstatusRet=0x14802000;\r
1423 PSXDisplay.Disabled=1;\r
1424 iDataWriteMode=iDataReadMode=DR_NORMAL;\r
1425 PSXDisplay.DrawOffset.x=PSXDisplay.DrawOffset.y=0;\r
1426 drawX=drawY=0;drawW=drawH=0;\r
1427 sSetMask=0;lSetMask=0;bCheckMask=FALSE;iSetMask=0;\r
1428 usMirror=0;\r
1429 GlobalTextAddrX=0;GlobalTextAddrY=0;\r
1430 GlobalTextTP=0;GlobalTextABR=0;\r
1431 PSXDisplay.RGB24=FALSE;\r
1432 PSXDisplay.Interlaced=FALSE;\r
1433 bUsingTWin = FALSE;\r
1434 return;\r
1435\r
1436 // dis/enable display\r
1437 case 0x03: \r
1438 PreviousPSXDisplay.Disabled = PSXDisplay.Disabled;\r
1439 PSXDisplay.Disabled = (gdata & 1);\r
1440\r
1441 if(PSXDisplay.Disabled) \r
1442 STATUSREG|=GPUSTATUS_DISPLAYDISABLED;\r
1443 else STATUSREG&=~GPUSTATUS_DISPLAYDISABLED;\r
1444\r
1445 if (iOffscreenDrawing==4 &&\r
1446 PreviousPSXDisplay.Disabled && \r
1447 !(PSXDisplay.Disabled))\r
1448 {\r
1449\r
1450 if(!PSXDisplay.RGB24)\r
1451 {\r
1452 PrepareFullScreenUpload(TRUE);\r
1453 UploadScreen(TRUE); \r
1454 updateDisplay();\r
1455 }\r
1456 }\r
1457\r
1458 return;\r
1459\r
1460 // setting transfer mode\r
1461 case 0x04:\r
1462 gdata &= 0x03; // only want the lower two bits\r
1463\r
1464 iDataWriteMode=iDataReadMode=DR_NORMAL;\r
1465 if(gdata==0x02) iDataWriteMode=DR_VRAMTRANSFER;\r
1466 if(gdata==0x03) iDataReadMode =DR_VRAMTRANSFER;\r
1467\r
1468 STATUSREG&=~GPUSTATUS_DMABITS; // clear the current settings of the DMA bits\r
1469 STATUSREG|=(gdata << 29); // set the DMA bits according to the received data\r
1470\r
1471 return;\r
1472\r
1473 // setting display position\r
1474 case 0x05: \r
1475 {\r
1476 short sx=(short)(gdata & 0x3ff);\r
1477 short sy;\r
1478\r
1479 if(iGPUHeight==1024)\r
1480 {\r
1481 if(dwGPUVersion==2) \r
1482 sy = (short)((gdata>>12)&0x3ff);\r
1483 else sy = (short)((gdata>>10)&0x3ff);\r
1484 }\r
1485 else sy = (short)((gdata>>10)&0x3ff); // really: 0x1ff, but we adjust it later\r
1486\r
1487 if (sy & 0x200) \r
1488 {\r
1489 sy|=0xfc00;\r
1490 PreviousPSXDisplay.DisplayModeNew.y=sy/PSXDisplay.Double;\r
1491 sy=0;\r
1492 }\r
1493 else PreviousPSXDisplay.DisplayModeNew.y=0;\r
1494\r
1495 if(sx>1000) sx=0;\r
1496\r
1497 if(usFirstPos)\r
1498 {\r
1499 usFirstPos--;\r
1500 if(usFirstPos)\r
1501 {\r
1502 PreviousPSXDisplay.DisplayPosition.x = sx;\r
1503 PreviousPSXDisplay.DisplayPosition.y = sy;\r
1504 PSXDisplay.DisplayPosition.x = sx;\r
1505 PSXDisplay.DisplayPosition.y = sy;\r
1506 }\r
1507 }\r
1508\r
1509 if(dwActFixes&8) \r
1510 {\r
1511 if((!PSXDisplay.Interlaced) &&\r
1512 PreviousPSXDisplay.DisplayPosition.x == sx &&\r
1513 PreviousPSXDisplay.DisplayPosition.y == sy)\r
1514 return;\r
1515\r
1516 PSXDisplay.DisplayPosition.x = PreviousPSXDisplay.DisplayPosition.x;\r
1517 PSXDisplay.DisplayPosition.y = PreviousPSXDisplay.DisplayPosition.y;\r
1518 PreviousPSXDisplay.DisplayPosition.x = sx;\r
1519 PreviousPSXDisplay.DisplayPosition.y = sy;\r
1520 }\r
1521 else\r
1522 {\r
1523 if((!PSXDisplay.Interlaced) &&\r
1524 PSXDisplay.DisplayPosition.x == sx &&\r
1525 PSXDisplay.DisplayPosition.y == sy)\r
1526 return;\r
1527 PreviousPSXDisplay.DisplayPosition.x = PSXDisplay.DisplayPosition.x;\r
1528 PreviousPSXDisplay.DisplayPosition.y = PSXDisplay.DisplayPosition.y;\r
1529 PSXDisplay.DisplayPosition.x = sx;\r
1530 PSXDisplay.DisplayPosition.y = sy;\r
1531 }\r
1532\r
1533 PSXDisplay.DisplayEnd.x=\r
1534 PSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;\r
1535 PSXDisplay.DisplayEnd.y=\r
1536 PSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;\r
1537\r
1538 PreviousPSXDisplay.DisplayEnd.x=\r
1539 PreviousPSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;\r
1540 PreviousPSXDisplay.DisplayEnd.y=\r
1541 PreviousPSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;\r
1542\r
1543 bDisplayNotSet = TRUE;\r
1544\r
1545 if (!(PSXDisplay.Interlaced))\r
1546 {\r
1547 updateDisplay();\r
1548 }\r
1549 else\r
1550 if(PSXDisplay.InterlacedTest && \r
1551 ((PreviousPSXDisplay.DisplayPosition.x != PSXDisplay.DisplayPosition.x)||\r
1552 (PreviousPSXDisplay.DisplayPosition.y != PSXDisplay.DisplayPosition.y)))\r
1553 PSXDisplay.InterlacedTest--;\r
1554\r
1555 return;\r
1556 }\r
1557\r
1558 // setting width\r
1559 case 0x06:\r
1560\r
1561 PSXDisplay.Range.x0=gdata & 0x7ff; //0x3ff;\r
1562 PSXDisplay.Range.x1=(gdata>>12) & 0xfff;//0x7ff;\r
1563\r
1564 PSXDisplay.Range.x1-=PSXDisplay.Range.x0;\r
1565\r
1566 ChangeDispOffsetsX();\r
1567\r
1568 return;\r
1569\r
1570 // setting height\r
1571 case 0x07:\r
1572\r
1573 PreviousPSXDisplay.Height = PSXDisplay.Height;\r
1574\r
1575 PSXDisplay.Range.y0=gdata & 0x3ff;\r
1576 PSXDisplay.Range.y1=(gdata>>10) & 0x3ff;\r
1577\r
1578 PSXDisplay.Height = PSXDisplay.Range.y1 - \r
1579 PSXDisplay.Range.y0 +\r
1580 PreviousPSXDisplay.DisplayModeNew.y;\r
1581\r
1582 if (PreviousPSXDisplay.Height != PSXDisplay.Height)\r
1583 {\r
1584 PSXDisplay.DisplayModeNew.y=PSXDisplay.Height*PSXDisplay.Double;\r
1585 ChangeDispOffsetsY();\r
1586 updateDisplayIfChanged();\r
1587 }\r
1588 return;\r
1589\r
1590 // setting display infos\r
1591 case 0x08:\r
1592\r
1593 PSXDisplay.DisplayModeNew.x = dispWidths[(gdata & 0x03) | ((gdata & 0x40) >> 4)];\r
1594\r
1595 if (gdata&0x04) PSXDisplay.Double=2;\r
1596 else PSXDisplay.Double=1;\r
1597 PSXDisplay.DisplayModeNew.y = PSXDisplay.Height*PSXDisplay.Double;\r
1598\r
1599 ChangeDispOffsetsY();\r
1600 \r
1601 PSXDisplay.PAL = (gdata & 0x08)?TRUE:FALSE; // if 1 - PAL mode, else NTSC\r
1602 PSXDisplay.RGB24New = (gdata & 0x10)?TRUE:FALSE; // if 1 - TrueColor\r
1603 PSXDisplay.InterlacedNew = (gdata & 0x20)?TRUE:FALSE; // if 1 - Interlace\r
1604\r
1605 STATUSREG&=~GPUSTATUS_WIDTHBITS; // clear the width bits\r
1606\r
1607 STATUSREG|=\r
1608 (((gdata & 0x03) << 17) | \r
1609 ((gdata & 0x40) << 10)); // set the width bits\r
1610\r
1611 PreviousPSXDisplay.InterlacedNew=FALSE;\r
1612 if (PSXDisplay.InterlacedNew)\r
1613 {\r
1614 if(!PSXDisplay.Interlaced)\r
1615 {\r
1616 PSXDisplay.InterlacedTest=2;\r
1617 PreviousPSXDisplay.DisplayPosition.x = PSXDisplay.DisplayPosition.x;\r
1618 PreviousPSXDisplay.DisplayPosition.y = PSXDisplay.DisplayPosition.y;\r
1619 PreviousPSXDisplay.InterlacedNew=TRUE;\r
1620 }\r
1621\r
1622 STATUSREG|=GPUSTATUS_INTERLACED;\r
1623 }\r
1624 else \r
1625 {\r
1626 PSXDisplay.InterlacedTest=0;\r
1627 STATUSREG&=~GPUSTATUS_INTERLACED;\r
1628 }\r
1629\r
1630 if (PSXDisplay.PAL)\r
1631 STATUSREG|=GPUSTATUS_PAL;\r
1632 else STATUSREG&=~GPUSTATUS_PAL;\r
1633\r
1634 if (PSXDisplay.Double==2)\r
1635 STATUSREG|=GPUSTATUS_DOUBLEHEIGHT;\r
1636 else STATUSREG&=~GPUSTATUS_DOUBLEHEIGHT;\r
1637\r
1638 if (PSXDisplay.RGB24New)\r
1639 STATUSREG|=GPUSTATUS_RGB24;\r
1640 else STATUSREG&=~GPUSTATUS_RGB24;\r
1641\r
1642 updateDisplayIfChanged();\r
1643\r
1644 return;\r
1645\r
1646 //--------------------------------------------------//\r
1647 // ask about GPU version and other stuff\r
1648 case 0x10: \r
1649\r
1650 gdata&=0xff;\r
1651\r
1652 switch(gdata) \r
1653 {\r
1654 case 0x02:\r
1655 GPUdataRet=ulGPUInfoVals[INFO_TW]; // tw infos\r
1656 return;\r
1657 case 0x03:\r
1658 GPUdataRet=ulGPUInfoVals[INFO_DRAWSTART]; // draw start\r
1659 return;\r
1660 case 0x04:\r
1661 GPUdataRet=ulGPUInfoVals[INFO_DRAWEND]; // draw end\r
1662 return;\r
1663 case 0x05:\r
1664 case 0x06:\r
1665 GPUdataRet=ulGPUInfoVals[INFO_DRAWOFF]; // draw offset\r
1666 return;\r
1667 case 0x07:\r
1668 if(dwGPUVersion==2)\r
1669 GPUdataRet=0x01;\r
1670 else GPUdataRet=0x02; // gpu type\r
1671 return;\r
1672 case 0x08:\r
1673 case 0x0F: // some bios addr?\r
1674 GPUdataRet=0xBFC03720;\r
1675 return;\r
1676 }\r
1677 return;\r
1678 //--------------------------------------------------//\r
1679 }\r
1680}\r
1681\r
1682////////////////////////////////////////////////////////////////////////\r
1683// vram read/write helpers\r
1684////////////////////////////////////////////////////////////////////////\r
1685\r
1686BOOL bNeedWriteUpload=FALSE;\r
1687\r
1688__inline void FinishedVRAMWrite(void)\r
1689{\r
1690 if(bNeedWriteUpload)\r
1691 {\r
1692 bNeedWriteUpload=FALSE;\r
1693 CheckWriteUpdate();\r
1694 }\r
1695\r
1696 // set register to NORMAL operation\r
1697 iDataWriteMode = DR_NORMAL;\r
1698\r
1699 // reset transfer values, to prevent mis-transfer of data\r
1700 VRAMWrite.ColsRemaining = 0;\r
1701 VRAMWrite.RowsRemaining = 0;\r
1702}\r
1703\r
1704__inline void FinishedVRAMRead(void)\r
1705{\r
1706 // set register to NORMAL operation\r
1707 iDataReadMode = DR_NORMAL;\r
1708 // reset transfer values, to prevent mis-transfer of data\r
1709 VRAMRead.x = 0;\r
1710 VRAMRead.y = 0;\r
1711 VRAMRead.Width = 0;\r
1712 VRAMRead.Height = 0;\r
1713 VRAMRead.ColsRemaining = 0;\r
1714 VRAMRead.RowsRemaining = 0;\r
1715\r
1716 // indicate GPU is no longer ready for VRAM data in the STATUS REGISTER\r
1717 STATUSREG&=~GPUSTATUS_READYFORVRAM;\r
1718}\r
1719\r
1720////////////////////////////////////////////////////////////////////////\r
1721// vram read check ex (reading from card's back/frontbuffer if needed...\r
1722// slow!)\r
1723////////////////////////////////////////////////////////////////////////\r
1724\r
1725void CheckVRamReadEx(int x, int y, int dx, int dy)\r
1726{\r
1727 unsigned short sArea;\r
1728 int ux,uy,udx,udy,wx,wy;\r
1729 unsigned short * p1, *p2;\r
1730 float XS,YS;\r
1731 unsigned char * ps;\r
1732 unsigned char * px;\r
1733 unsigned short s,sx;\r
1734\r
1735 if(STATUSREG&GPUSTATUS_RGB24) return;\r
1736\r
1737 if(((dx > PSXDisplay.DisplayPosition.x) &&\r
1738 (x < PSXDisplay.DisplayEnd.x) &&\r
1739 (dy > PSXDisplay.DisplayPosition.y) &&\r
1740 (y < PSXDisplay.DisplayEnd.y)))\r
1741 sArea=0;\r
1742 else\r
1743 if((!(PSXDisplay.InterlacedTest) &&\r
1744 (dx > PreviousPSXDisplay.DisplayPosition.x) &&\r
1745 (x < PreviousPSXDisplay.DisplayEnd.x) &&\r
1746 (dy > PreviousPSXDisplay.DisplayPosition.y) &&\r
1747 (y < PreviousPSXDisplay.DisplayEnd.y)))\r
1748 sArea=1;\r
1749 else \r
1750 {\r
1751 return;\r
1752 }\r
1753\r
1754 //////////////\r
1755\r
1756 if(iRenderFVR)\r
1757 {\r
1758 bFullVRam=TRUE;iRenderFVR=2;return;\r
1759 }\r
1760 bFullVRam=TRUE;iRenderFVR=2;\r
1761\r
1762 //////////////\r
1763\r
1764 p2=0;\r
1765\r
1766 if(sArea==0)\r
1767 {\r
1768 ux=PSXDisplay.DisplayPosition.x;\r
1769 uy=PSXDisplay.DisplayPosition.y;\r
1770 udx=PSXDisplay.DisplayEnd.x-ux;\r
1771 udy=PSXDisplay.DisplayEnd.y-uy;\r
1772 if((PreviousPSXDisplay.DisplayEnd.x-\r
1773 PreviousPSXDisplay.DisplayPosition.x)==udx &&\r
1774 (PreviousPSXDisplay.DisplayEnd.y-\r
1775 PreviousPSXDisplay.DisplayPosition.y)==udy)\r
1776 p2=(psxVuw + (1024*PreviousPSXDisplay.DisplayPosition.y) + \r
1777 PreviousPSXDisplay.DisplayPosition.x);\r
1778 }\r
1779 else\r
1780 {\r
1781 ux=PreviousPSXDisplay.DisplayPosition.x;\r
1782 uy=PreviousPSXDisplay.DisplayPosition.y;\r
1783 udx=PreviousPSXDisplay.DisplayEnd.x-ux;\r
1784 udy=PreviousPSXDisplay.DisplayEnd.y-uy;\r
1785 if((PSXDisplay.DisplayEnd.x-\r
1786 PSXDisplay.DisplayPosition.x)==udx &&\r
1787 (PSXDisplay.DisplayEnd.y-\r
1788 PSXDisplay.DisplayPosition.y)==udy)\r
1789 p2=(psxVuw + (1024*PSXDisplay.DisplayPosition.y) + \r
1790 PSXDisplay.DisplayPosition.x);\r
1791 }\r
1792\r
1793 p1=(psxVuw + (1024*uy) + ux);\r
1794 if(p1==p2) p2=0;\r
1795\r
1796 x=0;y=0;\r
1797 wx=dx=udx;wy=dy=udy;\r
1798\r
1799 if(udx<=0) return;\r
1800 if(udy<=0) return;\r
1801 if(dx<=0) return;\r
1802 if(dy<=0) return;\r
1803 if(wx<=0) return;\r
1804 if(wy<=0) return;\r
1805\r
1806 XS=(float)rRatioRect.right/(float)wx;\r
1807 YS=(float)rRatioRect.bottom/(float)wy;\r
1808\r
1809 dx=(int)((float)(dx)*XS);\r
1810 dy=(int)((float)(dy)*YS);\r
1811\r
1812 if(dx>iResX) dx=iResX;\r
1813 if(dy>iResY) dy=iResY;\r
1814\r
1815 if(dx<=0) return;\r
1816 if(dy<=0) return;\r
1817\r
1818 // ogl y adjust\r
1819 y=iResY-y-dy;\r
1820\r
1821 x+=rRatioRect.left;\r
1822 y-=rRatioRect.top;\r
1823\r
1824 if(y<0) y=0; if((y+dy)>iResY) dy=iResY-y;\r
1825\r
1826 if(!pGfxCardScreen)\r
1827 {\r
1828 glPixelStorei(GL_PACK_ALIGNMENT,1);\r
1829 pGfxCardScreen=(unsigned char *)malloc(iResX*iResY*4);\r
1830 }\r
1831\r
1832 ps=pGfxCardScreen;\r
1833 \r
1834 //if(!sArea) glReadBuffer(GL_FRONT);\r
1835\r
1836 glReadPixels(x,y,dx,dy,GL_RGB,GL_UNSIGNED_BYTE,ps);\r
1837 \r
1838 //if(!sArea) glReadBuffer(GL_BACK);\r
1839\r
1840 s=0;\r
1841\r
1842 XS=(float)dx/(float)(udx);\r
1843 YS=(float)dy/(float)(udy+1);\r
1844 \r
1845 for(y=udy;y>0;y--)\r
1846 {\r
1847 for(x=0;x<udx;x++)\r
1848 {\r
1849 if(p1>=psxVuw && p1<psxVuw_eom)\r
1850 {\r
1851 px=ps+(3*((int)((float)x * XS))+\r
1852 (3*dx)*((int)((float)y*YS)));\r
1853 sx=(*px)>>3;px++;\r
1854 s=sx;\r
1855 sx=(*px)>>3;px++;\r
1856 s|=sx<<5;\r
1857 sx=(*px)>>3;\r
1858 s|=sx<<10;\r
1859 s&=~0x8000;\r
1860 *p1=s;\r
1861 }\r
1862 if(p2>=psxVuw && p2<psxVuw_eom) *p2=s;\r
1863\r
1864 p1++;\r
1865 if(p2) p2++;\r
1866 }\r
1867\r
1868 p1 += 1024 - udx;\r
1869 if(p2) p2 += 1024 - udx;\r
1870 }\r
1871}\r
1872\r
1873////////////////////////////////////////////////////////////////////////\r
1874// vram read check (reading from card's back/frontbuffer if needed... \r
1875// slow!)\r
1876////////////////////////////////////////////////////////////////////////\r
1877\r
1878void CheckVRamRead(int x, int y, int dx, int dy, bool bFront)\r
1879{\r
1880 unsigned short sArea;unsigned short * p;\r
1881 int ux,uy,udx,udy,wx,wy;float XS,YS;\r
1882 unsigned char * ps, * px;\r
1883 unsigned short s=0,sx;\r
1884\r
1885 if(STATUSREG&GPUSTATUS_RGB24) return;\r
1886\r
1887 if(((dx > PSXDisplay.DisplayPosition.x) &&\r
1888 (x < PSXDisplay.DisplayEnd.x) &&\r
1889 (dy > PSXDisplay.DisplayPosition.y) &&\r
1890 (y < PSXDisplay.DisplayEnd.y)))\r
1891 sArea=0;\r
1892 else\r
1893 if((!(PSXDisplay.InterlacedTest) &&\r
1894 (dx > PreviousPSXDisplay.DisplayPosition.x) &&\r
1895 (x < PreviousPSXDisplay.DisplayEnd.x) &&\r
1896 (dy > PreviousPSXDisplay.DisplayPosition.y) &&\r
1897 (y < PreviousPSXDisplay.DisplayEnd.y)))\r
1898 sArea=1;\r
1899 else \r
1900 {\r
1901 return;\r
1902 }\r
1903\r
1904 if(dwActFixes&0x40)\r
1905 {\r
1906 if(iRenderFVR)\r
1907 {\r
1908 bFullVRam=TRUE;iRenderFVR=2;return;\r
1909 }\r
1910 bFullVRam=TRUE;iRenderFVR=2;\r
1911 }\r
1912\r
1913 ux=x;uy=y;udx=dx;udy=dy;\r
1914\r
1915 if(sArea==0)\r
1916 {\r
1917 x -=PSXDisplay.DisplayPosition.x;\r
1918 dx-=PSXDisplay.DisplayPosition.x;\r
1919 y -=PSXDisplay.DisplayPosition.y;\r
1920 dy-=PSXDisplay.DisplayPosition.y;\r
1921 wx=PSXDisplay.DisplayEnd.x-PSXDisplay.DisplayPosition.x;\r
1922 wy=PSXDisplay.DisplayEnd.y-PSXDisplay.DisplayPosition.y;\r
1923 }\r
1924 else\r
1925 {\r
1926 x -=PreviousPSXDisplay.DisplayPosition.x;\r
1927 dx-=PreviousPSXDisplay.DisplayPosition.x;\r
1928 y -=PreviousPSXDisplay.DisplayPosition.y;\r
1929 dy-=PreviousPSXDisplay.DisplayPosition.y;\r
1930 wx=PreviousPSXDisplay.DisplayEnd.x-PreviousPSXDisplay.DisplayPosition.x;\r
1931 wy=PreviousPSXDisplay.DisplayEnd.y-PreviousPSXDisplay.DisplayPosition.y;\r
1932 }\r
1933 if(x<0) {ux-=x;x=0;}\r
1934 if(y<0) {uy-=y;y=0;}\r
1935 if(dx>wx) {udx-=(dx-wx);dx=wx;}\r
1936 if(dy>wy) {udy-=(dy-wy);dy=wy;}\r
1937 udx-=ux;\r
1938 udy-=uy;\r
1939 \r
1940 p=(psxVuw + (1024*uy) + ux);\r
1941\r
1942 if(udx<=0) return;\r
1943 if(udy<=0) return;\r
1944 if(dx<=0) return;\r
1945 if(dy<=0) return;\r
1946 if(wx<=0) return;\r
1947 if(wy<=0) return;\r
1948\r
1949 XS=(float)rRatioRect.right/(float)wx;\r
1950 YS=(float)rRatioRect.bottom/(float)wy;\r
1951\r
1952 dx=(int)((float)(dx)*XS);\r
1953 dy=(int)((float)(dy)*YS);\r
1954 x=(int)((float)x*XS);\r
1955 y=(int)((float)y*YS);\r
1956\r
1957 dx-=x;\r
1958 dy-=y;\r
1959\r
1960 if(dx>iResX) dx=iResX;\r
1961 if(dy>iResY) dy=iResY;\r
1962\r
1963 if(dx<=0) return;\r
1964 if(dy<=0) return;\r
1965\r
1966 // ogl y adjust\r
1967 y=iResY-y-dy;\r
1968\r
1969 x+=rRatioRect.left;\r
1970 y-=rRatioRect.top;\r
1971\r
1972 if(y<0) y=0; if((y+dy)>iResY) dy=iResY-y;\r
1973\r
1974 if(!pGfxCardScreen)\r
1975 {\r
1976 glPixelStorei(GL_PACK_ALIGNMENT,1);\r
1977 pGfxCardScreen=(unsigned char *)malloc(iResX*iResY*4);\r
1978 }\r
1979\r
1980 ps=pGfxCardScreen;\r
1981 \r
1982// if(bFront) glReadBuffer(GL_FRONT);\r
1983\r
1984 glReadPixels(x,y,dx,dy,GL_RGB,GL_UNSIGNED_BYTE,ps);\r
1985 \r
1986// if(bFront) glReadBuffer(GL_BACK);\r
1987\r
1988 XS=(float)dx/(float)(udx);\r
1989 YS=(float)dy/(float)(udy+1);\r
1990 \r
1991 for(y=udy;y>0;y--)\r
1992 {\r
1993 for(x=0;x<udx;x++)\r
1994 {\r
1995 if(p>=psxVuw && p<psxVuw_eom)\r
1996 {\r
1997 px=ps+(3*((int)((float)x * XS))+\r
1998 (3*dx)*((int)((float)y*YS)));\r
1999 sx=(*px)>>3;px++;\r
2000 s=sx;\r
2001 sx=(*px)>>3;px++;\r
2002 s|=sx<<5;\r
2003 sx=(*px)>>3;\r
2004 s|=sx<<10;\r
2005 s&=~0x8000;\r
2006 *p=s;\r
2007 }\r
2008 p++;\r
2009 }\r
2010 p += 1024 - udx;\r
2011 }\r
2012}\r
2013\r
2014////////////////////////////////////////////////////////////////////////\r
2015// core read from vram\r
2016////////////////////////////////////////////////////////////////////////\r
2017\r
2018#ifdef _WINDOWS\r
2019void CALLBACK GPUreadDataMem(unsigned int * pMem, int iSize)\r
2020#else\r
2021void CALLBACK GPUreadDataMem(unsigned long * pMem, int iSize)\r
2022#endif\r
2023{\r
2024int i;\r
2025\r
2026if(iDataReadMode!=DR_VRAMTRANSFER) return;\r
2027\r
2028GPUIsBusy;\r
2029\r
2030// adjust read ptr, if necessary\r
2031while(VRAMRead.ImagePtr>=psxVuw_eom)\r
2032 VRAMRead.ImagePtr-=iGPUHeight*1024;\r
2033while(VRAMRead.ImagePtr<psxVuw)\r
2034 VRAMRead.ImagePtr+=iGPUHeight*1024;\r
2035\r
2036if((iFrameReadType&1 && iSize>1) &&\r
2037 !(iDrawnSomething==2 &&\r
2038 VRAMRead.x == VRAMWrite.x &&\r
2039 VRAMRead.y == VRAMWrite.y &&\r
2040 VRAMRead.Width == VRAMWrite.Width &&\r
2041 VRAMRead.Height == VRAMWrite.Height))\r
2042 CheckVRamRead(VRAMRead.x,VRAMRead.y,\r
2043 VRAMRead.x+VRAMRead.RowsRemaining,\r
2044 VRAMRead.y+VRAMRead.ColsRemaining,\r
2045 TRUE);\r
2046\r
2047for(i=0;i<iSize;i++)\r
2048 {\r
2049 // do 2 seperate 16bit reads for compatibility (wrap issues)\r
2050 if ((VRAMRead.ColsRemaining > 0) && (VRAMRead.RowsRemaining > 0))\r
2051 {\r
2052 // lower 16 bit\r
2053 GPUdataRet=(unsigned long)*VRAMRead.ImagePtr;\r
2054\r
2055 VRAMRead.ImagePtr++;\r
2056 if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;\r
2057 VRAMRead.RowsRemaining --;\r
2058\r
2059 if(VRAMRead.RowsRemaining<=0)\r
2060 {\r
2061 VRAMRead.RowsRemaining = VRAMRead.Width;\r
2062 VRAMRead.ColsRemaining--;\r
2063 VRAMRead.ImagePtr += 1024 - VRAMRead.Width;\r
2064 if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;\r
2065 }\r
2066\r
2067 // higher 16 bit (always, even if it's an odd width)\r
2068 GPUdataRet|=(unsigned long)(*VRAMRead.ImagePtr)<<16;\r
2069 *pMem++=GPUdataRet;\r
2070\r
2071 if(VRAMRead.ColsRemaining <= 0)\r
2072 {FinishedVRAMRead();goto ENDREAD;}\r
2073\r
2074 VRAMRead.ImagePtr++;\r
2075 if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;\r
2076 VRAMRead.RowsRemaining--;\r
2077 if(VRAMRead.RowsRemaining<=0)\r
2078 {\r
2079 VRAMRead.RowsRemaining = VRAMRead.Width;\r
2080 VRAMRead.ColsRemaining--;\r
2081 VRAMRead.ImagePtr += 1024 - VRAMRead.Width;\r
2082 if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;\r
2083 }\r
2084 if(VRAMRead.ColsRemaining <= 0)\r
2085 {FinishedVRAMRead();goto ENDREAD;}\r
2086 }\r
2087 else {FinishedVRAMRead();goto ENDREAD;}\r
2088 }\r
2089\r
2090ENDREAD:\r
2091GPUIsIdle;\r
2092}\r
2093\r
2094#ifdef _WINDOWS\r
2095unsigned long CALLBACK GPUreadData(void)\r
2096#else\r
2097unsigned long CALLBACK GPUreadData(void)\r
2098#endif\r
2099{\r
2100 unsigned long l;\r
2101#ifdef _WINDOWS\r
2102 GPUreadDataMem(&l,1);\r
2103#else\r
2104 GPUreadDataMem(&l,1);\r
2105#endif \r
2106 return GPUdataRet;\r
2107}\r
2108\r
2109////////////////////////////////////////////////////////////////////////\r
2110// helper table to know how much data is used by drawing commands\r
2111////////////////////////////////////////////////////////////////////////\r
2112\r
2113const unsigned char primTableCX[256] =\r
2114{\r
2115 // 00\r
2116 0,0,3,0,0,0,0,0,\r
2117 // 08\r
2118 0,0,0,0,0,0,0,0,\r
2119 // 10\r
2120 0,0,0,0,0,0,0,0,\r
2121 // 18\r
2122 0,0,0,0,0,0,0,0,\r
2123 // 20\r
2124 4,4,4,4,7,7,7,7,\r
2125 // 28\r
2126 5,5,5,5,9,9,9,9,\r
2127 // 30\r
2128 6,6,6,6,9,9,9,9,\r
2129 // 38\r
2130 8,8,8,8,12,12,12,12,\r
2131 // 40\r
2132 3,3,3,3,0,0,0,0,\r
2133 // 48\r
2134// 5,5,5,5,6,6,6,6, //FLINE\r
2135 254,254,254,254,254,254,254,254,\r
2136 // 50\r
2137 4,4,4,4,0,0,0,0,\r
2138 // 58\r
2139// 7,7,7,7,9,9,9,9, // LINEG3 LINEG4\r
2140 255,255,255,255,255,255,255,255,\r
2141 // 60\r
2142 3,3,3,3,4,4,4,4, // TILE SPRT\r
2143 // 68\r
2144 2,2,2,2,3,3,3,3, // TILE1\r
2145 // 70\r
2146 2,2,2,2,3,3,3,3,\r
2147 // 78\r
2148 2,2,2,2,3,3,3,3,\r
2149 // 80\r
2150 4,0,0,0,0,0,0,0,\r
2151 // 88\r
2152 0,0,0,0,0,0,0,0,\r
2153 // 90\r
2154 0,0,0,0,0,0,0,0,\r
2155 // 98\r
2156 0,0,0,0,0,0,0,0,\r
2157 // a0\r
2158 3,0,0,0,0,0,0,0,\r
2159 // a8\r
2160 0,0,0,0,0,0,0,0,\r
2161 // b0\r
2162 0,0,0,0,0,0,0,0,\r
2163 // b8\r
2164 0,0,0,0,0,0,0,0,\r
2165 // c0\r
2166 3,0,0,0,0,0,0,0,\r
2167 // c8\r
2168 0,0,0,0,0,0,0,0,\r
2169 // d0\r
2170 0,0,0,0,0,0,0,0,\r
2171 // d8\r
2172 0,0,0,0,0,0,0,0,\r
2173 // e0\r
2174 0,1,1,1,1,1,1,0,\r
2175 // e8\r
2176 0,0,0,0,0,0,0,0,\r
2177 // f0\r
2178 0,0,0,0,0,0,0,0,\r
2179 // f8\r
2180 0,0,0,0,0,0,0,0\r
2181};\r
2182\r
2183////////////////////////////////////////////////////////////////////////\r
2184// processes data send to GPU data register\r
2185////////////////////////////////////////////////////////////////////////\r
2186\r
2187#ifdef _WINDOWS\r
2188void CALLBACK GPUwriteDataMem(unsigned long * pMem, int iSize)\r
2189#else\r
2190void CALLBACK GPUwriteDataMem(unsigned long * pMem, int iSize)\r
2191#endif\r
2192{\r
2193unsigned char command;\r
2194unsigned long gdata=0;\r
2195int i=0;\r
2196GPUIsBusy;\r
2197GPUIsNotReadyForCommands;\r
2198\r
2199STARTVRAM:\r
2200\r
2201if(iDataWriteMode==DR_VRAMTRANSFER)\r
2202 {\r
2203 // make sure we are in vram\r
2204 while(VRAMWrite.ImagePtr>=psxVuw_eom)\r
2205 VRAMWrite.ImagePtr-=iGPUHeight*1024;\r
2206 while(VRAMWrite.ImagePtr<psxVuw)\r
2207 VRAMWrite.ImagePtr+=iGPUHeight*1024;\r
2208\r
2209 // now do the loop\r
2210 while(VRAMWrite.ColsRemaining>0)\r
2211 {\r
2212 while(VRAMWrite.RowsRemaining>0)\r
2213 {\r
2214 if(i>=iSize) {goto ENDVRAM;}\r
2215 i++;\r
2216\r
2217 gdata=*pMem++;\r
2218\r
2219 *VRAMWrite.ImagePtr++ = (unsigned short)gdata;\r
2220 if(VRAMWrite.ImagePtr>=psxVuw_eom) VRAMWrite.ImagePtr-=iGPUHeight*1024;\r
2221 VRAMWrite.RowsRemaining --;\r
2222\r
2223 if(VRAMWrite.RowsRemaining <= 0)\r
2224 {\r
2225 VRAMWrite.ColsRemaining--;\r
2226 if (VRAMWrite.ColsRemaining <= 0) // last pixel is odd width\r
2227 {\r
2228 gdata=(gdata&0xFFFF)|(((unsigned long)(*VRAMWrite.ImagePtr))<<16);\r
2229 FinishedVRAMWrite();\r
2230 goto ENDVRAM;\r
2231 }\r
2232 VRAMWrite.RowsRemaining = VRAMWrite.Width;\r
2233 VRAMWrite.ImagePtr += 1024 - VRAMWrite.Width;\r
2234 }\r
2235\r
2236 *VRAMWrite.ImagePtr++ = (unsigned short)(gdata>>16);\r
2237 if(VRAMWrite.ImagePtr>=psxVuw_eom) VRAMWrite.ImagePtr-=iGPUHeight*1024;\r
2238 VRAMWrite.RowsRemaining --;\r
2239 }\r
2240\r
2241 VRAMWrite.RowsRemaining = VRAMWrite.Width;\r
2242 VRAMWrite.ColsRemaining--;\r
2243 VRAMWrite.ImagePtr += 1024 - VRAMWrite.Width;\r
2244 }\r
2245\r
2246 FinishedVRAMWrite();\r
2247 }\r
2248\r
2249ENDVRAM:\r
2250\r
2251if(iDataWriteMode==DR_NORMAL)\r
2252 {\r
2253 void (* *primFunc)(unsigned char *);\r
2254 if(bSkipNextFrame) primFunc=primTableSkip;\r
2255 else primFunc=primTableJ;\r
2256\r
2257 for(;i<iSize;)\r
2258 {\r
2259 if(iDataWriteMode==DR_VRAMTRANSFER) goto STARTVRAM;\r
2260\r
2261 gdata=*pMem++;i++;\r
2262\r
2263 if(gpuDataC == 0)\r
2264 {\r
2265 command = (unsigned char)((gdata>>24) & 0xff);\r
2266\r
2267 if(primTableCX[command])\r
2268 {\r
2269 gpuDataC = primTableCX[command];\r
2270 gpuCommand = command;\r
2271 gpuDataM[0] = gdata;\r
2272 gpuDataP = 1;\r
2273 }\r
2274 else continue;\r
2275 }\r
2276 else\r
2277 {\r
2278 gpuDataM[gpuDataP] = gdata;\r
2279 if(gpuDataC>128)\r
2280 {\r
2281 if((gpuDataC==254 && gpuDataP>=3) ||\r
2282 (gpuDataC==255 && gpuDataP>=4 && !(gpuDataP&1)))\r
2283 {\r
2284 if((gpuDataM[gpuDataP] & 0xF000F000) == 0x50005000)\r
2285 gpuDataP=gpuDataC-1;\r
2286 }\r
2287 }\r
2288 gpuDataP++;\r
2289 }\r
2290\r
2291 if(gpuDataP == gpuDataC)\r
2292 {\r
2293 gpuDataC=gpuDataP=0;\r
2294 primFunc[gpuCommand]((unsigned char *)gpuDataM);\r
2295\r
2296 if(dwEmuFixes&0x0001 || dwActFixes&0x20000) // hack for emulating "gpu busy" in some games\r
2297 iFakePrimBusy=4;\r
2298 }\r
2299 } \r
2300 }\r
2301\r
2302GPUdataRet=gdata;\r
2303\r
2304GPUIsReadyForCommands;\r
2305GPUIsIdle; \r
2306}\r
2307\r
2308////////////////////////////////////////////////////////////////////////\r
2309\r
2310#ifdef _WINDOWS\r
2311void CALLBACK GPUwriteData(unsigned long gdata)\r
2312#else\r
2313void CALLBACK GPUwriteData(unsigned long gdata)\r
2314#endif\r
2315{\r
2316#ifdef _WINDOWS\r
2317 GPUwriteDataMem(&gdata,1);\r
2318#else\r
2319 GPUwriteDataMem(&gdata,1);\r
2320#endif \r
2321}\r
2322\r
2323////////////////////////////////////////////////////////////////////////\r
2324// this function will be removed soon (or 'soonish') (or never)\r
2325////////////////////////////////////////////////////////////////////////\r
2326\r
2327void CALLBACK GPUsetMode(unsigned int gdata)\r
2328{\r
2329 // ignore old psemu setmode:\r
2330\r
2331 // imageTransfer = gdata;\r
2332 // iDataWriteMode=(gdata&1)?DR_VRAMTRANSFER:DR_NORMAL;\r
2333 // iDataReadMode =(gdata&2)?DR_VRAMTRANSFER:DR_NORMAL;\r
2334}\r
2335\r
2336// and this function will be removed soon as well, hehehe...\r
2337long CALLBACK GPUgetMode(void)\r
2338{\r
2339 // ignore old psemu setmode\r
2340 // return imageTransfer;\r
2341\r
2342long iT=0;\r
2343\r
2344if(iDataWriteMode==DR_VRAMTRANSFER) iT|=0x1;\r
2345if(iDataReadMode ==DR_VRAMTRANSFER) iT|=0x2;\r
2346\r
2347return iT;\r
2348}\r
2349\r
2350////////////////////////////////////////////////////////////////////////\r
2351// call config dlg (Windows + Linux)\r
2352////////////////////////////////////////////////////////////////////////\r
2353\r
2354#ifndef _WINDOWS\r
2355\r
2356/*#include <unistd.h>\r
2357\r
2358void StartCfgTool(char * pCmdLine) // linux: start external cfg tool\r
2359{\r
2360 FILE * cf;char filename[255],t[255];\r
2361\r
2362 strcpy(filename,"cfg/cfgPeopsMesaGL"); // look in cfg sub folder first\r
2363 cf=fopen(filename,"rb");\r
2364 if(cf!=NULL)\r
2365 {\r
2366 fclose(cf);\r
2367 getcwd(t,255);\r
2368 chdir("cfg");\r
2369 sprintf(filename,"./cfgPeopsMesaGL %s",pCmdLine);\r
2370 system(filename);\r
2371 chdir(t);\r
2372 }\r
2373 else\r
2374 {\r
2375 strcpy(filename,"cfgPeopsMesaGL"); // look in current folder\r
2376 cf=fopen(filename,"rb");\r
2377 if(cf!=NULL)\r
2378 {\r
2379 fclose(cf);\r
2380 sprintf(filename,"./cfgPeopsMesaGL %s",pCmdLine);\r
2381 system(filename);\r
2382 }\r
2383 else\r
2384 {\r
2385 sprintf(filename,"%s/cfgPeopsMesaGL",getenv("HOME")); // look in home folder\r
2386 cf=fopen(filename,"rb");\r
2387 if(cf!=NULL)\r
2388 {\r
2389 fclose(cf);\r
2390 getcwd(t,255);\r
2391 chdir(getenv("HOME"));\r
2392 sprintf(filename,"./cfgPeopsMesaGL %s",pCmdLine);\r
2393 system(filename);\r
2394 chdir(t);\r
2395 }\r
2396 else printf("cfgPeopsMesaGL not found!\n");\r
2397 }\r
2398 }\r
2399}\r
2400*/\r
2401#endif\r
2402\r
2403\r
2404#ifdef _WINDOWS\r
2405long CALLBACK GPUconfigure(void)\r
2406#else\r
2407long CALLBACK GPUconfigure(void)\r
2408#endif\r
2409{\r
2410\r
2411#ifdef _WINDOWS\r
2412// HWND hWP=GetActiveWindow();\r
2413// DialogBox(hInst,MAKEINTRESOURCE(IDD_CFGDLG),\r
2414// hWP,(DLGPROC)CfgDlgProc);\r
2415#else\r
2416\r
2417// StartCfgTool("CFG");\r
2418\r
2419#endif\r
2420\r
2421 return 0;\r
2422}\r
2423\r
2424////////////////////////////////////////////////////////////////////////\r
2425// sets all kind of act fixes\r
2426////////////////////////////////////////////////////////////////////////\r
2427\r
2428void SetFixes(void)\r
2429{\r
2430 ReInitFrameCap();\r
2431\r
2432 if(dwActFixes & 0x2000) \r
2433 dispWidths[4]=384;\r
2434 else dispWidths[4]=368;\r
2435}\r
2436\r
2437////////////////////////////////////////////////////////////////////////\r
2438// Pete Special: make an 'intelligent' dma chain check (<-Tekken3)\r
2439////////////////////////////////////////////////////////////////////////\r
2440\r
2441unsigned long lUsedAddr[3];\r
2442\r
2443__inline BOOL CheckForEndlessLoop(unsigned long laddr)\r
2444{\r
2445if(laddr==lUsedAddr[1]) return TRUE;\r
2446if(laddr==lUsedAddr[2]) return TRUE;\r
2447\r
2448if(laddr<lUsedAddr[0]) lUsedAddr[1]=laddr;\r
2449else lUsedAddr[2]=laddr;\r
2450lUsedAddr[0]=laddr;\r
2451return FALSE;\r
2452}\r
2453\r
2454////////////////////////////////////////////////////////////////////////\r
2455// core gives a dma chain to gpu: same as the gpuwrite interface funcs\r
2456////////////////////////////////////////////////////////////////////////\r
2457\r
2458#ifdef _WINDOWS\r
2459long CALLBACK GPUdmaChain(unsigned long * baseAddrL, unsigned long addr)\r
2460#else\r
2461long CALLBACK GPUdmaChain(unsigned long * baseAddrL, unsigned long addr)\r
2462#endif\r
2463{\r
2464unsigned long dmaMem;\r
2465unsigned char * baseAddrB;\r
2466short count;unsigned int DMACommandCounter = 0;\r
2467\r
2468if(bIsFirstFrame) GLinitialize();\r
2469\r
2470GPUIsBusy;\r
2471\r
2472lUsedAddr[0]=lUsedAddr[1]=lUsedAddr[2]=0xffffff;\r
2473\r
2474baseAddrB = (unsigned char*) baseAddrL;\r
2475\r
2476do\r
2477 {\r
2478 if(iGPUHeight==512) addr&=0x1FFFFC;\r
2479\r
2480 if(DMACommandCounter++ > 2000000) break;\r
2481 if(CheckForEndlessLoop(addr)) break;\r
2482\r
2483 count = baseAddrB[addr+3];\r
2484\r
2485 dmaMem=addr+4;\r
2486\r
2487#ifdef _WINDOWS\r
2488 if(count>0) GPUwriteDataMem(&baseAddrL[dmaMem>>2],count);\r
2489#else\r
2490 if(count>0) GPUwriteDataMem(&baseAddrL[dmaMem>>2],count);\r
2491#endif\r
2492 \r
2493 addr = baseAddrL[addr>>2]&0xffffff;\r
2494 }\r
2495while (addr != 0xffffff);\r
2496\r
2497GPUIsIdle;\r
2498\r
2499return 0;\r
2500}\r
2501 \r
2502////////////////////////////////////////////////////////////////////////\r
2503// show about dlg\r
2504////////////////////////////////////////////////////////////////////////\r
2505\r
2506#ifdef _WINDOWS\r
2507void CALLBACK GPUabout(void)\r
2508#else\r
2509void CALLBACK GPUabout(void)\r
2510#endif\r
2511{\r
2512\r
2513}\r
2514\r
2515////////////////////////////////////////////////////////////////////////\r
2516// We are ever fine ;)\r
2517////////////////////////////////////////////////////////////////////////\r
2518\r
2519#ifdef _WINDOWS\r
2520long CALLBACK GPUtest(void)\r
2521#else\r
2522long CALLBACK GPUtest(void)\r
2523#endif\r
2524{\r
2525 // if test fails this function should return negative value for error (unable to continue)\r
2526 // and positive value for warning (can continue but output might be crappy)\r
2527\r
2528 return 0;\r
2529}\r
2530\r
2531////////////////////////////////////////////////////////////////////////\r
2532// save state funcs\r
2533////////////////////////////////////////////////////////////////////////\r
2534\r
2535////////////////////////////////////////////////////////////////////////\r
2536\r
2537#ifdef _WINDOWS\r
2538long CALLBACK GPUfreeze(unsigned long ulGetFreezeData,GPUFreeze_t * pF)\r
2539#else\r
2540long CALLBACK GPUfreeze(unsigned long ulGetFreezeData,GPUFreeze_t * pF)\r
2541#endif\r
2542{\r
2543if(ulGetFreezeData==2) \r
2544 {\r
2545 long lSlotNum=*((long *)pF);\r
2546 if(lSlotNum<0) return 0;\r
2547 if(lSlotNum>8) return 0;\r
2548 lSelectedSlot=lSlotNum+1;\r
2549 return 1;\r
2550 }\r
2551\r
2552if(!pF) return 0; \r
2553if(pF->ulFreezeVersion!=1) return 0;\r
2554\r
2555if(ulGetFreezeData==1)\r
2556 {\r
2557 pF->ulStatus=STATUSREG;\r
2558 memcpy(pF->ulControl,ulStatusControl,256*sizeof(unsigned long));\r
2559 memcpy(pF->psxVRam, psxVub, 1024*iGPUHeight*2);\r
2560\r
2561 return 1;\r
2562 }\r
2563\r
2564if(ulGetFreezeData!=0) return 0;\r
2565\r
2566STATUSREG=pF->ulStatus;\r
2567memcpy(ulStatusControl,pF->ulControl,256*sizeof(unsigned long));\r
2568memcpy(psxVub, pF->psxVRam, 1024*iGPUHeight*2);\r
2569\r
2570ResetTextureArea(TRUE);\r
2571\r
2572#ifdef _WINDOWS\r
2573 GPUwriteStatus(ulStatusControl[0]);\r
2574 GPUwriteStatus(ulStatusControl[1]);\r
2575 GPUwriteStatus(ulStatusControl[2]);\r
2576 GPUwriteStatus(ulStatusControl[3]);\r
2577 GPUwriteStatus(ulStatusControl[8]);\r
2578 GPUwriteStatus(ulStatusControl[6]);\r
2579 GPUwriteStatus(ulStatusControl[7]);\r
2580 GPUwriteStatus(ulStatusControl[5]);\r
2581 GPUwriteStatus(ulStatusControl[4]);\r
2582#else\r
2583 GPUwriteStatus(ulStatusControl[0]);\r
2584 GPUwriteStatus(ulStatusControl[1]);\r
2585 GPUwriteStatus(ulStatusControl[2]);\r
2586 GPUwriteStatus(ulStatusControl[3]);\r
2587 GPUwriteStatus(ulStatusControl[8]);\r
2588 GPUwriteStatus(ulStatusControl[6]);\r
2589 GPUwriteStatus(ulStatusControl[7]);\r
2590 GPUwriteStatus(ulStatusControl[5]);\r
2591 GPUwriteStatus(ulStatusControl[4]);\r
2592#endif\r
2593 return 1;\r
2594}\r
2595\r
2596////////////////////////////////////////////////////////////////////////\r
2597// special "emu infos" / "emu effects" functions\r
2598////////////////////////////////////////////////////////////////////////\r
2599\r
2600//00 = black\r
2601//01 = white\r
2602//10 = red\r
2603//11 = transparent\r
2604\r
2605unsigned char cFont[10][120]=\r
2606{\r
2607// 0\r
2608{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
2609 0x80,0x00,0x00,0x00,0x00,0x00,\r
2610 0x80,0x00,0x00,0x00,0x00,0x00,\r
2611 0x80,0x00,0x00,0x00,0x00,0x00,\r
2612 0x80,0x00,0x00,0x00,0x00,0x00,\r
2613 0x80,0x00,0x05,0x54,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,0x14,0x05,0x00,0x00,\r
2618 0x80,0x00,0x14,0x05,0x00,0x00,\r
2619 0x80,0x00,0x14,0x05,0x00,0x00,\r
2620 0x80,0x00,0x14,0x05,0x00,0x00,\r
2621 0x80,0x00,0x14,0x05,0x00,0x00,\r
2622 0x80,0x00,0x05,0x54,0x00,0x00,\r
2623 0x80,0x00,0x00,0x00,0x00,0x00,\r
2624 0x80,0x00,0x00,0x00,0x00,0x00,\r
2625 0x80,0x00,0x00,0x00,0x00,0x00,\r
2626 0x80,0x00,0x00,0x00,0x00,0x00,\r
2627 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
2628},\r
2629// 1\r
2630{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
2631 0x80,0x00,0x00,0x00,0x00,0x00,\r
2632 0x80,0x00,0x00,0x00,0x00,0x00,\r
2633 0x80,0x00,0x00,0x00,0x00,0x00,\r
2634 0x80,0x00,0x00,0x00,0x00,0x00,\r
2635 0x80,0x00,0x00,0x50,0x00,0x00,\r
2636 0x80,0x00,0x05,0x50,0x00,0x00,\r
2637 0x80,0x00,0x00,0x50,0x00,0x00,\r
2638 0x80,0x00,0x00,0x50,0x00,0x00,\r
2639 0x80,0x00,0x00,0x50,0x00,0x00,\r
2640 0x80,0x00,0x00,0x50,0x00,0x00,\r
2641 0x80,0x00,0x00,0x50,0x00,0x00,\r
2642 0x80,0x00,0x00,0x50,0x00,0x00,\r
2643 0x80,0x00,0x00,0x50,0x00,0x00,\r
2644 0x80,0x00,0x05,0x55,0x00,0x00,\r
2645 0x80,0x00,0x00,0x00,0x00,0x00,\r
2646 0x80,0x00,0x00,0x00,0x00,0x00,\r
2647 0x80,0x00,0x00,0x00,0x00,0x00,\r
2648 0x80,0x00,0x00,0x00,0x00,0x00,\r
2649 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
2650},\r
2651// 2\r
2652{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
2653 0x80,0x00,0x00,0x00,0x00,0x00,\r
2654 0x80,0x00,0x00,0x00,0x00,0x00,\r
2655 0x80,0x00,0x00,0x00,0x00,0x00,\r
2656 0x80,0x00,0x00,0x00,0x00,0x00,\r
2657 0x80,0x00,0x05,0x54,0x00,0x00,\r
2658 0x80,0x00,0x14,0x05,0x00,0x00,\r
2659 0x80,0x00,0x00,0x05,0x00,0x00,\r
2660 0x80,0x00,0x00,0x05,0x00,0x00,\r
2661 0x80,0x00,0x00,0x14,0x00,0x00,\r
2662 0x80,0x00,0x00,0x50,0x00,0x00,\r
2663 0x80,0x00,0x01,0x40,0x00,0x00,\r
2664 0x80,0x00,0x05,0x00,0x00,0x00,\r
2665 0x80,0x00,0x14,0x00,0x00,0x00,\r
2666 0x80,0x00,0x15,0x55,0x00,0x00,\r
2667 0x80,0x00,0x00,0x00,0x00,0x00,\r
2668 0x80,0x00,0x00,0x00,0x00,0x00,\r
2669 0x80,0x00,0x00,0x00,0x00,0x00,\r
2670 0x80,0x00,0x00,0x00,0x00,0x00,\r
2671 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
2672},\r
2673// 3\r
2674{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
2675 0x80,0x00,0x00,0x00,0x00,0x00,\r
2676 0x80,0x00,0x00,0x00,0x00,0x00,\r
2677 0x80,0x00,0x00,0x00,0x00,0x00,\r
2678 0x80,0x00,0x00,0x00,0x00,0x00,\r
2679 0x80,0x00,0x05,0x54,0x00,0x00,\r
2680 0x80,0x00,0x14,0x05,0x00,0x00,\r
2681 0x80,0x00,0x00,0x05,0x00,0x00,\r
2682 0x80,0x00,0x00,0x05,0x00,0x00,\r
2683 0x80,0x00,0x01,0x54,0x00,0x00,\r
2684 0x80,0x00,0x00,0x05,0x00,0x00,\r
2685 0x80,0x00,0x00,0x05,0x00,0x00,\r
2686 0x80,0x00,0x00,0x05,0x00,0x00,\r
2687 0x80,0x00,0x14,0x05,0x00,0x00,\r
2688 0x80,0x00,0x05,0x54,0x00,0x00,\r
2689 0x80,0x00,0x00,0x00,0x00,0x00,\r
2690 0x80,0x00,0x00,0x00,0x00,0x00,\r
2691 0x80,0x00,0x00,0x00,0x00,0x00,\r
2692 0x80,0x00,0x00,0x00,0x00,0x00,\r
2693 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
2694},\r
2695// 4\r
2696{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
2697 0x80,0x00,0x00,0x00,0x00,0x00,\r
2698 0x80,0x00,0x00,0x00,0x00,0x00,\r
2699 0x80,0x00,0x00,0x00,0x00,0x00,\r
2700 0x80,0x00,0x00,0x00,0x00,0x00,\r
2701 0x80,0x00,0x00,0x14,0x00,0x00,\r
2702 0x80,0x00,0x00,0x54,0x00,0x00,\r
2703 0x80,0x00,0x01,0x54,0x00,0x00,\r
2704 0x80,0x00,0x01,0x54,0x00,0x00,\r
2705 0x80,0x00,0x05,0x14,0x00,0x00,\r
2706 0x80,0x00,0x14,0x14,0x00,0x00,\r
2707 0x80,0x00,0x15,0x55,0x00,0x00,\r
2708 0x80,0x00,0x00,0x14,0x00,0x00,\r
2709 0x80,0x00,0x00,0x14,0x00,0x00,\r
2710 0x80,0x00,0x00,0x55,0x00,0x00,\r
2711 0x80,0x00,0x00,0x00,0x00,0x00,\r
2712 0x80,0x00,0x00,0x00,0x00,0x00,\r
2713 0x80,0x00,0x00,0x00,0x00,0x00,\r
2714 0x80,0x00,0x00,0x00,0x00,0x00,\r
2715 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
2716},\r
2717// 5\r
2718{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
2719 0x80,0x00,0x00,0x00,0x00,0x00,\r
2720 0x80,0x00,0x00,0x00,0x00,0x00,\r
2721 0x80,0x00,0x00,0x00,0x00,0x00,\r
2722 0x80,0x00,0x00,0x00,0x00,0x00,\r
2723 0x80,0x00,0x15,0x55,0x00,0x00,\r
2724 0x80,0x00,0x14,0x00,0x00,0x00,\r
2725 0x80,0x00,0x14,0x00,0x00,0x00,\r
2726 0x80,0x00,0x14,0x00,0x00,0x00,\r
2727 0x80,0x00,0x15,0x54,0x00,0x00,\r
2728 0x80,0x00,0x00,0x05,0x00,0x00,\r
2729 0x80,0x00,0x00,0x05,0x00,0x00,\r
2730 0x80,0x00,0x00,0x05,0x00,0x00,\r
2731 0x80,0x00,0x14,0x05,0x00,0x00,\r
2732 0x80,0x00,0x05,0x54,0x00,0x00,\r
2733 0x80,0x00,0x00,0x00,0x00,0x00,\r
2734 0x80,0x00,0x00,0x00,0x00,0x00,\r
2735 0x80,0x00,0x00,0x00,0x00,0x00,\r
2736 0x80,0x00,0x00,0x00,0x00,0x00,\r
2737 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
2738},\r
2739// 6\r
2740{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
2741 0x80,0x00,0x00,0x00,0x00,0x00,\r
2742 0x80,0x00,0x00,0x00,0x00,0x00,\r
2743 0x80,0x00,0x00,0x00,0x00,0x00,\r
2744 0x80,0x00,0x00,0x00,0x00,0x00,\r
2745 0x80,0x00,0x01,0x54,0x00,0x00,\r
2746 0x80,0x00,0x05,0x00,0x00,0x00,\r
2747 0x80,0x00,0x14,0x00,0x00,0x00,\r
2748 0x80,0x00,0x14,0x00,0x00,0x00,\r
2749 0x80,0x00,0x15,0x54,0x00,0x00,\r
2750 0x80,0x00,0x15,0x05,0x00,0x00,\r
2751 0x80,0x00,0x14,0x05,0x00,0x00,\r
2752 0x80,0x00,0x14,0x05,0x00,0x00,\r
2753 0x80,0x00,0x14,0x05,0x00,0x00,\r
2754 0x80,0x00,0x05,0x54,0x00,0x00,\r
2755 0x80,0x00,0x00,0x00,0x00,0x00,\r
2756 0x80,0x00,0x00,0x00,0x00,0x00,\r
2757 0x80,0x00,0x00,0x00,0x00,0x00,\r
2758 0x80,0x00,0x00,0x00,0x00,0x00,\r
2759 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
2760},\r
2761// 7\r
2762{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
2763 0x80,0x00,0x00,0x00,0x00,0x00,\r
2764 0x80,0x00,0x00,0x00,0x00,0x00,\r
2765 0x80,0x00,0x00,0x00,0x00,0x00,\r
2766 0x80,0x00,0x00,0x00,0x00,0x00,\r
2767 0x80,0x00,0x15,0x55,0x00,0x00,\r
2768 0x80,0x00,0x14,0x05,0x00,0x00,\r
2769 0x80,0x00,0x00,0x14,0x00,0x00,\r
2770 0x80,0x00,0x00,0x14,0x00,0x00,\r
2771 0x80,0x00,0x00,0x50,0x00,0x00,\r
2772 0x80,0x00,0x00,0x50,0x00,0x00,\r
2773 0x80,0x00,0x01,0x40,0x00,0x00,\r
2774 0x80,0x00,0x01,0x40,0x00,0x00,\r
2775 0x80,0x00,0x05,0x00,0x00,0x00,\r
2776 0x80,0x00,0x05,0x00,0x00,0x00,\r
2777 0x80,0x00,0x00,0x00,0x00,0x00,\r
2778 0x80,0x00,0x00,0x00,0x00,0x00,\r
2779 0x80,0x00,0x00,0x00,0x00,0x00,\r
2780 0x80,0x00,0x00,0x00,0x00,0x00,\r
2781 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
2782},\r
2783// 8\r
2784{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
2785 0x80,0x00,0x00,0x00,0x00,0x00,\r
2786 0x80,0x00,0x00,0x00,0x00,0x00,\r
2787 0x80,0x00,0x00,0x00,0x00,0x00,\r
2788 0x80,0x00,0x00,0x00,0x00,0x00,\r
2789 0x80,0x00,0x05,0x54,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,0x14,0x05,0x00,0x00,\r
2795 0x80,0x00,0x14,0x05,0x00,0x00,\r
2796 0x80,0x00,0x14,0x05,0x00,0x00,\r
2797 0x80,0x00,0x14,0x05,0x00,0x00,\r
2798 0x80,0x00,0x05,0x54,0x00,0x00,\r
2799 0x80,0x00,0x00,0x00,0x00,0x00,\r
2800 0x80,0x00,0x00,0x00,0x00,0x00,\r
2801 0x80,0x00,0x00,0x00,0x00,0x00,\r
2802 0x80,0x00,0x00,0x00,0x00,0x00,\r
2803 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
2804},\r
2805// 9\r
2806{0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,\r
2807 0x80,0x00,0x00,0x00,0x00,0x00,\r
2808 0x80,0x00,0x00,0x00,0x00,0x00,\r
2809 0x80,0x00,0x00,0x00,0x00,0x00,\r
2810 0x80,0x00,0x00,0x00,0x00,0x00,\r
2811 0x80,0x00,0x05,0x54,0x00,0x00,\r
2812 0x80,0x00,0x14,0x05,0x00,0x00,\r
2813 0x80,0x00,0x14,0x05,0x00,0x00,\r
2814 0x80,0x00,0x14,0x05,0x00,0x00,\r
2815 0x80,0x00,0x14,0x15,0x00,0x00,\r
2816 0x80,0x00,0x05,0x55,0x00,0x00,\r
2817 0x80,0x00,0x00,0x05,0x00,0x00,\r
2818 0x80,0x00,0x00,0x05,0x00,0x00,\r
2819 0x80,0x00,0x00,0x14,0x00,0x00,\r
2820 0x80,0x00,0x05,0x50,0x00,0x00,\r
2821 0x80,0x00,0x00,0x00,0x00,0x00,\r
2822 0x80,0x00,0x00,0x00,0x00,0x00,\r
2823 0x80,0x00,0x00,0x00,0x00,0x00,\r
2824 0x80,0x00,0x00,0x00,0x00,0x00,\r
2825 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa\r
2826}\r
2827};\r
2828\r
2829////////////////////////////////////////////////////////////////////////\r
2830\r
2831void PaintPicDot(unsigned char * p,unsigned char c)\r
2832{\r
2833 if(c==0) {*p++=0x00;*p++=0x00;*p=0x00;return;}\r
2834 if(c==1) {*p++=0xff;*p++=0xff;*p=0xff;return;}\r
2835 if(c==2) {*p++=0x00;*p++=0x00;*p=0xff;return;}\r
2836}\r
2837\r
2838////////////////////////////////////////////////////////////////////////\r
2839\r
2840#ifdef _WINDOWS\r
2841void CALLBACK GPUgetScreenPic(unsigned char * pMem)\r
2842#else\r
2843long CALLBACK GPUgetScreenPic(unsigned char * pMem)\r
2844#endif\r
2845{\r
2846 float XS,YS;int x,y,v;\r
2847 unsigned char * ps, * px, * pf;\r
2848 unsigned char c;\r
2849\r
2850 if(!pGfxCardScreen)\r
2851 {\r
2852 glPixelStorei(GL_PACK_ALIGNMENT,1);\r
2853 pGfxCardScreen=(unsigned char *)malloc(iResX*iResY*4);\r
2854 }\r
2855\r
2856 ps=pGfxCardScreen;\r
2857\r
2858// glReadBuffer(GL_FRONT);\r
2859\r
2860 glReadPixels(0,0,iResX,iResY,GL_RGB,GL_UNSIGNED_BYTE,ps);\r
2861 \r
2862// glReadBuffer(GL_BACK);\r
2863\r
2864 XS=(float)iResX/128;\r
2865 YS=(float)iResY/96;\r
2866 pf=pMem;\r
2867\r
2868 for(y=96;y>0;y--)\r
2869 {\r
2870 for(x=0;x<128;x++)\r
2871 {\r
2872 px=ps+(3*((int)((float)x * XS))+\r
2873 (3*iResX)*((int)((float)y*YS)));\r
2874 *(pf+0)=*(px+2);\r
2875 *(pf+1)=*(px+1);\r
2876 *(pf+2)=*(px+0);\r
2877 pf+=3;\r
2878 }\r
2879 }\r
2880\r
2881 /////////////////////////////////////////////////////////////////////\r
2882 // generic number/border painter\r
2883\r
2884 pf=pMem+(103*3);\r
2885\r
2886 for(y=0;y<20;y++)\r
2887 {\r
2888 for(x=0;x<6;x++)\r
2889 {\r
2890 c=cFont[lSelectedSlot][x+y*6];\r
2891 v=(c&0xc0)>>6;\r
2892 PaintPicDot(pf,(unsigned char)v);pf+=3; // paint the dots into the rect\r
2893 v=(c&0x30)>>4;\r
2894 PaintPicDot(pf,(unsigned char)v);pf+=3;\r
2895 v=(c&0x0c)>>2;\r
2896 PaintPicDot(pf,(unsigned char)v);pf+=3;\r
2897 v=c&0x03;\r
2898 PaintPicDot(pf,(unsigned char)v);pf+=3;\r
2899 }\r
2900 pf+=104*3;\r
2901 }\r
2902\r
2903 pf=pMem;\r
2904 for(x=0;x<128;x++)\r
2905 {\r
2906 *(pf+(95*128*3))=0x00;*pf++=0x00;\r
2907 *(pf+(95*128*3))=0x00;*pf++=0x00;\r
2908 *(pf+(95*128*3))=0xff;*pf++=0xff;\r
2909 }\r
2910 pf=pMem;\r
2911 for(y=0;y<96;y++)\r
2912 {\r
2913 *(pf+(127*3))=0x00;*pf++=0x00;\r
2914 *(pf+(127*3))=0x00;*pf++=0x00;\r
2915 *(pf+(127*3))=0xff;*pf++=0xff;\r
2916 pf+=127*3;\r
2917 }\r
2918\r
2919}\r
2920\r
2921////////////////////////////////////////////////////////////////////////\r
2922\r
2923#ifdef _WINDOWS\r
2924void CALLBACK GPUshowScreenPic(unsigned char * pMem)\r
2925#else\r
2926long CALLBACK GPUshowScreenPic(unsigned char * pMem)\r
2927#endif\r
2928{\r
2929// DestroyPic();\r
2930// if(pMem==0) return;\r
2931// CreatePic(pMem);\r
2932}\r
2933\r
2934////////////////////////////////////////////////////////////////////////\r
2935\r
2936void CALLBACK GPUsetfix(unsigned long dwFixBits)\r
2937{\r
2938 dwEmuFixes=dwFixBits;\r
2939}\r
2940\r
2941////////////////////////////////////////////////////////////////////////\r
2942 \r
2943void CALLBACK GPUvisualVibration(unsigned long iSmall, unsigned long iBig)\r
2944{\r
2945 int iVibVal;\r
2946\r
2947 if(PSXDisplay.DisplayModeNew.x) // calc min "shake pixel" from screen width\r
2948 iVibVal=max(1,iResX/PSXDisplay.DisplayModeNew.x);\r
2949 else iVibVal=1;\r
2950 // big rumble: 4...15 sp ; small rumble 1...3 sp\r
2951 if(iBig) iRumbleVal=max(4*iVibVal,min(15*iVibVal,((int)iBig *iVibVal)/10));\r
2952 else iRumbleVal=max(1*iVibVal,min( 3*iVibVal,((int)iSmall*iVibVal)/10));\r
2953\r
2954 srand(timeGetTime()); // init rand (will be used in BufferSwap)\r
2955\r
2956 iRumbleTime=15; // let the rumble last 16 buffer swaps\r
2957}\r
2958 \r
2959////////////////////////////////////////////////////////////////////////\r
2960// main emu can set display infos (A/M/G/D) \r
2961////////////////////////////////////////////////////////////////////////\r
2962\r
2963void CALLBACK GPUdisplayFlags(unsigned long dwFlags)\r
2964{\r
2965// dwCoreFlags=dwFlags;\r
2966}\r
2967\r
2968// pcsx-rearmed callbacks\r
2969void CALLBACK GPUrearmedCallbacks(const void **cbs)\r
2970{\r
2971 rearmed_get_layer_pos = cbs[0];\r
2972}\r
2973\r