7890a708 |
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 | |
5fa6cb17 |
19 | #include "gpuStdafx.h" |
7890a708 |
20 | #include "gpuDraw.c" |
21 | #include "gpuTexture.c" |
22 | #include "gpuPrim.c" |
0cc470cd |
23 | #include "hud.c" |
7890a708 |
24 | |
c9b09029 |
25 | static int is_opened; |
26 | |
7890a708 |
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 |
5fa6cb17 |
32 | int GlobalTextAddrX,GlobalTextAddrY,GlobalTextTP; |
33 | int GlobalTextREST,GlobalTextABR,GlobalTextPAGE; |
7890a708 |
34 | |
5fa6cb17 |
35 | unsigned int dwGPUVersion; |
7890a708 |
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; |
5fa6cb17 |
47 | int lGPUstatusRet; |
48 | unsigned int ulGPUInfoVals[16]; |
7890a708 |
49 | VRAMLoad_t VRAMWrite; |
50 | VRAMLoad_t VRAMRead; |
51 | int iDataWriteMode; |
52 | int iDataReadMode; |
53 | |
5fa6cb17 |
54 | int lClearOnSwap; |
55 | int lClearOnSwapColor; |
7890a708 |
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 | |
0cc470cd |
91 | static void fps_update(void); |
92 | |
7890a708 |
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) |
0cc470cd |
129 | { |
130 | fps_update(); |
7890a708 |
131 | eglSwapBuffers(display, surface); |
0cc470cd |
132 | iDrawnSomething=0; |
133 | } |
7890a708 |
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 | { |
5fa6cb17 |
201 | int lx,l;short sO; |
7890a708 |
202 | |
203 | if(!PSXDisplay.Range.x1) return; // some range given? |
204 | |
205 | l=PSXDisplay.DisplayMode.x; |
206 | |
5fa6cb17 |
207 | l*=(int)PSXDisplay.Range.x1; // some funky calculation |
7890a708 |
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 |
5fa6cb17 |
318 | void GPUwriteStatus_ext(unsigned int gdata) |
7890a708 |
319 | { |
c9b09029 |
320 | if (!is_opened) |
321 | return; |
322 | |
7890a708 |
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 | |
9ee0fd5b |
486 | static void set_vram(void *vram) |
7890a708 |
487 | { |
9ee0fd5b |
488 | psxVub=vram; |
7890a708 |
489 | psxVuw=(unsigned short *)psxVub; |
9ee0fd5b |
490 | } |
491 | |
492 | int renderer_init(void) |
493 | { |
494 | set_vram(gpu.vram); |
7890a708 |
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 | |
c9b09029 |
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 | |
e929dec5 |
540 | void renderer_finish(void) |
541 | { |
542 | } |
543 | |
544 | void renderer_notify_res_change(void) |
545 | { |
546 | } |
547 | |
2da2fc76 |
548 | void renderer_notify_scanout_change(int x, int y) |
0b4038f8 |
549 | { |
550 | } |
551 | |
7890a708 |
552 | extern const unsigned char cmd_lengths[256]; |
553 | |
b243416b |
554 | // XXX: mostly dupe code from soft peops |
8412166f |
555 | int do_cmd_list(uint32_t *list, int list_len, |
556 | int *cycles_sum_out, int *cycles_last, int *last_cmd) |
7890a708 |
557 | { |
558 | unsigned int cmd, len; |
b243416b |
559 | unsigned int *list_start = list; |
7890a708 |
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]; |
b243416b |
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 |
7890a708 |
577 | |
578 | primTableJ[cmd]((void *)list); |
579 | |
580 | switch(cmd) |
581 | { |
582 | case 0x48 ... 0x4F: |
583 | { |
b243416b |
584 | uint32_t num_vertexes = 2; |
585 | uint32_t *list_position = &(list[3]); |
7890a708 |
586 | |
587 | while(1) |
588 | { |
804789d7 |
589 | if(list_position >= list_end) { |
590 | cmd = -1; |
591 | goto breakloop; |
592 | } |
593 | |
594 | if((*list_position & 0xf000f000) == 0x50005000) |
7890a708 |
595 | break; |
596 | |
597 | list_position++; |
598 | num_vertexes++; |
599 | } |
600 | |
b243416b |
601 | len += (num_vertexes - 2); |
7890a708 |
602 | break; |
603 | } |
604 | |
605 | case 0x58 ... 0x5F: |
606 | { |
b243416b |
607 | uint32_t num_vertexes = 2; |
608 | uint32_t *list_position = &(list[4]); |
7890a708 |
609 | |
610 | while(1) |
611 | { |
804789d7 |
612 | if(list_position >= list_end) { |
613 | cmd = -1; |
614 | goto breakloop; |
615 | } |
616 | |
617 | if((*list_position & 0xf000f000) == 0x50005000) |
7890a708 |
618 | break; |
619 | |
620 | list_position += 2; |
621 | num_vertexes++; |
622 | } |
623 | |
b243416b |
624 | len += (num_vertexes - 2) * 2; |
7890a708 |
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 | } |
b243416b |
642 | |
804789d7 |
643 | breakloop: |
b243416b |
644 | gpu.ex_regs[1] &= ~0x1ff; |
645 | gpu.ex_regs[1] |= lGPUstatusRet & 0x1ff; |
646 | |
647 | *last_cmd = cmd; |
648 | return list - list_start; |
7890a708 |
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 | |
0b4038f8 |
661 | void renderer_update_caches(int x, int y, int w, int h, int state_changed) |
7890a708 |
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 | |
f665bfda |
689 | int vout_update(void) |
7890a708 |
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) |
f665bfda |
696 | return 1; |
7890a708 |
697 | } |
698 | } |
699 | else if(bRenderFrontBuffer) // no interlace mode? and some stuff in front has changed? |
700 | { |
701 | updateFrontDisplay(); // -> update front buffer |
f665bfda |
702 | return 1; |
7890a708 |
703 | } |
f665bfda |
704 | return 0; |
7890a708 |
705 | } |
706 | |
4ea086f6 |
707 | void vout_blank(void) |
708 | { |
709 | } |
710 | |
711 | void vout_set_config(const struct rearmed_cbs *cbs) |
712 | { |
713 | } |
714 | |
bb88ec28 |
715 | static struct rearmed_cbs *cbs; |
716 | |
71e413be |
717 | long GPUopen(unsigned long *disp, char *cap, char *cfg) |
7890a708 |
718 | { |
0cc470cd |
719 | int ret; |
720 | |
c9b09029 |
721 | if (is_opened) { |
722 | fprintf(stderr, "double GPUopen\n"); |
723 | return -1; |
724 | } |
bb88ec28 |
725 | iResX = cbs->screen_w; |
726 | iResY = cbs->screen_h; |
7890a708 |
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 |
7890a708 |
736 | |
418caf43 |
737 | ret = GLinitialize(cbs->gles_display, cbs->gles_surface); |
0cc470cd |
738 | MakeDisplayLists(); |
739 | |
740 | is_opened = 1; |
741 | return ret; |
7890a708 |
742 | } |
743 | |
744 | long GPUclose(void) |
745 | { |
c9b09029 |
746 | if (!is_opened) |
747 | return 0; |
7890a708 |
748 | is_opened = 0; |
749 | |
0cc470cd |
750 | KillDisplayLists(); |
c9b09029 |
751 | clear_gl_state_for_menu(); |
7890a708 |
752 | GLcleanup(); // close OGL |
753 | return 0; |
754 | } |
755 | |
7890a708 |
756 | /* acting as both renderer and vout handler here .. */ |
757 | void renderer_set_config(const struct rearmed_cbs *cbs_) |
758 | { |
0cc470cd |
759 | cbs = (void *)cbs_; // ugh.. |
7890a708 |
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; |
418caf43 |
776 | |
fa56d360 |
777 | if (cbs->pl_set_gpu_caps) |
778 | cbs->pl_set_gpu_caps(GPU_CAP_OWNS_DISPLAY); |
9ee0fd5b |
779 | |
418caf43 |
780 | if (is_opened && cbs->gles_display != NULL && cbs->gles_surface != NULL) { |
c9b09029 |
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 | } |
418caf43 |
787 | } |
788 | |
9ee0fd5b |
789 | set_vram(gpu.vram); |
7890a708 |
790 | } |
791 | |
7890a708 |
792 | void SetAspectRatio(void) |
793 | { |
38c2028e |
794 | if (cbs->pl_get_layer_pos) |
795 | cbs->pl_get_layer_pos(&rRatioRect.left, &rRatioRect.top, &rRatioRect.right, &rRatioRect.bottom); |
7890a708 |
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 | } |
0cc470cd |
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 | } |
79c4d434 |
822 | |
823 | void renderer_sync(void) |
824 | { |
825 | } |
826 | |
827 | void renderer_notify_update_lace(int updated) |
828 | { |
829 | } |