summaryrefslogtreecommitdiff
path: root/src/win95/wpchunk.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/win95/wpchunk.cpp')
-rw-r--r--src/win95/wpchunk.cpp575
1 files changed, 575 insertions, 0 deletions
diff --git a/src/win95/wpchunk.cpp b/src/win95/wpchunk.cpp
new file mode 100644
index 0000000..c26a5a6
--- /dev/null
+++ b/src/win95/wpchunk.cpp
@@ -0,0 +1,575 @@
+#include "wpchunk.hpp"
+
+//macro for helping to force inclusion of chunks when using libraries
+FORCE_CHUNK_INCLUDE_IMPLEMENT(wpchunk)
+
+ChunkWaypoint::ChunkWaypoint()
+{
+ index=-1;
+ NumWPLinks=0;
+ WayLinks=0;
+ NumModLinks=0;
+ ModLinks=0;
+ flags=0;
+ spare2=0;
+}
+ChunkWaypoint::~ChunkWaypoint()
+{
+ if(WayLinks) delete [] WayLinks;
+ if(ModLinks) delete [] ModLinks;
+}
+ModuleLink::~ModuleLink()
+{
+ if(module_name) delete module_name;
+}
+
+RIF_IMPLEMENT_DYNCREATE("WAYPOINT",Module_Waypoint_Chunk)
+
+
+#if UseOldChunkLoader
+Module_Waypoint_Chunk::Module_Waypoint_Chunk(Chunk_With_Children* parent,const char* data,size_t datasize)
+:Chunk(parent,"WAYPOINT")
+{
+ NumWaypoints=*(int*)data;
+ data+=4;
+ if(NumWaypoints)
+ Waypoints=new ChunkWaypoint[NumWaypoints];
+ else
+ Waypoints=0;
+
+ for(int i=0;i<NumWaypoints;i++)
+ {
+ ChunkWaypoint* cw=&Waypoints[i];
+ cw->index=i;
+
+ cw->min=*(ChunkVector*)data;
+ data+=sizeof(ChunkVector);
+ cw->max=*(ChunkVector*)data;
+ data+=sizeof(ChunkVector);
+ cw->centre=*(ChunkVector*)data;
+ data+=sizeof(ChunkVector);
+
+ cw->flags=*(int*)data;
+ data+=4;
+ cw->spare2=*(int*)data;
+ data+=4;
+
+ cw->NumWPLinks=*(int*)data;
+ data+=4;
+
+ if(cw->NumWPLinks)
+ cw->WayLinks=new WaypointLink[cw->NumWPLinks];
+ else
+ cw->WayLinks=0;
+
+ for(int j=0;j<cw->NumWPLinks;j++)
+ {
+ cw->WayLinks[j]=*(WaypointLink*)data;
+ data+=sizeof(WaypointLink);
+ }
+
+ cw->NumModLinks=*(int*)data;
+ data+=4;
+
+ if(cw->NumModLinks)
+ cw->ModLinks=new ModuleLink[cw->NumModLinks];
+ else
+ cw->ModLinks=0;
+
+ for(j=0;j<cw->NumModLinks;j++)
+ {
+ ModuleLink* ml=&cw->ModLinks[j];
+ ml->module_name=new char[strlen(data)+1];
+ strcpy(ml->module_name,data);
+ data+=(strlen(data)+4)&~3;
+ ml->flags=*(int*)data;
+ data+=4;
+ }
+
+
+ }
+
+ spare1=*(int*)data;
+ data+=4;
+ spare2=*(int*)data;
+ data+=4;
+}
+#else
+Module_Waypoint_Chunk::Module_Waypoint_Chunk(Chunk_With_Children* parent,const char* data,size_t datasize)
+:Chunk(parent,"WAYPOINT")
+{
+ NumWaypoints=*(int*)data;
+ data+=4;
+
+ NumGroundWaypoints=0;
+ NumAlienWaypoints=0;
+ AlienWaypoints=0;
+ GroundWaypoints=0;
+
+ if(NumWaypoints)
+ Waypoints=new ChunkWaypoint[NumWaypoints];
+ else
+ Waypoints=0;
+
+ if(NumWaypoints)
+ {
+ int first_ground_waypoint=-1;
+ for(int i=0;i<NumWaypoints;i++)
+ {
+ ChunkWaypoint* cw=&Waypoints[i];
+ cw->index=i;
+
+ cw->min=*(ChunkVectorInt*)data;
+ data+=sizeof(ChunkVectorInt);
+ cw->max=*(ChunkVectorInt*)data;
+ data+=sizeof(ChunkVectorInt);
+ cw->centre=*(ChunkVectorInt*)data;
+ data+=sizeof(ChunkVectorInt);
+
+ cw->flags=*(int*)data;
+ data+=4;
+ cw->spare2=*(int*)data;
+ data+=4;
+
+ cw->NumWPLinks=*(int*)data;
+ data+=4;
+
+ if(cw->NumWPLinks)
+ cw->WayLinks=new WaypointLink[cw->NumWPLinks];
+ else
+ cw->WayLinks=0;
+
+ for(int j=0;j<cw->NumWPLinks;j++)
+ {
+ cw->WayLinks[j]=*(WaypointLink*)data;
+ data+=sizeof(WaypointLink);
+ }
+
+ cw->NumModLinks=*(int*)data;
+ data+=4;
+
+ if(cw->NumModLinks)
+ cw->ModLinks=new ModuleLink[cw->NumModLinks];
+ else
+ cw->ModLinks=0;
+
+ for(j=0;j<cw->NumModLinks;j++)
+ {
+ ModuleLink* ml=&cw->ModLinks[j];
+ ml->module_name=new char[strlen(data)+1];
+ strcpy(ml->module_name,data);
+ data+=(strlen(data)+4)&~3;
+ ml->flags=*(int*)data;
+ data+=4;
+ }
+
+ if(cw->flags & WaypointFlag_FirstGroundWaypoint)
+ {
+ first_ground_waypoint=i;
+ cw->flags &=~WaypointFlag_FirstGroundWaypoint;
+ }
+ }
+
+ if(first_ground_waypoint>=0)
+ {
+ GroundWaypoints=&Waypoints[first_ground_waypoint];
+ NumGroundWaypoints=NumWaypoints-first_ground_waypoint;
+ }
+ NumAlienWaypoints=NumWaypoints-NumGroundWaypoints;
+ if(NumAlienWaypoints)
+ {
+ AlienWaypoints=&Waypoints[0];
+ }
+
+
+ }
+
+
+ spare1=*(int*)data;
+ data+=4;
+ spare2=*(int*)data;
+ data+=4;
+
+}
+#endif
+
+Module_Waypoint_Chunk::Module_Waypoint_Chunk(Chunk_With_Children* parent)
+:Chunk(parent,"WAYPOINT")
+{
+ NumWaypoints=0;
+ Waypoints=0;
+
+ NumAlienWaypoints=0;
+ AlienWaypoints=0;
+
+ NumGroundWaypoints=0;
+ GroundWaypoints=0;
+
+
+ spare1=0;
+ spare2=0;
+}
+
+Module_Waypoint_Chunk::~Module_Waypoint_Chunk()
+{
+ if(Waypoints)
+ delete [] Waypoints;
+}
+
+size_t Module_Waypoint_Chunk::size_chunk()
+{
+ chunk_size=16;
+ for(int i=0;i<NumWaypoints;i++)
+ {
+ chunk_size+=16+3*sizeof(ChunkVectorInt);
+ chunk_size+=sizeof(WaypointLink)*Waypoints[i].NumWPLinks;
+ for(int j=0;j<Waypoints[i].NumModLinks;j++)
+ {
+ chunk_size+=4;
+ chunk_size+=(strlen(Waypoints[i].ModLinks[j].module_name)+4)&~3;
+ }
+ }
+ return chunk_size;
+}
+
+void Module_Waypoint_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=NumWaypoints;
+ data_start+=4;
+
+ for(int i=0;i<NumWaypoints;i++)
+ {
+ ChunkWaypoint* cw=&Waypoints[i];
+
+ *(ChunkVectorInt*)data_start=cw->min;
+ data_start+=sizeof(ChunkVectorInt);
+ *(ChunkVectorInt*)data_start=cw->max;
+ data_start+=sizeof(ChunkVectorInt);
+ *(ChunkVectorInt*)data_start=cw->centre;
+ data_start+=sizeof(ChunkVectorInt);
+
+ if(i==NumAlienWaypoints)
+ {
+ //mark start of marine waypoints
+ *(int*)data_start=cw->flags | WaypointFlag_FirstGroundWaypoint;
+ }
+ else
+ {
+ *(int*)data_start=cw->flags;
+ }
+ data_start+=4;
+
+ *(int*)data_start=cw->spare2;
+ data_start+=4;
+
+ *(int*)data_start=cw->NumWPLinks;
+ data_start+=4;
+
+ for(int j=0;j<cw->NumWPLinks;j++)
+ {
+ *(WaypointLink*)data_start=cw->WayLinks[j];
+ data_start+=sizeof(WaypointLink);
+ }
+
+ *(int*)data_start=cw->NumModLinks;
+ data_start+=4;
+
+ for(j=0;j<cw->NumModLinks;j++)
+ {
+ ModuleLink* ml=&cw->ModLinks[j];
+ strcpy(data_start,ml->module_name);
+ data_start+=(strlen(ml->module_name)+4)&~3;
+ *(int*)data_start=ml->flags;
+ data_start+=4;
+ }
+
+ }
+}
+
+void Module_Waypoint_Chunk::TransferWaypointData(Module_Waypoint_Chunk* mwc_from)
+{
+ if(!mwc_from)return;
+ if(!mwc_from->NumWaypoints)return;
+ if(mwc_from==this)return;
+
+ if(mwc_from->NumWaypoints)
+ {
+ ChunkWaypoint* new_wp=new ChunkWaypoint[NumWaypoints+mwc_from->NumWaypoints];
+ //first take alien waypoints from this chunk
+ for(int i=0;i<NumAlienWaypoints;i++)
+ {
+ new_wp[i]=AlienWaypoints[i];
+ //set pointers to zero so the memory doesn't get deallocated when the old
+ //waypoint array is deleted
+ AlienWaypoints[i].WayLinks=0;
+ AlienWaypoints[i].ModLinks=0;
+ }
+
+ //copy alien waypoints from other chunk
+
+ for(i=0;i<mwc_from->NumAlienWaypoints;i++)
+ {
+ ChunkWaypoint* cw=&new_wp[i+NumAlienWaypoints];
+ *cw=mwc_from->AlienWaypoints[i];
+ //set pointers to zero so the memory doesn't get deallocated when the old
+ //waypoint chunk is deleted
+ mwc_from->AlienWaypoints[i].WayLinks=0;
+ mwc_from->AlienWaypoints[i].ModLinks=0;
+
+ //adjust the indeces
+ cw->index+=NumAlienWaypoints;
+ for(int j=0;j<cw->NumWPLinks;j++)
+ {
+ cw->WayLinks[j].index+=NumAlienWaypoints;
+ }
+ }
+ NumAlienWaypoints+=mwc_from->NumAlienWaypoints;
+
+ //now take ground waypoints from this chunk
+ for(i=0;i<NumGroundWaypoints;i++)
+ {
+ new_wp[NumAlienWaypoints+i]=GroundWaypoints[i];
+ //set pointers to zero so the memory doesn't get deallocated when the old
+ //waypoint array is deleted
+ GroundWaypoints[i].WayLinks=0;
+ GroundWaypoints[i].ModLinks=0;
+ }
+
+ //copy ground waypoints from other chunk
+
+ for(i=0;i<mwc_from->NumGroundWaypoints;i++)
+ {
+ ChunkWaypoint* cw=&new_wp[i+NumAlienWaypoints+NumGroundWaypoints];
+ *cw=mwc_from->GroundWaypoints[i];
+ //set pointers to zero so the memory doesn't get deallocated when the old
+ //waypoint chunk is deleted
+ mwc_from->GroundWaypoints[i].WayLinks=0;
+ mwc_from->GroundWaypoints[i].ModLinks=0;
+
+ //adjust the indeces
+ cw->index+=NumGroundWaypoints;
+ for(int j=0;j<cw->NumWPLinks;j++)
+ {
+ cw->WayLinks[j].index+=NumGroundWaypoints;
+ }
+ }
+ NumGroundWaypoints+=mwc_from->NumGroundWaypoints;
+
+ NumWaypoints+=mwc_from->NumWaypoints;
+ //replace pointer to waypoints
+ delete [] Waypoints;
+ Waypoints=new_wp;
+ }
+
+ if(NumAlienWaypoints)
+ AlienWaypoints=&Waypoints[0];
+ else
+ AlienWaypoints=0;
+
+ if(NumGroundWaypoints)
+ GroundWaypoints=&Waypoints[NumAlienWaypoints];
+ else
+ GroundWaypoints=0;
+
+
+ delete mwc_from;
+
+}
+///////////////////////////////////////////////////////////////////////////////
+
+RIF_IMPLEMENT_DYNCREATE("AIMODMAS",AI_Module_Master_Chunk)
+
+AI_Module_Master_Chunk::AI_Module_Master_Chunk(Chunk_With_Children* parent,const char* data,size_t)
+:Chunk(parent,"AIMODMAS")
+{
+}
+
+AI_Module_Master_Chunk::AI_Module_Master_Chunk(Object_Module_Data_Chunk* parent)
+:Chunk(parent,"AIMODMAS")
+{
+}
+
+
+size_t AI_Module_Master_Chunk::size_chunk()
+{
+ chunk_size=12;
+ return chunk_size;
+}
+
+void AI_Module_Master_Chunk::fill_data_block(char* data_start)
+{
+ strncpy (data_start, identifier, 8);
+ data_start += 8;
+ *((int *) data_start) = chunk_size;
+ data_start += 4;
+}
+
+AI_Module_Slave_Chunk* AddModuleSlaveChunk(Object_Chunk* oc,Object_Chunk* master)
+{
+ Object_Module_Data_Chunk* omdc=0;
+ omdc=(Object_Module_Data_Chunk*)oc->lookup_single_child("MODULEDT");
+ if(!omdc)
+ omdc=new Object_Module_Data_Chunk(oc);
+
+ Chunk* child_chunk=omdc->lookup_single_child("AIMODSLA");
+
+ if(child_chunk)
+ delete child_chunk;
+
+ return new AI_Module_Slave_Chunk(omdc,master);
+
+}
+
+void AI_Module_Master_Chunk::AddModule(Object_Chunk* oc)
+{
+ if(ModuleList.contains(oc)) return;
+ if(oc==get_my_object_chunk()) return;
+
+ Object_Module_Data_Chunk* omdc=0;
+ omdc=(Object_Module_Data_Chunk*)oc->lookup_single_child("MODULEDT");
+
+ if(omdc)
+ {
+ List<Chunk*> chlist;
+ omdc->lookup_child("AIMODMAS",chlist);
+ if(chlist.size())
+ {
+ //if the module being added is a master , add all its slaves as well
+ AI_Module_Master_Chunk* ammc=(AI_Module_Master_Chunk*)chlist.first_entry();
+ for(LIF<Object_Chunk*> oblif(&ammc->ModuleList);!oblif.done();oblif.next())
+ {
+ if(!ModuleList.contains(oblif()) && oblif()!=get_my_object_chunk())
+ {
+ ModuleList.add_entry(oblif());
+ //create new slave chunks for the modules being added
+ AddModuleSlaveChunk(oblif(),get_my_object_chunk());
+ }
+ }
+ delete ammc;
+ }
+ }
+
+ //add this module
+ ModuleList.add_entry(oc);
+ AddModuleSlaveChunk(oc,get_my_object_chunk());
+
+ //see if there are any waypoints to copy
+ if(omdc)
+ {
+ Module_Waypoint_Chunk* mwc_from=(Module_Waypoint_Chunk*)omdc->lookup_single_child("WAYPOINT");
+ if(mwc_from)
+ {
+ Module_Waypoint_Chunk* mwc_to=0;
+
+ mwc_to=(Module_Waypoint_Chunk*)parent->lookup_single_child("WAYPOINT");
+ if(!mwc_to)
+ mwc_to=new Module_Waypoint_Chunk(parent);
+
+ mwc_to->TransferWaypointData(mwc_from);
+
+
+ }
+ }
+
+}
+
+Object_Chunk* AI_Module_Master_Chunk::get_my_object_chunk()
+{
+ return (Object_Chunk*)((Object_Module_Data_Chunk*)parent)->parent;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+RIF_IMPLEMENT_DYNCREATE("AIMODSLA",AI_Module_Slave_Chunk)
+
+#if UseOldChunkLoader
+AI_Module_Slave_Chunk::AI_Module_Slave_Chunk(Object_Module_Data_Chunk* parent,const char* data,size_t)
+:Chunk(parent,"AIMODSLA")
+{
+ MasterModule=0;
+ MasterModuleName=new char[strlen(data)+1];
+ strcpy(MasterModuleName,data);
+ MasterModuleIndex=0;
+}
+#else
+AI_Module_Slave_Chunk::AI_Module_Slave_Chunk(Chunk_With_Children* parent,const char* data,size_t)
+:Chunk(parent,"AIMODSLA")
+{
+ MasterModule=0;
+ MasterModuleIndex=*(int*)data;
+}
+#endif
+
+AI_Module_Slave_Chunk::AI_Module_Slave_Chunk(Object_Module_Data_Chunk* parent,Object_Chunk* _MasterModule)
+:Chunk(parent,"AIMODSLA")
+{
+ MasterModule=_MasterModule;
+ MasterModuleIndex=MasterModule->object_data.index_num;
+}
+
+AI_Module_Slave_Chunk::~AI_Module_Slave_Chunk()
+{
+ #if UseOldChunkLoader
+ delete [] MasterModuleName;
+ #endif
+}
+
+size_t AI_Module_Slave_Chunk::size_chunk()
+{
+ chunk_size=16;
+ return chunk_size;
+}
+
+void AI_Module_Slave_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) = MasterModuleIndex;
+ data_start += 4;
+
+
+}
+
+void AI_Module_Slave_Chunk::post_input_processing()
+{
+ #if !UseOldChunkLoader
+ File_Chunk* fc=(File_Chunk*)GetRootChunk();
+ if(!strcmp(fc->identifier,"REBINFF2"))
+ {
+ Object_Chunk* oc=fc->get_object_by_index(MasterModuleIndex);
+ if(oc)
+ {
+ Object_Module_Data_Chunk* omdc=(Object_Module_Data_Chunk*)oc->lookup_single_child("MODULEDT");
+ if(!omdc)
+ {
+ return;
+ }
+
+ List<Chunk*> chlist;
+ omdc->lookup_child("AIMODMAS",chlist);
+ if(!chlist.size())
+ {
+ //master module doesn't have a master module chunk
+ return;
+ }
+ AI_Module_Master_Chunk* ammc=(AI_Module_Master_Chunk*)chlist.first_entry();
+ ammc->ModuleList.add_entry(get_my_object_chunk());
+ MasterModule=oc;
+ return;
+
+ }
+ }
+ #endif
+}
+
+Object_Chunk* AI_Module_Slave_Chunk::get_my_object_chunk()
+{
+ return (Object_Chunk*)((Object_Module_Data_Chunk*)parent)->parent;
+}