avp/src/win95/shpchunk.cpp

3358 lines
78 KiB
C++
Raw Normal View History

#include <math.h>
#include "chunk.hpp"
#include "chnktype.hpp"
#include "shpchunk.hpp"
#include "obchunk.hpp"
//macro for helping to force inclusion of chunks when using libraries
FORCE_CHUNK_INCLUDE_IMPLEMENT(shpchunk)
RIF_IMPLEMENT_DYNCREATE("REBSHAPE",Shape_Chunk)
int Shape_Chunk::max_id = 0;
BOOL Shape_External_File_Chunk::UpdatingExternalShape=FALSE;
// Class Shape_Chunk functions
/*
Children for Shape_Chunk :
"SHPRAWVT" Shape_Vertex_Chunk
"SHPPOLYS" Shape_Polygon_Chunk
"SHPHEAD1" Shape_Header_Chunk
"SHPVNORM" Shape_Vertex_Normal_Chunk
"SHPPNORM" Shape_Polygon_Normal_Chunk
"SHPTEXFN" Shape_Texture_Filenames_Chunk
"SHPUVCRD" Shape_UV_Coord_Chunk
"SHPMRGDT" Shape_Merge_Data_Chunk
"SHPCENTR" Shape_Centre_Chunk
"SHPMORPH" Shape_Morphing_Data_Chunk
"SHPEXTFL" Shape_External_File_Chunk
"SHPPCINF" Shape_Poly_Change_Info_Chunk
"TEXTANIM" Animation_Chunk
"SHPFRAGS" Shape_Fragments_Chunk
"ANIMSEQU" Anim_Shape_Sequence_Chunk
"PNOTINBB" Poly_Not_In_Bounding_Box_Chunk
"ANSHCEN2" Anim_Shape_Centre_Chunk
"ASALTTEX" Anim_Shape_Alternate_Texturing_Chunk
"SHPPRPRO" Shape_Preprocessed_Data_Chunk
*/
Shape_Chunk::Shape_Chunk(Chunk_With_Children * parent, const char *data, size_t size)
: Lockable_Chunk_With_Children (parent, "REBSHAPE"), shape_data ()
{
const char * buffer_ptr = data;
shape_data_store = (ChunkShape *) &shape_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;
}
/*--------------------------------------------------------------------**
** N.B. all changes to shape formats should be made to the sub shapes **
**--------------------------------------------------------------------*/
/*--------------------------------------------------------------------------**
** And of course the external file post input processing function should be **
** changed so that any new chunks will be copied over **
**--------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------**
** Oy READ THE NOTES, also destroy_auxiliary_chunks should be changed as well **
**----------------------------------------------------------------------------*/
DynCreate(data);
data += *(int *)(data + 8);
/*--------------------------------------------------------------------**
** N.B. all changes to shape formats should be made to the sub shapes **
**--------------------------------------------------------------------*/
/*--------------------------------------------------------------------------**
** And of course the external file post input processing function should be **
** changed so that any new chunks will be copied over **
**--------------------------------------------------------------------------*/
/*----------------------------------------------------------------------------**
** Oy READ THE NOTES, also destroy_auxiliary_chunks should be changed as well **
**----------------------------------------------------------------------------*/
}
}
Shape_Chunk::Shape_Chunk (Chunk_With_Children * parent, ChunkShape &shp_dat)
: Lockable_Chunk_With_Children (parent, "REBSHAPE"), shape_data (shp_dat)
{
shape_data_store = (ChunkShape *) &shape_data;
new Shape_Header_Chunk (this);
if (shape_data.v_list) new Shape_Vertex_Chunk (this, shape_data.num_verts);
if (shape_data.v_normal_list) new Shape_Vertex_Normal_Chunk (this, shape_data.num_verts);
if (shape_data.p_normal_list) new Shape_Polygon_Normal_Chunk (this, shape_data.num_polys);
if (shape_data.poly_list) new Shape_Polygon_Chunk (this, shape_data.num_polys);
if (shape_data.uv_list) new Shape_UV_Coord_Chunk (this, shape_data.num_uvs);
if (shape_data.texture_fns) new Shape_Texture_Filenames_Chunk (this, shape_data.num_texfiles);
//calculate the shape's centre and radius_about_centre
shape_data_store->centre=(shape_data_store->min+shape_data_store->max)/2;
shape_data_store->radius_about_centre=0;
for(int i=0;i<shape_data_store->num_verts;i++)
{
float length = (float) mod(shape_data_store->v_list[i]-shape_data_store->centre);
if(length>shape_data_store->radius_about_centre)
{
shape_data_store->radius_about_centre=length;
}
}
//if the shape hasn't got a Shape_Centre_Chunk , create one.
if(!lookup_single_child("SHPCENTR"))
{
new Shape_Centre_Chunk(this);
}
}
Shape_Chunk::~Shape_Chunk ()
{
}
Shape_Chunk* Shape_Chunk::make_copy_of_chunk()
{
char* Data=this->make_data_block_from_chunk();
Shape_Chunk* NewShape=new Shape_Chunk(parent,Data+12,this->size_chunk()-12);
delete [] Data;
delete NewShape->get_header();
new Shape_Header_Chunk(NewShape);
//need to call post_input_processing in order to copy morphing data correctly
NewShape->post_input_processing();
NewShape->updated=TRUE;
return NewShape;
}
Shape_Header_Chunk * Shape_Chunk::get_header()
{
return (Shape_Header_Chunk *) this->lookup_single_child ("SHPHEAD1");
}
List<Object_Chunk *> const & Shape_Chunk::list_assoc_objs()
{
if (!get_header())
{
static List<Object_Chunk *> empty_list;
return empty_list;
}
return get_header()->associated_objects_store;
}
BOOL Shape_Chunk::assoc_with_object (Object_Chunk *obch)
{
return obch->assoc_with_shape(this);
}
BOOL Shape_Chunk::deassoc_with_object (Object_Chunk *obch)
{
return obch->deassoc_with_shape(this);
}
void Shape_Chunk::post_input_processing()
{
if (get_header())
if (get_header()->flags & GENERAL_FLAG_LOCKED)
external_lock = TRUE;
#if 0 //shouldn't need to recalculate extents each time shape is loaded
// recalculate the shape extents
ChunkVector max, min;
max.x = -1000000000;
max.y = -1000000000;
max.z = -1000000000;
min.x = 1000000000;
min.y = 1000000000;
min.z = 1000000000;
float radius = 0;
for (int i=0; i<shape_data_store->num_verts; i++)
{
max.x = max(max.x, shape_data_store->v_list[i].x);
max.y = max(max.y, shape_data_store->v_list[i].y);
max.z = max(max.z, shape_data_store->v_list[i].z);
min.x = min(min.x, shape_data_store->v_list[i].x);
min.y = min(min.y, shape_data_store->v_list[i].y);
min.z = min(min.z, shape_data_store->v_list[i].z);
float temp_rad =(float) mod(shape_data_store->v_list[i]);
radius = max (radius, temp_rad);
}
shape_data_store->max = max;
shape_data_store->min = min;
shape_data_store->radius = radius;
#endif
Chunk_With_Children::post_input_processing();
}
void Shape_Chunk::destroy_auxiliary_chunks()
{
//split up into different blocks to stop compiler crashing when optimizations are turned on
List<Chunk *> chlst;
lookup_child("SHPZSPDT",chlst);
while (chlst.size())
{
delete chlst.first_entry();
chlst.delete_first_entry();
}
lookup_child("SHPMRGDT",chlst);
while (chlst.size())
{
delete chlst.first_entry();
chlst.delete_first_entry();
}
lookup_child("SHPMORPH",chlst);
while (chlst.size())
{
delete chlst.first_entry();
chlst.delete_first_entry();
}
lookup_child("TEXTANIM",chlst);
while (chlst.size())
{
delete chlst.first_entry();
chlst.delete_first_entry();
}
lookup_child("SHPPCINF",chlst);
while (chlst.size())
{
delete chlst.first_entry();
chlst.delete_first_entry();
}
lookup_child("SHPFRAGS",chlst);
while (chlst.size())
{
delete chlst.first_entry();
chlst.delete_first_entry();
}
lookup_child("ANIMSEQU",chlst);
while (chlst.size())
{
delete chlst.first_entry();
chlst.delete_first_entry();
}
lookup_child("PNOTINBB",chlst);
while (chlst.size())
{
delete chlst.first_entry();
chlst.delete_first_entry();
}
lookup_child("ANSHCEN2",chlst);
while (chlst.size())
{
delete chlst.first_entry();
chlst.delete_first_entry();
}
lookup_child("CONSHAPE",chlst);
while (chlst.size())
{
delete chlst.first_entry();
chlst.delete_first_entry();
}
lookup_child("ASALTTEX",chlst);
while (chlst.size())
{
delete chlst.first_entry();
chlst.delete_first_entry();
}
lookup_child("SHPPRPRO",chlst);
while (chlst.size())
{
delete chlst.first_entry();
chlst.delete_first_entry();
}
}
BOOL Shape_Chunk::file_equals(HANDLE &rif_file)
{
unsigned long bytes_read;
int id;
Shape_Header_Chunk * hdptr = get_header();
if (!hdptr) return (FALSE);
// get header list
List<int> obhead;
list_chunks_in_file (&obhead, rif_file, "SHPHEAD1");
if (obhead.size() != 1) return FALSE;
// get object identifier
SetFilePointer(rif_file,obhead.first_entry() + 32,0,FILE_BEGIN);
ReadFile (rif_file, (long *) &(id), 4, &bytes_read, 0);
if (hdptr->file_id_num == id) return TRUE;
return (FALSE);
}
const char * Shape_Chunk::get_head_id()
{
Shape_Header_Chunk * hdptr = get_header();
if (!hdptr) return (0);
return(hdptr->identifier);
}
void Shape_Chunk::set_lock_user (char * user)
{
Shape_Header_Chunk * hdptr = get_header();
if (!hdptr) return;
strncpy (hdptr->lock_user, user,16);
hdptr->lock_user[16] = 0;
}
BOOL Shape_Chunk::inc_v_no ()
{
Shape_Header_Chunk * hdptr = get_header();
if (!hdptr) return (FALSE);
hdptr->version_no++;
return (TRUE);
}
BOOL Shape_Chunk::same_and_updated(Shape_Chunk & shp)
{
Shape_Header_Chunk * hd1ptr = get_header();
if (!hd1ptr) return (0);
Shape_Header_Chunk * hd2ptr = shp.get_header();
if (!hd2ptr) return (0);
return (hd1ptr->version_no < hd2ptr->version_no && hd1ptr->file_id_num == hd2ptr->file_id_num);
}
BOOL Shape_Chunk::assoc_with_object_list(File_Chunk *fc)
{
Shape_Header_Chunk * hdptr = get_header();
Object_Chunk * ob = NULL;
if (!hdptr) return (FALSE);
List<Chunk *> chlst;
fc->lookup_child("RBOBJECT",chlst);
for (LIF<char *> n(&(hdptr->object_names_store)); !n.done(); n.next())
{
LIF<Chunk *> l(&chlst);
for (; !l.done(); l.next())
{
ob = (Object_Chunk *)l();
if ( !strcmp(ob->object_data.o_name, n()) )
break;
}
if (!l.done())
assoc_with_object(ob);
else
{
return(FALSE);
}
}
return(TRUE);
}
BOOL Shape_Chunk::update_my_chunkshape (ChunkShape & cshp)
{
// Firstly lose all the chunks that were with
// the old chunk shape
List <Chunk *> chlst;
lookup_child ("SHPRAWVT",chlst);
while (chlst.size())
{
delete chlst.first_entry();
chlst.delete_first_entry();
}
lookup_child ("SHPVNORM",chlst);
while (chlst.size())
{
delete chlst.first_entry();
chlst.delete_first_entry();
}
lookup_child ("SHPPNORM",chlst);
while (chlst.size())
{
delete chlst.first_entry();
chlst.delete_first_entry();
}
lookup_child ("SHPPOLYS",chlst);
while (chlst.size())
{
delete chlst.first_entry();
chlst.delete_first_entry();
}
lookup_child ("SHPUVCRD",chlst);
while (chlst.size())
{
delete chlst.first_entry();
chlst.delete_first_entry();
}
lookup_child ("SHPTEXFN",chlst);
while (chlst.size())
{
delete chlst.first_entry();
chlst.delete_first_entry();
}
*shape_data_store = cshp;
if (shape_data.v_list) new Shape_Vertex_Chunk (this, shape_data.num_verts);
if (shape_data.v_normal_list) new Shape_Vertex_Normal_Chunk (this, shape_data.num_verts);
if (shape_data.p_normal_list) new Shape_Polygon_Normal_Chunk (this, shape_data.num_polys);
if (shape_data.poly_list) new Shape_Polygon_Chunk (this, shape_data.num_polys);
if (shape_data.uv_list) new Shape_UV_Coord_Chunk (this, shape_data.num_uvs);
if (shape_data.texture_fns) new Shape_Texture_Filenames_Chunk (this, shape_data.num_texfiles);
//calculate the shape's centre and radius_about_centre
shape_data_store->centre=(shape_data_store->min+shape_data_store->max)/2;
shape_data_store->radius_about_centre=0;
for(int i=0;i<shape_data_store->num_verts;i++)
{
float length = (float) mod(shape_data_store->v_list[i]-shape_data_store->centre);
if(length>shape_data_store->radius_about_centre)
{
shape_data_store->radius_about_centre=length;
}
}
//if the shape hasn't got a Shape_Centre_Chunk , create one.
if(!lookup_single_child("SHPCENTR"))
{
new Shape_Centre_Chunk(this);
}
return TRUE;
}
Console_Shape_Chunk* Shape_Chunk::get_console_shape_data(Console_Type ct)
{
List<Chunk*> chlist;
lookup_child("CONSHAPE",chlist);
for(LIF<Chunk*> chlif(&chlist);!chlif.done();chlif.next())
{
Console_Shape_Chunk* csc=(Console_Shape_Chunk*)chlif();
List<Chunk*> chlist2;
csc->lookup_child("CONSTYPE",chlist2);
if(chlist2.size())
{
if(((Console_Type_Chunk*)chlist2.first_entry())->console==ct)
return csc;
}
}
return 0;//no console specific shape data
}
/////////////////////////////////////////
// Class Shape_Vertex_Chunk functions
// These can only be children of Shape_Chunks
// the shape chunks data will automatically be updated by it is created
// from buffer
RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPRAWVT",Shape_Vertex_Chunk,"REBSHAPE",Shape_Chunk)
RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPRAWVT",Shape_Vertex_Chunk,"SUBSHAPE",Shape_Sub_Shape_Chunk)
RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPRAWVT",Shape_Vertex_Chunk,"ANIMFRAM",Anim_Shape_Frame_Chunk)
Shape_Vertex_Chunk::Shape_Vertex_Chunk(Shape_Chunk * parent, const char * vtdata , size_t vtsize)
: Chunk (parent, "SHPRAWVT"), vert_data (NULL),
num_verts (vtsize / 12) // 12 bytes per vertex
{
int i;
parent->shape_data_store->v_list = new ChunkVectorInt[num_verts];
parent->shape_data_store->num_verts = num_verts;
*((ChunkVectorInt**) &vert_data) = parent->shape_data_store->v_list;
for (i=0;i<num_verts;i++)
{
parent->shape_data_store->v_list[i] = *((ChunkVectorInt *) vtdata );
vtdata+=sizeof(ChunkVectorInt);
}
}
Shape_Vertex_Chunk::Shape_Vertex_Chunk(Shape_Sub_Shape_Chunk * parent, const char * vtdata , size_t vtsize)
: Chunk (parent, "SHPRAWVT"), vert_data (NULL),
num_verts (vtsize / 12) // 12 bytes per vertex
{
int i;
parent->shape_data_store->v_list = new ChunkVectorInt[num_verts];
parent->shape_data_store->num_verts = num_verts;
*((ChunkVectorInt**) &vert_data) = parent->shape_data_store->v_list;
for (i=0;i<num_verts;i++)
{
parent->shape_data_store->v_list[i] = *((ChunkVectorInt *) vtdata );
vtdata+=sizeof(ChunkVectorInt);
}
}
Shape_Vertex_Chunk::Shape_Vertex_Chunk(Anim_Shape_Frame_Chunk * parent, const char * vtdata , size_t vtsize)
: Chunk (parent, "SHPRAWVT"), vert_data (NULL),
num_verts (vtsize / 12) // 12 bytes per vertex
{
int i;
ChunkVectorInt* v_list = new ChunkVectorInt[num_verts];
*(ChunkVectorInt**)&vert_data=v_list;
for (i=0;i<num_verts;i++)
{
v_list[i] = *((ChunkVectorInt *) vtdata );
vtdata+=sizeof(ChunkVectorInt);
}
}
BOOL Shape_Vertex_Chunk::output_chunk (HANDLE &hand)
{
unsigned long junk;
BOOL ok;
char * data_block;
data_block = this->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 Shape_Vertex_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<num_verts;i++)
{
*(ChunkVectorInt *) data_start = vert_data[i];
data_start+=sizeof(ChunkVectorInt);
}
}
/////////////////////////////////////////
// Class Shape_Vertex_Normal_Chunk functions
// These can only be children of Shape_Chunks
// the shape chunks data will automatically be updated by it is created
RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPVNORM",Shape_Vertex_Normal_Chunk,"REBSHAPE",Shape_Chunk)
RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPVNORM",Shape_Vertex_Normal_Chunk,"SUBSHAPE",Shape_Sub_Shape_Chunk)
// from buffer
Shape_Vertex_Normal_Chunk::Shape_Vertex_Normal_Chunk(Shape_Chunk * parent, const char * vtdata , size_t vtsize)
: Chunk (parent, "SHPVNORM"), vert_norm_data (NULL),
num_verts (vtsize / sizeof(ChunkVectorInt))
{
int i;
parent->shape_data_store->v_normal_list = new ChunkVectorFloat[num_verts];
*((ChunkVectorFloat**) &vert_norm_data) = parent->shape_data_store->v_normal_list;
for (i=0;i<num_verts;i++)
{
parent->shape_data_store->v_normal_list[i] = *((ChunkVectorFloat *) vtdata);
vtdata+=sizeof(ChunkVectorFloat);
}
}
Shape_Vertex_Normal_Chunk::Shape_Vertex_Normal_Chunk(Shape_Sub_Shape_Chunk * parent, const char * vtdata , size_t vtsize)
: Chunk (parent, "SHPVNORM"), vert_norm_data (NULL),
num_verts (vtsize / sizeof(ChunkVectorInt))
{
int i;
parent->shape_data_store->v_normal_list = new ChunkVectorFloat[num_verts];
*((ChunkVectorFloat**) &vert_norm_data) = parent->shape_data_store->v_normal_list;
for (i=0;i<num_verts;i++)
{
parent->shape_data_store->v_normal_list[i] = *((ChunkVectorFloat *) vtdata );
vtdata+=sizeof(ChunkVectorFloat);
}
}
BOOL Shape_Vertex_Normal_Chunk::output_chunk (HANDLE &hand)
{
unsigned long junk;
BOOL ok;
char * data_block;
data_block = this->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 Shape_Vertex_Normal_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<num_verts;i++)
{
*((ChunkVectorFloat *) data_start ) = vert_norm_data[i];
data_start+=sizeof(ChunkVectorFloat);
}
}
/////////////////////////////////////////
// Class Shape_Polygon_Normal_Chunk functions
// These can only be children of Shape_Chunks
// the shape chunks data will automatically be updated by it is created
RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPPNORM",Shape_Polygon_Normal_Chunk,"REBSHAPE",Shape_Chunk)
RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPPNORM",Shape_Polygon_Normal_Chunk,"SUBSHAPE",Shape_Sub_Shape_Chunk)
RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPPNORM",Shape_Polygon_Normal_Chunk,"ANIMFRAM",Anim_Shape_Frame_Chunk)
// from buffer
Shape_Polygon_Normal_Chunk::Shape_Polygon_Normal_Chunk(Shape_Chunk * parent, const char * pndata , size_t pnsize)
: Chunk (parent, "SHPPNORM"), poly_norm_data (NULL),
num_polys (pnsize / sizeof(ChunkVectorFloat))
{
int i;
parent->shape_data_store->p_normal_list = new ChunkVectorFloat[num_polys];
*((ChunkVectorFloat**) &poly_norm_data) = parent->shape_data_store->p_normal_list;
for (i=0;i<num_polys;i++)
{
parent->shape_data_store->p_normal_list[i] = *((ChunkVectorFloat *) pndata );
pndata+=sizeof(ChunkVectorFloat);
}
}
Shape_Polygon_Normal_Chunk::Shape_Polygon_Normal_Chunk(Shape_Sub_Shape_Chunk * parent, const char * pndata , size_t pnsize)
: Chunk (parent, "SHPPNORM"), poly_norm_data (NULL),
num_polys (pnsize / sizeof(ChunkVectorFloat))
{
int i;
parent->shape_data_store->p_normal_list = new ChunkVectorFloat[num_polys];
*((ChunkVectorFloat**) &poly_norm_data) = parent->shape_data_store->p_normal_list;
for (i=0;i<num_polys;i++)
{
parent->shape_data_store->p_normal_list[i] = *((ChunkVectorFloat *) pndata );
pndata+=sizeof(ChunkVectorFloat);
}
}
Shape_Polygon_Normal_Chunk::Shape_Polygon_Normal_Chunk(Anim_Shape_Frame_Chunk * parent, const char * pndata , size_t pnsize)
: Chunk (parent, "SHPPNORM"), poly_norm_data (NULL),
num_polys (pnsize / sizeof(ChunkVectorFloat))
{
int i;
ChunkVectorFloat* p_normal_list = new ChunkVectorFloat[num_polys];
*((ChunkVectorFloat**) &poly_norm_data) = p_normal_list;
for (i=0;i<num_polys;i++)
{
p_normal_list[i] = *((ChunkVectorFloat *) pndata );
pndata+=sizeof(ChunkVectorFloat);
}
}
BOOL Shape_Polygon_Normal_Chunk::output_chunk (HANDLE &hand)
{
unsigned long junk;
BOOL ok;
char * data_block;
data_block = this->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 Shape_Polygon_Normal_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<num_polys;i++)
{
*(ChunkVectorFloat *) data_start = poly_norm_data[i];
data_start+=sizeof(ChunkVectorFloat);
}
}
/////////////////////////////////////////
// Class Shape_Polygon_Chunk functions
// These can only be children of Shape_Chunks
// the shape chunks data will automatically be updated by it is created
RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPPOLYS",Shape_Polygon_Chunk,"REBSHAPE",Shape_Chunk)
RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPPOLYS",Shape_Polygon_Chunk,"SUBSHAPE",Shape_Sub_Shape_Chunk)
RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPPOLYS",Shape_Polygon_Chunk,"CONSHAPE",Console_Shape_Chunk)
// from buffer
Shape_Polygon_Chunk::Shape_Polygon_Chunk (Shape_Chunk * parent, const char * pdata, size_t psize)
: Chunk (parent, "SHPPOLYS"),
poly_data (parent->shape_data_store->poly_list), num_polys (psize / 36) // 9 * 4 bytes per polygon
{
int i, j;
parent->shape_data_store->poly_list = new ChunkPoly [num_polys];
parent->shape_data_store->num_polys = num_polys;
*((ChunkPoly **) &poly_data) = parent->shape_data_store->poly_list;
for (i=0; i<num_polys; i++)
{
parent->shape_data_store->poly_list[i].engine_type = *((int *) (pdata + (36*i)));
parent->shape_data_store->poly_list[i].normal_index = *((int *) (pdata + (36*i) + 4));
parent->shape_data_store->poly_list[i].flags = *((int *) (pdata + (36*i) + 8));
parent->shape_data_store->poly_list[i].colour = *((int *) (pdata + (36*i) + 12));
parent->shape_data_store->poly_list[i].num_verts = 0;
for (j=0; *((int *) (pdata + (36*i) + 16 + (j*4))) != -1; j++)
{
parent->shape_data_store->poly_list[i].vert_ind[j] = *((int *) (pdata + (36*i) + 16 + (j*4)));
parent->shape_data_store->poly_list[i].num_verts++;
}
}
}
Shape_Polygon_Chunk::Shape_Polygon_Chunk (Shape_Sub_Shape_Chunk * parent, const char * pdata, size_t psize)
: Chunk (parent, "SHPPOLYS"),
poly_data (parent->shape_data_store->poly_list), num_polys (psize / 36) // 9 * 4 bytes per polygon
{
int i, j;
parent->shape_data_store->poly_list = new ChunkPoly [num_polys];
parent->shape_data_store->num_polys = num_polys;
*((ChunkPoly **) &poly_data) = parent->shape_data_store->poly_list;
for (i=0; i<num_polys; i++)
{
parent->shape_data_store->poly_list[i].engine_type = *((int *) (pdata + (36*i)));
parent->shape_data_store->poly_list[i].normal_index = *((int *) (pdata + (36*i) + 4));
parent->shape_data_store->poly_list[i].flags = *((int *) (pdata + (36*i) + 8));
parent->shape_data_store->poly_list[i].colour = *((int *) (pdata + (36*i) + 12));
parent->shape_data_store->poly_list[i].num_verts = 0;
for (j=0; *((int *) (pdata + (36*i) + 16 + (j*4))) != -1; j++)
{
parent->shape_data_store->poly_list[i].vert_ind[j] = *((int *) (pdata + (36*i) + 16 + (j*4)));
parent->shape_data_store->poly_list[i].num_verts++;
}
}
}
Shape_Polygon_Chunk::Shape_Polygon_Chunk (Console_Shape_Chunk * parent, const char * pdata, size_t psize)
: Chunk (parent, "SHPPOLYS"),
poly_data(0), num_polys (psize / 36) // 9 * 4 bytes per polygon
{
int i, j;
ChunkPoly* poly_list = new ChunkPoly [num_polys];
*((ChunkPoly **) &poly_data) =poly_list;
for (i=0; i<num_polys; i++)
{
poly_list[i].engine_type = *((int *) (pdata + (36*i)));
poly_list[i].normal_index = *((int *) (pdata + (36*i) + 4));
poly_list[i].flags = *((int *) (pdata + (36*i) + 8));
poly_list[i].colour = *((int *) (pdata + (36*i) + 12));
poly_list[i].num_verts = 0;
for (j=0; *((int *) (pdata + (36*i) + 16 + (j*4))) != -1; j++)
{
poly_list[i].vert_ind[j] = *((int *) (pdata + (36*i) + 16 + (j*4)));
poly_list[i].num_verts++;
}
}
}
BOOL Shape_Polygon_Chunk::output_chunk (HANDLE &hand)
{
unsigned long junk;
BOOL ok;
char * data_block;
data_block = this->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 Shape_Polygon_Chunk::fill_data_block(char * data_start)
{
int i, j;
strncpy (data_start, identifier, 8);
data_start += 8;
*((int *) data_start) = chunk_size;
data_start += 4;
for (i=0;i<num_polys;i++) {
*((int *) (data_start + i*36)) = poly_data[i].engine_type;
*((int *) (data_start + i*36 + 4)) = poly_data[i].normal_index;
*((int *) (data_start + i*36 + 8)) = poly_data[i].flags;
*((int *) (data_start + i*36 + 12)) = poly_data[i].colour;
for (j = 0; j<poly_data[i].num_verts; j++)
*((int *) (data_start + i*36 + 16 + j*4)) = poly_data[i].vert_ind[j];
for (; j<5; j++)
*((int *) (data_start + i*36 + 16 + j*4)) = -1;
}
}
/////////////////////////////////////////
//Class Shape_Centre_Chunk :
RIF_IMPLEMENT_DYNCREATE("SHPCENTR",Shape_Centre_Chunk)
Shape_Centre_Chunk::Shape_Centre_Chunk(Chunk_With_Children* parent,const char* data, size_t datasize)
:Chunk (parent,"SHPCENTR")
{
assert(datasize==16);
//find parent's chunkshape
ChunkShape* cs=0;
if(!strcmp(parent->identifier,"REBSHAPE"))
{
cs=((Shape_Chunk*)parent)->shape_data_store;
}
else if(!strcmp(parent->identifier,"SUBSHAPE"))
{
cs=((Shape_Sub_Shape_Chunk*)parent)->shape_data_store;
}
assert(cs);
//fill in the appropriate entries
cs->centre=*(ChunkVectorInt*)data;
data+=sizeof(ChunkVectorInt);
cs->radius_about_centre=*(float*)data;
}
void Shape_Centre_Chunk::fill_data_block(char * data_start)
{
strncpy (data_start, identifier, 8);
data_start += 8;
*((int *) data_start) = chunk_size;
data_start += 4;
//find parent's chunkshape
ChunkShape* cs=0;
if(!strcmp(parent->identifier,"REBSHAPE"))
{
cs=((Shape_Chunk*)parent)->shape_data_store;
}
else if(!strcmp(parent->identifier,"SUBSHAPE"))
{
cs=((Shape_Sub_Shape_Chunk*)parent)->shape_data_store;
}
assert(cs);
*(ChunkVectorInt*)data_start=cs->centre;
data_start+=sizeof(ChunkVectorInt);
*(float*)data_start=cs->radius;
}
/////////////////////////////////////////
// Class Shape_UV_Coord_Chunk functions
// These can only be children of Shape_Chunks
// the shape chunks data will automatically be updated by it is created
RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPUVCRD",Shape_UV_Coord_Chunk,"REBSHAPE",Shape_Chunk)
RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPUVCRD",Shape_UV_Coord_Chunk,"SUBSHAPE",Shape_Sub_Shape_Chunk)
RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPUVCRD",Shape_UV_Coord_Chunk,"CONSHAPE",Console_Shape_Chunk)
// from buffer
Shape_UV_Coord_Chunk::Shape_UV_Coord_Chunk (Shape_Chunk * parent, const char * uvdata, size_t /*uvsize*/)
: Chunk (parent, "SHPUVCRD"),
uv_data (NULL), num_uvs (*((int *) uvdata))
{
int i,j;
if (num_uvs)
{
parent->shape_data_store->uv_list = new ChunkUV_List[num_uvs];
}
else
{
parent->shape_data_store->uv_list = 0;
}
*((ChunkUV_List**) &uv_data) = parent->shape_data_store->uv_list;
parent->shape_data_store->num_uvs = num_uvs;
uvdata += 4;
for (i=0;i<num_uvs;i++)
{
parent->shape_data_store->uv_list[i].num_verts = *((int *) uvdata);
uvdata += 4;
for (j=0; j<parent->shape_data_store->uv_list[i].num_verts; j++)
{
parent->shape_data_store->uv_list[i].vert[j] = *((ChunkUV *)uvdata);
uvdata += sizeof(ChunkUV);
}
}
}
Shape_UV_Coord_Chunk::Shape_UV_Coord_Chunk (Shape_Sub_Shape_Chunk * parent, const char * uvdata, size_t /*uvsize*/)
: Chunk (parent, "SHPUVCRD"),
uv_data (NULL), num_uvs (*((int *) uvdata))
{
int i,j;
parent->shape_data_store->uv_list = new ChunkUV_List[num_uvs];
*((ChunkUV_List**) &uv_data) = parent->shape_data_store->uv_list;
parent->shape_data_store->num_uvs = num_uvs;
uvdata += 4;
for (i=0;i<num_uvs;i++)
{
parent->shape_data_store->uv_list[i].num_verts = *((int *) uvdata);
uvdata += 4;
for (j=0; j<parent->shape_data_store->uv_list[i].num_verts; j++)
{
parent->shape_data_store->uv_list[i].vert[j] = *((ChunkUV *)uvdata);
uvdata += sizeof(ChunkUV);
}
}
}
Shape_UV_Coord_Chunk::Shape_UV_Coord_Chunk (Console_Shape_Chunk * parent, const char * uvdata, size_t /*uvsize*/)
: Chunk (parent, "SHPUVCRD"),
uv_data (NULL), num_uvs (*((int *) uvdata))
{
int i,j;
ChunkUV_List* uv_list= new ChunkUV_List[num_uvs];
*((ChunkUV_List**) &uv_data) = uv_list;
uvdata += 4;
for (i=0;i<num_uvs;i++)
{
uv_list[i].num_verts = *((int *) uvdata);
uvdata += 4;
for (j=0; j<uv_list[i].num_verts; j++)
{
uv_list[i].vert[j] = *((ChunkUV *)uvdata);
uvdata += sizeof(ChunkUV);
}
}
}
BOOL Shape_UV_Coord_Chunk::output_chunk (HANDLE &hand)
{
unsigned long junk;
BOOL ok;
char * data_block;
data_block = this->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 Shape_UV_Coord_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_uvs;
data_start += 4;
for (int i=0;i<num_uvs;i++)
{
*((int *)data_start) = uv_data[i].num_verts;
data_start += 4;
for (int j = 0; j< uv_data[i].num_verts; j++)
{
*((ChunkUV *) data_start) = uv_data[i].vert[j];
data_start += sizeof(ChunkUV);
}
}
}
size_t Shape_UV_Coord_Chunk::size_chunk ()
{
chunk_size = 12 + 4;
for (int i=0; i<num_uvs; i++)
chunk_size += (4+(sizeof(ChunkUV)*uv_data[i].num_verts));
return chunk_size;
}
/////////////////////////////////////////
// Class Shape_Texture_Filenames_Chunk functions
// These can only be children of Shape_Chunks
// the shape chunks data will automatically be updated by it is created
RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPTEXFN",Shape_Texture_Filenames_Chunk,"REBSHAPE",Shape_Chunk)
RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPTEXFN",Shape_Texture_Filenames_Chunk,"SUBSHAPE",Shape_Sub_Shape_Chunk)
// from buffer
Shape_Texture_Filenames_Chunk::Shape_Texture_Filenames_Chunk (Shape_Chunk * parent, const char * tfndata, size_t /*tfnsize*/)
: Chunk (parent, "SHPTEXFN"),
tex_fns (), num_tex_fns (*((int *) tfndata))
{
int i;
parent->shape_data_store->texture_fns = new char * [num_tex_fns];
*((char***) &tex_fns) = parent->shape_data_store->texture_fns;
parent->shape_data_store->num_texfiles = num_tex_fns;
tfndata += 4;
for (i=0; i<num_tex_fns; i++) {
parent->shape_data_store->texture_fns[i] = new char [strlen(tfndata)+1];
strcpy (parent->shape_data_store->texture_fns[i], tfndata);
tfndata += (strlen(tfndata)+1);
}
}
Shape_Texture_Filenames_Chunk::Shape_Texture_Filenames_Chunk (Shape_Sub_Shape_Chunk * parent, const char * tfndata, size_t /*tfnsize*/)
: Chunk (parent, "SHPTEXFN"),
tex_fns (), num_tex_fns (*((int *) tfndata))
{
int i;
parent->shape_data_store->texture_fns = new char * [num_tex_fns];
*((char***) &tex_fns) = parent->shape_data_store->texture_fns;
parent->shape_data_store->num_texfiles = num_tex_fns;
tfndata += 4;
for (i=0; i<num_tex_fns; i++) {
parent->shape_data_store->texture_fns[i] = new char [strlen(tfndata)+1];
strcpy (parent->shape_data_store->texture_fns[i], tfndata);
tfndata += (strlen(tfndata)+1);
}
}
BOOL Shape_Texture_Filenames_Chunk::output_chunk (HANDLE &hand)
{
unsigned long junk;
BOOL ok;
char * data_block;
data_block = this->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 Shape_Texture_Filenames_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_tex_fns;
data_start += 4;
for (int i=0;i<num_tex_fns;i++) {
sprintf(data_start, "%s", tex_fns[i]);
data_start += (strlen (tex_fns[i]) + 1);
}
}
size_t Shape_Texture_Filenames_Chunk::size_chunk()
{
chunk_size = 16;
for (int i=0;i<num_tex_fns;i++)
chunk_size += (strlen (tex_fns[i]) + 1);
chunk_size += (4-chunk_size%4)%4;
return chunk_size;
}
/////////////////////////////////////////
// Class Shape_Header_Chunk functions
// These can only be children of Shape_Chunks
// the shape chunks data will automatically be updated by it is created
RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPHEAD1",Shape_Header_Chunk,"REBSHAPE",Shape_Chunk)
Shape_Header_Chunk::Shape_Header_Chunk (Shape_Chunk * parent, const char * hdata, size_t /*hsize*/)
: Chunk (parent, "SHPHEAD1"),
shape_data (parent->shape_data_store)
{
int num_as_obj;
flags = *((int *) hdata);
strncpy (lock_user, (hdata + 4), 16);
lock_user[16] = '\0';
hdata+=20;
file_id_num = *((int *) hdata );
hdata+=4;
parent->shape_data_store->num_verts = *((int *) hdata );
hdata+=4;
parent->shape_data_store->num_polys = *((int *) hdata );
hdata+=4;
parent->shape_data_store->radius = *((float *) hdata);
hdata+=4;
parent->shape_data_store->max.x = *((int *) hdata);
hdata+=4;
parent->shape_data_store->min.x = *((int *) hdata);
hdata+=4;
parent->shape_data_store->max.y = *((int *) hdata);
hdata+=4;
parent->shape_data_store->min.y = *((int *) hdata);
hdata+=4;
parent->shape_data_store->max.z = *((int *) hdata);
hdata+=4;
parent->shape_data_store->min.z = *((int *) hdata);
hdata+=4;
version_no = *((int *) hdata);
hdata+=4;
num_as_obj = *((int *) hdata);
hdata+=4;
char * obj_store;
for (int i = 0; i< num_as_obj; i++)
{
obj_store = new char [strlen (hdata) +1];
strcpy (obj_store, (hdata));
object_names_store.add_entry(obj_store);
hdata += (strlen (hdata)+1);
}
}
Shape_Header_Chunk::~Shape_Header_Chunk()
{
for (LIF<char *> aon(&object_names_store);
!aon.done(); aon.next() )
delete [] aon();
}
size_t Shape_Header_Chunk::size_chunk()
{
int length = 80;
for (LIF<char *> aon(&object_names_store);
!aon.done(); aon.next() )
length += (strlen (aon()) + 1);
length += (4-length%4)%4;
chunk_size = length;
return length;
}
BOOL Shape_Header_Chunk::output_chunk(HANDLE & hand)
{
unsigned long junk;
BOOL ok;
char * data_block;
data_block = this->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 Shape_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);
*((int *) (data_start+20)) = file_id_num;
data_start+=24;
*((int *) data_start) = shape_data->num_verts;
data_start+=4;
*((int *) data_start) = shape_data->num_polys;
data_start+=4;
*((float *) data_start) = shape_data->radius;
data_start+=4;
*((int *) data_start) = shape_data->max.x;
data_start+=4;
*((int *) data_start) = shape_data->min.x;
data_start+=4;
*((int *) data_start) = shape_data->max.y;
data_start+=4;
*((int *) data_start) = shape_data->min.y;
data_start+=4;
*((int *) data_start) = shape_data->max.z;
data_start+=4;
*((int *) data_start) = shape_data->min.z;
data_start+=4;
*((int *) data_start) = version_no;
data_start+=4;
*((int *) data_start) = object_names_store.size();
data_start+=4;
for (LIF<char *> ons(&object_names_store); !ons.done(); ons.next())
{
strcpy (data_start, ons());
data_start += (strlen(ons())+1);
}
}
void Shape_Header_Chunk::prepare_for_output()
{
// this will also set the object chunks numbers as well,
// so that it is done in the right order
char * str;
if (file_id_num == -1) file_id_num = ++(Shape_Chunk::max_id);
while (object_names_store.size()) {
delete [] object_names_store.first_entry();
object_names_store.delete_first_entry();
}
for (LIF<Object_Chunk *> aosl(&associated_objects_store);
!aosl.done(); aosl.next() ) {
if (aosl()->get_header())
aosl()->get_header()->shape_id_no = file_id_num;
str = new char [strlen(aosl()->object_data.o_name) + 1];
strcpy(str, aosl()->object_data.o_name);
object_names_store.add_entry(str);
}
Shape_Chunk::max_id = max(Shape_Chunk::max_id, file_id_num);
// this should always be the last thing
version_no ++;
}
/////////////////////////////////////////
// Class Shape_Merge_Data_Chunk functions
RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPMRGDT",Shape_Merge_Data_Chunk,"REBSHAPE",Shape_Chunk)
RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPMRGDT",Shape_Merge_Data_Chunk,"SUBSHAPE",Shape_Sub_Shape_Chunk)
Shape_Merge_Data_Chunk::Shape_Merge_Data_Chunk(Shape_Chunk * parent, int * m_dt, int n_ps)
: Chunk (parent, "SHPMRGDT"), num_polys (n_ps)
{
merge_data = new int [n_ps];
for (int i=0; i<n_ps; i++)
{
merge_data[i] = m_dt[i];
}
}
Shape_Merge_Data_Chunk::Shape_Merge_Data_Chunk(Shape_Sub_Shape_Chunk * parent, int * m_dt, int n_ps)
: Chunk (parent, "SHPMRGDT"), num_polys (n_ps)
{
merge_data = new int [n_ps];
for (int i=0; i<n_ps; i++)
{
merge_data[i] = m_dt[i];
}
}
Shape_Merge_Data_Chunk::Shape_Merge_Data_Chunk (Shape_Chunk * parent, const char *md, size_t ms)
: Chunk (parent, "SHPMRGDT"), num_polys (ms/4)
{
merge_data = new int [num_polys];
for (int i=0; i<num_polys; i++)
{
merge_data[i] = *((int *)(md+4*i));
}
}
Shape_Merge_Data_Chunk::Shape_Merge_Data_Chunk (Shape_Sub_Shape_Chunk * parent, const char *md, size_t ms)
: Chunk (parent, "SHPMRGDT"), num_polys (ms/4)
{
merge_data = new int [num_polys];
for (int i=0; i<num_polys; i++)
{
merge_data[i] = *((int *)(md+4*i));
}
}
Shape_Merge_Data_Chunk::~Shape_Merge_Data_Chunk()
{
if (num_polys) delete [] merge_data;
}
void Shape_Merge_Data_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<num_polys; i++)
{
*((int *) (data_start+i*4) ) = merge_data[i];
}
}
/////////////////////////////////////////
RIF_IMPLEMENT_DYNCREATE("SHPEXTFL",Shape_External_File_Chunk)
/*
Children for Shape_External_File_Chunk :
"SHPEXTFN" Shape_External_Filename_Chunk)
"BMPLSTST" Bitmap_List_Store_Chunk)
"BMNAMVER" BMP_Names_Version_Chunk)
"BMNAMEXT" BMP_Names_ExtraData_Chunk)
"RIFFNAME" RIF_Name_Chunk)
"BMPMD5ID" Bitmap_MD5_Chunk)
"EXTOBJNM" Shape_External_Object_Name_Chunk)
*/
CHUNK_WITH_CHILDREN_LOADER("SHPEXTFL",Shape_External_File_Chunk)
Shape_External_File_Chunk::Shape_External_File_Chunk (Chunk_With_Children * parent, const char * fname)
:Chunk_With_Children (parent, "SHPEXTFL")
{
new Shape_External_Filename_Chunk (this, fname);
post_input_processing();
}
void Shape_External_File_Chunk::post_input_processing()
{
Chunk_With_Children::post_input_processing();
}
const char* Shape_External_File_Chunk::get_shape_name()
{
Shape_External_Object_Name_Chunk* seonc=(Shape_External_Object_Name_Chunk*)lookup_single_child("EXTOBJNM");
if(seonc)
{
return seonc->shape_name;
}
RIF_Name_Chunk* rnc=(RIF_Name_Chunk*)lookup_single_child("RIFFNAME");
if(rnc)
{
return rnc->rif_name;
}
return 0;
}
/////////////////////////////////////////
RIF_IMPLEMENT_DYNCREATE("SHPEXTFN",Shape_External_Filename_Chunk)
Shape_External_Filename_Chunk::Shape_External_Filename_Chunk(Chunk_With_Children * parent, const char * fname)
: Chunk (parent, "SHPEXTFN")
{
file_name = new char [strlen(fname)+1];
strcpy (file_name, fname);
rescale = 1;
version_no = -1;
}
Shape_External_Filename_Chunk::Shape_External_Filename_Chunk (Chunk_With_Children * parent, const char *fdata, size_t /*fsize*/)
: Chunk (parent, "SHPEXTFN")
{
rescale = *((double *) fdata);
fdata += 8;
version_no = *((int *) fdata);
fdata += 4;
file_name = new char [strlen(fdata)+1];
strcpy (file_name, fdata);
}
Shape_External_Filename_Chunk::~Shape_External_Filename_Chunk()
{
if (file_name)
delete [] file_name;
}
void Shape_External_Filename_Chunk::fill_data_block (char *data_start)
{
strncpy (data_start, identifier, 8);
data_start += 8;
*((int *) data_start) = chunk_size;
data_start += 4;
*((double *) data_start) = rescale;
data_start += 8;
*((int *) data_start) = version_no;
data_start += 4;
strcpy (data_start, file_name);
}
///////////////////////////////////////
RIF_IMPLEMENT_DYNCREATE("EXTOBJNM",Shape_External_Object_Name_Chunk)
Shape_External_Object_Name_Chunk::Shape_External_Object_Name_Chunk(Chunk_With_Children * parent, const char * oname)
: Chunk (parent, "EXTOBJNM")
{
object_name = new char [strlen(oname)+1];
shape_name=0;
strcpy (object_name, oname);
pad=0;
RIF_Name_Chunk* rnc=(RIF_Name_Chunk*)parent->lookup_single_child("RIFFNAME");
if(rnc)
{
shape_name=new char[strlen(object_name)+strlen(rnc->rif_name)+2];
sprintf(shape_name,"%s@%s",object_name,rnc->rif_name);
}
else
{
shape_name=new char[strlen(object_name)+10+2];
sprintf(shape_name,"%s@*NotFound*",object_name);
}
}
Shape_External_Object_Name_Chunk::Shape_External_Object_Name_Chunk (Chunk_With_Children * parent, const char *data, size_t /*fsize*/)
: Chunk (parent, "EXTOBJNM")
{
pad=*(int*)data;
data+=4;
object_name = new char [strlen(data)+1];
strcpy (object_name, data);
shape_name=0;
}
Shape_External_Object_Name_Chunk::~Shape_External_Object_Name_Chunk()
{
if (object_name)
delete [] object_name;
if(shape_name)
delete [] shape_name;
}
void Shape_External_Object_Name_Chunk::post_input_processing()
{
RIF_Name_Chunk* rnc=(RIF_Name_Chunk*)parent->lookup_single_child("RIFFNAME");
if(rnc)
{
shape_name=new char[strlen(object_name)+strlen(rnc->rif_name)+2];
sprintf(shape_name,"%s@%s",object_name,rnc->rif_name);
}
else
{
shape_name=new char[strlen(object_name)+10+2];
sprintf(shape_name,"%s@*NotFound*",object_name);
}
}
void Shape_External_Object_Name_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 =pad;
data_start+=4;
strcpy (data_start, object_name);
}
///////////////////////////////////////
RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPMORPH",Shape_Morphing_Data_Chunk,"REBSHAPE",Shape_Chunk)
RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPMORPH",Shape_Morphing_Data_Chunk,"SUBSHAPE",Shape_Sub_Shape_Chunk)
/*
Children for Shape_Morphing_Data_Chunk :
"SUBSHAPE" Shape_Sub_Shape_Chunk
"FRMMORPH" Shape_Morphing_Frame_Data_Chunk
*/
Shape_Morphing_Data_Chunk::Shape_Morphing_Data_Chunk (Shape_Chunk * parent, const char *data, size_t size)
: Chunk_With_Children (parent, "SHPMORPH"), parent_shape (parent), parent_sub_shape (0)
{
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);
}
}
Shape_Morphing_Data_Chunk::Shape_Morphing_Data_Chunk (Shape_Sub_Shape_Chunk * parent, const char *data, size_t size)
2001-12-18 02:23:39 +00:00
: Chunk_With_Children (parent, "SHPMORPH"), parent_shape (0), parent_sub_shape (parent)
{
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);
}
}
void Shape_Morphing_Data_Chunk::prepare_for_output()
{
int max_id = 0;
List<Chunk *> cl;
lookup_child("SUBSHAPE",cl);
LIF<Chunk *> cli(&cl);
for (; !cli.done(); cli.next())
{
max_id = max (max_id, ((Shape_Sub_Shape_Chunk *)cli())->get_header()->file_id_num);
}
for (cli.restart(); !cli.done(); cli.next())
{
if (((Shape_Sub_Shape_Chunk *)cli())->get_header()->file_id_num == -1)
{
((Shape_Sub_Shape_Chunk *)cli())->get_header()->file_id_num = ++max_id;
}
}
Chunk_With_Children::prepare_for_output();
}
///////////////////////////////////////
#ifdef new
#pragma message("new defined")
#endif
RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("FRMMORPH",Shape_Morphing_Frame_Data_Chunk,"SHPMORPH",Shape_Morphing_Data_Chunk)
Shape_Morphing_Frame_Data_Chunk::Shape_Morphing_Frame_Data_Chunk (Shape_Morphing_Data_Chunk * parent,const char *data, size_t /*size*/)
: Chunk (parent, "FRMMORPH")
{
a_flags = *((int *)data);
data +=4;
a_speed = *((int *)data);
data +=4;
num_frames = *((int *)data);
data +=4;
if (num_frames)
frame_store = new int [num_frames * 3];
else
frame_store=0;
for (int i=0; i<num_frames; i++)
{
frame_store[i*3] = *((int *)data);
data +=4;
frame_store[i*3+1] = *((int *)data);
data +=4;
frame_store[i*3+2] = *((int *)data);
data +=4;
}
}
void Shape_Morphing_Frame_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) = a_flags;
data_start += 4;
*((int *) data_start) = a_speed;
data_start += 4;
*((int *) data_start) = num_frames;
data_start += 4;
for (int i=0; i<num_frames; i++)
{
*((int *) data_start) = frame_store[i*3];
data_start += 4;
*((int *) data_start) = frame_store[i*3 + 1];
data_start += 4;
*((int *) data_start) = frame_store[i*3 + 2];
data_start += 4;
}
}
Shape_Morphing_Frame_Data_Chunk::~Shape_Morphing_Frame_Data_Chunk()
{
if (frame_store) delete [] frame_store;
while (anim_frames.size())
{
delete anim_frames.first_entry();
anim_frames.delete_first_entry();
}
}
void Shape_Morphing_Frame_Data_Chunk::prepare_for_output()
{
// get the number of each shape in each frame
// N.B. this relies on the fact that the shapes are numbered
// but they will be by the parent class which will have it's prepare
// for output called first
if (frame_store)
delete [] frame_store;
if (anim_frames.size())
{
frame_store = new int [ anim_frames.size() * 3 ];
}
else
{
frame_store = 0;
}
int num_f = 0;
for (LIF<a_frame *> afi(&anim_frames); !afi.done(); afi.next())
{
int s1no, s2no;
if (afi()->shape1a)
s1no = afi()->shape1a->get_header()->file_id_num;
else
s1no = -1;
if (afi()->shape2a)
s2no = afi()->shape2a->get_header()->file_id_num;
else
s2no = -1;
frame_store[num_f] = s1no;
frame_store[num_f+1] = s2no;
frame_store[num_f+2] = afi()->spare;
num_f ++;
}
num_frames = num_f;
}
void Shape_Morphing_Frame_Data_Chunk::post_input_processing()
{
List<Shape_Sub_Shape_Chunk *> shplist;
List<Chunk *> child_lists;
Shape_Morphing_Data_Chunk * pchnk = (Shape_Morphing_Data_Chunk *) parent;
pchnk->lookup_child("SUBSHAPE",child_lists);
while (child_lists.size()) {
shplist.add_entry((Shape_Sub_Shape_Chunk *)child_lists.first_entry());
child_lists.delete_first_entry();
}
LIF<Shape_Sub_Shape_Chunk *> sl(&shplist);
for (int i = 0; i<num_frames; i++)
{
Shape_Chunk * sh1b = 0, *sh2b = 0;
Shape_Sub_Shape_Chunk * sh1a = 0, *sh2a = 0;
a_frame * fr;
if (frame_store[i*2] == -1)
{
sh1b = pchnk->parent_shape;
}
else
{
for (; !sl.done(); sl.next()) {
if (sl()->get_header())
if (sl()->get_header()->file_id_num == frame_store[i])
break;
}
if (!sl.done())
{
sh1a = sl();
}
}
if (frame_store[i*2+1] == -1)
{
sh2b = pchnk->parent_shape;
}
else
{
for (sl.restart(); !sl.done(); sl.next()) {
if (sl()->get_header())
if (sl()->get_header()->file_id_num == frame_store[i+1])
break;
}
if (!sl.done())
{
sh2a = sl();
}
}
if ((sh1a || sh1b) && (sh2a || sh2b))
{
fr = new a_frame;
if (sh1a)
fr->shape1a = sh1a;
else if (sh1b)
fr->shape1b = sh1b;
if (sh2a)
fr->shape2a = sh2a;
else if (sh2b)
fr->shape2b = sh2b;
fr->spare = frame_store[i+2];
anim_frames.add_entry(fr);
}
}
}
/////////////////////////////////////////
// Class Shape_Sub_Shape_Chunk functions
RIF_IMPLEMENT_DYNCREATE("SUBSHAPE",Shape_Sub_Shape_Chunk)
/*
Children for Shape_Sub_Shape_Chunk :
"SHPRAWVT" Shape_Vertex_Chunk
"SHPPOLYS" Shape_Polygon_Chunk
"SUBSHPHD" Shape_Sub_Shape_Header_Chunk
"SHPVNORM" Shape_Vertex_Normal_Chunk
"SHPPNORM" Shape_Polygon_Normal_Chunk
"SHPTEXFN" Shape_Texture_Filenames_Chunk
"SHPUVCRD" Shape_UV_Coord_Chunk
"SHPMRGDT" Shape_Merge_Data_Chunk
"SHPCENTR" Shape_Centre_Chunk
"SHPMORPH" Shape_Morphing_Data_Chunk
"SHPEXTFL" Shape_External_File_Chunk
"SHPPCINF" Shape_Poly_Change_Info_Chunk
"TEXTANIM" Animation_Chunk
"SHPFRAGS" Shape_Fragments_Chunk
"ANIMSEQU" Anim_Shape_Sequence_Chunk
"PNOTINBB" Poly_Not_In_Bounding_Box_Chunk
"ANSHCEN2" Anim_Shape_Centre_Chunk
"ASALTTEX" Anim_Shape_Alternate_Texturing_Chunk
"SHPPRPRO" Shape_Preprocessed_Data_Chunk
"SHPFNAME" Shape_Name_Chunk
"FRAGDATA" Shape_Fragments_Data_Chunk
"FRAGLOCN" Shape_Fragment_Location_Chunk
*/
Shape_Sub_Shape_Chunk::Shape_Sub_Shape_Chunk(Chunk_With_Children * parent, const char *data, size_t size)
: Chunk_With_Children (parent, "SUBSHAPE"), shape_data ()
{
const char * buffer_ptr = data;
shape_data_store = (ChunkShape *) &shape_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);
}
}
Shape_Sub_Shape_Chunk::Shape_Sub_Shape_Chunk (Chunk_With_Children * parent, ChunkShape &shp_dat)
: Chunk_With_Children (parent, "SUBSHAPE"), shape_data (shp_dat)
{
shape_data_store = (ChunkShape *) &shape_data;
new Shape_Sub_Shape_Header_Chunk (this);
if (shape_data.v_list) new Shape_Vertex_Chunk (this, shape_data.num_verts);
if (shape_data.v_normal_list) new Shape_Vertex_Normal_Chunk (this, shape_data.num_verts);
if (shape_data.p_normal_list) new Shape_Polygon_Normal_Chunk (this, shape_data.num_polys);
if (shape_data.poly_list) new Shape_Polygon_Chunk (this, shape_data.num_polys);
if (shape_data.uv_list) new Shape_UV_Coord_Chunk (this, shape_data.num_uvs);
if (shape_data.texture_fns) new Shape_Texture_Filenames_Chunk (this, shape_data.num_texfiles);
//calculate the shape's centre and radius_about_centre
shape_data_store->centre=(shape_data_store->min+shape_data_store->max)/2;
shape_data_store->radius_about_centre=0;
for(int i=0;i<shape_data_store->num_verts;i++)
{
float length = (float) mod(shape_data_store->v_list[i]-shape_data_store->centre);
if(length>shape_data_store->radius_about_centre)
{
shape_data_store->radius_about_centre=length;
}
}
//if the shape hasn't got a Shape_Centre_Chunk , create one.
if(!lookup_single_child("SHPCENTR"))
{
new Shape_Centre_Chunk(this);
}
}
Shape_Sub_Shape_Chunk::~Shape_Sub_Shape_Chunk ()
{
}
Shape_Sub_Shape_Chunk* Shape_Sub_Shape_Chunk::make_copy_of_chunk()
{
char* Data=this->make_data_block_from_chunk();
Shape_Sub_Shape_Chunk* NewShape=new Shape_Sub_Shape_Chunk(parent,Data+12,this->size_chunk()-12);
delete [] Data;
delete NewShape->get_header();
new Shape_Sub_Shape_Header_Chunk(NewShape);
return NewShape;
}
Shape_Sub_Shape_Header_Chunk * Shape_Sub_Shape_Chunk::get_header()
{
return (Shape_Sub_Shape_Header_Chunk *) this->lookup_single_child ("SUBSHPHD");
}
BOOL Shape_Sub_Shape_Chunk::update_my_chunkshape (ChunkShape & cshp)
{
// Firstly lose all the chunks that were with
// the old chunk shape
List <Chunk *> chlst;
lookup_child ("SHPRAWVT",chlst);
while (chlst.size())
{
delete chlst.first_entry();
chlst.delete_first_entry();
}
lookup_child ("SHPVNORM",chlst);
while (chlst.size())
{
delete chlst.first_entry();
chlst.delete_first_entry();
}
lookup_child ("SHPPNORM",chlst);
while (chlst.size())
{
delete chlst.first_entry();
chlst.delete_first_entry();
}
lookup_child ("SHPPOLYS",chlst);
while (chlst.size())
{
delete chlst.first_entry();
chlst.delete_first_entry();
}
lookup_child ("SHPUVCRD",chlst);
while (chlst.size())
{
delete chlst.first_entry();
chlst.delete_first_entry();
}
lookup_child ("SHPTEXFN",chlst);
while (chlst.size())
{
delete chlst.first_entry();
chlst.delete_first_entry();
}
*shape_data_store = cshp;
if (shape_data.v_list) new Shape_Vertex_Chunk (this, shape_data.num_verts);
if (shape_data.v_normal_list) new Shape_Vertex_Normal_Chunk (this, shape_data.num_verts);
if (shape_data.p_normal_list) new Shape_Polygon_Normal_Chunk (this, shape_data.num_polys);
if (shape_data.poly_list) new Shape_Polygon_Chunk (this, shape_data.num_polys);
if (shape_data.uv_list) new Shape_UV_Coord_Chunk (this, shape_data.num_uvs);
if (shape_data.texture_fns) new Shape_Texture_Filenames_Chunk (this, shape_data.num_texfiles);
//calculate the shape's centre and radius_about_centre
shape_data_store->centre=(shape_data_store->min+shape_data_store->max)/2;
shape_data_store->radius_about_centre=0;
for(int i=0;i<shape_data_store->num_verts;i++)
{
float length=(float)mod(shape_data_store->v_list[i]-shape_data_store->centre);
if(length>shape_data_store->radius_about_centre)
{
shape_data_store->radius_about_centre=length;
}
}
//if the shape hasn't got a Shape_Centre_Chunk , create one.
if(!lookup_single_child("SHPCENTR"))
{
new Shape_Centre_Chunk(this);
}
return TRUE;
}
const char * Shape_Sub_Shape_Chunk::get_shape_name()
{
Shape_Name_Chunk* snc=(Shape_Name_Chunk*)lookup_single_child("SHPFNAME");
if (snc)
{
return snc->shape_name;
}
else
{
return(0);
}
}
Console_Shape_Chunk* Shape_Sub_Shape_Chunk::get_console_shape_data(Console_Type ct)
{
List<Chunk*> chlist;
lookup_child("CONSHAPE",chlist);
for(LIF<Chunk*> chlif(&chlist);!chlif.done();chlif.next())
{
Console_Shape_Chunk* csc=(Console_Shape_Chunk*)chlif();
List<Chunk*> chlist2;
csc->lookup_child("CONSTYPE",chlist2);
if(chlist2.size())
{
if(((Console_Type_Chunk*)chlist2.first_entry())->console==ct)
return csc;
}
}
return 0;//no console specific shape data
}
/////////////////////////////////////////
// Class Shape_Sub_Shape_Header_Chunk functions
RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SUBSHPHD",Shape_Sub_Shape_Header_Chunk,"SUBSHAPE",Shape_Sub_Shape_Chunk)
// These can only be children of Shape_Sub_Shape_Chunks
// the shape chunks data will automatically be updated by it is created
Shape_Sub_Shape_Header_Chunk::Shape_Sub_Shape_Header_Chunk (Shape_Sub_Shape_Chunk * parent, const char * hdata, size_t /*hsize*/)
: Chunk (parent, "SUBSHPHD"),
shape_data (parent->shape_data_store)
{
flags = *((int *) hdata);
hdata += 4;
file_id_num = *((int *) (hdata));
hdata += 4;
parent->shape_data_store->num_verts = *((int *) (hdata));
hdata += 4;
parent->shape_data_store->num_polys = *((int *) (hdata));
hdata += 4;
parent->shape_data_store->radius = *((float *) (hdata));
hdata += 4;
parent->shape_data_store->max.x = *((int *) (hdata));
hdata += 4;
parent->shape_data_store->min.x = *((int *) (hdata));
hdata += 4;
parent->shape_data_store->max.y = *((int *) (hdata));
hdata += 4;
parent->shape_data_store->min.y = *((int *) (hdata));
hdata += 4;
parent->shape_data_store->max.z = *((int *) (hdata));
hdata += 4;
parent->shape_data_store->min.z = *((int *) (hdata));
}
Shape_Sub_Shape_Header_Chunk::~Shape_Sub_Shape_Header_Chunk()
{
}
size_t Shape_Sub_Shape_Header_Chunk::size_chunk()
{
return chunk_size = 44 + 12;
}
void Shape_Sub_Shape_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;
data_start += 4;
*((int *) (data_start)) = file_id_num;
data_start += 4;
*((int *) (data_start)) = shape_data->num_verts;
data_start += 4;
*((int *) (data_start)) = shape_data->num_polys;
data_start += 4;
*((float *) (data_start)) = shape_data->radius;
data_start += 4;
*((int *) (data_start)) = shape_data->max.x;
data_start += 4;
*((int *) (data_start)) = shape_data->min.x;
data_start += 4;
*((int *) (data_start)) = shape_data->max.y;
data_start += 4;
*((int *) (data_start)) = shape_data->min.y;
data_start += 4;
*((int *) (data_start)) = shape_data->max.z;
data_start += 4;
*((int *) (data_start)) = shape_data->min.z;
}
/////////////////////////////////////////
// Class Shape_Poly_Change_Info_Chunk functions
RIF_IMPLEMENT_DYNCREATE("SHPPCINF",Shape_Poly_Change_Info_Chunk)
void Shape_Poly_Change_Info_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) = original_num_verts;
data_start += 4;
*((int *) data_start) = change_list.size();
data_start += 4;
for (LIF<poly_change_info> pcii(&change_list); !pcii.done(); pcii.next())
{
*((int *) data_start) = pcii().poly_num;
data_start += 4;
*((int *) data_start) = pcii().vert_num_before;
data_start += 4;
*((int *) data_start) = pcii().vert_num_after;
data_start += 4;
}
}
Shape_Poly_Change_Info_Chunk::Shape_Poly_Change_Info_Chunk (Chunk_With_Children * parent,const char * data, size_t /*size*/)
: Chunk (parent, "SHPPCINF")
{
original_num_verts = *((int *) data);
data += 4;
int n_entries = *((int *) data);
data += 4;
for (int i=0; i<n_entries; i++)
{
poly_change_info pci;
pci.poly_num = *((int *) data);
data += 4;
pci.vert_num_before = *((int *) data);
data += 4;
pci.vert_num_after = *((int *) data);
data += 4;
change_list.add_entry(pci);
}
}
/////////////////////////////////////////
// Class Shape_Name_Chunk functions
RIF_IMPLEMENT_DYNCREATE("SHPFNAME",Shape_Name_Chunk)
Shape_Name_Chunk::Shape_Name_Chunk (Chunk_With_Children * parent, const char * sname)
: Chunk (parent, "SHPFNAME")
{
shape_name = new char [strlen(sname)+1];
strcpy (shape_name, sname);
}
Shape_Name_Chunk::Shape_Name_Chunk (Chunk_With_Children * parent, const char * sndata, size_t /*rsize*/)
: Chunk (parent, "SHPFNAME")
{
shape_name = new char [strlen(sndata)+1];
strcpy (shape_name, sndata);
}
Shape_Name_Chunk::~Shape_Name_Chunk ()
{
if (shape_name)
delete [] shape_name;
}
void Shape_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, shape_name);
}
/////////////////////////////////////////
// Class Shape_Fragments_Chunk functions
RIF_IMPLEMENT_DYNCREATE("SHPFRAGS",Shape_Fragments_Chunk)
CHUNK_WITH_CHILDREN_LOADER("SHPFRAGS",Shape_Fragments_Chunk)
/*
Children for Shape_Fragments_Chunk :
"SUBSHAPE" Shape_Sub_Shape_Chunk
"SHPFRGTP" Shape_Fragment_Type_Chunk
"FRGSOUND" Fragment_Type_Sound_Chunk
*/
/////////////////////////////////////////
// Class Shape_Fragments_Data_Chunk functions
RIF_IMPLEMENT_DYNCREATE("FRAGDATA",Shape_Fragments_Data_Chunk)
void Shape_Fragments_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_fragments;
data_start += 4;
*((int *) data_start) = pad1;
data_start += 4;
*((int *) data_start) = pad2;
data_start += 4;
*((int *) data_start) = pad3;
}
Shape_Fragments_Data_Chunk::Shape_Fragments_Data_Chunk (Chunk_With_Children * parent, const char * sdata, size_t /*ssize*/)
: Chunk (parent, "FRAGDATA")
{
num_fragments = *((int *) sdata);
sdata += 4;
pad1 = *((int *) sdata);
sdata += 4;
pad2 = *((int *) sdata);
sdata += 4;
pad3 = *((int *) sdata);
sdata += 4;
}
/////////////////////////////////////////
// Class Shape_Fragments_Location_Chunk functions
RIF_IMPLEMENT_DYNCREATE("FRAGLOCN",Shape_Fragment_Location_Chunk)
void Shape_Fragment_Location_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) = frag_loc;
data_start += sizeof(ChunkVectorInt);
*((int *) data_start) = pad1;
data_start += 4;
*((int *) data_start) = pad2;
data_start += 4;
*((int *) data_start) = pad3;
data_start += 4;
*((int *) data_start) = pad4;
}
Shape_Fragment_Location_Chunk::Shape_Fragment_Location_Chunk (Chunk_With_Children * parent, const char * sdata, size_t /*ssize*/)
: Chunk (parent, "FRAGLOCN")
{
frag_loc = *((ChunkVectorInt *) sdata);
sdata += sizeof(ChunkVectorInt);
pad1 = *((int *) sdata);
sdata += 4;
pad2 = *((int *) sdata);
sdata += 4;
pad3 = *((int *) sdata);
sdata += 4;
pad4 = *((int *) sdata);
}
/////////////////////////////////////////
RIF_IMPLEMENT_DYNCREATE("SHPFRGTP",Shape_Fragment_Type_Chunk)
Shape_Fragment_Type_Chunk::Shape_Fragment_Type_Chunk(Chunk_With_Children* parent,const char* name)
:Chunk(parent,"SHPFRGTP")
{
frag_type_name=new char[strlen(name)+1];
strcpy(frag_type_name,name);
pad1=pad2-0;
}
Shape_Fragment_Type_Chunk::Shape_Fragment_Type_Chunk(Chunk_With_Children* const parent,const char* data,size_t const )
:Chunk(parent,"SHPFRGTP")
{
int length=strlen(data)+1;
frag_type_name=new char[length];
strcpy(frag_type_name,data);
data+=(length+3)&~3;
pad1=*(int*)data;
data+=4;
pad2=*(int*)data;
data+=4;
}
Shape_Fragment_Type_Chunk::~Shape_Fragment_Type_Chunk()
{
if(frag_type_name) delete [] frag_type_name;
}
void Shape_Fragment_Type_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,frag_type_name);
data_start+=(strlen(frag_type_name)+4)&~3;
*(int*)data_start=pad1;
data_start+=4;
*(int*)data_start=pad2;
data_start+=4;
}
size_t Shape_Fragment_Type_Chunk::size_chunk()
{
chunk_size=12+8;
chunk_size+=(strlen(frag_type_name)+4)&~3;
return chunk_size;
}
/////////////////////////////////////////
// Class Anim_Shape_Sequence_Chunk functions
RIF_IMPLEMENT_DYNCREATE("ANIMSEQU",Anim_Shape_Sequence_Chunk)
/*
Children for Anim_Shape_Sequence_Chunk :
"ANISEQDT" Anim_Shape_Sequence_Data_Chunk
"ANIMFRAM" Anim_Shape_Frame_Chunk
*/
Anim_Shape_Sequence_Chunk::Anim_Shape_Sequence_Chunk(Chunk_With_Children * const parent, const char *data, size_t const size)
: Chunk_With_Children (parent, "ANIMSEQU")
{
sequence_data_store=(ChunkAnimSequence*)&sequence_data;
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);
}
if(!ConstructSequenceDataFromChildren())
{
//this sequence is no longer valid
delete this;
}
}
Anim_Shape_Sequence_Chunk::Anim_Shape_Sequence_Chunk(Chunk_With_Children * const parent, int sequencenum,const char* name)
: Chunk_With_Children (parent, "ANIMSEQU")
{
sequence_data_store=(ChunkAnimSequence*)&sequence_data;
sequence_data_store->SequenceNum=sequencenum;
sequence_data_store->name=new char[strlen(name)+1];
strcpy(sequence_data_store->name,name);
RegenerateChildChunks();
}
Anim_Shape_Sequence_Chunk::Anim_Shape_Sequence_Chunk(Chunk_With_Children * const parent, ChunkAnimSequence const* cas )
: Chunk_With_Children (parent, "ANIMSEQU")
{
sequence_data_store=(ChunkAnimSequence*)&sequence_data;
*(ChunkAnimSequence*)&sequence_data=*cas;
RegenerateChildChunks();
}
int Anim_Shape_Sequence_Chunk::ConstructSequenceDataFromChildren()
{
Anim_Shape_Sequence_Data_Chunk* assdc=(Anim_Shape_Sequence_Data_Chunk*)lookup_single_child("ANISEQDT");
if(!assdc)
{
return 0;
}
sequence_data_store->name=assdc->name;
sequence_data_store->SequenceNum=assdc->SequenceNum;
sequence_data_store->flags=assdc->flags;
sequence_data_store->pad2=assdc->pad2;
sequence_data_store->pad3=assdc->pad3;
sequence_data_store->pad4=assdc->pad4;
List<Chunk*> chlist;
lookup_child("ANIMFRAM",chlist);
sequence_data_store->NumFrames=chlist.size();
if(sequence_data_store->NumFrames)
{
sequence_data_store->Frames=new ChunkAnimFrame*[sequence_data_store->NumFrames];
for(int i=0;i<sequence_data_store->NumFrames;i++)
{
sequence_data_store->Frames[i]=0;
}
}
for(LIF<Chunk*> chlif(& chlist);!chlif.done();chlif.next())
{
Anim_Shape_Frame_Chunk* asfc=(Anim_Shape_Frame_Chunk*)chlif();
Anim_Shape_Frame_Data_Chunk* asfdc=(Anim_Shape_Frame_Data_Chunk*)asfc->lookup_single_child("ANIFRADT");
if(!asfdc) return 0;
if(asfdc->FrameNum>=sequence_data_store->NumFrames) return 0;
if(sequence_data_store->Frames[asfdc->FrameNum])return 0;
sequence_data_store->Frames[asfdc->FrameNum]=new ChunkAnimFrame;
ChunkAnimFrame* caf=sequence_data_store->Frames[asfdc->FrameNum];
Shape_Vertex_Chunk* svc=(Shape_Vertex_Chunk*) asfc->lookup_single_child("SHPRAWVT");
if(!svc)return 0;
Shape_Polygon_Normal_Chunk* spnc=(Shape_Polygon_Normal_Chunk*)asfc->lookup_single_child("SHPPNORM");
if(!spnc) return 0;
caf->name=asfdc->name;
caf->flags=asfdc->flags;
caf->num_interp_frames=asfdc->num_interp_frames;
caf->pad3=asfdc->pad3;
caf->pad4=asfdc->pad4;
caf->num_verts=svc->num_verts;
caf->v_list=(ChunkVectorInt*)svc->vert_data;
caf->num_polys=spnc->num_polys;
caf->p_normal_list=(ChunkVectorFloat*)spnc->poly_norm_data;
}
return 1;
}
void Anim_Shape_Sequence_Chunk::post_input_processing()
{
List<int>* poly_not_in_bb=0;
List<Chunk*> chlist;
parent->lookup_child("PNOTINBB",chlist);
if(chlist.size())
poly_not_in_bb=&((Poly_Not_In_Bounding_Box_Chunk*)chlist.first_entry())->poly_no;
if(!strcmp(parent->identifier,"REBSHAPE"))
{
sequence_data_store->UpdateNormalsAndExtents(&((Shape_Chunk*)parent)->shape_data,poly_not_in_bb);
}
else if(!strcmp(parent->identifier,"SUBSHAPE"))
{
sequence_data_store->UpdateNormalsAndExtents(&((Shape_Sub_Shape_Chunk*)parent)->shape_data,poly_not_in_bb);
}
Chunk_With_Children::post_input_processing();
}
void Anim_Shape_Sequence_Chunk::update_my_sequencedata(ChunkAnimSequence & seq)
{
*sequence_data_store=seq;
RegenerateChildChunks();
}
void Anim_Shape_Sequence_Chunk::set_sequence_flags(int flags)
{
sequence_data_store->flags=flags;
}
void Anim_Shape_Sequence_Chunk::set_frame_flags(int frameno,int flags)
{
if(frameno< sequence_data_store->NumFrames)
{
if(sequence_data_store->Frames[frameno])
{
sequence_data_store->Frames[frameno]->flags=flags;
}
}
}
void Anim_Shape_Sequence_Chunk::RegenerateChildChunks()
{
List<Chunk*> chlist;
lookup_child("ANISEQDT",chlist);
while(chlist.size())
{
delete chlist.first_entry();
chlist.delete_first_entry();
}
lookup_child("ANIMFRAM",chlist);
while(chlist.size())
{
delete chlist.first_entry();
chlist.delete_first_entry();
}
new Anim_Shape_Sequence_Data_Chunk(this,sequence_data_store);
for(int i=0;i<sequence_data_store->NumFrames;i++)
{
if(sequence_data_store->Frames[i]->flags & animframeflag_interpolated_frame)continue;
new Anim_Shape_Frame_Chunk(this,sequence_data_store->Frames[i],i);
}
}
void Anim_Shape_Sequence_Chunk::GenerateInterpolatedFrames()
{
if(!strcmp(parent->identifier,"REBSHAPE"))
{
sequence_data_store->GenerateInterpolatedFrames(&((Shape_Chunk*)parent)->shape_data);
}
else if(!strcmp(parent->identifier,"SUBSHAPE"))
{
sequence_data_store->GenerateInterpolatedFrames(&((Shape_Sub_Shape_Chunk*)parent)->shape_data);
}
}
/////////////////////////////////////////
// Class Anim_Shape_Frame_Chunk functions
RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("ANIMFRAM",Anim_Shape_Frame_Chunk,"ANIMSEQU",Anim_Shape_Sequence_Chunk)
/*
Children for Anim_Shape_Frame_Chunk :
"ANIFRADT" Anim_Shape_Frame_Data_Chunk
"SHPPNORM" Shape_Polygon_Normal_Chunk
"SHPRAWVT" Shape_Vertex_Chunk
*/
Anim_Shape_Frame_Chunk::Anim_Shape_Frame_Chunk(Anim_Shape_Sequence_Chunk *const parent, const char *data, size_t const size)
: Chunk_With_Children (parent, "ANIMFRAM")
{
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);
}
}
Anim_Shape_Frame_Chunk::Anim_Shape_Frame_Chunk(Anim_Shape_Sequence_Chunk * const parent,ChunkAnimFrame* caf,int frameno)
: Chunk_With_Children (parent, "ANIMFRAM")
{
new Anim_Shape_Frame_Data_Chunk(this,caf,frameno);
new Shape_Vertex_Chunk(this,caf->v_list,caf->num_verts);
new Shape_Polygon_Normal_Chunk(this,caf->p_normal_list,caf->num_polys);
}
/////////////////////////////////////////
// Class Anim_Shape_Sequence_Data_Chunk functions
RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("ANISEQDT",Anim_Shape_Sequence_Data_Chunk,"ANIMSEQU",Anim_Shape_Sequence_Chunk)
Anim_Shape_Sequence_Data_Chunk::Anim_Shape_Sequence_Data_Chunk(Anim_Shape_Sequence_Chunk* const parent,const char* data,size_t const/*datasize*/)
: Chunk(parent, "ANISEQDT")
{
SequenceNum=*(int*)data;
data+=4;
flags=*(int*)data;
data+=4;
pad2=*(int*)data;
data+=4;
pad3=*(int*)data;
data+=4;
pad4=*(int*)data;
data+=4;
name=new char[strlen(data)+1];
strcpy(name,data);
}
Anim_Shape_Sequence_Data_Chunk::Anim_Shape_Sequence_Data_Chunk(Anim_Shape_Sequence_Chunk* const parent,ChunkAnimSequence* cas)
: Chunk(parent, "ANISEQDT")
{
SequenceNum=cas->SequenceNum;
name=cas->name;
flags=cas->flags;
pad2=cas->pad2;
pad3=cas->pad3;
pad4=cas->pad4;
}
void Anim_Shape_Sequence_Data_Chunk::fill_data_block(char* datastart)
{
strncpy (datastart, identifier, 8);
datastart += 8;
*((int *) datastart) = chunk_size;
datastart += 4;
*(int*)datastart=SequenceNum;
datastart+=4;
*(int*)datastart=flags;
datastart+=4;
*(int*)datastart=pad2;
datastart+=4;
*(int*)datastart=pad3;
datastart+=4;
*(int*)datastart=pad4;
datastart+=4;
strcpy(datastart,name ? name : "");
}
size_t Anim_Shape_Sequence_Data_Chunk::size_chunk()
{
return chunk_size = 12+20
+(name ? strlen(name) : 0)
+3 +3&~3;
}
/////////////////////////////////////////
// Class Anim_Shape_Frame_Data_Chunk functions
RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("ANIFRADT",Anim_Shape_Frame_Data_Chunk,"ANIMFRAM",Anim_Shape_Frame_Chunk)
Anim_Shape_Frame_Data_Chunk::Anim_Shape_Frame_Data_Chunk(Anim_Shape_Frame_Chunk* const parent,const char* data,size_t const /*datasize*/)
: Chunk(parent, "ANIFRADT")
{
FrameNum=*(int*)data;
data+=4;
flags=*(int*)data;
data+=4;
num_interp_frames=*(int*)data;
data+=4;
pad3=*(int*)data;
data+=4;
pad4=*(int*)data;
data+=4;
name=new char[strlen(data)+1];
strcpy(name,data);
}
Anim_Shape_Frame_Data_Chunk::Anim_Shape_Frame_Data_Chunk(Anim_Shape_Frame_Chunk* const parent,ChunkAnimFrame* caf,int frameno)
: Chunk(parent, "ANIFRADT")
{
FrameNum=frameno;
name=caf->name;
flags=caf->flags;
num_interp_frames=caf->num_interp_frames;
pad3=caf->pad3;
pad4=caf->pad4;
}
void Anim_Shape_Frame_Data_Chunk::fill_data_block(char* datastart)
{
strncpy (datastart, identifier, 8);
datastart += 8;
*((int *) datastart) = chunk_size;
datastart += 4;
*(int*)datastart=FrameNum;
datastart+=4;
*(int*)datastart=flags;
datastart+=4;
*(int*)datastart=num_interp_frames;
datastart+=4;
*(int*)datastart=pad3;
datastart+=4;
*(int*)datastart=pad4;
datastart+=4;
strcpy(datastart,name ? name : "");
}
size_t Anim_Shape_Frame_Data_Chunk::size_chunk()
{
return chunk_size = 12+20
+(name ? strlen(name) : 0)
+3 +3&~3;
}
/////////////////////////////////////////
// Class Anim_Shape_Alternate_Texturing_Chunk functions
RIF_IMPLEMENT_DYNCREATE("ASALTTEX",Anim_Shape_Alternate_Texturing_Chunk)
/*
Children for Anim_Shape_Alternate_Texturing_Chunk :
"SUBSHAPE" Shape_Sub_Shape_Chunk
*/
Anim_Shape_Alternate_Texturing_Chunk::Anim_Shape_Alternate_Texturing_Chunk(Chunk_With_Children *const parent, const char *data, size_t const size)
: Chunk_With_Children (parent, "ASALTTEX")
{
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);
}
}
Shape_Sub_Shape_Chunk* Anim_Shape_Alternate_Texturing_Chunk::CreateNewSubShape(const char* name)
{
if(!name) return 0;
//check to make sure that name isn't already in use
List<Chunk*> chlist;
lookup_child("SUBSHAPE",chlist);
for(LIF<Chunk*> chlif(& chlist);!chlif.done();chlif.next())
{
Shape_Sub_Shape_Chunk* sssc=(Shape_Sub_Shape_Chunk*) chlif();
if(!_stricmp(name,sssc->get_shape_name()))return 0;
}
ChunkShape cs;
if(!_stricmp(parent->identifier,"REBSHAPE"))
cs=((Shape_Chunk*)parent)->shape_data;
else if(!_stricmp(parent->identifier,"SUBSHAPE"))
cs=((Shape_Sub_Shape_Chunk*)parent)->shape_data;
else
return 0;
Shape_Sub_Shape_Chunk* sssc=new Shape_Sub_Shape_Chunk(this,cs);
new Shape_Name_Chunk(sssc,name);
//copy the texture animation data
Chunk_With_Children* anim_chunk=(Chunk_With_Children*)parent->lookup_single_child("TEXTANIM");
if(anim_chunk)
{
char * tempbuffer = anim_chunk->make_data_block_from_chunk();
sssc->DynCreate(tempbuffer);
delete [] tempbuffer;
}
Shape_Merge_Data_Chunk* smdc=(Shape_Merge_Data_Chunk*)parent->lookup_single_child("SHPMRGDT");
if(smdc)
{
new Shape_Merge_Data_Chunk(sssc,smdc->merge_data,smdc->num_polys);
}
return sssc;
}
/////////////////////////////////////////
// Class Poly_Not_In_Bounding_Box_Chunk functions
RIF_IMPLEMENT_DYNCREATE("PNOTINBB",Poly_Not_In_Bounding_Box_Chunk)
Poly_Not_In_Bounding_Box_Chunk::Poly_Not_In_Bounding_Box_Chunk(Chunk_With_Children* const parent,const char* data,size_t const datasize)
:Chunk(parent,"PNOTINBB")
{
for(int i=0;i<( ( (signed)datasize ) /4)-2;i++)
{
poly_no.add_entry(*(int*)data);
data+=4;
}
pad1=*(int*)data;
data+=4;
pad2=*(int*)data;
}
Poly_Not_In_Bounding_Box_Chunk::Poly_Not_In_Bounding_Box_Chunk(Chunk_With_Children* const parent)
:Chunk(parent,"PNOTINBB")
{
pad1=pad2=0;
}
size_t Poly_Not_In_Bounding_Box_Chunk::size_chunk()
{
return chunk_size=(20+4*poly_no.size());
}
void Poly_Not_In_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;
for(LIF<int> plif(&poly_no);!plif.done();plif.next())
{
*(int*)data_start=plif();
data_start+=4;
}
*(int*)data_start=pad1;
data_start+=4;
*(int*)data_start=pad2;
}
/////////////////////////////////////////
// Class Anim_Shape_Centre_Chunk functions
RIF_IMPLEMENT_DYNCREATE("ANSHCEN2",Anim_Shape_Centre_Chunk)
Anim_Shape_Centre_Chunk::Anim_Shape_Centre_Chunk(Chunk_With_Children* const parent,const char* data,size_t const /*datasize*/)
:Chunk(parent,"ANSHCEN2")
{
Centre=*(ChunkVectorInt*)data;
data+=sizeof(ChunkVectorInt);
flags=*(int*)data;
data+=4;
pad2=*(int*)data;
}
Anim_Shape_Centre_Chunk::Anim_Shape_Centre_Chunk(Chunk_With_Children* const parent)
:Chunk(parent,"ANSHCEN2")
{
Centre.x=0;
Centre.y=0;
Centre.z=0;
flags=pad2=0;
}
size_t Anim_Shape_Centre_Chunk::size_chunk()
{
return chunk_size=(20+sizeof(ChunkVectorInt));
}
void Anim_Shape_Centre_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=Centre;
data_start+=sizeof(ChunkVectorInt);
*(int*)data_start=flags;
data_start+=4;
*(int*)data_start=pad2;
}
/////////////////////////////////////////
// Class Console_Shape_Chunk functions
/*
Children for Console_Shape_Chunk :
"SHPPOLYS" Shape_Polygon_Chunk
"SHPUVCRD" Shape_UV_Coord_Chunk
"TEXTANIM" Animation_Chunk
"CONSTYPE" Console_Type_Chunk
*/
Console_Shape_Chunk::Console_Shape_Chunk(Chunk_With_Children * const parent, const char *data, size_t size)
: Chunk_With_Children (parent, "CONSHAPE")
{
shape_data_store=(ChunkShape*)&shape_data;
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);
}
}
}
Console_Shape_Chunk::Console_Shape_Chunk(Chunk_With_Children* const parent,Console_Type ct)
:Chunk_With_Children(parent,"CONSHAPE")
{
shape_data_store=(ChunkShape*)&shape_data;
new Console_Type_Chunk(this,ct);
}
void Console_Shape_Chunk::generate_console_chunkshape()
{
//sort out the chunkshape
if(!strcmp(parent->identifier,"REBSHAPE"))
{
*shape_data_store=((Shape_Chunk*)parent)->shape_data;
}
else if(!strcmp(parent->identifier,"SUBSHAPE"))
{
*shape_data_store=((Shape_Sub_Shape_Chunk*)parent)->shape_data;
}
else
{
delete this;
return;
}
Shape_Polygon_Chunk* spc=(Shape_Polygon_Chunk*)lookup_single_child("SHPPOLYS");
if(spc)
{
if(spc->num_polys!=shape_data_store->num_polys)
{
//console shape is no longer valid.kill it.
delete this;
return;
}
ChunkPoly* poly_list=shape_data_store->poly_list;
shape_data_store->poly_list=(ChunkPoly*)spc->poly_data;
for(int i=0;i<shape_data_store->num_polys;i++)
{
for(int j=0;j<4;j++)
{
shape_data_store->poly_list[i].vert_ind[j]=poly_list[i].vert_ind[j];
}
}
delete [] poly_list;
}
Shape_UV_Coord_Chunk* succ=(Shape_UV_Coord_Chunk*)lookup_single_child("SHPUVCRD");
if(succ)
{
delete [] shape_data_store->uv_list;
shape_data_store->uv_list=(ChunkUV_List*)succ->uv_data;
shape_data_store->num_uvs=succ->num_uvs;
}
}
void Console_Shape_Chunk::update_my_chunkshape(ChunkShape & cshp)
{
List<Chunk*> chlist;
lookup_child("SHPUVCRD",chlist);
while(chlist.size())
{
delete chlist.first_entry();
chlist.delete_first_entry();
}
lookup_child("SHPPOLYS",chlist);
while(chlist.size())
{
delete chlist.first_entry();
chlist.delete_first_entry();
}
*shape_data_store=cshp;
if (shape_data.poly_list) new Shape_Polygon_Chunk (this, shape_data.num_polys);
if (shape_data.uv_list) new Shape_UV_Coord_Chunk (this, shape_data.num_uvs);
}
/////////////////////////////////////////
// Class Console_Type_Chunk functions
RIF_IMPLEMENT_DYNCREATE("CONSTYPE",Console_Type_Chunk)
void Console_Type_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=(int)console;
}
/////////////////////////////////////////
RIF_IMPLEMENT_DYNCREATE("SHPPRPRO",Shape_Preprocessed_Data_Chunk)
Shape_Preprocessed_Data_Chunk::Shape_Preprocessed_Data_Chunk (Chunk_With_Children * parent, const char * data, size_t )
:Chunk(parent,"SHPPRPRO")
{
block_size=*(int*)data;
data+=4;
first_pointer=*(int*)data;
data+=4;
if(block_size)
{
memory_block=new unsigned int[block_size];
memcpy(memory_block,data,block_size*4);
data+=block_size*4;
}
else
{
memory_block=0;
}
num_extra_data=*(int*)data;
data+=4;
if(num_extra_data)
{
extra_data=new int[num_extra_data];
memcpy(extra_data,data,num_extra_data*4);
}
else
{
extra_data=0;
}
}
Shape_Preprocessed_Data_Chunk::Shape_Preprocessed_Data_Chunk (Chunk_With_Children * parent,int _block_size,int _first_pointer,unsigned int* _memory_block)
:Chunk(parent,"SHPPRPRO")
{
num_extra_data=0;
extra_data=0;
block_size=_block_size;
first_pointer=_first_pointer;
if(block_size)
{
memory_block=new unsigned int[block_size];
memcpy(memory_block,_memory_block,block_size*4);
}
else
{
memory_block=0;
}
}
void Shape_Preprocessed_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=block_size;
data_start+=4;
*(int*)data_start=first_pointer;
data_start+=4;
memcpy(data_start,memory_block,4*block_size);
data_start+=4*block_size;
*(int*)data_start=num_extra_data;
data_start+=4;
memcpy(data_start,extra_data,4*num_extra_data);
}
void* Shape_Preprocessed_Data_Chunk::GetMemoryBlock()
{
void* retval=memory_block;
// 64HACK
#pragma message ("64HACK")
#if 0
unsigned int* current=(unsigned int*)&first_pointer;
unsigned int* next;
while((*current>>16)!=0xffff)
{
next=&memory_block[(*current)>>16];
*current=(unsigned int)&memory_block[(*current)&0xffff];
current=next;
}
*current=(unsigned int)&memory_block[(*current)&0xffff];
#endif
memory_block=0;
block_size=0;
return retval;
}