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