Files
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

1951 lines
48 KiB
C++

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <basictypes.h>
#include "dpltypes.h"
#include "dpl.h"
#include "dpl_load.h"
/*{{{ banner*/
/* **************************************************
Copyright DIVISION Limited (c) 1994
All rights reserved
File : bizread.c
Project : dpl interface
host / platform independent section
Author : PJA
Date : 26/07/94
Function: Implements the b2z file reader for the dpl
interface
READ THE V2Z FILE FORMAT FOR DETAILS
History : Rev 1.1, 26 / 07 / 1994
**************************** */
/*}}} */
/*{{{ some statics to aid the process*/
static int32 little_endian=1;
static char material_name[256];
static char texture_name[256];
static char texmap_name[256];
static char ramp_name[256];
static char object_name[256];
static char patch_name[256];
static FILE *b2z_file=NULL;
static float b2z_units=1.0f;
static float b2z_scale=1.0f;
static char buffer[(1024*8)*2];
static char *buff_p=NULL;
static int buffered_bytes=0;
static int buffer_read_start=0;
static int b2z_ok = 1;
static int blocks_read=0;
static int b2z_open = 0;
static dpl_TEXMAP *texmap=NULL;
static dpl_TEXTURE *texture=NULL;
static dpl_MATERIAL *material=NULL, *default_mtl=NULL,
*f_mtl =NULL, *b_mtl =NULL,
*of_mtl=NULL, *ob_mtl=NULL;
static dpl_OBJECT *object=NULL;
static dpl_LOD *lod=NULL;
static dpl_GEOGROUP *geogroup=NULL;
static dpl_GEOMETRY *geometry=NULL;
static dpl_VERTEX_LIST *vertex_list=NULL;
static dpl_CONNECTION_LIST *connection_list=NULL;
static int32 draw_mode=0;
dpl_superlist named_local_list;
/*}}} */
static int b2z_trace = 0;
#define trprintf if (b2z_trace) printf
/*{{{ static void new_block ()*/
static void new_block ()
{
if (b2z_open == 0)
b2z_ok=0;
if (b2z_ok == 0)
return;
/* copy whats left in buffer to beginning of buffer */
memcpy ( buffer, buff_p, buffered_bytes );
buff_p=buffer;
if (fread ( &buffer[buffered_bytes], 1, 8*1024, b2z_file ) == 0)
b2z_open=0;
blocks_read++;
buffered_bytes+=8*1024;
trprintf ("new block, now buffered_bytes=%d\n", buffered_bytes );
}
/*}}} */
/*{{{ buffer access with endian correction*/
/*{{{ static char get_char ()*/
static char get_char ()
{
char v;
if (buffered_bytes < 1) new_block();
v=*buff_p++;
buffered_bytes--;
return v;
}
/*}}} */
/*{{{ static char get_char ()*/
static char get_int8 ()
{
int8 v;
char *vp=(char *) &v;
if (buffered_bytes < 1) new_block();
*vp=*buff_p++;
buffered_bytes--;
return v;
}
/*}}} */
/*{{{ static int16 get_int16 ( )*/
static int16 get_int16 ( )
{
int16 v;
char *cv=(char *) &v;
if (buffered_bytes < 2) new_block();
if (little_endian) {
cv[0]=*buff_p++;
cv[1]=*buff_p++;
buffered_bytes-=2;
return v;
}
else {
cv[1]=*buff_p++;
cv[0]=*buff_p++;
buffered_bytes-=2;
return v;
}
}
/*}}} */
/*{{{ static char *get_int32 ( char *b, int32 *v )*/
static int32 get_int32 ()
{
int32 v;
char *cv=(char *) &v;
if (buffered_bytes < 4) new_block();
if (little_endian) {
cv[0]=*buff_p++;
cv[1]=*buff_p++;
cv[2]=*buff_p++;
cv[3]=*buff_p++;
buffered_bytes-=4;
return v;
}
else {
cv[3]=*buff_p++;
cv[2]=*buff_p++;
cv[1]=*buff_p++;
cv[0]=*buff_p++;
buffered_bytes-=4;
return v;
}
}
/*}}} */
/*{{{ static float32 get_float32 ()*/
static float32 get_float32 ()
{
float32 v;
char *cv=(char *) &v;
if (buffered_bytes < 4) new_block();
if (little_endian) {
cv[0]=*buff_p++;
cv[1]=*buff_p++;
cv[2]=*buff_p++;
cv[3]=*buff_p++;
buffered_bytes-=4;
return v;
}
else {
cv[3]=*buff_p++;
cv[2]=*buff_p++;
cv[1]=*buff_p++;
cv[0]=*buff_p++;
buffered_bytes-=4;
return v;
}
}
/*}}} */
/*{{{ static void get_struct32 ( void *data, int n_words )*/
static void get_struct32 ( void *data, int n_words )
{
char *cv=(char *) data;
while (n_words) {
n_words--;
if (buffered_bytes < 4) new_block();
if (little_endian) {
cv[0]=*buff_p++;
cv[1]=*buff_p++;
cv[2]=*buff_p++;
cv[3]=*buff_p++;
buffered_bytes-=4;
cv+=4;
}
else {
cv[3]=*buff_p++;
cv[2]=*buff_p++;
cv[1]=*buff_p++;
cv[0]=*buff_p++;
buffered_bytes-=4;
cv+=4;
}
}
}
/*}}} */
/*{{{ static void get_string ( char *str, int32 length )*/
static void get_string ( char *str, int32 length )
{
int8 l;
int i;
if (length == (-1)) {
l=get_int8();
length=(int32) l;
}
for (i=0; i<length;i++) {
*str++=get_char();
}
*str++=0x0;
}
/*}}} */
/*{{{ static void skip_bytes ( int32 length )*/
static void skip_bytes ( int32 length )
{
if (buffered_bytes < length)
new_block();
buff_p+=length;
buffered_bytes-=length;
}
/*}}} */
/*}}} */
/*{{{ static void b2z_block ( int32 *hdr, int32 *length )*/
static int32 b2z_block ( int32 *hdr, int32 *length )
{
int32 bytes=2, block_hdr, block_len;
block_hdr=0xffff & get_int16();
switch ((block_hdr >> 12) & 0xc) {
case 0x8 :
block_len=get_int32();
bytes+=4;
break;
case 0x4 :
block_len=0xffff & get_int16();
bytes+=2;
break;
case 0x0 :
block_len=0xff & get_int8();
bytes+=1;
break;
default :
printf ("Unrecognised block header, exiting\n" );
b2z_ok=0;
break;
}
trprintf ("block 0x%x of length %d bytes\n", block_hdr, block_len );
*hdr =block_hdr;
*length=block_len;
return bytes;
}
/*}}} */
/*{{{ static void skip_block ( int length )*/
static void skip_block ( int length )
{
trprintf ("skip_block %d\n", length );
if (b2z_ok == 0) return;
while (length > 2048) {
skip_bytes(2048);
length-=2048;
}
skip_bytes(length);
}
/*}}} */
/*{{{ static dpl_node *look_up ( dpl_type t, char *name, node_create_function *f )*/
static dpl_node *look_up ( dpl_type t, char *name, node_create_function f )
{
dpl_node *n;
trprintf ( "lookup %s\n", name );
if ((n = dpl_FindNamedTypedNode ( t, name )) == NULL) {
trprintf ( "had to create it\n" );
n = f();
dpl_NameNode ( n, name );
}
else trprintf ( "found it!\n" );
return n;
}
/*}}} */
/*{{{ defaultize ( dpl_MATERIAL *default_mtl )*/
static void
defaultize ( dpl_MATERIAL *default_mtl )
{
default_mtl->ambient[0]=1.0f;
default_mtl->ambient[1]=0.0f;
default_mtl->ambient[2]=0.0f;
default_mtl->diffuse[0]=1.0f;
default_mtl->diffuse[1]=0.0f;
default_mtl->diffuse[2]=0.0f;
default_mtl->specular[0]=0.0f;
default_mtl->specular[1]=0.0f;
default_mtl->specular[2]=0.0f;
default_mtl->specular[3]=1.0f;
default_mtl->emissive[0]=0.0f;
default_mtl->emissive[1]=0.0f;
default_mtl->emissive[2]=0.0f;
default_mtl->ramp =NULL;
default_mtl->texture=NULL;
dpl_Flush ( default_mtl );
}
/*}}} */
/*{{{ deal with multiple connection lists per pmesh*/
typedef int pre_connect[7];
static pre_connect *pre_connections=NULL;
static int pre_connects=0;
static pre_connect *grow_connections(int more)
{
int prev=pre_connects;
pre_connect *new=(pre_connect *) malloc((prev+more)*sizeof(pre_connect));
trprintf ("grow %d connections\n", more );
if (pre_connections) {
memcpy (new, pre_connections,
prev*sizeof(pre_connect));
free(pre_connections);
}
pre_connects+=more;
pre_connections=new;
trprintf ("grew to %d connections\n", pre_connects );
return &new[prev];
}
/*}}} */
/*{{{ static void read_vertices ( int32 n_vertices, int32 hdr )*/
static int normal_offset;
static int texture_2doffset;
static int texture_3doffset;
static int color_offset;
static int luminance_offset;
static void read_vertices ( int32 floats_per_vertex, int32 n_vertices, int32 hdr )
{
float this_vert[16];
int i, vix;
dpl_VERTEX *vert;
dpl_VERTEX_LIST *vl;
trprintf ("read_vertices %d\n", n_vertices );
vl = vertex_list;
vix = 0;
vert = &vl->vertices[0];
for (i=0; i<n_vertices; i++ ) {
get_struct32 ( this_vert, floats_per_vertex );
/*{{{ move data into vert*/
vert->normcol[3]=1.0f;
vert->texcoords[2]=1.0f;
vert->position[0]=/* b2z_scale*b2z_units* */ this_vert[0];
vert->position[1]=/* b2z_scale*b2z_units* */ this_vert[1];
vert->position[2]=/* b2z_scale*b2z_units* */ this_vert[2];
if (normal_offset != (-1)) {
/* move normal into place */
vert->normcol[0]=this_vert[normal_offset];
vert->normcol[1]=this_vert[normal_offset+1];
vert->normcol[2]=this_vert[normal_offset+2];
}
if (texture_2doffset != (-1)) {
/* move texture coords into place */
vert->texcoords[0]=this_vert[texture_2doffset];
vert->texcoords[1]=this_vert[texture_2doffset+1];
}
if (texture_3doffset != (-1)) {
/* move 3d texture coords into place */
vert->texcoords[0]=this_vert[texture_3doffset];
vert->texcoords[1]=this_vert[texture_3doffset+1];
vert->texcoords[2]=this_vert[texture_3doffset+2];
}
if (color_offset != (-1)) {
/* move cooked rgba values into place */
vert->normcol[0]=this_vert[color_offset];
vert->normcol[1]=this_vert[color_offset+1];
vert->normcol[2]=this_vert[color_offset+2];
vert->normcol[3]=this_vert[color_offset+3];
}
if (luminance_offset != (-1)) {
/* move cooked llla values into place */
vert->normcol[0]=this_vert[luminance_offset];
vert->normcol[1]=this_vert[luminance_offset];
vert->normcol[2]=this_vert[luminance_offset];
vert->normcol[3]=this_vert[luminance_offset+1];
}
/*}}} */
vix++;
if (vix==DPL_VERTICES_PER_BLOCK) {
vix=0;
vl=vl->next;
if (vl) vert=&vl->vertices[0];
}
else vert++;
}
}
/*}}} */
/*{{{ static int parse_vertices ( int32 length )*/
static int parse_vertices ( int32 length, dpl_geo_type geotype )
{
int32 bytes=0, hdr, len, n_connections, total_connections, v_per_c, i;
dpl_CONNECTION *conn;
dpl_CONNECTION_LIST *cl;
pre_connect *pc;
int cix=0;
int pmesh_vert=0, pmesh_conn=0;
while (b2z_ok && (bytes < length)) {
int32 f_per_vertex, n_floats, n_vertices, verts_per_poly;
normal_offset = -1;
texture_2doffset = -1;
texture_3doffset = -1;
color_offset = -1;
luminance_offset = -1;
bytes+=b2z_block(&hdr, &len );
if (b2z_ok == 0) return 0;
bytes+=len;
n_floats=len>>2;
switch ( hdr ) {
/*{{{ pmesh triangle connectivity*/
case 0x0047 :
case 0x4047 :
case 0x8047 :
trprintf ( "PMESH TRIANGLE CONNECTIVITY len=%d\n", len );
n_connections=len/12;
pc=grow_connections(n_connections);
for (i=0; i<n_connections; i++ ) {
int v0, v1, v2;
v0=get_int32();
v1=get_int32();
v2=get_int32();
(*pc)[0]=3;
(*pc)[1]=v0;
(*pc)[2]=v1;
(*pc)[3]=v2;
pc++;
}
pmesh_conn=1;
break;
/*}}} */
/*{{{ pmesh polygon connectivity*/
case 0x004d :
case 0x404d :
case 0x804d :
trprintf ( "PMESH POLYGON CONNECTIVITY len=%d\n", len );
verts_per_poly=get_int8();
n_connections=(len-1)/(verts_per_poly * 4);
pc=grow_connections(n_connections);
for (i=0; i<n_connections; i++ ) {
int32 j, v;
trprintf ( "PMESH copy poly %d of %d\n", i, n_connections );
(*pc)[0]=verts_per_poly;
for (j=0; j<verts_per_poly; j++) {
trprintf ( "PMESH copy vertex index %d of %d\n", j,
verts_per_poly );
v=get_int32();
(*pc)[j+1]=v;
}
pc++;
}
pmesh_conn=1;
break;
/*}}} */
/*{{{ flat vertex*/
case 0x0080 :
case 0x4080 :
case 0x8080 :
trprintf ( "FLAT VERTEX\n" );
f_per_vertex=3;
n_vertices=n_floats/f_per_vertex;
geometry=dpl_NewGeometry();
dpl_SetGeometryGeotype ( geometry, geotype );
dpl_AddGeometryToGeogroup ( geogroup, geometry );
vertex_list = dpl_NewVertices ( n_vertices );
read_vertices ( f_per_vertex,n_vertices, hdr );
pmesh_vert=1;
break;
/*}}} */
/*{{{ vertex with normals*/
case 0x0081 :
case 0x4081 :
case 0x8081 :
trprintf ( "NROMAL VERTEX\n" );
f_per_vertex=6;
n_vertices=n_floats/f_per_vertex;
normal_offset = 3;
geometry=dpl_NewGeometry();
dpl_SetGeometryGeotype ( geometry, geotype );
dpl_AddGeometryToGeogroup ( geogroup, geometry );
vertex_list = dpl_NewVertices ( n_vertices );
read_vertices ( f_per_vertex,n_vertices, hdr );
pmesh_vert=1;
break;
/*}}} */
/*{{{ rgba vertex*/
case 0x0082 :
case 0x8082 :
case 0x4082 :
trprintf ( "COOKED VERTEX\n" );
f_per_vertex=7;
n_vertices=n_floats/f_per_vertex;
color_offset = 3;
geometry=dpl_NewGeometry();
dpl_SetGeometryGeotype ( geometry, geotype );
dpl_AddGeometryToGeogroup ( geogroup, geometry );
vertex_list = dpl_NewVertices ( n_vertices );
read_vertices ( f_per_vertex,n_vertices, hdr );
pmesh_vert=1;
break;
/*}}} */
/*{{{ rgba + normals vertex*/
case 0x0083 :
case 0x8083 :
case 0x4083 :
trprintf ( "NORMAL_COOK VERTEX\n" );
f_per_vertex=10;
n_vertices=n_floats/f_per_vertex;
color_offset = 6;
geometry=dpl_NewGeometry();
dpl_SetGeometryGeotype ( geometry, geotype );
dpl_AddGeometryToGeogroup ( geogroup, geometry );
vertex_list = dpl_NewVertices ( n_vertices );
read_vertices ( f_per_vertex,n_vertices, hdr );
pmesh_vert=1;
break;
/*}}} */
/*{{{ la vertex*/
case 0x0084 :
case 0x8084 :
case 0x4084 :
trprintf ( "LUMINANCE VERTEX\n" );
f_per_vertex=5;
n_vertices=n_floats/f_per_vertex;
luminance_offset = 3;
geometry=dpl_NewGeometry();
dpl_SetGeometryGeotype ( geometry, geotype );
dpl_AddGeometryToGeogroup ( geogroup, geometry );
vertex_list = dpl_NewVertices ( n_vertices );
read_vertices ( f_per_vertex,n_vertices, hdr );
pmesh_vert=1;
break;
/*}}} */
/*{{{ normal la vertex*/
case 0x0085 :
case 0x8085 :
case 0x4085 :
trprintf ( "NORMAL_LUMINANCE VERTEX\n" );
f_per_vertex=8;
n_vertices=n_floats/f_per_vertex;
luminance_offset = 6;
geometry=dpl_NewGeometry();
dpl_SetGeometryGeotype ( geometry, geotype );
dpl_AddGeometryToGeogroup ( geogroup, geometry );
vertex_list = dpl_NewVertices ( n_vertices );
read_vertices ( f_per_vertex,n_vertices, hdr );
pmesh_vert=1;
break;
/*}}} */
/*{{{ 2d texture vertex*/
case 0x0088 :
case 0x8088 :
case 0x4088 :
trprintf ( "2d TEX VERTEX\n" );
f_per_vertex=5;
n_vertices=n_floats/f_per_vertex;
texture_2doffset = 3;
geometry=dpl_NewGeometry();
dpl_SetGeometryGeotype ( geometry, geotype );
dpl_AddGeometryToGeogroup ( geogroup, geometry );
vertex_list = dpl_NewVertices ( n_vertices );
read_vertices ( f_per_vertex,n_vertices, hdr );
pmesh_vert=1;
break;
/*}}} */
/*{{{ 2d texture normal vertex*/
case 0x0089 :
case 0x8089 :
case 0x4089 :
trprintf ( "2d TEX NORMAL VERTEX\n" );
f_per_vertex=8;
n_vertices=n_floats/f_per_vertex;
normal_offset = 3;
texture_2doffset = 6;
geometry=dpl_NewGeometry();
dpl_SetGeometryGeotype ( geometry, geotype );
dpl_AddGeometryToGeogroup ( geogroup, geometry );
vertex_list = dpl_NewVertices ( n_vertices );
read_vertices ( f_per_vertex,n_vertices, hdr );
pmesh_vert=1;
break;
/*}}} */
/*{{{ 2d texture cook*/
case 0x008a :
case 0x808a :
case 0x408a :
trprintf ( "2d TEX COOK VERTEX\n" );
f_per_vertex=9;
n_vertices=n_floats/f_per_vertex;
color_offset = 3;
texture_2doffset = 7;
geometry=dpl_NewGeometry();
dpl_SetGeometryGeotype ( geometry, geotype );
dpl_AddGeometryToGeogroup ( geogroup, geometry );
vertex_list = dpl_NewVertices ( n_vertices );
read_vertices ( f_per_vertex,n_vertices, hdr );
pmesh_vert=1;
break;
/*}}} */
/*{{{ 2d texture la*/
case 0x008c :
case 0x808c :
case 0x408c :
trprintf ( "2d TEX LUMINACE VERTEX\n" );
f_per_vertex=7;
n_vertices=n_floats/f_per_vertex;
texture_2doffset = 5;
luminance_offset = 3;
geometry=dpl_NewGeometry();
dpl_SetGeometryGeotype ( geometry, geotype );
dpl_AddGeometryToGeogroup ( geogroup, geometry );
vertex_list = dpl_NewVertices ( n_vertices );
read_vertices ( f_per_vertex,n_vertices, hdr );
pmesh_vert=1;
break;
/*}}} */
/*{{{ 3d texture*/
case 0x0090 :
case 0x8090 :
case 0x4090 :
trprintf ( "3d TEX VERTEX\n" );
f_per_vertex=6;
n_vertices=n_floats/f_per_vertex;
texture_3doffset = 3;
geometry=dpl_NewGeometry();
dpl_SetGeometryGeotype ( geometry, geotype );
dpl_AddGeometryToGeogroup ( geogroup, geometry );
vertex_list = dpl_NewVertices ( n_vertices );
read_vertices ( f_per_vertex,n_vertices, hdr );
pmesh_vert=1;
break;
/*}}} */
/*{{{ 3d texture normal*/
case 0x0091 :
case 0x8091 :
case 0x4091 :
trprintf ( "3d TEX NORMAL VERTEX\n" );
f_per_vertex=9;
n_vertices=n_floats/f_per_vertex;
normal_offset = 3;
texture_3doffset = 6;
geometry=dpl_NewGeometry();
dpl_SetGeometryGeotype ( geometry, geotype );
dpl_AddGeometryToGeogroup ( geogroup, geometry );
vertex_list = dpl_NewVertices ( n_vertices );
read_vertices ( f_per_vertex,n_vertices, hdr );
pmesh_vert=1;
break;
/*}}} */
/*{{{ 3d texture cook*/
case 0x0092 :
case 0x8092 :
case 0x4092 :
trprintf ( "3d TEX COOK VERTEX\n" );
f_per_vertex=10;
n_vertices=n_floats/f_per_vertex;
color_offset = 3;
texture_3doffset = 7;
geometry=dpl_NewGeometry();
dpl_SetGeometryGeotype ( geometry, geotype );
dpl_AddGeometryToGeogroup ( geogroup, geometry );
vertex_list = dpl_NewVertices ( n_vertices );
read_vertices ( f_per_vertex,n_vertices, hdr );
pmesh_vert=1;
break;
/*}}} */
/*{{{ 3d texture la*/
case 0x0094 :
case 0x8094 :
case 0x4094 :
trprintf ( "3d TEX LUMINACE VERTEX\n" );
f_per_vertex=8;
n_vertices=n_floats/f_per_vertex;
luminance_offset = 3;
texture_3doffset = 5;
geometry=dpl_NewGeometry();
dpl_SetGeometryGeotype ( geometry, geotype );
dpl_AddGeometryToGeogroup ( geogroup, geometry );
vertex_list = dpl_NewVertices ( n_vertices );
read_vertices ( f_per_vertex,n_vertices, hdr );
pmesh_vert=1;
break;
/*}}} */
default :
printf ( "Unexpected vertex type 0x%x in vertex list\n", hdr );
skip_block(len);
break;
}
}
if (geotype == dpl_g_type_pmesh) {
if (pmesh_vert && pmesh_conn) {
int i, j;
pmesh_vert=0;
pmesh_conn=0;
trprintf ( "PMESH - do the real thing with %d connexions\n",
pre_connects );
connection_list=dpl_NewConnections ( pre_connects );
cl=connection_list;
conn=&cl->connections[0];
cix=0;
pc=pre_connections;
for (i=0; i<pre_connects; i++ ) {
conn->n_verts=(*pc)[0];
trprintf ( "n_verts=%d\n", conn->n_verts );
for (j=0; j<(*pc)[0]; j++ ) {
trprintf ( "vertex %d %d\n", j, (*pc)[j+1] );
conn->indices[j]=(*pc)[j+1];
}
pc++;
cix++;
if (cix==DPL_CONNECTIONS_PER_BLOCK) {
cix=0;
cl=cl->next;
if (cl) conn=&cl->connections[0];
}
else conn++;
}
free(pre_connections);
pre_connections=NULL;
pre_connects=0;
trprintf ("SETGEOMVERTICES WITH VERTEX AND CONNECTIONS\n" );
dpl_SetGeometryVertices ( geometry, vertex_list, connection_list );
trprintf ("did the setgeom thing\n" );
}
}
else {
if (pmesh_vert) {
pmesh_vert=0;
dpl_SetGeometryVertices ( geometry, vertex_list, NULL );
}
}
/* } */
return 1;
}
/*}}} */
/*{{{ static int parse_patch ( int32 length )*/
static int parse_patch ( int32 length )
{
int32 bytes=0, hdr, len;
char c, *name_p=patch_name;
int8 type;
f_mtl=of_mtl;
b_mtl=ob_mtl;
if (lod == NULL) {
lod=dpl_NewLod();
dpl_AddLodToObject ( object, lod );
}
geogroup=dpl_NewGeogroup();
dpl_AddGeogroupToLod ( lod, geogroup );
geogroup->draw_mode=draw_mode; /* inherit from object */
while (b2z_ok && (bytes < length)) {
bytes+=b2z_block(&hdr, &len );
if (b2z_ok == 0) return 0;
bytes+=len;
switch ( hdr ) {
/*{{{ name*/
case 0x2008 :
trprintf ( "PATCH NAME\n" );
while (c=get_char())
*name_p++=c;
*name_p++=0x0;
trprintf ("patch %s\n", patch_name );
break;
/*}}} */
/*{{{ f_mtl*/
case 0x2030 :
trprintf ( "FRONT MATERIAL\n" );
type=get_int8();
if (type == 0)
f_mtl=NULL;
else if (type == 2)
f_mtl=default_mtl;
else if (type==1) {
name_p=material_name;
while (c=get_char())
*name_p++=c;
*name_p++=0x0;
trprintf ("material %s\n", material_name );
f_mtl = (dpl_MATERIAL *) look_up ( dpl_type_material,
material_name,
(node_create_function) dpl_NewMaterial );
name_p=patch_name;
}
break;
/*}}} */
/*{{{ b_mtl*/
case 0x2031 :
trprintf ( "BACK MATERIAL\n" );
type=get_int8();
if (type == 0)
b_mtl=NULL;
else if (type == 2)
b_mtl=default_mtl;
else if (type==1) {
name_p=material_name;
while (c=get_char())
*name_p++=c;
*name_p++=0x0;
trprintf ("material %s\n", material_name );
b_mtl = (dpl_MATERIAL *) look_up ( dpl_type_material,
material_name,
(node_create_function) dpl_NewMaterial );
name_p=patch_name;
}
else if (type == 3)
b_mtl=f_mtl;
break;
/*}}} */
/*{{{ plane*/
case 0x2032 :
trprintf ( "PLANE\n" );
skip_block(len);
break;
/*}}} */
/*{{{ draw_mode*/
case 0x2033 :
trprintf ( "DRAW MODE\n" );
skip_block(len);
break;
/*}}} */
/*{{{ decal*/
case 0x2034 :
trprintf ( "DECAL\n" );
skip_block(len);
break;
/*}}} */
/*{{{ facet*/
case 0x2035 :
trprintf ( "FACET\n" );
skip_block(len);
break;
/*}}} */
/*{{{ vertex format*/
case 0x2036 :
trprintf ( "VERTEX FORMAT\n" );
geogroup->draw_mode=(int32) get_int8();
trprintf ("vertex format 0x%x\n", geogroup->draw_mode );
break;
/*}}} */
/*{{{ voodoo*/
case 0x2037 :
trprintf ( "SPECIAL VOODOO\n" );
skip_block(len);
break;
/*}}} */
/*{{{ polygon*/
case 0x4043 :
case 0x8043 :
case 0x0043 :
trprintf ( "POLYGON\n" );
parse_vertices ( len, dpl_g_type_polystrip );
break;
/*}}} */
/*{{{ tristrip*/
case 0x4044 :
case 0x8044 :
case 0x0044 :
trprintf ( "TRISTRIP\n" );
parse_vertices ( len, dpl_g_type_tristrip );
break;
/*}}} */
/*{{{ polystrip*/
case 0x4045 :
case 0x8045 :
case 0x0045 :
trprintf ( "POLYSTRIP\n" );
parse_vertices ( len, dpl_g_type_polystrip );
break;
/*}}} */
/*{{{ pmesh*/
case 0x4046 :
case 0x8046 :
case 0x0046 :
trprintf ( "PMESH\n" );
parse_vertices ( len, dpl_g_type_pmesh );
break;
/*}}} */
/*{{{ sphere NOT IMPLEMENTED*/
case 0x4048 :
case 0x8048 :
case 0x0048 :
trprintf ( "SPHERE\n" );
skip_block(len);
break;
/*}}} */
/*{{{ line NOT IMPLEMENTED*/
case 0x404a :
case 0x804a :
case 0x004a :
trprintf ( "LINE\n" );
skip_block(len);
break;
/*}}} */
/*{{{ text NOT IMPLEMENTED*/
case 0x404b :
case 0x804b :
case 0x004b :
trprintf ( "TEXT\n" );
skip_block(len);
break;
/*}}} */
default :
printf ( "Unexpected header 0x%x in patch\n", hdr );
skip_block(len);
break;
}
}
geogroup->f_material=f_mtl;
geogroup->b_material=b_mtl;
/* and the Bound flushes the geogroup */
dpl_BoundGeogroup ( geogroup );
dpl_BoundLod ( lod );
return 1;
}
/*}}} */
/*{{{ static int parse_lod ( int32 length )*/
static int parse_lod ( int32 length )
{
lod=dpl_NewLod();
dpl_AddLodToObject ( object, lod );
skip_block(length);
return 1;
}
/*}}} */
/*{{{ static int parse_object ( int32 length )*/
static int parse_object ( int32 length )
{
int32 bytes=0, hdr, len;
int8 type;
char c, *name_p=object_name;
of_mtl=NULL;
ob_mtl=NULL;
if (object == NULL) object=dpl_NewObject();
*name_p=0x0;
while (b2z_ok && (bytes < length)) {
bytes+=b2z_block(&hdr, &len );
if (b2z_ok == 0) return 0;
switch ( hdr ) {
/*{{{ name*/
case 0x2008 :
trprintf ( "OBJECT NAME\n" );
while (c=get_char())
*name_p++=c;
*name_p++=0x0;
trprintf ("object %s\n", object_name );
break;
/*}}} */
/*{{{ f_mtl*/
case 0x2030 :
trprintf ( "FRONT MATERIAL\n" );
type=get_int8();
if (type == 0)
of_mtl=NULL;
else if (type == 2)
of_mtl=default_mtl;
else if (type==1) {
name_p=material_name;
while (c=get_char())
*name_p++=c;
*name_p++=0x0;
trprintf ("material %s\n", material_name );
of_mtl = (dpl_MATERIAL *) look_up ( dpl_type_material,
material_name,
(node_create_function) dpl_NewMaterial );
name_p=object_name;
}
break;
/*}}} */
/*{{{ b_mtl*/
case 0x2031 :
trprintf ( "BACK MATERIAL\n" );
type=get_int8();
if (type == 0)
ob_mtl=NULL;
else if (type == 2)
ob_mtl=default_mtl;
else if (type==1) {
name_p=material_name;
while (c=get_char())
*name_p++=c;
*name_p++=0x0;
trprintf ("material %s\n", material_name );
ob_mtl = (dpl_MATERIAL *) look_up ( dpl_type_material,
material_name,
(node_create_function) dpl_NewMaterial );
name_p=object_name;
}
else if (type == 3)
ob_mtl=of_mtl;
break;
/*}}} */
/*{{{ plane*/
case 0x2032 :
trprintf ( "PLANE\n" );
skip_block(len);
break;
/*}}} */
/*{{{ draw mode*/
case 0x2033 :
trprintf ( "DRAW MODE\n" );
skip_block(len);
break;
/*}}} */
/*{{{ decal*/
case 0x2034 :
trprintf ( "DECAL\n" );
skip_block(len);
break;
/*}}} */
/*{{{ facet*/
case 0x2035 :
trprintf ( "FACET\n" );
skip_block(len);
break;
/*}}} */
/*{{{ vertex format*/
case 0x2036 :
trprintf ( "VERTEX FORMAT\n" );
draw_mode=(int32) get_int8();
break;
/*}}} */
/*{{{ special*/
case 0x2037 :
trprintf ( "SPECIAL VOODOO\n" );
skip_block(len);
break;
/*}}} */
/*{{{ patch*/
case 0x4042 :
case 0x8042 :
case 0x0042 :
trprintf ( "PATCH\n" );
parse_patch(len);
break;
/*}}} */
/*{{{ lod*/
case 0x4041 :
case 0x8041 :
case 0x0041 :
trprintf ( "LOD\n" );
parse_lod(len);
break;
/*}}} */
/*{{{ comment*/
case 0x0000 :
case 0x4000 :
case 0x8000 :
case 0x0001 :
case 0x4001 :
case 0x8001 :
case 0x2000 :
case 0x6000 :
case 0xa000 :
trprintf ( "COMMENT\n" );
skip_block(len);
break;
/*}}} */
default :
printf ( "Unexpected header 0x%x in object, bytes=%d length=%d\n",
hdr, bytes, length );
skip_block(len);
break;
}
bytes+=len;
}
return 1;
}
/*}}} */
/*{{{ static int parse_texture ( int32 length )*/
static int parse_texture ( int32 length )
{
/*
always create a new texture, but try to chain it to an
existing texmap
*/
dpl_TEXTURE *real_tex;
int32 bilinear, bytes=0, hdr, len;
int8 scope=0, minify=0, magnify=0, wrap_u=0, wrap_v=0, alpha=0, mode;
char c, *full_name, *name_p=texture_name;
*name_p=0x0;
while (b2z_ok && (bytes < length)) {
bytes+=b2z_block(&hdr, &len );
if (b2z_ok == 0) return 0;
switch ( hdr ) {
/*{{{ name*/
case 0x2008 :
trprintf ( "TEXTURE NAME\n" );
name_p=texture_name;
while (c=get_char())
*name_p++=c;
*name_p++=0x0;
trprintf ("texture %s\n", texture_name );
break;
/*}}} */
/*{{{ scope*/
case 0x200a :
trprintf ( "SCOPE\n" );
scope=get_int8();
trprintf ( "SCOPE = 0x%x\n", scope );
break;
/*}}} */
/*{{{ file name*/
case 0x0011 :
case 0x4011 :
case 0x8011 :
trprintf ( "TEXTURE FILE NAME\n" );
name_p=texmap_name;
while (c=get_char())
*name_p++=c;
*name_p++=0x0;
trprintf ("map name %s\n", texmap_name );
break;
/*}}} */
/*{{{ minify*/
case 0x0012 :
trprintf ( "MINIFY\n" );
minify=get_int8();
trprintf ( "MODE = 0x%x\n", minify );
break;
/*}}} */
/*{{{ magnify*/
case 0x0013 :
trprintf ( "MAGNIFY\n" );
magnify=get_int8();
trprintf ( "MODE = 0x%x\n", magnify );
break;
/*}}} */
/*{{{ alpha*/
case 0x0014 :
trprintf ( "ALPHA\n" );
alpha=get_int8();
trprintf ( "MODE = 0x%x\n", alpha );
break;
/*}}} */
/*{{{ wrap u*/
case 0x0015 :
trprintf ( "WRAP_U\n" );
wrap_u=get_int8();
trprintf ( "MODE = 0x%x\n", wrap_u );
break;
/*}}} */
/*{{{ wrap v*/
case 0x0016 :
trprintf ( "WRAP_V\n" );
wrap_v=get_int8();
trprintf ( "MODE = 0x%x\n", wrap_v );
break;
/*}}} */
/*{{{ detail*/
case 0x0017 :
trprintf ( "DETAIL\n" );
mode=get_int8();
trprintf ( "MODE = 0x%x\n", mode );
skip_block(len-1);
break;
/*}}} */
default :
printf ( "Unexpected header 0x%x in texture, bytes=%d length=%d\n",
hdr, bytes, length );
skip_block(len);
break;
}
bytes+=len;
}
texmap = (dpl_TEXMAP *) dpl_FindNamedTypedNode ( dpl_type_texmap,
texmap_name );
if (texmap == NULL) {
/*{{{ load up the texture map*/
/* first try to load the texture */
if ((magnify == 1) || (magnify == 0))
bilinear=0;
else
bilinear=1;
texmap = dpl_NewTexMap ();
dpl_NameNode ( (dpl_node *) texmap, texmap_name );
texmap->bits_per_texel=32; /* sorry about this hack */
full_name=dpl_FindTextureFile ( texmap_name, NULL );
if (load_svt((dpl_node *) texmap, full_name )) {
int *map_texels=texmap->texels;
/* this is HORRIBLE - i will fix it later....... */
texmap->texels=NULL;
trprintf ("went load_svt, have u_size %d v_size %d\n",
texmap->u_size, texmap->v_size );
dpl_SetTexmapTexels ( texmap,
map_texels,
texmap->u_size,
texmap->v_size,
bilinear );
/* and the call to SetTexMapTexels has flushed the node */
}
/*}}} */
}
real_tex = (dpl_TEXTURE *) look_up ( dpl_type_texture,
texture_name,
(node_create_function) dpl_NewTexture );
real_tex->minify = minify;
real_tex->magnify = magnify;
real_tex->alpha = alpha;
real_tex->wrap_u = wrap_u;
real_tex->wrap_v = wrap_v;
real_tex->texmap = texmap;
dpl_Flush(real_tex);
return 1;
}
/*}}} */
/*{{{ static int parse_material ( int32 length )*/
static int parse_material ( int32 length )
{
dpl_MATERIAL local_mtl, *real_mtl;
dpl_TEXTURE *mtl_texture=NULL;
dpl_RAMP *mtl_ramp=NULL;
int32 bytes=0, hdr, len;
int8 scope, mode;
char c, *name_p=material_name;
float32 r, g, b, pse;
*name_p=0x0;
/*{{{ init local_material*/
local_mtl.ambient[0]=1.0f;
local_mtl.ambient[1]=1.0f;
local_mtl.ambient[2]=1.0f;
local_mtl.diffuse[0]=1.0f;
local_mtl.diffuse[1]=1.0f;
local_mtl.diffuse[2]=1.0f;
local_mtl.emissive[0]=1.0f;
local_mtl.emissive[1]=1.0f;
local_mtl.emissive[2]=1.0f;
local_mtl.specular[0]=0.0f;
local_mtl.specular[1]=0.0f;
local_mtl.specular[2]=0.0f;
local_mtl.specular[3]=0.0f;
local_mtl.opacity[0]=1.0f;
local_mtl.opacity[1]=1.0f;
local_mtl.opacity[2]=1.0f;
/*}}} */
while (b2z_ok && (bytes < length)) {
bytes+=b2z_block(&hdr, &len );
if (b2z_ok == 0) return 0;
switch ( hdr ) {
/*{{{ name*/
case 0x2008 :
trprintf ( "MATERIAL NAME\n" );
while (c=get_char())
*name_p++=c;
*name_p++=0x0;
trprintf ("material %s\n", material_name );
break;
/*}}} */
/*{{{ scope*/
case 0x200a :
trprintf ( "SCOPE\n" );
scope=get_int8();
trprintf ( "SCOPE = 0x%x\n", scope );
break;
/*}}} */
/*{{{ texture*/
case 0x0021 :
trprintf ( "TEXTURE TYPE NAME\n" );
mode=get_int8();
trprintf ( " MODE = 0x%x\n", mode );
if (mode == 0)
texture=NULL;
else if (mode == 1)
texture=NULL;
else if (mode == 2) {
name_p=texture_name;
while (c=get_char())
*name_p++=c;
*name_p++=0x0;
trprintf ("texture %s\n", texture_name );
mtl_texture = (dpl_TEXTURE *) look_up ( dpl_type_texture,
texture_name,
(node_create_function) dpl_NewTexture );
name_p=material_name;
}
break;
/*}}} */
/*{{{ environment*/
case 0x0022 :
trprintf ( "ENVIRONMENT\n" );
skip_block(len);
break;
/*}}} */
/*{{{ ambient*/
case 0x0023 :
trprintf ( "AMBIENT\n" );
local_mtl.ambient[0]=get_float32();
local_mtl.ambient[1]=get_float32();
local_mtl.ambient[2]=get_float32();
trprintf ( "is %f %f %f\n",
local_mtl.ambient[0],
local_mtl.ambient[1],
local_mtl.ambient[2] );
break;
/*}}} */
/*{{{ diffuse*/
case 0x0024 :
trprintf ( "DIFFUSE\n" );
local_mtl.diffuse[0]=get_float32();
local_mtl.diffuse[1]=get_float32();
local_mtl.diffuse[2]=get_float32();
trprintf ( "is %f %f %f\n",
local_mtl.diffuse[0],
local_mtl.diffuse[1],
local_mtl.diffuse[2] );
break;
/*}}} */
/*{{{ specular*/
case 0x0025 :
trprintf ( "SPECULAR\n" );
local_mtl.specular[0]=get_float32();
local_mtl.specular[1]=get_float32();
local_mtl.specular[2]=get_float32();
local_mtl.specular[3]=get_float32();
trprintf ( "is %f %f %f\n",
local_mtl.specular[0],
local_mtl.specular[1],
local_mtl.specular[2] );
break;
/*}}} */
/*{{{ emissive*/
case 0x0026 :
trprintf ( "EMISSIVE\n" );
local_mtl.emissive[0]=get_float32();
local_mtl.emissive[1]=get_float32();
local_mtl.emissive[2]=get_float32();
trprintf ( "is %f %f %f\n",
local_mtl.emissive[0],
local_mtl.emissive[1],
local_mtl.emissive[2] );
break;
/*}}} */
/*{{{ opacity*/
case 0x0027 :
trprintf ( "OPACITY\n" );
local_mtl.opacity[0]=get_float32();
local_mtl.opacity[1]=get_float32();
local_mtl.opacity[2]=get_float32();
break;
/*}}} */
/*{{{ ramp*/
case 0x0028 :
trprintf ( "RAMP\n" );
name_p=ramp_name;
while (c=get_char())
*name_p++=c;
*name_p++=0x0;
trprintf ("ramp %s\n", texture_name );
mtl_ramp = (dpl_RAMP *) look_up ( dpl_type_ramp,
ramp_name,
(node_create_function) dpl_NewRamp );
name_p=material_name;
break;
/*}}} */
default :
printf ( "Unexpected header 0x%x in material, bytes=%d length=%d\n",
hdr, bytes, length );
skip_block(len);
break;
}
bytes+=len;
}
real_mtl = (dpl_MATERIAL *) look_up ( dpl_type_material,
material_name,
(node_create_function) dpl_NewMaterial );
memcpy ( real_mtl->emissive, local_mtl.emissive, 3*sizeof(float32));
memcpy ( real_mtl->ambient, local_mtl.ambient, 3*sizeof(float32));
memcpy ( real_mtl->diffuse, local_mtl.diffuse, 3*sizeof(float32));
memcpy ( real_mtl->opacity, local_mtl.opacity, 3*sizeof(float32));
memcpy ( real_mtl->specular, local_mtl.specular, 4*sizeof(float32));
real_mtl->texture=mtl_texture;
real_mtl->ramp=mtl_ramp;
dpl_Flush ( real_mtl );
return 1;
}
/*}}} */
/*{{{ static int parse_ramp ( int32 length )*/
static int parse_ramp ( int32 length )
{
dpl_RAMP local_ramp, *real_ramp;
dpl_node *node;
int32 bytes=0, hdr, len;
int8 scope, mode;
float32 r, g, b;
char c, *name_p=material_name;
*name_p=0x0;
while (b2z_ok && (bytes < length)) {
bytes+=b2z_block(&hdr, &len );
if (b2z_ok == 0) return 0;
switch ( hdr ) {
/*{{{ name*/
case 0x2008 :
trprintf ( "RAMP NAME\n" );
while (c=get_char())
*name_p++=c;
*name_p++=0x0;
trprintf ("ramp %s\n", ramp_name );
break;
/*}}} */
/*{{{ scope*/
case 0x200a :
trprintf ( "SCOPE\n" );
scope=get_int8();
trprintf ( "SCOPE = 0x%x\n", scope );
break;
/*}}} */
/*{{{ ramp data*/
case 0x0031 :
trprintf ( "RAMP DATA\n" );
local_ramp.color0[0]=get_float32();
local_ramp.color0[1]=get_float32();
local_ramp.color0[2]=get_float32();
local_ramp.color1[0]=get_float32();
local_ramp.color1[1]=get_float32();
local_ramp.color1[2]=get_float32();
break;
/*}}} */
default :
printf ( "Unexpected header 0x%x in ramp, bytes=%d length=%d\n",
hdr, bytes, length );
skip_block(len);
break;
}
bytes+=len;
}
real_ramp = (dpl_RAMP *) look_up ( dpl_type_ramp,
ramp_name,
(node_create_function) dpl_NewRamp );
memcpy ( real_ramp->color0, local_ramp.color0, 3*sizeof(float));
memcpy ( real_ramp->color1, local_ramp.color1, 3*sizeof(float));
dpl_Flush ( real_ramp );
return 1;
}
/*}}} */
/*{{{ static int parse_header ( int32 length )*/
static int parse_header ( int32 length )
{
int32 bytes=0, hdr, len;
int8 precision, unit;
while (b2z_ok && (bytes < length)) {
bytes+=b2z_block(&hdr, &len );
if (b2z_ok == 0) return 0;
bytes+=len;
switch ( hdr ) {
/*{{{ version*/
case 0x2002 :
trprintf ( "VERSION\n" );
skip_block(len);
break;
/*}}} */
/*{{{ date*/
case 0x2003 :
trprintf ( "DATE\n" );
skip_block(len);
break;
/*}}} */
/*{{{ time*/
case 0x2004 :
trprintf ( "TIME\n" );
skip_block(len);
break;
/*}}} */
/*{{{ scale*/
case 0x2005 :
trprintf ( "SCALE\n" );
b2z_scale=get_float32();
break;
/*}}} */
/*{{{ precision*/
case 0x2006 :
trprintf ( "PRECISION\n" );
precision=get_int8();
if (precision != 0) {
printf ("Error, cannot process double-precision files\n" );
b2z_ok=0;
return 0;
}
break;
/*}}} */
/*{{{ filetype*/
case 0x2007 :
trprintf ( "FILETYPE\n" );
skip_block(len);
break;
/*}}} */
/*{{{ unit*/
case 0x2009 :
trprintf ( "UNIT\n" );
unit=get_int8();
if (unit == 0x0)
b2z_units=1.0f;
else if (unit == 0x1)
b2z_units=1.0f / 25.4f;
else {
printf ("Error, unrecognized units 0x%x\n", unit );
b2z_ok=0;
return 0;
}
break;
/*}}} */
default :
printf ("Unrecognized block 0x%x in header\n", hdr );
skip_block(len);
break;
}
}
trprintf ("Exiting parse_header\n" );
return 1;
}
/*}}} */
/*{{{ static void forget_local_names ()*/
static void forget_local_names ()
{
/* should walk down named_local_list and forget all the names */
return;
}
/*}}} */
/*{{{ dpl_OBJECT *b2zread ( char *f )*/
dpl_OBJECT *
b2zread ( dpl_OBJECT *param_object, char *f )
{
FILE *fp=fopen(f, "rb" );
char biz_id[16];
/* determine endian-ness */
little_endian=0;
*((char *) &little_endian)=0x1;
little_endian&=0x1;
if (fp==NULL) {
printf ("Failed to open file %s\n", f );
return NULL;
}
else {
/*{{{ do some inits*/
b2z_open = 1;
b2z_file = fp;
buff_p = NULL;
buffered_bytes = 0;
buffer_read_start= 0;
little_endian = 1;
b2z_ok = 1;
blocks_read = 0;
texmap = NULL;
texture = NULL;
material = NULL;
object = param_object;
lod = NULL;
geogroup = NULL;
geometry = NULL;
vertex_list = NULL;
connection_list = NULL;
named_local_list.tail=NULL;
named_local_list.head=NULL;
named_local_list.last_accessed=NULL;
/*}}} */
get_string ( biz_id, 8 );
if (strcmp ( biz_id, "DIV-BIZ2") != 0) {
printf ( "Not a valid b2z file\n" );
fclose(fp);
return NULL;
}
else {
int32 block_hdr;
int32 length;
/*{{{ create a default material*/
default_mtl = (dpl_MATERIAL *) look_up ( dpl_type_material,
"DEFAULT",
(node_create_function) dpl_NewMaterial );
defaultize ( default_mtl );
/*}}} */
while (b2z_ok) {
b2z_block ( &block_hdr, &length );
switch (block_hdr & 0xfff) {
/*{{{ trailer*/
case 0x005 :
trprintf ("Trailer, exiting\n" );
fclose(fp);
if (b2z_ok) {
forget_local_names();
return object;
}
else {
forget_local_names();
return NULL;
}
break;
/*}}} */
/*{{{ header*/
case 0x003 :
trprintf ("Header\n" );
parse_header ( length );
break;
/*}}} */
/*{{{ comment*/
case 0x004 :
trprintf ("Comment\n" );
skip_block ( length );
break;
/*}}} */
/*{{{ texture*/
case 0x010 :
trprintf ("Texture\n" );
parse_texture ( length );
break;
/*}}} */
/*{{{ material*/
case 0x020 :
trprintf ("Material\n" );
parse_material ( length );
break;
/*}}} */
/*{{{ ramp*/
case 0x030 :
trprintf ("Ramp\n" );
parse_ramp ( length );
break;
/*}}} */
/*{{{ object*/
case 0x040 :
trprintf ("Object\n" );
parse_object ( length );
break;
/*}}} */
default :
skip_block ( length );
printf ("ERROR : unexpected tag 0x%x\n", block_hdr );
fclose(fp);
return NULL;
break;
}
}
if (b2z_ok) {
fclose(fp);
return object;
}
else
return NULL;
}
}
}
/*}}} */