home *** CD-ROM | disk | FTP | other *** search
- #include "gpulocal.h"
-
- #define CACHE_MAX 16
-
- // User-defined types
- typedef struct {
- INT16 *Texture;
- UINT32 tpage,clutid;
- } TextureCache;
-
- static UINT16 rgbtbl[65536]; /* bgr -> rgb */
- static TextureCache tcache[CACHE_MAX];
- static int tcache_index = 0;
-
- void CacheInit(void)
- {
- int i,r,g,b;
-
- for(b=i=0;b<32;b++)
- for(g=0;g<32;g++)
- for(r=0;r<32;r++,i++)
- rgbtbl[i] = (r<<10) | (g<<5) | b;
-
- for(i=0;i<32768;i++)
- rgbtbl[i+32768]=rgbtbl[i] | 0x8000;
-
- tcache[0].Texture = (INT16 *)malloc(256*256*CACHE_MAX*sizeof(INT16));
- tcache[0].tpage = tcache[0].clutid = -1;
- for (i=1; i<CACHE_MAX; i++)
- {
- tcache[i].Texture = tcache[0].Texture + 256*256*i;
- tcache[i].tpage = tcache[i].clutid = -1;
- }
- }
-
- void CacheDeinit(void)
- {
- free(tcache[0].Texture);
- }
-
- static void pixel2texel(UINT16 *t, UINT16 *p,int n)
- {
- do {
- *t++=rgbtbl[*p++];
- } while(--n);
- }
-
- static void load_texture(INT16 *texture,int tpage,int clut)
- {
- UINT16 *ctbl,*tex;
- UINT16 *t,ctbl2[256];
- int x,y,mode;
-
- mode = (tpage>>7)&3;
-
- ctbl = vram+(clut&0x7fff)*16;
- tex = vram+(tpage&15)*64 + (tpage&16)*16*FRAME_W;
- t = texture;
-
- switch (mode) {
- case 0: // 4bit
- pixel2texel(ctbl2,ctbl,16);
- for(y=0;y<256;y++) {
- for(x=0;x<256;x+=4) {
- int c = *tex++;
- t[0] = ctbl2[c&15];
- t[1] = ctbl2[(c>>4)&15];
- t[2] = ctbl2[(c>>8)&15];
- t[3] = ctbl2[(c>>12)];
- t+=4;
- }
- tex += FRAME_W-256/4;
- }
- break;
-
- case 1: // 8bit
- pixel2texel(ctbl2,ctbl,256);
- for(y=0;y<256;y++) {
- for(x=0;x<256;x+=2) {
- int c = *tex++;
- t[0] = ctbl2[c&255];
- t[1] = ctbl2[c>>8];
- t+=2;
- }
- tex += FRAME_W-256/2;
- }
- break;
-
- case 2: /* 16bit */
- for(y=0;y<256;y++) {
- pixel2texel(t,tex,256);
- tex += FRAME_W;
- t += 256;
- }
- break;
- }
- }
-
- INT16 *get_texture(UINT32 tpage, UINT32 clut)
- {
- TextureCache *tc;
- int tchanged,cchanged,i;
-
- tpage&=(3<<7)|31;
- clut &= 0x7fff;
-
- tchanged = tpage_changed(tpage);
- cchanged = clut_changed(clut);
-
- if (tchanged | cchanged) {
- // parge cache
- for(i=0, tc = tcache;i<CACHE_MAX;i++, tc++) {
- if ((cchanged && tc->clutid==clut ) ||
- (tchanged && tc->tpage==tpage)) {
- tc->clutid = -1;
- tc->tpage = -1;
- }
- }
- } else {
- // search cache
- for(i=0, tc = tcache;i<CACHE_MAX;i++, tc++) {
- if (tc->tpage==tpage && tc->clutid==clut)
- return tc->Texture;
- }
- }
-
- #if 0
- printf("Texture Cache miss hit tpage=%04x clut=%04x idx->%d\n",
- (int)tpage,(int)clut,(int)tcache_index);
- #endif
-
- tc = &tcache[tcache_index];
- if (++tcache_index >= CACHE_MAX) tcache_index = 0;
-
- tc->clutid = clut;
- tc->tpage = tpage;
-
- load_texture(tc->Texture,tpage,clut);
-
- return tc->Texture;
- }
-