1 /***************************************************************************
\r
4 begin : Sun Mar 08 2009
\r
5 copyright : (C) 1999-2009 by Pete Bernert
\r
6 web : www.pbernert.com
\r
7 ***************************************************************************/
\r
9 /***************************************************************************
\r
11 * This program is free software; you can redistribute it and/or modify *
\r
12 * it under the terms of the GNU General Public License as published by *
\r
13 * the Free Software Foundation; either version 2 of the License, or *
\r
14 * (at your option) any later version. See also the license.txt file for *
\r
15 * additional informations. *
\r
17 ***************************************************************************/
\r
19 //*************************************************************************//
\r
20 // History of changes:
\r
22 // 2009/03/08 - Pete
\r
23 // - generic cleanup for the Peops release
\r
25 //*************************************************************************//
\r
35 #include "externals.h"
\r
39 #include "texture.h"
\r
41 #include "gpuExternals.h"
\r
42 #include "GPUPlugin.h"
\r
43 #include "gpuDraw.h"
\r
44 #include "gpuPrim.h"
\r
45 #include "gpuTexture.h"
\r
46 #include "gpuStdafx.h"
\r
54 ////////////////////////////////////////////////////////////////////////////////////
\r
57 #define SIGNBIT 0x800
\r
58 #define S_MASK 0xf000
\r
59 #define L_MASK 0xfffff000
\r
61 // ownscale: some ogl drivers have buggy texture matrix funcs, so it
\r
62 // is safer to calc sow/tow ourselves
\r
66 ///////////////////////////////////////////////////////////////
\r
68 #define ST_FACSPRITE 255.99f
\r
69 #define ST_BFFACSPRITE 0.5f/256.0f
\r
70 #define ST_BFFACSPRITESORT 0.333f/256.0f
\r
72 #define ST_OFFSET 0.5f/256.0f;
\r
74 #define ST_FAC 255.99f
\r
75 #define ST_BFFAC 0.5f/256.0f
\r
76 #define ST_BFFACSORT 0.333f/256.0f
\r
78 #define ST_FACTRI 255.99f
\r
79 #define ST_BFFACTRI 0.5f/256.0f
\r
80 #define ST_BFFACTRISORT 0.333f/256.0f
\r
82 #define ST_FACVRAMX 255.0f
\r
83 #define ST_FACVRAM 256.0f
\r
85 ///////////////////////////////////////////////////////////////
\r
89 #define ST_BFFACSPRITE 0.5f
\r
90 #define ST_BFFACSPRITESORT 0.333f
\r
92 #define ST_BFFAC 0.5f
\r
93 #define ST_BFFACSORT 0.333f
\r
95 #define ST_BFFACTRI 0.5f
\r
96 #define ST_BFFACTRISORT 0.333f
\r
98 #define ST_OFFSET 0.5f;
\r
102 ////////////////////////////////////////////////////////////////////////////////////
\r
109 void glBlendEquationEXT(GLenum mode);
\r
110 void glColorTableEXT(GLenum target, GLenum internalFormat, GLsizei width, GLenum format,GLenum type, const GLvoid *data);
\r
113 // draw globals; most will be initialized again later (by config or checks)
\r
115 BOOL bIsFirstFrame=TRUE;
\r
117 // resolution/ratio vars
\r
121 BOOL bKeepRatio=FALSE;
\r
124 // psx mask related vars
\r
126 BOOL bCheckMask=FALSE;
\r
129 unsigned short sSetMask=0;
\r
130 unsigned long lSetMask=0;
\r
132 // drawing/coord vars
\r
134 OGLVertex vertex[4];
\r
137 short sprtY,sprtX,sprtH,sprtW;
\r
142 BOOL bAdvancedBlend;
\r
144 // OGL extension support
\r
147 // gfx card buffer infos
\r
150 int iZBufferDepth=0;
\r
151 GLbitfield uiBufferBits=GL_COLOR_BUFFER_BIT;
\r
153 ////////////////////////////////////////////////////////////////////////
\r
154 ////////////////////////////////////////////////////////////////////////
\r
155 ////////////////////////////////////////////////////////////////////////
\r
157 ////////////////////////////////////////////////////////////////////////
\r
158 // Set OGL pixel format
\r
159 ////////////////////////////////////////////////////////////////////////
\r
162 BOOL bSetupPixelFormat(HDC hDC)
\r
165 static PIXELFORMATDESCRIPTOR pfd =
\r
167 sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
\r
168 1, // version number
\r
169 PFD_DRAW_TO_WINDOW | // support window
\r
170 PFD_SUPPORT_OPENGL | // support OpenGL
\r
171 PFD_DOUBLEBUFFER, // double buffered
\r
172 PFD_TYPE_RGBA, // RGBA type
\r
173 16, // 16-bit color depth (adjusted later)
\r
174 0, 0, 0, 0, 0, 0, // color bits ignored
\r
175 0, // no alpha buffer
\r
176 0, // shift bit ignored
\r
177 0, // no accumulation buffer
\r
178 0, 0, 0, 0, // accum bits ignored
\r
181 0, // no auxiliary buffer
\r
182 PFD_MAIN_PLANE, // main layer
\r
184 0, 0, 0 // layer masks ignored
\r
187 pfd.cColorBits=iColDepth; // set user color depth
\r
188 pfd.cDepthBits=iZBufferDepth; // set user zbuffer (by psx mask)
\r
190 if((pixelformat=ChoosePixelFormat(hDC,&pfd))==0)
\r
192 MessageBox(NULL,"ChoosePixelFormat failed","Error",MB_OK);
\r
196 if(SetPixelFormat(hDC,pixelformat, &pfd)==FALSE)
\r
198 MessageBox(NULL,"SetPixelFormat failed","Error",MB_OK);
\r
206 ////////////////////////////////////////////////////////////////////////
\r
207 // Get extension infos (f.e. pal textures / packed pixels)
\r
208 ////////////////////////////////////////////////////////////////////////
\r
210 void GetExtInfos(void)
\r
212 BOOL bPacked=FALSE; // default: no packed pixel support
\r
214 if(strstr((s8 *)glGetString(GL_EXTENSIONS), // packed pixels available?
\r
215 "GL_EXT_packed_pixels"))
\r
216 bPacked=TRUE; // -> ok
\r
220 iClampType=GL_CLAMP;
\r
222 iClampType=GL_CLAMP_TO_EDGE;
\r
226 ////////////////////////////////////////////////////////////////////////
\r
227 // Setup some stuff depending on user settings or in-game toggle
\r
228 ////////////////////////////////////////////////////////////////////////
\r
230 void SetExtGLFuncs(void)
\r
232 //----------------------------------------------------//
\r
234 SetFixes(); // update fix infos
\r
236 //----------------------------------------------------//
\r
239 if(bAdvancedBlend) bUseMultiPass=TRUE; // -> pseudo-advanced with 2 passes
\r
240 else bUseMultiPass=FALSE; // -> or simple 'bright color' mode
\r
241 // bGLBlend=FALSE; // -> no ext blending!
\r
243 glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
\r
246 if(bOpaquePass) // opaque mode?
\r
251 PalTexturedColourFn=CP8RGBA; // -> init col func
\r
256 PalTexturedColourFn=XP8RGBA; // -> init col func
\r
260 glAlphaFuncx(GL_GREATER,0.49f);
\r
262 else // no opaque mode?
\r
264 TCF[0]=TCF[1]=P8RGBA;
\r
265 PalTexturedColourFn=P8RGBA; // -> init col func
\r
266 glAlphaFuncx(GL_NOTEQUAL,0); // --> set alpha func
\r
269 //----------------------------------------------------//
\r
271 LoadSubTexFn=LoadSubTexturePageSort; // init load tex ptr
\r
273 bBlendEnable=FALSE; // init blending: off
\r
274 glDisable(GL_BLEND);
\r
276 SetScanTrans(); // init scan lines (if wanted)
\r
279 ////////////////////////////////////////////////////////////////////////
\r
280 // setup scan lines
\r
281 ////////////////////////////////////////////////////////////////////////
\r
283 #define R_TSP 0x00,0x45,0x00,0xff
\r
284 #define G_TSP 0x00,0x00,0x45,0xff
\r
285 #define B_TSP 0x45,0x00,0x00,0xff
\r
286 #define O_TSP 0x45,0x45,0x45,0xff
\r
287 #define N_TSP 0x00,0x00,0x00,0xff
\r
289 GLuint gTexScanName=0;
\r
291 GLubyte texscan[4][16]=
\r
293 {R_TSP, G_TSP, B_TSP, N_TSP},
\r
294 {O_TSP, N_TSP, O_TSP, N_TSP},
\r
295 {B_TSP, N_TSP, R_TSP, G_TSP},
\r
296 {O_TSP, N_TSP, O_TSP, N_TSP}
\r
299 void CreateScanLines(void)
\r
303 ////////////////////////////////////////////////////////////////////////
\r
305 ////////////////////////////////////////////////////////////////////////
\r
308 HGLRC GLCONTEXT=NULL;
\r
311 #ifdef MAEMO_CHANGES
\r
312 bool TestEGLError(const char* pszLocation)
\r
315 eglGetError returns the last error that has happened using egl,
\r
316 not the status of the last called function. The user has to
\r
317 check after every single egl call or at least once every frame.
\r
319 EGLint iErr = eglGetError();
\r
320 if (iErr != EGL_SUCCESS)
\r
322 printf("%s failed (%d).\n", pszLocation, iErr);
\r
329 void maemoGLinit(){
\r
334 printf ("maemo GL init\n");
\r
335 long int winxid=GDK_WINDOW_XID(GTK_WIDGET(windowG)->window);
\r
336 printf ("%d\n",winxid);
\r
338 EGLContext context = 0;
\r
339 EGLConfig eglConfig = 0;
\r
340 EGLContext eglContext = 0;
\r
341 display = eglGetDisplay( EGL_DEFAULT_DISPLAY );
\r
343 if( eglInitialize( display, NULL, NULL ) == EGL_FALSE )
\r
345 printf( "EGL Initialize failed!\n" );
\r
349 const EGLint attributeList[] = {
\r
350 EGL_SURFACE_TYPE, EGL_WINDOW_BIT,
\r
351 /*EGL_BUFFER_SIZE, 32, */
\r
355 EGLint pi32ConfigAttribs[5];
\r
356 pi32ConfigAttribs[0] = EGL_SURFACE_TYPE;
\r
357 pi32ConfigAttribs[1] = EGL_WINDOW_BIT;
\r
358 pi32ConfigAttribs[2] = EGL_RENDERABLE_TYPE;
\r
359 pi32ConfigAttribs[3] = EGL_OPENGL_ES2_BIT;
\r
360 pi32ConfigAttribs[4] = EGL_NONE;
\r
362 EGLint pi32ContextAttribs[3];
\r
363 pi32ContextAttribs[0] = EGL_CONTEXT_CLIENT_VERSION;
\r
364 pi32ContextAttribs[1] = 2;
\r
365 pi32ContextAttribs[2] = EGL_NONE;
\r
368 if (!eglChooseConfig(display, attributeList, &eglConfig, 1, &iConfigs) || (iConfigs != 1))
\r
370 printf("Error: eglChooseConfig() failed.\n");
\r
372 printf ("%d\n",iConfigs);
\r
373 surface = eglCreateWindowSurface(display, eglConfig, (void*)winxid, NULL);
\r
374 printf ("%d\n",surface);
\r
375 if (!TestEGLError("eglCreateWindowSurface"))
\r
377 printf ("eglCreateWindowSurface fail");
\r
380 //context = eglCreateContext(display, eglConfig, NULL, pi32ContextAttribs);
\r
381 context =eglCreateContext( display, eglConfig,
\r
382 EGL_NO_CONTEXT, NULL
\r
384 printf ("%d\n",context);
\r
385 if (!TestEGLError("eglCreateContext"))
\r
387 printf("error eglCreateContext");
\r
390 eglMakeCurrent(display, surface, surface, context);
\r
392 if (!TestEGLError("eglMakeCurrent"))
\r
394 printf("error eglMakeCurrent");
\r
399 int GLinitialize()
\r
401 //----------------------------------------------------//
\r
405 dcGlobal = GetDC(hWWindow); // FIRST: dc/rc stuff
\r
406 objectRC = wglCreateContext(dcGlobal);
\r
407 GLCONTEXT=objectRC;
\r
408 wglMakeCurrent(dcGlobal, objectRC);
\r
409 // CheckWGLExtensions(dcGlobal);
\r
410 if(bWindowMode) ReleaseDC(hWWindow,dcGlobal); // win mode: release dc again
\r
412 #ifdef MAEMO_CHANGES
\r
415 //----------------------------------------------------//
\r
417 glViewport(rRatioRect.left, // init viewport by ratio rect
\r
418 iResY-(rRatioRect.top+rRatioRect.bottom),
\r
420 rRatioRect.bottom);
\r
422 glScissor(0, 0, iResX, iResY); // init clipping (fullscreen)
\r
423 glEnable(GL_SCISSOR_TEST);
\r
426 glMatrixMode(GL_TEXTURE); // init psx tex sow and tow if not "ownscale"
\r
428 glScalef(1.0f/255.99f,1.0f/255.99f,1.0f); // geforce precision hack
\r
431 glMatrixMode(GL_PROJECTION); // init projection with psx resolution
\r
433 glOrtho(0,PSXDisplay.DisplayMode.x,
\r
434 PSXDisplay.DisplayMode.y, 0, -1, 1);
\r
436 if(iZBufferDepth) // zbuffer?
\r
438 uiBufferBits=GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT;
\r
439 glEnable(GL_DEPTH_TEST);
\r
440 glDepthFunc(GL_ALWAYS);
\r
443 else // no zbuffer?
\r
445 uiBufferBits=GL_COLOR_BUFFER_BIT;
\r
446 glDisable(GL_DEPTH_TEST);
\r
449 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); // first buffer clear
\r
450 glClear(uiBufferBits);
\r
452 GetExtInfos(); // get ext infos
\r
453 SetExtGLFuncs(); // init all kind of stuff (tex function pointers)
\r
455 glEnable(GL_ALPHA_TEST); // wanna alpha test
\r
458 glDisable(GL_LINE_SMOOTH);
\r
459 glDisable(GL_POINT_SMOOTH);
\r
462 ubGloAlpha=127; // init some drawing vars
\r
464 TWin.UScaleFactor = 1;
\r
465 TWin.VScaleFactor = 1;
\r
466 bDrawMultiPass=FALSE;
\r
470 if(bDrawDither) glEnable(GL_DITHER); // dither mode
\r
471 else glDisable(GL_DITHER);
\r
473 glDisable(GL_FOG); // turn all (currently) unused modes off
\r
474 glDisable(GL_LIGHTING);
\r
475 glDisable(GL_STENCIL_TEST);
\r
476 glDisable(GL_TEXTURE_2D);
\r
477 glDisable(GL_CULL_FACE);
\r
479 glFlush(); // we are done...
\r
482 CreateScanLines(); // setup scanline stuff (if wanted)
\r
484 CheckTextureMemory(); // check available tex memory
\r
486 if(bKeepRatio) SetAspectRatio(); // set ratio
\r
489 bIsFirstFrame = FALSE; // we have survived the first frame :)
\r
494 ////////////////////////////////////////////////////////////////////////
\r
495 // clean up OGL stuff
\r
496 ////////////////////////////////////////////////////////////////////////
\r
500 CleanupTextureStore(); // bye textures
\r
503 wglMakeCurrent(NULL, NULL); // bye context
\r
504 if(GLCONTEXT) wglDeleteContext(GLCONTEXT);
\r
505 if(!bWindowMode && dcGlobal)
\r
506 ReleaseDC(hWWindow,dcGlobal);
\r
510 ////////////////////////////////////////////////////////////////////////
\r
511 ////////////////////////////////////////////////////////////////////////
\r
512 ////////////////////////////////////////////////////////////////////////
\r
514 ////////////////////////////////////////////////////////////////////////
\r
515 ////////////////////////////////////////////////////////////////////////
\r
516 ////////////////////////////////////////////////////////////////////////
\r
518 ////////////////////////////////////////////////////////////////////////
\r
520 ////////////////////////////////////////////////////////////////////////
\r
522 // please note: it is hardly do-able in a hw/accel plugin to get the
\r
523 // real psx polygon coord mapping right... the following
\r
524 // works not to bad with many games, though
\r
526 __inline BOOL CheckCoord4()
\r
530 if(((lx1-lx0)>CHKMAX_X) ||
\r
531 ((lx2-lx0)>CHKMAX_X))
\r
535 if((lx1-lx3)>CHKMAX_X) return TRUE;
\r
536 if((lx2-lx3)>CHKMAX_X) return TRUE;
\r
542 if((lx0-lx1)>CHKMAX_X) return TRUE;
\r
543 if((lx2-lx1)>CHKMAX_X) return TRUE;
\r
544 if((lx3-lx1)>CHKMAX_X) return TRUE;
\r
548 if((lx0-lx2)>CHKMAX_X) return TRUE;
\r
549 if((lx1-lx2)>CHKMAX_X) return TRUE;
\r
550 if((lx3-lx2)>CHKMAX_X) return TRUE;
\r
554 if(((lx1-lx3)>CHKMAX_X) ||
\r
555 ((lx2-lx3)>CHKMAX_X))
\r
559 if((lx1-lx0)>CHKMAX_X) return TRUE;
\r
560 if((lx2-lx0)>CHKMAX_X) return TRUE;
\r
568 if((ly1-ly0)>CHKMAX_Y) return TRUE;
\r
569 if((ly2-ly0)>CHKMAX_Y) return TRUE;
\r
573 if((ly0-ly1)>CHKMAX_Y) return TRUE;
\r
574 if((ly2-ly1)>CHKMAX_Y) return TRUE;
\r
575 if((ly3-ly1)>CHKMAX_Y) return TRUE;
\r
579 if((ly0-ly2)>CHKMAX_Y) return TRUE;
\r
580 if((ly1-ly2)>CHKMAX_Y) return TRUE;
\r
581 if((ly3-ly2)>CHKMAX_Y) return TRUE;
\r
585 if((ly1-ly3)>CHKMAX_Y) return TRUE;
\r
586 if((ly2-ly3)>CHKMAX_Y) return TRUE;
\r
592 __inline BOOL CheckCoord3()
\r
596 if((lx1-lx0)>CHKMAX_X) return TRUE;
\r
597 if((lx2-lx0)>CHKMAX_X) return TRUE;
\r
601 if((lx0-lx1)>CHKMAX_X) return TRUE;
\r
602 if((lx2-lx1)>CHKMAX_X) return TRUE;
\r
606 if((lx0-lx2)>CHKMAX_X) return TRUE;
\r
607 if((lx1-lx2)>CHKMAX_X) return TRUE;
\r
611 if((ly1-ly0)>CHKMAX_Y) return TRUE;
\r
612 if((ly2-ly0)>CHKMAX_Y) return TRUE;
\r
616 if((ly0-ly1)>CHKMAX_Y) return TRUE;
\r
617 if((ly2-ly1)>CHKMAX_Y) return TRUE;
\r
621 if((ly0-ly2)>CHKMAX_Y) return TRUE;
\r
622 if((ly1-ly2)>CHKMAX_Y) return TRUE;
\r
629 __inline BOOL CheckCoord2()
\r
633 if((lx1-lx0)>CHKMAX_X) return TRUE;
\r
637 if((lx0-lx1)>CHKMAX_X) return TRUE;
\r
641 if((ly1-ly0)>CHKMAX_Y) return TRUE;
\r
645 if((ly0-ly1)>CHKMAX_Y) return TRUE;
\r
651 // Pete's way: a very easy (and hopefully fast) approach for lines
\r
652 // without sqrt... using a small float -> short cast trick :)
\r
654 #define VERTEX_OFFX 0.2f
\r
655 #define VERTEX_OFFY 0.2f
\r
657 BOOL offsetline(void)
\r
659 short x0,x1,y0,y1,dx,dy;float px,py;
\r
662 SetOGLDisplaySettings(1);
\r
664 if(!(dwActFixes&16))
\r
666 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
667 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
668 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
669 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
671 if(CheckCoord2()) return TRUE;
\r
674 x0 = (lx0 + PSXDisplay.CumulOffset.x)+1;
\r
675 x1 = (lx1 + PSXDisplay.CumulOffset.x)+1;
\r
676 y0 = (ly0 + PSXDisplay.CumulOffset.y)+1;
\r
677 y1 = (ly1 + PSXDisplay.CumulOffset.y)+1;
\r
687 if(dx>dy) py=-0.5f;
\r
688 else if(dx<dy) py= 0.5f;
\r
695 if(dx>dy) px= 0.5f;
\r
696 else if(dx<dy) px=-0.5f;
\r
706 if(dx>dy) px=-0.5f;
\r
707 else if(dx<dy) px= 0.5f;
\r
713 if(dx>dy) py=-0.5f;
\r
714 else if(dx<dy) py= 0.5f;
\r
719 vertex[0].x=(short)((float)x0-px);
\r
720 vertex[3].x=(short)((float)x0+py);
\r
722 vertex[0].y=(short)((float)y0-py);
\r
723 vertex[3].y=(short)((float)y0-px);
\r
725 vertex[1].x=(short)((float)x1-py);
\r
726 vertex[2].x=(short)((float)x1+px);
\r
728 vertex[1].y=(short)((float)y1+px);
\r
729 vertex[2].y=(short)((float)y1+py);
\r
731 if(vertex[0].x==vertex[3].x && // ortho rect? done
\r
732 vertex[1].x==vertex[2].x &&
\r
733 vertex[0].y==vertex[1].y &&
\r
734 vertex[2].y==vertex[3].y) return FALSE;
\r
735 if(vertex[0].x==vertex[1].x &&
\r
736 vertex[2].x==vertex[3].x &&
\r
737 vertex[0].y==vertex[3].y &&
\r
738 vertex[1].y==vertex[2].y) return FALSE;
\r
740 vertex[0].x-=VERTEX_OFFX; // otherwise a small offset
\r
741 vertex[0].y-=VERTEX_OFFY; // to get better accuracy
\r
742 vertex[1].x-=VERTEX_OFFX;
\r
743 vertex[1].y-=VERTEX_OFFY;
\r
744 vertex[2].x-=VERTEX_OFFX;
\r
745 vertex[2].y-=VERTEX_OFFY;
\r
746 vertex[3].x-=VERTEX_OFFX;
\r
747 vertex[3].y-=VERTEX_OFFY;
\r
752 /////////////////////////////////////////////////////////
\r
757 SetOGLDisplaySettings(1);
\r
759 if(!(dwActFixes&16))
\r
761 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
762 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
763 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
764 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
766 if(CheckCoord2()) return TRUE;
\r
769 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
770 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
771 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
772 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
777 /////////////////////////////////////////////////////////
\r
782 SetOGLDisplaySettings(1);
\r
784 if(!(dwActFixes&16))
\r
786 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
787 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
788 lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);
\r
789 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
790 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
791 ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);
\r
793 if(CheckCoord3()) return TRUE;
\r
796 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
797 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
798 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;
\r
799 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
800 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
801 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;
\r
806 /////////////////////////////////////////////////////////
\r
811 SetOGLDisplaySettings(1);
\r
813 if(!(dwActFixes&16))
\r
815 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
816 lx1=(short)(((int)lx1<<SIGNSHIFT)>>SIGNSHIFT);
\r
817 lx2=(short)(((int)lx2<<SIGNSHIFT)>>SIGNSHIFT);
\r
818 lx3=(short)(((int)lx3<<SIGNSHIFT)>>SIGNSHIFT);
\r
819 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
820 ly1=(short)(((int)ly1<<SIGNSHIFT)>>SIGNSHIFT);
\r
821 ly2=(short)(((int)ly2<<SIGNSHIFT)>>SIGNSHIFT);
\r
822 ly3=(short)(((int)ly3<<SIGNSHIFT)>>SIGNSHIFT);
\r
824 if(CheckCoord4()) return TRUE;
\r
827 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
828 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
829 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;
\r
830 vertex[3].x=lx3+PSXDisplay.CumulOffset.x;
\r
831 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
832 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
833 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;
\r
834 vertex[3].y=ly3+PSXDisplay.CumulOffset.y;
\r
839 /////////////////////////////////////////////////////////
\r
841 void offsetST(void)
\r
844 SetOGLDisplaySettings(1);
\r
846 if(!(dwActFixes&16))
\r
848 lx0=(short)(((int)lx0<<SIGNSHIFT)>>SIGNSHIFT);
\r
849 ly0=(short)(((int)ly0<<SIGNSHIFT)>>SIGNSHIFT);
\r
851 if(lx0<-512 && PSXDisplay.DrawOffset.x<=-512)
\r
854 if(ly0<-512 && PSXDisplay.DrawOffset.y<=-512)
\r
859 ly2 = ly3 = ly0+sprtH;
\r
861 lx1 = lx2 = lx0+sprtW;
\r
863 vertex[0].x=lx0+PSXDisplay.CumulOffset.x;
\r
864 vertex[1].x=lx1+PSXDisplay.CumulOffset.x;
\r
865 vertex[2].x=lx2+PSXDisplay.CumulOffset.x;
\r
866 vertex[3].x=lx3+PSXDisplay.CumulOffset.x;
\r
867 vertex[0].y=ly0+PSXDisplay.CumulOffset.y;
\r
868 vertex[1].y=ly1+PSXDisplay.CumulOffset.y;
\r
869 vertex[2].y=ly2+PSXDisplay.CumulOffset.y;
\r
870 vertex[3].y=ly3+PSXDisplay.CumulOffset.y;
\r
873 /////////////////////////////////////////////////////////
\r
875 void offsetScreenUpload(long Position)
\r
878 SetOGLDisplaySettings(1);
\r
884 lmdx=xrUploadArea.x0;
\r
885 lmdy=xrUploadArea.y0;
\r
899 lx0-=PSXDisplay.DisplayPosition.x;
\r
900 ly0-=PSXDisplay.DisplayPosition.y;
\r
901 lx1-=PSXDisplay.DisplayPosition.x;
\r
902 ly1-=PSXDisplay.DisplayPosition.y;
\r
903 lx2-=PSXDisplay.DisplayPosition.x;
\r
904 ly2-=PSXDisplay.DisplayPosition.y;
\r
905 lx3-=PSXDisplay.DisplayPosition.x;
\r
906 ly3-=PSXDisplay.DisplayPosition.y;
\r
910 lx0-=PreviousPSXDisplay.DisplayPosition.x;
\r
911 ly0-=PreviousPSXDisplay.DisplayPosition.y;
\r
912 lx1-=PreviousPSXDisplay.DisplayPosition.x;
\r
913 ly1-=PreviousPSXDisplay.DisplayPosition.y;
\r
914 lx2-=PreviousPSXDisplay.DisplayPosition.x;
\r
915 ly2-=PreviousPSXDisplay.DisplayPosition.y;
\r
916 lx3-=PreviousPSXDisplay.DisplayPosition.x;
\r
917 ly3-=PreviousPSXDisplay.DisplayPosition.y;
\r
920 vertex[0].x=lx0 + PreviousPSXDisplay.Range.x0;
\r
921 vertex[1].x=lx1 + PreviousPSXDisplay.Range.x0;
\r
922 vertex[2].x=lx2 + PreviousPSXDisplay.Range.x0;
\r
923 vertex[3].x=lx3 + PreviousPSXDisplay.Range.x0;
\r
924 vertex[0].y=ly0 + PreviousPSXDisplay.Range.y0;
\r
925 vertex[1].y=ly1 + PreviousPSXDisplay.Range.y0;
\r
926 vertex[2].y=ly2 + PreviousPSXDisplay.Range.y0;
\r
927 vertex[3].y=ly3 + PreviousPSXDisplay.Range.y0;
\r
931 vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
\r
936 /////////////////////////////////////////////////////////
\r
938 void offsetBlk(void)
\r
941 SetOGLDisplaySettings(1);
\r
943 vertex[0].x=lx0-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
944 vertex[1].x=lx1-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
945 vertex[2].x=lx2-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
946 vertex[3].x=lx3-PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
\r
947 vertex[0].y=ly0-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
948 vertex[1].y=ly1-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
949 vertex[2].y=ly2-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
950 vertex[3].y=ly3-PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
\r
954 vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
\r
959 ////////////////////////////////////////////////////////////////////////
\r
960 // texture sow/tow calculations
\r
961 ////////////////////////////////////////////////////////////////////////
\r
963 void assignTextureVRAMWrite(void)
\r
967 vertex[0].sow=0.5f/ ST_FACVRAMX;
\r
968 vertex[0].tow=0.5f/ ST_FACVRAM;
\r
970 vertex[1].sow=(float)gl_ux[1]/ ST_FACVRAMX;
\r
971 vertex[1].tow=0.5f/ ST_FACVRAM;
\r
973 vertex[2].sow=(float)gl_ux[2]/ ST_FACVRAMX;
\r
974 vertex[2].tow=(float)gl_vy[2]/ ST_FACVRAM;
\r
976 vertex[3].sow=0.5f/ ST_FACVRAMX;
\r
977 vertex[3].tow=(float)gl_vy[3]/ ST_FACVRAM;
\r
983 vertex[0].sow=(gl_ux[0]*255.99f)/255.0f;
\r
984 vertex[1].sow=(gl_ux[1]*255.99f)/255.0f;
\r
985 vertex[2].sow=(gl_ux[2]*255.99f)/255.0f;
\r
986 vertex[3].sow=(gl_ux[3]*255.99f)/255.0f;
\r
990 vertex[0].sow=gl_ux[0];
\r
991 vertex[1].sow=gl_ux[1];
\r
992 vertex[2].sow=gl_ux[2];
\r
993 vertex[3].sow=gl_ux[3];
\r
996 vertex[0].tow=gl_vy[0];
\r
997 vertex[1].tow=gl_vy[1];
\r
998 vertex[2].tow=gl_vy[2];
\r
999 vertex[3].tow=gl_vy[3];
\r
1004 GLuint gLastTex=0;
\r
1005 GLuint gLastFMode=(GLuint)-1;
\r
1007 /////////////////////////////////////////////////////////
\r
1009 void assignTextureSprite(void)
\r
1013 vertex[0].sow=vertex[3].sow=(float)gl_ux[0]/TWin.UScaleFactor;
\r
1014 vertex[1].sow=vertex[2].sow=(float)sSprite_ux2/TWin.UScaleFactor;
\r
1015 vertex[0].tow=vertex[1].tow=(float)gl_vy[0]/TWin.VScaleFactor;
\r
1016 vertex[2].tow=vertex[3].tow=(float)sSprite_vy2/TWin.VScaleFactor;
\r
1017 gLastTex=gTexName;
\r
1023 vertex[0].sow=vertex[3].sow=(float)gl_ux[0] / ST_FACSPRITE;
\r
1024 vertex[1].sow=vertex[2].sow=(float)sSprite_ux2 / ST_FACSPRITE;
\r
1025 vertex[0].tow=vertex[1].tow=(float)gl_vy[0] / ST_FACSPRITE;
\r
1026 vertex[2].tow=vertex[3].tow=(float)sSprite_vy2 / ST_FACSPRITE;
\r
1030 vertex[0].sow=vertex[3].sow=gl_ux[0];
\r
1031 vertex[1].sow=vertex[2].sow=sSprite_ux2;
\r
1032 vertex[0].tow=vertex[1].tow=gl_vy[0];
\r
1033 vertex[2].tow=vertex[3].tow=sSprite_vy2;
\r
1037 if(iFilterType>2)
\r
1039 if(gLastTex!=gTexName || gLastFMode!=0)
\r
1041 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
\r
1042 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
\r
1043 gLastTex=gTexName;gLastFMode=0;
\r
1048 if(usMirror & 0x1000)
\r
1050 vertex[0].sow=vertex[1].sow;
\r
1051 vertex[1].sow=vertex[2].sow=vertex[3].sow;
\r
1052 vertex[3].sow=vertex[0].sow;
\r
1055 if(usMirror & 0x2000)
\r
1057 vertex[0].tow=vertex[3].tow;
\r
1058 vertex[2].tow=vertex[3].tow=vertex[1].tow;
\r
1059 vertex[1].tow=vertex[0].tow;
\r
1064 /////////////////////////////////////////////////////////
\r
1066 void assignTexture3(void)
\r
1070 vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;
\r
1071 vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;
\r
1072 vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;
\r
1073 vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;
\r
1074 vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;
\r
1075 vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor;
\r
1076 gLastTex=gTexName;
\r
1081 vertex[0].sow=(float)gl_ux[0] / ST_FACTRI;
\r
1082 vertex[0].tow=(float)gl_vy[0] / ST_FACTRI;
\r
1083 vertex[1].sow=(float)gl_ux[1] / ST_FACTRI;
\r
1085 vertex[1].tow=(float)gl_vy[1] / ST_FACTRI;
\r
1086 vertex[2].sow=(float)gl_ux[2] / ST_FACTRI;
\r
1087 vertex[2].tow=(float)gl_vy[2] / ST_FACTRI;
\r
1089 vertex[0].sow=gl_ux[0];
\r
1090 vertex[0].tow=gl_vy[0];
\r
1091 vertex[1].sow=gl_ux[1];
\r
1092 vertex[1].tow=gl_vy[1];
\r
1093 vertex[2].sow=gl_ux[2];
\r
1094 vertex[2].tow=gl_vy[2];
\r
1097 if(iFilterType>2)
\r
1099 if(gLastTex!=gTexName || gLastFMode!=1)
\r
1101 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
\r
1102 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
\r
1103 gLastTex=gTexName;gLastFMode=1;
\r
1109 float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;
\r
1112 if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;
\r
1113 if(vertex[i].tow<fymin) fymin=vertex[i].tow;
\r
1114 if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;
\r
1115 if(vertex[i].tow>fymax) fymax=vertex[i].tow;
\r
1120 if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;
\r
1121 if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;
\r
1122 if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;
\r
1123 if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;
\r
1129 /////////////////////////////////////////////////////////
\r
1131 void assignTexture4(void)
\r
1135 vertex[0].sow=(float)gl_ux[0]/TWin.UScaleFactor;
\r
1136 vertex[0].tow=(float)gl_vy[0]/TWin.VScaleFactor;
\r
1137 vertex[1].sow=(float)gl_ux[1]/TWin.UScaleFactor;
\r
1138 vertex[1].tow=(float)gl_vy[1]/TWin.VScaleFactor;
\r
1139 vertex[2].sow=(float)gl_ux[2]/TWin.UScaleFactor;
\r
1140 vertex[2].tow=(float)gl_vy[2]/TWin.VScaleFactor;
\r
1141 vertex[3].sow=(float)gl_ux[3]/TWin.UScaleFactor;
\r
1142 vertex[3].tow=(float)gl_vy[3]/TWin.VScaleFactor;
\r
1143 gLastTex=gTexName;
\r
1148 vertex[0].sow=(float)gl_ux[0] / ST_FAC;
\r
1149 vertex[0].tow=(float)gl_vy[0] / ST_FAC;
\r
1150 vertex[1].sow=(float)gl_ux[1] / ST_FAC;
\r
1151 vertex[1].tow=(float)gl_vy[1] / ST_FAC;
\r
1152 vertex[2].sow=(float)gl_ux[2] / ST_FAC;
\r
1153 vertex[2].tow=(float)gl_vy[2] / ST_FAC;
\r
1154 vertex[3].sow=(float)gl_ux[3] / ST_FAC;
\r
1155 vertex[3].tow=(float)gl_vy[3] / ST_FAC;
\r
1157 vertex[0].sow=gl_ux[0];
\r
1158 vertex[0].tow=gl_vy[0];
\r
1159 vertex[1].sow=gl_ux[1];
\r
1160 vertex[1].tow=gl_vy[1];
\r
1161 vertex[2].sow=gl_ux[2];
\r
1162 vertex[2].tow=gl_vy[2];
\r
1163 vertex[3].sow=gl_ux[3];
\r
1164 vertex[3].tow=gl_vy[3];
\r
1167 if(iFilterType>2)
\r
1169 if(gLastTex!=gTexName || gLastFMode!=1)
\r
1171 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
\r
1172 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
\r
1173 gLastTex=gTexName;gLastFMode=1;
\r
1179 float fxmin=256.0f,fxmax=0.0f,fymin=256.0f,fymax=0.0f;int i;
\r
1182 if(vertex[i].sow<fxmin) fxmin=vertex[i].sow;
\r
1183 if(vertex[i].tow<fymin) fymin=vertex[i].tow;
\r
1184 if(vertex[i].sow>fxmax) fxmax=vertex[i].sow;
\r
1185 if(vertex[i].tow>fymax) fymax=vertex[i].tow;
\r
1190 if(vertex[i].sow==fxmin) vertex[i].sow+=ST_BFFACSORT;
\r
1191 if(vertex[i].sow==fxmax) vertex[i].sow-=ST_BFFACSORT;
\r
1192 if(vertex[i].tow==fymin) vertex[i].tow+=ST_BFFACSORT;
\r
1193 if(vertex[i].tow==fymax) vertex[i].tow-=ST_BFFACSORT;
\r
1199 ////////////////////////////////////////////////////////////////////////
\r
1200 ////////////////////////////////////////////////////////////////////////
\r
1201 ////////////////////////////////////////////////////////////////////////
\r
1203 ////////////////////////////////////////////////////////////////////////
\r
1204 // render pos / buffers
\r
1205 ////////////////////////////////////////////////////////////////////////
\r
1208 #define EqualRect(pr1,pr2) ((pr1)->left==(pr2)->left && (pr1)->top==(pr2)->top && (pr1)->right==(pr2)->right && (pr1)->bottom==(pr2)->bottom)
\r
1211 ////////////////////////////////////////////////////////////////////////
\r
1212 // SetDisplaySettings: "simply" calcs the new drawing area and updates
\r
1213 // the ogl clipping (scissor)
\r
1215 BOOL bSetClip=FALSE;
\r
1217 void SetOGLDisplaySettings(BOOL DisplaySet)
\r
1219 static RECT rprev={0,0,0,0};
\r
1220 static RECT rC ={0,0,0,0};
\r
1221 static int iOldX=0;
\r
1222 static int iOldY=0;
\r
1223 RECT r;float XS,YS;
\r
1225 bDisplayNotSet = FALSE;
\r
1227 //----------------------------------------------------// that's a whole screen upload
\r
1231 PSXDisplay.GDrawOffset.x=0;
\r
1232 PSXDisplay.GDrawOffset.y=0;
\r
1234 PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x+PreviousPSXDisplay.Range.x0;
\r
1235 PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y+PreviousPSXDisplay.Range.y0;
\r
1237 rprev.left=rprev.left+1;
\r
1240 rX.top=iResY-(rRatioRect.top+rRatioRect.bottom);
\r
1242 if(bSetClip || !EqualRect(&rC,&rX))
\r
1245 glScissor(rC.left,rC.top,rC.right,rC.bottom);
\r
1250 //----------------------------------------------------//
\r
1252 PSXDisplay.GDrawOffset.y = PreviousPSXDisplay.DisplayPosition.y;
\r
1253 PSXDisplay.GDrawOffset.x = PreviousPSXDisplay.DisplayPosition.x;
\r
1254 PSXDisplay.CumulOffset.x = PSXDisplay.DrawOffset.x - PSXDisplay.GDrawOffset.x+PreviousPSXDisplay.Range.x0;
\r
1255 PSXDisplay.CumulOffset.y = PSXDisplay.DrawOffset.y - PSXDisplay.GDrawOffset.y+PreviousPSXDisplay.Range.y0;
\r
1257 r.top =PSXDisplay.DrawArea.y0 - PreviousPSXDisplay.DisplayPosition.y;
\r
1258 r.bottom=PSXDisplay.DrawArea.y1 - PreviousPSXDisplay.DisplayPosition.y;
\r
1260 if(r.bottom<0 || r.top>=PSXDisplay.DisplayMode.y)
\r
1262 r.top =PSXDisplay.DrawArea.y0 - PSXDisplay.DisplayPosition.y;
\r
1263 r.bottom=PSXDisplay.DrawArea.y1 - PSXDisplay.DisplayPosition.y;
\r
1266 r.left =PSXDisplay.DrawArea.x0 - PreviousPSXDisplay.DisplayPosition.x;
\r
1267 r.right =PSXDisplay.DrawArea.x1 - PreviousPSXDisplay.DisplayPosition.x;
\r
1269 if(r.right<0 || r.left>=PSXDisplay.DisplayMode.x)
\r
1271 r.left =PSXDisplay.DrawArea.x0 - PSXDisplay.DisplayPosition.x;
\r
1272 r.right =PSXDisplay.DrawArea.x1 - PSXDisplay.DisplayPosition.x;
\r
1275 if(!bSetClip && EqualRect(&r,&rprev) &&
\r
1276 iOldX == PSXDisplay.DisplayMode.x &&
\r
1277 iOldY == PSXDisplay.DisplayMode.y)
\r
1281 iOldX = PSXDisplay.DisplayMode.x;
\r
1282 iOldY = PSXDisplay.DisplayMode.y;
\r
1284 XS=(float)rRatioRect.right/(float)PSXDisplay.DisplayMode.x;
\r
1285 YS=(float)rRatioRect.bottom/(float)PSXDisplay.DisplayMode.y;
\r
1287 if(PreviousPSXDisplay.Range.x0)
\r
1289 short s=PreviousPSXDisplay.Range.x0+PreviousPSXDisplay.Range.x1;
\r
1291 r.left+=PreviousPSXDisplay.Range.x0+1;
\r
1293 r.right+=PreviousPSXDisplay.Range.x0;
\r
1295 if(r.left>s) r.left=s;
\r
1296 if(r.right>s) r.right=s;
\r
1299 if(PreviousPSXDisplay.Range.y0)
\r
1301 short s=PreviousPSXDisplay.Range.y0+PreviousPSXDisplay.Range.y1;
\r
1303 r.top+=PreviousPSXDisplay.Range.y0+1;
\r
1304 r.bottom+=PreviousPSXDisplay.Range.y0;
\r
1306 if(r.top>s) r.top=s;
\r
1307 if(r.bottom>s) r.bottom=s;
\r
1310 // Set the ClipArea variables to reflect the new screen,
\r
1311 // offset from zero (since it is a new display buffer)
\r
1312 r.left = (int)(((float)(r.left)) *XS);
\r
1313 r.top = (int)(((float)(r.top)) *YS);
\r
1314 r.right = (int)(((float)(r.right + 1))*XS);
\r
1315 r.bottom = (int)(((float)(r.bottom + 1))*YS);
\r
1317 // Limit clip area to the screen size
\r
1318 if (r.left > iResX) r.left = iResX;
\r
1319 if (r.left < 0) r.left = 0;
\r
1320 if (r.top > iResY) r.top = iResY;
\r
1321 if (r.top < 0) r.top = 0;
\r
1322 if (r.right > iResX) r.right = iResX;
\r
1323 if (r.right < 0) r.right = 0;
\r
1324 if (r.bottom > iResY) r.bottom = iResY;
\r
1325 if (r.bottom < 0) r.bottom = 0;
\r
1329 r.top=iResY-(r.top+r.bottom);
\r
1331 r.left+=rRatioRect.left;
\r
1332 r.top -=rRatioRect.top;
\r
1334 if(bSetClip || !EqualRect(&r,&rC))
\r
1336 glScissor(r.left,r.top,r.right,r.bottom);
\r
1342 ////////////////////////////////////////////////////////////////////////
\r
1343 ////////////////////////////////////////////////////////////////////////
\r
1344 ////////////////////////////////////////////////////////////////////////
\r