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>
1951 lines
48 KiB
C++
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;
|
|
}
|
|
}
|
|
}
|
|
/*}}} */
|
|
|