cdrom: change pause timing again
[pcsx_rearmed.git] / plugins / gpu-gles / gpulib_if.c
1 /***************************************************************************
2     begin                : Sun Mar 08 2009
3     copyright            : (C) 1999-2009 by Pete Bernert
4     email                : BlackDove@addcom.de
5
6     PCSX rearmed rework (C) notaz, 2012
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 #include "gpuStdafx.h"
20 #include "gpuDraw.c"
21 #include "gpuTexture.c"
22 #include "gpuPrim.c"
23 #include "hud.c"
24
25 static const short dispWidths[8] = {256,320,512,640,368,384,512,640};
26 short g_m1,g_m2,g_m3;
27 short DrawSemiTrans;
28
29 short          ly0,lx0,ly1,lx1,ly2,lx2,ly3,lx3;        // global psx vertex coords
30 int            GlobalTextAddrX,GlobalTextAddrY,GlobalTextTP;
31 int            GlobalTextREST,GlobalTextABR,GlobalTextPAGE;
32
33 unsigned int  dwGPUVersion;
34 int           iGPUHeight=512;
35 int           iGPUHeightMask=511;
36 int           GlobalTextIL;
37
38 unsigned char  *psxVub;
39 unsigned short *psxVuw;
40
41 GLfloat         gl_z=0.0f;
42 BOOL            bNeedInterlaceUpdate;
43 BOOL            bNeedRGB24Update;
44 BOOL            bChangeWinMode;
45 int             lGPUstatusRet;
46 unsigned int    ulGPUInfoVals[16];
47 VRAMLoad_t      VRAMWrite;
48 VRAMLoad_t      VRAMRead;
49 int             iDataWriteMode;
50 int             iDataReadMode;
51
52 int             lClearOnSwap;
53 int             lClearOnSwapColor;
54 BOOL            bSkipNextFrame;
55
56 PSXDisplay_t    PSXDisplay;
57 PSXDisplay_t    PreviousPSXDisplay;
58 TWin_t          TWin;
59 BOOL            bDisplayNotSet;
60 BOOL            bNeedWriteUpload;
61 int             iLastRGB24;
62
63 // don't do GL vram read
64 void CheckVRamRead(int x, int y, int dx, int dy, bool bFront)
65 {
66 }
67
68 void CheckVRamReadEx(int x, int y, int dx, int dy)
69 {
70 }
71
72 void SetFixes(void)
73 {
74 }
75
76 static void PaintBlackBorders(void)
77 {
78  short s;
79  glDisable(GL_SCISSOR_TEST); glError();
80  if(bTexEnabled) {glDisable(GL_TEXTURE_2D);bTexEnabled=FALSE;} glError();
81  if(bOldSmoothShaded) {glShadeModel(GL_FLAT);bOldSmoothShaded=FALSE;} glError();
82  if(bBlendEnable)     {glDisable(GL_BLEND);bBlendEnable=FALSE;} glError();
83  glDisable(GL_ALPHA_TEST); glError();
84
85  glEnable(GL_ALPHA_TEST); glError();
86  glEnable(GL_SCISSOR_TEST); glError();
87 }
88
89 static void fps_update(void);
90
91 void updateDisplay(void)
92 {
93  bFakeFrontBuffer=FALSE;
94  bRenderFrontBuffer=FALSE;
95
96  if(PSXDisplay.RGB24)// && !bNeedUploadAfter)         // (mdec) upload wanted?
97  {
98   PrepareFullScreenUpload(-1);
99   UploadScreen(PSXDisplay.Interlaced);                // -> upload whole screen from psx vram
100   bNeedUploadTest=FALSE;
101   bNeedInterlaceUpdate=FALSE;
102   bNeedUploadAfter=FALSE;
103   bNeedRGB24Update=FALSE;
104  }
105  else
106  if(bNeedInterlaceUpdate)                             // smaller upload?
107  {
108   bNeedInterlaceUpdate=FALSE;
109   xrUploadArea=xrUploadAreaIL;                        // -> upload this rect
110   UploadScreen(TRUE);
111  }
112
113  if(dwActFixes&512) bCheckFF9G4(NULL);                // special game fix for FF9 
114
115  if(PSXDisplay.Disabled)                              // display disabled?
116  {
117   // moved here
118   glDisable(GL_SCISSOR_TEST); glError();                       
119   glClearColor(0,0,0,128); glError();                 // -> clear whole backbuffer
120   glClear(uiBufferBits); glError();
121   glEnable(GL_SCISSOR_TEST); glError();                       
122   gl_z=0.0f;
123   bDisplayNotSet = TRUE;
124  }
125
126  if(iDrawnSomething)
127  {
128   fps_update();
129   eglSwapBuffers(display, surface);
130   iDrawnSomething=0;
131  }
132
133  if(lClearOnSwap)                                     // clear buffer after swap?
134  {
135   GLclampf g,b,r;
136
137   if(bDisplayNotSet)                                  // -> set new vals
138    SetOGLDisplaySettings(1);
139
140   g=((GLclampf)GREEN(lClearOnSwapColor))/255.0f;      // -> get col
141   b=((GLclampf)BLUE(lClearOnSwapColor))/255.0f;
142   r=((GLclampf)RED(lClearOnSwapColor))/255.0f;
143   glDisable(GL_SCISSOR_TEST); glError();                       
144   glClearColor(r,g,b,128); glError();                 // -> clear 
145   glClear(uiBufferBits); glError();
146   glEnable(GL_SCISSOR_TEST); glError();                       
147   lClearOnSwap=0;                                     // -> done
148  }
149  else 
150  {
151   if(iZBufferDepth)                                   // clear zbuffer as well (if activated)
152    {
153     glDisable(GL_SCISSOR_TEST); glError();
154     glClear(GL_DEPTH_BUFFER_BIT); glError();
155     glEnable(GL_SCISSOR_TEST); glError();
156    }
157  }
158  gl_z=0.0f;
159
160  // additional uploads immediatly after swapping
161  if(bNeedUploadAfter)                                 // upload wanted?
162  {
163   bNeedUploadAfter=FALSE;                           
164   bNeedUploadTest=FALSE;
165   UploadScreen(-1);                                   // -> upload
166  }
167
168  if(bNeedUploadTest)
169  {
170   bNeedUploadTest=FALSE;
171   if(PSXDisplay.InterlacedTest &&
172      //iOffscreenDrawing>2 &&
173      PreviousPSXDisplay.DisplayPosition.x==PSXDisplay.DisplayPosition.x &&
174      PreviousPSXDisplay.DisplayEnd.x==PSXDisplay.DisplayEnd.x &&
175      PreviousPSXDisplay.DisplayPosition.y==PSXDisplay.DisplayPosition.y &&
176      PreviousPSXDisplay.DisplayEnd.y==PSXDisplay.DisplayEnd.y)
177    {
178     PrepareFullScreenUpload(TRUE);
179     UploadScreen(TRUE);
180    }
181  }
182 }
183
184 void updateFrontDisplay(void)
185 {
186  if(PreviousPSXDisplay.Range.x0||
187     PreviousPSXDisplay.Range.y0)
188   PaintBlackBorders();
189
190  bFakeFrontBuffer=FALSE;
191  bRenderFrontBuffer=FALSE;
192
193  if(iDrawnSomething)                                  // linux:
194   eglSwapBuffers(display, surface);
195 }
196
197 static void ChangeDispOffsetsX(void)                  // CENTER X
198 {
199 int lx,l;short sO;
200
201 if(!PSXDisplay.Range.x1) return;                      // some range given?
202
203 l=PSXDisplay.DisplayMode.x;
204
205 l*=(int)PSXDisplay.Range.x1;                         // some funky calculation
206 l/=2560;lx=l;l&=0xfffffff8;
207
208 if(l==PreviousPSXDisplay.Range.x1) return;            // some change?
209
210 sO=PreviousPSXDisplay.Range.x0;                       // store old
211
212 if(lx>=PSXDisplay.DisplayMode.x)                      // range bigger?
213  {
214   PreviousPSXDisplay.Range.x1=                        // -> take display width
215    PSXDisplay.DisplayMode.x;
216   PreviousPSXDisplay.Range.x0=0;                      // -> start pos is 0
217  }
218 else                                                  // range smaller? center it
219  {
220   PreviousPSXDisplay.Range.x1=l;                      // -> store width (8 pixel aligned)
221    PreviousPSXDisplay.Range.x0=                       // -> calc start pos
222    (PSXDisplay.Range.x0-500)/8;
223   if(PreviousPSXDisplay.Range.x0<0)                   // -> we don't support neg. values yet
224    PreviousPSXDisplay.Range.x0=0;
225
226   if((PreviousPSXDisplay.Range.x0+lx)>                // -> uhuu... that's too much
227      PSXDisplay.DisplayMode.x)
228    {
229     PreviousPSXDisplay.Range.x0=                      // -> adjust start
230      PSXDisplay.DisplayMode.x-lx;
231     PreviousPSXDisplay.Range.x1+=lx-l;                // -> adjust width
232    }                   
233  }
234
235 if(sO!=PreviousPSXDisplay.Range.x0)                   // something changed?
236  {
237   bDisplayNotSet=TRUE;                                // -> recalc display stuff
238  }
239 }
240
241 ////////////////////////////////////////////////////////////////////////
242
243 static void ChangeDispOffsetsY(void)                  // CENTER Y
244 {
245 int iT;short sO;                                      // store previous y size
246
247 if(PSXDisplay.PAL) iT=48; else iT=28;                 // different offsets on PAL/NTSC
248
249 if(PSXDisplay.Range.y0>=iT)                           // crossed the security line? :)
250  {
251   PreviousPSXDisplay.Range.y1=                        // -> store width
252    PSXDisplay.DisplayModeNew.y;
253   
254   sO=(PSXDisplay.Range.y0-iT-4)*PSXDisplay.Double;    // -> calc offset
255   if(sO<0) sO=0;
256
257   PSXDisplay.DisplayModeNew.y+=sO;                    // -> add offset to y size, too
258  }
259 else sO=0;                                            // else no offset
260
261 if(sO!=PreviousPSXDisplay.Range.y0)                   // something changed?
262  {
263   PreviousPSXDisplay.Range.y0=sO;
264   bDisplayNotSet=TRUE;                                // -> recalc display stuff
265  }
266 }
267
268 static void updateDisplayIfChanged(void)
269 {
270 BOOL bUp;
271
272 if ((PSXDisplay.DisplayMode.y == PSXDisplay.DisplayModeNew.y) && 
273     (PSXDisplay.DisplayMode.x == PSXDisplay.DisplayModeNew.x))
274  {
275   if((PSXDisplay.RGB24      == PSXDisplay.RGB24New) && 
276      (PSXDisplay.Interlaced == PSXDisplay.InterlacedNew)) 
277      return;                                          // nothing has changed? fine, no swap buffer needed
278  }
279 else                                                  // some res change?
280  {
281   glLoadIdentity(); glError();
282   glOrtho(0,PSXDisplay.DisplayModeNew.x,              // -> new psx resolution
283             PSXDisplay.DisplayModeNew.y, 0, -1, 1); glError();
284   if(bKeepRatio) SetAspectRatio();
285  }
286
287 bDisplayNotSet = TRUE;                                // re-calc offsets/display area
288
289 bUp=FALSE;
290 if(PSXDisplay.RGB24!=PSXDisplay.RGB24New)             // clean up textures, if rgb mode change (usually mdec on/off)
291  {
292   PreviousPSXDisplay.RGB24=0;                         // no full 24 frame uploaded yet
293   ResetTextureArea(FALSE);
294   bUp=TRUE;
295  }
296
297 PSXDisplay.RGB24         = PSXDisplay.RGB24New;       // get new infos
298 PSXDisplay.DisplayMode.y = PSXDisplay.DisplayModeNew.y;
299 PSXDisplay.DisplayMode.x = PSXDisplay.DisplayModeNew.x;
300 PSXDisplay.Interlaced    = PSXDisplay.InterlacedNew;
301
302 PSXDisplay.DisplayEnd.x=                              // calc new ends
303  PSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;
304 PSXDisplay.DisplayEnd.y=
305  PSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;
306 PreviousPSXDisplay.DisplayEnd.x=
307  PreviousPSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;
308 PreviousPSXDisplay.DisplayEnd.y=
309  PreviousPSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;
310
311 ChangeDispOffsetsX();
312 if(bUp) updateDisplay();                              // yeah, real update (swap buffer)
313 }
314
315 #define GPUwriteStatus_ext GPUwriteStatus_ext // for gpulib to see this
316 void GPUwriteStatus_ext(unsigned int gdata)
317 {
318 switch((gdata>>24)&0xff)
319  {
320   case 0x00:
321    PSXDisplay.Disabled=1;
322    PSXDisplay.DrawOffset.x=PSXDisplay.DrawOffset.y=0;
323    drawX=drawY=0;drawW=drawH=0;
324    sSetMask=0;lSetMask=0;bCheckMask=FALSE;iSetMask=0;
325    usMirror=0;
326    GlobalTextAddrX=0;GlobalTextAddrY=0;
327    GlobalTextTP=0;GlobalTextABR=0;
328    PSXDisplay.RGB24=FALSE;
329    PSXDisplay.Interlaced=FALSE;
330    bUsingTWin = FALSE;
331    return;
332
333   case 0x03:  
334    PreviousPSXDisplay.Disabled = PSXDisplay.Disabled;
335    PSXDisplay.Disabled = (gdata & 1);
336
337    if (iOffscreenDrawing==4 &&
338         PreviousPSXDisplay.Disabled && 
339        !(PSXDisplay.Disabled))
340     {
341
342      if(!PSXDisplay.RGB24)
343       {
344        PrepareFullScreenUpload(TRUE);
345        UploadScreen(TRUE); 
346        updateDisplay();
347       }
348     }
349    return;
350
351   case 0x05: 
352    {
353     short sx=(short)(gdata & 0x3ff);
354     short sy;
355
356     sy = (short)((gdata>>10)&0x3ff);             // really: 0x1ff, but we adjust it later
357     if (sy & 0x200) 
358      {
359       sy|=0xfc00;
360       PreviousPSXDisplay.DisplayModeNew.y=sy/PSXDisplay.Double;
361       sy=0;
362      }
363     else PreviousPSXDisplay.DisplayModeNew.y=0;
364
365     if(sx>1000) sx=0;
366
367     if(dwActFixes&8) 
368      {
369       if((!PSXDisplay.Interlaced) &&
370          PreviousPSXDisplay.DisplayPosition.x == sx  &&
371          PreviousPSXDisplay.DisplayPosition.y == sy)
372        return;
373
374       PSXDisplay.DisplayPosition.x = PreviousPSXDisplay.DisplayPosition.x;
375       PSXDisplay.DisplayPosition.y = PreviousPSXDisplay.DisplayPosition.y;
376       PreviousPSXDisplay.DisplayPosition.x = sx;
377       PreviousPSXDisplay.DisplayPosition.y = sy;
378      }
379     else
380      {
381       if((!PSXDisplay.Interlaced) &&
382          PSXDisplay.DisplayPosition.x == sx  &&
383          PSXDisplay.DisplayPosition.y == sy)
384        return;
385       PreviousPSXDisplay.DisplayPosition.x = PSXDisplay.DisplayPosition.x;
386       PreviousPSXDisplay.DisplayPosition.y = PSXDisplay.DisplayPosition.y;
387       PSXDisplay.DisplayPosition.x = sx;
388       PSXDisplay.DisplayPosition.y = sy;
389      }
390
391     PSXDisplay.DisplayEnd.x=
392      PSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;
393     PSXDisplay.DisplayEnd.y=
394      PSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;
395
396     PreviousPSXDisplay.DisplayEnd.x=
397      PreviousPSXDisplay.DisplayPosition.x+ PSXDisplay.DisplayMode.x;
398     PreviousPSXDisplay.DisplayEnd.y=
399      PreviousPSXDisplay.DisplayPosition.y+ PSXDisplay.DisplayMode.y+PreviousPSXDisplay.DisplayModeNew.y;
400
401     bDisplayNotSet = TRUE;
402
403     if (!(PSXDisplay.Interlaced))
404      {
405       updateDisplay();
406      }
407     else
408     if(PSXDisplay.InterlacedTest && 
409        ((PreviousPSXDisplay.DisplayPosition.x != PSXDisplay.DisplayPosition.x)||
410         (PreviousPSXDisplay.DisplayPosition.y != PSXDisplay.DisplayPosition.y)))
411      PSXDisplay.InterlacedTest--;
412     return;
413    }
414
415   case 0x06:
416    PSXDisplay.Range.x0=gdata & 0x7ff;      //0x3ff;
417    PSXDisplay.Range.x1=(gdata>>12) & 0xfff;//0x7ff;
418
419    PSXDisplay.Range.x1-=PSXDisplay.Range.x0;
420
421    ChangeDispOffsetsX();
422    return;
423
424   case 0x07:
425    PreviousPSXDisplay.Height = PSXDisplay.Height;
426
427    PSXDisplay.Range.y0=gdata & 0x3ff;
428    PSXDisplay.Range.y1=(gdata>>10) & 0x3ff;
429
430    PSXDisplay.Height = PSXDisplay.Range.y1 - 
431                        PSXDisplay.Range.y0 +
432                        PreviousPSXDisplay.DisplayModeNew.y;
433
434    if (PreviousPSXDisplay.Height != PSXDisplay.Height)
435     {
436      PSXDisplay.DisplayModeNew.y=PSXDisplay.Height*PSXDisplay.Double;
437      ChangeDispOffsetsY();
438      updateDisplayIfChanged();
439     }
440    return;
441
442   case 0x08:
443    PSXDisplay.DisplayModeNew.x = dispWidths[(gdata & 0x03) | ((gdata & 0x40) >> 4)];
444
445    if (gdata&0x04) PSXDisplay.Double=2;
446    else            PSXDisplay.Double=1;
447    PSXDisplay.DisplayModeNew.y = PSXDisplay.Height*PSXDisplay.Double;
448
449    ChangeDispOffsetsY();
450  
451    PSXDisplay.PAL           = (gdata & 0x08)?TRUE:FALSE; // if 1 - PAL mode, else NTSC
452    PSXDisplay.RGB24New      = (gdata & 0x10)?TRUE:FALSE; // if 1 - TrueColor
453    PSXDisplay.InterlacedNew = (gdata & 0x20)?TRUE:FALSE; // if 1 - Interlace
454
455    PreviousPSXDisplay.InterlacedNew=FALSE;
456    if (PSXDisplay.InterlacedNew)
457     {
458      if(!PSXDisplay.Interlaced)
459       {
460        PSXDisplay.InterlacedTest=2;
461        PreviousPSXDisplay.DisplayPosition.x = PSXDisplay.DisplayPosition.x;
462        PreviousPSXDisplay.DisplayPosition.y = PSXDisplay.DisplayPosition.y;
463        PreviousPSXDisplay.InterlacedNew=TRUE;
464       }
465     }
466    else 
467     {
468      PSXDisplay.InterlacedTest=0;
469     }
470    updateDisplayIfChanged();
471    return;
472  }
473 }
474
475 /////////////////////////////////////////////////////////////////////////////
476
477 #include <stdint.h>
478
479 #include "../gpulib/gpu.c"
480
481 static int is_opened;
482
483 static void set_vram(void *vram)
484 {
485  psxVub=vram;
486  psxVuw=(unsigned short *)psxVub;
487 }
488
489 int renderer_init(void)
490 {
491  set_vram(gpu.vram);
492
493  PSXDisplay.RGB24        = FALSE;                      // init some stuff
494  PSXDisplay.Interlaced   = FALSE;
495  PSXDisplay.DrawOffset.x = 0;
496  PSXDisplay.DrawOffset.y = 0;
497  PSXDisplay.DisplayMode.x= 320;
498  PSXDisplay.DisplayMode.y= 240;
499  PSXDisplay.Disabled     = FALSE;
500  PSXDisplay.Range.x0=0;
501  PSXDisplay.Range.x1=0;
502  PSXDisplay.Double = 1;
503
504  lGPUstatusRet = 0x14802000;
505
506  return 0;
507 }
508
509 void renderer_finish(void)
510 {
511 }
512
513 void renderer_notify_res_change(void)
514 {
515 }
516
517 void renderer_notify_scanout_change(int x, int y)
518 {
519 }
520
521 extern const unsigned char cmd_lengths[256];
522
523 // XXX: mostly dupe code from soft peops
524 int do_cmd_list(uint32_t *list, int list_len,
525  int *cycles_sum_out, int *cycles_last, int *last_cmd)
526 {
527   unsigned int cmd, len;
528   unsigned int *list_start = list;
529   unsigned int *list_end = list + list_len;
530
531   for (; list < list_end; list += 1 + len)
532   {
533     cmd = *list >> 24;
534     len = cmd_lengths[cmd];
535     if (list + 1 + len > list_end) {
536       cmd = -1;
537       break;
538     }
539
540 #ifndef TEST
541     if (cmd == 0xa0 || cmd == 0xc0)
542       break; // image i/o, forward to upper layer
543     else if ((cmd & 0xf8) == 0xe0)
544       gpu.ex_regs[cmd & 7] = list[0];
545 #endif
546
547     primTableJ[cmd]((void *)list);
548
549     switch(cmd)
550     {
551       case 0x48 ... 0x4F:
552       {
553         uint32_t num_vertexes = 2;
554         uint32_t *list_position = &(list[3]);
555
556         while(1)
557         {
558           if(list_position >= list_end) {
559             cmd = -1;
560             goto breakloop;
561           }
562
563           if((*list_position & 0xf000f000) == 0x50005000)
564             break;
565
566           list_position++;
567           num_vertexes++;
568         }
569
570         len += (num_vertexes - 2);
571         break;
572       }
573
574       case 0x58 ... 0x5F:
575       {
576         uint32_t num_vertexes = 2;
577         uint32_t *list_position = &(list[4]);
578
579         while(1)
580         {
581           if(list_position >= list_end) {
582             cmd = -1;
583             goto breakloop;
584           }
585
586           if((*list_position & 0xf000f000) == 0x50005000)
587             break;
588
589           list_position += 2;
590           num_vertexes++;
591         }
592
593         len += (num_vertexes - 2) * 2;
594         break;
595       }
596
597 #ifdef TEST
598       case 0xA0:          //  sys -> vid
599       {
600         short *slist = (void *)list;
601         uint32_t load_width = slist[4];
602         uint32_t load_height = slist[5];
603         uint32_t load_size = load_width * load_height;
604
605         len += load_size / 2;
606         break;
607       }
608 #endif
609     }
610   }
611
612 breakloop:
613   gpu.ex_regs[1] &= ~0x1ff;
614   gpu.ex_regs[1] |= lGPUstatusRet & 0x1ff;
615
616   *last_cmd = cmd;
617   return list - list_start;
618 }
619
620 void renderer_sync_ecmds(uint32_t *ecmds)
621 {
622   cmdTexturePage((unsigned char *)&ecmds[1]);
623   cmdTextureWindow((unsigned char *)&ecmds[2]);
624   cmdDrawAreaStart((unsigned char *)&ecmds[3]);
625   cmdDrawAreaEnd((unsigned char *)&ecmds[4]);
626   cmdDrawOffset((unsigned char *)&ecmds[5]);
627   cmdSTP((unsigned char *)&ecmds[6]);
628 }
629
630 void renderer_update_caches(int x, int y, int w, int h, int state_changed)
631 {
632  VRAMWrite.x = x;
633  VRAMWrite.y = y;
634  VRAMWrite.Width = w;
635  VRAMWrite.Height = h;
636  if(is_opened)
637   CheckWriteUpdate();
638 }
639
640 void renderer_flush_queues(void)
641 {
642 }
643
644 void renderer_set_interlace(int enable, int is_odd)
645 {
646 }
647
648 int vout_init(void)
649 {
650   return 0;
651 }
652
653 int vout_finish(void)
654 {
655   return 0;
656 }
657
658 void vout_update(void)
659 {
660  if(PSXDisplay.Interlaced)                            // interlaced mode?
661  {
662   if(PSXDisplay.DisplayMode.x>0 && PSXDisplay.DisplayMode.y>0)
663    {
664     updateDisplay();                                  // -> swap buffers (new frame)
665    }
666  }
667  else if(bRenderFrontBuffer)                          // no interlace mode? and some stuff in front has changed?
668  {
669   updateFrontDisplay();                               // -> update front buffer
670  }
671 }
672
673 void vout_blank(void)
674 {
675 }
676
677 void vout_set_config(const struct rearmed_cbs *cbs)
678 {
679 }
680
681 static struct rearmed_cbs *cbs;
682
683 long GPUopen(unsigned long *disp, char *cap, char *cfg)
684 {
685  int ret;
686
687  iResX = cbs->screen_w;
688  iResY = cbs->screen_h;
689  rRatioRect.left   = rRatioRect.top=0;
690  rRatioRect.right  = iResX;
691  rRatioRect.bottom = iResY;
692
693  bDisplayNotSet = TRUE; 
694  bSetClip = TRUE;
695  CSTEXTURE = CSVERTEX = CSCOLOR = 0;
696
697  InitializeTextureStore();                             // init texture mem
698
699  ret = GLinitialize(cbs->gles_display, cbs->gles_surface);
700  MakeDisplayLists();
701
702  is_opened = 1;
703  return ret;
704 }
705
706 long GPUclose(void)
707 {
708  is_opened = 0;
709
710  KillDisplayLists();
711  GLcleanup();                                          // close OGL
712  return 0;
713 }
714
715 /* acting as both renderer and vout handler here .. */
716 void renderer_set_config(const struct rearmed_cbs *cbs_)
717 {
718  cbs = (void *)cbs_; // ugh..
719
720  iOffscreenDrawing = 0;
721  iZBufferDepth = 0;
722  iFrameReadType = 0;
723  bKeepRatio = TRUE;
724
725  dwActFixes = cbs->gpu_peopsgl.dwActFixes;
726  bDrawDither = cbs->gpu_peopsgl.bDrawDither;
727  iFilterType = cbs->gpu_peopsgl.iFilterType;
728  iFrameTexType = cbs->gpu_peopsgl.iFrameTexType;
729  iUseMask = cbs->gpu_peopsgl.iUseMask;
730  bOpaquePass = cbs->gpu_peopsgl.bOpaquePass;
731  bAdvancedBlend = cbs->gpu_peopsgl.bAdvancedBlend;
732  bUseFastMdec = cbs->gpu_peopsgl.bUseFastMdec;
733  iTexGarbageCollection = cbs->gpu_peopsgl.iTexGarbageCollection;
734  iVRamSize = cbs->gpu_peopsgl.iVRamSize;
735
736  if (cbs->pl_set_gpu_caps)
737   cbs->pl_set_gpu_caps(GPU_CAP_OWNS_DISPLAY);
738
739  if (is_opened && cbs->gles_display != NULL && cbs->gles_surface != NULL) {
740   // HACK..
741   GPUclose();
742   GPUopen(NULL, NULL, NULL);
743  }
744
745  set_vram(gpu.vram);
746 }
747
748 void SetAspectRatio(void)
749 {
750  if (cbs->pl_get_layer_pos)
751   cbs->pl_get_layer_pos(&rRatioRect.left, &rRatioRect.top, &rRatioRect.right, &rRatioRect.bottom);
752
753  glScissor(rRatioRect.left,
754            iResY-(rRatioRect.top+rRatioRect.bottom),
755            rRatioRect.right,rRatioRect.bottom);
756  glViewport(rRatioRect.left,
757            iResY-(rRatioRect.top+rRatioRect.bottom),
758            rRatioRect.right,rRatioRect.bottom);
759  glError();
760 }
761
762 static void fps_update(void)
763 {
764  char buf[16];
765
766  cbs->flip_cnt++;
767  if(cbs->flips_per_sec != 0)
768  {
769   snprintf(buf,sizeof(buf),"%2d %4.1f",cbs->flips_per_sec,cbs->vsps_cur);
770   DisplayText(buf, 0);
771  }
772  if(cbs->cpu_usage != 0)
773  {
774   snprintf(buf,sizeof(buf),"%3d",cbs->cpu_usage);
775   DisplayText(buf, 1);
776  }
777 }