1435 lines
29 KiB
C++
1435 lines
29 KiB
C++
![]() |
#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
|
||
|
*/
|