diff options
Diffstat (limited to 'plugins/peopsxgl/texture.c')
-rw-r--r-- | plugins/peopsxgl/texture.c | 4909 |
1 files changed, 4909 insertions, 0 deletions
diff --git a/plugins/peopsxgl/texture.c b/plugins/peopsxgl/texture.c new file mode 100644 index 0000000..01630da --- /dev/null +++ b/plugins/peopsxgl/texture.c @@ -0,0 +1,4909 @@ +/***************************************************************************
+ texture.c - description
+ -------------------
+ begin : Sun Mar 08 2009
+ copyright : (C) 1999-2009 by Pete Bernert
+ web : www.pbernert.com
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. See also the license.txt file for *
+ * additional informations. *
+ * *
+ ***************************************************************************/
+
+#include "stdafx.h" + +//////////////////////////////////////////////////////////////////////////////////// +// Texture related functions are here ! +//
+// The texture handling is heart and soul of this gpu. The plugin was developed
+// 1999, by this time no shaders were available. Since the psx gpu is making
+// heavy use of CLUT (="color lookup tables", aka palettized textures), it was
+// an interesting task to get those emulated at good speed on NV TNT cards
+// (which was my major goal when I created the first "gpuPeteTNT"). Later cards
+// (Geforce256) supported texture palettes by an OGL extension, but at some point
+// this support was dropped again by gfx card vendors.
+// Well, at least there is a certain advatage, if no texture palettes extension can
+// be used: it is possible to modify the textures in any way, allowing "hi-res"
+// textures and other tweaks.
+//
+// My main texture caching is kinda complex: the plugin is allocating "n" 256x256 textures,
+// and it places small psx texture parts inside them. The plugin keeps track what
+// part (with what palette) it had placed in which texture, so it can re-use this
+// part again. The more ogl textures it can use, the better (of course the managing/
+// searching will be slower, but everything is faster than uploading textures again
+// and again to a gfx card). My first card (TNT1) had 16 MB Vram, and it worked
+// well with many games, but I recommend nowadays 64 MB Vram to get a good speed.
+//
+// Sadly, there is also a second kind of texture cache needed, for "psx texture windows".
+// Those are "repeated" textures, so a psx "texture window" needs to be put in
+// a whole texture to use the GL_TEXTURE_WRAP_ features. This cache can get full very
+// fast in games which are having an heavy "texture window" usage, like RRT4. As an
+// alternative, this plugin can use the OGL "palette" extension on texture windows,
+// if available. Nowadays also a fragment shader can easily be used to emulate
+// texture wrapping in a texture atlas, so the main cache could hold the texture
+// windows as well (that's what I am doing in the OGL2 plugin). But currently the
+// OGL1 plugin is a "shader-free" zone, so heavy "texture window" games will cause
+// much texture uploads.
+//
+// Some final advice: take care if you change things in here. I've removed my ASM
+// handlers (they didn't cause much speed gain anyway) for readability/portability,
+// but still the functions/data structures used here are easy to mess up. I guess it
+// can be a pain in the ass to port the plugin to another byte order :)
+//
+////////////////////////////////////////////////////////////////////////////////////
+ +#define _IN_TEXTURE + +#include "externals.h" +#include "texture.h" +#include "gpu.h" +#include "prim.h" + +#define CLUTCHK 0x00060000 +#define CLUTSHIFT 17 + +//////////////////////////////////////////////////////////////////////// +// texture conversion buffer .. +//////////////////////////////////////////////////////////////////////// + +int iHiResTextures=0; +GLubyte ubPaletteBuffer[256][4]; +GLuint gTexMovieName=0; +GLuint gTexBlurName=0; +GLuint gTexFrameName=0; +int iTexGarbageCollection=1; +uint32_t dwTexPageComp=0; +int iVRamSize=0; +int iClampType=GL_CLAMP;
+ +void (*LoadSubTexFn) (int,int,short,short);
+uint32_t (*PalTexturedColourFn) (uint32_t); + +//////////////////////////////////////////////////////////////////////// +// defines +//////////////////////////////////////////////////////////////////////// + +#define PALCOL(x) PalTexturedColourFn (x) + +#define CSUBSIZE 2048 +#define CSUBSIZEA 8192 +#define CSUBSIZES 4096 + +#define OFFA 0 +#define OFFB 2048 +#define OFFC 4096 +#define OFFD 6144 + +#define XOFFA 0 +#define XOFFB 512 +#define XOFFC 1024 +#define XOFFD 1536 + +#define SOFFA 0 +#define SOFFB 1024 +#define SOFFC 2048 +#define SOFFD 3072 + +#define MAXWNDTEXCACHE 128 +
+#define XCHECK(pos1,pos2) ((pos1.c[0]>=pos2.c[1])&&(pos1.c[1]<=pos2.c[0])&&(pos1.c[2]>=pos2.c[3])&&(pos1.c[3]<=pos2.c[2])) +#define INCHECK(pos2,pos1) ((pos1.c[0]<=pos2.c[0]) && (pos1.c[1]>=pos2.c[1]) && (pos1.c[2]<=pos2.c[2]) && (pos1.c[3]>=pos2.c[3])) + +//////////////////////////////////////////////////////////////////////// + +unsigned char * CheckTextureInSubSCache(int TextureMode, uint32_t GivenClutId, unsigned short *pCache); +void LoadSubTexturePageSort(int pageid, int mode, short cx, short cy); +void LoadPackedSubTexturePageSort(int pageid, int mode, short cx, short cy); +void DefineSubTextureSort(void); + +//////////////////////////////////////////////////////////////////////// +// some globals +//////////////////////////////////////////////////////////////////////// + +GLint giWantedRGBA=4; +GLint giWantedFMT=GL_RGBA; +GLint giWantedTYPE=GL_UNSIGNED_BYTE; +int GlobalTexturePage; +GLint XTexS; +GLint YTexS; +GLint DXTexS; +GLint DYTexS; +int iSortTexCnt=32; +BOOL bUseFastMdec=FALSE; +BOOL bUse15bitMdec=FALSE; +int iFrameTexType=0; +int iFrameReadType=0; + +uint32_t (*TCF[2]) (uint32_t); +unsigned short (*PTCF[2]) (unsigned short); + +//////////////////////////////////////////////////////////////////////// +// texture cache implementation +//////////////////////////////////////////////////////////////////////// +
+// "texture window" cache entry
+ +typedef struct textureWndCacheEntryTag +{ + uint32_t ClutID; + short pageid; + short textureMode; + short Opaque; + short used; + EXLong pos; + GLuint texname; +} textureWndCacheEntry; +
+// "standard texture" cache entry (12 byte per entry, as small as possible... we need lots of them)
+ +typedef struct textureSubCacheEntryTagS +{ + uint32_t ClutID; + EXLong pos; + unsigned char posTX; + unsigned char posTY; + unsigned char cTexID; + unsigned char Opaque; +} textureSubCacheEntryS; + +//---------------------------------------------
+
+#define MAXTPAGES_MAX 64
+#define MAXSORTTEX_MAX 196
+
+//---------------------------------------------
+
+textureWndCacheEntry wcWndtexStore[MAXWNDTEXCACHE]; +textureSubCacheEntryS * pscSubtexStore[3][MAXTPAGES_MAX]; +EXLong * pxSsubtexLeft [MAXSORTTEX_MAX]; +GLuint uiStexturePage[MAXSORTTEX_MAX]; + +unsigned short usLRUTexPage = 0; + +int iMaxTexWnds = 0; +int iTexWndTurn = 0; +int iTexWndLimit = MAXWNDTEXCACHE/2; + +GLubyte * texturepart = NULL; +GLubyte * texturebuffer = NULL; +uint32_t g_x1,g_y1,g_x2,g_y2; +unsigned char ubOpaqueDraw = 0; +
+unsigned short MAXTPAGES = 32;
+unsigned short CLUTMASK = 0x7fff;
+unsigned short CLUTYMASK = 0x1ff;
+unsigned short MAXSORTTEX = 196;
+
+//////////////////////////////////////////////////////////////////////// +// Texture color conversions... all my ASM funcs are removed for easier
+// porting... and honestly: nowadays the speed gain would be pointless +//////////////////////////////////////////////////////////////////////// + +uint32_t XP8RGBA(uint32_t BGR) +{ + if(!(BGR&0xffff)) return 0x50000000; + if(DrawSemiTrans && !(BGR&0x8000)) + {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);} + return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000; +} + +uint32_t XP8RGBAEx(uint32_t BGR) +{ + if(!(BGR&0xffff)) return 0x03000000; + if(DrawSemiTrans && !(BGR&0x8000)) + {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);} + return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000; +} + +uint32_t CP8RGBA(uint32_t BGR) +{ + uint32_t l; + if(!(BGR&0xffff)) return 0x50000000; + if(DrawSemiTrans && !(BGR&0x8000)) + {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);} + l=((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000; + if(l==0xffffff00) l=0xff000000; + return l; +} + +uint32_t CP8RGBAEx(uint32_t BGR) +{ + uint32_t l; + if(!(BGR&0xffff)) return 0x03000000; + if(DrawSemiTrans && !(BGR&0x8000)) + {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);} + l=((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000; + if(l==0xffffff00) l=0xff000000; + return l; +} + +uint32_t XP8RGBA_0(uint32_t BGR) +{ + if(!(BGR&0xffff)) return 0x50000000; + return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000; +} + +uint32_t XP8RGBAEx_0(uint32_t BGR) +{ + if(!(BGR&0xffff)) return 0x03000000; + return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000; +} + +uint32_t XP8BGRA_0(uint32_t BGR) +{ + if(!(BGR&0xffff)) return 0x50000000; + return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000; +} + +uint32_t XP8BGRAEx_0(uint32_t BGR) +{ + if(!(BGR&0xffff)) return 0x03000000; + return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000; +} + +uint32_t CP8RGBA_0(uint32_t BGR) +{ + uint32_t l; + + if(!(BGR&0xffff)) return 0x50000000; + l=((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000; + if(l==0xfff8f800) l=0xff000000; + return l; +} + +uint32_t CP8RGBAEx_0(uint32_t BGR) +{ + uint32_t l; + + if(!(BGR&0xffff)) return 0x03000000; + l=((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000; + if(l==0xfff8f800) l=0xff000000; + return l; +} + +uint32_t CP8BGRA_0(uint32_t BGR) +{ + uint32_t l; + + if(!(BGR&0xffff)) return 0x50000000; + l=((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000; + if(l==0xff00f8f8) l=0xff000000; + return l; +} + +uint32_t CP8BGRAEx_0(uint32_t BGR) +{ + uint32_t l; + + if(!(BGR&0xffff)) return 0x03000000; + l=((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000; + if(l==0xff00f8f8) l=0xff000000; + return l; +} + +uint32_t XP8RGBA_1(uint32_t BGR) +{ + if(!(BGR&0xffff)) return 0x50000000; + if(!(BGR&0x8000)) {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);} + return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000; +} + +uint32_t XP8RGBAEx_1(uint32_t BGR) +{ + if(!(BGR&0xffff)) return 0x03000000; + if(!(BGR&0x8000)) {ubOpaqueDraw=1;return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff);} + return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000; +} + +uint32_t XP8BGRA_1(uint32_t BGR) +{ + if(!(BGR&0xffff)) return 0x50000000; + if(!(BGR&0x8000)) {ubOpaqueDraw=1;return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff);} + return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000; +} + +uint32_t XP8BGRAEx_1(uint32_t BGR) +{ + if(!(BGR&0xffff)) return 0x03000000; + if(!(BGR&0x8000)) {ubOpaqueDraw=1;return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff);} + return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000; +} + +uint32_t P8RGBA(uint32_t BGR) +{ + if(!(BGR&0xffff)) return 0; + return ((((BGR<<3)&0xf8)|((BGR<<6)&0xf800)|((BGR<<9)&0xf80000))&0xffffff)|0xff000000; +} + +uint32_t P8BGRA(uint32_t BGR) +{ + if(!(BGR&0xffff)) return 0; + return ((((BGR>>7)&0xf8)|((BGR<<6)&0xf800)|((BGR<<19)&0xf80000))&0xffffff)|0xff000000; +} + +unsigned short XP5RGBA(unsigned short BGR) +{ + if(!BGR) return 0; + if(DrawSemiTrans && !(BGR&0x8000)) + {ubOpaqueDraw=1;return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)));} + return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1; +} + +unsigned short XP5RGBA_0 (unsigned short BGR) +{ + if(!BGR) return 0; + + return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1; +} + +unsigned short CP5RGBA_0 (unsigned short BGR) +{ + unsigned short s; + + if(!BGR) return 0; + + s=((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1; + if(s==0x07ff) s=1; + return s; +} + +unsigned short XP5RGBA_1(unsigned short BGR) +{ + if(!BGR) return 0; + if(!(BGR&0x8000)) + {ubOpaqueDraw=1;return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)));} + return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1; +} + +unsigned short P5RGBA(unsigned short BGR) +{ + if(!BGR) return 0; + return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)))|1; +} + +unsigned short XP4RGBA(unsigned short BGR) +{ + if(!BGR) return 6; + if(DrawSemiTrans && !(BGR&0x8000)) + {ubOpaqueDraw=1;return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)));} + return (((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf; +} + +unsigned short XP4RGBA_0 (unsigned short BGR) +{ + if(!BGR) return 6; + return (((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf; +} + +unsigned short CP4RGBA_0 (unsigned short BGR) +{ + unsigned short s; + if(!BGR) return 6; + s=(((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf; + if(s==0x0fff) s=0x000f; + return s; +} + +unsigned short XP4RGBA_1(unsigned short BGR) +{ + if(!BGR) return 6; + if(!(BGR&0x8000)) + {ubOpaqueDraw=1;return ((((BGR<<11))|((BGR>>9)&0x3e)|((BGR<<1)&0x7c0)));} + return (((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf; +} + +unsigned short P4RGBA(unsigned short BGR) +{ + if(!BGR) return 0; + return (((((BGR&0x1e)<<11))|((BGR&0x7800)>>7)|((BGR&0x3c0)<<2)))|0xf; +} + +//////////////////////////////////////////////////////////////////////// +// CHECK TEXTURE MEM (on plugin startup) +//////////////////////////////////////////////////////////////////////// + +int iFTexA=512; +int iFTexB=512; + +void CheckTextureMemory(void) +{ + GLboolean b;GLboolean * bDetail; + int i,iCnt,iRam=iVRamSize*1024*1024; + int iTSize;char * p; + + if(iBlurBuffer) + { + char * p; + + if(iResX>1024) iFTexA=2048; + else + if(iResX>512) iFTexA=1024; + else iFTexA=512; + if(iResY>1024) iFTexB=2048; + else + if(iResY>512) iFTexB=1024; + else iFTexB=512; + + glGenTextures(1, &gTexBlurName); + gTexName=gTexBlurName; + glBindTexture(GL_TEXTURE_2D, gTexName); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + p=(char *)malloc(iFTexA*iFTexB*4); + memset(p,0,iFTexA*iFTexB*4); + glTexImage2D(GL_TEXTURE_2D, 0, 3, iFTexA, iFTexB, 0, GL_RGB, GL_UNSIGNED_BYTE, p); + free(p); + glGetError(); + iRam-=iFTexA*iFTexB*3; + iFTexA=(iResX*256)/iFTexA; + iFTexB=(iResY*256)/iFTexB; + } + + if(iVRamSize) + { + int ts; + + iRam-=(iResX*iResY*8); + iRam-=(iResX*iResY*(iZBufferDepth/8)); + + if(iTexQuality==0 || iTexQuality==3) ts=4; + else ts=2; + + if(iHiResTextures) + iSortTexCnt=iRam/(512*512*ts); + else iSortTexCnt=iRam/(256*256*ts); + + if(iSortTexCnt>MAXSORTTEX) + { + iSortTexCnt=MAXSORTTEX-min(1,iHiResTextures); + } + else + { + iSortTexCnt-=3+min(1,iHiResTextures); + if(iSortTexCnt<8) iSortTexCnt=8; + } + + for(i=0;i<MAXSORTTEX;i++) + uiStexturePage[i]=0; + + return; + } + + + if(iHiResTextures) iTSize=512; + else iTSize=256; + p=(char *)malloc(iTSize*iTSize*4); + + iCnt=0; + glGenTextures(MAXSORTTEX,uiStexturePage); + for(i=0;i<MAXSORTTEX;i++) + { + glBindTexture(GL_TEXTURE_2D,uiStexturePage[i]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, giWantedRGBA, iTSize, iTSize, 0,GL_RGBA, giWantedTYPE, p); + } + glBindTexture(GL_TEXTURE_2D,0); + + free(p); +
+ bDetail=malloc(MAXSORTTEX*sizeof(GLboolean)); + memset(bDetail,0,MAXSORTTEX*sizeof(GLboolean)); + b=glAreTexturesResident(MAXSORTTEX,uiStexturePage,bDetail); + + glDeleteTextures(MAXSORTTEX,uiStexturePage); + + for(i=0;i<MAXSORTTEX;i++) + { + if(bDetail[i]) iCnt++; + uiStexturePage[i]=0; + }
+
+ free(bDetail);
+ + if(b) iSortTexCnt=MAXSORTTEX-min(1,iHiResTextures); + else iSortTexCnt=iCnt-3+min(1,iHiResTextures); // place for menu&texwnd + + if(iSortTexCnt<8) iSortTexCnt=8; +} + +//////////////////////////////////////////////////////////////////////// +// Main init of textures +//////////////////////////////////////////////////////////////////////// + +void InitializeTextureStore() +{
+ int i,j;
+
+ if(iGPUHeight==1024)
+ {
+ MAXTPAGES = 64;
+ CLUTMASK = 0xffff;
+ CLUTYMASK = 0x3ff;
+ MAXSORTTEX = 128;
+ iTexGarbageCollection=0;
+ }
+ else
+ {
+ MAXTPAGES = 32;
+ CLUTMASK = 0x7fff;
+ CLUTYMASK = 0x1ff;
+ MAXSORTTEX = 196;
+ }
+ + memset(vertex,0,4*sizeof(OGLVertex)); // init vertices + + gTexName=0; // init main tex name + + iTexWndLimit=MAXWNDTEXCACHE; + if(!iUsePalTextures) iTexWndLimit/=2; + + memset(wcWndtexStore,0,sizeof(textureWndCacheEntry)* + MAXWNDTEXCACHE); + texturepart=(GLubyte *)malloc(256*256*4); + memset(texturepart,0,256*256*4); + if(iHiResTextures) + texturebuffer=(GLubyte *)malloc(512*512*4); + else texturebuffer=NULL; + + for(i=0;i<3;i++) // -> info for 32*3 + for(j=0;j<MAXTPAGES;j++) + { + pscSubtexStore[i][j]=(textureSubCacheEntryS *)malloc(CSUBSIZES*sizeof(textureSubCacheEntryS)); + memset(pscSubtexStore[i][j],0,CSUBSIZES*sizeof(textureSubCacheEntryS)); + } + for(i=0;i<MAXSORTTEX;i++) // -> info 0..511 + { + pxSsubtexLeft[i]=(EXLong *)malloc(CSUBSIZE*sizeof(EXLong)); + memset(pxSsubtexLeft[i],0,CSUBSIZE*sizeof(EXLong)); + uiStexturePage[i]=0; + } +} + +//////////////////////////////////////////////////////////////////////// +// Clean up on exit +//////////////////////////////////////////////////////////////////////// + +void CleanupTextureStore() +{ + int i,j;textureWndCacheEntry * tsx; + //----------------------------------------------------// + glBindTexture(GL_TEXTURE_2D,0); + //----------------------------------------------------// + free(texturepart); // free tex part + texturepart=0; + if(texturebuffer) + { + free(texturebuffer); + texturebuffer=0; + } + //----------------------------------------------------// + tsx=wcWndtexStore; // loop tex window cache + for(i=0;i<MAXWNDTEXCACHE;i++,tsx++) + { + if(tsx->texname) // -> some tex? + glDeleteTextures(1,&tsx->texname); // --> delete it + } + iMaxTexWnds=0; // no more tex wnds + //----------------------------------------------------// + if(gTexMovieName!=0) // some movie tex? + glDeleteTextures(1, &gTexMovieName); // -> delete it + gTexMovieName=0; // no more movie tex + //----------------------------------------------------// + if(gTexFrameName!=0) // some 15bit framebuffer tex? + glDeleteTextures(1, &gTexFrameName); // -> delete it + gTexFrameName=0; // no more movie tex + //----------------------------------------------------// + if(gTexBlurName!=0) // some 15bit framebuffer tex? + glDeleteTextures(1, &gTexBlurName); // -> delete it + gTexBlurName=0; // no more movie tex + //----------------------------------------------------// + for(i=0;i<3;i++) // -> loop + for(j=0;j<MAXTPAGES;j++) // loop tex pages + { + free(pscSubtexStore[i][j]); // -> clean mem + } + for(i=0;i<MAXSORTTEX;i++) + { + if(uiStexturePage[i]) // --> tex used ? + { + glDeleteTextures(1,&uiStexturePage[i]); + uiStexturePage[i]=0; // --> delete it + } + free(pxSsubtexLeft[i]); // -> clean mem + } + //----------------------------------------------------// +} + +//////////////////////////////////////////////////////////////////////// +// Reset textures in game... +//////////////////////////////////////////////////////////////////////// + +void ResetTextureArea(BOOL bDelTex) +{ + int i,j;textureSubCacheEntryS * tss;EXLong * lu; + textureWndCacheEntry * tsx; + //----------------------------------------------------// + + dwTexPageComp=0; + + //----------------------------------------------------// + if(bDelTex) {glBindTexture(GL_TEXTURE_2D,0);gTexName=0;} + //----------------------------------------------------// + tsx=wcWndtexStore; + for(i=0;i<MAXWNDTEXCACHE;i++,tsx++) + { + tsx->used=0; + if(bDelTex && tsx->texname) + { + glDeleteTextures(1,&tsx->texname); + tsx->texname=0; + } + } + iMaxTexWnds=0; + //----------------------------------------------------// + + for(i=0;i<3;i++) + for(j=0;j<MAXTPAGES;j++) + { + tss=pscSubtexStore[i][j]; + (tss+SOFFA)->pos.l=0; + (tss+SOFFB)->pos.l=0; + (tss+SOFFC)->pos.l=0; + (tss+SOFFD)->pos.l=0; + } + + for(i=0;i<iSortTexCnt;i++) + { + lu=pxSsubtexLeft[i]; + lu->l=0; + if(bDelTex && uiStexturePage[i]) + {glDeleteTextures(1,&uiStexturePage[i]);uiStexturePage[i]=0;} + } +} + + +//////////////////////////////////////////////////////////////////////// +// Invalidate tex windows +//////////////////////////////////////////////////////////////////////// + +void InvalidateWndTextureArea(int X, int Y, int W, int H) +{ + int i,px1,px2,py1,py2,iYM=1; + textureWndCacheEntry * tsw=wcWndtexStore; + + W+=X-1; + H+=Y-1; + if(X<0) X=0;if(X>1023) X=1023; + if(W<0) W=0;if(W>1023) W=1023;
+ if(Y<0) Y=0;if(Y>iGPUHeightMask) Y=iGPUHeightMask;
+ if(H<0) H=0;if(H>iGPUHeightMask) H=iGPUHeightMask;
+ W++;H++; +
+ if(iGPUHeight==1024) iYM=3;
+
+ py1=min(iYM,Y>>8);
+ py2=min(iYM,H>>8); // y: 0 or 1
+ + px1=max(0,(X>>6)); + px2=min(15,(W>>6)); + + if(py1==py2) + { + py1=py1<<4;px1+=py1;px2+=py1; // change to 0-31 + for(i=0;i<iMaxTexWnds;i++,tsw++) + { + if(tsw->used) + { + if(tsw->pageid>=px1 && tsw->pageid<=px2) + { + tsw->used=0; + } + } + } + } + else + { + py1=px1+16;py2=px2+16; + for(i=0;i<iMaxTexWnds;i++,tsw++) + { + if(tsw->used) + { + if((tsw->pageid>=px1 && tsw->pageid<=px2) || + (tsw->pageid>=py1 && tsw->pageid<=py2)) + { + tsw->used=0; + } + } + } + } + + // adjust tex window count + tsw=wcWndtexStore+iMaxTexWnds-1; + while(iMaxTexWnds && !tsw->used) {iMaxTexWnds--;tsw--;} +} + + + +//////////////////////////////////////////////////////////////////////// +// same for sort textures +//////////////////////////////////////////////////////////////////////// + +void MarkFree(textureSubCacheEntryS * tsx) +{ + EXLong * ul, * uls; + int j,iMax;unsigned char x1,y1,dx,dy; + + uls=pxSsubtexLeft[tsx->cTexID]; + iMax=uls->l;ul=uls+1; + + if(!iMax) return; + + for(j=0;j<iMax;j++,ul++) + if(ul->l==0xffffffff) break; + + if(j<CSUBSIZE-2) + { + if(j==iMax) uls->l=uls->l+1; + + x1=tsx->posTX;dx=tsx->pos.c[2]-tsx->pos.c[3]; + if(tsx->posTX) {x1--;dx+=3;} + y1=tsx->posTY;dy=tsx->pos.c[0]-tsx->pos.c[1]; + if(tsx->posTY) {y1--;dy+=3;} + + ul->c[3]=x1; + ul->c[2]=dx; + ul->c[1]=y1; + ul->c[0]=dy; + } +} + +void InvalidateSubSTextureArea(int X, int Y, int W, int H) +{ + int i,j,k,iMax,px,py,px1,px2,py1,py2,iYM = 1; + EXLong npos; + textureSubCacheEntryS *tsb; + int x1,x2,y1,y2,xa,sw; + + W+=X-1; + H+=Y-1; + if(X<0) X=0;if(X>1023) X=1023; + if(W<0) W=0;if(W>1023) W=1023;
+ if(Y<0) Y=0;if(Y>iGPUHeightMask) Y=iGPUHeightMask;
+ if(H<0) H=0;if(H>iGPUHeightMask) H=iGPUHeightMask;
+ W++;H++; +
+ if(iGPUHeight==1024) iYM=3;
+ + py1=min(iYM,Y>>8);
+ py2=min(iYM,H>>8); // y: 0 or 1
+ px1=max(0,(X>>6)-3);
+ px2=min(15,(W>>6)+3); // x: 0-15 + + for(py=py1;py<=py2;py++) + { + j=(py<<4)+px1; // get page + + y1=py*256;y2=y1+255; + + if(H<y1) continue; + if(Y>y2) continue; + + if(Y>y1) y1=Y; + if(H<y2) y2=H; + if(y2<y1) {sw=y1;y1=y2;y2=sw;} + y1=((y1%256)<<8); + y2=(y2%256); + + for(px=px1;px<=px2;px++,j++) + { + for(k=0;k<3;k++) + { + xa=x1=px<<6; + if(W<x1) continue; + x2=x1+(64<<k)-1; + if(X>x2) continue; + + if(X>x1) x1=X; + if(W<x2) x2=W; + if(x2<x1) {sw=x1;x1=x2;x2=sw;} +
+ if (dwGPUVersion == 2)
+ npos.l=0x00ff00ff;
+ else
+ npos.l=((x1-xa)<<(26-k))|((x2-xa)<<(18-k))|y1|y2; + + { + tsb=pscSubtexStore[k][j]+SOFFA;iMax=tsb->pos.l;tsb++; + for(i=0;i<iMax;i++,tsb++) + if(tsb->ClutID && XCHECK(tsb->pos,npos)) {tsb->ClutID=0;MarkFree(tsb);} + +// if(npos.l & 0x00800000) + { + tsb=pscSubtexStore[k][j]+SOFFB;iMax=tsb->pos.l;tsb++; + for(i=0;i<iMax;i++,tsb++) + if(tsb->ClutID && XCHECK(tsb->pos,npos)) {tsb->ClutID=0;MarkFree(tsb);} + } + +// if(npos.l & 0x00000080) + { + tsb=pscSubtexStore[k][j]+SOFFC;iMax=tsb->pos.l;tsb++; + for(i=0;i<iMax;i++,tsb++) + if(tsb->ClutID && XCHECK(tsb->pos,npos)) {tsb->ClutID=0;MarkFree(tsb);} + } + +// if(npos.l & 0x00800080) + { + tsb=pscSubtexStore[k][j]+SOFFD;iMax=tsb->pos.l;tsb++; + for(i=0;i<iMax;i++,tsb++) + if(tsb->ClutID && XCHECK(tsb->pos,npos)) {tsb->ClutID=0;MarkFree(tsb);} + } + } + } + } + } +} + +//////////////////////////////////////////////////////////////////////// +// Invalidate some parts of cache: main routine +//////////////////////////////////////////////////////////////////////// + +void InvalidateTextureAreaEx(void) +{ + short W=sxmax-sxmin; + short H=symax-symin; + + if (W == 0 && H == 0) return; + + if (iMaxTexWnds) + InvalidateWndTextureArea(sxmin,symin,W,H); + + InvalidateSubSTextureArea(sxmin,symin,W,H); +} + +//////////////////////////////////////////////////////////////////////// + +void InvalidateTextureArea(int X, int Y, int W, int H) +{ + if (W == 0 && H == 0) return; + + if (iMaxTexWnds) InvalidateWndTextureArea(X, Y, W, H); + + InvalidateSubSTextureArea(X, Y, W, H); +} + + +//////////////////////////////////////////////////////////////////////// +// tex window: define +//////////////////////////////////////////////////////////////////////// + +void DefineTextureWnd(void) +{ + if (gTexName == 0) + glGenTextures(1, &gTexName); + + glBindTexture(GL_TEXTURE_2D, gTexName); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + if(iFilterType && iFilterType<3 && iHiResTextures!=2) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + else + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } + + glTexImage2D(GL_TEXTURE_2D, 0,giWantedRGBA, + TWin.Position.x1, + TWin.Position.y1, + 0, giWantedFMT, giWantedTYPE, texturepart); +} + +//////////////////////////////////////////////////////////////////////// +// tex window: load packed stretch +//////////////////////////////////////////////////////////////////////// + +void LoadStretchPackedWndTexturePage(int pageid, int mode, short cx, short cy) +{ + uint32_t start, row, column, j, sxh, sxm, ldx, ldy, ldxo; + unsigned int palstart; + unsigned short *px, *pa, *ta; + unsigned char *cSRCPtr,*cOSRCPtr; + unsigned short *wSRCPtr,*wOSRCPtr; + uint32_t LineOffset; + unsigned short s; + int pmult = pageid / 16; + unsigned short (*LPTCOL)(unsigned short); + + LPTCOL = PTCF[DrawSemiTrans]; + + ldxo = TWin.Position.x1-TWin.OPosition.x1; + ldy = TWin.Position.y1-TWin.OPosition.y1; + + pa = px = (unsigned short *)ubPaletteBuffer; + ta = (unsigned short *)texturepart; + palstart = cx + (cy * 1024); + + ubOpaqueDraw = 0; + + switch (mode) + { + //--------------------------------------------------// + // 4bit texture load .. + case 0:
+ if(GlobalTextIL)
+ {
+ unsigned int TXV,TXU,n_xi,n_yi;
+
+ wSRCPtr=psxVuw+palstart;
+ for(row=0;row<16;row++)
+ *px++=LPTCOL(*wSRCPtr++);
+
+ column=g_y2-ldy;
+ for(TXV=g_y1;TXV<=column;TXV++)
+ {
+ ldx=ldxo;
+ for(TXU=g_x1;TXU<=g_x2-ldxo;TXU++)
+ {
+ n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );
+
+ s=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));
+ *ta++=s;
+
+ if(ldx) {*ta++=s;ldx--;}
+ }
+
+ if(ldy)
+ {ldy--;
+ for(TXU=g_x1;TXU<=g_x2;TXU++)
+ *ta++=*(ta-(g_x2-g_x1));
+ }
+ }
+
+ DefineTextureWnd();
+
+ break;
+ }
+ + + start=((pageid-16*pmult)*128)+256*2048*pmult; + + // convert CLUT to 32bits .. and then use THAT as a lookup table + + wSRCPtr=psxVuw+palstart; + for(row=0;row<16;row++) + *px++=LPTCOL(*wSRCPtr++); + + sxm=g_x1&1;sxh=g_x1>>1; + if(sxm) j=g_x1+1; else j=g_x1; + cSRCPtr = psxVub + start + (2048*g_y1) + sxh; + for(column=g_y1;column<=g_y2;column++) + { + cOSRCPtr=cSRCPtr;ldx=ldxo; + if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF)); + + for(row=j;row<=g_x2-ldxo;row++) + { + s=*(pa+(*cSRCPtr & 0xF)); + *ta++=s; + if(ldx) {*ta++=s;ldx--;} + row++; + if(row<=g_x2-ldxo) + { + s=*(pa+((*cSRCPtr >> 4) & 0xF)); + *ta++=s; + if(ldx) {*ta++=s;ldx--;} + } + cSRCPtr++; + } + + if(ldy && column&1) + {ldy--;cSRCPtr = cOSRCPtr;} + else cSRCPtr = psxVub + start + (2048*(column+1)) + sxh; + } + + DefineTextureWnd(); + break; + //--------------------------------------------------// + // 8bit texture load .. + case 1:
+ if(GlobalTextIL)
+ {
+ unsigned int TXV,TXU,n_xi,n_yi;
+
+ wSRCPtr=psxVuw+palstart;
+ for(row=0;row<256;row++)
+ *px++=LPTCOL(*wSRCPtr++);
+
+ column=g_y2-ldy;
+ for(TXV=g_y1;TXV<=column;TXV++)
+ {
+ ldx=ldxo;
+ for(TXU=g_x1;TXU<=g_x2-ldxo;TXU++)
+ {
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ s=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));
+
+ *ta++=s;
+ if(ldx) {*ta++=s;ldx--;}
+ }
+
+ if(ldy)
+ {ldy--;
+ for(TXU=g_x1;TXU<=g_x2;TXU++)
+ *ta++=*(ta-(g_x2-g_x1));
+ }
+
+ }
+
+ DefineTextureWnd();
+
+ break;
+ }
+
+ start=((pageid-16*pmult)*128)+256*2048*pmult; +
+ // not using a lookup table here... speeds up smaller texture areas + cSRCPtr = psxVub + start + (2048*g_y1) + g_x1; + LineOffset = 2048 - (g_x2-g_x1+1) +ldxo; + + for(column=g_y1;column<=g_y2;column++) + { + cOSRCPtr=cSRCPtr;ldx=ldxo; + for(row=g_x1;row<=g_x2-ldxo;row++) + { + s=LPTCOL(psxVuw[palstart+ *cSRCPtr++]); + *ta++=s; + if(ldx) {*ta++=s;ldx--;} + } + if(ldy && column&1) {ldy--;cSRCPtr=cOSRCPtr;} + else cSRCPtr+=LineOffset; + } + + DefineTextureWnd(); + break; + //--------------------------------------------------// + // 16bit texture load .. + case 2: + start=((pageid-16*pmult)*64)+256*1024*pmult; + wSRCPtr = psxVuw + start + (1024*g_y1) + g_x1; + LineOffset = 1024 - (g_x2-g_x1+1) +ldxo; + + for(column=g_y1;column<=g_y2;column++) + { + wOSRCPtr=wSRCPtr;ldx=ldxo; + for(row=g_x1;row<=g_x2-ldxo;row++) + { + s=LPTCOL(*wSRCPtr++); + *ta++=s; + if(ldx) {*ta++=s;ldx--;} + } + if(ldy && column&1) {ldy--;wSRCPtr=wOSRCPtr;} + else wSRCPtr+=LineOffset; + } + + DefineTextureWnd(); + break; + //--------------------------------------------------// + // others are not possible ! + } +} + +//////////////////////////////////////////////////////////////////////// +// tex window: load stretched +//////////////////////////////////////////////////////////////////////// + +void LoadStretchWndTexturePage(int pageid, int mode, short cx, short cy) +{ + uint32_t start,row,column,j,sxh,sxm,ldx,ldy,ldxo,s; + unsigned int palstart; + uint32_t *px,*pa,*ta; + unsigned char *cSRCPtr,*cOSRCPtr; + unsigned short *wSRCPtr,*wOSRCPtr; + uint32_t LineOffset; + int pmult = pageid / 16; + uint32_t (*LTCOL)(uint32_t); + + LTCOL = TCF[DrawSemiTrans]; + + ldxo=TWin.Position.x1-TWin.OPosition.x1; + ldy =TWin.Position.y1-TWin.OPosition.y1; + + pa = px = (uint32_t *)ubPaletteBuffer; + ta = (uint32_t *)texturepart; + palstart = cx + (cy * 1024); + + ubOpaqueDraw = 0; + + switch (mode) + { + //--------------------------------------------------// + // 4bit texture load .. + case 0:
+ //------------------- ZN STUFF
+
+ if(GlobalTextIL)
+ {
+ unsigned int TXV,TXU,n_xi,n_yi;
+
+ wSRCPtr=psxVuw+palstart;
+
+ row=4;do
+ {
+ *px =LTCOL(*wSRCPtr);
+ *(px+1)=LTCOL(*(wSRCPtr+1));
+ *(px+2)=LTCOL(*(wSRCPtr+2));
+ *(px+3)=LTCOL(*(wSRCPtr+3));
+ row--;px+=4;wSRCPtr+=4;
+ }
+ while (row);
+
+ column=g_y2-ldy;
+ for(TXV=g_y1;TXV<=column;TXV++)
+ {
+ ldx=ldxo;
+ for(TXU=g_x1;TXU<=g_x2-ldxo;TXU++)
+ {
+ n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );
+
+ s=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));
+ *ta++=s;
+
+ if(ldx) {*ta++=s;ldx--;}
+ }
+
+ if(ldy)
+ {ldy--;
+ for(TXU=g_x1;TXU<=g_x2;TXU++)
+ *ta++=*(ta-(g_x2-g_x1));
+ }
+ }
+
+ DefineTextureWnd();
+
+ break;
+ }
+
+ //-------------------
+ + start=((pageid-16*pmult)*128)+256*2048*pmult; + // convert CLUT to 32bits .. and then use THAT as a lookup table + + wSRCPtr=psxVuw+palstart; + for(row=0;row<16;row++) + *px++=LTCOL(*wSRCPtr++); + + sxm=g_x1&1;sxh=g_x1>>1; + if(sxm) j=g_x1+1; else j=g_x1; + cSRCPtr = psxVub + start + (2048*g_y1) + sxh; + for(column=g_y1;column<=g_y2;column++) + { + cOSRCPtr=cSRCPtr;ldx=ldxo; + if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF)); + + for(row=j;row<=g_x2-ldxo;row++) + { + s=*(pa+(*cSRCPtr & 0xF)); + *ta++=s; + if(ldx) {*ta++=s;ldx--;} + row++; + if(row<=g_x2-ldxo) + { + s=*(pa+((*cSRCPtr >> 4) & 0xF)); + *ta++=s; + if(ldx) {*ta++=s;ldx--;} + } + cSRCPtr++; + } + if(ldy && column&1) + {ldy--;cSRCPtr = cOSRCPtr;} + else cSRCPtr = psxVub + start + (2048*(column+1)) + sxh; + } + + DefineTextureWnd(); + break; + //--------------------------------------------------// + // 8bit texture load .. + case 1:
+ //------------ ZN STUFF
+ if(GlobalTextIL)
+ {
+ unsigned int TXV,TXU,n_xi,n_yi;
+
+ wSRCPtr=psxVuw+palstart;
+
+ row=64;do
+ {
+ *px =LTCOL(*wSRCPtr);
+ *(px+1)=LTCOL(*(wSRCPtr+1));
+ *(px+2)=LTCOL(*(wSRCPtr+2));
+ *(px+3)=LTCOL(*(wSRCPtr+3));
+ row--;px+=4;wSRCPtr+=4;
+ }
+ while (row);
+
+ column=g_y2-ldy;
+ for(TXV=g_y1;TXV<=column;TXV++)
+ {
+ ldx=ldxo;
+ for(TXU=g_x1;TXU<=g_x2-ldxo;TXU++)
+ {
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ s=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));
+ *ta++=s;
+ if(ldx) {*ta++=s;ldx--;}
+ }
+
+ if(ldy)
+ {ldy--;
+ for(TXU=g_x1;TXU<=g_x2;TXU++)
+ *ta++=*(ta-(g_x2-g_x1));
+ }
+
+ }
+
+ DefineTextureWnd();
+
+ break;
+ }
+ //------------
+ + start=((pageid-16*pmult)*128)+256*2048*pmult; + + // not using a lookup table here... speeds up smaller texture areas + cSRCPtr = psxVub + start + (2048*g_y1) + g_x1; + LineOffset = 2048 - (g_x2-g_x1+1) +ldxo; + + for(column=g_y1;column<=g_y2;column++) + { + cOSRCPtr=cSRCPtr;ldx=ldxo; + for(row=g_x1;row<=g_x2-ldxo;row++) + { + s=LTCOL(psxVuw[palstart+ *cSRCPtr++]); + *ta++=s; + if(ldx) {*ta++=s;ldx--;} + } + if(ldy && column&1) {ldy--;cSRCPtr=cOSRCPtr;} + else cSRCPtr+=LineOffset; + } + + DefineTextureWnd(); + break; + //--------------------------------------------------// + // 16bit texture load .. + case 2: + start=((pageid-16*pmult)*64)+256*1024*pmult; + + wSRCPtr = psxVuw + start + (1024*g_y1) + g_x1; + LineOffset = 1024 - (g_x2-g_x1+1) +ldxo; + + for(column=g_y1;column<=g_y2;column++) + { + wOSRCPtr=wSRCPtr;ldx=ldxo; + for(row=g_x1;row<=g_x2-ldxo;row++) + { + s=LTCOL(*wSRCPtr++); + *ta++=s; + if(ldx) {*ta++=s;ldx--;} + } + if(ldy && column&1) {ldy--;wSRCPtr=wOSRCPtr;} + else wSRCPtr+=LineOffset; + } + + DefineTextureWnd(); + break; + //--------------------------------------------------// + // others are not possible ! + } +} + +//////////////////////////////////////////////////////////////////////// +// tex window: load packed simple +//////////////////////////////////////////////////////////////////////// + +void LoadPackedWndTexturePage(int pageid, int mode, short cx, short cy) +{ + uint32_t start,row,column,j,sxh,sxm; + unsigned int palstart; + unsigned short *px,*pa,*ta; + unsigned char *cSRCPtr; + unsigned short *wSRCPtr; + uint32_t LineOffset; + int pmult=pageid/16; + unsigned short (*LPTCOL)(unsigned short); + + LPTCOL=PTCF[DrawSemiTrans]; + + pa=px=(unsigned short *)ubPaletteBuffer; + ta=(unsigned short *)texturepart; + palstart=cx+(cy*1024); + + ubOpaqueDraw=0; + + switch(mode) + { + //--------------------------------------------------// + // 4bit texture load .. + case 0:
+ if(GlobalTextIL)
+ {
+ unsigned int TXV,TXU,n_xi,n_yi;
+
+ wSRCPtr=psxVuw+palstart;
+ for(row=0;row<16;row++)
+ *px++=LPTCOL(*wSRCPtr++);
+
+ for(TXV=g_y1;TXV<=g_y2;TXV++)
+ {
+ for(TXU=g_x1;TXU<=g_x2;TXU++)
+ {
+ n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );
+
+ *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));
+ }
+ }
+
+ DefineTextureWnd();
+
+ break;
+ }
+ + start=((pageid-16*pmult)*128)+256*2048*pmult; + + // convert CLUT to 32bits .. and then use THAT as a lookup table + + wSRCPtr=psxVuw+palstart; + for(row=0;row<16;row++) + *px++=LPTCOL(*wSRCPtr++); + + sxm=g_x1&1;sxh=g_x1>>1; + if(sxm) j=g_x1+1; else j=g_x1; + cSRCPtr = psxVub + start + (2048*g_y1) + sxh; + for(column=g_y1;column<=g_y2;column++) + { + cSRCPtr = psxVub + start + (2048*column) + sxh; + + if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF)); + + for(row=j;row<=g_x2;row++) + { + *ta++=*(pa+(*cSRCPtr & 0xF)); row++; + if(row<=g_x2) *ta++=*(pa+((*cSRCPtr >> 4) & 0xF)); + cSRCPtr++; + } + } + + DefineTextureWnd(); + break; + //--------------------------------------------------// + // 8bit texture load .. + case 1:
+ if(GlobalTextIL)
+ {
+ unsigned int TXV,TXU,n_xi,n_yi;
+
+ wSRCPtr=psxVuw+palstart;
+ for(row=0;row<256;row++)
+ *px++=LPTCOL(*wSRCPtr++);
+
+ for(TXV=g_y1;TXV<=g_y2;TXV++)
+ {
+ for(TXU=g_x1;TXU<=g_x2;TXU++)
+ {
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));
+ }
+ }
+
+ DefineTextureWnd();
+
+ break;
+ }
+ + start=((pageid-16*pmult)*128)+256*2048*pmult; + + // not using a lookup table here... speeds up smaller texture areas + cSRCPtr = psxVub + start + (2048*g_y1) + g_x1; + LineOffset = 2048 - (g_x2-g_x1+1); + + for(column=g_y1;column<=g_y2;column++) + { + for(row=g_x1;row<=g_x2;row++) + *ta++=LPTCOL(psxVuw[palstart+ *cSRCPtr++]); + cSRCPtr+=LineOffset; + } + + DefineTextureWnd(); + break; + //--------------------------------------------------// + // 16bit texture load .. + case 2: + start=((pageid-16*pmult)*64)+256*1024*pmult; + wSRCPtr = psxVuw + start + (1024*g_y1) + g_x1; + LineOffset = 1024 - (g_x2-g_x1+1); + + for(column=g_y1;column<=g_y2;column++) + { + for(row=g_x1;row<=g_x2;row++) + *ta++=LPTCOL(*wSRCPtr++); + wSRCPtr+=LineOffset; + } + + DefineTextureWnd(); + break; + //--------------------------------------------------// + // others are not possible ! + } +} + +//////////////////////////////////////////////////////////////////////// +// tex window: load simple +//////////////////////////////////////////////////////////////////////// + +void LoadWndTexturePage(int pageid, int mode, short cx, short cy) +{ + uint32_t start,row,column,j,sxh,sxm; + unsigned int palstart; + uint32_t *px,*pa,*ta; + unsigned char *cSRCPtr; + unsigned short *wSRCPtr; + uint32_t LineOffset; + int pmult = pageid / 16; + uint32_t (*LTCOL)(uint32_t); + + LTCOL=TCF[DrawSemiTrans]; + + pa = px = (uint32_t *)ubPaletteBuffer; + ta = (uint32_t *)texturepart; + palstart = cx + (cy * 1024); + + ubOpaqueDraw = 0; + + switch (mode) + { + //--------------------------------------------------// + // 4bit texture load .. + case 0:
+ if(GlobalTextIL)
+ {
+ unsigned int TXV,TXU,n_xi,n_yi;
+
+ wSRCPtr=psxVuw+palstart;
+
+ row=4;do
+ {
+ *px =LTCOL(*wSRCPtr);
+ *(px+1)=LTCOL(*(wSRCPtr+1));
+ *(px+2)=LTCOL(*(wSRCPtr+2));
+ *(px+3)=LTCOL(*(wSRCPtr+3));
+ row--;px+=4;wSRCPtr+=4;
+ }
+ while (row);
+
+ for(TXV=g_y1;TXV<=g_y2;TXV++)
+ {
+ for(TXU=g_x1;TXU<=g_x2;TXU++)
+ {
+ n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );
+
+ *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));
+ }
+ }
+
+ DefineTextureWnd();
+
+ break;
+ }
+
+ start=((pageid-16*pmult)*128)+256*2048*pmult; + + // convert CLUT to 32bits .. and then use THAT as a lookup table + + wSRCPtr=psxVuw+palstart; + for(row=0;row<16;row++) + *px++=LTCOL(*wSRCPtr++); + + sxm=g_x1&1;sxh=g_x1>>1; + if(sxm) j=g_x1+1; else j=g_x1; + cSRCPtr = psxVub + start + (2048*g_y1) + sxh; + for(column=g_y1;column<=g_y2;column++) + { + cSRCPtr = psxVub + start + (2048*column) + sxh; + + if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF)); + + for(row=j;row<=g_x2;row++) + { + *ta++=*(pa+(*cSRCPtr & 0xF)); row++; + if(row<=g_x2) *ta++=*(pa+((*cSRCPtr >> 4) & 0xF)); + cSRCPtr++; + } + } + + DefineTextureWnd(); + break; + //--------------------------------------------------// + // 8bit texture load .. + case 1:
+ if(GlobalTextIL)
+ {
+ unsigned int TXV,TXU,n_xi,n_yi;
+
+ wSRCPtr=psxVuw+palstart;
+
+ row=64;do
+ {
+ *px =LTCOL(*wSRCPtr);
+ *(px+1)=LTCOL(*(wSRCPtr+1));
+ *(px+2)=LTCOL(*(wSRCPtr+2));
+ *(px+3)=LTCOL(*(wSRCPtr+3));
+ row--;px+=4;wSRCPtr+=4;
+ }
+ while (row);
+
+ for(TXV=g_y1;TXV<=g_y2;TXV++)
+ {
+ for(TXU=g_x1;TXU<=g_x2;TXU++)
+ {
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));
+ }
+ }
+
+ DefineTextureWnd();
+
+ break;
+ }
+
+ start=((pageid-16*pmult)*128)+256*2048*pmult; + + // not using a lookup table here... speeds up smaller texture areas + cSRCPtr = psxVub + start + (2048*g_y1) + g_x1; + LineOffset = 2048 - (g_x2-g_x1+1); + + for(column=g_y1;column<=g_y2;column++) + { + for(row=g_x1;row<=g_x2;row++) + *ta++=LTCOL(psxVuw[palstart+ *cSRCPtr++]); + cSRCPtr+=LineOffset; + } + + DefineTextureWnd(); + break; + //--------------------------------------------------// + // 16bit texture load .. + case 2: + start=((pageid-16*pmult)*64)+256*1024*pmult; + + wSRCPtr = psxVuw + start + (1024*g_y1) + g_x1; + LineOffset = 1024 - (g_x2-g_x1+1); + + for(column=g_y1;column<=g_y2;column++) + { + for(row=g_x1;row<=g_x2;row++) + *ta++=LTCOL(*wSRCPtr++); + wSRCPtr+=LineOffset; + } + + DefineTextureWnd(); + break; + //--------------------------------------------------// + // others are not possible ! + } +} + +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////// + +void UploadTexWndPal(int mode,short cx,short cy) +{ + unsigned int i,iSize; + unsigned short *wSrcPtr; + uint32_t *ta = (uint32_t *)texturepart; + + wSrcPtr = psxVuw + cx + (cy * 1024); + if (mode == 0) i = 4; else i = 64; + iSize = i << 2; + ubOpaqueDraw = 0; + + do + { + *ta =PALCOL(*wSrcPtr); + *(ta+1)=PALCOL(*(wSrcPtr+1)); + *(ta+2)=PALCOL(*(wSrcPtr+2)); + *(ta+3)=PALCOL(*(wSrcPtr+3)); + ta+=4;wSrcPtr+=4;i--; + } + while(i); + + (*glColorTableEXTEx)(GL_TEXTURE_2D,GL_RGBA8,iSize, + GL_RGBA,GL_UNSIGNED_BYTE,texturepart); +} + +//////////////////////////////////////////////////////////////////////// + +void DefinePalTextureWnd(void) +{ + if(gTexName==0) + glGenTextures(1, &gTexName); + + glBindTexture(GL_TEXTURE_2D, gTexName); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + if(iFilterType && iFilterType<3 && iHiResTextures!=2) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + else + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } + + glTexImage2D(GL_TEXTURE_2D, 0,GL_COLOR_INDEX8_EXT, + TWin.Position.x1, + TWin.Position.y1, + 0, GL_COLOR_INDEX, GL_UNSIGNED_BYTE,texturepart); +} + +/////////////////////////////////////////////////////// + +void LoadPalWndTexturePage(int pageid, int mode, short cx, short cy) +{ + uint32_t start,row,column,j,sxh,sxm; + unsigned char *ta; + unsigned char *cSRCPtr; + uint32_t LineOffset;
+ int pmult = pageid / 16; + + ta = (unsigned char *)texturepart; + + switch (mode) + { + //--------------------------------------------------// + // 4bit texture load .. + case 0:
+ start=((pageid-16*pmult)*128)+256*2048*pmult;
+ + sxm=g_x1&1;sxh=g_x1>>1; + if(sxm) j=g_x1+1; else j=g_x1; + cSRCPtr = psxVub + start + (2048*g_y1) + sxh; + for(column=g_y1;column<=g_y2;column++) + { + cSRCPtr = psxVub + start + (2048*column) + sxh; + + if(sxm) *ta++=((*cSRCPtr++ >> 4) & 0xF); + + for(row=j;row<=g_x2;row++) + { + *ta++=(*cSRCPtr & 0xF); row++; + if(row<=g_x2) *ta++=((*cSRCPtr >> 4) & 0xF); + cSRCPtr++; + } + } + + DefinePalTextureWnd(); + break; + //--------------------------------------------------// + // 8bit texture load .. + case 1:
+ start=((pageid-16*pmult)*128)+256*2048*pmult; + + // not using a lookup table here... speeds up smaller texture areas + cSRCPtr = psxVub + start + (2048*g_y1) + g_x1; + LineOffset = 2048 - (g_x2-g_x1+1); + + for(column=g_y1;column<=g_y2;column++) + { + for(row=g_x1;row<=g_x2;row++) + *ta++=*cSRCPtr++; + cSRCPtr+=LineOffset; + } + + DefinePalTextureWnd(); + break; + } + UploadTexWndPal(mode,cx,cy); +} + +//////////////////////////////////////////////////////////////////////// + +void LoadStretchPalWndTexturePage(int pageid, int mode, short cx, short cy) +{ + uint32_t start,row,column,j,sxh,sxm,ldx,ldy,ldxo; + unsigned char *ta,s; + unsigned char *cSRCPtr,*cOSRCPtr; + uint32_t LineOffset; + int pmult = pageid / 16;
+ + ldxo = TWin.Position.x1-TWin.OPosition.x1; + ldy = TWin.Position.y1-TWin.OPosition.y1; + + ta = (unsigned char *)texturepart; + + switch (mode) + { + //--------------------------------------------------// + // 4bit texture load .. + case 0: + start=((pageid-16*pmult)*128)+256*2048*pmult;
+ + sxm=g_x1&1;sxh=g_x1>>1; + if(sxm) j=g_x1+1; else j=g_x1; + cSRCPtr = psxVub + start + (2048*g_y1) + sxh; + for(column=g_y1;column<=g_y2;column++) + { + cOSRCPtr=cSRCPtr;ldx=ldxo; + if(sxm) *ta++=((*cSRCPtr++ >> 4) & 0xF); + + for(row=j;row<=g_x2-ldxo;row++) + { + s=(*cSRCPtr & 0xF); + *ta++=s; + if(ldx) {*ta++=s;ldx--;} + row++; + if(row<=g_x2-ldxo) + { + s=((*cSRCPtr >> 4) & 0xF); + *ta++=s; + if(ldx) {*ta++=s;ldx--;} + } + cSRCPtr++; + } + if(ldy && column&1) + {ldy--;cSRCPtr = cOSRCPtr;} + else cSRCPtr = psxVub + start + (2048*(column+1)) + sxh; + } + + DefinePalTextureWnd(); + break; + //--------------------------------------------------// + // 8bit texture load .. + case 1:
+ start=((pageid-16*pmult)*128)+256*2048*pmult;
+ + cSRCPtr = psxVub + start + (2048*g_y1) + g_x1; + LineOffset = 2048 - (g_x2-g_x1+1) +ldxo; + + for(column=g_y1;column<=g_y2;column++) + { + cOSRCPtr=cSRCPtr;ldx=ldxo; + for(row=g_x1;row<=g_x2-ldxo;row++) + { + s=*cSRCPtr++; + *ta++=s; + if(ldx) {*ta++=s;ldx--;} + } + if(ldy && column&1) {ldy--;cSRCPtr=cOSRCPtr;} + else cSRCPtr+=LineOffset; + } + + DefinePalTextureWnd(); + break; + } + UploadTexWndPal(mode,cx,cy); +} + +//////////////////////////////////////////////////////////////////////// +// tex window: main selecting, cache handler included +//////////////////////////////////////////////////////////////////////// + +GLuint LoadTextureWnd(int pageid, int TextureMode, uint32_t GivenClutId) +{ + textureWndCacheEntry *ts, *tsx = NULL; + int i; + short cx,cy; + EXLong npos; + + npos.c[3] = TWin.Position.x0; + npos.c[2] = TWin.OPosition.x1; + npos.c[1] = TWin.Position.y0; + npos.c[0] = TWin.OPosition.y1; + + g_x1 = TWin.Position.x0; g_x2 = g_x1 + TWin.Position.x1 - 1; + g_y1 = TWin.Position.y0; g_y2 = g_y1 + TWin.Position.y1 - 1; + + if (TextureMode == 2) { GivenClutId = 0; cx = cy = 0; } + else + { + cx = ((GivenClutId << 4) & 0x3F0); + cy = ((GivenClutId >> 6) & CLUTYMASK); + GivenClutId = (GivenClutId & CLUTMASK) | (DrawSemiTrans << 30); +
+ // palette check sum + { + uint32_t l = 0,row; + uint32_t *lSRCPtr = (uint32_t *)(psxVuw + cx + (cy * 1024)); + if(TextureMode==1) for(row=1;row<129;row++) l+=((*lSRCPtr++)-1)*row; + else for(row=1;row<9;row++) l+=((*lSRCPtr++)-1)<<row; + l=(l+HIWORD(l))&0x3fffL; + GivenClutId|=(l<<16); + } + + } + + ts=wcWndtexStore; + + for(i=0;i<iMaxTexWnds;i++,ts++) + { + if(ts->used) + { + if(ts->pos.l==npos.l && + ts->pageid==pageid && + ts->textureMode==TextureMode) + { + if(ts->ClutID==GivenClutId) + { + ubOpaqueDraw=ts->Opaque; + return ts->texname; + } + else if(glColorTableEXTEx && TextureMode!=2) + { + ts->ClutID=GivenClutId; + if(ts->texname!=gTexName) + { + gTexName=ts->texname; + glBindTexture(GL_TEXTURE_2D, gTexName); + } + UploadTexWndPal(TextureMode,cx,cy); + ts->Opaque=ubOpaqueDraw; + return gTexName; + } + } + } + else tsx=ts; + } + + if(!tsx) + { + if(iMaxTexWnds==iTexWndLimit) + { + tsx=wcWndtexStore+iTexWndTurn; + iTexWndTurn++; + if(iTexWndTurn==iTexWndLimit) iTexWndTurn=0; + } + else + { + tsx=wcWndtexStore+iMaxTexWnds; + iMaxTexWnds++; + } + } + + gTexName=tsx->texname; + + if(TWin.OPosition.y1==TWin.Position.y1 && + TWin.OPosition.x1==TWin.Position.x1) + { + if(glColorTableEXTEx && TextureMode!=2) + LoadPalWndTexturePage(pageid,TextureMode,cx,cy); + else + if(bGLExt) + LoadPackedWndTexturePage(pageid,TextureMode,cx,cy); + else + LoadWndTexturePage(pageid,TextureMode,cx,cy); + } + else + { + if(glColorTableEXTEx && TextureMode!=2) + LoadStretchPalWndTexturePage(pageid,TextureMode,cx,cy); + else + if(bGLExt) + LoadStretchPackedWndTexturePage(pageid,TextureMode,cx,cy); + else + LoadStretchWndTexturePage(pageid,TextureMode,cx,cy); + } + + tsx->Opaque=ubOpaqueDraw; + tsx->pos.l=npos.l; + tsx->ClutID=GivenClutId; + tsx->pageid=pageid; + tsx->textureMode=TextureMode; + tsx->texname=gTexName; + tsx->used=1; + + return gTexName; +} + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +// movie texture: define +//////////////////////////////////////////////////////////////////////// + +void DefinePackedTextureMovie(void) +{ + if(gTexMovieName==0) + { + glGenTextures(1, &gTexMovieName); + gTexName=gTexMovieName; + glBindTexture(GL_TEXTURE_2D, gTexName); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType); + + if(!bUseFastMdec) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + else + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } + + glTexImage2D(GL_TEXTURE_2D, 0, //giWantedRGBA, + GL_RGB5_A1, + 256, 256, 0, GL_RGBA, giWantedTYPE, texturepart); + } + else + { + gTexName=gTexMovieName;glBindTexture(GL_TEXTURE_2D, gTexName); + } + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, + (xrMovieArea.x1-xrMovieArea.x0), + (xrMovieArea.y1-xrMovieArea.y0), + GL_RGBA, + GL_UNSIGNED_SHORT_5_5_5_1_EXT, + texturepart); +} + +//////////////////////////////////////////////////////////////////////// + +void DefineTextureMovie(void) +{ + if(gTexMovieName==0) + { + glGenTextures(1, &gTexMovieName); + gTexName=gTexMovieName; + glBindTexture(GL_TEXTURE_2D, gTexName); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType); + + if(!bUseFastMdec) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + else + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } + + glTexImage2D(GL_TEXTURE_2D, 0, giWantedRGBA, 256, 256, 0, GL_RGBA, GL_UNSIGNED_BYTE, texturepart); + } + else + { + gTexName=gTexMovieName;glBindTexture(GL_TEXTURE_2D, gTexName); + } + + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, + (xrMovieArea.x1-xrMovieArea.x0), + (xrMovieArea.y1-xrMovieArea.y0), + GL_RGBA, GL_UNSIGNED_BYTE, texturepart); +} + +//////////////////////////////////////////////////////////////////////// +// movie texture: load +//////////////////////////////////////////////////////////////////////// + +#define MRED(x) ((x>>3) & 0x1f) +#define MGREEN(x) ((x>>6) & 0x3e0) +#define MBLUE(x) ((x>>9) & 0x7c00) + +#define XMGREEN(x) ((x>>5) & 0x07c0) +#define XMRED(x) ((x<<8) & 0xf800) +#define XMBLUE(x) ((x>>18) & 0x003e) + +//////////////////////////////////////////////////////////////////////// +// movie texture: load +//////////////////////////////////////////////////////////////////////// + +unsigned char * LoadDirectMovieFast(void) +{ + int row,column; + unsigned int startxy; + + uint32_t *ta=(uint32_t *)texturepart; + + if(PSXDisplay.RGB24) + { + unsigned char * pD; + + startxy=((1024)*xrMovieArea.y0)+xrMovieArea.x0; + + for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++,startxy+=1024) + { + pD=(unsigned char *)&psxVuw[startxy]; + for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) + { + *ta++=*((uint32_t *)pD)|0xff000000; + pD+=3; + } + } + } + else + { + uint32_t (*LTCOL)(uint32_t); + + LTCOL=XP8RGBA_0;//TCF[0]; + + ubOpaqueDraw=0; + + for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++) + { + startxy=((1024)*column)+xrMovieArea.x0; + for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) + *ta++=LTCOL(psxVuw[startxy++]|0x8000); + } + } + + return texturepart; +} + +//////////////////////////////////////////////////////////////////////// + +GLuint LoadTextureMovieFast(void) +{ + int row,column; + unsigned int start,startxy; + + if(bGLFastMovie) + { + if(PSXDisplay.RGB24) + { + unsigned char * pD; uint32_t lu1,lu2; + unsigned short * ta=(unsigned short *)texturepart; + short sx0=xrMovieArea.x1-1; + + start=0; + + startxy=((1024)*xrMovieArea.y0)+xrMovieArea.x0; + for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++) + { + pD=(unsigned char *)&psxVuw[startxy]; + startxy+=1024; +
+ for(row=xrMovieArea.x0;row<sx0;row+=2) + { + lu1=*((uint32_t *)pD);pD+=3; + lu2=*((uint32_t *)pD);pD+=3; + + *((uint32_t *)ta)= + (XMBLUE(lu1)|XMGREEN(lu1)|XMRED(lu1)|1)| + ((XMBLUE(lu2)|XMGREEN(lu2)|XMRED(lu2)|1)<<16); + ta+=2; + } + if(row==sx0) + { + lu1=*((uint32_t *)pD); + *ta++=XMBLUE(lu1)|XMGREEN(lu1)|XMRED(lu1)|1; + }
+ } + } + else + { + unsigned short *ta=(unsigned short *)texturepart; + uint32_t lc; + short sx0=xrMovieArea.x1-1; + + for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++) + { + startxy=((1024)*column)+xrMovieArea.x0; + for(row=xrMovieArea.x0;row<sx0;row+=2) + { + lc=*((uint32_t *)&psxVuw[startxy]); + *((uint32_t *)ta)= + ((lc&0x001f001f)<<11)|((lc&0x03e003e0)<<1)|((lc&0x7c007c00)>>9)|0x00010001; + ta+=2;startxy+=2; + } + if(row==sx0) *ta++=(psxVuw[startxy]<<1)|1; + } + } + DefinePackedTextureMovie(); + } + else + { + if(PSXDisplay.RGB24) + { + unsigned char *pD; + uint32_t *ta = (uint32_t *)texturepart; + + startxy=((1024)*xrMovieArea.y0)+xrMovieArea.x0; + + for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++,startxy+=1024) + { + //startxy=((1024)*column)+xrMovieArea.x0; + pD = (unsigned char *)&psxVuw[startxy]; + for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) + { + *ta++=*((uint32_t *)pD)|0xff000000; + pD+=3; + } + } + } + else + { + uint32_t (*LTCOL)(uint32_t); + uint32_t *ta; + + LTCOL = XP8RGBA_0;//TCF[0]; + + ubOpaqueDraw = 0; + ta = (uint32_t *)texturepart; + + for (column = xrMovieArea.y0; column < xrMovieArea.y1; column++) + { + startxy = (1024 * column) + xrMovieArea.x0; + for (row = xrMovieArea.x0; row < xrMovieArea.x1; row++) + *ta++=LTCOL(psxVuw[startxy++]|0x8000); + } + } + DefineTextureMovie(); + } + return gTexName; +} + +//////////////////////////////////////////////////////////////////////// + +GLuint LoadTextureMovie(void) +{ + short row,column,dx; + unsigned int startxy; + BOOL b_X,b_Y; + + if(bUseFastMdec) return LoadTextureMovieFast(); + + b_X=FALSE;b_Y=FALSE; + + if((xrMovieArea.x1-xrMovieArea.x0)<255) b_X=TRUE; + if((xrMovieArea.y1-xrMovieArea.y0)<255) b_Y=TRUE; + + if(bGLFastMovie) + { + unsigned short c; + + if(PSXDisplay.RGB24) + { + unsigned char * pD; + uint32_t lu; + unsigned short * ta=(unsigned short *)texturepart; + + if(b_X) + { + for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++) + { + startxy=((1024)*column)+xrMovieArea.x0; + pD=(unsigned char *)&psxVuw[startxy]; + for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) + { + lu=*((uint32_t *)pD);pD+=3; + *ta++=XMBLUE(lu)|XMGREEN(lu)|XMRED(lu)|1; + } + *ta++=*(ta-1); + } + if(b_Y) + { + dx=xrMovieArea.x1-xrMovieArea.x0+1; + for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) + *ta++=*(ta-dx); + *ta++=*(ta-1); + } + } + else + { + for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++) + { + startxy=((1024)*column)+xrMovieArea.x0; + pD=(unsigned char *)&psxVuw[startxy]; + for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) + { + lu=*((uint32_t *)pD);pD+=3; + *ta++=XMBLUE(lu)|XMGREEN(lu)|XMRED(lu)|1; + } + } + if(b_Y) + { + dx=xrMovieArea.x1-xrMovieArea.x0; + for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) + *ta++=*(ta-dx); + } + } + } + else + { + unsigned short *ta; + + ubOpaqueDraw=0; + + ta=(unsigned short *)texturepart; + + if(b_X) + { + for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++) + { + startxy=((1024)*column)+xrMovieArea.x0; + for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) + { + c=psxVuw[startxy++]; + *ta++=((c&0x1f)<<11)|((c&0x3e0)<<1)|((c&0x7c00)>>9)|1; + } + + *ta++=*(ta-1); + } + if(b_Y) + { + dx=xrMovieArea.x1-xrMovieArea.x0+1; + for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) + *ta++=*(ta-dx); + *ta++=*(ta-1); + } + } + else + { + for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++) + { + startxy=((1024)*column)+xrMovieArea.x0; + for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) + { + c=psxVuw[startxy++]; + *ta++=((c&0x1f)<<11)|((c&0x3e0)<<1)|((c&0x7c00)>>9)|1; + } + } + if(b_Y) + { + dx=xrMovieArea.x1-xrMovieArea.x0; + for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) + *ta++=*(ta-dx); + } + } + } + xrMovieArea.x1+=b_X;xrMovieArea.y1+=b_Y; + DefinePackedTextureMovie(); + xrMovieArea.x1-=b_X;xrMovieArea.y1-=b_Y; + } + else + { + if(PSXDisplay.RGB24) + { + unsigned char * pD; + uint32_t * ta=(uint32_t *)texturepart; + + if(b_X) + { + for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++) + { + startxy=((1024)*column)+xrMovieArea.x0; + pD=(unsigned char *)&psxVuw[startxy]; + for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) + { + *ta++=*((uint32_t *)pD)|0xff000000; + pD+=3; + } + *ta++=*(ta-1); + } + if(b_Y) + { + dx=xrMovieArea.x1-xrMovieArea.x0+1; + for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) + *ta++=*(ta-dx); + *ta++=*(ta-1); + } + } + else + { + for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++) + { + startxy=((1024)*column)+xrMovieArea.x0; + pD=(unsigned char *)&psxVuw[startxy]; + for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) + { + *ta++=*((uint32_t *)pD)|0xff000000; + pD+=3; + } + } + if(b_Y) + { + dx=xrMovieArea.x1-xrMovieArea.x0; + for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) + *ta++=*(ta-dx); + } + } + } + else + { + uint32_t (*LTCOL)(uint32_t); + uint32_t *ta; + + LTCOL=XP8RGBA_0;//TCF[0]; + + ubOpaqueDraw=0; + ta=(uint32_t *)texturepart; + + if(b_X) + { + for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++) + { + startxy=((1024)*column)+xrMovieArea.x0; + for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) + *ta++=LTCOL(psxVuw[startxy++]|0x8000); + *ta++=*(ta-1); + } + + if(b_Y) + { + dx=xrMovieArea.x1-xrMovieArea.x0+1; + for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) + *ta++=*(ta-dx); + *ta++=*(ta-1); + } + } + else + { + for(column=xrMovieArea.y0;column<xrMovieArea.y1;column++) + { + startxy=((1024)*column)+xrMovieArea.x0; + for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) + *ta++=LTCOL(psxVuw[startxy++]|0x8000); + } + + if(b_Y) + { + dx=xrMovieArea.x1-xrMovieArea.x0; + for(row=xrMovieArea.x0;row<xrMovieArea.x1;row++) + *ta++=*(ta-dx); + } + } + } + + xrMovieArea.x1+=b_X;xrMovieArea.y1+=b_Y; + DefineTextureMovie(); + xrMovieArea.x1-=b_X;xrMovieArea.y1-=b_Y; + } + return gTexName; +} + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + +GLuint BlackFake15BitTexture(void) +{ + int pmult;short x1,x2,y1,y2; + + if(PSXDisplay.InterlacedTest) return 0; + + pmult=GlobalTexturePage/16; + x1=gl_ux[7]; + x2=gl_ux[6]-gl_ux[7]; + y1=gl_ux[5]; + y2=gl_ux[4]-gl_ux[5]; + + if(iSpriteTex) + { + if(x2<255) x2++; + if(y2<255) y2++; + } + + y1+=pmult*256; + x1+=((GlobalTexturePage-16*pmult)<<6); + + if( FastCheckAgainstFrontScreen(x1,y1,x2,y2) + || FastCheckAgainstScreen(x1,y1,x2,y2)) + { + if(!gTexFrameName) + { + glGenTextures(1, &gTexFrameName); + gTexName=gTexFrameName; + glBindTexture(GL_TEXTURE_2D, gTexName); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + if(bGLExt) + { + unsigned short s;unsigned short * ta; + + if(giWantedTYPE==GL_UNSIGNED_SHORT_4_4_4_4_EXT) + s=0x000f; + else s=0x0001; + + ta=(unsigned short *)texturepart; + for(y1=0;y1<=4;y1++) + for(x1=0;x1<=4;x1++) + *ta++=s; + } + else + { + uint32_t *ta=(uint32_t *)texturepart; + for(y1=0;y1<=4;y1++) + for(x1=0;x1<=4;x1++) + *ta++=0xff000000; + } + glTexImage2D(GL_TEXTURE_2D, 0, giWantedRGBA, 4, 4, 0, GL_RGBA, GL_UNSIGNED_BYTE, texturepart); + } + else + { + gTexName=gTexFrameName; + glBindTexture(GL_TEXTURE_2D, gTexName); + } + + ubOpaqueDraw=0; + + return (GLuint)gTexName; + } + return 0; +} + +///////////////////////////////////////////////////////////////////////////// + +BOOL bFakeFrontBuffer=FALSE; +BOOL bIgnoreNextTile =FALSE; + +int iFTex=512; + +GLuint Fake15BitTexture(void) +{ + int pmult;short x1,x2,y1,y2;int iYAdjust; + float ScaleX,ScaleY;RECT rSrc; + + if(iFrameTexType==1) return BlackFake15BitTexture(); + if(PSXDisplay.InterlacedTest) return 0; + + pmult=GlobalTexturePage/16; + x1=gl_ux[7]; + x2=gl_ux[6]-gl_ux[7]; + y1=gl_ux[5]; + y2=gl_ux[4]-gl_ux[5]; + + y1+=pmult*256; + x1+=((GlobalTexturePage-16*pmult)<<6); + + if(iFrameTexType==3) + { + if(iFrameReadType==4) return 0; + + if(!FastCheckAgainstFrontScreen(x1,y1,x2,y2) && + !FastCheckAgainstScreen(x1,y1,x2,y2)) + return 0; + + if(bFakeFrontBuffer) bIgnoreNextTile=TRUE; + CheckVRamReadEx(x1,y1,x1+x2,y1+y2); + return 0; + }
+ + ///////////////////////// + + if(FastCheckAgainstFrontScreen(x1,y1,x2,y2)) + { + x1-=PSXDisplay.DisplayPosition.x; + y1-=PSXDisplay.DisplayPosition.y; + } + else + if(FastCheckAgainstScreen(x1,y1,x2,y2)) + { + x1-=PreviousPSXDisplay.DisplayPosition.x; + y1-=PreviousPSXDisplay.DisplayPosition.y; + } + else return 0; + + bDrawMultiPass = FALSE; + + if(!gTexFrameName) + { + char * p; + + if(iResX>1280 || iResY>1024) iFTex=2048; + else + if(iResX>640 || iResY>480) iFTex=1024; + else iFTex=512; + + glGenTextures(1, &gTexFrameName); + gTexName=gTexFrameName; + glBindTexture(GL_TEXTURE_2D, gTexName); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + + p=(char *)malloc(iFTex*iFTex*4); + memset(p,0,iFTex*iFTex*4); + glTexImage2D(GL_TEXTURE_2D, 0, 3, iFTex, iFTex, 0, GL_RGB, GL_UNSIGNED_BYTE, p); + free(p); + + glGetError(); + } + else + { + gTexName=gTexFrameName; + glBindTexture(GL_TEXTURE_2D, gTexName); + } + + x1+=PreviousPSXDisplay.Range.x0; + y1+=PreviousPSXDisplay.Range.y0; + + if(PSXDisplay.DisplayMode.x) + ScaleX=(float)rRatioRect.right/(float)PSXDisplay.DisplayMode.x; + else ScaleX=1.0f; + if(PSXDisplay.DisplayMode.y) + ScaleY=(float)rRatioRect.bottom/(float)PSXDisplay.DisplayMode.y; + else ScaleY=1.0f; + + rSrc.left =max(x1*ScaleX,0); + rSrc.right =min((x1+x2)*ScaleX+0.99f,iResX-1); + rSrc.top =max(y1*ScaleY,0); + rSrc.bottom=min((y1+y2)*ScaleY+0.99f,iResY-1); + + iYAdjust=(y1+y2)-PSXDisplay.DisplayMode.y; + if(iYAdjust>0) + iYAdjust=(int)((float)iYAdjust*ScaleY)+1; + else iYAdjust=0; + + gl_vy[0]=255-gl_vy[0]; + gl_vy[1]=255-gl_vy[1]; + gl_vy[2]=255-gl_vy[2]; + gl_vy[3]=255-gl_vy[3]; + + y1=min(gl_vy[0],min(gl_vy[1],min(gl_vy[2],gl_vy[3]))); + + gl_vy[0]-=y1; + gl_vy[1]-=y1; + gl_vy[2]-=y1; + gl_vy[3]-=y1; + gl_ux[0]-=gl_ux[7]; + gl_ux[1]-=gl_ux[7]; + gl_ux[2]-=gl_ux[7]; + gl_ux[3]-=gl_ux[7]; + + ScaleX*=256.0f/((float)(iFTex)); + ScaleY*=256.0f/((float)(iFTex)); + + y1=((float)gl_vy[0]*ScaleY); if(y1>255) y1=255; + gl_vy[0]=y1; + y1=((float)gl_vy[1]*ScaleY); if(y1>255) y1=255; + gl_vy[1]=y1; + y1=((float)gl_vy[2]*ScaleY); if(y1>255) y1=255; + gl_vy[2]=y1; + y1=((float)gl_vy[3]*ScaleY); if(y1>255) y1=255; + gl_vy[3]=y1; + + x1=((float)gl_ux[0]*ScaleX); if(x1>255) x1=255; + gl_ux[0]=x1; + x1=((float)gl_ux[1]*ScaleX); if(x1>255) x1=255; + gl_ux[1]=x1; + x1=((float)gl_ux[2]*ScaleX); if(x1>255) x1=255; + gl_ux[2]=x1; + x1=((float)gl_ux[3]*ScaleX); if(x1>255) x1=255; + gl_ux[3]=x1; + + x1=rSrc.right-rSrc.left; + if(x1<=0) x1=1; + if(x1>iFTex) x1=iFTex; + + y1=rSrc.bottom-rSrc.top; + if(y1<=0) y1=1; + if(y1+iYAdjust>iFTex) y1=iFTex-iYAdjust; + + if(bFakeFrontBuffer) glReadBuffer(GL_FRONT); + + glCopyTexSubImage2D( GL_TEXTURE_2D, 0, + 0, + iYAdjust, + rSrc.left+rRatioRect.left, + iResY-rSrc.bottom-rRatioRect.top, + x1,y1); + + if(glGetError()) + { + char * p=(char *)malloc(iFTex*iFTex*4); + memset(p,0,iFTex*iFTex*4); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, iFTex, iFTex, + GL_RGB, GL_UNSIGNED_BYTE, p); + free(p); + } + + if(bFakeFrontBuffer) + {glReadBuffer(GL_BACK);bIgnoreNextTile=TRUE;} + + ubOpaqueDraw=0; + + if(iSpriteTex) + { + sprtW=gl_ux[1]-gl_ux[0]; + sprtH=-(gl_vy[0]-gl_vy[2]); + } + + return (GLuint)gTexName; +} + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +// +// load texture part (unpacked) +// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + +void LoadSubTexturePageSort(int pageid, int mode, short cx, short cy) +{ + uint32_t start,row,column,j,sxh,sxm; + unsigned int palstart; + uint32_t *px,*pa,*ta; + unsigned char *cSRCPtr; + unsigned short *wSRCPtr; + uint32_t LineOffset; + uint32_t x2a,xalign=0; + uint32_t x1=gl_ux[7]; + uint32_t x2=gl_ux[6]; + uint32_t y1=gl_ux[5]; + uint32_t y2=gl_ux[4]; + uint32_t dx=x2-x1+1; + uint32_t dy=y2-y1+1; + int pmult=pageid/16; + uint32_t (*LTCOL)(uint32_t); + unsigned int a,r,g,b,cnt,h; + uint32_t scol[8]; + + LTCOL=TCF[DrawSemiTrans]; + + pa=px=(uint32_t *)ubPaletteBuffer; + ta=(uint32_t *)texturepart; + palstart=cx+(cy<<10); + + ubOpaqueDraw=0; + + if(YTexS) {ta+=dx;if(XTexS) ta+=2;} + if(XTexS) {ta+=1;xalign=2;} + + switch(mode) + { + //--------------------------------------------------// + // 4bit texture load .. + case 0:
+ if(GlobalTextIL)
+ {
+ unsigned int TXV,TXU,n_xi,n_yi;
+
+ wSRCPtr=psxVuw+palstart;
+
+ row=4;do
+ {
+ *px =LTCOL(*wSRCPtr);
+ *(px+1)=LTCOL(*(wSRCPtr+1));
+ *(px+2)=LTCOL(*(wSRCPtr+2));
+ *(px+3)=LTCOL(*(wSRCPtr+3));
+ row--;px+=4;wSRCPtr+=4;
+ }
+ while (row);
+
+ for(TXV=y1;TXV<=y2;TXV++)
+ {
+ for(TXU=x1;TXU<=x2;TXU++)
+ {
+ n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );
+
+ *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));
+ }
+ ta+=xalign;
+ }
+ break;
+ }
+ + start=((pageid-16*pmult)<<7)+524288*pmult; + // convert CLUT to 32bits .. and then use THAT as a lookup table + + wSRCPtr=psxVuw+palstart; + + row=4;do + { + *px =LTCOL(*wSRCPtr); + *(px+1)=LTCOL(*(wSRCPtr+1)); + *(px+2)=LTCOL(*(wSRCPtr+2)); + *(px+3)=LTCOL(*(wSRCPtr+3)); + row--;px+=4;wSRCPtr+=4; + } + while (row); + + x2a=x2?(x2-1):0;//if(x2) x2a=x2-1; else x2a=0; + sxm=x1&1;sxh=x1>>1; + j=sxm?(x1+1):x1;//if(sxm) j=x1+1; else j=x1; + for(column=y1;column<=y2;column++) + { + cSRCPtr = psxVub + start + (column<<11) + sxh; + + if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF)); + + for(row=j;row<x2a;row+=2) + { + *ta =*(pa+(*cSRCPtr & 0xF)); + *(ta+1)=*(pa+((*cSRCPtr >> 4) & 0xF)); + cSRCPtr++;ta+=2; + } + + if(row<=x2) + { + *ta++=*(pa+(*cSRCPtr & 0xF)); row++; + if(row<=x2) *ta++=*(pa+((*cSRCPtr >> 4) & 0xF)); + } + + ta+=xalign; + } + + break; + //--------------------------------------------------// + // 8bit texture load .. + case 1:
+ if(GlobalTextIL)
+ {
+ unsigned int TXV,TXU,n_xi,n_yi;
+
+ wSRCPtr=psxVuw+palstart;
+
+ row=64;do
+ {
+ *px =LTCOL(*wSRCPtr);
+ *(px+1)=LTCOL(*(wSRCPtr+1));
+ *(px+2)=LTCOL(*(wSRCPtr+2));
+ *(px+3)=LTCOL(*(wSRCPtr+3));
+ row--;px+=4;wSRCPtr+=4;
+ }
+ while (row);
+
+ for(TXV=y1;TXV<=y2;TXV++)
+ {
+ for(TXU=x1;TXU<=x2;TXU++)
+ {
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));
+ }
+ ta+=xalign;
+ }
+
+ break;
+ }
+ + start=((pageid-16*pmult)<<7)+524288*pmult; + + cSRCPtr = psxVub + start + (y1<<11) + x1; + LineOffset = 2048 - dx; + + if(dy*dx>384) + { + wSRCPtr=psxVuw+palstart; + + row=64;do + { + *px =LTCOL(*wSRCPtr); + *(px+1)=LTCOL(*(wSRCPtr+1)); + *(px+2)=LTCOL(*(wSRCPtr+2)); + *(px+3)=LTCOL(*(wSRCPtr+3)); + row--;px+=4;wSRCPtr+=4; + } + while (row); + + column=dy;do + { + row=dx; + do {*ta++=*(pa+(*cSRCPtr++));row--;} while(row); + ta+=xalign; + cSRCPtr+=LineOffset;column--; + } + while(column); + } + else + { + wSRCPtr=psxVuw+palstart; + + column=dy;do + { + row=dx; + do {*ta++=LTCOL(*(wSRCPtr+*cSRCPtr++));row--;} while(row); + ta+=xalign; + cSRCPtr+=LineOffset;column--; + } + while(column); + } + + break; + //--------------------------------------------------// + // 16bit texture load .. + case 2: + start=((pageid-16*pmult)<<6)+262144*pmult; + + wSRCPtr = psxVuw + start + (y1<<10) + x1; + LineOffset = 1024 - dx; + + column=dy;do + { + row=dx; + do {*ta++=LTCOL(*wSRCPtr++);row--;} while(row); + ta+=xalign; + wSRCPtr+=LineOffset;column--; + } + while(column); + + break; + //--------------------------------------------------// + // others are not possible ! + } + + x2a=dx+xalign; + + if(YTexS) + { + ta=(uint32_t *)texturepart; + pa=(uint32_t *)texturepart+x2a; + row=x2a;do {*ta++=*pa++;row--;} while(row); + pa=(uint32_t *)texturepart+dy*x2a; + ta=pa+x2a; + row=x2a;do {*ta++=*pa++;row--;} while(row); + YTexS--; + dy+=2; + } + + if(XTexS) + { + ta=(uint32_t *)texturepart; + pa=ta+1; + row=dy;do {*ta=*pa;ta+=x2a;pa+=x2a;row--;} while(row); + pa=(uint32_t *)texturepart+dx; + ta=pa+1; + row=dy;do {*ta=*pa;ta+=x2a;pa+=x2a;row--;} while(row); + XTexS--; + dx+=2; + } + + DXTexS=dx;DYTexS=dy; + + if(!iFilterType) {DefineSubTextureSort();return;} + if(iFilterType!=2 && iFilterType!=4 && iFilterType!=6) {DefineSubTextureSort();return;} + if((iFilterType==4 || iFilterType==6) && ly0==ly1 && ly2==ly3 && lx0==lx3 && lx1==lx2) + {DefineSubTextureSort();return;} + + ta=(uint32_t *)texturepart; + x1=dx-1; + y1=dy-1; + + if(bOpaquePass) + { + if(bSmallAlpha) + { + for(column=0;column<dy;column++) + { + for(row=0;row<dx;row++) + { + if(*ta==0x03000000) + { + cnt=0; + + if( column && *(ta-dx) >>24 !=0x03) scol[cnt++]=*(ta-dx); + if(row && *(ta-1) >>24 !=0x03) scol[cnt++]=*(ta-1); + if(row!=x1 && *(ta+1) >>24 !=0x03) scol[cnt++]=*(ta+1); + if( column!=y1 && *(ta+dx) >>24 !=0x03) scol[cnt++]=*(ta+dx); + + if(row && column && *(ta-dx-1)>>24 !=0x03) scol[cnt++]=*(ta-dx-1); + if(row!=x1 && column && *(ta-dx+1)>>24 !=0x03) scol[cnt++]=*(ta-dx+1); + if(row && column!=y1 && *(ta+dx-1)>>24 !=0x03) scol[cnt++]=*(ta+dx-1); + if(row!=x1 && column!=y1 && *(ta+dx+1)>>24 !=0x03) scol[cnt++]=*(ta+dx+1); + + if(cnt) + { + r=g=b=a=0; + for(h=0;h<cnt;h++) + { + r+=(scol[h]>>16)&0xff; + g+=(scol[h]>>8)&0xff; + b+=scol[h]&0xff; + } + r/=cnt;b/=cnt;g/=cnt; + + *ta=(r<<16)|(g<<8)|b; + *ta|=0x03000000; + } + } + ta++; + } + } + } + else + { + for(column=0;column<dy;column++) + { + for(row=0;row<dx;row++) + { + if(*ta==0x50000000) + { + cnt=0; + + if( column && *(ta-dx) !=0x50000000 && *(ta-dx)>>24!=1) scol[cnt++]=*(ta-dx); + if(row && *(ta-1) !=0x50000000 && *(ta-1)>>24!=1) scol[cnt++]=*(ta-1); + if(row!=x1 && *(ta+1) !=0x50000000 && *(ta+1)>>24!=1) scol[cnt++]=*(ta+1); + if( column!=y1 && *(ta+dx) !=0x50000000 && *(ta+dx)>>24!=1) scol[cnt++]=*(ta+dx); + + if(row && column && *(ta-dx-1)!=0x50000000 && *(ta-dx-1)>>24!=1) scol[cnt++]=*(ta-dx-1); + if(row!=x1 && column && *(ta-dx+1)!=0x50000000 && *(ta-dx+1)>>24!=1) scol[cnt++]=*(ta-dx+1); + if(row && column!=y1 && *(ta+dx-1)!=0x50000000 && *(ta+dx-1)>>24!=1) scol[cnt++]=*(ta+dx-1); + if(row!=x1 && column!=y1 && *(ta+dx+1)!=0x50000000 && *(ta+dx+1)>>24!=1) scol[cnt++]=*(ta+dx+1); + + if(cnt) + { + r=g=b=a=0; + for(h=0;h<cnt;h++) + { + a+=(scol[h]>>24); + r+=(scol[h]>>16)&0xff; + g+=(scol[h]>>8)&0xff; + b+=scol[h]&0xff; + } + r/=cnt;b/=cnt;g/=cnt; + + *ta=(r<<16)|(g<<8)|b; + if(a) *ta|=0x50000000; + else *ta|=0x01000000; + } + } + ta++; + } + } + } + } + else + for(column=0;column<dy;column++) + { + for(row=0;row<dx;row++) + { + if(*ta==0x00000000) + { + cnt=0; + + if(row!=x1 && *(ta+1) !=0x00000000) scol[cnt++]=*(ta+1); + if( column!=y1 && *(ta+dx) !=0x00000000) scol[cnt++]=*(ta+dx); + + if(cnt) + { + r=g=b=0; + for(h=0;h<cnt;h++) + { + r+=(scol[h]>>16)&0xff; + g+=(scol[h]>>8)&0xff; + b+=scol[h]&0xff; + } + r/=cnt;b/=cnt;g/=cnt; + *ta=(r<<16)|(g<<8)|b; + } + } + ta++; + } + } + + DefineSubTextureSort(); +} + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +//
+// load texture part (packed)
+//
+///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// + +void LoadPackedSubTexturePageSort(int pageid, int mode, short cx, short cy) +{ + uint32_t start,row,column,j,sxh,sxm; + unsigned int palstart; + unsigned short *px,*pa,*ta; + unsigned char *cSRCPtr; + unsigned short *wSRCPtr; + uint32_t LineOffset; + uint32_t x2a,xalign=0; + uint32_t x1=gl_ux[7]; + uint32_t x2=gl_ux[6]; + uint32_t y1=gl_ux[5]; + uint32_t y2=gl_ux[4]; + uint32_t dx=x2-x1+1; + uint32_t dy=y2-y1+1; + int pmult=pageid/16; + unsigned short (*LPTCOL)(unsigned short); + unsigned int a,r,g,b,cnt,h; + unsigned short scol[8]; + + LPTCOL=PTCF[DrawSemiTrans]; + + pa=px=(unsigned short *)ubPaletteBuffer; + ta=(unsigned short *)texturepart; + palstart=cx+(cy<<10); + + ubOpaqueDraw=0; + + if(YTexS) {ta+=dx;if(XTexS) ta+=2;} + if(XTexS) {ta+=1;xalign=2;} + + switch(mode) + { + //--------------------------------------------------// + // 4bit texture load .. + case 0:
+ if(GlobalTextIL)
+ {
+ unsigned int TXV,TXU,n_xi,n_yi;
+
+ wSRCPtr=psxVuw+palstart;
+ row=4;do
+ {
+ *px =LPTCOL(*wSRCPtr);
+ *(px+1)=LPTCOL(*(wSRCPtr+1));
+ *(px+2)=LPTCOL(*(wSRCPtr+2));
+ *(px+3)=LPTCOL(*(wSRCPtr+3));
+ row--;px+=4;wSRCPtr+=4;
+ }
+ while (row);
+
+ for(TXV=y1;TXV<=y2;TXV++)
+ {
+ for(TXU=x1;TXU<=x2;TXU++)
+ {
+ n_xi = ( ( TXU >> 2 ) & ~0x3c ) + ( ( TXV << 2 ) & 0x3c );
+ n_yi = ( TXV & ~0xf ) + ( ( TXU >> 4 ) & 0xf );
+
+ *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x03 ) << 2 ) ) & 0x0f ));
+ }
+ ta+=xalign;
+ }
+ break;
+ }
+ + start=((pageid-16*pmult)<<7)+524288*pmult; + + wSRCPtr=psxVuw+palstart; + row=4;do + { + *px =LPTCOL(*wSRCPtr); + *(px+1)=LPTCOL(*(wSRCPtr+1)); + *(px+2)=LPTCOL(*(wSRCPtr+2)); + *(px+3)=LPTCOL(*(wSRCPtr+3)); + row--;px+=4;wSRCPtr+=4; + } + while (row); + + x2a=x2?(x2-1):0;//if(x2) x2a=x2-1; else x2a=0; + sxm=x1&1;sxh=x1>>1; + j=sxm?(x1+1):x1;//if(sxm) j=x1+1; else j=x1; + + for(column=y1;column<=y2;column++) + { + cSRCPtr = psxVub + start + (column<<11) + sxh; + + if(sxm) *ta++=*(pa+((*cSRCPtr++ >> 4) & 0xF)); + + for(row=j;row<x2a;row+=2) + { + *ta =*(pa+(*cSRCPtr & 0xF)); + *(ta+1)=*(pa+((*cSRCPtr >> 4) & 0xF)); + cSRCPtr++;ta+=2; + } + + if(row<=x2) + { + *ta++=*(pa+(*cSRCPtr & 0xF));row++; + if(row<=x2) *ta++=*(pa+((*cSRCPtr >> 4) & 0xF)); + } + + ta+=xalign; + } + break; + //--------------------------------------------------// + // 8bit texture load .. + case 1:
+ if(GlobalTextIL)
+ {
+ unsigned int TXV,TXU,n_xi,n_yi;
+
+ wSRCPtr=psxVuw+palstart;
+
+ row=64;do
+ {
+ *px =LPTCOL(*wSRCPtr);
+ *(px+1)=LPTCOL(*(wSRCPtr+1));
+ *(px+2)=LPTCOL(*(wSRCPtr+2));
+ *(px+3)=LPTCOL(*(wSRCPtr+3));
+ row--;px+=4;wSRCPtr+=4;
+ }
+ while (row);
+
+ for(TXV=y1;TXV<=y2;TXV++)
+ {
+ for(TXU=x1;TXU<=x2;TXU++)
+ {
+ n_xi = ( ( TXU >> 1 ) & ~0x78 ) + ( ( TXU << 2 ) & 0x40 ) + ( ( TXV << 3 ) & 0x38 );
+ n_yi = ( TXV & ~0x7 ) + ( ( TXU >> 5 ) & 0x7 );
+
+ *ta++=*(pa+((*( psxVuw + ((GlobalTextAddrY + n_yi)*1024) + GlobalTextAddrX + n_xi ) >> ( ( TXU & 0x01 ) << 3 ) ) & 0xff));
+ }
+ ta+=xalign;
+ }
+
+ break;
+ }
+ + start=((pageid-16*pmult)<<7)+524288*pmult; + + cSRCPtr = psxVub + start + (y1<<11) + x1; + LineOffset = 2048 - dx; + + if(dy*dx>384) // more pix? use lut + { + wSRCPtr=psxVuw+palstart; + + row=64;do + { + *px =LPTCOL(*wSRCPtr); + *(px+1)=LPTCOL(*(wSRCPtr+1)); + *(px+2)=LPTCOL(*(wSRCPtr+2)); + *(px+3)=LPTCOL(*(wSRCPtr+3)); + row--;px+=4;wSRCPtr+=4; + } + while (row); + + column=dy;do + { + row=dx; + do {*ta++=*(pa+(*cSRCPtr++));row--;} while(row); + + ta+=xalign; + + cSRCPtr+=LineOffset;column--; + } + while(column); + } + else // small area? no lut + { + wSRCPtr=psxVuw+palstart; + + column=dy;do + { + row=dx; + do {*ta++=LPTCOL(*(wSRCPtr+*cSRCPtr++));row--;} while(row); + + ta+=xalign; + + cSRCPtr+=LineOffset;column--; + } + while(column); + } + break; + //--------------------------------------------------// + // 16bit texture load .. + case 2: + start=((pageid-16*pmult)<<6)+262144*pmult; + + wSRCPtr = psxVuw + start + (y1<<10) + x1; + LineOffset = 1024 - dx; + + column=dy;do + { + row=dx; + do {*ta++=LPTCOL(*wSRCPtr++);row--;} while(row); + + ta+=xalign; + + wSRCPtr+=LineOffset;column--; + } + while(column); + break; + //--------------------------------------------------// + // others are not possible ! + } + + //////////////////////////////////////////////////////// + + x2a=dx+xalign; + + if(YTexS) + { + ta=(unsigned short *)texturepart; + pa=(unsigned short *)texturepart+x2a; + row=x2a;do {*ta++=*pa++;row--;} while(row); + + pa=(unsigned short *)texturepart+dy*x2a; + ta=pa+x2a; + row=x2a;do {*ta++=*pa++;row--;} while(row); + + YTexS--; + dy+=2; + } + + if(XTexS) + { + ta=(unsigned short *)texturepart; + pa=ta+1; + row=dy;do {*ta=*pa;ta+=x2a;pa+=x2a;row--;} while(row); + + pa=(unsigned short *)texturepart+dx; + ta=pa+1; + row=dy;do {*ta=*pa;ta+=x2a;pa+=x2a;row--;} while(row); + + XTexS--; + dx+=2; + } + + DXTexS=dx;DYTexS=dy; + + if(!iFilterType) {DefineSubTextureSort();return;} + if(iFilterType!=2 && iFilterType!=4 && iFilterType!=6) {DefineSubTextureSort();return;} + if((iFilterType==4 || iFilterType==6) && ly0==ly1 && ly2==ly3 && lx0==lx3 && lx1==lx2) + {DefineSubTextureSort();return;} + + ta=(unsigned short *)texturepart; + x1=dx-1; + y1=dy-1; + + if(iTexQuality==1) + + { + if(bOpaquePass) + for(column=0;column<dy;column++) + { + for(row=0;row<dx;row++) + { + if(*ta==0x0006) + { + cnt=0; + + if( column && *(ta-dx) != 0x0006 && *(ta-dx)!=0) scol[cnt++]=*(ta-dx); + if(row && *(ta-1) != 0x0006 && *(ta-1) !=0) scol[cnt++]=*(ta-1); + if(row!=x1 && *(ta+1) != 0x0006 && *(ta+1) !=0) scol[cnt++]=*(ta+1); + if( column!=y1 && *(ta+dx) != 0x0006 && *(ta+dx)!=0) scol[cnt++]=*(ta+dx); + + if(row && column && *(ta-dx-1)!= 0x0006 && *(ta-dx-1)!=0) scol[cnt++]=*(ta-dx-1); + if(row!=x1 && column && *(ta-dx+1)!= 0x0006 && *(ta-dx+1)!=0) scol[cnt++]=*(ta-dx+1); + if(row && column!=y1 && *(ta+dx-1)!= 0x0006 && *(ta+dx-1)!=0) scol[cnt++]=*(ta+dx-1); + if(row!=x1 && column!=y1 && *(ta+dx+1)!= 0x0006 && *(ta+dx+1)!=0) scol[cnt++]=*(ta+dx+1); + + if(cnt) + { + r=g=b=a=0; + for(h=0;h<cnt;h++) + { + a+=scol[h]&0xf; + r+=scol[h]>>12; + g+=(scol[h]>>8)&0xf; + b+=(scol[h]>>4)&0xf; + } + r/=cnt;b/=cnt;g/=cnt; + *ta=(r<<12)|(g<<8)|(b<<4); + if(a) *ta|=6; + else *ta=0; + } + } + ta++; + } + } + else + for(column=0;column<dy;column++) + { + for(row=0;row<dx;row++) + { + if(*ta==0x0000) + { + cnt=0; + + if( column && *(ta-dx) != 0x0000) scol[cnt++]=*(ta-dx); + if(row && *(ta-1) != 0x0000) scol[cnt++]=*(ta-1); + if(row!=x1 && *(ta+1) != 0x0000) scol[cnt++]=*(ta+1); + if( column!=y1 && *(ta+dx) != 0x0000) scol[cnt++]=*(ta+dx); + + if(row && column && *(ta-dx-1)!= 0x0000) scol[cnt++]=*(ta-dx-1); + if(row!=x1 && column && *(ta-dx+1)!= 0x0000) scol[cnt++]=*(ta-dx+1); + if(row && column!=y1 && *(ta+dx-1)!= 0x0000) scol[cnt++]=*(ta+dx-1); + if(row!=x1 && column!=y1 && *(ta+dx+1)!= 0x0000) scol[cnt++]=*(ta+dx+1); + + if(cnt) + { + r=g=b=0; + for(h=0;h<cnt;h++) + { + r+=scol[h]>>12; + g+=(scol[h]>>8)&0xf; + b+=(scol[h]>>4)&0xf; + } + r/=cnt;b/=cnt;g/=cnt; + *ta=(r<<12)|(g<<8)|(b<<4); + } + } + ta++; + } + } + } + else + { + for(column=0;column<dy;column++) + { + for(row=0;row<dx;row++) + { + if(*ta==0) + { + cnt=0; + + if( column && *(ta-dx) &1) scol[cnt++]=*(ta-dx); + if(row && *(ta-1) &1) scol[cnt++]=*(ta-1); + if(row!=x1 && *(ta+1) &1) scol[cnt++]=*(ta+1); + if( column!=y1 && *(ta+dx) &1) scol[cnt++]=*(ta+dx); + + if(row && column && *(ta-dx-1)&1) scol[cnt++]=*(ta-dx-1); + if(row!=x1 && column && *(ta-dx+1)&1) scol[cnt++]=*(ta-dx+1); + if(row && column!=y1 && *(ta+dx-1)&1) scol[cnt++]=*(ta+dx-1); + if(row!=x1 && column!=y1 && *(ta+dx+1)&1) scol[cnt++]=*(ta+dx+1); + + if(cnt) + { + r=g=b=0; + for(h=0;h<cnt;h++) + { + r+=scol[h]>>11; + g+=(scol[h]>>6)&0x1f; + b+=(scol[h]>>1)&0x1f; + } + r/=cnt;b/=cnt;g/=cnt; + *ta=(r<<11)|(g<<6)|(b<<1); + } + } + ta++; + } + } + } + + DefineSubTextureSort(); +} + +///////////////////////////////////////////////////////////////////////////// +
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+//
+// hires texture funcs
+//
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+
+ +#define GET_RESULT(A, B, C, D) ((A != C || A != D) - (B != C || B != D)) + +//////////////////////////////////////////////////////////////////////// + +#define colorMask8 0x00FEFEFE +#define lowPixelMask8 0x00010101 +#define qcolorMask8 0x00FCFCFC +#define qlowpixelMask8 0x00030303 + + +#define INTERPOLATE8_02(A, B) (((((A & colorMask8) >> 1) + ((B & colorMask8) >> 1) + (A & B & lowPixelMask8))|((((A&0xFF000000)==0x03000000)?0x03000000:(((B&0xFF000000)==0x03000000)?0x03000000:(((A&0xFF000000)==0x00000000)?0x00000000:(((B&0xFF000000)==0x00000000)?0x00000000:0xFF000000))))))) + +#define Q_INTERPOLATE8_02(A, B, C, D) (((((A & qcolorMask8) >> 2) + ((B & qcolorMask8) >> 2) + ((C & qcolorMask8) >> 2) + ((D & qcolorMask8) >> 2) + ((((A & qlowpixelMask8) + (B & qlowpixelMask8) + (C & qlowpixelMask8) + (D & qlowpixelMask8)) >> 2) & qlowpixelMask8))|((((A&0xFF000000)==0x03000000)?0x03000000:(((B&0xFF000000)==0x03000000)?0x03000000:(((C&0xFF000000)==0x03000000)?0x03000000:(((D&0xFF000000)==0x03000000)?0x03000000:(((A&0xFF000000)==0x00000000)?0x00000000:(((B&0xFF000000)==0x00000000)?0x00000000:(((C&0xFF000000)==0x00000000)?0x00000000:(((D&0xFF000000)==0x00000000)?0x00000000:0xFF000000))))))))))) + +#define INTERPOLATE8(A, B) (((((A & colorMask8) >> 1) + ((B & colorMask8) >> 1) + (A & B & lowPixelMask8))|((((A&0xFF000000)==0x50000000)?0x50000000:(((B&0xFF000000)==0x50000000)?0x50000000:(((A&0xFF000000)==0x00000000)?0x00000000:(((B&0xFF000000)==0x00000000)?0x00000000:0xFF000000))))))) + +#define Q_INTERPOLATE8(A, B, C, D) (((((A & qcolorMask8) >> 2) + ((B & qcolorMask8) >> 2) + ((C & qcolorMask8) >> 2) + ((D & qcolorMask8) >> 2) + ((((A & qlowpixelMask8) + (B & qlowpixelMask8) + (C & qlowpixelMask8) + (D & qlowpixelMask8)) >> 2) & qlowpixelMask8))|((((A&0xFF000000)==0x50000000)?0x50000000:(((B&0xFF000000)==0x50000000)?0x50000000:(((C&0xFF000000)==0x50000000)?0x50000000:(((D&0xFF000000)==0x50000000)?0x50000000:(((A&0xFF000000)==0x00000000)?0x00000000:(((B&0xFF000000)==0x00000000)?0x00000000:(((C&0xFF000000)==0x00000000)?0x00000000:(((D&0xFF000000)==0x00000000)?0x00000000:0xFF000000))))))))))) + +void Super2xSaI_ex8_Ex(unsigned char *srcPtr, DWORD srcPitch, + unsigned char *dstBitmap, int width, int height) +{ + DWORD dstPitch = srcPitch * 2; + DWORD line; + DWORD *dP; + DWORD *bP; + int width2 = width*2; + int iXA,iXB,iXC,iYA,iYB,iYC,finish; + DWORD color4, color5, color6; + DWORD color1, color2, color3; + DWORD colorA0, colorA1, colorA2, colorA3, + colorB0, colorB1, colorB2, colorB3, + colorS1, colorS2; + DWORD product1a, product1b, + product2a, product2b; + + line = 0; + + { + for (; height; height-=1) + { + bP = (DWORD *)srcPtr; + dP = (DWORD *)(dstBitmap + line*dstPitch); + for (finish = width; finish; finish -= 1 ) + { +//--------------------------------------- B1 B2 +// 4 5 6 S2 +// 1 2 3 S1 +// A1 A2 + if(finish==width) iXA=0; + else iXA=1; + if(finish>4) {iXB=1;iXC=2;} + else + if(finish>3) {iXB=1;iXC=1;} + else {iXB=0;iXC=0;} + if(line==0) iYA=0; + else iYA=width; + if(height>4) {iYB=width;iYC=width2;} + else + if(height>3) {iYB=width;iYC=width;} + else {iYB=0;iYC=0;} + + + colorB0 = *(bP- iYA - iXA); + colorB1 = *(bP- iYA); + colorB2 = *(bP- iYA + iXB); + colorB3 = *(bP- iYA + iXC); + + color4 = *(bP - iXA); + color5 = *(bP); + color6 = *(bP + iXB); + colorS2 = *(bP + iXC); + + color1 = *(bP + iYB - iXA); + color2 = *(bP + iYB); + color3 = *(bP + iYB + iXB); + colorS1= *(bP + iYB + iXC); + + colorA0 = *(bP + iYC - iXA); + colorA1 = *(bP + iYC); + colorA2 = *(bP + iYC + iXB); + colorA3 = *(bP + iYC + iXC); + +//-------------------------------------- + if (color2 == color6 && color5 != color3) + { + product2b = product1b = color2; + } + else + if (color5 == color3 && color2 != color6) + { + product2b = product1b = color5; + } + else + if (color5 == color3 && color2 == color6) + { + register int r = 0; + + r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color1&0x00ffffff), (colorA1&0x00ffffff)); + r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color4&0x00ffffff), (colorB1&0x00ffffff)); + r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorA2&0x00ffffff), (colorS1&0x00ffffff)); + r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorB2&0x00ffffff), (colorS2&0x00ffffff)); + + if (r > 0) + product2b = product1b = color6; + else + if (r < 0) + product2b = product1b = color5; + else + { + product2b = product1b = INTERPOLATE8_02(color5, color6); + } + } + else + { + if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0) + product2b = Q_INTERPOLATE8_02 (color3, color3, color3, color2); + else + if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3) + product2b = Q_INTERPOLATE8_02 (color2, color2, color2, color3); + else + product2b = INTERPOLATE8_02 (color2, color3); + + if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0) + product1b = Q_INTERPOLATE8_02 (color6, color6, color6, color5); + else + if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3) + product1b = Q_INTERPOLATE8_02 (color6, color5, color5, color5); + else + product1b = INTERPOLATE8_02 (color5, color6); + } + + if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2) + product2a = INTERPOLATE8_02(color2, color5); + else + if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0) + product2a = INTERPOLATE8_02(color2, color5); + else + product2a = color2; + + if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2) + product1a = INTERPOLATE8_02(color2, color5); + else + if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0) + product1a = INTERPOLATE8_02(color2, color5); + else + product1a = color5; + + *dP=product1a; + *(dP+1)=product1b; + *(dP+(width2))=product2a; + *(dP+1+(width2))=product2b; + + bP += 1; + dP += 2; + }//end of for ( finish= width etc..) + + line += 2; + srcPtr += srcPitch; + }; //endof: for (; height; height--) + } +} + + +void Super2xSaI_ex8(unsigned char *srcPtr, DWORD srcPitch, + unsigned char *dstBitmap, int width, int height) +{ + DWORD dstPitch = srcPitch * 2; + DWORD line; + DWORD *dP; + DWORD *bP; + int width2 = width*2; + int iXA,iXB,iXC,iYA,iYB,iYC,finish; + DWORD color4, color5, color6; + DWORD color1, color2, color3; + DWORD colorA0, colorA1, colorA2, colorA3, + colorB0, colorB1, colorB2, colorB3, + colorS1, colorS2; + DWORD product1a, product1b, + product2a, product2b; + + line = 0; + + { + for (; height; height-=1) + { + bP = (DWORD *)srcPtr; + dP = (DWORD *)(dstBitmap + line*dstPitch); + for (finish = width; finish; finish -= 1 ) + { +//--------------------------------------- B1 B2 +// 4 5 6 S2 +// 1 2 3 S1 +// A1 A2 + if(finish==width) iXA=0; + else iXA=1; + if(finish>4) {iXB=1;iXC=2;} + else + if(finish>3) {iXB=1;iXC=1;} + else {iXB=0;iXC=0;} + if(line==0) iYA=0; + else iYA=width; + if(height>4) {iYB=width;iYC=width2;} + else + if(height>3) {iYB=width;iYC=width;} + else {iYB=0;iYC=0;} + + + colorB0 = *(bP- iYA - iXA); + colorB1 = *(bP- iYA); + colorB2 = *(bP- iYA + iXB); + colorB3 = *(bP- iYA + iXC); + + color4 = *(bP - iXA); + color5 = *(bP); + color6 = *(bP + iXB); + colorS2 = *(bP + iXC); + + color1 = *(bP + iYB - iXA); + color2 = *(bP + iYB); + color3 = *(bP + iYB + iXB); + colorS1= *(bP + iYB + iXC); + + colorA0 = *(bP + iYC - iXA); + colorA1 = *(bP + iYC); + colorA2 = *(bP + iYC + iXB); + colorA3 = *(bP + iYC + iXC); + +//-------------------------------------- + if (color2 == color6 && color5 != color3) + { + product2b = product1b = color2; + } + else + if (color5 == color3 && color2 != color6) + { + product2b = product1b = color5; + } + else + if (color5 == color3 && color2 == color6) + { + register int r = 0; + + r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color1&0x00ffffff), (colorA1&0x00ffffff)); + r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (color4&0x00ffffff), (colorB1&0x00ffffff)); + r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorA2&0x00ffffff), (colorS1&0x00ffffff)); + r += GET_RESULT ((color6&0x00ffffff), (color5&0x00ffffff), (colorB2&0x00ffffff), (colorS2&0x00ffffff)); + + if (r > 0) + product2b = product1b = color6; + else + if (r < 0) + product2b = product1b = color5; + else + { + product2b = product1b = INTERPOLATE8(color5, color6); + } + } + else + { + if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0) + product2b = Q_INTERPOLATE8 (color3, color3, color3, color2); + else + if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3) + product2b = Q_INTERPOLATE8 (color2, color2, color2, color3); + else + product2b = INTERPOLATE8 (color2, color3); + + if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0) + product1b = Q_INTERPOLATE8 (color6, color6, color6, color5); + else + if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3) + product1b = Q_INTERPOLATE8 (color6, color5, color5, color5); + else + product1b = INTERPOLATE8 (color5, color6); + } + + if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2) + product2a = INTERPOLATE8(color2, color5); + else + if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0) + product2a = INTERPOLATE8(color2, color5); + else + product2a = color2; + + if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2) + product1a = INTERPOLATE8(color2, color5); + else + if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0) + product1a = INTERPOLATE8(color2, color5); + else + product1a = color5; + + *dP=product1a; + *(dP+1)=product1b; + *(dP+(width2))=product2a; + *(dP+1+(width2))=product2b; + + bP += 1; + dP += 2; + }//end of for ( finish= width etc..) + + line += 2; + srcPtr += srcPitch; + }; //endof: for (; height; height--) + } +} +///////////////////////////////////////////////////////////////////////////// + +#define colorMask4 0x0000EEE0 +#define lowPixelMask4 0x00001110 +#define qcolorMask4 0x0000CCC0 +#define qlowpixelMask4 0x00003330 + +#define INTERPOLATE4(A, B) ((((A & colorMask4) >> 1) + ((B & colorMask4) >> 1) + (A & B & lowPixelMask4))|((((A&0x0000000F)==0x00000006)?0x00000006:(((B&0x0000000F)==0x00000006)?0x00000006:(((A&0x0000000F)==0x00000000)?0x00000000:(((B&0x0000000F)==0x00000000)?0x00000000:0x0000000F)))))) + +#define Q_INTERPOLATE4(A, B, C, D) ((((A & qcolorMask4) >> 2) + ((B & qcolorMask4) >> 2) + ((C & qcolorMask4) >> 2) + ((D & qcolorMask4) >> 2) + ((((A & qlowpixelMask4) + (B & qlowpixelMask4) + (C & qlowpixelMask4) + (D & qlowpixelMask4)) >> 2) & qlowpixelMask4))| ((((A&0x0000000F)==0x00000006)?0x00000006:(((B&0x0000000F)==0x00000006)?0x00000006:(((C&0x0000000F)==0x00000006)?0x00000006:(((D&0x0000000F)==0x00000006)?0x00000006:(((A&0x0000000F)==0x00000000)?0x00000000:(((B&0x0000000F)==0x00000000)?0x00000000:(((C&0x0000000F)==0x00000000)?0x00000000:(((D&0x0000000F)==0x00000000)?0x00000000:0x0000000F)))))))))) + +void Super2xSaI_ex4(unsigned char *srcPtr, DWORD srcPitch, + unsigned char *dstBitmap, int width, int height) +{ + DWORD dstPitch = srcPitch * 2; + DWORD line; + unsigned short *dP; + unsigned short *bP; + int width2 = width*2; + int iXA,iXB,iXC,iYA,iYB,iYC,finish; + DWORD color4, color5, color6; + DWORD color1, color2, color3; + DWORD colorA0, colorA1, colorA2, colorA3, + colorB0, colorB1, colorB2, colorB3, + colorS1, colorS2; + DWORD product1a, product1b, + product2a, product2b; + + line = 0; + + { + for (; height; height-=1) + { + bP = (unsigned short *)srcPtr; + dP = (unsigned short *)(dstBitmap + line*dstPitch); + for (finish = width; finish; finish -= 1 ) + { +//--------------------------------------- B1 B2 +// 4 5 6 S2 +// 1 2 3 S1 +// A1 A2 + if(finish==width) iXA=0; + else iXA=1; + if(finish>4) {iXB=1;iXC=2;} + else + if(finish>3) {iXB=1;iXC=1;} + else {iXB=0;iXC=0;} + if(line==0) iYA=0; + else iYA=width; + if(height>4) {iYB=width;iYC=width2;} + else + if(height>3) {iYB=width;iYC=width;} + else {iYB=0;iYC=0;} + + + colorB0 = *(bP- iYA - iXA); + colorB1 = *(bP- iYA); + colorB2 = *(bP- iYA + iXB); + colorB3 = *(bP- iYA + iXC); + + color4 = *(bP - iXA); + color5 = *(bP); + color6 = *(bP + iXB); + colorS2 = *(bP + iXC); + + color1 = *(bP + iYB - iXA); + color2 = *(bP + iYB); + color3 = *(bP + iYB + iXB); + colorS1= *(bP + iYB + iXC); + + colorA0 = *(bP + iYC - iXA); + colorA1 = *(bP + iYC); + colorA2 = *(bP + iYC + iXB); + colorA3 = *(bP + iYC + iXC); + +//-------------------------------------- + if (color2 == color6 && color5 != color3) + { + product2b = product1b = color2; + } + else + if (color5 == color3 && color2 != color6) + { + product2b = product1b = color5; + } + else + if (color5 == color3 && color2 == color6) + { + register int r = 0; + + r += GET_RESULT ((color6&0xfffffff0), (color5&0xfffffff0), (color1&0xfffffff0), (colorA1&0xfffffff0)); + r += GET_RESULT ((color6&0xfffffff0), (color5&0xfffffff0), (color4&0xfffffff0), (colorB1&0xfffffff0)); + r += GET_RESULT ((color6&0xfffffff0), (color5&0xfffffff0), (colorA2&0xfffffff0), (colorS1&0xfffffff0)); + r += GET_RESULT ((color6&0xfffffff0), (color5&0xfffffff0), (colorB2&0xfffffff0), (colorS2&0xfffffff0)); + + if (r > 0) + product2b = product1b = color6; + else + if (r < 0) + product2b = product1b = color5; + else + { + product2b = product1b = INTERPOLATE4 (color5, color6); + } + } + else + { + if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0) + product2b = Q_INTERPOLATE4 (color3, color3, color3, color2); + else + if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3) + product2b = Q_INTERPOLATE4 (color2, color2, color2, color3); + else + product2b = INTERPOLATE4 (color2, color3); + + if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0) + product1b = Q_INTERPOLATE4 (color6, color6, color6, color5); + else + if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3) + product1b = Q_INTERPOLATE4 (color6, color5, color5, color5); + else + product1b = INTERPOLATE4 (color5, color6); + } + + if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2) + product2a = INTERPOLATE4 (color2, color5); + else + if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0) + product2a = INTERPOLATE4(color2, color5); + else + product2a = color2; + + if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2) + product1a = INTERPOLATE4 (color2, color5); + else + if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0) + product1a = INTERPOLATE4(color2, color5); + else + product1a = color5; + + *dP=product1a; + *(dP+1)=product1b; + *(dP+(width2))=product2a; + *(dP+1+(width2))=product2b; + + bP += 1; + dP += 2; + }//end of for ( finish= width etc..) + + line += 2; + srcPtr += srcPitch; + }; //endof: for (; height; height--) + } +} + +///////////////////////////////////////////////////////////////////////////// + +#define colorMask5 0x0000F7BC +#define lowPixelMask5 0x00000842 +#define qcolorMask5 0x0000E738 +#define qlowpixelMask5 0x000018C6 + +#define INTERPOLATE5(A, B) ((((A & colorMask5) >> 1) + ((B & colorMask5) >> 1) + (A & B & lowPixelMask5))|((((A&0x00000001)==0x00000000)?0x00000000:(((B&0x00000001)==0x00000000)?0x00000000:0x00000001)))) + +#define Q_INTERPOLATE5(A, B, C, D) ((((A & qcolorMask5) >> 2) + ((B & qcolorMask5) >> 2) + ((C & qcolorMask5) >> 2) + ((D & qcolorMask5) >> 2) + ((((A & qlowpixelMask5) + (B & qlowpixelMask5) + (C & qlowpixelMask5) + (D & qlowpixelMask5)) >> 2) & qlowpixelMask5))| ((((A&0x00000001)==0x00000000)?0x00000000:(((B&0x00000001)==0x00000000)?0x00000000:(((C&0x00000001)==0x00000000)?0x00000000:(((D&0x00000001)==0x00000000)?0x00000000:0x00000001)))))) + +void Super2xSaI_ex5(unsigned char *srcPtr, DWORD srcPitch, + unsigned char *dstBitmap, int width, int height) +{ + DWORD dstPitch = srcPitch * 2; + DWORD line; + unsigned short *dP; + unsigned short *bP; + int width2 = width*2; + int iXA,iXB,iXC,iYA,iYB,iYC,finish; + DWORD color4, color5, color6; + DWORD color1, color2, color3; + DWORD colorA0, colorA1, colorA2, colorA3, + colorB0, colorB1, colorB2, colorB3, + colorS1, colorS2; + DWORD product1a, product1b, + product2a, product2b; + + line = 0; + + { + for (; height; height-=1) + { + bP = (unsigned short *)srcPtr; + dP = (unsigned short *)(dstBitmap + line*dstPitch); + for (finish = width; finish; finish -= 1 ) + { +//--------------------------------------- B1 B2 +// 4 5 6 S2 +// 1 2 3 S1 +// A1 A2 + if(finish==width) iXA=0; + else iXA=1; + if(finish>4) {iXB=1;iXC=2;} + else + if(finish>3) {iXB=1;iXC=1;} + else {iXB=0;iXC=0;} + if(line==0) iYA=0; + else iYA=width; + if(height>4) {iYB=width;iYC=width2;} + else + if(height>3) {iYB=width;iYC=width;} + else {iYB=0;iYC=0;} + + + colorB0 = *(bP- iYA - iXA); + colorB1 = *(bP- iYA); + colorB2 = *(bP- iYA + iXB); + colorB3 = *(bP- iYA + iXC); + + color4 = *(bP - iXA); + color5 = *(bP); + color6 = *(bP + iXB); + colorS2 = *(bP + iXC); + + color1 = *(bP + iYB - iXA); + color2 = *(bP + iYB); + color3 = *(bP + iYB + iXB); + colorS1= *(bP + iYB + iXC); + + colorA0 = *(bP + iYC - iXA); + colorA1 = *(bP + iYC); + colorA2 = *(bP + iYC + iXB); + colorA3 = *(bP + iYC + iXC); + +//-------------------------------------- + if (color2 == color6 && color5 != color3) + { + product2b = product1b = color2; + } + else + if (color5 == color3 && color2 != color6) + { + product2b = product1b = color5; + } + else + if (color5 == color3 && color2 == color6) + { + register int r = 0; + + r += GET_RESULT ((color6&0xfffffffe), (color5&0xfffffffe), (color1&0xfffffffe), (colorA1&0xfffffffe)); + r += GET_RESULT ((color6&0xfffffffe), (color5&0xfffffffe), (color4&0xfffffffe), (colorB1&0xfffffffe)); + r += GET_RESULT ((color6&0xfffffffe), (color5&0xfffffffe), (colorA2&0xfffffffe), (colorS1&0xfffffffe)); + r += GET_RESULT ((color6&0xfffffffe), (color5&0xfffffffe), (colorB2&0xfffffffe), (colorS2&0xfffffffe)); + + if (r > 0) + product2b = product1b = color6; + else + if (r < 0) + product2b = product1b = color5; + else + { + product2b = product1b = INTERPOLATE5 (color5, color6); + } + } + else + { + if (color6 == color3 && color3 == colorA1 && color2 != colorA2 && color3 != colorA0) + product2b = Q_INTERPOLATE5 (color3, color3, color3, color2); + else + if (color5 == color2 && color2 == colorA2 && colorA1 != color3 && color2 != colorA3) + product2b = Q_INTERPOLATE5 (color2, color2, color2, color3); + else + product2b = INTERPOLATE5 (color2, color3); + + if (color6 == color3 && color6 == colorB1 && color5 != colorB2 && color6 != colorB0) + product1b = Q_INTERPOLATE5 (color6, color6, color6, color5); + else + if (color5 == color2 && color5 == colorB2 && colorB1 != color6 && color5 != colorB3) + product1b = Q_INTERPOLATE5 (color6, color5, color5, color5); + else + product1b = INTERPOLATE5 (color5, color6); + } + + if (color5 == color3 && color2 != color6 && color4 == color5 && color5 != colorA2) + product2a = INTERPOLATE5 (color2, color5); + else + if (color5 == color1 && color6 == color5 && color4 != color2 && color5 != colorA0) + product2a = INTERPOLATE5(color2, color5); + else + product2a = color2; + + if (color2 == color6 && color5 != color3 && color1 == color2 && color2 != colorB2) + product1a = INTERPOLATE5(color2, color5); + else + if (color4 == color2 && color3 == color2 && color1 != color5 && color2 != colorB0) + product1a = INTERPOLATE5(color2, color5); + else + product1a = color5; + + *dP=product1a; + *(dP+1)=product1b; + *(dP+(width2))=product2a; + *(dP+1+(width2))=product2b; + + bP += 1; + dP += 2; + }//end of for ( finish= width etc..) + + line += 2; + srcPtr += srcPitch; + }; //endof: for (; height; height--) + } +} + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +//
+// ogl texture defines
+//
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+ +void DefineSubTextureSortHiRes(void) +{ + int x,y,dx2; + + if(!gTexName) + { + glGenTextures(1, &gTexName); + glBindTexture(GL_TEXTURE_2D, gTexName); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType); + + if(iFilterType) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + else + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } + glTexImage2D(GL_TEXTURE_2D, 0, giWantedRGBA, 512, 512, 0, giWantedFMT, giWantedTYPE, texturebuffer); + } + else glBindTexture(GL_TEXTURE_2D, gTexName); + + if(bGLExt && (iTexQuality==1 || iTexQuality==2)) + { + if(DXTexS < 4 || DYTexS < 4 || iHiResTextures==2) + { + unsigned short * pS,*pD1,*pD2; + dx2=(DXTexS<<1); + pS=(unsigned short *)texturepart; + pD1=(unsigned short *)texturebuffer; + pD2=(unsigned short *)texturebuffer; + pD2+=dx2; + for(y=0;y<DYTexS;y++) + { + for(x=0;x<DXTexS;x++) + { + *(pD2+1)=*pD2=*(pD1+1)=*pD1=*pS; + pS++; + pD1+=2; + pD2+=2; + } + pD1+=dx2; + pD2+=dx2; + } + } + else + { + if(iTexQuality==1) + Super2xSaI_ex4(texturepart, DXTexS<<1, texturebuffer, DXTexS, DYTexS); + else + Super2xSaI_ex5(texturepart, DXTexS<<1, texturebuffer, DXTexS, DYTexS); + } + } + else + { + if(DXTexS < 4 || DYTexS < 4 || iHiResTextures==2) + { + uint32_t * pS,*pD1,*pD2; + dx2=(DXTexS<<1); + pS=(uint32_t *)texturepart; + pD1=(uint32_t *)texturebuffer; + pD2=(uint32_t *)texturebuffer; + pD2+=dx2; + for(y=0;y<DYTexS;y++) + { + for(x=0;x<DXTexS;x++) + { + *(pD2+1)=*pD2=*(pD1+1)=*pD1=*pS; + pS++; + pD1+=2; + pD2+=2; + } + pD1+=dx2; + pD2+=dx2; + } + } + else + if(bSmallAlpha) + Super2xSaI_ex8_Ex(texturepart, DXTexS*4, texturebuffer, DXTexS, DYTexS); + else + Super2xSaI_ex8(texturepart, DXTexS*4, texturebuffer, DXTexS, DYTexS); + } + + glTexSubImage2D(GL_TEXTURE_2D, 0, XTexS<<1, YTexS<<1, + DXTexS<<1, DYTexS<<1, + giWantedFMT, giWantedTYPE, texturebuffer); +} + +///////////////////////////////////////////////////////////////////////////// + +void DefineSubTextureSort(void) +{ + if(iHiResTextures) + { + DefineSubTextureSortHiRes(); + return; + } + + if(!gTexName) + { + glGenTextures(1, &gTexName); + glBindTexture(GL_TEXTURE_2D, gTexName); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, iClampType); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, iClampType); + + if(iFilterType) + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + else + { + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } + glTexImage2D(GL_TEXTURE_2D, 0, giWantedRGBA, 256, 256, 0,giWantedFMT, giWantedTYPE, texturepart); + } + else glBindTexture(GL_TEXTURE_2D, gTexName); + + glTexSubImage2D(GL_TEXTURE_2D, 0, XTexS, YTexS, + DXTexS, DYTexS, + giWantedFMT, giWantedTYPE, texturepart); +} + +///////////////////////////////////////////////////////////////////////////// +
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+//
+// texture cache garbage collection
+//
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+ +void DoTexGarbageCollection(void) +{ + static unsigned short LRUCleaned=0; + unsigned short iC,iC1,iC2; + int i,j,iMax;textureSubCacheEntryS * tsb; + + iC=4;//=iSortTexCnt/2, + LRUCleaned+=iC; // we clean different textures each time + if((LRUCleaned+iC)>=iSortTexCnt) LRUCleaned=0; // wrap? wrap! + iC1=LRUCleaned; // range of textures to clean + iC2=LRUCleaned+iC; + + for(iC=iC1;iC<iC2;iC++) // make some textures available + { + pxSsubtexLeft[iC]->l=0; + } + + for(i=0;i<3;i++) // remove all references to that textures + for(j=0;j<MAXTPAGES;j++) + for(iC=0;iC<4;iC++) // loop all texture rect info areas + { + tsb=pscSubtexStore[i][j]+(iC*SOFFB); + iMax=tsb->pos.l; + if(iMax) + do + { + tsb++; + if(tsb->cTexID>=iC1 && tsb->cTexID<iC2) // info uses the cleaned textures? remove info + tsb->ClutID=0; + } + while(--iMax); + } + + usLRUTexPage=LRUCleaned; +} + +/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+//
+// search cache for existing (already used) parts
+//
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+ +unsigned char * CheckTextureInSubSCache(int TextureMode, uint32_t GivenClutId, unsigned short * pCache) +{ + textureSubCacheEntryS * tsx, * tsb, *tsg;//, *tse=NULL; + int i,iMax;EXLong npos; + unsigned char cx,cy; + int iC,j,k;uint32_t rx,ry,mx,my; + EXLong * ul=0, * uls; + EXLong rfree; + unsigned char cXAdj,cYAdj; + + npos.l=*((uint32_t *)&gl_ux[4]); + + //--------------------------------------------------------------// + // find matching texturepart first... speed up... + //--------------------------------------------------------------// + + tsg=pscSubtexStore[TextureMode][GlobalTexturePage]; + tsg+=((GivenClutId&CLUTCHK)>>CLUTSHIFT)*SOFFB; + + iMax=tsg->pos.l; + if(iMax) + { + i=iMax; + tsb=tsg+1; + do + { + if(GivenClutId==tsb->ClutID && + (INCHECK(tsb->pos,npos))) + { + { + cx=tsb->pos.c[3]-tsb->posTX; + cy=tsb->pos.c[1]-tsb->posTY; + + gl_ux[0]-=cx; + gl_ux[1]-=cx; + gl_ux[2]-=cx; + gl_ux[3]-=cx; + gl_vy[0]-=cy; + gl_vy[1]-=cy; + gl_vy[2]-=cy; + gl_vy[3]-=cy; + + ubOpaqueDraw=tsb->Opaque; + *pCache=tsb->cTexID; + return NULL; + } + } + tsb++; + } + while(--i); + } + + //----------------------------------------------------// + + cXAdj=1;cYAdj=1; + + rx=(int)gl_ux[6]-(int)gl_ux[7]; + ry=(int)gl_ux[4]-(int)gl_ux[5]; + + tsx=NULL;tsb=tsg+1; + for(i=0;i<iMax;i++,tsb++) + { + if(!tsb->ClutID) {tsx=tsb;break;} + } + + if(!tsx) + { + iMax++; + if(iMax>=SOFFB-2) + { + if(iTexGarbageCollection) // gc mode? + { + if(*pCache==0) + { + dwTexPageComp|=(1<<GlobalTexturePage); + *pCache=0xffff; + return 0; + } + + iMax--; + tsb=tsg+1; + + for(i=0;i<iMax;i++,tsb++) // 1. search other slots with same cluts, and unite the area + if(GivenClutId==tsb->ClutID) + { + if(!tsx) {tsx=tsb;rfree.l=npos.l;} // + else tsb->ClutID=0; + rfree.c[3]=min(rfree.c[3],tsb->pos.c[3]); + rfree.c[2]=max(rfree.c[2],tsb->pos.c[2]); + rfree.c[1]=min(rfree.c[1],tsb->pos.c[1]); + rfree.c[0]=max(rfree.c[0],tsb->pos.c[0]); + MarkFree(tsb); + } + + if(tsx) // 3. if one or more found, create a new rect with bigger size + { + *((uint32_t *)&gl_ux[4])=npos.l=rfree.l; + rx=(int)rfree.c[2]-(int)rfree.c[3]; + ry=(int)rfree.c[0]-(int)rfree.c[1]; + DoTexGarbageCollection(); + + goto ENDLOOP3; + } + } + + iMax=1; + } + tsx=tsg+iMax; + tsg->pos.l=iMax; + } + + //----------------------------------------------------// + // now get a free texture space + //----------------------------------------------------// + + if(iTexGarbageCollection) usLRUTexPage=0; + +ENDLOOP3: + + rx+=3;if(rx>255) {cXAdj=0;rx=255;} + ry+=3;if(ry>255) {cYAdj=0;ry=255;} + + iC=usLRUTexPage; + + for(k=0;k<iSortTexCnt;k++) + { + uls=pxSsubtexLeft[iC]; + iMax=uls->l;ul=uls+1; + + //--------------------------------------------------// + // first time + + if(!iMax) + { + rfree.l=0; + + if(rx>252 && ry>252) + {uls->l=1;ul->l=0xffffffff;ul=0;goto ENDLOOP;} + + if(rx<253) + { + uls->l=uls->l+1; + ul->c[3]=rx; + ul->c[2]=255-rx; + ul->c[1]=0; + ul->c[0]=ry; + ul++; + } + + if(ry<253) + { + uls->l=uls->l+1; + ul->c[3]=0; + ul->c[2]=255; + ul->c[1]=ry; + ul->c[0]=255-ry; + } + ul=0; + goto ENDLOOP; + } + + //--------------------------------------------------// + for(i=0;i<iMax;i++,ul++) + { + if(ul->l!=0xffffffff && + ry<=ul->c[0] && + rx<=ul->c[2]) + { + rfree=*ul; + mx=ul->c[2]-2; + my=ul->c[0]-2; + if(rx<mx && ry<my) + { + ul->c[3]+=rx; + ul->c[2]-=rx; + ul->c[0]=ry; + + for(ul=uls+1,j=0;j<iMax;j++,ul++) + if(ul->l==0xffffffff) break; + + if(j<CSUBSIZE-2) + { + if(j==iMax) uls->l=uls->l+1; + + ul->c[3]=rfree.c[3]; + ul->c[2]=rfree.c[2]; + ul->c[1]=rfree.c[1]+ry; + ul->c[0]=rfree.c[0]-ry; + } + } + else if(rx<mx) + { + ul->c[3]+=rx; + ul->c[2]-=rx; + } + else if(ry<my) + { + ul->c[1]+=ry; + ul->c[0]-=ry; + } + else + { + ul->l=0xffffffff; + } + ul=0; + goto ENDLOOP; + } + } + + //--------------------------------------------------// + + iC++; if(iC>=iSortTexCnt) iC=0; + } + + //----------------------------------------------------// + // check, if free space got + //----------------------------------------------------// + +ENDLOOP: + if(ul) + { + ////////////////////////////////////////////////////// +
+ { + dwTexPageComp=0; + + for(i=0;i<3;i++) // cleaning up + for(j=0;j<MAXTPAGES;j++) + { + tsb=pscSubtexStore[i][j]; + (tsb+SOFFA)->pos.l=0; + (tsb+SOFFB)->pos.l=0; + (tsb+SOFFC)->pos.l=0; + (tsb+SOFFD)->pos.l=0; + } + for(i=0;i<iSortTexCnt;i++) + {ul=pxSsubtexLeft[i];ul->l=0;} + usLRUTexPage=0; + } + + ////////////////////////////////////////////////////// + iC=usLRUTexPage; + uls=pxSsubtexLeft[usLRUTexPage]; + uls->l=0;ul=uls+1; + rfree.l=0; + + if(rx>252 && ry>252) + {uls->l=1;ul->l=0xffffffff;} + else + { + if(rx<253) + { + uls->l=uls->l+1; + ul->c[3]=rx; + ul->c[2]=255-rx; + ul->c[1]=0; + ul->c[0]=ry; + ul++; + } + if(ry<253) + { + uls->l=uls->l+1; + ul->c[3]=0; + ul->c[2]=255; + ul->c[1]=ry; + ul->c[0]=255-ry; + } + } + tsg->pos.l=1;tsx=tsg+1; + } + + rfree.c[3]+=cXAdj; + rfree.c[1]+=cYAdj; + + tsx->cTexID =*pCache=iC; + tsx->pos = npos; + tsx->ClutID = GivenClutId; + tsx->posTX = rfree.c[3]; + tsx->posTY = rfree.c[1]; + + cx=gl_ux[7]-rfree.c[3]; + cy=gl_ux[5]-rfree.c[1]; + + gl_ux[0]-=cx; + gl_ux[1]-=cx; + gl_ux[2]-=cx; + gl_ux[3]-=cx; + gl_vy[0]-=cy; + gl_vy[1]-=cy; + gl_vy[2]-=cy; + gl_vy[3]-=cy; + + XTexS=rfree.c[3]; + YTexS=rfree.c[1]; + + return &tsx->Opaque; +} + +/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+//
+// search cache for free place (on compress)
+//
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+ +BOOL GetCompressTexturePlace(textureSubCacheEntryS * tsx) +{ + int i,j,k,iMax,iC;uint32_t rx,ry,mx,my; + EXLong * ul=0, * uls, rfree; + unsigned char cXAdj=1,cYAdj=1; + + rx=(int)tsx->pos.c[2]-(int)tsx->pos.c[3]; + ry=(int)tsx->pos.c[0]-(int)tsx->pos.c[1]; + + rx+=3;if(rx>255) {cXAdj=0;rx=255;} + ry+=3;if(ry>255) {cYAdj=0;ry=255;} + + iC=usLRUTexPage; + + for(k=0;k<iSortTexCnt;k++) + { + uls=pxSsubtexLeft[iC]; + iMax=uls->l;ul=uls+1; + + //--------------------------------------------------// + // first time + + if(!iMax) + { + rfree.l=0; + + if(rx>252 && ry>252) + {uls->l=1;ul->l=0xffffffff;ul=0;goto TENDLOOP;} + + if(rx<253) + { + uls->l=uls->l+1; + ul->c[3]=rx; + ul->c[2]=255-rx; + ul->c[1]=0; + ul->c[0]=ry; + ul++; + } + + if(ry<253) + { + uls->l=uls->l+1; + ul->c[3]=0; + ul->c[2]=255; + ul->c[1]=ry; + ul->c[0]=255-ry; + } + ul=0; + goto TENDLOOP; + } + + //--------------------------------------------------// + for(i=0;i<iMax;i++,ul++) + { + if(ul->l!=0xffffffff && + ry<=ul->c[0] && + rx<=ul->c[2]) + { + rfree=*ul; + mx=ul->c[2]-2; + my=ul->c[0]-2; +
+ if(rx<mx && ry<my) + { + ul->c[3]+=rx; + ul->c[2]-=rx; + ul->c[0]=ry; + + for(ul=uls+1,j=0;j<iMax;j++,ul++) + if(ul->l==0xffffffff) break; + + if(j<CSUBSIZE-2) + { + if(j==iMax) uls->l=uls->l+1; + + ul->c[3]=rfree.c[3]; + ul->c[2]=rfree.c[2]; + ul->c[1]=rfree.c[1]+ry; + ul->c[0]=rfree.c[0]-ry; + } + } + else if(rx<mx) + { + ul->c[3]+=rx; + ul->c[2]-=rx; + } + else if(ry<my) + { + ul->c[1]+=ry; + ul->c[0]-=ry; + } + else + { + ul->l=0xffffffff; + } + ul=0; + goto TENDLOOP; + } + } + + //--------------------------------------------------// + + iC++; if(iC>=iSortTexCnt) iC=0; + } + + //----------------------------------------------------// + // check, if free space got + //----------------------------------------------------// + +TENDLOOP: + if(ul) return FALSE; + + rfree.c[3]+=cXAdj; + rfree.c[1]+=cYAdj; + + tsx->cTexID = iC; + tsx->posTX = rfree.c[3]; + tsx->posTY = rfree.c[1]; + + XTexS=rfree.c[3]; + YTexS=rfree.c[1]; + + return TRUE; +} + +/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+//
+// compress texture cache (to make place for new texture part, if needed)
+//
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+ +void CompressTextureSpace(void) +{ + textureSubCacheEntryS * tsx, * tsg, * tsb; + int i,j,k,m,n,iMax;EXLong * ul, r,opos; + short sOldDST=DrawSemiTrans,cx,cy; + int lOGTP=GlobalTexturePage; + uint32_t l,row; + uint32_t *lSRCPtr; + + opos.l=*((uint32_t *)&gl_ux[4]); + + // 1. mark all textures as free + for(i=0;i<iSortTexCnt;i++) + {ul=pxSsubtexLeft[i];ul->l=0;} + usLRUTexPage=0; + + // 2. compress + for(j=0;j<3;j++) + { + for(k=0;k<MAXTPAGES;k++) + { + tsg=pscSubtexStore[j][k]; + + if((!(dwTexPageComp&(1<<k)))) + { + (tsg+SOFFA)->pos.l=0; + (tsg+SOFFB)->pos.l=0; + (tsg+SOFFC)->pos.l=0; + (tsg+SOFFD)->pos.l=0; + continue; + } + + for(m=0;m<4;m++,tsg+=SOFFB) + { + iMax=tsg->pos.l; + + tsx=tsg+1; + for(i=0;i<iMax;i++,tsx++) + { + if(tsx->ClutID) + { + r.l=tsx->pos.l; + for(n=i+1,tsb=tsx+1;n<iMax;n++,tsb++) + { + if(tsx->ClutID==tsb->ClutID) + { + r.c[3]=min(r.c[3],tsb->pos.c[3]); + r.c[2]=max(r.c[2],tsb->pos.c[2]); + r.c[1]=min(r.c[1],tsb->pos.c[1]); + r.c[0]=max(r.c[0],tsb->pos.c[0]); + tsb->ClutID=0; + } + } +
+// if(r.l!=tsx->pos.l) + { + cx=((tsx->ClutID << 4) & 0x3F0); + cy=((tsx->ClutID >> 6) & CLUTYMASK); + + if(j!=2) + {
+ // palette check sum + l=0;lSRCPtr=(uint32_t *)(psxVuw+cx+(cy*1024)); + if(j==1) for(row=1;row<129;row++) l+=((*lSRCPtr++)-1)*row; + else for(row=1;row<9;row++) l+=((*lSRCPtr++)-1)<<row; + l=((l+HIWORD(l))&0x3fffL)<<16; + if(l!=(tsx->ClutID&(0x00003fff<<16))) + { + tsx->ClutID=0;continue; + } + } + + tsx->pos.l=r.l; + if(!GetCompressTexturePlace(tsx)) // no place?
+ { + for(i=0;i<3;i++) // -> clean up everything
+ for(j=0;j<MAXTPAGES;j++) + { + tsb=pscSubtexStore[i][j]; + (tsb+SOFFA)->pos.l=0; + (tsb+SOFFB)->pos.l=0; + (tsb+SOFFC)->pos.l=0; + (tsb+SOFFD)->pos.l=0; + } + for(i=0;i<iSortTexCnt;i++) + {ul=pxSsubtexLeft[i];ul->l=0;} + usLRUTexPage=0; + DrawSemiTrans=sOldDST; + GlobalTexturePage=lOGTP; + *((uint32_t *)&gl_ux[4])=opos.l; + dwTexPageComp=0; + + return; + } + + if(tsx->ClutID&(1<<30)) DrawSemiTrans=1; + else DrawSemiTrans=0; + *((uint32_t *)&gl_ux[4])=r.l; + + gTexName=uiStexturePage[tsx->cTexID]; + LoadSubTexFn(k,j,cx,cy); + uiStexturePage[tsx->cTexID]=gTexName; + tsx->Opaque=ubOpaqueDraw; + } + } + } + + if(iMax) + { + tsx=tsg+iMax; + while(!tsx->ClutID && iMax) {tsx--;iMax--;} + tsg->pos.l=iMax; + } + + } + } + } + + if(dwTexPageComp==0xffffffff) dwTexPageComp=0; + + *((uint32_t *)&gl_ux[4])=opos.l; + GlobalTexturePage=lOGTP; + DrawSemiTrans=sOldDST; +} + +/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+//
+// main entry for searching/creating textures, called from prim.c
+//
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////
+ +GLuint SelectSubTextureS(int TextureMode, uint32_t GivenClutId) +{ + unsigned char * OPtr;unsigned short iCache;short cx,cy; +
+ // sort sow/tow infos for fast access
+ + unsigned char ma1,ma2,mi1,mi2; + if(gl_ux[0]>gl_ux[1]) {mi1=gl_ux[1];ma1=gl_ux[0];} + else {mi1=gl_ux[0];ma1=gl_ux[1];} + if(gl_ux[2]>gl_ux[3]) {mi2=gl_ux[3];ma2=gl_ux[2];} + else {mi2=gl_ux[2];ma2=gl_ux[3];} + if(mi1>mi2) gl_ux[7]=mi2; + else gl_ux[7]=mi1; + if(ma1>ma2) gl_ux[6]=ma1; + else gl_ux[6]=ma2; + + if(gl_vy[0]>gl_vy[1]) {mi1=gl_vy[1];ma1=gl_vy[0];} + else {mi1=gl_vy[0];ma1=gl_vy[1];} + if(gl_vy[2]>gl_vy[3]) {mi2=gl_vy[3];ma2=gl_vy[2];} + else {mi2=gl_vy[2];ma2=gl_vy[3];} + if(mi1>mi2) gl_ux[5]=mi2; + else gl_ux[5]=mi1; + if(ma1>ma2) gl_ux[4]=ma1; + else gl_ux[4]=ma2; +
+ // get clut infos in one 32 bit val
+ + if(TextureMode==2) // no clut here
+ { + GivenClutId=CLUTUSED|(DrawSemiTrans<<30);cx=cy=0; + + if(iFrameTexType && Fake15BitTexture()) + return (GLuint)gTexName; + } + else + { + cx=((GivenClutId << 4) & 0x3F0); // but here + cy=((GivenClutId >> 6) & CLUTYMASK); + GivenClutId=(GivenClutId&CLUTMASK)|(DrawSemiTrans<<30)|CLUTUSED; +
+ // palette check sum.. removed MMX asm, this easy func works as well + { + uint32_t l=0,row; + + uint32_t *lSRCPtr = (uint32_t *)(psxVuw+cx+(cy*1024)); + if(TextureMode==1) for(row=1;row<129;row++) l+=((*lSRCPtr++)-1)*row; + else for(row=1;row<9;row++) l+=((*lSRCPtr++)-1)<<row; + l=(l+HIWORD(l))&0x3fffL; + GivenClutId|=(l<<16); + } + + } +
+ // search cache + iCache=0; + OPtr=CheckTextureInSubSCache(TextureMode,GivenClutId,&iCache);
+
+ // cache full? compress and try again + if(iCache==0xffff) + { + CompressTextureSpace(); + OPtr=CheckTextureInSubSCache(TextureMode,GivenClutId,&iCache); + }
+
+ // found? fine + usLRUTexPage=iCache; + if(!OPtr) return uiStexturePage[iCache];
+
+ // not found? upload texture and store infos in cache + gTexName=uiStexturePage[iCache]; + LoadSubTexFn(GlobalTexturePage,TextureMode,cx,cy); + uiStexturePage[iCache]=gTexName; + *OPtr=ubOpaqueDraw; + return (GLuint) gTexName; +} + +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// +///////////////////////////////////////////////////////////////////////////// |