4024 lines
103 KiB
C++
4024 lines
103 KiB
C++
#include <stdlib.h>
|
|
#include <string.hpp>
|
|
|
|
#include "list_tem.hpp"
|
|
#include "chnkload.hpp"
|
|
#include "oechunk.h"
|
|
#include "stratdef.h"
|
|
//#include "bh_types.h"
|
|
#include "shpchunk.hpp"
|
|
#include "envchunk.hpp"
|
|
#include "obchunk.hpp"
|
|
#include "chunkpal.hpp"
|
|
#include "bmpnames.hpp"
|
|
#include "ltchunk.hpp"
|
|
#include "chnktexi.h"
|
|
#include "sprchunk.hpp"
|
|
#include "gsprchnk.hpp"
|
|
#include "animchnk.hpp"
|
|
#include "fragchnk.hpp"
|
|
#include "jsndsup.h"
|
|
#include "mempool.h"
|
|
#include <math.h>
|
|
// for log file
|
|
void SetupAnimatedTextures(Shape_Chunk* sc,SHAPEHEADER* shp,Animation_Chunk* ac,Shape_Merge_Data_Chunk* smdc);
|
|
void SetupAnimOnTriangle(SHAPEHEADER* shp,TEXANIM* ta,int poly);
|
|
void SetupAnimOnQuad(Shape_Chunk* sc,SHAPEHEADER* shp,TEXANIM* ta1,TEXANIM* ta2,int poly);
|
|
|
|
// what we need to do for now is load shapes into the mainshapelist
|
|
// and objects into the Mapheader - Map
|
|
|
|
|
|
double local_scale;
|
|
|
|
File_Chunk * Env_Chunk = 0;
|
|
|
|
RIFFHANDLE current_rif_handle;
|
|
|
|
unsigned char const * PaletteMapTable;
|
|
|
|
//////////////////////////////////////////////////////////
|
|
extern LOADED_SOUND const * GetSoundForMainRif(const char* wav_name);
|
|
extern char * extsounddir ;
|
|
extern char * sounddir ;
|
|
|
|
struct Shape_Fragment_Type
|
|
{
|
|
Shape_Fragment_Type(const char*);
|
|
~Shape_Fragment_Type();
|
|
void AddShape(SHAPEHEADER*);
|
|
void Setup_sh_frags(Fragment_Type_Chunk*);
|
|
|
|
char* name;
|
|
List<SHAPEHEADER*> shapelist;
|
|
SHAPEFRAGMENTDESC* sh_fragdesc;
|
|
};
|
|
|
|
Shape_Fragment_Type::Shape_Fragment_Type(const char* _name)
|
|
{
|
|
name=new char[strlen(_name)+1];
|
|
strcpy(name,_name);
|
|
sh_fragdesc=0;
|
|
}
|
|
|
|
Shape_Fragment_Type::~Shape_Fragment_Type()
|
|
{
|
|
while(shapelist.size())
|
|
{
|
|
shapelist.first_entry()->sh_fragdesc=0;
|
|
delete shapelist.first_entry();
|
|
}
|
|
if(sh_fragdesc)
|
|
{
|
|
#if USE_LEVEL_MEMORY_POOL
|
|
if(sh_fragdesc->sh_fragsound)
|
|
{
|
|
if(sh_fragdesc->sh_fragsound->sound_loaded)
|
|
LoseSound(sh_fragdesc->sh_fragsound->sound_loaded);
|
|
}
|
|
#else
|
|
if(sh_fragdesc->sh_frags)DeallocateMem(sh_fragdesc->sh_frags);
|
|
if(sh_fragdesc->sh_fragsound)
|
|
{
|
|
if(sh_fragdesc->sh_fragsound->sound_loaded)
|
|
LoseSound(sh_fragdesc->sh_fragsound->sound_loaded);
|
|
DeallocateMem(sh_fragdesc->sh_fragsound);
|
|
}
|
|
DeallocateMem(sh_fragdesc);
|
|
#endif
|
|
|
|
}
|
|
if(name) delete name;
|
|
}
|
|
|
|
void Shape_Fragment_Type::AddShape(SHAPEHEADER* shp)
|
|
{
|
|
shapelist.add_entry(shp);
|
|
if(sh_fragdesc) shp->sh_fragdesc=sh_fragdesc;
|
|
}
|
|
|
|
|
|
void Shape_Fragment_Type::Setup_sh_frags(Fragment_Type_Chunk* ftc)
|
|
{
|
|
if(sh_fragdesc) return;
|
|
List<Chunk*> chlist;
|
|
ftc->lookup_child("FRGTYPSC",chlist);
|
|
|
|
sh_fragdesc=(SHAPEFRAGMENTDESC*)PoolAllocateMem(sizeof(SHAPEFRAGMENTDESC));
|
|
for(LIF<SHAPEHEADER*> slif(&shapelist);!slif.done();slif.next())
|
|
{
|
|
slif()->sh_fragdesc=sh_fragdesc;
|
|
}
|
|
|
|
|
|
sh_fragdesc->sh_frags = (SHAPEFRAGMENT *)PoolAllocateMem((chlist.size()+1) * sizeof(SHAPEFRAGMENT));
|
|
int pos=0;
|
|
while(chlist.size())
|
|
{
|
|
Fragment_Type_Shape_Chunk* ftsc=(Fragment_Type_Shape_Chunk*)chlist.first_entry();
|
|
|
|
int shapeindex=GetLoadedShapeMSL(ftsc->name);
|
|
if(shapeindex!=-1)
|
|
{
|
|
sh_fragdesc->sh_frags[pos].ShapeIndex=shapeindex;
|
|
sh_fragdesc->sh_frags[pos].NumFrags=ftsc->num_fragments;
|
|
|
|
sh_fragdesc->sh_frags[pos].x_offset = 0;
|
|
sh_fragdesc->sh_frags[pos].y_offset = 0;
|
|
sh_fragdesc->sh_frags[pos].z_offset = 0;
|
|
pos++;
|
|
}
|
|
|
|
chlist.delete_first_entry();
|
|
}
|
|
sh_fragdesc->sh_frags[pos].ShapeIndex = -1;
|
|
sh_fragdesc->sh_frags[pos].NumFrags = -1;
|
|
|
|
sh_fragdesc->sh_fragsound=0;
|
|
|
|
Chunk * pChunk = ftc->lookup_single_child("FRGSOUND");
|
|
if(pChunk)
|
|
{
|
|
Fragment_Type_Sound_Chunk* ftsoc=(Fragment_Type_Sound_Chunk*) pChunk;
|
|
|
|
|
|
sh_fragdesc->sh_fragsound=(SHAPEFRAGMENTSOUND*)PoolAllocateMem(sizeof(SHAPEFRAGMENTSOUND));
|
|
sh_fragdesc->sh_fragsound->sound_loaded=GetSoundForMainRif (ftsoc->wav_name);
|
|
sh_fragdesc->sh_fragsound->inner_range=ftsoc->inner_range*local_scale;
|
|
sh_fragdesc->sh_fragsound->outer_range=ftsoc->outer_range*local_scale;
|
|
sh_fragdesc->sh_fragsound->pitch=ftsoc->pitch;
|
|
sh_fragdesc->sh_fragsound->max_volume=ftsoc->max_volume;
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
static List<Shape_Fragment_Type*> FragList;
|
|
|
|
void ApplyFragTypeToShape(SHAPEHEADER* shp,const char* name)
|
|
{
|
|
for(LIF<Shape_Fragment_Type*> flif(&FragList);!flif.done();flif.next())
|
|
{
|
|
if(!_stricmp(flif()->name,name))
|
|
{
|
|
flif()->AddShape(shp);
|
|
return;
|
|
}
|
|
}
|
|
Shape_Fragment_Type* sft=new Shape_Fragment_Type(name);
|
|
sft->AddShape(shp);
|
|
FragList.add_entry(sft);
|
|
}
|
|
|
|
void SetupFragmentType(Fragment_Type_Chunk* ftc)
|
|
{
|
|
const char* name=ftc->get_name();
|
|
if(!name) return;
|
|
|
|
Shape_Fragment_Type* sft=0;
|
|
for(LIF<Shape_Fragment_Type*> flif(&FragList);!flif.done();flif.next())
|
|
{
|
|
if(!_stricmp(flif()->name,name))
|
|
{
|
|
sft=flif();
|
|
break;
|
|
}
|
|
}
|
|
if(!sft)
|
|
{
|
|
return;
|
|
}
|
|
|
|
sft->Setup_sh_frags(ftc);
|
|
}
|
|
|
|
void DeallocateFragments(SHAPEHEADER* shp,SHAPEFRAGMENTDESC* sh_fragdesc)
|
|
{
|
|
for(LIF<Shape_Fragment_Type*> flif(&FragList);!flif.done();flif.next())
|
|
{
|
|
if(flif()->sh_fragdesc==sh_fragdesc)
|
|
{
|
|
flif()->shapelist.delete_entry(shp);
|
|
if(!flif()->shapelist.size())
|
|
{
|
|
//no more shapes use this fragment type - so deallocate it
|
|
delete flif();
|
|
flif.delete_current();
|
|
}
|
|
return;
|
|
}
|
|
}
|
|
//sh_fragdesc not generated by a fragment type so deallocate it.
|
|
#if USE_LEVEL_MEMORY_POOL
|
|
if(sh_fragdesc->sh_fragsound)
|
|
{
|
|
if(sh_fragdesc->sh_fragsound->sound_loaded)
|
|
LoseSound(sh_fragdesc->sh_fragsound->sound_loaded);
|
|
}
|
|
#else
|
|
if(sh_fragdesc->sh_frags)DeallocateMem(sh_fragdesc->sh_frags);
|
|
if(sh_fragdesc->sh_fragsound)
|
|
{
|
|
if(sh_fragdesc->sh_fragsound->sound_loaded)
|
|
LoseSound(sh_fragdesc->sh_fragsound->sound_loaded);
|
|
DeallocateMem(sh_fragdesc->sh_fragsound);
|
|
}
|
|
DeallocateMem(sh_fragdesc);
|
|
#endif
|
|
}
|
|
|
|
void DeallocateAllFragments()
|
|
{
|
|
while(FragList.size())
|
|
{
|
|
Shape_Fragment_Type* frag_type=FragList.first_entry();
|
|
|
|
while(frag_type->shapelist.size())
|
|
{
|
|
frag_type->shapelist.delete_first_entry();
|
|
}
|
|
frag_type->sh_fragdesc=0;
|
|
delete frag_type;
|
|
|
|
FragList.delete_first_entry();
|
|
}
|
|
}
|
|
|
|
/////////////////////////////////////////
|
|
/////////////////////////////////////////
|
|
// Hold data about chunk loaded shapes //
|
|
/////////////////////////////////////////
|
|
/////////////////////////////////////////
|
|
|
|
class ShapeInMSL
|
|
{
|
|
private:
|
|
void AddToHashTables();
|
|
void RemoveFromHashTables();
|
|
|
|
#define SIM_HASH_BITS 6
|
|
#define SIM_HASH_SIZE (1<<SIM_HASH_BITS)
|
|
#define SIM_HASH_MASK (SIM_HASH_SIZE-1)
|
|
|
|
static List<ShapeInMSL const *> hash_msl[];
|
|
static List<ShapeInMSL const *> hash_ptr[];
|
|
static List<ShapeInMSL const *> hash_name[];
|
|
|
|
static int HashMSLFunc(int);
|
|
static int HashPtrFunc(SHAPEHEADER *);
|
|
static int HashNameFunc(char const *);
|
|
|
|
|
|
int listpos;
|
|
SHAPEHEADER * shptr;
|
|
String name;
|
|
BOOL in_hash_table;
|
|
|
|
public:
|
|
|
|
inline int Listpos() const { return listpos; }
|
|
inline SHAPEHEADER * Shptr() const { return shptr; }
|
|
inline char const * Name() const { return name; }
|
|
|
|
static ShapeInMSL const * GetByName(char const *);
|
|
static ShapeInMSL const * GetByMSL(int);
|
|
static ShapeInMSL const * GetByPtr(SHAPEHEADER *);
|
|
static void PurgeMSLShapeList();
|
|
|
|
ShapeInMSL();
|
|
ShapeInMSL(int _p);
|
|
ShapeInMSL(SHAPEHEADER * _s, char const * _n, int _p);
|
|
ShapeInMSL(ShapeInMSL const &);
|
|
ShapeInMSL & operator = (ShapeInMSL const &);
|
|
~ShapeInMSL();
|
|
|
|
BOOL operator == (ShapeInMSL const & s2) const
|
|
{ return (GLS_NOTINLIST==listpos && GLS_NOTINLIST==s2.listpos) ? shptr == s2.shptr : listpos == s2.listpos; }
|
|
inline BOOL operator != (ShapeInMSL const & s2) const { return ! operator == (s2); }
|
|
};
|
|
|
|
void ShapeInMSL::AddToHashTables()
|
|
{
|
|
if (GLS_NOTINLIST != listpos)
|
|
hash_msl[HashMSLFunc(listpos)].add_entry(this);
|
|
hash_ptr[HashPtrFunc(shptr)].add_entry(this);
|
|
hash_name[HashNameFunc(name)].add_entry(this);
|
|
|
|
in_hash_table = TRUE;
|
|
}
|
|
|
|
void ShapeInMSL::RemoveFromHashTables()
|
|
{
|
|
if (GLS_NOTINLIST != listpos)
|
|
hash_msl[HashMSLFunc(listpos)].delete_entry(this);
|
|
hash_ptr[HashPtrFunc(shptr)].delete_entry(this);
|
|
hash_name[HashNameFunc(name)].delete_entry(this);
|
|
|
|
in_hash_table = FALSE;
|
|
}
|
|
|
|
List<ShapeInMSL const *> ShapeInMSL::hash_msl[SIM_HASH_SIZE];
|
|
List<ShapeInMSL const *> ShapeInMSL::hash_ptr[SIM_HASH_SIZE];
|
|
List<ShapeInMSL const *> ShapeInMSL::hash_name[SIM_HASH_SIZE];
|
|
|
|
int ShapeInMSL::HashMSLFunc(int pos)
|
|
{
|
|
return pos & SIM_HASH_MASK;
|
|
}
|
|
|
|
int ShapeInMSL::HashPtrFunc(SHAPEHEADER * shp)
|
|
{
|
|
size_t p = (size_t)shp;
|
|
|
|
while (p>=SIM_HASH_SIZE)
|
|
p = (p & SIM_HASH_MASK) ^ (p>>SIM_HASH_BITS);
|
|
|
|
return (int)p;
|
|
}
|
|
|
|
int ShapeInMSL::HashNameFunc(char const * nam)
|
|
{
|
|
int v = 0;
|
|
|
|
while (*nam) v += (unsigned char)toupper(*nam++);
|
|
|
|
return v & SIM_HASH_MASK;
|
|
}
|
|
|
|
ShapeInMSL const * ShapeInMSL::GetByMSL(int pos)
|
|
{
|
|
for (LIF<ShapeInMSL const *> i(&hash_msl[HashMSLFunc(pos)]); !i.done(); i.next())
|
|
{
|
|
if (i()->listpos == pos) return i();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
ShapeInMSL const * ShapeInMSL::GetByPtr(SHAPEHEADER * shp)
|
|
{
|
|
for (LIF<ShapeInMSL const *> i(&hash_ptr[HashPtrFunc(shp)]); !i.done(); i.next())
|
|
{
|
|
if (i()->shptr == shp) return i();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
ShapeInMSL const * ShapeInMSL::GetByName(char const * nam)
|
|
{
|
|
for (LIF<ShapeInMSL const *> i(&hash_name[HashNameFunc(nam)]); !i.done(); i.next())
|
|
{
|
|
if (!_stricmp(i()->name,nam)) return i();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
ShapeInMSL::ShapeInMSL()
|
|
: shptr(0)
|
|
, listpos(GLS_NOTINLIST)
|
|
, in_hash_table(FALSE)
|
|
{
|
|
}
|
|
|
|
ShapeInMSL::ShapeInMSL(int _p)
|
|
: shptr(0)
|
|
, listpos(_p)
|
|
, in_hash_table(FALSE)
|
|
{
|
|
}
|
|
|
|
ShapeInMSL::ShapeInMSL(SHAPEHEADER * _s, char const * _n, int _p)
|
|
: shptr(_s)
|
|
, name(_n)
|
|
, listpos(_p)
|
|
, in_hash_table(FALSE)
|
|
{
|
|
AddToHashTables();
|
|
}
|
|
|
|
ShapeInMSL::ShapeInMSL(ShapeInMSL const & sim)
|
|
: shptr(sim.shptr)
|
|
, name(sim.name)
|
|
, listpos(sim.listpos)
|
|
, in_hash_table(FALSE)
|
|
{
|
|
if (sim.in_hash_table) AddToHashTables();
|
|
}
|
|
|
|
ShapeInMSL & ShapeInMSL::operator = (ShapeInMSL const & sim)
|
|
{
|
|
if (&sim != this)
|
|
{
|
|
if (in_hash_table) RemoveFromHashTables();
|
|
shptr = sim.shptr;
|
|
name = sim.name;
|
|
listpos = sim.listpos;
|
|
if (sim.in_hash_table) AddToHashTables();
|
|
}
|
|
return *this;
|
|
}
|
|
|
|
ShapeInMSL::~ShapeInMSL()
|
|
{
|
|
if (in_hash_table) RemoveFromHashTables();
|
|
}
|
|
|
|
|
|
static List<ShapeInMSL*> msl_shapes;
|
|
|
|
void ShapeInMSL::PurgeMSLShapeList()
|
|
{
|
|
for(int i=0;i<SIM_HASH_SIZE;i++)
|
|
{
|
|
while(hash_msl[i].size())hash_msl[i].delete_first_entry();
|
|
while(hash_ptr[i].size())hash_ptr[i].delete_first_entry();
|
|
while(hash_name[i].size())hash_name[i].delete_first_entry();
|
|
}
|
|
|
|
while(msl_shapes.size())
|
|
{
|
|
ShapeInMSL* shp_msl=msl_shapes.first_entry();
|
|
shp_msl->in_hash_table=FALSE;
|
|
delete shp_msl;
|
|
msl_shapes.delete_first_entry();
|
|
}
|
|
}
|
|
void PurgeMSLShapeList()
|
|
{
|
|
ShapeInMSL::PurgeMSLShapeList();
|
|
}
|
|
|
|
/////////////////////////////////////////
|
|
/////////////////////////////////////////
|
|
/////////////////////////////////////////
|
|
|
|
extern "C"
|
|
{
|
|
extern unsigned char *TextureLightingTable;
|
|
extern int ScanDrawMode;
|
|
};
|
|
|
|
|
|
/////////////////////////////////////////
|
|
// Functions which operate on RIFFHANDLEs
|
|
/////////////////////////////////////////
|
|
|
|
// load a rif file into memory
|
|
RIFFHANDLE load_rif (const char * fname)
|
|
{
|
|
File_Chunk * fc = new File_Chunk (fname);
|
|
|
|
if (fc->error_code != 0)
|
|
{
|
|
delete fc;
|
|
#if OUTPUT_LOG
|
|
CL_LogFile.lprintf("FAILED TO LOAD RIF: %s\n",fname);
|
|
#endif
|
|
ReleaseDirect3D();
|
|
char message[200];
|
|
sprintf(message,"Error loading %s",fname);
|
|
MessageBox(NULL,message,"AvP",MB_OK+MB_SYSTEMMODAL);
|
|
exit(0x111);
|
|
return INVALID_RIFFHANDLE;
|
|
}
|
|
#if OUTPUT_LOG
|
|
CL_LogFile.lprintf("Successfully Loaded RIF: %s\n",fname);
|
|
#endif
|
|
|
|
RIFFHANDLE h = current_rif_handle = new _RifHandle;
|
|
h->fc = Env_Chunk = fc;
|
|
|
|
Chunk * pChunk = fc->lookup_single_child("REBENVDT");
|
|
if (pChunk)
|
|
{
|
|
h->envd = (Environment_Data_Chunk *)pChunk;
|
|
}
|
|
|
|
return h;
|
|
}
|
|
|
|
RIFFHANDLE load_rif_non_env (const char * fname)
|
|
{
|
|
File_Chunk * fc = new File_Chunk (fname);
|
|
|
|
if (fc->error_code != 0)
|
|
{
|
|
delete fc;
|
|
#if OUTPUT_LOG
|
|
CL_LogFile.lprintf("FAILED TO LOAD RIF: %s\n",fname);
|
|
#endif
|
|
|
|
ReleaseDirect3D();
|
|
char message[200];
|
|
sprintf(message,"Error loading %s",fname);
|
|
MessageBox(NULL,message,"AvP",MB_OK+MB_SYSTEMMODAL);
|
|
exit(0x111);
|
|
return INVALID_RIFFHANDLE;
|
|
}
|
|
#if OUTPUT_LOG
|
|
CL_LogFile.lprintf("Successfully Loaded RIF: %s\n",fname);
|
|
#endif
|
|
|
|
RIFFHANDLE h = current_rif_handle = new _RifHandle;
|
|
h->fc = fc;
|
|
|
|
Chunk * pChunk = fc->lookup_single_child("REBENVDT");
|
|
if (pChunk)
|
|
{
|
|
h->envd = (Environment_Data_Chunk *)pChunk;
|
|
}
|
|
|
|
return h;
|
|
}
|
|
|
|
|
|
// deallocate the shapes, unload the rif, close the handle
|
|
void undo_rif_load (RIFFHANDLE h)
|
|
{
|
|
deallocate_loaded_shapes(h);
|
|
unload_rif(h);
|
|
close_rif_handle(h);
|
|
}
|
|
|
|
// deallocate the shapes copied from the rif
|
|
void deallocate_loaded_shapes (RIFFHANDLE h)
|
|
{
|
|
|
|
// because the SHAPEHEADER is calloced, we can
|
|
// just delete the arrays we want
|
|
|
|
LIF<ShapeInMSL*> msl_shape_lif(&msl_shapes);
|
|
|
|
while (h->shape_nums.size())
|
|
{
|
|
#if !StandardShapeLanguage
|
|
#error Must have standard shape language
|
|
#endif
|
|
|
|
int list_pos = h->shape_nums.first_entry();
|
|
h->shape_nums.delete_first_entry();
|
|
|
|
DeallocateLoadedShapeheader(mainshapelist[list_pos]);
|
|
|
|
FreeMSLPos(list_pos);
|
|
|
|
for(msl_shape_lif.restart();!msl_shape_lif.done();msl_shape_lif.next())
|
|
{
|
|
if(list_pos==msl_shape_lif()->Listpos())
|
|
{
|
|
delete msl_shape_lif();
|
|
msl_shape_lif.delete_current();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// ?????????? FIXME
|
|
if (Map[0].MapType6Objects)
|
|
{
|
|
DeallocateMem (Map[0].MapType6Objects);
|
|
Map[0].MapType6Objects = 0;
|
|
}
|
|
}
|
|
|
|
// unloads the rif but keeps the handle and associated copied shapes
|
|
void unload_rif (RIFFHANDLE h)
|
|
{
|
|
if (h->fc)
|
|
{
|
|
if (h->fc == Env_Chunk)
|
|
Env_Chunk = 0;
|
|
delete h->fc;
|
|
h->fc = 0;
|
|
}
|
|
h->envd = 0;
|
|
h->palparent = 0;
|
|
h->max_index = 0;
|
|
if (h->tex_index_nos) delete[] h->tex_index_nos;
|
|
h->tex_index_nos = 0;
|
|
}
|
|
|
|
// close the handle - performs tidying up and memory deallocation
|
|
void close_rif_handle (RIFFHANDLE h)
|
|
{
|
|
delete h;
|
|
}
|
|
|
|
|
|
//////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
// copies sprite to msl
|
|
int copy_sprite_to_mainshapelist(RIFFHANDLE h, Sprite_Header_Chunk * shc, int/* flags*/)
|
|
{
|
|
int list_pos = GetMSLPos();
|
|
|
|
copy_sprite_to_shapeheader (h, mainshapelist[list_pos], shc, list_pos);
|
|
|
|
post_process_shape(mainshapelist[list_pos]);
|
|
|
|
h->shape_nums.add_entry(list_pos);
|
|
|
|
return list_pos;
|
|
}
|
|
|
|
static void setup_tex_conv_array (
|
|
int & max_indices,
|
|
int * & conv_array,
|
|
RIFFHANDLE h,
|
|
Chunk_With_Children * tmpshp
|
|
)
|
|
{
|
|
String rif_name;
|
|
|
|
max_indices = h->max_index;
|
|
conv_array = h->tex_index_nos;
|
|
|
|
// find out if its come from elsewhere!!!!!!!
|
|
// Doo Dee Doo Doh
|
|
// Just come back from the pub - sorry
|
|
|
|
Chunk * pChunk = tmpshp->lookup_single_child("SHPEXTFL");
|
|
|
|
Shape_External_File_Chunk * seflc = 0;
|
|
Bitmap_List_Store_Chunk * blsc = 0;
|
|
|
|
|
|
if (pChunk)
|
|
{
|
|
seflc = (Shape_External_File_Chunk *)pChunk;
|
|
pChunk = seflc->lookup_single_child("BMPLSTST");
|
|
if (pChunk)
|
|
{
|
|
blsc = (Bitmap_List_Store_Chunk *) pChunk;
|
|
}
|
|
pChunk = seflc->lookup_single_child("RIFFNAME");
|
|
if (pChunk)
|
|
{
|
|
rif_name = ((RIF_Name_Chunk *)pChunk)->rif_name;
|
|
}
|
|
}
|
|
|
|
if (blsc)
|
|
{
|
|
|
|
// load in the textures from the shape
|
|
|
|
max_indices = 0;
|
|
for (LIF<BMP_Name> bns (&blsc->bmps); !bns.done(); bns.next())
|
|
{
|
|
max_indices = max(bns().index,max_indices);
|
|
}
|
|
|
|
conv_array = new int [max_indices+1];
|
|
for (int i=0; i<=max_indices; i++)
|
|
{
|
|
conv_array[i] = -1;
|
|
}
|
|
|
|
if (Env_Chunk == 0)
|
|
Env_Chunk = h->fc;
|
|
// JH 17-2-97 -- image loaders have changed to avoid loading the same image twice
|
|
for (bns.restart() ; !bns.done(); bns.next())
|
|
{
|
|
if (!(bns().flags & ChunkBMPFlag_NotInPC))
|
|
{
|
|
String tex;
|
|
if (bns().flags & ChunkBMPFlag_IFF)
|
|
{
|
|
tex = bns().filename;
|
|
}
|
|
else
|
|
{
|
|
tex = rif_name;
|
|
tex += "\\";
|
|
tex += bns().filename;
|
|
}
|
|
|
|
int imgnum = load_rif_bitmap(tex,bns().flags);
|
|
if (GEI_NOTLOADED != imgnum)
|
|
conv_array[bns().index] = imgnum;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
CopyShapeAnimationHeader(SHAPEHEADER* shpfrom,SHAPEHEADER* shpto)
|
|
{
|
|
GLOBALASSERT(shpfrom->numitems==shpto->numitems);
|
|
GLOBALASSERT(shpfrom->animation_header);
|
|
shpto->animation_header=shpfrom->animation_header;
|
|
shpto->animation_header->num_shapes_using_this++;
|
|
//find a sequence which has some frames;
|
|
|
|
shapeanimationsequence* sas=0;
|
|
for(int i=0;i<shpto->animation_header->num_sequences;i++)
|
|
{
|
|
sas=&shpto->animation_header->anim_sequences[i];
|
|
if(sas->num_frames)
|
|
break;
|
|
|
|
}
|
|
GLOBALASSERT(i<shpto->animation_header->num_sequences);
|
|
|
|
//copy the pointers for the first frame of this sequence
|
|
#if !USE_LEVEL_MEMORY_POOL
|
|
DeallocateMem(shpto->points[0]);
|
|
DeallocateMem(shpto->sh_normals[0]);
|
|
DeallocateMem(shpto->sh_vnormals[0]);
|
|
#endif
|
|
|
|
shpto->points[0]=sas->anim_frames[0].vertices;
|
|
shpto->sh_normals[0]=sas->anim_frames[0].item_normals;
|
|
shpto->sh_vnormals[0]=sas->vertex_normals;
|
|
|
|
}
|
|
|
|
// copies shape to msl
|
|
CTM_ReturnType copy_to_mainshapelist(RIFFHANDLE h, Shape_Chunk * tmpshp, int flags,const ChunkObject* object)
|
|
{
|
|
int local_max_index;
|
|
int * local_tex_index_nos;
|
|
|
|
int list_pos = GetMSLPos();
|
|
int main_shape_num = list_pos;
|
|
int start_shape_no = list_pos;
|
|
String rif_name;
|
|
|
|
setup_tex_conv_array (local_max_index, local_tex_index_nos, h, tmpshp);
|
|
|
|
|
|
Shape_Preprocessed_Data_Chunk* spdc=(Shape_Preprocessed_Data_Chunk*)tmpshp->lookup_single_child("SHPPRPRO");
|
|
if(spdc)
|
|
{
|
|
copy_preprocessed_to_shapeheader (
|
|
h,
|
|
spdc,
|
|
mainshapelist[list_pos],
|
|
tmpshp,
|
|
flags,
|
|
local_max_index,
|
|
local_tex_index_nos,
|
|
list_pos,
|
|
object
|
|
);
|
|
}
|
|
else
|
|
{
|
|
|
|
copy_to_shapeheader (
|
|
h,
|
|
tmpshp->shape_data,
|
|
mainshapelist[list_pos],
|
|
tmpshp,
|
|
flags,
|
|
local_max_index,
|
|
local_tex_index_nos,
|
|
list_pos,
|
|
object
|
|
);
|
|
}
|
|
|
|
Shape_External_File_Chunk * seflc = 0;
|
|
|
|
Chunk * pChunk = tmpshp->lookup_single_child("SHPEXTFL");
|
|
|
|
if (pChunk)
|
|
{
|
|
seflc = (Shape_External_File_Chunk *)pChunk;
|
|
rif_name = seflc->get_shape_name();
|
|
msl_shapes.add_entry(new ShapeInMSL(mainshapelist[list_pos],rif_name,list_pos));
|
|
}
|
|
else
|
|
{
|
|
List<Object_Chunk*> const & oblist=tmpshp->list_assoc_objs();
|
|
if(oblist.size())
|
|
{
|
|
Object_Chunk* oc=oblist.first_entry();
|
|
if(oc->get_header()->flags & OBJECT_FLAG_PLACED_OBJECT)
|
|
{
|
|
msl_shapes.add_entry(new ShapeInMSL(mainshapelist[list_pos],oc->object_data.o_name,list_pos));
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
post_process_shape(mainshapelist[list_pos]);
|
|
|
|
h->shape_nums.add_entry(list_pos);
|
|
|
|
if (tmpshp->count_children("ANIMSEQU"))
|
|
{
|
|
//look for alternate texture mappings
|
|
pChunk=tmpshp->lookup_single_child("ASALTTEX");
|
|
if(pChunk)
|
|
{
|
|
List<Chunk *> chlst;
|
|
((Chunk_With_Children*)pChunk)->lookup_child("SUBSHAPE",chlst);
|
|
for(LIF<Chunk*> chlif(&chlst);!chlif.done();chlif.next())
|
|
{
|
|
Shape_Sub_Shape_Chunk* sssc=(Shape_Sub_Shape_Chunk*)chlif();
|
|
|
|
list_pos=GetMSLPos();
|
|
copy_to_shapeheader (
|
|
h,
|
|
sssc->shape_data,
|
|
mainshapelist[list_pos],
|
|
sssc,
|
|
flags,
|
|
local_max_index,
|
|
local_tex_index_nos,
|
|
list_pos,
|
|
object
|
|
);
|
|
CopyShapeAnimationHeader(mainshapelist[start_shape_no],mainshapelist[list_pos]);
|
|
|
|
const char* shpname=sssc->get_shape_name();
|
|
GLOBALASSERT(shpname);
|
|
msl_shapes.add_entry(new ShapeInMSL(mainshapelist[list_pos],shpname,list_pos));
|
|
h->shape_nums.add_entry(list_pos);
|
|
|
|
post_process_shape(mainshapelist[list_pos]);
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
Shape_Fragments_Chunk * sfc = 0;
|
|
|
|
pChunk = tmpshp->lookup_single_child ("SHPFRAGS");
|
|
|
|
if (pChunk)
|
|
{
|
|
sfc = (Shape_Fragments_Chunk *)pChunk;
|
|
|
|
pChunk=sfc->lookup_single_child("SHPFRGTP");
|
|
if(pChunk)
|
|
{
|
|
//the shape is using a fragment type
|
|
Shape_Fragment_Type_Chunk* sftc=(Shape_Fragment_Type_Chunk*)pChunk;
|
|
ApplyFragTypeToShape(mainshapelist[main_shape_num],sftc->frag_type_name);
|
|
}
|
|
else
|
|
{
|
|
List<Chunk *> cl;
|
|
sfc->lookup_child ("SUBSHAPE", cl);
|
|
if (cl.size())
|
|
{
|
|
mainshapelist[main_shape_num]->sh_fragdesc = (SHAPEFRAGMENTDESC *)PoolAllocateMem(sizeof(SHAPEFRAGMENTDESC));
|
|
|
|
mainshapelist[main_shape_num]->sh_fragdesc->sh_frags = (SHAPEFRAGMENT *)PoolAllocateMem((cl.size()+1) * sizeof(SHAPEFRAGMENT));
|
|
mainshapelist[main_shape_num]->sh_fragdesc->sh_fragsound = 0;
|
|
|
|
int fragpos = 0;
|
|
|
|
for (LIF<Chunk *> cli(&cl); !cli.done(); cli.next(), fragpos++)
|
|
{
|
|
Shape_Sub_Shape_Chunk * sssc = ((Shape_Sub_Shape_Chunk *)cli());
|
|
|
|
list_pos = GetMSLPos();
|
|
|
|
|
|
copy_to_shapeheader (
|
|
h,
|
|
sssc->shape_data,
|
|
mainshapelist[list_pos],
|
|
sssc,
|
|
flags,
|
|
local_max_index,
|
|
local_tex_index_nos,
|
|
list_pos,
|
|
object
|
|
);
|
|
post_process_shape(mainshapelist[list_pos]);
|
|
h->shape_nums.add_entry(list_pos);
|
|
|
|
int num_frags = 1;
|
|
|
|
pChunk = sssc->lookup_single_child("FRAGDATA");
|
|
if (pChunk)
|
|
{
|
|
num_frags = ((Shape_Fragments_Data_Chunk *)pChunk)->num_fragments;
|
|
}
|
|
|
|
Shape_Fragment_Location_Chunk * sflc = 0;
|
|
|
|
pChunk = sssc->lookup_single_child("FRAGLOCN");
|
|
if (pChunk)
|
|
{
|
|
sflc = (Shape_Fragment_Location_Chunk *)pChunk;
|
|
}
|
|
|
|
|
|
mainshapelist[main_shape_num]->sh_fragdesc->sh_frags[fragpos].ShapeIndex = list_pos;
|
|
mainshapelist[main_shape_num]->sh_fragdesc->sh_frags[fragpos].NumFrags = num_frags;
|
|
|
|
if (sflc)
|
|
{
|
|
mainshapelist[main_shape_num]->sh_fragdesc->sh_frags[fragpos].x_offset = sflc->frag_loc.x * local_scale;
|
|
mainshapelist[main_shape_num]->sh_fragdesc->sh_frags[fragpos].y_offset = sflc->frag_loc.y * local_scale;
|
|
mainshapelist[main_shape_num]->sh_fragdesc->sh_frags[fragpos].z_offset = sflc->frag_loc.z * local_scale;
|
|
|
|
}
|
|
else
|
|
{
|
|
mainshapelist[main_shape_num]->sh_fragdesc->sh_frags[fragpos].x_offset = 0;
|
|
mainshapelist[main_shape_num]->sh_fragdesc->sh_frags[fragpos].y_offset = 0;
|
|
mainshapelist[main_shape_num]->sh_fragdesc->sh_frags[fragpos].z_offset = 0;
|
|
}
|
|
|
|
}
|
|
|
|
mainshapelist[main_shape_num]->sh_fragdesc->sh_frags[fragpos].ShapeIndex = -1;
|
|
mainshapelist[main_shape_num]->sh_fragdesc->sh_frags[fragpos].NumFrags = -1;
|
|
|
|
//see if fragment has a sound to go with it
|
|
Fragment_Type_Sound_Chunk* ftsoc=(Fragment_Type_Sound_Chunk*) sfc->lookup_single_child("FRGSOUND");
|
|
if(ftsoc)
|
|
{
|
|
mainshapelist[main_shape_num]->sh_fragdesc->sh_fragsound=(SHAPEFRAGMENTSOUND*)PoolAllocateMem(sizeof(SHAPEFRAGMENTSOUND));
|
|
mainshapelist[main_shape_num]->sh_fragdesc->sh_fragsound->sound_loaded=GetSoundForMainRif (ftsoc->wav_name);
|
|
mainshapelist[main_shape_num]->sh_fragdesc->sh_fragsound->inner_range=ftsoc->inner_range*local_scale;
|
|
mainshapelist[main_shape_num]->sh_fragdesc->sh_fragsound->outer_range=ftsoc->outer_range*local_scale;
|
|
mainshapelist[main_shape_num]->sh_fragdesc->sh_fragsound->pitch=ftsoc->pitch;
|
|
mainshapelist[main_shape_num]->sh_fragdesc->sh_fragsound->max_volume=ftsoc->max_volume;
|
|
}
|
|
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
#if SupportMorphing && LOAD_MORPH_SHAPES
|
|
|
|
/*-------------------**
|
|
** Morphing stuff **
|
|
**-------------------*/
|
|
MORPHCTRL * mc = 0;
|
|
|
|
if (!(flags & CCF_NOMORPH))
|
|
{
|
|
pChunk = tmpshp->lookup_single_child ("SHPMORPH");
|
|
if (pChunk)
|
|
{
|
|
// this shape has some morphing data
|
|
|
|
// (store the list no. of the shape)
|
|
Shape_Morphing_Data_Chunk * smdc = (Shape_Morphing_Data_Chunk *)pChunk;
|
|
|
|
// set all the subshape list_pos numbers to -1
|
|
// so later we can check to see if it has already been loaded
|
|
List<Chunk *> chlst;
|
|
smdc->lookup_child("SUBSHAPE",chlst);
|
|
for (LIF<Chunk *> ssi(&chlst); !ssi.done(); ssi.next())
|
|
{
|
|
((Shape_Sub_Shape_Chunk *)ssi())->list_pos_number = -1;
|
|
}
|
|
|
|
pChunk = smdc->lookup_single_child("FRMMORPH");
|
|
if (pChunk)
|
|
{
|
|
Shape_Morphing_Frame_Data_Chunk * smfdc = (Shape_Morphing_Frame_Data_Chunk *)pChunk;
|
|
// Check there are some frames!!
|
|
if (smfdc->anim_frames.size())
|
|
{
|
|
mc = (MORPHCTRL *)AllocateMem(sizeof(MORPHCTRL));
|
|
mc->ObMorphFlags = smfdc->a_flags;
|
|
mc->ObMorphSpeed = smfdc->a_speed;
|
|
MORPHHEADER * mh = (MORPHHEADER *)AllocateMem(sizeof(MORPHHEADER));
|
|
mc->ObMorphHeader = mh;
|
|
mh->mph_numframes = 0;
|
|
mh->mph_frames = (MORPHFRAME *)AllocateMem(sizeof(MORPHFRAME) * (smfdc->anim_frames.size()) );
|
|
|
|
int frame_no = 0;
|
|
|
|
for (LIF<a_frame *> afi(&smfdc->anim_frames); !afi.done(); afi.next())
|
|
{
|
|
if (afi()->shape1a)
|
|
{
|
|
if (afi()->shape1a->list_pos_number == -1)
|
|
{
|
|
list_pos = GetMSLPos();
|
|
|
|
Shape_Preprocessed_Data_Chunk* spdc=(Shape_Preprocessed_Data_Chunk*)afi()->shape1a->lookup_single_child("SHPPRPRO");
|
|
if(spdc)
|
|
{
|
|
copy_preprocessed_to_shapeheader (
|
|
h,
|
|
spdc,
|
|
mainshapelist[list_pos],
|
|
afi()->shape1a,
|
|
flags,
|
|
local_max_index,
|
|
local_tex_index_nos,
|
|
list_pos,
|
|
object
|
|
);
|
|
}
|
|
else
|
|
{
|
|
|
|
copy_to_shapeheader (
|
|
h,
|
|
afi()->shape1a->shape_data,
|
|
mainshapelist[list_pos],
|
|
afi()->shape1a,
|
|
flags,
|
|
local_max_index,
|
|
local_tex_index_nos,
|
|
list_pos,
|
|
object
|
|
);
|
|
}
|
|
|
|
post_process_shape(mainshapelist[list_pos]);
|
|
afi()->shape1a->list_pos_number = list_pos;
|
|
h->shape_nums.add_entry(list_pos);
|
|
/*
|
|
Copy the item data for this door shape from the main shape. This is largely done to cope
|
|
with the problem of the polygons being merged differently in different morph shapes.
|
|
*/
|
|
SHAPEHEADER* main_shape=mainshapelist[main_shape_num];
|
|
SHAPEHEADER* this_shape=mainshapelist[list_pos];
|
|
|
|
this_shape->numitems=main_shape->numitems;
|
|
this_shape->items=main_shape->items;
|
|
this_shape->sh_textures=main_shape->sh_textures;
|
|
this_shape->sh_normals=main_shape->sh_normals;
|
|
|
|
//update shape instructions (probably not uses anyway)
|
|
this_shape->sh_instruction[1].sh_numitems=main_shape->numitems;
|
|
this_shape->sh_instruction[1].sh_instr_data=main_shape->sh_normals;
|
|
|
|
this_shape->sh_instruction[4].sh_numitems=main_shape->numitems;
|
|
this_shape->sh_instruction[4].sh_instr_data=main_shape->items;
|
|
|
|
}
|
|
mh->mph_frames[frame_no].mf_shape1 = afi()->shape1a->list_pos_number;
|
|
}
|
|
else
|
|
{
|
|
mh->mph_frames[frame_no].mf_shape1 = main_shape_num;
|
|
}
|
|
|
|
if (afi()->shape2a)
|
|
{
|
|
if (afi()->shape2a->list_pos_number == -1)
|
|
{
|
|
list_pos = GetMSLPos();
|
|
|
|
Shape_Preprocessed_Data_Chunk* spdc=(Shape_Preprocessed_Data_Chunk*)afi()->shape2a->lookup_single_child("SHPPRPRO");
|
|
if(spdc)
|
|
{
|
|
copy_preprocessed_to_shapeheader (
|
|
h,
|
|
spdc,
|
|
mainshapelist[list_pos],
|
|
afi()->shape1a,
|
|
flags,
|
|
local_max_index,
|
|
local_tex_index_nos,
|
|
list_pos,
|
|
object
|
|
);
|
|
}
|
|
else
|
|
{
|
|
|
|
copy_to_shapeheader (
|
|
h,
|
|
afi()->shape2a->shape_data,
|
|
mainshapelist[list_pos],
|
|
afi()->shape2a,
|
|
0,
|
|
local_max_index,
|
|
local_tex_index_nos,
|
|
list_pos,
|
|
object
|
|
);
|
|
}
|
|
post_process_shape(mainshapelist[list_pos]);
|
|
afi()->shape2a->list_pos_number = list_pos;
|
|
h->shape_nums.add_entry(list_pos);
|
|
|
|
/*
|
|
Copy the item data for this door shape from the main shape. This is largely done to cope
|
|
with the problem of the polygons being merged differently in different morph shapes.
|
|
*/
|
|
SHAPEHEADER* main_shape=mainshapelist[main_shape_num];
|
|
SHAPEHEADER* this_shape=mainshapelist[list_pos];
|
|
|
|
this_shape->numitems=main_shape->numitems;
|
|
this_shape->items=main_shape->items;
|
|
this_shape->sh_textures=main_shape->sh_textures;
|
|
this_shape->sh_normals=main_shape->sh_normals;
|
|
|
|
//update shape instructions (probably not uses anyway)
|
|
this_shape->sh_instruction[1].sh_numitems=main_shape->numitems;
|
|
this_shape->sh_instruction[1].sh_instr_data=main_shape->sh_normals;
|
|
|
|
this_shape->sh_instruction[4].sh_numitems=main_shape->numitems;
|
|
this_shape->sh_instruction[4].sh_instr_data=main_shape->items;
|
|
}
|
|
mh->mph_frames[frame_no].mf_shape2 = afi()->shape2a->list_pos_number;
|
|
}
|
|
else
|
|
{
|
|
mh->mph_frames[frame_no].mf_shape2 = main_shape_num;
|
|
}
|
|
if (frame_no == 0)
|
|
{
|
|
start_shape_no = mh->mph_frames[frame_no].mf_shape1;
|
|
}
|
|
frame_no ++;
|
|
}
|
|
mh->mph_numframes = frame_no;
|
|
mh->mph_maxframes = frame_no << 16;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
CTM_ReturnType retval = { start_shape_no, main_shape_num, mc };
|
|
if(local_tex_index_nos!=h->tex_index_nos) delete [] local_tex_index_nos;
|
|
return retval;
|
|
|
|
#else
|
|
|
|
if(local_tex_index_nos!=h->tex_index_nos) delete [] local_tex_index_nos;
|
|
return list_pos;
|
|
|
|
#endif
|
|
}
|
|
|
|
// load textures for environment
|
|
BOOL load_rif_bitmaps (RIFFHANDLE h, int/* flags*/)
|
|
{
|
|
Global_BMP_Name_Chunk * gbnc = 0;
|
|
|
|
if (h->envd)
|
|
{
|
|
Chunk * pChunk = h->envd->lookup_single_child ("BMPNAMES");
|
|
if (pChunk) gbnc = (Global_BMP_Name_Chunk *) pChunk;
|
|
}
|
|
|
|
h->max_index = 0;
|
|
|
|
if (gbnc)
|
|
{
|
|
for (LIF<BMP_Name> bns (&gbnc->bmps); !bns.done(); bns.next())
|
|
{
|
|
h->max_index = max(bns().index,h->max_index);
|
|
}
|
|
|
|
if (h->tex_index_nos) delete h->tex_index_nos;
|
|
h->tex_index_nos = new int [h->max_index+1];
|
|
for (int i=0; i<=h->max_index; i++)
|
|
{
|
|
h->tex_index_nos[i] = -1;
|
|
}
|
|
|
|
if (Env_Chunk == 0)
|
|
Env_Chunk = h->fc;
|
|
for (bns.restart() ; !bns.done(); bns.next())
|
|
{
|
|
if (!(bns().flags & ChunkBMPFlag_NotInPC))
|
|
{
|
|
// JH 17-2-97 -- image loaders have changed to avoid loading the same image twice
|
|
int imgnum = load_rif_bitmap(bns().filename,bns().flags);
|
|
if (GEI_NOTLOADED != imgnum)
|
|
h->tex_index_nos[bns().index] = imgnum;
|
|
}
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
else return FALSE;
|
|
}
|
|
|
|
// set the quantization event depending on cl_pszGameMode
|
|
BOOL set_quantization_event(RIFFHANDLE h, int /*flags*/)
|
|
{
|
|
if (h->envd)
|
|
{
|
|
h->palparent = h->envd;
|
|
|
|
if (cl_pszGameMode)
|
|
{
|
|
List<Chunk *> egmcs;
|
|
h->envd->lookup_child("GAMEMODE",egmcs);
|
|
|
|
for (LIF<Chunk *> egmcLIF(&egmcs); !egmcLIF.done(); egmcLIF.next())
|
|
{
|
|
Environment_Game_Mode_Chunk * egmcm = (Environment_Game_Mode_Chunk *) egmcLIF();
|
|
if (egmcm->id_equals(cl_pszGameMode))
|
|
{
|
|
h->palparent = egmcm;
|
|
break;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
return TRUE;
|
|
}
|
|
else
|
|
{
|
|
h->palparent = 0;
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
// copy palette
|
|
BOOL copy_rif_palette (RIFFHANDLE h, int /*flags*/)
|
|
{
|
|
if (h->palparent)
|
|
{
|
|
List<Chunk *> chlst;
|
|
h->palparent->lookup_child("ENVPALET",chlst);
|
|
for (LIF<Chunk *> i_ch(&chlst); !i_ch.done(); i_ch.next())
|
|
{
|
|
Environment_Palette_Chunk * palch = (Environment_Palette_Chunk *)i_ch();
|
|
if (!(palch->flags & EnvPalFlag_V2) && palch->width*palch->height <= 256 )
|
|
{
|
|
for (int i=0; i<palch->width*palch->height*3; i++)
|
|
{
|
|
TestPalette[i] = (unsigned char)(palch->pixel_data[i] >> 2);
|
|
}
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// copy texture lighting table
|
|
BOOL copy_rif_tlt (RIFFHANDLE h, int /*flags*/)
|
|
{
|
|
if (h->palparent)
|
|
{
|
|
List<Chunk *> chlst;
|
|
h->palparent->lookup_child("ENVTXLIT",chlst);
|
|
if(TextureLightingTable)
|
|
{
|
|
DeallocateMem(TextureLightingTable);
|
|
TextureLightingTable = 0;
|
|
}
|
|
for (LIF<Chunk *> i_ch(&chlst); !i_ch.done(); i_ch.next())
|
|
{
|
|
Environment_TLT_Chunk * tltch = (Environment_TLT_Chunk *)i_ch();
|
|
|
|
if ((tltch->flags & ChunkTLTFlag_V2 &&
|
|
ScreenDescriptorBlock.SDB_Flags & SDB_Flag_TLTPalette ||
|
|
!(tltch->flags & ChunkTLTFlag_V2) &&
|
|
!(ScreenDescriptorBlock.SDB_Flags & SDB_Flag_TLTPalette)) &&
|
|
tltch->table
|
|
){
|
|
TextureLightingTable = (unsigned char*)AllocateMem(tltch->width * tltch->num_levels);
|
|
memcpy(TextureLightingTable,tltch->table,tltch->width*tltch->num_levels);
|
|
if (ScreenDescriptorBlock.SDB_Flags & SDB_Flag_TLTPalette)
|
|
{
|
|
ScreenDescriptorBlock.SDB_Flags &= ~(SDB_Flag_TLTSize|SDB_Flag_TLTShift);
|
|
if (tltch->width != 256)
|
|
{
|
|
ScreenDescriptorBlock.SDB_Flags |= SDB_Flag_TLTSize;
|
|
ScreenDescriptorBlock.TLTSize = tltch->width;
|
|
for (int shft = 0; 1<<shft < tltch->width; ++shft)
|
|
;
|
|
if (1<<shft==tltch->width)
|
|
{
|
|
ScreenDescriptorBlock.SDB_Flags |= SDB_Flag_TLTShift;
|
|
ScreenDescriptorBlock.TLTShift = shft;
|
|
}
|
|
}
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// copy palette remap table (15-bit) - post_process_shape may use it
|
|
BOOL get_rif_palette_remap_table (RIFFHANDLE h, int /*flags*/)
|
|
{
|
|
PaletteMapTable = 0;
|
|
if (h->palparent)
|
|
{
|
|
Chunk * pChunk = h->palparent->lookup_single_child("CLRLOOKP");
|
|
if (pChunk)
|
|
{
|
|
Coloured_Polygons_Lookup_Chunk * cplook = (Coloured_Polygons_Lookup_Chunk *)pChunk;
|
|
|
|
if (cplook->table)
|
|
{
|
|
PaletteMapTable = cplook->table;
|
|
return TRUE;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
// copy one named shape or sprite; intended to go in position listpos
|
|
static SHAPEHEADER * CreateShapeFromRif (RIFFHANDLE h, char const * shapename, int listpos = GLS_NOTINLIST)
|
|
{
|
|
if (!h->fc) return 0; // no rif file loaded
|
|
|
|
List<Chunk *> shape_chunks;
|
|
h->fc->lookup_child("REBSHAPE",shape_chunks);
|
|
|
|
for (LIF<Chunk *> search(&shape_chunks); !search.done(); search.next())
|
|
{
|
|
Shape_Chunk * cur_shape = (Shape_Chunk *) search();
|
|
|
|
Chunk * pShpextfile = cur_shape->lookup_single_child("SHPEXTFL");
|
|
|
|
if (pShpextfile)
|
|
{
|
|
Shape_External_File_Chunk * shexdata = (Shape_External_File_Chunk *) pShpextfile;
|
|
|
|
Chunk * pRnc = shexdata->lookup_single_child("RIFFNAME");
|
|
if (pRnc)
|
|
{
|
|
RIF_Name_Chunk * rnc = (RIF_Name_Chunk *) pRnc;
|
|
if (!_stricmp(rnc->rif_name,shapename)) // haha! matching shape found
|
|
{
|
|
SHAPEHEADER * shptr = 0;
|
|
int local_max_index;
|
|
int * local_tex_index_nos;
|
|
setup_tex_conv_array (local_max_index, local_tex_index_nos, h, cur_shape);
|
|
|
|
copy_to_shapeheader(
|
|
h,
|
|
cur_shape->shape_data,
|
|
shptr,
|
|
cur_shape,
|
|
0,
|
|
local_max_index,
|
|
local_tex_index_nos,
|
|
listpos
|
|
);
|
|
if(local_tex_index_nos!=h->tex_index_nos) delete [] local_tex_index_nos;
|
|
|
|
return shptr;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//look to see if is a sprite
|
|
Chunk * pSprite_chunks = h->fc->lookup_single_child("RSPRITES");
|
|
if(pSprite_chunks)
|
|
{
|
|
AllSprites_Chunk* asc=(AllSprites_Chunk*) pSprite_chunks;
|
|
List<Chunk *> sprite_chunks;
|
|
asc->lookup_child("SPRIHEAD",sprite_chunks);
|
|
for(LIF<Chunk*> slif(&sprite_chunks);!slif.done();slif.next())
|
|
{
|
|
Sprite_Header_Chunk* shc=(Sprite_Header_Chunk*)slif();
|
|
Chunk * pRn=shc->lookup_single_child("RIFFNAME");
|
|
if(pRn)
|
|
{
|
|
RIF_Name_Chunk* rnc=(RIF_Name_Chunk*)pRn;
|
|
if (!_stricmp(rnc->rif_name,shapename)) // haha! matching sprite found
|
|
{
|
|
SHAPEHEADER * shptr = 0;
|
|
copy_sprite_to_shapeheader(h,shptr, shc, listpos);
|
|
return shptr;
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
return 0; // could not match shape
|
|
}
|
|
|
|
// copy one named shape or sprite; does not put in main shape list
|
|
SHAPEHEADER * CopyNamedShapePtr (RIFFHANDLE h, char const * shapename)
|
|
{
|
|
return CreateShapeFromRif(h,shapename);
|
|
}
|
|
|
|
// copy one named shape or sprite; put it in the main shape list
|
|
int CopyNamedShapeMSL (RIFFHANDLE h, char const * shapename)
|
|
{
|
|
int listpos = GetMSLPos();
|
|
SHAPEHEADER * shp = CreateShapeFromRif(h,shapename,listpos);
|
|
if (shp)
|
|
{
|
|
h->shape_nums.add_entry(listpos);
|
|
mainshapelist[listpos] = shp;
|
|
return listpos;
|
|
}
|
|
else
|
|
{
|
|
FreeMSLPos(listpos);
|
|
return GLS_NOTINLIST;
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// Functions which do not operate on RIFFHANDLEs and may become obsolete
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
SHAPEHEADER * CopyNamedShape (char const * shapename)
|
|
{
|
|
return CopyNamedShapePtr (current_rif_handle,shapename);
|
|
}
|
|
|
|
/////////////////////////////////////////////
|
|
// Functions for handling the main shape list
|
|
/////////////////////////////////////////////
|
|
|
|
////////////////////////////////////////////////
|
|
// Functions retrieving data about loaded shapes
|
|
////////////////////////////////////////////////
|
|
|
|
// gets the main shape list position of a shape loaded into the msl
|
|
int GetLoadedShapeMSL(char const * shapename)
|
|
{
|
|
ShapeInMSL const * sim = ShapeInMSL::GetByName(shapename);
|
|
|
|
if (sim)
|
|
return sim->Listpos();
|
|
else
|
|
return GLS_NOTINLIST;
|
|
}
|
|
|
|
// ditto, but returns a pointer; the shape need not be in the msl
|
|
SHAPEHEADER * GetLoadedShapePtr(char const * shapename)
|
|
{
|
|
ShapeInMSL const * sim = ShapeInMSL::GetByName(shapename);
|
|
|
|
if (sim)
|
|
return sim->Shptr();
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
// gets name of shape from msl pos
|
|
char const * GetMSLLoadedShapeName(int listpos)
|
|
{
|
|
ShapeInMSL const * sim = ShapeInMSL::GetByMSL(listpos);
|
|
|
|
if (sim)
|
|
return sim->Name();
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
// gets name of shape from pointer; the shape need not be in msl
|
|
char const * GetPtrLoadedShapeName(SHAPEHEADER * shptr)
|
|
{
|
|
ShapeInMSL const * sim = ShapeInMSL::GetByPtr(shptr);
|
|
|
|
if (sim)
|
|
return sim->Name();
|
|
else
|
|
return 0;
|
|
}
|
|
|
|
// free a reference to a named shape if it exists - not necessary since these are all tidied up
|
|
void FreeShapeNameReference(SHAPEHEADER * shptr)
|
|
{
|
|
for (LIF<ShapeInMSL*> search(&msl_shapes); !search.done(); search.next())
|
|
{
|
|
if (search()->Shptr() == shptr)
|
|
{
|
|
delete search();
|
|
search.delete_current();
|
|
break;
|
|
}
|
|
}
|
|
|
|
return;
|
|
}
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
// Initializing, deallocating of shapes, mainly hooks for project specific fns
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
// delete a shape by the shapeheader
|
|
void DeallocateLoadedShapePtr(SHAPEHEADER * shp)
|
|
{
|
|
DeallocateLoadedShapeheader(shp);
|
|
|
|
FreeShapeNameReference(shp);
|
|
}
|
|
|
|
// delete a shape by the shape list number
|
|
void DeallocateLoadedShapeMSL(RIFFHANDLE h, int list_pos)
|
|
{
|
|
h->shape_nums.delete_entry(list_pos);
|
|
|
|
DeallocateLoadedShapeheader(mainshapelist[list_pos]);
|
|
|
|
FreeMSLPos(list_pos);
|
|
|
|
for(LIF<ShapeInMSL*> msl_shape_lif(&msl_shapes);!msl_shape_lif.done();msl_shape_lif.next())
|
|
{
|
|
if(list_pos==msl_shape_lif()->Listpos())
|
|
{
|
|
delete msl_shape_lif();
|
|
msl_shape_lif.delete_current();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void DeallocateRifLoadedShapeheader(SHAPEHEADER * shp)
|
|
{
|
|
// because the SHAPEHEADER is calloced, we can
|
|
// just delete the arrays we want
|
|
|
|
#if !StandardShapeLanguage
|
|
#error Must have standard shape language
|
|
#endif
|
|
|
|
int max_num_texs = 0;
|
|
int i;
|
|
|
|
if(shp->animation_header)
|
|
{
|
|
// so it gets deallocated properly
|
|
shp->points[0] = 0;
|
|
shp->sh_normals[0] = 0;
|
|
shp->sh_vnormals[0] = 0;
|
|
}
|
|
if (shp->sh_fragdesc)
|
|
{
|
|
DeallocateFragments(shp,shp->sh_fragdesc);
|
|
}
|
|
|
|
#if !USE_LEVEL_MEMORY_POOL
|
|
if (shp->points)
|
|
{
|
|
if (*shp->points) DeallocateMem(*shp->points);
|
|
DeallocateMem(shp->points);
|
|
}
|
|
if (shp->sh_normals)
|
|
{
|
|
if (*shp->sh_normals) DeallocateMem(*shp->sh_normals);
|
|
DeallocateMem(shp->sh_normals);
|
|
}
|
|
if (shp->sh_vnormals)
|
|
{
|
|
if (*shp->sh_vnormals) DeallocateMem(*shp->sh_vnormals);
|
|
DeallocateMem(shp->sh_vnormals);
|
|
}
|
|
if (shp->sh_extraitemdata)
|
|
DeallocateMem(shp->sh_extraitemdata);
|
|
/* the items are allocated in one big bunch
|
|
// 9 int's per item (to make bsp simple)
|
|
// this should be changed if it is to be done
|
|
// a different way
|
|
*/
|
|
if (shp->items)
|
|
{
|
|
if(shp->shapeflags & ShapeFlag_MultiViewSprite)
|
|
{
|
|
TXANIMHEADER** thlist=(TXANIMHEADER**)shp->sh_textures[0];
|
|
for(int j=1;thlist[j]!=0;j++)
|
|
{
|
|
int k;
|
|
TXANIMHEADER* th=thlist[j];
|
|
for(k=0;k<th->txa_numframes;k++)
|
|
{
|
|
txanimframe_mvs* tf=(txanimframe_mvs*)&th->txa_framedata[k];
|
|
if(tf->txf_uvdata[0])DeallocateMem(tf->txf_uvdata[0]);
|
|
if(tf->txf_uvdata)DeallocateMem(tf->txf_uvdata);
|
|
if(tf->txf_images)DeallocateMem(tf->txf_images);
|
|
}
|
|
if(th->txa_framedata)DeallocateMem (th->txa_framedata);
|
|
DeallocateMem (th);
|
|
}
|
|
DeallocateMem (thlist);
|
|
shp->sh_textures[0]=0;
|
|
}
|
|
else
|
|
{
|
|
for (i=0; i<shp->numitems; i++)
|
|
{
|
|
if (is_textured(shp->items[i][0]))
|
|
{
|
|
int UVIndex = (shp->items[i][3] &0xffff0000) >> 16;
|
|
max_num_texs = max (max_num_texs, shp->items[i][3] &0x7fff);
|
|
if(shp->items[i][2]& iflag_txanim)
|
|
{
|
|
int j;
|
|
TXANIMHEADER** thlist=(TXANIMHEADER**)shp->sh_textures[UVIndex];
|
|
for(j=1;thlist[j]!=0;j++)
|
|
{
|
|
int k;
|
|
TXANIMHEADER* th=thlist[j];
|
|
for(k=0;k<th->txa_numframes;k++)
|
|
{
|
|
if(th->txa_framedata[k].txf_uvdata)DeallocateMem(th->txa_framedata[k].txf_uvdata);
|
|
}
|
|
if(th->txa_framedata)DeallocateMem (th->txa_framedata);
|
|
DeallocateMem (th);
|
|
}
|
|
DeallocateMem (thlist);
|
|
shp->sh_textures[UVIndex]=0;
|
|
}
|
|
else
|
|
{
|
|
if(shp->sh_textures[UVIndex])DeallocateMem(shp->sh_textures[UVIndex]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
DeallocateMem (*shp->items);
|
|
DeallocateMem (shp->items);
|
|
}
|
|
|
|
if (shp->sh_textures)
|
|
{
|
|
DeallocateMem (shp->sh_textures);
|
|
}
|
|
|
|
if (shp->sh_localtextures)
|
|
{
|
|
for (i=0; i<(max_num_texs+1); i++)
|
|
{
|
|
DeallocateMem (shp->sh_localtextures[i]);
|
|
}
|
|
DeallocateMem (shp->sh_localtextures);
|
|
}
|
|
|
|
|
|
|
|
#if SupportTrackOptimisation
|
|
if (shp->sh_track_data)
|
|
DeallocateMem(shp->sh_track_data);
|
|
#endif
|
|
if (shp->sh_instruction)
|
|
DeallocateMem(shp->sh_instruction);
|
|
#if SupportBSP
|
|
if (shp->sh_bsp_blocks)
|
|
DeallocateMem(shp->sh_bsp_blocks);
|
|
#endif
|
|
|
|
if(shp->animation_header)
|
|
{
|
|
shp->animation_header->num_shapes_using_this--;
|
|
if(shp->animation_header->num_shapes_using_this==0)
|
|
{
|
|
shapeanimationheader* sah=shp->animation_header;
|
|
for(int i=0;i<sah->num_sequences;i++)
|
|
{
|
|
shapeanimationsequence* sas=&sah->anim_sequences[i];
|
|
for(int j=0;j<sas->num_frames;j++)
|
|
{
|
|
shapeanimationframe*saf=&sas->anim_frames[j];
|
|
DeallocateMem(saf->vertices);
|
|
DeallocateMem(saf->item_normals);
|
|
}
|
|
if(sas->vertex_normals)DeallocateMem(sas->vertex_normals);
|
|
if(sas->anim_frames)DeallocateMem(sas->anim_frames);
|
|
}
|
|
DeallocateMem(sah->anim_sequences);
|
|
DeallocateMem(sah);
|
|
}
|
|
}
|
|
|
|
if(shp->shape_degradation_array)
|
|
{
|
|
DeallocateMem(shp->shape_degradation_array);
|
|
}
|
|
|
|
DeallocateMem(shp);
|
|
#endif //!USE_LEVEL_MEMORY_POOL
|
|
}
|
|
|
|
///////
|
|
// Misc
|
|
///////
|
|
|
|
// return TRUE if the poly item type corresponds to a textured polygon
|
|
BOOL is_textured (int type)
|
|
{
|
|
if (
|
|
type == I_2dTexturedPolygon
|
|
|| type == I_Gouraud2dTexturedPolygon
|
|
|| type == I_3dTexturedPolygon
|
|
|| type == I_Gouraud3dTexturedPolygon
|
|
|| type == I_ZB_2dTexturedPolygon
|
|
|| type == I_ZB_Gouraud2dTexturedPolygon
|
|
|| type == I_ZB_3dTexturedPolygon
|
|
|| type == I_ZB_Gouraud3dTexturedPolygon
|
|
)
|
|
{
|
|
return(TRUE);
|
|
}
|
|
return(FALSE);
|
|
}
|
|
|
|
|
|
#if SupportModules
|
|
|
|
// static Object_Chunk ** o_chunk_array;
|
|
|
|
void copy_to_module (Object_Chunk * ob, int mod_pos, int shplst_pos)
|
|
{
|
|
Object_Project_Data_Chunk * opdc = 0;
|
|
Map_Block_Chunk * mapblok = 0;
|
|
Strategy_Chunk * strat = 0;
|
|
|
|
MODULEMAPBLOCK * Map = (MODULEMAPBLOCK *) PoolAllocateMem (sizeof(MODULEMAPBLOCK));
|
|
|
|
*Map = Empty_Module_Map;
|
|
|
|
MainScene.sm_module[mod_pos].m_mapptr = Map;
|
|
MainScene.sm_module[mod_pos].name = (char *) PoolAllocateMem (strlen (ob->object_data.o_name)+1);
|
|
strcpy (MainScene.sm_module[mod_pos].name, ob->object_data.o_name);
|
|
|
|
*((int *)MainScene.sm_module[mod_pos].m_name) = mod_pos + ONE_FIXED;
|
|
// add 65536 to this value to this value to preserve 0
|
|
|
|
Chunk * pChunk = ob->lookup_single_child("OBJPRJDT");
|
|
if (pChunk) opdc = (Object_Project_Data_Chunk *)pChunk;
|
|
if (opdc)
|
|
{
|
|
pChunk = opdc->lookup_single_child("MAPBLOCK");
|
|
if (pChunk) mapblok = (Map_Block_Chunk *)pChunk;
|
|
pChunk = opdc->lookup_single_child("STRATEGY");
|
|
if (pChunk) strat = (Strategy_Chunk *)pChunk;
|
|
}
|
|
|
|
if (mapblok)
|
|
{
|
|
Map->MapType = mapblok->map_data.MapType;
|
|
Map->MapFlags= mapblok->map_data.MapFlags;
|
|
#if (StandardStrategyAndCollisions || IntermediateSSACM)
|
|
Map->MapCType = mapblok->map_data.MapCType;
|
|
Map->MapCGameType = mapblok->map_data.MapCGameType;
|
|
Map->MapCStrategyS = mapblok->map_data.MapCStrategyS;
|
|
Map->MapCStrategyL = mapblok->map_data.MapCStrategyL;
|
|
#endif
|
|
Map->MapInteriorType = mapblok->map_data.MapInteriorType;
|
|
// Map->MapLightType = mapblok->map_data.MapLightType;
|
|
// Map->MapMass = mapblok->map_data.MapMass;
|
|
// Map->MapNewtonV.vx = mapblok->map_data.MapNewtonV.vx;
|
|
// Map->MapNewtonV.vy = mapblok->map_data.MapNewtonV.vy;
|
|
// Map->MapNewtonV.vz = mapblok->map_data.MapNewtonV.vz;
|
|
// Map->MapOrigin.vx = mapblok->map_data.MapOrigin.vx;
|
|
// Map->MapOrigin.vy = mapblok->map_data.MapOrigin.vy;
|
|
// Map->MapOrigin.vz = mapblok->map_data.MapOrigin.vz;
|
|
// Map->MapViewType = mapblok->map_data.MapViewType;
|
|
}
|
|
|
|
#if (StandardStrategyAndCollisions || IntermediateSSACM)
|
|
if (strat)
|
|
{
|
|
Map->MapStrategy = strat->strategy_data.Strategy;
|
|
}
|
|
#endif
|
|
|
|
Map->MapShape = shplst_pos;
|
|
|
|
Map->MapWorld.vx = (int) (ob->object_data.location.x*local_scale);
|
|
Map->MapWorld.vy = (int) (ob->object_data.location.y*local_scale);
|
|
Map->MapWorld.vz = (int) (ob->object_data.location.z*local_scale);
|
|
|
|
#if 0
|
|
QUAT q;
|
|
|
|
q.quatx = (int) (ob->object_data.orientation.x*ONE_FIXED);
|
|
q.quaty = (int) (ob->object_data.orientation.y*ONE_FIXED);
|
|
q.quatz = (int) (ob->object_data.orientation.z*ONE_FIXED);
|
|
q.quatw = (int) (ob->object_data.orientation.w*ONE_FIXED);
|
|
|
|
|
|
MATRIXCH m;
|
|
|
|
QuatToMat (&q, &m);
|
|
|
|
EULER e;
|
|
|
|
MatrixToEuler(&m, &e);
|
|
|
|
Map->MapEuler.EulerX = -e.EulerX;
|
|
Map->MapEuler.EulerY = -e.EulerY;
|
|
Map->MapEuler.EulerZ = -e.EulerZ;
|
|
|
|
#endif
|
|
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
void SetupAnimOnTriangle(SHAPEHEADER* shp,TEXANIM* ta,int poly, int * local_tex_index_nos)
|
|
{
|
|
if(!is_textured(shp->items[poly][0]))return;
|
|
txanimheader** thlist=(txanimheader**)PoolAllocateMem((ta->NumSeq+2)*sizeof(txanimheader*));
|
|
thlist[0]=0;
|
|
thlist[ta->NumSeq+1]=0;
|
|
for(int i=0;i<ta->NumSeq;i++)
|
|
{
|
|
thlist[i+1]=(txanimheader*)PoolAllocateMem(sizeof(txanimheader));
|
|
txanimheader* th=thlist[i+1];
|
|
|
|
FrameList* fl=ta->Seq[i];
|
|
th->txa_flags=fl->Flags;
|
|
if(!(ta->AnimFlags & AnimFlag_NotPlaying))th->txa_flags|=txa_flag_play;
|
|
th->txa_numframes=fl->NumFrames+1;
|
|
if(fl->Flags & txa_flag_nointerptofirst)
|
|
{
|
|
th->txa_flags&=~txa_flag_nointerptofirst;
|
|
th->txa_numframes--;
|
|
}
|
|
th->txa_currentframe=0;
|
|
th->txa_state=0;
|
|
th->txa_maxframe=(th->txa_numframes-1)<<16;
|
|
th->txa_speed=fl->Speed;
|
|
th->txa_framedata=(txanimframe*)PoolAllocateMem(th->txa_numframes*sizeof(txanimframe));
|
|
th->txa_anim_id=ta->Identifier;
|
|
|
|
txanimframe* tf;
|
|
for(int j=0;j<th->txa_numframes;j++)
|
|
{
|
|
tf=&th->txa_framedata[j];
|
|
tf->txf_flags=0;
|
|
tf->txf_scale=ONE_FIXED;
|
|
tf->txf_scalex=0;
|
|
tf->txf_scaley=0;
|
|
tf->txf_orient=0;
|
|
tf->txf_orientx=0;
|
|
tf->txf_orienty=0;
|
|
tf->txf_numuvs=3;
|
|
tf->txf_uvdata=(int*)PoolAllocateMem(6*sizeof(int));
|
|
if(j==fl->NumFrames)
|
|
{
|
|
tf->txf_image=local_tex_index_nos[fl->Textures[0]];
|
|
for(int k=0;k<6;k++)
|
|
{
|
|
tf->txf_uvdata[k]=fl->UVCoords[k]<<16;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
tf->txf_image=local_tex_index_nos[fl->Textures[j]];
|
|
for(int k=0;k<6;k++)
|
|
{
|
|
tf->txf_uvdata[k]=fl->UVCoords[j*6+k]<<16;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
int UVIndex=shp->items[poly][3]>>16;
|
|
#if !USE_LEVEL_MEMORY_POOL
|
|
if(shp->sh_textures[UVIndex])DeallocateMem(shp->sh_textures[UVIndex]);
|
|
#endif
|
|
shp->sh_textures[UVIndex]=(int*)thlist;
|
|
shp->items[poly][2]|=iflag_txanim;
|
|
shp->items[poly][3]=UVIndex<<16;
|
|
|
|
}
|
|
void SetupAnimOnQuad(Shape_Chunk* sc,SHAPEHEADER* shp,TEXANIM* ta1,TEXANIM* ta2,int poly, int * local_tex_index_nos)
|
|
{
|
|
if(!is_textured(shp->items[poly][0]))return;
|
|
if(ta1->ID!=ta2->ID)return;
|
|
int VertConv[3];//conversion between vert nos in triangles and vert nos in quad
|
|
int VertFrom,VertTo;//for remaining vert in second poly
|
|
VertTo=6;
|
|
for(int i=0;i<3;i++)
|
|
{
|
|
for(int j=0;j<4;j++)
|
|
{
|
|
if(sc->shape_data.poly_list[ta1->poly].vert_ind[i]==(shp->items[poly][j+4]))break;
|
|
}
|
|
if(j==4)return;
|
|
VertConv[i]=j;
|
|
VertTo-=j;
|
|
}
|
|
for(i=0;i<3;i++)
|
|
{
|
|
if(sc->shape_data.poly_list[ta2->poly].vert_ind[i]==(shp->items[poly][4+VertTo]))break;
|
|
}
|
|
if(i==3)return;
|
|
VertFrom=i;
|
|
|
|
txanimheader** thlist=(txanimheader**)PoolAllocateMem((ta1->NumSeq+2)*sizeof(txanimheader*));
|
|
thlist[0]=0;
|
|
thlist[ta1->NumSeq+1]=0;
|
|
for(i=0;i<ta1->NumSeq;i++)
|
|
{
|
|
thlist[i+1]=(txanimheader*)PoolAllocateMem(sizeof(txanimheader));
|
|
txanimheader* th=thlist[i+1];
|
|
FrameList* fl1=ta1->Seq[i];
|
|
FrameList* fl2=ta2->Seq[i];
|
|
th->txa_flags=fl1->Flags;
|
|
if(!(ta1->AnimFlags & AnimFlag_NotPlaying))th->txa_flags|=txa_flag_play;
|
|
th->txa_numframes=fl1->NumFrames+1;
|
|
if(fl1->Flags & txa_flag_nointerptofirst)
|
|
{
|
|
th->txa_flags&=~txa_flag_nointerptofirst;
|
|
th->txa_numframes--;
|
|
}
|
|
th->txa_currentframe=0;
|
|
th->txa_state=0;
|
|
th->txa_maxframe=(th->txa_numframes-1)<<16;
|
|
th->txa_speed=fl1->Speed;
|
|
th->txa_framedata=(txanimframe*)PoolAllocateMem(th->txa_numframes*sizeof(txanimframe));
|
|
th->txa_anim_id=ta1->Identifier;
|
|
|
|
txanimframe* tf;
|
|
for(int j=0;j<th->txa_numframes;j++)
|
|
{
|
|
tf=&th->txa_framedata[j];
|
|
tf->txf_flags=0;
|
|
tf->txf_scale=ONE_FIXED;
|
|
tf->txf_scalex=0;
|
|
tf->txf_scaley=0;
|
|
tf->txf_orient=0;
|
|
tf->txf_orientx=0;
|
|
tf->txf_orienty=0;
|
|
tf->txf_numuvs=4;
|
|
tf->txf_uvdata=(int*)PoolAllocateMem(8*sizeof(int));
|
|
if(j==fl1->NumFrames)
|
|
{
|
|
tf->txf_image=local_tex_index_nos[fl1->Textures[0]];
|
|
for(int k=0;k<3;k++)
|
|
{
|
|
tf->txf_uvdata[VertConv[k]*2]=fl1->UVCoords[k*2]<<16;
|
|
tf->txf_uvdata[VertConv[k]*2+1]=fl1->UVCoords[k*2+1]<<16;
|
|
}
|
|
tf->txf_uvdata[VertTo*2]=fl2->UVCoords[VertFrom*2]<<16;
|
|
tf->txf_uvdata[VertTo*2+1]=fl2->UVCoords[VertFrom*2+1]<<16;
|
|
|
|
}
|
|
else
|
|
{
|
|
tf->txf_image=local_tex_index_nos[fl1->Textures[j]];
|
|
for(int k=0;k<3;k++)
|
|
{
|
|
tf->txf_uvdata[VertConv[k]*2]=fl1->UVCoords[j*6+k*2]<<16;
|
|
tf->txf_uvdata[VertConv[k]*2+1]=fl1->UVCoords[j*6+k*2+1]<<16;
|
|
}
|
|
tf->txf_uvdata[VertTo*2]=fl2->UVCoords[j*6+VertFrom*2]<<16;
|
|
tf->txf_uvdata[VertTo*2+1]=fl2->UVCoords[j*6+VertFrom*2+1]<<16;
|
|
}
|
|
}
|
|
}
|
|
int UVIndex=shp->items[poly][3]>>16;
|
|
#if !USE_LEVEL_MEMORY_POOL
|
|
if(shp->sh_textures[UVIndex])DeallocateMem(shp->sh_textures[UVIndex]);
|
|
#endif
|
|
shp->sh_textures[UVIndex]=(int*)thlist;
|
|
shp->items[poly][2]|=iflag_txanim;
|
|
shp->items[poly][3]=UVIndex<<16;
|
|
|
|
|
|
}
|
|
void SetupAnimatedTextures(Shape_Chunk* sc,SHAPEHEADER* shp,Animation_Chunk* ac,Shape_Merge_Data_Chunk* smdc, int * local_tex_index_nos)
|
|
{
|
|
//create conversion between unmerged poly nos and merged poly nos
|
|
int* PolyConv=0;
|
|
int* mgd=0;
|
|
|
|
if(smdc)
|
|
{
|
|
mgd=smdc->merge_data;
|
|
PolyConv=new int[smdc->num_polys];
|
|
for(int i=0, j=0;i<smdc->num_polys;i++)
|
|
{
|
|
if(mgd[i]==-1)
|
|
{
|
|
PolyConv[i]=j;
|
|
j++;
|
|
}
|
|
else if(mgd[i]>i)
|
|
{
|
|
if(shp->items[j][7]==-1)
|
|
{
|
|
//quad in merge data,but not actually merged;
|
|
PolyConv[i]=j;
|
|
j++;
|
|
PolyConv[mgd[i]]=j;
|
|
j++;
|
|
}
|
|
else
|
|
{
|
|
PolyConv[i]=j;
|
|
PolyConv[mgd[i]]=j;
|
|
j++;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
for(i=0;i<ac->NumPolys;i++)
|
|
{
|
|
TEXANIM* ta1,*ta2;
|
|
ta1=ac->AnimList[i];
|
|
if(mgd[ta1->poly]==-1)
|
|
{
|
|
SetupAnimOnTriangle(shp,ta1,PolyConv[ta1->poly], local_tex_index_nos);
|
|
}
|
|
else if(mgd[ta1->poly]>ta1->poly)
|
|
{
|
|
for(j=0;j<ac->NumPolys;j++)
|
|
{
|
|
if(ac->AnimList[j]->poly==mgd[ta1->poly])break;
|
|
}
|
|
if(j<ac->NumPolys)
|
|
{
|
|
ta2=ac->AnimList[j];
|
|
if(PolyConv[ta1->poly]==PolyConv[ta2->poly])
|
|
{
|
|
SetupAnimOnQuad(sc,shp,ta1,ta2,PolyConv[ta1->poly], local_tex_index_nos);
|
|
}
|
|
else
|
|
{
|
|
SetupAnimOnTriangle(shp,ta1,PolyConv[ta1->poly], local_tex_index_nos);
|
|
SetupAnimOnTriangle(shp,ta2,PolyConv[ta2->poly], local_tex_index_nos);
|
|
}
|
|
}
|
|
else if(PolyConv[ta1->poly]!=PolyConv[mgd[ta1->poly]])
|
|
{
|
|
SetupAnimOnTriangle(shp,ta1,PolyConv[ta1->poly], local_tex_index_nos);
|
|
}
|
|
}
|
|
}
|
|
if(PolyConv)delete [] PolyConv;
|
|
}
|
|
else
|
|
{
|
|
for(int i=0;i<ac->NumPolys;i++)
|
|
{
|
|
SetupAnimOnTriangle(shp,ac->AnimList[i],ac->AnimList[i]->poly, local_tex_index_nos);
|
|
}
|
|
}
|
|
shp->shapeflags|=ShapeFlag_HasTextureAnimation;
|
|
}
|
|
|
|
|
|
void SetupAnimatingShape(Shape_Chunk* sc,SHAPEHEADER* shp, Shape_Merge_Data_Chunk* smdc)
|
|
{
|
|
//create conversion between unmerged poly nos and merged poly nos
|
|
int* PolyConv=0;
|
|
int* mgd=0;
|
|
|
|
PolyConv=new int[smdc->num_polys];
|
|
|
|
if(smdc)
|
|
{
|
|
mgd=smdc->merge_data;
|
|
for(int i=0, j=0;i<smdc->num_polys;i++)
|
|
{
|
|
if(mgd[i]==-1)
|
|
{
|
|
PolyConv[i]=j;
|
|
j++;
|
|
}
|
|
else if(mgd[i]>i)
|
|
{
|
|
if(shp->items[j][7]==-1)
|
|
{
|
|
//quad in merge data,but not actually merged;
|
|
PolyConv[i]=j;
|
|
j++;
|
|
PolyConv[mgd[i]]=j;
|
|
j++;
|
|
}
|
|
else
|
|
{
|
|
PolyConv[i]=j;
|
|
PolyConv[mgd[i]]=j;
|
|
j++;
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
for(int i=0;i<smdc->num_polys;i++)
|
|
{
|
|
PolyConv[i]=i;
|
|
}
|
|
}
|
|
|
|
ChunkVectorInt Centre={0,0,0};
|
|
Chunk * pChunk = sc->lookup_single_child("ANSHCEN2");
|
|
if(pChunk)
|
|
Centre=((Anim_Shape_Centre_Chunk*)pChunk)->Centre;
|
|
|
|
int numseq=0;
|
|
List<Chunk *> chlist;
|
|
sc->lookup_child("ANIMSEQU",chlist);
|
|
for(LIF<Chunk*> chlif(&chlist);!chlif.done();chlif.next())
|
|
{
|
|
Anim_Shape_Sequence_Chunk* assc=(Anim_Shape_Sequence_Chunk*)chlif();
|
|
numseq=max(assc->sequence_data.SequenceNum+1,numseq);
|
|
}
|
|
|
|
shapeanimationheader* sah=(shapeanimationheader*)PoolAllocateMem(sizeof(shapeanimationheader));
|
|
shp->animation_header=sah;
|
|
sah->num_sequences=numseq;
|
|
sah->anim_sequences=(shapeanimationsequence*)PoolAllocateMem(sizeof(shapeanimationsequence)*numseq);
|
|
sah->num_shapes_using_this=1;
|
|
//sah->vertices_store = shp->points[0];
|
|
//sah->item_normals_store = shp->sh_normals[0];
|
|
//sah->vertex_normals_store = shp->sh_vnormals[0];
|
|
|
|
for( int i=0;i<numseq;i++)
|
|
{
|
|
sah->anim_sequences[i].num_frames=0;
|
|
sah->anim_sequences[i].anim_frames=0;
|
|
}
|
|
|
|
|
|
|
|
for(chlif.restart();!chlif.done();chlif.next())
|
|
{
|
|
Anim_Shape_Sequence_Chunk* assc=(Anim_Shape_Sequence_Chunk*)chlif();
|
|
assc->GenerateInterpolatedFrames();
|
|
const ChunkAnimSequence * cas=& assc->sequence_data;
|
|
if(!cas->NumFrames)continue;
|
|
shapeanimationsequence* sas =&sah->anim_sequences[cas->SequenceNum];
|
|
|
|
sas->max_x=(int)((cas->max.x-Centre.x)*local_scale);
|
|
sas->min_x=(int)((cas->min.x-Centre.x)*local_scale);
|
|
sas->max_y=(int)((cas->max.y-Centre.y)*local_scale);
|
|
sas->min_y=(int)((cas->min.y-Centre.y)*local_scale);
|
|
sas->max_z=(int)((cas->max.z-Centre.z)*local_scale);
|
|
sas->min_z=(int)((cas->min.z-Centre.z)*local_scale);
|
|
|
|
int x=max(-sas->min_x,sas->max_x);
|
|
int y=max(-sas->min_y,sas->max_y);
|
|
int z=max(-sas->min_z,sas->max_z);
|
|
sas->radius=sqrt(x*x+y*y+z*z);
|
|
|
|
|
|
sas->vertex_normals=(int*)PoolAllocateMem(sizeof(VECTORCH)*cas->num_verts);
|
|
for(i=0;i<cas->num_verts;i++)
|
|
{
|
|
sas->vertex_normals[i*3]=(int)(cas->v_normal_list[i].x*ONE_FIXED);
|
|
sas->vertex_normals[i*3+1]=(int)(cas->v_normal_list[i].y*ONE_FIXED);
|
|
sas->vertex_normals[i*3+2]=(int)(cas->v_normal_list[i].z*ONE_FIXED);
|
|
}
|
|
|
|
sas->num_frames=cas->NumFrames;
|
|
sas->anim_frames=(shapeanimationframe*)PoolAllocateMem(sizeof(shapeanimationframe)*cas->NumFrames);
|
|
|
|
for(i=0;i<cas->NumFrames;i++)
|
|
{
|
|
const ChunkAnimFrame* caf=cas->Frames[i];
|
|
shapeanimationframe* saf=&sas->anim_frames[i];
|
|
|
|
saf->vertices=(int*)PoolAllocateMem(sizeof(VECTORCH)*caf->num_verts);
|
|
for(int j=0;j<caf->num_verts;j++)
|
|
{
|
|
saf->vertices[j*3]=(int)((caf->v_list[j].x-Centre.x)*local_scale);
|
|
saf->vertices[j*3+1]=(int)((caf->v_list[j].y-Centre.y)*local_scale);
|
|
saf->vertices[j*3+2]=(int)((caf->v_list[j].z-Centre.z)*local_scale);
|
|
}
|
|
|
|
saf->item_normals=(int*) PoolAllocateMem(sizeof(VECTORCH)*shp->numitems);
|
|
for(j=0;j<caf->num_polys;j++)
|
|
{
|
|
saf->item_normals[PolyConv[j]*3]=(int)(caf->p_normal_list[j].x*ONE_FIXED);
|
|
saf->item_normals[PolyConv[j]*3+1]=(int)(caf->p_normal_list[j].y*ONE_FIXED);
|
|
saf->item_normals[PolyConv[j]*3+2]=(int)(caf->p_normal_list[j].z*ONE_FIXED);
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
delete [] PolyConv;
|
|
|
|
|
|
//find a sequence which has some frames;
|
|
shapeanimationsequence* sas=0;
|
|
for(i=0;i<shp->animation_header->num_sequences;i++)
|
|
{
|
|
sas=&shp->animation_header->anim_sequences[i];
|
|
if(sas->num_frames)
|
|
break;
|
|
|
|
}
|
|
GLOBALASSERT(i<shp->animation_header->num_sequences);
|
|
|
|
//copy the pointers for the first frame of this sequence
|
|
#if !USE_LEVEL_MEMORY_POOL
|
|
DeallocateMem(shp->points[0]);
|
|
DeallocateMem(shp->sh_normals[0]);
|
|
DeallocateMem(shp->sh_vnormals[0]);
|
|
#endif
|
|
|
|
shp->points[0]=sas->anim_frames[0].vertices;
|
|
shp->sh_normals[0]=sas->anim_frames[0].item_normals;
|
|
shp->sh_vnormals[0]=sas->vertex_normals;
|
|
}
|
|
|
|
|
|
BOOL copy_to_shapeheader (
|
|
RIFFHANDLE h,
|
|
ChunkShape const & cshp,
|
|
SHAPEHEADER *& shphd,
|
|
Chunk_With_Children * shape,
|
|
int flags,
|
|
int local_max_index,
|
|
int * local_tex_index_nos,
|
|
int /*listpos*/,
|
|
const ChunkObject* object
|
|
)
|
|
{
|
|
ChunkShape merged_cshp;
|
|
const ChunkShape* cshp_ptr;
|
|
|
|
if(shape->lookup_single_child("SHPMRGDT"))
|
|
{
|
|
merged_cshp=cshp;
|
|
pre_process_shape(h,merged_cshp,shape,flags);
|
|
|
|
cshp_ptr=&merged_cshp;
|
|
}
|
|
else
|
|
{
|
|
cshp_ptr=&cshp;
|
|
}
|
|
|
|
shphd = (SHAPEHEADER *) PoolAllocateMem(sizeof(SHAPEHEADER));
|
|
memset(shphd,0,sizeof(SHAPEHEADER));
|
|
|
|
int i,j;
|
|
int * tptr;
|
|
|
|
// header data (note shapeheader is calloced)
|
|
|
|
shphd->numpoints = cshp_ptr->num_verts;
|
|
shphd->numitems = cshp_ptr->num_polys;
|
|
|
|
|
|
shphd->shaperadius = (int) (cshp_ptr->radius*local_scale);
|
|
|
|
shphd->shapemaxx = (int) (cshp_ptr->max.x*local_scale);
|
|
shphd->shapeminx = (int) (cshp_ptr->min.x*local_scale);
|
|
shphd->shapemaxy = (int) (cshp_ptr->max.y*local_scale);
|
|
shphd->shapeminy = (int) (cshp_ptr->min.y*local_scale);
|
|
shphd->shapemaxz = (int) (cshp_ptr->max.z*local_scale);
|
|
shphd->shapeminz = (int) (cshp_ptr->min.z*local_scale);
|
|
|
|
// AllocateMem arrays
|
|
|
|
shphd->points = (int **) PoolAllocateMem (sizeof(int *));
|
|
*(shphd->points) = (int *) PoolAllocateMem (sizeof(int) * shphd->numpoints * 3);
|
|
|
|
shphd->sh_vnormals = (int **) PoolAllocateMem (sizeof(int *));
|
|
*(shphd->sh_vnormals) = (int *) PoolAllocateMem (sizeof(int) * shphd->numpoints * 3);
|
|
|
|
shphd->sh_normals = (int **) PoolAllocateMem (sizeof(int *));
|
|
*(shphd->sh_normals) = (int *) PoolAllocateMem (sizeof(int) * shphd->numitems * 3);
|
|
|
|
// for textures
|
|
if (cshp_ptr->num_uvs)
|
|
shphd->sh_textures = (int **) PoolAllocateMem (sizeof(int *) * cshp_ptr->num_uvs);
|
|
if (cshp_ptr->num_texfiles)
|
|
shphd->sh_localtextures = (char **) PoolAllocateMem (sizeof(char *) * (cshp_ptr->num_texfiles+1));
|
|
|
|
int * item_list;
|
|
|
|
shphd->items = (int **) PoolAllocateMem (sizeof(int *) * shphd->numitems);
|
|
item_list = (int *) PoolAllocateMem (sizeof(int) * shphd->numitems * 9);
|
|
|
|
tptr = *(shphd->points);
|
|
|
|
|
|
|
|
if(object && local_scale!=1)
|
|
{
|
|
//convert from floating point to integers using world coordinates in an attempt to stop
|
|
//tears from being generated
|
|
ChunkVector object_float;
|
|
object_float.x=(double)object->location.x;
|
|
object_float.y=(double)object->location.y;
|
|
object_float.z=(double)object->location.z;
|
|
|
|
VECTORCH object_int;
|
|
object_int.vx=object_float.x*local_scale;
|
|
object_int.vy=object_float.y*local_scale;
|
|
object_int.vz=object_float.z*local_scale;
|
|
|
|
for (i=0; i<shphd->numpoints; i++) {
|
|
tptr[i*3] = (int) ((cshp_ptr->v_list[i].x+object_float.x)*local_scale);
|
|
tptr[i*3 + 1] = (int) ((cshp_ptr->v_list[i].y+object_float.y)*local_scale);
|
|
tptr[i*3 + 2] = (int) ((cshp_ptr->v_list[i].z+object_float.z)*local_scale);
|
|
|
|
tptr[i*3]-=object_int.vx;
|
|
tptr[i*3+1]-=object_int.vy;
|
|
tptr[i*3+2]-=object_int.vz;
|
|
}
|
|
|
|
}
|
|
else
|
|
{
|
|
for (i=0; i<shphd->numpoints; i++) {
|
|
tptr[i*3] = (int) (cshp_ptr->v_list[i].x*local_scale);
|
|
tptr[i*3 + 1] = (int) (cshp_ptr->v_list[i].y*local_scale);
|
|
tptr[i*3 + 2] = (int) (cshp_ptr->v_list[i].z*local_scale);
|
|
}
|
|
}
|
|
|
|
tptr = *(shphd->sh_vnormals);
|
|
|
|
for (i=0; i<shphd->numpoints; i++) {
|
|
tptr[i*3] =(int) (cshp_ptr->v_normal_list[i].x*ONE_FIXED);
|
|
tptr[i*3 + 1] =(int) (cshp_ptr->v_normal_list[i].y*ONE_FIXED);
|
|
tptr[i*3 + 2] =(int) (cshp_ptr->v_normal_list[i].z*ONE_FIXED);
|
|
}
|
|
|
|
tptr = *(shphd->sh_normals);
|
|
|
|
for (i=0; i<shphd->numitems; i++) {
|
|
tptr[i*3] =(int) (cshp_ptr->p_normal_list[i].x*ONE_FIXED);
|
|
tptr[i*3 + 1] =(int) (cshp_ptr->p_normal_list[i].y*ONE_FIXED);
|
|
tptr[i*3 + 2] =(int) (cshp_ptr->p_normal_list[i].z*ONE_FIXED);
|
|
}
|
|
|
|
|
|
for (i=0; i<shphd->numitems; i++)
|
|
shphd->items[i] = &item_list[i*9];
|
|
|
|
int * uv_imnums = 0;
|
|
if (cshp_ptr->num_uvs)
|
|
{
|
|
uv_imnums = new int[cshp_ptr->num_uvs];
|
|
for (i=0; i<cshp_ptr->num_uvs; ++i)
|
|
{
|
|
uv_imnums[i]=-1;
|
|
shphd->sh_textures[i]=0;
|
|
}
|
|
}
|
|
|
|
for (i=0; i<shphd->numitems; i++) {
|
|
|
|
item_list[i*9] = (cshp_ptr->poly_list[i].engine_type);
|
|
item_list[i*9 + 1] = (cshp_ptr->poly_list[i].normal_index * 3);
|
|
item_list[i*9 + 2] = (cshp_ptr->poly_list[i].flags&~ChunkInternalItemFlags);
|
|
item_list[i*9 + 3] = (cshp_ptr->poly_list[i].colour);
|
|
|
|
if ( is_textured(item_list[i*9]) && !( item_list[i*9 + 3] & 0x8000 ) )
|
|
{
|
|
int texno = item_list[i*9 + 3] & 0x7fff;
|
|
int UVIndex= item_list[i*9 + 3]>>16;
|
|
|
|
if (texno <= local_max_index &&
|
|
local_tex_index_nos[texno] != -1 &&
|
|
cshp_ptr->uv_list[UVIndex].num_verts)
|
|
|
|
{
|
|
item_list[i*9 + 3] &= 0xffff0000;
|
|
uv_imnums[item_list[i*9+3]>>16]=local_tex_index_nos[texno];
|
|
item_list[i*9 + 3] += local_tex_index_nos[texno];
|
|
|
|
shphd->sh_textures[UVIndex] = (int *) PoolAllocateMem (sizeof(int) * cshp_ptr->uv_list[UVIndex].num_verts * 2);
|
|
for (j=0; j<cshp_ptr->uv_list[UVIndex].num_verts; j++) {
|
|
(shphd->sh_textures[UVIndex])[(j*2)] = ProcessUVCoord(h,UVC_POLY_U,(int)cshp_ptr->uv_list[UVIndex].vert[j].u,uv_imnums[UVIndex]);
|
|
(shphd->sh_textures[UVIndex])[(j*2)+1] = ProcessUVCoord(h,UVC_POLY_V,(int)cshp_ptr->uv_list[UVIndex].vert[j].v,uv_imnums[UVIndex]);
|
|
}
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
item_list[i*9] = I_Polyline;
|
|
item_list[i*9 + 2] = (cshp_ptr->poly_list[i].flags&~ChunkInternalItemFlags) | iflag_nolight;
|
|
item_list[i*9 + 3] = 0xffffffff;
|
|
}
|
|
}
|
|
|
|
|
|
for (j=0;j<cshp_ptr->poly_list[i].num_verts;j++)
|
|
// item_list[i*9 + 4 +j] = (cshp_ptr->poly_list[i].vert_ind[j] *3);
|
|
/* KJL 12:21:58 9/17/97 - I've removed the annoying *3 */
|
|
item_list[i*9 + 4 +j] = (cshp_ptr->poly_list[i].vert_ind[j]);
|
|
for (;j<5;j++)
|
|
item_list[i*9 + 4 +j] = -1;
|
|
}
|
|
|
|
if (uv_imnums) delete[] uv_imnums;
|
|
|
|
if (cshp_ptr->num_texfiles)
|
|
{
|
|
for (i=0; i<cshp_ptr->num_texfiles; i++) {
|
|
#if john
|
|
shphd->sh_localtextures[i] =
|
|
(char *) PoolAllocateMem (sizeof(char) * (strlen(cshp_ptr->texture_fns[i]) + strlen(TexturesRoot) + 1) );
|
|
sprintf (shphd->sh_localtextures[i],"%s%s",TexturesRoot, cshp_ptr->texture_fns[i]);
|
|
char * dotpos;
|
|
dotpos = strrchr (shphd->sh_localtextures[i], '.');
|
|
sprintf (dotpos,".pg0");
|
|
#else
|
|
shphd->sh_localtextures[i] =
|
|
(char *) PoolAllocateMem (sizeof(char) * (strlen(cshp_ptr->texture_fns[i]) + 1) );
|
|
strcpy (shphd->sh_localtextures[i], cshp_ptr->texture_fns[i]);
|
|
#endif
|
|
}
|
|
shphd->sh_localtextures[i] = 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
SHAPEINSTR * instruct = (SHAPEINSTR *)PoolAllocateMem(sizeof(SHAPEINSTR)*6);
|
|
|
|
shphd->sh_instruction = instruct;
|
|
|
|
|
|
instruct[0].sh_instr = I_ShapePoints; /*I_shapepoints*/
|
|
instruct[0].sh_numitems = shphd->numpoints;
|
|
instruct[0].sh_instr_data = shphd->points;
|
|
|
|
instruct[1].sh_instr = I_ShapeNormals; /*I_shapenormals*/
|
|
instruct[1].sh_numitems = shphd->numitems;
|
|
instruct[1].sh_instr_data = shphd->sh_normals;
|
|
|
|
instruct[2].sh_instr = I_ShapeProject; /*I_shapeproject*/
|
|
instruct[2].sh_numitems = shphd->numpoints;
|
|
instruct[2].sh_instr_data = shphd->points;
|
|
|
|
instruct[3].sh_instr = I_ShapeVNormals; /*I_shapevnormals*/
|
|
instruct[3].sh_numitems = shphd->numpoints;
|
|
instruct[3].sh_instr_data = shphd->sh_vnormals;
|
|
|
|
instruct[4].sh_instr = I_ShapeItems;
|
|
instruct[4].sh_numitems = shphd->numitems;
|
|
instruct[4].sh_instr_data = shphd->items;
|
|
|
|
instruct[5].sh_instr = I_ShapeEnd; /*I_shapeEND*/
|
|
instruct[5].sh_numitems = 0;
|
|
instruct[5].sh_instr_data = 0;
|
|
|
|
|
|
Chunk * pchAnim = shape->lookup_single_child("TEXTANIM");
|
|
if(pchAnim)
|
|
{
|
|
Animation_Chunk* ac=(Animation_Chunk*)pchAnim;
|
|
Shape_Merge_Data_Chunk* smdc=0;
|
|
Chunk * pCh = shape->lookup_single_child("SHPMRGDT");
|
|
if(pCh) smdc=(Shape_Merge_Data_Chunk*)pCh;
|
|
SetupAnimatedTextures((Shape_Chunk*)shape,shphd,ac,smdc, local_tex_index_nos);
|
|
}
|
|
|
|
if(shape->count_children("ANIMSEQU"))
|
|
{
|
|
Shape_Merge_Data_Chunk* smdc=0;
|
|
Chunk * pCh=shape->lookup_single_child("SHPMRGDT");
|
|
if(pCh) smdc=(Shape_Merge_Data_Chunk*)pCh;
|
|
SetupAnimatingShape((Shape_Chunk*)shape,shphd,smdc);
|
|
}
|
|
|
|
return TRUE;
|
|
|
|
|
|
}
|
|
BOOL copy_preprocessed_to_shapeheader (
|
|
RIFFHANDLE h,
|
|
Shape_Preprocessed_Data_Chunk* spdc,
|
|
SHAPEHEADER *& shphd,
|
|
Chunk_With_Children * shape,
|
|
int /*flags*/,
|
|
int local_max_index,
|
|
int * local_tex_index_nos,
|
|
int /*listpos*/,
|
|
const ChunkObject* object
|
|
)
|
|
{
|
|
shphd = (SHAPEHEADER*)spdc->GetMemoryBlock();
|
|
|
|
for (int i=0; i<shphd->numitems; i++)
|
|
{
|
|
if(is_textured(shphd->items[i][0]))
|
|
{
|
|
int texno = shphd->items[i][3] & 0x7fff;
|
|
if (texno <= local_max_index &&
|
|
local_tex_index_nos[texno] != -1)
|
|
|
|
{
|
|
shphd->items[i][3] &= 0xffff0000;
|
|
shphd->items[i][3] += local_tex_index_nos[texno];
|
|
|
|
|
|
}
|
|
else
|
|
{
|
|
shphd->items[i][0] = I_Polyline;
|
|
shphd->items[i][2] |=iflag_nolight;
|
|
shphd->items[i][3] = 0xffffffff;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
return TRUE;
|
|
|
|
|
|
}
|
|
|
|
BOOL copy_sprite_to_shapeheader (RIFFHANDLE h, SHAPEHEADER *& shphd,Sprite_Header_Chunk* shc, int listpos)
|
|
{
|
|
Chunk * pChunk=shc->lookup_single_child("SPRITEPC");
|
|
if(!pChunk)
|
|
{
|
|
return 0;
|
|
}
|
|
PC_Sprite_Chunk* sc=(PC_Sprite_Chunk*)pChunk;
|
|
|
|
pChunk = shc->lookup_single_child("SPRISIZE");
|
|
if(!pChunk)
|
|
{
|
|
return 0;
|
|
}
|
|
Sprite_Size_Chunk* ssc=(Sprite_Size_Chunk*)pChunk;
|
|
|
|
Sprite_Extent_Chunk* sec=0;
|
|
pChunk=shc->lookup_single_child("SPREXTEN");
|
|
if(pChunk)
|
|
sec=(Sprite_Extent_Chunk*)pChunk;
|
|
|
|
pChunk=shc->lookup_single_child("SPRBMPSC");
|
|
if(!pChunk)
|
|
{
|
|
return 0;
|
|
}
|
|
Sprite_Bitmap_Scale_Chunk* sbsc=(Sprite_Bitmap_Scale_Chunk*)pChunk;
|
|
|
|
shphd = (SHAPEHEADER *) PoolAllocateMem(sizeof(SHAPEHEADER));
|
|
memset(shphd,0,sizeof(SHAPEHEADER));
|
|
|
|
int i;
|
|
int * tptr;
|
|
int * BmpConv=0;
|
|
int local_max_index;
|
|
String sprite_name;
|
|
|
|
|
|
|
|
Bitmap_List_Store_Chunk * blsc = 0;
|
|
|
|
|
|
pChunk = shc->lookup_single_child("BMPLSTST");
|
|
if (pChunk)
|
|
{
|
|
blsc = (Bitmap_List_Store_Chunk *) pChunk;
|
|
}
|
|
pChunk = shc->lookup_single_child("RIFFNAME");
|
|
if (pChunk)
|
|
{
|
|
sprite_name = ((RIF_Name_Chunk *)pChunk)->rif_name;
|
|
msl_shapes.add_entry(new ShapeInMSL(shphd,sprite_name,listpos));
|
|
}
|
|
|
|
if (blsc)
|
|
{
|
|
// load in the textures from the shape
|
|
|
|
local_max_index = 0;
|
|
for (LIF<BMP_Name> bns (&blsc->bmps); !bns.done(); bns.next())
|
|
{
|
|
local_max_index = max(bns().index,local_max_index);
|
|
}
|
|
|
|
BmpConv = new int [local_max_index+1];
|
|
for (i=0; i<=local_max_index; i++)
|
|
{
|
|
BmpConv[i] = -1;
|
|
}
|
|
|
|
if (Env_Chunk == 0)
|
|
Env_Chunk = h->fc;
|
|
// JH 17-2-97 -- image loaders have changed to avoid loading the same image twice
|
|
for (bns.restart() ; !bns.done(); bns.next())
|
|
{
|
|
if(bns().flags & ChunkBMPFlag_NotInPC) continue;
|
|
|
|
String tex;
|
|
if (bns().flags & ChunkBMPFlag_IFF)
|
|
{
|
|
tex = bns().filename;
|
|
}
|
|
else
|
|
{
|
|
tex = sprite_name;
|
|
tex += "\\";
|
|
tex += bns().filename;
|
|
}
|
|
|
|
int imgnum = load_rif_bitmap(bns().filename,bns().flags);
|
|
if (GEI_NOTLOADED != imgnum)
|
|
BmpConv[bns().index] = imgnum;
|
|
}
|
|
|
|
}
|
|
// header data (note shapeheader is calloced)
|
|
|
|
shphd->numpoints = 4;
|
|
shphd->numitems = 1;
|
|
|
|
|
|
shphd->shaperadius =ssc->radius*GlobalScale;
|
|
|
|
if(sec)
|
|
{
|
|
shphd->shapemaxx =sec->maxx*GlobalScale;
|
|
shphd->shapeminx =sec->minx*GlobalScale;
|
|
shphd->shapemaxy =sec->maxy*GlobalScale;
|
|
shphd->shapeminy =sec->miny*GlobalScale;
|
|
|
|
}
|
|
else
|
|
{
|
|
shphd->shapemaxx =ssc->maxx*GlobalScale;
|
|
shphd->shapeminx =-ssc->maxx*GlobalScale;
|
|
shphd->shapemaxy =ssc->maxy*GlobalScale;
|
|
shphd->shapeminy =-ssc->maxy*GlobalScale;
|
|
}
|
|
shphd->shapemaxz =501*GlobalScale;
|
|
shphd->shapeminz =-501*GlobalScale;
|
|
|
|
// AllocateMem arrays
|
|
|
|
shphd->points = (int **) PoolAllocateMem (sizeof(int *));
|
|
*(shphd->points) = (int *) PoolAllocateMem (sizeof(int) * shphd->numpoints * 3);
|
|
|
|
shphd->sh_vnormals = (int **) PoolAllocateMem (sizeof(int *));
|
|
*(shphd->sh_vnormals) = (int *) PoolAllocateMem (sizeof(int) * shphd->numpoints * 3);
|
|
|
|
shphd->sh_normals = (int **) PoolAllocateMem (sizeof(int *));
|
|
*(shphd->sh_normals) = (int *) PoolAllocateMem (sizeof(int) * shphd->numitems * 3);
|
|
|
|
shphd->sh_textures = (int **) PoolAllocateMem (sizeof(int *));
|
|
|
|
int * item_list;
|
|
|
|
shphd->items = (int **) PoolAllocateMem (sizeof(int *) * shphd->numitems);
|
|
item_list = (int *) PoolAllocateMem (sizeof(int) * shphd->numitems * 9);
|
|
|
|
tptr = *(shphd->points);
|
|
|
|
tptr[0]=shphd->shapemaxx;
|
|
tptr[1]=shphd->shapeminy;
|
|
tptr[2]=0;
|
|
tptr[3]=shphd->shapemaxx;
|
|
tptr[4]=shphd->shapemaxy;
|
|
tptr[5]=0;
|
|
tptr[6]=shphd->shapeminx;
|
|
tptr[7]=shphd->shapemaxy;
|
|
tptr[8]=0;
|
|
tptr[9]=shphd->shapeminx;
|
|
tptr[10]=shphd->shapeminy;
|
|
tptr[11]=0;
|
|
|
|
tptr = *(shphd->sh_vnormals);
|
|
|
|
for (i=0; i<shphd->numpoints; i++) {
|
|
tptr[i*3] = 0;
|
|
tptr[i*3 + 1] = 0;
|
|
tptr[i*3 + 2] = ONE_FIXED;
|
|
}
|
|
|
|
tptr = *(shphd->sh_normals);
|
|
|
|
for (i=0; i<shphd->numitems; i++) {
|
|
tptr[i*3] = 0;
|
|
tptr[i*3 + 1] = 0;
|
|
tptr[i*3 + 2] = ONE_FIXED;
|
|
}
|
|
|
|
|
|
for (i=0; i<shphd->numitems; i++)
|
|
shphd->items[i] = &item_list[i*9];
|
|
|
|
|
|
item_list[0]=I_2dTexturedPolygon;
|
|
item_list[1]=0;
|
|
item_list[2]=iflag_ignore0| iflag_txanim|iflag_no_bfc;
|
|
if(ssc->Flags & SpriteFlag_NoLight) item_list[2]|=iflag_nolight;
|
|
if(ssc->Flags & SpriteFlag_SemiTrans) item_list[2]|=iflag_transparent;
|
|
item_list[3]=0;
|
|
item_list[4]=0;
|
|
item_list[5]=1;
|
|
item_list[6]=2;
|
|
item_list[7]=3;
|
|
item_list[8]=-1;
|
|
|
|
SHAPEINSTR * instruct = (SHAPEINSTR *)PoolAllocateMem(sizeof(SHAPEINSTR)*6);
|
|
|
|
shphd->sh_instruction = instruct;
|
|
|
|
instruct[0].sh_instr = I_ShapeSpriteRPoints; /*I_shapepoints*/
|
|
instruct[0].sh_numitems = 4;
|
|
instruct[0].sh_instr_data = shphd->points;
|
|
|
|
instruct[1].sh_instr = I_ShapeNormals; /*I_shapenormals*/
|
|
instruct[1].sh_numitems = shphd->numitems;
|
|
instruct[1].sh_instr_data = shphd->sh_normals;
|
|
|
|
instruct[2].sh_instr = I_ShapeProject; /*I_shapeproject*/
|
|
instruct[2].sh_numitems = shphd->numpoints;
|
|
instruct[2].sh_instr_data = shphd->points;
|
|
|
|
instruct[3].sh_instr = I_ShapeVNormals; /*I_shapevnormals*/
|
|
instruct[3].sh_numitems = shphd->numpoints;
|
|
instruct[3].sh_instr_data = shphd->sh_vnormals;
|
|
|
|
instruct[4].sh_instr = I_ShapeItems;
|
|
instruct[4].sh_numitems = shphd->numitems;
|
|
instruct[4].sh_instr_data = shphd->items;
|
|
|
|
instruct[5].sh_instr = I_ShapeEnd; /*I_shapeEND*/
|
|
instruct[5].sh_numitems = 0;
|
|
instruct[5].sh_instr_data = 0;
|
|
|
|
shphd->shapeflags=ShapeFlag_MultiViewSprite|ShapeFlag_SpriteResizing|ShapeFlag_Sprite;
|
|
|
|
List<Chunk *> chlist;
|
|
sc->lookup_child("SPRACTIO",chlist);
|
|
|
|
int MaxSeq=0;
|
|
for(LIF<Chunk*>chlif(&chlist);!chlif.done();chlif.next())
|
|
{
|
|
MaxSeq=max(MaxSeq,((Sprite_Action_Chunk*)chlif())->Action);
|
|
}
|
|
txanimheader** thlist=(txanimheader**)PoolAllocateMem((3+MaxSeq)*sizeof(txanimheader));
|
|
thlist[0]=thlist[MaxSeq+2]=0;
|
|
for(i=1;i<MaxSeq+2;i++)
|
|
{
|
|
thlist[i]=(txanimheader*)PoolAllocateMem(sizeof(txanimheader));
|
|
thlist[i]->txa_numframes=0;
|
|
thlist[i]->txa_maxframe=0;
|
|
thlist[i]->txa_num_mvs_images=0;
|
|
thlist[i]->txa_framedata=0;
|
|
}
|
|
while(chlist.size())
|
|
{
|
|
Sprite_Action_Chunk* sac=(Sprite_Action_Chunk*) chlist.first_entry();
|
|
txanimheader* th=thlist[sac->Action+1];
|
|
|
|
th->txa_flags=txa_flag_play;
|
|
th->txa_numframes=sac->NumFrames+1;
|
|
th->txa_currentframe=0;
|
|
th->txa_state=0;
|
|
th->txa_maxframe=(th->txa_numframes-1)<<16;
|
|
if(sac->FrameTime)
|
|
th->txa_speed=65536000/sac->FrameTime;
|
|
else
|
|
th->txa_speed=65536*8;
|
|
|
|
th->txa_num_mvs_images=sac->NumYaw*sac->NumPitch*2;
|
|
|
|
th->txa_eulerxshift=12;
|
|
int j=sac->NumPitch;
|
|
while(j)
|
|
{
|
|
j=j>>1;
|
|
th->txa_eulerxshift--;
|
|
}
|
|
th->txa_euleryshift=12;
|
|
j=sac->NumYaw;
|
|
while(j)
|
|
{
|
|
j=j>>1;
|
|
th->txa_euleryshift--;
|
|
}
|
|
if(sac->NumYaw==1)
|
|
{
|
|
th->txa_euleryshift=12;
|
|
th->txa_num_mvs_images=sac->NumPitch;
|
|
}
|
|
|
|
th->txa_framedata=(txanimframe*)PoolAllocateMem(th->txa_numframes*sizeof(txanimframe_mvs));
|
|
|
|
txanimframe_mvs* tf;
|
|
for(j=0;j<th->txa_numframes;j++)
|
|
{
|
|
int framefrom=j;
|
|
if(j==sac->NumFrames) framefrom=0;
|
|
tf=(txanimframe_mvs*)&th->txa_framedata[j];
|
|
tf->txf_flags=0;
|
|
tf->txf_scale=ONE_FIXED;
|
|
tf->txf_scalex=0;
|
|
tf->txf_scaley=0;
|
|
tf->txf_orient=0;
|
|
tf->txf_orientx=0;
|
|
tf->txf_orienty=0;
|
|
tf->txf_numuvs=4;
|
|
|
|
tf->txf_uvdata=(int**)PoolAllocateMem((th->txa_num_mvs_images)*sizeof(int*));
|
|
int* uvdata=(int*)PoolAllocateMem(th->txa_num_mvs_images*16*sizeof(int));
|
|
for(int k=0;k<th->txa_num_mvs_images;k++)
|
|
{
|
|
tf->txf_uvdata[k]=&uvdata[16*k];
|
|
}
|
|
|
|
tf->txf_images=(int*)PoolAllocateMem(th->txa_num_mvs_images*sizeof(int));
|
|
int ny=2*sac->NumYaw;
|
|
if(sac->NumYaw==1) ny=1;
|
|
int y,y2;
|
|
int pos,pos2;
|
|
for(y=0;y<ny;y+=2)
|
|
{
|
|
for(int p=0;p<sac->NumPitch;p++)
|
|
{
|
|
y2=(y-1+ny)%ny;
|
|
pos=y*sac->NumPitch+p;
|
|
pos2=y2*sac->NumPitch+p;
|
|
Frame* f=&sac->FrameList[y/2][p][framefrom];
|
|
|
|
GLOBALASSERT(f->Texture<=local_max_index);
|
|
GLOBALASSERT(f->Texture>=0);
|
|
GLOBALASSERT(BmpConv[f->Texture]!=-1);
|
|
|
|
tf->txf_images[pos]=BmpConv[f->Texture];
|
|
tf->txf_images[pos2]=BmpConv[f->Texture];
|
|
|
|
float bmpscale=sbsc->Scale[f->Texture];
|
|
if(y>ny/2 && (sac->Flags & SpriteActionFlag_FlipSecondSide))
|
|
{
|
|
for(int l=0;l<4;l++)
|
|
{
|
|
tf->txf_uvdata[pos][l*2]=ProcessUVCoord(h,UVC_SPRITE_U,f->UVCoords[3-l][0]<<16,BmpConv[f->Texture]);
|
|
tf->txf_uvdata[pos][l*2+1]=ProcessUVCoord(h,UVC_SPRITE_V,f->UVCoords[3-l][1]<<16,BmpConv[f->Texture]);
|
|
tf->txf_uvdata[pos2][l*2]=ProcessUVCoord(h,UVC_SPRITE_U,f->UVCoords[3-l][0]<<16,BmpConv[f->Texture]);
|
|
tf->txf_uvdata[pos2][l*2+1]=ProcessUVCoord(h,UVC_SPRITE_V,f->UVCoords[3-l][1]<<16,BmpConv[f->Texture]);
|
|
|
|
|
|
tf->txf_uvdata[pos][l*2+8]=-(f->UVCoords[3-l][0]-f->CentreX)*bmpscale*GlobalScale;
|
|
tf->txf_uvdata[pos][l*2+9]=(f->UVCoords[3-l][1]-f->CentreY)*bmpscale*GlobalScale;
|
|
tf->txf_uvdata[pos2][l*2+8]=-(f->UVCoords[3-l][0]-f->CentreX)*bmpscale*GlobalScale;
|
|
tf->txf_uvdata[pos2][l*2+9]=(f->UVCoords[3-l][1]-f->CentreY)*bmpscale*GlobalScale;
|
|
|
|
}
|
|
}
|
|
else
|
|
{
|
|
for(int l=0;l<4;l++)
|
|
{
|
|
tf->txf_uvdata[pos][l*2]=ProcessUVCoord(h,UVC_SPRITE_U,f->UVCoords[l][0]<<16,BmpConv[f->Texture]);
|
|
tf->txf_uvdata[pos][l*2+1]=ProcessUVCoord(h,UVC_SPRITE_V,f->UVCoords[l][1]<<16,BmpConv[f->Texture]);
|
|
tf->txf_uvdata[pos2][l*2]=ProcessUVCoord(h,UVC_SPRITE_U,f->UVCoords[l][0]<<16,BmpConv[f->Texture]);
|
|
tf->txf_uvdata[pos2][l*2+1]=ProcessUVCoord(h,UVC_SPRITE_V,f->UVCoords[l][1]<<16,BmpConv[f->Texture]);
|
|
|
|
|
|
tf->txf_uvdata[pos][l*2+8]=(f->UVCoords[l][0]-f->CentreX)*bmpscale*GlobalScale;
|
|
tf->txf_uvdata[pos][l*2+9]=(f->UVCoords[l][1]-f->CentreY)*bmpscale*GlobalScale;
|
|
tf->txf_uvdata[pos2][l*2+8]=(f->UVCoords[l][0]-f->CentreX)*bmpscale*GlobalScale;
|
|
tf->txf_uvdata[pos2][l*2+9]=(f->UVCoords[l][1]-f->CentreY)*bmpscale*GlobalScale;
|
|
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
chlist.delete_first_entry();
|
|
}
|
|
shphd->sh_textures[0]=(int*)thlist;
|
|
delete [] BmpConv;
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
BOOL copy_to_map6(Object_Chunk * ob,MAPBLOCK6* mapblock, int shplst_pos)
|
|
{
|
|
|
|
Object_Project_Data_Chunk * opdc = 0;
|
|
Map_Block_Chunk * mapblok = 0;
|
|
Strategy_Chunk * strat = 0;
|
|
|
|
if (ob->object_data.is_base_object)
|
|
*mapblock = Empty_Landscape_Type6;
|
|
else *mapblock = Empty_Object_Type6;
|
|
|
|
|
|
|
|
Chunk * pChunk = ob->lookup_single_child("OBJPRJDT");
|
|
if (pChunk) opdc = (Object_Project_Data_Chunk *)pChunk;
|
|
if (opdc)
|
|
{
|
|
pChunk = opdc->lookup_single_child("MAPBLOCK");
|
|
if (pChunk) mapblok = (Map_Block_Chunk *)pChunk;
|
|
pChunk = opdc->lookup_single_child("STRATEGY");
|
|
if (pChunk) strat = (Strategy_Chunk *)pChunk;
|
|
}
|
|
|
|
if (mapblok)
|
|
{
|
|
mapblock->MapType = mapblok->map_data.MapType;
|
|
mapblock->MapFlags= mapblok->map_data.MapFlags;
|
|
|
|
#if (StandardStrategyAndCollisions || IntermediateSSACM)
|
|
mapblock->MapCType = mapblok->map_data.MapCType;
|
|
mapblock->MapCGameType = mapblok->map_data.MapCGameType;
|
|
mapblock->MapCStrategyS = mapblok->map_data.MapCStrategyS;
|
|
mapblock->MapCStrategyL = mapblok->map_data.MapCStrategyL;
|
|
#endif
|
|
|
|
mapblock->MapInteriorType = mapblok->map_data.MapInteriorType;
|
|
// mapblock->MapLightType = mapblok->map_data.MapLightType;
|
|
// mapblock->MapMass = mapblok->map_data.MapMass;
|
|
// mapblock->MapNewtonV.vx = mapblok->map_data.MapNewtonV.vx;
|
|
// mapblock->MapNewtonV.vy = mapblok->map_data.MapNewtonV.vy;
|
|
// mapblock->MapNewtonV.vz = mapblok->map_data.MapNewtonV.vz;
|
|
// mapblock->MapOrigin.vx = mapblok->map_data.MapOrigin.vx;
|
|
// mapblock->MapOrigin.vy = mapblok->map_data.MapOrigin.vy;
|
|
// mapblock->MapOrigin.vz = mapblok->map_data.MapOrigin.vz;
|
|
// mapblock->MapViewType = mapblok->map_data.MapViewType;
|
|
}
|
|
|
|
#if (StandardStrategyAndCollisions || IntermediateSSACM)
|
|
if (strat)
|
|
{
|
|
mapblock->MapStrategy = strat->strategy_data.Strategy;
|
|
}
|
|
#endif
|
|
|
|
mapblock->MapShape = shplst_pos;
|
|
|
|
mapblock->MapWorld.vx = (int) (ob->object_data.location.x*local_scale);
|
|
mapblock->MapWorld.vy = (int) (ob->object_data.location.y*local_scale);
|
|
mapblock->MapWorld.vz = (int) (ob->object_data.location.z*local_scale);
|
|
|
|
QUAT q;
|
|
|
|
q.quatx = -ob->object_data.orientation.x*ONE_FIXED;
|
|
q.quaty = -ob->object_data.orientation.y*ONE_FIXED;
|
|
q.quatz = -ob->object_data.orientation.z*ONE_FIXED;
|
|
q.quatw = ob->object_data.orientation.w*ONE_FIXED;
|
|
|
|
MATRIXCH m;
|
|
|
|
QuatToMat (&q, &m);
|
|
|
|
EULER e;
|
|
|
|
MatrixToEuler(&m, &e);
|
|
|
|
/*
|
|
This function is only being used by the tools.
|
|
At least for the moment I need the Euler to contain
|
|
the 'inverse' rotation ,until I get round to sorting things
|
|
out properly. Richard
|
|
*/
|
|
|
|
mapblock->MapEuler.EulerX = e.EulerX;
|
|
mapblock->MapEuler.EulerY = e.EulerY;
|
|
mapblock->MapEuler.EulerZ = e.EulerZ;
|
|
|
|
#if InterfaceEngine
|
|
mapblock->o_chunk = (void *)ob;
|
|
#endif
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
BOOL tex_merge_polys ( ChunkPoly & p1, ChunkPoly & p2, ChunkPoly & p, ChunkShape & shp, int * /*mgd*/)
|
|
{
|
|
int j;
|
|
|
|
if (p1.engine_type != p2.engine_type)
|
|
return(FALSE);
|
|
|
|
if ((p1.colour & 0xffff) != (p2.colour & 0xffff))
|
|
return(FALSE);
|
|
|
|
if (p1.flags != p2.flags)
|
|
return(FALSE);
|
|
|
|
|
|
int p1_uvind = p1.colour >> 16;
|
|
int p2_uvind = p2.colour >> 16;
|
|
|
|
ChunkUV_List uv;
|
|
p = p1;
|
|
p.num_verts = 4;
|
|
uv.num_verts = 4;
|
|
|
|
int num_ins = 0;
|
|
int p_onv = 0;
|
|
int new_p_onv;
|
|
int * p_on = p1.vert_ind;
|
|
int * p_oth = p2.vert_ind;
|
|
int * temp;
|
|
|
|
ChunkUV * uv_on = shp.uv_list[p1_uvind].vert;
|
|
ChunkUV * uv_oth = shp.uv_list[p2_uvind].vert;
|
|
ChunkUV * uvtemp;
|
|
|
|
while (num_ins < 4)
|
|
{
|
|
uv.vert[num_ins] = uv_on[p_onv];
|
|
p.vert_ind[num_ins++] = p_on[p_onv];
|
|
for (j=0; j<3; j++)
|
|
{
|
|
if (p_on[p_onv] == p_oth[j] &&
|
|
(uv_on[p_onv].u != uv_oth[j].u || uv_on[p_onv].v != uv_oth[j].v))
|
|
{
|
|
return(FALSE);
|
|
}
|
|
if (p_on[p_onv] == p_oth[j])
|
|
break;
|
|
}
|
|
if (j==3) p_onv = (p_onv+1)%3;
|
|
else
|
|
{
|
|
new_p_onv = j;
|
|
for (j=0; j<3; j++)
|
|
{
|
|
if (p_on[(p_onv+1)%3] == p_oth[j] &&
|
|
(uv_on[(p_onv+1)%3].u != uv_oth[j].u || uv_on[(p_onv+1)%3].v != uv_oth[j].v))
|
|
{
|
|
return (FALSE);
|
|
}
|
|
if (p_on[(p_onv+1)%3] == p_oth[j])
|
|
break;
|
|
}
|
|
if (j==3) p_onv = (p_onv+1)%3;
|
|
else
|
|
{
|
|
temp = p_on;
|
|
p_on = p_oth;
|
|
p_oth = temp;
|
|
p_onv = (new_p_onv+1)%3;
|
|
|
|
uvtemp = uv_on;
|
|
uv_on = uv_oth;
|
|
uv_oth = uvtemp;
|
|
}
|
|
}
|
|
}
|
|
|
|
shp.uv_list[p1_uvind] = uv;
|
|
|
|
return(TRUE);
|
|
|
|
|
|
}
|
|
|
|
BOOL merge_polys ( ChunkPoly & p1, ChunkPoly & p2, ChunkPoly & p, int * /*mgd*/)
|
|
{
|
|
int j;
|
|
|
|
if (p1.engine_type != p2.engine_type)
|
|
return(FALSE);
|
|
|
|
if (p1.colour != p2.colour)
|
|
return(FALSE);
|
|
|
|
if (p1.flags != p2.flags)
|
|
return(FALSE);
|
|
|
|
|
|
p = p1;
|
|
p.num_verts = 4;
|
|
int num_ins = 0;
|
|
int p_onv = 0;
|
|
int new_p_onv;
|
|
int * p_on = p1.vert_ind;
|
|
int * p_oth = p2.vert_ind;
|
|
int * temp;
|
|
|
|
while (num_ins < 4)
|
|
{
|
|
p.vert_ind[num_ins++] = p_on[p_onv];
|
|
for (j=0; j<3; j++)
|
|
{
|
|
if (p_on[p_onv] == p_oth[j])
|
|
break;
|
|
}
|
|
if (j==3) p_onv = (p_onv+1)%3;
|
|
else
|
|
{
|
|
new_p_onv = j;
|
|
for (j=0; j<3; j++)
|
|
{
|
|
if (p_on[(p_onv+1)%3] == p_oth[j])
|
|
break;
|
|
}
|
|
if (j==3) p_onv = (p_onv+1)%3;
|
|
else
|
|
{
|
|
temp = p_on;
|
|
p_on = p_oth;
|
|
p_oth = temp;
|
|
p_onv = (new_p_onv+1)%3;
|
|
}
|
|
}
|
|
}
|
|
return(TRUE);
|
|
}
|
|
|
|
|
|
void merge_polygons_in_chunkshape (ChunkShape & shp, Shape_Merge_Data_Chunk * smdc)
|
|
{
|
|
int * mgd = smdc->merge_data;
|
|
|
|
int p_no = 0;
|
|
|
|
|
|
ChunkPoly * new_polys = new ChunkPoly [shp.num_polys];
|
|
ChunkVectorFloat * new_pnorms = new ChunkVectorFloat [shp.num_polys];
|
|
|
|
for (int i = 0; i<shp.num_polys; i++)
|
|
{
|
|
if (mgd[i] == -1)
|
|
{
|
|
new_polys[p_no] = shp.poly_list[i];
|
|
new_polys[p_no].normal_index = p_no;
|
|
new_pnorms[p_no] = shp.p_normal_list[i];
|
|
p_no ++;
|
|
}
|
|
else if (mgd[i]>i)
|
|
{
|
|
ChunkPoly p;
|
|
|
|
BOOL merged = FALSE;
|
|
|
|
//make sure points are within 10mm of being planar
|
|
|
|
int mpoly=mgd[i];
|
|
//find the 'unique vertex' in the second triangle
|
|
for(int j=0;j<3;j++)
|
|
{
|
|
for(int k=0;k<3;k++)
|
|
{
|
|
if(shp.poly_list[mpoly].vert_ind[j]==shp.poly_list[i].vert_ind[k])break;
|
|
}
|
|
if(k==3)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
GLOBALASSERT(j!=3);
|
|
int vert1=shp.poly_list[mpoly].vert_ind[j];
|
|
int vert2=shp.poly_list[mpoly].vert_ind[(j+1)%3];
|
|
ChunkVectorInt diff=shp.v_list[vert1]-shp.v_list[vert2];
|
|
ChunkVectorFloat* norm=&shp.p_normal_list[i];
|
|
|
|
//take the dot product of the normal and the difference to find the distance form the first
|
|
//triangles plane
|
|
float distance= (float)diff.x*norm->x + (float)diff.y*norm->y + (float)diff.z*norm->z;
|
|
|
|
if(distance>-1 && distance <1)
|
|
{
|
|
if (is_textured(shp.poly_list[i].engine_type))
|
|
{
|
|
merged = tex_merge_polys ( shp.poly_list[i], shp.poly_list[mgd[i]], p, shp, mgd);
|
|
}
|
|
else
|
|
{
|
|
merged = merge_polys ( shp.poly_list[i], shp.poly_list[mgd[i]], p, mgd);
|
|
}
|
|
}
|
|
if (merged)
|
|
{
|
|
p.normal_index = p_no;
|
|
new_polys[p_no] = p;
|
|
new_pnorms[p_no] = shp.p_normal_list[i];
|
|
p_no++;
|
|
}
|
|
else
|
|
{
|
|
new_polys[p_no] = shp.poly_list[i];
|
|
new_polys[p_no].normal_index = p_no;
|
|
new_pnorms[p_no] = shp.p_normal_list[i];
|
|
p_no ++;
|
|
|
|
new_polys[p_no] = shp.poly_list[mgd[i]];
|
|
new_polys[p_no].normal_index = p_no;
|
|
new_pnorms[p_no] = shp.p_normal_list[mgd[i]];
|
|
p_no ++;
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
delete [] shp.poly_list;
|
|
delete [] shp.p_normal_list;
|
|
shp.poly_list = new_polys;
|
|
shp.p_normal_list = new_pnorms;
|
|
shp.num_polys = p_no;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
BOOL copy_to_mainshpl (Shape_Chunk * shp, int list_pos)
|
|
{
|
|
SHAPEHEADER * shphd = (SHAPEHEADER *) AllocateMem(sizeof(SHAPEHEADER));
|
|
memset(shphd,0,sizeof(SHAPEHEADER));
|
|
|
|
ChunkShape cshp = shp->shape_data;
|
|
|
|
Shape_Merge_Data_Chunk * smdc = 0;
|
|
|
|
Chunk * pChunk = shp->lookup_single_child("SHPMRGDT");
|
|
if (pChunk)
|
|
{
|
|
smdc = (Shape_Merge_Data_Chunk *) pChunk;
|
|
}
|
|
|
|
merge_polygons_in_chunkshape (cshp,smdc);
|
|
|
|
int i,j, * tptr;
|
|
|
|
mainshapelist[list_pos] = shphd;
|
|
|
|
// header data (note shapeheader is calloced)
|
|
|
|
shphd->shapeflags = shphd->shapeflags | (ShapeFlag_AugZ | ShapeFlag_AugZ_Lite |
|
|
ShapeFlag_SizeSortItems); // SIZE HACK!!!
|
|
shphd->numpoints = cshp.num_verts;
|
|
shphd->numitems = cshp.num_polys;
|
|
|
|
shphd->shaperadius = (int) (cshp.radius*local_scale);
|
|
|
|
shphd->shapemaxx = (int) (cshp.max.x*local_scale);
|
|
shphd->shapeminx = (int) (cshp.min.x*local_scale);
|
|
shphd->shapemaxy = (int) (cshp.max.y*local_scale);
|
|
shphd->shapeminy = (int) (cshp.min.y*local_scale);
|
|
shphd->shapemaxz = (int) (cshp.max.z*local_scale);
|
|
shphd->shapeminz = (int) (cshp.min.z*local_scale);
|
|
|
|
// AllocateMem arrays
|
|
|
|
shphd->points = (int **) AllocateMem (sizeof(int *));
|
|
*(shphd->points) = (int *) AllocateMem (sizeof(int) * shphd->numpoints * 3);
|
|
|
|
shphd->sh_vnormals = (int **) AllocateMem (sizeof(int *));
|
|
*(shphd->sh_vnormals) = (int *) AllocateMem (sizeof(int) * shphd->numpoints * 3);
|
|
|
|
shphd->sh_normals = (int **) AllocateMem (sizeof(int *));
|
|
*(shphd->sh_normals) = (int *) AllocateMem (sizeof(int) * shphd->numitems * 3);
|
|
|
|
// for textures
|
|
if (cshp.num_uvs)
|
|
shphd->sh_textures = (int **) AllocateMem (sizeof(int *) * cshp.num_uvs);
|
|
if (cshp.num_texfiles)
|
|
shphd->sh_localtextures = (char **) AllocateMem (sizeof(char *) * (cshp.num_texfiles+1));
|
|
|
|
int * item_list;
|
|
|
|
shphd->items = (int **) AllocateMem (sizeof(int *) * shphd->numitems);
|
|
item_list = (int *) AllocateMem (sizeof(int) * shphd->numitems * 9);
|
|
|
|
tptr = *(shphd->points);
|
|
|
|
for (i=0; i<shphd->numpoints; i++) {
|
|
tptr[i*3] = (int) (cshp.v_list[i].x*local_scale);
|
|
tptr[i*3 + 1] = (int) (cshp.v_list[i].y*local_scale);
|
|
tptr[i*3 + 2] = (int) (cshp.v_list[i].z*local_scale);
|
|
}
|
|
|
|
tptr = *(shphd->sh_vnormals);
|
|
|
|
for (i=0; i<shphd->numpoints; i++) {
|
|
tptr[i*3] = (int) (cshp.v_normal_list[i].x*ONE_FIXED);
|
|
tptr[i*3 + 1] = (int) (cshp.v_normal_list[i].y*ONE_FIXED);
|
|
tptr[i*3 + 2] = (int) (cshp.v_normal_list[i].z*ONE_FIXED);
|
|
}
|
|
|
|
tptr = *(shphd->sh_normals);
|
|
|
|
for (i=0; i<shphd->numitems; i++) {
|
|
tptr[i*3] = (int) (cshp.p_normal_list[i].x*ONE_FIXED);
|
|
tptr[i*3 + 1] = (int) (cshp.p_normal_list[i].y*ONE_FIXED);
|
|
tptr[i*3 + 2] = (int) (cshp.p_normal_list[i].z*ONE_FIXED);
|
|
}
|
|
|
|
|
|
for (i=0; i<shphd->numitems; i++)
|
|
shphd->items[i] = &item_list[i*9];
|
|
|
|
|
|
|
|
for (i=0; i<shphd->numitems; i++) {
|
|
|
|
|
|
item_list[i*9] = (cshp.poly_list[i].engine_type);
|
|
// item_list[i*9] = I_Polyline;
|
|
|
|
/* trap for polylines*/
|
|
if((item_list[i*9] < 2 ) || (item_list[i*9] > 9))
|
|
{
|
|
item_list[i*9] = I_Polygon;
|
|
}
|
|
#if 1
|
|
/* try to set gouraud, for hazing*/
|
|
|
|
if(item_list[i*9] == I_Polygon)
|
|
{
|
|
item_list[i*9] = I_GouraudPolygon;
|
|
}
|
|
|
|
if(item_list[i*9] == I_2dTexturedPolygon)
|
|
{
|
|
item_list[i*9] = I_Gouraud2dTexturedPolygon;
|
|
}
|
|
|
|
if(item_list[i*9] == I_3dTexturedPolygon)
|
|
{
|
|
item_list[i*9] = I_Gouraud2dTexturedPolygon;
|
|
}
|
|
#endif
|
|
|
|
// if(item_list[i*9] == I_Polygon)
|
|
// {
|
|
// item_list[i*9] = I_ZB_Polygon;
|
|
// /*HACK HACK ROXHACK*/
|
|
// }
|
|
|
|
#if SupportZBuffering
|
|
#else
|
|
if(item_list[i*9] == I_ZB_Polygon)
|
|
item_list[i*9] = I_Polygon;
|
|
|
|
if(item_list[i*9] == I_ZB_GouraudPolygon)
|
|
item_list[i*9] = I_GouraudPolygon;
|
|
|
|
if(item_list[i*9] == I_ZB_PhongPolygon)
|
|
item_list[i*9] = I_PhongPolygon;
|
|
|
|
if(item_list[i*9] == I_ZB_2dTexturedPolygon)
|
|
item_list[i*9] = I_2dTexturedPolygon;
|
|
|
|
if(item_list[i*9] == I_ZB_Gouraud2dTexturedPolygon)
|
|
item_list[i*9] = I_Gouraud2dTexturedPolygon;
|
|
|
|
if(item_list[i*9] == I_ZB_3dTexturedPolygon)
|
|
item_list[i*9] = I_3dTexturedPolygon;
|
|
#endif
|
|
|
|
|
|
|
|
item_list[i*9 + 1] = (cshp.poly_list[i].normal_index * 3);
|
|
item_list[i*9 + 2] = (cshp.poly_list[i].flags&~ChunkInternalItemFlags);
|
|
// item_list[i*9 + 2] = (cshp.poly_list[i].flags) | iflag_nolight;
|
|
item_list[i*9 + 3] = (cshp.poly_list[i].colour);
|
|
|
|
#if 1
|
|
if ( (item_list[i*9] == I_2dTexturedPolygon
|
|
|| item_list[i*9] == I_Gouraud2dTexturedPolygon
|
|
|| item_list[i*9] == I_3dTexturedPolygon
|
|
|| item_list[i*9] == I_Gouraud3dTexturedPolygon
|
|
) &&
|
|
!( item_list[i*9 + 3] & 0x8000 ) )
|
|
{
|
|
int texno = item_list[i*9 + 3] & 0x7fff;
|
|
|
|
if (texno <= max_index)
|
|
if ((tex_index_nos[texno] != -1))
|
|
{
|
|
item_list[i*9 + 3] &= 0xffff0000;
|
|
item_list[i*9 + 3] += tex_index_nos[texno];
|
|
|
|
/* hack in iflag_no_light */
|
|
item_list[i*9 + 2] |= iflag_gsort_ptest /*| iflag_nolight*/ | iflag_linear_s | iflag_tx2dor3d;
|
|
|
|
}
|
|
else
|
|
{
|
|
item_list[i*9] = I_Polygon;
|
|
item_list[i*9 + 2] = (cshp.poly_list[i].flags&~ChunkInternalItemFlags) | iflag_nolight;
|
|
item_list[i*9 + 3] = 0xffffffff;
|
|
}
|
|
else
|
|
{
|
|
item_list[i*9] = I_Polygon;
|
|
item_list[i*9 + 2] = (cshp.poly_list[i].flags&~ChunkInternalItemFlags) | iflag_nolight;
|
|
item_list[i*9 + 3] = 0xffffffff;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// item_list[i*9 + 3] = 0xffffffff;
|
|
|
|
|
|
for (j=0;j<cshp.poly_list[i].num_verts;j++)
|
|
// item_list[i*9 + 4 +j] = (cshp.poly_list[i].vert_ind[j] *3);
|
|
/* KJL 12:21:58 9/17/97 - I've removed the annoying *3 */
|
|
item_list[i*9 + 4 +j] = (cshp.poly_list[i].vert_ind[j]);
|
|
for (;j<5;j++)
|
|
item_list[i*9 + 4 +j] = -1;
|
|
}
|
|
|
|
if (cshp.num_uvs)
|
|
{
|
|
for (i=0; i<cshp.num_uvs; i++) {
|
|
shphd->sh_textures[i] = (int *) AllocateMem (sizeof(int) * cshp.uv_list[i].num_verts * 2);
|
|
for (j=0; j<cshp.uv_list[i].num_verts; j++) {
|
|
(shphd->sh_textures[i])[(j*2)] = (int)cshp.uv_list[i].vert[j].u;
|
|
(shphd->sh_textures[i])[(j*2)+1] = (int)cshp.uv_list[i].vert[j].v;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (cshp.num_texfiles)
|
|
{
|
|
for (i=0; i<cshp.num_texfiles; i++) {
|
|
#if john
|
|
shphd->sh_localtextures[i] =
|
|
(char *) AllocateMem (sizeof(char) * (strlen(cshp.texture_fns[i]) + strlen(TexturesRoot) + 1) );
|
|
sprintf (shphd->sh_localtextures[i],"%s%s",TexturesRoot, cshp.texture_fns[i]);
|
|
char * dotpos;
|
|
dotpos = strrchr (shphd->sh_localtextures[i], '.');
|
|
sprintf (dotpos,".pg0");
|
|
#else
|
|
shphd->sh_localtextures[i] =
|
|
(char *) AllocateMem (sizeof(char) * (strlen(cshp.texture_fns[i]) + 1) );
|
|
strcpy (shphd->sh_localtextures[i], cshp.texture_fns[i]);
|
|
#endif
|
|
}
|
|
shphd->sh_localtextures[i] = 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
SHAPEINSTR * instruct = (SHAPEINSTR *)AllocateMem(sizeof(SHAPEINSTR)*6);
|
|
|
|
shphd->sh_instruction = instruct;
|
|
|
|
|
|
|
|
instruct[0].sh_instr = I_ShapePoints; /*I_shapepoints*/
|
|
instruct[0].sh_numitems = shphd->numpoints;
|
|
instruct[0].sh_instr_data = shphd->points;
|
|
|
|
instruct[1].sh_instr = I_ShapeNormals; /*I_shapenormals*/
|
|
instruct[1].sh_numitems = shphd->numitems;
|
|
instruct[1].sh_instr_data = shphd->sh_normals;
|
|
|
|
instruct[2].sh_instr = I_ShapeProject; /*I_shapeproject*/
|
|
instruct[2].sh_numitems = shphd->numpoints;
|
|
instruct[2].sh_instr_data = shphd->points;
|
|
|
|
instruct[3].sh_instr = I_ShapeVNormals; /*I_shapevnormals*/
|
|
instruct[3].sh_numitems = shphd->numpoints;
|
|
instruct[3].sh_instr_data = shphd->sh_vnormals;
|
|
|
|
instruct[4].sh_instr = I_ShapeItems;
|
|
instruct[4].sh_numitems = shphd->numitems;
|
|
instruct[4].sh_instr_data = shphd->items;
|
|
|
|
instruct[5].sh_instr = I_ShapeEnd; /*I_shapeEND*/
|
|
instruct[5].sh_numitems = 0;
|
|
instruct[5].sh_instr_data = 0;
|
|
|
|
|
|
Chunk * pchAnim = shp->lookup_single_child("TEXTANIM");
|
|
if (pchAnim)
|
|
{
|
|
Shape_Merge_Data_Chunk* smdc=0;
|
|
Chunk * pChunk=shp->lookup_single_child("SHPMRGDT");
|
|
if(pChunk) smdc=(Shape_Merge_Data_Chunk*)pChunk;
|
|
SetupAnimatedTextures(shp,shphd,(Animation_Chunk*)pchAnim,smdc);
|
|
}
|
|
|
|
|
|
|
|
return TRUE;
|
|
|
|
}
|
|
#endif
|
|
|
|
#if 0
|
|
BOOL copy_to_mainshpl (Shape_Sub_Shape_Chunk * shp, int list_pos)
|
|
{
|
|
SHAPEHEADER * shphd = (SHAPEHEADER *) AllocateMem(sizeof(SHAPEHEADER));
|
|
memset(shphd,0,sizeof(SHAPEHEADER));
|
|
|
|
ChunkShape cshp = shp->shape_data;
|
|
|
|
Shape_Merge_Data_Chunk * smdc = 0;
|
|
|
|
Chunk * pChunk = shp->lookup_single_child("SHPMRGDT");
|
|
if (pChunk)
|
|
{
|
|
smdc = (Shape_Merge_Data_Chunk *) pChunk;
|
|
}
|
|
|
|
merge_polygons_in_chunkshape (cshp,smdc);
|
|
|
|
int i,j, * tptr;
|
|
|
|
mainshapelist[list_pos] = shphd;
|
|
|
|
// header data (note shapeheader is calloced)
|
|
|
|
shphd->shapeflags = shphd->shapeflags | (ShapeFlag_AugZ | ShapeFlag_AugZ_Lite |
|
|
ShapeFlag_SizeSortItems); // SIZE HACK!!!
|
|
shphd->numpoints = cshp.num_verts;
|
|
shphd->numitems = cshp.num_polys;
|
|
|
|
shphd->shaperadius = (int) (cshp.radius*local_scale);
|
|
|
|
shphd->shapemaxx = (int) (cshp.max.x*local_scale);
|
|
shphd->shapeminx = (int) (cshp.min.x*local_scale);
|
|
shphd->shapemaxy = (int) (cshp.max.y*local_scale);
|
|
shphd->shapeminy = (int) (cshp.min.y*local_scale);
|
|
shphd->shapemaxz = (int) (cshp.max.z*local_scale);
|
|
shphd->shapeminz = (int) (cshp.min.z*local_scale);
|
|
|
|
// AllocateMem arrays
|
|
|
|
shphd->points = (int **) AllocateMem (sizeof(int *));
|
|
*(shphd->points) = (int *) AllocateMem (sizeof(int) * shphd->numpoints * 3);
|
|
|
|
shphd->sh_vnormals = (int **) AllocateMem (sizeof(int *));
|
|
*(shphd->sh_vnormals) = (int *) AllocateMem (sizeof(int) * shphd->numpoints * 3);
|
|
|
|
shphd->sh_normals = (int **) AllocateMem (sizeof(int *));
|
|
*(shphd->sh_normals) = (int *) AllocateMem (sizeof(int) * shphd->numitems * 3);
|
|
|
|
// for textures
|
|
if (cshp.num_uvs)
|
|
shphd->sh_textures = (int **) AllocateMem (sizeof(int *) * cshp.num_uvs);
|
|
if (cshp.num_texfiles)
|
|
shphd->sh_localtextures = (char **) AllocateMem (sizeof(char *) * (cshp.num_texfiles+1));
|
|
|
|
int * item_list;
|
|
|
|
shphd->items = (int **) AllocateMem (sizeof(int *) * shphd->numitems);
|
|
item_list = (int *) AllocateMem (sizeof(int) * shphd->numitems * 9);
|
|
|
|
tptr = *(shphd->points);
|
|
|
|
for (i=0; i<shphd->numpoints; i++) {
|
|
tptr[i*3] = (int) (cshp.v_list[i].x*local_scale);
|
|
tptr[i*3 + 1] = (int) (cshp.v_list[i].y*local_scale);
|
|
tptr[i*3 + 2] = (int) (cshp.v_list[i].z*local_scale);
|
|
}
|
|
|
|
tptr = *(shphd->sh_vnormals);
|
|
|
|
for (i=0; i<shphd->numpoints; i++) {
|
|
tptr[i*3] = (int) (cshp.v_normal_list[i].x*ONE_FIXED);
|
|
tptr[i*3 + 1] = (int) (cshp.v_normal_list[i].y*ONE_FIXED);
|
|
tptr[i*3 + 2] = (int) (cshp.v_normal_list[i].z*ONE_FIXED);
|
|
}
|
|
|
|
tptr = *(shphd->sh_normals);
|
|
|
|
for (i=0; i<shphd->numitems; i++) {
|
|
tptr[i*3] = (int) (cshp.p_normal_list[i].x*ONE_FIXED);
|
|
tptr[i*3 + 1] = (int) (cshp.p_normal_list[i].y*ONE_FIXED);
|
|
tptr[i*3 + 2] = (int) (cshp.p_normal_list[i].z*ONE_FIXED);
|
|
}
|
|
|
|
|
|
for (i=0; i<shphd->numitems; i++)
|
|
shphd->items[i] = &item_list[i*9];
|
|
|
|
|
|
|
|
for (i=0; i<shphd->numitems; i++) {
|
|
|
|
|
|
item_list[i*9] = (cshp.poly_list[i].engine_type);
|
|
// item_list[i*9] = I_Polyline;
|
|
#if 1
|
|
/* try to set gouraud, for hazing*/
|
|
|
|
if(item_list[i*9] == I_Polygon)
|
|
{
|
|
item_list[i*9] = I_GouraudPolygon;
|
|
}
|
|
|
|
if(item_list[i*9] == I_2dTexturedPolygon)
|
|
{
|
|
item_list[i*9] = I_Gouraud2dTexturedPolygon;
|
|
}
|
|
|
|
if(item_list[i*9] == I_3dTexturedPolygon)
|
|
{
|
|
item_list[i*9] = I_Gouraud2dTexturedPolygon;
|
|
}
|
|
#endif
|
|
|
|
// if((item_list[i*9] < 2 ) || (item_list[i*9] > 9))
|
|
// {
|
|
// item_list[i*9] = I_Polygon;
|
|
// }
|
|
#if 1
|
|
/* try to set gouraud, for hazing*/
|
|
|
|
if(item_list[i*9] == I_Polygon)
|
|
{
|
|
item_list[i*9] = I_GouraudPolygon;
|
|
}
|
|
|
|
if(item_list[i*9] == I_2dTexturedPolygon)
|
|
{
|
|
item_list[i*9] = I_Gouraud2dTexturedPolygon;
|
|
}
|
|
|
|
if(item_list[i*9] == I_3dTexturedPolygon)
|
|
{
|
|
item_list[i*9] = I_Gouraud2dTexturedPolygon;
|
|
}
|
|
#endif
|
|
|
|
// if(item_list[i*9] == I_Polygon)
|
|
// {
|
|
// item_list[i*9] = I_ZB_Polygon;
|
|
// /*HACK HACK ROXHACK*/
|
|
// }
|
|
|
|
#if SupportZBuffering
|
|
#else
|
|
if(item_list[i*9] == I_ZB_Polygon)
|
|
item_list[i*9] = I_Polygon;
|
|
|
|
if(item_list[i*9] == I_ZB_GouraudPolygon)
|
|
item_list[i*9] = I_GouraudPolygon;
|
|
|
|
if(item_list[i*9] == I_ZB_PhongPolygon)
|
|
item_list[i*9] = I_PhongPolygon;
|
|
|
|
if(item_list[i*9] == I_ZB_2dTexturedPolygon)
|
|
item_list[i*9] = I_2dTexturedPolygon;
|
|
|
|
if(item_list[i*9] == I_ZB_Gouraud2dTexturedPolygon)
|
|
item_list[i*9] = I_Gouraud2dTexturedPolygon;
|
|
|
|
if(item_list[i*9] == I_ZB_3dTexturedPolygon)
|
|
item_list[i*9] = I_3dTexturedPolygon;
|
|
#endif
|
|
|
|
|
|
|
|
item_list[i*9 + 1] = (cshp.poly_list[i].normal_index * 3);
|
|
item_list[i*9 + 2] = (cshp.poly_list[i].flags&~ChunkInternalItemFlags);
|
|
// item_list[i*9 + 2] = (cshp.poly_list[i].flags) | iflag_nolight;
|
|
item_list[i*9 + 3] = (cshp.poly_list[i].colour);
|
|
|
|
#if 1
|
|
if ( (item_list[i*9] == 5 || item_list[i*9] == 6
|
|
|| item_list[i*9] == 7) &&
|
|
!( item_list[i*9 + 3] & 0x8000 ) )
|
|
{
|
|
int texno = item_list[i*9 + 3] & 0x7fff;
|
|
|
|
if (texno <= max_index)
|
|
if ((tex_index_nos[texno] != -1))
|
|
{
|
|
item_list[i*9 + 3] &= 0xffff0000;
|
|
item_list[i*9 + 3] += tex_index_nos[texno];
|
|
|
|
/* hack in iflag_no_light */
|
|
item_list[i*9 + 2] |= iflag_gsort_ptest /*| iflag_nolight*/ | iflag_linear_s | iflag_tx2dor3d;
|
|
|
|
}
|
|
else
|
|
{
|
|
item_list[i*9] = I_Polygon;
|
|
item_list[i*9 + 2] = (cshp.poly_list[i].flags&~ChunkInternalItemFlags) | iflag_nolight;
|
|
item_list[i*9 + 3] = 0xffffffff;
|
|
}
|
|
else
|
|
{
|
|
item_list[i*9] = I_Polygon;
|
|
item_list[i*9 + 2] = (cshp.poly_list[i].flags &~ChunkInternalItemFlags) | iflag_nolight;
|
|
item_list[i*9 + 3] = 0xffffffff;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
// item_list[i*9 + 3] = 0xffffffff;
|
|
|
|
|
|
for (j=0;j<cshp.poly_list[i].num_verts;j++)
|
|
// item_list[i*9 + 4 +j] = (cshp.poly_list[i].vert_ind[j] *3);
|
|
/* KJL 12:23:02 9/17/97 - I've removed the annoying *3 */
|
|
item_list[i*9 + 4 +j] = (cshp.poly_list[i].vert_ind[j]);
|
|
for (;j<5;j++)
|
|
item_list[i*9 + 4 +j] = -1;
|
|
}
|
|
|
|
if (cshp.num_uvs)
|
|
{
|
|
for (i=0; i<cshp.num_uvs; i++) {
|
|
shphd->sh_textures[i] = (int *) AllocateMem (sizeof(int) * cshp.uv_list[i].num_verts * 2);
|
|
for (j=0; j<cshp.uv_list[i].num_verts; j++) {
|
|
(shphd->sh_textures[i])[(j*2)] = (int)cshp.uv_list[i].vert[j].u;
|
|
(shphd->sh_textures[i])[(j*2)+1] = (int)cshp.uv_list[i].vert[j].v;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (cshp.num_texfiles)
|
|
{
|
|
for (i=0; i<cshp.num_texfiles; i++) {
|
|
#if john
|
|
shphd->sh_localtextures[i] =
|
|
(char *) AllocateMem (sizeof(char) * (strlen(cshp.texture_fns[i]) + strlen(TexturesRoot) + 1) );
|
|
sprintf (shphd->sh_localtextures[i],"%s%s",TexturesRoot, cshp.texture_fns[i]);
|
|
char * dotpos;
|
|
dotpos = strrchr (shphd->sh_localtextures[i], '.');
|
|
sprintf (dotpos,".pg0");
|
|
#else
|
|
shphd->sh_localtextures[i] =
|
|
(char *) AllocateMem (sizeof(char) * (strlen(cshp.texture_fns[i]) + 1) );
|
|
strcpy (shphd->sh_localtextures[i], cshp.texture_fns[i]);
|
|
#endif
|
|
}
|
|
shphd->sh_localtextures[i] = 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
SHAPEINSTR * instruct = (SHAPEINSTR *)AllocateMem(sizeof(SHAPEINSTR)*6);
|
|
|
|
shphd->sh_instruction = instruct;
|
|
|
|
|
|
instruct[0].sh_instr = I_ShapePoints; /*I_shapepoints*/
|
|
instruct[0].sh_numitems = shphd->numpoints;
|
|
instruct[0].sh_instr_data = shphd->points;
|
|
|
|
instruct[1].sh_instr = I_ShapeNormals; /*I_shapenormals*/
|
|
instruct[1].sh_numitems = shphd->numitems;
|
|
instruct[1].sh_instr_data = shphd->sh_normals;
|
|
|
|
instruct[2].sh_instr = I_ShapeProject; /*I_shapeproject*/
|
|
instruct[2].sh_numitems = shphd->numpoints;
|
|
instruct[2].sh_instr_data = shphd->points;
|
|
|
|
instruct[3].sh_instr = I_ShapeVNormals; /*I_shapevnormals*/
|
|
instruct[3].sh_numitems = shphd->numpoints;
|
|
instruct[3].sh_instr_data = shphd->sh_vnormals;
|
|
|
|
instruct[4].sh_instr = I_ShapeItems;
|
|
instruct[4].sh_numitems = shphd->numitems;
|
|
instruct[4].sh_instr_data = shphd->items;
|
|
|
|
instruct[5].sh_instr = I_ShapeEnd; /*I_shapeEND*/
|
|
instruct[5].sh_numitems = 0;
|
|
instruct[5].sh_instr_data = 0;
|
|
|
|
|
|
|
|
return TRUE;
|
|
#if 0
|
|
SHAPEHEADER * shphd = (SHAPEHEADER *) AllocateMem(sizeof(SHAPEHEADER));
|
|
memset(shphd,0,sizeof(SHAPEHEADER));
|
|
|
|
ChunkShape cshp = shp->shape_data;
|
|
|
|
Shape_Merge_Data_Chunk * smdc = 0;
|
|
|
|
Chunk * pChunk = shp->lookup_single_child("SHPMRGDT");
|
|
if (pChunk)
|
|
{
|
|
smdc = (Shape_Merge_Data_Chunk *) pChunk;
|
|
}
|
|
|
|
merge_polygons_in_chunkshape (cshp,smdc);
|
|
|
|
int i,j, * tptr;
|
|
|
|
mainshapelist[list_pos] = shphd;
|
|
|
|
// header data (note shapeheader is calloced)
|
|
|
|
shphd->numpoints = cshp.num_verts;
|
|
shphd->numitems = cshp.num_polys;
|
|
|
|
shphd->shaperadius = (int) (cshp.radius*local_scale);
|
|
|
|
shphd->shapeflags = shphd->shapeflags | (ShapeFlag_AugZ | ShapeFlag_AugZ_Lite |
|
|
ShapeFlag_SizeSortItems); // SIZE HACK!!!
|
|
|
|
shphd->shapemaxx = (int) (cshp.max.x*local_scale);
|
|
shphd->shapeminx = (int) (cshp.min.x*local_scale);
|
|
shphd->shapemaxy = (int) (cshp.max.y*local_scale);
|
|
shphd->shapeminy = (int) (cshp.min.y*local_scale);
|
|
shphd->shapemaxz = (int) (cshp.max.z*local_scale);
|
|
shphd->shapeminz = (int) (cshp.min.z*local_scale);
|
|
|
|
// AllocateMem arrays
|
|
|
|
shphd->points = (int **) AllocateMem (sizeof(int *));
|
|
*(shphd->points) = (int *) AllocateMem (sizeof(int) * shphd->numpoints * 3);
|
|
|
|
shphd->sh_vnormals = (int **) AllocateMem (sizeof(int *));
|
|
*(shphd->sh_vnormals) = (int *) AllocateMem (sizeof(int) * shphd->numpoints * 3);
|
|
|
|
shphd->sh_normals = (int **) AllocateMem (sizeof(int *));
|
|
*(shphd->sh_normals) = (int *) AllocateMem (sizeof(int) * shphd->numitems * 3);
|
|
|
|
// for textures
|
|
if (cshp.num_uvs)
|
|
shphd->sh_textures = (int **) AllocateMem (sizeof(int *) * cshp.num_uvs);
|
|
if (cshp.num_texfiles)
|
|
shphd->sh_localtextures = (char **) AllocateMem (sizeof(char *) * (cshp.num_texfiles+1));
|
|
|
|
int * item_list;
|
|
|
|
shphd->items = (int **) AllocateMem (sizeof(int *) * shphd->numitems);
|
|
item_list = (int *) AllocateMem (sizeof(int) * shphd->numitems * 9);
|
|
|
|
tptr = *(shphd->points);
|
|
|
|
for (i=0; i<shphd->numpoints; i++) {
|
|
tptr[i*3] = (int) (cshp.v_list[i].x*local_scale);
|
|
tptr[i*3 + 1] = (int) (cshp.v_list[i].y*local_scale);
|
|
tptr[i*3 + 2] = (int) (cshp.v_list[i].z*local_scale);
|
|
}
|
|
|
|
tptr = *(shphd->sh_vnormals);
|
|
|
|
for (i=0; i<shphd->numpoints; i++) {
|
|
tptr[i*3] = (int) (cshp.v_normal_list[i].x*ONE_FIXED);
|
|
tptr[i*3 + 1] = (int) (cshp.v_normal_list[i].y*ONE_FIXED);
|
|
tptr[i*3 + 2] = (int) (cshp.v_normal_list[i].z*ONE_FIXED);
|
|
}
|
|
|
|
tptr = *(shphd->sh_normals);
|
|
|
|
for (i=0; i<shphd->numitems; i++) {
|
|
tptr[i*3] = (int) (cshp.p_normal_list[i].x*ONE_FIXED);
|
|
tptr[i*3 + 1] = (int) (cshp.p_normal_list[i].y*ONE_FIXED);
|
|
tptr[i*3 + 2] = (int) (cshp.p_normal_list[i].z*ONE_FIXED);
|
|
}
|
|
|
|
|
|
for (i=0; i<shphd->numitems; i++)
|
|
shphd->items[i] = &item_list[i*9];
|
|
|
|
|
|
for (i=0; i<shphd->numitems; i++) {
|
|
item_list[i*9] = (cshp.poly_list[i].engine_type);
|
|
// item_list[i*9] = I_Polyline;
|
|
|
|
|
|
if((item_list[i*9] < 2 ) || (item_list[i*9] > 9))
|
|
{
|
|
item_list[i*9] = I_Polygon;
|
|
}
|
|
|
|
if(item_list[i*9] == I_2dTexturedPolygon)
|
|
{
|
|
item_list[i*9] = I_Polygon;
|
|
}
|
|
|
|
if(item_list[i*9] == I_3dTexturedPolygon)
|
|
{
|
|
item_list[i*9] = I_2dTexturedPolygon;
|
|
}
|
|
|
|
// if(item_list[i*9] == I_Polygon)
|
|
// {
|
|
// item_list[i*9] = I_ZB_Polygon;
|
|
// /*HACK HACK ROXHACK*/
|
|
// }
|
|
|
|
item_list[i*9 + 1] = (cshp.poly_list[i].normal_index * 3);
|
|
item_list[i*9 + 2] = (cshp.poly_list[i].flags&~ChunkInternalItemFlags);
|
|
// item_list[i*9 + 2] = (cshp.poly_list[i].flags) | iflag_nolight;
|
|
item_list[i*9 + 3] = (cshp.poly_list[i].colour);
|
|
|
|
if ( (item_list[i*9] == 5 || item_list[i*9] == 6) &&
|
|
!( item_list[i*9 + 3] & 0x8000 ) )
|
|
{
|
|
int texno = item_list[i*9 + 3] & 0x7fff;
|
|
|
|
if (texno < max_index)
|
|
if (tex_index_nos[texno] != -1)
|
|
{
|
|
item_list[i*9 + 3] &= 0xffff0000;
|
|
item_list[i*9 + 3] += tex_index_nos[texno];
|
|
}
|
|
else
|
|
{
|
|
item_list[i*9] = I_Polyline;
|
|
item_list[i*9 + 2] = (cshp.poly_list[i].flags &~ChunkInternalItemFlags) /*| iflag_nolight*/;
|
|
item_list[i*9 + 3] = 0xffffffff;
|
|
}
|
|
else
|
|
{
|
|
item_list[i*9] = I_Polyline;
|
|
item_list[i*9 + 2] = (cshp.poly_list[i].flags &~ChunkInternalItemFlags) /*| iflag_nolight*/;
|
|
item_list[i*9 + 3] = 0xffffffff;
|
|
}
|
|
}
|
|
|
|
|
|
// item_list[i*9 + 3] = 0xffffffff;
|
|
for (j=0;j<cshp.poly_list[i].num_verts;j++)
|
|
// item_list[i*9 + 4 +j] = (cshp.poly_list[i].vert_ind[j] *3);
|
|
/* KJL 12:23:02 9/17/97 - I've removed the annoying *3 */
|
|
item_list[i*9 + 4 +j] = (cshp.poly_list[i].vert_ind[j]);
|
|
for (;j<5;j++)
|
|
item_list[i*9 + 4 +j] = -1;
|
|
}
|
|
|
|
if (cshp.num_uvs)
|
|
{
|
|
for (i=0; i<cshp.num_uvs; i++) {
|
|
shphd->sh_textures[i] = (int *) AllocateMem (sizeof(int) * cshp.uv_list[i].num_verts * 2);
|
|
for (j=0; j<cshp.uv_list[i].num_verts; j++) {
|
|
(shphd->sh_textures[i])[(j*2)] = (int)cshp.uv_list[i].vert[j].u;
|
|
(shphd->sh_textures[i])[(j*2)+1] = (int)cshp.uv_list[i].vert[j].v;
|
|
}
|
|
}
|
|
}
|
|
/*
|
|
* FILENAME: e:\avpcode\3dc\win95\chnkload.cpp
|
|
*
|
|
* PARAMETERS:
|
|
*
|
|
* DESCRIPTION:
|
|
*
|
|
* RETURNS:
|
|
*
|
|
*/
|
|
|
|
|
|
if (cshp.num_texfiles)
|
|
{
|
|
for (i=0; i<cshp.num_texfiles; i++) {
|
|
#if john
|
|
shphd->sh_localtextures[i] =
|
|
(char *) AllocateMem (sizeof(char) * (strlen(cshp.texture_fns[i]) + strlen(TexturesRoot) + 1) );
|
|
sprintf (shphd->sh_localtextures[i],"%s%s",TexturesRoot, cshp.texture_fns[i]);
|
|
char * dotpos;
|
|
dotpos = strrchr (shphd->sh_localtextures[i], '.');
|
|
sprintf (dotpos,".pg0");
|
|
#else
|
|
shphd->sh_localtextures[i] =
|
|
(char *) AllocateMem (sizeof(char) * (strlen(cshp.texture_fns[i]) + 1) );
|
|
strcpy (shphd->sh_localtextures[i], cshp.texture_fns[i]);
|
|
#endif
|
|
}
|
|
shphd->sh_localtextures[i] = 0;
|
|
}
|
|
|
|
|
|
|
|
|
|
SHAPEINSTR * instruct = (SHAPEINSTR *)AllocateMem(sizeof(SHAPEINSTR)*6);
|
|
|
|
shphd->sh_instruction = instruct;
|
|
|
|
|
|
instruct[0].sh_instr = I_ShapePoints; /*I_shapepoints*/
|
|
instruct[0].sh_numitems = shphd->numpoints;
|
|
instruct[0].sh_instr_data = shphd->points;
|
|
|
|
instruct[1].sh_instr = I_ShapeNormals; /*I_shapenormals*/
|
|
instruct[1].sh_numitems = shphd->numitems;
|
|
instruct[1].sh_instr_data = shphd->sh_normals;
|
|
|
|
instruct[2].sh_instr = I_ShapeProject; /*I_shapeproject*/
|
|
instruct[2].sh_numitems = shphd->numpoints;
|
|
instruct[2].sh_instr_data = shphd->points;
|
|
|
|
instruct[3].sh_instr = I_ShapeVNormals; /*I_shapevnormals*/
|
|
instruct[3].sh_numitems = shphd->numpoints;
|
|
instruct[3].sh_instr_data = shphd->sh_vnormals;
|
|
|
|
instruct[4].sh_instr = I_ShapeItems;
|
|
instruct[4].sh_numitems = shphd->numitems;
|
|
instruct[4].sh_instr_data = shphd->items;
|
|
|
|
instruct[5].sh_instr = I_ShapeEnd; /*I_shapeEND*/
|
|
instruct[5].sh_numitems = 0;
|
|
instruct[5].sh_instr_data = 0;
|
|
|
|
|
|
|
|
return TRUE;
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|