1 /***************************************************************************
\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
9 /***************************************************************************
\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
17 ***************************************************************************/
\r
19 //*************************************************************************//
\r
20 // History of changes:
\r
22 // 2009/03/08 - Pete
\r
23 // - generic cleanup for the Peops release
\r
25 //*************************************************************************//
\r
27 //#include "gpuStdafx.h"
\r
29 //#include <mmsystem.h>
\r
36 #include "gpuExternals.h"
\r
37 #include "gpuPlugin.h"
\r
38 #include "gpuDraw.h"
\r
39 #include "gpuTexture.h"
\r
41 #include "gpuPrim.h"
\r
43 //#include "NoPic.h"
\r
45 #include "gpuStdafx.h"
\r
47 short g_m1=255,g_m2=255,g_m3=255;
\r
48 short DrawSemiTrans=FALSE;
\r
52 short ly0,lx0,ly1,lx1,ly2,lx2,ly3,lx3; // global psx vertex coords
\r
53 long GlobalTextAddrX,GlobalTextAddrY,GlobalTextTP;
\r
54 long GlobalTextREST,GlobalTextABR,GlobalTextPAGE;
\r
56 unsigned long dwGPUVersion=0;
\r
58 int iGPUHeightMask=511;
\r
62 ////////////////////////////////////////////////////////////////////////
\r
63 // memory image of the PSX vram
\r
64 ////////////////////////////////////////////////////////////////////////
\r
66 unsigned char *psxVSecure;
\r
67 unsigned char *psxVub;
\r
68 signed char *psxVsb;
\r
69 unsigned short *psxVuw;
\r
70 unsigned short *psxVuw_eom;
\r
71 signed short *psxVsw;
\r
72 unsigned long *psxVul;
\r
73 signed long *psxVsl;
\r
75 // macro for easy access to packet information
\r
76 #define GPUCOMMAND(x) ((x>>24) & 0xff)
\r
79 BOOL bNeedInterlaceUpdate=FALSE;
\r
80 BOOL bNeedRGB24Update=FALSE;
\r
81 BOOL bChangeWinMode=FALSE;
\r
83 unsigned long ulStatusControl[256];
\r
85 ////////////////////////////////////////////////////////////////////////
\r
87 ////////////////////////////////////////////////////////////////////////
\r
89 static long GPUdataRet;
\r
93 static unsigned long gpuDataM[256];
\r
94 static unsigned char gpuCommand = 0;
\r
95 static long gpuDataC = 0;
\r
96 static long gpuDataP = 0;
\r
98 VRAMLoad_t VRAMWrite;
\r
99 VRAMLoad_t VRAMRead;
\r
100 int iDataWriteMode;
\r
104 long lClearOnSwapColor;
\r
105 BOOL bSkipNextFrame = FALSE;
\r
111 // possible psx display widths
\r
112 short dispWidths[8] = {256,320,512,640,368,384,512,640};
\r
114 PSXDisplay_t PSXDisplay;
\r
115 PSXDisplay_t PreviousPSXDisplay;
\r
117 short imageX0,imageX1;
\r
118 short imageY0,imageY1;
\r
119 BOOL bDisplayNotSet = TRUE;
\r
120 GLuint uiScanLine=0;
\r
121 int iUseScanLines=0;
\r
122 long lSelectedSlot=0;
\r
123 unsigned char * pGfxCardScreen=0;
\r
127 int iNoScreenSaver=0;
\r
128 unsigned long ulGPUInfoVals[16];
\r
129 int iFakePrimBusy = 0;
\r
130 int iRumbleVal = 0;
\r
131 int iRumbleTime = 0;
\r
133 static void (*rearmed_get_layer_pos)(int *x, int *y, int *w, int *h);
\r
134 static void flipEGL(void);
\r
136 ////////////////////////////////////////////////////////////////////////
\r
137 // stuff to make this a true PDK module
\r
138 ////////////////////////////////////////////////////////////////////////
\r
140 ////////////////////////////////////////////////////////////////////////
\r
141 // snapshot funcs (saves screen to bitmap / text infos into file)
\r
142 ////////////////////////////////////////////////////////////////////////
\r
144 void ResizeWindow()
\r
146 rRatioRect.left = rRatioRect.top=0;
\r
147 rRatioRect.right = iResX;
\r
148 rRatioRect.bottom = iResY;
\r
149 glViewport(rRatioRect.left, // init viewport by ratio rect
\r
150 iResY-(rRatioRect.top+rRatioRect.bottom),
\r
152 rRatioRect.bottom); glError();
\r
154 glScissor(0, 0, iResX, iResY); glError(); // init clipping (fullscreen)
\r
155 glEnable(GL_SCISSOR_TEST); glError();
\r
158 glMatrixMode(GL_TEXTURE); // init psx tex sow and tow if not "ownscale"
\r
160 glScalef(1.0f/255.99f,1.0f/255.99f,1.0f); // geforce precision hack
\r
163 glMatrixMode(GL_PROJECTION); glError(); // init projection with psx resolution
\r
164 glLoadIdentity(); glError();
\r
165 glOrtho(0,PSXDisplay.DisplayMode.x,
\r
166 PSXDisplay.DisplayMode.y, 0, -1, 1); glError();
\r
171 char * GetConfigInfos(int hW)
\r
173 char szO[2][4]={"off","on "};
\r
175 char * pB=(char *)malloc(32767);
\r
177 if(!pB) return NULL;
\r
179 //----------------------------------------------------//
\r
186 bSetupPixelFormat(hdc);
\r
187 hglrc = wglCreateContext(hdc);
\r
188 wglMakeCurrent(hdc, hglrc);
\r
191 sprintf(szTxt,"Card vendor: %s\r\n",(char *)glGetString(GL_VENDOR));
\r
193 sprintf(szTxt,"GFX card: %s\r\n",(char *)glGetString(GL_RENDERER));
\r
195 sprintf(szTxt,"OGL version: %s\r\n\r\n",(char *)glGetString(GL_VERSION));
\r
197 //strcat(pB,(char *)glGetString(GL_EXTENSIONS));
\r
198 //strcat(pB,"\r\n\r\n");
\r
203 wglMakeCurrent(NULL, NULL);
\r
204 wglDeleteContext(hglrc);
\r
207 //----------------------------------------------------//
\r
209 if(hW && bWindowMode)
\r
210 sprintf(szTxt,"Resolution/Color:\r\n- %dx%d ",LOWORD(iWinSize),HIWORD(iWinSize));
\r
212 sprintf(szTxt,"Resolution/Color:\r\n- %dx%d ",iResX,iResY);
\r
214 if(bWindowMode) sprintf(szTxt,"Window mode\r\n");
\r
217 sprintf(szTxt,"Fullscreen ");
\r
219 if(bChangeRes) sprintf(szTxt,"- Desktop changing [%d Bit]\r\n",iColDepth);
\r
220 else sprintf(szTxt,"- NO desktop changing\r\n");
\r
224 // if(iForceVSync>=0) sprintf(szTxt,"- V-Sync: %s\r\n",szO[iForceVSync]);
\r
225 // else strcpy(szTxt,"- V-Sync: Driver\r\n");
\r
227 sprintf(szTxt,"- Keep psx aspect ratio: %s\r\n\r\n",szO[bKeepRatio]);
\r
229 //----------------------------------------------------//
\r
230 strcpy(szTxt,"Textures:\r\n- ");
\r
231 /*! if(iTexQuality==0) strcat(szTxt,"Default");
\r
232 else if(iTexQuality==1) strcat(szTxt,"R4G4B4A4");
\r
233 else if(iTexQuality==2) strcat(szTxt,"R5G5B5A1");
\r
234 else if(iTexQuality==3) strcat(szTxt,"R8G8A8A8");
\r
235 else if(iTexQuality==4) strcat(szTxt,"B8G8R8A8");
\r
236 if(!hW && bGLExt) strcat(szTxt," (packed pixels)\r\n");
\r
237 else strcat(szTxt,"\r\n");
\r
241 sprintf(szTxt,"- Filtering: %d - edge clamping ",iFilterType);
\r
242 if(iClampType==GL_TO_EDGE_CLAMP) strcat(szTxt,"supported\r\n");
\r
243 else strcat(szTxt,"NOT supported\r\n");
\r
245 else sprintf(szTxt,"- iFiltering: %d\r\n",iFilterType);
\r
247 sprintf(szTxt,"- Hi-Res textures: %d\r\n",iHiResTextures);
\r
251 sprintf(szTxt,"- Palettized tex windows: %s\r\n",szO[iUsePalTextures]);
\r
255 /*sprintf(szTxt,"- VRam size: %d MBytes",iVRamSize);
\r
257 sprintf(szTxt+strlen(szTxt)," - %d textures usable\r\n\r\n",iSortTexCnt);
\r
258 else strcat(szTxt,"\r\n\r\n");
\r
260 //----------------------------------------------------//
\r
261 sprintf(szTxt,"Framerate:\r\n- FPS limitation: %s\r\n",szO[bUseFrameLimit]);
\r
263 sprintf(szTxt,"- Frame skipping: %s\r\n",szO[bUseFrameSkip]);
\r
266 strcpy(szTxt,"- FPS limit: Auto\r\n\r\n");
\r
267 else sprintf(szTxt,"- FPS limit: %.1f\r\n\r\n",fFrameRate);
\r
269 //----------------------------------------------------//
\r
270 sprintf(szTxt,"Compatibility:\r\n- Offscreen drawing: %d\r\n",iOffscreenDrawing);
\r
272 sprintf(szTxt,"- Framebuffer texture: %d",iFrameTexType);
\r
273 if(!hW && iFrameTexType==2)
\r
275 if(gTexFrameName) strcat(szTxt," - texture created\r\n");
\r
276 else strcat(szTxt," - not used yet\r\n");
\r
278 else strcat(szTxt,"\r\n");
\r
280 sprintf(szTxt,"- Framebuffer access: %d\r\n",iFrameReadType);
\r
282 // sprintf(szTxt,"- Alpha multipass: %s\r\n",szO[bOpaquePass]);
\r
284 sprintf(szTxt,"- Mask bit: %s\r\n",szO[iUseMask]);
\r
286 //sprintf(szTxt,"- Advanced blending: %s",szO[bAdvancedBlend]);
\r
287 //if(!hW && bAdvancedBlend)
\r
289 // if(bGLBlend) strcat(szTxt," (hardware)\r\n");
\r
290 // else strcat(szTxt," (software)\r\n");
\r
292 strcat(szTxt,"\r\n");
\r
297 strcpy(szTxt,"- Subtractive blending: ");
\r
298 // if(glBlendEquationEXTEx)
\r
300 // if(bUseMultiPass) strcat(szTxt,"supported, but not used!");
\r
301 // else strcat(szTxt,"activated");
\r
303 strcat(szTxt," NOT supported!");
\r
304 strcat(szTxt,"\r\n\r\n");
\r
306 else strcpy(szTxt,"\r\n");
\r
309 //----------------------------------------------------//
\r
310 sprintf(szTxt,"Misc:\r\n- Scanlines: %s",szO[iUseScanLines]);
\r
312 if(iUseScanLines) sprintf(szTxt," [%d]\r\n",iScanBlend);
\r
313 else strcpy(szTxt,"\r\n");
\r
315 // sprintf(szTxt,"- Line mode: %s\r\n",szO[bUseLines]);
\r
317 // sprintf(szTxt,"- Line AA: %s\r\n",szO[bUseAntiAlias]);
\r
318 // fwrite(szTxt,lstrlen(szTxt),1,txtfile);
\r
319 sprintf(szTxt,"- Unfiltered FB: %s\r\n",szO[bUseFastMdec]);
\r
321 sprintf(szTxt,"- 15 bit FB: %s\r\n",szO[bUse15bitMdec]);
\r
323 sprintf(szTxt,"- Dithering: %s\r\n",szO[bDrawDither]);
\r
325 sprintf(szTxt,"- Screen smoothing: %s",szO[iBlurBuffer]);
\r
327 if(!hW && iBlurBuffer)
\r
329 if(gTexBlurName) strcat(pB," - supported\r\n");
\r
330 else strcat(pB," - not supported\r\n");
\r
332 else strcat(pB,"\r\n");
\r
333 sprintf(szTxt,"- Game fixes: %s [%08lx]\r\n",szO[bUseFixes],dwCfgFixes);
\r
335 //----------------------------------------------------//
\r
339 ////////////////////////////////////////////////////////////////////////
\r
340 // save text infos to file
\r
341 ////////////////////////////////////////////////////////////////////////
\r
343 void DoTextSnapShot(int iNum)
\r
347 ////////////////////////////////////////////////////////////////////////
\r
348 // saves screen bitmap to file
\r
349 ////////////////////////////////////////////////////////////////////////
\r
351 void DoSnapShot(void)
\r
355 void CALLBACK GPUmakeSnapshot(void)
\r
357 //bSnapShot = TRUE;
\r
360 ////////////////////////////////////////////////////////////////////////
\r
361 // GPU INIT... here starts it all (first func called by emu)
\r
362 ////////////////////////////////////////////////////////////////////////
\r
364 long CALLBACK GPUinit()
\r
366 memset(ulStatusControl,0,256*sizeof(unsigned long));
\r
372 // different ways of accessing PSX VRAM
\r
374 psxVSecure=(unsigned char *)malloc((iGPUHeight*2)*1024 + (1024*1024)); // always alloc one extra MB for soft drawing funcs security
\r
375 if(!psxVSecure) return -1;
\r
377 psxVub=psxVSecure+512*1024; // security offset into double sized psx vram!
\r
378 psxVsb=(signed char *)psxVub;
\r
379 psxVsw=(signed short *)psxVub;
\r
380 psxVsl=(signed long *)psxVub;
\r
381 psxVuw=(unsigned short *)psxVub;
\r
382 psxVul=(unsigned long *)psxVub;
\r
384 psxVuw_eom=psxVuw+1024*iGPUHeight; // pre-calc of end of vram
\r
386 memset(psxVSecure,0x00,(iGPUHeight*2)*1024 + (1024*1024));
\r
387 memset(ulGPUInfoVals,0x00,16*sizeof(unsigned long));
\r
389 InitFrameCap(); // init frame rate stuff
\r
391 PSXDisplay.RGB24 = 0; // init vars
\r
392 PreviousPSXDisplay.RGB24= 0;
\r
393 PSXDisplay.Interlaced = 0;
\r
394 PSXDisplay.InterlacedTest=0;
\r
395 PSXDisplay.DrawOffset.x = 0;
\r
396 PSXDisplay.DrawOffset.y = 0;
\r
397 PSXDisplay.DrawArea.x0 = 0;
\r
398 PSXDisplay.DrawArea.y0 = 0;
\r
399 PSXDisplay.DrawArea.x1 = 320;
\r
400 PSXDisplay.DrawArea.y1 = 240;
\r
401 PSXDisplay.DisplayMode.x= 320;
\r
402 PSXDisplay.DisplayMode.y= 240;
\r
403 PSXDisplay.Disabled = FALSE;
\r
404 PreviousPSXDisplay.Range.x0 =0;
\r
405 PreviousPSXDisplay.Range.x1 =0;
\r
406 PreviousPSXDisplay.Range.y0 =0;
\r
407 PreviousPSXDisplay.Range.y1 =0;
\r
408 PSXDisplay.Range.x0=0;
\r
409 PSXDisplay.Range.x1=0;
\r
410 PSXDisplay.Range.y0=0;
\r
411 PSXDisplay.Range.y1=0;
\r
412 PreviousPSXDisplay.DisplayPosition.x = 1;
\r
413 PreviousPSXDisplay.DisplayPosition.y = 1;
\r
414 PSXDisplay.DisplayPosition.x = 1;
\r
415 PSXDisplay.DisplayPosition.y = 1;
\r
416 PreviousPSXDisplay.DisplayModeNew.y=0;
\r
417 PSXDisplay.Double=1;
\r
420 PSXDisplay.DisplayModeNew.x=0;
\r
421 PSXDisplay.DisplayModeNew.y=0;
\r
423 //PreviousPSXDisplay.Height = PSXDisplay.Height = 239;
\r
425 iDataWriteMode = DR_NORMAL;
\r
427 // Reset transfer values, to prevent mis-transfer of data
\r
428 memset(&VRAMWrite,0,sizeof(VRAMLoad_t));
\r
429 memset(&VRAMRead,0,sizeof(VRAMLoad_t));
\r
431 // device initialised already !
\r
432 //lGPUstatusRet = 0x74000000;
\r
434 STATUSREG = 0x14802000;
\r
436 GPUIsReadyForCommands;
\r
442 ////////////////////////////////////////////////////////////////////////
\r
443 // OPEN interface func: attention!
\r
444 // some emus are calling this func in their main Window thread,
\r
445 // but all other interface funcs (to draw stuff) in a different thread!
\r
446 // that's a problem, since OGL is thread safe! Therefore we cannot
\r
447 // initialize the OGL stuff right here, we simply set a "bIsFirstFrame = TRUE"
\r
448 // flag, to initialize OGL on the first real draw call.
\r
449 // btw, we also call this open func ourselfes, each time when the user
\r
450 // is changing between fullscreen/window mode (ENTER key)
\r
451 // btw part 2: in windows the plugin gets the window handle from the
\r
452 // main emu, and doesn't create it's own window (if it would do it,
\r
453 // some PAD or SPU plugins would not work anymore)
\r
454 ////////////////////////////////////////////////////////////////////////
\r
456 long CALLBACK GPUopen(int hwndGPU)
\r
458 iResX=800;iResY=480;
\r
464 // bAdvancedBlend=FALSE;
\r
466 // bUseLines=FALSE;
\r
467 bUseFrameLimit=FALSE;
\r
468 bUseFrameSkip=FALSE;
\r
471 iOffscreenDrawing=0;
\r
472 //bOpaquePass=FALSE;
\r
473 //bUseAntiAlias=FALSE;
\r
477 bUseFastMdec=FALSE;
\r
478 bUse15bitMdec=FALSE;
\r
481 // iUseScanLines=0;
\r
488 iTexGarbageCollection=0;
\r
490 //iHiResTextures=0;
\r
496 bIsFirstFrame = TRUE; // flag: we have to init OGL later in windows!
\r
498 rRatioRect.left = rRatioRect.top=0;
\r
499 rRatioRect.right = iResX;
\r
500 rRatioRect.bottom = iResY;
\r
502 bDisplayNotSet = TRUE;
\r
505 SetFixes(); // setup game fixes
\r
507 InitializeTextureStore(); // init texture mem
\r
509 CSTEXTURE = CSVERTEX = CSCOLOR = 0;
\r
511 // lGPUstatusRet = 0x74000000;
\r
513 // with some emus, we could do the OGL init right here... oh my
\r
514 if(bIsFirstFrame) GLinitialize(NULL, NULL);
\r
519 ////////////////////////////////////////////////////////////////////////
\r
521 ////////////////////////////////////////////////////////////////////////
\r
524 long GPUclose() // LINUX CLOSE
\r
526 GLcleanup(); // close OGL
\r
528 if(pGfxCardScreen) free(pGfxCardScreen); // free helper memory
\r
531 // osd_close_display(); // destroy display
\r
536 ////////////////////////////////////////////////////////////////////////
\r
537 // I shot the sheriff... last function called from emu
\r
538 ////////////////////////////////////////////////////////////////////////
\r
540 long CALLBACK GPUshutdown()
\r
542 if(psxVSecure) free(psxVSecure); // kill emulated vram memory
\r
548 ////////////////////////////////////////////////////////////////////////
\r
549 // paint it black: simple func to clean up optical border garbage
\r
550 ////////////////////////////////////////////////////////////////////////
\r
552 void PaintBlackBorders(void)
\r
555 glDisable(GL_SCISSOR_TEST); glError();
\r
556 if(bTexEnabled) {glDisable(GL_TEXTURE_2D);bTexEnabled=FALSE;} glError();
\r
557 if(bOldSmoothShaded) {glShadeModel(GL_FLAT);bOldSmoothShaded=FALSE;} glError();
\r
558 if(bBlendEnable) {glDisable(GL_BLEND);bBlendEnable=FALSE;} glError();
\r
559 glDisable(GL_ALPHA_TEST); glError();
\r
561 glEnable(GL_ALPHA_TEST); glError();
\r
562 glEnable(GL_SCISSOR_TEST); glError();
\r
566 ////////////////////////////////////////////////////////////////////////
\r
567 // helper to draw scanlines
\r
568 ////////////////////////////////////////////////////////////////////////
\r
570 __inline void XPRIMdrawTexturedQuad(OGLVertex* vertex1, OGLVertex* vertex2,
\r
571 OGLVertex* vertex3, OGLVertex* vertex4)
\r
576 ////////////////////////////////////////////////////////////////////////
\r
578 ////////////////////////////////////////////////////////////////////////
\r
580 void SetScanLines(void)
\r
584 ////////////////////////////////////////////////////////////////////////
\r
585 // blur, babe, blur (heavy performance hit for a so-so fullscreen effect)
\r
586 ////////////////////////////////////////////////////////////////////////
\r
589 ////////////////////////////////////////////////////////////////////////
\r
590 // Update display (swap buffers)... called in interlaced mode on
\r
591 // every emulated vsync, otherwise whenever the displayed screen region
\r
592 // has been changed
\r
593 ////////////////////////////////////////////////////////////////////////
\r
595 int iLastRGB24=0; // special vars for checking when to skip two display updates
\r
597 void GPUvSinc(void){
\r
600 void updateDisplay(void) // UPDATE DISPLAY
\r
605 bFakeFrontBuffer=FALSE;
\r
606 bRenderFrontBuffer=FALSE;
\r
608 if(iRenderFVR) // frame buffer read fix mode still active?
\r
610 iRenderFVR--; // -> if some frames in a row without read access: turn off mode
\r
611 if(!iRenderFVR) bFullVRam=FALSE;
\r
614 if(iLastRGB24 && iLastRGB24!=PSXDisplay.RGB24+1) // (mdec) garbage check
\r
616 iSkipTwo=2; // -> skip two frames to avoid garbage if color mode changes
\r
620 if(PSXDisplay.RGB24)// && !bNeedUploadAfter) // (mdec) upload wanted?
\r
622 PrepareFullScreenUpload(-1);
\r
623 UploadScreen(PSXDisplay.Interlaced); // -> upload whole screen from psx vram
\r
624 bNeedUploadTest=FALSE;
\r
625 bNeedInterlaceUpdate=FALSE;
\r
626 bNeedUploadAfter=FALSE;
\r
627 bNeedRGB24Update=FALSE;
\r
630 if(bNeedInterlaceUpdate) // smaller upload?
\r
632 bNeedInterlaceUpdate=FALSE;
\r
633 xrUploadArea=xrUploadAreaIL; // -> upload this rect
\r
634 UploadScreen(TRUE);
\r
637 if(dwActFixes&512) bCheckFF9G4(NULL); // special game fix for FF9
\r
639 if(PreviousPSXDisplay.Range.x0|| // paint black borders around display area, if needed
\r
640 PreviousPSXDisplay.Range.y0)
\r
641 PaintBlackBorders();
\r
643 if(PSXDisplay.Disabled) // display disabled?
\r
645 //LOGE("PSXDisplay.Disabled");
\r
648 glDisable(GL_SCISSOR_TEST); glError();
\r
649 glClearColor(0,0,0,128); glError(); // -> clear whole backbuffer
\r
650 glClear(uiBufferBits); glError();
\r
651 glEnable(GL_SCISSOR_TEST); glError();
\r
653 bDisplayNotSet = TRUE;
\r
656 if(iSkipTwo) // we are in skipping mood?
\r
659 iDrawnSomething=0; // -> simply lie about something drawn
\r
662 //if(iBlurBuffer && !bSkipNextFrame) // "blur display" activated?
\r
663 // {BlurBackBuffer();bBlur=TRUE;} // -> blur it
\r
665 // if(iUseScanLines) SetScanLines(); // "scan lines" activated? do it
\r
667 // if(usCursorActive) ShowGunCursor(); // "gun cursor" wanted? show 'em
\r
669 if(dwActFixes&128) // special FPS limitation mode?
\r
671 if(bUseFrameLimit) PCFrameCap(); // -> ok, do it
\r
672 // if(bUseFrameSkip || ulKeybits&KEY_SHOWFPS)
\r
676 // if(gTexPicName) DisplayPic(); // some gpu info picture active? display it
\r
678 // if(bSnapShot) DoSnapShot(); // snapshot key pressed? cheeeese :)
\r
680 // if(ulKeybits&KEY_SHOWFPS) // wanna see FPS?
\r
682 // sprintf(szDispBuf,"%06.1f",fps_cur);
\r
683 // DisplayText(); // -> show it
\r
686 //----------------------------------------------------//
\r
687 // main buffer swapping (well, or skip it)
\r
689 if(bUseFrameSkip) // frame skipping active ?
\r
691 if(!bSkipNextFrame)
\r
693 if(iDrawnSomething) flipEGL();
\r
695 if((fps_skip < fFrameRateHz) && !(bSkipNextFrame))
\r
696 {bSkipNextFrame = TRUE; fps_skip=fFrameRateHz;}
\r
697 else bSkipNextFrame = FALSE;
\r
702 if(iDrawnSomething) flipEGL();
\r
707 //----------------------------------------------------//
\r
709 if(lClearOnSwap) // clear buffer after swap?
\r
713 if(bDisplayNotSet) // -> set new vals
\r
714 SetOGLDisplaySettings(1);
\r
716 g=((GLclampf)GREEN(lClearOnSwapColor))/255.0f; // -> get col
\r
717 b=((GLclampf)BLUE(lClearOnSwapColor))/255.0f;
\r
718 r=((GLclampf)RED(lClearOnSwapColor))/255.0f;
\r
719 glDisable(GL_SCISSOR_TEST); glError();
\r
720 glClearColor(r,g,b,128); glError(); // -> clear
\r
721 glClear(uiBufferBits); glError();
\r
722 glEnable(GL_SCISSOR_TEST); glError();
\r
723 lClearOnSwap=0; // -> done
\r
727 // if(bBlur) UnBlurBackBuffer(); // unblur buff, if blurred before
\r
729 if(iZBufferDepth) // clear zbuffer as well (if activated)
\r
731 glDisable(GL_SCISSOR_TEST); glError();
\r
732 glClear(GL_DEPTH_BUFFER_BIT); glError();
\r
733 glEnable(GL_SCISSOR_TEST); glError();
\r
739 //----------------------------------------------------//
\r
740 // additional uploads immediatly after swapping
\r
742 if(bNeedUploadAfter) // upload wanted?
\r
744 bNeedUploadAfter=FALSE;
\r
745 bNeedUploadTest=FALSE;
\r
746 UploadScreen(-1); // -> upload
\r
749 if(bNeedUploadTest)
\r
751 bNeedUploadTest=FALSE;
\r
752 if(PSXDisplay.InterlacedTest &&
\r
753 //iOffscreenDrawing>2 &&
\r
754 PreviousPSXDisplay.DisplayPosition.x==PSXDisplay.DisplayPosition.x &&
\r
755 PreviousPSXDisplay.DisplayEnd.x==PSXDisplay.DisplayEnd.x &&
\r
756 PreviousPSXDisplay.DisplayPosition.y==PSXDisplay.DisplayPosition.y &&
\r
757 PreviousPSXDisplay.DisplayEnd.y==PSXDisplay.DisplayEnd.y)
\r
759 PrepareFullScreenUpload(TRUE);
\r
760 UploadScreen(TRUE);
\r
764 //----------------------------------------------------//
\r
765 // rumbling (main emu pad effect)
\r
767 if(iRumbleTime) // shake screen by modifying view port
\r
769 int i1=0,i2=0,i3=0,i4=0;
\r
774 i1=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2);
\r
775 i2=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2);
\r
776 i3=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2);
\r
777 i4=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2);
\r
780 glViewport(rRatioRect.left+i1,
\r
781 iResY-(rRatioRect.top+rRatioRect.bottom)+i2,
\r
782 rRatioRect.right+i3,
\r
783 rRatioRect.bottom+i4); glError();
\r
786 //----------------------------------------------------//
\r
790 // if(ulKeybits&KEY_RESETTEXSTORE) ResetStuff(); // reset on gpu mode changes? do it before next frame is filled
\r
793 ////////////////////////////////////////////////////////////////////////
\r
794 // update front display: smaller update func, if something has changed
\r
795 // in the frontbuffer... dirty, but hey... real men know no pain
\r
796 ////////////////////////////////////////////////////////////////////////
\r
798 void updateFrontDisplay(void)
\r
800 if(PreviousPSXDisplay.Range.x0||
\r
801 PreviousPSXDisplay.Range.y0)
\r
802 PaintBlackBorders();
\r
804 //if(iBlurBuffer) BlurBackBuffer();
\r
806 //if(iUseScanLines) SetScanLines();
\r
808 // if(usCursorActive) ShowGunCursor();
\r
810 bFakeFrontBuffer=FALSE;
\r
811 bRenderFrontBuffer=FALSE;
\r
813 // if(gTexPicName) DisplayPic();
\r
814 // if(ulKeybits&KEY_SHOWFPS) DisplayText();
\r
816 if(iDrawnSomething) // linux:
\r
820 //if(iBlurBuffer) UnBlurBackBuffer();
\r
823 ////////////////////////////////////////////////////////////////////////
\r
824 // check if update needed
\r
825 ////////////////////////////////////////////////////////////////////////
\r
826 void ChangeDispOffsetsX(void) // CENTER X
\r
828 long lx,l;short sO;
\r
830 if(!PSXDisplay.Range.x1) return; // some range given?
\r
832 l=PSXDisplay.DisplayMode.x;
\r
834 l*=(long)PSXDisplay.Range.x1; // some funky calculation
\r
835 l/=2560;lx=l;l&=0xfffffff8;
\r
837 if(l==PreviousPSXDisplay.Range.x1) return; // some change?
\r
839 sO=PreviousPSXDisplay.Range.x0; // store old
\r
841 if(lx>=PSXDisplay.DisplayMode.x) // range bigger?
\r
843 PreviousPSXDisplay.Range.x1= // -> take display width
\r
844 PSXDisplay.DisplayMode.x;
\r
845 PreviousPSXDisplay.Range.x0=0; // -> start pos is 0
\r
847 else // range smaller? center it
\r
849 PreviousPSXDisplay.Range.x1=l; // -> store width (8 pixel aligned)
\r
850 PreviousPSXDisplay.Range.x0= // -> calc start pos
\r
851 (PSXDisplay.Range.x0-500)/8;
\r
852 if(PreviousPSXDisplay.Range.x0<0) // -> we don't support neg. values yet
\r
853 PreviousPSXDisplay.Range.x0=0;
\r
855 if((PreviousPSXDisplay.Range.x0+lx)> // -> uhuu... that's too much
\r
856 PSXDisplay.DisplayMode.x)
\r
858 PreviousPSXDisplay.Range.x0= // -> adjust start
\r
859 PSXDisplay.DisplayMode.x-lx;
\r
860 PreviousPSXDisplay.Range.x1+=lx-l; // -> adjust width
\r
864 if(sO!=PreviousPSXDisplay.Range.x0) // something changed?
\r
866 bDisplayNotSet=TRUE; // -> recalc display stuff
\r
870 ////////////////////////////////////////////////////////////////////////
\r
872 void ChangeDispOffsetsY(void) // CENTER Y
\r
874 int iT;short sO; // store previous y size
\r
876 if(PSXDisplay.PAL) iT=48; else iT=28; // different offsets on PAL/NTSC
\r
878 if(PSXDisplay.Range.y0>=iT) // crossed the security line? :)
\r
880 PreviousPSXDisplay.Range.y1= // -> store width
\r
881 PSXDisplay.DisplayModeNew.y;
\r
883 sO=(PSXDisplay.Range.y0-iT-4)*PSXDisplay.Double; // -> calc offset
\r
886 PSXDisplay.DisplayModeNew.y+=sO; // -> add offset to y size, too
\r
888 else sO=0; // else no offset
\r
890 if(sO!=PreviousPSXDisplay.Range.y0) // something changed?
\r
892 PreviousPSXDisplay.Range.y0=sO;
\r
893 bDisplayNotSet=TRUE; // -> recalc display stuff
\r
897 ////////////////////////////////////////////////////////////////////////
\r
898 // Aspect ratio of ogl screen: simply adjusting ogl view port
\r
899 ////////////////////////////////////////////////////////////////////////
\r
901 void SetAspectRatio(void)
\r
903 float xs,ys,s;RECT r;
\r
905 if(!PSXDisplay.DisplayModeNew.x) return;
\r
906 if(!PSXDisplay.DisplayModeNew.y) return;
\r
909 xs=(float)iResX/(float)PSXDisplay.DisplayModeNew.x;
\r
910 ys=(float)iResY/(float)PSXDisplay.DisplayModeNew.y;
\r
913 r.right =(int)((float)PSXDisplay.DisplayModeNew.x*s);
\r
914 r.bottom=(int)((float)PSXDisplay.DisplayModeNew.y*s);
\r
915 if(r.right > iResX) r.right = iResX;
\r
916 if(r.bottom > iResY) r.bottom = iResY;
\r
917 if(r.right < 1) r.right = 1;
\r
918 if(r.bottom < 1) r.bottom = 1;
\r
920 r.left = (iResX-r.right)/2;
\r
921 r.top = (iResY-r.bottom)/2;
\r
922 if(r.bottom<rRatioRect.bottom ||
\r
923 r.right <rRatioRect.right)
\r
926 glClearColor(0,0,0,128); glError();
\r
928 if(r.right <rRatioRect.right)
\r
934 glScissor(rC.left,rC.top,rC.right,rC.bottom); glError();
\r
935 glClear(uiBufferBits); glError();
\r
936 rC.left=iResX-rC.right;
\r
937 glScissor(rC.left,rC.top,rC.right,rC.bottom); glError();
\r
939 glClear(uiBufferBits); glError();
\r
942 if(r.bottom <rRatioRect.bottom)
\r
948 glScissor(rC.left,rC.top,rC.right,rC.bottom); glError();
\r
950 glClear(uiBufferBits); glError();
\r
951 rC.top=iResY-rC.bottom;
\r
952 glScissor(rC.left,rC.top,rC.right,rC.bottom); glError();
\r
953 glClear(uiBufferBits); glError();
\r
957 bDisplayNotSet=TRUE;
\r
962 // pcsx-rearmed hack
\r
963 if (rearmed_get_layer_pos != NULL)
\r
964 rearmed_get_layer_pos(&rRatioRect.left, &rRatioRect.top, &rRatioRect.right, &rRatioRect.bottom);
\r
967 glViewport(rRatioRect.left,
\r
968 iResY-(rRatioRect.top+rRatioRect.bottom),
\r
970 rRatioRect.bottom); glError(); // init viewport
\r
973 ////////////////////////////////////////////////////////////////////////
\r
974 // big ass check, if an ogl swap buffer is needed
\r
975 ////////////////////////////////////////////////////////////////////////
\r
977 void updateDisplayIfChanged(void)
\r
981 if ((PSXDisplay.DisplayMode.y == PSXDisplay.DisplayModeNew.y) &&
\r
982 (PSXDisplay.DisplayMode.x == PSXDisplay.DisplayModeNew.x))
\r
984 if((PSXDisplay.RGB24 == PSXDisplay.RGB24New) &&
\r
985 (PSXDisplay.Interlaced == PSXDisplay.InterlacedNew))
\r
986 return; // nothing has changed? fine, no swap buffer needed
\r
988 else // some res change?
\r
990 glLoadIdentity(); glError();
\r
991 glOrtho(0,PSXDisplay.DisplayModeNew.x, // -> new psx resolution
\r
992 PSXDisplay.DisplayModeNew.y, 0, -1, 1); glError();
\r
993 if(bKeepRatio) SetAspectRatio();
\r
996 bDisplayNotSet = TRUE; // re-calc offsets/display area
\r
999 if(PSXDisplay.RGB24!=PSXDisplay.RGB24New) // clean up textures, if rgb mode change (usually mdec on/off)
\r
1001 PreviousPSXDisplay.RGB24=0; // no full 24 frame uploaded yet
\r
1002 ResetTextureArea(FALSE);
\r
1006 PSXDisplay.RGB24 = PSXDisplay.RGB24New; // get new infos
\r
1007 PSXDisplay.DisplayMode.y = PSXDisplay.DisplayModeNew.y;
\r
1008 PSXDisplay.DisplayMode.x = PSXDisplay.DisplayModeNew.x;
\r
1009 PSXDisplay.Interlaced = PSXDisplay.InterlacedNew;
\r
1011 PSXDisplay.DisplayEnd.x= // calc new ends
\r
1012 PSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;
\r
1013 PSXDisplay.DisplayEnd.y=
\r
1014 PSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;
\r
1015 PreviousPSXDisplay.DisplayEnd.x=
\r
1016 PreviousPSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;
\r
1017 PreviousPSXDisplay.DisplayEnd.y=
\r
1018 PreviousPSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;
\r
1020 ChangeDispOffsetsX();
\r
1022 if(iFrameLimit==2) SetAutoFrameCap(); // set new fps limit vals (depends on interlace)
\r
1024 if(bUp) updateDisplay(); // yeah, real update (swap buffer)
\r
1027 ////////////////////////////////////////////////////////////////////////
\r
1028 // window mode <-> fullscreen mode (windows)
\r
1029 ////////////////////////////////////////////////////////////////////////
\r
1032 ////////////////////////////////////////////////////////////////////////
\r
1033 // swap update check (called by psx vsync function)
\r
1034 ////////////////////////////////////////////////////////////////////////
\r
1036 BOOL bSwapCheck(void)
\r
1038 static int iPosCheck=0;
\r
1039 static PSXPoint_t pO;
\r
1040 static PSXPoint_t pD;
\r
1041 static int iDoAgain=0;
\r
1043 if(PSXDisplay.DisplayPosition.x==pO.x &&
\r
1044 PSXDisplay.DisplayPosition.y==pO.y &&
\r
1045 PSXDisplay.DisplayEnd.x==pD.x &&
\r
1046 PSXDisplay.DisplayEnd.y==pD.y)
\r
1050 pO=PSXDisplay.DisplayPosition;
\r
1051 pD=PSXDisplay.DisplayEnd;
\r
1053 if(iPosCheck<=4) return FALSE;
\r
1057 if(PSXDisplay.Interlaced) return FALSE;
\r
1059 if (bNeedInterlaceUpdate||
\r
1060 bNeedRGB24Update ||
\r
1061 bNeedUploadAfter||
\r
1062 bNeedUploadTest ||
\r
1067 if(bNeedUploadAfter)
\r
1069 if(bNeedUploadTest && PSXDisplay.InterlacedTest)
\r
1072 bDisplayNotSet = TRUE;
\r
1075 PreviousPSXDisplay.DisplayPosition.x=PSXDisplay.DisplayPosition.x;
\r
1076 PreviousPSXDisplay.DisplayPosition.y=PSXDisplay.DisplayPosition.y;
\r
1077 PreviousPSXDisplay.DisplayEnd.x=PSXDisplay.DisplayEnd.x;
\r
1078 PreviousPSXDisplay.DisplayEnd.y=PSXDisplay.DisplayEnd.y;
\r
1079 pO=PSXDisplay.DisplayPosition;
\r
1080 pD=PSXDisplay.DisplayEnd;
\r
1087 ////////////////////////////////////////////////////////////////////////
\r
1088 // gun cursor func: player=0-7, x=0-511, y=0-255
\r
1089 ////////////////////////////////////////////////////////////////////////
\r
1091 ////////////////////////////////////////////////////////////////////////
\r
1092 // update lace is called every VSync. Basically we limit frame rate
\r
1093 // here, and in interlaced mode we swap ogl display buffers.
\r
1094 ////////////////////////////////////////////////////////////////////////
\r
1096 static unsigned short usFirstPos=2;
\r
1098 void CALLBACK GPUupdateLace(void)
\r
1100 if(!(dwActFixes&0x1000))
\r
1101 STATUSREG^=0x80000000; // interlaced bit toggle, if the CC game fix is not active (see gpuReadStatus)
\r
1103 if(!(dwActFixes&128)) // normal frame limit func
\r
1106 if(iOffscreenDrawing==4) // special check if high offscreen drawing is on
\r
1108 if(bSwapCheck()) return;
\r
1111 if(PSXDisplay.Interlaced) // interlaced mode?
\r
1113 if(PSXDisplay.DisplayMode.x>0 && PSXDisplay.DisplayMode.y>0)
\r
1115 updateDisplay(); // -> swap buffers (new frame)
\r
1118 else if(bRenderFrontBuffer) // no interlace mode? and some stuff in front has changed?
\r
1120 updateFrontDisplay(); // -> update front buffer
\r
1122 else if(usFirstPos==1) // initial updates (after startup)
\r
1129 ////////////////////////////////////////////////////////////////////////
\r
1130 // process read request from GPU status register
\r
1131 ////////////////////////////////////////////////////////////////////////
\r
1133 unsigned long CALLBACK GPUreadStatus(void)
\r
1135 if(dwActFixes&0x1000) // CC game fix
\r
1137 static int iNumRead=0;
\r
1138 if((iNumRead++)==2)
\r
1141 STATUSREG^=0x80000000; // interlaced bit toggle... we do it on every second read status... needed by some games (like ChronoCross)
\r
1145 if(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
1149 if(iFakePrimBusy&1) // we do a busy-idle-busy-idle sequence after/while drawing prims
\r
1152 GPUIsNotReadyForCommands;
\r
1157 GPUIsReadyForCommands;
\r
1164 ////////////////////////////////////////////////////////////////////////
\r
1165 // processes data send to GPU status register
\r
1166 // these are always single packet commands.
\r
1167 ////////////////////////////////////////////////////////////////////////
\r
1169 void CALLBACK GPUwriteStatus(unsigned long gdata)
\r
1171 unsigned long lCommand=(gdata>>24)&0xff;
\r
1173 if(bIsFirstFrame) GLinitialize(NULL, NULL); // real ogl startup (needed by some emus)
\r
1175 ulStatusControl[lCommand]=gdata;
\r
1179 //--------------------------------------------------//
\r
1182 memset(ulGPUInfoVals,0x00,16*sizeof(unsigned long));
\r
1183 lGPUstatusRet=0x14802000;
\r
1184 PSXDisplay.Disabled=1;
\r
1185 iDataWriteMode=iDataReadMode=DR_NORMAL;
\r
1186 PSXDisplay.DrawOffset.x=PSXDisplay.DrawOffset.y=0;
\r
1187 drawX=drawY=0;drawW=drawH=0;
\r
1188 sSetMask=0;lSetMask=0;bCheckMask=FALSE;iSetMask=0;
\r
1190 GlobalTextAddrX=0;GlobalTextAddrY=0;
\r
1191 GlobalTextTP=0;GlobalTextABR=0;
\r
1192 PSXDisplay.RGB24=FALSE;
\r
1193 PSXDisplay.Interlaced=FALSE;
\r
1194 bUsingTWin = FALSE;
\r
1197 // dis/enable display
\r
1199 PreviousPSXDisplay.Disabled = PSXDisplay.Disabled;
\r
1200 PSXDisplay.Disabled = (gdata & 1);
\r
1202 if(PSXDisplay.Disabled)
\r
1203 STATUSREG|=GPUSTATUS_DISPLAYDISABLED;
\r
1204 else STATUSREG&=~GPUSTATUS_DISPLAYDISABLED;
\r
1206 if (iOffscreenDrawing==4 &&
\r
1207 PreviousPSXDisplay.Disabled &&
\r
1208 !(PSXDisplay.Disabled))
\r
1211 if(!PSXDisplay.RGB24)
\r
1213 PrepareFullScreenUpload(TRUE);
\r
1214 UploadScreen(TRUE);
\r
1221 // setting transfer mode
\r
1223 gdata &= 0x03; // only want the lower two bits
\r
1225 iDataWriteMode=iDataReadMode=DR_NORMAL;
\r
1226 if(gdata==0x02) iDataWriteMode=DR_VRAMTRANSFER;
\r
1227 if(gdata==0x03) iDataReadMode =DR_VRAMTRANSFER;
\r
1229 STATUSREG&=~GPUSTATUS_DMABITS; // clear the current settings of the DMA bits
\r
1230 STATUSREG|=(gdata << 29); // set the DMA bits according to the received data
\r
1234 // setting display position
\r
1237 short sx=(short)(gdata & 0x3ff);
\r
1240 if(iGPUHeight==1024)
\r
1242 if(dwGPUVersion==2)
\r
1243 sy = (short)((gdata>>12)&0x3ff);
\r
1244 else sy = (short)((gdata>>10)&0x3ff);
\r
1246 else sy = (short)((gdata>>10)&0x3ff); // really: 0x1ff, but we adjust it later
\r
1251 PreviousPSXDisplay.DisplayModeNew.y=sy/PSXDisplay.Double;
\r
1254 else PreviousPSXDisplay.DisplayModeNew.y=0;
\r
1263 PreviousPSXDisplay.DisplayPosition.x = sx;
\r
1264 PreviousPSXDisplay.DisplayPosition.y = sy;
\r
1265 PSXDisplay.DisplayPosition.x = sx;
\r
1266 PSXDisplay.DisplayPosition.y = sy;
\r
1272 if((!PSXDisplay.Interlaced) &&
\r
1273 PreviousPSXDisplay.DisplayPosition.x == sx &&
\r
1274 PreviousPSXDisplay.DisplayPosition.y == sy)
\r
1277 PSXDisplay.DisplayPosition.x = PreviousPSXDisplay.DisplayPosition.x;
\r
1278 PSXDisplay.DisplayPosition.y = PreviousPSXDisplay.DisplayPosition.y;
\r
1279 PreviousPSXDisplay.DisplayPosition.x = sx;
\r
1280 PreviousPSXDisplay.DisplayPosition.y = sy;
\r
1284 if((!PSXDisplay.Interlaced) &&
\r
1285 PSXDisplay.DisplayPosition.x == sx &&
\r
1286 PSXDisplay.DisplayPosition.y == sy)
\r
1288 PreviousPSXDisplay.DisplayPosition.x = PSXDisplay.DisplayPosition.x;
\r
1289 PreviousPSXDisplay.DisplayPosition.y = PSXDisplay.DisplayPosition.y;
\r
1290 PSXDisplay.DisplayPosition.x = sx;
\r
1291 PSXDisplay.DisplayPosition.y = sy;
\r
1294 PSXDisplay.DisplayEnd.x=
\r
1295 PSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;
\r
1296 PSXDisplay.DisplayEnd.y=
\r
1297 PSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;
\r
1299 PreviousPSXDisplay.DisplayEnd.x=
\r
1300 PreviousPSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;
\r
1301 PreviousPSXDisplay.DisplayEnd.y=
\r
1302 PreviousPSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;
\r
1304 bDisplayNotSet = TRUE;
\r
1306 if (!(PSXDisplay.Interlaced))
\r
1311 if(PSXDisplay.InterlacedTest &&
\r
1312 ((PreviousPSXDisplay.DisplayPosition.x != PSXDisplay.DisplayPosition.x)||
\r
1313 (PreviousPSXDisplay.DisplayPosition.y != PSXDisplay.DisplayPosition.y)))
\r
1314 PSXDisplay.InterlacedTest--;
\r
1322 PSXDisplay.Range.x0=gdata & 0x7ff; //0x3ff;
\r
1323 PSXDisplay.Range.x1=(gdata>>12) & 0xfff;//0x7ff;
\r
1325 PSXDisplay.Range.x1-=PSXDisplay.Range.x0;
\r
1327 ChangeDispOffsetsX();
\r
1334 PreviousPSXDisplay.Height = PSXDisplay.Height;
\r
1336 PSXDisplay.Range.y0=gdata & 0x3ff;
\r
1337 PSXDisplay.Range.y1=(gdata>>10) & 0x3ff;
\r
1339 PSXDisplay.Height = PSXDisplay.Range.y1 -
\r
1340 PSXDisplay.Range.y0 +
\r
1341 PreviousPSXDisplay.DisplayModeNew.y;
\r
1343 if (PreviousPSXDisplay.Height != PSXDisplay.Height)
\r
1345 PSXDisplay.DisplayModeNew.y=PSXDisplay.Height*PSXDisplay.Double;
\r
1346 ChangeDispOffsetsY();
\r
1347 updateDisplayIfChanged();
\r
1351 // setting display infos
\r
1354 PSXDisplay.DisplayModeNew.x = dispWidths[(gdata & 0x03) | ((gdata & 0x40) >> 4)];
\r
1356 if (gdata&0x04) PSXDisplay.Double=2;
\r
1357 else PSXDisplay.Double=1;
\r
1358 PSXDisplay.DisplayModeNew.y = PSXDisplay.Height*PSXDisplay.Double;
\r
1360 ChangeDispOffsetsY();
\r
1362 PSXDisplay.PAL = (gdata & 0x08)?TRUE:FALSE; // if 1 - PAL mode, else NTSC
\r
1363 PSXDisplay.RGB24New = (gdata & 0x10)?TRUE:FALSE; // if 1 - TrueColor
\r
1364 PSXDisplay.InterlacedNew = (gdata & 0x20)?TRUE:FALSE; // if 1 - Interlace
\r
1366 STATUSREG&=~GPUSTATUS_WIDTHBITS; // clear the width bits
\r
1369 (((gdata & 0x03) << 17) |
\r
1370 ((gdata & 0x40) << 10)); // set the width bits
\r
1372 PreviousPSXDisplay.InterlacedNew=FALSE;
\r
1373 if (PSXDisplay.InterlacedNew)
\r
1375 if(!PSXDisplay.Interlaced)
\r
1377 PSXDisplay.InterlacedTest=2;
\r
1378 PreviousPSXDisplay.DisplayPosition.x = PSXDisplay.DisplayPosition.x;
\r
1379 PreviousPSXDisplay.DisplayPosition.y = PSXDisplay.DisplayPosition.y;
\r
1380 PreviousPSXDisplay.InterlacedNew=TRUE;
\r
1383 STATUSREG|=GPUSTATUS_INTERLACED;
\r
1387 PSXDisplay.InterlacedTest=0;
\r
1388 STATUSREG&=~GPUSTATUS_INTERLACED;
\r
1391 if (PSXDisplay.PAL)
\r
1392 STATUSREG|=GPUSTATUS_PAL;
\r
1393 else STATUSREG&=~GPUSTATUS_PAL;
\r
1395 if (PSXDisplay.Double==2)
\r
1396 STATUSREG|=GPUSTATUS_DOUBLEHEIGHT;
\r
1397 else STATUSREG&=~GPUSTATUS_DOUBLEHEIGHT;
\r
1399 if (PSXDisplay.RGB24New)
\r
1400 STATUSREG|=GPUSTATUS_RGB24;
\r
1401 else STATUSREG&=~GPUSTATUS_RGB24;
\r
1403 updateDisplayIfChanged();
\r
1407 //--------------------------------------------------//
\r
1408 // ask about GPU version and other stuff
\r
1416 GPUdataRet=ulGPUInfoVals[INFO_TW]; // tw infos
\r
1419 GPUdataRet=ulGPUInfoVals[INFO_DRAWSTART]; // draw start
\r
1422 GPUdataRet=ulGPUInfoVals[INFO_DRAWEND]; // draw end
\r
1426 GPUdataRet=ulGPUInfoVals[INFO_DRAWOFF]; // draw offset
\r
1429 if(dwGPUVersion==2)
\r
1431 else GPUdataRet=0x02; // gpu type
\r
1434 case 0x0F: // some bios addr?
\r
1435 GPUdataRet=0xBFC03720;
\r
1439 //--------------------------------------------------//
\r
1443 ////////////////////////////////////////////////////////////////////////
\r
1444 // vram read/write helpers
\r
1445 ////////////////////////////////////////////////////////////////////////
\r
1447 BOOL bNeedWriteUpload=FALSE;
\r
1449 __inline void FinishedVRAMWrite(void)
\r
1451 if(bNeedWriteUpload)
\r
1453 bNeedWriteUpload=FALSE;
\r
1454 CheckWriteUpdate();
\r
1457 // set register to NORMAL operation
\r
1458 iDataWriteMode = DR_NORMAL;
\r
1460 // reset transfer values, to prevent mis-transfer of data
\r
1461 VRAMWrite.ColsRemaining = 0;
\r
1462 VRAMWrite.RowsRemaining = 0;
\r
1465 __inline void FinishedVRAMRead(void)
\r
1467 // set register to NORMAL operation
\r
1468 iDataReadMode = DR_NORMAL;
\r
1469 // reset transfer values, to prevent mis-transfer of data
\r
1472 VRAMRead.Width = 0;
\r
1473 VRAMRead.Height = 0;
\r
1474 VRAMRead.ColsRemaining = 0;
\r
1475 VRAMRead.RowsRemaining = 0;
\r
1477 // indicate GPU is no longer ready for VRAM data in the STATUS REGISTER
\r
1478 STATUSREG&=~GPUSTATUS_READYFORVRAM;
\r
1481 ////////////////////////////////////////////////////////////////////////
\r
1482 // vram read check ex (reading from card's back/frontbuffer if needed...
\r
1484 ////////////////////////////////////////////////////////////////////////
\r
1486 void CheckVRamReadEx(int x, int y, int dx, int dy)
\r
1488 unsigned short sArea;
\r
1489 int ux,uy,udx,udy,wx,wy;
\r
1490 unsigned short * p1, *p2;
\r
1492 unsigned char * ps;
\r
1493 unsigned char * px;
\r
1494 unsigned short s,sx;
\r
1496 if(STATUSREG&GPUSTATUS_RGB24) return;
\r
1498 if(((dx > PSXDisplay.DisplayPosition.x) &&
\r
1499 (x < PSXDisplay.DisplayEnd.x) &&
\r
1500 (dy > PSXDisplay.DisplayPosition.y) &&
\r
1501 (y < PSXDisplay.DisplayEnd.y)))
\r
1504 if((!(PSXDisplay.InterlacedTest) &&
\r
1505 (dx > PreviousPSXDisplay.DisplayPosition.x) &&
\r
1506 (x < PreviousPSXDisplay.DisplayEnd.x) &&
\r
1507 (dy > PreviousPSXDisplay.DisplayPosition.y) &&
\r
1508 (y < PreviousPSXDisplay.DisplayEnd.y)))
\r
1519 bFullVRam=TRUE;iRenderFVR=2;return;
\r
1521 bFullVRam=TRUE;iRenderFVR=2;
\r
1529 ux=PSXDisplay.DisplayPosition.x;
\r
1530 uy=PSXDisplay.DisplayPosition.y;
\r
1531 udx=PSXDisplay.DisplayEnd.x-ux;
\r
1532 udy=PSXDisplay.DisplayEnd.y-uy;
\r
1533 if((PreviousPSXDisplay.DisplayEnd.x-
\r
1534 PreviousPSXDisplay.DisplayPosition.x)==udx &&
\r
1535 (PreviousPSXDisplay.DisplayEnd.y-
\r
1536 PreviousPSXDisplay.DisplayPosition.y)==udy)
\r
1537 p2=(psxVuw + (1024*PreviousPSXDisplay.DisplayPosition.y) +
\r
1538 PreviousPSXDisplay.DisplayPosition.x);
\r
1542 ux=PreviousPSXDisplay.DisplayPosition.x;
\r
1543 uy=PreviousPSXDisplay.DisplayPosition.y;
\r
1544 udx=PreviousPSXDisplay.DisplayEnd.x-ux;
\r
1545 udy=PreviousPSXDisplay.DisplayEnd.y-uy;
\r
1546 if((PSXDisplay.DisplayEnd.x-
\r
1547 PSXDisplay.DisplayPosition.x)==udx &&
\r
1548 (PSXDisplay.DisplayEnd.y-
\r
1549 PSXDisplay.DisplayPosition.y)==udy)
\r
1550 p2=(psxVuw + (1024*PSXDisplay.DisplayPosition.y) +
\r
1551 PSXDisplay.DisplayPosition.x);
\r
1554 p1=(psxVuw + (1024*uy) + ux);
\r
1558 wx=dx=udx;wy=dy=udy;
\r
1560 if(udx<=0) return;
\r
1561 if(udy<=0) return;
\r
1567 XS=(float)rRatioRect.right/(float)wx;
\r
1568 YS=(float)rRatioRect.bottom/(float)wy;
\r
1570 dx=(int)((float)(dx)*XS);
\r
1571 dy=(int)((float)(dy)*YS);
\r
1573 if(dx>iResX) dx=iResX;
\r
1574 if(dy>iResY) dy=iResY;
\r
1582 x+=rRatioRect.left;
\r
1583 y-=rRatioRect.top;
\r
1585 if(y<0) y=0; if((y+dy)>iResY) dy=iResY-y;
\r
1587 if(!pGfxCardScreen)
\r
1589 glPixelStorei(GL_PACK_ALIGNMENT,1); glError();
\r
1590 pGfxCardScreen=(unsigned char *)malloc(iResX*iResY*4);
\r
1593 ps=pGfxCardScreen;
\r
1595 //if(!sArea) glReadBuffer(GL_FRONT);
\r
1597 glReadPixels(x,y,dx,dy,GL_RGB,GL_UNSIGNED_BYTE,ps); glError();
\r
1598 //if(!sArea) glReadBuffer(GL_BACK);
\r
1602 XS=(float)dx/(float)(udx);
\r
1603 YS=(float)dy/(float)(udy+1);
\r
1605 for(y=udy;y>0;y--)
\r
1607 for(x=0;x<udx;x++)
\r
1609 if(p1>=psxVuw && p1<psxVuw_eom)
\r
1611 px=ps+(3*((int)((float)x * XS))+
\r
1612 (3*dx)*((int)((float)y*YS)));
\r
1622 if(p2>=psxVuw && p2<psxVuw_eom) *p2=s;
\r
1629 if(p2) p2 += 1024 - udx;
\r
1633 ////////////////////////////////////////////////////////////////////////
\r
1634 // vram read check (reading from card's back/frontbuffer if needed...
\r
1636 ////////////////////////////////////////////////////////////////////////
\r
1638 void CheckVRamRead(int x, int y, int dx, int dy, bool bFront)
\r
1640 unsigned short sArea;unsigned short * p;
\r
1641 int ux,uy,udx,udy,wx,wy;float XS,YS;
\r
1642 unsigned char * ps, * px;
\r
1643 unsigned short s=0,sx;
\r
1645 if(STATUSREG&GPUSTATUS_RGB24) return;
\r
1647 if(((dx > PSXDisplay.DisplayPosition.x) &&
\r
1648 (x < PSXDisplay.DisplayEnd.x) &&
\r
1649 (dy > PSXDisplay.DisplayPosition.y) &&
\r
1650 (y < PSXDisplay.DisplayEnd.y)))
\r
1653 if((!(PSXDisplay.InterlacedTest) &&
\r
1654 (dx > PreviousPSXDisplay.DisplayPosition.x) &&
\r
1655 (x < PreviousPSXDisplay.DisplayEnd.x) &&
\r
1656 (dy > PreviousPSXDisplay.DisplayPosition.y) &&
\r
1657 (y < PreviousPSXDisplay.DisplayEnd.y)))
\r
1664 if(dwActFixes&0x40)
\r
1668 bFullVRam=TRUE;iRenderFVR=2;return;
\r
1670 bFullVRam=TRUE;iRenderFVR=2;
\r
1673 ux=x;uy=y;udx=dx;udy=dy;
\r
1677 x -=PSXDisplay.DisplayPosition.x;
\r
1678 dx-=PSXDisplay.DisplayPosition.x;
\r
1679 y -=PSXDisplay.DisplayPosition.y;
\r
1680 dy-=PSXDisplay.DisplayPosition.y;
\r
1681 wx=PSXDisplay.DisplayEnd.x-PSXDisplay.DisplayPosition.x;
\r
1682 wy=PSXDisplay.DisplayEnd.y-PSXDisplay.DisplayPosition.y;
\r
1686 x -=PreviousPSXDisplay.DisplayPosition.x;
\r
1687 dx-=PreviousPSXDisplay.DisplayPosition.x;
\r
1688 y -=PreviousPSXDisplay.DisplayPosition.y;
\r
1689 dy-=PreviousPSXDisplay.DisplayPosition.y;
\r
1690 wx=PreviousPSXDisplay.DisplayEnd.x-PreviousPSXDisplay.DisplayPosition.x;
\r
1691 wy=PreviousPSXDisplay.DisplayEnd.y-PreviousPSXDisplay.DisplayPosition.y;
\r
1693 if(x<0) {ux-=x;x=0;}
\r
1694 if(y<0) {uy-=y;y=0;}
\r
1695 if(dx>wx) {udx-=(dx-wx);dx=wx;}
\r
1696 if(dy>wy) {udy-=(dy-wy);dy=wy;}
\r
1700 p=(psxVuw + (1024*uy) + ux);
\r
1702 if(udx<=0) return;
\r
1703 if(udy<=0) return;
\r
1709 XS=(float)rRatioRect.right/(float)wx;
\r
1710 YS=(float)rRatioRect.bottom/(float)wy;
\r
1712 dx=(int)((float)(dx)*XS);
\r
1713 dy=(int)((float)(dy)*YS);
\r
1714 x=(int)((float)x*XS);
\r
1715 y=(int)((float)y*YS);
\r
1720 if(dx>iResX) dx=iResX;
\r
1721 if(dy>iResY) dy=iResY;
\r
1729 x+=rRatioRect.left;
\r
1730 y-=rRatioRect.top;
\r
1732 if(y<0) y=0; if((y+dy)>iResY) dy=iResY-y;
\r
1734 if(!pGfxCardScreen)
\r
1736 glPixelStorei(GL_PACK_ALIGNMENT,1); glError();
\r
1737 pGfxCardScreen=(unsigned char *)malloc(iResX*iResY*4);
\r
1740 ps=pGfxCardScreen;
\r
1742 // if(bFront) glReadBuffer(GL_FRONT);
\r
1744 glReadPixels(x,y,dx,dy,GL_RGB,GL_UNSIGNED_BYTE,ps); glError(); glError();
\r
1745 // if(bFront) glReadBuffer(GL_BACK);
\r
1747 XS=(float)dx/(float)(udx);
\r
1748 YS=(float)dy/(float)(udy+1);
\r
1750 for(y=udy;y>0;y--)
\r
1752 for(x=0;x<udx;x++)
\r
1754 if(p>=psxVuw && p<psxVuw_eom)
\r
1756 px=ps+(3*((int)((float)x * XS))+
\r
1757 (3*dx)*((int)((float)y*YS)));
\r
1773 ////////////////////////////////////////////////////////////////////////
\r
1774 // core read from vram
\r
1775 ////////////////////////////////////////////////////////////////////////
\r
1777 void CALLBACK GPUreadDataMem(unsigned long * pMem, int iSize)
\r
1781 if(iDataReadMode!=DR_VRAMTRANSFER) return;
\r
1785 // adjust read ptr, if necessary
\r
1786 while(VRAMRead.ImagePtr>=psxVuw_eom)
\r
1787 VRAMRead.ImagePtr-=iGPUHeight*1024;
\r
1788 while(VRAMRead.ImagePtr<psxVuw)
\r
1789 VRAMRead.ImagePtr+=iGPUHeight*1024;
\r
1791 if((iFrameReadType&1 && iSize>1) &&
\r
1792 !(iDrawnSomething==2 &&
\r
1793 VRAMRead.x == VRAMWrite.x &&
\r
1794 VRAMRead.y == VRAMWrite.y &&
\r
1795 VRAMRead.Width == VRAMWrite.Width &&
\r
1796 VRAMRead.Height == VRAMWrite.Height))
\r
1797 CheckVRamRead(VRAMRead.x,VRAMRead.y,
\r
1798 VRAMRead.x+VRAMRead.RowsRemaining,
\r
1799 VRAMRead.y+VRAMRead.ColsRemaining,
\r
1802 for(i=0;i<iSize;i++)
\r
1804 // do 2 seperate 16bit reads for compatibility (wrap issues)
\r
1805 if ((VRAMRead.ColsRemaining > 0) && (VRAMRead.RowsRemaining > 0))
\r
1808 GPUdataRet=(unsigned long)*VRAMRead.ImagePtr;
\r
1810 VRAMRead.ImagePtr++;
\r
1811 if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;
\r
1812 VRAMRead.RowsRemaining --;
\r
1814 if(VRAMRead.RowsRemaining<=0)
\r
1816 VRAMRead.RowsRemaining = VRAMRead.Width;
\r
1817 VRAMRead.ColsRemaining--;
\r
1818 VRAMRead.ImagePtr += 1024 - VRAMRead.Width;
\r
1819 if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;
\r
1822 // higher 16 bit (always, even if it's an odd width)
\r
1823 GPUdataRet|=(unsigned long)(*VRAMRead.ImagePtr)<<16;
\r
1824 *pMem++=GPUdataRet;
\r
1826 if(VRAMRead.ColsRemaining <= 0)
\r
1827 {FinishedVRAMRead();goto ENDREAD;}
\r
1829 VRAMRead.ImagePtr++;
\r
1830 if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;
\r
1831 VRAMRead.RowsRemaining--;
\r
1832 if(VRAMRead.RowsRemaining<=0)
\r
1834 VRAMRead.RowsRemaining = VRAMRead.Width;
\r
1835 VRAMRead.ColsRemaining--;
\r
1836 VRAMRead.ImagePtr += 1024 - VRAMRead.Width;
\r
1837 if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;
\r
1839 if(VRAMRead.ColsRemaining <= 0)
\r
1840 {FinishedVRAMRead();goto ENDREAD;}
\r
1842 else {FinishedVRAMRead();goto ENDREAD;}
\r
1849 unsigned long CALLBACK GPUreadData(void)
\r
1852 GPUreadDataMem(&l,1);
\r
1853 return GPUdataRet;
\r
1856 ////////////////////////////////////////////////////////////////////////
\r
1857 // helper table to know how much data is used by drawing commands
\r
1858 ////////////////////////////////////////////////////////////////////////
\r
1860 const unsigned char primTableCX[256] =
\r
1877 8,8,8,8,12,12,12,12,
\r
1881 // 5,5,5,5,6,6,6,6, //FLINE
\r
1882 254,254,254,254,254,254,254,254,
\r
1886 // 7,7,7,7,9,9,9,9, // LINEG3 LINEG4
\r
1887 255,255,255,255,255,255,255,255,
\r
1889 3,3,3,3,4,4,4,4, // TILE SPRT
\r
1891 2,2,2,2,3,3,3,3, // TILE1
\r
1930 ////////////////////////////////////////////////////////////////////////
\r
1931 // processes data send to GPU data register
\r
1932 ////////////////////////////////////////////////////////////////////////
\r
1934 void CALLBACK GPUwriteDataMem(unsigned long * pMem, int iSize)
\r
1936 unsigned char command;
\r
1937 unsigned long gdata=0;
\r
1940 GPUIsNotReadyForCommands;
\r
1944 if(iDataWriteMode==DR_VRAMTRANSFER)
\r
1946 // make sure we are in vram
\r
1947 while(VRAMWrite.ImagePtr>=psxVuw_eom)
\r
1948 VRAMWrite.ImagePtr-=iGPUHeight*1024;
\r
1949 while(VRAMWrite.ImagePtr<psxVuw)
\r
1950 VRAMWrite.ImagePtr+=iGPUHeight*1024;
\r
1952 // now do the loop
\r
1953 while(VRAMWrite.ColsRemaining>0)
\r
1955 while(VRAMWrite.RowsRemaining>0)
\r
1957 if(i>=iSize) {goto ENDVRAM;}
\r
1962 *VRAMWrite.ImagePtr++ = (unsigned short)gdata;
\r
1963 if(VRAMWrite.ImagePtr>=psxVuw_eom) VRAMWrite.ImagePtr-=iGPUHeight*1024;
\r
1964 VRAMWrite.RowsRemaining --;
\r
1966 if(VRAMWrite.RowsRemaining <= 0)
\r
1968 VRAMWrite.ColsRemaining--;
\r
1969 if (VRAMWrite.ColsRemaining <= 0) // last pixel is odd width
\r
1971 gdata=(gdata&0xFFFF)|(((unsigned long)(*VRAMWrite.ImagePtr))<<16);
\r
1972 FinishedVRAMWrite();
\r
1975 VRAMWrite.RowsRemaining = VRAMWrite.Width;
\r
1976 VRAMWrite.ImagePtr += 1024 - VRAMWrite.Width;
\r
1979 *VRAMWrite.ImagePtr++ = (unsigned short)(gdata>>16);
\r
1980 if(VRAMWrite.ImagePtr>=psxVuw_eom) VRAMWrite.ImagePtr-=iGPUHeight*1024;
\r
1981 VRAMWrite.RowsRemaining --;
\r
1984 VRAMWrite.RowsRemaining = VRAMWrite.Width;
\r
1985 VRAMWrite.ColsRemaining--;
\r
1986 VRAMWrite.ImagePtr += 1024 - VRAMWrite.Width;
\r
1989 FinishedVRAMWrite();
\r
1994 if(iDataWriteMode==DR_NORMAL)
\r
1996 void (* *primFunc)(unsigned char *);
\r
1997 if(bSkipNextFrame) primFunc=primTableSkip;
\r
1998 else primFunc=primTableJ;
\r
2002 if(iDataWriteMode==DR_VRAMTRANSFER) goto STARTVRAM;
\r
2004 gdata=*pMem++;i++;
\r
2008 command = (unsigned char)((gdata>>24) & 0xff);
\r
2010 if(primTableCX[command])
\r
2012 gpuDataC = primTableCX[command];
\r
2013 gpuCommand = command;
\r
2014 gpuDataM[0] = gdata;
\r
2021 gpuDataM[gpuDataP] = gdata;
\r
2024 if((gpuDataC==254 && gpuDataP>=3) ||
\r
2025 (gpuDataC==255 && gpuDataP>=4 && !(gpuDataP&1)))
\r
2027 if((gpuDataM[gpuDataP] & 0xF000F000) == 0x50005000)
\r
2028 gpuDataP=gpuDataC-1;
\r
2034 if(gpuDataP == gpuDataC)
\r
2036 gpuDataC=gpuDataP=0;
\r
2037 primFunc[gpuCommand]((unsigned char *)gpuDataM);
\r
2039 if(dwEmuFixes&0x0001 || dwActFixes&0x20000) // hack for emulating "gpu busy" in some games
\r
2047 GPUIsReadyForCommands;
\r
2051 ////////////////////////////////////////////////////////////////////////
\r
2053 void CALLBACK GPUwriteData(unsigned long gdata)
\r
2055 GPUwriteDataMem(&gdata,1);
\r
2058 ////////////////////////////////////////////////////////////////////////
\r
2059 // this function will be removed soon (or 'soonish') (or never)
\r
2060 ////////////////////////////////////////////////////////////////////////
\r
2062 void CALLBACK GPUsetMode(unsigned int gdata)
\r
2064 // ignore old psemu setmode:
\r
2066 // imageTransfer = gdata;
\r
2067 // iDataWriteMode=(gdata&1)?DR_VRAMTRANSFER:DR_NORMAL;
\r
2068 // iDataReadMode =(gdata&2)?DR_VRAMTRANSFER:DR_NORMAL;
\r
2071 // and this function will be removed soon as well, hehehe...
\r
2072 long CALLBACK GPUgetMode(void)
\r
2074 // ignore old psemu setmode
\r
2075 // return imageTransfer;
\r
2079 if(iDataWriteMode==DR_VRAMTRANSFER) iT|=0x1;
\r
2080 if(iDataReadMode ==DR_VRAMTRANSFER) iT|=0x2;
\r
2085 ////////////////////////////////////////////////////////////////////////
\r
2086 // call config dlg (Windows + Linux)
\r
2087 ////////////////////////////////////////////////////////////////////////
\r
2091 /*#include <unistd.h>
\r
2093 void StartCfgTool(char * pCmdLine) // linux: start external cfg tool
\r
2095 FILE * cf;char filename[255],t[255];
\r
2097 strcpy(filename,"cfg/cfgPeopsMesaGL"); // look in cfg sub folder first
\r
2098 cf=fopen(filename,"rb");
\r
2104 sprintf(filename,"./cfgPeopsMesaGL %s",pCmdLine);
\r
2110 strcpy(filename,"cfgPeopsMesaGL"); // look in current folder
\r
2111 cf=fopen(filename,"rb");
\r
2115 sprintf(filename,"./cfgPeopsMesaGL %s",pCmdLine);
\r
2120 sprintf(filename,"%s/cfgPeopsMesaGL",getenv("HOME")); // look in home folder
\r
2121 cf=fopen(filename,"rb");
\r
2126 chdir(getenv("HOME"));
\r
2127 sprintf(filename,"./cfgPeopsMesaGL %s",pCmdLine);
\r
2131 else printf("cfgPeopsMesaGL not found!\n");
\r
2139 long CALLBACK GPUconfigure(void)
\r
2146 ////////////////////////////////////////////////////////////////////////
\r
2147 // sets all kind of act fixes
\r
2148 ////////////////////////////////////////////////////////////////////////
\r
2150 void SetFixes(void)
\r
2154 if(dwActFixes & 0x2000)
\r
2155 dispWidths[4]=384;
\r
2156 else dispWidths[4]=368;
\r
2159 ////////////////////////////////////////////////////////////////////////
\r
2160 // Pete Special: make an 'intelligent' dma chain check (<-Tekken3)
\r
2161 ////////////////////////////////////////////////////////////////////////
\r
2163 unsigned long lUsedAddr[3];
\r
2165 __inline BOOL CheckForEndlessLoop(unsigned long laddr)
\r
2167 if(laddr==lUsedAddr[1]) return TRUE;
\r
2168 if(laddr==lUsedAddr[2]) return TRUE;
\r
2170 if(laddr<lUsedAddr[0]) lUsedAddr[1]=laddr;
\r
2171 else lUsedAddr[2]=laddr;
\r
2172 lUsedAddr[0]=laddr;
\r
2176 ////////////////////////////////////////////////////////////////////////
\r
2177 // core gives a dma chain to gpu: same as the gpuwrite interface funcs
\r
2178 ////////////////////////////////////////////////////////////////////////
\r
2180 long CALLBACK GPUdmaChain(unsigned long * baseAddrL, unsigned long addr)
\r
2182 unsigned long dmaMem;
\r
2183 unsigned char * baseAddrB;
\r
2184 short count;unsigned int DMACommandCounter = 0;
\r
2186 if(bIsFirstFrame) GLinitialize(NULL, NULL);
\r
2190 lUsedAddr[0]=lUsedAddr[1]=lUsedAddr[2]=0xffffff;
\r
2192 baseAddrB = (unsigned char*) baseAddrL;
\r
2196 if(iGPUHeight==512) addr&=0x1FFFFC;
\r
2198 if(DMACommandCounter++ > 2000000) break;
\r
2199 if(CheckForEndlessLoop(addr)) break;
\r
2201 count = baseAddrB[addr+3];
\r
2205 if(count>0) GPUwriteDataMem(&baseAddrL[dmaMem>>2],count);
\r
2207 addr = baseAddrL[addr>>2]&0xffffff;
\r
2209 while (addr != 0xffffff);
\r
2216 ////////////////////////////////////////////////////////////////////////
\r
2218 ////////////////////////////////////////////////////////////////////////
\r
2220 void CALLBACK GPUabout(void)
\r
2225 ////////////////////////////////////////////////////////////////////////
\r
2226 // We are ever fine ;)
\r
2227 ////////////////////////////////////////////////////////////////////////
\r
2229 long CALLBACK GPUtest(void)
\r
2231 // if test fails this function should return negative value for error (unable to continue)
\r
2232 // and positive value for warning (can continue but output might be crappy)
\r
2237 ////////////////////////////////////////////////////////////////////////
\r
2238 // save state funcs
\r
2239 ////////////////////////////////////////////////////////////////////////
\r
2241 ////////////////////////////////////////////////////////////////////////
\r
2243 long CALLBACK GPUfreeze(unsigned long ulGetFreezeData,GPUFreeze_t * pF)
\r
2245 if(ulGetFreezeData==2)
\r
2247 long lSlotNum=*((long *)pF);
\r
2248 if(lSlotNum<0) return 0;
\r
2249 if(lSlotNum>8) return 0;
\r
2250 lSelectedSlot=lSlotNum+1;
\r
2254 if(!pF) return 0;
\r
2255 if(pF->ulFreezeVersion!=1) return 0;
\r
2257 if(ulGetFreezeData==1)
\r
2259 pF->ulStatus=STATUSREG;
\r
2260 memcpy(pF->ulControl,ulStatusControl,256*sizeof(unsigned long));
\r
2261 memcpy(pF->psxVRam, psxVub, 1024*iGPUHeight*2);
\r
2266 if(ulGetFreezeData!=0) return 0;
\r
2268 STATUSREG=pF->ulStatus;
\r
2269 memcpy(ulStatusControl,pF->ulControl,256*sizeof(unsigned long));
\r
2270 memcpy(psxVub, pF->psxVRam, 1024*iGPUHeight*2);
\r
2272 ResetTextureArea(TRUE);
\r
2274 GPUwriteStatus(ulStatusControl[0]);
\r
2275 GPUwriteStatus(ulStatusControl[1]);
\r
2276 GPUwriteStatus(ulStatusControl[2]);
\r
2277 GPUwriteStatus(ulStatusControl[3]);
\r
2278 GPUwriteStatus(ulStatusControl[8]);
\r
2279 GPUwriteStatus(ulStatusControl[6]);
\r
2280 GPUwriteStatus(ulStatusControl[7]);
\r
2281 GPUwriteStatus(ulStatusControl[5]);
\r
2282 GPUwriteStatus(ulStatusControl[4]);
\r
2286 ////////////////////////////////////////////////////////////////////////
\r
2287 // special "emu infos" / "emu effects" functions
\r
2288 ////////////////////////////////////////////////////////////////////////
\r
2293 //11 = transparent
\r
2295 unsigned char cFont[10][120]=
\r
2298 {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
\r
2299 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2300 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2301 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2302 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2303 0x80,0x00,0x05,0x54,0x00,0x00,
\r
2304 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2305 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2306 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2307 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2308 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2309 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2310 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2311 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2312 0x80,0x00,0x05,0x54,0x00,0x00,
\r
2313 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2314 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2315 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2316 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2317 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
\r
2320 {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
\r
2321 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2322 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2323 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2324 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2325 0x80,0x00,0x00,0x50,0x00,0x00,
\r
2326 0x80,0x00,0x05,0x50,0x00,0x00,
\r
2327 0x80,0x00,0x00,0x50,0x00,0x00,
\r
2328 0x80,0x00,0x00,0x50,0x00,0x00,
\r
2329 0x80,0x00,0x00,0x50,0x00,0x00,
\r
2330 0x80,0x00,0x00,0x50,0x00,0x00,
\r
2331 0x80,0x00,0x00,0x50,0x00,0x00,
\r
2332 0x80,0x00,0x00,0x50,0x00,0x00,
\r
2333 0x80,0x00,0x00,0x50,0x00,0x00,
\r
2334 0x80,0x00,0x05,0x55,0x00,0x00,
\r
2335 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2336 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2337 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2338 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2339 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
\r
2342 {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
\r
2343 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2344 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2345 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2346 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2347 0x80,0x00,0x05,0x54,0x00,0x00,
\r
2348 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2349 0x80,0x00,0x00,0x05,0x00,0x00,
\r
2350 0x80,0x00,0x00,0x05,0x00,0x00,
\r
2351 0x80,0x00,0x00,0x14,0x00,0x00,
\r
2352 0x80,0x00,0x00,0x50,0x00,0x00,
\r
2353 0x80,0x00,0x01,0x40,0x00,0x00,
\r
2354 0x80,0x00,0x05,0x00,0x00,0x00,
\r
2355 0x80,0x00,0x14,0x00,0x00,0x00,
\r
2356 0x80,0x00,0x15,0x55,0x00,0x00,
\r
2357 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2358 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2359 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2360 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2361 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
\r
2364 {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
\r
2365 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2366 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2367 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2368 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2369 0x80,0x00,0x05,0x54,0x00,0x00,
\r
2370 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2371 0x80,0x00,0x00,0x05,0x00,0x00,
\r
2372 0x80,0x00,0x00,0x05,0x00,0x00,
\r
2373 0x80,0x00,0x01,0x54,0x00,0x00,
\r
2374 0x80,0x00,0x00,0x05,0x00,0x00,
\r
2375 0x80,0x00,0x00,0x05,0x00,0x00,
\r
2376 0x80,0x00,0x00,0x05,0x00,0x00,
\r
2377 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2378 0x80,0x00,0x05,0x54,0x00,0x00,
\r
2379 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2380 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2381 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2382 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2383 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
\r
2386 {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
\r
2387 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2388 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2389 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2390 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2391 0x80,0x00,0x00,0x14,0x00,0x00,
\r
2392 0x80,0x00,0x00,0x54,0x00,0x00,
\r
2393 0x80,0x00,0x01,0x54,0x00,0x00,
\r
2394 0x80,0x00,0x01,0x54,0x00,0x00,
\r
2395 0x80,0x00,0x05,0x14,0x00,0x00,
\r
2396 0x80,0x00,0x14,0x14,0x00,0x00,
\r
2397 0x80,0x00,0x15,0x55,0x00,0x00,
\r
2398 0x80,0x00,0x00,0x14,0x00,0x00,
\r
2399 0x80,0x00,0x00,0x14,0x00,0x00,
\r
2400 0x80,0x00,0x00,0x55,0x00,0x00,
\r
2401 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2402 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2403 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2404 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2405 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
\r
2408 {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
\r
2409 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2410 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2411 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2412 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2413 0x80,0x00,0x15,0x55,0x00,0x00,
\r
2414 0x80,0x00,0x14,0x00,0x00,0x00,
\r
2415 0x80,0x00,0x14,0x00,0x00,0x00,
\r
2416 0x80,0x00,0x14,0x00,0x00,0x00,
\r
2417 0x80,0x00,0x15,0x54,0x00,0x00,
\r
2418 0x80,0x00,0x00,0x05,0x00,0x00,
\r
2419 0x80,0x00,0x00,0x05,0x00,0x00,
\r
2420 0x80,0x00,0x00,0x05,0x00,0x00,
\r
2421 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2422 0x80,0x00,0x05,0x54,0x00,0x00,
\r
2423 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2424 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2425 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2426 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2427 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
\r
2430 {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
\r
2431 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2432 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2433 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2434 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2435 0x80,0x00,0x01,0x54,0x00,0x00,
\r
2436 0x80,0x00,0x05,0x00,0x00,0x00,
\r
2437 0x80,0x00,0x14,0x00,0x00,0x00,
\r
2438 0x80,0x00,0x14,0x00,0x00,0x00,
\r
2439 0x80,0x00,0x15,0x54,0x00,0x00,
\r
2440 0x80,0x00,0x15,0x05,0x00,0x00,
\r
2441 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2442 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2443 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2444 0x80,0x00,0x05,0x54,0x00,0x00,
\r
2445 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2446 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2447 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2448 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2449 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
\r
2452 {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
\r
2453 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2454 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2455 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2456 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2457 0x80,0x00,0x15,0x55,0x00,0x00,
\r
2458 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2459 0x80,0x00,0x00,0x14,0x00,0x00,
\r
2460 0x80,0x00,0x00,0x14,0x00,0x00,
\r
2461 0x80,0x00,0x00,0x50,0x00,0x00,
\r
2462 0x80,0x00,0x00,0x50,0x00,0x00,
\r
2463 0x80,0x00,0x01,0x40,0x00,0x00,
\r
2464 0x80,0x00,0x01,0x40,0x00,0x00,
\r
2465 0x80,0x00,0x05,0x00,0x00,0x00,
\r
2466 0x80,0x00,0x05,0x00,0x00,0x00,
\r
2467 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2468 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2469 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2470 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2471 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
\r
2474 {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
\r
2475 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2476 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2477 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2478 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2479 0x80,0x00,0x05,0x54,0x00,0x00,
\r
2480 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2481 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2482 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2483 0x80,0x00,0x05,0x54,0x00,0x00,
\r
2484 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2485 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2486 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2487 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2488 0x80,0x00,0x05,0x54,0x00,0x00,
\r
2489 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2490 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2491 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2492 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2493 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
\r
2496 {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
\r
2497 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2498 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2499 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2500 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2501 0x80,0x00,0x05,0x54,0x00,0x00,
\r
2502 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2503 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2504 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2505 0x80,0x00,0x14,0x15,0x00,0x00,
\r
2506 0x80,0x00,0x05,0x55,0x00,0x00,
\r
2507 0x80,0x00,0x00,0x05,0x00,0x00,
\r
2508 0x80,0x00,0x00,0x05,0x00,0x00,
\r
2509 0x80,0x00,0x00,0x14,0x00,0x00,
\r
2510 0x80,0x00,0x05,0x50,0x00,0x00,
\r
2511 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2512 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2513 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2514 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2515 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
\r
2519 ////////////////////////////////////////////////////////////////////////
\r
2521 void PaintPicDot(unsigned char * p,unsigned char c)
\r
2523 if(c==0) {*p++=0x00;*p++=0x00;*p=0x00;return;}
\r
2524 if(c==1) {*p++=0xff;*p++=0xff;*p=0xff;return;}
\r
2525 if(c==2) {*p++=0x00;*p++=0x00;*p=0xff;return;}
\r
2528 ////////////////////////////////////////////////////////////////////////
\r
2530 long CALLBACK GPUgetScreenPic(unsigned char * pMem)
\r
2532 float XS,YS;int x,y,v;
\r
2533 unsigned char * ps, * px, * pf;
\r
2536 if(!pGfxCardScreen)
\r
2538 glPixelStorei(GL_PACK_ALIGNMENT,1); glError();
\r
2539 pGfxCardScreen=(unsigned char *)malloc(iResX*iResY*4);
\r
2542 ps=pGfxCardScreen;
\r
2544 // glReadBuffer(GL_FRONT);
\r
2546 glReadPixels(0,0,iResX,iResY,GL_RGB,GL_UNSIGNED_BYTE,ps); glError();
\r
2548 // glReadBuffer(GL_BACK);
\r
2550 XS=(float)iResX/128;
\r
2551 YS=(float)iResY/96;
\r
2556 for(x=0;x<128;x++)
\r
2558 px=ps+(3*((int)((float)x * XS))+
\r
2559 (3*iResX)*((int)((float)y*YS)));
\r
2567 /////////////////////////////////////////////////////////////////////
\r
2568 // generic number/border painter
\r
2576 c=cFont[lSelectedSlot][x+y*6];
\r
2578 PaintPicDot(pf,(unsigned char)v);pf+=3; // paint the dots into the rect
\r
2580 PaintPicDot(pf,(unsigned char)v);pf+=3;
\r
2582 PaintPicDot(pf,(unsigned char)v);pf+=3;
\r
2584 PaintPicDot(pf,(unsigned char)v);pf+=3;
\r
2590 for(x=0;x<128;x++)
\r
2592 *(pf+(95*128*3))=0x00;*pf++=0x00;
\r
2593 *(pf+(95*128*3))=0x00;*pf++=0x00;
\r
2594 *(pf+(95*128*3))=0xff;*pf++=0xff;
\r
2599 *(pf+(127*3))=0x00;*pf++=0x00;
\r
2600 *(pf+(127*3))=0x00;*pf++=0x00;
\r
2601 *(pf+(127*3))=0xff;*pf++=0xff;
\r
2607 ////////////////////////////////////////////////////////////////////////
\r
2609 long CALLBACK GPUshowScreenPic(unsigned char * pMem)
\r
2612 // if(pMem==0) return;
\r
2613 // CreatePic(pMem);
\r
2616 ////////////////////////////////////////////////////////////////////////
\r
2618 void CALLBACK GPUsetfix(unsigned long dwFixBits)
\r
2620 dwEmuFixes=dwFixBits;
\r
2623 ////////////////////////////////////////////////////////////////////////
\r
2625 void CALLBACK GPUvisualVibration(unsigned long iSmall, unsigned long iBig)
\r
2629 if(PSXDisplay.DisplayModeNew.x) // calc min "shake pixel" from screen width
\r
2630 iVibVal=max(1,iResX/PSXDisplay.DisplayModeNew.x);
\r
2632 // big rumble: 4...15 sp ; small rumble 1...3 sp
\r
2633 if(iBig) iRumbleVal=max(4*iVibVal,min(15*iVibVal,((int)iBig *iVibVal)/10));
\r
2634 else iRumbleVal=max(1*iVibVal,min( 3*iVibVal,((int)iSmall*iVibVal)/10));
\r
2636 srand(timeGetTime()); // init rand (will be used in BufferSwap)
\r
2638 iRumbleTime=15; // let the rumble last 16 buffer swaps
\r
2641 ////////////////////////////////////////////////////////////////////////
\r
2642 // main emu can set display infos (A/M/G/D)
\r
2643 ////////////////////////////////////////////////////////////////////////
\r
2645 void CALLBACK GPUdisplayFlags(unsigned long dwFlags)
\r
2647 // dwCoreFlags=dwFlags;
\r
2650 // pcsx-rearmed callbacks
\r
2651 void CALLBACK GPUrearmedCallbacks(const void **cbs)
\r
2653 rearmed_get_layer_pos = cbs[0];
\r
2656 static void flipEGL(void)
\r
2658 eglSwapBuffers(display, surface);
\r