/*{{{ all about pxpl5 card*/ /* The texture manager associated with the pxpl5 card is all in here. This is not based on the TEXHSP card texture format, since pxpl5 is much easier to deal with. Textures are addressed as 64x64x1 word units, and 64x64 is the only alignment demanded by the card. A free list of 64x64 chunks is maintained, SORTED, in memory. To acquire a 128x128 we just look for a free 64x64, then check the next 3 items in the list. If all 4 are consecutive, we remove all 4 from the list and hand them back to the application. */ /*}}} */ #include #include #include "dpltypes.h" #include "culltypes.h" #include "vpxtypes.h" /* #define dbgtex 1 */ #define total_texture_space (512*512) /*{{{ structs, statics*/ static texcell *freeCell, *list_head; static int texturesInited=0; /*}}} */ /*{{{ static texcell *newCell( int size, int id )*/ static texcell *newCell( int size, int id ) { texcell *p; p=(texcell *) malloc (sizeof(texcell)); if (p!=NULL) { p->edge=size; p->id=id; p->hwareOffs=id; /* same number now */ p->next=NULL; } return p; } /*}}} */ /*{{{ static int cell_hwareSize ( int edge )*/ static int cell_hwareSize ( int edge ) { /* ************************************************** 0 = 64x64 1 = 128x128 2 = 256x256 *************************************************** */ if (edge == 64) return 0; if (edge == 128) return 1; if (edge == 256) return 2; return 1; } /*}}} */ /*{{{ void texInit ()*/ void texInit () { int i; texcell *a, *b, *c, *d; if (texturesInited) return; texturesInited=1; freeCell=NULL; /* pre-malloc texcells */ for (i=0; i<(total_texture_space>>12); i++ ) { a=newCell (64, 0); a->next=freeCell; freeCell=a; } list_head=a; for (i=0, a=freeCell; a; i++, a=a->next ) { a->id=i; a->hwareOffs=i; } } /*}}} */ /*{{{ texcell *allocateHSPtexture( int u_size, int v_size )*/ texcell *allocateHSPtexture( int u_size, int v_size ) { texcell *cell; int i, cells, u, v; #if dbgtex printf ("allocateHSPtex, u_size=%d v_size=%d\n", u_size, v_size ); #endif if (u_size != v_size) return NULL; else if ((u_size != 256) && (u_size != 128) && (u_size != 64)) return NULL; else { texcell *p=list_head, *prev=NULL; if (u_size==256) cells=16; else if (u_size==128) cells=4; else if (u_size== 64) cells=1; if (cells == 1) { /*{{{ pull just 1 off head of list*/ if (p) { texcell *cell=p; /*{{{ */ #if dbgtex printf ("allocateTexture requires just 1 cell\n" ); #endif /*}}} */ cell->hwareSize=cell_hwareSize(u_size); list_head=cell->next; cell->next=NULL; /*{{{ */ #if dbgtex printf ("allocateTexture returned id 0x%x hwareID 0x%x hwareSize %d\n", cell->id, cell->hwareOffs, cell->hwareSize ); #endif /*}}} */ return cell; } else { /*{{{ */ #if dbgtex printf ("allocateTexture, list empty\n" ); #endif /*}}} */ return NULL; } /*}}} */ } else { /*{{{ */ #if dbgtex printf ("allocateTexture needs %d consecutive cells\n", cells ); #endif /*}}} */ while (p) { texcell *cell=p->next, *firstcell=p; int looking = 1, found_cells=1, found_id=p->id+1; /*{{{ */ #if dbgtex printf ("allocateTexture search head now 0x%x\n", p ); #endif /*}}} */ while (looking) { /*{{{ check for consecutive numbers*/ if (cell == NULL) { /*{{{ */ #if dbgtex printf ("allocateTexture ran off end of list\n" ); #endif /*}}} */ return NULL; } if (cell->id == found_id) { /*{{{ doing fine, keep looking*/ found_cells++; found_id++; /*{{{ */ #if dbgtex printf ("allocateTexture found consecutive id, now found %d\n", found_cells ); #endif /*}}} */ if (found_cells == cells) { /*{{{ done it, patch list + return*/ texcell *nextcell=cell->next; cell->next=NULL; cell=firstcell; /* found it, remove cells from p upwards, chain prev */ if (prev==NULL) list_head=nextcell; else prev->next=nextcell; cell->hwareSize=cell_hwareSize(u_size); #if dbgtex while (cell) { printf ("allocateTexture returned id 0x%x hwareID 0x%x hwareSize %d\n", cell->id, cell->hwareOffs, cell->hwareSize ); cell=cell->next; } #endif return firstcell; /*}}} */ } cell=cell->next; /*}}} */ } else { printf ( "no contiguous, restarting search\n" ); looking=0; } /*}}} */ } prev=p; p=p->next; } } } return NULL; } /*}}} */ /*{{{ static int paletfix ( int r )*/ static int paletfix ( int r ) { if (r < 0) r=0; if (r > 255) r=255; return r>>4; } /*}}} */ /*{{{ int codeWordFromRamp ( cull_RAMP *ramp, int entry )*/ void codeWordFromRamp ( cull_RAMP *ramp, int entry ) { int ir0, ir1, ig0, ig1, ib0, ib1; float texscale=255.9f; if ((entry < 0) || (entry >= 4)) return; ir0=paletfix ((int) (ramp->color0[0]*texscale)); ig0=paletfix ((int) (ramp->color0[1]*texscale)); ib0=paletfix ((int) (ramp->color0[2]*texscale)); ir1=paletfix ((int) (ramp->color1[0]*texscale)); ig1=paletfix ((int) (ramp->color1[1]*texscale)); ib1=paletfix ((int) (ramp->color1[2]*texscale)); ramp->codeWord=entry | ((ir0 |(ir1<<4)| (ig0<<8) |(ig1<<12)| (ib0<<16)|(ib1<<20)) << 3); } /*}}} */ /*{{{ void setRampEntry ( cull_RAMP *ramp, int entry,*/ void setRampEntry ( cull_RAMP *ramp, int entry, float r0, float g0, float b0, float r1, float g1, float b1 ) { if ((entry < 0) || (entry >= 4)) return; ramp->color0[0]=r0; ramp->color0[1]=g0; ramp->color0[2]=b0; ramp->color1[0]=r1; ramp->color1[1]=g1; ramp->color1[2]=b1; codeWordFromRamp ( ramp, entry ); /* printf ("setRampEntry %f %f %f %f %f %f ramp %d\n", r0,g0,b0, r1,g1,b1, entry ); */ } /*}}} */