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