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 // lGPUstatusRet = 0x74000000;
\r
511 // with some emus, we could do the OGL init right here... oh my
\r
512 if(bIsFirstFrame) GLinitialize();
\r
517 ////////////////////////////////////////////////////////////////////////
\r
519 ////////////////////////////////////////////////////////////////////////
\r
522 long GPUclose() // LINUX CLOSE
\r
524 GLcleanup(); // close OGL
\r
526 if(pGfxCardScreen) free(pGfxCardScreen); // free helper memory
\r
529 // osd_close_display(); // destroy display
\r
534 ////////////////////////////////////////////////////////////////////////
\r
535 // I shot the sheriff... last function called from emu
\r
536 ////////////////////////////////////////////////////////////////////////
\r
538 long CALLBACK GPUshutdown()
\r
540 if(psxVSecure) free(psxVSecure); // kill emulated vram memory
\r
546 ////////////////////////////////////////////////////////////////////////
\r
547 // paint it black: simple func to clean up optical border garbage
\r
548 ////////////////////////////////////////////////////////////////////////
\r
550 void PaintBlackBorders(void)
\r
553 glDisable(GL_SCISSOR_TEST); glError();
\r
554 if(bTexEnabled) {glDisable(GL_TEXTURE_2D);bTexEnabled=FALSE;} glError();
\r
555 if(bOldSmoothShaded) {glShadeModel(GL_FLAT);bOldSmoothShaded=FALSE;} glError();
\r
556 if(bBlendEnable) {glDisable(GL_BLEND);bBlendEnable=FALSE;} glError();
\r
557 glDisable(GL_ALPHA_TEST); glError();
\r
559 glEnable(GL_ALPHA_TEST); glError();
\r
560 glEnable(GL_SCISSOR_TEST); glError();
\r
564 ////////////////////////////////////////////////////////////////////////
\r
565 // helper to draw scanlines
\r
566 ////////////////////////////////////////////////////////////////////////
\r
568 __inline void XPRIMdrawTexturedQuad(OGLVertex* vertex1, OGLVertex* vertex2,
\r
569 OGLVertex* vertex3, OGLVertex* vertex4)
\r
574 ////////////////////////////////////////////////////////////////////////
\r
576 ////////////////////////////////////////////////////////////////////////
\r
578 void SetScanLines(void)
\r
582 ////////////////////////////////////////////////////////////////////////
\r
583 // blur, babe, blur (heavy performance hit for a so-so fullscreen effect)
\r
584 ////////////////////////////////////////////////////////////////////////
\r
587 ////////////////////////////////////////////////////////////////////////
\r
588 // Update display (swap buffers)... called in interlaced mode on
\r
589 // every emulated vsync, otherwise whenever the displayed screen region
\r
590 // has been changed
\r
591 ////////////////////////////////////////////////////////////////////////
\r
593 int iLastRGB24=0; // special vars for checking when to skip two display updates
\r
595 void GPUvSinc(void){
\r
598 void updateDisplay(void) // UPDATE DISPLAY
\r
603 bFakeFrontBuffer=FALSE;
\r
604 bRenderFrontBuffer=FALSE;
\r
606 if(iRenderFVR) // frame buffer read fix mode still active?
\r
608 iRenderFVR--; // -> if some frames in a row without read access: turn off mode
\r
609 if(!iRenderFVR) bFullVRam=FALSE;
\r
612 if(iLastRGB24 && iLastRGB24!=PSXDisplay.RGB24+1) // (mdec) garbage check
\r
614 iSkipTwo=2; // -> skip two frames to avoid garbage if color mode changes
\r
618 if(PSXDisplay.RGB24)// && !bNeedUploadAfter) // (mdec) upload wanted?
\r
620 PrepareFullScreenUpload(-1);
\r
621 UploadScreen(PSXDisplay.Interlaced); // -> upload whole screen from psx vram
\r
622 bNeedUploadTest=FALSE;
\r
623 bNeedInterlaceUpdate=FALSE;
\r
624 bNeedUploadAfter=FALSE;
\r
625 bNeedRGB24Update=FALSE;
\r
628 if(bNeedInterlaceUpdate) // smaller upload?
\r
630 bNeedInterlaceUpdate=FALSE;
\r
631 xrUploadArea=xrUploadAreaIL; // -> upload this rect
\r
632 UploadScreen(TRUE);
\r
635 if(dwActFixes&512) bCheckFF9G4(NULL); // special game fix for FF9
\r
637 if(PreviousPSXDisplay.Range.x0|| // paint black borders around display area, if needed
\r
638 PreviousPSXDisplay.Range.y0)
\r
639 PaintBlackBorders();
\r
641 if(PSXDisplay.Disabled) // display disabled?
\r
643 //LOGE("PSXDisplay.Disabled");
\r
646 glDisable(GL_SCISSOR_TEST); glError();
\r
647 glClearColor(0,0,0,128); glError(); // -> clear whole backbuffer
\r
648 glClear(uiBufferBits); glError();
\r
649 glEnable(GL_SCISSOR_TEST); glError();
\r
651 bDisplayNotSet = TRUE;
\r
654 if(iSkipTwo) // we are in skipping mood?
\r
657 iDrawnSomething=0; // -> simply lie about something drawn
\r
660 //if(iBlurBuffer && !bSkipNextFrame) // "blur display" activated?
\r
661 // {BlurBackBuffer();bBlur=TRUE;} // -> blur it
\r
663 // if(iUseScanLines) SetScanLines(); // "scan lines" activated? do it
\r
665 // if(usCursorActive) ShowGunCursor(); // "gun cursor" wanted? show 'em
\r
667 if(dwActFixes&128) // special FPS limitation mode?
\r
669 if(bUseFrameLimit) PCFrameCap(); // -> ok, do it
\r
670 // if(bUseFrameSkip || ulKeybits&KEY_SHOWFPS)
\r
674 // if(gTexPicName) DisplayPic(); // some gpu info picture active? display it
\r
676 // if(bSnapShot) DoSnapShot(); // snapshot key pressed? cheeeese :)
\r
678 // if(ulKeybits&KEY_SHOWFPS) // wanna see FPS?
\r
680 // sprintf(szDispBuf,"%06.1f",fps_cur);
\r
681 // DisplayText(); // -> show it
\r
684 //----------------------------------------------------//
\r
685 // main buffer swapping (well, or skip it)
\r
687 if(bUseFrameSkip) // frame skipping active ?
\r
689 if(!bSkipNextFrame)
\r
691 if(iDrawnSomething) flipEGL();
\r
693 if((fps_skip < fFrameRateHz) && !(bSkipNextFrame))
\r
694 {bSkipNextFrame = TRUE; fps_skip=fFrameRateHz;}
\r
695 else bSkipNextFrame = FALSE;
\r
700 if(iDrawnSomething) flipEGL();
\r
705 //----------------------------------------------------//
\r
707 if(lClearOnSwap) // clear buffer after swap?
\r
711 if(bDisplayNotSet) // -> set new vals
\r
712 SetOGLDisplaySettings(1);
\r
714 g=((GLclampf)GREEN(lClearOnSwapColor))/255.0f; // -> get col
\r
715 b=((GLclampf)BLUE(lClearOnSwapColor))/255.0f;
\r
716 r=((GLclampf)RED(lClearOnSwapColor))/255.0f;
\r
717 glDisable(GL_SCISSOR_TEST); glError();
\r
718 glClearColor(r,g,b,128); glError(); // -> clear
\r
719 glClear(uiBufferBits); glError();
\r
720 glEnable(GL_SCISSOR_TEST); glError();
\r
721 lClearOnSwap=0; // -> done
\r
725 // if(bBlur) UnBlurBackBuffer(); // unblur buff, if blurred before
\r
727 if(iZBufferDepth) // clear zbuffer as well (if activated)
\r
729 glDisable(GL_SCISSOR_TEST); glError();
\r
730 glClear(GL_DEPTH_BUFFER_BIT); glError();
\r
731 glEnable(GL_SCISSOR_TEST); glError();
\r
737 //----------------------------------------------------//
\r
738 // additional uploads immediatly after swapping
\r
740 if(bNeedUploadAfter) // upload wanted?
\r
742 bNeedUploadAfter=FALSE;
\r
743 bNeedUploadTest=FALSE;
\r
744 UploadScreen(-1); // -> upload
\r
747 if(bNeedUploadTest)
\r
749 bNeedUploadTest=FALSE;
\r
750 if(PSXDisplay.InterlacedTest &&
\r
751 //iOffscreenDrawing>2 &&
\r
752 PreviousPSXDisplay.DisplayPosition.x==PSXDisplay.DisplayPosition.x &&
\r
753 PreviousPSXDisplay.DisplayEnd.x==PSXDisplay.DisplayEnd.x &&
\r
754 PreviousPSXDisplay.DisplayPosition.y==PSXDisplay.DisplayPosition.y &&
\r
755 PreviousPSXDisplay.DisplayEnd.y==PSXDisplay.DisplayEnd.y)
\r
757 PrepareFullScreenUpload(TRUE);
\r
758 UploadScreen(TRUE);
\r
762 //----------------------------------------------------//
\r
763 // rumbling (main emu pad effect)
\r
765 if(iRumbleTime) // shake screen by modifying view port
\r
767 int i1=0,i2=0,i3=0,i4=0;
\r
772 i1=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2);
\r
773 i2=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2);
\r
774 i3=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2);
\r
775 i4=((rand()*iRumbleVal)/RAND_MAX)-(iRumbleVal/2);
\r
778 glViewport(rRatioRect.left+i1,
\r
779 iResY-(rRatioRect.top+rRatioRect.bottom)+i2,
\r
780 rRatioRect.right+i3,
\r
781 rRatioRect.bottom+i4); glError();
\r
784 //----------------------------------------------------//
\r
788 // if(ulKeybits&KEY_RESETTEXSTORE) ResetStuff(); // reset on gpu mode changes? do it before next frame is filled
\r
791 ////////////////////////////////////////////////////////////////////////
\r
792 // update front display: smaller update func, if something has changed
\r
793 // in the frontbuffer... dirty, but hey... real men know no pain
\r
794 ////////////////////////////////////////////////////////////////////////
\r
796 void updateFrontDisplay(void)
\r
798 if(PreviousPSXDisplay.Range.x0||
\r
799 PreviousPSXDisplay.Range.y0)
\r
800 PaintBlackBorders();
\r
802 //if(iBlurBuffer) BlurBackBuffer();
\r
804 //if(iUseScanLines) SetScanLines();
\r
806 // if(usCursorActive) ShowGunCursor();
\r
808 bFakeFrontBuffer=FALSE;
\r
809 bRenderFrontBuffer=FALSE;
\r
811 // if(gTexPicName) DisplayPic();
\r
812 // if(ulKeybits&KEY_SHOWFPS) DisplayText();
\r
814 if(iDrawnSomething) // linux:
\r
818 //if(iBlurBuffer) UnBlurBackBuffer();
\r
821 ////////////////////////////////////////////////////////////////////////
\r
822 // check if update needed
\r
823 ////////////////////////////////////////////////////////////////////////
\r
824 void ChangeDispOffsetsX(void) // CENTER X
\r
826 long lx,l;short sO;
\r
828 if(!PSXDisplay.Range.x1) return; // some range given?
\r
830 l=PSXDisplay.DisplayMode.x;
\r
832 l*=(long)PSXDisplay.Range.x1; // some funky calculation
\r
833 l/=2560;lx=l;l&=0xfffffff8;
\r
835 if(l==PreviousPSXDisplay.Range.x1) return; // some change?
\r
837 sO=PreviousPSXDisplay.Range.x0; // store old
\r
839 if(lx>=PSXDisplay.DisplayMode.x) // range bigger?
\r
841 PreviousPSXDisplay.Range.x1= // -> take display width
\r
842 PSXDisplay.DisplayMode.x;
\r
843 PreviousPSXDisplay.Range.x0=0; // -> start pos is 0
\r
845 else // range smaller? center it
\r
847 PreviousPSXDisplay.Range.x1=l; // -> store width (8 pixel aligned)
\r
848 PreviousPSXDisplay.Range.x0= // -> calc start pos
\r
849 (PSXDisplay.Range.x0-500)/8;
\r
850 if(PreviousPSXDisplay.Range.x0<0) // -> we don't support neg. values yet
\r
851 PreviousPSXDisplay.Range.x0=0;
\r
853 if((PreviousPSXDisplay.Range.x0+lx)> // -> uhuu... that's too much
\r
854 PSXDisplay.DisplayMode.x)
\r
856 PreviousPSXDisplay.Range.x0= // -> adjust start
\r
857 PSXDisplay.DisplayMode.x-lx;
\r
858 PreviousPSXDisplay.Range.x1+=lx-l; // -> adjust width
\r
862 if(sO!=PreviousPSXDisplay.Range.x0) // something changed?
\r
864 bDisplayNotSet=TRUE; // -> recalc display stuff
\r
868 ////////////////////////////////////////////////////////////////////////
\r
870 void ChangeDispOffsetsY(void) // CENTER Y
\r
872 int iT;short sO; // store previous y size
\r
874 if(PSXDisplay.PAL) iT=48; else iT=28; // different offsets on PAL/NTSC
\r
876 if(PSXDisplay.Range.y0>=iT) // crossed the security line? :)
\r
878 PreviousPSXDisplay.Range.y1= // -> store width
\r
879 PSXDisplay.DisplayModeNew.y;
\r
881 sO=(PSXDisplay.Range.y0-iT-4)*PSXDisplay.Double; // -> calc offset
\r
884 PSXDisplay.DisplayModeNew.y+=sO; // -> add offset to y size, too
\r
886 else sO=0; // else no offset
\r
888 if(sO!=PreviousPSXDisplay.Range.y0) // something changed?
\r
890 PreviousPSXDisplay.Range.y0=sO;
\r
891 bDisplayNotSet=TRUE; // -> recalc display stuff
\r
895 ////////////////////////////////////////////////////////////////////////
\r
896 // Aspect ratio of ogl screen: simply adjusting ogl view port
\r
897 ////////////////////////////////////////////////////////////////////////
\r
899 void SetAspectRatio(void)
\r
901 float xs,ys,s;RECT r;
\r
903 if(!PSXDisplay.DisplayModeNew.x) return;
\r
904 if(!PSXDisplay.DisplayModeNew.y) return;
\r
907 xs=(float)iResX/(float)PSXDisplay.DisplayModeNew.x;
\r
908 ys=(float)iResY/(float)PSXDisplay.DisplayModeNew.y;
\r
911 r.right =(int)((float)PSXDisplay.DisplayModeNew.x*s);
\r
912 r.bottom=(int)((float)PSXDisplay.DisplayModeNew.y*s);
\r
913 if(r.right > iResX) r.right = iResX;
\r
914 if(r.bottom > iResY) r.bottom = iResY;
\r
915 if(r.right < 1) r.right = 1;
\r
916 if(r.bottom < 1) r.bottom = 1;
\r
918 r.left = (iResX-r.right)/2;
\r
919 r.top = (iResY-r.bottom)/2;
\r
920 if(r.bottom<rRatioRect.bottom ||
\r
921 r.right <rRatioRect.right)
\r
924 glClearColor(0,0,0,128); glError();
\r
926 if(r.right <rRatioRect.right)
\r
932 glScissor(rC.left,rC.top,rC.right,rC.bottom); glError();
\r
933 glClear(uiBufferBits); glError();
\r
934 rC.left=iResX-rC.right;
\r
935 glScissor(rC.left,rC.top,rC.right,rC.bottom); glError();
\r
937 glClear(uiBufferBits); glError();
\r
940 if(r.bottom <rRatioRect.bottom)
\r
946 glScissor(rC.left,rC.top,rC.right,rC.bottom); glError();
\r
948 glClear(uiBufferBits); glError();
\r
949 rC.top=iResY-rC.bottom;
\r
950 glScissor(rC.left,rC.top,rC.right,rC.bottom); glError();
\r
951 glClear(uiBufferBits); glError();
\r
955 bDisplayNotSet=TRUE;
\r
960 // pcsx-rearmed hack
\r
961 if (rearmed_get_layer_pos != NULL)
\r
962 rearmed_get_layer_pos(&rRatioRect.left, &rRatioRect.top, &rRatioRect.right, &rRatioRect.bottom);
\r
965 glViewport(rRatioRect.left,
\r
966 iResY-(rRatioRect.top+rRatioRect.bottom),
\r
968 rRatioRect.bottom); glError(); // init viewport
\r
971 ////////////////////////////////////////////////////////////////////////
\r
972 // big ass check, if an ogl swap buffer is needed
\r
973 ////////////////////////////////////////////////////////////////////////
\r
975 void updateDisplayIfChanged(void)
\r
979 if ((PSXDisplay.DisplayMode.y == PSXDisplay.DisplayModeNew.y) &&
\r
980 (PSXDisplay.DisplayMode.x == PSXDisplay.DisplayModeNew.x))
\r
982 if((PSXDisplay.RGB24 == PSXDisplay.RGB24New) &&
\r
983 (PSXDisplay.Interlaced == PSXDisplay.InterlacedNew))
\r
984 return; // nothing has changed? fine, no swap buffer needed
\r
986 else // some res change?
\r
988 glLoadIdentity(); glError();
\r
989 glOrtho(0,PSXDisplay.DisplayModeNew.x, // -> new psx resolution
\r
990 PSXDisplay.DisplayModeNew.y, 0, -1, 1); glError();
\r
991 if(bKeepRatio) SetAspectRatio();
\r
994 bDisplayNotSet = TRUE; // re-calc offsets/display area
\r
997 if(PSXDisplay.RGB24!=PSXDisplay.RGB24New) // clean up textures, if rgb mode change (usually mdec on/off)
\r
999 PreviousPSXDisplay.RGB24=0; // no full 24 frame uploaded yet
\r
1000 ResetTextureArea(FALSE);
\r
1004 PSXDisplay.RGB24 = PSXDisplay.RGB24New; // get new infos
\r
1005 PSXDisplay.DisplayMode.y = PSXDisplay.DisplayModeNew.y;
\r
1006 PSXDisplay.DisplayMode.x = PSXDisplay.DisplayModeNew.x;
\r
1007 PSXDisplay.Interlaced = PSXDisplay.InterlacedNew;
\r
1009 PSXDisplay.DisplayEnd.x= // calc new ends
\r
1010 PSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;
\r
1011 PSXDisplay.DisplayEnd.y=
\r
1012 PSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;
\r
1013 PreviousPSXDisplay.DisplayEnd.x=
\r
1014 PreviousPSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;
\r
1015 PreviousPSXDisplay.DisplayEnd.y=
\r
1016 PreviousPSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;
\r
1018 ChangeDispOffsetsX();
\r
1020 if(iFrameLimit==2) SetAutoFrameCap(); // set new fps limit vals (depends on interlace)
\r
1022 if(bUp) updateDisplay(); // yeah, real update (swap buffer)
\r
1025 ////////////////////////////////////////////////////////////////////////
\r
1026 // window mode <-> fullscreen mode (windows)
\r
1027 ////////////////////////////////////////////////////////////////////////
\r
1030 ////////////////////////////////////////////////////////////////////////
\r
1031 // swap update check (called by psx vsync function)
\r
1032 ////////////////////////////////////////////////////////////////////////
\r
1034 BOOL bSwapCheck(void)
\r
1036 static int iPosCheck=0;
\r
1037 static PSXPoint_t pO;
\r
1038 static PSXPoint_t pD;
\r
1039 static int iDoAgain=0;
\r
1041 if(PSXDisplay.DisplayPosition.x==pO.x &&
\r
1042 PSXDisplay.DisplayPosition.y==pO.y &&
\r
1043 PSXDisplay.DisplayEnd.x==pD.x &&
\r
1044 PSXDisplay.DisplayEnd.y==pD.y)
\r
1048 pO=PSXDisplay.DisplayPosition;
\r
1049 pD=PSXDisplay.DisplayEnd;
\r
1051 if(iPosCheck<=4) return FALSE;
\r
1055 if(PSXDisplay.Interlaced) return FALSE;
\r
1057 if (bNeedInterlaceUpdate||
\r
1058 bNeedRGB24Update ||
\r
1059 bNeedUploadAfter||
\r
1060 bNeedUploadTest ||
\r
1065 if(bNeedUploadAfter)
\r
1067 if(bNeedUploadTest && PSXDisplay.InterlacedTest)
\r
1070 bDisplayNotSet = TRUE;
\r
1073 PreviousPSXDisplay.DisplayPosition.x=PSXDisplay.DisplayPosition.x;
\r
1074 PreviousPSXDisplay.DisplayPosition.y=PSXDisplay.DisplayPosition.y;
\r
1075 PreviousPSXDisplay.DisplayEnd.x=PSXDisplay.DisplayEnd.x;
\r
1076 PreviousPSXDisplay.DisplayEnd.y=PSXDisplay.DisplayEnd.y;
\r
1077 pO=PSXDisplay.DisplayPosition;
\r
1078 pD=PSXDisplay.DisplayEnd;
\r
1085 ////////////////////////////////////////////////////////////////////////
\r
1086 // gun cursor func: player=0-7, x=0-511, y=0-255
\r
1087 ////////////////////////////////////////////////////////////////////////
\r
1089 ////////////////////////////////////////////////////////////////////////
\r
1090 // update lace is called every VSync. Basically we limit frame rate
\r
1091 // here, and in interlaced mode we swap ogl display buffers.
\r
1092 ////////////////////////////////////////////////////////////////////////
\r
1094 static unsigned short usFirstPos=2;
\r
1096 void CALLBACK GPUupdateLace(void)
\r
1098 if(!(dwActFixes&0x1000))
\r
1099 STATUSREG^=0x80000000; // interlaced bit toggle, if the CC game fix is not active (see gpuReadStatus)
\r
1101 if(!(dwActFixes&128)) // normal frame limit func
\r
1104 if(iOffscreenDrawing==4) // special check if high offscreen drawing is on
\r
1106 if(bSwapCheck()) return;
\r
1109 if(PSXDisplay.Interlaced) // interlaced mode?
\r
1111 if(PSXDisplay.DisplayMode.x>0 && PSXDisplay.DisplayMode.y>0)
\r
1113 updateDisplay(); // -> swap buffers (new frame)
\r
1116 else if(bRenderFrontBuffer) // no interlace mode? and some stuff in front has changed?
\r
1118 updateFrontDisplay(); // -> update front buffer
\r
1120 else if(usFirstPos==1) // initial updates (after startup)
\r
1127 ////////////////////////////////////////////////////////////////////////
\r
1128 // process read request from GPU status register
\r
1129 ////////////////////////////////////////////////////////////////////////
\r
1131 unsigned long CALLBACK GPUreadStatus(void)
\r
1133 if(dwActFixes&0x1000) // CC game fix
\r
1135 static int iNumRead=0;
\r
1136 if((iNumRead++)==2)
\r
1139 STATUSREG^=0x80000000; // interlaced bit toggle... we do it on every second read status... needed by some games (like ChronoCross)
\r
1143 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
1147 if(iFakePrimBusy&1) // we do a busy-idle-busy-idle sequence after/while drawing prims
\r
1150 GPUIsNotReadyForCommands;
\r
1155 GPUIsReadyForCommands;
\r
1162 ////////////////////////////////////////////////////////////////////////
\r
1163 // processes data send to GPU status register
\r
1164 // these are always single packet commands.
\r
1165 ////////////////////////////////////////////////////////////////////////
\r
1167 void CALLBACK GPUwriteStatus(unsigned long gdata)
\r
1169 unsigned long lCommand=(gdata>>24)&0xff;
\r
1171 if(bIsFirstFrame) GLinitialize(); // real ogl startup (needed by some emus)
\r
1173 ulStatusControl[lCommand]=gdata;
\r
1177 //--------------------------------------------------//
\r
1180 memset(ulGPUInfoVals,0x00,16*sizeof(unsigned long));
\r
1181 lGPUstatusRet=0x14802000;
\r
1182 PSXDisplay.Disabled=1;
\r
1183 iDataWriteMode=iDataReadMode=DR_NORMAL;
\r
1184 PSXDisplay.DrawOffset.x=PSXDisplay.DrawOffset.y=0;
\r
1185 drawX=drawY=0;drawW=drawH=0;
\r
1186 sSetMask=0;lSetMask=0;bCheckMask=FALSE;iSetMask=0;
\r
1188 GlobalTextAddrX=0;GlobalTextAddrY=0;
\r
1189 GlobalTextTP=0;GlobalTextABR=0;
\r
1190 PSXDisplay.RGB24=FALSE;
\r
1191 PSXDisplay.Interlaced=FALSE;
\r
1192 bUsingTWin = FALSE;
\r
1195 // dis/enable display
\r
1197 PreviousPSXDisplay.Disabled = PSXDisplay.Disabled;
\r
1198 PSXDisplay.Disabled = (gdata & 1);
\r
1200 if(PSXDisplay.Disabled)
\r
1201 STATUSREG|=GPUSTATUS_DISPLAYDISABLED;
\r
1202 else STATUSREG&=~GPUSTATUS_DISPLAYDISABLED;
\r
1204 if (iOffscreenDrawing==4 &&
\r
1205 PreviousPSXDisplay.Disabled &&
\r
1206 !(PSXDisplay.Disabled))
\r
1209 if(!PSXDisplay.RGB24)
\r
1211 PrepareFullScreenUpload(TRUE);
\r
1212 UploadScreen(TRUE);
\r
1219 // setting transfer mode
\r
1221 gdata &= 0x03; // only want the lower two bits
\r
1223 iDataWriteMode=iDataReadMode=DR_NORMAL;
\r
1224 if(gdata==0x02) iDataWriteMode=DR_VRAMTRANSFER;
\r
1225 if(gdata==0x03) iDataReadMode =DR_VRAMTRANSFER;
\r
1227 STATUSREG&=~GPUSTATUS_DMABITS; // clear the current settings of the DMA bits
\r
1228 STATUSREG|=(gdata << 29); // set the DMA bits according to the received data
\r
1232 // setting display position
\r
1235 short sx=(short)(gdata & 0x3ff);
\r
1238 if(iGPUHeight==1024)
\r
1240 if(dwGPUVersion==2)
\r
1241 sy = (short)((gdata>>12)&0x3ff);
\r
1242 else sy = (short)((gdata>>10)&0x3ff);
\r
1244 else sy = (short)((gdata>>10)&0x3ff); // really: 0x1ff, but we adjust it later
\r
1249 PreviousPSXDisplay.DisplayModeNew.y=sy/PSXDisplay.Double;
\r
1252 else PreviousPSXDisplay.DisplayModeNew.y=0;
\r
1261 PreviousPSXDisplay.DisplayPosition.x = sx;
\r
1262 PreviousPSXDisplay.DisplayPosition.y = sy;
\r
1263 PSXDisplay.DisplayPosition.x = sx;
\r
1264 PSXDisplay.DisplayPosition.y = sy;
\r
1270 if((!PSXDisplay.Interlaced) &&
\r
1271 PreviousPSXDisplay.DisplayPosition.x == sx &&
\r
1272 PreviousPSXDisplay.DisplayPosition.y == sy)
\r
1275 PSXDisplay.DisplayPosition.x = PreviousPSXDisplay.DisplayPosition.x;
\r
1276 PSXDisplay.DisplayPosition.y = PreviousPSXDisplay.DisplayPosition.y;
\r
1277 PreviousPSXDisplay.DisplayPosition.x = sx;
\r
1278 PreviousPSXDisplay.DisplayPosition.y = sy;
\r
1282 if((!PSXDisplay.Interlaced) &&
\r
1283 PSXDisplay.DisplayPosition.x == sx &&
\r
1284 PSXDisplay.DisplayPosition.y == sy)
\r
1286 PreviousPSXDisplay.DisplayPosition.x = PSXDisplay.DisplayPosition.x;
\r
1287 PreviousPSXDisplay.DisplayPosition.y = PSXDisplay.DisplayPosition.y;
\r
1288 PSXDisplay.DisplayPosition.x = sx;
\r
1289 PSXDisplay.DisplayPosition.y = sy;
\r
1292 PSXDisplay.DisplayEnd.x=
\r
1293 PSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;
\r
1294 PSXDisplay.DisplayEnd.y=
\r
1295 PSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;
\r
1297 PreviousPSXDisplay.DisplayEnd.x=
\r
1298 PreviousPSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;
\r
1299 PreviousPSXDisplay.DisplayEnd.y=
\r
1300 PreviousPSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;
\r
1302 bDisplayNotSet = TRUE;
\r
1304 if (!(PSXDisplay.Interlaced))
\r
1309 if(PSXDisplay.InterlacedTest &&
\r
1310 ((PreviousPSXDisplay.DisplayPosition.x != PSXDisplay.DisplayPosition.x)||
\r
1311 (PreviousPSXDisplay.DisplayPosition.y != PSXDisplay.DisplayPosition.y)))
\r
1312 PSXDisplay.InterlacedTest--;
\r
1320 PSXDisplay.Range.x0=gdata & 0x7ff; //0x3ff;
\r
1321 PSXDisplay.Range.x1=(gdata>>12) & 0xfff;//0x7ff;
\r
1323 PSXDisplay.Range.x1-=PSXDisplay.Range.x0;
\r
1325 ChangeDispOffsetsX();
\r
1332 PreviousPSXDisplay.Height = PSXDisplay.Height;
\r
1334 PSXDisplay.Range.y0=gdata & 0x3ff;
\r
1335 PSXDisplay.Range.y1=(gdata>>10) & 0x3ff;
\r
1337 PSXDisplay.Height = PSXDisplay.Range.y1 -
\r
1338 PSXDisplay.Range.y0 +
\r
1339 PreviousPSXDisplay.DisplayModeNew.y;
\r
1341 if (PreviousPSXDisplay.Height != PSXDisplay.Height)
\r
1343 PSXDisplay.DisplayModeNew.y=PSXDisplay.Height*PSXDisplay.Double;
\r
1344 ChangeDispOffsetsY();
\r
1345 updateDisplayIfChanged();
\r
1349 // setting display infos
\r
1352 PSXDisplay.DisplayModeNew.x = dispWidths[(gdata & 0x03) | ((gdata & 0x40) >> 4)];
\r
1354 if (gdata&0x04) PSXDisplay.Double=2;
\r
1355 else PSXDisplay.Double=1;
\r
1356 PSXDisplay.DisplayModeNew.y = PSXDisplay.Height*PSXDisplay.Double;
\r
1358 ChangeDispOffsetsY();
\r
1360 PSXDisplay.PAL = (gdata & 0x08)?TRUE:FALSE; // if 1 - PAL mode, else NTSC
\r
1361 PSXDisplay.RGB24New = (gdata & 0x10)?TRUE:FALSE; // if 1 - TrueColor
\r
1362 PSXDisplay.InterlacedNew = (gdata & 0x20)?TRUE:FALSE; // if 1 - Interlace
\r
1364 STATUSREG&=~GPUSTATUS_WIDTHBITS; // clear the width bits
\r
1367 (((gdata & 0x03) << 17) |
\r
1368 ((gdata & 0x40) << 10)); // set the width bits
\r
1370 PreviousPSXDisplay.InterlacedNew=FALSE;
\r
1371 if (PSXDisplay.InterlacedNew)
\r
1373 if(!PSXDisplay.Interlaced)
\r
1375 PSXDisplay.InterlacedTest=2;
\r
1376 PreviousPSXDisplay.DisplayPosition.x = PSXDisplay.DisplayPosition.x;
\r
1377 PreviousPSXDisplay.DisplayPosition.y = PSXDisplay.DisplayPosition.y;
\r
1378 PreviousPSXDisplay.InterlacedNew=TRUE;
\r
1381 STATUSREG|=GPUSTATUS_INTERLACED;
\r
1385 PSXDisplay.InterlacedTest=0;
\r
1386 STATUSREG&=~GPUSTATUS_INTERLACED;
\r
1389 if (PSXDisplay.PAL)
\r
1390 STATUSREG|=GPUSTATUS_PAL;
\r
1391 else STATUSREG&=~GPUSTATUS_PAL;
\r
1393 if (PSXDisplay.Double==2)
\r
1394 STATUSREG|=GPUSTATUS_DOUBLEHEIGHT;
\r
1395 else STATUSREG&=~GPUSTATUS_DOUBLEHEIGHT;
\r
1397 if (PSXDisplay.RGB24New)
\r
1398 STATUSREG|=GPUSTATUS_RGB24;
\r
1399 else STATUSREG&=~GPUSTATUS_RGB24;
\r
1401 updateDisplayIfChanged();
\r
1405 //--------------------------------------------------//
\r
1406 // ask about GPU version and other stuff
\r
1414 GPUdataRet=ulGPUInfoVals[INFO_TW]; // tw infos
\r
1417 GPUdataRet=ulGPUInfoVals[INFO_DRAWSTART]; // draw start
\r
1420 GPUdataRet=ulGPUInfoVals[INFO_DRAWEND]; // draw end
\r
1424 GPUdataRet=ulGPUInfoVals[INFO_DRAWOFF]; // draw offset
\r
1427 if(dwGPUVersion==2)
\r
1429 else GPUdataRet=0x02; // gpu type
\r
1432 case 0x0F: // some bios addr?
\r
1433 GPUdataRet=0xBFC03720;
\r
1437 //--------------------------------------------------//
\r
1441 ////////////////////////////////////////////////////////////////////////
\r
1442 // vram read/write helpers
\r
1443 ////////////////////////////////////////////////////////////////////////
\r
1445 BOOL bNeedWriteUpload=FALSE;
\r
1447 __inline void FinishedVRAMWrite(void)
\r
1449 if(bNeedWriteUpload)
\r
1451 bNeedWriteUpload=FALSE;
\r
1452 CheckWriteUpdate();
\r
1455 // set register to NORMAL operation
\r
1456 iDataWriteMode = DR_NORMAL;
\r
1458 // reset transfer values, to prevent mis-transfer of data
\r
1459 VRAMWrite.ColsRemaining = 0;
\r
1460 VRAMWrite.RowsRemaining = 0;
\r
1463 __inline void FinishedVRAMRead(void)
\r
1465 // set register to NORMAL operation
\r
1466 iDataReadMode = DR_NORMAL;
\r
1467 // reset transfer values, to prevent mis-transfer of data
\r
1470 VRAMRead.Width = 0;
\r
1471 VRAMRead.Height = 0;
\r
1472 VRAMRead.ColsRemaining = 0;
\r
1473 VRAMRead.RowsRemaining = 0;
\r
1475 // indicate GPU is no longer ready for VRAM data in the STATUS REGISTER
\r
1476 STATUSREG&=~GPUSTATUS_READYFORVRAM;
\r
1479 ////////////////////////////////////////////////////////////////////////
\r
1480 // vram read check ex (reading from card's back/frontbuffer if needed...
\r
1482 ////////////////////////////////////////////////////////////////////////
\r
1484 void CheckVRamReadEx(int x, int y, int dx, int dy)
\r
1486 unsigned short sArea;
\r
1487 int ux,uy,udx,udy,wx,wy;
\r
1488 unsigned short * p1, *p2;
\r
1490 unsigned char * ps;
\r
1491 unsigned char * px;
\r
1492 unsigned short s,sx;
\r
1494 if(STATUSREG&GPUSTATUS_RGB24) return;
\r
1496 if(((dx > PSXDisplay.DisplayPosition.x) &&
\r
1497 (x < PSXDisplay.DisplayEnd.x) &&
\r
1498 (dy > PSXDisplay.DisplayPosition.y) &&
\r
1499 (y < PSXDisplay.DisplayEnd.y)))
\r
1502 if((!(PSXDisplay.InterlacedTest) &&
\r
1503 (dx > PreviousPSXDisplay.DisplayPosition.x) &&
\r
1504 (x < PreviousPSXDisplay.DisplayEnd.x) &&
\r
1505 (dy > PreviousPSXDisplay.DisplayPosition.y) &&
\r
1506 (y < PreviousPSXDisplay.DisplayEnd.y)))
\r
1517 bFullVRam=TRUE;iRenderFVR=2;return;
\r
1519 bFullVRam=TRUE;iRenderFVR=2;
\r
1527 ux=PSXDisplay.DisplayPosition.x;
\r
1528 uy=PSXDisplay.DisplayPosition.y;
\r
1529 udx=PSXDisplay.DisplayEnd.x-ux;
\r
1530 udy=PSXDisplay.DisplayEnd.y-uy;
\r
1531 if((PreviousPSXDisplay.DisplayEnd.x-
\r
1532 PreviousPSXDisplay.DisplayPosition.x)==udx &&
\r
1533 (PreviousPSXDisplay.DisplayEnd.y-
\r
1534 PreviousPSXDisplay.DisplayPosition.y)==udy)
\r
1535 p2=(psxVuw + (1024*PreviousPSXDisplay.DisplayPosition.y) +
\r
1536 PreviousPSXDisplay.DisplayPosition.x);
\r
1540 ux=PreviousPSXDisplay.DisplayPosition.x;
\r
1541 uy=PreviousPSXDisplay.DisplayPosition.y;
\r
1542 udx=PreviousPSXDisplay.DisplayEnd.x-ux;
\r
1543 udy=PreviousPSXDisplay.DisplayEnd.y-uy;
\r
1544 if((PSXDisplay.DisplayEnd.x-
\r
1545 PSXDisplay.DisplayPosition.x)==udx &&
\r
1546 (PSXDisplay.DisplayEnd.y-
\r
1547 PSXDisplay.DisplayPosition.y)==udy)
\r
1548 p2=(psxVuw + (1024*PSXDisplay.DisplayPosition.y) +
\r
1549 PSXDisplay.DisplayPosition.x);
\r
1552 p1=(psxVuw + (1024*uy) + ux);
\r
1556 wx=dx=udx;wy=dy=udy;
\r
1558 if(udx<=0) return;
\r
1559 if(udy<=0) return;
\r
1565 XS=(float)rRatioRect.right/(float)wx;
\r
1566 YS=(float)rRatioRect.bottom/(float)wy;
\r
1568 dx=(int)((float)(dx)*XS);
\r
1569 dy=(int)((float)(dy)*YS);
\r
1571 if(dx>iResX) dx=iResX;
\r
1572 if(dy>iResY) dy=iResY;
\r
1580 x+=rRatioRect.left;
\r
1581 y-=rRatioRect.top;
\r
1583 if(y<0) y=0; if((y+dy)>iResY) dy=iResY-y;
\r
1585 if(!pGfxCardScreen)
\r
1587 glPixelStorei(GL_PACK_ALIGNMENT,1); glError();
\r
1588 pGfxCardScreen=(unsigned char *)malloc(iResX*iResY*4);
\r
1591 ps=pGfxCardScreen;
\r
1593 //if(!sArea) glReadBuffer(GL_FRONT);
\r
1595 glReadPixels(x,y,dx,dy,GL_RGB,GL_UNSIGNED_BYTE,ps); glError();
\r
1596 //if(!sArea) glReadBuffer(GL_BACK);
\r
1600 XS=(float)dx/(float)(udx);
\r
1601 YS=(float)dy/(float)(udy+1);
\r
1603 for(y=udy;y>0;y--)
\r
1605 for(x=0;x<udx;x++)
\r
1607 if(p1>=psxVuw && p1<psxVuw_eom)
\r
1609 px=ps+(3*((int)((float)x * XS))+
\r
1610 (3*dx)*((int)((float)y*YS)));
\r
1620 if(p2>=psxVuw && p2<psxVuw_eom) *p2=s;
\r
1627 if(p2) p2 += 1024 - udx;
\r
1631 ////////////////////////////////////////////////////////////////////////
\r
1632 // vram read check (reading from card's back/frontbuffer if needed...
\r
1634 ////////////////////////////////////////////////////////////////////////
\r
1636 void CheckVRamRead(int x, int y, int dx, int dy, bool bFront)
\r
1638 unsigned short sArea;unsigned short * p;
\r
1639 int ux,uy,udx,udy,wx,wy;float XS,YS;
\r
1640 unsigned char * ps, * px;
\r
1641 unsigned short s=0,sx;
\r
1643 if(STATUSREG&GPUSTATUS_RGB24) return;
\r
1645 if(((dx > PSXDisplay.DisplayPosition.x) &&
\r
1646 (x < PSXDisplay.DisplayEnd.x) &&
\r
1647 (dy > PSXDisplay.DisplayPosition.y) &&
\r
1648 (y < PSXDisplay.DisplayEnd.y)))
\r
1651 if((!(PSXDisplay.InterlacedTest) &&
\r
1652 (dx > PreviousPSXDisplay.DisplayPosition.x) &&
\r
1653 (x < PreviousPSXDisplay.DisplayEnd.x) &&
\r
1654 (dy > PreviousPSXDisplay.DisplayPosition.y) &&
\r
1655 (y < PreviousPSXDisplay.DisplayEnd.y)))
\r
1662 if(dwActFixes&0x40)
\r
1666 bFullVRam=TRUE;iRenderFVR=2;return;
\r
1668 bFullVRam=TRUE;iRenderFVR=2;
\r
1671 ux=x;uy=y;udx=dx;udy=dy;
\r
1675 x -=PSXDisplay.DisplayPosition.x;
\r
1676 dx-=PSXDisplay.DisplayPosition.x;
\r
1677 y -=PSXDisplay.DisplayPosition.y;
\r
1678 dy-=PSXDisplay.DisplayPosition.y;
\r
1679 wx=PSXDisplay.DisplayEnd.x-PSXDisplay.DisplayPosition.x;
\r
1680 wy=PSXDisplay.DisplayEnd.y-PSXDisplay.DisplayPosition.y;
\r
1684 x -=PreviousPSXDisplay.DisplayPosition.x;
\r
1685 dx-=PreviousPSXDisplay.DisplayPosition.x;
\r
1686 y -=PreviousPSXDisplay.DisplayPosition.y;
\r
1687 dy-=PreviousPSXDisplay.DisplayPosition.y;
\r
1688 wx=PreviousPSXDisplay.DisplayEnd.x-PreviousPSXDisplay.DisplayPosition.x;
\r
1689 wy=PreviousPSXDisplay.DisplayEnd.y-PreviousPSXDisplay.DisplayPosition.y;
\r
1691 if(x<0) {ux-=x;x=0;}
\r
1692 if(y<0) {uy-=y;y=0;}
\r
1693 if(dx>wx) {udx-=(dx-wx);dx=wx;}
\r
1694 if(dy>wy) {udy-=(dy-wy);dy=wy;}
\r
1698 p=(psxVuw + (1024*uy) + ux);
\r
1700 if(udx<=0) return;
\r
1701 if(udy<=0) return;
\r
1707 XS=(float)rRatioRect.right/(float)wx;
\r
1708 YS=(float)rRatioRect.bottom/(float)wy;
\r
1710 dx=(int)((float)(dx)*XS);
\r
1711 dy=(int)((float)(dy)*YS);
\r
1712 x=(int)((float)x*XS);
\r
1713 y=(int)((float)y*YS);
\r
1718 if(dx>iResX) dx=iResX;
\r
1719 if(dy>iResY) dy=iResY;
\r
1727 x+=rRatioRect.left;
\r
1728 y-=rRatioRect.top;
\r
1730 if(y<0) y=0; if((y+dy)>iResY) dy=iResY-y;
\r
1732 if(!pGfxCardScreen)
\r
1734 glPixelStorei(GL_PACK_ALIGNMENT,1); glError();
\r
1735 pGfxCardScreen=(unsigned char *)malloc(iResX*iResY*4);
\r
1738 ps=pGfxCardScreen;
\r
1740 // if(bFront) glReadBuffer(GL_FRONT);
\r
1742 glReadPixels(x,y,dx,dy,GL_RGB,GL_UNSIGNED_BYTE,ps); glError(); glError();
\r
1743 // if(bFront) glReadBuffer(GL_BACK);
\r
1745 XS=(float)dx/(float)(udx);
\r
1746 YS=(float)dy/(float)(udy+1);
\r
1748 for(y=udy;y>0;y--)
\r
1750 for(x=0;x<udx;x++)
\r
1752 if(p>=psxVuw && p<psxVuw_eom)
\r
1754 px=ps+(3*((int)((float)x * XS))+
\r
1755 (3*dx)*((int)((float)y*YS)));
\r
1771 ////////////////////////////////////////////////////////////////////////
\r
1772 // core read from vram
\r
1773 ////////////////////////////////////////////////////////////////////////
\r
1775 void CALLBACK GPUreadDataMem(unsigned long * pMem, int iSize)
\r
1779 if(iDataReadMode!=DR_VRAMTRANSFER) return;
\r
1783 // adjust read ptr, if necessary
\r
1784 while(VRAMRead.ImagePtr>=psxVuw_eom)
\r
1785 VRAMRead.ImagePtr-=iGPUHeight*1024;
\r
1786 while(VRAMRead.ImagePtr<psxVuw)
\r
1787 VRAMRead.ImagePtr+=iGPUHeight*1024;
\r
1789 if((iFrameReadType&1 && iSize>1) &&
\r
1790 !(iDrawnSomething==2 &&
\r
1791 VRAMRead.x == VRAMWrite.x &&
\r
1792 VRAMRead.y == VRAMWrite.y &&
\r
1793 VRAMRead.Width == VRAMWrite.Width &&
\r
1794 VRAMRead.Height == VRAMWrite.Height))
\r
1795 CheckVRamRead(VRAMRead.x,VRAMRead.y,
\r
1796 VRAMRead.x+VRAMRead.RowsRemaining,
\r
1797 VRAMRead.y+VRAMRead.ColsRemaining,
\r
1800 for(i=0;i<iSize;i++)
\r
1802 // do 2 seperate 16bit reads for compatibility (wrap issues)
\r
1803 if ((VRAMRead.ColsRemaining > 0) && (VRAMRead.RowsRemaining > 0))
\r
1806 GPUdataRet=(unsigned long)*VRAMRead.ImagePtr;
\r
1808 VRAMRead.ImagePtr++;
\r
1809 if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;
\r
1810 VRAMRead.RowsRemaining --;
\r
1812 if(VRAMRead.RowsRemaining<=0)
\r
1814 VRAMRead.RowsRemaining = VRAMRead.Width;
\r
1815 VRAMRead.ColsRemaining--;
\r
1816 VRAMRead.ImagePtr += 1024 - VRAMRead.Width;
\r
1817 if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;
\r
1820 // higher 16 bit (always, even if it's an odd width)
\r
1821 GPUdataRet|=(unsigned long)(*VRAMRead.ImagePtr)<<16;
\r
1822 *pMem++=GPUdataRet;
\r
1824 if(VRAMRead.ColsRemaining <= 0)
\r
1825 {FinishedVRAMRead();goto ENDREAD;}
\r
1827 VRAMRead.ImagePtr++;
\r
1828 if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;
\r
1829 VRAMRead.RowsRemaining--;
\r
1830 if(VRAMRead.RowsRemaining<=0)
\r
1832 VRAMRead.RowsRemaining = VRAMRead.Width;
\r
1833 VRAMRead.ColsRemaining--;
\r
1834 VRAMRead.ImagePtr += 1024 - VRAMRead.Width;
\r
1835 if(VRAMRead.ImagePtr>=psxVuw_eom) VRAMRead.ImagePtr-=iGPUHeight*1024;
\r
1837 if(VRAMRead.ColsRemaining <= 0)
\r
1838 {FinishedVRAMRead();goto ENDREAD;}
\r
1840 else {FinishedVRAMRead();goto ENDREAD;}
\r
1847 unsigned long CALLBACK GPUreadData(void)
\r
1850 GPUreadDataMem(&l,1);
\r
1851 return GPUdataRet;
\r
1854 ////////////////////////////////////////////////////////////////////////
\r
1855 // helper table to know how much data is used by drawing commands
\r
1856 ////////////////////////////////////////////////////////////////////////
\r
1858 const unsigned char primTableCX[256] =
\r
1875 8,8,8,8,12,12,12,12,
\r
1879 // 5,5,5,5,6,6,6,6, //FLINE
\r
1880 254,254,254,254,254,254,254,254,
\r
1884 // 7,7,7,7,9,9,9,9, // LINEG3 LINEG4
\r
1885 255,255,255,255,255,255,255,255,
\r
1887 3,3,3,3,4,4,4,4, // TILE SPRT
\r
1889 2,2,2,2,3,3,3,3, // TILE1
\r
1928 ////////////////////////////////////////////////////////////////////////
\r
1929 // processes data send to GPU data register
\r
1930 ////////////////////////////////////////////////////////////////////////
\r
1932 void CALLBACK GPUwriteDataMem(unsigned long * pMem, int iSize)
\r
1934 unsigned char command;
\r
1935 unsigned long gdata=0;
\r
1938 GPUIsNotReadyForCommands;
\r
1942 if(iDataWriteMode==DR_VRAMTRANSFER)
\r
1944 // make sure we are in vram
\r
1945 while(VRAMWrite.ImagePtr>=psxVuw_eom)
\r
1946 VRAMWrite.ImagePtr-=iGPUHeight*1024;
\r
1947 while(VRAMWrite.ImagePtr<psxVuw)
\r
1948 VRAMWrite.ImagePtr+=iGPUHeight*1024;
\r
1950 // now do the loop
\r
1951 while(VRAMWrite.ColsRemaining>0)
\r
1953 while(VRAMWrite.RowsRemaining>0)
\r
1955 if(i>=iSize) {goto ENDVRAM;}
\r
1960 *VRAMWrite.ImagePtr++ = (unsigned short)gdata;
\r
1961 if(VRAMWrite.ImagePtr>=psxVuw_eom) VRAMWrite.ImagePtr-=iGPUHeight*1024;
\r
1962 VRAMWrite.RowsRemaining --;
\r
1964 if(VRAMWrite.RowsRemaining <= 0)
\r
1966 VRAMWrite.ColsRemaining--;
\r
1967 if (VRAMWrite.ColsRemaining <= 0) // last pixel is odd width
\r
1969 gdata=(gdata&0xFFFF)|(((unsigned long)(*VRAMWrite.ImagePtr))<<16);
\r
1970 FinishedVRAMWrite();
\r
1973 VRAMWrite.RowsRemaining = VRAMWrite.Width;
\r
1974 VRAMWrite.ImagePtr += 1024 - VRAMWrite.Width;
\r
1977 *VRAMWrite.ImagePtr++ = (unsigned short)(gdata>>16);
\r
1978 if(VRAMWrite.ImagePtr>=psxVuw_eom) VRAMWrite.ImagePtr-=iGPUHeight*1024;
\r
1979 VRAMWrite.RowsRemaining --;
\r
1982 VRAMWrite.RowsRemaining = VRAMWrite.Width;
\r
1983 VRAMWrite.ColsRemaining--;
\r
1984 VRAMWrite.ImagePtr += 1024 - VRAMWrite.Width;
\r
1987 FinishedVRAMWrite();
\r
1992 if(iDataWriteMode==DR_NORMAL)
\r
1994 void (* *primFunc)(unsigned char *);
\r
1995 if(bSkipNextFrame) primFunc=primTableSkip;
\r
1996 else primFunc=primTableJ;
\r
2000 if(iDataWriteMode==DR_VRAMTRANSFER) goto STARTVRAM;
\r
2002 gdata=*pMem++;i++;
\r
2006 command = (unsigned char)((gdata>>24) & 0xff);
\r
2008 if(primTableCX[command])
\r
2010 gpuDataC = primTableCX[command];
\r
2011 gpuCommand = command;
\r
2012 gpuDataM[0] = gdata;
\r
2019 gpuDataM[gpuDataP] = gdata;
\r
2022 if((gpuDataC==254 && gpuDataP>=3) ||
\r
2023 (gpuDataC==255 && gpuDataP>=4 && !(gpuDataP&1)))
\r
2025 if((gpuDataM[gpuDataP] & 0xF000F000) == 0x50005000)
\r
2026 gpuDataP=gpuDataC-1;
\r
2032 if(gpuDataP == gpuDataC)
\r
2034 gpuDataC=gpuDataP=0;
\r
2035 primFunc[gpuCommand]((unsigned char *)gpuDataM);
\r
2037 if(dwEmuFixes&0x0001 || dwActFixes&0x20000) // hack for emulating "gpu busy" in some games
\r
2045 GPUIsReadyForCommands;
\r
2049 ////////////////////////////////////////////////////////////////////////
\r
2051 void CALLBACK GPUwriteData(unsigned long gdata)
\r
2053 GPUwriteDataMem(&gdata,1);
\r
2056 ////////////////////////////////////////////////////////////////////////
\r
2057 // this function will be removed soon (or 'soonish') (or never)
\r
2058 ////////////////////////////////////////////////////////////////////////
\r
2060 void CALLBACK GPUsetMode(unsigned int gdata)
\r
2062 // ignore old psemu setmode:
\r
2064 // imageTransfer = gdata;
\r
2065 // iDataWriteMode=(gdata&1)?DR_VRAMTRANSFER:DR_NORMAL;
\r
2066 // iDataReadMode =(gdata&2)?DR_VRAMTRANSFER:DR_NORMAL;
\r
2069 // and this function will be removed soon as well, hehehe...
\r
2070 long CALLBACK GPUgetMode(void)
\r
2072 // ignore old psemu setmode
\r
2073 // return imageTransfer;
\r
2077 if(iDataWriteMode==DR_VRAMTRANSFER) iT|=0x1;
\r
2078 if(iDataReadMode ==DR_VRAMTRANSFER) iT|=0x2;
\r
2083 ////////////////////////////////////////////////////////////////////////
\r
2084 // call config dlg (Windows + Linux)
\r
2085 ////////////////////////////////////////////////////////////////////////
\r
2089 /*#include <unistd.h>
\r
2091 void StartCfgTool(char * pCmdLine) // linux: start external cfg tool
\r
2093 FILE * cf;char filename[255],t[255];
\r
2095 strcpy(filename,"cfg/cfgPeopsMesaGL"); // look in cfg sub folder first
\r
2096 cf=fopen(filename,"rb");
\r
2102 sprintf(filename,"./cfgPeopsMesaGL %s",pCmdLine);
\r
2108 strcpy(filename,"cfgPeopsMesaGL"); // look in current folder
\r
2109 cf=fopen(filename,"rb");
\r
2113 sprintf(filename,"./cfgPeopsMesaGL %s",pCmdLine);
\r
2118 sprintf(filename,"%s/cfgPeopsMesaGL",getenv("HOME")); // look in home folder
\r
2119 cf=fopen(filename,"rb");
\r
2124 chdir(getenv("HOME"));
\r
2125 sprintf(filename,"./cfgPeopsMesaGL %s",pCmdLine);
\r
2129 else printf("cfgPeopsMesaGL not found!\n");
\r
2137 long CALLBACK GPUconfigure(void)
\r
2144 ////////////////////////////////////////////////////////////////////////
\r
2145 // sets all kind of act fixes
\r
2146 ////////////////////////////////////////////////////////////////////////
\r
2148 void SetFixes(void)
\r
2152 if(dwActFixes & 0x2000)
\r
2153 dispWidths[4]=384;
\r
2154 else dispWidths[4]=368;
\r
2157 ////////////////////////////////////////////////////////////////////////
\r
2158 // Pete Special: make an 'intelligent' dma chain check (<-Tekken3)
\r
2159 ////////////////////////////////////////////////////////////////////////
\r
2161 unsigned long lUsedAddr[3];
\r
2163 __inline BOOL CheckForEndlessLoop(unsigned long laddr)
\r
2165 if(laddr==lUsedAddr[1]) return TRUE;
\r
2166 if(laddr==lUsedAddr[2]) return TRUE;
\r
2168 if(laddr<lUsedAddr[0]) lUsedAddr[1]=laddr;
\r
2169 else lUsedAddr[2]=laddr;
\r
2170 lUsedAddr[0]=laddr;
\r
2174 ////////////////////////////////////////////////////////////////////////
\r
2175 // core gives a dma chain to gpu: same as the gpuwrite interface funcs
\r
2176 ////////////////////////////////////////////////////////////////////////
\r
2178 long CALLBACK GPUdmaChain(unsigned long * baseAddrL, unsigned long addr)
\r
2180 unsigned long dmaMem;
\r
2181 unsigned char * baseAddrB;
\r
2182 short count;unsigned int DMACommandCounter = 0;
\r
2184 if(bIsFirstFrame) GLinitialize();
\r
2188 lUsedAddr[0]=lUsedAddr[1]=lUsedAddr[2]=0xffffff;
\r
2190 baseAddrB = (unsigned char*) baseAddrL;
\r
2194 if(iGPUHeight==512) addr&=0x1FFFFC;
\r
2196 if(DMACommandCounter++ > 2000000) break;
\r
2197 if(CheckForEndlessLoop(addr)) break;
\r
2199 count = baseAddrB[addr+3];
\r
2203 if(count>0) GPUwriteDataMem(&baseAddrL[dmaMem>>2],count);
\r
2205 addr = baseAddrL[addr>>2]&0xffffff;
\r
2207 while (addr != 0xffffff);
\r
2214 ////////////////////////////////////////////////////////////////////////
\r
2216 ////////////////////////////////////////////////////////////////////////
\r
2218 void CALLBACK GPUabout(void)
\r
2223 ////////////////////////////////////////////////////////////////////////
\r
2224 // We are ever fine ;)
\r
2225 ////////////////////////////////////////////////////////////////////////
\r
2227 long CALLBACK GPUtest(void)
\r
2229 // if test fails this function should return negative value for error (unable to continue)
\r
2230 // and positive value for warning (can continue but output might be crappy)
\r
2235 ////////////////////////////////////////////////////////////////////////
\r
2236 // save state funcs
\r
2237 ////////////////////////////////////////////////////////////////////////
\r
2239 ////////////////////////////////////////////////////////////////////////
\r
2241 long CALLBACK GPUfreeze(unsigned long ulGetFreezeData,GPUFreeze_t * pF)
\r
2243 if(ulGetFreezeData==2)
\r
2245 long lSlotNum=*((long *)pF);
\r
2246 if(lSlotNum<0) return 0;
\r
2247 if(lSlotNum>8) return 0;
\r
2248 lSelectedSlot=lSlotNum+1;
\r
2252 if(!pF) return 0;
\r
2253 if(pF->ulFreezeVersion!=1) return 0;
\r
2255 if(ulGetFreezeData==1)
\r
2257 pF->ulStatus=STATUSREG;
\r
2258 memcpy(pF->ulControl,ulStatusControl,256*sizeof(unsigned long));
\r
2259 memcpy(pF->psxVRam, psxVub, 1024*iGPUHeight*2);
\r
2264 if(ulGetFreezeData!=0) return 0;
\r
2266 STATUSREG=pF->ulStatus;
\r
2267 memcpy(ulStatusControl,pF->ulControl,256*sizeof(unsigned long));
\r
2268 memcpy(psxVub, pF->psxVRam, 1024*iGPUHeight*2);
\r
2270 ResetTextureArea(TRUE);
\r
2272 GPUwriteStatus(ulStatusControl[0]);
\r
2273 GPUwriteStatus(ulStatusControl[1]);
\r
2274 GPUwriteStatus(ulStatusControl[2]);
\r
2275 GPUwriteStatus(ulStatusControl[3]);
\r
2276 GPUwriteStatus(ulStatusControl[8]);
\r
2277 GPUwriteStatus(ulStatusControl[6]);
\r
2278 GPUwriteStatus(ulStatusControl[7]);
\r
2279 GPUwriteStatus(ulStatusControl[5]);
\r
2280 GPUwriteStatus(ulStatusControl[4]);
\r
2284 ////////////////////////////////////////////////////////////////////////
\r
2285 // special "emu infos" / "emu effects" functions
\r
2286 ////////////////////////////////////////////////////////////////////////
\r
2291 //11 = transparent
\r
2293 unsigned char cFont[10][120]=
\r
2296 {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
\r
2297 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2298 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2299 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2300 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2301 0x80,0x00,0x05,0x54,0x00,0x00,
\r
2302 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2303 0x80,0x00,0x14,0x05,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,0x05,0x54,0x00,0x00,
\r
2311 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2312 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2313 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2314 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2315 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
\r
2318 {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
\r
2319 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2320 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2321 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2322 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2323 0x80,0x00,0x00,0x50,0x00,0x00,
\r
2324 0x80,0x00,0x05,0x50,0x00,0x00,
\r
2325 0x80,0x00,0x00,0x50,0x00,0x00,
\r
2326 0x80,0x00,0x00,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,0x05,0x55,0x00,0x00,
\r
2333 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2334 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2335 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2336 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2337 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
\r
2340 {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
\r
2341 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2342 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2343 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2344 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2345 0x80,0x00,0x05,0x54,0x00,0x00,
\r
2346 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2347 0x80,0x00,0x00,0x05,0x00,0x00,
\r
2348 0x80,0x00,0x00,0x05,0x00,0x00,
\r
2349 0x80,0x00,0x00,0x14,0x00,0x00,
\r
2350 0x80,0x00,0x00,0x50,0x00,0x00,
\r
2351 0x80,0x00,0x01,0x40,0x00,0x00,
\r
2352 0x80,0x00,0x05,0x00,0x00,0x00,
\r
2353 0x80,0x00,0x14,0x00,0x00,0x00,
\r
2354 0x80,0x00,0x15,0x55,0x00,0x00,
\r
2355 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2356 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2357 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2358 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2359 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
\r
2362 {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
\r
2363 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2364 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2365 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2366 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2367 0x80,0x00,0x05,0x54,0x00,0x00,
\r
2368 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2369 0x80,0x00,0x00,0x05,0x00,0x00,
\r
2370 0x80,0x00,0x00,0x05,0x00,0x00,
\r
2371 0x80,0x00,0x01,0x54,0x00,0x00,
\r
2372 0x80,0x00,0x00,0x05,0x00,0x00,
\r
2373 0x80,0x00,0x00,0x05,0x00,0x00,
\r
2374 0x80,0x00,0x00,0x05,0x00,0x00,
\r
2375 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2376 0x80,0x00,0x05,0x54,0x00,0x00,
\r
2377 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2378 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2379 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2380 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2381 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
\r
2384 {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
\r
2385 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2386 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2387 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2388 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2389 0x80,0x00,0x00,0x14,0x00,0x00,
\r
2390 0x80,0x00,0x00,0x54,0x00,0x00,
\r
2391 0x80,0x00,0x01,0x54,0x00,0x00,
\r
2392 0x80,0x00,0x01,0x54,0x00,0x00,
\r
2393 0x80,0x00,0x05,0x14,0x00,0x00,
\r
2394 0x80,0x00,0x14,0x14,0x00,0x00,
\r
2395 0x80,0x00,0x15,0x55,0x00,0x00,
\r
2396 0x80,0x00,0x00,0x14,0x00,0x00,
\r
2397 0x80,0x00,0x00,0x14,0x00,0x00,
\r
2398 0x80,0x00,0x00,0x55,0x00,0x00,
\r
2399 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2400 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2401 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2402 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2403 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
\r
2406 {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
\r
2407 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2408 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2409 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2410 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2411 0x80,0x00,0x15,0x55,0x00,0x00,
\r
2412 0x80,0x00,0x14,0x00,0x00,0x00,
\r
2413 0x80,0x00,0x14,0x00,0x00,0x00,
\r
2414 0x80,0x00,0x14,0x00,0x00,0x00,
\r
2415 0x80,0x00,0x15,0x54,0x00,0x00,
\r
2416 0x80,0x00,0x00,0x05,0x00,0x00,
\r
2417 0x80,0x00,0x00,0x05,0x00,0x00,
\r
2418 0x80,0x00,0x00,0x05,0x00,0x00,
\r
2419 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2420 0x80,0x00,0x05,0x54,0x00,0x00,
\r
2421 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2422 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2423 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2424 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2425 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
\r
2428 {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
\r
2429 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2430 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2431 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2432 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2433 0x80,0x00,0x01,0x54,0x00,0x00,
\r
2434 0x80,0x00,0x05,0x00,0x00,0x00,
\r
2435 0x80,0x00,0x14,0x00,0x00,0x00,
\r
2436 0x80,0x00,0x14,0x00,0x00,0x00,
\r
2437 0x80,0x00,0x15,0x54,0x00,0x00,
\r
2438 0x80,0x00,0x15,0x05,0x00,0x00,
\r
2439 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2440 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2441 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2442 0x80,0x00,0x05,0x54,0x00,0x00,
\r
2443 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2444 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2445 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2446 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2447 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
\r
2450 {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
\r
2451 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2452 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2453 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2454 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2455 0x80,0x00,0x15,0x55,0x00,0x00,
\r
2456 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2457 0x80,0x00,0x00,0x14,0x00,0x00,
\r
2458 0x80,0x00,0x00,0x14,0x00,0x00,
\r
2459 0x80,0x00,0x00,0x50,0x00,0x00,
\r
2460 0x80,0x00,0x00,0x50,0x00,0x00,
\r
2461 0x80,0x00,0x01,0x40,0x00,0x00,
\r
2462 0x80,0x00,0x01,0x40,0x00,0x00,
\r
2463 0x80,0x00,0x05,0x00,0x00,0x00,
\r
2464 0x80,0x00,0x05,0x00,0x00,0x00,
\r
2465 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2466 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2467 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2468 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2469 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
\r
2472 {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
\r
2473 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2474 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2475 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2476 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2477 0x80,0x00,0x05,0x54,0x00,0x00,
\r
2478 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2479 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2480 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2481 0x80,0x00,0x05,0x54,0x00,0x00,
\r
2482 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2483 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2484 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2485 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2486 0x80,0x00,0x05,0x54,0x00,0x00,
\r
2487 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2488 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2489 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2490 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2491 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
\r
2494 {0xaa,0xaa,0xaa,0xaa,0xaa,0xaa,
\r
2495 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2496 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2497 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2498 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2499 0x80,0x00,0x05,0x54,0x00,0x00,
\r
2500 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2501 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2502 0x80,0x00,0x14,0x05,0x00,0x00,
\r
2503 0x80,0x00,0x14,0x15,0x00,0x00,
\r
2504 0x80,0x00,0x05,0x55,0x00,0x00,
\r
2505 0x80,0x00,0x00,0x05,0x00,0x00,
\r
2506 0x80,0x00,0x00,0x05,0x00,0x00,
\r
2507 0x80,0x00,0x00,0x14,0x00,0x00,
\r
2508 0x80,0x00,0x05,0x50,0x00,0x00,
\r
2509 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2510 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2511 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2512 0x80,0x00,0x00,0x00,0x00,0x00,
\r
2513 0xaa,0xaa,0xaa,0xaa,0xaa,0xaa
\r
2517 ////////////////////////////////////////////////////////////////////////
\r
2519 void PaintPicDot(unsigned char * p,unsigned char c)
\r
2521 if(c==0) {*p++=0x00;*p++=0x00;*p=0x00;return;}
\r
2522 if(c==1) {*p++=0xff;*p++=0xff;*p=0xff;return;}
\r
2523 if(c==2) {*p++=0x00;*p++=0x00;*p=0xff;return;}
\r
2526 ////////////////////////////////////////////////////////////////////////
\r
2528 long CALLBACK GPUgetScreenPic(unsigned char * pMem)
\r
2530 float XS,YS;int x,y,v;
\r
2531 unsigned char * ps, * px, * pf;
\r
2534 if(!pGfxCardScreen)
\r
2536 glPixelStorei(GL_PACK_ALIGNMENT,1); glError();
\r
2537 pGfxCardScreen=(unsigned char *)malloc(iResX*iResY*4);
\r
2540 ps=pGfxCardScreen;
\r
2542 // glReadBuffer(GL_FRONT);
\r
2544 glReadPixels(0,0,iResX,iResY,GL_RGB,GL_UNSIGNED_BYTE,ps); glError();
\r
2546 // glReadBuffer(GL_BACK);
\r
2548 XS=(float)iResX/128;
\r
2549 YS=(float)iResY/96;
\r
2554 for(x=0;x<128;x++)
\r
2556 px=ps+(3*((int)((float)x * XS))+
\r
2557 (3*iResX)*((int)((float)y*YS)));
\r
2565 /////////////////////////////////////////////////////////////////////
\r
2566 // generic number/border painter
\r
2574 c=cFont[lSelectedSlot][x+y*6];
\r
2576 PaintPicDot(pf,(unsigned char)v);pf+=3; // paint the dots into the rect
\r
2578 PaintPicDot(pf,(unsigned char)v);pf+=3;
\r
2580 PaintPicDot(pf,(unsigned char)v);pf+=3;
\r
2582 PaintPicDot(pf,(unsigned char)v);pf+=3;
\r
2588 for(x=0;x<128;x++)
\r
2590 *(pf+(95*128*3))=0x00;*pf++=0x00;
\r
2591 *(pf+(95*128*3))=0x00;*pf++=0x00;
\r
2592 *(pf+(95*128*3))=0xff;*pf++=0xff;
\r
2597 *(pf+(127*3))=0x00;*pf++=0x00;
\r
2598 *(pf+(127*3))=0x00;*pf++=0x00;
\r
2599 *(pf+(127*3))=0xff;*pf++=0xff;
\r
2605 ////////////////////////////////////////////////////////////////////////
\r
2607 long CALLBACK GPUshowScreenPic(unsigned char * pMem)
\r
2610 // if(pMem==0) return;
\r
2611 // CreatePic(pMem);
\r
2614 ////////////////////////////////////////////////////////////////////////
\r
2616 void CALLBACK GPUsetfix(unsigned long dwFixBits)
\r
2618 dwEmuFixes=dwFixBits;
\r
2621 ////////////////////////////////////////////////////////////////////////
\r
2623 void CALLBACK GPUvisualVibration(unsigned long iSmall, unsigned long iBig)
\r
2627 if(PSXDisplay.DisplayModeNew.x) // calc min "shake pixel" from screen width
\r
2628 iVibVal=max(1,iResX/PSXDisplay.DisplayModeNew.x);
\r
2630 // big rumble: 4...15 sp ; small rumble 1...3 sp
\r
2631 if(iBig) iRumbleVal=max(4*iVibVal,min(15*iVibVal,((int)iBig *iVibVal)/10));
\r
2632 else iRumbleVal=max(1*iVibVal,min( 3*iVibVal,((int)iSmall*iVibVal)/10));
\r
2634 srand(timeGetTime()); // init rand (will be used in BufferSwap)
\r
2636 iRumbleTime=15; // let the rumble last 16 buffer swaps
\r
2639 ////////////////////////////////////////////////////////////////////////
\r
2640 // main emu can set display infos (A/M/G/D)
\r
2641 ////////////////////////////////////////////////////////////////////////
\r
2643 void CALLBACK GPUdisplayFlags(unsigned long dwFlags)
\r
2645 // dwCoreFlags=dwFlags;
\r
2648 // pcsx-rearmed callbacks
\r
2649 void CALLBACK GPUrearmedCallbacks(const void **cbs)
\r
2651 rearmed_get_layer_pos = cbs[0];
\r
2654 static void flipEGL(void)
\r
2656 eglSwapBuffers(display, surface);
\r