summaryrefslogtreecommitdiff
path: root/src/win95/chnkload.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/win95/chnkload.cpp')
-rw-r--r--src/win95/chnkload.cpp4024
1 files changed, 4024 insertions, 0 deletions
diff --git a/src/win95/chnkload.cpp b/src/win95/chnkload.cpp
new file mode 100644
index 0000000..2113372
--- /dev/null
+++ b/src/win95/chnkload.cpp
@@ -0,0 +1,4024 @@
+#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
+
+
+
+
+