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>
422 lines
9.5 KiB
C++
422 lines
9.5 KiB
C++
/*
|
|
|
|
File material.c
|
|
Project pazpl5
|
|
|
|
Author P J Atkin
|
|
|
|
(c) DIVISION Ltd 1993
|
|
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include "pazpl5.h"
|
|
|
|
/*{{{ some PAZlists used in here*/
|
|
|
|
/*
|
|
list of currently resolved materials
|
|
*/
|
|
static PAZlist *material_head=NULL, *material_tail=NULL;
|
|
|
|
/*
|
|
list of PATCHES containing unresolved front materials
|
|
*/
|
|
static PAZlist *funresolved_head=NULL, *funresolved_tail=NULL;
|
|
|
|
/*
|
|
list of PATCHES containing unresolved back materials
|
|
*/
|
|
static PAZlist *bunresolved_head=NULL, *bunresolved_tail=NULL;
|
|
|
|
/*
|
|
list of currently resolved textures
|
|
*/
|
|
static PAZlist *texture_head=NULL, *texture_tail=NULL;
|
|
|
|
/*
|
|
list of MATERIALs containing unresolved textures
|
|
*/
|
|
static PAZlist *unresolved_tex_head=NULL, *unresolved_tex_tail=NULL;
|
|
/*}}} */
|
|
|
|
/*
|
|
#define debug_mtl 1
|
|
*/
|
|
|
|
int resolved=0;
|
|
|
|
/*{{{ void resolve_material ( MATERIAL *m )*/
|
|
/* ******************
|
|
take a newly loaded material, scour unresolved PATCH list for references to
|
|
it. if a newly loaded material resolves any currently unresolved PATCHes,
|
|
do resolving and free up list storage
|
|
*/
|
|
|
|
void resolve_material ( MATERIAL *m )
|
|
{
|
|
int resolved=0;
|
|
PAZlist *item, *prev;
|
|
|
|
/*{{{ resolve material from front list*/
|
|
item=funresolved_head, prev=item;
|
|
|
|
#if debug_mtl
|
|
printf ("resolve_material %s\n", m->material_name );
|
|
#endif
|
|
|
|
while (item) {
|
|
PATCH *p=(PATCH *) item->data;
|
|
|
|
prev=item;
|
|
item=item->next;
|
|
|
|
#if debug_mtl
|
|
printf ("compare material name %s with unresolved %s\n",
|
|
m->material_name, p->fmaterial_name );
|
|
#endif
|
|
if (strcmp (m->material_name, p->fmaterial_name) == 0) {
|
|
/* found it, resolve material */
|
|
#if debug_mtl
|
|
printf ("found material, can resolve patch 0x%x!\n", p );
|
|
#endif
|
|
|
|
removePAZitem ( prev, &funresolved_head, &funresolved_tail );
|
|
p->fmaterial=m;
|
|
m->usage_count++;
|
|
}
|
|
}
|
|
/*}}} */
|
|
/*{{{ resolve material from back list*/
|
|
item=bunresolved_head, prev=item;
|
|
|
|
#if debug_mtl
|
|
printf ("resolve_material %s\n", m->material_name );
|
|
#endif
|
|
|
|
while (item) {
|
|
PATCH *p=(PATCH *) item->data;
|
|
|
|
prev=item;
|
|
item=item->next;
|
|
|
|
#if debug_mtl
|
|
printf ("compare material name %s with unresolved %s\n",
|
|
m->material_name, p->bmaterial_name );
|
|
#endif
|
|
if (strcmp (m->material_name, p->bmaterial_name) == 0) {
|
|
/* found it, resolve material */
|
|
#if debug_mtl
|
|
printf ("found material, can resolve patch 0x%x!\n", p );
|
|
#endif
|
|
|
|
removePAZitem ( prev, &bunresolved_head, &bunresolved_tail );
|
|
p->bmaterial=m;
|
|
m->usage_count++;
|
|
}
|
|
}
|
|
/*}}} */
|
|
/*{{{ resolve texture*/
|
|
|
|
item=texture_head, prev=item;
|
|
|
|
#if debug_mtl
|
|
printf ("resolve_material %s\n", m->material_name );
|
|
#endif
|
|
|
|
while (item) {
|
|
TEXTURE *tex=(TEXTURE *) item->data;
|
|
char *name;
|
|
|
|
prev=item;
|
|
item=item->next;
|
|
name=&m->texture_name[0];
|
|
|
|
#if debug_mtl
|
|
printf ("compare material 0x%x tex name %s with texture %s\n",
|
|
m, name, tex->texture_name );
|
|
#endif
|
|
if ((resolved==0) && (strcmp ( name, tex->texture_name) == 0)) {
|
|
/* found it, resolve material */
|
|
#if debug_mtl
|
|
printf ("found texture %s ! (0x%x)\n", tex->texture_name, (int) tex );
|
|
#endif
|
|
|
|
m->tex=tex;
|
|
resolved=1;
|
|
}
|
|
}
|
|
/*}}} */
|
|
/*{{{ add to unresolved texture list?*/
|
|
if (resolved==0) {
|
|
addPAZitem ( m, &unresolved_tex_head, &unresolved_tex_tail );
|
|
}
|
|
/*}}} */
|
|
|
|
}
|
|
/*}}} */
|
|
/*{{{ void add_material ( MATERIAL *m )*/
|
|
/* ******************
|
|
append a new material to list, and attempt to resolve PATCH list
|
|
*/
|
|
|
|
void add_material ( MATERIAL *m )
|
|
{
|
|
#if debug_mtl
|
|
printf ("adding material %s\n", m->material_name );
|
|
#endif
|
|
|
|
addPAZitem ( m, &material_head, &material_tail );
|
|
|
|
resolve_material ( m );
|
|
}
|
|
/*}}} */
|
|
/*{{{ MATERIAL *createMaterial ( void )*/
|
|
MATERIAL *create_material ()
|
|
{
|
|
MATERIAL *m=(MATERIAL *) malloc(sizeof(MATERIAL));
|
|
if (m==NULL) return NULL;
|
|
#if debug_mtl
|
|
printf ("create_material\n" );
|
|
#endif
|
|
|
|
m->usage_count=0;
|
|
m->material_name[0]=(char) 0x0;
|
|
|
|
m->triangle_fn=NULL;
|
|
m->pxpl5codeword=0x0;
|
|
m->kd[0] =1.0f;
|
|
m->kd[1] =1.0f;
|
|
m->kd[2] =1.0f;
|
|
m->ks =0.0f;
|
|
m->power =0.0f;
|
|
m->opacity =1.0f;
|
|
m->tex =NULL;
|
|
m->ramp_entry =0x0;
|
|
m->texture_name[0]=(char) 0x0;
|
|
|
|
return m;
|
|
}
|
|
/*}}} */
|
|
|
|
/*{{{ int resolve_texture ( TEXTURE *t )*/
|
|
/* ******************
|
|
does a newly loaded texture resolve any materials? scour the unresolved
|
|
textures list, if we match any, patch them up and remove them.
|
|
*/
|
|
|
|
int resolve_texture ( TEXTURE *t )
|
|
{
|
|
PAZlist *item=unresolved_tex_head;
|
|
char *name;
|
|
|
|
#if debug_mtl
|
|
printf ("resolve_texture %s\n", t->texture_name );
|
|
#endif
|
|
|
|
while (item) {
|
|
MATERIAL *m=(MATERIAL *) item->data;
|
|
PAZlist *prev=item;
|
|
|
|
name=m->texture_name;
|
|
|
|
#if debug_mtl
|
|
printf ("compare texture name %s with material %s\n",
|
|
t->texture_name, m->material_name );
|
|
#endif
|
|
if (strcmp (t->texture_name, name) == 0) {
|
|
#if debug_mtl
|
|
printf ("found it! setting %s->tex to 0x%x\n", m->material_name, t );
|
|
#endif
|
|
m->tex=t;
|
|
removePAZitem ( prev, &unresolved_tex_head, &unresolved_tex_tail );
|
|
}
|
|
item=item->next;
|
|
}
|
|
return 0;
|
|
}
|
|
/*}}} */
|
|
/*{{{ void add_texture ( TEXTURE *t )*/
|
|
/* ******************
|
|
append a new texture to list, and attempt to resolve MATERIAL list
|
|
*/
|
|
|
|
void add_texture ( TEXTURE *t )
|
|
{
|
|
#if debug_mtl
|
|
printf ("adding texture %s\n", t->texture_name );
|
|
#endif
|
|
|
|
addPAZitem ( t, &texture_head, &texture_tail );
|
|
|
|
resolve_texture ( t );
|
|
}
|
|
/*}}} */
|
|
|
|
/*{{{ int resolve_patch ( PATCH *p )*/
|
|
/* ******************
|
|
a newly loaded patch references a front and back material.
|
|
scour the materials list - if the material matches, patch up the patch.
|
|
if not, add the patch to the unresolved patch list
|
|
*/
|
|
|
|
int resolve_patch ( PATCH *p )
|
|
{
|
|
PAZlist *item=material_head;
|
|
int f_ok=0, b_ok=0;
|
|
|
|
#if debug_mtl
|
|
printf ("resolve_patch %s %s\n",
|
|
p->fmaterial_name,
|
|
p->bmaterial_name );
|
|
#endif
|
|
|
|
/*{{{ resolve front*/
|
|
while (item) {
|
|
MATERIAL *m=(MATERIAL *) item->data;
|
|
|
|
#if debug_mtl
|
|
printf ("compare material name %s with material %s\n",
|
|
p->fmaterial_name, m->material_name );
|
|
#endif
|
|
if (strcmp (p->fmaterial_name, m->material_name) == 0) {
|
|
#if debug_mtl
|
|
printf ("found front!\n" );
|
|
#endif
|
|
p->fmaterial=m;
|
|
f_ok=1;
|
|
m->usage_count++;
|
|
if (f_ok && b_ok)
|
|
return 1;
|
|
}
|
|
#if debug_mtl
|
|
printf ("compare material name %s with material %s\n",
|
|
p->bmaterial_name, m->material_name );
|
|
#endif
|
|
if (strcmp (p->bmaterial_name, m->material_name) == 0) {
|
|
#if debug_mtl
|
|
printf ("found back!\n" );
|
|
#endif
|
|
p->bmaterial=m;
|
|
b_ok=1;
|
|
m->usage_count++;
|
|
if (f_ok && b_ok)
|
|
return 1;
|
|
}
|
|
item=item->next;
|
|
}
|
|
/*}}} */
|
|
|
|
if (f_ok == 0) {
|
|
#if debug_mtl
|
|
printf ("didnt find front mtl, adding to unresolved list\n" );
|
|
#endif
|
|
addPAZitem ( p, &funresolved_head, &funresolved_tail );
|
|
return 0;
|
|
}
|
|
|
|
if (b_ok == 0) {
|
|
#if debug_mtl
|
|
printf ("didnt find back mtl, adding to unresolved list\n" );
|
|
#endif
|
|
addPAZitem ( p, &bunresolved_head, &bunresolved_tail );
|
|
return 0;
|
|
}
|
|
}
|
|
/*}}} */
|
|
|
|
/*{{{ int resolve_scene ()*/
|
|
int resolve_scene ()
|
|
{
|
|
/* this is the UTTERLY brute force scene material / texture resolver */
|
|
/* first all materials are resolved to their respective textures */
|
|
/* then all patch / pmeshes are resolved to their respective materials */
|
|
|
|
if (resolved == 0) {
|
|
/* */
|
|
}
|
|
|
|
resolved=1;
|
|
}
|
|
/*}}} */
|
|
|
|
/*{{{ void trace_materials ()*/
|
|
/* ******************
|
|
debug, trace materials
|
|
*/
|
|
|
|
void trace_materials ()
|
|
{
|
|
PAZlist *item;
|
|
PATCH *p;
|
|
MATERIAL *m, *mtl;
|
|
TEXTURE *t;
|
|
|
|
/*{{{ printf ("trace materials\n" );*/
|
|
printf ("trace materials\n" );
|
|
|
|
for (item=material_head; item; item=item->next ) {
|
|
mtl=(MATERIAL *) item->data;
|
|
printf ( "material name %s\n", mtl->material_name );
|
|
}
|
|
|
|
/*}}} */
|
|
/*{{{ printf ("trace unresolved f materials\n" );*/
|
|
printf ("trace unresolved f materials\n" );
|
|
|
|
item=funresolved_head;
|
|
|
|
while (item) {
|
|
p=(PATCH *) item->data;
|
|
printf ( "unresolved name %s ", p->fmaterial_name );
|
|
|
|
item=item->next;
|
|
}
|
|
|
|
/*}}} */
|
|
/*{{{ printf ("trace unresolved b materials\n" );*/
|
|
printf ("trace unresolved b materials\n" );
|
|
|
|
item=bunresolved_head;
|
|
|
|
while (item) {
|
|
p=(PATCH *) item->data;
|
|
printf ( "unresolved name %s in patch 0x%x (%d)\n",
|
|
p->bmaterial_name, p, strlen(p->bmaterial_name));
|
|
|
|
item=item->next;
|
|
}
|
|
|
|
/*}}} */
|
|
/*{{{ printf ("trace textures\n" );*/
|
|
printf ("trace textures\n" );
|
|
|
|
item=texture_head;
|
|
|
|
while (item) {
|
|
t=(TEXTURE *) item->data;
|
|
|
|
printf ( "texture %s\n", t->texture_name );
|
|
|
|
item=item->next;
|
|
}
|
|
/*}}} */
|
|
/*{{{ printf ("trace unresolved textures\n" );*/
|
|
printf ("trace unresolved textures\n" );
|
|
|
|
item=unresolved_tex_head;
|
|
|
|
while (item) {
|
|
m=(MATERIAL *) item->data;
|
|
|
|
if (m->tex == NULL)
|
|
printf ( "unresolved texture %s\n", m->texture_name );
|
|
|
|
item=item->next;
|
|
}
|
|
/*}}} */
|
|
}
|
|
/*}}} */
|
|
|