summaryrefslogtreecommitdiff
path: root/src/win95/hierchnk.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/win95/hierchnk.cpp')
-rw-r--r--src/win95/hierchnk.cpp609
1 files changed, 609 insertions, 0 deletions
diff --git a/src/win95/hierchnk.cpp b/src/win95/hierchnk.cpp
new file mode 100644
index 0000000..5b26379
--- /dev/null
+++ b/src/win95/hierchnk.cpp
@@ -0,0 +1,609 @@
+#include "hierchnk.hpp"
+#include "obchunk.hpp"
+//#include "animobs.hpp"
+
+//macro for helping to force inclusion of chunks when using libraries
+FORCE_CHUNK_INCLUDE_IMPLEMENT(hierchnk)
+
+/////////////Object_Hierarchy_Chunk////////////////////
+RIF_IMPLEMENT_DYNCREATE("OBJCHIER",Object_Hierarchy_Chunk)
+
+//loader for Object_Hierarchy_Chunk
+CHUNK_WITH_CHILDREN_LOADER("OBJCHIER",Object_Hierarchy_Chunk)
+
+/*
+children for Object_Hierarchy_Chunk:
+
+"OBJCHIER" Object_Hierarchy_Chunk)
+"OBJHIERD" Object_Hierarchy_Data_Chunk)
+"OBHIERNM" Object_Hierarchy_Name_Chunk)
+"HIERBBOX" Hierarchy_Bounding_Box_Chunk)
+"OBANSEQS" Object_Animation_Sequences_Chunk)
+"OBANALLS" Object_Animation_All_Sequence_Chunk)
+
+*/
+
+List <Object_Hierarchy_Chunk *> Object_Hierarchy_Chunk::list_h_children()
+{
+ List <Chunk *> cl;
+ lookup_child ("OBJCHIER",cl);
+ List <Object_Hierarchy_Chunk *> h_l;
+
+ for (LIF<Chunk *> cli(&cl); !cli.done(); cli.next())
+ {
+ h_l.add_entry((Object_Hierarchy_Chunk *)cli());
+ }
+ return(h_l);
+
+}
+
+Object_Hierarchy_Data_Chunk * Object_Hierarchy_Chunk::get_data ()
+{
+ return((Object_Hierarchy_Data_Chunk *)lookup_single_child ("OBJHIERD"));
+
+}
+
+Object_Hierarchy_Name_Chunk * Object_Hierarchy_Chunk::get_name ()
+{
+ return((Object_Hierarchy_Name_Chunk *)lookup_single_child ("OBHIERNM"));
+}
+//////////////////////////////////////////////////////
+
+RIF_IMPLEMENT_DYNCREATE("OBJHIERD",Object_Hierarchy_Data_Chunk)
+
+Object_Hierarchy_Data_Chunk::Object_Hierarchy_Data_Chunk (Object_Hierarchy_Chunk * parent, const char * obname)
+: Chunk (parent, "OBJHIERD"), ob_name (0), object(0)
+{
+ num_extra_data=0;
+ extra_data=0;
+
+ if (obname)
+ {
+ ob_name = new char [strlen(obname)+1];
+ strcpy (ob_name, obname);
+
+ Chunk_With_Children * root = GetRootChunk();
+
+ List<Chunk *> oblist;
+ root->lookup_child ("RBOBJECT",oblist);
+
+ for (LIF<Chunk *> oli(&oblist); !oli.done(); oli.next())
+ {
+ Object_Chunk * ob = (Object_Chunk *)oli();
+
+ if (!strcmp (ob->object_data.o_name, ob_name))
+ {
+ *((Object_Chunk **)&object) = ob;
+ break;
+ }
+ }
+ }
+
+}
+
+Object_Hierarchy_Data_Chunk::~Object_Hierarchy_Data_Chunk()
+{
+ if (ob_name)
+ delete [] ob_name;
+
+ if(extra_data)
+ delete extra_data;
+}
+
+
+size_t Object_Hierarchy_Data_Chunk::size_chunk ()
+{
+ if (ob_name)
+ {
+ chunk_size = 12 + 4+4*num_extra_data + strlen(ob_name) + 4 - strlen(ob_name)%4;
+ }
+ else
+ {
+ chunk_size = 12 + 4+4*num_extra_data + 4;
+ }
+ return chunk_size;
+}
+
+
+void Object_Hierarchy_Data_Chunk::fill_data_block (char *data_start)
+{
+ strncpy (data_start, identifier, 8);
+
+ data_start += 8;
+
+ *((int *) data_start) = chunk_size;
+
+ data_start += 4;
+
+ *(int*) data_start=num_extra_data;
+ data_start+=4;
+
+ for (int i=0; i<num_extra_data; i++)
+ {
+ *((int *) data_start) = extra_data[i];
+ data_start += 4;
+ }
+
+ if (ob_name)
+ {
+ sprintf (data_start, "%s", ob_name);
+ }
+ else
+ {
+ *data_start = 0;
+ }
+
+}
+
+#if UseOldChunkLoader
+Object_Hierarchy_Data_Chunk::Object_Hierarchy_Data_Chunk (Object_Hierarchy_Chunk * parent, const char * data_start, size_t /*ssize*/)
+: Chunk (parent, "OBJHIERD"), object(0), ob_name (0)
+{
+
+ num_extra_data=0;
+ extra_data=0;
+
+ data_start+=40;
+
+ if (strlen(data_start))
+ {
+ ob_name = new char [strlen(data_start) + 1];
+ strcpy (ob_name, data_start);
+ }
+}
+#else
+Object_Hierarchy_Data_Chunk::Object_Hierarchy_Data_Chunk (Chunk_With_Children * parent, const char * data_start, size_t /*ssize*/)
+: Chunk (parent, "OBJHIERD"), object(0), ob_name (0)
+{
+ num_extra_data=*(int*)data_start;
+ data_start+=4;
+
+ if(num_extra_data)
+ extra_data=new int[num_extra_data];
+ else
+ extra_data=0;
+
+
+ for (int i=0; i<num_extra_data; i++)
+ {
+ extra_data[i] = *((int *) data_start);
+ data_start += 4;
+ }
+
+ if (strlen(data_start))
+ {
+ ob_name = new char [strlen(data_start) + 1];
+ strcpy (ob_name, data_start);
+ }
+}
+#endif
+
+void Object_Hierarchy_Data_Chunk::post_input_processing ()
+{
+ find_object_for_this_section();
+}
+
+void Object_Hierarchy_Data_Chunk::find_object_for_this_section ()
+{
+ *((Object_Chunk **)&object) = NULL;
+
+ Chunk_With_Children * root = GetRootChunk();
+
+ List<Chunk *> oblist;
+ root->lookup_child ("RBOBJECT",oblist);
+
+ for (LIF<Chunk *> oli(&oblist); !oli.done(); oli.next())
+ {
+ Object_Chunk * ob = (Object_Chunk *)oli();
+
+ if (!strcmp (ob->object_data.o_name, ob_name))
+ {
+ *((Object_Chunk **)&object) = ob;
+ break;
+ }
+ }
+}
+//////////////////////////////////////
+
+RIF_IMPLEMENT_DYNCREATE("OBHIERNM",Object_Hierarchy_Name_Chunk)
+
+Object_Hierarchy_Name_Chunk::Object_Hierarchy_Name_Chunk (Object_Hierarchy_Chunk * parent, const char * hname)
+: Chunk (parent, "OBHIERNM")
+{
+ if (hname)
+ {
+ hierarchy_name = new char [strlen(hname)+1];
+ strcpy (hierarchy_name, hname);
+ }
+ else
+ {
+ hierarchy_name = new char [1];
+ *hierarchy_name = 0;
+ }
+}
+
+Object_Hierarchy_Name_Chunk::~Object_Hierarchy_Name_Chunk()
+{
+ if (hierarchy_name)
+ {
+ delete [] hierarchy_name;
+ }
+}
+
+void Object_Hierarchy_Name_Chunk::fill_data_block (char *data_start)
+{
+ strncpy (data_start, identifier, 8);
+
+ data_start += 8;
+
+ *((int *) data_start) = chunk_size;
+
+ data_start += 4;
+
+ strcpy (data_start, hierarchy_name);
+
+}
+
+Object_Hierarchy_Name_Chunk::Object_Hierarchy_Name_Chunk (Chunk_With_Children * parent, const char * data, size_t /*ssize*/)
+: Chunk (parent, "OBHIERNM")
+{
+ hierarchy_name = new char [strlen(data)+1];
+ strcpy (hierarchy_name, data);
+}
+
+
+///////////////////////////////////////////////////
+RIF_IMPLEMENT_DYNCREATE("OBHALTSH",Object_Hierarchy_Alternate_Shape_Set_Chunk)
+
+Object_Hierarchy_Alternate_Shape_Set_Chunk::Object_Hierarchy_Alternate_Shape_Set_Chunk(Chunk_With_Children* parent,int num,const char* name)
+:Chunk(parent,"OBHALTSH")
+{
+ Shape_Set_Name=new char[strlen(name)+1];
+ Shape_Set_Num=num;
+ strcpy(Shape_Set_Name,name);
+ flags=0;
+ spare[0]=spare[1]=spare[2]=0;
+}
+Object_Hierarchy_Alternate_Shape_Set_Chunk::Object_Hierarchy_Alternate_Shape_Set_Chunk(Chunk_With_Children* parent,const char* name)
+:Chunk(parent,"OBHALTSH")
+{
+ Shape_Set_Name=new char[strlen(name)+1];
+ strcpy(Shape_Set_Name,name);
+ flags=0;
+ spare[0]=spare[1]=spare[2]=0;
+ Shape_Set_Num=-1;
+
+ //find next available shape set number
+ List<Chunk*> chlist;
+ parent->lookup_child("OBHALTSH",chlist);
+ int num=0;
+ for(LIF<Chunk*> chlif(&chlist);!chlif.done();)
+ {
+ Object_Hierarchy_Alternate_Shape_Set_Chunk* ohassc=(Object_Hierarchy_Alternate_Shape_Set_Chunk*) chlif();
+ if(ohassc->Shape_Set_Num==num)
+ {
+ num++;
+ chlif.restart();
+ }
+ else
+ {
+ chlif.next();
+ }
+ }
+
+ Shape_Set_Num=num;
+
+}
+
+Object_Hierarchy_Alternate_Shape_Set_Chunk::Object_Hierarchy_Alternate_Shape_Set_Chunk(Chunk_With_Children* parent,const char* data,size_t)
+:Chunk(parent,"OBHALTSH")
+{
+
+ Shape_Set_Num=*(int*)data;
+ data+=4;
+
+ int name_length=strlen(data)+1;
+ Shape_Set_Name=new char[name_length];
+ strcpy(Shape_Set_Name,data);
+ data+=(name_length+3)&~3;
+
+ int num_shapes=*(int*)data;
+ data+=4;
+
+ for(int i=0;i<num_shapes;i++)
+ {
+ Replaced_Shape_Details* rsd=new Replaced_Shape_Details;
+
+ name_length=strlen(data)+1;
+ rsd->old_object_name=new char[name_length];
+ strcpy(rsd->old_object_name,data);
+ data+=(name_length+3)&~3;
+
+ name_length=strlen(data)+1;
+ rsd->new_object_name=new char[name_length];
+ strcpy(rsd->new_object_name,data);
+ data+=(name_length+3)&~3;
+
+ Replaced_Shape_List.add_entry(rsd);
+ }
+
+ flags=*(int*)data;
+ data+=4;
+
+ for(i=0;i<3;i++)
+ {
+ spare[i]=*(int*)data;
+ data+=4;
+ }
+
+}
+
+Object_Hierarchy_Alternate_Shape_Set_Chunk::~Object_Hierarchy_Alternate_Shape_Set_Chunk()
+{
+ if(Shape_Set_Name) delete Shape_Set_Name;
+
+ while(Replaced_Shape_List.size())
+ {
+ delete Replaced_Shape_List.first_entry();
+ Replaced_Shape_List.delete_first_entry();
+ }
+
+}
+
+void Object_Hierarchy_Alternate_Shape_Set_Chunk::fill_data_block(char* data_start)
+{
+ strncpy (data_start, identifier, 8);
+
+ data_start += 8;
+
+ *((int *) data_start) = chunk_size;
+
+ data_start += 4;
+
+ *(int*)data_start=Shape_Set_Num;
+ data_start+=4;
+
+ strcpy(data_start,Shape_Set_Name);
+ data_start+=(strlen(Shape_Set_Name)+4)&~3;
+
+ *(int*)data_start=Replaced_Shape_List.size();
+ data_start+=4;
+
+ for(LIF<Replaced_Shape_Details*> rlif(&Replaced_Shape_List);!rlif.done();rlif.next())
+ {
+ strcpy(data_start,rlif()->old_object_name);
+ data_start+=(strlen(rlif()->old_object_name)+4)&~3;
+
+ strcpy(data_start,rlif()->new_object_name);
+ data_start+=(strlen(rlif()->new_object_name)+4)&~3;
+ }
+
+ *(int*)data_start=flags;
+ data_start+=4;
+
+ for(int i=0;i<3;i++)
+ {
+ *(int*)data_start=spare[i];
+ data_start+=4;
+ }
+
+}
+
+size_t Object_Hierarchy_Alternate_Shape_Set_Chunk::size_chunk()
+{
+ chunk_size=36;
+ chunk_size+=(strlen(Shape_Set_Name)+4)&~3;
+ for(LIF<Replaced_Shape_Details*> rlif(&Replaced_Shape_List);!rlif.done();rlif.next())
+ {
+ chunk_size+=(strlen(rlif()->old_object_name)+4)&~3;
+ chunk_size+=(strlen(rlif()->new_object_name)+4)&~3;
+ }
+ return chunk_size;
+
+}
+
+
+///////////////////////////////////////////////////
+RIF_IMPLEMENT_DYNCREATE("HSETCOLL",Hierarchy_Shape_Set_Collection_Chunk)
+
+Hierarchy_Shape_Set_Collection_Chunk::Hierarchy_Shape_Set_Collection_Chunk(Chunk_With_Children* parent,int num,const char* name)
+:Chunk(parent,"HSETCOLL")
+{
+ Set_Collection_Name=new char[strlen(name)+1];
+ Set_Collection_Num=num;
+ strcpy(Set_Collection_Name,name);
+ TypeIndex=flags=0;
+}
+
+
+Hierarchy_Shape_Set_Collection_Chunk::Hierarchy_Shape_Set_Collection_Chunk(Chunk_With_Children* parent,const char* data,size_t)
+:Chunk(parent,"HSETCOLL")
+{
+
+ Set_Collection_Num=*(int*)data;
+ data+=4;
+
+ int name_length=strlen(data)+1;
+ Set_Collection_Name=new char[name_length];
+ strcpy(Set_Collection_Name,data);
+ data+=(name_length+3)&~3;
+
+ int list_length=*(int*)data;
+ data+=4;
+
+ for(int i=0;i<list_length;i++)
+ {
+ Index_List.add_entry(*(int*)data);
+ data+=4;
+ }
+
+ TypeIndex=*(int*)data;
+ data+=4;
+ flags=*(int*)data;
+ data+=4;
+}
+
+Hierarchy_Shape_Set_Collection_Chunk::~Hierarchy_Shape_Set_Collection_Chunk()
+{
+ if(Set_Collection_Name) delete Set_Collection_Name;
+}
+
+void Hierarchy_Shape_Set_Collection_Chunk::fill_data_block(char* data_start)
+{
+ strncpy (data_start, identifier, 8);
+
+ data_start += 8;
+
+ *((int *) data_start) = chunk_size;
+
+ data_start += 4;
+
+ *(int*)data_start=Set_Collection_Num;
+ data_start+=4;
+
+ strcpy(data_start,Set_Collection_Name);
+ data_start+=(strlen(Set_Collection_Name)+4)&~3;
+
+ *(int*)data_start=Index_List.size();
+ data_start+=4;
+
+ for(LIF<int> slif(&Index_List);!slif.done();slif.next())
+ {
+ *(int*)data_start=slif();
+ data_start+=4;
+ }
+
+ *(int*)data_start=TypeIndex;
+ data_start+=4;
+ *(int*)data_start=flags;
+ data_start+=4;
+
+}
+
+size_t Hierarchy_Shape_Set_Collection_Chunk::size_chunk()
+{
+ chunk_size=12+16;
+ chunk_size+=(strlen(Set_Collection_Name)+4)&~3;
+ chunk_size+=Index_List.size()*4;
+ return chunk_size;
+
+}
+
+///////////////////////////////////////////////////
+
+RIF_IMPLEMENT_DYNCREATE("HIDEGDIS",Hierarchy_Degradation_Distance_Chunk)
+
+Hierarchy_Degradation_Distance_Chunk::Hierarchy_Degradation_Distance_Chunk(Chunk_With_Children* parent,int _num_detail_levels)
+:Chunk(parent,"HIDEGDIS")
+{
+ num_detail_levels=_num_detail_levels;
+ if(num_detail_levels)
+ {
+ distance_array=new int[num_detail_levels];
+ }
+ else
+ {
+ distance_array=0;
+ }
+ //fill in some arbitrary distance values
+ for(int i=0;i<num_detail_levels;i++)
+ {
+ distance_array[i]=i*10000;
+ }
+
+}
+
+Hierarchy_Degradation_Distance_Chunk::Hierarchy_Degradation_Distance_Chunk(Chunk_With_Children* parent,const char* data,size_t)
+:Chunk(parent,"HIDEGDIS")
+{
+ num_detail_levels=*(int*)data;
+ data+=sizeof(int);
+
+ if(num_detail_levels)
+ {
+ distance_array=new int[num_detail_levels];
+ }
+ else
+ {
+ distance_array=0;
+ }
+
+ for(int i=0;i<num_detail_levels;i++)
+ {
+ distance_array[i]=*(int*)data;
+ data+=sizeof(int);
+ }
+
+}
+
+Hierarchy_Degradation_Distance_Chunk::~Hierarchy_Degradation_Distance_Chunk()
+{
+ if(distance_array)delete distance_array;
+}
+
+void Hierarchy_Degradation_Distance_Chunk::fill_data_block(char* data_start)
+{
+ strncpy (data_start, identifier, 8);
+
+ data_start += 8;
+
+ *((int *) data_start) = chunk_size;
+
+ data_start += 4;
+
+ *(int*)data_start=num_detail_levels;
+ data_start+=4;
+
+ for(int i=0;i<num_detail_levels;i++)
+ {
+ *(int*)data_start=distance_array[i];
+ data_start+=4;
+ }
+}
+
+size_t Hierarchy_Degradation_Distance_Chunk::size_chunk()
+{
+ chunk_size=16+num_detail_levels*4;
+ return chunk_size;
+
+}
+
+
+///////////////////////////////////////////////////
+
+RIF_IMPLEMENT_DYNCREATE("HIERBBOX",Hierarchy_Bounding_Box_Chunk)
+
+#if UseOldChunkLoader
+Hierarchy_Bounding_Box_Chunk::Hierarchy_Bounding_Box_Chunk(Chunk_With_Children* parent,const char* data,size_t datasize)
+:Chunk(parent,"HIERBBOX")
+{
+ assert(datasize==2*sizeof(ChunkVector));
+
+
+ min=*(ChunkVector*)data;
+ data+=sizeof(ChunkVector);
+ max=*(ChunkVector*)data;
+}
+#else
+Hierarchy_Bounding_Box_Chunk::Hierarchy_Bounding_Box_Chunk(Chunk_With_Children* parent,const char* data,size_t datasize)
+:Chunk(parent,"HIERBBOX")
+{
+ assert(datasize==2*sizeof(ChunkVectorInt));
+
+ min=*(ChunkVectorInt*)data;
+ data+=sizeof(ChunkVectorInt);
+ max=*(ChunkVectorInt*)data;
+}
+#endif
+void Hierarchy_Bounding_Box_Chunk::fill_data_block(char* data_start)
+{
+ strncpy (data_start, identifier, 8);
+ data_start += 8;
+ *((int *) data_start) = chunk_size;
+ data_start += 4;
+
+ *(ChunkVectorInt*)data_start=min;
+ data_start+=sizeof(ChunkVectorInt);
+ *(ChunkVectorInt*)data_start=max;
+}
+///////////////////////////////////////////////////