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