Commit | Line | Data |
---|---|---|
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 | ||
c94fde37 | 19 | #include "gpuStdafx.h" |
7890a708 | 20 | #include "gpuDraw.c" |
21 | #include "gpuTexture.c" | |
22 | #include "gpuPrim.c" | |
0cc470cd | 23 | #include "hud.c" |
7890a708 | 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 | |
c94fde37 | 30 | int GlobalTextAddrX,GlobalTextAddrY,GlobalTextTP; |
31 | int GlobalTextREST,GlobalTextABR,GlobalTextPAGE; | |
7890a708 | 32 | |
c94fde37 | 33 | unsigned int dwGPUVersion; |
7890a708 | 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; | |
c94fde37 | 45 | int lGPUstatusRet; |
46 | unsigned int ulGPUInfoVals[16]; | |
7890a708 | 47 | VRAMLoad_t VRAMWrite; |
48 | VRAMLoad_t VRAMRead; | |
49 | int iDataWriteMode; | |
50 | int iDataReadMode; | |
51 | ||
c94fde37 | 52 | int lClearOnSwap; |
53 | int lClearOnSwapColor; | |
7890a708 | 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 | ||
0cc470cd | 89 | static void fps_update(void); |
90 | ||
7890a708 | 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) | |
0cc470cd | 127 | { |
128 | fps_update(); | |
7890a708 | 129 | eglSwapBuffers(display, surface); |
0cc470cd | 130 | iDrawnSomething=0; |
131 | } | |
7890a708 | 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 | { | |
c94fde37 | 199 | int lx,l;short sO; |
7890a708 | 200 | |
201 | if(!PSXDisplay.Range.x1) return; // some range given? | |
202 | ||
203 | l=PSXDisplay.DisplayMode.x; | |
204 | ||
c94fde37 | 205 | l*=(int)PSXDisplay.Range.x1; // some funky calculation |
7890a708 | 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 | |
c94fde37 | 316 | void GPUwriteStatus_ext(unsigned int gdata) |
7890a708 | 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 | ||
9ee0fd5b | 483 | static void set_vram(void *vram) |
7890a708 | 484 | { |
9ee0fd5b | 485 | psxVub=vram; |
7890a708 | 486 | psxVuw=(unsigned short *)psxVub; |
9ee0fd5b | 487 | } |
488 | ||
489 | int renderer_init(void) | |
490 | { | |
491 | set_vram(gpu.vram); | |
7890a708 | 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 | ||
e929dec5 | 509 | void renderer_finish(void) |
510 | { | |
511 | } | |
512 | ||
513 | void renderer_notify_res_change(void) | |
514 | { | |
515 | } | |
516 | ||
3b7b0065 | 517 | void renderer_notify_scanout_x_change(int x, int w) |
518 | { | |
519 | } | |
520 | ||
7890a708 | 521 | extern const unsigned char cmd_lengths[256]; |
522 | ||
b243416b | 523 | // XXX: mostly dupe code from soft peops |
524 | int do_cmd_list(unsigned int *list, int list_len, int *last_cmd) | |
7890a708 | 525 | { |
526 | unsigned int cmd, len; | |
b243416b | 527 | unsigned int *list_start = list; |
7890a708 | 528 | unsigned int *list_end = list + list_len; |
529 | ||
530 | for (; list < list_end; list += 1 + len) | |
531 | { | |
532 | cmd = *list >> 24; | |
533 | len = cmd_lengths[cmd]; | |
b243416b | 534 | if (list + 1 + len > list_end) { |
535 | cmd = -1; | |
536 | break; | |
537 | } | |
538 | ||
539 | #ifndef TEST | |
540 | if (cmd == 0xa0 || cmd == 0xc0) | |
541 | break; // image i/o, forward to upper layer | |
542 | else if ((cmd & 0xf8) == 0xe0) | |
543 | gpu.ex_regs[cmd & 7] = list[0]; | |
544 | #endif | |
7890a708 | 545 | |
546 | primTableJ[cmd]((void *)list); | |
547 | ||
548 | switch(cmd) | |
549 | { | |
550 | case 0x48 ... 0x4F: | |
551 | { | |
b243416b | 552 | uint32_t num_vertexes = 2; |
553 | uint32_t *list_position = &(list[3]); | |
7890a708 | 554 | |
555 | while(1) | |
556 | { | |
804789d7 | 557 | if(list_position >= list_end) { |
558 | cmd = -1; | |
559 | goto breakloop; | |
560 | } | |
561 | ||
562 | if((*list_position & 0xf000f000) == 0x50005000) | |
7890a708 | 563 | break; |
564 | ||
565 | list_position++; | |
566 | num_vertexes++; | |
567 | } | |
568 | ||
b243416b | 569 | len += (num_vertexes - 2); |
7890a708 | 570 | break; |
571 | } | |
572 | ||
573 | case 0x58 ... 0x5F: | |
574 | { | |
b243416b | 575 | uint32_t num_vertexes = 2; |
576 | uint32_t *list_position = &(list[4]); | |
7890a708 | 577 | |
578 | while(1) | |
579 | { | |
804789d7 | 580 | if(list_position >= list_end) { |
581 | cmd = -1; | |
582 | goto breakloop; | |
583 | } | |
584 | ||
585 | if((*list_position & 0xf000f000) == 0x50005000) | |
7890a708 | 586 | break; |
587 | ||
588 | list_position += 2; | |
589 | num_vertexes++; | |
590 | } | |
591 | ||
b243416b | 592 | len += (num_vertexes - 2) * 2; |
7890a708 | 593 | break; |
594 | } | |
595 | ||
596 | #ifdef TEST | |
597 | case 0xA0: // sys -> vid | |
598 | { | |
599 | short *slist = (void *)list; | |
600 | uint32_t load_width = slist[4]; | |
601 | uint32_t load_height = slist[5]; | |
602 | uint32_t load_size = load_width * load_height; | |
603 | ||
604 | len += load_size / 2; | |
605 | break; | |
606 | } | |
607 | #endif | |
608 | } | |
609 | } | |
b243416b | 610 | |
804789d7 | 611 | breakloop: |
b243416b | 612 | gpu.ex_regs[1] &= ~0x1ff; |
613 | gpu.ex_regs[1] |= lGPUstatusRet & 0x1ff; | |
614 | ||
615 | *last_cmd = cmd; | |
616 | return list - list_start; | |
7890a708 | 617 | } |
618 | ||
619 | void renderer_sync_ecmds(uint32_t *ecmds) | |
620 | { | |
621 | cmdTexturePage((unsigned char *)&ecmds[1]); | |
622 | cmdTextureWindow((unsigned char *)&ecmds[2]); | |
623 | cmdDrawAreaStart((unsigned char *)&ecmds[3]); | |
624 | cmdDrawAreaEnd((unsigned char *)&ecmds[4]); | |
625 | cmdDrawOffset((unsigned char *)&ecmds[5]); | |
626 | cmdSTP((unsigned char *)&ecmds[6]); | |
627 | } | |
628 | ||
3b7b0065 | 629 | void renderer_update_caches(int x, int y, int w, int h, int state_changed) |
7890a708 | 630 | { |
631 | VRAMWrite.x = x; | |
632 | VRAMWrite.y = y; | |
633 | VRAMWrite.Width = w; | |
634 | VRAMWrite.Height = h; | |
635 | if(is_opened) | |
636 | CheckWriteUpdate(); | |
637 | } | |
638 | ||
639 | void renderer_flush_queues(void) | |
640 | { | |
641 | } | |
642 | ||
643 | void renderer_set_interlace(int enable, int is_odd) | |
644 | { | |
645 | } | |
646 | ||
647 | int vout_init(void) | |
648 | { | |
649 | return 0; | |
650 | } | |
651 | ||
652 | int vout_finish(void) | |
653 | { | |
654 | return 0; | |
655 | } | |
656 | ||
657 | void vout_update(void) | |
658 | { | |
659 | if(PSXDisplay.Interlaced) // interlaced mode? | |
660 | { | |
661 | if(PSXDisplay.DisplayMode.x>0 && PSXDisplay.DisplayMode.y>0) | |
662 | { | |
663 | updateDisplay(); // -> swap buffers (new frame) | |
664 | } | |
665 | } | |
666 | else if(bRenderFrontBuffer) // no interlace mode? and some stuff in front has changed? | |
667 | { | |
668 | updateFrontDisplay(); // -> update front buffer | |
669 | } | |
670 | } | |
671 | ||
4ea086f6 | 672 | void vout_blank(void) |
673 | { | |
674 | } | |
675 | ||
676 | void vout_set_config(const struct rearmed_cbs *cbs) | |
677 | { | |
678 | } | |
679 | ||
bb88ec28 | 680 | static struct rearmed_cbs *cbs; |
681 | ||
7890a708 | 682 | long GPUopen(void **dpy) |
683 | { | |
0cc470cd | 684 | int ret; |
685 | ||
bb88ec28 | 686 | iResX = cbs->screen_w; |
687 | iResY = cbs->screen_h; | |
7890a708 | 688 | rRatioRect.left = rRatioRect.top=0; |
689 | rRatioRect.right = iResX; | |
690 | rRatioRect.bottom = iResY; | |
691 | ||
692 | bDisplayNotSet = TRUE; | |
693 | bSetClip = TRUE; | |
694 | CSTEXTURE = CSVERTEX = CSCOLOR = 0; | |
695 | ||
696 | InitializeTextureStore(); // init texture mem | |
7890a708 | 697 | |
418caf43 | 698 | ret = GLinitialize(cbs->gles_display, cbs->gles_surface); |
0cc470cd | 699 | MakeDisplayLists(); |
700 | ||
701 | is_opened = 1; | |
702 | return ret; | |
7890a708 | 703 | } |
704 | ||
705 | long GPUclose(void) | |
706 | { | |
707 | is_opened = 0; | |
708 | ||
0cc470cd | 709 | KillDisplayLists(); |
7890a708 | 710 | GLcleanup(); // close OGL |
711 | return 0; | |
712 | } | |
713 | ||
7890a708 | 714 | /* acting as both renderer and vout handler here .. */ |
715 | void renderer_set_config(const struct rearmed_cbs *cbs_) | |
716 | { | |
0cc470cd | 717 | cbs = (void *)cbs_; // ugh.. |
7890a708 | 718 | |
719 | iOffscreenDrawing = 0; | |
720 | iZBufferDepth = 0; | |
721 | iFrameReadType = 0; | |
722 | bKeepRatio = TRUE; | |
723 | ||
724 | dwActFixes = cbs->gpu_peopsgl.dwActFixes; | |
725 | bDrawDither = cbs->gpu_peopsgl.bDrawDither; | |
726 | iFilterType = cbs->gpu_peopsgl.iFilterType; | |
727 | iFrameTexType = cbs->gpu_peopsgl.iFrameTexType; | |
728 | iUseMask = cbs->gpu_peopsgl.iUseMask; | |
729 | bOpaquePass = cbs->gpu_peopsgl.bOpaquePass; | |
730 | bAdvancedBlend = cbs->gpu_peopsgl.bAdvancedBlend; | |
731 | bUseFastMdec = cbs->gpu_peopsgl.bUseFastMdec; | |
732 | iTexGarbageCollection = cbs->gpu_peopsgl.iTexGarbageCollection; | |
733 | iVRamSize = cbs->gpu_peopsgl.iVRamSize; | |
418caf43 | 734 | |
fa56d360 | 735 | if (cbs->pl_set_gpu_caps) |
736 | cbs->pl_set_gpu_caps(GPU_CAP_OWNS_DISPLAY); | |
9ee0fd5b | 737 | |
418caf43 | 738 | if (is_opened && cbs->gles_display != NULL && cbs->gles_surface != NULL) { |
739 | // HACK.. | |
740 | GPUclose(); | |
741 | GPUopen(NULL); | |
742 | } | |
743 | ||
9ee0fd5b | 744 | set_vram(gpu.vram); |
7890a708 | 745 | } |
746 | ||
7890a708 | 747 | void SetAspectRatio(void) |
748 | { | |
38c2028e | 749 | if (cbs->pl_get_layer_pos) |
750 | cbs->pl_get_layer_pos(&rRatioRect.left, &rRatioRect.top, &rRatioRect.right, &rRatioRect.bottom); | |
7890a708 | 751 | |
752 | glScissor(rRatioRect.left, | |
753 | iResY-(rRatioRect.top+rRatioRect.bottom), | |
754 | rRatioRect.right,rRatioRect.bottom); | |
755 | glViewport(rRatioRect.left, | |
756 | iResY-(rRatioRect.top+rRatioRect.bottom), | |
757 | rRatioRect.right,rRatioRect.bottom); | |
758 | glError(); | |
759 | } | |
0cc470cd | 760 | |
761 | static void fps_update(void) | |
762 | { | |
763 | char buf[16]; | |
764 | ||
765 | cbs->flip_cnt++; | |
766 | if(cbs->flips_per_sec != 0) | |
767 | { | |
768 | snprintf(buf,sizeof(buf),"%2d %4.1f",cbs->flips_per_sec,cbs->vsps_cur); | |
769 | DisplayText(buf, 0); | |
770 | } | |
771 | if(cbs->cpu_usage != 0) | |
772 | { | |
773 | snprintf(buf,sizeof(buf),"%3d",cbs->cpu_usage); | |
774 | DisplayText(buf, 1); | |
775 | } | |
776 | } | |
c765eb86 JW |
777 | |
778 | void renderer_sync(void) | |
779 | { | |
780 | } | |
781 | ||
782 | void renderer_notify_update_lace(int updated) | |
783 | { | |
784 | } |