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>
389 lines
7.4 KiB
C++
389 lines
7.4 KiB
C++
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
int *big_map=NULL,
|
|
*temp_map=NULL;
|
|
|
|
int map_edge;
|
|
|
|
/*{{{ friggy stuff*/
|
|
static int clut[16] = { 4, 5, 6, 7,
|
|
8, 10, 12, 14,
|
|
16, 20, 24, 28,
|
|
32, 40, 48, 56 };
|
|
/*}}} */
|
|
|
|
/*{{{ static int funny_fourbits ( int eight )*/
|
|
static int funny_fourbits ( int eight )
|
|
{
|
|
int ix=0, c0, c1;
|
|
|
|
if ((eight & 15) > 7) {
|
|
eight+=15;
|
|
if (eight > 255) return 15;
|
|
}
|
|
return eight>>4;
|
|
|
|
eight>>=2;
|
|
|
|
if (eight > clut[15])
|
|
eight=clut[15];
|
|
|
|
while (clut[ix+1] < eight)
|
|
ix++;
|
|
|
|
c0=clut[ix];
|
|
c1=clut[ix+1];
|
|
|
|
c0-=eight;
|
|
c1-=eight;
|
|
|
|
if ((c0*c0) < (c1*c1))
|
|
return ix;
|
|
else
|
|
return ix+1;
|
|
}
|
|
/*}}} */
|
|
|
|
|
|
/*{{{ static void fourbit_mono ( int field, int *temp_map, int *big_map )*/
|
|
static void fourbit_mono ( int field, int *temp_map, int *big_map )
|
|
{
|
|
int i, mask, shift;
|
|
|
|
mask=~(0xf<<field);
|
|
|
|
shift=field;
|
|
|
|
printf ("fourbitmono, field 0x%x mask 0x%x shift 0x%x\n", field, mask, shift );
|
|
printf ("Munging %d texels\n", map_edge );
|
|
|
|
for (i=0; i<map_edge; i++ ) {
|
|
int v, w, r, g, b;
|
|
|
|
v=*temp_map;
|
|
|
|
b=0xff & (v>>8);
|
|
r=0xff & (v>>16);
|
|
g=0xff & (v>>24);
|
|
|
|
v=0xff & (((180*g)+(51*r)+(25*b)) >> 8);
|
|
v=funny_fourbits(v);
|
|
w=*big_map;
|
|
|
|
*big_map=(w&mask)|(v<<shift);
|
|
temp_map++;
|
|
big_map++;
|
|
|
|
}
|
|
}
|
|
/*}}} */
|
|
/*{{{ static void eightbit_mono ( int field, int *temp_map, int *big_map )*/
|
|
static void eightbit_mono ( int field, int *temp_map, int *big_map )
|
|
{
|
|
int i, mask, shift;
|
|
|
|
mask=~(0xff<<field);
|
|
|
|
shift=field;
|
|
|
|
printf ("eightbitmono, field 0x%x mask 0x%x shift 0x%x\n", field, mask, shift );
|
|
|
|
for (i=0; i<map_edge; i++ ) {
|
|
int v, w, r, g, b;
|
|
|
|
printf ("Munging %d texels\n", map_edge );
|
|
v=*temp_map;
|
|
|
|
b=0xff & (v>>8);
|
|
r=0xff & (v>>16);
|
|
g=0xff & (v>>24);
|
|
|
|
v=0xff & (((180*g)+(51*r)+(25*b)) >> 8);
|
|
w=*big_map;
|
|
|
|
*big_map=(w&mask)|(v<<shift);
|
|
|
|
temp_map++;
|
|
big_map++;
|
|
|
|
}
|
|
}
|
|
/*}}} */
|
|
/*{{{ static void bilinear ( int *temp_map, int *big_map )*/
|
|
static void bilinear ( int *temp_map, int *big_map )
|
|
{
|
|
printf ("Dont bother - just make the loader do it\n");
|
|
memcpy ( big_map, temp_map, 4*map_edge );
|
|
}
|
|
/*}}} */
|
|
/*{{{ static void eightbit_color ( int field, int *temp_map, int *big_map )*/
|
|
static void eightbit_color ( int field, int *temp_map, int *big_map )
|
|
{
|
|
int i, mask, shift;
|
|
|
|
mask=~(0xff<<field);
|
|
|
|
shift=field;
|
|
|
|
printf ("eightbitcolor, field 0x%x mask 0x%x shift 0x%x\n", field, mask, shift );
|
|
printf ("Munging %d texels\n", map_edge );
|
|
|
|
for (i=0; i<map_edge; i++ ) {
|
|
int v, w, r, g, b;
|
|
|
|
v=*temp_map;
|
|
|
|
b=0xff & (v>>8);
|
|
g=0xff & (v>>16);
|
|
r=0xff & (v>>24);
|
|
|
|
r = (r>>5) & 0x7;
|
|
g = (g>>5) & 0x7;
|
|
b = (b>>6) & 0x3;
|
|
|
|
v=r|(g<<3)|(b<<6);
|
|
|
|
w=*big_map;
|
|
|
|
*big_map=(w&mask)|(v<<shift);
|
|
temp_map++;
|
|
big_map++;
|
|
|
|
}
|
|
}
|
|
/*}}} */
|
|
/*{{{ static void twelvebit_color ( int field, int *temp_map, int *big_map )*/
|
|
static void twelvebit_color ( int field, int *temp_map, int *big_map )
|
|
{
|
|
|
|
int i, mask, shift;
|
|
|
|
mask=~(0xfff<<field);
|
|
|
|
shift=field;
|
|
|
|
printf ("twelvebitcolor, field 0x%x mask 0x%x shift 0x%x\n", field, mask, shift );
|
|
printf ("Munging %d texels\n", map_edge );
|
|
|
|
for (i=0; i<map_edge; i++ ) {
|
|
int v, w, r, g, b;
|
|
|
|
v=*temp_map;
|
|
|
|
b=0xff & (v>>8);
|
|
g=0xff & (v>>16);
|
|
r=0xff & (v>>24);
|
|
|
|
r=funny_fourbits ( r );
|
|
g=funny_fourbits ( g );
|
|
b=funny_fourbits ( b );
|
|
|
|
v=r|(g<<4)|(b<<8);
|
|
|
|
w=*big_map;
|
|
|
|
*big_map=(w&mask)|(v<<shift);
|
|
temp_map++;
|
|
big_map++;
|
|
|
|
}
|
|
}
|
|
/*}}} */
|
|
|
|
|
|
/*{{{ load_svt ( char *full_name )*/
|
|
int
|
|
load_svt ( char *full_name, int mode )
|
|
{
|
|
FILE *fp=fopen(full_name, "rb" );
|
|
long l_edge, texels;
|
|
int i, edge;
|
|
char *texelp;
|
|
|
|
if (fp==NULL) {
|
|
printf ("failed to open file %s\n", full_name );
|
|
return 0;
|
|
}
|
|
else {
|
|
fseek ( fp, 0L, SEEK_END );
|
|
l_edge=ftell(fp);
|
|
fseek ( fp, 0L, SEEK_SET );
|
|
|
|
edge=128;
|
|
|
|
if (l_edge == 16384L) edge=64;
|
|
else if (l_edge == 65536L) edge=128;
|
|
else if (l_edge == 262144L) edge=256;
|
|
else {
|
|
printf("Bad texture file size 0x%lx\n",l_edge);
|
|
fclose(fp);
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
texels=edge*edge;
|
|
|
|
if (temp_map == NULL) {
|
|
map_edge=texels;
|
|
temp_map=malloc(texels*4);
|
|
big_map =malloc(texels*4);
|
|
for (i=0; i<texels; i++ ) {
|
|
temp_map[i]=0x0;
|
|
big_map[i]=0x0;
|
|
}
|
|
}
|
|
else {
|
|
if (map_edge != texels) {
|
|
printf ("File size mismatch\n" );
|
|
exit (666);
|
|
}
|
|
}
|
|
|
|
texelp=(char *) temp_map;
|
|
|
|
while (texels) {
|
|
int i;
|
|
fread ( texelp, 1, 8192, fp );
|
|
|
|
texels-=2048;
|
|
texelp+=8192;
|
|
}
|
|
fclose(fp);
|
|
|
|
switch ( mode) {
|
|
case 0x3 :
|
|
fourbit_mono ( 8, temp_map, big_map );
|
|
break;
|
|
case 0x2 :
|
|
fourbit_mono ( 12, temp_map, big_map );
|
|
break;
|
|
case 0x1 :
|
|
fourbit_mono ( 16, temp_map, big_map );
|
|
break;
|
|
case 0x0 :
|
|
fourbit_mono ( 20, temp_map, big_map );
|
|
break;
|
|
|
|
case 0x4 :
|
|
eightbit_mono ( 8, temp_map, big_map );
|
|
break;
|
|
|
|
case 0x5 :
|
|
bilinear ( temp_map, big_map );
|
|
break;
|
|
|
|
case 0x6 :
|
|
eightbit_color ( 0, temp_map, big_map );
|
|
break;
|
|
|
|
case 0x7 :
|
|
twelvebit_color ( 0, temp_map, big_map );
|
|
break;
|
|
|
|
}
|
|
return 1;
|
|
}
|
|
/*}}} */
|
|
/*{{{ save_svt ( char *full_name )*/
|
|
int
|
|
save_svt ( char *full_name )
|
|
{
|
|
FILE *fp=fopen(full_name, "wb" );
|
|
long texels;
|
|
char *texelp;
|
|
|
|
if (fp==NULL) {
|
|
printf ("failed to open write file %s\n", full_name );
|
|
return 0;
|
|
}
|
|
if (big_map==NULL) {
|
|
printf ("No operations performed to generate file %s\n", full_name );
|
|
fclose(fp);
|
|
return 0;
|
|
}
|
|
else {
|
|
texelp=(char *) big_map;
|
|
texels=map_edge;
|
|
printf ("Saving %d texels\n", texels );
|
|
|
|
while (texels) {
|
|
int i;
|
|
|
|
for (i=0; i<2048; i++ ) {
|
|
char a, b, c, d;
|
|
int ix=i<<2;
|
|
|
|
a=texelp[ix+0];
|
|
b=texelp[ix+1];
|
|
c=texelp[ix+2];
|
|
d=texelp[ix+3];
|
|
|
|
texelp[ix+0]=d;
|
|
texelp[ix+1]=c;
|
|
texelp[ix+2]=b;
|
|
texelp[ix+3]=a;
|
|
}
|
|
fwrite ( texelp, 1, 8192, fp );
|
|
|
|
texels-=2048;
|
|
texelp+=8192;
|
|
}
|
|
fclose(fp);
|
|
}
|
|
return 1;
|
|
}
|
|
/*}}} */
|
|
|
|
|
|
|
|
/*
|
|
|
|
usage - glomm /mode 0x0 name /mode 0x1 name destname
|
|
|
|
*/
|
|
|
|
int main ( int argc, char **argv )
|
|
{
|
|
int n_files, i=0;
|
|
char *write_name=NULL;
|
|
|
|
for (i=1; i<argc; i++) {
|
|
char *s=argv[i];
|
|
int l=strlen(s);
|
|
|
|
if (strcmp(s,"/mode") == 0) {
|
|
int mode;
|
|
char *fname;
|
|
/* got a file thing, do it */
|
|
i++;
|
|
if (i == argc) {
|
|
printf ("malformed arguments\n" );
|
|
exit(666);
|
|
}
|
|
s=argv[i];
|
|
sscanf ( s, "%x", &mode );
|
|
i++;
|
|
if (i == argc) {
|
|
printf ("malformed arguments\n" );
|
|
exit(666);
|
|
}
|
|
fname=argv[i];
|
|
load_svt ( fname, mode );
|
|
}
|
|
else {
|
|
if (write_name) {
|
|
printf ("destination file name specified twice : %s : %s\n",
|
|
write_name, s );
|
|
exit(666);
|
|
}
|
|
else write_name=s;
|
|
}
|
|
}
|
|
if (write_name)
|
|
save_svt(write_name);
|
|
else
|
|
printf ("No destination name specified\n");
|
|
}
|