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
23 #include "externals.h"
29 ////////////////////////////////////////////////////////////////////////
31 ////////////////////////////////////////////////////////////////////////
33 #define DEFOPAQUEON glAlphaFunc(GL_EQUAL,0.0f);bBlendEnable=FALSE;glDisable(GL_BLEND);
34 #define DEFOPAQUEOFF glAlphaFunc(GL_GREATER,0.49f);
36 ////////////////////////////////////////////////////////////////////////
38 ////////////////////////////////////////////////////////////////////////
40 BOOL bDrawTextured; // current active drawing states
\r
41 BOOL bDrawSmoothShaded;
42 BOOL bOldSmoothShaded;
45 int iOffscreenDrawing;
46 int iDrawnSomething=0;
48 BOOL bRenderFrontBuffer=FALSE; // flag for front buffer rendering
\r
50 GLubyte ubGloAlpha; // texture alpha
\r
51 GLubyte ubGloColAlpha; // color alpha
\r
52 int iFilterType; // type of filter
\r
53 BOOL bFullVRam=FALSE; // sign for tex win
\r
54 BOOL bDrawDither; // sign for dither
\r
55 BOOL bUseMultiPass; // sign for multi pass
\r
56 GLuint gTexName; // binded texture
\r
57 BOOL bTexEnabled; // texture enable flag
\r
58 BOOL bBlendEnable; // blend enable flag
\r
59 PSXRect_t xrUploadArea; // rect to upload
\r
60 PSXRect_t xrUploadAreaIL; // rect to upload
\r
61 PSXRect_t xrUploadAreaRGB24; // rect to upload rgb24
\r
62 int iSpriteTex=0; // flag for "hey, it's a sprite"
\r
63 unsigned short usMirror; // mirror, mirror on the wall
\r
65 BOOL bNeedUploadAfter=FALSE; // sign for uploading in next frame
\r
66 BOOL bNeedUploadTest=FALSE; // sign for upload test
\r
67 BOOL bUsingTWin=FALSE; // tex win active flag
\r
68 BOOL bUsingMovie=FALSE; // movie active flag
\r
69 PSXRect_t xrMovieArea; // rect for movie upload
\r
70 short sSprite_ux2; // needed for sprire adjust
\r
71 short sSprite_vy2; //
\r
72 uint32_t ulOLDCOL=0; // active color
\r
73 uint32_t ulClutID; // clut
\r
75 uint32_t dwCfgFixes; // game fixes
\r
76 uint32_t dwActFixes=0;
\r
77 uint32_t dwEmuFixes=0;
80 int drawX,drawY,drawW,drawH; // offscreen drawing checkers
\r
81 short sxmin,sxmax,symin,symax;
83 ////////////////////////////////////////////////////////////////////////
84 // Update global TP infos
85 ////////////////////////////////////////////////////////////////////////
87 void UpdateGlobalTP(unsigned short gdata)
89 GlobalTextAddrX = (gdata << 6) & 0x3c0;
91 if(iGPUHeight==1024) // ZN mode
\r
93 if(dwGPUVersion==2) // very special zn gpu
\r
95 GlobalTextAddrY =((gdata & 0x60 ) << 3);
\r
96 GlobalTextIL =(gdata & 0x2000) >> 13;
\r
97 GlobalTextABR = (unsigned short)((gdata >> 7) & 0x3);
\r
98 GlobalTextTP = (gdata >> 9) & 0x3;
\r
99 if(GlobalTextTP==3) GlobalTextTP=2;
\r
100 GlobalTexturePage = (GlobalTextAddrX>>6)+(GlobalTextAddrY>>4);
\r
102 STATUSREG = (STATUSREG & 0xffffe000 ) | (gdata & 0x1fff );
\r
105 else // "enhanced" psx gpu
\r
107 GlobalTextAddrY = (unsigned short)(((gdata << 4) & 0x100) | ((gdata >> 2) & 0x200));
\r
110 else GlobalTextAddrY = (gdata << 4) & 0x100; // "normal" psx gpu
\r
112 usMirror=gdata&0x3000;
114 GlobalTextTP = (gdata >> 7) & 0x3; // tex mode (4,8,15)
115 if(GlobalTextTP==3) GlobalTextTP=2; // seen in Wild9 :(
116 GlobalTextABR = (gdata >> 5) & 0x3; // blend mode
118 GlobalTexturePage = (GlobalTextAddrX>>6)+(GlobalTextAddrY>>4);
120 STATUSREG&=~0x07ff; // Clear the necessary bits
121 STATUSREG|=(gdata & 0x07ff); // set the necessary bits
124 unsigned int DoubleBGR2RGB (unsigned int BGR)
126 unsigned int ebx,eax,edx;
128 ebx=(BGR&0x000000ff)<<1;
129 if(ebx&0x00000100) ebx=0x000000ff;
131 eax=(BGR&0x0000ff00)<<1;
132 if(eax&0x00010000) eax=0x0000ff00;
134 edx=(BGR&0x00ff0000)<<1;
135 if(edx&0x01000000) edx=0x00ff0000;
137 return (ebx|eax|edx);
140 unsigned short BGR24to16 (uint32_t BGR)
142 return ((BGR>>3)&0x1f)|((BGR&0xf80000)>>9)|((BGR&0xf800)>>6);
145 ////////////////////////////////////////////////////////////////////////
146 // OpenGL primitive drawing commands
147 ////////////////////////////////////////////////////////////////////////
149 __inline void PRIMdrawTexturedQuad(OGLVertex* vertex1, OGLVertex* vertex2,
150 OGLVertex* vertex3, OGLVertex* vertex4)
152 glBegin(GL_TRIANGLE_STRIP);
153 glTexCoord2fv(&vertex1->sow);
154 glVertex3fv(&vertex1->x);
156 glTexCoord2fv(&vertex2->sow);
157 glVertex3fv(&vertex2->x);
159 glTexCoord2fv(&vertex4->sow);
160 glVertex3fv(&vertex4->x);
162 glTexCoord2fv(&vertex3->sow);
163 glVertex3fv(&vertex3->x);
167 /////////////////////////////////////////////////////////
169 __inline void PRIMdrawTexturedTri(OGLVertex* vertex1, OGLVertex* vertex2,
172 glBegin(GL_TRIANGLES);
173 glTexCoord2fv(&vertex1->sow);
174 glVertex3fv(&vertex1->x);
176 glTexCoord2fv(&vertex2->sow);
177 glVertex3fv(&vertex2->x);
179 glTexCoord2fv(&vertex3->sow);
180 glVertex3fv(&vertex3->x);
184 /////////////////////////////////////////////////////////
186 __inline void PRIMdrawTexGouraudTriColor(OGLVertex* vertex1, OGLVertex* vertex2,
189 glBegin(GL_TRIANGLES);
192 glTexCoord2fv(&vertex1->sow);
193 glVertex3fv(&vertex1->x);
196 glTexCoord2fv(&vertex2->sow);
197 glVertex3fv(&vertex2->x);
200 glTexCoord2fv(&vertex3->sow);
201 glVertex3fv(&vertex3->x);
205 /////////////////////////////////////////////////////////
207 __inline void PRIMdrawTexGouraudTriColorQuad(OGLVertex* vertex1, OGLVertex* vertex2,
208 OGLVertex* vertex3, OGLVertex* vertex4)
210 glBegin(GL_TRIANGLE_STRIP);
212 glTexCoord2fv(&vertex1->sow);
213 glVertex3fv(&vertex1->x);
216 glTexCoord2fv(&vertex2->sow);
217 glVertex3fv(&vertex2->x);
220 glTexCoord2fv(&vertex4->sow);
221 glVertex3fv(&vertex4->x);
224 glTexCoord2fv(&vertex3->sow);
225 glVertex3fv(&vertex3->x);
229 /////////////////////////////////////////////////////////
231 __inline void PRIMdrawTri(OGLVertex* vertex1, OGLVertex* vertex2, OGLVertex* vertex3)
233 glBegin(GL_TRIANGLES);
234 glVertex3fv(&vertex1->x);
235 glVertex3fv(&vertex2->x);
236 glVertex3fv(&vertex3->x);
240 /////////////////////////////////////////////////////////
242 __inline void PRIMdrawTri2(OGLVertex* vertex1, OGLVertex* vertex2,
243 OGLVertex* vertex3, OGLVertex* vertex4)
245 glBegin(GL_TRIANGLE_STRIP);
246 glVertex3fv(&vertex1->x);
247 glVertex3fv(&vertex3->x);
248 glVertex3fv(&vertex2->x);
249 glVertex3fv(&vertex4->x);
253 /////////////////////////////////////////////////////////
255 __inline void PRIMdrawGouraudTriColor(OGLVertex* vertex1, OGLVertex* vertex2,
258 glBegin(GL_TRIANGLES);
260 glVertex3fv(&vertex1->x);
263 glVertex3fv(&vertex2->x);
266 glVertex3fv(&vertex3->x);
270 /////////////////////////////////////////////////////////
272 __inline void PRIMdrawGouraudTri2Color(OGLVertex* vertex1, OGLVertex* vertex2,
273 OGLVertex* vertex3, OGLVertex* vertex4)
275 glBegin(GL_TRIANGLE_STRIP);
277 glVertex3fv(&vertex1->x);
280 glVertex3fv(&vertex3->x);
283 glVertex3fv(&vertex2->x);
286 glVertex3fv(&vertex4->x);
290 /////////////////////////////////////////////////////////
292 __inline void PRIMdrawFlatLine(OGLVertex* vertex1, OGLVertex* vertex2,OGLVertex* vertex3, OGLVertex* vertex4)
298 glVertex3fv(&vertex1->x);
299 glVertex3fv(&vertex2->x);
300 glVertex3fv(&vertex3->x);
301 glVertex3fv(&vertex4->x);
305 /////////////////////////////////////////////////////////
307 __inline void PRIMdrawGouraudLine(OGLVertex* vertex1, OGLVertex* vertex2,OGLVertex* vertex3, OGLVertex* vertex4)
312 glVertex3fv(&vertex1->x);
315 glVertex3fv(&vertex2->x);
318 glVertex3fv(&vertex3->x);
321 glVertex3fv(&vertex4->x);
325 /////////////////////////////////////////////////////////
327 __inline void PRIMdrawQuad(OGLVertex* vertex1, OGLVertex* vertex2,
328 OGLVertex* vertex3, OGLVertex* vertex4)
331 glVertex3fv(&vertex1->x);
332 glVertex3fv(&vertex2->x);
333 glVertex3fv(&vertex3->x);
334 glVertex3fv(&vertex4->x);
338 ////////////////////////////////////////////////////////////////////////
339 // Transparent blending settings
340 ////////////////////////////////////////////////////////////////////////
342 static GLenum obm1=GL_ZERO;
343 static GLenum obm2=GL_ZERO;
345 typedef struct SEMITRANSTAG
352 SemiTransParams TransSets[4]=
354 {GL_SRC_ALPHA,GL_SRC_ALPHA, 127},
355 {GL_ONE, GL_ONE, 255},
356 {GL_ZERO, GL_ONE_MINUS_SRC_COLOR,255},
357 {GL_ONE_MINUS_SRC_ALPHA,GL_ONE, 192}
\r
360 ////////////////////////////////////////////////////////////////////////
362 void SetSemiTrans(void)
371 if(!DrawSemiTrans) // no semi trans at all?
374 {glDisable(GL_BLEND);bBlendEnable=FALSE;} // -> don't wanna blend
375 ubGloAlpha=ubGloColAlpha=255; // -> full alpha
\r
376 return; // -> and bye
379 ubGloAlpha=ubGloColAlpha=TransSets[GlobalTextABR].alpha;
382 {glEnable(GL_BLEND);bBlendEnable=TRUE;} // wanna blend
384 if(TransSets[GlobalTextABR].srcFac!=obm1 ||
385 TransSets[GlobalTextABR].dstFac!=obm2)
387 if(glBlendEquationEXTEx==NULL)
389 obm1=TransSets[GlobalTextABR].srcFac;
390 obm2=TransSets[GlobalTextABR].dstFac;
391 glBlendFunc(obm1,obm2); // set blend func
\r
394 if(TransSets[GlobalTextABR].dstFac !=GL_ONE_MINUS_SRC_COLOR)
396 if(obm2==GL_ONE_MINUS_SRC_COLOR)
397 glBlendEquationEXTEx(FUNC_ADD_EXT);
398 obm1=TransSets[GlobalTextABR].srcFac;
399 obm2=TransSets[GlobalTextABR].dstFac;
400 glBlendFunc(obm1,obm2); // set blend func
\r
404 glBlendEquationEXTEx(FUNC_REVERSESUBTRACT_EXT);
405 obm1=TransSets[GlobalTextABR].srcFac;
406 obm2=TransSets[GlobalTextABR].dstFac;
407 glBlendFunc(GL_ONE,GL_ONE); // set blend func
\r
412 void SetScanTrans(void) // blending for scan lines
\r
414 if(glBlendEquationEXTEx!=NULL)
416 if(obm2==GL_ONE_MINUS_SRC_COLOR)
417 glBlendEquationEXTEx(FUNC_ADD_EXT);
420 obm1=TransSets[0].srcFac;
421 obm2=TransSets[0].dstFac;
422 glBlendFunc(obm1,obm2); // set blend func
\r
425 void SetScanTexTrans(void) // blending for scan mask texture
\r
427 if(glBlendEquationEXTEx!=NULL)
429 if(obm2==GL_ONE_MINUS_SRC_COLOR)
430 glBlendEquationEXTEx(FUNC_ADD_EXT);
433 obm1=TransSets[2].srcFac;
434 obm2=TransSets[2].dstFac;
435 glBlendFunc(obm1,obm2); // set blend func
\r
438 ////////////////////////////////////////////////////////////////////////
439 // multi pass in old 'Advanced blending' mode... got it from Lewpy :)
440 ////////////////////////////////////////////////////////////////////////
442 SemiTransParams MultiTexTransSets[4][2]=
445 {GL_ONE ,GL_SRC_ALPHA, 127},
446 {GL_SRC_ALPHA,GL_ONE, 127}
449 {GL_ONE, GL_SRC_ALPHA, 255},
450 {GL_SRC_ALPHA,GL_ONE, 255}
453 {GL_ZERO, GL_ONE_MINUS_SRC_COLOR,255},
454 {GL_ZERO, GL_ONE_MINUS_SRC_COLOR,255}
457 {GL_SRC_ALPHA,GL_ONE, 127},
458 {GL_ONE_MINUS_SRC_ALPHA,GL_ONE, 255}
462 ////////////////////////////////////////////////////////////////////////
464 SemiTransParams MultiColTransSets[4]=
466 {GL_ONE_MINUS_SRC_ALPHA,GL_SRC_ALPHA,127},
467 {GL_ONE, GL_ONE, 255},
468 {GL_ZERO, GL_ONE_MINUS_SRC_COLOR,255},
469 {GL_SRC_ALPHA,GL_ONE, 127}
472 ////////////////////////////////////////////////////////////////////////
474 void SetSemiTransMulti(int Pass)
476 static GLenum bm1=GL_ZERO;
477 static GLenum bm2=GL_ONE;
482 // are we enabling SemiTransparent mode?
487 bm1=MultiTexTransSets[GlobalTextABR][Pass].srcFac;
488 bm2=MultiTexTransSets[GlobalTextABR][Pass].dstFac;
489 ubGloAlpha=MultiTexTransSets[GlobalTextABR][Pass].alpha;
494 bm1=MultiColTransSets[GlobalTextABR].srcFac;
495 bm2=MultiColTransSets[GlobalTextABR].dstFac;
496 ubGloColAlpha=MultiColTransSets[GlobalTextABR].alpha;
505 bm1=GL_ONE;bm2=GL_ZERO;
509 // disable blending, but add src col a second time
510 bm1=GL_ONE;bm2=GL_ONE;
515 {glEnable(GL_BLEND);bBlendEnable=TRUE;} // wanna blend
\r
517 if(bm1!=obm1 || bm2!=obm2)
519 glBlendFunc(bm1,bm2); // set blend func
\r
524 ////////////////////////////////////////////////////////////////////////
525 // Set several rendering stuff including blending
526 ////////////////////////////////////////////////////////////////////////
528 __inline void SetZMask3O(void)
530 if(iUseMask && DrawSemiTrans && !iSetMask)
532 vertex[0].z=vertex[1].z=vertex[2].z=gl_z;
537 __inline void SetZMask3(void)
541 if(iSetMask || DrawSemiTrans)
542 {vertex[0].z=vertex[1].z=vertex[2].z=0.95f;}
545 vertex[0].z=vertex[1].z=vertex[2].z=gl_z;
551 __inline void SetZMask3NT(void)
556 {vertex[0].z=vertex[1].z=vertex[2].z=0.95f;}
559 vertex[0].z=vertex[1].z=vertex[2].z=gl_z;
565 ////////////////////////////////////////////////////////////////////////
567 __inline void SetZMask4O(void)
569 if(iUseMask && DrawSemiTrans && !iSetMask)
571 vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
576 __inline void SetZMask4(void)
580 if(iSetMask || DrawSemiTrans)
581 {vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=0.95f;}
584 vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
590 __inline void SetZMask4NT(void)
595 {vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=0.95f;}
598 vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
604 __inline void SetZMask4SP(void)
\r
609 {vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=0.95f;}
\r
614 vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=gl_z;
\r
618 {vertex[0].z=vertex[1].z=vertex[2].z=vertex[3].z=0.95f;}
\r
623 ////////////////////////////////////////////////////////////////////////
625 __inline void SetRenderState(uint32_t DrawAttributes)
627 bDrawNonShaded = (SHADETEXBIT(DrawAttributes)) ? TRUE : FALSE;
628 DrawSemiTrans = (SEMITRANSBIT(DrawAttributes)) ? TRUE : FALSE;
631 ////////////////////////////////////////////////////////////////////////
633 __inline void SetRenderColor(uint32_t DrawAttributes)
635 if(bDrawNonShaded) {g_m1=g_m2=g_m3=128;}
638 g_m1=DrawAttributes&0xff;
639 g_m2=(DrawAttributes>>8)&0xff;
640 g_m3=(DrawAttributes>>16)&0xff;
644 ////////////////////////////////////////////////////////////////////////
646 void SetRenderMode(uint32_t DrawAttributes, BOOL bSCol)
648 if((bUseMultiPass) && (bDrawTextured) && !(bDrawNonShaded))
649 {bDrawMultiPass = TRUE; SetSemiTransMulti(0);}
650 else {bDrawMultiPass = FALSE;SetSemiTrans();}
652 if(bDrawTextured) // texture ? build it/get it from cache
655 if(bUsingTWin) currTex=LoadTextureWnd(GlobalTexturePage,GlobalTextTP, ulClutID);
656 else if(bUsingMovie) currTex=LoadTextureMovie();
657 else currTex=SelectSubTextureS(GlobalTextTP,ulClutID);
659 if(gTexName!=currTex)
660 {gTexName=currTex;glBindTexture(GL_TEXTURE_2D,currTex);}
662 if(!bTexEnabled) // -> turn texturing on
663 {bTexEnabled=TRUE;glEnable(GL_TEXTURE_2D);}
667 {bTexEnabled=FALSE;glDisable(GL_TEXTURE_2D);} // -> turn texturing off
669 if(bSCol) // also set color ?
671 if((dwActFixes&4) && ((DrawAttributes&0x00ffffff)==0))
672 DrawAttributes|=0x007f7f7f;
674 if(bDrawNonShaded) // -> non shaded?
\r
676 if(bGLBlend) vertex[0].c.lcol=0x7f7f7f; // --> solid color...
\r
677 else vertex[0].c.lcol=0xffffff;
681 if(!bUseMultiPass && !bGLBlend) // --> given color...
\r
682 vertex[0].c.lcol=DoubleBGR2RGB(DrawAttributes);
683 else vertex[0].c.lcol=DrawAttributes;
685 vertex[0].c.col[3]=ubGloAlpha; // -> set color with
\r
686 SETCOL(vertex[0]); // texture alpha
689 if(bDrawSmoothShaded!=bOldSmoothShaded) // shading changed?
\r
691 if(bDrawSmoothShaded) glShadeModel(GL_SMOOTH); // -> set actual shading
\r
692 else glShadeModel(GL_FLAT);
693 bOldSmoothShaded=bDrawSmoothShaded;
697 ////////////////////////////////////////////////////////////////////////
698 // Set Opaque multipass color
699 ////////////////////////////////////////////////////////////////////////
701 void SetOpaqueColor(uint32_t DrawAttributes)
703 if(bDrawNonShaded) return; // no shading? bye
\r
705 DrawAttributes=DoubleBGR2RGB(DrawAttributes); // multipass is just half color, so double it on opaque pass
706 vertex[0].c.lcol=DrawAttributes|0xff000000;
707 SETCOL(vertex[0]); // set color
710 ////////////////////////////////////////////////////////////////////////
711 // Fucking stupid screen coord checking
712 ////////////////////////////////////////////////////////////////////////
714 BOOL ClipVertexListScreen(void)
716 if (lx0 >= PSXDisplay.DisplayEnd.x) goto NEXTSCRTEST;
717 if (ly0 >= PSXDisplay.DisplayEnd.y) goto NEXTSCRTEST;
718 if (lx2 < PSXDisplay.DisplayPosition.x) goto NEXTSCRTEST;
719 if (ly2 < PSXDisplay.DisplayPosition.y) goto NEXTSCRTEST;
724 if(PSXDisplay.InterlacedTest) return FALSE;
726 if (lx0 >= PreviousPSXDisplay.DisplayEnd.x) return FALSE;
727 if (ly0 >= PreviousPSXDisplay.DisplayEnd.y) return FALSE;
728 if (lx2 < PreviousPSXDisplay.DisplayPosition.x) return FALSE;
729 if (ly2 < PreviousPSXDisplay.DisplayPosition.y) return FALSE;
734 ////////////////////////////////////////////////////////////////////////
736 BOOL bDrawOffscreenFront(void)
738 if(sxmin < PSXDisplay.DisplayPosition.x) return FALSE; // must be complete in front
739 if(symin < PSXDisplay.DisplayPosition.y) return FALSE;
740 if(sxmax > PSXDisplay.DisplayEnd.x) return FALSE;
741 if(symax > PSXDisplay.DisplayEnd.y) return FALSE;
745 BOOL bOnePointInFront(void)
747 if(sxmax< PSXDisplay.DisplayPosition.x)
750 if(symax< PSXDisplay.DisplayPosition.y)
753 if(sxmin>=PSXDisplay.DisplayEnd.x)
756 if(symin>=PSXDisplay.DisplayEnd.y)
763 BOOL bOnePointInBack(void)
765 if(sxmax< PreviousPSXDisplay.DisplayPosition.x)
768 if(symax< PreviousPSXDisplay.DisplayPosition.y)
771 if(sxmin>=PreviousPSXDisplay.DisplayEnd.x)
774 if(symin>=PreviousPSXDisplay.DisplayEnd.y)
780 BOOL bDrawOffscreen4(void)
782 BOOL bFront;short sW,sH;
784 sxmax=max(lx0,max(lx1,max(lx2,lx3)));
785 if(sxmax<drawX) return FALSE;
786 sxmin=min(lx0,min(lx1,min(lx2,lx3)));
787 if(sxmin>drawW) return FALSE;
788 symax=max(ly0,max(ly1,max(ly2,ly3)));
789 if(symax<drawY) return FALSE;
790 symin=min(ly0,min(ly1,min(ly2,ly3)));
791 if(symin>drawH) return FALSE;
793 if(PSXDisplay.Disabled) return TRUE; // disabled? ever
795 if(iOffscreenDrawing==1) return bFullVRam;
797 if(dwActFixes&1 && iOffscreenDrawing==4)
799 if(PreviousPSXDisplay.DisplayPosition.x==PSXDisplay.DisplayPosition.x &&
800 PreviousPSXDisplay.DisplayPosition.y==PSXDisplay.DisplayPosition.y &&
801 PreviousPSXDisplay.DisplayEnd.x==PSXDisplay.DisplayEnd.x &&
802 PreviousPSXDisplay.DisplayEnd.y==PSXDisplay.DisplayEnd.y)
804 bRenderFrontBuffer=TRUE;
809 sW=drawW-1;sH=drawH-1;
811 sxmin=min(sW,max(sxmin,drawX));
812 sxmax=max(drawX,min(sxmax,sW));
813 symin=min(sH,max(symin,drawY));
814 symax=max(drawY,min(symax,sH));
816 if(bOnePointInBack()) return bFullVRam;
818 if(iOffscreenDrawing==2)
819 bFront=bDrawOffscreenFront();
820 else bFront=bOnePointInFront();
824 if(PSXDisplay.InterlacedTest) return bFullVRam; // -> ok, no need for adjust
826 vertex[0].x=lx0 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;
827 vertex[1].x=lx1 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;
828 vertex[2].x=lx2 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;
829 vertex[3].x=lx3 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;
830 vertex[0].y=ly0 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;
831 vertex[1].y=ly1 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;
832 vertex[2].y=ly2 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;
833 vertex[3].y=ly3 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;
835 if(iOffscreenDrawing==4 && !(dwActFixes&1)) // -> frontbuffer wanted
\r
837 bRenderFrontBuffer=TRUE;
840 return bFullVRam; // -> but no od
\r
846 ////////////////////////////////////////////////////////////////////////
848 BOOL bDrawOffscreen3(void)
850 BOOL bFront;short sW,sH;
852 sxmax=max(lx0,max(lx1,lx2));
853 if(sxmax<drawX) return FALSE;
854 sxmin=min(lx0,min(lx1,lx2));
855 if(sxmin>drawW) return FALSE;
856 symax=max(ly0,max(ly1,ly2));
857 if(symax<drawY) return FALSE;
858 symin=min(ly0,min(ly1,ly2));
859 if(symin>drawH) return FALSE;
861 if(PSXDisplay.Disabled) return TRUE; // disabled? ever
\r
863 if(iOffscreenDrawing==1) return bFullVRam;
865 sW=drawW-1;sH=drawH-1;
866 sxmin=min(sW,max(sxmin,drawX));
867 sxmax=max(drawX,min(sxmax,sW));
868 symin=min(sH,max(symin,drawY));
869 symax=max(drawY,min(symax,sH));
871 if(bOnePointInBack()) return bFullVRam;
873 if(iOffscreenDrawing==2)
874 bFront=bDrawOffscreenFront();
875 else bFront=bOnePointInFront();
879 if(PSXDisplay.InterlacedTest) return bFullVRam; // -> ok, no need for adjust
\r
881 vertex[0].x=lx0 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;
882 vertex[1].x=lx1 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;
883 vertex[2].x=lx2 - PSXDisplay.DisplayPosition.x+PreviousPSXDisplay.Range.x0;
884 vertex[0].y=ly0 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;
885 vertex[1].y=ly1 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;
886 vertex[2].y=ly2 - PSXDisplay.DisplayPosition.y+PreviousPSXDisplay.Range.y0;
888 if(iOffscreenDrawing==4) // -> frontbuffer wanted
\r
890 bRenderFrontBuffer=TRUE;
894 return bFullVRam; // -> but no od
\r
900 ////////////////////////////////////////////////////////////////////////
902 BOOL FastCheckAgainstScreen(short imageX0,short imageY0,short imageX1,short imageY1)
904 PSXRect_t xUploadArea;
909 if (imageX0 < PreviousPSXDisplay.DisplayPosition.x)
910 xUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x;
912 if (imageX0 > PreviousPSXDisplay.DisplayEnd.x)
913 xUploadArea.x0 = PreviousPSXDisplay.DisplayEnd.x;
915 xUploadArea.x0 = imageX0;
917 if(imageX1 < PreviousPSXDisplay.DisplayPosition.x)
918 xUploadArea.x1 = PreviousPSXDisplay.DisplayPosition.x;
920 if (imageX1 > PreviousPSXDisplay.DisplayEnd.x)
921 xUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x;
923 xUploadArea.x1 = imageX1;
925 if (imageY0 < PreviousPSXDisplay.DisplayPosition.y)
926 xUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y;
928 if (imageY0 > PreviousPSXDisplay.DisplayEnd.y)
929 xUploadArea.y0 = PreviousPSXDisplay.DisplayEnd.y;
931 xUploadArea.y0 = imageY0;
933 if (imageY1 < PreviousPSXDisplay.DisplayPosition.y)
934 xUploadArea.y1 = PreviousPSXDisplay.DisplayPosition.y;
936 if (imageY1 > PreviousPSXDisplay.DisplayEnd.y)
937 xUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y;
939 xUploadArea.y1 = imageY1;
941 if ((xUploadArea.x0 != xUploadArea.x1) && (xUploadArea.y0 != xUploadArea.y1))
946 BOOL CheckAgainstScreen(short imageX0,short imageY0,short imageX1,short imageY1)
951 if (imageX0 < PreviousPSXDisplay.DisplayPosition.x)
952 xrUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x;
954 if (imageX0 > PreviousPSXDisplay.DisplayEnd.x)
955 xrUploadArea.x0 = PreviousPSXDisplay.DisplayEnd.x;
957 xrUploadArea.x0 = imageX0;
959 if(imageX1 < PreviousPSXDisplay.DisplayPosition.x)
960 xrUploadArea.x1 = PreviousPSXDisplay.DisplayPosition.x;
962 if (imageX1 > PreviousPSXDisplay.DisplayEnd.x)
963 xrUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x;
965 xrUploadArea.x1 = imageX1;
967 if (imageY0 < PreviousPSXDisplay.DisplayPosition.y)
968 xrUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y;
970 if (imageY0 > PreviousPSXDisplay.DisplayEnd.y)
971 xrUploadArea.y0 = PreviousPSXDisplay.DisplayEnd.y;
973 xrUploadArea.y0 = imageY0;
975 if (imageY1 < PreviousPSXDisplay.DisplayPosition.y)
976 xrUploadArea.y1 = PreviousPSXDisplay.DisplayPosition.y;
978 if (imageY1 > PreviousPSXDisplay.DisplayEnd.y)
979 xrUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y;
981 xrUploadArea.y1 = imageY1;
983 if ((xrUploadArea.x0 != xrUploadArea.x1) && (xrUploadArea.y0 != xrUploadArea.y1))
988 BOOL FastCheckAgainstFrontScreen(short imageX0,short imageY0,short imageX1,short imageY1)
990 PSXRect_t xUploadArea;
995 if (imageX0 < PSXDisplay.DisplayPosition.x)
996 xUploadArea.x0 = PSXDisplay.DisplayPosition.x;
998 if (imageX0 > PSXDisplay.DisplayEnd.x)
999 xUploadArea.x0 = PSXDisplay.DisplayEnd.x;
1001 xUploadArea.x0 = imageX0;
1003 if(imageX1 < PSXDisplay.DisplayPosition.x)
1004 xUploadArea.x1 = PSXDisplay.DisplayPosition.x;
1006 if (imageX1 > PSXDisplay.DisplayEnd.x)
1007 xUploadArea.x1 = PSXDisplay.DisplayEnd.x;
1009 xUploadArea.x1 = imageX1;
1011 if (imageY0 < PSXDisplay.DisplayPosition.y)
1012 xUploadArea.y0 = PSXDisplay.DisplayPosition.y;
1014 if (imageY0 > PSXDisplay.DisplayEnd.y)
1015 xUploadArea.y0 = PSXDisplay.DisplayEnd.y;
1017 xUploadArea.y0 = imageY0;
1019 if (imageY1 < PSXDisplay.DisplayPosition.y)
1020 xUploadArea.y1 = PSXDisplay.DisplayPosition.y;
1022 if (imageY1 > PSXDisplay.DisplayEnd.y)
1023 xUploadArea.y1 = PSXDisplay.DisplayEnd.y;
1025 xUploadArea.y1 = imageY1;
1027 if ((xUploadArea.x0 != xUploadArea.x1) && (xUploadArea.y0 != xUploadArea.y1))
1032 BOOL CheckAgainstFrontScreen(short imageX0,short imageY0,short imageX1,short imageY1)
1037 if (imageX0 < PSXDisplay.DisplayPosition.x)
1038 xrUploadArea.x0 = PSXDisplay.DisplayPosition.x;
1040 if (imageX0 > PSXDisplay.DisplayEnd.x)
1041 xrUploadArea.x0 = PSXDisplay.DisplayEnd.x;
1043 xrUploadArea.x0 = imageX0;
1045 if(imageX1 < PSXDisplay.DisplayPosition.x)
1046 xrUploadArea.x1 = PSXDisplay.DisplayPosition.x;
1048 if (imageX1 > PSXDisplay.DisplayEnd.x)
1049 xrUploadArea.x1 = PSXDisplay.DisplayEnd.x;
1051 xrUploadArea.x1 = imageX1;
1053 if (imageY0 < PSXDisplay.DisplayPosition.y)
1054 xrUploadArea.y0 = PSXDisplay.DisplayPosition.y;
1056 if (imageY0 > PSXDisplay.DisplayEnd.y)
1057 xrUploadArea.y0 = PSXDisplay.DisplayEnd.y;
1059 xrUploadArea.y0 = imageY0;
1061 if (imageY1 < PSXDisplay.DisplayPosition.y)
1062 xrUploadArea.y1 = PSXDisplay.DisplayPosition.y;
1064 if (imageY1 > PSXDisplay.DisplayEnd.y)
1065 xrUploadArea.y1 = PSXDisplay.DisplayEnd.y;
1067 xrUploadArea.y1 = imageY1;
1069 if ((xrUploadArea.x0 != xrUploadArea.x1) && (xrUploadArea.y0 != xrUploadArea.y1))
1074 ////////////////////////////////////////////////////////////////////////
1076 void PrepareFullScreenUpload (int Position)
1078 if (Position==-1) // rgb24
1080 if(PSXDisplay.Interlaced)
1082 xrUploadArea.x0 = PSXDisplay.DisplayPosition.x;
1083 xrUploadArea.x1 = PSXDisplay.DisplayEnd.x;
1084 xrUploadArea.y0 = PSXDisplay.DisplayPosition.y;
1085 xrUploadArea.y1 = PSXDisplay.DisplayEnd.y;
1089 xrUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x;
1090 xrUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x;
1091 xrUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y;
1092 xrUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y;
1095 if(bNeedRGB24Update)
1102 if(PSXDisplay.Interlaced && PreviousPSXDisplay.RGB24<2) // in interlaced mode we upload at least two full frames (GT1 menu)
\r
1104 PreviousPSXDisplay.RGB24++;
1108 xrUploadArea.y1 = min(xrUploadArea.y0+xrUploadAreaRGB24.y1,xrUploadArea.y1);
1109 xrUploadArea.y0+=xrUploadAreaRGB24.y0;
1116 xrUploadArea.x0 = PSXDisplay.DisplayPosition.x;
1117 xrUploadArea.x1 = PSXDisplay.DisplayEnd.x;
1118 xrUploadArea.y0 = PSXDisplay.DisplayPosition.y;
1119 xrUploadArea.y1 = PSXDisplay.DisplayEnd.y;
1123 xrUploadArea.x0 = PreviousPSXDisplay.DisplayPosition.x;
1124 xrUploadArea.x1 = PreviousPSXDisplay.DisplayEnd.x;
1125 xrUploadArea.y0 = PreviousPSXDisplay.DisplayPosition.y;
1126 xrUploadArea.y1 = PreviousPSXDisplay.DisplayEnd.y;
1129 if (xrUploadArea.x0 < 0) xrUploadArea.x0 = 0;
1131 if (xrUploadArea.x0 > 1023) xrUploadArea.x0 = 1023;
1133 if (xrUploadArea.x1 < 0) xrUploadArea.x1 = 0;
1135 if (xrUploadArea.x1 > 1024) xrUploadArea.x1 = 1024;
1137 if (xrUploadArea.y0 < 0) xrUploadArea.y0 = 0;
1139 if (xrUploadArea.y0 > iGPUHeightMask) xrUploadArea.y0 = iGPUHeightMask;
1141 if (xrUploadArea.y1 < 0) xrUploadArea.y1 = 0;
1143 if (xrUploadArea.y1 > iGPUHeight) xrUploadArea.y1 = iGPUHeight;
1145 if (PSXDisplay.RGB24)
1147 InvalidateTextureArea(xrUploadArea.x0,xrUploadArea.y0,xrUploadArea.x1-xrUploadArea.x0,xrUploadArea.y1-xrUploadArea.y0);
1151 ////////////////////////////////////////////////////////////////////////
1152 // Upload screen (MDEC and such)
1153 ////////////////////////////////////////////////////////////////////////
1154 ////////////////////////////////////////////////////////////////////////
1156 unsigned char * LoadDirectMovieFast(void);
\r
1158 void UploadScreenEx(int Position)
\r
1160 short ya,yb,xa,xb,x, y, YStep, XStep, U, UStep,ux[4],vy[4];
\r
1162 if(!PSXDisplay.DisplayMode.x) return;
\r
1163 if(!PSXDisplay.DisplayMode.y) return;
\r
1165 glDisable(GL_SCISSOR_TEST);
\r
1166 glShadeModel(GL_FLAT);
\r
1167 bOldSmoothShaded=FALSE;
\r
1168 glDisable(GL_BLEND);
\r
1169 bBlendEnable=FALSE;
\r
1170 glDisable(GL_TEXTURE_2D);
\r
1171 bTexEnabled=FALSE;
\r
1172 glDisable(GL_ALPHA_TEST);
\r
1174 glPixelZoom(((float)rRatioRect.right)/((float)PSXDisplay.DisplayMode.x),
\r
1175 -1.0f*(((float)rRatioRect.bottom)/((float)PSXDisplay.DisplayMode.y)));
\r
1177 //----------------------------------------------------//
\r
1179 YStep = 256; // max texture size
\r
1181 UStep = (PSXDisplay.RGB24 ? 128 : 0);
\r
1182 ya = xrUploadArea.y0;
\r
1183 yb = xrUploadArea.y1;
\r
1184 xa = xrUploadArea.x0;
\r
1185 xb = xrUploadArea.x1;
\r
1187 for(y=ya;y<=yb;y+=YStep) // loop y
\r
1190 for(x=xa;x<=xb;x+=XStep) // loop x
\r
1192 ly0 = ly1 = y; // -> get y coords
\r
1194 if (ly2 > yb) ly2 = yb;
\r
1197 lx0 = lx3 = x; // -> get x coords
\r
1199 if (lx1 > xb) lx1 = xb;
\r
1203 ux[0]=ux[3]=(xa - x); // -> set tex x coords
\r
1204 if (ux[0] < 0) ux[0]=ux[3]=0;
\r
1205 ux[2]=ux[1]=(xb - x);
\r
1206 if (ux[2] > 256) ux[2]=ux[1]=256;
\r
1208 vy[0]=vy[1]=(ya - y); // -> set tex y coords
\r
1209 if (vy[0] < 0) vy[0]=vy[1]=0;
\r
1210 vy[2]=vy[3]=(yb - y);
\r
1211 if (vy[2] > 256) vy[2]=vy[3]=256;
\r
1213 if ((ux[0] >= ux[2]) || // -> cheaters never win...
\r
1214 (vy[0] >= vy[2])) continue; // (but winners always cheat...)
\r
1216 xrMovieArea.x0=lx0+U; xrMovieArea.y0=ly0;
\r
1217 xrMovieArea.x1=lx2+U; xrMovieArea.y1=ly2;
\r
1219 offsetScreenUpload(Position);
\r
1221 glRasterPos2f(vertex[0].x,vertex[0].y);
\r
1223 glDrawPixels(xrMovieArea.x1-xrMovieArea.x0,
\r
1224 xrMovieArea.y1-xrMovieArea.y0,
\r
1225 GL_RGBA,GL_UNSIGNED_BYTE,
\r
1226 LoadDirectMovieFast());
\r
1232 //----------------------------------------------------//
\r
1234 glPixelZoom(1.0F,1.0F);
\r
1236 glEnable(GL_ALPHA_TEST);
\r
1237 glEnable(GL_SCISSOR_TEST);
\r
1240 ////////////////////////////////////////////////////////////////////////
\r
1242 void UploadScreen(int Position)
1244 short x, y, YStep, XStep, U, s, UStep,ux[4],vy[4];
1247 if(xrUploadArea.x0>1023) xrUploadArea.x0=1023;
1248 if(xrUploadArea.x1>1024) xrUploadArea.x1=1024;
1249 if(xrUploadArea.y0>iGPUHeightMask) xrUploadArea.y0=iGPUHeightMask;
\r
1250 if(xrUploadArea.y1>iGPUHeight) xrUploadArea.y1=iGPUHeight;
\r
1252 if(xrUploadArea.x0==xrUploadArea.x1) return;
1253 if(xrUploadArea.y0==xrUploadArea.y1) return;
1255 if(PSXDisplay.Disabled && iOffscreenDrawing<4) return;
1257 iDrawnSomething = 2;
\r
1258 iLastRGB24=PSXDisplay.RGB24+1;
\r
1260 if(bSkipNextFrame) return;
\r
1262 if(dwActFixes & 2) {UploadScreenEx(Position);return;}
\r
1265 bDrawTextured = TRUE; // just doing textures
\r
1266 bDrawSmoothShaded = FALSE;
1268 if(bGLBlend) vertex[0].c.lcol=0xff7f7f7f; // set solid col
\r
1269 else vertex[0].c.lcol=0xffffffff;
1272 SetOGLDisplaySettings(0);
1274 YStep = 256; // max texture size
1277 UStep = (PSXDisplay.RGB24 ? 128 : 0);
1284 for(y=ya;y<=yb;y+=YStep) // loop y
\r
1287 for(x=xa;x<=xb;x+=XStep) // loop x
\r
1289 ly0 = ly1 = y; // -> get y coords
1291 if (ly2 > yb) ly2 = yb;
1294 lx0 = lx3 = x; // -> get x coords
1296 if (lx1 > xb) lx1 = xb;
1300 ux[0]=ux[3]=(xa - x); // -> set tex x coords
\r
1301 if (ux[0] < 0) ux[0]=ux[3]=0;
1302 ux[2]=ux[1]=(xb - x);
1303 if (ux[2] > 256) ux[2]=ux[1]=256;
1305 vy[0]=vy[1]=(ya - y); // -> set tex y coords
\r
1306 if (vy[0] < 0) vy[0]=vy[1]=0;
1307 vy[2]=vy[3]=(yb - y);
1308 if (vy[2] > 256) vy[2]=vy[3]=256;
1310 if ((ux[0] >= ux[2]) || // -> cheaters never win...
\r
1311 (vy[0] >= vy[2])) continue; // (but winners always cheat...)
1313 xrMovieArea.x0=lx0+U; xrMovieArea.y0=ly0;
1314 xrMovieArea.x1=lx2+U; xrMovieArea.y1=ly2;
1316 s=ux[2] - ux[0]; if(s>255) s=255;
1318 gl_ux[2] = gl_ux[1] = s;
1319 s=vy[2] - vy[0]; if(s>255) s=255;
1320 gl_vy[2] = gl_vy[3] = s;
1321 gl_ux[0] = gl_ux[3] = gl_vy[0] = gl_vy[1] = 0;
1323 SetRenderState((uint32_t)0x01000000);
1324 SetRenderMode((uint32_t)0x01000000, FALSE); // upload texture data
1325 offsetScreenUpload(Position);
1326 assignTextureVRAMWrite();
1328 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
1334 bUsingMovie=FALSE; // done...
\r
1335 bDisplayNotSet = TRUE;
1338 ////////////////////////////////////////////////////////////////////////
1339 // Detect next screen
1340 ////////////////////////////////////////////////////////////////////////
1342 BOOL IsCompleteInsideNextScreen(short x, short y, short xoff, short yoff)
1344 if (x > PSXDisplay.DisplayPosition.x+1) return FALSE;
1345 if ((x + xoff) < PSXDisplay.DisplayEnd.x-1) return FALSE;
1347 if (y >= PSXDisplay.DisplayPosition.y &&
1348 y <= PSXDisplay.DisplayEnd.y )
1350 if ((yoff) >= PSXDisplay.DisplayPosition.y &&
1351 (yoff) <= PSXDisplay.DisplayEnd.y ) return TRUE;
1353 if (y > PSXDisplay.DisplayPosition.y+1) return FALSE;
1354 if (yoff < PSXDisplay.DisplayEnd.y-1) return FALSE;
1358 BOOL IsPrimCompleteInsideNextScreen(short x, short y, short xoff, short yoff)
1360 x+=PSXDisplay.DrawOffset.x;
1361 if (x > PSXDisplay.DisplayPosition.x+1) return FALSE;
1362 y+=PSXDisplay.DrawOffset.y;
1363 if (y > PSXDisplay.DisplayPosition.y+1) return FALSE;
1364 xoff+=PSXDisplay.DrawOffset.x;
1365 if (xoff < PSXDisplay.DisplayEnd.x-1) return FALSE;
1366 yoff+=PSXDisplay.DrawOffset.y;
1367 if (yoff < PSXDisplay.DisplayEnd.y-1) return FALSE;
1371 BOOL IsInsideNextScreen(short x, short y, short xoff, short yoff)
1373 if (x > PSXDisplay.DisplayEnd.x) return FALSE;
1374 if (y > PSXDisplay.DisplayEnd.y) return FALSE;
1375 if ((x + xoff) < PSXDisplay.DisplayPosition.x) return FALSE;
1376 if ((y + yoff) < PSXDisplay.DisplayPosition.y) return FALSE;
1380 ////////////////////////////////////////////////////////////////////////
1382 ////////////////////////////////////////////////////////////////////////
1384 //Mask1 Set mask bit while drawing. 1 = on
1385 //Mask2 Do not draw to mask areas. 1= on
1387 void cmdSTP(unsigned char * baseAddr)
1389 uint32_t gdata = ((uint32_t*)baseAddr)[0];
1391 STATUSREG&=~0x1800; // clear the necessary bits
1392 STATUSREG|=((gdata & 0x03) << 11); // set the current bits
1394 if(!iUseMask) return;
1396 if(gdata&1) {sSetMask=0x8000;lSetMask=0x80008000;iSetMask=1;}
\r
1397 else {sSetMask=0; lSetMask=0; iSetMask=0;}
\r
1401 if(!(gdata&1)) iSetMask=2;
\r
1403 if(iDepthFunc==0) return;
\r
1405 glDepthFunc(GL_LESS);
\r
1410 if(iDepthFunc==1) return;
\r
1411 glDepthFunc(GL_ALWAYS);
\r
1416 ////////////////////////////////////////////////////////////////////////
1417 // cmd: Set texture page infos
1418 ////////////////////////////////////////////////////////////////////////
1420 void cmdTexturePage(unsigned char * baseAddr)
1422 uint32_t gdata = ((uint32_t *)baseAddr)[0];
1423 UpdateGlobalTP((unsigned short)gdata);
1424 GlobalTextREST = (gdata&0x00ffffff)>>9;
1427 ////////////////////////////////////////////////////////////////////////
1428 // cmd: turn on/off texture window
1429 ////////////////////////////////////////////////////////////////////////
1431 void cmdTextureWindow(unsigned char *baseAddr)
1433 uint32_t gdata = ((uint32_t *)baseAddr)[0];
\r
1434 uint32_t YAlign,XAlign;
\r
1436 ulGPUInfoVals[INFO_TW]=gdata&0xFFFFF;
\r
1439 TWin.Position.y1 = 8; // xxxx1
\r
1440 else if (gdata & 0x040)
\r
1441 TWin.Position.y1 = 16; // xxx10
\r
1442 else if (gdata & 0x080)
\r
1443 TWin.Position.y1 = 32; // xx100
\r
1444 else if (gdata & 0x100)
\r
1445 TWin.Position.y1 = 64; // x1000
\r
1446 else if (gdata & 0x200)
\r
1447 TWin.Position.y1 = 128; // 10000
\r
1449 TWin.Position.y1 = 256; // 00000
\r
1451 // Texture window size is determined by the least bit set of the relevant 5 bits
\r
1453 if (gdata & 0x001)
\r
1454 TWin.Position.x1 = 8; // xxxx1
\r
1455 else if (gdata & 0x002)
\r
1456 TWin.Position.x1 = 16; // xxx10
\r
1457 else if (gdata & 0x004)
\r
1458 TWin.Position.x1 = 32; // xx100
\r
1459 else if (gdata & 0x008)
\r
1460 TWin.Position.x1 = 64; // x1000
\r
1461 else if (gdata & 0x010)
\r
1462 TWin.Position.x1 = 128; // 10000
\r
1464 TWin.Position.x1 = 256; // 00000
\r
1466 // Re-calculate the bit field, because we can't trust what is passed in the data
\r
1468 YAlign = (uint32_t)(32 - (TWin.Position.y1 >> 3));
\r
1469 XAlign = (uint32_t)(32 - (TWin.Position.x1 >> 3));
\r
1471 // Absolute position of the start of the texture window
\r
1473 TWin.Position.y0 = (short)(((gdata >> 15) & YAlign) << 3);
\r
1474 TWin.Position.x0 = (short)(((gdata >> 10) & XAlign) << 3);
\r
1476 if((TWin.Position.x0 == 0 && // tw turned off
\r
1477 TWin.Position.y0 == 0 &&
1478 TWin.Position.x1 == 0 &&
1479 TWin.Position.y1 == 0) ||
1480 (TWin.Position.x1 == 256 &&
1481 TWin.Position.y1 == 256))
1483 bUsingTWin = FALSE; // -> just do it
\r
1486 TWin.UScaleFactor = 1.0f;
1487 TWin.VScaleFactor = 1.0f;
1490 TWin.VScaleFactor = 1.0f/256.0f;
1493 else // tw turned on
1497 TWin.OPosition.y1 = TWin.Position.y1; // -> get psx sizes
1498 TWin.OPosition.x1 = TWin.Position.x1;
1500 if(TWin.Position.x1<=2) TWin.Position.x1=2; // -> set OGL sizes
1502 if(TWin.Position.x1<=4) TWin.Position.x1=4;
1504 if(TWin.Position.x1<=8) TWin.Position.x1=8;
1506 if(TWin.Position.x1<=16) TWin.Position.x1=16;
1508 if(TWin.Position.x1<=32) TWin.Position.x1=32;
1510 if(TWin.Position.x1<=64) TWin.Position.x1=64;
1512 if(TWin.Position.x1<=128) TWin.Position.x1=128;
1514 if(TWin.Position.x1<=256) TWin.Position.x1=256;
1516 if(TWin.Position.y1<=2) TWin.Position.y1=2;
1518 if(TWin.Position.y1<=4) TWin.Position.y1=4;
1520 if(TWin.Position.y1<=8) TWin.Position.y1=8;
1522 if(TWin.Position.y1<=16) TWin.Position.y1=16;
1524 if(TWin.Position.y1<=32) TWin.Position.y1=32;
1526 if(TWin.Position.y1<=64) TWin.Position.y1=64;
1528 if(TWin.Position.y1<=128) TWin.Position.y1=128;
1530 if(TWin.Position.y1<=256) TWin.Position.y1=256;
1533 TWin.UScaleFactor = (float)TWin.Position.x1;
1534 TWin.VScaleFactor = (float)TWin.Position.y1;
1536 TWin.UScaleFactor = ((float)TWin.Position.x1)/256.0f; // -> set scale factor
\r
1537 TWin.VScaleFactor = ((float)TWin.Position.y1)/256.0f;
1542 ////////////////////////////////////////////////////////////////////////
1543 // mmm, Lewpy uses that in TileS ... I don't ;)
1544 ////////////////////////////////////////////////////////////////////////
1547 void ClampToPSXDrawAreaOffset(short *x0, short *y0, short *x1, short *y1)
1549 if (*x0 < PSXDisplay.DrawArea.x0)
1551 *x1 -= (PSXDisplay.DrawArea.x0 - *x0);
1552 *x0 = PSXDisplay.DrawArea.x0;
1555 if (*x0 > PSXDisplay.DrawArea.x1)
1557 *x0 = PSXDisplay.DrawArea.x1;
1561 if (*y0 < PSXDisplay.DrawArea.y0)
1563 *y1 -= (PSXDisplay.DrawArea.y0 - *y0);
1564 *y0 = PSXDisplay.DrawArea.y0;
1567 if (*y0 > PSXDisplay.DrawArea.y1)
1569 *y0 = PSXDisplay.DrawArea.y1;
1573 if (*x1 < 0) *x1 = 0;
1575 if ((*x1 + *x0) > PSXDisplay.DrawArea.x1)
1576 *x1 = (PSXDisplay.DrawArea.x1 - *x0 + 1);
1578 if (*y1 < 0) *y1 = 0;
1580 if ((*y1 + *y0) > PSXDisplay.DrawArea.y1)
1581 *y1 = (PSXDisplay.DrawArea.y1 - *y0 + 1);
1585 ////////////////////////////////////////////////////////////////////////
1586 // Check draw area dimensions
1587 ////////////////////////////////////////////////////////////////////////
1589 void ClampToPSXScreen(short *x0, short *y0, short *x1, short *y1)
1591 if (*x0 < 0) *x0 = 0;
1593 if (*x0 > 1023) *x0 = 1023;
1595 if (*x1 < 0) *x1 = 0;
1597 if (*x1 > 1023) *x1 = 1023;
1599 if (*y0 < 0) *y0 = 0;
1601 if (*y0 > iGPUHeightMask) *y0 = iGPUHeightMask;
\r
1603 if (*y1 < 0) *y1 = 0;
1605 if (*y1 > iGPUHeightMask) *y1 = iGPUHeightMask;
\r
1608 ////////////////////////////////////////////////////////////////////////
1609 // Used in Load Image and Blk Fill
1610 ////////////////////////////////////////////////////////////////////////
1612 void ClampToPSXScreenOffset(short *x0, short *y0, short *x1, short *y1)
1615 { *x1 += *x0; *x0 = 0; }
1618 { *x0 = 1023; *x1 = 0; }
1621 { *y1 += *y0; *y0 = 0; }
1623 if (*y0 > iGPUHeightMask)
\r
1624 { *y0 = iGPUHeightMask; *y1 = 0; }
\r
1626 if (*x1 < 0) *x1 = 0;
1628 if ((*x1 + *x0) > 1024) *x1 = (1024 - *x0);
1630 if (*y1 < 0) *y1 = 0;
1632 if ((*y1 + *y0) > iGPUHeight) *y1 = (iGPUHeight - *y0);
\r
1635 ////////////////////////////////////////////////////////////////////////
1636 // cmd: start of drawing area... primitives will be clipped inside
1637 ////////////////////////////////////////////////////////////////////////
1639 void cmdDrawAreaStart(unsigned char * baseAddr)
1641 uint32_t gdata = ((uint32_t *)baseAddr)[0];
1643 drawX = gdata & 0x3ff; // for soft drawing
\r
1644 if(drawX>=1024) drawX=1023;
\r
1646 if(dwGPUVersion==2)
\r
1648 ulGPUInfoVals[INFO_DRAWSTART]=gdata&0x3FFFFF;
\r
1649 drawY = (gdata>>12)&0x3ff;
\r
1653 ulGPUInfoVals[INFO_DRAWSTART]=gdata&0xFFFFF;
\r
1654 drawY = (gdata>>10)&0x3ff;
\r
1657 if(drawY>=iGPUHeight) drawY=iGPUHeightMask;
\r
1659 PreviousPSXDisplay.DrawArea.y0=PSXDisplay.DrawArea.y0;
1660 PreviousPSXDisplay.DrawArea.x0=PSXDisplay.DrawArea.x0;
1662 PSXDisplay.DrawArea.y0 = (short)drawY; // for OGL drawing
\r
1663 PSXDisplay.DrawArea.x0 = (short)drawX;
1666 ////////////////////////////////////////////////////////////////////////
1667 // cmd: end of drawing area... primitives will be clipped inside
1668 ////////////////////////////////////////////////////////////////////////
1670 void cmdDrawAreaEnd(unsigned char * baseAddr)
1672 uint32_t gdata = ((uint32_t *)baseAddr)[0];
1674 drawW = gdata & 0x3ff; // for soft drawing
1675 if(drawW>=1024) drawW=1023;
1677 if(dwGPUVersion==2)
\r
1679 ulGPUInfoVals[INFO_DRAWEND]=gdata&0x3FFFFF;
\r
1680 drawH = (gdata>>12)&0x3ff;
\r
1684 ulGPUInfoVals[INFO_DRAWEND]=gdata&0xFFFFF;
\r
1685 drawH = (gdata>>10)&0x3ff;
\r
1688 if(drawH>=iGPUHeight) drawH=iGPUHeightMask;
\r
1690 PSXDisplay.DrawArea.y1 = (short)drawH; // for OGL drawing
\r
1691 PSXDisplay.DrawArea.x1 = (short)drawW;
1693 ClampToPSXScreen(&PSXDisplay.DrawArea.x0, // clamp
1694 &PSXDisplay.DrawArea.y0,
1695 &PSXDisplay.DrawArea.x1,
1696 &PSXDisplay.DrawArea.y1);
1698 bDisplayNotSet = TRUE;
1701 ////////////////////////////////////////////////////////////////////////
1702 // cmd: draw offset... will be added to prim coords
1703 ////////////////////////////////////////////////////////////////////////
1705 void cmdDrawOffset(unsigned char * baseAddr)
1707 uint32_t gdata = ((uint32_t *)baseAddr)[0];
1709 PreviousPSXDisplay.DrawOffset.x =
1710 PSXDisplay.DrawOffset.x = (short)(gdata & 0x7ff);
\r
1712 if (dwGPUVersion == 2)
\r
1714 ulGPUInfoVals[INFO_DRAWOFF] = gdata&0x7FFFFF;
\r
1715 PSXDisplay.DrawOffset.y = (short)((gdata>>12) & 0x7ff);
\r
1719 ulGPUInfoVals[INFO_DRAWOFF]=gdata&0x3FFFFF;
\r
1720 PSXDisplay.DrawOffset.y = (short)((gdata>>11) & 0x7ff);
\r
1723 PSXDisplay.DrawOffset.x=(short)(((int)PSXDisplay.DrawOffset.x<<21)>>21);
1724 PSXDisplay.DrawOffset.y=(short)(((int)PSXDisplay.DrawOffset.y<<21)>>21);
1726 PSXDisplay.CumulOffset.x = // new OGL prim offsets
\r
1727 PSXDisplay.DrawOffset.x - PSXDisplay.GDrawOffset.x + PreviousPSXDisplay.Range.x0;
1728 PSXDisplay.CumulOffset.y =
1729 PSXDisplay.DrawOffset.y - PSXDisplay.GDrawOffset.y + PreviousPSXDisplay.Range.y0;
1732 ////////////////////////////////////////////////////////////////////////
1733 // cmd: load image to vram
1734 ////////////////////////////////////////////////////////////////////////
1736 void primLoadImage(unsigned char * baseAddr)
1738 unsigned short *sgpuData = ((unsigned short *) baseAddr);
1740 VRAMWrite.x = sgpuData[2]&0x03ff;
1741 VRAMWrite.y = sgpuData[3]&iGPUHeightMask;
1742 VRAMWrite.Width = sgpuData[4];
1743 VRAMWrite.Height = sgpuData[5];
1745 iDataWriteMode = DR_VRAMTRANSFER;
1746 VRAMWrite.ImagePtr = psxVuw + (VRAMWrite.y<<10) + VRAMWrite.x;
1747 VRAMWrite.RowsRemaining = VRAMWrite.Width;
1748 VRAMWrite.ColsRemaining = VRAMWrite.Height;
1750 bNeedWriteUpload=TRUE;
1753 ////////////////////////////////////////////////////////////////////////
1755 void PrepareRGB24Upload(void)
1757 VRAMWrite.x=(VRAMWrite.x*2)/3;
1758 VRAMWrite.Width=(VRAMWrite.Width*2)/3;
1760 if(!PSXDisplay.InterlacedTest && // NEW
1761 CheckAgainstScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height))
1763 xrUploadArea.x0-=PreviousPSXDisplay.DisplayPosition.x;
1764 xrUploadArea.x1-=PreviousPSXDisplay.DisplayPosition.x;
1765 xrUploadArea.y0-=PreviousPSXDisplay.DisplayPosition.y;
1766 xrUploadArea.y1-=PreviousPSXDisplay.DisplayPosition.y;
1769 if(CheckAgainstFrontScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height))
1771 xrUploadArea.x0-=PSXDisplay.DisplayPosition.x;
1772 xrUploadArea.x1-=PSXDisplay.DisplayPosition.x;
1773 xrUploadArea.y0-=PSXDisplay.DisplayPosition.y;
1774 xrUploadArea.y1-=PSXDisplay.DisplayPosition.y;
1778 if(bRenderFrontBuffer)
1780 updateFrontDisplay();
1783 if(bNeedRGB24Update==FALSE)
1785 xrUploadAreaRGB24=xrUploadArea;
1786 bNeedRGB24Update=TRUE;
1790 xrUploadAreaRGB24.x0=min(xrUploadAreaRGB24.x0,xrUploadArea.x0);
1791 xrUploadAreaRGB24.x1=max(xrUploadAreaRGB24.x1,xrUploadArea.x1);
1792 xrUploadAreaRGB24.y0=min(xrUploadAreaRGB24.y0,xrUploadArea.y0);
1793 xrUploadAreaRGB24.y1=max(xrUploadAreaRGB24.y1,xrUploadArea.y1);
1797 ////////////////////////////////////////////////////////////////////////
1799 void CheckWriteUpdate()
1803 if(VRAMWrite.Width) iX=1;
1804 if(VRAMWrite.Height) iY=1;
1806 InvalidateTextureArea(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width-iX, VRAMWrite.Height-iY);
1808 if(PSXDisplay.Interlaced && !iOffscreenDrawing) return;
1810 if(PSXDisplay.RGB24) {PrepareRGB24Upload();return;}
1812 if(!PSXDisplay.InterlacedTest &&
1813 CheckAgainstScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height))
1815 if(dwActFixes&0x800) return;
1817 if(bRenderFrontBuffer)
1819 updateFrontDisplay();
1822 UploadScreen(FALSE);
1824 bNeedUploadTest=TRUE;
1827 if(iOffscreenDrawing)
1829 if (CheckAgainstFrontScreen(VRAMWrite.x, VRAMWrite.y, VRAMWrite.Width, VRAMWrite.Height))
1831 if(PSXDisplay.InterlacedTest)
1833 if(PreviousPSXDisplay.InterlacedNew)
1835 PreviousPSXDisplay.InterlacedNew=FALSE;
1836 bNeedInterlaceUpdate=TRUE;
1837 xrUploadAreaIL.x0=PSXDisplay.DisplayPosition.x;
1838 xrUploadAreaIL.y0=PSXDisplay.DisplayPosition.y;
1839 xrUploadAreaIL.x1=PSXDisplay.DisplayPosition.x+PSXDisplay.DisplayModeNew.x;
1840 xrUploadAreaIL.y1=PSXDisplay.DisplayPosition.y+PSXDisplay.DisplayModeNew.y;
1841 if(xrUploadAreaIL.x1>1023) xrUploadAreaIL.x1=1023;
1842 if(xrUploadAreaIL.y1>511) xrUploadAreaIL.y1=511;
1845 if(bNeedInterlaceUpdate==FALSE)
1847 xrUploadAreaIL=xrUploadArea;
1848 bNeedInterlaceUpdate=TRUE;
1852 xrUploadAreaIL.x0=min(xrUploadAreaIL.x0,xrUploadArea.x0);
1853 xrUploadAreaIL.x1=max(xrUploadAreaIL.x1,xrUploadArea.x1);
1854 xrUploadAreaIL.y0=min(xrUploadAreaIL.y0,xrUploadArea.y0);
1855 xrUploadAreaIL.y1=max(xrUploadAreaIL.y1,xrUploadArea.y1);
1860 if(!bNeedUploadAfter)
1862 bNeedUploadAfter = TRUE;
1863 xrUploadArea.x0=VRAMWrite.x;
1864 xrUploadArea.x1=VRAMWrite.x+VRAMWrite.Width;
1865 xrUploadArea.y0=VRAMWrite.y;
1866 xrUploadArea.y1=VRAMWrite.y+VRAMWrite.Height;
1870 xrUploadArea.x0=min(xrUploadArea.x0,VRAMWrite.x);
1871 xrUploadArea.x1=max(xrUploadArea.x1,VRAMWrite.x+VRAMWrite.Width);
1872 xrUploadArea.y0=min(xrUploadArea.y0,VRAMWrite.y);
1873 xrUploadArea.y1=max(xrUploadArea.y1,VRAMWrite.y+VRAMWrite.Height);
1876 if(dwActFixes&0x8000)
\r
1878 if((xrUploadArea.x1-xrUploadArea.x0)>=(PSXDisplay.DisplayMode.x-32) &&
\r
1879 (xrUploadArea.y1-xrUploadArea.y0)>=(PSXDisplay.DisplayMode.y-32))
\r
1882 updateFrontDisplay();
\r
1889 ////////////////////////////////////////////////////////////////////////
1890 // cmd: vram -> psx mem
1891 ////////////////////////////////////////////////////////////////////////
1893 void primStoreImage(unsigned char * baseAddr)
1895 unsigned short *sgpuData = ((unsigned short *) baseAddr);
1897 VRAMRead.x = sgpuData[2]&0x03ff;
1898 VRAMRead.y = sgpuData[3]&iGPUHeightMask;
1899 VRAMRead.Width = sgpuData[4];
1900 VRAMRead.Height = sgpuData[5];
1902 VRAMRead.ImagePtr = psxVuw + (VRAMRead.y<<10) + VRAMRead.x;
1903 VRAMRead.RowsRemaining = VRAMRead.Width;
1904 VRAMRead.ColsRemaining = VRAMRead.Height;
1906 iDataReadMode = DR_VRAMTRANSFER;
1908 STATUSREG |= GPUSTATUS_READYFORVRAM;
1911 ////////////////////////////////////////////////////////////////////////
1912 // cmd: blkfill - NO primitive! Doesn't care about draw areas...
1913 ////////////////////////////////////////////////////////////////////////
1915 void primBlkFill(unsigned char * baseAddr)
1917 uint32_t *gpuData = ((uint32_t *) baseAddr);
1918 short *sgpuData = ((short *) baseAddr);
1920 iDrawnSomething = 1;
1922 sprtX = sgpuData[2];
1923 sprtY = sgpuData[3];
1924 sprtW = sgpuData[4] & 0x3ff;
1925 sprtH = sgpuData[5] & iGPUHeightMask;
\r
1927 sprtW = (sprtW + 15) & ~15;
\r
1929 // Increase H & W if they are one short of full values, because they never can be full values
1930 if (sprtH == iGPUHeightMask) sprtH=iGPUHeight;
1931 if (sprtW == 1023) sprtW=1024;
1935 ly2 = ly3 = (sprtY+sprtH);
1937 lx1 = lx2 = (sprtX+sprtW);
1941 if(ClipVertexListScreen())
\r
1944 if(PSXDisplay.InterlacedTest) pd=&PSXDisplay;
1945 else pd=&PreviousPSXDisplay;
1947 if ((lx0 <= pd->DisplayPosition.x+16) &&
1948 (ly0 <= pd->DisplayPosition.y+16) &&
1949 (lx2 >= pd->DisplayEnd.x-16) &&
1950 (ly2 >= pd->DisplayEnd.y-16))
1953 g=((GLclampf)GREEN(gpuData[0]))/255.0f;
1954 b=((GLclampf)BLUE(gpuData[0]))/255.0f;
1955 r=((GLclampf)RED(gpuData[0]))/255.0f;
1957 glDisable(GL_SCISSOR_TEST);
1958 glClearColor(r,g,b,1.0f);
1959 glClear(uiBufferBits);
1962 if(gpuData[0]!=0x02000000 &&
1963 (ly0>pd->DisplayPosition.y ||
1964 ly2<pd->DisplayEnd.y))
1966 bDrawTextured = FALSE;
1967 bDrawSmoothShaded = FALSE;
1968 SetRenderState((uint32_t)0x01000000);
1969 SetRenderMode((uint32_t)0x01000000, FALSE);
1970 vertex[0].c.lcol=0xff000000;
1972 if(ly0>pd->DisplayPosition.y)
1974 vertex[0].x=0;vertex[0].y=0;
1975 vertex[1].x=pd->DisplayEnd.x-pd->DisplayPosition.x;vertex[1].y=0;
1976 vertex[2].x=vertex[1].x;vertex[2].y=ly0-pd->DisplayPosition.y;
1977 vertex[3].x=0;vertex[3].y=vertex[2].y;
1978 PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
1980 if(ly2<pd->DisplayEnd.y)
1982 vertex[0].x=0;vertex[0].y=(pd->DisplayEnd.y-pd->DisplayPosition.y)-(pd->DisplayEnd.y-ly2);
\r
1983 vertex[1].x=pd->DisplayEnd.x-pd->DisplayPosition.x;vertex[1].y=vertex[0].y;
1984 vertex[2].x=vertex[1].x;vertex[2].y=pd->DisplayEnd.y;
1985 vertex[3].x=0;vertex[3].y=vertex[2].y;
1986 PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
1990 glEnable(GL_SCISSOR_TEST);
1994 bDrawTextured = FALSE;
1995 bDrawSmoothShaded = FALSE;
1996 SetRenderState((uint32_t)0x01000000);
1997 SetRenderMode((uint32_t)0x01000000, FALSE);
1998 vertex[0].c.lcol=gpuData[0]|0xff000000;
2000 glDisable(GL_SCISSOR_TEST);
2001 PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2002 glEnable(GL_SCISSOR_TEST);
2006 //mmm... will clean all stuff, also if not all _should_ be cleaned...
2007 //if (IsInsideNextScreen(sprtX, sprtY, sprtW, sprtH))
2009 if (IsCompleteInsideNextScreen(sprtX, sprtY, sprtW, sprtH))
2011 lClearOnSwapColor = COLOR(gpuData[0]);
2015 if(iOffscreenDrawing)
2017 ClampToPSXScreenOffset( &sprtX, &sprtY, &sprtW, &sprtH);
2018 if ((sprtW == 0) || (sprtH == 0)) return;
2019 InvalidateTextureArea(sprtX, sprtY, sprtW-1, sprtH-1);
2024 FillSoftwareArea(sprtX, sprtY, sprtW, sprtH, BGR24to16(gpuData[0]));
2028 ////////////////////////////////////////////////////////////////////////
2029 // cmd: move image vram -> vram
2030 ////////////////////////////////////////////////////////////////////////
2032 void MoveImageWrapped(short imageX0,short imageY0,
2033 short imageX1,short imageY1,
2034 short imageSX,short imageSY)
2036 int i,j,imageXE,imageYE;
2038 if(iFrameReadType&2)
2040 imageXE=imageX0+imageSX;
2041 imageYE=imageY0+imageSY;
2043 if(imageYE>iGPUHeight && imageXE>1024)
2047 (imageY0&iGPUHeightMask),
2053 CheckVRamRead(0,imageY0,
2055 (imageYE>iGPUHeight)?iGPUHeight:imageYE,
2059 if(imageYE>iGPUHeight)
2061 CheckVRamRead(imageX0,0,
2062 (imageXE>1024)?1024:imageXE,
2063 imageYE&iGPUHeightMask,
2067 CheckVRamRead(imageX0,imageY0,
2068 (imageXE>1024)?1024:imageXE,
2069 (imageYE>iGPUHeight)?iGPUHeight:imageYE,
2073 for(j=0;j<imageSY;j++)
2074 for(i=0;i<imageSX;i++)
2075 psxVuw [(1024*((imageY1+j)&iGPUHeightMask))+((imageX1+i)&0x3ff)]=
2076 psxVuw[(1024*((imageY0+j)&iGPUHeightMask))+((imageX0+i)&0x3ff)];
2078 if(!PSXDisplay.RGB24)
2080 imageXE=imageX1+imageSX;
2081 imageYE=imageY1+imageSY;
2083 if(imageYE>iGPUHeight && imageXE>1024)
2085 InvalidateTextureArea(0,0,
2087 (imageYE&iGPUHeightMask)-1);
2092 InvalidateTextureArea(0,imageY1,
2094 ((imageYE>iGPUHeight)?iGPUHeight:imageYE)-imageY1-1);
2097 if(imageYE>iGPUHeight)
2099 InvalidateTextureArea(imageX1,0,
2100 ((imageXE>1024)?1024:imageXE)-imageX1-1,
2101 (imageYE&iGPUHeightMask)-1);
2104 InvalidateTextureArea(imageX1,imageY1,
2105 ((imageXE>1024)?1024:imageXE)-imageX1-1,
2106 ((imageYE>iGPUHeight)?iGPUHeight:imageYE)-imageY1-1);
2110 ////////////////////////////////////////////////////////////////////////
2112 void primMoveImage(unsigned char * baseAddr)
2114 short *sgpuData = ((short *) baseAddr);
2115 short imageY0,imageX0,imageY1,imageX1,imageSX,imageSY,i,j;
2117 imageX0 = sgpuData[2]&0x03ff;
2118 imageY0 = sgpuData[3]&iGPUHeightMask;
2119 imageX1 = sgpuData[4]&0x03ff;
2120 imageY1 = sgpuData[5]&iGPUHeightMask;
2121 imageSX = sgpuData[6];
2122 imageSY = sgpuData[7];
2124 if((imageX0 == imageX1) && (imageY0 == imageY1)) return;
2125 if(imageSX<=0) return;
2126 if(imageSY<=0) return;
2128 if(iGPUHeight==1024 && sgpuData[7]>1024) return;
\r
2130 if((imageY0+imageSY)>iGPUHeight ||
2131 (imageX0+imageSX)>1024 ||
2132 (imageY1+imageSY)>iGPUHeight ||
2133 (imageX1+imageSX)>1024)
2135 MoveImageWrapped(imageX0,imageY0,imageX1,imageY1,imageSX,imageSY);
2136 if((imageY0+imageSY)>iGPUHeight) imageSY=iGPUHeight-imageY0;
2137 if((imageX0+imageSX)>1024) imageSX=1024-imageX0;
2138 if((imageY1+imageSY)>iGPUHeight) imageSY=iGPUHeight-imageY1;
2139 if((imageX1+imageSX)>1024) imageSX=1024-imageX1;
2142 if(iFrameReadType&2)
2143 CheckVRamRead(imageX0,imageY0,
2150 unsigned short *SRCPtr, *DSTPtr;
2151 unsigned short LineOffset;
2153 SRCPtr = psxVuw + (1024*imageY0) + imageX0;
2154 DSTPtr = psxVuw + (1024*imageY1) + imageX1;
2156 LineOffset = 1024 - imageSX;
2158 for(j=0;j<imageSY;j++)
2160 for(i=0;i<imageSX;i++) *DSTPtr++ = *SRCPtr++;
2161 SRCPtr += LineOffset;
2162 DSTPtr += LineOffset;
2167 uint32_t *SRCPtr, *DSTPtr;
2168 unsigned short LineOffset;
2171 SRCPtr = (uint32_t *)(psxVuw + (1024*imageY0) + imageX0);
2172 DSTPtr = (uint32_t *)(psxVuw + (1024*imageY1) + imageX1);
2174 LineOffset = 512 - dx;
2176 for(j=0;j<imageSY;j++)
2178 for(i=0;i<dx;i++) *DSTPtr++ = *SRCPtr++;
2179 SRCPtr += LineOffset;
2180 DSTPtr += LineOffset;
2184 if (!PSXDisplay.RGB24)
2186 InvalidateTextureArea(imageX1,imageY1,imageSX-1,imageSY-1);
2188 if (CheckAgainstScreen(imageX1,imageY1,imageSX,imageSY))
2190 if(imageX1>=PreviousPSXDisplay.DisplayPosition.x &&
2191 imageX1<PreviousPSXDisplay.DisplayEnd.x &&
2192 imageY1>=PreviousPSXDisplay.DisplayPosition.y &&
2193 imageY1<PreviousPSXDisplay.DisplayEnd.y)
2198 if(imageX1>=PreviousPSXDisplay.DisplayPosition.x &&
2199 imageX1<=PreviousPSXDisplay.DisplayEnd.x &&
2200 imageY1>=PreviousPSXDisplay.DisplayPosition.y &&
2201 imageY1<=PreviousPSXDisplay.DisplayEnd.y)
2204 imageX0>=PSXDisplay.DisplayPosition.x &&
2205 imageX0<PSXDisplay.DisplayEnd.x &&
2206 imageY0>=PSXDisplay.DisplayPosition.y &&
2207 imageY0<PSXDisplay.DisplayEnd.y
2210 if(bRenderFrontBuffer)
2212 updateFrontDisplay();
2215 UploadScreen(FALSE);
2217 else bFakeFrontBuffer=TRUE;
2221 bNeedUploadTest=TRUE;
2224 if(iOffscreenDrawing)
2226 if (CheckAgainstFrontScreen(imageX1,imageY1,imageSX,imageSY))
2228 if(!PSXDisplay.InterlacedTest &&
2231 imageX0>=PreviousPSXDisplay.DisplayPosition.x &&
2232 imageX0<PreviousPSXDisplay.DisplayEnd.x &&
2233 imageY0>=PreviousPSXDisplay.DisplayPosition.y &&
2234 imageY0<PreviousPSXDisplay.DisplayEnd.y
2237 imageX0>=PSXDisplay.DisplayPosition.x &&
2238 imageX0<PSXDisplay.DisplayEnd.x &&
2239 imageY0>=PSXDisplay.DisplayPosition.y &&
2240 imageY0<PSXDisplay.DisplayEnd.y
2244 bNeedUploadTest=TRUE;
2246 if(!bNeedUploadAfter)
2248 bNeedUploadAfter = TRUE;
2249 xrUploadArea.x0=imageX0;
2250 xrUploadArea.x1=imageX0+imageSX;
2251 xrUploadArea.y0=imageY0;
2252 xrUploadArea.y1=imageY0+imageSY;
2256 xrUploadArea.x0=min(xrUploadArea.x0,imageX0);
2257 xrUploadArea.x1=max(xrUploadArea.x1,imageX0+imageSX);
2258 xrUploadArea.y0=min(xrUploadArea.y0,imageY0);
2259 xrUploadArea.y1=max(xrUploadArea.y1,imageY0+imageSY);
2267 ////////////////////////////////////////////////////////////////////////
2268 // cmd: draw free-size Tile
2269 ////////////////////////////////////////////////////////////////////////
2271 void primTileS(unsigned char * baseAddr)
2273 uint32_t *gpuData = ((uint32_t *)baseAddr);
2274 short *sgpuData = ((short *) baseAddr);
2276 sprtX = sgpuData[2];
2277 sprtY = sgpuData[3];
2278 sprtW = sgpuData[4] & 0x3ff;
2279 sprtH = sgpuData[5] & iGPUHeightMask;
2288 if((dwActFixes&1) && // FF7 special game gix (battle cursor)
\r
2289 sprtX==0 && sprtY==0 && sprtW==24 && sprtH==16)
\r
2292 bDrawTextured = FALSE;
2293 bDrawSmoothShaded = FALSE;
2295 SetRenderState(gpuData[0]);
2297 if(iOffscreenDrawing)
2299 if(IsPrimCompleteInsideNextScreen(lx0,ly0,lx2,ly2) ||
2300 (ly0==-6 && ly2==10)) // OH MY GOD... I DIDN'T WANT TO DO IT... BUT I'VE FOUND NO OTHER WAY... HACK FOR GRADIUS SHOOTER :(
\r
2302 lClearOnSwapColor = COLOR(gpuData[0]);
2307 if(bDrawOffscreen4())
2309 if(!(iTileCheat && sprtH==32 && gpuData[0]==0x60ffffff)) // special cheat for certain ZiNc games
\r
2311 InvalidateTextureAreaEx();
2312 FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,
2313 BGR24to16(gpuData[0]));
\r
2318 SetRenderMode(gpuData[0], FALSE);
2321 if(bIgnoreNextTile) {bIgnoreNextTile=FALSE;return;}
2323 vertex[0].c.lcol=gpuData[0];
2324 vertex[0].c.col[3]=ubGloColAlpha;
2327 PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2332 ////////////////////////////////////////////////////////////////////////
2333 // cmd: draw 1 dot Tile (point)
2334 ////////////////////////////////////////////////////////////////////////
2336 void primTile1(unsigned char * baseAddr)
2338 uint32_t *gpuData = ((uint32_t *)baseAddr);
2339 short *sgpuData = ((short *)baseAddr);
2341 sprtX = sgpuData[2];
2342 sprtY = sgpuData[3];
2351 bDrawTextured = FALSE;
2352 bDrawSmoothShaded = FALSE;
2354 SetRenderState(gpuData[0]);
2356 if(iOffscreenDrawing)
2360 if(bDrawOffscreen4())
2362 InvalidateTextureAreaEx();
2363 FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,
2364 BGR24to16(gpuData[0]));
2368 SetRenderMode(gpuData[0], FALSE);
2371 vertex[0].c.lcol=gpuData[0];vertex[0].c.col[3]=ubGloColAlpha;
2374 PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2379 ////////////////////////////////////////////////////////////////////////
2380 // cmd: draw 8 dot Tile (small rect)
2381 ////////////////////////////////////////////////////////////////////////
2383 void primTile8(unsigned char * baseAddr)
2385 uint32_t *gpuData = ((uint32_t *)baseAddr);
2386 short *sgpuData = ((short *) baseAddr);
2388 sprtX = sgpuData[2];
2389 sprtY = sgpuData[3];
2398 bDrawTextured = FALSE;
2399 bDrawSmoothShaded = FALSE;
2400 SetRenderState(gpuData[0]);
2402 if(iOffscreenDrawing)
2406 if(bDrawOffscreen4())
2408 InvalidateTextureAreaEx();
2409 FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,
2410 BGR24to16(gpuData[0]));
2414 SetRenderMode(gpuData[0], FALSE);
2417 vertex[0].c.lcol=gpuData[0];
2418 vertex[0].c.col[3]=ubGloColAlpha;
2421 PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2426 ////////////////////////////////////////////////////////////////////////
2427 // cmd: draw 16 dot Tile (medium rect)
2428 ////////////////////////////////////////////////////////////////////////
2430 void primTile16(unsigned char * baseAddr)
2432 uint32_t *gpuData = ((uint32_t *)baseAddr);
2433 short *sgpuData = ((short *)baseAddr);
2435 sprtX = sgpuData[2];
2436 sprtY = sgpuData[3];
2445 bDrawTextured = FALSE;
2446 bDrawSmoothShaded = FALSE;
2447 SetRenderState(gpuData[0]);
2449 if(iOffscreenDrawing)
2453 if(bDrawOffscreen4())
2455 InvalidateTextureAreaEx();
2456 FillSoftwareAreaTrans(lx0,ly0,lx2,ly2,
2457 BGR24to16(gpuData[0]));
2461 SetRenderMode(gpuData[0], FALSE);
2464 vertex[0].c.lcol=gpuData[0];
2465 vertex[0].c.col[3]=ubGloColAlpha;
2468 PRIMdrawQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2473 ////////////////////////////////////////////////////////////////////////
2474 // helper: filter effect by multipass rendering
2475 ////////////////////////////////////////////////////////////////////////
2477 void DrawMultiBlur(void)
2485 fx=(float)PSXDisplay.DisplayMode.x/(float)(iResX);
2486 fy=(float)PSXDisplay.DisplayMode.y/(float)(iResY);
2488 vertex[0].x+=fx;vertex[1].x+=fx;
2489 vertex[2].x+=fx;vertex[3].x+=fx;
2495 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2497 vertex[0].y+=fy;vertex[1].y+=fy;
2498 vertex[2].y+=fy;vertex[3].y+=fy;
2499 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2501 if(bDrawMultiPass) {obm1=obm2=GL_SRC_ALPHA;}
2507 ////////////////////////////////////////////////////////////////////////
2511 void DrawMultiFilterSprite(void)
2515 if(bUseMultiPass || DrawSemiTrans || ubOpaqueDraw)
2517 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2523 vertex[0].c.col[3]=ubGloAlpha/2; // -> set color with
\r
2524 SETCOL(vertex[0]); // texture alpha
\r
2525 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2526 vertex[0].x+=POFF;vertex[1].x+=POFF;
2527 vertex[2].x+=POFF;vertex[3].x+=POFF;
2528 vertex[0].y+=POFF;vertex[1].y+=POFF;
2529 vertex[2].y+=POFF;vertex[3].y+=POFF;
2533 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2538 ////////////////////////////////////////////////////////////////////////
2539 // cmd: small sprite (textured rect)
2540 ////////////////////////////////////////////////////////////////////////
2542 void primSprt8(unsigned char * baseAddr)
2544 uint32_t *gpuData = ((uint32_t *) baseAddr);
2545 short *sgpuData = ((short *) baseAddr);
2550 sprtX = sgpuData[2];
2551 sprtY = sgpuData[3];
2561 gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;
\r
2563 if(usMirror & 0x1000)
\r
2568 gl_ux[0]=gl_ux[3]=s;
\r
2571 sSprite_ux2=s=gl_ux[0]+sprtW;
2574 gl_ux[1]=gl_ux[2]=s;
2576 gl_vy[0]=gl_vy[1]=baseAddr[9];//(gpuData[2]>>8)&0xff;
\r
2578 if(usMirror & 0x2000)
\r
2583 gl_vy[0]=gl_vy[1]=s;
\r
2586 sSprite_vy2=s=gl_vy[0]+sprtH;
2589 gl_vy[2]=gl_vy[3]=s;
2591 ulClutID=(gpuData[2]>>16);
2593 bDrawTextured = TRUE;
2594 bDrawSmoothShaded = FALSE;
2595 SetRenderState(gpuData[0]);
2597 if(iOffscreenDrawing)
2601 if(bDrawOffscreen4())
2603 InvalidateTextureAreaEx();
2604 SetRenderColor(gpuData[0]);
2605 lx0-=PSXDisplay.DrawOffset.x;
2606 ly0-=PSXDisplay.DrawOffset.y;
2608 if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,8,8);
2610 if(usMirror) DrawSoftwareSpriteMirror(baseAddr,8,8);
2612 DrawSoftwareSprite(baseAddr,8,8,baseAddr[8],baseAddr[9]);
\r
2616 SetRenderMode(gpuData[0], TRUE);
2619 sSprite_ux2=gl_ux[0]+sprtW;
2620 sSprite_vy2=gl_vy[0]+sprtH;
2622 assignTextureSprite();
2625 DrawMultiFilterSprite();
2627 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2631 SetSemiTransMulti(1);
2632 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2638 if(bUseMultiPass) SetOpaqueColor(gpuData[0]);
2641 if(bSmallAlpha && iFilterType<=2)
\r
2643 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
\r
2644 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
\r
2645 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
\r
2646 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
\r
2647 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
\r
2651 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2659 ////////////////////////////////////////////////////////////////////////
2660 // cmd: medium sprite (textured rect)
2661 ////////////////////////////////////////////////////////////////////////
2663 void primSprt16(unsigned char * baseAddr)
2665 uint32_t *gpuData = ((uint32_t *) baseAddr);
2666 short *sgpuData = ((short *) baseAddr);
2671 sprtX = sgpuData[2];
2672 sprtY = sgpuData[3];
2682 gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;
\r
2684 if(usMirror & 0x1000)
\r
2689 gl_ux[0]=gl_ux[3]=s;
\r
2692 sSprite_ux2=s=gl_ux[0]+sprtW;
2695 gl_ux[1]=gl_ux[2]=s;
2697 gl_vy[0]=gl_vy[1]=baseAddr[9];//(gpuData[2]>>8)&0xff;
\r
2699 if(usMirror & 0x2000)
\r
2704 gl_vy[0]=gl_vy[1]=s;
\r
2707 sSprite_vy2=s=gl_vy[0]+sprtH;
2710 gl_vy[2]=gl_vy[3]=s;
2712 ulClutID=(gpuData[2]>>16);
2714 bDrawTextured = TRUE;
2715 bDrawSmoothShaded = FALSE;
2716 SetRenderState(gpuData[0]);
2718 if(iOffscreenDrawing)
2722 if(bDrawOffscreen4())
2724 InvalidateTextureAreaEx();
2725 SetRenderColor(gpuData[0]);
2726 lx0-=PSXDisplay.DrawOffset.x;
2727 ly0-=PSXDisplay.DrawOffset.y;
2728 if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,16,16);
2730 if(usMirror) DrawSoftwareSpriteMirror(baseAddr,16,16);
2732 DrawSoftwareSprite(baseAddr,16,16,baseAddr[8],baseAddr[9]);
\r
2736 SetRenderMode(gpuData[0], TRUE);
2739 sSprite_ux2=gl_ux[0]+sprtW;
2740 sSprite_vy2=gl_vy[0]+sprtH;
2742 assignTextureSprite();
2745 DrawMultiFilterSprite();
2747 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2751 SetSemiTransMulti(1);
2752 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2758 if(bUseMultiPass) SetOpaqueColor(gpuData[0]);
2761 if(bSmallAlpha && iFilterType<=2)
\r
2763 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
\r
2764 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
\r
2765 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
\r
2766 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
\r
2767 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
\r
2771 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2779 ////////////////////////////////////////////////////////////////////////
2780 // cmd: free-size sprite (textured rect)
2781 ////////////////////////////////////////////////////////////////////////
2783 void primSprtSRest(unsigned char * baseAddr,unsigned short type)
2785 uint32_t *gpuData = ((uint32_t *)baseAddr);
2786 short *sgpuData = ((short *) baseAddr);
2788 unsigned short sTypeRest=0;
2790 sprtX = sgpuData[2];
2791 sprtY = sgpuData[3];
2792 sprtW = sgpuData[6] & 0x3ff;
2793 sprtH = sgpuData[7] & 0x1ff;
2799 gl_vy[0]=gl_vy[1]=baseAddr[9];
2803 gl_ux[0]=gl_ux[3]=0;
2806 gl_ux[0]=gl_ux[3]=baseAddr[8];
2810 gl_vy[0]=gl_vy[1]=0;
2816 gl_ux[0]=gl_ux[3]=0;
2820 gl_vy[0]=gl_vy[1]=0;
2824 gl_vy[0]=gl_vy[1]=baseAddr[9];
2828 gl_ux[0]=gl_ux[3]=0;
2831 gl_ux[0]=gl_ux[3]=baseAddr[8];
2835 gl_vy[0]=gl_vy[1]=0;
2841 gl_ux[0]=gl_ux[3]=0;
2845 gl_vy[0]=gl_vy[1]=0;
2850 if(usMirror & 0x1000)
2853 s-=sprtW-1;if(s<0) s=0;
2854 gl_ux[0]=gl_ux[3]=s;
2856 if(usMirror & 0x2000)
\r
2859 s-=sprtH-1;if(s<0) {s=0;}
\r
2860 gl_vy[0]=gl_vy[1]=s;
\r
2863 sSprite_ux2=s=gl_ux[0]+sprtW;
2865 gl_ux[1]=gl_ux[2]=s;
2866 sSprite_vy2=s=gl_vy[0]+sprtH;
2868 gl_vy[2]=gl_vy[3]=s;
2873 {sprtW=256-gl_ux[0];sSprite_ux2=256;sTypeRest+=1;}
2875 {sprtH=256-gl_vy[0];sSprite_vy2=256;sTypeRest+=2;}
2883 ulClutID=(gpuData[2]>>16);
2885 bDrawTextured = TRUE;
2886 bDrawSmoothShaded = FALSE;
2887 SetRenderState(gpuData[0]);
2889 if(iOffscreenDrawing)
2893 if(bDrawOffscreen4())
2895 InvalidateTextureAreaEx();
2896 SetRenderColor(gpuData[0]);
2897 lx0-=PSXDisplay.DrawOffset.x;
2898 ly0-=PSXDisplay.DrawOffset.y;
2899 if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,sprtW,sprtH);
2901 if(usMirror) DrawSoftwareSpriteMirror(baseAddr,sprtW,sprtH);
2903 DrawSoftwareSprite(baseAddr,sprtW,sprtH,baseAddr[8],baseAddr[9]);
\r
2907 SetRenderMode(gpuData[0], TRUE);
2910 sSprite_ux2=gl_ux[0]+sprtW;
2911 sSprite_vy2=gl_vy[0]+sprtH;
2913 assignTextureSprite();
2916 DrawMultiFilterSprite();
2918 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2922 SetSemiTransMulti(1);
2923 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2929 if(bUseMultiPass) SetOpaqueColor(gpuData[0]);
2932 if(bSmallAlpha && iFilterType<=2)
\r
2934 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
\r
2935 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
\r
2936 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
\r
2937 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
\r
2938 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
\r
2942 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
2946 if(sTypeRest && type<4)
2948 if(sTypeRest&1 && type==1) primSprtSRest(baseAddr,4);
2949 if(sTypeRest&2 && type==2) primSprtSRest(baseAddr,5);
2950 if(sTypeRest==3 && type==3) primSprtSRest(baseAddr,6);
2954 void primSprtS(unsigned char * baseAddr)
2956 uint32_t *gpuData = ((uint32_t *) baseAddr);
2957 short *sgpuData = ((short *) baseAddr);
2960 unsigned short sTypeRest=0;
2962 sprtX = sgpuData[2];
2963 sprtY = sgpuData[3];
2964 sprtW = sgpuData[6] & 0x3ff;
2965 sprtH = sgpuData[7] & 0x1ff;
2973 gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;
2974 gl_vy[0]=gl_vy[1]=baseAddr[9];//(gpuData[2]>>8)&0xff;
2976 if(usMirror & 0x1000)
2981 gl_ux[0]=gl_ux[3]=s;
2983 if(usMirror & 0x2000)
\r
2988 gl_vy[0]=gl_vy[1]=s;
\r
2991 sSprite_ux2=s=gl_ux[0]+sprtW;
2994 gl_ux[1]=gl_ux[2]=s;
2995 sSprite_vy2=s=gl_vy[0]+sprtH;
2998 gl_vy[2]=gl_vy[3]=s;
3003 {sprtW=256-gl_ux[0];sSprite_ux2=256;sTypeRest+=1;}
3005 {sprtH=256-gl_vy[0];sSprite_vy2=256;sTypeRest+=2;}
3013 ulClutID=(gpuData[2]>>16);
3015 bDrawTextured = TRUE;
3016 bDrawSmoothShaded = FALSE;
3017 SetRenderState(gpuData[0]);
3019 if(iOffscreenDrawing)
3023 if(bDrawOffscreen4())
3025 InvalidateTextureAreaEx();
3026 SetRenderColor(gpuData[0]);
3027 lx0-=PSXDisplay.DrawOffset.x;
3028 ly0-=PSXDisplay.DrawOffset.y;
3029 if(bUsingTWin) DrawSoftwareSpriteTWin(baseAddr,sprtW,sprtH);
3031 if(usMirror) DrawSoftwareSpriteMirror(baseAddr,sprtW,sprtH);
3033 DrawSoftwareSprite(baseAddr,sprtW,sprtH,baseAddr[8],baseAddr[9]);
\r
3037 SetRenderMode(gpuData[0], TRUE);
3040 if((dwActFixes&1) && gTexFrameName && gTexName==gTexFrameName)
3041 {iSpriteTex=0;return;}
3043 sSprite_ux2=gl_ux[0]+sprtW;
3044 sSprite_vy2=gl_vy[0]+sprtH;
3046 assignTextureSprite();
3049 DrawMultiFilterSprite();
3051 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
3055 SetSemiTransMulti(1);
3056 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
3062 if(bUseMultiPass) SetOpaqueColor(gpuData[0]);
3065 if(bSmallAlpha && iFilterType<=2)
\r
3067 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
\r
3068 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
\r
3069 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
\r
3070 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
\r
3071 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
\r
3075 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
3081 if(sTypeRest&1) primSprtSRest(baseAddr,1);
3082 if(sTypeRest&2) primSprtSRest(baseAddr,2);
3083 if(sTypeRest==3) primSprtSRest(baseAddr,3);
3090 ////////////////////////////////////////////////////////////////////////
3091 // cmd: flat shaded Poly4
3092 ////////////////////////////////////////////////////////////////////////
3094 void primPolyF4(unsigned char *baseAddr)
3096 uint32_t *gpuData = ((uint32_t *) baseAddr);
3097 short *sgpuData = ((short *) baseAddr);
3108 if(offset4()) return;
3110 bDrawTextured = FALSE;
3111 bDrawSmoothShaded = FALSE;
3112 SetRenderState(gpuData[0]);
3114 if(iOffscreenDrawing)
3117 if(bDrawOffscreen4())
3119 InvalidateTextureAreaEx();
3120 drawPoly4F(gpuData[0]);
3124 SetRenderMode(gpuData[0], FALSE);
3127 vertex[0].c.lcol=gpuData[0];vertex[0].c.col[3]=ubGloColAlpha;
3130 PRIMdrawTri2(&vertex[0], &vertex[1], &vertex[2],&vertex[3]);
3135 ////////////////////////////////////////////////////////////////////////
3136 // cmd: smooth shaded Poly4
3137 ////////////////////////////////////////////////////////////////////////
3139 void primPolyG4(unsigned char * baseAddr);
3141 BOOL bDrawOffscreenFrontFF9G4(void)
3143 if(lx0< PSXDisplay.DisplayPosition.x) return FALSE; // must be complete in front
3144 if(lx0> PSXDisplay.DisplayEnd.x) return FALSE;
3145 if(ly0< PSXDisplay.DisplayPosition.y) return FALSE;
3146 if(ly0> PSXDisplay.DisplayEnd.y) return FALSE;
3147 if(lx1< PSXDisplay.DisplayPosition.x) return FALSE;
3148 if(lx1> PSXDisplay.DisplayEnd.x) return FALSE;
3149 if(ly1< PSXDisplay.DisplayPosition.y) return FALSE;
3150 if(ly1> PSXDisplay.DisplayEnd.y) return FALSE;
3151 if(lx2< PSXDisplay.DisplayPosition.x) return FALSE;
3152 if(lx2> PSXDisplay.DisplayEnd.x) return FALSE;
3153 if(ly2< PSXDisplay.DisplayPosition.y) return FALSE;
3154 if(ly2> PSXDisplay.DisplayEnd.y) return FALSE;
3155 if(lx3< PSXDisplay.DisplayPosition.x) return FALSE;
3156 if(lx3> PSXDisplay.DisplayEnd.x) return FALSE;
3157 if(ly3< PSXDisplay.DisplayPosition.y) return FALSE;
3158 if(ly3> PSXDisplay.DisplayEnd.y) return FALSE;
3162 BOOL bCheckFF9G4(unsigned char * baseAddr)
3164 static unsigned char pFF9G4Cache[32];
3165 static int iFF9Fix=0;
3171 if(bDrawOffscreenFrontFF9G4())
3173 short *sgpuData = ((short *) pFF9G4Cache);
\r
3175 memcpy(pFF9G4Cache,baseAddr,32);
\r
3177 if(sgpuData[2]==142)
\r
3191 int labr=GlobalTextABR;
3193 primPolyG4(pFF9G4Cache);
3194 GlobalTextABR = labr;
3201 ////////////////////////////////////////////////////////////////////////
3203 void primPolyG4(unsigned char * baseAddr)
3205 uint32_t *gpuData = (uint32_t *)baseAddr;
3206 short *sgpuData = ((short *)baseAddr);
3217 if(offset4()) return;
3219 bDrawTextured = FALSE;
3220 bDrawSmoothShaded = TRUE;
3221 SetRenderState(gpuData[0]);
3223 if(iOffscreenDrawing)
3227 if((dwActFixes&512) && bCheckFF9G4(baseAddr)) return;
3229 if(bDrawOffscreen4())
3231 InvalidateTextureAreaEx();
3232 drawPoly4G(gpuData[0], gpuData[2], gpuData[4], gpuData[6]);
3236 SetRenderMode(gpuData[0], FALSE);
3239 vertex[0].c.lcol=gpuData[0];
3240 vertex[1].c.lcol=gpuData[2];
3241 vertex[2].c.lcol=gpuData[4];
3242 vertex[3].c.lcol=gpuData[6];
3244 vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=vertex[3].c.col[3]=ubGloAlpha;
3247 PRIMdrawGouraudTri2Color(&vertex[0],&vertex[1], &vertex[2], &vertex[3]);
3252 ////////////////////////////////////////////////////////////////////////
3253 // cmd: flat shaded Texture3
3254 ////////////////////////////////////////////////////////////////////////
3256 BOOL DoLineCheck(uint32_t *gpuData)
3258 BOOL bQuad=FALSE;short dx,dy;
3262 dx=lx0-lx2;if(dx<0) dx=-dx;
3266 dy=ly1-ly0;if(dy<0) dy=-dy;
3269 vertex[3]=vertex[2];
3270 vertex[2]=vertex[0];
3271 vertex[2].x=vertex[3].x;
3276 vertex[3]=vertex[2];
3277 vertex[2].y=vertex[0].y;
3286 dy=ly0-ly1;if(dy<0) dy=-dy;
3289 vertex[3]=vertex[1];
3290 vertex[3].x=vertex[2].x;
3295 vertex[3]=vertex[2];
3296 vertex[3].y=vertex[1].y;
3306 dx=lx0-lx1;if(dx<0) dx=-dx;
3310 dy=ly2-ly0;if(dy<0) dy=-dy;
3313 vertex[3]=vertex[1];
3314 vertex[1]=vertex[0];
3315 vertex[1].x=vertex[3].x;
3320 vertex[3]=vertex[1];
3321 vertex[1].y=vertex[0].y;
3330 dy=ly2-ly0;if(dy<0) dy=-dy;
3333 vertex[3]=vertex[2];
3334 vertex[3].x=vertex[1].x;
3339 vertex[3]=vertex[1];
3340 vertex[3].y=vertex[2].y;
3350 dx=lx1-lx0;if(dx<0) dx=-dx;
3354 dy=ly1-ly2;if(dy<0) dy=-dy;
3358 vertex[3]=vertex[2];
3359 vertex[2].x=vertex[0].x;
3364 vertex[3]=vertex[2];
3365 vertex[2]=vertex[0];
3366 vertex[2].y=vertex[3].y;
3375 dy=ly2-ly1;if(dy<0) dy=-dy;
3379 vertex[3]=vertex[1];
3380 vertex[1].x=vertex[0].x;
3385 vertex[3]=vertex[1];
3386 vertex[1]=vertex[0];
3387 vertex[1].y=vertex[3].y;
3395 if(!bQuad) return FALSE;
3397 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);
3401 SetSemiTransMulti(1);
3402 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);
3408 if(bUseMultiPass) SetOpaqueColor(gpuData[0]);
3410 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);
3419 ////////////////////////////////////////////////////////////////////////
3421 void primPolyFT3(unsigned char * baseAddr)
3423 uint32_t *gpuData = ((uint32_t *) baseAddr);
3424 short *sgpuData = ((short *) baseAddr);
3433 if(offset3()) return;
3435 // do texture UV coordinates stuff
3436 gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;
3437 gl_vy[0]=gl_vy[3]=baseAddr[9];//(gpuData[2]>>8)&0xff;
3438 gl_ux[1]=baseAddr[16];//gpuData[4]&0xff;
3439 gl_vy[1]=baseAddr[17];//(gpuData[4]>>8)&0xff;
3440 gl_ux[2]=baseAddr[24];//gpuData[6]&0xff;
3441 gl_vy[2]=baseAddr[25];//(gpuData[6]>>8)&0xff;
3443 UpdateGlobalTP((unsigned short)(gpuData[4]>>16));
3444 ulClutID=gpuData[2]>>16;
3446 bDrawTextured = TRUE;
3447 bDrawSmoothShaded = FALSE;
3448 SetRenderState(gpuData[0]);
3450 if(iOffscreenDrawing)
3453 if(bDrawOffscreen3())
3455 InvalidateTextureAreaEx();
3456 SetRenderColor(gpuData[0]);
3457 drawPoly3FT(baseAddr);
3461 SetRenderMode(gpuData[0], TRUE);
3466 if(!(dwActFixes&0x10))
3468 if(DoLineCheck(gpuData)) return;
3471 PRIMdrawTexturedTri(&vertex[0], &vertex[1], &vertex[2]);
3475 SetSemiTransMulti(1);
3476 PRIMdrawTexturedTri(&vertex[0], &vertex[1], &vertex[2]);
3482 if(bUseMultiPass) SetOpaqueColor(gpuData[0]);
3484 PRIMdrawTexturedTri(&vertex[0], &vertex[1], &vertex[2]);
3491 ////////////////////////////////////////////////////////////////////////
3492 // cmd: flat shaded Texture4
3493 ////////////////////////////////////////////////////////////////////////
3495 #define ST_FAC 255.99f
\r
3497 void RectTexAlign(void)
\r
3499 int UFlipped = FALSE;
\r
3500 int VFlipped = FALSE;
\r
3502 if(gTexName==gTexFrameName) return;
\r
3506 if(!((lx1==lx3 && ly3==ly2 && lx2==lx0) ||
\r
3507 (lx1==lx2 && ly2==ly3 && lx3==lx0)))
\r
3512 if (vertex[0].tow > vertex[2].tow)
\r
3517 if (vertex[0].tow < vertex[2].tow)
\r
3524 if(!((lx2==lx3 && ly3==ly1 && lx1==lx0) ||
\r
3525 (lx2==lx1 && ly1==ly3 && lx3==lx0)))
\r
3530 if (vertex[0].tow > vertex[1].tow)
\r
3535 if (vertex[0].tow < vertex[1].tow)
\r
3542 if(!((lx3==lx2 && ly2==ly1 && lx1==lx0) ||
\r
3543 (lx3==lx1 && ly1==ly2 && lx2==lx0)))
\r
3548 if (vertex[0].tow > vertex[1].tow)
\r
3553 if (vertex[0].tow < vertex[1].tow)
\r
3563 if (vertex[0].sow > vertex[2].sow)
\r
3568 if (vertex[0].sow < vertex[2].sow)
\r
3577 if (vertex[0].sow > vertex[1].sow)
\r
3582 if (vertex[0].sow < vertex[1].sow)
\r
3591 if (vertex[0].sow > vertex[1].sow)
\r
3596 if (vertex[0].sow < vertex[1].sow)
\r
3609 vertex[2].sow+=0.95f/TWin.UScaleFactor;
\r
3610 vertex[3].sow+=0.95f/TWin.UScaleFactor;
\r
3613 vertex[0].sow+=0.95f/TWin.UScaleFactor;
\r
3614 vertex[1].sow+=0.95f/TWin.UScaleFactor;
\r
3617 vertex[1].sow+=0.95f/TWin.UScaleFactor;
\r
3618 vertex[3].sow+=0.95f/TWin.UScaleFactor;
\r
3621 vertex[0].sow+=0.95f/TWin.UScaleFactor;
\r
3622 vertex[2].sow+=0.95f/TWin.UScaleFactor;
\r
3625 vertex[1].sow+=0.95f/TWin.UScaleFactor;
\r
3626 vertex[2].sow+=0.95f/TWin.UScaleFactor;
\r
3629 vertex[0].sow+=0.95f/TWin.UScaleFactor;
\r
3630 vertex[3].sow+=0.95f/TWin.UScaleFactor;
\r
3639 vertex[2].sow+=1.0f/ST_FAC;
\r
3640 vertex[3].sow+=1.0f/ST_FAC;
\r
3643 vertex[0].sow+=1.0f/ST_FAC;
\r
3644 vertex[1].sow+=1.0f/ST_FAC;
\r
3647 vertex[1].sow+=1.0f/ST_FAC;
\r
3648 vertex[3].sow+=1.0f/ST_FAC;
\r
3651 vertex[0].sow+=1.0f/ST_FAC;
\r
3652 vertex[2].sow+=1.0f/ST_FAC;
\r
3655 vertex[1].sow+=1.0f/ST_FAC;
\r
3656 vertex[2].sow+=1.0f/ST_FAC;
\r
3659 vertex[0].sow+=1.0f/ST_FAC;
\r
3660 vertex[3].sow+=1.0f/ST_FAC;
\r
3670 vertex[2].sow+=1.0f/TWin.UScaleFactor;
\r
3671 vertex[3].sow+=1.0f/TWin.UScaleFactor;
\r
3674 vertex[0].sow+=1.0f/TWin.UScaleFactor;
\r
3675 vertex[1].sow+=1.0f/TWin.UScaleFactor;
\r
3678 vertex[1].sow+=1.0f/TWin.UScaleFactor;
\r
3679 vertex[3].sow+=1.0f/TWin.UScaleFactor;
\r
3682 vertex[0].sow+=1.0f/TWin.UScaleFactor;
\r
3683 vertex[2].sow+=1.0f/TWin.UScaleFactor;
\r
3686 vertex[1].sow+=1.0f/TWin.UScaleFactor;
\r
3687 vertex[2].sow+=1.0f/TWin.UScaleFactor;
\r
3690 vertex[0].sow+=1.0f/TWin.UScaleFactor;
\r
3691 vertex[3].sow+=1.0f/TWin.UScaleFactor;
\r
3700 vertex[2].sow+=1.0f;
\r
3701 vertex[3].sow+=1.0f;
\r
3704 vertex[0].sow+=1.0f;
\r
3705 vertex[1].sow+=1.0f;
\r
3708 vertex[1].sow+=1.0f;
\r
3709 vertex[3].sow+=1.0f;
\r
3712 vertex[0].sow+=1.0f;
\r
3713 vertex[2].sow+=1.0f;
\r
3716 vertex[1].sow+=1.0f;
\r
3717 vertex[2].sow+=1.0f;
\r
3720 vertex[0].sow+=1.0f;
\r
3721 vertex[3].sow+=1.0f;
\r
3736 vertex[2].tow+=0.95f/TWin.VScaleFactor;
\r
3737 vertex[3].tow+=0.95f/TWin.VScaleFactor;
\r
3740 vertex[0].tow+=0.95f/TWin.VScaleFactor;
\r
3741 vertex[1].tow+=0.95f/TWin.VScaleFactor;
\r
3744 vertex[1].tow+=0.95f/TWin.VScaleFactor;
\r
3745 vertex[3].tow+=0.95f/TWin.VScaleFactor;
\r
3748 vertex[0].tow+=0.95f/TWin.VScaleFactor;
\r
3749 vertex[2].tow+=0.95f/TWin.VScaleFactor;
\r
3752 vertex[1].tow+=0.95f/TWin.VScaleFactor;
\r
3753 vertex[2].tow+=0.95f/TWin.VScaleFactor;
\r
3756 vertex[0].tow+=0.95f/TWin.VScaleFactor;
\r
3757 vertex[3].tow+=0.95f/TWin.VScaleFactor;
\r
3766 vertex[2].tow+=1.0f/ST_FAC;
\r
3767 vertex[3].tow+=1.0f/ST_FAC;
\r
3770 vertex[0].tow+=1.0f/ST_FAC;
\r
3771 vertex[1].tow+=1.0f/ST_FAC;
\r
3774 vertex[1].tow+=1.0f/ST_FAC;
\r
3775 vertex[3].tow+=1.0f/ST_FAC;
\r
3778 vertex[0].tow+=1.0f/ST_FAC;
\r
3779 vertex[2].tow+=1.0f/ST_FAC;
\r
3782 vertex[1].tow+=1.0f/ST_FAC;
\r
3783 vertex[2].tow+=1.0f/ST_FAC;
\r
3786 vertex[0].tow+=1.0f/ST_FAC;
\r
3787 vertex[3].tow+=1.0f/ST_FAC;
\r
3797 vertex[2].tow+=1.0f/TWin.VScaleFactor;
\r
3798 vertex[3].tow+=1.0f/TWin.VScaleFactor;
\r
3801 vertex[0].tow+=1.0f/TWin.VScaleFactor;
\r
3802 vertex[1].tow+=1.0f/TWin.VScaleFactor;
\r
3805 vertex[1].tow+=1.0f/TWin.VScaleFactor;
\r
3806 vertex[3].tow+=1.0f/TWin.VScaleFactor;
\r
3809 vertex[0].tow+=1.0f/TWin.VScaleFactor;
\r
3810 vertex[2].tow+=1.0f/TWin.VScaleFactor;
\r
3813 vertex[1].tow+=1.0f/TWin.VScaleFactor;
\r
3814 vertex[2].tow+=1.0f/TWin.VScaleFactor;
\r
3817 vertex[0].tow+=1.0f/TWin.VScaleFactor;
\r
3818 vertex[3].tow+=1.0f/TWin.VScaleFactor;
\r
3827 vertex[2].tow+=1.0f;
\r
3828 vertex[3].tow+=1.0f;
\r
3831 vertex[0].tow+=1.0f;
\r
3832 vertex[1].tow+=1.0f;
\r
3835 vertex[1].tow+=1.0f;
\r
3836 vertex[3].tow+=1.0f;
\r
3839 vertex[0].tow+=1.0f;
\r
3840 vertex[2].tow+=1.0f;
\r
3843 vertex[1].tow+=1.0f;
\r
3844 vertex[2].tow+=1.0f;
\r
3847 vertex[0].tow+=1.0f;
\r
3848 vertex[3].tow+=1.0f;
\r
3857 void primPolyFT4(unsigned char * baseAddr)
3859 uint32_t *gpuData = ((uint32_t *)baseAddr);
3860 short *sgpuData = ((short *) baseAddr);
3871 if(offset4()) return;
3873 gl_vy[0]=baseAddr[9];//((gpuData[2]>>8)&0xff);
3874 gl_vy[1]=baseAddr[17];//((gpuData[4]>>8)&0xff);
3875 gl_vy[2]=baseAddr[25];//((gpuData[6]>>8)&0xff);
3876 gl_vy[3]=baseAddr[33];//((gpuData[8]>>8)&0xff);
3878 gl_ux[0]=baseAddr[8];//(gpuData[2]&0xff);
3879 gl_ux[1]=baseAddr[16];//(gpuData[4]&0xff);
3880 gl_ux[2]=baseAddr[24];//(gpuData[6]&0xff);
3881 gl_ux[3]=baseAddr[32];//(gpuData[8]&0xff);
3883 UpdateGlobalTP((unsigned short)(gpuData[4]>>16));
3884 ulClutID=(gpuData[2]>>16);
3886 bDrawTextured = TRUE;
3887 bDrawSmoothShaded = FALSE;
3888 SetRenderState(gpuData[0]);
3890 if(iOffscreenDrawing)
3893 if(bDrawOffscreen4())
3895 InvalidateTextureAreaEx();
3896 SetRenderColor(gpuData[0]);
3897 drawPoly4FT(baseAddr);
3901 SetRenderMode(gpuData[0], TRUE);
3909 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);
3913 SetSemiTransMulti(1);
3914 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);
3920 if(bUseMultiPass) SetOpaqueColor(gpuData[0]);
3923 if(bSmallAlpha && iFilterType<=2)
\r
3925 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
\r
3926 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
\r
3927 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);
\r
3928 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
\r
3929 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
\r
3933 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);
3940 ////////////////////////////////////////////////////////////////////////
3941 // cmd: smooth shaded Texture3
3942 ////////////////////////////////////////////////////////////////////////
3944 void primPolyGT3(unsigned char *baseAddr)
3946 uint32_t *gpuData = ((uint32_t *) baseAddr);
3947 short *sgpuData = ((short *) baseAddr);
3956 if(offset3()) return;
3959 gl_ux[0]=gl_ux[3]=baseAddr[8];//gpuData[2]&0xff;
3960 gl_vy[0]=gl_vy[3]=baseAddr[9];//(gpuData[2]>>8)&0xff;
3961 gl_ux[1]=baseAddr[20];//gpuData[5]&0xff;
3962 gl_vy[1]=baseAddr[21];//(gpuData[5]>>8)&0xff;
3963 gl_ux[2]=baseAddr[32];//gpuData[8]&0xff;
3964 gl_vy[2]=baseAddr[33];//(gpuData[8]>>8)&0xff;
3966 UpdateGlobalTP((unsigned short)(gpuData[5]>>16));
3967 ulClutID=(gpuData[2]>>16);
3969 bDrawTextured = TRUE;
3970 bDrawSmoothShaded = TRUE;
3971 SetRenderState(gpuData[0]);
3973 if(iOffscreenDrawing)
3976 if(bDrawOffscreen3())
3978 InvalidateTextureAreaEx();
3979 drawPoly3GT(baseAddr);
3983 SetRenderMode(gpuData[0], FALSE);
3990 //if(!bUseMultiPass) vertex[0].lcol=DoubleBGR2RGB(gpuData[0]); else vertex[0].lcol=gpuData[0];
3992 if(bGLBlend) vertex[0].c.lcol=0x7f7f7f;
3993 else vertex[0].c.lcol=0xffffff;
3994 vertex[0].c.col[3]=ubGloAlpha;
3997 PRIMdrawTexturedTri(&vertex[0], &vertex[1], &vertex[2]);
4003 PRIMdrawTexturedTri(&vertex[0], &vertex[1], &vertex[2]);
4009 if(!bUseMultiPass && !bGLBlend)
4011 vertex[0].c.lcol=DoubleBGR2RGB(gpuData[0]);
4012 vertex[1].c.lcol=DoubleBGR2RGB(gpuData[3]);
4013 vertex[2].c.lcol=DoubleBGR2RGB(gpuData[6]);
4017 vertex[0].c.lcol=gpuData[0];
4018 vertex[1].c.lcol=gpuData[3];
4019 vertex[2].c.lcol=gpuData[6];
4021 vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=ubGloAlpha;
4023 PRIMdrawTexGouraudTriColor(&vertex[0], &vertex[1], &vertex[2]);
4027 SetSemiTransMulti(1);
4028 PRIMdrawTexGouraudTriColor(&vertex[0], &vertex[1], &vertex[2]);
4036 vertex[0].c.lcol=DoubleBGR2RGB(gpuData[0]);
4037 vertex[1].c.lcol=DoubleBGR2RGB(gpuData[3]);
4038 vertex[2].c.lcol=DoubleBGR2RGB(gpuData[6]);
4039 vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=ubGloAlpha;
4042 PRIMdrawTexGouraudTriColor(&vertex[0], &vertex[1], &vertex[2]);
4049 ////////////////////////////////////////////////////////////////////////
4050 // cmd: smooth shaded Poly3
4051 ////////////////////////////////////////////////////////////////////////
4053 void primPolyG3(unsigned char *baseAddr)
4055 uint32_t *gpuData = ((uint32_t *)baseAddr);
4056 short *sgpuData = ((short *) baseAddr);
4065 if(offset3()) return;
4067 bDrawTextured = FALSE;
4068 bDrawSmoothShaded = TRUE;
4069 SetRenderState(gpuData[0]);
4071 if(iOffscreenDrawing)
4074 if(bDrawOffscreen3())
4076 InvalidateTextureAreaEx();
4077 drawPoly3G(gpuData[0], gpuData[2], gpuData[4]);
4081 SetRenderMode(gpuData[0], FALSE);
4084 vertex[0].c.lcol=gpuData[0];
4085 vertex[1].c.lcol=gpuData[2];
4086 vertex[2].c.lcol=gpuData[4];
4087 vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=ubGloColAlpha;
4089 PRIMdrawGouraudTriColor(&vertex[0], &vertex[1], &vertex[2]);
4094 ////////////////////////////////////////////////////////////////////////
4095 // cmd: smooth shaded Texture4
4096 ////////////////////////////////////////////////////////////////////////
4098 void primPolyGT4(unsigned char *baseAddr)
4100 uint32_t *gpuData = ((uint32_t *)baseAddr);
4101 short *sgpuData = ((short *)baseAddr);
4112 if(offset4()) return;
4115 gl_ux[0]=baseAddr[8];//gpuData[2]&0xff;
4116 gl_vy[0]=baseAddr[9];//(gpuData[2]>>8)&0xff;
4117 gl_ux[1]=baseAddr[20];//gpuData[5]&0xff;
4118 gl_vy[1]=baseAddr[21];//(gpuData[5]>>8)&0xff;
4119 gl_ux[2]=baseAddr[32];//gpuData[8]&0xff;
4120 gl_vy[2]=baseAddr[33];//(gpuData[8]>>8)&0xff;
4121 gl_ux[3]=baseAddr[44];//gpuData[11]&0xff;
4122 gl_vy[3]=baseAddr[45];//(gpuData[11]>>8)&0xff;
4124 UpdateGlobalTP((unsigned short)(gpuData[5]>>16));
4125 ulClutID=(gpuData[2]>>16);
4127 bDrawTextured = TRUE;
4128 bDrawSmoothShaded = TRUE;
4129 SetRenderState(gpuData[0]);
4131 if(iOffscreenDrawing)
4134 if(bDrawOffscreen4())
4136 InvalidateTextureAreaEx();
4137 drawPoly4GT(baseAddr);
4141 SetRenderMode(gpuData[0], FALSE);
4150 //if(!bUseMultiPass) vertex[0].lcol=DoubleBGR2RGB(gpuData[0]); else vertex[0].lcol=gpuData[0];
4151 if(bGLBlend) vertex[0].c.lcol=0x7f7f7f;
4152 else vertex[0].c.lcol=0xffffff;
4153 vertex[0].c.col[3]=ubGloAlpha;
4156 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);
4161 ubGloAlpha=ubGloColAlpha=0xff;
4163 PRIMdrawTexturedQuad(&vertex[0], &vertex[1], &vertex[3], &vertex[2]);
4169 if(!bUseMultiPass && !bGLBlend)
4171 vertex[0].c.lcol=DoubleBGR2RGB(gpuData[0]);
4172 vertex[1].c.lcol=DoubleBGR2RGB(gpuData[3]);
4173 vertex[2].c.lcol=DoubleBGR2RGB(gpuData[6]);
4174 vertex[3].c.lcol=DoubleBGR2RGB(gpuData[9]);
4178 vertex[0].c.lcol=gpuData[0];
4179 vertex[1].c.lcol=gpuData[3];
4180 vertex[2].c.lcol=gpuData[6];
4181 vertex[3].c.lcol=gpuData[9];
4184 vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=vertex[3].c.col[3]=ubGloAlpha;
4186 PRIMdrawTexGouraudTriColorQuad(&vertex[0], &vertex[1], &vertex[3],&vertex[2]);
4190 SetSemiTransMulti(1);
4191 PRIMdrawTexGouraudTriColorQuad(&vertex[0], &vertex[1], &vertex[3],&vertex[2]);
4199 vertex[0].c.lcol=DoubleBGR2RGB(gpuData[0]);
4200 vertex[1].c.lcol=DoubleBGR2RGB(gpuData[3]);
4201 vertex[2].c.lcol=DoubleBGR2RGB(gpuData[6]);
4202 vertex[3].c.lcol=DoubleBGR2RGB(gpuData[9]);
4203 vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=vertex[3].c.col[3]=ubGloAlpha;
4205 ubGloAlpha=ubGloColAlpha=0xff;
4207 PRIMdrawTexGouraudTriColorQuad(&vertex[0], &vertex[1], &vertex[3],&vertex[2]);
4214 ////////////////////////////////////////////////////////////////////////
4215 // cmd: smooth shaded Poly3
4216 ////////////////////////////////////////////////////////////////////////
4218 void primPolyF3(unsigned char *baseAddr)
4220 uint32_t *gpuData = ((uint32_t *) baseAddr);
4221 short *sgpuData = ((short *) baseAddr);
4230 if(offset3()) return;
4232 bDrawTextured = FALSE;
4233 bDrawSmoothShaded = FALSE;
4234 SetRenderState(gpuData[0]);
4236 if(iOffscreenDrawing)
4239 if(bDrawOffscreen3())
4241 InvalidateTextureAreaEx();
4242 drawPoly3F(gpuData[0]);
4246 SetRenderMode(gpuData[0], FALSE);
4249 vertex[0].c.lcol=gpuData[0];
4250 vertex[0].c.col[3]=ubGloColAlpha;
4253 PRIMdrawTri(&vertex[0], &vertex[1], &vertex[2]);
4258 ////////////////////////////////////////////////////////////////////////
4259 // cmd: skipping shaded polylines
4260 ////////////////////////////////////////////////////////////////////////
4262 void primLineGSkip(unsigned char *baseAddr)
4264 uint32_t *gpuData = ((uint32_t *) baseAddr);
4265 short *sgpuData = ((short *) baseAddr);
4272 while(!(((gpuData[i] & 0xF000F000) == 0x50005000) && i>=4))
\r
4276 ly1 = (short)((gpuData[i]>>16) & 0xffff);
4277 lx1 = (short)(gpuData[i] & 0xffff);
4279 i++;if(i>iMax) break;
4283 ////////////////////////////////////////////////////////////////////////
4284 // cmd: shaded polylines
4285 ////////////////////////////////////////////////////////////////////////
4287 void primLineGEx(unsigned char *baseAddr)
4289 uint32_t *gpuData = ((uint32_t *) baseAddr);
4291 short cx0,cx1,cy0,cy1;int i;BOOL bDraw=TRUE;
4293 bDrawTextured = FALSE;
4294 bDrawSmoothShaded = TRUE;
4295 SetRenderState(gpuData[0]);
4296 SetRenderMode(gpuData[0], FALSE);
4299 vertex[0].c.lcol=vertex[3].c.lcol=gpuData[0];
4300 vertex[0].c.col[3]=vertex[3].c.col[3]=ubGloColAlpha;
4301 ly1 = (short)((gpuData[1]>>16) & 0xffff);
4302 lx1 = (short)(gpuData[1] & 0xffff);
4306 //while((gpuData[i]>>24)!=0x55)
4307 //while((gpuData[i]&0x50000000)!=0x50000000)
\r
4308 // currently best way to check for poly line end:
\r
4309 while(!(((gpuData[i] & 0xF000F000) == 0x50005000) && i>=4))
\r
4312 vertex[1].c.lcol=vertex[2].c.lcol=vertex[0].c.lcol;
4313 vertex[0].c.lcol=vertex[3].c.lcol=gpuData[i];
4314 vertex[0].c.col[3]=vertex[3].c.col[3]=ubGloColAlpha;
4318 ly1 = (short)((gpuData[i]>>16) & 0xffff);
4319 lx1 = (short)(gpuData[i] & 0xffff);
4321 if(offsetline()) bDraw=FALSE; else bDraw=TRUE;
\r
4323 if (bDraw && ((lx0 != lx1) || (ly0 != ly1)))
4325 if(iOffscreenDrawing)
4327 cx0=lx0;cx1=lx1;cy0=ly0;cy1=ly1;
4329 if(bDrawOffscreen4())
4331 InvalidateTextureAreaEx();
4332 drawPoly4G(gpuData[i-3],gpuData[i-1],gpuData[i-3],gpuData[i-1]);
4334 lx0=cx0;lx1=cx1;ly0=cy0;ly1=cy1;
4337 PRIMdrawGouraudLine(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
4347 ////////////////////////////////////////////////////////////////////////
4348 // cmd: shaded polyline2
4349 ////////////////////////////////////////////////////////////////////////
4351 void primLineG2(unsigned char *baseAddr)
4353 uint32_t *gpuData = ((uint32_t *) baseAddr);
4354 short *sgpuData = ((short *) baseAddr);
4361 vertex[0].c.lcol=vertex[3].c.lcol=gpuData[0];
4362 vertex[1].c.lcol=vertex[2].c.lcol=gpuData[2];
4363 vertex[0].c.col[3]=vertex[1].c.col[3]=vertex[2].c.col[3]=vertex[3].c.col[3]=ubGloColAlpha;
4365 bDrawTextured = FALSE;
4366 bDrawSmoothShaded = TRUE;
4368 if((lx0 == lx1) && (ly0 == ly1)) return;
4370 if(offsetline()) return;
4372 SetRenderState(gpuData[0]);
4373 SetRenderMode(gpuData[0], FALSE);
4376 if(iOffscreenDrawing)
4379 if(bDrawOffscreen4())
4381 InvalidateTextureAreaEx();
4382 drawPoly4G(gpuData[0],gpuData[2],gpuData[0],gpuData[2]);
4386 //if(ClipVertexList4())
4387 PRIMdrawGouraudLine(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
4392 ////////////////////////////////////////////////////////////////////////
4393 // cmd: skipping flat polylines
4394 ////////////////////////////////////////////////////////////////////////
4396 void primLineFSkip(unsigned char *baseAddr)
4398 uint32_t *gpuData = ((uint32_t *) baseAddr);
4401 ly1 = (short)((gpuData[1]>>16) & 0xffff);
4402 lx1 = (short)(gpuData[1] & 0xffff);
4404 while(!(((gpuData[i] & 0xF000F000) == 0x50005000) && i>=3))
\r
4406 ly1 = (short)((gpuData[i]>>16) & 0xffff);
4407 lx1 = (short)(gpuData[i] & 0xffff);
4408 i++;if(i>iMax) break;
4412 ////////////////////////////////////////////////////////////////////////
4413 // cmd: drawing flat polylines
4414 ////////////////////////////////////////////////////////////////////////
4416 void primLineFEx(unsigned char *baseAddr)
4418 uint32_t *gpuData = ((uint32_t *) baseAddr);
4420 short cx0,cx1,cy0,cy1;int i;
4424 bDrawTextured = FALSE;
4425 bDrawSmoothShaded = FALSE;
4426 SetRenderState(gpuData[0]);
4427 SetRenderMode(gpuData[0], FALSE);
4430 vertex[0].c.lcol=gpuData[0];
4431 vertex[0].c.col[3]=ubGloColAlpha;
4433 ly1 = (short)((gpuData[1]>>16) & 0xffff);
4434 lx1 = (short)(gpuData[1] & 0xffff);
4438 // while(!(gpuData[i]&0x40000000))
4439 // while((gpuData[i]>>24)!=0x55)
4440 // while((gpuData[i]&0x50000000)!=0x50000000)
4441 // currently best way to check for poly line end:
4442 while(!(((gpuData[i] & 0xF000F000) == 0x50005000) && i>=3))
\r
4445 ly1 = (short)((gpuData[i]>>16) & 0xffff);
4446 lx1 = (short)(gpuData[i] & 0xffff);
4450 if(iOffscreenDrawing)
4452 cx0=lx0;cx1=lx1;cy0=ly0;cy1=ly1;
4454 if(bDrawOffscreen4())
4456 InvalidateTextureAreaEx();
4457 drawPoly4F(gpuData[0]);
4459 lx0=cx0;lx1=cx1;ly0=cy0;ly1=cy1;
4461 PRIMdrawFlatLine(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
4464 i++;if(i>iMax) break;
4470 ////////////////////////////////////////////////////////////////////////
4471 // cmd: drawing flat polyline2
4472 ////////////////////////////////////////////////////////////////////////
4474 void primLineF2(unsigned char *baseAddr)
4476 uint32_t *gpuData = ((uint32_t *) baseAddr);
4477 short *sgpuData = ((short *) baseAddr);
4484 if(offsetline()) return;
4486 bDrawTextured = FALSE;
4487 bDrawSmoothShaded = FALSE;
4488 SetRenderState(gpuData[0]);
4489 SetRenderMode(gpuData[0], FALSE);
4492 vertex[0].c.lcol=gpuData[0];
4493 vertex[0].c.col[3]=ubGloColAlpha;
4495 if(iOffscreenDrawing)
4498 if(bDrawOffscreen4())
4500 InvalidateTextureAreaEx();
4501 drawPoly4F(gpuData[0]);
4505 //if(ClipVertexList4())
4506 PRIMdrawFlatLine(&vertex[0], &vertex[1], &vertex[2], &vertex[3]);
4511 ////////////////////////////////////////////////////////////////////////
4512 // cmd: well, easiest command... not implemented
4513 ////////////////////////////////////////////////////////////////////////
4515 void primNI(unsigned char *bA)
4519 ////////////////////////////////////////////////////////////////////////
4520 // cmd func ptr table
4521 ////////////////////////////////////////////////////////////////////////
4523 void (*primTableJ[256])(unsigned char *) =
4526 primNI,primNI,primBlkFill,primNI,primNI,primNI,primNI,primNI,
4528 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4530 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4532 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4534 primPolyF3,primPolyF3,primPolyF3,primPolyF3,primPolyFT3,primPolyFT3,primPolyFT3,primPolyFT3,
4536 primPolyF4,primPolyF4,primPolyF4,primPolyF4,primPolyFT4,primPolyFT4,primPolyFT4,primPolyFT4,
4538 primPolyG3,primPolyG3,primPolyG3,primPolyG3,primPolyGT3,primPolyGT3,primPolyGT3,primPolyGT3,
4540 primPolyG4,primPolyG4,primPolyG4,primPolyG4,primPolyGT4,primPolyGT4,primPolyGT4,primPolyGT4,
4542 primLineF2,primLineF2,primLineF2,primLineF2,primNI,primNI,primNI,primNI,
4544 primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,primLineFEx,
4546 primLineG2,primLineG2,primLineG2,primLineG2,primNI,primNI,primNI,primNI,
4548 primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,primLineGEx,
4550 primTileS,primTileS,primTileS,primTileS,primSprtS,primSprtS,primSprtS,primSprtS,
4552 primTile1,primTile1,primTile1,primTile1,primNI,primNI,primNI,primNI,
4554 primTile8,primTile8,primTile8,primTile8,primSprt8,primSprt8,primSprt8,primSprt8,
4556 primTile16,primTile16,primTile16,primTile16,primSprt16,primSprt16,primSprt16,primSprt16,
4558 primMoveImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4560 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4562 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4564 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4566 primLoadImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4568 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4570 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4572 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4574 primStoreImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4576 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4578 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4580 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4582 primNI,cmdTexturePage,cmdTextureWindow,cmdDrawAreaStart,cmdDrawAreaEnd,cmdDrawOffset,cmdSTP,primNI,
4584 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4586 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4588 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI
4591 ////////////////////////////////////////////////////////////////////////
4592 // cmd func ptr table for skipping
4593 ////////////////////////////////////////////////////////////////////////
4595 void (*primTableSkip[256])(unsigned char *) =
4598 primNI,primNI,primBlkFill,primNI,primNI,primNI,primNI,primNI,
4600 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4602 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4604 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4606 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4608 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4610 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4612 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4614 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4616 primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,primLineFSkip,
4618 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4620 primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,primLineGSkip,
4622 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4624 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4626 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4628 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4630 primMoveImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4632 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4634 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4636 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4638 primLoadImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4640 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4642 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4644 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4646 primStoreImage,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4648 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4650 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4652 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4654 primNI,cmdTexturePage,cmdTextureWindow,cmdDrawAreaStart,cmdDrawAreaEnd,cmdDrawOffset,cmdSTP,primNI,
4656 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4658 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI,
4660 primNI,primNI,primNI,primNI,primNI,primNI,primNI,primNI