avp/3dc/win95/OBCHUNK.CPP

1435 lines
29 KiB
C++
Raw Normal View History

#include "chunk.hpp"
#include "chnktype.hpp"
#include "mishchnk.hpp"
#include "obchunk.hpp"
#include "shpchunk.hpp"
#include "envchunk.hpp"
#include "md5.h"
// Class Object_Chunk functions
#ifdef cencon
#define new my_new
#endif
//macro for helping to force inclusion of chunks when using libraries
FORCE_CHUNK_INCLUDE_IMPLEMENT(obchunk)
RIF_IMPLEMENT_DYNCREATE("RBOBJECT",Object_Chunk)
/*
Children for Object_Chunk :
"OBJHEAD1" Object_Header_Chunk
"OBINTDT" Object_Interface_Data_Chunk
"OBJPRJDT" Object_Project_Data_Chunk
"MODULEDT" Object_Module_Data_Chunk
"SHPVTINT" Shape_Vertex_Intensities_Chunk
"OBJTRAK2" Object_Track_Chunk2
"TRAKSOUN" Object_Track_Sound_Chunk
"OBANSEQS" Object_Animation_Sequences_Chunk
"PLOBJLIT" Placed_Object_Light_Chunk
"ALTLOCAT" Object_Alternate_Locations_Chunk
*/
// from buffer
Object_Chunk::Object_Chunk(Chunk_With_Children * parent, const char *data, size_t size)
: Lockable_Chunk_With_Children (parent, "RBOBJECT"),
object_data ()
{
const char * buffer_ptr = data;
object_data_store = (ChunkObject *) &object_data;
while ((data-buffer_ptr)< (signed) size) {
if ((*(int *)(data + 8)) + (data-buffer_ptr) > (signed) size) {
Parent_File->error_code = CHUNK_FAILED_ON_LOAD_NOT_RECOGNISED;
break;
}
DynCreate(data);
data += *(int *)(data + 8);
}
program_object_index=-1;
}
// from data
Object_Chunk::Object_Chunk (Chunk_With_Children * parent, ChunkObject &obj)
: Lockable_Chunk_With_Children (parent, "RBOBJECT"),
object_data (obj)
{
object_data_store = (ChunkObject *) &object_data;
object_data_store->index_num=-1;
new Object_Header_Chunk(this);
new Object_Interface_Data_Chunk(this);
//if the parent is a file_chunk get an object index
if(!strcmp(parent->identifier,"REBINFF2"))
{
((File_Chunk*)parent)->assign_index_to_object(this);
}
program_object_index=-1;
CalculateID();
}
Object_Chunk::~Object_Chunk()
{
}
Object_Header_Chunk * Object_Chunk::get_header()
{
return (Object_Header_Chunk *) this->lookup_single_child ("OBJHEAD1");
}
Shape_Chunk * Object_Chunk::get_assoc_shape()
{
if (!get_header()) return 0;
return get_header()->associated_shape;
}
BOOL Object_Chunk::assoc_with_shape (Shape_Chunk * shpch)
{
Object_Header_Chunk * obhead = get_header();
if (!obhead) return 0;
// check that we are not already associated with this shape
if (obhead->associated_shape == shpch) return 1;
Shape_Header_Chunk * shphead = shpch->get_header();
if (!shphead) return 0;
// deassociate with the old shape
if (obhead->associated_shape)
deassoc_with_shape (obhead->associated_shape);
// associate with the new
obhead->associated_shape = shpch;
if (!shphead->associated_objects_store.contains(this))
shphead->associated_objects_store.add_entry(this);
return 1;
}
BOOL Object_Chunk::deassoc_with_shape (Shape_Chunk * shpch)
{
Shape_Header_Chunk * shphead = shpch->get_header();
if (!shphead) return 0;
if (shphead->associated_objects_store.contains(this))
shphead->associated_objects_store.delete_entry(this);
Object_Header_Chunk * obhead = get_header();
obhead->associated_shape = 0;
return 1;
}
BOOL Object_Chunk::file_equals(HANDLE &rif_file)
{
unsigned long bytes_read;
char name[50];
// get header list
List<int> obhead;
list_chunks_in_file (&obhead, rif_file, "OBJHEAD1");
if (obhead.size() != 1) return FALSE;
// get object identifier
SetFilePointer(rif_file,obhead.first_entry() + 96,0,FILE_BEGIN);
int i = 0;
do ReadFile (rif_file, (long *) (name + i), 1, &bytes_read, 0);
while (name[i++] != 0);
if (!strcmp(name, object_data.o_name) ) return (TRUE);
return (FALSE);
}
const char * Object_Chunk::get_head_id()
{
Object_Header_Chunk * hdptr = get_header();
if (!hdptr) return (0);
return(hdptr->identifier);
}
void Object_Chunk::set_lock_user (char * user)
{
Object_Header_Chunk * hdptr = get_header();
if (!hdptr) return;
strncpy (hdptr->lock_user, user,16);
hdptr->lock_user[16] = 0;
}
BOOL Object_Chunk::inc_v_no ()
{
Object_Header_Chunk * hdptr = get_header();
if (!hdptr) return (FALSE);
hdptr->version_no++;
return (TRUE);
}
BOOL Object_Chunk::same_and_updated(Object_Chunk & obj)
{
Object_Header_Chunk * hd1ptr = get_header();
if (!hd1ptr) return (0);
Object_Header_Chunk * hd2ptr = obj.get_header();
if (!hd2ptr) return (0);
return (hd1ptr->version_no < hd2ptr->version_no &&
(!strcmp(obj.object_data.o_name, object_data.o_name)) );
}
BOOL Object_Chunk::assoc_with_shape_no(File_Chunk *fc)
{
Object_Header_Chunk * hdptr = get_header();
Shape_Chunk * shp = NULL;
Shape_Header_Chunk * shphd;
if (!hdptr) return (FALSE);
List<Chunk *> chlst;
fc->lookup_child("REBSHAPE",chlst);
for (LIF<Chunk *> l(&chlst); !l.done(); l.next())
{
shp = (Shape_Chunk *)l();
shphd = shp->get_header();
if (shphd)
{
if (hdptr->shape_id_no == shphd->file_id_num)
break;
}
}
if (!l.done())
{
assoc_with_shape(shp);
}
else
{
return(FALSE);
}
return(TRUE);
}
void Object_Chunk::post_input_processing()
{
CalculateID();
if (get_header())
if (get_header()->flags & GENERAL_FLAG_LOCKED)
external_lock = TRUE;
Chunk_With_Children::post_input_processing();
}
VModule_Array_Chunk * Object_Chunk::get_vmod_chunk()
{
Object_Module_Data_Chunk * omdc = 0;
omdc = (Object_Module_Data_Chunk *) lookup_single_child ("MODULEDT");
if (omdc)
{
VModule_Array_Chunk * vmac = 0;
vmac = (VModule_Array_Chunk *)omdc->lookup_single_child ("VMDARRAY") ;
if (vmac) return(vmac);
}
return(0);
}
void Object_Chunk::destroy(File_Chunk * fc)
{
List<Chunk *> cl;
fc->lookup_child("RBOBJECT",cl);
for (LIF<Chunk *> cli(&cl); !cli.done(); cli.next())
{
Object_Chunk * ob = (Object_Chunk *)cli();
if (ob == this) continue;
VModule_Array_Chunk * vmac = ob->get_vmod_chunk();
BOOL in_object_va = FALSE;
if (vmac)
{
int pos=0;
for(int i=0;i<vmac->num_array_items;i++)
{
if (vmac->vmod_array[i].object_index==object_data.index_num)
{
in_object_va=TRUE;
//update branch indeces for branches that go beyond this point
for(int j=0;j<vmac->num_array_items;j++)
{
if(vmac->vmod_array[j].branch_no> pos)
vmac->vmod_array[j].branch_no--;
}
}
else
{
if(pos!=i)
{
vmac->vmod_array[pos]=vmac->vmod_array[i];
}
pos++;
}
}
if(in_object_va)
{
if(pos==0)
{
delete vmac;
}
else
{
//excess entries should be properly deleted when the array is deleted
vmac->num_array_items=pos;
}
}
}
//now remove this object from any adjacency data
Object_Module_Data_Chunk* omdc=(Object_Module_Data_Chunk*)ob->lookup_single_child("MODULEDT");
if(omdc)
{
Adjacent_Module_Entry_Points_Chunk* amepc=(Adjacent_Module_Entry_Points_Chunk*)omdc->lookup_single_child("ADJMDLEP");
if(amepc)
{
for(LIF<Adjacent_Module> ad_lif(&amepc->adjacent_modules_list);!ad_lif.done();)
{
if(ad_lif().object_index==object_data.index_num)
ad_lif.delete_current();
else
ad_lif.next();
}
}
}
}
Shape_Chunk * shp = get_assoc_shape();
deassoc_with_shape (shp);
lock_chunk(*fc);
deleted = TRUE;
unlock_chunk(*fc,TRUE);
}
void Object_Chunk::update_my_chunkobject(ChunkObject & cob)
{
//store the object's index , so that it doesn't get lost
int object_index=object_data_store->index_num;
*object_data_store = cob;
//replace the object index
object_data_store->index_num=object_index;
//recalculate the object's id in case the name has changed
CalculateID();
}
ObjectID Object_Chunk::CalculateID()
{
ObjectID retval={0,0};
List<Chunk*> chlist;
parent->lookup_child("REBENVDT",chlist);
if(!chlist.size()) return retval;
((Environment_Data_Chunk*)chlist.first_entry())->lookup_child("RIFFNAME",chlist);
if(!chlist.size()) return retval;
char Name[100];
#if InterfaceEngine||cencon
//need to check for console specific rif files,and skip the 'sat' or 'psx'
//so that they get the same ids as the pc
const char* r_name=((RIF_Name_Chunk*)chlist.first_entry())->rif_name;
if(tolower(r_name[0])=='p' && tolower(r_name[1])=='s' && tolower(r_name[2])=='x' )
strcpy(Name,&r_name[3]);
else if (tolower(r_name[0])=='s' && tolower(r_name[1])=='a' && tolower(r_name[2])=='t' )
strcpy(Name,&r_name[3]);
else
strcpy(Name,r_name);
#else
strcpy(Name,((RIF_Name_Chunk*)chlist.first_entry())->rif_name);
#endif
strcat(Name,object_data.o_name);
char buffer[16];
md5_buffer(Name,strlen(Name),&buffer[0]);
buffer[7]=0;
object_data_store->ID=*(ObjectID*)&buffer[0];
return object_data_store->ID;
}
/////////////////////////////////////////
// Class Object_Header_Chunk functions
RIF_IMPLEMENT_DYNCREATE("OBJHEAD1",Object_Header_Chunk)
// from buffer
#if UseOldChunkLoader
Object_Header_Chunk::Object_Header_Chunk(Object_Chunk * parent, const char * hdata, size_t /*hsize*/)
: Chunk (parent, "OBJHEAD1"), object_data (parent->object_data_store),
flags(0), version_no (0), associated_shape (0)
{
flags = *((int *) hdata);
if (flags & OBJECT_FLAG_BASE_OBJECT)
parent->object_data_store->is_base_object = TRUE;
else
{
parent->object_data_store->is_base_object = FALSE;
}
strncpy (lock_user, (hdata + 4), 16);
lock_user[16] = '\0';
parent->object_data_store->float_location = *((ChunkVector *) (hdata + 20));
parent->object_data_store->location = parent->object_data_store->float_location;
parent->object_data_store->orientation.x =- *((double *) (hdata + 44));
parent->object_data_store->orientation.y =- *((double *) (hdata + 52));
parent->object_data_store->orientation.z =- *((double *) (hdata + 60));
parent->object_data_store->orientation.w = *((double *) (hdata + 68));
version_no = *((int *) (hdata + 76));
shape_id_no = *((int *) (hdata + 80));
strcpy (parent->object_data_store->o_name, (hdata + 84));
parent->object_data_store->ID.id1=0;
parent->object_data_store->ID.id2=0;
parent->object_data_store->index_num=-1;
}
#else
Object_Header_Chunk::Object_Header_Chunk(Chunk_With_Children * parent, const char * hdata, size_t /*hsize*/)
: Chunk (parent, "OBJHEAD1"), object_data (((Object_Chunk*)parent)->object_data_store),
flags(0), version_no (0), associated_shape (0)
{
Object_Chunk* parent_object = (Object_Chunk*) parent;
flags = *((int *) hdata);
if (flags & OBJECT_FLAG_BASE_OBJECT)
parent_object->object_data_store->is_base_object = TRUE;
else
{
parent_object->object_data_store->is_base_object = FALSE;
}
strncpy (lock_user, (hdata + 4), 16);
lock_user[16] = '\0';
hdata+=20;
parent_object->object_data_store->location = *(ChunkVectorInt*) hdata;
hdata+=sizeof(ChunkVectorInt);
parent_object->object_data_store->orientation = *((ChunkQuat *) hdata);
hdata+=sizeof(ChunkQuat);
parent_object->object_data_store->index_num = *(int *) hdata;
hdata+=4;
version_no = *((int *) hdata);
hdata+=4;
shape_id_no = *((int *) hdata);
hdata+=4;
strcpy (parent_object->object_data_store->o_name, hdata);
parent_object->object_data_store->ID.id1=0;
parent_object->object_data_store->ID.id2=0;
}
#endif
//from data
Object_Header_Chunk::Object_Header_Chunk (Object_Chunk * parent)
: Chunk (parent, "OBJHEAD1"),
object_data (parent->object_data_store),
flags (0), version_no (0), associated_shape(0)
{
if (object_data->is_base_object) {
flags = OBJECT_FLAG_BASE_OBJECT;
}
}
size_t Object_Header_Chunk::size_chunk()
{
int length = 72;
length += (strlen(object_data->o_name)+1);
length += (4-length%4)%4;
chunk_size = length;
return length;
}
BOOL Object_Header_Chunk::output_chunk (HANDLE & hand)
{
unsigned long junk;
BOOL ok;
char * data_block;
data_block = make_data_block_from_chunk();
ok = WriteFile (hand, (long *) data_block, (unsigned long) chunk_size, &junk, 0);
delete [] data_block;
if (!ok) return FALSE;
return TRUE;
}
void Object_Header_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) = flags;
strncpy ((data_start + 4), lock_user, 16);
data_start+=20;
*((ChunkVectorInt *) (data_start)) = object_data->location;
data_start+=sizeof(ChunkVectorInt);
*((ChunkQuat *) (data_start)) = object_data->orientation;
data_start+=sizeof(ChunkQuat);
*(int*) data_start=object_data->index_num;
data_start+=4;
*((int *) data_start) = version_no;
data_start+=4;
*((int *) data_start) = shape_id_no;
data_start+=4;
strcpy (data_start, object_data->o_name);
}
void Object_Header_Chunk::prepare_for_output()
{
version_no ++;
}
/////////////////////////////////////////
// Class Object_Interface_Data_Chunk functions
RIF_IMPLEMENT_DYNCREATE("OBINTDT",Object_Interface_Data_Chunk)
/*
Children for Object_Interface_Data_Chunk :
"OBJNOTES" Object_Notes_Chunk
*/
// from buffer
Object_Interface_Data_Chunk::Object_Interface_Data_Chunk(Chunk_With_Children * parent, const char *data, size_t size)
: Chunk_With_Children (parent, "OBINTDT")
{
const char * buffer_ptr = data;
while ((data-buffer_ptr)< (signed) size) {
if ((*(int *)(data + 8)) + (data-buffer_ptr) > (signed) size) {
Parent_File->error_code = CHUNK_FAILED_ON_LOAD_NOT_RECOGNISED;
break;
}
DynCreate(data);
data += *(int *)(data + 8);
}
}
Object_Interface_Data_Chunk::Object_Interface_Data_Chunk (Object_Chunk * parent)
: Chunk_With_Children (parent, "OBINTDT")
{
new Object_Notes_Chunk (this, "Enter notes here", strlen("Enter notes here") + 1);
}
///////////////////////////////////////
// Class Object_Notes_Chunk functions
RIF_IMPLEMENT_DYNCREATE("OBJNOTES",Object_Notes_Chunk)
Object_Notes_Chunk::Object_Notes_Chunk (Chunk_With_Children * parent,
const char * _data, size_t _data_size)
: Chunk(parent, "OBJNOTES"),
data(NULL), data_size(_data_size)
{
data_store = new char [data_size];
*((char **) &data) = data_store;
for (int i = 0; i<(signed) data_size; i++)
data_store[i] = _data[i];
}
void Object_Notes_Chunk::fill_data_block (char * data_start)
{
strncpy (data_start, identifier, 8);
data_start += 8;
*((int *) data_start) = chunk_size;
data_start += 4;
for (int i = 0; i<((signed) chunk_size-12); i++)
data_start[i] = data[i];
}
Object_Notes_Chunk::~Object_Notes_Chunk ()
{
delete [] data_store;
}
BOOL Object_Notes_Chunk::output_chunk (HANDLE &hand)
{
unsigned long junk;
BOOL ok;
char * data_block;
data_block = make_data_block_from_chunk();
ok = WriteFile (hand, (long *) data_block, (unsigned long) chunk_size, &junk, 0);
delete [] data_block;
if (!ok) return FALSE;
return TRUE;
}
///////////////////////////////////////
RIF_IMPLEMENT_DYNCREATE("MODULEDT",Object_Module_Data_Chunk)
/*
Children For Object_Module_Data_Chunk :
"VMDARRAY" VModule_Array_Chunk
"ADJMDLEP" Adjacent_Module_Entry_Points_Chunk
"MODFLAGS" Module_Flag_Chunk
"WAYPOINT" Module_Waypoint_Chunk
"MODACOUS" Module_Acoustics_Chunk
"AIMODMAS" AI_Module_Master_Chunk
"AIMODSLA" AI_Module_Slave_Chunk
*/
Object_Module_Data_Chunk::Object_Module_Data_Chunk (Chunk_With_Children * parent,const char * mdata, size_t msize)
: Chunk_With_Children (parent, "MODULEDT")
{
const char * buffer_ptr = mdata;
while ((mdata-buffer_ptr)< (signed) msize) {
if ((*(int *)(mdata + 8)) + (mdata-buffer_ptr) > (signed) msize) {
Parent_File->error_code = CHUNK_FAILED_ON_LOAD_NOT_RECOGNISED;
break;
}
DynCreate(mdata);
mdata += *(int *)(mdata + 8);
}
}
///////////////////////////////////////
RIF_IMPLEMENT_DYNCREATE("VMDARRAY",VModule_Array_Chunk)
VModule_Array_Chunk::VModule_Array_Chunk(Object_Module_Data_Chunk * parent, VMod_Arr_Item * vma, int num_in_vma)
: Chunk (parent, "VMDARRAY")
{
int i;
num_array_items = num_in_vma;
vmod_array = new VMod_Arr_Item [num_in_vma];
for (i=0; i<num_in_vma; i++)
{
vmod_array[i] = vma[i];
}
}
void VModule_Array_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_array_items;
data_start += 4;
for (int i=0; i<num_array_items; i++)
{
*((int *) data_start) = vmod_array[i].object_index;
data_start += 4;
*((int *) data_start) = vmod_array[i].branch_no;
data_start += 4;
*((int *) data_start) = vmod_array[i].flags;
data_start += 4;
*((int *) data_start) = vmod_array[i].spare;
data_start += 4;
}
}
size_t VModule_Array_Chunk::size_chunk()
{
chunk_size =16+16*num_array_items;
return(chunk_size);
}
#if UseOldChunkLoader
VModule_Array_Chunk::VModule_Array_Chunk (Object_Module_Data_Chunk * parent, const char * vmdata, size_t /*vmsize*/)
: Chunk (parent, "VMDARRAY")
{
num_array_items = *((int *) vmdata);
vmdata += 4;
vmod_array = new VMod_Arr_Item [num_array_items];
for (int i=0; i<num_array_items; i++)
{
//vmod_array[i].type = *((int *) vmdata);
vmdata += 4;
vmod_array[i].branch_no = *((int *) vmdata);
vmdata += 4;
//vmod_array[i].dir.x = *((double *) vmdata);
vmdata += 8;
//vmod_array[i].dir.y = *((double *) vmdata);
vmdata += 8;
//vmod_array[i].dir.z = *((double *) vmdata);
vmdata += 8;
//vmod_array[i].angle = *((double *) vmdata);
vmdata += 8;
vmod_array[i].flags = *((int *) vmdata);
vmdata += 4;
vmod_array[i].spare = *((int *) vmdata);
vmdata += 4;
vmod_array[i].object_index=-1;
vmod_array[i].o_name = new char [strlen(vmdata) + 1];
strcpy (vmod_array[i].o_name, vmdata);
vmdata += (strlen(vmod_array[i].o_name) + 1) + (4-(strlen(vmod_array[i].o_name) + 1)%4)%4;
}
}
#else
VModule_Array_Chunk::VModule_Array_Chunk (Chunk_With_Children * parent, const char * vmdata, size_t /*vmsize*/)
: Chunk (parent, "VMDARRAY")
{
num_array_items = *((int *) vmdata);
vmdata += 4;
vmod_array = new VMod_Arr_Item [num_array_items];
for (int i=0; i<num_array_items; i++)
{
vmod_array[i].object_index = *((int *) vmdata);
vmdata += 4;
vmod_array[i].branch_no = *((int *) vmdata);
vmdata += 4;
vmod_array[i].flags = *((int *) vmdata);
vmdata += 4;
vmod_array[i].spare = *((int *) vmdata);
vmdata += 4;
}
}
#endif
VModule_Array_Chunk::~VModule_Array_Chunk ()
{
delete [] vmod_array;
}
///////////////////////////////////////
#if 0
void Adjacent_Modules_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) = adjacent_modules_list.size();
data_start += 4;
for (LIF<Adjacent_Module> ami(&adjacent_modules_list); !ami.done(); ami.next())
{
*((int *) data_start) = 0;
data_start += 4;
*((int *) data_start) = 0;
data_start += 4;
strcpy (data_start, ami().o_name);
data_start += (strlen(ami().o_name) + 1) + (4-(strlen(ami().o_name) + 1)%4)%4;
}
}
size_t Adjacent_Modules_Chunk::size_chunk()
{
int size = 16;
for (LIF<Adjacent_Module> ami(&adjacent_modules_list); !ami.done(); ami.next())
{
size += 8;
size += (strlen(ami().o_name) + 1) + (4-(strlen(ami().o_name) + 1)%4)%4;
}
chunk_size = size;
return(size);
}
Adjacent_Modules_Chunk::Adjacent_Modules_Chunk (Object_Module_Data_Chunk * parent, const char * data, size_t /*size*/)
: Chunk (parent, "ADJMDLST")
{
int num_array_items = *((int *) data);
data += 4;
for (int i=0; i<num_array_items; i++)
{
Adjacent_Module am;
data += 8;
am.o_name = new char [strlen(data) + 1];
strcpy (am.o_name, data);
data += (strlen(am.o_name) + 1) + (4-(strlen(am.o_name) + 1)%4)%4;
adjacent_modules_list.add_entry(am);
}
}
#endif
///////////////////////////////////////
RIF_IMPLEMENT_DYNCREATE("ADJMDLEP",Adjacent_Module_Entry_Points_Chunk)
void Adjacent_Module_Entry_Points_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) = adjacent_modules_list.size();
data_start += 4;
for (LIF<Adjacent_Module> ami(&adjacent_modules_list); !ami.done(); ami.next())
{
*((int *) data_start) = ami().object_index;
data_start += 4;
*((int *) data_start) = ami().flags;
data_start += 4;
*((ChunkVectorInt *) data_start) = ami().entry_point;
data_start += sizeof(ChunkVectorInt);
}
}
size_t Adjacent_Module_Entry_Points_Chunk::size_chunk()
{
chunk_size = 16+adjacent_modules_list.size()*20;
return(chunk_size);
}
#if UseOldChunkLoader
Adjacent_Module_Entry_Points_Chunk::Adjacent_Module_Entry_Points_Chunk (Object_Module_Data_Chunk * parent, const char * data, size_t /*size*/)
: Chunk (parent, "ADJMDLEP")
{
int num_array_items = *((int *) data);
data += 4;
for (int i=0; i<num_array_items; i++)
{
Adjacent_Module am;
am.flags = *((int *) data);
data += 4;
am.entry_point = *((ChunkVector *) data);
data += sizeof(ChunkVector);
am.o_name = new char [strlen(data) + 1];
strcpy (am.o_name, data);
data += (strlen(am.o_name) + 4)&~3;
am.object_index=-1;
adjacent_modules_list.add_entry(am);
}
}
#else
Adjacent_Module_Entry_Points_Chunk::Adjacent_Module_Entry_Points_Chunk (Chunk_With_Children * parent, const char * data, size_t /*size*/)
: Chunk (parent, "ADJMDLEP")
{
int num_array_items = *((int *) data);
data += 4;
for (int i=0; i<num_array_items; i++)
{
Adjacent_Module am;
am.object_index = *((int *) data);
data += 4;
am.flags = *((int *) data);
data += 4;
am.entry_point = *((ChunkVectorInt *) data);
data += sizeof(ChunkVectorInt);
adjacent_modules_list.add_entry(am);
}
}
#endif
///////////////////////////////////////
RIF_IMPLEMENT_DYNCREATE("MODFLAGS",Module_Flag_Chunk)
Module_Flag_Chunk::Module_Flag_Chunk(Object_Module_Data_Chunk* parent)
:Chunk(parent,"MODFLAGS")
{
Flags=spare=0;
}
Module_Flag_Chunk::Module_Flag_Chunk(Chunk_With_Children* parent,const char* data,size_t)
:Chunk(parent,"MODFLAGS")
{
Flags=*(int*)data;
data+=4;
spare=*(int*)data;
}
void Module_Flag_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=Flags;
data_start+=4;
*(int*)data_start=spare;
}
///////////////////////////////////////
RIF_IMPLEMENT_DYNCREATE("MODZONE",Module_Zone_Chunk)
Module_Zone_Chunk::Module_Zone_Chunk(Object_Module_Data_Chunk* parent)
:Chunk(parent,"MODZONE")
{
Zone=spare=0;
}
Module_Zone_Chunk::Module_Zone_Chunk(Chunk_With_Children* parent,const char* data,size_t)
:Chunk(parent,"MODZONE")
{
Zone=*(int*)data;
data+=4;
spare=*(int*)data;
}
void Module_Zone_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=Zone;
data_start+=4;
*(int*)data_start=spare;
}
///////////////////////////////////////
RIF_IMPLEMENT_DYNCREATE("MODACOUS",Module_Acoustics_Chunk)
Module_Acoustics_Chunk::Module_Acoustics_Chunk(Object_Module_Data_Chunk* parent)
:Chunk(parent,"MODACOUS")
{
env_index=-1; //negative means default environment acoustics
reverb=-1.0;
spare=0;
}
Module_Acoustics_Chunk::Module_Acoustics_Chunk(Chunk_With_Children* parent,const char* data,size_t)
:Chunk(parent,"MODACOUS")
{
env_index=*(int*)data;
data+=4;
reverb=*(float*)data;
data+=4;
spare=*(int*)data;
}
void Module_Acoustics_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=env_index;
data_start+=4;
*(float*)data_start=reverb;
data_start+=4;
*(int*)data_start=spare;
}
///////////////////////////////////////
RIF_IMPLEMENT_DYNCREATE("OBJTRAK2",Object_Track_Chunk2)
Object_Track_Chunk2::Object_Track_Chunk2(Object_Chunk * parent)
: Chunk (parent, "OBJTRAK2")
{
num_sections=0;
sections=0;
flags=timer_start=0;
}
Object_Track_Chunk2::~Object_Track_Chunk2()
{
if(sections) delete sections;
}
void Object_Track_Chunk2::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_sections;
data_start+=4;
for(int i=0;i<num_sections;i++)
{
*(ChunkTrackSection*)data_start=sections[i];
data_start+=sizeof(ChunkTrackSection);
}
*(int*)data_start=flags;
data_start+=4;
*(int*)data_start=timer_start;
}
size_t Object_Track_Chunk2::size_chunk ()
{
chunk_size = 12 + 12 +num_sections*sizeof(ChunkTrackSection) ;
return(chunk_size);
}
#if UseOldChunkLoader
Object_Track_Chunk2::Object_Track_Chunk2 (Chunk_With_Children * parent,const char * data, size_t /*size*/)
: Chunk (parent, "OBJTRAK2")
{
num_sections=*(int*)data;
data+=4;
if(num_sections)
sections=new ChunkTrackSection[num_sections];
else
sections=0;
for(int i=0;i<num_sections;i++)
{
sections[i].quat_start.w=(*(int*)data)/65536.0;
data+=4;
sections[i].quat_start.x=(*(int*)data)/-65536.0;
data+=4;
sections[i].quat_start.y=(*(int*)data)/-65536.0;
data+=4;
sections[i].quat_start.z=(*(int*)data)/-65536.0;
data+=4;
sections[i].quat_end.w=(*(int*)data)/65536.0;
data+=4;
sections[i].quat_end.x=(*(int*)data)/-65536.0;
data+=4;
sections[i].quat_end.y=(*(int*)data)/-65536.0;
data+=4;
sections[i].quat_end.z=(*(int*)data)/-65536.0;
data+=4;
sections[i].pivot_start=*(ChunkVector*)data;
data+=sizeof(ChunkVector);
sections[i].pivot_end=*(ChunkVector*)data;
data+=sizeof(ChunkVector);
sections[i].object_offset=*(ChunkVector*)data;
data+=sizeof(ChunkVector);
sections[i].time_for_section=*(int*)data;
data+=sizeof(int);
sections[i].spare=*(int*)data;
data+=sizeof(int);
}
flags=*(int*)data;
flags|=TrackFlag_QuatProblemSorted;
data+=4;
spare2=*(int*)timer_start;
}
#else
Object_Track_Chunk2::Object_Track_Chunk2 (Chunk_With_Children * parent,const char * data, size_t /*size*/)
: Chunk (parent, "OBJTRAK2")
{
num_sections=*(int*)data;
data+=4;
if(num_sections)
sections=new ChunkTrackSection[num_sections];
else
sections=0;
for(int i=0;i<num_sections;i++)
{
sections[i]=*(ChunkTrackSection*)data;
data+=sizeof(ChunkTrackSection);
}
flags=*(int*)data;
data+=4;
timer_start=*(int*)data;
if(!(flags & TrackFlag_QuatProblemSorted))
{
for(i=0;i<num_sections;i++)
{
ChunkQuat temp=sections[i].quat_start;
sections[i].quat_start.x=-temp.w;
sections[i].quat_start.y=temp.x;
sections[i].quat_start.z=temp.y;
sections[i].quat_start.w=-temp.z;
temp=sections[i].quat_end;
sections[i].quat_end.x=-temp.w;
sections[i].quat_end.y=temp.x;
sections[i].quat_end.z=temp.y;
sections[i].quat_end.w=-temp.z;
}
flags|=TrackFlag_QuatProblemSorted;
}
}
#endif
///////////////////////////////////////
RIF_IMPLEMENT_DYNCREATE("TRAKSOUN",Object_Track_Sound_Chunk)
Object_Track_Sound_Chunk::Object_Track_Sound_Chunk(Chunk_With_Children* parent)
:Chunk(parent,"TRAKSOUN")
{
wav_name=0;
inner_range=5000;
outer_range=40000;
max_volume=127;
pitch=0;
flags=0;
index=0;
}
Object_Track_Sound_Chunk::Object_Track_Sound_Chunk(Chunk_With_Children* const parent,const char* data,size_t const )
:Chunk(parent,"TRAKSOUN")
{
inner_range=*(unsigned long*)data;
data+=4;
outer_range=*(unsigned long*)data;
data+=4;
max_volume=*(int*)data;
data+=4;
pitch=*(int*)data;
data+=4;
flags=*(int*)data;
data+=4;
index=*(int*)data;
data+=4;
wav_name=new char[strlen(data)+1];
strcpy(wav_name,data);
}
Object_Track_Sound_Chunk::~Object_Track_Sound_Chunk()
{
if(wav_name) delete wav_name;
}
void Object_Track_Sound_Chunk::fill_data_block(char* data_start)
{
strncpy (data_start, identifier, 8);
data_start += 8;
*((int *) data_start) = chunk_size;
data_start += 4;
*(unsigned long*)data_start=inner_range;
data_start+=4;
*(unsigned long*)data_start=outer_range;
data_start+=4;
*(int*)data_start=max_volume;
data_start+=4;
*(int*)data_start=pitch;
data_start+=4;
*(int*)data_start=flags;
data_start+=4;
*(int*)data_start=index;
data_start+=4;
strcpy(data_start,wav_name);
}
size_t Object_Track_Sound_Chunk::size_chunk()
{
chunk_size=12+24;
chunk_size+=(strlen(wav_name)+4)&~3;
return chunk_size;
}
///////////////////////////////////////
RIF_IMPLEMENT_DYNCREATE("ALTLOCAT",Object_Alternate_Locations_Chunk)
Object_Alternate_Locations_Chunk::Object_Alternate_Locations_Chunk(Chunk_With_Children* parent,const char* data,size_t)
:Chunk(parent,"ALTLOCAT")
{
group=*(int*) data;
data+=4;
spare2=*(int*) data;
data+=4;
num_locations=*(int*) data;
data+=4;
if(num_locations)
locations=new AltObjectLocation[num_locations];
else
locations=0;
for(int i=0;i<num_locations;i++)
{
locations[i] = *(AltObjectLocation*) data;
data+=sizeof(AltObjectLocation);
}
}
Object_Alternate_Locations_Chunk::Object_Alternate_Locations_Chunk(Chunk_With_Children* parent)
:Chunk(parent,"ALTLOCAT")
{
num_locations=0;
locations=0;
group=spare2=0;
}
Object_Alternate_Locations_Chunk::~Object_Alternate_Locations_Chunk()
{
if(locations) delete [] locations;
}
void Object_Alternate_Locations_Chunk::fill_data_block(char* data)
{
strncpy (data, identifier, 8);
data += 8;
*((int *) data) = chunk_size;
data += 4;
*(int*)data=group;
data+=4;
*(int*)data=spare2;
data+=4;
*(int*) data = num_locations;
data+=4;
for(int i=0;i<num_locations;i++)
{
*(AltObjectLocation*)data=locations[i];
data+=sizeof(AltObjectLocation);
}
}
size_t Object_Alternate_Locations_Chunk::size_chunk()
{
chunk_size=24+num_locations*sizeof(AltObjectLocation);
return chunk_size;
}
/////////////////////////////////////////
//class Object_Project_Data_Chunk
RIF_IMPLEMENT_DYNCREATE("OBJPRJDT",Object_Project_Data_Chunk)
CHUNK_WITH_CHILDREN_LOADER("OBJPRJDT",Object_Project_Data_Chunk)
/*
Children for Object_Project_Data_Chunk :
"MAPBLOCK" Map_Block_Chunk
"STRATEGY" Strategy_Chunk
"AVPSTRAT" AVP_Strategy_Chunk
*/