Files
TeslaRel410/sda4/DPL3/VRENDER/TEXTURE.C
T
CydandClaude Fable 5 db7745fcd0 sda4: commit the Glaze developer hard-drive dump
Un-ignored: the dev drive is the ground truth the restoration and
emulator work constantly reference (DPL3/LIBDPL + VRENDER i860 renderer
source, BT/RP live+dev game trees, VGL_LABS pod boot, scene/audio
content). Kept in-repo for the pod-owner community.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-04 19:41:15 -05:00

285 lines
6.9 KiB
C++

/*{{{ 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 <stdio.h>
#include <stdlib.h>
#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 );
*/
}
/*}}} */