1 /***************************************************************************
2 draw.c - description
3 -------------------
4 begin : Sun Mar 08 2009
5 copyright : (C) 1999-2009 by Pete Bernert
6 web : www.pbernert.com
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. See also the license.txt file for *
15 * additional informations. *
16 * *
17 ***************************************************************************/
18
19 //*************************************************************************//
20 // History of changes:
21 //
22 // 2009/03/08 - Pete
23 // - generic cleanup for the Peops release
24 //
25 //*************************************************************************//
26
27
28 #define _IN_DRAW
29
30
31 #include "gpuExternals.h"
32 #include "gpuPlugin.h"
33 #include "gpuDraw.h"
34 #include "gpuPrim.h"
35 #include "gpuTexture.h"
36 #include "gpuStdafx.h"
37
38 #include <stdio.h>
39 #include <stdlib.h>
40 #include <math.h>
41 //#include "menu.h"
42
43 ////////////////////////////////////////////////////////////////////////////////////
44 // defines
45
46 #define SIGNBIT 0x800
47 #define S_MASK 0xf000
48 #define L_MASK 0xfffff000
49
50 // ownscale: some ogl drivers have buggy texture matrix funcs, so it
51 // is safer to calc sow/tow ourselves
52
53 #ifdef OWNSCALE
54
55 ///////////////////////////////////////////////////////////////
56
57 #define ST_FACSPRITE 255.99f
58 #define ST_BFFACSPRITE 0.5f/256.0f
59 #define ST_BFFACSPRITESORT 0.333f/256.0f
60
61 #define ST_OFFSET 0.5f/256.0f;
62
63 #define ST_FAC 255.99f
64 #define ST_BFFAC 0.5f/256.0f
65 #define ST_BFFACSORT 0.333f/256.0f
66
67 #define ST_FACTRI 255.99f
68 #define ST_BFFACTRI 0.5f/256.0f
69 #define ST_BFFACTRISORT 0.333f/256.0f
70
71 #define ST_FACVRAMX 255.0f
72 #define ST_FACVRAM 256.0f
73
74 ///////////////////////////////////////////////////////////////
75
76 #else
77
78 #define ST_BFFACSPRITE 0.5f
79 #define ST_BFFACSPRITESORT 0.333f
80
81 #define ST_BFFAC 0.5f
82 #define ST_BFFACSORT 0.333f
83
84 #define ST_BFFACTRI 0.5f
85 #define ST_BFFACTRISORT 0.333f
86
87 #define ST_OFFSET 0.5f;
88
89 #endif
90
91 ////////////////////////////////////////////////////////////////////////////////////
92 // draw globals
93
94 void glBlendEquationEXT(GLenum mode);
95 void glColorTableEXT(GLenum target, GLenum internalFormat, GLsizei width, GLenum format,GLenum type, const GLvoid *data);
96
97 // draw globals; most will be initialized again later (by config or checks)
98
99 BOOL bIsFirstFrame=TRUE;
100
101 // resolution/ratio vars
102
103 int iResX;
104 int iResY;
105 BOOL bKeepRatio=FALSE;
106 RECT rRatioRect;
107
108 // psx mask related vars
109
110 BOOL bCheckMask=FALSE;
111 int iUseMask=0;
112 int iSetMask=0;
113 unsigned short sSetMask=0;
114 unsigned long lSetMask=0;
115
116 // drawing/coord vars
117
118 OGLVertex vertex[4];
119 GLubyte gl_ux[8];
120 GLubyte gl_vy[8];
121 short sprtY,sprtX,sprtH,sprtW;
122
123 // drawing options
124
125 BOOL bOpaquePass;
126 BOOL bAdvancedBlend;
127
128 // OGL extension support
129
130
131 // gfx card buffer infos
132
133 int iDepthFunc=0;
134 int iZBufferDepth=0;
135 GLbitfield uiBufferBits=GL_COLOR_BUFFER_BIT;
136
137 ////////////////////////////////////////////////////////////////////////
138 ////////////////////////////////////////////////////////////////////////
139 ////////////////////////////////////////////////////////////////////////
140
141 ////////////////////////////////////////////////////////////////////////
142 // Set OGL pixel format
143 ////////////////////////////////////////////////////////////////////////
144
145
146 ////////////////////////////////////////////////////////////////////////
147 // Get extension infos (f.e. pal textures / packed pixels)
148 ////////////////////////////////////////////////////////////////////////
149
GetExtInfos(void)150 void GetExtInfos(void)
151 {
152 BOOL bPacked=FALSE; // default: no packed pixel support
153
154 if(strstr((char *)glGetString(GL_EXTENSIONS), // packed pixels available?
155 "GL_EXT_packed_pixels"))
156 bPacked=TRUE; // -> ok
157
158
159 iClampType=GL_CLAMP_TO_EDGE;
160 }
161
162 ////////////////////////////////////////////////////////////////////////
163 // Setup some stuff depending on user settings or in-game toggle
164 ////////////////////////////////////////////////////////////////////////
165
SetExtGLFuncs(void)166 void SetExtGLFuncs(void)
167 {
168 //----------------------------------------------------//
169
170 SetFixes(); // update fix infos
171
172 //----------------------------------------------------//
173
174 {
175 if(bAdvancedBlend) bUseMultiPass=TRUE; // -> pseudo-advanced with 2 passes
176 else bUseMultiPass=FALSE; // -> or simple 'bright color' mode
177 // bGLBlend=FALSE; // -> no ext blending!
178 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); glError();
179 }
180
181 if(bOpaquePass) // opaque mode?
182 {
183 if(dwActFixes&32)
184 {
185 TCF[0]=CP8RGBA_0;
186 PalTexturedColourFn=CP8RGBA; // -> init col func
187 }
188 else
189 {
190 TCF[0]=XP8RGBA_0;
191 PalTexturedColourFn=XP8RGBA; // -> init col func
192 }
193
194 TCF[1]=XP8RGBA_1;
195 glAlphaFuncx(GL_GREATER,0.49f); glError();
196
197 }
198 else // no opaque mode?
199 {
200 TCF[0]=TCF[1]=P8RGBA;
201 PalTexturedColourFn=P8RGBA; // -> init col func
202 glAlphaFuncx(GL_NOTEQUAL,0); glError(); // --> set alpha func
203
204 }
205
206 //----------------------------------------------------//
207
208 LoadSubTexFn=LoadSubTexturePageSort; // init load tex ptr
209
210 bBlendEnable=FALSE; // init blending: off
211 glDisable(GL_BLEND); glError();
212
213
214 SetScanTrans(); // init scan lines (if wanted)
215 }
216
217 ////////////////////////////////////////////////////////////////////////
218 // setup scan lines
219 ////////////////////////////////////////////////////////////////////////
220
221 #define R_TSP 0x00,0x45,0x00,0xff
222 #define G_TSP 0x00,0x00,0x45,0xff
223 #define B_TSP 0x45,0x00,0x00,0xff
224 #define O_TSP 0x45,0x45,0x45,0xff
225 #define N_TSP 0x00,0x00,0x00,0xff
226
227 GLuint gTexScanName=0;
228
229 GLubyte texscan[4][16]=
230 {
231 {R_TSP, G_TSP, B_TSP, N_TSP},
232 {O_TSP, N_TSP, O_TSP, N_TSP},
233 {B_TSP, N_TSP, R_TSP, G_TSP},
234 {O_TSP, N_TSP, O_TSP, N_TSP}
235 };
236
CreateScanLines(void)237 void CreateScanLines(void)
238 {
239 }
240
241 ////////////////////////////////////////////////////////////////////////
242 // Initialize OGL
243 ////////////////////////////////////////////////////////////////////////
244
245 #define MODE_RAW 0
246 #define MODE_X11 1
247 #define MODE_SDL 2
248 int use_fsaa = 0;
249
250 EGLDisplay display;
251 EGLSurface surface;
252 static EGLConfig config;
253 static EGLContext context;
254
255 #if defined(USE_X11)
256 #include "X11/Xlib.h"
257 #include "X11/Xutil.h"
258 #include "X11/Xatom.h"
259
260 Window x11Window = 0;
261 Display* x11Display = 0;
262 long x11Screen = 0;
263 XVisualInfo x11Visual;
264 XVisualInfo* px11Visual = 0;
265 Colormap x11Colormap = 0;
266 #endif
267
268 EGLint attrib_list_fsaa[] =
269 {
270 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
271 EGL_BUFFER_SIZE, 0,
272 EGL_DEPTH_SIZE, 16,
273 EGL_SAMPLE_BUFFERS, 1,
274 EGL_SAMPLES, 4,
275 EGL_NONE
276 };
277
278 EGLint attrib_list[] =
279 {
280 // EGL_DEPTH_SIZE, 16,
281 EGL_NONE
282 };
283
TestEGLError(const char * pszLocation)284 bool TestEGLError(const char* pszLocation)
285 {
286 /*
287 eglGetError returns the last error that has happened using egl,
288 not the status of the last called function. The user has to
289 check after every single egl call or at least once every frame.
290 */
291 EGLint iErr = eglGetError();
292 if (iErr != EGL_SUCCESS)
293 {
294 printf("%s failed (0x%x).\n", pszLocation, iErr);
295 return FALSE;
296 }
297
298 return TRUE;
299 }
300
initEGL(void)301 static int initEGL(void)
302 {
303 NativeWindowType window = 0;
304
305 printf ("GL init\n");
306
307 EGLint numConfigs;
308 EGLint majorVersion;
309 EGLint minorVersion;
310 #if defined(USE_X11)
311 enum
312 {
313 _NET_WM_STATE_REMOVE =0,
314 _NET_WM_STATE_ADD = 1,
315 _NET_WM_STATE_TOGGLE =2
316 };
317
318 Window sRootWindow;
319 XSetWindowAttributes sWA;
320 unsigned int ui32Mask;
321 int i32Depth;
322 #endif
323
324 EGLint *attribList = NULL;
325 if (use_fsaa)
326 {
327 printf( "GLES: Using Full Scene Antialiasing\n" );
328 attribList = attrib_list_fsaa;
329 }
330 else
331 {
332 attribList = attrib_list;
333 }
334
335 #if defined(USE_X11)
336 // Initializes the display and screen
337 x11Display = XOpenDisplay( ":0" );
338 if (!x11Display)
339 {
340 printf("GLES Error: Unable to open X display\n");
341 return -1;
342 }
343 x11Screen = XDefaultScreen( x11Display );
344
345 // Gets the display parameters so we can pass the same parameters to the window to be created.
346 sRootWindow = RootWindow(x11Display, x11Screen);
347 i32Depth = DefaultDepth(x11Display, x11Screen);
348 px11Visual = &x11Visual;
349 XMatchVisualInfo( x11Display, x11Screen, i32Depth, TrueColor, px11Visual);
350 if (!px11Visual)
351 {
352 printf("GLES Error: Unable to acquire visual\n");
353 return -1;
354 }
355 // Colormap of the specified visual type for the display.
356 x11Colormap = XCreateColormap( x11Display, sRootWindow, px11Visual->visual, AllocNone );
357 sWA.colormap = x11Colormap;
358
359 // List of events to be handled by the application. Add to these for handling other events.
360 sWA.event_mask = StructureNotifyMask | ExposureMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask | KeyReleaseMask;
361
362 // Display capabilities list.
363 ui32Mask = CWBackPixel | CWBorderPixel | CWEventMask | CWColormap;
364
365 // Creates the X11 window
366 x11Window = XCreateWindow( x11Display, RootWindow(x11Display, x11Screen), 0, 0, iResX, iResY,
367 0, CopyFromParent, InputOutput, CopyFromParent, ui32Mask, &sWA);
368
369 // Make the window viewable and flush the output buffer.
370 XMapWindow(x11Display, x11Window);
371 XFlush(x11Display);
372
373 // Make the window fullscreen
374 unsigned char fullScreen = 1;
375 Atom wmState = XInternAtom(x11Display, "_NET_WM_STATE", False);
376 Atom wmFullScreen = XInternAtom(x11Display,"_NET_WM_STATE_FULLSCREEN", False);
377
378 XEvent xev;
379 xev.xclient.type = ClientMessage;
380 xev.xclient.serial = 0;
381 xev.xclient.send_event = True;
382 xev.xclient.window = x11Window;
383 xev.xclient.message_type = wmState;
384 xev.xclient.format = 32;
385 xev.xclient.data.l[0] = (fullScreen ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE);
386 xev.xclient.data.l[1] = wmFullScreen;
387 xev.xclient.data.l[2] = 0;
388
389 XSendEvent(x11Display, DefaultRootWindow(x11Display), False, SubstructureRedirectMask | SubstructureNotifyMask, &xev);
390
391 display = eglGetDisplay( (EGLNativeDisplayType)x11Display );
392 window = x11Window;
393 #else
394 display = eglGetDisplay( (EGLNativeDisplayType)0 );
395 #endif
396
397 if( display == EGL_NO_DISPLAY )
398 {
399 printf( "GLES EGL Error: GL No Display\n" );
400 return -1;
401 }
402
403 if( !eglInitialize( display, &majorVersion, &minorVersion ) )
404 {
405 printf( "GLES EGL Error: eglInitialize failed\n" );
406 return -1;
407 }
408
409 if( !eglChooseConfig( display, attribList, &config, 1, &numConfigs ) )
410 {
411 printf( "GLES EGL Error: eglChooseConfig failed\n" );
412 return -1;
413 }
414
415 context = eglCreateContext( display, config, NULL, NULL );
416 if( context==0 )
417 {
418 printf( "GLES EGL Error: eglCreateContext failed\n" );
419 return -1;
420 }
421
422 #ifdef FAKE_WINDOW
423 // broken Caanoo libs won't accept NULL window
424 window = (NativeWindowType)1;
425 #endif
426 surface = eglCreateWindowSurface( display, config, window, NULL );
427 if (!TestEGLError("eglCreateWindowSurface"))
428 return -1;
429
430 eglMakeCurrent( display, surface, surface, context );
431 if (!TestEGLError("eglMakeCurrent"))
432 return -1;
433
434 printf("GLES init ok\n");
435 return 0;
436 }
437
438 static int created_gles_context;
439
GLinitialize(void * ext_gles_display,void * ext_gles_surface)440 int GLinitialize(void *ext_gles_display, void *ext_gles_surface)
441 {
442 if(ext_gles_display != NULL && ext_gles_surface != NULL) {
443 display = (EGLDisplay)ext_gles_display;
444 surface = (EGLSurface)ext_gles_surface;
445 }
446 else {
447 if(initEGL()!=0)
448 return -1;
449 created_gles_context=1;
450 }
451
452 //----------------------------------------------------//
453
454 glDepthRangef(0.0f, 1.0f);glError();
455
456 glViewport(rRatioRect.left, // init viewport by ratio rect
457 iResY-(rRatioRect.top+rRatioRect.bottom),
458 rRatioRect.right,
459 rRatioRect.bottom); glError();
460
461 glScissor(0, 0, iResX, iResY); glError(); // init clipping (fullscreen)
462 glEnable(GL_SCISSOR_TEST); glError();
463
464 #ifndef OWNSCALE
465 glMatrixMode(GL_TEXTURE); // init psx tex sow and tow if not "ownscale"
466 glLoadIdentity();
467 glScalef(1.0f/255.99f,1.0f/255.99f,1.0f); // geforce precision hack
468 #endif
469
470 //glPolygonOffset( -0.2f, -0.2f );glError();
471
472 glMatrixMode(GL_PROJECTION); glError(); // init projection with psx resolution
473 glLoadIdentity(); glError();
474
475 glOrtho(0,PSXDisplay.DisplayMode.x,
476 PSXDisplay.DisplayMode.y, 0, -1, 1); glError();
477
478 if(iZBufferDepth) // zbuffer?
479 {
480 uiBufferBits=GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT;
481 glEnable(GL_DEPTH_TEST); glError();
482 glDepthFunc(GL_ALWAYS); glError();
483 iDepthFunc=1;
484 }
485 else // no zbuffer?
486 {
487 uiBufferBits=GL_COLOR_BUFFER_BIT;
488 glDisable(GL_DEPTH_TEST); glError();
489 }
490
491 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glError(); // first buffer clear
492 glClear(uiBufferBits); glError();
493
494 GetExtInfos(); // get ext infos
495 SetExtGLFuncs(); // init all kind of stuff (tex function pointers)
496
497 glEnable(GL_ALPHA_TEST); glError(); // wanna alpha test
498
499 {
500 glDisable(GL_LINE_SMOOTH); glError();
501 glDisable(GL_POINT_SMOOTH); glError();
502 }
503
504 ubGloAlpha=127; // init some drawing vars
505 ubGloColAlpha=127;
506 TWin.UScaleFactor = 1;
507 TWin.VScaleFactor = 1;
508 bDrawMultiPass=FALSE;
509 bTexEnabled=FALSE;
510 bUsingTWin=FALSE;
511
512 if(bDrawDither) glEnable(GL_DITHER); // dither mode
513 else glDisable(GL_DITHER);
514 glError();
515 glDisable(GL_FOG); glError(); // turn all (currently) unused modes off
516 glDisable(GL_LIGHTING); glError();
517 glDisable(GL_STENCIL_TEST); glError();
518 glDisable(GL_TEXTURE_2D); glError();
519 glDisable(GL_CULL_FACE);
520
521 glFlush(); glError(); // we are done...
522 glFinish(); glError();
523
524 CreateScanLines(); // setup scanline stuff (if wanted)
525
526 CheckTextureMemory(); // check available tex memory
527
528 if(bKeepRatio) SetAspectRatio(); // set ratio
529
530
531 bIsFirstFrame = FALSE; // we have survived the first frame :)
532
533 return 0;
534 }
535
536 ////////////////////////////////////////////////////////////////////////
537 // clean up OGL stuff
538 ////////////////////////////////////////////////////////////////////////
539
GLcleanup()540 void GLcleanup()
541 {
542 CleanupTextureStore(); // bye textures
543
544 if(created_gles_context) {
545 eglMakeCurrent( display, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT );
546 eglDestroySurface( display, surface );
547 eglDestroyContext( display, context );
548 eglTerminate( display );
549
550 #if defined(USE_X11)
551 if (x11Window) XDestroyWindow(x11Display, x11Window);
552 if (x11Colormap) XFreeColormap( x11Display, x11Colormap );
553 if (x11Display) XCloseDisplay(x11Display);
554 #endif
555 created_gles_context=0;
556 }
557 }
558
559 ////////////////////////////////////////////////////////////////////////
560 ////////////////////////////////////////////////////////////////////////
561 ////////////////////////////////////////////////////////////////////////
562
563 ////////////////////////////////////////////////////////////////////////
564 ////////////////////////////////////////////////////////////////////////
565 ////////////////////////////////////////////////////////////////////////
566
567 ////////////////////////////////////////////////////////////////////////
568 // Offset stuff
569 ////////////////////////////////////////////////////////////////////////
570
571 // please note: it is hardly do-able in a hw/accel plugin to get the
572 // real psx polygon coord mapping right... the following
573 // works not to bad with many games, though
574
CheckCoord4()575 __inline BOOL CheckCoord4()
576 {
577 if(lx0<0)
578 {
579 if(((lx1-lx0)>CHKMAX_X) ||
580 ((lx2-lx0)>CHKMAX_X))
581 {
582 if(lx3<0)
583 {
584 if((lx1-lx3)>CHKMAX_X) return TRUE;
585 if((lx2-lx3)>CHKMAX_X) return TRUE;
586 }
587 }
588 }
589 if(lx1<0)
590 {
591 if((lx0-lx1)>CHKMAX_X) return TRUE;
592 if((lx2-lx1)>CHKMAX_X) return TRUE;
593 if((lx3-lx1)>CHKMAX_X) return TRUE;
594 }
595 if(lx2<0)
596 {
597 if((lx0-lx2)>CHKMAX_X) return TRUE;
598 if((lx1-lx2)>CHKMAX_X) return TRUE;
599 if((lx3-lx2)>CHKMAX_X) return TRUE;
600 }
601 if(lx3<0)
602 {
603 if(((lx1-lx3)>CHKMAX_X) ||
604 ((lx2-lx3)>CHKMAX_X))
605 {
606 if(lx0<0)
607 {
608 if((lx1-lx0)>CHKMAX_X) return TRUE;
609 if((lx2-lx0)>CHKMAX_X) return TRUE;
610 }
611 }
612 }
613
614
615 if(ly0<0)
616 {
617 if((ly1-ly0)>CHKMAX_Y) return TRUE;
618 if((ly2-ly0)>CHKMAX_Y) return TRUE;
619 }
620 if(ly1<0)
621 {
622 if((ly0-ly1)>CHKMAX_Y) return TRUE;
623 if((ly2-ly1)>CHKMAX_Y) return TRUE;
624 if((ly3-ly1)>CHKMAX_Y) return TRUE;
625 }
626 if(ly2<0)
627 {
628 if((ly0-ly2)>CHKMAX_Y) return TRUE;
629 if((ly1-ly2)>CHKMAX_Y) return TRUE;
630 if((ly3-ly2)>CHKMAX_Y) return TRUE;
631 }
632 if(ly3<0)
633 {
634 if((ly1-ly3)>CHKMAX_Y) return TRUE;
635 if((ly2-ly3)>CHKMAX_Y) return TRUE;
636 }
637
638 return FALSE;
639 }
640
CheckCoord3()641 __inline BOOL CheckCoord3()
642 {
643 if(lx0<0)
644 {
645 if((lx1-lx0)>CHKMAX_X) return TRUE;
646 if((lx2-lx0)>CHKMAX_X) return TRUE;
647 }
648 if(lx1<0)
649 {
650 if((lx0-lx1)>CHKMAX_X) return TRUE;
651 if((lx2-lx1)>CHKMAX_X) return TRUE;
652 }
653 if(lx2<0)
654 {
655 if((lx0-lx2)>CHKMAX_X) return TRUE;
656 if((lx1-lx2)>CHKMAX_X) return TRUE;
657 }
658 if(ly0<0)
659 {
660 if((ly1-ly0)>CHKMAX_Y) return TRUE;
661 if((ly2-ly0)>CHKMAX_Y) return TRUE;
662 }
663 if(ly1<0)
664 {
665 if((ly0-ly1)>CHKMAX_Y) return TRUE;
666 if((ly2-ly1)>CHKMAX_Y) return TRUE;
667 }
668 if(ly2<0)
669 {
670 if((ly0-ly2)>CHKMAX_Y) return TRUE;
671 if((ly1-ly2)>CHKMAX_Y) return TRUE;
672 }
673
674 return FALSE;
675 }
676
677
CheckCoord2()678 __inline BOOL CheckCoord2()
679 {
680 if(lx0<0)
681 {
682 if((lx1-lx0)>CHKMAX_X) return TRUE;
683 }
684 if(lx1<0)
685 {
686 if((lx0-lx1)>CHKMAX_X) return TRUE;
687 }
688 if(ly0<0)
689 {
690 if((ly1-ly0)>CHKMAX_Y) return TRUE;
691 }
692 if(ly1<0)
693 {
694 if((ly0-ly1)>CHKMAX_Y) return TRUE;
695 }
696
697 return FALSE;
698 }
699
700 // Pete's way: a very easy (and hopefully fast) approach for lines
701 // without sqrt... using a small float -> short cast trick :)
702
703 #define VERTEX_OFFX 0.2f
704 #define VERTEX_OFFY 0.2f
705
offsetline(void)706 BOOL offsetline(void)
707 {
708 short x0,x1,y0,y1,dx,dy;float px,py;
709
710 if(bDisplayNotSet)
711 SetOGLDisplaySettings(1);
712
713 if(!(dwActFixes&16))
714 {
715 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
716 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
717 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
718 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
719
720 if(CheckCoord2()) return TRUE;
721 }
722
723 x0 = (lx0 + PSXDisplay.CumulOffset.x)+1;
724 x1 = (lx1 + PSXDisplay.CumulOffset.x)+1;
725 y0 = (ly0 + PSXDisplay.CumulOffset.y)+1;
726 y1 = (ly1 + PSXDisplay.CumulOffset.y)+1;
727
728 dx=x1-x0;
729 dy=y1-y0;
730
731 if(dx>=0)
732 {
733 if(dy>=0)
734 {
735 px=0.5f;
736 if(dx>dy) py=-0.5f;
737 else if(dx<dy) py= 0.5f;
738 else py= 0.0f;
739 }
740 else
741 {
742 py=-0.5f;
743 dy=-dy;
744 if(dx>dy) px= 0.5f;
745 else if(dx<dy) px=-0.5f;
746 else px= 0.0f;
747 }
748 }
749 else
750 {
751 if(dy>=0)
752 {
753 py=0.5f;
754 dx=-dx;
755 if(dx>dy) px=-0.5f;
756 else if(dx<dy) px= 0.5f;
757 else px= 0.0f;
758 }
759 else
760 {
761 px=-0.5f;
762 if(dx>dy) py=-0.5f;
763 else if(dx<dy) py= 0.5f;
764 else py= 0.0f;
765 }
766 }
767
768 vertex[0].x=(short)((float)x0-px);
769 vertex[3].x=(short)((float)x0+py);
770
771 vertex[0].y=(short)((float)y0-py);
772 vertex[3].y=(short)((float)y0-px);
773
774 vertex[1].x=(short)((float)x1-py);
775 vertex[2].x=(short)((float)x1+px);
776
777 vertex[1].y=(short)((float)y1+px);
778 vertex[2].y=(short)((float)y1+py);
779
780 if(vertex[0].x==vertex[3].x && // ortho rect? done
781 vertex[1].x==vertex[2].x &&
782 vertex[0].y==vertex[1].y &&
783 vertex[2].y==vertex[3].y) return FALSE;
784 if(vertex[0].x==vertex[1].x &&
785 vertex[2].x==vertex[3].x &&
786 vertex[0].y==vertex[3].y &&
787 vertex[1].y==vertex[2].y) return FALSE;
788
789 vertex[0].x-=VERTEX_OFFX; // otherwise a small offset
790 vertex[0].y-=VERTEX_OFFY; // to get better accuracy
791 vertex[1].x-=VERTEX_OFFX;
792 vertex[1].y-=VERTEX_OFFY;
793 vertex[2].x-=VERTEX_OFFX;
794 vertex[2].y-=VERTEX_OFFY;
795 vertex[3].x-=VERTEX_OFFX;
796 vertex[3].y-=VERTEX_OFFY;
797
798 return FALSE;
799 }
800
801 /////////////////////////////////////////////////////////
802
offset2(void)803 BOOL offset2(void)
804 {
805 if(bDisplayNotSet)
806 SetOGLDisplaySettings(1);
807
808 if(!(dwActFixes&16))
809 {
810 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
811 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
812 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
813 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
814
815 if(CheckCoord2()) return TRUE;
816 }
817
818 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
819 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
820 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
821 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
822
823 return FALSE;
824 }
825
826 /////////////////////////////////////////////////////////
827
offset3(void)828 BOOL offset3(void)
829 {
830 if(bDisplayNotSet)
831 SetOGLDisplaySettings(1);
832
833 if(!(dwActFixes&16))
834 {
835 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
836 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
837 lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);
838 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
839 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
840 ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);
841
842 if(CheckCoord3()) return TRUE;
843 }
844
845 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
846 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
847 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;
848 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
849 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
850 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;
851
852 return FALSE;
853 }
854
855 /////////////////////////////////////////////////////////
856
offset4(void)857 BOOL offset4(void)
858 {
859 if(bDisplayNotSet)
860 SetOGLDisplaySettings(1);
861
862 if(!(dwActFixes&16))
863 {
864 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
865 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
866 lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);
867 lx3=(short)(((int)lx3<<SIGNSHIFT)>>SIGNSHIFT);
868 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
869 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
870 ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);
871 ly3=(short)(((int)ly3<<SIGNSHIFT)>>SIGNSHIFT);
872
873 if(CheckCoord4()) return TRUE;
874 }
875
876 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
877 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
878 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;
879 vertex[3].x=lx3+PSXDisplay.CumulOffset.x;
880 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
881 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
882 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;
883 vertex[3].y=ly3+PSXDisplay.CumulOffset.y;
884
885 return FALSE;
886 }
887
888 /////////////////////////////////////////////////////////
889
offsetST(void)890 void offsetST(void)
891 {
892 if(bDisplayNotSet)
893 SetOGLDisplaySettings(1);
894
895 if(!(dwActFixes&16))
896 {
897 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
898 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
899
900 if(lx0<-512 && PSXDisplay.DrawOffset.x<=-512)
901 lx0+=2048;
902
903 if(ly0<-512 && PSXDisplay.DrawOffset.y<=-512)
904 ly0+=2048;
905 }
906
907 ly1 = ly0;
908 ly2 = ly3 = ly0+sprtH;
909 lx3 = lx0;
910 lx1 = lx2 = lx0+sprtW;
911
912 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
913 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
914 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;
915 vertex[3].x=lx3+PSXDisplay.CumulOffset.x;
916 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
917 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
918 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;
919 vertex[3].y=ly3+PSXDisplay.CumulOffset.y;
920 }
921
922 /////////////////////////////////////////////////////////
923
offsetScreenUpload(long Position)924 void offsetScreenUpload(long Position)
925 {
926 if(bDisplayNotSet)
927 SetOGLDisplaySettings(1);
928
929 if(Position==-1)
930 {
931 long lmdx,lmdy;
932
933 lmdx=xrUploadArea.x0;
934 lmdy=xrUploadArea.y0;
935
936 lx0-=lmdx;
937 ly0-=lmdy;
938 lx1-=lmdx;
939 ly1-=lmdy;
940 lx2-=lmdx;
941 ly2-=lmdy;
942 lx3-=lmdx;
943 ly3-=lmdy;
944 }
945 else
946 if(Position)
947 {
948 lx0-=PSXDisplay.DisplayPosition.x;
949 ly0-=PSXDisplay.DisplayPosition.y;
950 lx1-=PSXDisplay.DisplayPosition.x;
951 ly1-=PSXDisplay.DisplayPosition.y;
952 lx2-=PSXDisplay.DisplayPosition.x;
953 ly2-=PSXDisplay.DisplayPosition.y;
954 lx3-=PSXDisplay.DisplayPosition.x;
955 ly3-=PSXDisplay.DisplayPosition.y;
956 }
957 else
958 {
959 lx0-=PreviousPSXDisplay.DisplayPosition.x;
960 ly0-=PreviousPSXDisplay.DisplayPosition.y;
961 lx1-=PreviousPSXDisplay.DisplayPosition.x;
962 ly1-=PreviousPSXDisplay.DisplayPosition.y;
963 lx2-=PreviousPSXDisplay.DisplayPosition.x;
964 ly2-=PreviousPSXDisplay.DisplayPosition.y;
965 lx3-=PreviousPSXDisplay.DisplayPosition.x;
966 ly3-=PreviousPSXDisplay.DisplayPosition.y;
967 }
968
969 vertex[0].x=lx0 + PreviousPSXDisplay.Range.x0;
970 vertex[1].x=lx1 + PreviousPSXDisplay.Range.x0;
971 vertex[2].x=lx2 + PreviousPSXDisplay.Range.x0;
972 vertex[3].x=lx3 + PreviousPSXDisplay.Range.x0;
973 vertex[0].y=ly0 + PreviousPSXDisplay.Range.y0;
974 vertex[1].y=ly1 + PreviousPSXDisplay.Range.y0;
975 vertex[2].y=ly2 + PreviousPSXDisplay.Range.y0;
976 vertex[3].y=ly3 + PreviousPSXDisplay.Range.y0;
977
978 if(iUseMask)
979 {
980 vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
981 gl_z+=0.00004f;
982 }
983 }
984
985 /////////////////////////////////////////////////////////
986
offsetBlk(void)987 void offsetBlk(void)
988 {
989 if(bDisplayNotSet)
990 SetOGLDisplaySettings(1);
991
992 vertex[0].x=lx0-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
993 vertex[1].x=lx1-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
994 vertex[2].x=lx2-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
995 vertex[3].x=lx3-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
996 vertex[0].y=ly0-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
997 vertex[1].y=ly1-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
998 vertex[2].y=ly2-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
999 vertex[3].y=ly3-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
1000
1001 if(iUseMask)
1002 {
1003 vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
1004 gl_z+=0.00004f;
1005 }
1006 }
1007
1008 ////////////////////////////////////////////////////////////////////////
1009 // texture sow/tow calculations
1010 ////////////////////////////////////////////////////////////////////////
1011
assignTextureVRAMWrite(void)1012 void assignTextureVRAMWrite(void)
1013 {
1014 #ifdef OWNSCALE
1015
1016 vertex[0].sow=0.5f/ ST_FACVRAMX;
1017 vertex[0].tow=0.5f/ ST_FACVRAM;
1018
1019 vertex[1].sow=(float)gl_ux[1]/ ST_FACVRAMX;
1020 vertex[1].tow=0.5f/ ST_FACVRAM;
1021
1022 vertex[2].sow=(float)gl_ux[2]/ ST_FACVRAMX;
1023 vertex[2].tow=(float)gl_vy[2]/ ST_FACVRAM;
1024
1025 vertex[3].sow=0.5f/ ST_FACVRAMX;
1026 vertex[3].tow=(float)gl_vy[3]/ ST_FACVRAM;
1027
1028 #else
1029
1030 if(gl_ux[1]==255)
1031 {
1032 vertex[0].sow=(gl_ux[0]*255.99f)/255.0f;
1033 vertex[1].sow=(gl_ux[1]*255.99f)/255.0f;
1034 vertex[2].sow=(gl_ux[2]*255.99f)/255.0f;
1035 vertex[3].sow=(gl_ux[3]*255.99f)/255.0f;
1036 }
1037 else
1038 {
1039 vertex[0].sow=gl_ux[0];
1040 vertex[1].sow=gl_ux[1];
1041 vertex[2].sow=gl_ux[2];
1042 vertex[3].sow=gl_ux[3];
1043 }
1044
1045 vertex[0].tow=gl_vy[0];
1046 vertex[1].tow=gl_vy[1];
1047 vertex[2].tow=gl_vy[2];
1048 vertex[3].tow=gl_vy[3];
1049
1050 #endif
1051 }
1052
1053 GLuint gLastTex=0;
1054 GLuint gLastFMode=(GLuint)-1;
1055
1056 /////////////////////////////////////////////////////////
1057
assignTextureSprite(void)1058 void assignTextureSprite(void)
1059 {
1060 if(bUsingTWin)
1061 {
1062 vertex[0].sow=vertex[3].sow=(float)gl_ux[0]/TWin.UScaleFactor;
1063 vertex[1].sow=vertex[2].sow=(float)sSprite_ux2/TWin.UScaleFactor;
1064 vertex[0].tow=vertex[1].tow=(float)gl_vy[0]/TWin.VScaleFactor;
1065 vertex[2].tow=vertex[3].tow=(float)sSprite_vy2/TWin.VScaleFactor;
1066 gLastTex=gTexName;
1067 }
1068 else
1069 {
1070 #ifdef OWNSCALE
1071
1072 vertex[0].sow=vertex[3].sow=(float)gl_ux[0] / ST_FACSPRITE;
1073 vertex[1].sow=vertex[2].sow=(float)sSprite_ux2 / ST_FACSPRITE;
1074 vertex[0].tow=vertex[1].tow=(float)gl_vy[0] / ST_FACSPRITE;
1075 vertex[2].tow=vertex[3].tow=(float)sSprite_vy2 / ST_FACSPRITE;
1076
1077 #else
1078
1079 vertex[0].sow=vertex[3].sow=gl_ux[0];
1080 vertex[1].sow=vertex[2].sow=sSprite_ux2;
1081 vertex[0].tow=vertex[1].tow=gl_vy[0];
1082 vertex[2].tow=vertex[3].tow=sSprite_vy2;
1083
1084 #endif
1085
1086 if(iFilterType>2)
1087 {
1088 if(gLastTex!=gTexName || gLastFMode!=0)
1089 {
1090 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glError();
1091 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glError();
1092 gLastTex=gTexName;gLastFMode=0;
1093 }
1094 }
1095 }
1096
1097 if(usMirror & 0x1000)
1098 {
1099 vertex[0].sow=vertex[1].sow;
1100 vertex[1].sow=vertex[2].sow=vertex[3].sow;
1101 vertex[3].sow=vertex[0].sow;
1102 }
1103
1104 if(usMirror & 0x2000)
1105 {
1106 vertex[0].tow=vertex[3].tow;
1107 vertex[2].tow=vertex[3].tow=vertex[1].tow;
1108 vertex[1].tow=vertex[0].tow;
1109 }
1110
1111 }
1112
1113 /////////////////////////////////////////////////////////
1114
assignTexture3(void)1115 void assignTexture3(void)
1116 {
1117 if(bUsingTWin)
1118 {
1119 vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;
1120 vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;
1121 vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;
1122 vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;
1123 vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;
1124 vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor;
1125 gLastTex=gTexName;
1126 }
1127 else
1128 {
1129 #ifdef OWNSCALE
1130 vertex[0].sow=(float)gl_ux[0] / ST_FACTRI;
1131 vertex[0].tow=(float)gl_vy[0] / ST_FACTRI;
1132 vertex[1].sow=(float)gl_ux[1] / ST_FACTRI;
1133
1134 vertex[1].tow=(float)gl_vy[1] / ST_FACTRI;
1135 vertex[2].sow=(float)gl_ux[2] / ST_FACTRI;
1136 vertex[2].tow=(float)gl_vy[2] / ST_FACTRI;
1137 #else
1138 vertex[0].sow=gl_ux[0];
1139 vertex[0].tow=gl_vy[0];
1140 vertex[1].sow=gl_ux[1];
1141 vertex[1].tow=gl_vy[1];
1142 vertex[2].sow=gl_ux[2];
1143 vertex[2].tow=gl_vy[2];
1144 #endif
1145
1146 if(iFilterType>2)
1147 {
1148 if(gLastTex!=gTexName || gLastFMode!=1)
1149 {
1150 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glError();
1151 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glError();
1152 gLastTex=gTexName;gLastFMode=1;
1153 }
1154 }
1155
1156 if(iFilterType)
1157 {
1158 float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;
1159 for(i=0;i<3;i++)
1160 {
1161 if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;
1162 if(vertex[i].tow<fymin) fymin=vertex[i].tow;
1163 if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;
1164 if(vertex[i].tow>fymax) fymax=vertex[i].tow;
1165 }
1166
1167 for(i=0;i<3;i++)
1168 {
1169 if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;
1170 if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;
1171 if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;
1172 if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;
1173 }
1174 }
1175 }
1176 }
1177
1178 /////////////////////////////////////////////////////////
1179
assignTexture4(void)1180 void assignTexture4(void)
1181 {
1182 if(bUsingTWin)
1183 {
1184 vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;
1185 vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;
1186 vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;
1187 vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;
1188 vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;
1189 vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor;
1190 vertex[3].sow=(float)gl_ux[3]/TWin.UScaleFactor;
1191 vertex[3].tow=(float)gl_vy[3]/TWin.VScaleFactor;
1192 gLastTex=gTexName;
1193 }
1194 else
1195 {
1196 #ifdef OWNSCALE
1197 vertex[0].sow=(float)gl_ux[0] / ST_FAC;
1198 vertex[0].tow=(float)gl_vy[0] / ST_FAC;
1199 vertex[1].sow=(float)gl_ux[1] / ST_FAC;
1200 vertex[1].tow=(float)gl_vy[1] / ST_FAC;
1201 vertex[2].sow=(float)gl_ux[2] / ST_FAC;
1202 vertex[2].tow=(float)gl_vy[2] / ST_FAC;
1203 vertex[3].sow=(float)gl_ux[3] / ST_FAC;
1204 vertex[3].tow=(float)gl_vy[3] / ST_FAC;
1205 #else
1206 vertex[0].sow=gl_ux[0];
1207 vertex[0].tow=gl_vy[0];
1208 vertex[1].sow=gl_ux[1];
1209 vertex[1].tow=gl_vy[1];
1210 vertex[2].sow=gl_ux[2];
1211 vertex[2].tow=gl_vy[2];
1212 vertex[3].sow=gl_ux[3];
1213 vertex[3].tow=gl_vy[3];
1214 #endif
1215
1216 if(iFilterType>2)
1217 {
1218 if(gLastTex!=gTexName || gLastFMode!=1)
1219 {
1220 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glError();
1221 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glError();
1222 gLastTex=gTexName;gLastFMode=1;
1223 }
1224 }
1225
1226 if(iFilterType)
1227 {
1228 float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;
1229 for(i=0;i<4;i++)
1230 {
1231 if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;
1232 if(vertex[i].tow<fymin) fymin=vertex[i].tow;
1233 if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;
1234 if(vertex[i].tow>fymax) fymax=vertex[i].tow;
1235 }
1236
1237 for(i=0;i<4;i++)
1238 {
1239 if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;
1240 if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;
1241 if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;
1242 if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;
1243 }
1244 }
1245 }
1246 }
1247
1248 ////////////////////////////////////////////////////////////////////////
1249 ////////////////////////////////////////////////////////////////////////
1250 ////////////////////////////////////////////////////////////////////////
1251
1252 ////////////////////////////////////////////////////////////////////////
1253 // render pos / buffers
1254 ////////////////////////////////////////////////////////////////////////
1255
1256 #define EqualRect(pr1,pr2) ((pr1)->left==(pr2)->left && (pr1)->top==(pr2)->top && (pr1)->right==(pr2)->right && (pr1)->bottom==(pr2)->bottom)
1257
1258 ////////////////////////////////////////////////////////////////////////
1259 // SetDisplaySettings: "simply" calcs the new drawing area and updates
1260 // the ogl clipping (scissor)
1261
1262 BOOL bSetClip=FALSE;
1263
SetOGLDisplaySettings(BOOL DisplaySet)1264 void SetOGLDisplaySettings(BOOL DisplaySet)
1265 {
1266 static RECT rprev={0,0,0,0};
1267 static RECT rC ={0,0,0,0};
1268 static int iOldX=0;
1269 static int iOldY=0;
1270 RECT r;float XS,YS;
1271
1272 bDisplayNotSet = FALSE;
1273
1274 //----------------------------------------------------// that's a whole screen upload
1275 if(!DisplaySet)
1276 {
1277 RECT rX;
1278 PSXDisplay.GDrawOffset.x=0;
1279 PSXDisplay.GDrawOffset.y=0;
1280
1281 PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x+PreviousPSXDisplay.Range.x0;
1282 PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y+PreviousPSXDisplay.Range.y0;
1283
1284 rprev.left=rprev.left+1;
1285
1286 rX=rRatioRect;
1287 rX.top=iResY-(rRatioRect.top+rRatioRect.bottom);
1288
1289 if(bSetClip || !EqualRect(&rC,&rX))
1290 {
1291 rC=rX;
1292 glScissor(rC.left,rC.top,rC.right,rC.bottom); glError();
1293 //LOGE("glscissor:%d %d %d %d",rC.left,rC.top,rC.right,rC.bottom);
1294 bSetClip=FALSE;
1295 }
1296 return;
1297 }
1298 //----------------------------------------------------//
1299
1300 PSXDisplay.GDrawOffset.y = PreviousPSXDisplay.DisplayPosition.y;
1301 PSXDisplay.GDrawOffset.x = PreviousPSXDisplay.DisplayPosition.x;
1302 PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x - PSXDisplay.GDrawOffset.x+PreviousPSXDisplay.Range.x0;
1303 PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y - PSXDisplay.GDrawOffset.y+PreviousPSXDisplay.Range.y0;
1304
1305 r.top =PSXDisplay.DrawArea.y0 - PreviousPSXDisplay.DisplayPosition.y;
1306 r.bottom=PSXDisplay.DrawArea.y1 - PreviousPSXDisplay.DisplayPosition.y;
1307
1308 if(r.bottom<0 || r.top>=PSXDisplay.DisplayMode.y)
1309 {
1310 r.top =PSXDisplay.DrawArea.y0 - PSXDisplay.DisplayPosition.y;
1311 r.bottom=PSXDisplay.DrawArea.y1 - PSXDisplay.DisplayPosition.y;
1312 }
1313
1314 r.left =PSXDisplay.DrawArea.x0 - PreviousPSXDisplay.DisplayPosition.x;
1315 r.right =PSXDisplay.DrawArea.x1 - PreviousPSXDisplay.DisplayPosition.x;
1316
1317 if(r.right<0 || r.left>=PSXDisplay.DisplayMode.x)
1318 {
1319 r.left =PSXDisplay.DrawArea.x0 - PSXDisplay.DisplayPosition.x;
1320 r.right =PSXDisplay.DrawArea.x1 - PSXDisplay.DisplayPosition.x;
1321 }
1322
1323 if(!bSetClip && EqualRect(&r,&rprev) &&
1324 iOldX == PSXDisplay.DisplayMode.x &&
1325 iOldY == PSXDisplay.DisplayMode.y)
1326 return;
1327
1328 rprev = r;
1329 iOldX = PSXDisplay.DisplayMode.x;
1330 iOldY = PSXDisplay.DisplayMode.y;
1331
1332 XS=(float)rRatioRect.right/(float)PSXDisplay.DisplayMode.x;
1333 YS=(float)rRatioRect.bottom/(float)PSXDisplay.DisplayMode.y;
1334
1335 if(PreviousPSXDisplay.Range.x0)
1336 {
1337 short s=PreviousPSXDisplay.Range.x0+PreviousPSXDisplay.Range.x1;
1338
1339 r.left+=PreviousPSXDisplay.Range.x0+1;
1340
1341 r.right+=PreviousPSXDisplay.Range.x0;
1342
1343 if(r.left>s) r.left=s;
1344 if(r.right>s) r.right=s;
1345 }
1346
1347 if(PreviousPSXDisplay.Range.y0)
1348 {
1349 short s=PreviousPSXDisplay.Range.y0+PreviousPSXDisplay.Range.y1;
1350
1351 r.top+=PreviousPSXDisplay.Range.y0+1;
1352 r.bottom+=PreviousPSXDisplay.Range.y0;
1353
1354 if(r.top>s) r.top=s;
1355 if(r.bottom>s) r.bottom=s;
1356 }
1357
1358 // Set the ClipArea variables to reflect the new screen,
1359 // offset from zero (since it is a new display buffer)
1360 r.left = (int)(((float)(r.left)) *XS);
1361 r.top = (int)(((float)(r.top)) *YS);
1362 r.right = (int)(((float)(r.right + 1))*XS);
1363 r.bottom = (int)(((float)(r.bottom + 1))*YS);
1364
1365 // Limit clip area to the screen size
1366 if (r.left > iResX) r.left = iResX;
1367 if (r.left < 0) r.left = 0;
1368 if (r.top > iResY) r.top = iResY;
1369 if (r.top < 0) r.top = 0;
1370 if (r.right > iResX) r.right = iResX;
1371 if (r.right < 0) r.right = 0;
1372 if (r.bottom > iResY) r.bottom = iResY;
1373 if (r.bottom < 0) r.bottom = 0;
1374
1375 r.right -=r.left;
1376 r.bottom-=r.top;
1377 r.top=iResY-(r.top+r.bottom);
1378
1379 r.left+=rRatioRect.left;
1380 r.top -=rRatioRect.top;
1381
1382 if(bSetClip || !EqualRect(&r,&rC))
1383 {
1384 glScissor(r.left,r.top,r.right,r.bottom); glError();
1385
1386 rC=r;
1387 bSetClip=FALSE;
1388 }
1389 }
1390
1391 ////////////////////////////////////////////////////////////////////////
1392 ////////////////////////////////////////////////////////////////////////
1393 ////////////////////////////////////////////////////////////////////////
1394
1395