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