1 #include <math.h>
2 #include "unaligned.h"
3 #include "chunk.hpp"
4 #include "chnktype.hpp"
5 #include "shpchunk.hpp"
6 #include "obchunk.hpp"
7 
8 
9 //macro for helping to force inclusion of chunks when using libraries
10 FORCE_CHUNK_INCLUDE_IMPLEMENT(shpchunk)
11 
12 RIF_IMPLEMENT_DYNCREATE("REBSHAPE",Shape_Chunk)
13 
14 int Shape_Chunk::max_id = 0;
15 BOOL Shape_External_File_Chunk::UpdatingExternalShape=FALSE;
16 
17 // Class Shape_Chunk functions
18 
19 /*
20 Children for Shape_Chunk :
21 
22 "SHPRAWVT"		Shape_Vertex_Chunk
23 "SHPPOLYS"		Shape_Polygon_Chunk
24 "SHPHEAD1"		Shape_Header_Chunk
25 "SHPVNORM"		Shape_Vertex_Normal_Chunk
26 "SHPPNORM"		Shape_Polygon_Normal_Chunk
27 "SHPTEXFN"		Shape_Texture_Filenames_Chunk
28 "SHPUVCRD"		Shape_UV_Coord_Chunk
29 "SHPMRGDT"		Shape_Merge_Data_Chunk
30 "SHPCENTR"		Shape_Centre_Chunk
31 "SHPMORPH"		Shape_Morphing_Data_Chunk
32 "SHPEXTFL"		Shape_External_File_Chunk
33 "SHPPCINF"		Shape_Poly_Change_Info_Chunk
34 "TEXTANIM"		Animation_Chunk
35 "SHPFRAGS"		Shape_Fragments_Chunk
36 "ANIMSEQU"		Anim_Shape_Sequence_Chunk
37 "PNOTINBB"		Poly_Not_In_Bounding_Box_Chunk
38 "ANSHCEN2"		Anim_Shape_Centre_Chunk
39 "ASALTTEX"		Anim_Shape_Alternate_Texturing_Chunk
40 "SHPPRPRO"		Shape_Preprocessed_Data_Chunk
41 */
42 
Shape_Chunk(Chunk_With_Children * parent,const char * data,size_t size)43 Shape_Chunk::Shape_Chunk(Chunk_With_Children * parent, const char *data, size_t size)
44 : Lockable_Chunk_With_Children (parent, "REBSHAPE"), shape_data ()
45 {
46 	const char * buffer_ptr = data;
47 
48 	shape_data_store = (ChunkShape *) &shape_data;
49 
50 	while ((data-buffer_ptr)< (signed)size) {
51 
52 		if ((*(int *)(data + 8)) + (data-buffer_ptr) > (signed)size) {
53 			Parent_File->error_code = CHUNK_FAILED_ON_LOAD_NOT_RECOGNISED;
54 			break;
55 		}
56 
57 /*--------------------------------------------------------------------**
58 ** N.B. all changes to shape formats should be made to the sub shapes **
59 **--------------------------------------------------------------------*/
60 
61 /*--------------------------------------------------------------------------**
62 ** And of course the external file post input processing function should be **
63 ** changed so that any new chunks will be copied over                       **
64 **--------------------------------------------------------------------------*/
65 
66 /*----------------------------------------------------------------------------**
67 ** Oy READ THE NOTES, also destroy_auxiliary_chunks should be changed as well **
68 **----------------------------------------------------------------------------*/
69 
70 		DynCreate(data);
71 		data += *(int *)(data + 8);
72 
73 /*--------------------------------------------------------------------**
74 ** N.B. all changes to shape formats should be made to the sub shapes **
75 **--------------------------------------------------------------------*/
76 
77 /*--------------------------------------------------------------------------**
78 ** And of course the external file post input processing function should be **
79 ** changed so that any new chunks will be copied over                       **
80 **--------------------------------------------------------------------------*/
81 
82 /*----------------------------------------------------------------------------**
83 ** Oy READ THE NOTES, also destroy_auxiliary_chunks should be changed as well **
84 **----------------------------------------------------------------------------*/
85 
86 	}
87 }
88 
Shape_Chunk(Chunk_With_Children * parent,ChunkShape & shp_dat)89 Shape_Chunk::Shape_Chunk (Chunk_With_Children * parent, ChunkShape &shp_dat)
90 : Lockable_Chunk_With_Children (parent, "REBSHAPE"), shape_data (shp_dat)
91 {
92 	shape_data_store = (ChunkShape *) &shape_data;
93 
94 	new Shape_Header_Chunk (this);
95 
96 	if (shape_data.v_list) new Shape_Vertex_Chunk (this, shape_data.num_verts);
97 	if (shape_data.v_normal_list) new Shape_Vertex_Normal_Chunk (this, shape_data.num_verts);
98 	if (shape_data.p_normal_list) new Shape_Polygon_Normal_Chunk (this, shape_data.num_polys);
99 	if (shape_data.poly_list) new Shape_Polygon_Chunk (this, shape_data.num_polys);
100 	if (shape_data.uv_list) new Shape_UV_Coord_Chunk (this, shape_data.num_uvs);
101 	if (shape_data.texture_fns) new Shape_Texture_Filenames_Chunk (this, shape_data.num_texfiles);
102 
103 
104 
105 	//calculate the shape's centre and radius_about_centre
106 	shape_data_store->centre=(shape_data_store->min+shape_data_store->max)/2;
107 	shape_data_store->radius_about_centre=0;
108 	for(int i=0;i<shape_data_store->num_verts;i++)
109 	{
110 		float length = (float) mod(shape_data_store->v_list[i]-shape_data_store->centre);
111 		if(length>shape_data_store->radius_about_centre)
112 		{
113 			shape_data_store->radius_about_centre=length;
114 		}
115 	}
116 
117 	//if the shape hasn't got a Shape_Centre_Chunk , create one.
118 
119 	if(!lookup_single_child("SHPCENTR"))
120 	{
121 		new Shape_Centre_Chunk(this);
122 	}
123 }
124 
~Shape_Chunk()125 Shape_Chunk::~Shape_Chunk ()
126 {
127 }
128 
make_copy_of_chunk()129 Shape_Chunk* Shape_Chunk::make_copy_of_chunk()
130 {
131 	char* Data=this->make_data_block_from_chunk();
132 	Shape_Chunk* NewShape=new Shape_Chunk(parent,Data+12,this->size_chunk()-12);
133 	delete [] Data;
134 	delete NewShape->get_header();
135 	new Shape_Header_Chunk(NewShape);
136 	//need to call post_input_processing in order to copy morphing data correctly
137 	NewShape->post_input_processing();
138 	NewShape->updated=TRUE;
139 	return NewShape;
140 }
141 
get_header()142 Shape_Header_Chunk * Shape_Chunk::get_header()
143 {
144 
145 	return (Shape_Header_Chunk *) this->lookup_single_child ("SHPHEAD1");
146 
147 }
148 
list_assoc_objs()149 List<Object_Chunk *> const & Shape_Chunk::list_assoc_objs()
150 {
151 	if (!get_header())
152 	{
153 		static List<Object_Chunk *> empty_list;
154 		return empty_list;
155 	}
156 
157 	return get_header()->associated_objects_store;
158 }
159 
assoc_with_object(Object_Chunk * obch)160 BOOL Shape_Chunk::assoc_with_object (Object_Chunk *obch)
161 {
162 	return obch->assoc_with_shape(this);
163 }
164 
deassoc_with_object(Object_Chunk * obch)165 BOOL Shape_Chunk::deassoc_with_object (Object_Chunk *obch)
166 {
167 	return obch->deassoc_with_shape(this);
168 }
169 
170 
post_input_processing()171 void Shape_Chunk::post_input_processing()
172 {
173 	if (get_header())
174 		if (get_header()->flags & GENERAL_FLAG_LOCKED)
175 			external_lock = TRUE;
176 
177 #if 0 //shouldn't need to recalculate extents each time shape is loaded
178 	// recalculate the shape extents
179 
180 	ChunkVector max, min;
181 
182 	max.x = -1000000000;
183 	max.y = -1000000000;
184 	max.z = -1000000000;
185 
186 	min.x = 1000000000;
187 	min.y = 1000000000;
188 	min.z = 1000000000;
189 
190 	float radius = 0;
191 
192 	for (int i=0; i<shape_data_store->num_verts; i++)
193 	{
194 		max.x = max(max.x, shape_data_store->v_list[i].x);
195 		max.y = max(max.y, shape_data_store->v_list[i].y);
196 		max.z = max(max.z, shape_data_store->v_list[i].z);
197 
198 		min.x = min(min.x, shape_data_store->v_list[i].x);
199 		min.y = min(min.y, shape_data_store->v_list[i].y);
200 		min.z = min(min.z, shape_data_store->v_list[i].z);
201 
202 		float temp_rad =(float) mod(shape_data_store->v_list[i]);
203 
204 		radius = max (radius, temp_rad);
205 	}
206 
207 	shape_data_store->max = max;
208 	shape_data_store->min = min;
209 	shape_data_store->radius = radius;
210 #endif
211 
212 
213 	Chunk_With_Children::post_input_processing();
214 
215 }
216 
destroy_auxiliary_chunks()217 void Shape_Chunk::destroy_auxiliary_chunks()
218 {
219 	//split up into different blocks to stop compiler crashing when optimizations are turned on
220 
221 	List<Chunk *> chlst;
222 
223 	lookup_child("SHPZSPDT",chlst);
224 	while (chlst.size())
225 	{
226 		delete chlst.first_entry();
227 		chlst.delete_first_entry();
228 	}
229 
230 
231 	lookup_child("SHPMRGDT",chlst);
232 	while (chlst.size())
233 	{
234 		delete chlst.first_entry();
235 		chlst.delete_first_entry();
236 	}
237 
238 
239 
240 	lookup_child("SHPMORPH",chlst);
241 	while (chlst.size())
242 	{
243 		delete chlst.first_entry();
244 		chlst.delete_first_entry();
245 	}
246 
247 
248 
249 	lookup_child("TEXTANIM",chlst);
250 	while (chlst.size())
251 	{
252 		delete chlst.first_entry();
253 		chlst.delete_first_entry();
254 	}
255 
256 
257 
258 	lookup_child("SHPPCINF",chlst);
259 	while (chlst.size())
260 	{
261 		delete chlst.first_entry();
262 		chlst.delete_first_entry();
263 	}
264 
265 
266 	lookup_child("SHPFRAGS",chlst);
267 	while (chlst.size())
268 	{
269 		delete chlst.first_entry();
270 		chlst.delete_first_entry();
271 	}
272 
273 
274 	lookup_child("ANIMSEQU",chlst);
275 	while (chlst.size())
276 	{
277 		delete chlst.first_entry();
278 		chlst.delete_first_entry();
279 	}
280 
281 
282 	lookup_child("PNOTINBB",chlst);
283 	while (chlst.size())
284 	{
285 		delete chlst.first_entry();
286 		chlst.delete_first_entry();
287 	}
288 
289 
290 	lookup_child("ANSHCEN2",chlst);
291 	while (chlst.size())
292 	{
293 		delete chlst.first_entry();
294 		chlst.delete_first_entry();
295 	}
296 
297 
298 	lookup_child("CONSHAPE",chlst);
299 	while (chlst.size())
300 	{
301 		delete chlst.first_entry();
302 		chlst.delete_first_entry();
303 	}
304 
305 
306 	lookup_child("ASALTTEX",chlst);
307 	while (chlst.size())
308 	{
309 		delete chlst.first_entry();
310 		chlst.delete_first_entry();
311 	}
312 
313 	lookup_child("SHPPRPRO",chlst);
314 	while (chlst.size())
315 	{
316 		delete chlst.first_entry();
317 		chlst.delete_first_entry();
318 	}
319 
320 }
321 
322 
323 
file_equals(HANDLE & rif_file)324 BOOL Shape_Chunk::file_equals(HANDLE &rif_file)
325 {
326 	unsigned long bytes_read;
327 	int id;
328 	Shape_Header_Chunk * hdptr = get_header();
329 
330 	if (!hdptr) return (FALSE);
331 
332 	// get header list
333 	List<int> obhead;
334 	list_chunks_in_file (&obhead, rif_file, "SHPHEAD1");
335 
336 	if (obhead.size() != 1) return FALSE;
337 
338 	// get object identifier
339 	SetFilePointer(rif_file,obhead.first_entry() + 32,0,FILE_BEGIN);
340 	ReadFile (rif_file, (long *) &(id), 4, &bytes_read, 0);
341 
342 	if (hdptr->file_id_num == id) return TRUE;
343 
344 	return (FALSE);
345 }
346 
get_head_id()347 const char * Shape_Chunk::get_head_id()
348 {
349 	Shape_Header_Chunk * hdptr = get_header();
350 
351 	if (!hdptr) return (0);
352 
353 	return(hdptr->identifier);
354 }
355 
set_lock_user(char * user)356 void Shape_Chunk::set_lock_user (char * user)
357 {
358 	Shape_Header_Chunk * hdptr = get_header();
359 
360 	if (!hdptr) return;
361 
362 	strncpy (hdptr->lock_user, user,16);
363 
364 	hdptr->lock_user[16] = 0;
365 }
366 
inc_v_no()367 BOOL Shape_Chunk::inc_v_no ()
368 {
369 	Shape_Header_Chunk * hdptr = get_header();
370 
371 	if (!hdptr) return (FALSE);
372 
373 	hdptr->version_no++;
374 
375 	return (TRUE);
376 }
377 
same_and_updated(Shape_Chunk & shp)378 BOOL Shape_Chunk::same_and_updated(Shape_Chunk & shp)
379 {
380 
381 	Shape_Header_Chunk * hd1ptr = get_header();
382 
383 	if (!hd1ptr) return (0);
384 
385 	Shape_Header_Chunk * hd2ptr = shp.get_header();
386 
387 	if (!hd2ptr) return (0);
388 
389 	return (hd1ptr->version_no < hd2ptr->version_no && hd1ptr->file_id_num == hd2ptr->file_id_num);
390 
391 }
392 
assoc_with_object_list(File_Chunk * fc)393 BOOL Shape_Chunk::assoc_with_object_list(File_Chunk *fc)
394 {
395 	Shape_Header_Chunk * hdptr = get_header();
396 	Object_Chunk * ob = NULL;
397 
398 	if (!hdptr) return (FALSE);
399 
400 	List<Chunk *> chlst;
401 	fc->lookup_child("RBOBJECT",chlst);
402 
403 	for (LIF<char *> n(&(hdptr->object_names_store)); !n.done(); n.next())
404 	{
405 		LIF<Chunk *> l(&chlst);
406 
407 		for (; !l.done(); l.next())
408 		{
409 			ob = (Object_Chunk *)l();
410 			if ( !strcmp(ob->object_data.o_name, n()) )
411 				break;
412 		}
413 		if (!l.done())
414 			assoc_with_object(ob);
415 		else
416 		{
417 			return(FALSE);
418 		}
419 	}
420 	return(TRUE);
421 
422 
423 }
424 
update_my_chunkshape(ChunkShape & cshp)425 BOOL Shape_Chunk::update_my_chunkshape (ChunkShape & cshp)
426 {
427 	// Firstly lose all the chunks that were with
428 	// the old chunk shape
429 	List <Chunk *> chlst;
430 
431 	lookup_child ("SHPRAWVT",chlst);
432 
433 	while (chlst.size())
434 	{
435 		delete chlst.first_entry();
436 		chlst.delete_first_entry();
437 	}
438 
439 	lookup_child ("SHPVNORM",chlst);
440 
441 	while (chlst.size())
442 	{
443 		delete chlst.first_entry();
444 		chlst.delete_first_entry();
445 	}
446 
447 
448 	lookup_child ("SHPPNORM",chlst);
449 
450 	while (chlst.size())
451 	{
452 		delete chlst.first_entry();
453 		chlst.delete_first_entry();
454 	}
455 
456 
457 	lookup_child ("SHPPOLYS",chlst);
458 
459 	while (chlst.size())
460 	{
461 		delete chlst.first_entry();
462 		chlst.delete_first_entry();
463 	}
464 
465 
466 	lookup_child ("SHPUVCRD",chlst);
467 
468 	while (chlst.size())
469 	{
470 		delete chlst.first_entry();
471 		chlst.delete_first_entry();
472 	}
473 
474 
475 	lookup_child ("SHPTEXFN",chlst);
476 
477 	while (chlst.size())
478 	{
479 		delete chlst.first_entry();
480 		chlst.delete_first_entry();
481 	}
482 
483 	*shape_data_store = cshp;
484 
485 	if (shape_data.v_list) new Shape_Vertex_Chunk (this, shape_data.num_verts);
486 	if (shape_data.v_normal_list) new Shape_Vertex_Normal_Chunk (this, shape_data.num_verts);
487 	if (shape_data.p_normal_list) new Shape_Polygon_Normal_Chunk (this, shape_data.num_polys);
488 	if (shape_data.poly_list) new Shape_Polygon_Chunk (this, shape_data.num_polys);
489 	if (shape_data.uv_list) new Shape_UV_Coord_Chunk (this, shape_data.num_uvs);
490 	if (shape_data.texture_fns) new Shape_Texture_Filenames_Chunk (this, shape_data.num_texfiles);
491 
492 
493 	//calculate the shape's centre and radius_about_centre
494 	shape_data_store->centre=(shape_data_store->min+shape_data_store->max)/2;
495 	shape_data_store->radius_about_centre=0;
496 	for(int i=0;i<shape_data_store->num_verts;i++)
497 	{
498 		float length = (float) mod(shape_data_store->v_list[i]-shape_data_store->centre);
499 		if(length>shape_data_store->radius_about_centre)
500 		{
501 			shape_data_store->radius_about_centre=length;
502 		}
503 	}
504 
505 	//if the shape hasn't got a Shape_Centre_Chunk , create one.
506 
507 	if(!lookup_single_child("SHPCENTR"))
508 	{
509 		new Shape_Centre_Chunk(this);
510 	}
511 
512 
513 	return TRUE;
514 }
515 
get_console_shape_data(Console_Type ct)516 Console_Shape_Chunk* Shape_Chunk::get_console_shape_data(Console_Type ct)
517 {
518 	List<Chunk*> chlist;
519 	lookup_child("CONSHAPE",chlist);
520 	for(LIF<Chunk*> chlif(&chlist);!chlif.done();chlif.next())
521 	{
522 		Console_Shape_Chunk* csc=(Console_Shape_Chunk*)chlif();
523 		List<Chunk*> chlist2;
524 		csc->lookup_child("CONSTYPE",chlist2);
525 		if(chlist2.size())
526 		{
527 			if(((Console_Type_Chunk*)chlist2.first_entry())->console==ct)
528 				return csc;
529 		}
530 	}
531 
532 	return 0;//no console specific shape data
533 }
534 
535 /////////////////////////////////////////
536 
537 // Class Shape_Vertex_Chunk functions
538 
539 // These can only be children of Shape_Chunks
540 // the shape chunks data will automatically be updated by it is created
541 
542 // from buffer
543 
544 RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPRAWVT",Shape_Vertex_Chunk,"REBSHAPE",Shape_Chunk)
545 RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPRAWVT",Shape_Vertex_Chunk,"SUBSHAPE",Shape_Sub_Shape_Chunk)
546 RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPRAWVT",Shape_Vertex_Chunk,"ANIMFRAM",Anim_Shape_Frame_Chunk)
547 
Shape_Vertex_Chunk(Shape_Chunk * parent,const char * vtdata,size_t vtsize)548 Shape_Vertex_Chunk::Shape_Vertex_Chunk(Shape_Chunk * parent, const char * vtdata , size_t vtsize)
549 : Chunk (parent, "SHPRAWVT"), vert_data (NULL),
550 	num_verts (vtsize / 12) // 12 bytes per vertex
551 {
552 	int i;
553 
554 	parent->shape_data_store->v_list = new ChunkVectorInt[num_verts];
555 	parent->shape_data_store->num_verts = num_verts;
556 
557 	*((ChunkVectorInt**) &vert_data) = parent->shape_data_store->v_list;
558 
559 	for (i=0;i<num_verts;i++)
560 	{
561 		parent->shape_data_store->v_list[i] = *((ChunkVectorInt *) vtdata );
562 		vtdata+=sizeof(ChunkVectorInt);
563 	}
564 
565 }
566 
567 
Shape_Vertex_Chunk(Shape_Sub_Shape_Chunk * parent,const char * vtdata,size_t vtsize)568 Shape_Vertex_Chunk::Shape_Vertex_Chunk(Shape_Sub_Shape_Chunk * parent, const char * vtdata , size_t vtsize)
569 : Chunk (parent, "SHPRAWVT"), vert_data (NULL),
570 	num_verts (vtsize / 12) // 12 bytes per vertex
571 {
572 	int i;
573 
574 	parent->shape_data_store->v_list = new ChunkVectorInt[num_verts];
575 	parent->shape_data_store->num_verts = num_verts;
576 
577 	*((ChunkVectorInt**) &vert_data) = parent->shape_data_store->v_list;
578 
579 	for (i=0;i<num_verts;i++)
580 	{
581 		parent->shape_data_store->v_list[i] = *((ChunkVectorInt *) vtdata );
582 		vtdata+=sizeof(ChunkVectorInt);
583 	}
584 
585 }
586 
587 
Shape_Vertex_Chunk(Anim_Shape_Frame_Chunk * parent,const char * vtdata,size_t vtsize)588 Shape_Vertex_Chunk::Shape_Vertex_Chunk(Anim_Shape_Frame_Chunk * parent, const char * vtdata , size_t vtsize)
589 : Chunk (parent, "SHPRAWVT"), vert_data (NULL),
590 	num_verts (vtsize / 12) // 12 bytes per vertex
591 {
592 	int i;
593 
594 	ChunkVectorInt* v_list = new ChunkVectorInt[num_verts];
595 	*(ChunkVectorInt**)&vert_data=v_list;
596 
597 	for (i=0;i<num_verts;i++)
598 	{
599 		v_list[i] = *((ChunkVectorInt *) vtdata );
600 		vtdata+=sizeof(ChunkVectorInt);
601 	}
602 
603 }
604 
output_chunk(HANDLE & hand)605 BOOL Shape_Vertex_Chunk::output_chunk (HANDLE &hand)
606 {
607 	unsigned long junk;
608 	BOOL ok;
609 	char * data_block;
610 
611 	data_block = this->make_data_block_from_chunk();
612 
613 	ok = WriteFile (hand, (long *) data_block, (unsigned long) chunk_size, &junk, 0);
614 
615 	delete [] data_block;
616 
617 	if (!ok) return FALSE;
618 
619 	return TRUE;
620 
621 }
622 
fill_data_block(char * data_start)623 void Shape_Vertex_Chunk::fill_data_block(char * data_start)
624 {
625 	strncpy (data_start, identifier, 8);
626 
627 	data_start += 8;
628 
629 	*((int *) data_start) = chunk_size;
630 
631 	data_start += 4;
632 
633 	for (int i=0;i<num_verts;i++)
634 	{
635 		*(ChunkVectorInt *) data_start  = vert_data[i];
636 		data_start+=sizeof(ChunkVectorInt);
637 
638 	}
639 }
640 
641 /////////////////////////////////////////
642 
643 // Class Shape_Vertex_Normal_Chunk functions
644 
645 // These can only be children of Shape_Chunks
646 // the shape chunks data will automatically be updated by it is created
647 RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPVNORM",Shape_Vertex_Normal_Chunk,"REBSHAPE",Shape_Chunk)
648 RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPVNORM",Shape_Vertex_Normal_Chunk,"SUBSHAPE",Shape_Sub_Shape_Chunk)
649 
650 // from buffer
Shape_Vertex_Normal_Chunk(Shape_Chunk * parent,const char * vtdata,size_t vtsize)651 Shape_Vertex_Normal_Chunk::Shape_Vertex_Normal_Chunk(Shape_Chunk * parent, const char * vtdata , size_t vtsize)
652 : Chunk (parent, "SHPVNORM"), vert_norm_data (NULL),
653 	num_verts (vtsize / sizeof(ChunkVectorInt))
654 {
655 	int i;
656 
657 	parent->shape_data_store->v_normal_list = new ChunkVectorFloat[num_verts];
658 	*((ChunkVectorFloat**) &vert_norm_data) = parent->shape_data_store->v_normal_list;
659 
660 	for (i=0;i<num_verts;i++)
661 	{
662 		parent->shape_data_store->v_normal_list[i] = *((ChunkVectorFloat *) vtdata);
663 		vtdata+=sizeof(ChunkVectorFloat);
664 	}
665 
666 }
667 
Shape_Vertex_Normal_Chunk(Shape_Sub_Shape_Chunk * parent,const char * vtdata,size_t vtsize)668 Shape_Vertex_Normal_Chunk::Shape_Vertex_Normal_Chunk(Shape_Sub_Shape_Chunk * parent, const char * vtdata , size_t vtsize)
669 : Chunk (parent, "SHPVNORM"), vert_norm_data (NULL),
670 	num_verts (vtsize / sizeof(ChunkVectorInt))
671 {
672 	int i;
673 
674 	parent->shape_data_store->v_normal_list = new ChunkVectorFloat[num_verts];
675 	*((ChunkVectorFloat**) &vert_norm_data) = parent->shape_data_store->v_normal_list;
676 
677 	for (i=0;i<num_verts;i++)
678 	{
679 		parent->shape_data_store->v_normal_list[i] = *((ChunkVectorFloat *) vtdata );
680 		vtdata+=sizeof(ChunkVectorFloat);
681 	}
682 
683 }
684 
output_chunk(HANDLE & hand)685 BOOL Shape_Vertex_Normal_Chunk::output_chunk (HANDLE &hand)
686 {
687 	unsigned long junk;
688 	BOOL ok;
689 	char * data_block;
690 
691 	data_block = this->make_data_block_from_chunk();
692 
693 	ok = WriteFile (hand, (long *) data_block, (unsigned long) chunk_size, &junk, 0);
694 
695 	delete [] data_block;
696 
697 	if (!ok) return FALSE;
698 
699 	return TRUE;
700 
701 }
702 
fill_data_block(char * data_start)703 void Shape_Vertex_Normal_Chunk::fill_data_block(char * data_start)
704 {
705 	strncpy (data_start, identifier, 8);
706 
707 	data_start += 8;
708 
709 	*((int *) data_start) = chunk_size;
710 
711 	data_start += 4;
712 
713 	for (int i=0;i<num_verts;i++)
714 	{
715 		*((ChunkVectorFloat *) data_start ) = vert_norm_data[i];
716 		data_start+=sizeof(ChunkVectorFloat);
717 	}
718 
719 }
720 /////////////////////////////////////////
721 
722 // Class Shape_Polygon_Normal_Chunk functions
723 
724 // These can only be children of Shape_Chunks
725 // the shape chunks data will automatically be updated by it is created
726 RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPPNORM",Shape_Polygon_Normal_Chunk,"REBSHAPE",Shape_Chunk)
727 RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPPNORM",Shape_Polygon_Normal_Chunk,"SUBSHAPE",Shape_Sub_Shape_Chunk)
728 RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPPNORM",Shape_Polygon_Normal_Chunk,"ANIMFRAM",Anim_Shape_Frame_Chunk)
729 
730 // from buffer
Shape_Polygon_Normal_Chunk(Shape_Chunk * parent,const char * pndata,size_t pnsize)731 Shape_Polygon_Normal_Chunk::Shape_Polygon_Normal_Chunk(Shape_Chunk * parent, const char * pndata , size_t pnsize)
732 : Chunk (parent, "SHPPNORM"), poly_norm_data (NULL),
733 	num_polys (pnsize / sizeof(ChunkVectorFloat))
734 {
735 	int i;
736 
737 	parent->shape_data_store->p_normal_list = new ChunkVectorFloat[num_polys];
738 	*((ChunkVectorFloat**) &poly_norm_data) = parent->shape_data_store->p_normal_list;
739 
740 	for (i=0;i<num_polys;i++)
741 	{
742 		parent->shape_data_store->p_normal_list[i] = *((ChunkVectorFloat *) pndata  );
743 		pndata+=sizeof(ChunkVectorFloat);
744 	}
745 
746 }
747 
Shape_Polygon_Normal_Chunk(Shape_Sub_Shape_Chunk * parent,const char * pndata,size_t pnsize)748 Shape_Polygon_Normal_Chunk::Shape_Polygon_Normal_Chunk(Shape_Sub_Shape_Chunk * parent, const char * pndata , size_t pnsize)
749 : Chunk (parent, "SHPPNORM"), poly_norm_data (NULL),
750 	num_polys (pnsize / sizeof(ChunkVectorFloat))
751 {
752 	int i;
753 
754 	parent->shape_data_store->p_normal_list = new ChunkVectorFloat[num_polys];
755 	*((ChunkVectorFloat**) &poly_norm_data) = parent->shape_data_store->p_normal_list;
756 
757 	for (i=0;i<num_polys;i++)
758 	{
759 		parent->shape_data_store->p_normal_list[i] = *((ChunkVectorFloat *) pndata  );
760 		pndata+=sizeof(ChunkVectorFloat);
761 	}
762 
763 }
764 
Shape_Polygon_Normal_Chunk(Anim_Shape_Frame_Chunk * parent,const char * pndata,size_t pnsize)765 Shape_Polygon_Normal_Chunk::Shape_Polygon_Normal_Chunk(Anim_Shape_Frame_Chunk * parent, const char * pndata , size_t pnsize)
766 : Chunk (parent, "SHPPNORM"), poly_norm_data (NULL),
767 	num_polys (pnsize / sizeof(ChunkVectorFloat))
768 {
769 	int i;
770 
771 	ChunkVectorFloat* p_normal_list = new ChunkVectorFloat[num_polys];
772 	*((ChunkVectorFloat**) &poly_norm_data) = p_normal_list;
773 
774 	for (i=0;i<num_polys;i++)
775 	{
776 		p_normal_list[i] = *((ChunkVectorFloat *) pndata  );
777 		pndata+=sizeof(ChunkVectorFloat);
778 	}
779 
780 }
781 
output_chunk(HANDLE & hand)782 BOOL Shape_Polygon_Normal_Chunk::output_chunk (HANDLE &hand)
783 {
784 	unsigned long junk;
785 	BOOL ok;
786 	char * data_block;
787 
788 	data_block = this->make_data_block_from_chunk();
789 
790 	ok = WriteFile (hand, (long *) data_block, (unsigned long) chunk_size, &junk, 0);
791 
792 	delete [] data_block;
793 
794 	if (!ok) return FALSE;
795 
796 	return TRUE;
797 
798 }
799 
fill_data_block(char * data_start)800 void Shape_Polygon_Normal_Chunk::fill_data_block(char * data_start)
801 {
802 	strncpy (data_start, identifier, 8);
803 
804 	data_start += 8;
805 
806 	*((int *) data_start) = chunk_size;
807 
808 	data_start += 4;
809 
810 	for (int i=0;i<num_polys;i++)
811 	{
812 		*(ChunkVectorFloat *) data_start  = poly_norm_data[i];
813 		data_start+=sizeof(ChunkVectorFloat);
814 	}
815 
816 }
817 
818 /////////////////////////////////////////
819 
820 // Class Shape_Polygon_Chunk functions
821 
822 // These can only be children of Shape_Chunks
823 // the shape chunks data will automatically be updated by it is created
824 
825 RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPPOLYS",Shape_Polygon_Chunk,"REBSHAPE",Shape_Chunk)
826 RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPPOLYS",Shape_Polygon_Chunk,"SUBSHAPE",Shape_Sub_Shape_Chunk)
827 RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPPOLYS",Shape_Polygon_Chunk,"CONSHAPE",Console_Shape_Chunk)
828 
829 // from buffer
Shape_Polygon_Chunk(Shape_Chunk * parent,const char * pdata,size_t psize)830 Shape_Polygon_Chunk::Shape_Polygon_Chunk (Shape_Chunk * parent, const char * pdata, size_t psize)
831 : Chunk (parent, "SHPPOLYS"),
832 	poly_data (parent->shape_data_store->poly_list), num_polys (psize / 36) // 9 * 4 bytes per polygon
833 {
834 	int i, j;
835 
836 	parent->shape_data_store->poly_list = new ChunkPoly [num_polys];
837 	parent->shape_data_store->num_polys = num_polys;
838 
839 	*((ChunkPoly **) &poly_data) = parent->shape_data_store->poly_list;
840 
841 	for (i=0; i<num_polys; i++)
842 	{
843 		parent->shape_data_store->poly_list[i].engine_type = *((int *) (pdata + (36*i)));
844 		parent->shape_data_store->poly_list[i].normal_index = *((int *) (pdata + (36*i) + 4));
845 		parent->shape_data_store->poly_list[i].flags = *((int *) (pdata + (36*i) + 8));
846 		parent->shape_data_store->poly_list[i].colour = *((int *) (pdata + (36*i) + 12));
847 
848 		parent->shape_data_store->poly_list[i].num_verts = 0;
849 
850 		for (j=0; *((int *) (pdata + (36*i) + 16 + (j*4))) != -1; j++)
851 		{
852 			parent->shape_data_store->poly_list[i].vert_ind[j] = *((int *) (pdata + (36*i) + 16 + (j*4)));
853 			parent->shape_data_store->poly_list[i].num_verts++;
854 		}
855 
856 	}
857 
858 }
859 
Shape_Polygon_Chunk(Shape_Sub_Shape_Chunk * parent,const char * pdata,size_t psize)860 Shape_Polygon_Chunk::Shape_Polygon_Chunk (Shape_Sub_Shape_Chunk * parent, const char * pdata, size_t psize)
861 : Chunk (parent, "SHPPOLYS"),
862 	poly_data (parent->shape_data_store->poly_list), num_polys (psize / 36) // 9 * 4 bytes per polygon
863 {
864 	int i, j;
865 
866 	parent->shape_data_store->poly_list = new ChunkPoly [num_polys];
867 	parent->shape_data_store->num_polys = num_polys;
868 
869 	*((ChunkPoly **) &poly_data) = parent->shape_data_store->poly_list;
870 
871 	for (i=0; i<num_polys; i++)
872 	{
873 		parent->shape_data_store->poly_list[i].engine_type = *((int *) (pdata + (36*i)));
874 		parent->shape_data_store->poly_list[i].normal_index = *((int *) (pdata + (36*i) + 4));
875 		parent->shape_data_store->poly_list[i].flags = *((int *) (pdata + (36*i) + 8));
876 		parent->shape_data_store->poly_list[i].colour = *((int *) (pdata + (36*i) + 12));
877 
878 		parent->shape_data_store->poly_list[i].num_verts = 0;
879 
880 		for (j=0; *((int *) (pdata + (36*i) + 16 + (j*4))) != -1; j++)
881 		{
882 			parent->shape_data_store->poly_list[i].vert_ind[j] = *((int *) (pdata + (36*i) + 16 + (j*4)));
883 			parent->shape_data_store->poly_list[i].num_verts++;
884 		}
885 
886 	}
887 
888 }
889 
Shape_Polygon_Chunk(Console_Shape_Chunk * parent,const char * pdata,size_t psize)890 Shape_Polygon_Chunk::Shape_Polygon_Chunk (Console_Shape_Chunk * parent, const char * pdata, size_t psize)
891 : Chunk (parent, "SHPPOLYS"),
892 	poly_data(0), num_polys (psize / 36) // 9 * 4 bytes per polygon
893 {
894 	int i, j;
895 
896 	ChunkPoly* poly_list = new ChunkPoly [num_polys];
897 
898 	*((ChunkPoly **) &poly_data) =poly_list;
899 
900 	for (i=0; i<num_polys; i++)
901 	{
902 		poly_list[i].engine_type = *((int *) (pdata + (36*i)));
903 		poly_list[i].normal_index = *((int *) (pdata + (36*i) + 4));
904 		poly_list[i].flags = *((int *) (pdata + (36*i) + 8));
905 		poly_list[i].colour = *((int *) (pdata + (36*i) + 12));
906 
907 		poly_list[i].num_verts = 0;
908 
909 		for (j=0; *((int *) (pdata + (36*i) + 16 + (j*4))) != -1; j++)
910 		{
911 			poly_list[i].vert_ind[j] = *((int *) (pdata + (36*i) + 16 + (j*4)));
912 			poly_list[i].num_verts++;
913 		}
914 
915 	}
916 
917 }
918 
output_chunk(HANDLE & hand)919 BOOL Shape_Polygon_Chunk::output_chunk (HANDLE &hand)
920 {
921 	unsigned long junk;
922 	BOOL ok;
923 	char * data_block;
924 
925 	data_block = this->make_data_block_from_chunk();
926 
927 	ok = WriteFile (hand, (long *) data_block, (unsigned long) chunk_size, &junk, 0);
928 
929 	delete [] data_block;
930 
931 	if (!ok) return FALSE;
932 
933 	return TRUE;
934 
935 }
936 
fill_data_block(char * data_start)937 void Shape_Polygon_Chunk::fill_data_block(char * data_start)
938 {
939 	int i, j;
940 
941 	strncpy (data_start, identifier, 8);
942 
943 	data_start += 8;
944 
945 	*((int *) data_start) = chunk_size;
946 
947 	data_start += 4;
948 
949 	for (i=0;i<num_polys;i++) {
950 		*((int *) (data_start + i*36)) = poly_data[i].engine_type;
951 		*((int *) (data_start + i*36 + 4)) = poly_data[i].normal_index;
952 		*((int *) (data_start + i*36 + 8)) = poly_data[i].flags;
953 		*((int *) (data_start + i*36 + 12)) = poly_data[i].colour;
954 		for (j = 0; j<poly_data[i].num_verts; j++)
955 			*((int *) (data_start + i*36 + 16 + j*4)) = poly_data[i].vert_ind[j];
956 		for (; j<5; j++)
957 			*((int *) (data_start + i*36 + 16 + j*4)) = -1;
958 
959 	}
960 
961 }
962 /////////////////////////////////////////
963 //Class Shape_Centre_Chunk :
964 
965 RIF_IMPLEMENT_DYNCREATE("SHPCENTR",Shape_Centre_Chunk)
966 
Shape_Centre_Chunk(Chunk_With_Children * parent,const char * data,size_t datasize)967 Shape_Centre_Chunk::Shape_Centre_Chunk(Chunk_With_Children* parent,const char* data, size_t datasize)
968 :Chunk (parent,"SHPCENTR")
969 {
970 	assert(datasize==16);
971 
972 	//find parent's chunkshape
973 	ChunkShape* cs=0;
974 	if(!strcmp(parent->identifier,"REBSHAPE"))
975 	{
976 		cs=((Shape_Chunk*)parent)->shape_data_store;
977 	}
978 	else if(!strcmp(parent->identifier,"SUBSHAPE"))
979 	{
980 		cs=((Shape_Sub_Shape_Chunk*)parent)->shape_data_store;
981 	}
982 	assert(cs);
983 
984 	//fill in the appropriate entries
985 	cs->centre=*(ChunkVectorInt*)data;
986 	data+=sizeof(ChunkVectorInt);
987 
988 	cs->radius_about_centre=*(float*)data;
989 }
990 
fill_data_block(char * data_start)991 void Shape_Centre_Chunk::fill_data_block(char * data_start)
992 {
993 	strncpy (data_start, identifier, 8);
994 	data_start += 8;
995 	*((int *) data_start) = chunk_size;
996 	data_start += 4;
997 
998 	//find parent's chunkshape
999 	ChunkShape* cs=0;
1000 	if(!strcmp(parent->identifier,"REBSHAPE"))
1001 	{
1002 		cs=((Shape_Chunk*)parent)->shape_data_store;
1003 	}
1004 	else if(!strcmp(parent->identifier,"SUBSHAPE"))
1005 	{
1006 		cs=((Shape_Sub_Shape_Chunk*)parent)->shape_data_store;
1007 	}
1008 	assert(cs);
1009 
1010 
1011 	*(ChunkVectorInt*)data_start=cs->centre;
1012 	data_start+=sizeof(ChunkVectorInt);
1013 
1014 	*(float*)data_start=cs->radius;
1015 }
1016 
1017 
1018 /////////////////////////////////////////
1019 
1020 // Class Shape_UV_Coord_Chunk functions
1021 
1022 // These can only be children of Shape_Chunks
1023 // the shape chunks data will automatically be updated by it is created
1024 RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPUVCRD",Shape_UV_Coord_Chunk,"REBSHAPE",Shape_Chunk)
1025 RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPUVCRD",Shape_UV_Coord_Chunk,"SUBSHAPE",Shape_Sub_Shape_Chunk)
1026 RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPUVCRD",Shape_UV_Coord_Chunk,"CONSHAPE",Console_Shape_Chunk)
1027 
1028 // from buffer
Shape_UV_Coord_Chunk(Shape_Chunk * parent,const char * uvdata,size_t)1029 Shape_UV_Coord_Chunk::Shape_UV_Coord_Chunk (Shape_Chunk * parent, const char * uvdata, size_t /*uvsize*/)
1030 : Chunk (parent, "SHPUVCRD"),
1031 uv_data (NULL), num_uvs (*((int *) uvdata))
1032 {
1033 	int i,j;
1034 
1035 	if (num_uvs)
1036 	{
1037 		parent->shape_data_store->uv_list = new ChunkUV_List[num_uvs];
1038 	}
1039 	else
1040 	{
1041 		parent->shape_data_store->uv_list = 0;
1042 	}
1043 	*((ChunkUV_List**) &uv_data) = parent->shape_data_store->uv_list;
1044 
1045 	parent->shape_data_store->num_uvs = num_uvs;
1046 
1047 	uvdata += 4;
1048 
1049 	for (i=0;i<num_uvs;i++)
1050 	{
1051 		parent->shape_data_store->uv_list[i].num_verts = *((int *) uvdata);
1052 		uvdata += 4;
1053 
1054 		for (j=0; j<parent->shape_data_store->uv_list[i].num_verts; j++)
1055 		{
1056 			parent->shape_data_store->uv_list[i].vert[j] = *((ChunkUV *)uvdata);
1057 			uvdata += sizeof(ChunkUV);
1058 		}
1059 	}
1060 
1061 }
1062 
Shape_UV_Coord_Chunk(Shape_Sub_Shape_Chunk * parent,const char * uvdata,size_t)1063 Shape_UV_Coord_Chunk::Shape_UV_Coord_Chunk (Shape_Sub_Shape_Chunk * parent, const char * uvdata, size_t /*uvsize*/)
1064 : Chunk (parent, "SHPUVCRD"),
1065 uv_data (NULL), num_uvs (*((int *) uvdata))
1066 {
1067 	int i,j;
1068 
1069 	parent->shape_data_store->uv_list = new ChunkUV_List[num_uvs];
1070 	*((ChunkUV_List**) &uv_data) = parent->shape_data_store->uv_list;
1071 
1072 	parent->shape_data_store->num_uvs = num_uvs;
1073 
1074 	uvdata += 4;
1075 
1076 	for (i=0;i<num_uvs;i++)
1077 	{
1078 		parent->shape_data_store->uv_list[i].num_verts = *((int *) uvdata);
1079 		uvdata += 4;
1080 
1081 		for (j=0; j<parent->shape_data_store->uv_list[i].num_verts; j++)
1082 		{
1083 			parent->shape_data_store->uv_list[i].vert[j] = *((ChunkUV *)uvdata);
1084 			uvdata += sizeof(ChunkUV);
1085 		}
1086 	}
1087 
1088 }
1089 
Shape_UV_Coord_Chunk(Console_Shape_Chunk * parent,const char * uvdata,size_t)1090 Shape_UV_Coord_Chunk::Shape_UV_Coord_Chunk (Console_Shape_Chunk * parent, const char * uvdata, size_t /*uvsize*/)
1091 : Chunk (parent, "SHPUVCRD"),
1092 uv_data (NULL), num_uvs (*((int *) uvdata))
1093 {
1094 	int i,j;
1095 
1096 	ChunkUV_List* uv_list= new ChunkUV_List[num_uvs];
1097 	*((ChunkUV_List**) &uv_data) = uv_list;
1098 
1099 	uvdata += 4;
1100 
1101 	for (i=0;i<num_uvs;i++)
1102 	{
1103 		uv_list[i].num_verts = *((int *) uvdata);
1104 		uvdata += 4;
1105 
1106 		for (j=0; j<uv_list[i].num_verts; j++)
1107 		{
1108 			uv_list[i].vert[j] = *((ChunkUV *)uvdata);
1109 			uvdata += sizeof(ChunkUV);
1110 		}
1111 	}
1112 
1113 }
1114 
output_chunk(HANDLE & hand)1115 BOOL Shape_UV_Coord_Chunk::output_chunk (HANDLE &hand)
1116 {
1117 	unsigned long junk;
1118 	BOOL ok;
1119 	char * data_block;
1120 
1121 	data_block = this->make_data_block_from_chunk();
1122 
1123 	ok = WriteFile (hand, (long *) data_block, (unsigned long) chunk_size, &junk, 0);
1124 
1125 	delete [] data_block;
1126 
1127 	if (!ok) return FALSE;
1128 
1129 	return TRUE;
1130 
1131 }
1132 
1133 
fill_data_block(char * data_start)1134 void Shape_UV_Coord_Chunk::fill_data_block(char * data_start)
1135 {
1136 	strncpy (data_start, identifier, 8);
1137 
1138 	data_start += 8;
1139 
1140 	*((int *) data_start) = chunk_size;
1141 
1142 	data_start += 4;
1143 
1144 	*((int *) data_start) = num_uvs;
1145 
1146 	data_start += 4;
1147 
1148 	for (int i=0;i<num_uvs;i++)
1149 	{
1150 		*((int *)data_start) = uv_data[i].num_verts;
1151 		data_start += 4;
1152 		for (int j = 0; j< uv_data[i].num_verts; j++)
1153 		{
1154 			*((ChunkUV *) data_start) = uv_data[i].vert[j];
1155 			data_start += sizeof(ChunkUV);
1156 		}
1157 	}
1158 
1159 }
1160 
size_chunk()1161 size_t Shape_UV_Coord_Chunk::size_chunk ()
1162 {
1163 	chunk_size = 12 + 4;
1164 	for (int i=0; i<num_uvs; i++)
1165 		chunk_size += (4+(sizeof(ChunkUV)*uv_data[i].num_verts));
1166 
1167 	return chunk_size;
1168 
1169 }
1170 
1171 /////////////////////////////////////////
1172 
1173 // Class Shape_Texture_Filenames_Chunk functions
1174 
1175 // These can only be children of Shape_Chunks
1176 // the shape chunks data will automatically be updated by it is created
1177 
1178 RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPTEXFN",Shape_Texture_Filenames_Chunk,"REBSHAPE",Shape_Chunk)
1179 RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPTEXFN",Shape_Texture_Filenames_Chunk,"SUBSHAPE",Shape_Sub_Shape_Chunk)
1180 // from buffer
Shape_Texture_Filenames_Chunk(Shape_Chunk * parent,const char * tfndata,size_t)1181 Shape_Texture_Filenames_Chunk::Shape_Texture_Filenames_Chunk (Shape_Chunk * parent, const char * tfndata, size_t /*tfnsize*/)
1182 : Chunk (parent, "SHPTEXFN"),
1183 tex_fns (), num_tex_fns (*((int *) tfndata))
1184 {
1185 	int i;
1186 
1187 	parent->shape_data_store->texture_fns = new char * [num_tex_fns];
1188 	*((char***) &tex_fns) = parent->shape_data_store->texture_fns;
1189 
1190 	parent->shape_data_store->num_texfiles = num_tex_fns;
1191 
1192 	tfndata += 4;
1193 
1194 	for (i=0; i<num_tex_fns; i++) {
1195 		parent->shape_data_store->texture_fns[i] = new char [strlen(tfndata)+1];
1196 		strcpy (parent->shape_data_store->texture_fns[i], tfndata);
1197 		tfndata += (strlen(tfndata)+1);
1198 	}
1199 
1200 }
1201 
Shape_Texture_Filenames_Chunk(Shape_Sub_Shape_Chunk * parent,const char * tfndata,size_t)1202 Shape_Texture_Filenames_Chunk::Shape_Texture_Filenames_Chunk (Shape_Sub_Shape_Chunk * parent, const char * tfndata, size_t /*tfnsize*/)
1203 : Chunk (parent, "SHPTEXFN"),
1204 tex_fns (), num_tex_fns (*((int *) tfndata))
1205 {
1206 	int i;
1207 
1208 	parent->shape_data_store->texture_fns = new char * [num_tex_fns];
1209 	*((char***) &tex_fns) = parent->shape_data_store->texture_fns;
1210 
1211 	parent->shape_data_store->num_texfiles = num_tex_fns;
1212 
1213 	tfndata += 4;
1214 
1215 	for (i=0; i<num_tex_fns; i++) {
1216 		parent->shape_data_store->texture_fns[i] = new char [strlen(tfndata)+1];
1217 		strcpy (parent->shape_data_store->texture_fns[i], tfndata);
1218 		tfndata += (strlen(tfndata)+1);
1219 	}
1220 
1221 }
1222 
output_chunk(HANDLE & hand)1223 BOOL Shape_Texture_Filenames_Chunk::output_chunk (HANDLE &hand)
1224 {
1225 	unsigned long junk;
1226 	BOOL ok;
1227 	char * data_block;
1228 
1229 	data_block = this->make_data_block_from_chunk();
1230 
1231 	ok = WriteFile (hand, (long *) data_block, (unsigned long) chunk_size, &junk, 0);
1232 
1233 	delete [] data_block;
1234 
1235 	if (!ok) return FALSE;
1236 
1237 	return TRUE;
1238 }
1239 
1240 
fill_data_block(char * data_start)1241 void Shape_Texture_Filenames_Chunk::fill_data_block(char * data_start)
1242 {
1243 	strncpy (data_start, identifier, 8);
1244 
1245 	data_start += 8;
1246 
1247 	*((int *) data_start) = chunk_size;
1248 
1249 	data_start += 4;
1250 
1251 	*((int *) data_start) = num_tex_fns;
1252 
1253 	data_start += 4;
1254 
1255 	for (int i=0;i<num_tex_fns;i++) {
1256 		sprintf(data_start, "%s", tex_fns[i]);
1257 		data_start += (strlen (tex_fns[i]) + 1);
1258 	}
1259 
1260 }
1261 
size_chunk()1262 size_t Shape_Texture_Filenames_Chunk::size_chunk()
1263 {
1264 	chunk_size = 16;
1265 
1266 	for (int i=0;i<num_tex_fns;i++)
1267 		chunk_size += (strlen (tex_fns[i]) + 1);
1268 
1269 	chunk_size += (4-chunk_size%4)%4;
1270 
1271 	return chunk_size;
1272 
1273 }
1274 
1275 
1276 /////////////////////////////////////////
1277 
1278 // Class Shape_Header_Chunk functions
1279 
1280 // These can only be children of Shape_Chunks
1281 // the shape chunks data will automatically be updated by it is created
1282 RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPHEAD1",Shape_Header_Chunk,"REBSHAPE",Shape_Chunk)
1283 
1284 
Shape_Header_Chunk(Shape_Chunk * parent,const char * hdata,size_t)1285 Shape_Header_Chunk::Shape_Header_Chunk (Shape_Chunk * parent, const char * hdata, size_t /*hsize*/)
1286 	: Chunk (parent, "SHPHEAD1"),
1287 	shape_data (parent->shape_data_store)
1288 {
1289 	int num_as_obj;
1290 
1291 	flags = *((int *) hdata);
1292 
1293 	strncpy (lock_user, (hdata + 4), 16);
1294 	lock_user[16] = '\0';
1295 	hdata+=20;
1296 
1297 	file_id_num = *((int *) hdata );
1298 	hdata+=4;
1299 
1300 
1301 	parent->shape_data_store->num_verts = *((int *) hdata );
1302 	hdata+=4;
1303 	parent->shape_data_store->num_polys = *((int *) hdata );
1304 	hdata+=4;
1305 
1306 	parent->shape_data_store->radius = *((float *) hdata);
1307 	hdata+=4;
1308 
1309 	parent->shape_data_store->max.x = *((int *) hdata);
1310 	hdata+=4;
1311 	parent->shape_data_store->min.x = *((int *) hdata);
1312 	hdata+=4;
1313 
1314 	parent->shape_data_store->max.y = *((int *) hdata);
1315 	hdata+=4;
1316 	parent->shape_data_store->min.y = *((int *) hdata);
1317 	hdata+=4;
1318 
1319 	parent->shape_data_store->max.z = *((int *) hdata);
1320 	hdata+=4;
1321 	parent->shape_data_store->min.z = *((int *) hdata);
1322 	hdata+=4;
1323 
1324 	version_no = *((int *) hdata);
1325 	hdata+=4;
1326 
1327 	num_as_obj = *((int *) hdata);
1328 	hdata+=4;
1329 
1330 	char * obj_store;
1331 
1332 	for (int i = 0; i< num_as_obj; i++)
1333 	{
1334 		obj_store = new char [strlen (hdata) +1];
1335 		strcpy (obj_store, (hdata));
1336 		object_names_store.add_entry(obj_store);
1337 		hdata += (strlen (hdata)+1);
1338 	}
1339 
1340 }
1341 
~Shape_Header_Chunk()1342 Shape_Header_Chunk::~Shape_Header_Chunk()
1343 {
1344 	for (LIF<char *> aon(&object_names_store);
1345 			!aon.done(); aon.next() )
1346 		delete [] aon();
1347 }
1348 
size_chunk()1349 size_t Shape_Header_Chunk::size_chunk()
1350 {
1351 	int length = 80;
1352 
1353 	for (LIF<char *> aon(&object_names_store);
1354 			!aon.done(); aon.next() )
1355 		length += (strlen (aon()) + 1);
1356 
1357 	length += (4-length%4)%4;
1358 
1359 	chunk_size = length;
1360 
1361 	return length;
1362 }
1363 
output_chunk(HANDLE & hand)1364 BOOL Shape_Header_Chunk::output_chunk(HANDLE & hand)
1365 {
1366 	unsigned long junk;
1367 	BOOL ok;
1368 	char * data_block;
1369 
1370 	data_block = this->make_data_block_from_chunk();
1371 
1372 	ok = WriteFile (hand, (long *) data_block, (unsigned long) chunk_size, &junk, 0);
1373 
1374 	delete [] data_block;
1375 
1376 	if (!ok) return FALSE;
1377 
1378 	return TRUE;
1379 }
1380 
fill_data_block(char * data_start)1381 void Shape_Header_Chunk::fill_data_block(char * data_start)
1382 {
1383 
1384 	strncpy (data_start, identifier, 8);
1385 
1386 	data_start += 8;
1387 
1388 	*((int *) data_start) = chunk_size;
1389 
1390 	data_start += 4;
1391 
1392 	*((int *) data_start) = flags;
1393 	strncpy ((data_start + 4), lock_user, 16);
1394 	*((int *) (data_start+20)) = file_id_num;
1395 	data_start+=24;
1396 
1397 	*((int *) data_start) = shape_data->num_verts;
1398 	data_start+=4;
1399 	*((int *) data_start) = shape_data->num_polys;
1400 	data_start+=4;
1401 
1402 	*((float *) data_start) = shape_data->radius;
1403 	data_start+=4;
1404 
1405 	*((int *) data_start) = shape_data->max.x;
1406 	data_start+=4;
1407 	*((int *) data_start) = shape_data->min.x;
1408 	data_start+=4;
1409 
1410 	*((int *) data_start) = shape_data->max.y;
1411 	data_start+=4;
1412 	*((int *) data_start) = shape_data->min.y;
1413 	data_start+=4;
1414 
1415 	*((int *) data_start) = shape_data->max.z;
1416 	data_start+=4;
1417 	*((int *) data_start) = shape_data->min.z;
1418 	data_start+=4;
1419 
1420 	*((int *) data_start) = version_no;
1421 	data_start+=4;
1422 
1423 	*((int *) data_start) = object_names_store.size();
1424 	data_start+=4;
1425 
1426 
1427 	for (LIF<char *> ons(&object_names_store); !ons.done(); ons.next())
1428 	{
1429 		strcpy (data_start, ons());
1430 		data_start += (strlen(ons())+1);
1431 	}
1432 
1433 }
1434 
1435 
prepare_for_output()1436 void Shape_Header_Chunk::prepare_for_output()
1437 {
1438 // this will also set the object chunks numbers as well,
1439 // so that it is done in the right order
1440 
1441 	char * str;
1442 
1443 	if (file_id_num == -1) file_id_num = ++(Shape_Chunk::max_id);
1444 
1445 	while (object_names_store.size()) {
1446 		delete [] object_names_store.first_entry();
1447 		object_names_store.delete_first_entry();
1448 	}
1449 
1450 	for (LIF<Object_Chunk *> aosl(&associated_objects_store);
1451 		!aosl.done(); aosl.next() ) {
1452 
1453 		if (aosl()->get_header())
1454 			aosl()->get_header()->shape_id_no = file_id_num;
1455 
1456 		str = new char [strlen(aosl()->object_data.o_name) + 1];
1457 		strcpy(str, aosl()->object_data.o_name);
1458 		object_names_store.add_entry(str);
1459 
1460 	}
1461 
1462 	Shape_Chunk::max_id = max(Shape_Chunk::max_id, file_id_num);
1463 
1464 // this should always be the last thing
1465 
1466 	version_no ++;
1467 }
1468 
1469 
1470 
1471 /////////////////////////////////////////
1472 
1473 // Class Shape_Merge_Data_Chunk functions
1474 
1475 RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPMRGDT",Shape_Merge_Data_Chunk,"REBSHAPE",Shape_Chunk)
1476 RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPMRGDT",Shape_Merge_Data_Chunk,"SUBSHAPE",Shape_Sub_Shape_Chunk)
1477 
Shape_Merge_Data_Chunk(Shape_Chunk * parent,int * m_dt,int n_ps)1478 Shape_Merge_Data_Chunk::Shape_Merge_Data_Chunk(Shape_Chunk * parent, int * m_dt, int n_ps)
1479 : Chunk (parent, "SHPMRGDT"), num_polys (n_ps)
1480 {
1481 	merge_data = new int [n_ps];
1482 	for (int i=0; i<n_ps; i++)
1483 	{
1484 		merge_data[i] = m_dt[i];
1485 	}
1486 
1487 }
1488 
Shape_Merge_Data_Chunk(Shape_Sub_Shape_Chunk * parent,int * m_dt,int n_ps)1489 Shape_Merge_Data_Chunk::Shape_Merge_Data_Chunk(Shape_Sub_Shape_Chunk * parent, int * m_dt, int n_ps)
1490 : Chunk (parent, "SHPMRGDT"), num_polys (n_ps)
1491 {
1492 	merge_data = new int [n_ps];
1493 	for (int i=0; i<n_ps; i++)
1494 	{
1495 		merge_data[i] = m_dt[i];
1496 	}
1497 
1498 }
1499 
1500 
Shape_Merge_Data_Chunk(Shape_Chunk * parent,const char * md,size_t ms)1501 Shape_Merge_Data_Chunk::Shape_Merge_Data_Chunk (Shape_Chunk * parent, const char *md, size_t ms)
1502 : Chunk (parent, "SHPMRGDT"), num_polys (ms/4)
1503 {
1504 
1505 	merge_data = new int [num_polys];
1506 	for (int i=0; i<num_polys; i++)
1507 	{
1508 		merge_data[i] = *((int *)(md+4*i));
1509 	}
1510 }
1511 
Shape_Merge_Data_Chunk(Shape_Sub_Shape_Chunk * parent,const char * md,size_t ms)1512 Shape_Merge_Data_Chunk::Shape_Merge_Data_Chunk (Shape_Sub_Shape_Chunk * parent, const char *md, size_t ms)
1513 : Chunk (parent, "SHPMRGDT"), num_polys (ms/4)
1514 {
1515 
1516 	merge_data = new int [num_polys];
1517 	for (int i=0; i<num_polys; i++)
1518 	{
1519 		merge_data[i] = *((int *)(md+4*i));
1520 	}
1521 }
1522 
1523 
~Shape_Merge_Data_Chunk()1524 Shape_Merge_Data_Chunk::~Shape_Merge_Data_Chunk()
1525 {
1526 	if (num_polys) delete [] merge_data;
1527 }
1528 
fill_data_block(char * data_start)1529 void Shape_Merge_Data_Chunk::fill_data_block(char * data_start)
1530 {
1531 	strncpy (data_start, identifier, 8);
1532 
1533 	data_start += 8;
1534 
1535 	*((int *) data_start) = chunk_size;
1536 
1537 	data_start += 4;
1538 
1539 	for (int i=0; i<num_polys; i++)
1540 	{
1541 		*((int *) (data_start+i*4) ) = merge_data[i];
1542 	}
1543 
1544 }
1545 
1546 
1547 /////////////////////////////////////////
1548 RIF_IMPLEMENT_DYNCREATE("SHPEXTFL",Shape_External_File_Chunk)
1549 
1550 /*
1551 Children for Shape_External_File_Chunk :
1552 
1553 "SHPEXTFN"		Shape_External_Filename_Chunk)
1554 "BMPLSTST"		Bitmap_List_Store_Chunk)
1555 "BMNAMVER"		BMP_Names_Version_Chunk)
1556 "BMNAMEXT"		BMP_Names_ExtraData_Chunk)
1557 "RIFFNAME"		RIF_Name_Chunk)
1558 "BMPMD5ID"		Bitmap_MD5_Chunk)
1559 "EXTOBJNM"		Shape_External_Object_Name_Chunk)
1560 */
1561 
1562 CHUNK_WITH_CHILDREN_LOADER("SHPEXTFL",Shape_External_File_Chunk)
1563 
1564 
1565 
Shape_External_File_Chunk(Chunk_With_Children * parent,const char * fname)1566 Shape_External_File_Chunk::Shape_External_File_Chunk (Chunk_With_Children * parent, const char * fname)
1567 :Chunk_With_Children (parent, "SHPEXTFL")
1568 {
1569 	new Shape_External_Filename_Chunk (this, fname);
1570 	post_input_processing();
1571 }
1572 
post_input_processing()1573 void Shape_External_File_Chunk::post_input_processing()
1574 {
1575 	Chunk_With_Children::post_input_processing();
1576 }
1577 
get_shape_name()1578 const char* Shape_External_File_Chunk::get_shape_name()
1579 {
1580 	Shape_External_Object_Name_Chunk* seonc=(Shape_External_Object_Name_Chunk*)lookup_single_child("EXTOBJNM");
1581 	if(seonc)
1582 	{
1583 		return seonc->shape_name;
1584 	}
1585 
1586 	RIF_Name_Chunk* rnc=(RIF_Name_Chunk*)lookup_single_child("RIFFNAME");
1587 	if(rnc)
1588 	{
1589 		return rnc->rif_name;
1590 	}
1591 
1592 	return 0;
1593 
1594 }
1595 
1596 /////////////////////////////////////////
1597 RIF_IMPLEMENT_DYNCREATE("SHPEXTFN",Shape_External_Filename_Chunk)
1598 
Shape_External_Filename_Chunk(Chunk_With_Children * parent,const char * fname)1599 Shape_External_Filename_Chunk::Shape_External_Filename_Chunk(Chunk_With_Children * parent, const char * fname)
1600 : Chunk (parent, "SHPEXTFN")
1601 {
1602 	file_name = new char [strlen(fname)+1];
1603 	strcpy (file_name, fname);
1604 
1605 	rescale = 1;
1606 	version_no = -1;
1607 
1608 }
1609 
Shape_External_Filename_Chunk(Chunk_With_Children * parent,const char * fdata,size_t)1610 Shape_External_Filename_Chunk::Shape_External_Filename_Chunk (Chunk_With_Children * parent, const char *fdata, size_t /*fsize*/)
1611 : Chunk (parent, "SHPEXTFN")
1612 {
1613 	rescale = *((unaligned_f64 *) fdata);
1614 	fdata += 8;
1615 	version_no = *((unaligned_s32 *) fdata);
1616 	fdata += 4;
1617 	file_name = new char [strlen(fdata)+1];
1618 	strcpy (file_name, fdata);
1619 }
1620 
~Shape_External_Filename_Chunk()1621 Shape_External_Filename_Chunk::~Shape_External_Filename_Chunk()
1622 {
1623 	if (file_name)
1624 		delete [] file_name;
1625 }
1626 
fill_data_block(char * data_start)1627 void Shape_External_Filename_Chunk::fill_data_block (char *data_start)
1628 {
1629 	strncpy (data_start, identifier, 8);
1630 
1631 	data_start += 8;
1632 
1633 	*((int *) data_start) = chunk_size;
1634 
1635 	data_start += 4;
1636 
1637 	*((double *) data_start) = rescale;
1638 
1639 	data_start += 8;
1640 
1641 	*((int *) data_start) = version_no;
1642 
1643 	data_start += 4;
1644 
1645 	strcpy (data_start, file_name);
1646 
1647 }
1648 
1649 ///////////////////////////////////////
1650 RIF_IMPLEMENT_DYNCREATE("EXTOBJNM",Shape_External_Object_Name_Chunk)
1651 
Shape_External_Object_Name_Chunk(Chunk_With_Children * parent,const char * oname)1652 Shape_External_Object_Name_Chunk::Shape_External_Object_Name_Chunk(Chunk_With_Children * parent, const char * oname)
1653 : Chunk (parent, "EXTOBJNM")
1654 {
1655 	object_name = new char [strlen(oname)+1];
1656 	shape_name=0;
1657 	strcpy (object_name, oname);
1658 	pad=0;
1659 
1660 	RIF_Name_Chunk* rnc=(RIF_Name_Chunk*)parent->lookup_single_child("RIFFNAME");
1661 	if(rnc)
1662 	{
1663 		shape_name=new char[strlen(object_name)+strlen(rnc->rif_name)+2];
1664 		sprintf(shape_name,"%s@%s",object_name,rnc->rif_name);
1665 	}
1666 	else
1667 	{
1668 		shape_name=new char[strlen(object_name)+10+2];
1669 		sprintf(shape_name,"%s@*NotFound*",object_name);
1670 	}
1671 }
1672 
Shape_External_Object_Name_Chunk(Chunk_With_Children * parent,const char * data,size_t)1673 Shape_External_Object_Name_Chunk::Shape_External_Object_Name_Chunk (Chunk_With_Children * parent, const char *data, size_t /*fsize*/)
1674 : Chunk (parent, "EXTOBJNM")
1675 {
1676 	pad=*(int*)data;
1677 	data+=4;
1678 	object_name = new char [strlen(data)+1];
1679 	strcpy (object_name, data);
1680 	shape_name=0;
1681 }
1682 
~Shape_External_Object_Name_Chunk()1683 Shape_External_Object_Name_Chunk::~Shape_External_Object_Name_Chunk()
1684 {
1685 	if (object_name)
1686 		delete [] object_name;
1687 	if(shape_name)
1688 		delete [] shape_name;
1689 }
1690 
post_input_processing()1691 void  Shape_External_Object_Name_Chunk::post_input_processing()
1692 {
1693 	RIF_Name_Chunk* rnc=(RIF_Name_Chunk*)parent->lookup_single_child("RIFFNAME");
1694 	if(rnc)
1695 	{
1696 		shape_name=new char[strlen(object_name)+strlen(rnc->rif_name)+2];
1697 		sprintf(shape_name,"%s@%s",object_name,rnc->rif_name);
1698 	}
1699 	else
1700 	{
1701 		shape_name=new char[strlen(object_name)+10+2];
1702 		sprintf(shape_name,"%s@*NotFound*",object_name);
1703 	}
1704 }
1705 
fill_data_block(char * data_start)1706 void Shape_External_Object_Name_Chunk::fill_data_block (char *data_start)
1707 {
1708 	strncpy (data_start, identifier, 8);
1709 
1710 	data_start += 8;
1711 
1712 	*((int *) data_start) = chunk_size;
1713 
1714 	data_start += 4;
1715 
1716 	*(int*)data_start =pad;
1717 
1718 	data_start+=4;
1719 
1720 	strcpy (data_start, object_name);
1721 
1722 }
1723 
1724 ///////////////////////////////////////
1725 
1726 RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPMORPH",Shape_Morphing_Data_Chunk,"REBSHAPE",Shape_Chunk)
1727 RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SHPMORPH",Shape_Morphing_Data_Chunk,"SUBSHAPE",Shape_Sub_Shape_Chunk)
1728 
1729 /*
1730 Children for Shape_Morphing_Data_Chunk :
1731 
1732 "SUBSHAPE"		Shape_Sub_Shape_Chunk
1733 "FRMMORPH"		Shape_Morphing_Frame_Data_Chunk
1734 */
1735 
1736 
Shape_Morphing_Data_Chunk(Shape_Chunk * parent,const char * data,size_t size)1737 Shape_Morphing_Data_Chunk::Shape_Morphing_Data_Chunk (Shape_Chunk * parent, const char *data, size_t size)
1738 : Chunk_With_Children (parent, "SHPMORPH"), parent_shape (parent), parent_sub_shape (0)
1739 {
1740 	const char * buffer_ptr = data;
1741 
1742 	while ((data-buffer_ptr)< (signed)size) {
1743 
1744 		if ((*(int *)(data + 8)) + (data-buffer_ptr) > (signed)size) {
1745 			Parent_File->error_code = CHUNK_FAILED_ON_LOAD_NOT_RECOGNISED;
1746 			break;
1747 		}
1748 
1749 		DynCreate(data);
1750 		data += *(int *)(data + 8);
1751 
1752 	}
1753 
1754 }
Shape_Morphing_Data_Chunk(Shape_Sub_Shape_Chunk * parent,const char * data,size_t size)1755 Shape_Morphing_Data_Chunk::Shape_Morphing_Data_Chunk (Shape_Sub_Shape_Chunk * parent, const char *data, size_t size)
1756 : Chunk_With_Children (parent, "SHPMORPH"), parent_shape (0), parent_sub_shape (parent)
1757 {
1758 	const char * buffer_ptr = data;
1759 
1760 	while ((data-buffer_ptr)< (signed)size) {
1761 
1762 		if ((*(int *)(data + 8)) + (data-buffer_ptr) > (signed)size) {
1763 			Parent_File->error_code = CHUNK_FAILED_ON_LOAD_NOT_RECOGNISED;
1764 			break;
1765 		}
1766 		DynCreate(data);
1767 		data += *(int *)(data + 8);
1768 
1769 
1770 	}
1771 
1772 }
1773 
1774 
prepare_for_output()1775 void Shape_Morphing_Data_Chunk::prepare_for_output()
1776 {
1777 	int max_id = 0;
1778 
1779 	List<Chunk *> cl;
1780 	lookup_child("SUBSHAPE",cl);
1781 
1782 	LIF<Chunk *> cli(&cl);
1783 
1784 	for (; !cli.done(); cli.next())
1785 	{
1786 		max_id = max (max_id, ((Shape_Sub_Shape_Chunk *)cli())->get_header()->file_id_num);
1787 	}
1788 
1789 	for (cli.restart(); !cli.done(); cli.next())
1790 	{
1791 		if (((Shape_Sub_Shape_Chunk *)cli())->get_header()->file_id_num == -1)
1792 		{
1793 			((Shape_Sub_Shape_Chunk *)cli())->get_header()->file_id_num = ++max_id;
1794 		}
1795 	}
1796 	Chunk_With_Children::prepare_for_output();
1797 
1798 }
1799 
1800 ///////////////////////////////////////
1801 
1802 #ifdef new
1803 #pragma message("new defined")
1804 #endif
1805 
1806 RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("FRMMORPH",Shape_Morphing_Frame_Data_Chunk,"SHPMORPH",Shape_Morphing_Data_Chunk)
1807 
Shape_Morphing_Frame_Data_Chunk(Shape_Morphing_Data_Chunk * parent,const char * data,size_t)1808 Shape_Morphing_Frame_Data_Chunk::Shape_Morphing_Frame_Data_Chunk (Shape_Morphing_Data_Chunk * parent,const char *data, size_t /*size*/)
1809 : Chunk (parent, "FRMMORPH")
1810 {
1811 	a_flags = *((int *)data);
1812 	data +=4;
1813 	a_speed = *((int *)data);
1814 	data +=4;
1815 	num_frames = *((int *)data);
1816 	data +=4;
1817 
1818 	if (num_frames)
1819 		frame_store = new int [num_frames * 3];
1820 	else
1821 		frame_store=0;
1822 	for (int i=0; i<num_frames; i++)
1823 	{
1824 		frame_store[i*3] = *((int *)data);
1825 		data +=4;
1826 		frame_store[i*3+1] = *((int *)data);
1827 		data +=4;
1828 		frame_store[i*3+2] = *((int *)data);
1829 		data +=4;
1830 	}
1831 }
1832 
fill_data_block(char * data_start)1833 void Shape_Morphing_Frame_Data_Chunk::fill_data_block ( char * data_start)
1834 {
1835 	strncpy (data_start, identifier, 8);
1836 	data_start += 8;
1837 	*((int *) data_start) = chunk_size;
1838 	data_start += 4;
1839 	*((int *) data_start) = a_flags;
1840 	data_start += 4;
1841 	*((int *) data_start) = a_speed;
1842 	data_start += 4;
1843 	*((int *) data_start) = num_frames;
1844 	data_start += 4;
1845 	for (int i=0; i<num_frames; i++)
1846 	{
1847 		*((int *) data_start) = frame_store[i*3];
1848 		data_start += 4;
1849 		*((int *) data_start) = frame_store[i*3 + 1];
1850 		data_start += 4;
1851 		*((int *) data_start) = frame_store[i*3 + 2];
1852 		data_start += 4;
1853 	}
1854 }
1855 
~Shape_Morphing_Frame_Data_Chunk()1856 Shape_Morphing_Frame_Data_Chunk::~Shape_Morphing_Frame_Data_Chunk()
1857 {
1858 	if (frame_store) delete [] frame_store;
1859 	while (anim_frames.size())
1860 	{
1861 		delete anim_frames.first_entry();
1862 		anim_frames.delete_first_entry();
1863 	}
1864 }
1865 
prepare_for_output()1866 void Shape_Morphing_Frame_Data_Chunk::prepare_for_output()
1867 {
1868 	// get the number of each shape in each frame
1869 
1870 	// N.B. this relies on the fact that the shapes are numbered
1871 	// but they will be by the parent class which will have it's prepare
1872 	// for output called first
1873 
1874 	if (frame_store)
1875 		delete [] frame_store;
1876 
1877 	if (anim_frames.size())
1878 	{
1879 		frame_store = new int [ anim_frames.size() * 3 ];
1880 	}
1881 	else
1882 	{
1883 		frame_store = 0;
1884 	}
1885 
1886 	int num_f = 0;
1887 
1888 	for (LIF<a_frame *> afi(&anim_frames); !afi.done(); afi.next())
1889 	{
1890 		int s1no, s2no;
1891 		if (afi()->shape1a)
1892 			s1no = afi()->shape1a->get_header()->file_id_num;
1893 		else
1894 			s1no = -1;
1895 		if (afi()->shape2a)
1896 			s2no = afi()->shape2a->get_header()->file_id_num;
1897 		else
1898 			s2no = -1;
1899 
1900 		frame_store[num_f] = s1no;
1901 		frame_store[num_f+1] = s2no;
1902 		frame_store[num_f+2] = afi()->spare;
1903 		num_f ++;
1904 	}
1905 	num_frames = num_f;
1906 }
1907 
1908 
post_input_processing()1909 void Shape_Morphing_Frame_Data_Chunk::post_input_processing()
1910 {
1911 	List<Shape_Sub_Shape_Chunk *> shplist;
1912 	List<Chunk *> child_lists;
1913 
1914 	Shape_Morphing_Data_Chunk * pchnk = (Shape_Morphing_Data_Chunk *) parent;
1915 
1916 	pchnk->lookup_child("SUBSHAPE",child_lists);
1917 
1918 	while (child_lists.size()) {
1919 		shplist.add_entry((Shape_Sub_Shape_Chunk *)child_lists.first_entry());
1920 		child_lists.delete_first_entry();
1921 	}
1922 
1923 	LIF<Shape_Sub_Shape_Chunk *> sl(&shplist);
1924 
1925 	for (int i = 0; i<num_frames; i++)
1926 	{
1927 		Shape_Chunk * sh1b = 0, *sh2b = 0;
1928 		Shape_Sub_Shape_Chunk * sh1a = 0, *sh2a = 0;
1929 		a_frame * fr;
1930 
1931 		if (frame_store[i*2] == -1)
1932 		{
1933 			sh1b = pchnk->parent_shape;
1934 		}
1935 		else
1936 		{
1937 			for (; !sl.done(); sl.next()) {
1938 				if (sl()->get_header())
1939 					if (sl()->get_header()->file_id_num == frame_store[i])
1940 						break;
1941 			}
1942 			if (!sl.done())
1943 			{
1944 				sh1a = sl();
1945 			}
1946 		}
1947 
1948 		if (frame_store[i*2+1] == -1)
1949 		{
1950 			sh2b = pchnk->parent_shape;
1951 		}
1952 		else
1953 		{
1954 			for (sl.restart(); !sl.done(); sl.next()) {
1955 				if (sl()->get_header())
1956 					if (sl()->get_header()->file_id_num == frame_store[i+1])
1957 						break;
1958 			}
1959 			if (!sl.done())
1960 			{
1961 				sh2a = sl();
1962 			}
1963 		}
1964 		if ((sh1a || sh1b) && (sh2a || sh2b))
1965 		{
1966 		 	fr = new a_frame;
1967 			if (sh1a)
1968 				fr->shape1a = sh1a;
1969 			else if (sh1b)
1970 				fr->shape1b = sh1b;
1971 
1972 			if (sh2a)
1973 				fr->shape2a = sh2a;
1974 			else if (sh2b)
1975 				fr->shape2b = sh2b;
1976 
1977 			fr->spare = frame_store[i+2];
1978 			anim_frames.add_entry(fr);
1979 		}
1980 
1981 	}
1982 }
1983 
1984 /////////////////////////////////////////
1985 
1986 // Class Shape_Sub_Shape_Chunk functions
1987 
1988 
1989 RIF_IMPLEMENT_DYNCREATE("SUBSHAPE",Shape_Sub_Shape_Chunk)
1990 /*
1991 Children for Shape_Sub_Shape_Chunk :
1992 
1993 "SHPRAWVT"		Shape_Vertex_Chunk
1994 "SHPPOLYS"		Shape_Polygon_Chunk
1995 "SUBSHPHD"		Shape_Sub_Shape_Header_Chunk
1996 "SHPVNORM"		Shape_Vertex_Normal_Chunk
1997 "SHPPNORM"		Shape_Polygon_Normal_Chunk
1998 "SHPTEXFN"		Shape_Texture_Filenames_Chunk
1999 "SHPUVCRD"		Shape_UV_Coord_Chunk
2000 "SHPMRGDT"		Shape_Merge_Data_Chunk
2001 "SHPCENTR"		Shape_Centre_Chunk
2002 "SHPMORPH"		Shape_Morphing_Data_Chunk
2003 "SHPEXTFL"		Shape_External_File_Chunk
2004 "SHPPCINF"		Shape_Poly_Change_Info_Chunk
2005 "TEXTANIM"		Animation_Chunk
2006 "SHPFRAGS"		Shape_Fragments_Chunk
2007 "ANIMSEQU"		Anim_Shape_Sequence_Chunk
2008 "PNOTINBB"		Poly_Not_In_Bounding_Box_Chunk
2009 "ANSHCEN2"		Anim_Shape_Centre_Chunk
2010 "ASALTTEX"		Anim_Shape_Alternate_Texturing_Chunk
2011 "SHPPRPRO"		Shape_Preprocessed_Data_Chunk
2012 
2013 
2014 "SHPFNAME"		Shape_Name_Chunk
2015 "FRAGDATA"		Shape_Fragments_Data_Chunk
2016 "FRAGLOCN"		Shape_Fragment_Location_Chunk
2017 */
2018 
Shape_Sub_Shape_Chunk(Chunk_With_Children * parent,const char * data,size_t size)2019 Shape_Sub_Shape_Chunk::Shape_Sub_Shape_Chunk(Chunk_With_Children * parent, const char *data, size_t size)
2020 : Chunk_With_Children (parent, "SUBSHAPE"), shape_data ()
2021 {
2022 	const char * buffer_ptr = data;
2023 
2024 	shape_data_store = (ChunkShape *) &shape_data;
2025 
2026 	while ((data-buffer_ptr)< (signed)size) {
2027 
2028 		if ((*(int *)(data + 8)) + (data-buffer_ptr) > (signed)size) {
2029 			Parent_File->error_code = CHUNK_FAILED_ON_LOAD_NOT_RECOGNISED;
2030 			break;
2031 		}
2032 
2033 		DynCreate(data);
2034 		data += *(int *)(data + 8);
2035 
2036 	}
2037 }
2038 
Shape_Sub_Shape_Chunk(Chunk_With_Children * parent,ChunkShape & shp_dat)2039 Shape_Sub_Shape_Chunk::Shape_Sub_Shape_Chunk (Chunk_With_Children * parent, ChunkShape &shp_dat)
2040 : Chunk_With_Children (parent, "SUBSHAPE"), shape_data (shp_dat)
2041 {
2042 	shape_data_store = (ChunkShape *) &shape_data;
2043 
2044 	new Shape_Sub_Shape_Header_Chunk (this);
2045 
2046 	if (shape_data.v_list) new Shape_Vertex_Chunk (this, shape_data.num_verts);
2047 	if (shape_data.v_normal_list) new Shape_Vertex_Normal_Chunk (this, shape_data.num_verts);
2048 	if (shape_data.p_normal_list) new Shape_Polygon_Normal_Chunk (this, shape_data.num_polys);
2049 	if (shape_data.poly_list) new Shape_Polygon_Chunk (this, shape_data.num_polys);
2050 	if (shape_data.uv_list) new Shape_UV_Coord_Chunk (this, shape_data.num_uvs);
2051 	if (shape_data.texture_fns) new Shape_Texture_Filenames_Chunk (this, shape_data.num_texfiles);
2052 
2053 	//calculate the shape's centre and radius_about_centre
2054 	shape_data_store->centre=(shape_data_store->min+shape_data_store->max)/2;
2055 	shape_data_store->radius_about_centre=0;
2056 	for(int i=0;i<shape_data_store->num_verts;i++)
2057 	{
2058 		float length = (float) mod(shape_data_store->v_list[i]-shape_data_store->centre);
2059 		if(length>shape_data_store->radius_about_centre)
2060 		{
2061 			shape_data_store->radius_about_centre=length;
2062 		}
2063 	}
2064 
2065 	//if the shape hasn't got a Shape_Centre_Chunk , create one.
2066 
2067 	if(!lookup_single_child("SHPCENTR"))
2068 	{
2069 		new Shape_Centre_Chunk(this);
2070 	}
2071 }
2072 
~Shape_Sub_Shape_Chunk()2073 Shape_Sub_Shape_Chunk::~Shape_Sub_Shape_Chunk ()
2074 {
2075 }
2076 
make_copy_of_chunk()2077 Shape_Sub_Shape_Chunk* Shape_Sub_Shape_Chunk::make_copy_of_chunk()
2078 {
2079 	char* Data=this->make_data_block_from_chunk();
2080 	Shape_Sub_Shape_Chunk* NewShape=new Shape_Sub_Shape_Chunk(parent,Data+12,this->size_chunk()-12);
2081 	delete [] Data;
2082 	delete NewShape->get_header();
2083 	new Shape_Sub_Shape_Header_Chunk(NewShape);
2084 	return NewShape;
2085 }
2086 
get_header()2087 Shape_Sub_Shape_Header_Chunk * Shape_Sub_Shape_Chunk::get_header()
2088 {
2089 
2090 	return (Shape_Sub_Shape_Header_Chunk *) this->lookup_single_child ("SUBSHPHD");
2091 
2092 }
2093 
update_my_chunkshape(ChunkShape & cshp)2094 BOOL Shape_Sub_Shape_Chunk::update_my_chunkshape (ChunkShape & cshp)
2095 {
2096 	// Firstly lose all the chunks that were with
2097 	// the old chunk shape
2098 	List <Chunk *> chlst;
2099 
2100 	lookup_child ("SHPRAWVT",chlst);
2101 
2102 	while (chlst.size())
2103 	{
2104 		delete chlst.first_entry();
2105 		chlst.delete_first_entry();
2106 	}
2107 
2108 	lookup_child ("SHPVNORM",chlst);
2109 
2110 	while (chlst.size())
2111 	{
2112 		delete chlst.first_entry();
2113 		chlst.delete_first_entry();
2114 	}
2115 
2116 
2117 	lookup_child ("SHPPNORM",chlst);
2118 
2119 	while (chlst.size())
2120 	{
2121 		delete chlst.first_entry();
2122 		chlst.delete_first_entry();
2123 	}
2124 
2125 
2126 	lookup_child ("SHPPOLYS",chlst);
2127 
2128 	while (chlst.size())
2129 	{
2130 		delete chlst.first_entry();
2131 		chlst.delete_first_entry();
2132 	}
2133 
2134 
2135 	lookup_child ("SHPUVCRD",chlst);
2136 
2137 	while (chlst.size())
2138 	{
2139 		delete chlst.first_entry();
2140 		chlst.delete_first_entry();
2141 	}
2142 
2143 
2144 	lookup_child ("SHPTEXFN",chlst);
2145 
2146 	while (chlst.size())
2147 	{
2148 		delete chlst.first_entry();
2149 		chlst.delete_first_entry();
2150 	}
2151 
2152 	*shape_data_store = cshp;
2153 
2154 	if (shape_data.v_list) new Shape_Vertex_Chunk (this, shape_data.num_verts);
2155 	if (shape_data.v_normal_list) new Shape_Vertex_Normal_Chunk (this, shape_data.num_verts);
2156 	if (shape_data.p_normal_list) new Shape_Polygon_Normal_Chunk (this, shape_data.num_polys);
2157 	if (shape_data.poly_list) new Shape_Polygon_Chunk (this, shape_data.num_polys);
2158 	if (shape_data.uv_list) new Shape_UV_Coord_Chunk (this, shape_data.num_uvs);
2159 	if (shape_data.texture_fns) new Shape_Texture_Filenames_Chunk (this, shape_data.num_texfiles);
2160 
2161 	//calculate the shape's centre and radius_about_centre
2162 	shape_data_store->centre=(shape_data_store->min+shape_data_store->max)/2;
2163 	shape_data_store->radius_about_centre=0;
2164 	for(int i=0;i<shape_data_store->num_verts;i++)
2165 	{
2166 		float length=(float)mod(shape_data_store->v_list[i]-shape_data_store->centre);
2167 		if(length>shape_data_store->radius_about_centre)
2168 		{
2169 			shape_data_store->radius_about_centre=length;
2170 		}
2171 	}
2172 
2173 	//if the shape hasn't got a Shape_Centre_Chunk , create one.
2174 
2175 	if(!lookup_single_child("SHPCENTR"))
2176 	{
2177 		new Shape_Centre_Chunk(this);
2178 	}
2179 
2180 
2181 	return TRUE;
2182 }
2183 
2184 
get_shape_name()2185 const char * Shape_Sub_Shape_Chunk::get_shape_name()
2186 {
2187 	Shape_Name_Chunk* snc=(Shape_Name_Chunk*)lookup_single_child("SHPFNAME");
2188 	if (snc)
2189 	{
2190 		return snc->shape_name;
2191 	}
2192 	else
2193 	{
2194 		return(0);
2195 	}
2196 }
2197 
get_console_shape_data(Console_Type ct)2198 Console_Shape_Chunk* Shape_Sub_Shape_Chunk::get_console_shape_data(Console_Type ct)
2199 {
2200 	List<Chunk*> chlist;
2201 	lookup_child("CONSHAPE",chlist);
2202 	for(LIF<Chunk*> chlif(&chlist);!chlif.done();chlif.next())
2203 	{
2204 		Console_Shape_Chunk* csc=(Console_Shape_Chunk*)chlif();
2205 		List<Chunk*> chlist2;
2206 		csc->lookup_child("CONSTYPE",chlist2);
2207 		if(chlist2.size())
2208 		{
2209 			if(((Console_Type_Chunk*)chlist2.first_entry())->console==ct)
2210 				return csc;
2211 		}
2212 	}
2213 
2214 	return 0;//no console specific shape data
2215 }
2216 
2217 /////////////////////////////////////////
2218 
2219 // Class Shape_Sub_Shape_Header_Chunk functions
2220 
2221 RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("SUBSHPHD",Shape_Sub_Shape_Header_Chunk,"SUBSHAPE",Shape_Sub_Shape_Chunk)
2222 
2223 // These can only be children of Shape_Sub_Shape_Chunks
2224 // the shape chunks data will automatically be updated by it is created
2225 
Shape_Sub_Shape_Header_Chunk(Shape_Sub_Shape_Chunk * parent,const char * hdata,size_t)2226 Shape_Sub_Shape_Header_Chunk::Shape_Sub_Shape_Header_Chunk (Shape_Sub_Shape_Chunk * parent, const char * hdata, size_t /*hsize*/)
2227 	: Chunk (parent, "SUBSHPHD"),
2228 	shape_data (parent->shape_data_store)
2229 {
2230 	flags = *((int *) hdata);
2231 	hdata += 4;
2232 
2233 	file_id_num = *((int *) (hdata));
2234 	hdata += 4;
2235 
2236 	parent->shape_data_store->num_verts = *((int *) (hdata));
2237 	hdata += 4;
2238 	parent->shape_data_store->num_polys = *((int *) (hdata));
2239 	hdata += 4;
2240 
2241 	parent->shape_data_store->radius = *((float *) (hdata));
2242 	hdata += 4;
2243 
2244 	parent->shape_data_store->max.x = *((int *) (hdata));
2245 	hdata += 4;
2246 	parent->shape_data_store->min.x = *((int *) (hdata));
2247 	hdata += 4;
2248 
2249 	parent->shape_data_store->max.y = *((int *) (hdata));
2250 	hdata += 4;
2251 	parent->shape_data_store->min.y = *((int *) (hdata));
2252 	hdata += 4;
2253 
2254 	parent->shape_data_store->max.z = *((int *) (hdata));
2255 	hdata += 4;
2256 	parent->shape_data_store->min.z = *((int *) (hdata));
2257 }
2258 
~Shape_Sub_Shape_Header_Chunk()2259 Shape_Sub_Shape_Header_Chunk::~Shape_Sub_Shape_Header_Chunk()
2260 {
2261 }
2262 
size_chunk()2263 size_t Shape_Sub_Shape_Header_Chunk::size_chunk()
2264 {
2265 	return chunk_size = 44 + 12;
2266 }
2267 
2268 
fill_data_block(char * data_start)2269 void Shape_Sub_Shape_Header_Chunk::fill_data_block(char * data_start)
2270 {
2271 
2272 	strncpy (data_start, identifier, 8);
2273 
2274 	data_start += 8;
2275 
2276 	*((int *) data_start) = chunk_size;
2277 
2278 	data_start += 4;
2279 
2280 	*((int *) data_start) = flags;
2281 	data_start += 4;
2282 
2283 	*((int *) (data_start)) = file_id_num;
2284 	data_start += 4;
2285 
2286 	*((int *) (data_start)) = shape_data->num_verts;
2287 	data_start += 4;
2288 	*((int *) (data_start)) = shape_data->num_polys;
2289 	data_start += 4;
2290 
2291 	*((float *) (data_start)) = shape_data->radius;
2292 	data_start += 4;
2293 
2294 	*((int *) (data_start)) = shape_data->max.x;
2295 	data_start += 4;
2296 	*((int *) (data_start)) = shape_data->min.x;
2297 	data_start += 4;
2298 
2299 	*((int *) (data_start)) = shape_data->max.y;
2300 	data_start += 4;
2301 	*((int *) (data_start)) = shape_data->min.y;
2302 	data_start += 4;
2303 
2304 	*((int *) (data_start)) = shape_data->max.z;
2305 	data_start += 4;
2306 	*((int *) (data_start)) = shape_data->min.z;
2307 
2308 }
2309 
2310 /////////////////////////////////////////
2311 
2312 
2313 // Class Shape_Poly_Change_Info_Chunk functions
2314 
2315 RIF_IMPLEMENT_DYNCREATE("SHPPCINF",Shape_Poly_Change_Info_Chunk)
2316 
fill_data_block(char * data_start)2317 void Shape_Poly_Change_Info_Chunk::fill_data_block(char * data_start)
2318 {
2319 	strncpy (data_start, identifier, 8);
2320 
2321 	data_start += 8;
2322 
2323 	*((int *) data_start) = chunk_size;
2324 
2325 	data_start += 4;
2326 
2327 	*((int *) data_start) = original_num_verts;
2328 
2329 	data_start += 4;
2330 
2331 	*((int *) data_start) = change_list.size();
2332 
2333 	data_start += 4;
2334 
2335 	for (LIF<poly_change_info> pcii(&change_list); !pcii.done(); pcii.next())
2336 	{
2337 		*((int *) data_start) = pcii().poly_num;
2338 
2339 		data_start += 4;
2340 
2341 		*((int *) data_start) = pcii().vert_num_before;
2342 
2343 		data_start += 4;
2344 
2345 		*((int *) data_start) = pcii().vert_num_after;
2346 
2347 		data_start += 4;
2348 	}
2349 
2350 
2351 }
2352 
Shape_Poly_Change_Info_Chunk(Chunk_With_Children * parent,const char * data,size_t)2353 Shape_Poly_Change_Info_Chunk::Shape_Poly_Change_Info_Chunk (Chunk_With_Children * parent,const char * data, size_t /*size*/)
2354 : Chunk (parent, "SHPPCINF")
2355 {
2356 	original_num_verts = *((int *) data);
2357 
2358 	data += 4;
2359 
2360 	int n_entries = *((int *) data);
2361 
2362 	data += 4;
2363 
2364 	for (int i=0; i<n_entries; i++)
2365 	{
2366 		poly_change_info pci;
2367 
2368 		pci.poly_num = *((int *) data);
2369 		data += 4;
2370 		pci.vert_num_before = *((int *) data);
2371 		data += 4;
2372 		pci.vert_num_after = *((int *) data);
2373 		data += 4;
2374 
2375 		change_list.add_entry(pci);
2376 	}
2377 
2378 }
2379 
2380 
2381 /////////////////////////////////////////
2382 
2383 // Class Shape_Name_Chunk functions
2384 
2385 RIF_IMPLEMENT_DYNCREATE("SHPFNAME",Shape_Name_Chunk)
2386 
Shape_Name_Chunk(Chunk_With_Children * parent,const char * sname)2387 Shape_Name_Chunk::Shape_Name_Chunk (Chunk_With_Children * parent, const char * sname)
2388 : Chunk (parent, "SHPFNAME")
2389 {
2390 	shape_name = new char [strlen(sname)+1];
2391 	strcpy (shape_name, sname);
2392 }
2393 
Shape_Name_Chunk(Chunk_With_Children * parent,const char * sndata,size_t)2394 Shape_Name_Chunk::Shape_Name_Chunk (Chunk_With_Children * parent, const char * sndata, size_t /*rsize*/)
2395 : Chunk (parent, "SHPFNAME")
2396 {
2397 	shape_name = new char [strlen(sndata)+1];
2398 	strcpy (shape_name, sndata);
2399 }
2400 
~Shape_Name_Chunk()2401 Shape_Name_Chunk::~Shape_Name_Chunk ()
2402 {
2403 	if (shape_name)
2404 		delete [] shape_name;
2405 }
2406 
2407 
fill_data_block(char * data_start)2408 void Shape_Name_Chunk::fill_data_block (char * data_start)
2409 {
2410 	strncpy (data_start, identifier, 8);
2411 
2412 	data_start += 8;
2413 
2414 	*((int *) data_start) = chunk_size;
2415 
2416 	data_start += 4;
2417 
2418 	strcpy (data_start, shape_name);
2419 
2420 }
2421 
2422 /////////////////////////////////////////
2423 
2424 // Class Shape_Fragments_Chunk functions
2425 
2426 RIF_IMPLEMENT_DYNCREATE("SHPFRAGS",Shape_Fragments_Chunk)
2427 
2428 CHUNK_WITH_CHILDREN_LOADER("SHPFRAGS",Shape_Fragments_Chunk)
2429 /*
2430 Children for Shape_Fragments_Chunk :
2431 
2432 "SUBSHAPE"		Shape_Sub_Shape_Chunk
2433 "SHPFRGTP"		Shape_Fragment_Type_Chunk
2434 "FRGSOUND"		Fragment_Type_Sound_Chunk
2435 */
2436 
2437 
2438 /////////////////////////////////////////
2439 
2440 // Class Shape_Fragments_Data_Chunk functions
2441 RIF_IMPLEMENT_DYNCREATE("FRAGDATA",Shape_Fragments_Data_Chunk)
2442 
fill_data_block(char * data_start)2443 void Shape_Fragments_Data_Chunk::fill_data_block (char * data_start)
2444 {
2445 	strncpy (data_start, identifier, 8);
2446 
2447 	data_start += 8;
2448 
2449 	*((int *) data_start) = chunk_size;
2450 
2451 	data_start += 4;
2452 
2453 	*((int *) data_start) = num_fragments;
2454 
2455 	data_start += 4;
2456 
2457 	*((int *) data_start) = pad1;
2458 
2459 	data_start += 4;
2460 
2461 	*((int *) data_start) = pad2;
2462 
2463 	data_start += 4;
2464 
2465 	*((int *) data_start) = pad3;
2466 
2467 }
2468 
Shape_Fragments_Data_Chunk(Chunk_With_Children * parent,const char * sdata,size_t)2469 Shape_Fragments_Data_Chunk::Shape_Fragments_Data_Chunk (Chunk_With_Children * parent, const char * sdata, size_t /*ssize*/)
2470 : Chunk (parent, "FRAGDATA")
2471 {
2472 	num_fragments = *((int *) sdata);
2473 
2474 	sdata += 4;
2475 
2476 	pad1 = *((int *) sdata);
2477 
2478 	sdata += 4;
2479 
2480 	pad2 = *((int *) sdata);
2481 
2482 	sdata += 4;
2483 
2484 	pad3 = *((int *) sdata);
2485 
2486 	sdata += 4;
2487 
2488 }
2489 
2490 
2491 /////////////////////////////////////////
2492 
2493 // Class Shape_Fragments_Location_Chunk functions
2494 RIF_IMPLEMENT_DYNCREATE("FRAGLOCN",Shape_Fragment_Location_Chunk)
2495 
fill_data_block(char * data_start)2496 void Shape_Fragment_Location_Chunk::fill_data_block (char * data_start)
2497 {
2498 	strncpy (data_start, identifier, 8);
2499 
2500 	data_start += 8;
2501 
2502 	*((int *) data_start) = chunk_size;
2503 
2504 	data_start += 4;
2505 
2506 	*((ChunkVectorInt *) data_start) = frag_loc;
2507 
2508 	data_start += sizeof(ChunkVectorInt);
2509 
2510 
2511 	*((int *) data_start) = pad1;
2512 
2513 	data_start += 4;
2514 
2515 	*((int *) data_start) = pad2;
2516 
2517 	data_start += 4;
2518 
2519 	*((int *) data_start) = pad3;
2520 
2521 	data_start += 4;
2522 
2523 	*((int *) data_start) = pad4;
2524 
2525 }
2526 
Shape_Fragment_Location_Chunk(Chunk_With_Children * parent,const char * sdata,size_t)2527 Shape_Fragment_Location_Chunk::Shape_Fragment_Location_Chunk (Chunk_With_Children * parent, const char * sdata, size_t /*ssize*/)
2528 : Chunk (parent, "FRAGLOCN")
2529 {
2530 	frag_loc = *((ChunkVectorInt *) sdata);
2531 
2532 	sdata += sizeof(ChunkVectorInt);
2533 
2534 
2535 	pad1 = *((int *) sdata);
2536 
2537 	sdata += 4;
2538 
2539 	pad2 = *((int *) sdata);
2540 
2541 	sdata += 4;
2542 
2543 	pad3 = *((int *) sdata);
2544 
2545 	sdata += 4;
2546 
2547 	pad4 = *((int *) sdata);
2548 
2549 }
2550 
2551 /////////////////////////////////////////
2552 
2553 RIF_IMPLEMENT_DYNCREATE("SHPFRGTP",Shape_Fragment_Type_Chunk)
Shape_Fragment_Type_Chunk(Chunk_With_Children * parent,const char * name)2554 Shape_Fragment_Type_Chunk::Shape_Fragment_Type_Chunk(Chunk_With_Children* parent,const char* name)
2555 :Chunk(parent,"SHPFRGTP")
2556 {
2557 	frag_type_name=new char[strlen(name)+1];
2558 	strcpy(frag_type_name,name);
2559 	pad1=pad2-0;
2560 }
2561 
Shape_Fragment_Type_Chunk(Chunk_With_Children * const parent,const char * data,size_t const)2562 Shape_Fragment_Type_Chunk::Shape_Fragment_Type_Chunk(Chunk_With_Children* const parent,const char* data,size_t const )
2563 :Chunk(parent,"SHPFRGTP")
2564 {
2565 	int length=strlen(data)+1;
2566 	frag_type_name=new char[length];
2567 	strcpy(frag_type_name,data);
2568 	data+=(length+3)&~3;
2569 
2570 	pad1=*(int*)data;
2571 	data+=4;
2572 	pad2=*(int*)data;
2573 	data+=4;
2574 }
2575 
~Shape_Fragment_Type_Chunk()2576 Shape_Fragment_Type_Chunk::~Shape_Fragment_Type_Chunk()
2577 {
2578 	if(frag_type_name) delete [] frag_type_name;
2579 }
2580 
fill_data_block(char * data_start)2581 void Shape_Fragment_Type_Chunk::fill_data_block(char* data_start)
2582 {
2583 	strncpy (data_start, identifier, 8);
2584 	data_start += 8;
2585 	*((int *) data_start) = chunk_size;
2586 	data_start += 4;
2587 
2588 	strcpy(data_start,frag_type_name);
2589 	data_start+=(strlen(frag_type_name)+4)&~3;
2590 
2591 	*(int*)data_start=pad1;
2592 	data_start+=4;
2593 	*(int*)data_start=pad2;
2594 	data_start+=4;
2595 
2596 }
2597 
size_chunk()2598 size_t Shape_Fragment_Type_Chunk::size_chunk()
2599 {
2600 	chunk_size=12+8;
2601 	chunk_size+=(strlen(frag_type_name)+4)&~3;
2602 	return chunk_size;
2603 }
2604 
2605 
2606 /////////////////////////////////////////
2607 
2608 // Class Anim_Shape_Sequence_Chunk functions
2609 
2610 RIF_IMPLEMENT_DYNCREATE("ANIMSEQU",Anim_Shape_Sequence_Chunk)
2611 
2612 /*
2613 Children for Anim_Shape_Sequence_Chunk :
2614 "ANISEQDT"		Anim_Shape_Sequence_Data_Chunk
2615 "ANIMFRAM"		Anim_Shape_Frame_Chunk
2616 */
2617 
Anim_Shape_Sequence_Chunk(Chunk_With_Children * const parent,const char * data,size_t const size)2618 Anim_Shape_Sequence_Chunk::Anim_Shape_Sequence_Chunk(Chunk_With_Children * const parent, const char *data, size_t const size)
2619 : Chunk_With_Children (parent, "ANIMSEQU")
2620 {
2621 
2622 	sequence_data_store=(ChunkAnimSequence*)&sequence_data;
2623 
2624 	const char * buffer_ptr = data;
2625 
2626 	while ((data-buffer_ptr)< (signed)size) {
2627 
2628 		if ((*(int *)(data + 8)) + (data-buffer_ptr) > (signed)size) {
2629 			Parent_File->error_code = CHUNK_FAILED_ON_LOAD_NOT_RECOGNISED;
2630 			break;
2631 		}
2632 
2633 		DynCreate(data);
2634 		data += *(int *)(data + 8);
2635 
2636 	}
2637 	if(!ConstructSequenceDataFromChildren())
2638 	{
2639 		//this sequence is no longer valid
2640 		delete this;
2641 	}
2642 }
Anim_Shape_Sequence_Chunk(Chunk_With_Children * const parent,int sequencenum,const char * name)2643 Anim_Shape_Sequence_Chunk::Anim_Shape_Sequence_Chunk(Chunk_With_Children * const parent, int sequencenum,const char* name)
2644 : Chunk_With_Children (parent, "ANIMSEQU")
2645 {
2646 
2647 	sequence_data_store=(ChunkAnimSequence*)&sequence_data;
2648 
2649 	sequence_data_store->SequenceNum=sequencenum;
2650 	sequence_data_store->name=new char[strlen(name)+1];
2651 	strcpy(sequence_data_store->name,name);
2652 	RegenerateChildChunks();
2653 }
2654 
Anim_Shape_Sequence_Chunk(Chunk_With_Children * const parent,ChunkAnimSequence const * cas)2655 Anim_Shape_Sequence_Chunk::Anim_Shape_Sequence_Chunk(Chunk_With_Children * const parent, ChunkAnimSequence const* cas )
2656 : Chunk_With_Children (parent, "ANIMSEQU")
2657 {
2658 
2659 	sequence_data_store=(ChunkAnimSequence*)&sequence_data;
2660 	*(ChunkAnimSequence*)&sequence_data=*cas;
2661 	RegenerateChildChunks();
2662 }
2663 
2664 
ConstructSequenceDataFromChildren()2665 int Anim_Shape_Sequence_Chunk::ConstructSequenceDataFromChildren()
2666 {
2667 	Anim_Shape_Sequence_Data_Chunk* assdc=(Anim_Shape_Sequence_Data_Chunk*)lookup_single_child("ANISEQDT");
2668 	if(!assdc)
2669 	{
2670 		return 0;
2671 	}
2672 	sequence_data_store->name=assdc->name;
2673 	sequence_data_store->SequenceNum=assdc->SequenceNum;
2674 	sequence_data_store->flags=assdc->flags;
2675 	sequence_data_store->pad2=assdc->pad2;
2676 	sequence_data_store->pad3=assdc->pad3;
2677 	sequence_data_store->pad4=assdc->pad4;
2678 
2679 	List<Chunk*> chlist;
2680 	lookup_child("ANIMFRAM",chlist);
2681 	sequence_data_store->NumFrames=chlist.size();
2682 	if(sequence_data_store->NumFrames)
2683 	{
2684 		sequence_data_store->Frames=new ChunkAnimFrame*[sequence_data_store->NumFrames];
2685 		for(int i=0;i<sequence_data_store->NumFrames;i++)
2686 		{
2687 			sequence_data_store->Frames[i]=0;
2688 		}
2689 	}
2690 	for(LIF<Chunk*> chlif(& chlist);!chlif.done();chlif.next())
2691 	{
2692 		Anim_Shape_Frame_Chunk* asfc=(Anim_Shape_Frame_Chunk*)chlif();
2693 
2694 		Anim_Shape_Frame_Data_Chunk* asfdc=(Anim_Shape_Frame_Data_Chunk*)asfc->lookup_single_child("ANIFRADT");
2695 		if(!asfdc) return 0;
2696 		if(asfdc->FrameNum>=sequence_data_store->NumFrames) return 0;
2697 
2698 		if(sequence_data_store->Frames[asfdc->FrameNum])return 0;
2699 		sequence_data_store->Frames[asfdc->FrameNum]=new ChunkAnimFrame;
2700 		ChunkAnimFrame* caf=sequence_data_store->Frames[asfdc->FrameNum];
2701 
2702 		Shape_Vertex_Chunk* svc=(Shape_Vertex_Chunk*) asfc->lookup_single_child("SHPRAWVT");
2703 		if(!svc)return 0;
2704 
2705 		Shape_Polygon_Normal_Chunk* spnc=(Shape_Polygon_Normal_Chunk*)asfc->lookup_single_child("SHPPNORM");
2706 		if(!spnc) return 0;
2707 
2708 		caf->name=asfdc->name;
2709 		caf->flags=asfdc->flags;
2710 		caf->num_interp_frames=asfdc->num_interp_frames;
2711 		caf->pad3=asfdc->pad3;
2712 		caf->pad4=asfdc->pad4;
2713 
2714 		caf->num_verts=svc->num_verts;
2715 		caf->v_list=(ChunkVectorInt*)svc->vert_data;
2716 
2717 		caf->num_polys=spnc->num_polys;
2718 		caf->p_normal_list=(ChunkVectorFloat*)spnc->poly_norm_data;
2719 
2720 	}
2721 	return 1;
2722 }
post_input_processing()2723 void Anim_Shape_Sequence_Chunk::post_input_processing()
2724 {
2725 
2726 	List<int>* poly_not_in_bb=0;
2727 	List<Chunk*> chlist;
2728 	parent->lookup_child("PNOTINBB",chlist);
2729 	if(chlist.size())
2730 		poly_not_in_bb=&((Poly_Not_In_Bounding_Box_Chunk*)chlist.first_entry())->poly_no;
2731 	if(!strcmp(parent->identifier,"REBSHAPE"))
2732 	{
2733 		sequence_data_store->UpdateNormalsAndExtents(&((Shape_Chunk*)parent)->shape_data,poly_not_in_bb);
2734 	}
2735 	else if(!strcmp(parent->identifier,"SUBSHAPE"))
2736 	{
2737 		sequence_data_store->UpdateNormalsAndExtents(&((Shape_Sub_Shape_Chunk*)parent)->shape_data,poly_not_in_bb);
2738 	}
2739 
2740 	Chunk_With_Children::post_input_processing();
2741 }
2742 
2743 
update_my_sequencedata(ChunkAnimSequence & seq)2744 void Anim_Shape_Sequence_Chunk::update_my_sequencedata(ChunkAnimSequence & seq)
2745 {
2746 	*sequence_data_store=seq;
2747 	RegenerateChildChunks();
2748 }
2749 
set_sequence_flags(int flags)2750 void Anim_Shape_Sequence_Chunk::set_sequence_flags(int flags)
2751 {
2752 	sequence_data_store->flags=flags;
2753 }
set_frame_flags(int frameno,int flags)2754 void Anim_Shape_Sequence_Chunk::set_frame_flags(int frameno,int flags)
2755 {
2756 	if(frameno< sequence_data_store->NumFrames)
2757 	{
2758 		if(sequence_data_store->Frames[frameno])
2759 		{
2760 			sequence_data_store->Frames[frameno]->flags=flags;
2761 		}
2762 	}
2763 }
2764 
RegenerateChildChunks()2765 void Anim_Shape_Sequence_Chunk::RegenerateChildChunks()
2766 {
2767 	List<Chunk*> chlist;
2768 	lookup_child("ANISEQDT",chlist);
2769 	while(chlist.size())
2770 	{
2771 		delete chlist.first_entry();
2772 		chlist.delete_first_entry();
2773 	}
2774 	lookup_child("ANIMFRAM",chlist);
2775 	while(chlist.size())
2776 	{
2777 		delete chlist.first_entry();
2778 		chlist.delete_first_entry();
2779 	}
2780 
2781 	new Anim_Shape_Sequence_Data_Chunk(this,sequence_data_store);
2782 	for(int i=0;i<sequence_data_store->NumFrames;i++)
2783 	{
2784 	 	if(sequence_data_store->Frames[i]->flags & animframeflag_interpolated_frame)continue;
2785 	 	new Anim_Shape_Frame_Chunk(this,sequence_data_store->Frames[i],i);
2786 	}
2787 }
2788 
GenerateInterpolatedFrames()2789 void Anim_Shape_Sequence_Chunk::GenerateInterpolatedFrames()
2790 {
2791 
2792 	if(!strcmp(parent->identifier,"REBSHAPE"))
2793 	{
2794 		sequence_data_store->GenerateInterpolatedFrames(&((Shape_Chunk*)parent)->shape_data);
2795 	}
2796 	else if(!strcmp(parent->identifier,"SUBSHAPE"))
2797 	{
2798 		sequence_data_store->GenerateInterpolatedFrames(&((Shape_Sub_Shape_Chunk*)parent)->shape_data);
2799 	}
2800 }
2801 /////////////////////////////////////////
2802 
2803 // Class Anim_Shape_Frame_Chunk functions
2804 RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("ANIMFRAM",Anim_Shape_Frame_Chunk,"ANIMSEQU",Anim_Shape_Sequence_Chunk)
2805 
2806 /*
2807 Children for Anim_Shape_Frame_Chunk :
2808 
2809 "ANIFRADT"		Anim_Shape_Frame_Data_Chunk
2810 "SHPPNORM"		Shape_Polygon_Normal_Chunk
2811 "SHPRAWVT"		Shape_Vertex_Chunk
2812 */
2813 
Anim_Shape_Frame_Chunk(Anim_Shape_Sequence_Chunk * const parent,const char * data,size_t const size)2814 Anim_Shape_Frame_Chunk::Anim_Shape_Frame_Chunk(Anim_Shape_Sequence_Chunk *const parent, const char *data, size_t const size)
2815 : Chunk_With_Children (parent, "ANIMFRAM")
2816 {
2817 	const char * buffer_ptr = data;
2818 
2819 	while ((data-buffer_ptr)< (signed)size) {
2820 
2821 		if ((*(int *)(data + 8)) + (data-buffer_ptr) > (signed)size) {
2822 			Parent_File->error_code = CHUNK_FAILED_ON_LOAD_NOT_RECOGNISED;
2823 			break;
2824 		}
2825 		DynCreate(data);
2826 		data += *(int *)(data + 8);
2827 	}
2828 }
2829 
2830 
Anim_Shape_Frame_Chunk(Anim_Shape_Sequence_Chunk * const parent,ChunkAnimFrame * caf,int frameno)2831 Anim_Shape_Frame_Chunk::Anim_Shape_Frame_Chunk(Anim_Shape_Sequence_Chunk * const parent,ChunkAnimFrame* caf,int frameno)
2832 : Chunk_With_Children (parent, "ANIMFRAM")
2833 {
2834 	new Anim_Shape_Frame_Data_Chunk(this,caf,frameno);
2835 	new Shape_Vertex_Chunk(this,caf->v_list,caf->num_verts);
2836 	new Shape_Polygon_Normal_Chunk(this,caf->p_normal_list,caf->num_polys);
2837 
2838 }
2839 /////////////////////////////////////////
2840 
2841 // Class Anim_Shape_Sequence_Data_Chunk functions
2842 
2843 RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("ANISEQDT",Anim_Shape_Sequence_Data_Chunk,"ANIMSEQU",Anim_Shape_Sequence_Chunk)
2844 
Anim_Shape_Sequence_Data_Chunk(Anim_Shape_Sequence_Chunk * const parent,const char * data,size_t const)2845 Anim_Shape_Sequence_Data_Chunk::Anim_Shape_Sequence_Data_Chunk(Anim_Shape_Sequence_Chunk* const parent,const char* data,size_t const/*datasize*/)
2846 : Chunk(parent, "ANISEQDT")
2847 {
2848 	SequenceNum=*(int*)data;
2849 	data+=4;
2850 	flags=*(int*)data;
2851 	data+=4;
2852 	pad2=*(int*)data;
2853 	data+=4;
2854 	pad3=*(int*)data;
2855 	data+=4;
2856 	pad4=*(int*)data;
2857 	data+=4;
2858 	name=new char[strlen(data)+1];
2859 	strcpy(name,data);
2860 
2861 }
2862 
Anim_Shape_Sequence_Data_Chunk(Anim_Shape_Sequence_Chunk * const parent,ChunkAnimSequence * cas)2863 Anim_Shape_Sequence_Data_Chunk::Anim_Shape_Sequence_Data_Chunk(Anim_Shape_Sequence_Chunk* const parent,ChunkAnimSequence* cas)
2864 : Chunk(parent, "ANISEQDT")
2865 {
2866 	SequenceNum=cas->SequenceNum;
2867 	name=cas->name;
2868 	flags=cas->flags;
2869 	pad2=cas->pad2;
2870 	pad3=cas->pad3;
2871 	pad4=cas->pad4;
2872 
2873 }
2874 
fill_data_block(char * datastart)2875 void Anim_Shape_Sequence_Data_Chunk::fill_data_block(char* datastart)
2876 {
2877 	strncpy (datastart, identifier, 8);
2878 	datastart += 8;
2879 	*((int *) datastart) = chunk_size;
2880 	datastart += 4;
2881 
2882 	*(int*)datastart=SequenceNum;
2883 	datastart+=4;
2884 	*(int*)datastart=flags;
2885 	datastart+=4;
2886 	*(int*)datastart=pad2;
2887 	datastart+=4;
2888 	*(int*)datastart=pad3;
2889 	datastart+=4;
2890 	*(int*)datastart=pad4;
2891 	datastart+=4;
2892 
2893 	strcpy(datastart,name ? name : "");
2894 
2895 }
2896 
size_chunk()2897 size_t Anim_Shape_Sequence_Data_Chunk::size_chunk()
2898 {
2899 	return chunk_size =	12+20
2900 		+(name ? strlen(name) : 0)
2901 		+3 +3&~3;
2902 }
2903 
2904 
2905 /////////////////////////////////////////
2906 
2907 // Class Anim_Shape_Frame_Data_Chunk functions
2908 RIF_IMPLEMENT_DYNCREATE_DECLARE_PARENT("ANIFRADT",Anim_Shape_Frame_Data_Chunk,"ANIMFRAM",Anim_Shape_Frame_Chunk)
2909 
Anim_Shape_Frame_Data_Chunk(Anim_Shape_Frame_Chunk * const parent,const char * data,size_t const)2910 Anim_Shape_Frame_Data_Chunk::Anim_Shape_Frame_Data_Chunk(Anim_Shape_Frame_Chunk* const parent,const char* data,size_t const /*datasize*/)
2911 : Chunk(parent, "ANIFRADT")
2912 {
2913 	FrameNum=*(int*)data;
2914 	data+=4;
2915 	flags=*(int*)data;
2916 	data+=4;
2917 	num_interp_frames=*(int*)data;
2918 	data+=4;
2919 	pad3=*(int*)data;
2920 	data+=4;
2921 	pad4=*(int*)data;
2922 	data+=4;
2923 	name=new char[strlen(data)+1];
2924 	strcpy(name,data);
2925 
2926 }
2927 
Anim_Shape_Frame_Data_Chunk(Anim_Shape_Frame_Chunk * const parent,ChunkAnimFrame * caf,int frameno)2928 Anim_Shape_Frame_Data_Chunk::Anim_Shape_Frame_Data_Chunk(Anim_Shape_Frame_Chunk* const parent,ChunkAnimFrame* caf,int frameno)
2929 : Chunk(parent, "ANIFRADT")
2930 {
2931 	FrameNum=frameno;
2932 	name=caf->name;
2933 	flags=caf->flags;
2934 	num_interp_frames=caf->num_interp_frames;
2935 	pad3=caf->pad3;
2936 	pad4=caf->pad4;
2937 
2938 }
2939 
2940 
fill_data_block(char * datastart)2941 void Anim_Shape_Frame_Data_Chunk::fill_data_block(char* datastart)
2942 {
2943 	strncpy (datastart, identifier, 8);
2944 	datastart += 8;
2945 	*((int *) datastart) = chunk_size;
2946 	datastart += 4;
2947 
2948 	*(int*)datastart=FrameNum;
2949 	datastart+=4;
2950 	*(int*)datastart=flags;
2951 	datastart+=4;
2952 	*(int*)datastart=num_interp_frames;
2953 	datastart+=4;
2954 	*(int*)datastart=pad3;
2955 	datastart+=4;
2956 	*(int*)datastart=pad4;
2957 	datastart+=4;
2958 
2959 	strcpy(datastart,name ? name : "");
2960 
2961 }
2962 
size_chunk()2963 size_t Anim_Shape_Frame_Data_Chunk::size_chunk()
2964 {
2965 	return chunk_size =	12+20
2966 		+(name ? strlen(name) : 0)
2967 		+3 +3&~3;
2968 }
2969 
2970 /////////////////////////////////////////
2971 
2972 // Class Anim_Shape_Alternate_Texturing_Chunk functions
2973 RIF_IMPLEMENT_DYNCREATE("ASALTTEX",Anim_Shape_Alternate_Texturing_Chunk)
2974 
2975 /*
2976 Children for Anim_Shape_Alternate_Texturing_Chunk :
2977 "SUBSHAPE"		Shape_Sub_Shape_Chunk
2978 */
2979 
Anim_Shape_Alternate_Texturing_Chunk(Chunk_With_Children * const parent,const char * data,size_t const size)2980 Anim_Shape_Alternate_Texturing_Chunk::Anim_Shape_Alternate_Texturing_Chunk(Chunk_With_Children *const parent, const char *data, size_t const size)
2981 : Chunk_With_Children (parent, "ASALTTEX")
2982 {
2983 	const char * buffer_ptr = data;
2984 
2985 	while ((data-buffer_ptr)< (signed)size) {
2986 
2987 		if ((*(int *)(data + 8)) + (data-buffer_ptr) > (signed)size) {
2988 			Parent_File->error_code = CHUNK_FAILED_ON_LOAD_NOT_RECOGNISED;
2989 			break;
2990 		}
2991 		DynCreate(data);
2992 		data += *(int *)(data + 8);
2993 	}
2994 }
2995 
CreateNewSubShape(const char * name)2996 Shape_Sub_Shape_Chunk* Anim_Shape_Alternate_Texturing_Chunk::CreateNewSubShape(const char* name)
2997 {
2998 	if(!name) return 0;
2999 	//check to make sure that name isn't already in use
3000 	List<Chunk*> chlist;
3001 	lookup_child("SUBSHAPE",chlist);
3002 	for(LIF<Chunk*> chlif(& chlist);!chlif.done();chlif.next())
3003 	{
3004 		Shape_Sub_Shape_Chunk* sssc=(Shape_Sub_Shape_Chunk*) chlif();
3005 		if(!_stricmp(name,sssc->get_shape_name()))return 0;
3006 	}
3007 	ChunkShape cs;
3008 	if(!_stricmp(parent->identifier,"REBSHAPE"))
3009 		cs=((Shape_Chunk*)parent)->shape_data;
3010 	else if(!_stricmp(parent->identifier,"SUBSHAPE"))
3011 		cs=((Shape_Sub_Shape_Chunk*)parent)->shape_data;
3012 	else
3013 		return 0;
3014 	Shape_Sub_Shape_Chunk* sssc=new Shape_Sub_Shape_Chunk(this,cs);
3015 	new Shape_Name_Chunk(sssc,name);
3016 
3017 
3018 	//copy the texture animation data
3019 	Chunk_With_Children* anim_chunk=(Chunk_With_Children*)parent->lookup_single_child("TEXTANIM");
3020 	if(anim_chunk)
3021 	{
3022 		char * tempbuffer = anim_chunk->make_data_block_from_chunk();
3023 		sssc->DynCreate(tempbuffer);
3024 		delete [] tempbuffer;
3025 
3026 	}
3027 
3028 	Shape_Merge_Data_Chunk* smdc=(Shape_Merge_Data_Chunk*)parent->lookup_single_child("SHPMRGDT");
3029 	if(smdc)
3030 	{
3031 		new Shape_Merge_Data_Chunk(sssc,smdc->merge_data,smdc->num_polys);
3032 	}
3033 	return sssc;
3034 
3035 }
3036 
3037 /////////////////////////////////////////
3038 
3039 // Class Poly_Not_In_Bounding_Box_Chunk functions
3040 RIF_IMPLEMENT_DYNCREATE("PNOTINBB",Poly_Not_In_Bounding_Box_Chunk)
3041 
Poly_Not_In_Bounding_Box_Chunk(Chunk_With_Children * const parent,const char * data,size_t const datasize)3042 Poly_Not_In_Bounding_Box_Chunk::Poly_Not_In_Bounding_Box_Chunk(Chunk_With_Children* const parent,const char* data,size_t const datasize)
3043 :Chunk(parent,"PNOTINBB")
3044 {
3045 	for(int i=0;i<( ( (signed)datasize ) /4)-2;i++)
3046 	{
3047 		poly_no.add_entry(*(int*)data);
3048 		data+=4;
3049 	}
3050 	pad1=*(int*)data;
3051 	data+=4;
3052 	pad2=*(int*)data;
3053 
3054 }
3055 
Poly_Not_In_Bounding_Box_Chunk(Chunk_With_Children * const parent)3056 Poly_Not_In_Bounding_Box_Chunk::Poly_Not_In_Bounding_Box_Chunk(Chunk_With_Children* const parent)
3057 :Chunk(parent,"PNOTINBB")
3058 {
3059 	pad1=pad2=0;
3060 }
3061 
size_chunk()3062 size_t Poly_Not_In_Bounding_Box_Chunk::size_chunk()
3063 {
3064 	return chunk_size=(20+4*poly_no.size());
3065 }
3066 
fill_data_block(char * data_start)3067 void Poly_Not_In_Bounding_Box_Chunk::fill_data_block(char* data_start)
3068 {
3069 	strncpy (data_start, identifier, 8);
3070 	data_start += 8;
3071 	*((int *) data_start) = chunk_size;
3072 	data_start += 4;
3073 
3074 	for(LIF<int> plif(&poly_no);!plif.done();plif.next())
3075 	{
3076 		*(int*)data_start=plif();
3077 		data_start+=4;
3078 	}
3079 	*(int*)data_start=pad1;
3080 	data_start+=4;
3081 	*(int*)data_start=pad2;
3082 }
3083 
3084 
3085 /////////////////////////////////////////
3086 
3087 // Class Anim_Shape_Centre_Chunk functions
3088 
3089 RIF_IMPLEMENT_DYNCREATE("ANSHCEN2",Anim_Shape_Centre_Chunk)
3090 
Anim_Shape_Centre_Chunk(Chunk_With_Children * const parent,const char * data,size_t const)3091 Anim_Shape_Centre_Chunk::Anim_Shape_Centre_Chunk(Chunk_With_Children* const parent,const char* data,size_t const /*datasize*/)
3092 :Chunk(parent,"ANSHCEN2")
3093 {
3094 	Centre=*(ChunkVectorInt*)data;
3095 	data+=sizeof(ChunkVectorInt);
3096 	flags=*(int*)data;
3097 	data+=4;
3098 	pad2=*(int*)data;
3099 
3100 }
3101 
Anim_Shape_Centre_Chunk(Chunk_With_Children * const parent)3102 Anim_Shape_Centre_Chunk::Anim_Shape_Centre_Chunk(Chunk_With_Children* const parent)
3103 :Chunk(parent,"ANSHCEN2")
3104 {
3105 	Centre.x=0;
3106 	Centre.y=0;
3107 	Centre.z=0;
3108 	flags=pad2=0;
3109 }
3110 
size_chunk()3111 size_t Anim_Shape_Centre_Chunk::size_chunk()
3112 {
3113 	return chunk_size=(20+sizeof(ChunkVectorInt));
3114 }
3115 
fill_data_block(char * data_start)3116 void Anim_Shape_Centre_Chunk::fill_data_block(char* data_start)
3117 {
3118 	strncpy (data_start, identifier, 8);
3119 	data_start += 8;
3120 	*((int *) data_start) = chunk_size;
3121 	data_start += 4;
3122 
3123 	*(ChunkVectorInt*)data_start=Centre;
3124 	data_start+=sizeof(ChunkVectorInt);
3125 	*(int*)data_start=flags;
3126 	data_start+=4;
3127 	*(int*)data_start=pad2;
3128 
3129 }
3130 
3131 
3132 
3133 /////////////////////////////////////////
3134 
3135 // Class Console_Shape_Chunk functions
3136 
3137 /*
3138 Children for Console_Shape_Chunk :
3139 
3140 "SHPPOLYS"		Shape_Polygon_Chunk
3141 "SHPUVCRD"		Shape_UV_Coord_Chunk
3142 "TEXTANIM"		Animation_Chunk
3143 
3144 "CONSTYPE"		Console_Type_Chunk
3145 */
3146 
3147 
Console_Shape_Chunk(Chunk_With_Children * const parent,const char * data,size_t size)3148 Console_Shape_Chunk::Console_Shape_Chunk(Chunk_With_Children * const parent, const char *data, size_t  size)
3149 : Chunk_With_Children (parent, "CONSHAPE")
3150 {
3151 
3152 	shape_data_store=(ChunkShape*)&shape_data;
3153 
3154 	const char * buffer_ptr = data;
3155 
3156 	while ((data-buffer_ptr)< (signed)size) {
3157 
3158 		if ((*(int *)(data + 8)) + (data-buffer_ptr) > (signed)size) {
3159 			Parent_File->error_code = CHUNK_FAILED_ON_LOAD_NOT_RECOGNISED;
3160 			break;
3161 
3162 		DynCreate(data);
3163 		data += *(int *)(data + 8);
3164 		}
3165 	}
3166 
3167 }
3168 
Console_Shape_Chunk(Chunk_With_Children * const parent,Console_Type ct)3169 Console_Shape_Chunk::Console_Shape_Chunk(Chunk_With_Children* const parent,Console_Type ct)
3170 :Chunk_With_Children(parent,"CONSHAPE")
3171 {
3172 	shape_data_store=(ChunkShape*)&shape_data;
3173 	new Console_Type_Chunk(this,ct);
3174 }
generate_console_chunkshape()3175 void Console_Shape_Chunk::generate_console_chunkshape()
3176 {
3177 	//sort out the chunkshape
3178 	if(!strcmp(parent->identifier,"REBSHAPE"))
3179 	{
3180 		*shape_data_store=((Shape_Chunk*)parent)->shape_data;
3181 	}
3182 	else if(!strcmp(parent->identifier,"SUBSHAPE"))
3183 	{
3184 		*shape_data_store=((Shape_Sub_Shape_Chunk*)parent)->shape_data;
3185 	}
3186 	else
3187 	{
3188 		delete this;
3189 		return;
3190 	}
3191 
3192 	Shape_Polygon_Chunk* spc=(Shape_Polygon_Chunk*)lookup_single_child("SHPPOLYS");
3193 	if(spc)
3194 	{
3195 		if(spc->num_polys!=shape_data_store->num_polys)
3196 		{
3197 			//console shape is no longer valid.kill it.
3198 			delete this;
3199 			return;
3200 		}
3201 
3202 		ChunkPoly* poly_list=shape_data_store->poly_list;
3203 		shape_data_store->poly_list=(ChunkPoly*)spc->poly_data;
3204 		for(int i=0;i<shape_data_store->num_polys;i++)
3205 		{
3206 			for(int j=0;j<4;j++)
3207 			{
3208 				shape_data_store->poly_list[i].vert_ind[j]=poly_list[i].vert_ind[j];
3209 			}
3210 		}
3211 		delete [] poly_list;
3212 	}
3213 	Shape_UV_Coord_Chunk* succ=(Shape_UV_Coord_Chunk*)lookup_single_child("SHPUVCRD");
3214 	if(succ)
3215 	{
3216 		delete [] shape_data_store->uv_list;
3217 		shape_data_store->uv_list=(ChunkUV_List*)succ->uv_data;
3218 		shape_data_store->num_uvs=succ->num_uvs;
3219 	}
3220 }
3221 
update_my_chunkshape(ChunkShape & cshp)3222 void Console_Shape_Chunk::update_my_chunkshape(ChunkShape & cshp)
3223 {
3224 	List<Chunk*> chlist;
3225 	lookup_child("SHPUVCRD",chlist);
3226 	while(chlist.size())
3227 	{
3228 		delete chlist.first_entry();
3229 		chlist.delete_first_entry();
3230 	}
3231 	lookup_child("SHPPOLYS",chlist);
3232 	while(chlist.size())
3233 	{
3234 		delete chlist.first_entry();
3235 		chlist.delete_first_entry();
3236 	}
3237 	*shape_data_store=cshp;
3238 	if (shape_data.poly_list) new Shape_Polygon_Chunk (this, shape_data.num_polys);
3239 	if (shape_data.uv_list) new Shape_UV_Coord_Chunk (this, shape_data.num_uvs);
3240 
3241 }
3242 
3243 
3244 /////////////////////////////////////////
3245 
3246 // Class Console_Type_Chunk functions
3247 RIF_IMPLEMENT_DYNCREATE("CONSTYPE",Console_Type_Chunk)
3248 
fill_data_block(char * data_start)3249 void Console_Type_Chunk::fill_data_block(char* data_start)
3250 {
3251 	strncpy (data_start, identifier, 8);
3252 	data_start += 8;
3253 	*((int *) data_start) = chunk_size;
3254 	data_start += 4;
3255 
3256 	*(int*)data_start=(int)console;
3257 }
3258 
3259 
3260 /////////////////////////////////////////
3261 RIF_IMPLEMENT_DYNCREATE("SHPPRPRO",Shape_Preprocessed_Data_Chunk)
3262 
Shape_Preprocessed_Data_Chunk(Chunk_With_Children * parent,const char * data,size_t)3263 Shape_Preprocessed_Data_Chunk::Shape_Preprocessed_Data_Chunk (Chunk_With_Children * parent, const char * data, size_t )
3264 :Chunk(parent,"SHPPRPRO")
3265 {
3266 	block_size=*(int*)data;
3267 	data+=4;
3268 	first_pointer=*(int*)data;
3269 	data+=4;
3270 
3271 	if(block_size)
3272 	{
3273 		memory_block=new unsigned int[block_size];
3274 		memcpy(memory_block,data,block_size*4);
3275 		data+=block_size*4;
3276 	}
3277 	else
3278 	{
3279 		memory_block=0;
3280 	}
3281 
3282 	num_extra_data=*(int*)data;
3283 	data+=4;
3284 
3285 	if(num_extra_data)
3286 	{
3287 		extra_data=new int[num_extra_data];
3288 		memcpy(extra_data,data,num_extra_data*4);
3289 	}
3290 	else
3291 	{
3292 		extra_data=0;
3293 	}
3294 }
3295 
Shape_Preprocessed_Data_Chunk(Chunk_With_Children * parent,int _block_size,int _first_pointer,unsigned int * _memory_block)3296 Shape_Preprocessed_Data_Chunk::Shape_Preprocessed_Data_Chunk (Chunk_With_Children * parent,int _block_size,int _first_pointer,unsigned int* _memory_block)
3297 :Chunk(parent,"SHPPRPRO")
3298 {
3299 	num_extra_data=0;
3300 	extra_data=0;
3301 	block_size=_block_size;
3302 	first_pointer=_first_pointer;
3303 
3304 	if(block_size)
3305 	{
3306 		memory_block=new unsigned int[block_size];
3307 		memcpy(memory_block,_memory_block,block_size*4);
3308 	}
3309 	else
3310 	{
3311 		memory_block=0;
3312 	}
3313 
3314 }
3315 
fill_data_block(char * data_start)3316 void Shape_Preprocessed_Data_Chunk::fill_data_block(char* data_start)
3317 {
3318 	strncpy (data_start, identifier, 8);
3319 	data_start += 8;
3320 	*((int *) data_start) = chunk_size;
3321 	data_start += 4;
3322 
3323 	*(int*)data_start=block_size;
3324 	data_start+=4;
3325 	*(int*)data_start=first_pointer;
3326 	data_start+=4;
3327 
3328 	memcpy(data_start,memory_block,4*block_size);
3329 	data_start+=4*block_size;
3330 
3331 	*(int*)data_start=num_extra_data;
3332 	data_start+=4;
3333 	memcpy(data_start,extra_data,4*num_extra_data);
3334 }
3335 
GetMemoryBlock()3336 void* Shape_Preprocessed_Data_Chunk::GetMemoryBlock()
3337 {
3338 	void* retval=memory_block;
3339 
3340 // 64HACK
3341 #pragma message ("64HACK")
3342 #if 0
3343 	unsigned int* current=(unsigned int*)&first_pointer;
3344 	unsigned int* next;
3345 	while((*current>>16)!=0xffff)
3346 	{
3347 		next=&memory_block[(*current)>>16];
3348 		*current=(unsigned int)&memory_block[(*current)&0xffff];
3349 		current=next;
3350 	}
3351 	*current=(unsigned int)&memory_block[(*current)&0xffff];
3352 #endif
3353 	memory_block=0;
3354 	block_size=0;
3355 	return retval;
3356 }
3357 
3358